StdStrBuf StdCompilerConfigRead::ReadString()
{
	// Virtual key?
	if (pKey->Virtual)
		{ excNotFound("Could not read value %s! Parent key doesn't exist!", pKey->Name.getData()); return StdStrBuf(); }
	// Wrong type?
	if (pKey->Type != REG_SZ)
		{ excNotFound("Wrong value type!"); return StdStrBuf(); }
	// Get size of string
	DWORD iSize;
	if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
	                    0, NULL,
	                    NULL,
	                    &iSize) != ERROR_SUCCESS)
		{ excNotFound("Could not read value %s!", pKey->Name.getData()); return StdStrBuf(); }
	// Allocate string
	StdBuf Result; Result.SetSize(iSize);
	// Read
	if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
	                    0, NULL,
	                    reinterpret_cast<BYTE *>(Result.getMData()),
	                    &iSize) != ERROR_SUCCESS)
		{ excNotFound("Could not read value %s!", pKey->Name.getData()); return StdStrBuf(); }
	// Check size
	if (wcslen(getBufPtr<wchar_t>(Result)) + 1 != iSize / sizeof(wchar_t))
		{ excCorrupt("Wrong size of a string!"); return StdStrBuf(); }
	return StdStrBuf(getBufPtr<wchar_t>(Result));
}
void StdCompilerConfigWrite::WriteDWord(uint32_t iVal)
{
	// Set the value
	if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
	                  0, REG_DWORD, reinterpret_cast<const BYTE *>(&iVal),
	                  sizeof(iVal)) != ERROR_SUCCESS)
		excCorrupt("Could not write key %s!", pKey->Name.getData());
}
void StdCompilerConfigWrite::WriteString(const char *szString)
{
	// Append or set the value
	if (LastString.getLength()) LastString.Append(szString); else LastString.Copy(szString);
	StdBuf v = LastString.GetWideCharBuf();
	if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
	                  0, REG_SZ, getBufPtr<BYTE>(v), v.getSize()) != ERROR_SUCCESS)
		excCorrupt("Could not write key %s!", pKey->Name.getData());
}
void StdCompilerBinRead::String(char *szString, size_t iMaxLength, RawCompileType eType)
{
	// At least one byte data needed
	if (iPos >= Buf.getSize())
		{ excEOF(); return; }
	// Copy until no data left
	char *pPos = szString;
	while ((*pPos++ = *getBufPtr<char>(Buf, iPos++)))
		if (iPos >= Buf.getSize())
			{ excEOF(); return; }
		else if (pPos > szString + iMaxLength)
			{ excCorrupt("string too long"); return; }
}
void StdCompilerConfigWrite::CreateKey(HKEY hParent)
{
	// Already open?
	if (pKey->Handle)
		return;
	// Open/Create registry key
	if (RegCreateKeyExW(hParent ? hParent : pKey->Parent->Handle,
	                   pKey->Name.GetWideChar(),
	                   0, L"", REG_OPTION_NON_VOLATILE,
	                   KEY_WRITE, NULL,
	                   &pKey->Handle, NULL) != ERROR_SUCCESS)
		excCorrupt("Could not create key %s!", pKey->Name.getData());
}
uint32_t StdCompilerConfigRead::ReadDWord()
{
	// Virtual key?
	if (pKey->Virtual)
		{ excNotFound("Could not read value %s! Parent key doesn't exist!", pKey->Name.getData()); return 0; }
	// Wrong type?
	if (pKey->Type != REG_DWORD && pKey->Type != REG_DWORD_LITTLE_ENDIAN)
		{ excNotFound("Wrong value type!"); return 0; }
	// Read
	uint32_t iVal; DWORD iSize = sizeof(iVal);
	if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
	                    0, NULL,
	                    reinterpret_cast<LPBYTE>(&iVal),
	                    &iSize) != ERROR_SUCCESS)
		{ excNotFound("Could not read value %s!", pKey->Name.getData()); return 0; }
	// Check size
	if (iSize != sizeof(iVal))
		{ excCorrupt("Wrong size of a DWord!"); return 0; }
	// Return
	return iVal;
}
void StdCompilerConfigRead::Raw(void *pData, size_t iSize, RawCompileType eType)
{
	excCorrupt(0, "Raw values aren't supported for registry compilers!");
}