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.

978 lines
26 KiB

  1. #define SRVDBG 1
  2. #define SRVKD 1
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <ntverp.h>
  7. #include <windows.h>
  8. #include <ntosp.h>
  9. #include <wdbgexts.h>
  10. #define NT
  11. #include <tdi.h>
  12. #include <tdikrnl.h>
  13. #include <tdistat.h>
  14. #include <tdiinfo.h>
  15. #include <irda.h>
  16. #include <irlmp.h>
  17. #include <irlmpp.h>
  18. #include <irdap.h>
  19. #include <dbgmsg.h>
  20. #include <irioctl.h>
  21. #include <irlap.h>
  22. #include <irlapp.h>
  23. /*
  24. #define DBG_NDIS 0x00000002 // keep in sync with test\irdakdx
  25. #define DBG_TIMER 0x00000004
  26. #define DBG_IRMAC 0x00000008
  27. #define DBG_IRLAP 0x00000010
  28. #define DBG_IRLAPLOG 0x00000020
  29. #define DBG_RXFRAME 0x00000040
  30. #define DBG_TXFRAME 0x00000080
  31. #define DBG_IRLMP 0x00000100
  32. #define DBG_IRLMP_CONN 0x00000200
  33. #define DBG_IRLMP_CRED 0x00000400
  34. #define DBG_IRLMP_IAS 0x00000800
  35. #define DBG_DISCOVERY 0x00001000
  36. #define DBG_PRINT 0x00002000
  37. #define DBG_ADDR 0x00004000
  38. #define DBG_REF 0x00010000
  39. #define DBG_TDI 0x00020000
  40. #define DBG_TDI_IRP 0x00040000
  41. #define DBG_ALLOC 0x10000000
  42. #define DBG_FUNCTION 0x20000000
  43. #define DBG_WARN 0x40000000
  44. #define DBG_ERROR 0x80000000
  45. */
  46. WINDBG_EXTENSION_APIS ExtensionApis;
  47. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 };
  48. #define ERRPRT dprintf
  49. #define NL 1
  50. #define NONL 0
  51. USHORT SavedMajorVersion;
  52. USHORT SavedMinorVersion;
  53. BOOL ChkTarget; // is debuggee a CHK build?
  54. typedef struct
  55. {
  56. char Name[16];
  57. int Val;
  58. } DBG_LEVEL;
  59. DBG_LEVEL DbgLevel[] = {
  60. {"RXFRAME", DBG_RXFRAME },
  61. {"TXFRAME", DBG_TXFRAME },
  62. {"NDIS", DBG_NDIS },
  63. {"IRMAC", DBG_IRMAC },
  64. {"IRLAP", DBG_IRLAP },
  65. {"IRLAPLOG", DBG_IRLAPLOG },
  66. {"IRLMP", DBG_IRLMP },
  67. {"IRLMP_CONN", DBG_IRLMP_CONN },
  68. {"IRLMP_CRED", DBG_IRLMP_CRED },
  69. {"IRLMP_IAS", DBG_IRLMP_IAS },
  70. {"DISCOVERY", DBG_DISCOVERY },
  71. {"TDI", DBG_TDI },
  72. {"TDI_IRP", DBG_TDI_IRP },
  73. {"ALLOC", DBG_ALLOC },
  74. {"TIMER ", DBG_TIMER },
  75. {"PRINT", DBG_PRINT },
  76. {"ADDRESS", DBG_ADDR },
  77. {"REFERENCE", DBG_REF },
  78. {"FUNCTION", DBG_FUNCTION },
  79. {"WARN", DBG_WARN },
  80. {"ERROR", DBG_ERROR }};
  81. char *IrlmpState[] =
  82. {"LINK_DOWN",
  83. "LINK_DISCONNECTED",
  84. "LINK_DISCONNECTING",
  85. "LINK_IN_DISCOVERY",
  86. "LINK_CONNECTING",
  87. "LINK_READY"};
  88. char *LsapState[] =
  89. {"LSAP_CREATED",
  90. "LSAP_DISCONNECTED",
  91. "LSAP_IRLAP_CONN_PEND",
  92. "LSAP_LMCONN_CONF_PEND",
  93. "LSAP_CONN_RESP_PEND",
  94. "LSAP_CONN_REQ_PEND",
  95. "LSAP_EXCLUSIVEMODE_PEND",
  96. "LSAP_MULTIPLEXEDMODE_PEND",
  97. "LSAP_READY",
  98. "LSAP_NO_TX_CREDIT"};
  99. char *ConnObjState[] =
  100. {"IRDA_CONN_CREATED",
  101. "IRDA_CONN_CLOSING",
  102. "IRDA_CONN_OPENING",
  103. "IRDA_CONN_OPEN"};
  104. char *IrlapState[] =
  105. { "NDM",
  106. "DSCV_MEDIA_SENSE",
  107. "DSCV_QUERY",
  108. "DSCV_REPLY",
  109. "CONN_MEDIA_SENSE",
  110. "SNRM_SENT",
  111. "BACKOFF_WAIT",
  112. "SNRM_RECEIVED",
  113. "P_XMIT",
  114. "P_RECV",
  115. "P_DISCONNECT_PEND",
  116. "P_CLOSE",
  117. "S_NRM",
  118. "S_DISCONNECT_PEND",
  119. "S_ERROR",
  120. "S_CLOSE"};
  121. /*
  122. * Print out an optional message, an ANSI_STRING, and maybe a new-line
  123. */
  124. BOOL
  125. PrintStringA( IN LPSTR msg OPTIONAL, IN PANSI_STRING pStr, IN BOOL nl )
  126. {
  127. PCHAR StringData;
  128. ULONG BytesRead;
  129. if( msg )
  130. dprintf( msg );
  131. if( pStr->Length == 0 ) {
  132. if( nl )
  133. dprintf( "\n" );
  134. return TRUE;
  135. }
  136. StringData = (PCHAR)LocalAlloc( LPTR, pStr->Length + 1 );
  137. if( StringData == NULL ) {
  138. ERRPRT( "Out of memory!\n" );
  139. return FALSE;
  140. }
  141. ReadMemory((ULONG_PTR) pStr->Buffer,
  142. StringData,
  143. pStr->Length,
  144. &BytesRead );
  145. if ( BytesRead ) {
  146. StringData[ pStr->Length ] = '\0';
  147. dprintf("%s%s", StringData, nl ? "\n" : "" );
  148. }
  149. LocalFree((HLOCAL)StringData);
  150. return BytesRead;
  151. }
  152. /*
  153. * Get 'size' bytes from the debuggee program at 'dwAddress' and place it
  154. * in our address space at 'ptr'. Use 'type' in an error printout if necessary
  155. */
  156. BOOL
  157. GetData( IN LPVOID ptr, IN DWORD_PTR dwAddress, IN ULONG size, IN PCSTR type )
  158. {
  159. BOOL b;
  160. ULONG BytesRead;
  161. ULONG count = size;
  162. while( size > 0 ) {
  163. if (count >= 3000)
  164. count = 3000;
  165. b = ReadMemory((ULONG) dwAddress, ptr, count, &BytesRead );
  166. if (!b || BytesRead != count ) {
  167. ERRPRT( "Unable to read %u bytes at %X, for %s\n", size, dwAddress, type );
  168. return FALSE;
  169. }
  170. dwAddress += count;
  171. size -= count;
  172. ptr = (LPVOID)((ULONG_PTR)ptr + count);
  173. }
  174. return TRUE;
  175. }
  176. /*
  177. * Follow a LIST_ENTRY list beginning with a head at dwListHeadAddr in the debugee's
  178. * address space. For each element in the list, print out the pointer value at 'offset'
  179. */
  180. BOOL
  181. PrintListEntryList( IN DWORD dwListHeadAddr, IN LONG offset )
  182. {
  183. LIST_ENTRY ListEntry;
  184. ULONG i=0;
  185. BOOL retval = TRUE;
  186. ULONG count = 20;
  187. if( !GetData( &ListEntry, dwListHeadAddr, sizeof( ListEntry ), "LIST_ENTRY" ) )
  188. return FALSE;
  189. while( count-- ) {
  190. if( (DWORD_PTR)ListEntry.Flink == dwListHeadAddr || (DWORD_PTR)ListEntry.Flink == 0 )
  191. break;
  192. if( !GetData( &ListEntry, (DWORD_PTR)ListEntry.Flink, (ULONG)sizeof( ListEntry ), "ListEntry" ) ) {
  193. retval = FALSE;
  194. break;
  195. }
  196. dprintf( "%16X%s", (DWORD_PTR)ListEntry.Flink + offset, (i && !(i&3)) ? "\n" : "" );
  197. i++;
  198. }
  199. if( count == 0 && (DWORD_PTR)ListEntry.Flink != dwListHeadAddr && ListEntry.Flink ) {
  200. dprintf( "\nTruncated list dump\n" );
  201. } else if( ! ( i && !(i&3) ) ) {
  202. dprintf( "\n" );
  203. }
  204. return retval;
  205. }
  206. /*
  207. * Print out a single HEX character
  208. */
  209. VOID
  210. PrintHexChar( IN UCHAR c )
  211. {
  212. dprintf( "%c%c", "0123456789abcdef"[ (c>>4)&0xf ], "0123456789abcdef"[ c&0xf ] );
  213. }
  214. /*
  215. * Print out 'buf' of 'cbuf' bytes as HEX characters
  216. */
  217. VOID
  218. PrintHexBuf( IN PUCHAR buf, IN ULONG cbuf )
  219. {
  220. while( cbuf-- ) {
  221. PrintHexChar( *buf++ );
  222. dprintf( " " );
  223. }
  224. }
  225. /*
  226. * Fetch the null terminated UNICODE string at dwAddress into buf
  227. */
  228. BOOL
  229. GetString( IN DWORD_PTR dwAddress, IN LPSTR buf, IN ULONG MaxChars )
  230. {
  231. do {
  232. if( !GetData( buf, dwAddress, sizeof( *buf ), "Character" ) )
  233. return FALSE;
  234. dwAddress += sizeof( *buf );
  235. } while( --MaxChars && *buf++ != '\0' );
  236. return TRUE;
  237. }
  238. char *mystrtok ( char *string, char * control )
  239. {
  240. static unsigned char *str;
  241. char *p, *s;
  242. if( string )
  243. str = string;
  244. if( str == NULL || *str == '\0' )
  245. return NULL;
  246. //
  247. // Skip leading delimiters...
  248. //
  249. for( ; *str; str++ ) {
  250. for( s=control; *s; s++ ) {
  251. if( *str == *s )
  252. break;
  253. }
  254. if( *s == '\0' )
  255. break;
  256. }
  257. //
  258. // Was it was all delimiters?
  259. //
  260. if( *str == '\0' ) {
  261. str = NULL;
  262. return NULL;
  263. }
  264. //
  265. // We've got a string, terminate it at first delimeter
  266. //
  267. for( p = str+1; *p; p++ ) {
  268. for( s = control; *s; s++ ) {
  269. if( *p == *s ) {
  270. s = str;
  271. *p = '\0';
  272. str = p+1;
  273. return s;
  274. }
  275. }
  276. }
  277. //
  278. // We've got a string that ends with the NULL
  279. //
  280. s = str;
  281. str = NULL;
  282. return s;
  283. }
  284. DECLARE_API( help )
  285. {
  286. int i;
  287. dprintf("IrDA extenstions:\n");
  288. dprintf(" dbgmsgs dump debug message buffer\n");
  289. dprintf(" dbg [Level [Level] ...] toggle debug level\n");
  290. }
  291. DECLARE_API( dbgmsgs )
  292. {
  293. DWORD p;
  294. DWORD Last, First;
  295. char DbgMsg[MAX_MSG_LEN];
  296. ULONG Read;
  297. char *DbgMsgs;
  298. if (!GetData(&Last,
  299. GetExpression("irda!Last"),
  300. sizeof(Last), "DWORD"))
  301. {
  302. dprintf("error\n");
  303. return;
  304. }
  305. if (!GetData(&First,
  306. GetExpression("irda!First"),
  307. sizeof(Last), "DWORD"))
  308. {
  309. dprintf("error\n");
  310. return;
  311. }
  312. DbgMsgs = (char *) GetExpression("irda!dbgmsgs");
  313. dprintf("\n\n");
  314. while (First != Last)
  315. {
  316. if (!GetString((DWORD_PTR) (DbgMsgs + First * MAX_MSG_LEN),
  317. DbgMsg, MAX_MSG_LEN))
  318. break;
  319. /*
  320. ReadMemory((ULONG) (DbgMsgs + First * MAX_MSG_LEN),
  321. DbgMsg, MAX_MSG_LEN, &Read); */
  322. dprintf("%s", DbgMsg);
  323. First++;
  324. if (First == DBG_MSG_CNT)
  325. First = 0;
  326. }
  327. }
  328. DECLARE_API( dbg )
  329. {
  330. int i;
  331. int col = 0;
  332. DWORD DbgSettings;
  333. char argbuf[ MAX_PATH ];
  334. char *p;
  335. DWORD_PTR dwAddress;
  336. DWORD Written;
  337. dwAddress = GetExpression("irda!dbgsettings");
  338. if (!GetData(&DbgSettings,
  339. dwAddress,
  340. sizeof(DbgSettings), "DWORD"))
  341. {
  342. dprintf("error\n");
  343. return;
  344. }
  345. if (!args || !*args)
  346. {
  347. dprintf("Current settings:\n");
  348. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  349. {
  350. if (DbgSettings & DbgLevel[i].Val)
  351. {
  352. dprintf(" %s", DbgLevel[i].Name);
  353. if (col == 4)
  354. {
  355. col = 0;
  356. dprintf("\n");
  357. }
  358. else
  359. {
  360. col ++;
  361. }
  362. }
  363. }
  364. if (col != 0)
  365. dprintf("\n");
  366. col = 0;
  367. dprintf("Available settings:\n");
  368. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  369. {
  370. if (!(DbgSettings & DbgLevel[i].Val))
  371. {
  372. dprintf(" %s", DbgLevel[i].Name);
  373. if (col == 4)
  374. {
  375. col = 0;
  376. dprintf("\n");
  377. }
  378. else
  379. {
  380. col++;
  381. }
  382. }
  383. }
  384. if (col != 0)
  385. dprintf("\n");
  386. return;
  387. }
  388. strcpy( argbuf, args );
  389. for (p = mystrtok( argbuf, " \t,;" );
  390. p && *p;
  391. p = mystrtok(NULL, " \t,;"))
  392. {
  393. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  394. {
  395. if (strcmp(p, DbgLevel[i].Name) == 0)
  396. {
  397. if (DbgSettings & DbgLevel[i].Val)
  398. {
  399. DbgSettings &= ~DbgLevel[i].Val;
  400. }
  401. else
  402. {
  403. DbgSettings |= DbgLevel[i].Val;
  404. }
  405. }
  406. }
  407. }
  408. WriteMemory(dwAddress, &DbgSettings, sizeof(DWORD), &Written);
  409. }
  410. DECLARE_API( link )
  411. {
  412. LIST_ENTRY IrdaLinkCbList, *pIrdaLinkCbList;
  413. PIRDA_LINK_CB pIrdaLinkCb;
  414. IRDA_LINK_CB IrdaLinkCb;
  415. LIST_ENTRY *pListEntry, ListEntry, *pListHead;
  416. pIrdaLinkCbList = (LIST_ENTRY *) GetExpression("irda!IrdaLinkCbList");
  417. if (!GetData(&IrdaLinkCbList,
  418. (DWORD_PTR) pIrdaLinkCbList,
  419. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  420. {
  421. return;
  422. }
  423. for (pIrdaLinkCb = (PIRDA_LINK_CB) IrdaLinkCbList.Flink;
  424. (LIST_ENTRY *) pIrdaLinkCb != pIrdaLinkCbList;
  425. pIrdaLinkCb = (PIRDA_LINK_CB) IrdaLinkCb.Linkage.Flink)
  426. {
  427. if (!GetData(&IrdaLinkCb,
  428. (DWORD_PTR) pIrdaLinkCb,
  429. sizeof(IRDA_LINK_CB), "IRDA_LINK_CB"))
  430. {
  431. return;
  432. }
  433. dprintf("IrdaLinkCb:%X, Irlap:%X, Irlmp:%X NdisBindingHandle:%X\n", pIrdaLinkCb,
  434. IrdaLinkCb.IrlapContext, IrdaLinkCb.IrlmpContext,
  435. IrdaLinkCb.NdisBindingHandle);
  436. dprintf(" MinTat:%d, WaitMinTat:%d, SendOutCnt %d\n",
  437. IrdaLinkCb.MinTat, IrdaLinkCb.WaitMinTat, IrdaLinkCb.SendOutCnt);
  438. #if DBG
  439. dprintf(" DelayedRxFrameCnt %d\n", IrdaLinkCb.DelayedRxFrameCnt);
  440. #endif
  441. pListHead = (PLIST_ENTRY) ((char *) pIrdaLinkCb +
  442. FIELD_OFFSET(IRDA_LINK_CB, TxMsgFreeList));
  443. dprintf("TxMsgFreeList:%X len %d\n", pListHead,
  444. IrdaLinkCb.TxMsgFreeListLen);
  445. for (pListEntry = IrdaLinkCb.TxMsgFreeList.Flink;
  446. pListEntry != pListHead;
  447. pListEntry = ListEntry.Flink)
  448. {
  449. if (!GetData(&ListEntry,
  450. (DWORD_PTR) pListEntry,
  451. sizeof(LIST_ENTRY),
  452. "LIST_ENTRY"))
  453. {
  454. return;
  455. }
  456. dprintf(" %X\n", pListEntry);
  457. }
  458. pListHead = (PLIST_ENTRY) ((char *) pIrdaLinkCb +
  459. FIELD_OFFSET(IRDA_LINK_CB, RxMsgFreeList));
  460. dprintf("RxMsgFreeList:%X len %d\n", pListHead,
  461. IrdaLinkCb.RxMsgFreeListLen);
  462. for (pListEntry = IrdaLinkCb.RxMsgFreeList.Flink;
  463. pListEntry != pListHead;
  464. pListEntry = ListEntry.Flink)
  465. {
  466. if (!GetData(&ListEntry,
  467. (DWORD_PTR) pListEntry,
  468. sizeof(LIST_ENTRY),
  469. "LIST_ENTRY"))
  470. {
  471. return;
  472. }
  473. dprintf(" %X\n", pListEntry);
  474. }
  475. pListHead = (PLIST_ENTRY) ((char *) pIrdaLinkCb +
  476. FIELD_OFFSET(IRDA_LINK_CB, RxMsgList));
  477. dprintf("RxMsgList:%Xd\n", pListHead);
  478. for (pListEntry = IrdaLinkCb.RxMsgList.Flink;
  479. pListEntry != pListHead;
  480. pListEntry = ListEntry.Flink)
  481. {
  482. if (!GetData(&ListEntry,
  483. (DWORD_PTR) pListEntry,
  484. sizeof(LIST_ENTRY),
  485. "LIST_ENTRY"))
  486. {
  487. return;
  488. }
  489. dprintf(" %X\n", pListEntry);
  490. }
  491. }
  492. }
  493. DECLARE_API( irlmp )
  494. {
  495. LIST_ENTRY IrdaLinkCbList, *pIrdaLinkCbList;
  496. PIRDA_LINK_CB pIrdaLinkCb;
  497. IRDA_LINK_CB IrdaLinkCb;
  498. IRLMP_LINK_CB IrlmpLinkCb;
  499. PIRLMP_LSAP_CB pLsapCb;
  500. IRLMP_LSAP_CB LsapCb;
  501. IRDA_MSG *pMsg, IMsg;
  502. pIrdaLinkCbList = (LIST_ENTRY *) GetExpression("irda!IrdaLinkCbList");
  503. if (!GetData(&IrdaLinkCbList,
  504. (DWORD_PTR) pIrdaLinkCbList,
  505. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  506. {
  507. return;
  508. }
  509. for (pIrdaLinkCb = (PIRDA_LINK_CB) IrdaLinkCbList.Flink;
  510. (LIST_ENTRY *) pIrdaLinkCb != pIrdaLinkCbList;
  511. pIrdaLinkCb = (PIRDA_LINK_CB) IrdaLinkCb.Linkage.Flink)
  512. {
  513. if (!GetData(&IrdaLinkCb,
  514. (DWORD_PTR) pIrdaLinkCb,
  515. sizeof(IRDA_LINK_CB), "IRDA_LINK_CB"))
  516. {
  517. return;
  518. }
  519. if (!GetData(&IrlmpLinkCb,
  520. (DWORD_PTR) IrdaLinkCb.IrlmpContext,
  521. sizeof(IRLMP_LINK_CB), "IRLMP_LINK_CB"))
  522. {
  523. return;
  524. }
  525. dprintf("IrlmpLinkCb %x, State:%s, MaxSlot:%d, MaxPdu:%d, WindowSize:%d\n",
  526. IrdaLinkCb.IrlmpContext,
  527. IrlmpState[IrlmpLinkCb.LinkState],
  528. IrlmpLinkCb.MaxSlot, IrlmpLinkCb.MaxPDUSize,
  529. IrlmpLinkCb.WindowSize);
  530. dprintf(" Exclusive LsapCb:%x\n", IrlmpLinkCb.pExclLsapCb);
  531. for (pLsapCb = (PIRLMP_LSAP_CB) IrlmpLinkCb.LsapCbList.Flink;
  532. pLsapCb != (PIRLMP_LSAP_CB) ((char *)IrdaLinkCb.IrlmpContext + FIELD_OFFSET(IRLMP_LINK_CB, LsapCbList));
  533. pLsapCb = (PIRLMP_LSAP_CB) LsapCb.Linkage.Flink)
  534. {
  535. if (!GetData(&LsapCb,
  536. (DWORD_PTR) pLsapCb,
  537. sizeof(IRLMP_LSAP_CB), "IRLMP_LSAP_CB"))
  538. {
  539. return;
  540. }
  541. dprintf(" LsapCb:%x State:%s LocalLsapSel:%d RemoteLsapSel:%d\n",
  542. pLsapCb, LsapState[LsapCb.State],
  543. LsapCb.LocalLsapSel, LsapCb.RemoteLsapSel);
  544. dprintf(" TdiContext:%x AvailCredit:%d LocalCredit:%d RemoteCredit:%d, RefCnt:%d\n",
  545. LsapCb.TdiContext, LsapCb.AvailableCredit,
  546. LsapCb.LocalTxCredit,
  547. LsapCb.RemoteTxCredit,
  548. LsapCb.RefCnt.Count);
  549. dprintf(" TxMsgList:%x\n", LsapCb.TxMsgList);
  550. for (pMsg = (IRDA_MSG *) LsapCb.TxMsgList.Flink;
  551. pMsg != (IRDA_MSG *) ((char *) pLsapCb + FIELD_OFFSET(IRLMP_LSAP_CB, TxMsgList));
  552. pMsg = (IRDA_MSG *) IMsg.Linkage.Flink)
  553. {
  554. if (!GetData(&IMsg,
  555. (DWORD_PTR) pMsg,
  556. sizeof(IRDA_MSG), "IRDA_MSG"))
  557. {
  558. dprintf("error\n");
  559. }
  560. dprintf(" Msg:%x\n", pMsg);
  561. }
  562. dprintf(" SegTxMsgList:%x\n", LsapCb.TxMsgList);
  563. for (pMsg = (IRDA_MSG *) LsapCb.SegTxMsgList.Flink;
  564. pMsg != (IRDA_MSG *) ((char *) pLsapCb + FIELD_OFFSET(IRLMP_LSAP_CB, SegTxMsgList));
  565. pMsg = (IRDA_MSG *) IMsg.Linkage.Flink)
  566. {
  567. if (!GetData(&IMsg,
  568. (DWORD_PTR) pMsg,
  569. sizeof(IRDA_MSG), "IRDA_MSG"))
  570. {
  571. return;
  572. }
  573. dprintf(" Msg:%x\n", pMsg);
  574. }
  575. }
  576. }
  577. }
  578. DECLARE_API( irlap )
  579. {
  580. LIST_ENTRY IrdaLinkCbList, *pIrdaLinkCbList;
  581. IRDA_LINK_CB IrdaLinkCb, *pIrdaLinkCb;
  582. IRLAP_CB IrlapCb;
  583. int i;
  584. pIrdaLinkCbList = (LIST_ENTRY *) GetExpression("irda!IrdaLinkCbList");
  585. if (!GetData(&IrdaLinkCbList,
  586. (DWORD_PTR) pIrdaLinkCbList,
  587. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  588. {
  589. return;
  590. }
  591. for (pIrdaLinkCb = (PIRDA_LINK_CB) IrdaLinkCbList.Flink;
  592. (LIST_ENTRY *) pIrdaLinkCb != pIrdaLinkCbList;
  593. pIrdaLinkCb = (PIRDA_LINK_CB) IrdaLinkCb.Linkage.Flink)
  594. {
  595. if (!GetData(&IrdaLinkCb,
  596. (DWORD_PTR) pIrdaLinkCb,
  597. sizeof(IRDA_LINK_CB), "IRDA_LINK_CB"))
  598. {
  599. return;
  600. }
  601. if (!GetData(&IrlapCb,
  602. (DWORD_PTR) IrdaLinkCb.IrlapContext,
  603. sizeof(IRLAP_CB), "IRLAP_CB"))
  604. {
  605. return;
  606. }
  607. dprintf("\nIrlapCb:%X State:%s Vs:%d Vr:%d FTimerExpCnt:%d RetranCnt:%d\n",
  608. IrdaLinkCb.IrlapContext,
  609. IrlapState[IrlapCb.State],
  610. IrlapCb.Vs, IrlapCb.Vr, IrlapCb.FTimerExpCnt, IrlapCb.RetranCnt);
  611. #if DBG
  612. dprintf("DelayedConfirms:%d\n", IrlapCb.DelayedConf);
  613. #endif
  614. dprintf(" TxMsgList:%X\n",
  615. *(DWORD*)&IrlapCb.TxMsgList);
  616. dprintf(" RxWin start:%d end:%d pMsgs:\n",
  617. IrlapCb.RxWin.Start,
  618. IrlapCb.RxWin.End);
  619. for (i = 0; i < IRLAP_MOD; i++)
  620. {
  621. dprintf(" %d. %X\n", i, IrlapCb.RxWin.pMsg[i]);
  622. }
  623. dprintf("TxWin start:%d end:%d pMsgs:\n",
  624. IrlapCb.TxWin.Start,
  625. IrlapCb.TxWin.End);
  626. for (i = 0; i < IRLAP_MOD; i++)
  627. {
  628. dprintf(" %d. %X\n", i, IrlapCb.TxWin.pMsg[i]);
  629. }
  630. }
  631. }
  632. VOID
  633. DumpIrpList(LIST_ENTRY *pIrpList)
  634. {
  635. LIST_ENTRY IrpList, *pListEntry, ListEntry;
  636. IRP *pIrp;
  637. if (!GetData(&IrpList,
  638. (DWORD_PTR) pIrpList,
  639. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  640. {
  641. return;
  642. }
  643. for (pListEntry = IrpList.Flink;
  644. pListEntry != pIrpList;
  645. pListEntry = ListEntry.Flink)
  646. {
  647. if (!GetData(&ListEntry,
  648. (DWORD_PTR) pListEntry,
  649. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  650. {
  651. return;
  652. }
  653. pIrp = CONTAINING_RECORD(pListEntry, IRP, Tail.Overlay.ListEntry);
  654. dprintf(" %x\n", pIrp);
  655. }
  656. }
  657. DECLARE_API( tdi )
  658. {
  659. PIRDA_CONN_OBJ pConnObjList, pConnObj;
  660. PIRDA_ADDR_OBJ pAddrObjList, pAddrObj;
  661. IRDA_ADDR_OBJ AddrObj;
  662. IRDA_CONN_OBJ ConnObj;
  663. int i;
  664. pAddrObjList = (PIRDA_ADDR_OBJ) GetExpression("irda!AddrObjList");
  665. if (!GetData(&pAddrObj,
  666. (DWORD_PTR) pAddrObjList,
  667. sizeof(PIRDA_ADDR_OBJ), "IRDA_ADDR_OBJ_LIST"))
  668. {
  669. return;
  670. }
  671. if (pAddrObj == NULL)
  672. {
  673. dprintf("No address objects\n");
  674. return;
  675. }
  676. while (pAddrObj)
  677. {
  678. if (!GetData(&AddrObj,
  679. (DWORD_PTR) pAddrObj,
  680. sizeof(IRDA_ADDR_OBJ), "IRDA_ADDR_OBJ"))
  681. {
  682. return;
  683. }
  684. dprintf("AddrObj:%x Server:%s LocalLsapSel:%d Service:%s\n", pAddrObj,
  685. AddrObj.IsServer ? "TRUE":"FALSE", AddrObj.LocalLsapSel,
  686. AddrObj.LocalAddr.irdaServiceName);
  687. pConnObj = AddrObj.ConnObjList;
  688. if (pConnObj == NULL)
  689. {
  690. dprintf(" No connect objects\n");
  691. }
  692. while (pConnObj)
  693. {
  694. IRDA_RECV_BUF *pRecvBuf, RecvBuf;
  695. if (!GetData(&ConnObj,
  696. (DWORD_PTR) pConnObj,
  697. sizeof(IRDA_CONN_OBJ), "IRDA_CONN_OBJ"))
  698. {
  699. return;
  700. }
  701. dprintf(" ConnObj:%x State:%s Irlmp:%X TtpCreditsLeft:%d RecvBusy:%s\n",
  702. pConnObj,
  703. ConnObjState[ConnObj.ConnState],
  704. ConnObj.IrlmpContext,
  705. ConnObj.TtpRecvCreditsLeft,
  706. ConnObj.RecvBusy ? "TRUE":"FALSE");
  707. dprintf(" LocalLsapSel:%d Addr:\"%s\" RemoteLsapSel:%d Addr:\"%s\"\n",
  708. ConnObj.LocalLsapSel, ConnObj.LocalAddr.irdaServiceName,
  709. ConnObj.RemoteLsapSel, ConnObj.RemoteAddr.irdaServiceName);
  710. /*
  711. i = 0;
  712. for (pRecvBuf = (PIRDA_RECV_BUF) ConnObj.RecvBufList.Flink;
  713. pRecvBuf != (PIRDA_RECV_BUF) ((char *) pConnObj + FIELD_OFFSET(IRDA_CONN_OBJ, RecvBufList));
  714. pRecvBuf = (PIRDA_RECV_BUF) RecvBuf.Linkage.Flink)
  715. {
  716. i++;
  717. if (!GetData(&RecvBuf,
  718. (DWORD_PTR) pRecvBuf,
  719. sizeof(IRDA_RECV_BUF)-IRDA_MAX_DATA_SIZE,
  720. "IRDA_RECV_BUF"))
  721. {
  722. break;
  723. }
  724. dprintf(" RecvBuf:%x Len:%d Offset:%d\n",
  725. pRecvBuf, RecvBuf.Len, RecvBuf.Offset);
  726. if (i > 100)
  727. {
  728. dprintf(" !!! Infinite loop ???\n");
  729. break;
  730. }
  731. }
  732. */
  733. dprintf(" SendIrpList:\n");
  734. DumpIrpList((LIST_ENTRY *) ((char *) pConnObj + FIELD_OFFSET(IRDA_CONN_OBJ, SendIrpList)));
  735. dprintf(" RecvIrpList:\n");
  736. DumpIrpList((LIST_ENTRY *) ((char *) pConnObj + FIELD_OFFSET(IRDA_CONN_OBJ, RecvIrpList)));
  737. pConnObj = ConnObj.pNext;
  738. }
  739. pAddrObj = AddrObj.pNext;
  740. }
  741. dprintf("IasIrp %x\n", GetExpression("irda!pIasIrp"));
  742. dprintf("DscvIrpList:\n");
  743. DumpIrpList((LIST_ENTRY *) GetExpression("irda!DscvIrpList"));
  744. dprintf("IasIrpList:\n");
  745. DumpIrpList((LIST_ENTRY *) GetExpression("irda!IasIrpList"));
  746. dprintf("ConnIrpList:\n");
  747. DumpIrpList((LIST_ENTRY *) GetExpression("irda!ConnIrpList"));
  748. }
  749. VOID
  750. WinDbgExtensionDllInit(
  751. PWINDBG_EXTENSION_APIS lpExtensionApis,
  752. USHORT MajorVersion,
  753. USHORT MinorVersion
  754. )
  755. {
  756. ExtensionApis = *lpExtensionApis;
  757. SavedMajorVersion = MajorVersion;
  758. SavedMinorVersion = MinorVersion;
  759. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  760. }
  761. DECLARE_API( version )
  762. {
  763. #if DBG
  764. PCSTR kind = "Checked";
  765. #else
  766. PCSTR kind = "Free";
  767. #endif
  768. dprintf(
  769. "%s SMB Extension dll for Build %d debugging %s kernel for Build %d\n",
  770. kind,
  771. VER_PRODUCTBUILD,
  772. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  773. SavedMinorVersion
  774. );
  775. }
  776. VOID
  777. CheckVersion(
  778. VOID
  779. )
  780. {
  781. #if DBG
  782. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  783. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  784. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  785. }
  786. #else
  787. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  788. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  789. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  790. }
  791. #endif
  792. }
  793. LPEXT_API_VERSION
  794. ExtensionApiVersion(
  795. VOID
  796. )
  797. {
  798. return &ApiVersion;
  799. }