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.

630 lines
20 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. CellUtil.cxx
  5. Abstract:
  6. Utility functions for manipulating cells
  7. Author:
  8. Kamen Moutafov (kamenm) Dec 99 - Feb 2000
  9. Revision History:
  10. --*/
  11. #include <precomp.hxx>
  12. #include <DbgLib.hxx>
  13. DebugCellUnion *GetCellByIndex(IN OpenedDbgSection *pSection, IN DWORD CellIndex)
  14. {
  15. DWORD LocalPageSize = GetPageSize();
  16. DebugCellGeneric *LastCellForSection;
  17. DebugCellGeneric *CurrentCell;
  18. ASSERT(pSection != NULL);
  19. ASSERT(pSection->SectionCopy != NULL);
  20. #ifdef _WIN64
  21. if (CellIndex <= 1)
  22. return NULL;
  23. #else
  24. if (CellIndex == 0)
  25. return NULL;
  26. #endif
  27. LastCellForSection = GetLastCellForSection(pSection, LocalPageSize);
  28. CurrentCell = GetCellForSection(pSection, CellIndex);
  29. // Check if we we were asked to retrieve a cell that is
  30. // outside the range of the section.
  31. if (CurrentCell <= LastCellForSection)
  32. {
  33. return (DebugCellUnion *) CurrentCell;
  34. }
  35. else
  36. {
  37. ASSERT(0);
  38. return NULL;
  39. }
  40. }
  41. DebugCellUnion *GetCellByDebugCellID(IN CellEnumerationHandle CellEnumHandle, IN DebugCellID CellID)
  42. {
  43. SectionsSnapshot *Snapshot;
  44. OpenedDbgSection *CurrentSection;
  45. DebugCellUnion *Cell = NULL;
  46. Snapshot = (SectionsSnapshot *)CellEnumHandle;
  47. ASSERT(Snapshot != NULL);
  48. CurrentSection = Snapshot->FirstOpenedSection;
  49. while (TRUE)
  50. {
  51. if (CurrentSection->SectionID == CellID.SectionID)
  52. {
  53. Cell = GetCellByIndex(CurrentSection, CellID.CellID);
  54. break;
  55. }
  56. if (CurrentSection->SectionsList.Flink == NULL)
  57. break;
  58. CurrentSection = CONTAINING_RECORD(CurrentSection->SectionsList.Flink, OpenedDbgSection, SectionsList);
  59. }
  60. return Cell;
  61. }
  62. RPC_STATUS GetCellByDebugCellID(IN DWORD ProcessID, IN DebugCellID CellID, OUT DebugCellUnion *Container)
  63. {
  64. RPC_STATUS Status;
  65. CellEnumerationHandle CellEnumHandle;
  66. DebugCellUnion *Cell;
  67. ASSERT(Container != NULL);
  68. Status = OpenRPCServerDebugInfo(ProcessID, &CellEnumHandle);
  69. if (Status != RPC_S_OK)
  70. {
  71. return Status;
  72. }
  73. Cell = GetCellByDebugCellID(CellEnumHandle, CellID);
  74. if (Cell)
  75. {
  76. memcpy(Container, Cell, sizeof(DebugCellUnion));
  77. }
  78. else
  79. Status = ERROR_FILE_NOT_FOUND;
  80. CloseRPCServerDebugInfo(&CellEnumHandle);
  81. return Status;
  82. }
  83. /////////////////////////////////////////////////////
  84. typedef struct tagRPCDebugCallInfoEnumState
  85. {
  86. DWORD CallID;
  87. DWORD IfStart;
  88. int ProcNum;
  89. DWORD ProcessID;
  90. union
  91. {
  92. // if ProcessID != 0, cellEnum is used (i.e. we have process wide enumeration
  93. // otherwise, systemWideEnum is used - we have system wide enumeration
  94. RPCSystemWideCellEnumerationHandle systemWideEnum;
  95. CellEnumerationHandle cellEnum;
  96. };
  97. } RPCDebugCallInfoEnumState;
  98. RPC_STATUS OpenRPCDebugCallInfoEnumeration(IN DWORD CallID OPTIONAL, IN DWORD IfStart OPTIONAL,
  99. IN int ProcNum OPTIONAL,
  100. IN DWORD ProcessID OPTIONAL,
  101. OUT CallInfoEnumerationHandle *pHandle)
  102. {
  103. RPCDebugCallInfoEnumState *pCallEnumeration;
  104. RPC_STATUS Status;
  105. *pHandle = NULL;
  106. pCallEnumeration = new RPCDebugCallInfoEnumState;
  107. if (pCallEnumeration == NULL)
  108. return RPC_S_OUT_OF_MEMORY;
  109. pCallEnumeration->CallID = CallID;
  110. pCallEnumeration->IfStart = IfStart;
  111. pCallEnumeration->ProcessID = ProcessID;
  112. pCallEnumeration->ProcNum = ProcNum;
  113. if (ProcessID != 0)
  114. {
  115. Status = OpenRPCServerDebugInfo(ProcessID, &pCallEnumeration->cellEnum);
  116. if (Status == ERROR_FILE_NOT_FOUND)
  117. {
  118. delete pCallEnumeration;
  119. return RPC_S_DBG_NOT_AN_RPC_SERVER;
  120. }
  121. else if (Status != RPC_S_OK)
  122. {
  123. delete pCallEnumeration;
  124. return Status;
  125. }
  126. }
  127. else
  128. {
  129. Status = OpenRPCSystemWideCellEnumeration(&pCallEnumeration->systemWideEnum);
  130. if (Status != RPC_S_OK)
  131. {
  132. delete pCallEnumeration;
  133. return Status;
  134. }
  135. }
  136. *pHandle = (CallInfoEnumerationHandle) pCallEnumeration;
  137. return RPC_S_OK;
  138. }
  139. RPC_STATUS GetNextRPCDebugCallInfo(IN CallInfoEnumerationHandle handle, OUT DebugCallInfo **NextCall,
  140. OUT DebugCellID *CellID, OUT DWORD *ServerPID)
  141. {
  142. RPCDebugCallInfoEnumState *pCallEnumeration = (RPCDebugCallInfoEnumState *)handle;
  143. RPC_STATUS Status;
  144. DebugCallInfo *CallInfo;
  145. DebugCellUnion *NextCell;
  146. ASSERT(pCallEnumeration != NULL);
  147. ASSERT(NextCall != NULL);
  148. ASSERT(ServerPID != NULL);
  149. // loop until we find something or run out of cells/servers
  150. while (TRUE)
  151. {
  152. if (pCallEnumeration->ProcessID != 0)
  153. {
  154. *ServerPID = pCallEnumeration->ProcessID;
  155. NextCell = GetNextDebugCellInfo(pCallEnumeration->cellEnum, CellID);
  156. if (NextCell == NULL)
  157. return RPC_S_DBG_ENUMERATION_DONE;
  158. }
  159. else
  160. {
  161. Status = GetNextRPCSystemWideCell(pCallEnumeration->systemWideEnum, &NextCell, CellID, ServerPID);
  162. if (Status == RPC_S_INVALID_BOUND)
  163. return RPC_S_DBG_ENUMERATION_DONE;
  164. if (Status != RPC_S_OK)
  165. return Status;
  166. }
  167. // NextCell must be non-NULL here, or we have a bug
  168. ASSERT(NextCell != NULL);
  169. if (NextCell->callInfo.Type != dctCallInfo)
  170. continue;
  171. CallInfo = &NextCell->callInfo;
  172. if ((pCallEnumeration->CallID != 0) && (CallInfo->CallID != pCallEnumeration->CallID))
  173. continue;
  174. if ((pCallEnumeration->IfStart != 0) && (CallInfo->InterfaceUUIDStart != pCallEnumeration->IfStart))
  175. continue;
  176. if (((USHORT)pCallEnumeration->ProcNum != (USHORT)RPCDBG_NO_PROCNUM_SPECIFIED)
  177. && (CallInfo->ProcNum != pCallEnumeration->ProcNum))
  178. continue;
  179. // if we have survived all checks until now, we have found it - return it
  180. *NextCall = CallInfo;
  181. return RPC_S_OK;
  182. }
  183. }
  184. void FinishRPCDebugCallInfoEnumeration(IN OUT CallInfoEnumerationHandle *pHandle)
  185. {
  186. RPCDebugCallInfoEnumState *pCallEnumeration;
  187. ASSERT(pHandle != NULL);
  188. pCallEnumeration = (RPCDebugCallInfoEnumState *)*pHandle;
  189. ASSERT(pCallEnumeration != NULL);
  190. if (pCallEnumeration->ProcessID != 0)
  191. {
  192. CloseRPCServerDebugInfo(&pCallEnumeration->cellEnum);
  193. }
  194. else
  195. {
  196. FinishRPCSystemWideCellEnumeration(&pCallEnumeration->systemWideEnum);
  197. }
  198. }
  199. RPC_STATUS ResetRPCDebugCallInfoEnumeration(IN CallInfoEnumerationHandle handle)
  200. {
  201. RPCDebugCallInfoEnumState *pCallEnumeration = (RPCDebugCallInfoEnumState *)handle;
  202. ASSERT(pCallEnumeration != NULL);
  203. if (pCallEnumeration->ProcessID != 0)
  204. {
  205. ResetRPCServerDebugInfo(pCallEnumeration->cellEnum);
  206. return RPC_S_OK;
  207. }
  208. else
  209. {
  210. return ResetRPCSystemWideCellEnumeration(pCallEnumeration->systemWideEnum);
  211. }
  212. }
  213. ////////////////////////////////////
  214. typedef struct tagRPCDebugEndpointInfoEnumState
  215. {
  216. char *Endpoint;
  217. RPCSystemWideCellEnumerationHandle systemWideEnum;
  218. } RPCDebugEndpointInfoEnumState;
  219. RPC_STATUS OpenRPCDebugEndpointInfoEnumeration(IN char *Endpoint OPTIONAL,
  220. OUT EndpointInfoEnumerationHandle *pHandle)
  221. {
  222. RPCDebugEndpointInfoEnumState *pEndpointEnumeration;
  223. RPC_STATUS Status;
  224. int EndpointLength;
  225. *pHandle = NULL;
  226. pEndpointEnumeration = new RPCDebugEndpointInfoEnumState;
  227. if (pEndpointEnumeration == NULL)
  228. return RPC_S_OUT_OF_MEMORY;
  229. if (ARGUMENT_PRESENT(Endpoint))
  230. {
  231. EndpointLength = strlen(Endpoint);
  232. pEndpointEnumeration->Endpoint = new char [EndpointLength + 1];
  233. if (pEndpointEnumeration->Endpoint == NULL)
  234. {
  235. delete pEndpointEnumeration;
  236. return RPC_S_OUT_OF_MEMORY;
  237. }
  238. memcpy(pEndpointEnumeration->Endpoint, Endpoint, EndpointLength + 1);
  239. }
  240. else
  241. {
  242. pEndpointEnumeration->Endpoint = NULL;
  243. }
  244. Status = OpenRPCSystemWideCellEnumeration(&pEndpointEnumeration->systemWideEnum);
  245. if (Status != RPC_S_OK)
  246. {
  247. delete pEndpointEnumeration;
  248. return Status;
  249. }
  250. *pHandle = (EndpointInfoEnumerationHandle) pEndpointEnumeration;
  251. return RPC_S_OK;
  252. }
  253. RPC_STATUS GetNextRPCDebugEndpointInfo(IN CallInfoEnumerationHandle handle, OUT DebugEndpointInfo **NextEndpoint,
  254. OUT DebugCellID *CellID, OUT DWORD *ServerPID)
  255. {
  256. RPCDebugEndpointInfoEnumState *pEndpointEnumeration = (RPCDebugEndpointInfoEnumState *)handle;
  257. RPC_STATUS Status;
  258. DebugEndpointInfo *EndpointInfo;
  259. DebugCellUnion *NextCell;
  260. ASSERT(pEndpointEnumeration != NULL);
  261. ASSERT(NextEndpoint != NULL);
  262. ASSERT(ServerPID != NULL);
  263. // loop until we find something or run out of cells/servers
  264. while (TRUE)
  265. {
  266. Status = GetNextRPCSystemWideCell(pEndpointEnumeration->systemWideEnum, &NextCell, CellID, ServerPID);
  267. if (Status == RPC_S_INVALID_BOUND)
  268. return RPC_S_DBG_ENUMERATION_DONE;
  269. if (Status != RPC_S_OK)
  270. return Status;
  271. // NextCell must be non-NULL here, or we have a bug
  272. ASSERT(NextCell != NULL);
  273. if (NextCell->callInfo.Type != dctEndpointInfo)
  274. continue;
  275. EndpointInfo = &NextCell->endpointInfo;
  276. if (pEndpointEnumeration->Endpoint != NULL)
  277. {
  278. if (strncmp(EndpointInfo->EndpointName, pEndpointEnumeration->Endpoint, sizeof(EndpointInfo->EndpointName)) != 0)
  279. continue;
  280. }
  281. // if we have survived all checks until now, we have found it - return it
  282. *NextEndpoint = EndpointInfo;
  283. return RPC_S_OK;
  284. }
  285. }
  286. void FinishRPCDebugEndpointInfoEnumeration(IN OUT EndpointInfoEnumerationHandle *pHandle)
  287. {
  288. RPCDebugEndpointInfoEnumState *pEndpointEnumeration;
  289. ASSERT(pHandle != NULL);
  290. pEndpointEnumeration = (RPCDebugEndpointInfoEnumState *)*pHandle;
  291. ASSERT(pEndpointEnumeration != NULL);
  292. FinishRPCSystemWideCellEnumeration(&pEndpointEnumeration->systemWideEnum);
  293. }
  294. RPC_STATUS ResetRPCDebugEndpointInfoEnumeration(IN EndpointInfoEnumerationHandle handle)
  295. {
  296. RPCDebugEndpointInfoEnumState *pEndpointEnumeration = (RPCDebugEndpointInfoEnumState *)handle;
  297. ASSERT(pEndpointEnumeration != NULL);
  298. return ResetRPCSystemWideCellEnumeration(pEndpointEnumeration->systemWideEnum);
  299. }
  300. ////////////////////////////////////////////////
  301. typedef struct tagRPCDebugThreadInfoEnumState
  302. {
  303. DWORD ProcessID;
  304. DWORD ThreadID;
  305. CellEnumerationHandle cellEnum;
  306. } RPCDebugThreadInfoEnumState;
  307. RPC_STATUS OpenRPCDebugThreadInfoEnumeration(IN DWORD ProcessID,
  308. IN DWORD ThreadID OPTIONAL,
  309. OUT ThreadInfoEnumerationHandle *pHandle)
  310. {
  311. RPCDebugThreadInfoEnumState *pThreadEnumeration;
  312. RPC_STATUS Status;
  313. ASSERT(ProcessID != 0);
  314. *pHandle = NULL;
  315. pThreadEnumeration = new RPCDebugThreadInfoEnumState;
  316. if (pThreadEnumeration == NULL)
  317. return RPC_S_OUT_OF_MEMORY;
  318. pThreadEnumeration->ProcessID = ProcessID;
  319. pThreadEnumeration->ThreadID = ThreadID;
  320. Status = OpenRPCServerDebugInfo(ProcessID, &pThreadEnumeration->cellEnum);
  321. if (Status == ERROR_FILE_NOT_FOUND)
  322. {
  323. delete pThreadEnumeration;
  324. return RPC_S_DBG_NOT_AN_RPC_SERVER;
  325. }
  326. else if (Status != RPC_S_OK)
  327. {
  328. delete pThreadEnumeration;
  329. return Status;
  330. }
  331. *pHandle = (ThreadInfoEnumerationHandle) pThreadEnumeration;
  332. return RPC_S_OK;
  333. }
  334. RPC_STATUS GetNextRPCDebugThreadInfo(IN ThreadInfoEnumerationHandle handle, OUT DebugThreadInfo **NextThread,
  335. OUT DebugCellID *CellID, OUT DWORD *ServerPID)
  336. {
  337. RPCDebugThreadInfoEnumState *pThreadEnumeration = (RPCDebugThreadInfoEnumState *)handle;
  338. RPC_STATUS Status;
  339. DebugThreadInfo *ThreadInfo;
  340. DebugCellUnion *NextCell;
  341. ASSERT(pThreadEnumeration != NULL);
  342. ASSERT(NextThread != NULL);
  343. ASSERT(ServerPID != NULL);
  344. // loop until we find something or run out of cells/servers
  345. while (TRUE)
  346. {
  347. *ServerPID = pThreadEnumeration->ProcessID;
  348. NextCell = GetNextDebugCellInfo(pThreadEnumeration->cellEnum, CellID);
  349. if (NextCell == NULL)
  350. return RPC_S_DBG_ENUMERATION_DONE;
  351. if (NextCell->callInfo.Type != dctThreadInfo)
  352. continue;
  353. ThreadInfo = &NextCell->threadInfo;
  354. if ((pThreadEnumeration->ThreadID != 0) && (ThreadInfo->TID != pThreadEnumeration->ThreadID))
  355. continue;
  356. // if we have survived all checks until now, we have found it - return it
  357. *NextThread = ThreadInfo;
  358. return RPC_S_OK;
  359. }
  360. }
  361. void FinishRPCDebugThreadInfoEnumeration(IN OUT ThreadInfoEnumerationHandle *pHandle)
  362. {
  363. RPCDebugThreadInfoEnumState *pThreadEnumeration;
  364. ASSERT(pHandle != NULL);
  365. pThreadEnumeration = (RPCDebugThreadInfoEnumState *)*pHandle;
  366. ASSERT(pThreadEnumeration != NULL);
  367. CloseRPCServerDebugInfo(&pThreadEnumeration->cellEnum);
  368. }
  369. RPC_STATUS ResetRPCDebugThreadInfoEnumeration(IN ThreadInfoEnumerationHandle handle)
  370. {
  371. RPCDebugThreadInfoEnumState *pThreadEnumeration = (RPCDebugThreadInfoEnumState *)handle;
  372. ASSERT(pThreadEnumeration != NULL);
  373. ResetRPCServerDebugInfo(pThreadEnumeration->cellEnum);
  374. return RPC_S_OK;
  375. }
  376. /////////////////////////////////////////////////////
  377. typedef struct tagRPCDebugClientCallInfoEnumState
  378. {
  379. DWORD CallID;
  380. DWORD IfStart;
  381. int ProcNum;
  382. DWORD ProcessID;
  383. union
  384. {
  385. // if ProcessID != 0, cellEnum is used (i.e. we have process wide enumeration
  386. // otherwise, systemWideEnum is used - we have system wide enumeration
  387. RPCSystemWideCellEnumerationHandle systemWideEnum;
  388. CellEnumerationHandle cellEnum;
  389. };
  390. } RPCDebugClientCallInfoEnumState;
  391. RPC_STATUS OpenRPCDebugClientCallInfoEnumeration(IN DWORD CallID OPTIONAL, IN DWORD IfStart OPTIONAL,
  392. IN int ProcNum OPTIONAL,
  393. IN DWORD ProcessID OPTIONAL,
  394. OUT ClientCallInfoEnumerationHandle *pHandle)
  395. {
  396. RPCDebugClientCallInfoEnumState *pCallEnumeration;
  397. RPC_STATUS Status;
  398. *pHandle = NULL;
  399. pCallEnumeration = new RPCDebugClientCallInfoEnumState;
  400. if (pCallEnumeration == NULL)
  401. return RPC_S_OUT_OF_MEMORY;
  402. pCallEnumeration->CallID = CallID;
  403. pCallEnumeration->IfStart = IfStart;
  404. pCallEnumeration->ProcessID = ProcessID;
  405. pCallEnumeration->ProcNum = ProcNum;
  406. if (ProcessID != 0)
  407. {
  408. Status = OpenRPCServerDebugInfo(ProcessID, &pCallEnumeration->cellEnum);
  409. if (Status == ERROR_FILE_NOT_FOUND)
  410. {
  411. delete pCallEnumeration;
  412. return RPC_S_DBG_NOT_AN_RPC_SERVER;
  413. }
  414. else if (Status != RPC_S_OK)
  415. {
  416. delete pCallEnumeration;
  417. return Status;
  418. }
  419. }
  420. else
  421. {
  422. Status = OpenRPCSystemWideCellEnumeration(&pCallEnumeration->systemWideEnum);
  423. if (Status != RPC_S_OK)
  424. {
  425. delete pCallEnumeration;
  426. return Status;
  427. }
  428. }
  429. *pHandle = (ClientCallInfoEnumerationHandle) pCallEnumeration;
  430. return RPC_S_OK;
  431. }
  432. RPC_STATUS GetNextRPCDebugClientCallInfo(IN ClientCallInfoEnumerationHandle handle,
  433. OUT DebugClientCallInfo **NextCall,
  434. OUT DebugCallTargetInfo **NextCallTarget,
  435. OUT DebugCellID *CellID, OUT DWORD *ServerPID)
  436. {
  437. RPCDebugClientCallInfoEnumState *pCallEnumeration = (RPCDebugClientCallInfoEnumState *)handle;
  438. RPC_STATUS Status;
  439. DebugClientCallInfo *CallInfo;
  440. DebugCallTargetInfo *CallTargetInfo;
  441. DebugCellUnion *NextCell;
  442. ASSERT(pCallEnumeration != NULL);
  443. ASSERT(NextCall != NULL);
  444. ASSERT(ServerPID != NULL);
  445. // loop until we find something or run out of cells/servers
  446. while (TRUE)
  447. {
  448. if (pCallEnumeration->ProcessID != 0)
  449. {
  450. *ServerPID = pCallEnumeration->ProcessID;
  451. NextCell = GetNextDebugCellInfo(pCallEnumeration->cellEnum, CellID);
  452. if (NextCell == NULL)
  453. return RPC_S_DBG_ENUMERATION_DONE;
  454. }
  455. else
  456. {
  457. Status = GetNextRPCSystemWideCell(pCallEnumeration->systemWideEnum, &NextCell, CellID, ServerPID);
  458. if (Status == RPC_S_INVALID_BOUND)
  459. return RPC_S_DBG_ENUMERATION_DONE;
  460. if (Status != RPC_S_OK)
  461. return Status;
  462. }
  463. // NextCell must be non-NULL here, or we have a bug
  464. ASSERT(NextCell != NULL);
  465. if (NextCell->callInfo.Type != dctClientCallInfo)
  466. continue;
  467. CallInfo = &NextCell->clientCallInfo;
  468. if ((pCallEnumeration->CallID != 0) && (CallInfo->CallID != pCallEnumeration->CallID))
  469. continue;
  470. if ((pCallEnumeration->IfStart != 0) && (CallInfo->IfStart != pCallEnumeration->IfStart))
  471. continue;
  472. if (((USHORT)pCallEnumeration->ProcNum != (USHORT)RPCDBG_NO_PROCNUM_SPECIFIED)
  473. && (CallInfo->ProcNum != pCallEnumeration->ProcNum))
  474. continue;
  475. if (pCallEnumeration->ProcessID != 0)
  476. {
  477. CallTargetInfo = (DebugCallTargetInfo *) GetCellByDebugCellID(pCallEnumeration->cellEnum,
  478. NextCell->clientCallInfo.CallTargetID);
  479. }
  480. else
  481. {
  482. CallTargetInfo = (DebugCallTargetInfo *) GetRPCSystemWideCellFromCellID(pCallEnumeration->systemWideEnum,
  483. NextCell->clientCallInfo.CallTargetID);
  484. }
  485. // if we have survived all checks until now, we have found it - return it
  486. *NextCall = CallInfo;
  487. *NextCallTarget = CallTargetInfo;
  488. return RPC_S_OK;
  489. }
  490. }
  491. void FinishRPCDebugClientCallInfoEnumeration(IN OUT ClientCallInfoEnumerationHandle *pHandle)
  492. {
  493. RPCDebugClientCallInfoEnumState *pCallEnumeration;
  494. ASSERT(pHandle != NULL);
  495. pCallEnumeration = (RPCDebugClientCallInfoEnumState *)*pHandle;
  496. ASSERT(pCallEnumeration != NULL);
  497. if (pCallEnumeration->ProcessID != 0)
  498. {
  499. CloseRPCServerDebugInfo(&pCallEnumeration->cellEnum);
  500. }
  501. else
  502. {
  503. FinishRPCSystemWideCellEnumeration(&pCallEnumeration->systemWideEnum);
  504. }
  505. }
  506. RPC_STATUS ResetRPCDebugClientCallInfoEnumeration(IN CallInfoEnumerationHandle handle)
  507. {
  508. RPCDebugClientCallInfoEnumState *pCallEnumeration = (RPCDebugClientCallInfoEnumState *)handle;
  509. ASSERT(pCallEnumeration != NULL);
  510. if (pCallEnumeration->ProcessID != 0)
  511. {
  512. ResetRPCServerDebugInfo(pCallEnumeration->cellEnum);
  513. return RPC_S_OK;
  514. }
  515. else
  516. {
  517. return ResetRPCSystemWideCellEnumeration(pCallEnumeration->systemWideEnum);
  518. }
  519. }