Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
9.1 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1998
  5. //
  6. // File: RegSettingsIO.cxx
  7. //
  8. // Contents: Register Settings IO functions
  9. //
  10. // Written by Lyle Corbin
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "headers.hxx"
  14. #include "RegSettingsIO.h"
  15. const WCHAR *g_szRegistry = L"Software\\Microsoft\\MTScript";
  16. HRESULT
  17. RegSettingsIO(const WCHAR *szRegistry, BOOL fSave, const REGKEYINFORMATION *aKeyValues, int cKeyValues, BYTE *pBase)
  18. {
  19. LONG lRet;
  20. HKEY hKeyRoot = NULL;
  21. HKEY hKeySub = NULL;
  22. int i;
  23. DWORD dwType;
  24. DWORD dwSize;
  25. DWORD dwDisposition;
  26. DWORD dwDataBuf[MAX_REG_VALUE_LENGTH];
  27. BYTE * bDataBuf = (BYTE*) dwDataBuf;
  28. BYTE * pbData;
  29. BOOL fWriteReg = fSave;
  30. WCHAR * pch;
  31. const REGKEYINFORMATION * prki;
  32. lRet = RegCreateKeyEx(HKEY_CURRENT_USER,
  33. g_szRegistry,
  34. 0,
  35. NULL,
  36. 0,
  37. KEY_ALL_ACCESS,
  38. NULL,
  39. &hKeyRoot,
  40. &dwDisposition);
  41. if( lRet != ERROR_SUCCESS )
  42. return S_FALSE;
  43. if (dwDisposition == REG_CREATED_NEW_KEY)
  44. {
  45. //
  46. // The key didn't exist. Write out the default values.
  47. //
  48. fWriteReg = TRUE;
  49. }
  50. for (i = 0; i < cKeyValues; i++)
  51. {
  52. prki = &aKeyValues[i];
  53. switch (prki->rkiType)
  54. {
  55. case RKI_KEY:
  56. if (!prki->pszName)
  57. {
  58. hKeySub = hKeyRoot;
  59. }
  60. else
  61. {
  62. if (hKeySub && (hKeySub != hKeyRoot))
  63. {
  64. RegCloseKey(hKeySub);
  65. hKeySub = NULL;
  66. fWriteReg = fSave;
  67. }
  68. pch = prki->pszName;
  69. lRet = RegCreateKeyEx(hKeyRoot,
  70. pch,
  71. 0,
  72. NULL,
  73. 0,
  74. KEY_ALL_ACCESS,
  75. NULL,
  76. &hKeySub,
  77. &dwDisposition);
  78. if (lRet != ERROR_SUCCESS)
  79. {
  80. // We couldn't get this key, skip it.
  81. i++;
  82. while (i < cKeyValues &&
  83. aKeyValues[i].rkiType != RKI_KEY)
  84. {
  85. i++;
  86. }
  87. i--; // Account for the fact that continue will increment i again.
  88. hKeySub = NULL;
  89. continue;
  90. }
  91. else if (dwDisposition == REG_CREATED_NEW_KEY)
  92. {
  93. //
  94. // The key didn't exist. Write out the default values.
  95. //
  96. fWriteReg = TRUE;
  97. }
  98. }
  99. break;
  100. case RKI_BOOL:
  101. Assert(hKeySub);
  102. if (fWriteReg)
  103. {
  104. RegSetValueEx(hKeySub,
  105. prki->pszName,
  106. 0,
  107. REG_DWORD,
  108. (BYTE*)((BYTE *)pBase + prki->cbOffset),
  109. sizeof(BOOL));
  110. }
  111. else
  112. {
  113. dwSize = MAX_REG_VALUE_LENGTH;
  114. lRet = RegQueryValueEx(hKeySub,
  115. prki->pszName,
  116. 0,
  117. &dwType,
  118. bDataBuf,
  119. &dwSize);
  120. if (lRet == ERROR_SUCCESS)
  121. {
  122. pbData = (BYTE*)((BYTE *)pBase + prki->cbOffset);
  123. if (dwType == REG_DWORD)
  124. {
  125. *pbData = (*(DWORD*)bDataBuf != 0);
  126. }
  127. else if (dwType == REG_SZ)
  128. {
  129. TCHAR ch = *(TCHAR *)bDataBuf;
  130. if (ch == _T('1') ||
  131. ch == _T('y') ||
  132. ch == _T('Y'))
  133. {
  134. *pbData = TRUE;
  135. }
  136. else
  137. {
  138. *pbData = FALSE;
  139. }
  140. } else if (dwType == REG_BINARY)
  141. {
  142. *pbData = (*(BYTE*)bDataBuf != 0);
  143. }
  144. // Can't convert other types. Just leave it the default.
  145. }
  146. }
  147. break;
  148. case RKI_DWORD:
  149. Assert(hKeySub);
  150. if (fWriteReg)
  151. {
  152. RegSetValueEx(hKeySub,
  153. prki->pszName,
  154. 0,
  155. REG_DWORD,
  156. (BYTE*)((BYTE *)pBase + prki->cbOffset),
  157. sizeof(DWORD));
  158. }
  159. else
  160. {
  161. dwSize = sizeof(DWORD);
  162. lRet = RegQueryValueEx(hKeySub,
  163. prki->pszName,
  164. 0,
  165. &dwType,
  166. bDataBuf,
  167. &dwSize);
  168. if (lRet == ERROR_SUCCESS && (dwType == REG_BINARY || dwType == REG_DWORD))
  169. {
  170. *(DWORD*)((BYTE *)pBase + prki->cbOffset) = *(DWORD*)bDataBuf;
  171. }
  172. }
  173. break;
  174. case RKI_STRING:
  175. case RKI_EXPANDSZ:
  176. Assert(hKeySub);
  177. {
  178. CStr *pstr = ((CStr *)((BYTE *)pBase + prki->cbOffset));
  179. if (fWriteReg)
  180. {
  181. //
  182. // Only write it out if there is a value there. That way
  183. // we get the default next time we load even if it may
  184. // evaluate differently (e.g. location of this exe
  185. // changes).
  186. //
  187. RegSetValueEx(hKeySub,
  188. prki->pszName,
  189. 0,
  190. (prki->rkiType == RKI_STRING) ? REG_SZ : REG_EXPAND_SZ,
  191. (BYTE*)((pstr->Length() > 0) ? (LPTSTR)*pstr : L""),
  192. (pstr->Length()+1) * sizeof(TCHAR));
  193. }
  194. else
  195. {
  196. dwSize = 0;
  197. // get the size of string
  198. lRet = RegQueryValueEx(hKeySub,
  199. prki->pszName,
  200. 0,
  201. &dwType,
  202. NULL,
  203. &dwSize);
  204. if (lRet == ERROR_SUCCESS && dwSize - sizeof(TCHAR) > 0)
  205. {
  206. // Set already adds 1 for a terminating NULL, and
  207. // dwSize is including it as well.
  208. pstr->Set(NULL, (dwSize / sizeof(TCHAR)) - 1);
  209. lRet = RegQueryValueEx(hKeySub,
  210. prki->pszName,
  211. 0,
  212. &dwType,
  213. (BYTE*)(LPTSTR)*pstr,
  214. &dwSize);
  215. if (lRet != ERROR_SUCCESS ||
  216. (dwType != REG_SZ && dwType != REG_EXPAND_SZ))
  217. {
  218. pstr->Free();
  219. }
  220. if (dwType == REG_EXPAND_SZ)
  221. {
  222. CStr cstrExpand;
  223. dwSize = ExpandEnvironmentStrings(*pstr, NULL, 0);
  224. // Set already adds 1 for a terminating NULL, and
  225. // dwSize is including it as well.
  226. cstrExpand.Set(NULL, dwSize - 1);
  227. dwSize = ExpandEnvironmentStrings(*pstr, cstrExpand, dwSize + 1);
  228. pstr->TakeOwnership(cstrExpand);
  229. }
  230. pstr->TrimTrailingWhitespace();
  231. }
  232. }
  233. }
  234. break;
  235. default:
  236. AssertSz(FALSE, "Unrecognized RKI Type");
  237. break;
  238. }
  239. }
  240. if (hKeySub && (hKeySub != hKeyRoot))
  241. RegCloseKey(hKeySub);
  242. RegCloseKey( hKeyRoot );
  243. return S_OK;
  244. }