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.

396 lines
9.4 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: catdbcli.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include <wincrypt.h>
  12. #include "unicode.h"
  13. #include "catdb.h"
  14. #include "catdbcli.h"
  15. #include "..\..\cryptsvc\service.h"
  16. #include "errlog.h"
  17. #include "waitsvc.h"
  18. #ifndef KEYSVC_LOCAL_ENDPOINT
  19. #define KEYSVC_LOCAL_ENDPOINT (L"keysvc")
  20. #endif
  21. #ifndef KEYSVC_LOCAL_PROT_SEQ
  22. #define KEYSVC_LOCAL_PROT_SEQ (L"ncalrpc")
  23. #endif
  24. #define CATDBCLI_LOGERR_LASTERR() ErrLog_LogError(NULL, \
  25. ERRLOG_CLIENT_ID_CATDBCLI, \
  26. __LINE__, \
  27. 0, \
  28. FALSE, \
  29. FALSE);
  30. #define CATDBCLI_LOGERR(x) ErrLog_LogError(NULL, \
  31. ERRLOG_CLIENT_ID_CATDBCLI, \
  32. __LINE__, \
  33. x, \
  34. FALSE, \
  35. FALSE);
  36. #define MAX_RPCRETRIES 20
  37. void
  38. _SSCatDBTeardownRPCConnection(
  39. RPC_BINDING_HANDLE *phRPCBinding)
  40. {
  41. RpcBindingFree(phRPCBinding);
  42. }
  43. DWORD
  44. _SSCatDBSetupRPCConnection(
  45. RPC_BINDING_HANDLE *phRPCBinding)
  46. {
  47. unsigned short *pStringBinding = NULL;
  48. RPC_STATUS rpcStatus = RPC_S_OK;
  49. static BOOL fDone = FALSE;
  50. //
  51. // wait for the service to be available before attempting bind
  52. //
  53. if (!WaitForCryptService(SZSERVICENAME, &fDone, TRUE))
  54. {
  55. CATDBCLI_LOGERR_LASTERR()
  56. return ERROR_SERVICE_NOT_ACTIVE;
  57. }
  58. //
  59. // get a binding handle
  60. //
  61. if (RPC_S_OK != (rpcStatus = RpcStringBindingComposeW(
  62. NULL,
  63. (unsigned short *)KEYSVC_LOCAL_PROT_SEQ,
  64. NULL, //LPC - no machine name
  65. (unsigned short *)KEYSVC_LOCAL_ENDPOINT,
  66. 0,
  67. &pStringBinding)))
  68. {
  69. CATDBCLI_LOGERR(rpcStatus)
  70. goto Ret;
  71. }
  72. if (RPC_S_OK != (rpcStatus = RpcBindingFromStringBindingW(
  73. pStringBinding,
  74. phRPCBinding)))
  75. {
  76. CATDBCLI_LOGERR(rpcStatus)
  77. goto Ret;
  78. }
  79. if (RPC_S_OK != (rpcStatus = RpcEpResolveBinding(
  80. *phRPCBinding,
  81. ICatDBSvc_v1_0_c_ifspec)))
  82. {
  83. CATDBCLI_LOGERR(rpcStatus)
  84. _SSCatDBTeardownRPCConnection(phRPCBinding);
  85. goto Ret;
  86. }
  87. Ret:
  88. if (pStringBinding != NULL)
  89. {
  90. RpcStringFreeW(&pStringBinding);
  91. }
  92. return ((DWORD) rpcStatus);
  93. }
  94. DWORD
  95. Client_SSCatDBAddCatalog(
  96. /* [in] */ DWORD dwFlags,
  97. /* [in] */ LPCWSTR pwszSubSysGUID,
  98. /* [in] */ LPCWSTR pwszCatalogFile,
  99. /* [in] */ LPCWSTR pwszCatName,
  100. /* [out] */ LPWSTR *ppwszCatalogNameUsed)
  101. {
  102. RPC_BINDING_HANDLE hRPCBinding;
  103. DWORD dwErr = 0;
  104. DWORD dwRetryCount = 0;
  105. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  106. if (dwErr != 0)
  107. {
  108. CATDBCLI_LOGERR(dwErr)
  109. return dwErr;
  110. }
  111. dwErr = RPC_S_SERVER_TOO_BUSY;
  112. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  113. (dwRetryCount < MAX_RPCRETRIES))
  114. {
  115. __try
  116. {
  117. dwErr = SSCatDBAddCatalog(
  118. hRPCBinding,
  119. GetCurrentProcessId(),
  120. dwFlags,
  121. pwszSubSysGUID,
  122. pwszCatalogFile,
  123. pwszCatName,
  124. ppwszCatalogNameUsed);
  125. }
  126. __except ( EXCEPTION_EXECUTE_HANDLER )
  127. {
  128. dwErr = _exception_code();
  129. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  130. {
  131. Sleep(100);
  132. }
  133. }
  134. dwRetryCount++;
  135. }
  136. if (dwErr != 0)
  137. {
  138. CATDBCLI_LOGERR(dwErr)
  139. }
  140. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  141. return dwErr;
  142. }
  143. DWORD Client_SSCatDBDeleteCatalog(
  144. /* [in] */ DWORD dwFlags,
  145. /* [in] */ LPCWSTR pwszSubSysGUID,
  146. /* [in] */ LPCWSTR pwszCatalogFile)
  147. {
  148. RPC_BINDING_HANDLE hRPCBinding;
  149. DWORD dwErr = 0;
  150. DWORD dwRetryCount = 0;
  151. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  152. if (dwErr != 0)
  153. {
  154. CATDBCLI_LOGERR(dwErr)
  155. return dwErr;
  156. }
  157. dwErr = RPC_S_SERVER_TOO_BUSY;
  158. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  159. (dwRetryCount < MAX_RPCRETRIES))
  160. {
  161. __try
  162. {
  163. dwErr = SSCatDBDeleteCatalog(
  164. hRPCBinding,
  165. GetCurrentProcessId(),
  166. dwFlags,
  167. pwszSubSysGUID,
  168. pwszCatalogFile);
  169. }
  170. __except ( EXCEPTION_EXECUTE_HANDLER )
  171. {
  172. dwErr = _exception_code();
  173. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  174. {
  175. Sleep(100);
  176. }
  177. }
  178. dwRetryCount++;
  179. }
  180. if (dwErr != 0)
  181. {
  182. CATDBCLI_LOGERR(dwErr)
  183. }
  184. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  185. return dwErr;
  186. }
  187. DWORD
  188. Client_SSCatDBEnumCatalogs(
  189. /* [in] */ DWORD dwFlags,
  190. /* [in] */ LPCWSTR pwszSubSysGUID,
  191. /* [size_is][in] */ BYTE *pbHash,
  192. /* [in] */ DWORD cbHash,
  193. /* [out] */ DWORD *pdwNumCatalogNames,
  194. /* [size_is][size_is][out] */ LPWSTR **pppwszCatalogNames)
  195. {
  196. RPC_BINDING_HANDLE hRPCBinding;
  197. DWORD dwErr = 0;
  198. DWORD dwRetryCount = 0;
  199. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  200. if (dwErr != 0)
  201. {
  202. CATDBCLI_LOGERR(dwErr)
  203. return dwErr;
  204. }
  205. dwErr = RPC_S_SERVER_TOO_BUSY;
  206. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  207. (dwRetryCount < MAX_RPCRETRIES))
  208. {
  209. __try
  210. {
  211. dwErr = SSCatDBEnumCatalogs(
  212. hRPCBinding,
  213. GetCurrentProcessId(),
  214. dwFlags,
  215. pwszSubSysGUID,
  216. pbHash,
  217. cbHash,
  218. pdwNumCatalogNames,
  219. pppwszCatalogNames);
  220. }
  221. __except ( EXCEPTION_EXECUTE_HANDLER )
  222. {
  223. dwErr = _exception_code();
  224. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  225. {
  226. Sleep(100);
  227. }
  228. }
  229. dwRetryCount++;
  230. }
  231. if (dwErr != 0)
  232. {
  233. CATDBCLI_LOGERR(dwErr)
  234. }
  235. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  236. return dwErr;
  237. }
  238. DWORD
  239. Client_SSCatDBRegisterForChangeNotification(
  240. /* [in] */ DWORD_PTR EventHandle,
  241. /* [in] */ DWORD dwFlags,
  242. /* [in] */ LPCWSTR pwszSubSysGUID,
  243. /* [in] */ BOOL fUnRegister)
  244. {
  245. RPC_BINDING_HANDLE hRPCBinding;
  246. DWORD dwErr = 0;
  247. DWORD dwRetryCount = 0;
  248. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  249. if (dwErr != 0)
  250. {
  251. CATDBCLI_LOGERR(dwErr)
  252. return dwErr;
  253. }
  254. dwErr = RPC_S_SERVER_TOO_BUSY;
  255. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  256. (dwRetryCount < MAX_RPCRETRIES))
  257. {
  258. __try
  259. {
  260. dwErr = SSCatDBRegisterForChangeNotification(
  261. hRPCBinding,
  262. GetCurrentProcessId(),
  263. EventHandle,
  264. dwFlags,
  265. pwszSubSysGUID,
  266. fUnRegister);
  267. }
  268. __except ( EXCEPTION_EXECUTE_HANDLER )
  269. {
  270. dwErr = _exception_code();
  271. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  272. {
  273. Sleep(100);
  274. }
  275. }
  276. dwRetryCount++;
  277. }
  278. if (dwErr != 0)
  279. {
  280. CATDBCLI_LOGERR(dwErr)
  281. }
  282. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  283. return dwErr;
  284. }
  285. DWORD
  286. Client_SSCatDBPauseResumeService(
  287. /* [in] */ DWORD dwFlags,
  288. /* [in] */ BOOL fResume)
  289. {
  290. RPC_BINDING_HANDLE hRPCBinding;
  291. DWORD dwErr = 0;
  292. DWORD dwRetryCount = 0;
  293. dwErr = _SSCatDBSetupRPCConnection(&hRPCBinding);
  294. if (dwErr != 0)
  295. {
  296. CATDBCLI_LOGERR(dwErr)
  297. return dwErr;
  298. }
  299. dwErr = RPC_S_SERVER_TOO_BUSY;
  300. while ( (dwErr == RPC_S_SERVER_TOO_BUSY) &&
  301. (dwRetryCount < MAX_RPCRETRIES))
  302. {
  303. __try
  304. {
  305. dwErr = SSCatDBPauseResumeService(
  306. hRPCBinding,
  307. GetCurrentProcessId(),
  308. dwFlags,
  309. fResume);
  310. }
  311. __except ( EXCEPTION_EXECUTE_HANDLER )
  312. {
  313. dwErr = _exception_code();
  314. if (dwErr == RPC_S_SERVER_TOO_BUSY)
  315. {
  316. Sleep(100);
  317. }
  318. }
  319. dwRetryCount++;
  320. }
  321. if (dwErr != 0)
  322. {
  323. CATDBCLI_LOGERR(dwErr)
  324. }
  325. _SSCatDBTeardownRPCConnection(&hRPCBinding);
  326. return dwErr;
  327. }