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.

849 lines
23 KiB

  1. #include <precomp.h>
  2. #include "wzcsvc.h"
  3. #include "tracing.h"
  4. #include "utils.h"
  5. #include "intflist.h"
  6. #include "rpcsrv.h"
  7. #include "database.h"
  8. extern HASH sessionHash;
  9. //-------------------------------------------------
  10. // Globals used for the RPC interface
  11. BOOL g_bRpcStarted = FALSE;
  12. PSECURITY_DESCRIPTOR g_pSecurityDescr = NULL;
  13. GENERIC_MAPPING g_Mapping = {
  14. WZC_READ,
  15. WZC_WRITE,
  16. WZC_EXECUTE,
  17. WZC_ALL_ACCESS};
  18. //-------------------------------------------------
  19. // Initialize the security settings for the RPC API
  20. DWORD
  21. WZCSvcInitRPCSecurity()
  22. {
  23. DWORD dwErr = ERROR_SUCCESS;
  24. NTSTATUS ntStatus;
  25. ACE_DATA AceData[6] = {
  26. {ACCESS_ALLOWED_ACE_TYPE, 0, 0, WZC_ACCESS_SET|WZC_ACCESS_QUERY, &LocalSystemSid},
  27. {ACCESS_ALLOWED_ACE_TYPE, 0, 0, WZC_ACCESS_SET|WZC_ACCESS_QUERY, &AliasAdminsSid},
  28. {ACCESS_ALLOWED_ACE_TYPE, 0, 0, WZC_ACCESS_SET|WZC_ACCESS_QUERY, &AliasAccountOpsSid},
  29. {ACCESS_ALLOWED_ACE_TYPE, 0, 0, WZC_ACCESS_SET|WZC_ACCESS_QUERY, &AliasSystemOpsSid},
  30. {ACCESS_ALLOWED_ACE_TYPE, 0, 0, WZC_ACCESS_SET|WZC_ACCESS_QUERY, &AliasUsersSid},
  31. // for now (WinXP Client RTM) the decision was made to let everybody party, but based on
  32. // the acl below. Later, the security schema won't change by default, but support will be
  33. // added allowing admins to tighten up the access to the service RPC APIs.
  34. {ACCESS_ALLOWED_ACE_TYPE, 0, 0, WZC_ACCESS_SET|WZC_ACCESS_QUERY, &WorldSid}};
  35. DbgPrint((TRC_TRACK, "[WZCSvcInitRPCSecurity"));
  36. // create the well known SIDs;
  37. dwErr = RtlNtStatusToDosError(
  38. NetpCreateWellKnownSids(NULL)
  39. );
  40. DbgAssert((dwErr == ERROR_SUCCESS, "Error %d creating the well known Sids!", dwErr));
  41. // create the security object.
  42. if (dwErr == ERROR_SUCCESS)
  43. {
  44. dwErr = RtlNtStatusToDosError(
  45. NetpCreateSecurityObject(
  46. AceData,
  47. sizeof(AceData)/sizeof(ACE_DATA),
  48. NULL,
  49. NULL,
  50. &g_Mapping,
  51. &g_pSecurityDescr)
  52. );
  53. DbgAssert((dwErr == ERROR_SUCCESS, "Error %d creating the global security object!", dwErr));
  54. }
  55. DbgPrint((TRC_TRACK, "WZCSvcInitRPCSecurity]=%d", dwErr));
  56. return dwErr;
  57. }
  58. //-------------------------------------------------
  59. // Check the access for the particular access mask provided
  60. DWORD
  61. WZCSvcCheckRPCAccess(DWORD dwAccess)
  62. {
  63. DWORD dwErr = ERROR_SUCCESS;
  64. if (g_pSecurityDescr != NULL)
  65. {
  66. dwErr = NetpAccessCheckAndAudit(
  67. _T("WZCSVC"),
  68. _T("WZCSVC"),
  69. g_pSecurityDescr,
  70. dwAccess,
  71. &g_Mapping);
  72. DbgPrint((TRC_GENERIC, ">>> Security check reports err=%d.", dwErr));
  73. }
  74. return dwErr;
  75. }
  76. //-------------------------------------------------
  77. // Check the validity of a RAW_DATA pointer
  78. DWORD
  79. WZCSvcCheckParamRawData(PRAW_DATA prd)
  80. {
  81. DWORD dwErr = ERROR_SUCCESS;
  82. if (prd != NULL)
  83. {
  84. if (prd->dwDataLen != 0 && prd->pData == NULL)
  85. dwErr = ERROR_INVALID_PARAMETER;
  86. }
  87. return dwErr;
  88. }
  89. //-------------------------------------------------
  90. // Check the validity of an SSID embedded in a RAW_DATA pointer
  91. DWORD
  92. WZCSvcCheckSSID(PNDIS_802_11_SSID pndSSID, UINT nBytes)
  93. {
  94. DWORD dwErr = ERROR_SUCCESS;
  95. if (pndSSID != NULL)
  96. {
  97. if (nBytes < FIELD_OFFSET(NDIS_802_11_SSID, Ssid) ||
  98. pndSSID->SsidLength > nBytes - FIELD_OFFSET(NDIS_802_11_SSID, Ssid))
  99. dwErr = ERROR_INVALID_PARAMETER;
  100. }
  101. return dwErr;
  102. }
  103. //-------------------------------------------------
  104. // Check the validity of a list of configurations embedded in a RAW_DATA pointer
  105. DWORD
  106. WZCSvcCheckConfig(PWZC_WLAN_CONFIG pwzcConfig, UINT nBytes)
  107. {
  108. DWORD dwErr = ERROR_SUCCESS;
  109. if (pwzcConfig != NULL)
  110. {
  111. if (pwzcConfig->Length > nBytes ||
  112. pwzcConfig->Length != sizeof(WZC_WLAN_CONFIG))
  113. dwErr = ERROR_INVALID_PARAMETER;
  114. if (dwErr == ERROR_SUCCESS)
  115. dwErr = WZCSvcCheckSSID(&pwzcConfig->Ssid, sizeof(NDIS_802_11_SSID));
  116. if (dwErr == ERROR_SUCCESS &&
  117. pwzcConfig->KeyLength > WZCCTL_MAX_WEPK_MATERIAL)
  118. dwErr = ERROR_INVALID_PARAMETER;
  119. }
  120. return dwErr;
  121. }
  122. //-------------------------------------------------
  123. // Check the validity of a list of configurations embedded in a RAW_DATA pointer
  124. DWORD
  125. WZCSvcCheckConfigList(PWZC_802_11_CONFIG_LIST pwzcList, UINT nBytes)
  126. {
  127. DWORD dwErr = ERROR_SUCCESS;
  128. if (pwzcList != NULL)
  129. {
  130. UINT i;
  131. if (nBytes < FIELD_OFFSET(WZC_802_11_CONFIG_LIST, Config))
  132. dwErr = ERROR_INVALID_PARAMETER;
  133. nBytes -= FIELD_OFFSET(WZC_802_11_CONFIG_LIST, Config);
  134. if (dwErr == ERROR_SUCCESS &&
  135. ((pwzcList->NumberOfItems * sizeof(WZC_WLAN_CONFIG) > nBytes) ||
  136. (pwzcList->Index > pwzcList->NumberOfItems)
  137. )
  138. )
  139. dwErr = ERROR_INVALID_PARAMETER;
  140. for (i = 0; i < pwzcList->NumberOfItems && dwErr == ERROR_SUCCESS; i++)
  141. dwErr = WZCSvcCheckConfig(&(pwzcList->Config[i]), sizeof(WZC_WLAN_CONFIG));
  142. }
  143. return dwErr;
  144. }
  145. //-------------------------------------------------
  146. // Check the validity of the "input" fields from the INTF_ENTRY.
  147. DWORD
  148. WZCSvcCheckParamIntfEntry(PINTF_ENTRY pIntfEntry)
  149. {
  150. DWORD dwErr = ERROR_SUCCESS;
  151. if (pIntfEntry != NULL)
  152. {
  153. if (dwErr == ERROR_SUCCESS)
  154. dwErr = WZCSvcCheckParamRawData(&pIntfEntry->rdSSID);
  155. if (dwErr == ERROR_SUCCESS)
  156. dwErr = WZCSvcCheckParamRawData(&pIntfEntry->rdBSSID);
  157. if (dwErr == ERROR_SUCCESS)
  158. dwErr = WZCSvcCheckParamRawData(&pIntfEntry->rdStSSIDList);
  159. if (dwErr == ERROR_SUCCESS)
  160. dwErr = WZCSvcCheckConfigList(
  161. (PWZC_802_11_CONFIG_LIST)pIntfEntry->rdStSSIDList.pData,
  162. pIntfEntry->rdStSSIDList.dwDataLen);
  163. if (dwErr == ERROR_SUCCESS)
  164. dwErr = WZCSvcCheckParamRawData(&pIntfEntry->rdCtrlData);
  165. }
  166. return dwErr;
  167. }
  168. //-------------------------------------------------
  169. // Cleanup whatever data was used for RPC security settings
  170. DWORD
  171. WZCSvcTermRPCSecurity()
  172. {
  173. DWORD dwErr = ERROR_SUCCESS;
  174. DbgPrint((TRC_TRACK, "[WZCSvcTermRPCSecurity"));
  175. dwErr = RtlNtStatusToDosError(NetpDeleteSecurityObject(&g_pSecurityDescr));
  176. DbgAssert((dwErr == ERROR_SUCCESS, "Failed to delete the global security descriptor!"));
  177. g_pSecurityDescr = NULL;
  178. NetpFreeWellKnownSids();
  179. DbgPrint((TRC_TRACK, "WZCSvcTermRPCSecurity]=%d", dwErr));
  180. return dwErr;
  181. }
  182. RPC_STATUS CallbackCheckLocal(
  183. IN RPC_IF_HANDLE *Interface,
  184. IN void *Context)
  185. {
  186. RPC_STATUS rpcStat = RPC_S_OK;
  187. LPTSTR pBinding = NULL;
  188. LPTSTR pProtSeq = NULL;
  189. rpcStat = RpcBindingToStringBinding(Context, &pBinding);
  190. if (rpcStat == RPC_S_OK)
  191. {
  192. rpcStat = RpcStringBindingParse(
  193. pBinding,
  194. NULL,
  195. &pProtSeq,
  196. NULL,
  197. NULL,
  198. NULL);
  199. }
  200. if (rpcStat == RPC_S_OK)
  201. {
  202. if (_tcsicmp((LPCTSTR)pProtSeq, _T("ncalrpc")) != 0)
  203. rpcStat = RPC_S_ACCESS_DENIED;
  204. }
  205. if (pBinding != NULL)
  206. RpcStringFree(&pBinding);
  207. if (pProtSeq != NULL)
  208. RpcStringFree(&pProtSeq);
  209. return rpcStat;
  210. }
  211. DWORD
  212. WZCSvcStartRPCServer()
  213. {
  214. DWORD dwStatus = RPC_S_OK;
  215. DbgPrint((TRC_TRACK, "[WZCSvcStartRPCServer"));
  216. if (dwStatus == RPC_S_OK)
  217. {
  218. dwStatus = RpcServerUseProtseqEp(
  219. L"ncalrpc",
  220. 10,
  221. L"wzcsvc",
  222. NULL);
  223. if (dwStatus == RPC_S_DUPLICATE_ENDPOINT)
  224. dwStatus = RPC_S_OK;
  225. }
  226. if (dwStatus == RPC_S_OK)
  227. {
  228. dwStatus = RpcServerRegisterIfEx(
  229. winwzc_ServerIfHandle,
  230. 0,
  231. 0,
  232. RPC_IF_ALLOW_SECURE_ONLY, // WZCSAPI is using RPC_C_PROTECT_LEVEL_PKT_PRIVACY
  233. 0, // ignored for non auto-listen interfaces
  234. CallbackCheckLocal);
  235. }
  236. if (dwStatus == RPC_S_OK)
  237. {
  238. dwStatus = RpcServerRegisterAuthInfo(
  239. 0,
  240. RPC_C_AUTHN_WINNT,
  241. 0,
  242. 0);
  243. }
  244. if (dwStatus == RPC_S_OK)
  245. {
  246. dwStatus = RpcServerRegisterAuthInfo(
  247. 0,
  248. RPC_C_AUTHN_GSS_KERBEROS,
  249. 0,
  250. 0);
  251. }
  252. if (dwStatus == RPC_S_OK)
  253. {
  254. dwStatus = RpcServerRegisterAuthInfo(
  255. 0,
  256. RPC_C_AUTHN_GSS_NEGOTIATE,
  257. 0,
  258. 0);
  259. }
  260. if (dwStatus == RPC_S_OK)
  261. {
  262. dwStatus = RpcServerListen(
  263. 3,
  264. RPC_C_LISTEN_MAX_CALLS_DEFAULT,
  265. TRUE);
  266. if (dwStatus == RPC_S_ALREADY_LISTENING)
  267. dwStatus = RPC_S_OK;
  268. }
  269. if (dwStatus != RPC_S_OK)
  270. {
  271. RpcServerUnregisterIfEx(
  272. winwzc_ServerIfHandle,
  273. 0,
  274. 0);
  275. }
  276. g_bRpcStarted = (dwStatus == RPC_S_OK);
  277. WZCSvcInitRPCSecurity();
  278. DbgPrint((TRC_TRACK, "WZCSvcStartRPCServer]=%d", dwStatus));
  279. return (dwStatus);
  280. }
  281. DWORD
  282. WZCSvcStopRPCServer()
  283. {
  284. DWORD dwStatus = RPC_S_OK;
  285. DbgPrint((TRC_TRACK, "[WZCSvcStopRPCServer"));
  286. if (g_bRpcStarted)
  287. {
  288. g_bRpcStarted = FALSE;
  289. WZCSvcTermRPCSecurity();
  290. dwStatus = RpcServerUnregisterIfEx(
  291. winwzc_ServerIfHandle,
  292. 0,
  293. 0);
  294. // don't stop RPC from listening - other services could rely on this
  295. //RpcMgmtStopServerListening(0);
  296. }
  297. DbgPrint((TRC_TRACK, "WZCSvcStopRPCServer]=%d", dwStatus));
  298. return (dwStatus);
  299. }
  300. DWORD
  301. RpcEnumInterfaces(
  302. STRING_HANDLE pSrvAddr,
  303. PINTFS_KEY_TABLE pIntfsTable)
  304. {
  305. DWORD dwErr = ERROR_SUCCESS;
  306. DWORD dwNumIntfs;
  307. InterlockedIncrement(&g_nThreads);
  308. DbgPrint((TRC_TRACK, "[RpcEnumInterfaces"));
  309. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  310. if (dwErr == ERROR_SUCCESS)
  311. {
  312. dwNumIntfs = LstNumInterfaces();
  313. DbgPrint((TRC_GENERIC,
  314. "Num interfaces = %d",
  315. dwNumIntfs));
  316. if (dwNumIntfs == 0)
  317. goto exit;
  318. pIntfsTable->pIntfs = RpcCAlloc(dwNumIntfs*sizeof(INTF_KEY_ENTRY));
  319. if (pIntfsTable->pIntfs == NULL)
  320. {
  321. dwErr = GetLastError();
  322. goto exit;
  323. }
  324. dwErr = LstGetIntfsKeyInfo(pIntfsTable->pIntfs, &dwNumIntfs);
  325. if (dwErr != ERROR_SUCCESS || dwNumIntfs == 0)
  326. {
  327. RpcFree(pIntfsTable->pIntfs);
  328. pIntfsTable->pIntfs = NULL;
  329. goto exit;
  330. }
  331. pIntfsTable->dwNumIntfs = dwNumIntfs;
  332. for (dwNumIntfs = 0; dwNumIntfs < pIntfsTable->dwNumIntfs; dwNumIntfs++)
  333. {
  334. DbgPrint((TRC_GENERIC,
  335. "Intf %d:\t%S",
  336. dwNumIntfs,
  337. pIntfsTable->pIntfs[dwNumIntfs].wszGuid == NULL ?
  338. L"(null)" :
  339. pIntfsTable->pIntfs[dwNumIntfs].wszGuid));
  340. }
  341. }
  342. exit:
  343. DbgPrint((TRC_TRACK, "RpcEnumInterfaces]=%d", dwErr));
  344. InterlockedDecrement(&g_nThreads);
  345. return dwErr;
  346. }
  347. DWORD
  348. RpcQueryInterface(
  349. STRING_HANDLE pSrvAddr,
  350. DWORD dwInFlags,
  351. PINTF_ENTRY pIntfEntry,
  352. LPDWORD pdwOutFlags)
  353. {
  354. DWORD dwErr = ERROR_SUCCESS;
  355. InterlockedIncrement(&g_nThreads);
  356. DbgPrint((TRC_TRACK, "[RpcQueryInterface(0x%x,%S)", dwInFlags, pIntfEntry->wszGuid));
  357. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  358. if (dwErr == ERROR_SUCCESS)
  359. {
  360. dwErr = LstQueryInterface(dwInFlags, pIntfEntry, pdwOutFlags);
  361. }
  362. DbgPrint((TRC_TRACK, "RpcQueryInterface]=%d", dwErr));
  363. InterlockedDecrement(&g_nThreads);
  364. return dwErr;
  365. }
  366. DWORD
  367. RpcSetInterface(
  368. STRING_HANDLE pSrvAddr,
  369. DWORD dwInFlags,
  370. PINTF_ENTRY pIntfEntry,
  371. LPDWORD pdwOutFlags)
  372. {
  373. DWORD dwErr = ERROR_SUCCESS;
  374. InterlockedIncrement(&g_nThreads);
  375. DbgPrint((TRC_TRACK, "[RpcSetInterface(0x%x,%S)", dwInFlags, pIntfEntry->wszGuid));
  376. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_SET);
  377. if (dwErr == ERROR_SUCCESS)
  378. {
  379. dwErr = WZCSvcCheckParamIntfEntry(pIntfEntry);
  380. }
  381. if (dwErr == ERROR_SUCCESS)
  382. {
  383. dwErr = LstSetInterface(dwInFlags, pIntfEntry, pdwOutFlags);
  384. }
  385. DbgPrint((TRC_TRACK, "RpcSetInterface]=%d", dwErr));
  386. InterlockedDecrement(&g_nThreads);
  387. return dwErr;
  388. }
  389. DWORD
  390. RpcRefreshInterface(
  391. STRING_HANDLE pSrvAddr,
  392. DWORD dwInFlags,
  393. PINTF_ENTRY pIntfEntry,
  394. LPDWORD pdwOutFlags)
  395. {
  396. DWORD dwErr = ERROR_SUCCESS;
  397. InterlockedIncrement(&g_nThreads);
  398. DbgPrint((TRC_TRACK, "[RpcRefreshInterface(0x%x,%S)", dwInFlags, pIntfEntry->wszGuid));
  399. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_SET);
  400. if (dwErr == ERROR_SUCCESS)
  401. {
  402. dwErr = LstRefreshInterface(dwInFlags, pIntfEntry, pdwOutFlags);
  403. }
  404. DbgPrint((TRC_TRACK, "RpcRefreshInterface]=%d", dwErr));
  405. InterlockedDecrement(&g_nThreads);
  406. return dwErr;
  407. }
  408. DWORD
  409. RpcQueryContext(
  410. STRING_HANDLE pSrvAddr,
  411. DWORD dwInFlags,
  412. PWZC_CONTEXT pContext,
  413. LPDWORD pdwOutFlags)
  414. {
  415. DWORD dwErr = ERROR_SUCCESS;
  416. InterlockedIncrement(&g_nThreads);
  417. DbgPrint((TRC_TRACK, "[RpcQueryContext(0x%x)", dwInFlags));
  418. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  419. if (dwErr == ERROR_SUCCESS)
  420. {
  421. dwErr = WzcContextQuery(dwInFlags, pContext, pdwOutFlags);
  422. }
  423. DbgPrint((TRC_TRACK, "RpcQueryContext]=%d", dwErr));
  424. InterlockedDecrement(&g_nThreads);
  425. return dwErr;
  426. }
  427. DWORD
  428. RpcSetContext(
  429. STRING_HANDLE pSrvAddr,
  430. DWORD dwInFlags,
  431. PWZC_CONTEXT pContext,
  432. LPDWORD pdwOutFlags)
  433. {
  434. DWORD dwErr = ERROR_SUCCESS;
  435. BOOL bLogEnabled = FALSE;
  436. InterlockedIncrement(&g_nThreads);
  437. DbgPrint((TRC_TRACK, "[RpcSetContext(0x%x)", dwInFlags));
  438. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_SET);
  439. if (dwErr == ERROR_SUCCESS)
  440. {
  441. dwErr = WzcContextSet(dwInFlags, pContext, pdwOutFlags);
  442. }
  443. DbgPrint((TRC_TRACK, "RpcSetContext]=%d", dwErr));
  444. BAIL_ON_WIN32_ERROR(dwErr);
  445. EnterCriticalSection(&g_wzcInternalCtxt.csContext);
  446. bLogEnabled = ((g_wzcInternalCtxt.wzcContext.dwFlags & WZC_CTXT_LOGGING_ON) != 0);
  447. dwErr = WZCSetLoggingState(bLogEnabled);
  448. BAIL_ON_LOCK_ERROR(dwErr);
  449. lock:
  450. LeaveCriticalSection(&g_wzcInternalCtxt.csContext);
  451. error:
  452. InterlockedDecrement(&g_nThreads);
  453. return dwErr;
  454. }
  455. extern SERVICE_STATUS g_WZCSvcStatus;
  456. DWORD
  457. RpcCmdInterface(
  458. IN DWORD dwHandle,
  459. IN DWORD dwCmdCode,
  460. IN LPWSTR wszIntfGuid,
  461. IN PRAW_DATA prdUserData)
  462. {
  463. DWORD dwErr = ERROR_SUCCESS;
  464. InterlockedIncrement(&g_nThreads);
  465. // We need to avoid processing this command if the service is not currently running
  466. // We need this protection only for this call because other than for the other calls,
  467. // RpcCmdInterface is called from 802.1x which runs within the same service. For all
  468. // the other Rpc stubs, the RPC server is shut down prior to destroying the global data
  469. // hence there is guaranteed no other calls will be made afterwards.
  470. if (g_WZCSvcStatus.dwCurrentState == SERVICE_RUNNING)
  471. {
  472. DbgPrint((TRC_TRACK, "[RpcCmdInterface(0x%x,%S)", dwCmdCode, wszIntfGuid));
  473. dwErr = WZCSvcCheckRPCAccess(WZC_ACCESS_SET);
  474. // currently this is not an RPC call! This is called directly from 802.1x. Consequently,
  475. // WZCSvcCheckRPCAccess will return RPC_S_NO_CALL_ACTIVE. We could either remove the
  476. // RPC check for now, or pass through the RPC_S_NO_CALL_ACTIVE (since later this could
  477. // become an RPC call). We do the latter!
  478. if (dwErr == ERROR_SUCCESS || dwErr == RPC_S_NO_CALL_ACTIVE)
  479. {
  480. dwErr = LstCmdInterface(dwHandle, dwCmdCode, wszIntfGuid, prdUserData);
  481. }
  482. DbgPrint((TRC_TRACK, "RpcCmdInterface]=%d", dwErr));
  483. }
  484. InterlockedDecrement(&g_nThreads);
  485. return dwErr;
  486. }
  487. VOID
  488. WZC_DBLOG_SESSION_HANDLE_rundown(
  489. WZC_DBLOG_SESSION_HANDLE hSession
  490. )
  491. {
  492. if (!g_bRpcStarted) {
  493. return;
  494. }
  495. if (!IsDBOpened()) {
  496. return;
  497. }
  498. if (hSession) {
  499. (VOID) CloseWZCDbLogSession(
  500. hSession
  501. );
  502. }
  503. return;
  504. }
  505. DWORD
  506. RpcOpenWZCDbLogSession(
  507. STRING_HANDLE pServerName,
  508. WZC_DBLOG_SESSION_HANDLE * phSession
  509. )
  510. {
  511. DWORD dwError = 0;
  512. InterlockedIncrement(&g_nThreads);
  513. dwError = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  514. BAIL_ON_WIN32_ERROR(dwError);
  515. if (!phSession) {
  516. dwError = ERROR_INVALID_PARAMETER;
  517. BAIL_ON_WIN32_ERROR(dwError);
  518. }
  519. dwError = OpenWZCDbLogSession(
  520. pServerName,
  521. 0,
  522. phSession
  523. );
  524. BAIL_ON_WIN32_ERROR(dwError);
  525. error:
  526. InterlockedDecrement(&g_nThreads);
  527. return (dwError);
  528. }
  529. DWORD
  530. RpcCloseWZCDbLogSession(
  531. WZC_DBLOG_SESSION_HANDLE * phSession
  532. )
  533. {
  534. DWORD dwError = 0;
  535. InterlockedIncrement(&g_nThreads);
  536. dwError = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  537. BAIL_ON_WIN32_ERROR(dwError);
  538. if (!IsDBOpened()) {
  539. dwError = ERROR_SERVICE_DISABLED;
  540. BAIL_ON_WIN32_ERROR(dwError);
  541. }
  542. if (!phSession) {
  543. InterlockedDecrement(&g_nThreads);
  544. return (ERROR_INVALID_PARAMETER);
  545. }
  546. dwError = CloseWZCDbLogSession(
  547. *phSession
  548. );
  549. BAIL_ON_WIN32_ERROR(dwError);
  550. *phSession = NULL;
  551. error:
  552. InterlockedDecrement(&g_nThreads);
  553. return (dwError);
  554. }
  555. DWORD
  556. RpcEnumWZCDbLogRecords(
  557. WZC_DBLOG_SESSION_HANDLE hSession,
  558. PWZC_DB_RECORD_CONTAINER pTemplateRecordContainer,
  559. PBOOL pbEnumFromStart,
  560. DWORD dwPreferredNumEntries,
  561. PWZC_DB_RECORD_CONTAINER * ppRecordContainer
  562. )
  563. {
  564. DWORD dwError = 0;
  565. PWZC_DB_RECORD pWZCRecords = NULL;
  566. DWORD dwNumRecords = 0;
  567. PWZC_DB_RECORD pTemplateRecord = NULL;
  568. InterlockedIncrement(&g_nThreads);
  569. dwError = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  570. BAIL_ON_WIN32_ERROR(dwError);
  571. if (!IsDBOpened()) {
  572. dwError = ERROR_SERVICE_DISABLED;
  573. BAIL_ON_WIN32_ERROR(dwError);
  574. }
  575. if (!hSession || !pbEnumFromStart) {
  576. InterlockedDecrement(&g_nThreads);
  577. return (ERROR_NOT_SUPPORTED);
  578. }
  579. if (!pTemplateRecordContainer || !ppRecordContainer ||
  580. !*ppRecordContainer) {
  581. InterlockedDecrement(&g_nThreads);
  582. return (ERROR_INVALID_PARAMETER);
  583. }
  584. if (pTemplateRecordContainer->pWZCRecords) {
  585. if (pTemplateRecordContainer->dwNumRecords != 1) {
  586. InterlockedDecrement(&g_nThreads);
  587. return (ERROR_INVALID_PARAMETER);
  588. }
  589. pTemplateRecord = pTemplateRecordContainer->pWZCRecords;
  590. }
  591. dwError = EnumWZCDbLogRecordsSummary(
  592. hSession,
  593. pTemplateRecord,
  594. pbEnumFromStart,
  595. dwPreferredNumEntries,
  596. &pWZCRecords,
  597. &dwNumRecords,
  598. NULL
  599. );
  600. if (dwError != ERROR_NO_MORE_ITEMS) {
  601. BAIL_ON_WIN32_ERROR(dwError);
  602. }
  603. (*ppRecordContainer)->pWZCRecords = pWZCRecords;
  604. (*ppRecordContainer)->dwNumRecords = dwNumRecords;
  605. InterlockedDecrement(&g_nThreads);
  606. return (dwError);
  607. error:
  608. (*ppRecordContainer)->pWZCRecords = NULL;
  609. (*ppRecordContainer)->dwNumRecords = 0;
  610. InterlockedDecrement(&g_nThreads);
  611. return (dwError);
  612. }
  613. DWORD
  614. RpcFlushWZCDbLog(
  615. WZC_DBLOG_SESSION_HANDLE hSession
  616. )
  617. {
  618. DWORD dwError = 0;
  619. InterlockedIncrement(&g_nThreads);
  620. dwError = WZCSvcCheckRPCAccess(WZC_ACCESS_SET);
  621. BAIL_ON_WIN32_ERROR(dwError);
  622. if (!IsDBOpened()) {
  623. dwError = ERROR_SERVICE_DISABLED;
  624. BAIL_ON_WIN32_ERROR(dwError);
  625. }
  626. if (!hSession){
  627. InterlockedDecrement(&g_nThreads);
  628. return(ERROR_INVALID_PARAMETER);
  629. }
  630. dwError = FlushWZCDbLog(
  631. hSession
  632. );
  633. BAIL_ON_WIN32_ERROR(dwError);
  634. error:
  635. InterlockedDecrement(&g_nThreads);
  636. return (dwError);
  637. }
  638. DWORD
  639. RpcGetWZCDbLogRecord(
  640. WZC_DBLOG_SESSION_HANDLE hSession,
  641. PWZC_DB_RECORD_CONTAINER pTemplateRecordContainer,
  642. PWZC_DB_RECORD_CONTAINER * ppRecordContainer
  643. )
  644. {
  645. DWORD dwError = 0;
  646. PWZC_DB_RECORD pWZCRecords = NULL;
  647. DWORD dwNumRecords = 0;
  648. PWZC_DB_RECORD pTemplateRecord = NULL;
  649. InterlockedIncrement(&g_nThreads);
  650. dwError = WZCSvcCheckRPCAccess(WZC_ACCESS_QUERY);
  651. BAIL_ON_WIN32_ERROR(dwError);
  652. if (!IsDBOpened()) {
  653. dwError = ERROR_SERVICE_DISABLED;
  654. BAIL_ON_WIN32_ERROR(dwError);
  655. }
  656. if(!hSession){
  657. InterlockedDecrement(&g_nThreads);
  658. return(ERROR_NOT_SUPPORTED);
  659. }
  660. if (!pTemplateRecordContainer || !ppRecordContainer ||
  661. !*ppRecordContainer) {
  662. InterlockedDecrement(&g_nThreads);
  663. return (ERROR_INVALID_PARAMETER);
  664. }
  665. if (pTemplateRecordContainer->pWZCRecords) {
  666. if (pTemplateRecordContainer->dwNumRecords != 1) {
  667. InterlockedDecrement(&g_nThreads);
  668. return (ERROR_INVALID_PARAMETER);
  669. }
  670. pTemplateRecord = pTemplateRecordContainer->pWZCRecords;
  671. }
  672. dwError = GetWZCDbLogRecord(
  673. hSession,
  674. pTemplateRecord,
  675. &pWZCRecords,
  676. NULL
  677. );
  678. BAIL_ON_WIN32_ERROR(dwError);
  679. (*ppRecordContainer)->pWZCRecords = pWZCRecords;
  680. (*ppRecordContainer)->dwNumRecords = 1;
  681. InterlockedDecrement(&g_nThreads);
  682. return (dwError);
  683. error:
  684. (*ppRecordContainer)->pWZCRecords = NULL;
  685. (*ppRecordContainer)->dwNumRecords = 0;
  686. InterlockedDecrement(&g_nThreads);
  687. return (dwError);
  688. }