25 StdCopyStrBuf GetRegistryString(
const char *szSubKey,
const char *szValueName)
30 if (RegOpenKeyExW(HKEY_CURRENT_USER,
GetWideChar(szSubKey), 0, KEY_READ, &ckey)!=ERROR_SUCCESS)
34 DWORD dwValSize = 128;
39 switch(RegQueryValueExW(ckey,
GetWideChar(szValueName),
nullptr, &valtype,
44 if (valtype == REG_SZ)
57 sValue =
new BYTE[dwValSize];
63 bool SetRegistryString(
const char *szSubKey,
64 const char *szValueName,
73 if ((qerr=RegCreateKeyExW(HKEY_CURRENT_USER,
77 REG_OPTION_NON_VOLATILE,
82 ))!=ERROR_SUCCESS)
return false;
86 if ((qerr=RegSetValueExW(ckey,
92 ))!=ERROR_SUCCESS) { RegCloseKey(ckey);
return false; }
100 static bool DeleteRegistryKey(HKEY hKey,
const wchar_t *szSubKey)
104 if (RegOpenKeyExW(hKey, szSubKey, 0, KEY_ALL_ACCESS, &ckey) != ERROR_SUCCESS)
return false;
106 wchar_t strChild[1024 + 1];
107 while (RegEnumKeyW(ckey, 0, strChild, 1024) == ERROR_SUCCESS)
108 if (!DeleteRegistryKey(ckey, strChild))
114 if (RegDeleteKeyW(hKey, szSubKey) != ERROR_SUCCESS)
return false;
119 static bool SetRegClassesRoot(
const wchar_t *szSubKey,
120 const wchar_t *szValueName,
121 const wchar_t *szStringValue)
129 if ((qerr=RegCreateKeyExW(HKEY_CLASSES_ROOT,
133 REG_OPTION_NON_VOLATILE,
138 ))!=ERROR_SUCCESS)
return false;
141 if ((qerr=RegSetValueExW(ckey,
145 (
const BYTE*)szStringValue,
146 (wcslen(szStringValue) + 1) *
sizeof(
wchar_t)
147 ))!=ERROR_SUCCESS) { RegCloseKey(ckey);
return false; }
155 bool SetRegShell(
const wchar_t *szClassName,
156 const wchar_t *szShellName,
157 const wchar_t *szShellCaption,
158 const wchar_t *szCommand,
161 wchar_t szKeyName[256+1];
163 _snwprintf(szKeyName,256,L
"%s\\Shell\\%s",szClassName,szShellName);
164 if (!SetRegClassesRoot(szKeyName,
nullptr, szShellCaption))
return false;
166 _snwprintf(szKeyName,256,L
"%s\\Shell\\%s\\Command",szClassName,szShellName);
167 if (!SetRegClassesRoot(szKeyName,
nullptr, szCommand))
return false;
171 _snwprintf(szKeyName, 256,L
"%s\\Shell", szClassName);
172 if (!SetRegClassesRoot(szKeyName,
nullptr, szShellName))
return false;
177 bool RemoveRegShell(
const char *szClassName,
178 const char *szShellName)
180 wchar_t strKey[256+1];
182 if (!DeleteRegistryKey(HKEY_CLASSES_ROOT, strKey))
return false;
188 bool StoreWindowPosition(HWND hwnd,
189 const char *szWindowName,
190 const char *szSubKey,
196 return SetRegistryString(szSubKey,szWindowName,
"Maximized");
198 return SetRegistryString(szSubKey,szWindowName,
"Minimized");
199 if (!GetWindowRect(hwnd,&winpos))
return false;
200 if (fStoreSize)
sprintf(regstr,
"%ld,%ld,%ld,%ld",winpos.left,winpos.top,winpos.right-winpos.left,winpos.bottom-winpos.top);
201 else sprintf(regstr,
"%ld,%ld",winpos.left,winpos.top);
202 return SetRegistryString(szSubKey,szWindowName,regstr);
205 bool RestoreWindowPosition(HWND hwnd,
206 const char *szWindowName,
207 const char *szSubKey,
213 StdCopyStrBuf regstr = GetRegistryString(szSubKey,szWindowName);
217 if (regstr ==
"Maximized")
218 return !!ShowWindow(hwnd,SW_MAXIMIZE | SW_NORMAL);
219 if (regstr ==
"Minimized")
220 return !!ShowWindow(hwnd,SW_MINIMIZE | SW_NORMAL);
223 if (
SCopySegment(regstr.
getData(),2,buffer2,
',',4)) sscanf(buffer2,
"%i",&wdt);
else fSetSize=
false;
224 if (
SCopySegment(regstr.
getData(),3,buffer2,
',',4)) sscanf(buffer2,
"%i",&hgt);
else fSetSize=
false;
227 RECT winpos;
if (!GetWindowRect(hwnd,&winpos))
return false;
228 wdt=winpos.right-winpos.left; hgt=winpos.bottom-winpos.top;
231 WINDOWPLACEMENT wp; memset(&wp, 0,
sizeof(WINDOWPLACEMENT)); wp.length =
sizeof(WINDOWPLACEMENT);
232 GetWindowPlacement(hwnd, &wp);
234 normalpos.left = x; normalpos.right = wdt + x;
235 normalpos.top = y; normalpos.bottom = hgt + y;
236 wp.rcNormalPosition = normalpos;
237 if (SetWindowPlacement(hwnd, &wp))
241 return !!ShowWindow(hwnd, SW_HIDE);
243 return !!ShowWindow(hwnd, SW_NORMAL);
250 StdCompilerConfigWrite::StdCompilerConfigWrite(HKEY hRoot,
const char *szPath)
251 : iDepth(0), pKey(new Key())
255 pKey->Handle =
nullptr;
259 StdCompilerConfigWrite::~StdCompilerConfigWrite()
262 if (pKey->Handle) RegCloseKey(pKey->Handle);
266 bool StdCompilerConfigWrite::Name(
const char *szName)
271 auto *pnKey =
new Key();
272 pnKey->Handle =
nullptr;
274 if (pKey->LastChildName == szName)
275 pnKey->Name.Format(
"%s%d", szName, (
int)++pKey->subindex);
278 pnKey->Name = szName;
279 pKey->LastChildName = szName;
281 pnKey->Parent = pKey;
284 last_written_string.clear();
288 void StdCompilerConfigWrite::NameEnd(
bool fBreak)
293 RegCloseKey(pKey->Handle);
296 pKey = poKey->Parent;
299 last_written_string.clear();
302 bool StdCompilerConfigWrite::FollowName(
const char *szName)
304 NameEnd();
return Name(szName);
307 bool StdCompilerConfigWrite::Default(
const char *szName)
312 DeleteRegistryKey(pKey->Handle,
GetWideChar(szName));
313 RegDeleteValueW(pKey->Handle,
GetWideChar(szName));
318 bool StdCompilerConfigWrite::Separator(Sep eSep)
321 const char s[2] = { SeparatorToChar(eSep) ,
'\0' };
326 void StdCompilerConfigWrite::DWord(int32_t &rInt)
330 void StdCompilerConfigWrite::DWord(uint32_t &rInt)
334 void StdCompilerConfigWrite::Word(int16_t &rInt)
338 void StdCompilerConfigWrite::Word(uint16_t &rInt)
342 void StdCompilerConfigWrite::Byte(int8_t &rInt)
346 void StdCompilerConfigWrite::Byte(uint8_t &rInt)
350 void StdCompilerConfigWrite::Boolean(
bool &rBool)
352 WriteDWord(rBool ? 1 : 0);
354 void StdCompilerConfigWrite::Character(
char &rChar)
361 WriteString(szString);
366 WriteString(pszString ? *pszString :
"");
371 WriteString(str.c_str());
374 void StdCompilerConfigWrite::Raw(
void *pData,
size_t iSize, RawCompileType eType)
376 excCorrupt(
"Raw values aren't supported for registry compilers!");
379 void StdCompilerConfigWrite::Begin()
384 void StdCompilerConfigWrite::End()
389 void StdCompilerConfigWrite::CreateKey(HKEY hParent)
395 if (RegCreateKeyExW(hParent ? hParent : pKey->Parent->Handle,
396 pKey->Name.GetWideChar(),
397 0,
nullptr, REG_OPTION_NON_VOLATILE,
399 &pKey->Handle,
nullptr) != ERROR_SUCCESS)
400 excCorrupt(
"Could not create key %s!", pKey->Name.getData());
403 void StdCompilerConfigWrite::WriteDWord(uint32_t iVal)
406 if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
407 0, REG_DWORD,
reinterpret_cast<const BYTE *
>(&iVal),
408 sizeof(iVal)) != ERROR_SUCCESS)
409 excCorrupt(
"Could not write key %s!", pKey->Name.getData());
412 void StdCompilerConfigWrite::WriteString(
const char *szString)
416 last_written_string += szString;
418 if (RegSetValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
419 0, REG_SZ, getBufPtr<BYTE>(v), v.
getSize()) != ERROR_SUCCESS)
420 excCorrupt(
"Could not write key %s!", pKey->Name.getData());
425 StdCompilerConfigRead::StdCompilerConfigRead(HKEY hRoot,
const char *szPath)
426 : iDepth(0), pKey(new Key())
429 pKey->Virtual =
false;
434 &pKey->Handle) != ERROR_SUCCESS)
435 pKey->Handle =
nullptr;
438 StdCompilerConfigRead::~StdCompilerConfigRead()
441 if (pKey->Handle) RegCloseKey(pKey->Handle);
445 bool StdCompilerConfigRead::Name(
const char *szName)
449 if (pKey->LastChildName == szName)
450 sName.
Format(
"%s%d", szName, (
int)++pKey->subindex);
454 pKey->LastChildName = szName;
458 HKEY hSubKey;
DWORD dwType = 0;
459 if (RegOpenKeyExW(pKey->Handle, sName.GetWideChar(),
461 &hSubKey) != ERROR_SUCCESS)
465 if (RegQueryValueExW(pKey->Handle, sName.GetWideChar(),
466 nullptr, &dwType,
nullptr,
nullptr) != ERROR_SUCCESS)
470 Key *pnKey =
new Key();
471 pnKey->Handle = hSubKey;
474 pnKey->Parent = pKey;
475 pnKey->Virtual = !fFound;
476 pnKey->Type = dwType;
483 void StdCompilerConfigRead::NameEnd(
bool fBreak)
488 RegCloseKey(pKey->Handle);
491 pKey = poKey->Parent;
497 void StdCompilerConfigRead::ResetLastString()
499 has_read_string =
false;
500 has_separator_mismatch =
false;
501 last_read_string.clear();
504 bool StdCompilerConfigRead::FollowName(
const char *szName)
506 NameEnd();
return Name(szName);
509 bool StdCompilerConfigRead::Separator(Sep eSep)
514 if (last_read_string.size() && (last_read_string.front() == SeparatorToChar(eSep)))
517 last_read_string = last_read_string.substr(1);
523 has_separator_mismatch =
true;
528 void StdCompilerConfigRead::NoSeparator() {
529 has_separator_mismatch =
false;
532 void StdCompilerConfigRead::DWord(int32_t &rInt)
534 rInt = int32_t(ReadDWord());
536 void StdCompilerConfigRead::DWord(uint32_t &rInt)
540 void StdCompilerConfigRead::Word(int16_t &rInt)
542 rInt = int16_t(ReadDWord());
544 void StdCompilerConfigRead::Word(uint16_t &rInt)
546 rInt = uint16_t(ReadDWord());
548 void StdCompilerConfigRead::Byte(int8_t &rInt)
550 rInt = int8_t(ReadDWord());
552 void StdCompilerConfigRead::Byte(uint8_t &rInt)
554 rInt = uint8_t(ReadDWord());
556 void StdCompilerConfigRead::Boolean(
bool &rBool)
561 rBool = (!has_separator_mismatch && (last_read_string ==
"true"));
563 catch (NotFoundException *pExc)
566 uint32_t iVal = ReadDWord();
570 void StdCompilerConfigRead::Character(
char &rChar)
575 rChar = (last_read_string.length() && !has_separator_mismatch) ? last_read_string.front() :
'\0';
577 catch (NotFoundException *pExc)
580 uint32_t iVal = ReadDWord();
589 SCopy(
s.c_str(), szString, iMaxLength);
598 *pszString = sbuf.GrabPointer();
605 if (has_separator_mismatch || !last_read_string.length()) { str =
"\0";
return; }
606 size_t string_end_pos = 0;
607 const char *
s = last_read_string.c_str();
609 while (!IsStringEnd(
s[spos],
type)) ++spos;
610 if (spos < last_read_string.length())
612 str = last_read_string.substr(0, spos);
613 last_read_string = last_read_string.substr(spos);
617 str = last_read_string;
618 last_read_string.clear();
622 void StdCompilerConfigRead::Raw(
void *pData,
size_t iSize, RawCompileType eType)
624 excCorrupt(
nullptr,
"Raw values aren't supported for registry compilers!");
627 void StdCompilerConfigRead::Begin()
632 void StdCompilerConfigRead::End()
637 uint32_t StdCompilerConfigRead::ReadDWord()
641 { excNotFound(
"Could not read value %s! Parent key doesn't exist!", pKey->Name.getData());
return 0; }
643 if (pKey->Type != REG_DWORD && pKey->Type != REG_DWORD_LITTLE_ENDIAN)
644 { excNotFound(
"Wrong value type!");
return 0; }
649 if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
651 reinterpret_cast<LPBYTE
>(&iVal),
652 &
iSize) != ERROR_SUCCESS)
653 { excNotFound(
"Could not read value %s!", pKey->Name.getData());
return 0; }
655 if (
iSize !=
sizeof(iVal))
656 { excCorrupt(
"Wrong size of a DWord!");
return 0; }
661 void StdCompilerConfigRead::ReadString()
664 if (!has_read_string)
670 excNotFound(
"Could not read value %s! Parent key doesn't exist!", pKey->Name.getData());
return;
673 if (pKey->Type != REG_SZ)
675 excNotFound(
"Wrong value type!");
return;
679 if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
682 &
iSize) != ERROR_SUCCESS)
684 excNotFound(
"Could not read value %s!", pKey->Name.getData());
return;
689 if (RegQueryValueExW(pKey->Parent->Handle, pKey->Name.GetWideChar(),
692 &
iSize) != ERROR_SUCCESS)
694 excNotFound(
"Could not read value %s!", pKey->Name.getData());
return;
697 if (wcslen(getBufPtr<wchar_t>(Result)) + 1 !=
iSize /
sizeof(
wchar_t))
699 excCorrupt(
"Wrong size of a string!");
return;
702 StdStrBuf str_result(getBufPtr<wchar_t>(Result));
703 last_read_string = str_result.getData();
704 has_read_string =
true;
C4String * String(const char *str)
StdStrBuf::wchar_t_holder GetWideChar(const char *utf8, bool double_null_terminate=false)
StdBuf GetWideCharBuf(const char *utf8)
bool SCopySegment(const char *szString, int iSegment, char *sTarget, char cSeparator, int iMaxL, bool fSkipWhitespace)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
StdStrBuf FormatString(const char *szFmt,...)
void SetSize(size_t inSize)
const char * getData() const
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O