#ifndef DBG #define DBG 1 #endif #define SRVDBG 1 #define SRVKD 1 #include #include #include #include #include #include #include #include #include #define NT #include #include #include #include #include #include WINDBG_EXTENSION_APIS ExtensionApis; EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER, 0 }; #define ERRPRT dprintf #define NL 1 #define NONL 0 USHORT SavedMajorVersion; USHORT SavedMinorVersion; BOOL ChkTarget; // is debuggee a CHK build? #define PROV_SIZE sizeof(TDI_PROVIDER_RESOURCE) + 32 CHAR provBuf[PROV_SIZE]; TDI_PROVIDER_RESOURCE *pProvider = (TDI_PROVIDER_RESOURCE *) provBuf; typedef struct _TDI_EXEC_PARAMS { LIST_ENTRY Linkage; UINT Signature; PLIST_ENTRY ClientList; PLIST_ENTRY ProviderList; PLIST_ENTRY RequestList; TDI_SERIALIZED_REQUEST Request; PETHREAD *CurrentThread; CTEEvent *RequestCTEEvent; PBOOLEAN SerializeFlag; BOOLEAN ResetSerializeFlag; } TDI_EXEC_PARAMS, *PTDI_EXEC_PARAMS; typedef struct { char Name[16]; int Val; } DBG_LEVEL; #if 0 DBG_LEVEL DbgLevel[] = { {"RXFRAME", DBG_RXFRAME }, {"TXFRAME", DBG_TXFRAME }, {"NDIS", DBG_NDIS }, {"IRMAC", DBG_IRMAC }, {"IRLAP", DBG_IRLAP }, {"IRLAPLOG", DBG_IRLAPLOG }, {"IRLMP", DBG_IRLMP }, {"IRLMP_CONN", DBG_IRLMP_CONN }, {"IRLMP_CRED", DBG_IRLMP_CRED }, {"IRLMP_IAS", DBG_IRLMP_IAS }, {"DISCOVERY", DBG_DISCOVERY }, {"TDI", DBG_TDI }, {"TDI_IRP", DBG_TDI_IRP }, {"ALLOC", DBG_ALLOC }, {"TIMER ", DBG_TIMER }, {"PRINT", DBG_PRINT }, {"ADDRESS", DBG_ADDR }, {"REFERENCE", DBG_REF }, {"FUNCTION", DBG_FUNCTION }, {"WARN", DBG_WARN }, {"ERROR", DBG_ERROR }}; char *IrlmpState[] = {"LINK_DISCONNECTED", "LINK_DISCONNECTING", "LINK_IN_DISCOVERY", "LINK_CONNECTING", "LINK_READY"}; char *LsapState[] = {"LSAP_DISCONNECTED", "LSAP_IRLAP_CONN_PEND", "LSAP_LMCONN_CONF_PEND", "LSAP_CONN_RESP_PEND", "LSAP_CONN_REQ_PEND", "LSAP_EXCLUSIVEMODE_PEND", "LSAP_MULTIPLEXEDMODE_PEND", "LSAP_READY", "LSAP_NO_TX_CREDIT"}; char *ConnObjState[] = {"IRDA_CONN_CREATED", "IRDA_CONN_CLOSING", "IRDA_CONN_OPENING", "IRDA_CONN_OPEN"}; #endif void TDIDumpDevice( TDI_PROVIDER_RESOURCE *prov ); void TDIDumpAddress( TDI_PROVIDER_RESOURCE *prov ); void TDIDumpProvider( TDI_PROVIDER_RESOURCE *prov ); /* * Print out an optional message, an ANSI_STRING, and maybe a new-line */ BOOL PrintStringA( IN LPSTR msg OPTIONAL, IN PANSI_STRING pStr, IN BOOL nl ) { PCHAR StringData; ULONG BytesRead; if( msg ) dprintf( msg ); if( pStr->Length == 0 ) { if( nl ) dprintf( "\n" ); return TRUE; } StringData = (PCHAR)LocalAlloc( LPTR, pStr->Length + 1 ); if( StringData == NULL ) { ERRPRT( "Out of memory!\n" ); return FALSE; } ReadMemory((ULONG) pStr->Buffer, StringData, pStr->Length, &BytesRead ); if ( BytesRead ) { StringData[ pStr->Length ] = '\0'; dprintf("%s%s", StringData, nl ? "\n" : "" ); } LocalFree((HLOCAL)StringData); return BytesRead; } /* * Get 'size' bytes from the debuggee program at 'dwAddress' and place it * in our address space at 'ptr'. Use 'type' in an error printout if necessary */ BOOL GetData( IN LPVOID ptr, IN DWORD dwAddress, IN ULONG size, IN PCSTR type ) { BOOL b; ULONG BytesRead; ULONG count = size; while( size > 0 ) { if (count >= 3000) count = 3000; b = ReadMemory((ULONG) dwAddress, ptr, count, &BytesRead ); if (!b || BytesRead != count ) { ERRPRT( "Unable to read %u bytes at %X, for %s\n", size, dwAddress, type ); return FALSE; } dwAddress += count; size -= count; ptr = (LPVOID)((ULONG)ptr + count); } return TRUE; } /* * Follow a LIST_ENTRY list beginning with a head at dwListHeadAddr in the debugee's * address space. For each element in the list, print out the pointer value at 'offset' */ BOOL PrintListEntryList( IN DWORD dwListHeadAddr, IN LONG offset ) { LIST_ENTRY ListEntry; ULONG i=0; BOOL retval = TRUE; ULONG count = 20; if( !GetData( &ListEntry, dwListHeadAddr, sizeof( ListEntry ), "LIST_ENTRY" ) ) return FALSE; while( count-- ) { if( (DWORD)ListEntry.Flink == dwListHeadAddr || (DWORD)ListEntry.Flink == 0 ) break; if( !GetData( &ListEntry, (DWORD)ListEntry.Flink, sizeof( ListEntry ), "ListEntry" ) ) { retval = FALSE; break; } dprintf( "%16X%s", (LONG)ListEntry.Flink + offset, (i && !(i&3)) ? "\n" : "" ); i++; } if( count == 0 && (DWORD)ListEntry.Flink != dwListHeadAddr && ListEntry.Flink ) { dprintf( "\nTruncated list dump\n" ); } else if( ! ( i && !(i&3) ) ) { dprintf( "\n" ); } return retval; } /* * Print out a single HEX character */ VOID PrintHexChar( IN UCHAR c ) { dprintf( "%c%c", "0123456789abcdef"[ (c>>4)&0xf ], "0123456789abcdef"[ c&0xf ] ); } /* * Print out 'buf' of 'cbuf' bytes as HEX characters */ VOID PrintHexBuf( IN PUCHAR buf, IN ULONG cbuf ) { while( cbuf-- ) { PrintHexChar( *buf++ ); dprintf( " " ); } } /* * Fetch the null terminated UNICODE string at dwAddress into buf */ BOOL GetString( IN DWORD dwAddress, IN LPSTR buf, IN ULONG MaxChars ) { do { if( !GetData( buf, dwAddress, sizeof( *buf ), "Character" ) ) return FALSE; dwAddress += sizeof( *buf ); } while( --MaxChars && *buf++ != '\0' ); return TRUE; } char *mystrtok ( char *string, char * control ) { static unsigned char *str; char *p, *s; if( string ) str = string; if( str == NULL || *str == '\0' ) return NULL; // // Skip leading delimiters... // for( ; *str; str++ ) { for( s=control; *s; s++ ) { if( *str == *s ) break; } if( *s == '\0' ) break; } // // Was it was all delimiters? // if( *str == '\0' ) { str = NULL; return NULL; } // // We've got a string, terminate it at first delimeter // for( p = str+1; *p; p++ ) { for( s = control; *s; s++ ) { if( *p == *s ) { s = str; *p = '\0'; str = p+1; return s; } } } // // We've got a string that ends with the NULL // s = str; str = NULL; return s; } DECLARE_API( help ) { int i; dprintf("TDI extenstions:\n"); dprintf(" All dumps All Lists\n"); dprintf(" Providers dumps Providers List\n"); dprintf(" Clients dumps Clients List\n"); dprintf(" Request dumps Request List\n"); dprintf(" Address dumps Provider Addresses\n"); dprintf(" Devices dumps Provider Device Objects\n"); dprintf(" ProviderReady dumps Provider Device Objects\n"); dprintf(" item formats a TDI_REQUEST structure\n"); } #if 0 DECLARE_API( dbgmsgs ) { DWORD p; DWORD Last, First; char DbgMsg[MAX_MSG_LEN]; ULONG Read; char *DbgMsgs; if (!GetData(&Last, GetExpression("irda!Last"), sizeof(Last), "DWORD")) { dprintf("error\n"); return; } if (!GetData(&First, GetExpression("irda!First"), sizeof(Last), "DWORD")) { dprintf("error\n"); return; } DbgMsgs = (char *) GetExpression("irda!dbgmsgs"); dprintf("\n\n"); while (First != Last) { if (!GetString((ULONG) (DbgMsgs + First * MAX_MSG_LEN), DbgMsg, MAX_MSG_LEN)) break; /* ReadMemory((ULONG) (DbgMsgs + First * MAX_MSG_LEN), DbgMsg, MAX_MSG_LEN, &Read); */ dprintf("%s", DbgMsg); First++; if (First == LOG_MSG_CNT) First = 0; } } DECLARE_API( dbg ) { int i; int col = 0; DWORD DbgSettings; char argbuf[ MAX_PATH ]; char *p; DWORD dwAddress; DWORD Written; dwAddress = GetExpression("irda!dbgsettings"); if (!GetData(&DbgSettings, dwAddress, sizeof(DbgSettings), "DWORD")) { dprintf("error\n"); return; } if (!args || !*args) { dprintf("Current settings:\n"); for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++) { if (DbgSettings & DbgLevel[i].Val) { dprintf(" %s", DbgLevel[i].Name); if (col == 4) { col = 0; dprintf("\n"); } else { col ++; } } } if (col != 0) dprintf("\n"); col = 0; dprintf("Available settings:\n"); for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++) { if (!(DbgSettings & DbgLevel[i].Val)) { dprintf(" %s", DbgLevel[i].Name); if (col == 4) { col = 0; dprintf("\n"); } else { col++; } } } if (col != 0) dprintf("\n"); return; } strcpy( argbuf, args ); for (p = mystrtok( argbuf, " \t,;" ); p && *p; p = mystrtok(NULL, " \t,;")) { for (i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++) { if (strcmp(p, DbgLevel[i].Name) == 0) { if (DbgSettings & DbgLevel[i].Val) { DbgSettings &= ~DbgLevel[i].Val; } else { DbgSettings |= DbgLevel[i].Val; } } } } WriteMemory(dwAddress, &DbgSettings, sizeof(DWORD), &Written); } VOID DumpIrpList(LIST_ENTRY *pIrpList) { LIST_ENTRY IrpList, *pListEntry, ListEntry; IRP *pIrp; if (!GetData(&IrpList, (DWORD) pIrpList, sizeof(LIST_ENTRY), "LIST_ENTRY")) { return; } for (pListEntry = IrpList.Flink; pListEntry != pIrpList; pListEntry = ListEntry.Flink) { if (!GetData(&ListEntry, (DWORD) pListEntry, sizeof(LIST_ENTRY), "LIST_ENTRY")) { return; } pIrp = CONTAINING_RECORD(pListEntry, IRP, Tail.Overlay.ListEntry); dprintf(" %x\n", pIrp); } } #endif #define PROV_TYPE 1 #define CLIENT_TYPE 2 #define NEITHER 3 DECLARE_API( request ) { LIST_ENTRY List, *pList, *start; TDI_EXEC_PARAMS TdiExec; TDI_SERIALIZED_REQUEST Request; BOOLEAN ElementTypeProvider = NEITHER; TDI_NOTIFY_PNP_ELEMENT Client; INT i = 1; pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerRequestList"); if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "REQUEST_LIST")) { return; } if (List.Flink == List.Blink) { dprintf("No Requests\n"); return; } start = pList; pList = List.Flink; while (pList != start) { if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "REQUEST_LIST")) { return; } if (!GetData(&TdiExec, (DWORD) pList, sizeof(TDI_EXEC_PARAMS), "EXEC PARAMS")) { return; } if(0x1234cdef != TdiExec.Signature) { dprintf("signature is BAD - %d not 0x1234cdef\r\n", TdiExec.Signature); return; } if (!GetData(&Request, (DWORD) &TdiExec.Request, sizeof (TDI_SERIALIZED_REQUEST), "REQUEST")) { return; } dprintf("%d. Request(%X) Element @ %x\t Type: ", i++, Request.Element); switch (Request.Type) { case TDI_REGISTER_HANDLERS_PNP: dprintf("TDI_REGISTER_HANDLERS_PNP\n"); ElementTypeProvider = CLIENT_TYPE; break; case TDI_DEREGISTER_HANDLERS_PNP: dprintf("TDI_DEREGISTER_HANDLERS_PNP\n"); ElementTypeProvider = CLIENT_TYPE; break; case TDI_REGISTER_PNP_POWER_EVENT: dprintf("TDI_REGISTER_PNP_POWER_EVENT\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_REGISTER_ADDRESS_PNP: dprintf("TDI_REGISTER_ADDRESS_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_DEREGISTER_ADDRESS_PNP: dprintf("TDI_DEREGISTER_ADDRESS_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_REGISTER_DEVICE_PNP: dprintf("TDI_REGISTER_DEVICE_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_DEREGISTER_DEVICE_PNP: dprintf("TDI_DEREGISTER_DEVICE_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_NDIS_IOCTL_HANDLER_PNP: dprintf("TDI_NDIS_IOCTL_HANDLER_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_ENUMERATE_ADDRESSES: dprintf("TDI_ENUMERATE_ADDRESSES\n"); ElementTypeProvider = CLIENT_TYPE; break; case TDI_REGISTER_PROVIDER_PNP: dprintf("TDI_REGISTER_PROVIDER_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_DEREGISTER_PROVIDER_PNP: dprintf("TDI_DEREGISTER_PROVIDER_PNP\n"); ElementTypeProvider = PROV_TYPE; break; case TDI_PROVIDER_READY_PNP: dprintf("TDI_PROVIDER_READY_PNP\n"); ElementTypeProvider = PROV_TYPE; break; default: dprintf("TDI - UNKNOWN REQUEST TYPE!!!\n"); ElementTypeProvider = NEITHER; break; } if (PROV_TYPE == ElementTypeProvider) { if (!GetData(pProvider, (DWORD) Request.Element, PROV_SIZE, "PROVIDER_RESOURCE")) { return; } if(TDI_RESOURCE_DEVICE == pProvider->Common.Type) { TDIDumpDevice(pProvider); } else if (TDI_RESOURCE_NET_ADDRESS == pProvider->Common.Type) { TDIDumpAddress(pProvider); } else if (TDI_RESOURCE_PROVIDER == pProvider->Common.Type) { TDIDumpProvider(pProvider); } else { dprintf("Unknown type: %x\n", ElementTypeProvider); return; } } else if (CLIENT_TYPE == ElementTypeProvider) { if (!GetData(&Client, (DWORD) Request.Element, sizeof (TDI_NOTIFY_PNP_ELEMENT), "CLIENT_RESOURCE")) { return; } dprintf("Its a client!\n Need to add some code for this \n"); } else { dprintf("Unknown element type on request list\n"); } dprintf("\n--------------------------------------------------------\n"); //Print(TdiExec.Request); pList = List.Flink; } } /* typedef struct _TDI_PROVIDER_RESOURCE { TDI_PROVIDER_COMMON Common; // defined in netpnp.h PNET_PNP_EVENT PnpPowerEvent; // Each TDI Client gets back and tells us what the status NTSTATUS Status; // These are mostly Address Specific. PTDI_PNP_CONTEXT Context1; PTDI_PNP_CONTEXT Context2; KEVENT PowerSyncEvent; ULONG PowerHandlers; PVOID PreviousContext; union { TDI_PROVIDER_DEVICE Device; TDI_PROVIDER_NET_ADDRESS NetAddress; } Specific; */ DECLARE_API( providers ) { LIST_ENTRY List, *pList, *start; pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList"); if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (List.Flink == List.Blink) { dprintf("No Providers\n"); return; } dprintf("---------------------------------------------------------------------\n"); start = pList; pList = List.Flink; while (List.Flink != start) { if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (!GetData(pProvider, (DWORD) pList, PROV_SIZE, "PROVIDER_RESOURCE")) { return; } dprintf("Entry: %X\n", pList); if(TDI_RESOURCE_DEVICE == pProvider->Common.Type) { TDIDumpDevice(pProvider); } else if (TDI_RESOURCE_NET_ADDRESS == pProvider->Common.Type) { TDIDumpAddress(pProvider); } else if (TDI_RESOURCE_PROVIDER == pProvider->Common.Type) { TDIDumpProvider(pProvider); } else { dprintf("Unknown type: %x\n", pProvider->Common.Type); return; } dprintf("---------------------------------------------------------------------\n"); //Print(TdiExec.Request); pList = List.Flink; } } DECLARE_API( devices ) { LIST_ENTRY List, *pList, *start; pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList"); if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (List.Flink == List.Blink) { dprintf("No Devices\n"); return; } start = pList; pList = List.Flink; dprintf("---------------------------------------------------------------------\n"); while (List.Flink != start) { if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (!GetData(pProvider, (DWORD) pList, PROV_SIZE, "PROVIDER_RESOURCE")) { return; } if(TDI_RESOURCE_DEVICE == pProvider->Common.Type) { dprintf("Entry: %X\n", pList); TDIDumpDevice(pProvider); dprintf("---------------------------------------------------------------------\n"); } //Print(TdiExec.Request); pList = List.Flink; } } DECLARE_API( providerready ) { LIST_ENTRY List, *pList, *start; pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList"); if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (List.Flink == List.Blink) { dprintf("No Devices\n"); return; } start = pList; pList = List.Flink; dprintf("---------------------------------------------------------------------\n"); while (List.Flink != start) { if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (!GetData(pProvider, (DWORD) pList, PROV_SIZE, "PROVIDER_RESOURCE")) { return; } if (TDI_RESOURCE_PROVIDER == pProvider->Common.Type) { dprintf("Entry: %X\n", pList); TDIDumpProvider(pProvider); dprintf("---------------------------------------------------------------------\n"); } //Print(TdiExec.Request); pList = List.Flink; } } DECLARE_API( addresses ) { LIST_ENTRY List, *pList, *start; pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerProviderList"); if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (List.Flink == List.Blink) { dprintf("No Devices\n"); return; } start = pList; pList = List.Flink; dprintf("---------------------------------------------------------------------\n"); while (List.Flink != start) { if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "PROVIDER_LIST")) { return; } if (!GetData(pProvider, (DWORD) pList, PROV_SIZE, "PROVIDER_RESOURCE")) { return; } if (TDI_RESOURCE_NET_ADDRESS == pProvider->Common.Type) { dprintf("Entry: %X\n", pList); TDIDumpAddress(pProvider); dprintf("---------------------------------------------------------------------\n"); } //Print(TdiExec.Request); pList = List.Flink; } } void TDIDumpDevice( TDI_PROVIDER_RESOURCE *pProvider ) { CHAR *Buffer; Buffer = malloc (sizeof(WCHAR) * pProvider->Specific.Device.DeviceName.MaximumLength); if (!Buffer) { dprintf("Cant alloc memory\n"); return; } if (!GetData(Buffer, (DWORD) pProvider->Specific.Device.DeviceName.Buffer, pProvider->Specific.Device.DeviceName.MaximumLength, "PROVIDER_LIST")) { free(Buffer); return; } dprintf("Device: %ws\n", Buffer); free(Buffer); return; } void TDIDumpAddress( TDI_PROVIDER_RESOURCE *prov ) { int j; //dprintf ("ADDRESS: len %d ", prov->Specific.NetAddress.Address.AddressLength); if (prov->Specific.NetAddress.Address.AddressType == TDI_ADDRESS_TYPE_IP) { dprintf("Type: IP\n"); dprintf("Address: %d.%d.%d.%d\n", prov->Specific.NetAddress.Address.Address[2], prov->Specific.NetAddress.Address.Address[3], prov->Specific.NetAddress.Address.Address[4], prov->Specific.NetAddress.Address.Address[5]); } else if (prov->Specific.NetAddress.Address.AddressType == TDI_ADDRESS_TYPE_NETBIOS) { if (prov->Specific.NetAddress.Address.Address[2] == '\0') { dprintf("Type: NETBIOS reserved\n"); dprintf("Address: %02x %02x %02x %02x %02x %02x\n", (ULONG)(prov->Specific.NetAddress.Address.Address[12]), (ULONG)(prov->Specific.NetAddress.Address.Address[13]), (ULONG)(prov->Specific.NetAddress.Address.Address[14]), (ULONG)(prov->Specific.NetAddress.Address.Address[15]), (ULONG)(prov->Specific.NetAddress.Address.Address[16]), (ULONG)(prov->Specific.NetAddress.Address.Address[17])); } else { dprintf("Type: NETBIOS\n"); dprintf("Address: %.16s\n", prov->Specific.NetAddress.Address.Address+2); } } else { dprintf("Type: %d\n", prov->Specific.NetAddress.Address.AddressType); dprintf("Address: "); for (j = 0; j < prov->Specific.NetAddress.Address.AddressLength; j++) { dprintf ("%02x ", (ULONG)(prov->Specific.NetAddress.Address.Address[j])); } dprintf ("\n"); } dprintf("Context1: %x\n", prov->Context1); dprintf("Context2: %x\n", prov->Context2); } void TDIDumpProvider( TDI_PROVIDER_RESOURCE *pProvider ) { CHAR *Buffer; Buffer = malloc (sizeof(WCHAR) * pProvider->Specific.Device.DeviceName.MaximumLength); if (!Buffer) { dprintf("Cant alloc memory\n"); return; } if (!GetData(Buffer, (DWORD) pProvider->Specific.Device.DeviceName.Buffer, pProvider->Specific.Device.DeviceName.MaximumLength, "PROVIDER_LIST")) { free(Buffer); return; } dprintf("Provider: %ws\n", Buffer); if (pProvider->ProviderReady) { dprintf("Ready: yes\n"); } else { dprintf("Ready: no\n"); } free(Buffer); return; } DECLARE_API( clients ) { LIST_ENTRY List, *pList, *start; TDI_NOTIFY_PNP_ELEMENT client; CHAR *Buffer; pList = (PLIST_ENTRY) GetExpression("tdi!PnpHandlerClientList"); if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "CLIENT_LIST1")) { return; } if (List.Flink == List.Blink) { dprintf("No Clients\n"); return; } start = pList; pList = List.Flink; dprintf("---------------------------------------------------------------------\n"); while (List.Flink != start) { if (!GetData(&List, (DWORD) pList, sizeof(LIST_ENTRY), "CLIENT_LIST2")) { return; } dprintf("Entry: %x\n", pList); if (!GetData(&client, (DWORD) pList, sizeof(TDI_NOTIFY_PNP_ELEMENT), "CLIENT_RESOURCE")) { return; } Buffer = malloc (sizeof(WCHAR) * client.ElementName.MaximumLength); if (!Buffer) { dprintf("Cant alloc memory\n"); return; } if (!GetData(Buffer, (DWORD) client.ElementName.Buffer, client.ElementName.MaximumLength, "CLIENT_LIST3")) { free(Buffer); return; } dprintf("Name: %ws\n", Buffer); free(Buffer); dprintf("Version: %x.%x\n", (client.TdiVersion), (0xff & (client.TdiVersion >> 8))); if (TDI_VERSION_ONE == client.TdiVersion) { dprintf("BindHandler: %lx\n", client.Bind.BindHandler); dprintf("UnBindHandler: %lx\n", client.Bind.UnbindHandler); } else { dprintf("BindingHandler: %lx\n", client.BindingHandler); } dprintf("AddAddressHandler: %lx\n", client.AddressElement.AddHandler); dprintf("DeleteAddressHandler: %lx\n", client.AddressElement.DeleteHandler); //dprintf("List of Interested Providers: %lx\n", client.AddressElement.ListofProviders); if (TDI_VERSION_ONE != client.TdiVersion) { dprintf("PnPPowerHandler: %lx\n", client.PnpPowerHandler); } dprintf("---------------------------------------------------------------------\n"); //Print(TdiExec.Request); pList = List.Flink; } } DECLARE_API( dbgmsgs ) { DWORD p; DWORD Last, First; char DbgMsg[MAX_MSG_LEN]; ULONG Read; char *DbgMsgs; if (!GetData(&Last, GetExpression("tdi!Last"), sizeof(Last), "DWORD")) { dprintf("1. error\n"); return; } if (!GetData(&First, GetExpression("tdi!First"), sizeof(Last), "DWORD")) { dprintf("2. error\n"); return; } DbgMsgs = (char *) GetExpression("tdi!dbgmsgs"); dprintf("\n\n"); while (First != Last) { if (!GetString((ULONG) (DbgMsgs + First * MAX_MSG_LEN), DbgMsg, MAX_MSG_LEN)) break; /* ReadMemory((ULONG) (DbgMsgs + First * MAX_MSG_LEN), DbgMsg, MAX_MSG_LEN, &Read); */ dprintf("%s", DbgMsg); First++; if (First == LOG_MSG_CNT) First = 0; } } VOID WinDbgExtensionDllInit( PWINDBG_EXTENSION_APIS lpExtensionApis, USHORT MajorVersion, USHORT MinorVersion ) { ExtensionApis = *lpExtensionApis; SavedMajorVersion = MajorVersion; SavedMinorVersion = MinorVersion; ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE; } DECLARE_API( version ) { #if DBG PCSTR kind = "Checked"; #else PCSTR kind = "Free"; #endif dprintf( "%s SMB Extension dll for Build %d debugging %s kernel for Build %d\n", kind, VER_PRODUCTBUILD, SavedMajorVersion == 0x0c ? "Checked" : "Free", SavedMinorVersion ); } VOID CheckVersion( VOID ) { #if DBG if ((SavedMajorVersion != 0x0c) || (SavedMinorVersion != VER_PRODUCTBUILD)) { dprintf("\r\n*** Extension DLL(%d Checked) does not match target system(%d %s)\r\n\r\n", VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" ); } #else if ((SavedMajorVersion != 0x0f) || (SavedMinorVersion != VER_PRODUCTBUILD)) { dprintf("\r\n*** Extension DLL(%d Free) does not match target system(%d %s)\r\n\r\n", VER_PRODUCTBUILD, SavedMinorVersion, (SavedMajorVersion==0x0f) ? "Free" : "Checked" ); } #endif } LPEXT_API_VERSION ExtensionApiVersion( VOID ) { return &ApiVersion; }