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.

346 lines
8.2 KiB

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