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.

715 lines
22 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1996 - 1999
  3. Module Name:
  4. DbgSvr.cxx
  5. Abstract:
  6. The debugging support interfaces in RPCSS
  7. Author:
  8. Kamen Moutafov [KamenM]
  9. Revision History:
  10. KamenM Dec 99 Creation
  11. --*/
  12. #include <sysinc.h>
  13. #include <wincrypt.h>
  14. #include <wtypes.h>
  15. #include <rpc.h>
  16. #include <rpcdcep.h>
  17. #include <rpcerrp.h>
  18. #include <rpctrans.hxx>
  19. #include <objidl.h>
  20. #include <CellDef.hxx>
  21. #include <DbgIdl.h>
  22. START_C_EXTERN
  23. RPC_STATUS RPC_ENTRY
  24. DebugServerSecurityCallback (
  25. IN RPC_IF_HANDLE InterfaceUuid,
  26. IN void *Context
  27. )
  28. {
  29. RPC_STATUS Status, TempStatus;
  30. HANDLE TempHandle;
  31. PVOID SectionPointer;
  32. // Context is an SCALL
  33. Status = RpcImpersonateClient(Context);
  34. if (Status != RPC_S_OK)
  35. {
  36. return Status;
  37. }
  38. // try to open our own section - this is protected by ACL for admins & local system
  39. // only, so this should filter out unauthorized access
  40. Status = OpenDbgSection(&TempHandle, &SectionPointer, GetCurrentProcessId(), NULL);
  41. if (Status == RPC_S_OK)
  42. {
  43. CloseDbgSection(TempHandle, SectionPointer);
  44. }
  45. TempStatus = RpcRevertToSelfEx(Context);
  46. ASSERT(TempStatus == RPC_S_OK);
  47. return Status;
  48. }
  49. ////////////////////////////////////////////////////////////////////
  50. /// Local representation to wire representation translation routines
  51. ////////////////////////////////////////////////////////////////////
  52. void TranslateLocalCallInfoToRemoteCallInfo(IN DebugCallInfo *LocalDebugInfo,
  53. OUT RemoteDebugCallInfo *RemoteCallInfo)
  54. {
  55. RemoteCallInfo->Type = LocalDebugInfo->Type;
  56. RemoteCallInfo->Status = LocalDebugInfo->Status;
  57. RemoteCallInfo->ProcNum = LocalDebugInfo->ProcNum;
  58. RemoteCallInfo->InterfaceUUIDStart = LocalDebugInfo->InterfaceUUIDStart;
  59. RemoteCallInfo->ServicingTID = LocalDebugInfo->ServicingTID;
  60. RemoteCallInfo->CallFlags = LocalDebugInfo->CallFlags;
  61. RemoteCallInfo->CallID = LocalDebugInfo->CallID;
  62. RemoteCallInfo->LastUpdateTime = LocalDebugInfo->LastUpdateTime;
  63. if (LocalDebugInfo->CallFlags & DBGCELL_LRPC_CALL)
  64. {
  65. RemoteCallInfo->ConnectionType = crtLrpcConnection;
  66. RemoteCallInfo->connInfo.Connection = LocalDebugInfo->Connection;
  67. }
  68. else
  69. {
  70. RemoteCallInfo->ConnectionType = crtOsfConnection;
  71. RemoteCallInfo->connInfo.Caller.PID = LocalDebugInfo->PID;
  72. RemoteCallInfo->connInfo.Caller.TID = LocalDebugInfo->TID;
  73. }
  74. }
  75. void TranslateLocalEndpointInfoToRemoteEndpointInfo(IN DebugEndpointInfo *LocalDebugInfo,
  76. OUT RemoteDebugEndpointInfo *RemoteEndpointInfo)
  77. {
  78. RemoteEndpointInfo->Type = LocalDebugInfo->Type;
  79. RemoteEndpointInfo->ProtseqType = LocalDebugInfo->ProtseqType;
  80. RemoteEndpointInfo->Status = LocalDebugInfo->Status;
  81. // the endpoint name in the debug cell is not null terminated - process it specially
  82. RemoteEndpointInfo->EndpointNameLength = 0;
  83. RemoteEndpointInfo->EndpointName
  84. = (unsigned char *)MIDL_user_allocate(DebugEndpointNameLength + 1);
  85. if (RemoteEndpointInfo->EndpointName != NULL)
  86. {
  87. memcpy(RemoteEndpointInfo->EndpointName,
  88. LocalDebugInfo->EndpointName, DebugEndpointNameLength);
  89. RemoteEndpointInfo->EndpointName[DebugEndpointNameLength] = 0;
  90. RemoteEndpointInfo->EndpointNameLength
  91. = strlen((const char *) RemoteEndpointInfo->EndpointName) + 1;
  92. }
  93. }
  94. void TranslateLocalThreadInfoToRemoteThreadInfo(IN DebugThreadInfo *LocalDebugInfo,
  95. OUT RemoteDebugThreadInfo *RemoteThreadInfo)
  96. {
  97. RemoteThreadInfo->Type = LocalDebugInfo->Type;
  98. RemoteThreadInfo->Status = LocalDebugInfo->Status;
  99. RemoteThreadInfo->LastUpdateTime = LocalDebugInfo->LastUpdateTime;
  100. RemoteThreadInfo->TID = LocalDebugInfo->TID;
  101. RemoteThreadInfo->Endpoint = LocalDebugInfo->Endpoint;
  102. }
  103. void TranslateLocalClientCallInfoToRemoteClientCallInfo(IN DebugClientCallInfo *LocalDebugInfo,
  104. OUT RemoteDebugClientCallInfo *RemoteClientCallInfo)
  105. {
  106. RemoteClientCallInfo->Type = LocalDebugInfo->Type;
  107. RemoteClientCallInfo->ProcNum = LocalDebugInfo->ProcNum;
  108. RemoteClientCallInfo->ServicingThread = LocalDebugInfo->ServicingThread;
  109. RemoteClientCallInfo->IfStart = LocalDebugInfo->IfStart;
  110. RemoteClientCallInfo->CallID = LocalDebugInfo->CallID;
  111. RemoteClientCallInfo->CallTargetID = LocalDebugInfo->CallTargetID;
  112. // the endpoint in the debug cell is not null terminated - process it specially
  113. RemoteClientCallInfo->EndpointLength = 0;
  114. RemoteClientCallInfo->Endpoint
  115. = (unsigned char *)MIDL_user_allocate(ClientCallEndpointLength + 1);
  116. if (RemoteClientCallInfo->Endpoint != NULL)
  117. {
  118. memcpy(RemoteClientCallInfo->Endpoint,
  119. LocalDebugInfo->Endpoint, ClientCallEndpointLength);
  120. RemoteClientCallInfo->Endpoint[ClientCallEndpointLength] = 0;
  121. RemoteClientCallInfo->EndpointLength
  122. = strlen((const char *) RemoteClientCallInfo->Endpoint) + 1;
  123. }
  124. }
  125. void TranslateLocalConnectionInfoToRemoteConnectionInfo(IN DebugConnectionInfo *LocalDebugInfo,
  126. OUT RemoteDebugConnectionInfo *RemoteConnectionInfo)
  127. {
  128. RemoteConnectionInfo->Type = LocalDebugInfo->Type;
  129. RemoteConnectionInfo->Flags = LocalDebugInfo->Flags;
  130. RemoteConnectionInfo->LastTransmitFragmentSize
  131. = LocalDebugInfo->LastTransmitFragmentSize;
  132. RemoteConnectionInfo->Endpoint = LocalDebugInfo->Endpoint;
  133. RemoteConnectionInfo->ConnectionID[0]
  134. = HandleToUlong(LocalDebugInfo->ConnectionID[0]);
  135. RemoteConnectionInfo->ConnectionID[1]
  136. = HandleToUlong(LocalDebugInfo->ConnectionID[1]);
  137. RemoteConnectionInfo->LastSendTime = LocalDebugInfo->LastSendTime;
  138. RemoteConnectionInfo->LastReceiveTime = LocalDebugInfo->LastReceiveTime;
  139. }
  140. void TranslateLocalCallTargetInfoToRemoteCallTargetInfo(IN DebugCallTargetInfo *LocalDebugInfo,
  141. OUT RemoteDebugCallTargetInfo *RemoteCallTargetInfo)
  142. {
  143. RemoteCallTargetInfo->Type = LocalDebugInfo->Type;
  144. RemoteCallTargetInfo->ProtocolSequence = LocalDebugInfo->ProtocolSequence;
  145. RemoteCallTargetInfo->LastUpdateTime = LocalDebugInfo->LastUpdateTime;
  146. // the target server name in the debug cell is not null terminated - process it specially
  147. RemoteCallTargetInfo->TargetServerLength = 0;
  148. RemoteCallTargetInfo->TargetServer
  149. = (unsigned char *)MIDL_user_allocate(TargetServerNameLength + 1);
  150. if (RemoteCallTargetInfo->TargetServer != NULL)
  151. {
  152. memcpy(RemoteCallTargetInfo->TargetServer,
  153. LocalDebugInfo->TargetServer, TargetServerNameLength);
  154. RemoteCallTargetInfo->TargetServer[TargetServerNameLength] = 0;
  155. RemoteCallTargetInfo->TargetServerLength
  156. = strlen((const char *) RemoteCallTargetInfo->TargetServer) + 1;
  157. }
  158. }
  159. ////////////////////////////////////////////////////////////////////
  160. /// Remote get cell info routine
  161. ////////////////////////////////////////////////////////////////////
  162. /* [fault_status][comm_status] */ error_status_t RemoteGetCellByDebugCellID(
  163. /* [in] */ handle_t IDL_handle,
  164. /* [in] */ DWORD ProcessID,
  165. /* [in] */ DebugCellID CellID,
  166. /* [in, out, unique] */ RemoteDebugCellUnion __RPC_FAR *__RPC_FAR *debugInfo)
  167. {
  168. DebugCellUnion Container;
  169. RemoteDebugCellUnion *ActualDebugInfo;
  170. RPC_STATUS Status;
  171. if (debugInfo == NULL)
  172. RpcRaiseException(ERROR_INVALID_PARAMETER);
  173. *debugInfo = NULL;
  174. ActualDebugInfo = (RemoteDebugCellUnion *) MIDL_user_allocate(sizeof(RemoteDebugCellUnion));
  175. if (ActualDebugInfo == NULL)
  176. return RPC_S_OUT_OF_MEMORY;
  177. Status = GetCellByDebugCellID(ProcessID, CellID, &Container);
  178. if (Status != RPC_S_OK)
  179. {
  180. MIDL_user_free(ActualDebugInfo);
  181. return Status;
  182. }
  183. ActualDebugInfo->UnionType = Container.callInfo.Type;
  184. if ((ActualDebugInfo->UnionType < dctFirstEntry) || (ActualDebugInfo->UnionType > dctLastEntry)
  185. || (ActualDebugInfo->UnionType == dctInvalid) || (ActualDebugInfo->UnionType == dctFree)
  186. || (ActualDebugInfo->UnionType == dctUsedGeneric))
  187. {
  188. MIDL_user_free(ActualDebugInfo);
  189. return RPC_S_OBJECT_NOT_FOUND;
  190. }
  191. switch(ActualDebugInfo->UnionType)
  192. {
  193. case dctCallInfo:
  194. TranslateLocalCallInfoToRemoteCallInfo(&Container.callInfo,
  195. &ActualDebugInfo->debugInfo.callInfo);
  196. break;
  197. case dctThreadInfo:
  198. TranslateLocalThreadInfoToRemoteThreadInfo(&Container.threadInfo,
  199. &ActualDebugInfo->debugInfo.threadInfo);
  200. break;
  201. case dctEndpointInfo:
  202. TranslateLocalEndpointInfoToRemoteEndpointInfo(&Container.endpointInfo,
  203. &ActualDebugInfo->debugInfo.endpointInfo);
  204. break;
  205. case dctClientCallInfo:
  206. TranslateLocalClientCallInfoToRemoteClientCallInfo(&Container.clientCallInfo,
  207. &ActualDebugInfo->debugInfo.clientCallInfo);
  208. break;
  209. case dctConnectionInfo:
  210. TranslateLocalConnectionInfoToRemoteConnectionInfo(&Container.connectionInfo,
  211. &ActualDebugInfo->debugInfo.connectionInfo);
  212. break;
  213. case dctCallTargetInfo:
  214. TranslateLocalCallTargetInfoToRemoteCallTargetInfo(&Container.callTargetInfo,
  215. &ActualDebugInfo->debugInfo.callTargetInfo);
  216. break;
  217. default:
  218. ASSERT(0);
  219. }
  220. *debugInfo = ActualDebugInfo;
  221. return RPC_S_OK;
  222. }
  223. ////////////////////////////////////////////////////////////////////
  224. /// Remote call enumeration routines
  225. ////////////////////////////////////////////////////////////////////
  226. typedef enum tagRemoteEnumerationHandleType
  227. {
  228. rehtCallInfo,
  229. rehtEndpointInfo,
  230. rehtThreadInfo,
  231. rehtClientCallInfo
  232. } RemoteEnumerationHandleType;
  233. typedef struct tagRemoteCallInfoEnumerationHandle
  234. {
  235. RemoteEnumerationHandleType ThisHandleType;
  236. CallInfoEnumerationHandle h;
  237. } RemoteCallInfoEnumerationHandle;
  238. error_status_t RemoteOpenRPCDebugCallInfoEnumeration(
  239. /* [in] */ handle_t IDL_handle,
  240. /* [out] */ DbgCallEnumHandle __RPC_FAR *h,
  241. /* [in] */ DWORD CallID,
  242. /* [in] */ DWORD IfStart,
  243. /* [in] */ int ProcNum,
  244. /* [in] */ DWORD ProcessID)
  245. {
  246. RemoteCallInfoEnumerationHandle *rh;
  247. RPC_STATUS Status;
  248. *h = NULL;
  249. rh = new RemoteCallInfoEnumerationHandle;
  250. if (rh == NULL)
  251. return RPC_S_OUT_OF_MEMORY;
  252. rh->ThisHandleType = rehtCallInfo;
  253. Status = OpenRPCDebugCallInfoEnumeration(CallID, IfStart, ProcNum, ProcessID, &rh->h);
  254. if (Status != RPC_S_OK)
  255. {
  256. delete rh;
  257. return Status;
  258. }
  259. *h = rh;
  260. return RPC_S_OK;
  261. }
  262. error_status_t RemoteGetNextRPCDebugCallInfo(
  263. /* [in] */ DbgCallEnumHandle h,
  264. /* [unique][out][in] */ RemoteDebugCallInfo __RPC_FAR *__RPC_FAR *debugInfo,
  265. /* [out] */ DebugCellID __RPC_FAR *CellID,
  266. /* [out] */ DWORD __RPC_FAR *ProcessID)
  267. {
  268. RemoteCallInfoEnumerationHandle *rh;
  269. RPC_STATUS Status;
  270. DebugCallInfo *NextCall;
  271. if (debugInfo == NULL)
  272. RpcRaiseException(ERROR_INVALID_PARAMETER);
  273. *debugInfo = NULL;
  274. CellID->SectionID = 0;
  275. CellID->CellID = 0;
  276. rh = (RemoteCallInfoEnumerationHandle *)h;
  277. if (rh->ThisHandleType != rehtCallInfo)
  278. return ERROR_INVALID_HANDLE;
  279. Status = GetNextRPCDebugCallInfo(rh->h, &NextCall, CellID, ProcessID);
  280. if (Status == RPC_S_OK)
  281. {
  282. *debugInfo = (RemoteDebugCallInfo *) MIDL_user_allocate(sizeof(RemoteDebugCallInfo));
  283. if (*debugInfo != NULL)
  284. {
  285. TranslateLocalCallInfoToRemoteCallInfo(NextCall, *debugInfo);
  286. }
  287. else
  288. Status = RPC_S_OUT_OF_MEMORY;
  289. }
  290. return Status;
  291. }
  292. error_status_t RemoteFinishRPCDebugCallInfoEnumeration(
  293. /* [out][in] */ DbgCallEnumHandle __RPC_FAR *h)
  294. {
  295. RemoteCallInfoEnumerationHandle *rh;
  296. rh = (RemoteCallInfoEnumerationHandle *)*h;
  297. if (rh == NULL)
  298. RpcRaiseException(ERROR_INVALID_PARAMETER);
  299. if (rh->ThisHandleType != rehtCallInfo)
  300. return ERROR_INVALID_HANDLE;
  301. DbgCallEnumHandle_rundown(*h);
  302. *h = NULL;
  303. return RPC_S_OK;
  304. }
  305. void __RPC_USER DbgCallEnumHandle_rundown(DbgCallEnumHandle h)
  306. {
  307. RemoteCallInfoEnumerationHandle *rh;
  308. rh = (RemoteCallInfoEnumerationHandle *)h;
  309. FinishRPCDebugCallInfoEnumeration(&rh->h);
  310. delete rh;
  311. }
  312. ////////////////////////////////////////////////////////////////////
  313. /// Remote endpoint enumeration routines
  314. ////////////////////////////////////////////////////////////////////
  315. typedef struct tagRemoteEndpointInfoEnumerationHandle
  316. {
  317. RemoteEnumerationHandleType ThisHandleType;
  318. EndpointInfoEnumerationHandle h;
  319. } RemoteEndpointInfoEnumerationHandle;
  320. error_status_t RemoteOpenRPCDebugEndpointInfoEnumeration(
  321. /* [in] */ handle_t IDL_handle,
  322. /* [out] */ DbgEndpointEnumHandle __RPC_FAR *h,
  323. /* [in] */ short EndpointSize,
  324. /* [size_is][in] */ unsigned char __RPC_FAR *Endpoint)
  325. {
  326. RemoteEndpointInfoEnumerationHandle *rh;
  327. RPC_STATUS Status;
  328. *h = NULL;
  329. rh = new RemoteEndpointInfoEnumerationHandle;
  330. if (rh == NULL)
  331. return RPC_S_OUT_OF_MEMORY;
  332. rh->ThisHandleType = rehtEndpointInfo;
  333. Status = OpenRPCDebugEndpointInfoEnumeration((EndpointSize > 0) ? (char *)Endpoint : NULL, &rh->h);
  334. if (Status != RPC_S_OK)
  335. {
  336. delete rh;
  337. return Status;
  338. }
  339. *h = rh;
  340. return RPC_S_OK;
  341. }
  342. error_status_t RemoteGetNextRPCDebugEndpointInfo(
  343. /* [in] */ DbgEndpointEnumHandle h,
  344. /* [unique][out][in] */ RemoteDebugEndpointInfo __RPC_FAR *__RPC_FAR *debugInfo,
  345. /* [out] */ DebugCellID __RPC_FAR *CellID,
  346. /* [out] */ DWORD __RPC_FAR *ProcessID)
  347. {
  348. RemoteEndpointInfoEnumerationHandle *rh;
  349. RPC_STATUS Status;
  350. DebugEndpointInfo *NextEndpoint;
  351. if (debugInfo == NULL)
  352. RpcRaiseException(ERROR_INVALID_PARAMETER);
  353. *debugInfo = NULL;
  354. CellID->SectionID = 0;
  355. CellID->CellID = 0;
  356. rh = (RemoteEndpointInfoEnumerationHandle *)h;
  357. if (rh->ThisHandleType != rehtEndpointInfo)
  358. return ERROR_INVALID_HANDLE;
  359. Status = GetNextRPCDebugEndpointInfo(rh->h, &NextEndpoint, CellID, ProcessID);
  360. if (Status == RPC_S_OK)
  361. {
  362. *debugInfo = (RemoteDebugEndpointInfo *) MIDL_user_allocate(sizeof(RemoteDebugEndpointInfo));
  363. if (*debugInfo != NULL)
  364. {
  365. TranslateLocalEndpointInfoToRemoteEndpointInfo(NextEndpoint, *debugInfo);
  366. }
  367. else
  368. Status = RPC_S_OUT_OF_MEMORY;
  369. }
  370. return Status;
  371. }
  372. error_status_t RemoteFinishRPCDebugEndpointInfoEnumeration(
  373. /* [out][in] */ DbgEndpointEnumHandle __RPC_FAR *h)
  374. {
  375. RemoteEndpointInfoEnumerationHandle *rh;
  376. rh = (RemoteEndpointInfoEnumerationHandle *)*h;
  377. if (rh == NULL)
  378. RpcRaiseException(ERROR_INVALID_PARAMETER);
  379. if (rh->ThisHandleType != rehtEndpointInfo)
  380. return ERROR_INVALID_HANDLE;
  381. DbgEndpointEnumHandle_rundown(*h);
  382. *h = NULL;
  383. return RPC_S_OK;
  384. }
  385. void __RPC_USER DbgEndpointEnumHandle_rundown(DbgEndpointEnumHandle h)
  386. {
  387. RemoteEndpointInfoEnumerationHandle *rh;
  388. rh = (RemoteEndpointInfoEnumerationHandle *)h;
  389. FinishRPCDebugEndpointInfoEnumeration(&rh->h);
  390. delete rh;
  391. }
  392. ////////////////////////////////////////////////////////////////////
  393. /// Remote thread enumeration routines
  394. ////////////////////////////////////////////////////////////////////
  395. typedef struct tagRemoteThreadInfoEnumerationHandle
  396. {
  397. RemoteEnumerationHandleType ThisHandleType;
  398. ThreadInfoEnumerationHandle h;
  399. } RemoteThreadInfoEnumerationHandle;
  400. error_status_t RemoteOpenRPCDebugThreadInfoEnumeration(
  401. /* [in] */ handle_t IDL_handle,
  402. /* [out] */ DbgThreadEnumHandle __RPC_FAR *h,
  403. /* [in] */ DWORD ProcessID,
  404. /* [in] */ DWORD ThreadID)
  405. {
  406. RemoteThreadInfoEnumerationHandle *rh;
  407. RPC_STATUS Status;
  408. *h = NULL;
  409. rh = new RemoteThreadInfoEnumerationHandle;
  410. if (rh == NULL)
  411. return RPC_S_OUT_OF_MEMORY;
  412. rh->ThisHandleType = rehtThreadInfo;
  413. Status = OpenRPCDebugThreadInfoEnumeration(ProcessID, ThreadID, &rh->h);
  414. if (Status != RPC_S_OK)
  415. {
  416. delete rh;
  417. return Status;
  418. }
  419. *h = rh;
  420. return RPC_S_OK;
  421. }
  422. error_status_t RemoteGetNextRPCDebugThreadInfo(
  423. /* [in] */ DbgThreadEnumHandle h,
  424. /* [unique][out][in] */ RemoteDebugThreadInfo __RPC_FAR *__RPC_FAR *debugInfo,
  425. /* [out] */ DebugCellID __RPC_FAR *CellID,
  426. /* [out] */ DWORD __RPC_FAR *ProcessID)
  427. {
  428. RemoteThreadInfoEnumerationHandle *rh;
  429. RPC_STATUS Status;
  430. DebugThreadInfo *NextThread;
  431. if (debugInfo == NULL)
  432. RpcRaiseException(ERROR_INVALID_PARAMETER);
  433. *debugInfo = NULL;
  434. CellID->SectionID = 0;
  435. CellID->CellID = 0;
  436. rh = (RemoteThreadInfoEnumerationHandle *)h;
  437. if (rh->ThisHandleType != rehtThreadInfo)
  438. return ERROR_INVALID_HANDLE;
  439. Status = GetNextRPCDebugThreadInfo(rh->h, &NextThread, CellID, ProcessID);
  440. if (Status == RPC_S_OK)
  441. {
  442. *debugInfo = (RemoteDebugThreadInfo *) MIDL_user_allocate(sizeof(RemoteDebugThreadInfo));
  443. if (*debugInfo != NULL)
  444. {
  445. TranslateLocalThreadInfoToRemoteThreadInfo(NextThread, *debugInfo);
  446. }
  447. else
  448. Status = RPC_S_OUT_OF_MEMORY;
  449. }
  450. return Status;
  451. }
  452. error_status_t RemoteFinishRPCDebugThreadInfoEnumeration(
  453. /* [out][in] */ DbgThreadEnumHandle __RPC_FAR *h)
  454. {
  455. RemoteThreadInfoEnumerationHandle *rh;
  456. rh = (RemoteThreadInfoEnumerationHandle *)*h;
  457. if (rh == NULL)
  458. RpcRaiseException(ERROR_INVALID_PARAMETER);
  459. if (rh->ThisHandleType != rehtThreadInfo)
  460. return ERROR_INVALID_HANDLE;
  461. DbgThreadEnumHandle_rundown(*h);
  462. *h = NULL;
  463. return RPC_S_OK;
  464. }
  465. void __RPC_USER DbgThreadEnumHandle_rundown(DbgThreadEnumHandle h)
  466. {
  467. RemoteThreadInfoEnumerationHandle *rh;
  468. rh = (RemoteThreadInfoEnumerationHandle *)h;
  469. FinishRPCDebugThreadInfoEnumeration(&rh->h);
  470. delete rh;
  471. }
  472. ////////////////////////////////////////////////////////////////////
  473. /// Remote client call enumeration routines
  474. ////////////////////////////////////////////////////////////////////
  475. typedef struct tagRemoteClientCallInfoEnumerationHandle
  476. {
  477. RemoteEnumerationHandleType ThisHandleType;
  478. ClientCallInfoEnumerationHandle h;
  479. } RemoteClientCallInfoEnumerationHandle;
  480. error_status_t RemoteOpenRPCDebugClientCallInfoEnumeration(
  481. /* [in] */ handle_t IDL_handle,
  482. /* [out] */ DbgClientCallEnumHandle __RPC_FAR *h,
  483. /* [in] */ DWORD CallID,
  484. /* [in] */ DWORD IfStart,
  485. /* [in] */ int ProcNum,
  486. /* [in] */ DWORD ProcessID)
  487. {
  488. RemoteClientCallInfoEnumerationHandle *rh;
  489. RPC_STATUS Status;
  490. *h = NULL;
  491. rh = new RemoteClientCallInfoEnumerationHandle;
  492. if (rh == NULL)
  493. return RPC_S_OUT_OF_MEMORY;
  494. rh->ThisHandleType = rehtClientCallInfo;
  495. Status = OpenRPCDebugClientCallInfoEnumeration(CallID, IfStart, ProcNum, ProcessID, &rh->h);
  496. if (Status != RPC_S_OK)
  497. {
  498. delete rh;
  499. return Status;
  500. }
  501. *h = rh;
  502. return RPC_S_OK;
  503. }
  504. error_status_t RemoteGetNextRPCDebugClientCallInfo(
  505. /* [in] */ DbgClientCallEnumHandle h,
  506. /* [unique][out][in] */ RemoteDebugClientCallInfo __RPC_FAR *__RPC_FAR *debugInfo,
  507. /* [unique][out][in] */ RemoteDebugCallTargetInfo __RPC_FAR *__RPC_FAR *CallTargetDebugInfo,
  508. /* [out] */ DebugCellID __RPC_FAR *CellID,
  509. /* [out] */ DWORD __RPC_FAR *ProcessID)
  510. {
  511. RemoteClientCallInfoEnumerationHandle *rh;
  512. RPC_STATUS Status;
  513. DebugClientCallInfo *NextClientCall;
  514. DebugCallTargetInfo *NextCallTarget;
  515. if (debugInfo == NULL)
  516. RpcRaiseException(ERROR_INVALID_PARAMETER);
  517. if (CallTargetDebugInfo == NULL)
  518. RpcRaiseException(ERROR_INVALID_PARAMETER);
  519. *debugInfo = NULL;
  520. *CallTargetDebugInfo = NULL;
  521. CellID->SectionID = 0;
  522. CellID->CellID = 0;
  523. rh = (RemoteClientCallInfoEnumerationHandle *)h;
  524. if (rh->ThisHandleType != rehtClientCallInfo)
  525. return ERROR_INVALID_HANDLE;
  526. Status = GetNextRPCDebugClientCallInfo(rh->h, &NextClientCall, &NextCallTarget,
  527. CellID, ProcessID);
  528. if (Status == RPC_S_OK)
  529. {
  530. *debugInfo = (RemoteDebugClientCallInfo *) MIDL_user_allocate(sizeof(RemoteDebugClientCallInfo));
  531. if (*debugInfo != NULL)
  532. {
  533. TranslateLocalClientCallInfoToRemoteClientCallInfo(NextClientCall, *debugInfo);
  534. *CallTargetDebugInfo
  535. = (RemoteDebugCallTargetInfo *)MIDL_user_allocate(sizeof(RemoteDebugCallTargetInfo));
  536. if (*CallTargetDebugInfo != NULL)
  537. {
  538. if ((NextCallTarget != NULL) && (NextCallTarget->Type != dctCallTargetInfo))
  539. {
  540. // inconsistent info - return NULL for call target
  541. MIDL_user_free(*CallTargetDebugInfo);
  542. *CallTargetDebugInfo = NULL;
  543. NextCallTarget = NULL;
  544. }
  545. else
  546. {
  547. TranslateLocalCallTargetInfoToRemoteCallTargetInfo(NextCallTarget, *CallTargetDebugInfo);
  548. }
  549. }
  550. // else - don't care - this is a best effort. We will return what we
  551. // can. Client is prepared to handle NULL in the call target
  552. }
  553. else
  554. Status = RPC_S_OUT_OF_MEMORY;
  555. }
  556. return Status;
  557. }
  558. error_status_t RemoteFinishRPCDebugClientCallInfoEnumeration(
  559. /* [out][in] */ DbgClientCallEnumHandle __RPC_FAR *h)
  560. {
  561. RemoteClientCallInfoEnumerationHandle *rh;
  562. rh = (RemoteClientCallInfoEnumerationHandle *)*h;
  563. if (rh == NULL)
  564. RpcRaiseException(ERROR_INVALID_PARAMETER);
  565. if (rh->ThisHandleType != rehtClientCallInfo)
  566. return ERROR_INVALID_HANDLE;
  567. DbgClientCallEnumHandle_rundown(*h);
  568. *h = NULL;
  569. return RPC_S_OK;
  570. }
  571. void __RPC_USER DbgClientCallEnumHandle_rundown(DbgClientCallEnumHandle h)
  572. {
  573. RemoteClientCallInfoEnumerationHandle *rh;
  574. rh = (RemoteClientCallInfoEnumerationHandle *)h;
  575. FinishRPCDebugClientCallInfoEnumeration(&rh->h);
  576. delete rh;
  577. }
  578. END_C_EXTERN