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.

536 lines
17 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 2001
  3. Module Name:
  4. NtTrans.cxx
  5. Abstract:
  6. NTSD/KD extensions for debugging Windows NT transport interface
  7. data structures.
  8. Author:
  9. Mario Goertzel [MarioGo]
  10. Revision History:
  11. MarioGo 3/21/1997 Bits 'n pieces
  12. GrigoriK Mar 2001 Added support for type info.
  13. --*/
  14. #undef _RPCRT4_
  15. #define KDEXT_64BIT
  16. #define private public
  17. #include "..\trans\Common\precomp.hxx"
  18. #include "..\mtrt\precomp.hxx"
  19. #include <stddef.h>
  20. #include <wdbgexts.h>
  21. #include <rpcexts.hxx>
  22. VOID do_trans(ULONG64);
  23. VOID do_protocols(ULONG64);
  24. VOID do_overlap(ULONG64);
  25. VOID do_addrvect(ULONG64);
  26. MY_DECLARE_API(trans);
  27. MY_DECLARE_API(overlap);
  28. MY_DECLARE_API(addrvect);
  29. const char *Protocols[] =
  30. {
  31. "INVALID",
  32. "TCP/IP",
  33. #ifdef SPX_ON
  34. "SPX",
  35. #else
  36. "Invalid",
  37. #endif
  38. "Named pipes",
  39. #ifdef NETBIOS_ON
  40. "NetBEUI",
  41. "Netbios(TCP)",
  42. "Netbios(IPX)",
  43. #else
  44. "Invalid",
  45. "Invalid",
  46. "Invalid",
  47. #endif
  48. #ifdef APPLETALK_ON
  49. "Appletalk DSP",
  50. #else
  51. "Invalid",
  52. #endif
  53. "Invalid", // former "Vines SPP",
  54. "HTTP",
  55. "UDP/IP",
  56. #ifdef IPX_ON
  57. "IPX",
  58. #else
  59. "Invalid",
  60. #endif
  61. "CDP",
  62. #ifdef NCADG_MQ_ON
  63. "MSMQ",
  64. #else
  65. "Invalid",
  66. #endif
  67. "TCP/IPv6"
  68. };
  69. const INT cProtocols = sizeof(Protocols)/sizeof(char *);
  70. VOID
  71. do_trans(
  72. ULONG64 qwAddr
  73. )
  74. {
  75. char const *pszProtocol;
  76. ULONG64 tmp1;
  77. ULONG tmp2;
  78. DWORD protocol;
  79. ULONG64 id;
  80. ULONG64 type;
  81. GET_MEMBER(qwAddr, BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, id, id);
  82. GET_MEMBER(qwAddr, BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, type, type);
  83. // Display protocol
  84. if ((ULONG)id <= 0 ||
  85. (ULONG)id >= cProtocols)
  86. {
  87. dprintf("Invalid protocol ID %d\n", id);
  88. return;
  89. }
  90. protocol = (ULONG)id;
  91. pszProtocol = Protocols[protocol];
  92. dprintf("Object (0x%p), protocol\t - %s\n", qwAddr, pszProtocol);
  93. switch(type & PROTO_MASK)
  94. {
  95. case CONNECTION:
  96. {
  97. if ((type & TYPE_MASK) == CLIENT)
  98. {
  99. dprintf("Client-side connection\t\t - (%p)\n", type);
  100. }
  101. else if (type & SERVER)
  102. {
  103. dprintf("Server-side connection\t\t - (%p)\n", type);
  104. }
  105. else
  106. {
  107. dprintf("Unknown type %d\n", type);
  108. break;
  109. }
  110. PRINT_ADDRESS_OF(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, Conn, tmp2);
  111. PRINT_MEMBER_BOOLEAN(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, fAborted, tmp1);
  112. PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, StartingReadIo, tmp1);
  113. PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, StartingWriteIo, tmp1);
  114. PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, iPostSize, tmp1);
  115. ULONG64 Read;
  116. GET_ADDRESS_OF(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, Read, Read, tmp2);
  117. do_overlap(Read);
  118. PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, pReadBuffer, tmp1);
  119. PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, maxReadBuffer, tmp1);
  120. PRINT_MEMBER(qwAddr, BASE_CONNECTION, RPCRT4!BASE_CONNECTION, iLastRead, tmp1);
  121. ULONG64 pAddress;
  122. if (protocol == NMP)
  123. {
  124. GET_MEMBER(qwAddr, NMP_CONNECTION, RPCRT4!NMP_CONNECTION, pAddress, pAddress);
  125. dprintf("Associated address\t\t - 0x%I64x\n", pAddress);
  126. }
  127. else if (protocol == TCP)
  128. {
  129. GET_MEMBER(qwAddr, WS_CONNECTION, RPCRT4!WS_CONNECTION, pAddress, pAddress);
  130. dprintf("Associated address\t\t - 0x%I64x\n", pAddress);
  131. }
  132. else
  133. {
  134. GET_MEMBER(qwAddr, WS_CONNECTION, RPCRT4!WS_CONNECTION, saClientAddress, pAddress);
  135. dprintf("Winsock sockaddr (server)\t - 0x%I64x\n", pAddress);
  136. #ifdef NETBIOS_ON
  137. if ( protocol == NBF
  138. || protocol == NBT
  139. || protocol == NBI)
  140. {
  141. ULONG64 SequenceNumber;
  142. GET_MEMBER(qwAddr, NB_CONNECTION, RPCRT4!NB_CONNECTION, SequenceNumber, SequenceNumber);
  143. // Netbios based connection has more state
  144. dprintf("Netbios sequence number\t\t - %d\n", (ULONG)SequenceNumber);
  145. }
  146. else
  147. #endif
  148. if ((type & TYPE_MASK) == CLIENT)
  149. {
  150. // Client-side non-netbios connections have more state
  151. PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, fCallStarted, tmp1);
  152. PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, fShutdownReceived, tmp1);
  153. PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, fReceivePending, tmp1);
  154. PRINT_MEMBER(qwAddr, WS_CLIENT_CONNECTION, RPCRT4!WS_CLIENT_CONNECTION, dwLastCallTime, tmp1);
  155. }
  156. }
  157. break;
  158. }
  159. case ADDRESS:
  160. case DATAGRAM|ADDRESS:
  161. {
  162. dprintf("Address type\t\t\t - (%p)", type);
  163. if (type & ~(PROTO_MASK | TYPE_MASK | IO_MASK))
  164. {
  165. dprintf(" unknown bits 0x%lx\n", type & ~(PROTO_MASK | TYPE_MASK | IO_MASK));
  166. }
  167. else
  168. {
  169. if (type & DATAGRAM)
  170. dprintf(" d/g");
  171. else
  172. dprintf(" c/o");
  173. if (type & SERVER)
  174. dprintf(" server");
  175. else
  176. dprintf(" client or bit not set");
  177. dprintf("\n");
  178. }
  179. ULONG64 Endpoint;
  180. GET_MEMBER(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, Endpoint, Endpoint);
  181. if (Endpoint)
  182. {
  183. dprintf("Endpoint\t\t\t - %ws\n", ReadProcessRpcChar(Endpoint));
  184. }
  185. else
  186. {
  187. dprintf("Endpoint\t\t\t - (null)\n");
  188. }
  189. ULONG64 pAddressVector;
  190. GET_MEMBER(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, pAddressVector, pAddressVector);
  191. if (pAddressVector)
  192. {
  193. do_addrvect(pAddressVector);
  194. }
  195. else
  196. {
  197. dprintf("No address vector\n");
  198. }
  199. ULONG64 SubmitListen;
  200. GET_MEMBER(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, SubmitListen, SubmitListen);
  201. dprintf("SubmitListen (pfn)\t\t - 0x%I64x %s\n", SubmitListen,
  202. MapSymbol(SubmitListen));
  203. PRINT_MEMBER_WITH_LABEL(qwAddr, BASE_ADDRESS, RPCRT4!BASE_ADDRESS, pNext, "Next\t\t\t\t", tmp1);
  204. if (
  205. #ifdef IPX_ON
  206. protocol != IPX &&
  207. #endif
  208. protocol != UDP &&
  209. protocol != CDP)
  210. {
  211. GET_OFFSET_OF(CO_ADDRESS, RPCRT4!CO_ADDRESS, Listen, &tmp2);
  212. do_overlap(qwAddr+tmp2);
  213. ULONG64 NewConnection;
  214. GET_MEMBER(qwAddr, CO_ADDRESS, RPCRT4!CO_ADDRESS, NewConnection, NewConnection);
  215. dprintf("NewConnection (pfn)\t\t - 0x%I64x %s\n", NewConnection, MapSymbol(NewConnection));
  216. }
  217. #ifdef NETBIOS_ON
  218. BOOL fNetbios = FALSE;
  219. #endif
  220. switch(protocol)
  221. {
  222. #ifdef NETBIOS_ON
  223. case NBI:
  224. case NBT:
  225. case NBF:
  226. fNetbios = TRUE;
  227. // Fall into winsock case
  228. #endif
  229. case TCP:
  230. #ifdef SPX_ON
  231. case SPX:
  232. #endif
  233. #ifdef APPLETALK_ON
  234. case DSP:
  235. #endif
  236. {
  237. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, pFirstAddress, "Real address\t\t\t", tmp1);
  238. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, pNextAddress, "Next address\t\t\t", tmp1);
  239. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, ListenSocket, "Listen socket\t\t\t", tmp1);
  240. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, ConnectionSocket, "Connect socket\t\t\t", tmp1);
  241. #ifdef NETBIOS_ON
  242. ULONG64 dwProtocolMultiplier;
  243. GET_MEMBER(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, dwProtocolMultiplier, dwProtocolMultiplier);
  244. if (dwProtocolMultiplier != 1
  245. && !fNetbios)
  246. {
  247. dprintf("Invalid protocol multipler (%d) for winsock address\n", (ULONG)dwProtocolMultiplier);
  248. }
  249. else
  250. {
  251. dprintf("Multipler\t\t\t - %d\n", (ULONG)dwProtocolMultiplier);
  252. }
  253. #endif
  254. PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, WS_ADDRESS, RPCRT4!WS_ADDRESS, AcceptBuffer, "AcceptBuffer\t\t\t", tmp2);
  255. break;
  256. }
  257. case NMP:
  258. {
  259. PRINT_MEMBER_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, hConnectPipe, "Connect pipe\t\t\t", tmp1);
  260. PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, sparePipes, "Spare pipes\t\t\t", tmp2);
  261. PRINT_MEMBER_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, SecurityDescriptor, "Security descriptor\t\t", tmp1);
  262. PRINT_MEMBER_WITH_LABEL(qwAddr, NMP_ADDRESS, RPCRT4!NMP_ADDRESS, LocalEndpoint, "Local Endpoint\t\t\t", tmp1);
  263. break;
  264. }
  265. case UDP:
  266. #ifdef IPX_ON
  267. case IPX:
  268. #endif
  269. case CDP:
  270. {
  271. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, Socket, "The socket\t\t\t", tmp1);
  272. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, cPendingIos, "Pending recvs\t\t\t", tmp1);
  273. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, cMinimumIos, "Min recvs\t\t\t", tmp1);
  274. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, cMaximumIos, "Max recvs\t\t\t", tmp1);
  275. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM_ENDPOINT, RPCRT4!WS_DATAGRAM_ENDPOINT, aDatagrams, "Array of datagrams\t\t", tmp1);
  276. }
  277. default:
  278. {
  279. dprintf("ERROR: Invalid/unknown protocol\n");
  280. }
  281. }
  282. break;
  283. }
  284. case DATAGRAM:
  285. {
  286. dprintf("Datagram\t\t\t - (%p)\n", type);
  287. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, pEndpoint, "Pointer to owning address\t", tmp1);
  288. PRINT_MEMBER_BOOLEAN_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, Busy, "Busy\t\t\t\t", tmp1);
  289. PRINT_MEMBER_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, AddressPair, "AddrPair\t\t\t", tmp1);
  290. PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, WS_DATAGRAM, RPCRT4!WS_DATAGRAM, Packet, "Packet", tmp2);
  291. GET_OFFSET_OF(WS_DATAGRAM, RPCRT4!WS_DATAGRAM, Read, &tmp2)
  292. do_overlap(qwAddr + tmp2);
  293. break;
  294. }
  295. default:
  296. dprintf("Unknown type %d\n", type);
  297. break;
  298. }
  299. dprintf("\n");
  300. return;
  301. }
  302. char *strtok(char *String);
  303. DECLARE_API( protocols )
  304. {
  305. ULONG64 qwAddr;
  306. BOOL fArgNotSpecified = FALSE;
  307. ULONG64 ProtocolArrayAddress;
  308. LPSTR lpArgumentString = (LPSTR)args;
  309. if (0 == strtok(lpArgumentString))
  310. {
  311. lpArgumentString = "rpcrt4!TransportProtocolArray";
  312. fArgNotSpecified = TRUE;
  313. }
  314. qwAddr = GetExpression(lpArgumentString);
  315. if ( !qwAddr )
  316. {
  317. dprintf("Error: can't evaluate '%s'\n", lpArgumentString);
  318. return;
  319. }
  320. if (fArgNotSpecified)
  321. {
  322. if (!ReadPointer(qwAddr, &ProtocolArrayAddress))
  323. {
  324. dprintf("couldn't read memory at address %I64x\n", qwAddr);
  325. return;
  326. }
  327. }
  328. else
  329. ProtocolArrayAddress = qwAddr;
  330. do_protocols(ProtocolArrayAddress);
  331. }
  332. const char *ProtocolStateNames[] = {"ProtocolNotLoaded", "ProtocolLoadedWithoutAddress" ,
  333. "ProtocolWasLoadedOrNeedsAct.", "ProtocolLoaded",
  334. "ProtocolWasLoadedOrNAWithoutAddr",
  335. "ProtocolLoadedAndMonitored"};
  336. VOID
  337. do_protocols(
  338. ULONG64 qwAddr
  339. )
  340. {
  341. ULONG64 pTransportProtocol;
  342. const char *pProtStateName;
  343. ULONG64 ListHead;
  344. ULONG64 ObjectEntry;
  345. ULONG64 pCurrentObject;
  346. int i;
  347. BOOL fFirstObject;
  348. BOOL b;
  349. ULONG64 tmp1;
  350. ULONG tmp2;
  351. dprintf(" Protocol State AddrChngSock AddrChngOl\n");
  352. dprintf("-----------------------------------------------------------------------\n");
  353. pTransportProtocol = qwAddr;
  354. for (i = 1; i < MAX_PROTOCOLS; i++)
  355. {
  356. fFirstObject = TRUE;
  357. ULONG64 State;
  358. ULONG64 addressChangeSocket;
  359. ULONG64 addressChangeOverlapped;
  360. GET_MEMBER(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, State, State);
  361. GET_ADDRESS_OF(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, addressChangeSocket, addressChangeSocket, tmp2);
  362. GET_ADDRESS_OF(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, addressChangeOverlapped, addressChangeOverlapped, tmp2);
  363. if ((ULONG)State >= sizeof(ProtocolStateNames)/sizeof(ProtocolStateNames[0]))
  364. pProtStateName = "INVALID";
  365. else
  366. pProtStateName = ProtocolStateNames[(ULONG)State];
  367. dprintf("%13s%31s%15I64x%12I64x\n", Protocols[i], pProtStateName,
  368. addressChangeSocket, addressChangeOverlapped);
  369. GET_OFFSET_OF(TransportProtocol, RPCRT4!TransportProtocol, ObjectList, &tmp2);
  370. ListHead = pTransportProtocol;
  371. ListHead += tmp2;
  372. ULONG64 ObjectList;
  373. GET_ADDRESS_OF(pTransportProtocol, TransportProtocol, RPCRT4!TransportProtocol, ObjectList, ObjectList, tmp2);
  374. ULONG64 Flink;
  375. GET_MEMBER(ObjectList, _LIST_ENTRY, RPCRT4!_LIST_ENTRY, Flink, Flink);
  376. ObjectEntry = Flink;
  377. while (ObjectEntry != ListHead)
  378. {
  379. GET_OFFSET_OF(BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, ObjectList, &tmp2);
  380. pCurrentObject = ObjectEntry;
  381. pCurrentObject -= tmp2;
  382. if (fFirstObject)
  383. {
  384. dprintf("Object List:\n");
  385. fFirstObject = FALSE;
  386. }
  387. dprintf("%8lX\n", pCurrentObject);
  388. // move to the next element in the list
  389. GET_ADDRESS_OF(pCurrentObject, BASE_ASYNC_OBJECT, RPCRT4!BASE_ASYNC_OBJECT, ObjectList, ObjectList, tmp2);
  390. GET_MEMBER(ObjectList, _LIST_ENTRY, RPCRT4!_LIST_ENTRY, Flink, Flink);
  391. }
  392. pTransportProtocol += GET_TYPE_SIZE(TransportProtocol, RPCRT4!TransportProtocol);
  393. }
  394. }
  395. VOID
  396. do_overlap(
  397. ULONG64 qwAddr
  398. )
  399. {
  400. ULONG64 tmp1;
  401. ULONG tmp2;
  402. PRINT_ADDRESS_OF_WITH_LABEL(qwAddr, BASE_OVERLAPPED, RPCRT4!BASE_OVERLAPPED, pAsyncObject, "Overlapped\t\t\t", tmp2);
  403. ULONG64 ol;
  404. GET_ADDRESS_OF(qwAddr, BASE_OVERLAPPED, RPCRT4!BASE_OVERLAPPED, ol, ol, tmp2);
  405. PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, Pointer, "Overlapped, containing object\t", tmp1);
  406. PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, Internal, "ol.Internal (status)\t\t", tmp1);
  407. PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, InternalHigh, "ol.InternalHigh\t\t\t", tmp1);
  408. PRINT_MEMBER_WITH_LABEL(ol, _OVERLAPPED, RPCRT4!_OVERLAPPED, hEvent, "ol.hEvent\t\t\t", tmp1);
  409. return;
  410. }
  411. VOID
  412. do_addrvect(
  413. ULONG64 qwAddr
  414. )
  415. {
  416. DWORD count;
  417. BOOL b;
  418. ULONG64 p;
  419. GetData(qwAddr, &count, sizeof(count));
  420. dprintf("Address vector entries\t\t - %d\n", count);
  421. for (unsigned i = 0; i < count; i++)
  422. {
  423. ULONG64 tmp;
  424. tmp = qwAddr + (i + 1) * AddressSize;
  425. ReadPointer(tmp, &p);
  426. dprintf("NetworkAddress[%d]\t\t - (0x%I64x) %ws\n",
  427. i,
  428. p,
  429. ReadProcessRpcChar(p));
  430. }
  431. }