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.

383 lines
9.5 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1999
  5. //
  6. // File: config.cpp
  7. //
  8. // Contents: CConfigStorage implements read/write to CA configuration data
  9. // currently stored under HKLM\System\CCS\Services\Certsvc\
  10. // Configuration
  11. //
  12. //---------------------------------------------------------------------------
  13. #include <pch.cpp>
  14. #pragma hdrstop
  15. #include <config.h>
  16. #define __dwFILE__ __dwFILE_CERTLIB_CNFGSTG_CPP__
  17. using namespace CertSrv;
  18. HRESULT CConfigStorage::InitMachine(LPCWSTR pcwszMachine)
  19. {
  20. m_pwszMachine = new WCHAR[wcslen(pcwszMachine)+3];
  21. if(!m_pwszMachine)
  22. {
  23. return E_OUTOFMEMORY;
  24. }
  25. m_pwszMachine[0] = L'\0';
  26. if(pcwszMachine[0]!=L'\\' &&
  27. pcwszMachine[1]!=L'\\')
  28. {
  29. wcscpy(m_pwszMachine, L"\\\\");
  30. }
  31. wcscat(m_pwszMachine, pcwszMachine);
  32. return S_OK;
  33. }
  34. CConfigStorage::~CConfigStorage()
  35. {
  36. if(m_hRemoteHKLM)
  37. RegCloseKey(m_hRemoteHKLM);
  38. if(m_hRootConfigKey)
  39. RegCloseKey(m_hRootConfigKey);
  40. if(m_hCAKey)
  41. RegCloseKey(m_hCAKey);
  42. if(m_pwszMachine)
  43. delete[] m_pwszMachine;
  44. }
  45. // Retrieve a CA configuration value. If no authority name is specified, the
  46. // node path must be NULL and value is queried from the Configuration root.
  47. // If an authority name is passed in, the value is retrieved from the authority
  48. // node; if a node path is passed in, it is used relative to the authority node
  49. // to read the value.
  50. // For example, to read Configuration\DBDirectory, call:
  51. //
  52. // GetEntry(NULL, NULL, L"DBDirectory", &var)
  53. //
  54. // To read Configuration\MyCA\CAServerName, call:
  55. //
  56. // GetEntry(L"MyCA", NULL, L"CAServerName", &var)
  57. //
  58. // To read Configuration\MyCA\CSP\HashAlgorithm, call:
  59. //
  60. // GetEntry(L"MyCA", L"CSP", L"HashAlgorithm"
  61. //
  62. //
  63. // If pcwszValue is null, getentry returns a VT_ARRAY|VT_BSTR with a list
  64. // of subkey names.
  65. HRESULT CConfigStorage::GetEntry(
  66. LPCWSTR pcwszAuthorityName,
  67. LPCWSTR pcwszRelativeNodePath,
  68. LPCWSTR pcwszValue,
  69. VARIANT *pVariant)
  70. {
  71. HRESULT hr = S_OK;
  72. HKEY hKey = NULL;
  73. LPBYTE pData = NULL, pTmp;
  74. DWORD cData = 0;
  75. HKEY hKeyTmp = NULL;
  76. DWORD dwType;
  77. DWORD nIndex;
  78. DWORD cName;
  79. DWORD cKeys;
  80. if(EmptyString(pcwszAuthorityName))
  81. {
  82. if(!EmptyString(pcwszRelativeNodePath))
  83. {
  84. hr = E_INVALIDARG;
  85. _JumpError(hr, error, "CConfigStorage::GetEntry");
  86. }
  87. hr = InitRootKey();
  88. _JumpIfError(hr, error, "CConfigStorage::InitRootKey");
  89. hKey = m_hRootConfigKey;
  90. }
  91. else
  92. {
  93. hr = InitCAKey(pcwszAuthorityName);
  94. _JumpIfError(hr, error, "CConfigStorage::InitCAKey");
  95. hKey = m_hCAKey;
  96. }
  97. CSASSERT(hKey);
  98. if(!EmptyString(pcwszRelativeNodePath))
  99. {
  100. hr = RegOpenKeyEx(
  101. hKey,
  102. pcwszRelativeNodePath,
  103. 0,
  104. KEY_ALL_ACCESS,
  105. &hKeyTmp);
  106. if ((HRESULT) ERROR_ACCESS_DENIED == hr)
  107. {
  108. hr = RegOpenKeyEx(
  109. hKey,
  110. pcwszRelativeNodePath,
  111. 0,
  112. KEY_READ,
  113. &hKeyTmp);
  114. }
  115. _JumpIfErrorStr(hr, error, "RegOpenKeyEx", pcwszRelativeNodePath);
  116. hKey = hKeyTmp;
  117. }
  118. if(EmptyString(pcwszValue))
  119. {
  120. dwType = REG_MULTI_SZ;
  121. cData = 2;
  122. hr = RegQueryInfoKey(
  123. hKey,
  124. NULL,NULL,NULL,
  125. &cKeys,
  126. &cName,
  127. NULL,NULL,NULL,NULL,NULL,NULL);
  128. _JumpIfError(hr, error, "RegQueryInfoKey");
  129. cData = (cName+1)*cKeys*sizeof(WCHAR);
  130. pData = (LPBYTE)LocalAlloc(LMEM_FIXED, cData);
  131. if(!pData)
  132. {
  133. hr = E_OUTOFMEMORY;
  134. _JumpError(hr, error, "LocalAlloc");
  135. }
  136. pTmp = pData;
  137. for(nIndex=0;nIndex<cKeys; nIndex++)
  138. {
  139. cName = cData;
  140. hr = RegEnumKeyEx(
  141. hKey,
  142. nIndex,
  143. (LPWSTR)pTmp,
  144. &cName,
  145. 0, NULL, NULL, NULL);
  146. _JumpIfError(hr, error, "RegEnumKeyEx");
  147. pTmp = pTmp+(wcslen((LPWSTR)pTmp)+1)*sizeof(WCHAR);
  148. }
  149. *(LPWSTR)pTmp= L'\0';
  150. hr = myRegValueToVariant(
  151. dwType,
  152. cData,
  153. pData,
  154. pVariant);
  155. _JumpIfError(hr, error, "myRegValueToVariant");
  156. }
  157. else
  158. {
  159. hr = RegQueryValueEx(
  160. hKey,
  161. pcwszValue,
  162. NULL,
  163. &dwType,
  164. NULL,
  165. &cData);
  166. _JumpIfError2(hr, error, "RegQueryValueEx", ERROR_FILE_NOT_FOUND);
  167. pData = (LPBYTE)LocalAlloc(LMEM_FIXED, cData);
  168. if(!pData)
  169. {
  170. hr = E_OUTOFMEMORY;
  171. _JumpError(hr, error, "LocalAlloc");
  172. }
  173. hr = RegQueryValueEx(
  174. hKey,
  175. pcwszValue,
  176. NULL,
  177. &dwType,
  178. pData,
  179. &cData);
  180. _JumpIfError(hr, error, "RegQueryValueEx");
  181. hr = myRegValueToVariant(
  182. dwType,
  183. cData,
  184. pData,
  185. pVariant);
  186. _JumpIfError(hr, error, "myRegValueToVariant");
  187. }
  188. error:
  189. if(hKeyTmp)
  190. RegCloseKey(hKeyTmp);
  191. if(pData)
  192. LocalFree(pData);
  193. return myHError(hr);
  194. }
  195. // If variant type is VT_EMPTY, SetEntry deletes the value. Otherwise it
  196. // set the value, see myRegValueToVariant for supported types
  197. HRESULT CConfigStorage::SetEntry(
  198. LPCWSTR pcwszAuthorityName,
  199. LPCWSTR pcwszRelativeNodePath,
  200. LPCWSTR pcwszValue,
  201. VARIANT *pVariant)
  202. {
  203. HRESULT hr = S_OK;
  204. HKEY hKey = NULL;
  205. LPBYTE pData = NULL;
  206. DWORD cData;
  207. HKEY hKeyTmp = NULL;
  208. DWORD dwType;
  209. if(EmptyString(pcwszAuthorityName))
  210. {
  211. if(!EmptyString(pcwszRelativeNodePath))
  212. {
  213. hr = E_INVALIDARG;
  214. _JumpError(hr, error, "CConfigStorage::GetEntry");
  215. }
  216. hr = InitRootKey();
  217. _JumpIfError(hr, error, "CConfigStorage::InitRootKey");
  218. hKey = m_hRootConfigKey;
  219. }
  220. else
  221. {
  222. hr = InitCAKey(pcwszAuthorityName);
  223. _JumpIfError(hr, error, "CConfigStorage::InitCAKey");
  224. hKey = m_hCAKey;
  225. }
  226. CSASSERT(hKey);
  227. if(!EmptyString(pcwszRelativeNodePath))
  228. {
  229. hr = RegOpenKeyEx(
  230. hKey,
  231. pcwszRelativeNodePath,
  232. 0,
  233. KEY_ALL_ACCESS,
  234. &hKeyTmp);
  235. _JumpIfErrorStr(hr, error, "RegOpenKeyEx", pcwszRelativeNodePath);
  236. hKey = hKeyTmp;
  237. }
  238. if(VT_EMPTY == V_VT(pVariant))
  239. {
  240. // delete value
  241. hr = RegDeleteValue(
  242. hKey,
  243. pcwszValue);
  244. _JumpIfErrorStr(hr, error, "RegDeleteValue", pcwszValue);
  245. }
  246. else
  247. {
  248. // set value
  249. hr = myVariantToRegValue(
  250. pVariant,
  251. &dwType,
  252. &cData,
  253. &pData);
  254. _JumpIfError(hr, error, "myVariantToRegValue");
  255. hr = RegSetValueEx(
  256. hKey,
  257. pcwszValue,
  258. NULL,
  259. dwType,
  260. pData,
  261. cData);
  262. _JumpIfErrorStr(hr, error, "RegSetValueEx", pcwszValue);
  263. }
  264. error:
  265. if(hKeyTmp)
  266. RegCloseKey(hKeyTmp);
  267. if(pData)
  268. LocalFree(pData);
  269. return myHError(hr);
  270. }
  271. HRESULT CConfigStorage::InitRootKey()
  272. {
  273. HRESULT hr = S_OK;
  274. if(!m_hRootConfigKey)
  275. {
  276. if(m_pwszMachine)
  277. {
  278. hr = RegConnectRegistry(
  279. m_pwszMachine,
  280. HKEY_LOCAL_MACHINE,
  281. &m_hRemoteHKLM);
  282. _JumpIfError(hr, error, "RegConnectRegistry");
  283. }
  284. hr = RegOpenKeyEx(
  285. m_hRemoteHKLM?m_hRemoteHKLM:HKEY_LOCAL_MACHINE,
  286. wszREGKEYCONFIGPATH,
  287. 0,
  288. KEY_ALL_ACCESS,
  289. &m_hRootConfigKey);
  290. if ((HRESULT) ERROR_ACCESS_DENIED == hr)
  291. {
  292. hr = RegOpenKeyEx(
  293. m_hRemoteHKLM?m_hRemoteHKLM:HKEY_LOCAL_MACHINE,
  294. wszREGKEYCONFIGPATH,
  295. 0,
  296. KEY_READ,
  297. &m_hRootConfigKey);
  298. }
  299. _JumpIfErrorStr(hr, error, "RegOpenKeyEx", wszREGKEYCONFIGPATH);
  300. }
  301. error:
  302. return hr;
  303. }
  304. HRESULT CConfigStorage::InitCAKey(LPCWSTR pcwszAuthority)
  305. {
  306. HRESULT hr = S_OK;
  307. if(!m_hCAKey)
  308. {
  309. hr = InitRootKey();
  310. _JumpIfError(hr, error, "CConfigStorage::InitRootKey");
  311. hr = RegOpenKeyEx(
  312. m_hRootConfigKey,
  313. pcwszAuthority,
  314. 0,
  315. KEY_ALL_ACCESS,
  316. &m_hCAKey);
  317. if ((HRESULT) ERROR_ACCESS_DENIED == hr)
  318. {
  319. hr = RegOpenKeyEx(
  320. m_hRootConfigKey,
  321. pcwszAuthority,
  322. 0,
  323. KEY_READ,
  324. &m_hCAKey);
  325. }
  326. _JumpIfErrorStr(hr, error, "RegOpenKeyEx", pcwszAuthority);
  327. }
  328. error:
  329. return hr;
  330. }