Leaked source code of windows server 2003
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.

476 lines
12 KiB

  1. #include <windows.h>
  2. #include <fusenetincludes.h>
  3. #define REGISTRY_BASE_LOCATION L"Software\\Microsoft\\Fusion\\Installer\\"
  4. //////////////////////////////////////////////////////////////////////////////
  5. //
  6. // Emitter
  7. //
  8. //////////////////////////////////////////////////////////////////////////////
  9. // ---------------------------------------------------------------------------
  10. // CRegEmit ctor
  11. // ---------------------------------------------------------------------------
  12. CRegEmit::CRegEmit()
  13. : _hr(S_OK), _hBaseKey((HKEY) INVALID_HANDLE_VALUE)
  14. {}
  15. // ---------------------------------------------------------------------------
  16. // CRegEmit dtor
  17. // ---------------------------------------------------------------------------
  18. CRegEmit::~CRegEmit()
  19. {
  20. if (_hBaseKey != INVALID_HANDLE_VALUE)
  21. IF_FAILED_EXIT(RegCloseKey(_hBaseKey));
  22. exit:
  23. return;
  24. }
  25. // ---------------------------------------------------------------------------
  26. // CRegEmit::Create
  27. // ---------------------------------------------------------------------------
  28. HRESULT CRegEmit::Create(CRegEmit **ppEmit, LPCWSTR pwzRelKeyPath,
  29. CRegEmit* pParentEmit)
  30. {
  31. HRESULT hr = S_OK;
  32. MAKE_ERROR_MACROS_STATIC(hr);
  33. HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
  34. LONG lReturn = 0;
  35. DWORD dwDisposition = 0;
  36. CString sBasePath;
  37. CRegEmit *pEmit = NULL;
  38. if (!pParentEmit)
  39. {
  40. IF_FAILED_EXIT(sBasePath.Assign(REGISTRY_BASE_LOCATION));
  41. if (pwzRelKeyPath)
  42. IF_FAILED_EXIT(sBasePath.Append(pwzRelKeyPath));
  43. hKey = HKEY_CURRENT_USER;
  44. }
  45. else
  46. {
  47. IF_NULL_EXIT(pwzRelKeyPath, E_INVALIDARG);
  48. sBasePath.Assign(pwzRelKeyPath);
  49. hKey = pParentEmit->_hBaseKey;
  50. }
  51. IF_ALLOC_FAILED_EXIT(pEmit = new CRegEmit);
  52. lReturn = RegCreateKeyEx(
  53. hKey,
  54. sBasePath._pwz,
  55. 0,
  56. NULL,
  57. REG_OPTION_NON_VOLATILE,
  58. KEY_WRITE,
  59. NULL,
  60. &pEmit->_hBaseKey,
  61. &dwDisposition);
  62. IF_WIN32_FAILED_EXIT(lReturn);
  63. *ppEmit = pEmit;
  64. exit:
  65. if (FAILED(hr))
  66. SAFEDELETE(pEmit);
  67. return hr;
  68. }
  69. // ---------------------------------------------------------------------------
  70. // WriteDword
  71. // ---------------------------------------------------------------------------
  72. HRESULT CRegEmit::WriteDword(LPCWSTR pwzValue, DWORD dwData)
  73. {
  74. LONG lReturn = 0;
  75. lReturn = RegSetValueEx(_hBaseKey, pwzValue, 0, REG_DWORD, (LPBYTE) &dwData, sizeof(DWORD));
  76. IF_WIN32_FAILED_EXIT(lReturn);
  77. exit:
  78. return _hr;
  79. }
  80. // ---------------------------------------------------------------------------
  81. // WriteString
  82. // ---------------------------------------------------------------------------
  83. HRESULT CRegEmit::WriteString(LPCWSTR pwzValue, LPCWSTR pwzData, DWORD ccData)
  84. {
  85. LONG lReturn = 0;
  86. DWORD cbData = 0;
  87. IF_FALSE_EXIT(pwzData, E_INVALIDARG);
  88. if (ccData)
  89. cbData = ccData * sizeof(WCHAR);
  90. else
  91. cbData = (lstrlen(pwzData) + 1) * sizeof(WCHAR);
  92. lReturn = RegSetValueEx(_hBaseKey, pwzValue, 0, REG_SZ, (LPBYTE) pwzData, cbData);
  93. IF_WIN32_FAILED_EXIT(lReturn);
  94. exit:
  95. return _hr;
  96. }
  97. // ---------------------------------------------------------------------------
  98. // WriteString
  99. // ---------------------------------------------------------------------------
  100. HRESULT CRegEmit::WriteString(LPCWSTR pwzValue, CString &sData)
  101. {
  102. return WriteString(pwzValue, sData._pwz, sData._cc);
  103. }
  104. // ---------------------------------------------------------------------------
  105. // DeleteKey
  106. // The one and only place we use the lousy Shlwapi apis.
  107. // ---------------------------------------------------------------------------
  108. HRESULT CRegEmit::DeleteKey(LPCWSTR pwzSubKey)
  109. {
  110. IF_FAILED_EXIT(SHDeleteKey(_hBaseKey, pwzSubKey));
  111. exit:
  112. return _hr;
  113. }
  114. //////////////////////////////////////////////////////////////////////////////
  115. //
  116. // Importer
  117. //
  118. //////////////////////////////////////////////////////////////////////////////
  119. // ---------------------------------------------------------------------------
  120. // CRegImport ctor
  121. // ---------------------------------------------------------------------------
  122. CRegImport::CRegImport()
  123. : _hr(S_OK), _hBaseKey((HKEY) INVALID_HANDLE_VALUE)
  124. {}
  125. // ---------------------------------------------------------------------------
  126. // CRegImport dtor
  127. // ---------------------------------------------------------------------------
  128. CRegImport::~CRegImport()
  129. {
  130. if (_hBaseKey != INVALID_HANDLE_VALUE)
  131. IF_FAILED_EXIT(RegCloseKey(_hBaseKey));
  132. exit:
  133. return;
  134. }
  135. // ---------------------------------------------------------------------------
  136. // CRegImport::Create
  137. // ---------------------------------------------------------------------------
  138. HRESULT CRegImport::Create(CRegImport **ppImport, LPCWSTR pwzRelKeyPath,
  139. CRegImport *pParentImport)
  140. {
  141. HRESULT hr = S_OK;
  142. MAKE_ERROR_MACROS_STATIC(hr);
  143. HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
  144. LONG lReturn = 0;
  145. DWORD dwDisposition = 0;
  146. CString sBasePath;
  147. CRegImport *pImport = NULL;
  148. if (!pParentImport)
  149. {
  150. IF_FAILED_EXIT(sBasePath.Assign(REGISTRY_BASE_LOCATION));
  151. if (pwzRelKeyPath)
  152. IF_FAILED_EXIT(sBasePath.Append(pwzRelKeyPath));
  153. hKey = HKEY_CURRENT_USER;
  154. }
  155. else
  156. {
  157. IF_NULL_EXIT(pwzRelKeyPath, E_INVALIDARG);
  158. sBasePath.Assign(pwzRelKeyPath);
  159. hKey = pParentImport->_hBaseKey;
  160. }
  161. IF_ALLOC_FAILED_EXIT(pImport = new CRegImport);
  162. lReturn = RegOpenKeyEx(
  163. hKey,
  164. sBasePath._pwz,
  165. 0,
  166. KEY_READ,
  167. &pImport->_hBaseKey);
  168. if (lReturn == ERROR_FILE_NOT_FOUND)
  169. {
  170. hr = S_FALSE;
  171. *ppImport = NULL;
  172. goto exit;
  173. }
  174. IF_WIN32_FAILED_EXIT(lReturn);
  175. *ppImport = pImport;
  176. exit:
  177. if (FAILED(hr))
  178. SAFEDELETE(pImport);
  179. return hr;
  180. }
  181. // ---------------------------------------------------------------------------
  182. // CRegImport::Create
  183. // ---------------------------------------------------------------------------
  184. HRESULT CRegImport::Create(CRegImport **ppImport, LPCWSTR pwzRelKeyPath,
  185. HKEY hkeyRoot)
  186. {
  187. HRESULT hr = S_OK;
  188. MAKE_ERROR_MACROS_STATIC(hr);
  189. LONG lReturn = 0;
  190. DWORD dwDisposition = 0;
  191. CString sBasePath;
  192. CRegImport *pImport = NULL;
  193. IF_NULL_EXIT(pwzRelKeyPath, E_INVALIDARG);
  194. IF_FAILED_EXIT(sBasePath.Assign(pwzRelKeyPath));
  195. IF_ALLOC_FAILED_EXIT(pImport = new CRegImport);
  196. lReturn = RegOpenKeyEx(
  197. hkeyRoot,
  198. sBasePath._pwz,
  199. 0,
  200. KEY_READ,
  201. &pImport->_hBaseKey);
  202. if (lReturn == ERROR_FILE_NOT_FOUND)
  203. {
  204. hr = S_FALSE;
  205. *ppImport = NULL;
  206. goto exit;
  207. }
  208. IF_WIN32_FAILED_EXIT(lReturn);
  209. *ppImport = pImport;
  210. exit:
  211. if (FAILED(hr))
  212. SAFEDELETE(pImport);
  213. return hr;
  214. }
  215. // ---------------------------------------------------------------------------
  216. // Check
  217. // ---------------------------------------------------------------------------
  218. HRESULT CRegImport::Check(LPCWSTR pwzValue, BOOL &bExist)
  219. {
  220. LONG lReturn = 0;
  221. bExist = FALSE;
  222. lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, NULL, NULL, NULL);
  223. IF_TRUE_EXIT(lReturn == ERROR_FILE_NOT_FOUND, S_FALSE);
  224. IF_WIN32_FAILED_EXIT(lReturn);
  225. bExist = TRUE;
  226. exit:
  227. return _hr;
  228. }
  229. // ---------------------------------------------------------------------------
  230. // ReadDword
  231. // ---------------------------------------------------------------------------
  232. HRESULT CRegImport::ReadDword(LPCWSTR pwzValue, LPDWORD pdwData)
  233. {
  234. LONG lReturn = 0;
  235. DWORD dwType = REG_DWORD;
  236. DWORD cbData = sizeof(DWORD);
  237. lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, &dwType, (LPBYTE) pdwData, &cbData);
  238. IF_WIN32_FAILED_EXIT(lReturn);
  239. // Validate reg value type
  240. IF_FALSE_EXIT(dwType == REG_DWORD || dwType == REG_DWORD_LITTLE_ENDIAN, E_UNEXPECTED);
  241. exit:
  242. return _hr;
  243. }
  244. // ---------------------------------------------------------------------------
  245. // ReadString
  246. // ---------------------------------------------------------------------------
  247. HRESULT CRegImport::ReadString(LPCWSTR pwzValue, CString& sData)
  248. {
  249. LONG lReturn = 0;
  250. DWORD dwType = REG_SZ;
  251. DWORD cbData = 0;
  252. DWORD dwCC = 0;
  253. DWORD dwBufLen = 0;
  254. CStringAccessor<CString> acc;
  255. LPWSTR pwzData = NULL;
  256. // IF_FALSE_EXIT(pwzValue, E_INVALIDARG); // if pwzValue == NULL or "", the "default" value is returned
  257. lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, &dwType, NULL, &cbData);
  258. IF_WIN32_FAILED_EXIT(lReturn);
  259. IF_FALSE_EXIT(cbData, E_FAIL);
  260. // Validate reg value type
  261. IF_FALSE_EXIT(dwType == REG_SZ || dwType == REG_EXPAND_SZ, E_UNEXPECTED);
  262. // Allocate for call to RQEX, with one extra char in case
  263. // returned buffer is not null terminated.
  264. dwCC = cbData / sizeof(WCHAR);
  265. dwBufLen = dwCC+1;
  266. // check overflow
  267. IF_FALSE_EXIT(dwBufLen > dwCC, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
  268. IF_ALLOC_FAILED_EXIT(pwzData = new WCHAR[dwBufLen]);
  269. lReturn = RegQueryValueEx(_hBaseKey, pwzValue, NULL, &dwType, (LPBYTE) pwzData, &cbData);
  270. IF_WIN32_FAILED_EXIT(lReturn);
  271. // Null terminate returned buffer.
  272. *(pwzData + dwCC) = L'\0';
  273. if (*(pwzData + dwCC - 1) != L'\0')
  274. dwCC++;
  275. sData.FreeBuffer();
  276. // Attach accessor, set buffer, detach with corrected length.
  277. IF_FAILED_EXIT(acc.Attach(sData));
  278. *(&acc) = pwzData;
  279. // Buffer size could be dwCC+1
  280. IF_FAILED_EXIT(acc.Detach(dwCC));
  281. // If Detach succeeds, reset pointer so that it is freed once.
  282. pwzData = NULL;
  283. exit:
  284. SAFEDELETEARRAY(pwzData);
  285. return _hr;
  286. }
  287. // ---------------------------------------------------------------------------
  288. // EnumKeys
  289. // ---------------------------------------------------------------------------
  290. HRESULT CRegImport::EnumKeys(DWORD n, CString &sSubKey)
  291. {
  292. LONG lReturn = 0;
  293. DWORD cSubKeys = 0, ccMaxSubKeyLen = 0, cValues = 0,
  294. cMaxValueNameLen = 0, cMaxValueLen = 0;
  295. DWORD ccSubKey = 0;
  296. LPWSTR pwzSubKey = NULL;
  297. // ISSUE-2002/03/04-adriaanc
  298. // A race condition exists where a key could be added
  299. // between RegQueryInfoKey and RegEnumKey. If a key
  300. // greater than ccMaxSubKeyLen is added this will cause
  301. // the enum call to fail. Need synchronization.
  302. lReturn = RegQueryInfoKey(
  303. _hBaseKey,
  304. NULL,
  305. NULL,
  306. NULL,
  307. &cSubKeys,
  308. &ccMaxSubKeyLen,
  309. NULL,
  310. &cValues,
  311. &cMaxValueNameLen,
  312. &cMaxValueLen,
  313. NULL,
  314. NULL);
  315. IF_WIN32_FAILED_EXIT(lReturn);
  316. ccSubKey = ccMaxSubKeyLen + 1;
  317. IF_ALLOC_FAILED_EXIT(pwzSubKey = new WCHAR[ccSubKey]);
  318. lReturn = RegEnumKeyEx(
  319. _hBaseKey,
  320. n,
  321. pwzSubKey,
  322. &ccSubKey,
  323. 0,
  324. NULL,
  325. NULL,
  326. NULL);
  327. if (lReturn == ERROR_NO_MORE_ITEMS)
  328. {
  329. _hr = S_FALSE;
  330. goto exit;
  331. }
  332. IF_WIN32_FAILED_EXIT(lReturn);
  333. sSubKey.Assign(pwzSubKey);
  334. exit:
  335. SAFEDELETEARRAY(pwzSubKey);
  336. return _hr;
  337. }
  338. // ---------------------------------------------------------------------------
  339. // EnumKeys
  340. // ---------------------------------------------------------------------------
  341. HRESULT CRegImport::EnumKeys(DWORD n, CRegImport **ppImport)
  342. {
  343. CString sSubKey;
  344. CRegImport *pImport = NULL;
  345. IF_FAILED_EXIT(EnumKeys(n, sSubKey));
  346. if (_hr == S_FALSE)
  347. {
  348. *ppImport = NULL;
  349. goto exit;
  350. }
  351. IF_FAILED_EXIT(CRegImport::Create(&pImport, sSubKey._pwz, this));
  352. *ppImport = pImport;
  353. exit:
  354. return _hr;
  355. }