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.

1282 lines
32 KiB

  1. #ifndef DBG
  2. #define DBG 1
  3. #endif
  4. #define SRVDBG 1
  5. #define SRVKD 1
  6. #include <nt.h>
  7. #include <ntrtl.h>
  8. #include <nturtl.h>
  9. #include <ntverp.h>
  10. #include <windef.h>
  11. #include <winbase.h>
  12. #include <ntosp.h>
  13. #include <wdbgexts.h>
  14. #include <stdlib.h>
  15. #define NT
  16. #include <tdikrnl.h>
  17. #include <cxport.h>
  18. #include <ndis.h>
  19. #include <netpnp.h>
  20. #include <tdipnp.h>
  21. #include <tdidebug.h>
  22. WINDBG_EXTENSION_APIS ExtensionApis;
  23. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 };
  24. #define ERRPRT dprintf
  25. #define NL 1
  26. #define NONL 0
  27. USHORT SavedMajorVersion;
  28. USHORT SavedMinorVersion;
  29. BOOL ChkTarget; // is debuggee a CHK build?
  30. #define PROV_SIZE sizeof(TDI_PROVIDER_RESOURCE) + 32
  31. CHAR provBuf[PROV_SIZE];
  32. TDI_PROVIDER_RESOURCE *pProvider = (TDI_PROVIDER_RESOURCE *) provBuf;
  33. typedef struct _TDI_EXEC_PARAMS {
  34. LIST_ENTRY Linkage;
  35. UINT Signature;
  36. PLIST_ENTRY ClientList;
  37. PLIST_ENTRY ProviderList;
  38. PLIST_ENTRY RequestList;
  39. TDI_SERIALIZED_REQUEST Request;
  40. PETHREAD *CurrentThread;
  41. CTEEvent *RequestCTEEvent;
  42. PBOOLEAN SerializeFlag;
  43. BOOLEAN ResetSerializeFlag;
  44. } TDI_EXEC_PARAMS, *PTDI_EXEC_PARAMS;
  45. typedef struct
  46. {
  47. char Name[16];
  48. int Val;
  49. } DBG_LEVEL;
  50. #if 0
  51. DBG_LEVEL DbgLevel[] = {
  52. {"RXFRAME", DBG_RXFRAME },
  53. {"TXFRAME", DBG_TXFRAME },
  54. {"NDIS", DBG_NDIS },
  55. {"IRMAC", DBG_IRMAC },
  56. {"IRLAP", DBG_IRLAP },
  57. {"IRLAPLOG", DBG_IRLAPLOG },
  58. {"IRLMP", DBG_IRLMP },
  59. {"IRLMP_CONN", DBG_IRLMP_CONN },
  60. {"IRLMP_CRED", DBG_IRLMP_CRED },
  61. {"IRLMP_IAS", DBG_IRLMP_IAS },
  62. {"DISCOVERY", DBG_DISCOVERY },
  63. {"TDI", DBG_TDI },
  64. {"TDI_IRP", DBG_TDI_IRP },
  65. {"ALLOC", DBG_ALLOC },
  66. {"TIMER ", DBG_TIMER },
  67. {"PRINT", DBG_PRINT },
  68. {"ADDRESS", DBG_ADDR },
  69. {"REFERENCE", DBG_REF },
  70. {"FUNCTION", DBG_FUNCTION },
  71. {"WARN", DBG_WARN },
  72. {"ERROR", DBG_ERROR }};
  73. char *IrlmpState[] =
  74. {"LINK_DISCONNECTED",
  75. "LINK_DISCONNECTING",
  76. "LINK_IN_DISCOVERY",
  77. "LINK_CONNECTING",
  78. "LINK_READY"};
  79. char *LsapState[] =
  80. {"LSAP_DISCONNECTED",
  81. "LSAP_IRLAP_CONN_PEND",
  82. "LSAP_LMCONN_CONF_PEND",
  83. "LSAP_CONN_RESP_PEND",
  84. "LSAP_CONN_REQ_PEND",
  85. "LSAP_EXCLUSIVEMODE_PEND",
  86. "LSAP_MULTIPLEXEDMODE_PEND",
  87. "LSAP_READY",
  88. "LSAP_NO_TX_CREDIT"};
  89. char *ConnObjState[] =
  90. {"IRDA_CONN_CREATED",
  91. "IRDA_CONN_CLOSING",
  92. "IRDA_CONN_OPENING",
  93. "IRDA_CONN_OPEN"};
  94. #endif
  95. void
  96. TDIDumpDevice(
  97. TDI_PROVIDER_RESOURCE *prov
  98. );
  99. void
  100. TDIDumpAddress(
  101. TDI_PROVIDER_RESOURCE *prov
  102. );
  103. void
  104. TDIDumpProvider(
  105. TDI_PROVIDER_RESOURCE *prov
  106. );
  107. /*
  108. * Print out an optional message, an ANSI_STRING, and maybe a new-line
  109. */
  110. BOOL
  111. PrintStringA( IN LPSTR msg OPTIONAL, IN PANSI_STRING pStr, IN BOOL nl )
  112. {
  113. PCHAR StringData;
  114. ULONG BytesRead;
  115. if( msg )
  116. dprintf( msg );
  117. if( pStr->Length == 0 ) {
  118. if( nl )
  119. dprintf( "\n" );
  120. return TRUE;
  121. }
  122. StringData = (PCHAR)LocalAlloc( LPTR, pStr->Length + 1 );
  123. if( StringData == NULL ) {
  124. ERRPRT( "Out of memory!\n" );
  125. return FALSE;
  126. }
  127. ReadMemory((ULONG) pStr->Buffer,
  128. StringData,
  129. pStr->Length,
  130. &BytesRead );
  131. if ( BytesRead ) {
  132. StringData[ pStr->Length ] = '\0';
  133. dprintf("%s%s", StringData, nl ? "\n" : "" );
  134. }
  135. LocalFree((HLOCAL)StringData);
  136. return BytesRead;
  137. }
  138. /*
  139. * Get 'size' bytes from the debuggee program at 'dwAddress' and place it
  140. * in our address space at 'ptr'. Use 'type' in an error printout if necessary
  141. */
  142. BOOL
  143. GetData( IN LPVOID ptr, IN DWORD dwAddress, IN ULONG size, IN PCSTR type )
  144. {
  145. BOOL b;
  146. ULONG BytesRead;
  147. ULONG count = size;
  148. while( size > 0 ) {
  149. if (count >= 3000)
  150. count = 3000;
  151. b = ReadMemory((ULONG) dwAddress, ptr, count, &BytesRead );
  152. if (!b || BytesRead != count ) {
  153. ERRPRT( "Unable to read %u bytes at %X, for %s\n", size, dwAddress, type );
  154. return FALSE;
  155. }
  156. dwAddress += count;
  157. size -= count;
  158. ptr = (LPVOID)((ULONG)ptr + count);
  159. }
  160. return TRUE;
  161. }
  162. /*
  163. * Follow a LIST_ENTRY list beginning with a head at dwListHeadAddr in the debugee's
  164. * address space. For each element in the list, print out the pointer value at 'offset'
  165. */
  166. BOOL
  167. PrintListEntryList( IN DWORD dwListHeadAddr, IN LONG offset )
  168. {
  169. LIST_ENTRY ListEntry;
  170. ULONG i=0;
  171. BOOL retval = TRUE;
  172. ULONG count = 20;
  173. if( !GetData( &ListEntry, dwListHeadAddr, sizeof( ListEntry ), "LIST_ENTRY" ) )
  174. return FALSE;
  175. while( count-- ) {
  176. if( (DWORD)ListEntry.Flink == dwListHeadAddr || (DWORD)ListEntry.Flink == 0 )
  177. break;
  178. if( !GetData( &ListEntry, (DWORD)ListEntry.Flink, sizeof( ListEntry ), "ListEntry" ) ) {
  179. retval = FALSE;
  180. break;
  181. }
  182. dprintf( "%16X%s", (LONG)ListEntry.Flink + offset, (i && !(i&3)) ? "\n" : "" );
  183. i++;
  184. }
  185. if( count == 0 && (DWORD)ListEntry.Flink != dwListHeadAddr && ListEntry.Flink ) {
  186. dprintf( "\nTruncated list dump\n" );
  187. } else if( ! ( i && !(i&3) ) ) {
  188. dprintf( "\n" );
  189. }
  190. return retval;
  191. }
  192. /*
  193. * Print out a single HEX character
  194. */
  195. VOID
  196. PrintHexChar( IN UCHAR c )
  197. {
  198. dprintf( "%c%c", "0123456789abcdef"[ (c>>4)&0xf ], "0123456789abcdef"[ c&0xf ] );
  199. }
  200. /*
  201. * Print out 'buf' of 'cbuf' bytes as HEX characters
  202. */
  203. VOID
  204. PrintHexBuf( IN PUCHAR buf, IN ULONG cbuf )
  205. {
  206. while( cbuf-- ) {
  207. PrintHexChar( *buf++ );
  208. dprintf( " " );
  209. }
  210. }
  211. /*
  212. * Fetch the null terminated UNICODE string at dwAddress into buf
  213. */
  214. BOOL
  215. GetString( IN DWORD dwAddress, IN LPSTR buf, IN ULONG MaxChars )
  216. {
  217. do {
  218. if( !GetData( buf, dwAddress, sizeof( *buf ), "Character" ) )
  219. return FALSE;
  220. dwAddress += sizeof( *buf );
  221. } while( --MaxChars && *buf++ != '\0' );
  222. return TRUE;
  223. }
  224. char *mystrtok ( char *string, char * control )
  225. {
  226. static unsigned char *str;
  227. char *p, *s;
  228. if( string )
  229. str = string;
  230. if( str == NULL || *str == '\0' )
  231. return NULL;
  232. //
  233. // Skip leading delimiters...
  234. //
  235. for( ; *str; str++ ) {
  236. for( s=control; *s; s++ ) {
  237. if( *str == *s )
  238. break;
  239. }
  240. if( *s == '\0' )
  241. break;
  242. }
  243. //
  244. // Was it was all delimiters?
  245. //
  246. if( *str == '\0' ) {
  247. str = NULL;
  248. return NULL;
  249. }
  250. //
  251. // We've got a string, terminate it at first delimeter
  252. //
  253. for( p = str+1; *p; p++ ) {
  254. for( s = control; *s; s++ ) {
  255. if( *p == *s ) {
  256. s = str;
  257. *p = '\0';
  258. str = p+1;
  259. return s;
  260. }
  261. }
  262. }
  263. //
  264. // We've got a string that ends with the NULL
  265. //
  266. s = str;
  267. str = NULL;
  268. return s;
  269. }
  270. DECLARE_API( help )
  271. {
  272. int i;
  273. dprintf("TDI extenstions:\n");
  274. dprintf(" All dumps All Lists\n");
  275. dprintf(" Providers dumps Providers List\n");
  276. dprintf(" Clients dumps Clients List\n");
  277. dprintf(" Request dumps Request List\n");
  278. dprintf(" Address dumps Provider Addresses\n");
  279. dprintf(" Devices dumps Provider Device Objects\n");
  280. dprintf(" ProviderReady dumps Provider Device Objects\n");
  281. dprintf(" item formats a TDI_REQUEST structure\n");
  282. }
  283. #if 0
  284. DECLARE_API( dbgmsgs )
  285. {
  286. DWORD p;
  287. DWORD Last, First;
  288. char DbgMsg[MAX_MSG_LEN];
  289. ULONG Read;
  290. char *DbgMsgs;
  291. if (!GetData(&Last,
  292. GetExpression("irda!Last"),
  293. sizeof(Last), "DWORD"))
  294. {
  295. dprintf("error\n");
  296. return;
  297. }
  298. if (!GetData(&First,
  299. GetExpression("irda!First"),
  300. sizeof(Last), "DWORD"))
  301. {
  302. dprintf("error\n");
  303. return;
  304. }
  305. DbgMsgs = (char *) GetExpression("irda!dbgmsgs");
  306. dprintf("\n\n");
  307. while (First != Last)
  308. {
  309. if (!GetString((ULONG) (DbgMsgs + First * MAX_MSG_LEN),
  310. DbgMsg, MAX_MSG_LEN))
  311. break;
  312. /*
  313. ReadMemory((ULONG) (DbgMsgs + First * MAX_MSG_LEN),
  314. DbgMsg, MAX_MSG_LEN, &Read); */
  315. dprintf("%s", DbgMsg);
  316. First++;
  317. if (First == LOG_MSG_CNT)
  318. First = 0;
  319. }
  320. }
  321. DECLARE_API( dbg )
  322. {
  323. int i;
  324. int col = 0;
  325. DWORD DbgSettings;
  326. char argbuf[ MAX_PATH ];
  327. char *p;
  328. DWORD dwAddress;
  329. DWORD Written;
  330. dwAddress = GetExpression("irda!dbgsettings");
  331. if (!GetData(&DbgSettings,
  332. dwAddress,
  333. sizeof(DbgSettings), "DWORD"))
  334. {
  335. dprintf("error\n");
  336. return;
  337. }
  338. if (!args || !*args)
  339. {
  340. dprintf("Current settings:\n");
  341. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  342. {
  343. if (DbgSettings & DbgLevel[i].Val)
  344. {
  345. dprintf(" %s", DbgLevel[i].Name);
  346. if (col == 4)
  347. {
  348. col = 0;
  349. dprintf("\n");
  350. }
  351. else
  352. {
  353. col ++;
  354. }
  355. }
  356. }
  357. if (col != 0)
  358. dprintf("\n");
  359. col = 0;
  360. dprintf("Available settings:\n");
  361. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  362. {
  363. if (!(DbgSettings & DbgLevel[i].Val))
  364. {
  365. dprintf(" %s", DbgLevel[i].Name);
  366. if (col == 4)
  367. {
  368. col = 0;
  369. dprintf("\n");
  370. }
  371. else
  372. {
  373. col++;
  374. }
  375. }
  376. }
  377. if (col != 0)
  378. dprintf("\n");
  379. return;
  380. }
  381. strcpy( argbuf, args );
  382. for (p = mystrtok( argbuf, " \t,;" );
  383. p && *p;
  384. p = mystrtok(NULL, " \t,;"))
  385. {
  386. for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  387. {
  388. if (strcmp(p, DbgLevel[i].Name) == 0)
  389. {
  390. if (DbgSettings & DbgLevel[i].Val)
  391. {
  392. DbgSettings &= ~DbgLevel[i].Val;
  393. }
  394. else
  395. {
  396. DbgSettings |= DbgLevel[i].Val;
  397. }
  398. }
  399. }
  400. }
  401. WriteMemory(dwAddress, &DbgSettings, sizeof(DWORD), &Written);
  402. }
  403. VOID
  404. DumpIrpList(LIST_ENTRY *pIrpList)
  405. {
  406. LIST_ENTRY IrpList, *pListEntry, ListEntry;
  407. IRP *pIrp;
  408. if (!GetData(&IrpList,
  409. (DWORD) pIrpList,
  410. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  411. {
  412. return;
  413. }
  414. for (pListEntry = IrpList.Flink;
  415. pListEntry != pIrpList;
  416. pListEntry = ListEntry.Flink)
  417. {
  418. if (!GetData(&ListEntry,
  419. (DWORD) pListEntry,
  420. sizeof(LIST_ENTRY), "LIST_ENTRY"))
  421. {
  422. return;
  423. }
  424. pIrp = CONTAINING_RECORD(pListEntry, IRP, Tail.Overlay.ListEntry);
  425. dprintf(" %x\n", pIrp);
  426. }
  427. }
  428. #endif
  429. #define PROV_TYPE 1
  430. #define CLIENT_TYPE 2
  431. #define NEITHER 3
  432. DECLARE_API( request )
  433. {
  434. LIST_ENTRY List, *pList, *start;
  435. TDI_EXEC_PARAMS TdiExec;
  436. TDI_SERIALIZED_REQUEST Request;
  437. BOOLEAN ElementTypeProvider = NEITHER;
  438. TDI_NOTIFY_PNP_ELEMENT Client;
  439. INT i = 1;
  440. pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerRequestList");
  441. if (!GetData(&List,
  442. (DWORD) pList,
  443. sizeof(LIST_ENTRY), "REQUEST_LIST"))
  444. {
  445. return;
  446. }
  447. if (List.Flink == List.Blink)
  448. {
  449. dprintf("No Requests\n");
  450. return;
  451. }
  452. start = pList;
  453. pList = List.Flink;
  454. while (pList != start)
  455. {
  456. if (!GetData(&List,
  457. (DWORD) pList,
  458. sizeof(LIST_ENTRY), "REQUEST_LIST"))
  459. {
  460. return;
  461. }
  462. if (!GetData(&TdiExec,
  463. (DWORD) pList,
  464. sizeof(TDI_EXEC_PARAMS), "EXEC PARAMS"))
  465. {
  466. return;
  467. }
  468. if(0x1234cdef != TdiExec.Signature) {
  469. dprintf("signature is BAD - %d not 0x1234cdef\r\n", TdiExec.Signature);
  470. return;
  471. }
  472. if (!GetData(&Request,
  473. (DWORD) &TdiExec.Request,
  474. sizeof (TDI_SERIALIZED_REQUEST), "REQUEST")) {
  475. return;
  476. }
  477. dprintf("%d. Request(%X) Element @ %x\t Type: ", i++, Request.Element);
  478. switch (Request.Type) {
  479. case TDI_REGISTER_HANDLERS_PNP:
  480. dprintf("TDI_REGISTER_HANDLERS_PNP\n");
  481. ElementTypeProvider = CLIENT_TYPE;
  482. break;
  483. case TDI_DEREGISTER_HANDLERS_PNP:
  484. dprintf("TDI_DEREGISTER_HANDLERS_PNP\n");
  485. ElementTypeProvider = CLIENT_TYPE;
  486. break;
  487. case TDI_REGISTER_PNP_POWER_EVENT:
  488. dprintf("TDI_REGISTER_PNP_POWER_EVENT\n");
  489. ElementTypeProvider = PROV_TYPE;
  490. break;
  491. case TDI_REGISTER_ADDRESS_PNP:
  492. dprintf("TDI_REGISTER_ADDRESS_PNP\n");
  493. ElementTypeProvider = PROV_TYPE;
  494. break;
  495. case TDI_DEREGISTER_ADDRESS_PNP:
  496. dprintf("TDI_DEREGISTER_ADDRESS_PNP\n");
  497. ElementTypeProvider = PROV_TYPE;
  498. break;
  499. case TDI_REGISTER_DEVICE_PNP:
  500. dprintf("TDI_REGISTER_DEVICE_PNP\n");
  501. ElementTypeProvider = PROV_TYPE;
  502. break;
  503. case TDI_DEREGISTER_DEVICE_PNP:
  504. dprintf("TDI_DEREGISTER_DEVICE_PNP\n");
  505. ElementTypeProvider = PROV_TYPE;
  506. break;
  507. case TDI_NDIS_IOCTL_HANDLER_PNP:
  508. dprintf("TDI_NDIS_IOCTL_HANDLER_PNP\n");
  509. ElementTypeProvider = PROV_TYPE;
  510. break;
  511. case TDI_ENUMERATE_ADDRESSES:
  512. dprintf("TDI_ENUMERATE_ADDRESSES\n");
  513. ElementTypeProvider = CLIENT_TYPE;
  514. break;
  515. case TDI_REGISTER_PROVIDER_PNP:
  516. dprintf("TDI_REGISTER_PROVIDER_PNP\n");
  517. ElementTypeProvider = PROV_TYPE;
  518. break;
  519. case TDI_DEREGISTER_PROVIDER_PNP:
  520. dprintf("TDI_DEREGISTER_PROVIDER_PNP\n");
  521. ElementTypeProvider = PROV_TYPE;
  522. break;
  523. case TDI_PROVIDER_READY_PNP:
  524. dprintf("TDI_PROVIDER_READY_PNP\n");
  525. ElementTypeProvider = PROV_TYPE;
  526. break;
  527. default:
  528. dprintf("TDI - UNKNOWN REQUEST TYPE!!!\n");
  529. ElementTypeProvider = NEITHER;
  530. break;
  531. }
  532. if (PROV_TYPE == ElementTypeProvider) {
  533. if (!GetData(pProvider,
  534. (DWORD) Request.Element,
  535. PROV_SIZE, "PROVIDER_RESOURCE")) {
  536. return;
  537. }
  538. if(TDI_RESOURCE_DEVICE == pProvider->Common.Type) {
  539. TDIDumpDevice(pProvider);
  540. } else if (TDI_RESOURCE_NET_ADDRESS == pProvider->Common.Type) {
  541. TDIDumpAddress(pProvider);
  542. } else if (TDI_RESOURCE_PROVIDER == pProvider->Common.Type) {
  543. TDIDumpProvider(pProvider);
  544. } else {
  545. dprintf("Unknown type: %x\n", ElementTypeProvider);
  546. return;
  547. }
  548. } else if (CLIENT_TYPE == ElementTypeProvider) {
  549. if (!GetData(&Client,
  550. (DWORD) Request.Element,
  551. sizeof (TDI_NOTIFY_PNP_ELEMENT), "CLIENT_RESOURCE")) {
  552. return;
  553. }
  554. dprintf("Its a client!\n Need to add some code for this \n");
  555. } else {
  556. dprintf("Unknown element type on request list\n");
  557. }
  558. dprintf("\n--------------------------------------------------------\n");
  559. //Print(TdiExec.Request);
  560. pList = List.Flink;
  561. }
  562. }
  563. /*
  564. typedef struct _TDI_PROVIDER_RESOURCE {
  565. TDI_PROVIDER_COMMON Common;
  566. // defined in netpnp.h
  567. PNET_PNP_EVENT PnpPowerEvent;
  568. // Each TDI Client gets back and tells us what the status
  569. NTSTATUS Status;
  570. // These are mostly Address Specific.
  571. PTDI_PNP_CONTEXT Context1;
  572. PTDI_PNP_CONTEXT Context2;
  573. KEVENT PowerSyncEvent;
  574. ULONG PowerHandlers;
  575. PVOID PreviousContext;
  576. union {
  577. TDI_PROVIDER_DEVICE Device;
  578. TDI_PROVIDER_NET_ADDRESS NetAddress;
  579. } Specific;
  580. */
  581. DECLARE_API( providers )
  582. {
  583. LIST_ENTRY List, *pList, *start;
  584. pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList");
  585. if (!GetData(&List,
  586. (DWORD) pList,
  587. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  588. {
  589. return;
  590. }
  591. if (List.Flink == List.Blink)
  592. {
  593. dprintf("No Providers\n");
  594. return;
  595. }
  596. dprintf("---------------------------------------------------------------------\n");
  597. start = pList;
  598. pList = List.Flink;
  599. while (List.Flink != start)
  600. {
  601. if (!GetData(&List,
  602. (DWORD) pList,
  603. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  604. {
  605. return;
  606. }
  607. if (!GetData(pProvider,
  608. (DWORD) pList,
  609. PROV_SIZE, "PROVIDER_RESOURCE"))
  610. {
  611. return;
  612. }
  613. dprintf("Entry: %X\n", pList);
  614. if(TDI_RESOURCE_DEVICE == pProvider->Common.Type) {
  615. TDIDumpDevice(pProvider);
  616. } else if (TDI_RESOURCE_NET_ADDRESS == pProvider->Common.Type) {
  617. TDIDumpAddress(pProvider);
  618. } else if (TDI_RESOURCE_PROVIDER == pProvider->Common.Type) {
  619. TDIDumpProvider(pProvider);
  620. } else {
  621. dprintf("Unknown type: %x\n", pProvider->Common.Type);
  622. return;
  623. }
  624. dprintf("---------------------------------------------------------------------\n");
  625. //Print(TdiExec.Request);
  626. pList = List.Flink;
  627. }
  628. }
  629. DECLARE_API( devices )
  630. {
  631. LIST_ENTRY List, *pList, *start;
  632. pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList");
  633. if (!GetData(&List,
  634. (DWORD) pList,
  635. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  636. {
  637. return;
  638. }
  639. if (List.Flink == List.Blink)
  640. {
  641. dprintf("No Devices\n");
  642. return;
  643. }
  644. start = pList;
  645. pList = List.Flink;
  646. dprintf("---------------------------------------------------------------------\n");
  647. while (List.Flink != start)
  648. {
  649. if (!GetData(&List,
  650. (DWORD) pList,
  651. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  652. {
  653. return;
  654. }
  655. if (!GetData(pProvider,
  656. (DWORD) pList,
  657. PROV_SIZE, "PROVIDER_RESOURCE"))
  658. {
  659. return;
  660. }
  661. if(TDI_RESOURCE_DEVICE == pProvider->Common.Type) {
  662. dprintf("Entry: %X\n", pList);
  663. TDIDumpDevice(pProvider);
  664. dprintf("---------------------------------------------------------------------\n");
  665. }
  666. //Print(TdiExec.Request);
  667. pList = List.Flink;
  668. }
  669. }
  670. DECLARE_API( providerready )
  671. {
  672. LIST_ENTRY List, *pList, *start;
  673. pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList");
  674. if (!GetData(&List,
  675. (DWORD) pList,
  676. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  677. {
  678. return;
  679. }
  680. if (List.Flink == List.Blink)
  681. {
  682. dprintf("No Devices\n");
  683. return;
  684. }
  685. start = pList;
  686. pList = List.Flink;
  687. dprintf("---------------------------------------------------------------------\n");
  688. while (List.Flink != start)
  689. {
  690. if (!GetData(&List,
  691. (DWORD) pList,
  692. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  693. {
  694. return;
  695. }
  696. if (!GetData(pProvider,
  697. (DWORD) pList,
  698. PROV_SIZE, "PROVIDER_RESOURCE"))
  699. {
  700. return;
  701. }
  702. if (TDI_RESOURCE_PROVIDER == pProvider->Common.Type) {
  703. dprintf("Entry: %X\n", pList);
  704. TDIDumpProvider(pProvider);
  705. dprintf("---------------------------------------------------------------------\n");
  706. }
  707. //Print(TdiExec.Request);
  708. pList = List.Flink;
  709. }
  710. }
  711. DECLARE_API( addresses )
  712. {
  713. LIST_ENTRY List, *pList, *start;
  714. pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList");
  715. if (!GetData(&List,
  716. (DWORD) pList,
  717. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  718. {
  719. return;
  720. }
  721. if (List.Flink == List.Blink)
  722. {
  723. dprintf("No Devices\n");
  724. return;
  725. }
  726. start = pList;
  727. pList = List.Flink;
  728. dprintf("---------------------------------------------------------------------\n");
  729. while (List.Flink != start)
  730. {
  731. if (!GetData(&List,
  732. (DWORD) pList,
  733. sizeof(LIST_ENTRY), "PROVIDER_LIST"))
  734. {
  735. return;
  736. }
  737. if (!GetData(pProvider,
  738. (DWORD) pList,
  739. PROV_SIZE, "PROVIDER_RESOURCE"))
  740. {
  741. return;
  742. }
  743. if (TDI_RESOURCE_NET_ADDRESS == pProvider->Common.Type) {
  744. dprintf("Entry: %X\n", pList);
  745. TDIDumpAddress(pProvider);
  746. dprintf("---------------------------------------------------------------------\n");
  747. }
  748. //Print(TdiExec.Request);
  749. pList = List.Flink;
  750. }
  751. }
  752. void
  753. TDIDumpDevice(
  754. TDI_PROVIDER_RESOURCE *pProvider
  755. )
  756. {
  757. CHAR *Buffer;
  758. Buffer = malloc (sizeof(WCHAR) * pProvider->Specific.Device.DeviceName.MaximumLength);
  759. if (!Buffer) {
  760. dprintf("Cant alloc memory\n");
  761. return;
  762. }
  763. if (!GetData(Buffer,
  764. (DWORD) pProvider->Specific.Device.DeviceName.Buffer,
  765. pProvider->Specific.Device.DeviceName.MaximumLength, "PROVIDER_LIST"))
  766. {
  767. free(Buffer);
  768. return;
  769. }
  770. dprintf("Device: %ws\n", Buffer);
  771. free(Buffer);
  772. return;
  773. }
  774. void
  775. TDIDumpAddress(
  776. TDI_PROVIDER_RESOURCE *prov
  777. )
  778. {
  779. int j;
  780. //dprintf ("ADDRESS: len %d ", prov->Specific.NetAddress.Address.AddressLength);
  781. if (prov->Specific.NetAddress.Address.AddressType == TDI_ADDRESS_TYPE_IP) {
  782. dprintf("Type: IP\n");
  783. dprintf("Address: %d.%d.%d.%d\n",
  784. prov->Specific.NetAddress.Address.Address[2],
  785. prov->Specific.NetAddress.Address.Address[3],
  786. prov->Specific.NetAddress.Address.Address[4],
  787. prov->Specific.NetAddress.Address.Address[5]);
  788. } else if (prov->Specific.NetAddress.Address.AddressType == TDI_ADDRESS_TYPE_NETBIOS) {
  789. if (prov->Specific.NetAddress.Address.Address[2] == '\0') {
  790. dprintf("Type: NETBIOS reserved\n");
  791. dprintf("Address: %02x %02x %02x %02x %02x %02x\n",
  792. (ULONG)(prov->Specific.NetAddress.Address.Address[12]),
  793. (ULONG)(prov->Specific.NetAddress.Address.Address[13]),
  794. (ULONG)(prov->Specific.NetAddress.Address.Address[14]),
  795. (ULONG)(prov->Specific.NetAddress.Address.Address[15]),
  796. (ULONG)(prov->Specific.NetAddress.Address.Address[16]),
  797. (ULONG)(prov->Specific.NetAddress.Address.Address[17]));
  798. } else {
  799. dprintf("Type: NETBIOS\n");
  800. dprintf("Address: %.16s\n", prov->Specific.NetAddress.Address.Address+2);
  801. }
  802. } else {
  803. dprintf("Type: %d\n", prov->Specific.NetAddress.Address.AddressType);
  804. dprintf("Address: ");
  805. for (j = 0; j < prov->Specific.NetAddress.Address.AddressLength; j++) {
  806. dprintf ("%02x ", (ULONG)(prov->Specific.NetAddress.Address.Address[j]));
  807. }
  808. dprintf ("\n");
  809. }
  810. dprintf("Context1: %x\n", prov->Context1);
  811. dprintf("Context2: %x\n", prov->Context2);
  812. }
  813. void
  814. TDIDumpProvider(
  815. TDI_PROVIDER_RESOURCE *pProvider
  816. )
  817. {
  818. CHAR *Buffer;
  819. Buffer = malloc (sizeof(WCHAR) * pProvider->Specific.Device.DeviceName.MaximumLength);
  820. if (!Buffer) {
  821. dprintf("Cant alloc memory\n");
  822. return;
  823. }
  824. if (!GetData(Buffer,
  825. (DWORD) pProvider->Specific.Device.DeviceName.Buffer,
  826. pProvider->Specific.Device.DeviceName.MaximumLength, "PROVIDER_LIST"))
  827. {
  828. free(Buffer);
  829. return;
  830. }
  831. dprintf("Provider: %ws\n", Buffer);
  832. if (pProvider->ProviderReady) {
  833. dprintf("Ready: yes\n");
  834. } else {
  835. dprintf("Ready: no\n");
  836. }
  837. free(Buffer);
  838. return;
  839. }
  840. DECLARE_API( clients )
  841. {
  842. LIST_ENTRY List, *pList, *start;
  843. TDI_NOTIFY_PNP_ELEMENT client;
  844. CHAR *Buffer;
  845. pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerClientList");
  846. if (!GetData(&List,
  847. (DWORD) pList,
  848. sizeof(LIST_ENTRY), "CLIENT_LIST1"))
  849. {
  850. return;
  851. }
  852. if (List.Flink == List.Blink)
  853. {
  854. dprintf("No Clients\n");
  855. return;
  856. }
  857. start = pList;
  858. pList = List.Flink;
  859. dprintf("---------------------------------------------------------------------\n");
  860. while (List.Flink != start)
  861. {
  862. if (!GetData(&List,
  863. (DWORD) pList,
  864. sizeof(LIST_ENTRY), "CLIENT_LIST2"))
  865. {
  866. return;
  867. }
  868. dprintf("Entry: %x\n", pList);
  869. if (!GetData(&client,
  870. (DWORD) pList,
  871. sizeof(TDI_NOTIFY_PNP_ELEMENT), "CLIENT_RESOURCE"))
  872. {
  873. return;
  874. }
  875. Buffer = malloc (sizeof(WCHAR) * client.ElementName.MaximumLength);
  876. if (!Buffer) {
  877. dprintf("Cant alloc memory\n");
  878. return;
  879. }
  880. if (!GetData(Buffer,
  881. (DWORD) client.ElementName.Buffer,
  882. client.ElementName.MaximumLength, "CLIENT_LIST3"))
  883. {
  884. free(Buffer);
  885. return;
  886. }
  887. dprintf("Name: %ws\n", Buffer);
  888. free(Buffer);
  889. dprintf("Version: %x.%x\n", (client.TdiVersion), (0xff & (client.TdiVersion >> 8)));
  890. if (TDI_VERSION_ONE == client.TdiVersion) {
  891. dprintf("BindHandler: %lx\n", client.Bind.BindHandler);
  892. dprintf("UnBindHandler: %lx\n", client.Bind.UnbindHandler);
  893. } else {
  894. dprintf("BindingHandler: %lx\n", client.BindingHandler);
  895. }
  896. dprintf("AddAddressHandler: %lx\n", client.AddressElement.AddHandler);
  897. dprintf("DeleteAddressHandler: %lx\n", client.AddressElement.DeleteHandler);
  898. //dprintf("List of Interested Providers: %lx\n", client.AddressElement.ListofProviders);
  899. if (TDI_VERSION_ONE != client.TdiVersion) {
  900. dprintf("PnPPowerHandler: %lx\n", client.PnpPowerHandler);
  901. }
  902. dprintf("---------------------------------------------------------------------\n");
  903. //Print(TdiExec.Request);
  904. pList = List.Flink;
  905. }
  906. }
  907. DECLARE_API( dbgmsgs )
  908. {
  909. DWORD p;
  910. DWORD Last, First;
  911. char DbgMsg[MAX_MSG_LEN];
  912. ULONG Read;
  913. char *DbgMsgs;
  914. if (!GetData(&Last,
  915. GetExpression("tdi!Last"),
  916. sizeof(Last), "DWORD"))
  917. {
  918. dprintf("1. error\n");
  919. return;
  920. }
  921. if (!GetData(&First,
  922. GetExpression("tdi!First"),
  923. sizeof(Last), "DWORD"))
  924. {
  925. dprintf("2. error\n");
  926. return;
  927. }
  928. DbgMsgs = (char *) GetExpression("tdi!dbgmsgs");
  929. dprintf("\n\n");
  930. while (First != Last)
  931. {
  932. if (!GetString((ULONG) (DbgMsgs + First * MAX_MSG_LEN),
  933. DbgMsg, MAX_MSG_LEN))
  934. break;
  935. /*
  936. ReadMemory((ULONG) (DbgMsgs + First * MAX_MSG_LEN),
  937. DbgMsg, MAX_MSG_LEN, &Read); */
  938. dprintf("%s", DbgMsg);
  939. First++;
  940. if (First == LOG_MSG_CNT)
  941. First = 0;
  942. }
  943. }
  944. VOID
  945. WinDbgExtensionDllInit(
  946. PWINDBG_EXTENSION_APIS lpExtensionApis,
  947. USHORT MajorVersion,
  948. USHORT MinorVersion
  949. )
  950. {
  951. ExtensionApis = *lpExtensionApis;
  952. SavedMajorVersion = MajorVersion;
  953. SavedMinorVersion = MinorVersion;
  954. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  955. }
  956. DECLARE_API( version )
  957. {
  958. #if DBG
  959. PCSTR kind = "Checked";
  960. #else
  961. PCSTR kind = "Free";
  962. #endif
  963. dprintf(
  964. "%s SMB Extension dll for Build %d debugging %s kernel for Build %d\n",
  965. kind,
  966. VER_PRODUCTBUILD,
  967. SavedMajorVersion == 0x0c ? "Checked" : "Free",
  968. SavedMinorVersion
  969. );
  970. }
  971. VOID
  972. CheckVersion(
  973. VOID
  974. )
  975. {
  976. #if DBG
  977. if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  978. dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n",
  979. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  980. }
  981. #else
  982. if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) {
  983. dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n",
  984. VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" );
  985. }
  986. #endif
  987. }
  988. LPEXT_API_VERSION
  989. ExtensionApiVersion(
  990. VOID
  991. )
  992. {
  993. return &ApiVersion;
  994. }