/*++ Copyright (c) 1997 FORE Systems, Inc. Copyright (c) 1997 Microsoft Corporation Module Name: atmlane.c Abstract: ATM LAN Emulation Client Admin Utility. Usage: atmlane Revision History: Who When What -------- -------- --------------------------------------------- v-lcleet 02-03-98 Created Notes: Modelled after atmadm utility from the UNI 3.1 Call Manager --*/ #include #include #include #include #include #include #include #include #include #include #include #include #ifndef NDIS_STATUS #define NDIS_STATUS ULONG #endif #include "laneinfo.h" #include "atmmsg.h" // // Private types // typedef struct { DWORD Message; LPSTR String; } MESSAGE_STRING, *PMESSAGE_STRING; #define MSG_NO_MESSAGE 0 #define MAX_ATMLANE_ADAPTERS 64 #define MAX_ATMLANE_ELANS 64 #define MAX_ATMLANE_NAME_LEN 256 #define MAX_ATMLANE_ARP_ENTRIES 4096 #define MAX_ATMLANE_CONNECTIONS 4096 // // Globals // CHAR DefaultDeviceName[] = "\\\\.\\AtmLane"; CHAR *pDeviceName = DefaultDeviceName; // // Data structures to store list of adapters: // #define ADAPTER_LIST_BUFFER_SIZE (sizeof(ATMLANE_ADAPTER_LIST) + \ (MAX_ATMLANE_ADAPTERS * \ (sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR))))) UCHAR AdapterListBuffer[ADAPTER_LIST_BUFFER_SIZE]; PATMLANE_ADAPTER_LIST pAdapterList = (PATMLANE_ADAPTER_LIST)AdapterListBuffer; // // Data structures to store list of ELANS on an adapter: // #define ELAN_LIST_BUFFER_SIZE (sizeof(ATMLANE_ELAN_LIST) + \ (MAX_ATMLANE_ELANS * \ (sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR))))) UCHAR ElanListBuffer[ELAN_LIST_BUFFER_SIZE]; PATMLANE_ELAN_LIST pElanList = (PATMLANE_ELAN_LIST)ElanListBuffer; // // Data structure to hold ELAN information // #define ELAN_INFO_BUFFER_SIZE (sizeof(ATMLANE_ELANINFO) + \ ((sizeof(UNICODE_STRING) + (MAX_ATMLANE_NAME_LEN * sizeof(WCHAR))) * 2)) UCHAR ElanInfoBuffer[ELAN_INFO_BUFFER_SIZE]; PATMLANE_ELANINFO pElanInfo = (PATMLANE_ELANINFO)ElanInfoBuffer; // // Data structure to hold an ELAN's ARP table // #define ARP_TABLE_BUFFER_SIZE (sizeof(ATMLANE_ARPTABLE) + \ ((sizeof(ATMLANE_ARPENTRY) * MAX_ATMLANE_ARP_ENTRIES))) UCHAR ArpTableBuffer[ARP_TABLE_BUFFER_SIZE]; PATMLANE_ARPTABLE pArpTable = (PATMLANE_ARPTABLE)ArpTableBuffer; // // Data structure to hold an ELAN's connection table // #define CONN_TABLE_BUFFER_SIZE (sizeof(ATMLANE_CONNECTTABLE) + \ ((sizeof(ATMLANE_CONNECTENTRY) * MAX_ATMLANE_CONNECTIONS))) UCHAR ConnTableBuffer[CONN_TABLE_BUFFER_SIZE]; PATMLANE_CONNECTTABLE pConnTable = (PATMLANE_CONNECTTABLE)ConnTableBuffer; // // Internationalizable message strings loaded by this module. If we fail // to load, default to English language strings. // MESSAGE_STRING ElanState[] = { MSG_ELAN_STATE_UNKNOWN, TEXT(" ? "), MSG_ELAN_STATE_INIT, TEXT("INITIAL"), MSG_ELAN_STATE_LECS_CONNECT_ILMI, TEXT("LECS CONNECT ILMI"), MSG_ELAN_STATE_LECS_CONNECT_WKA, TEXT("LECS CONNECT WKA"), MSG_ELAN_STATE_LECS_CONNECT_PVC, TEXT("LECS CONNECT PVC"), MSG_ELAN_STATE_LECS_CONNECT_CFG, TEXT("LECS CONNECT CFG"), MSG_ELAN_STATE_CONFIGURE, TEXT("CONFIGURE"), MSG_ELAN_STATE_LES_CONNECT, TEXT("LES CONNECT"), MSG_ELAN_STATE_JOIN, TEXT("JOIN"), MSG_ELAN_STATE_BUS_CONNECT, TEXT("BUS CONNECT"), MSG_ELAN_STATE_OPERATIONAL, TEXT("OPERATIONAL"), MSG_ELAN_STATE_SHUTDOWN, TEXT("SHUTDOWN") }; #define NUMBER_OF_ELAN_STATES (sizeof(ElanState)/sizeof(ElanState[0])) MESSAGE_STRING LanType[] = { MSG_LANTYPE_UNKNOWN, TEXT(" ? "), MSG_LANTYPE_UNSPECIFIED, TEXT("Unspecified"), MSG_LANTYPE_ETHERNET, TEXT("Ethernet/802.3"), MSG_LANTYPE_TOKENRING, TEXT("Token Ring/802.5") }; #define NUMBER_OF_LAN_TYPES (sizeof(LanType)/sizeof(LanType[0])) MESSAGE_STRING VcType[] = { MSG_VCTYPE_UNKNOWN, TEXT(" ? "), MSG_VCTYPE_DATA_DIRECT, TEXT("DataDirect"), MSG_VCTYPE_CONFIG_DIRECT, TEXT("ConfigDirect"), MSG_VCTYPE_CONTROL_DIRECT, TEXT("CtrlDirect"), MSG_VCTYPE_CONTROL_DISTRIBUTE, TEXT("+ CtrlDistr"), MSG_VCTYPE_MULTI_SEND, TEXT("McastSend"), MSG_VCTYPE_MULTI_FORWARD, TEXT("+ McastFwd") }; #define NUMBER_OF_VC_TYPES (sizeof(VcType)/sizeof(VcType[0])) MESSAGE_STRING McastSendVcType[] = { MSG_MCAST_VCTYPE_UNKNOWN, TEXT(" ? "), MSG_MCAST_VCTYPE_BESTEFFORT, TEXT("Best Effort"), MSG_MCAST_VCTYPE_VARIABLE, TEXT("Variable"), MSG_MCAST_VCTYPE_VARIABLE, TEXT("Constant"), }; #define NUMBER_OF_MCAST_VC_TYPES (sizeof(McastSendVcType)/sizeof(McastSendVcType[0])) MESSAGE_STRING Misc[] = { MSG_NONE, TEXT("None"), MSG_OFF, TEXT("Off"), MSG_ON, TEXT("On"), MSG_UNSPECIFIED, TEXT("Unspecified"), MSG_NOCONNECT, TEXT("") }; #define NUMBER_OF_MISC (sizeof(Misc)/sizeof(Misc[0])) MESSAGE_STRING ConnType[] = { MSG_CONNTYPE_PEER, TEXT("PEER"), MSG_CONNTYPE_LECS, TEXT("LECS"), MSG_CONNTYPE_LES, TEXT("LES "), MSG_CONNTYPE_BUS, TEXT("BUS ") }; #define NUMBER_OF_CONN_TYPES (sizeof(ConnType)/sizeof(ConnType[0])) // // LoadMessageTable // // Loads internationalizable strings into a table, replacing the default for // each. If an error occurs, the English language default is left in place. // // VOID LoadMessageTable( PMESSAGE_STRING Table, UINT MessageCount ) { LPTSTR string; DWORD count; // // for all messages in a MESSAGE_STRING table, load the string from this // module, replacing the default string in the table (only there in case // we get an error while loading the string, so we at least have English // to fall back on) // while (MessageCount--) { if (Table->Message != MSG_NO_MESSAGE) { // // we really want LoadString here, but LoadString doesn't indicate // how big the string is, so it doesn't give us an opportunity to // allocate exactly the right buffer size. FormatMessage does the // right thing // count = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, NULL, // use default hModule Table->Message, 0, // use default language (LPTSTR)&string, 0, // minimum size to allocate NULL // no arguments for inclusion in strings ); if (count) { // // Format message returned the string: replace the English // language default // Table->String = string; } else { // // this is ok if there is no string (e.g. just %0) in the .mc // file // Table->String = TEXT(""); } } ++Table; } } // // LoadMessages - courtesy IPCONFIG // // Loads all internationalizable messages into the various tables // VOID LoadMessages( ) { LoadMessageTable(ElanState, NUMBER_OF_ELAN_STATES); LoadMessageTable(LanType, NUMBER_OF_LAN_TYPES); LoadMessageTable(VcType, NUMBER_OF_VC_TYPES); LoadMessageTable(McastSendVcType, NUMBER_OF_MCAST_VC_TYPES); LoadMessageTable(Misc, NUMBER_OF_MISC); LoadMessageTable(ConnType, NUMBER_OF_CONN_TYPES); } VOID DisplayMessage( IN BOOLEAN Tabbed, IN DWORD MessageId, ... ) { va_list pArg; CHAR MessageBuffer[2048]; INT Count; va_start(pArg, MessageId); Count = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE, NULL, // default hModule MessageId, 0, // default language MessageBuffer, sizeof(MessageBuffer), &pArg ); va_end(pArg); if (Tabbed) { putchar('\t'); } printf(MessageBuffer); } HANDLE OpenDevice( CHAR *pDeviceName ) { DWORD DesiredAccess; DWORD ShareMode; LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL; DWORD CreationDistribution; DWORD FlagsAndAttributes; HANDLE TemplateFile; HANDLE Handle; DesiredAccess = GENERIC_READ|GENERIC_WRITE; ShareMode = 0; CreationDistribution = OPEN_EXISTING; FlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; TemplateFile = (HANDLE)INVALID_HANDLE_VALUE; Handle = CreateFile( pDeviceName, DesiredAccess, ShareMode, lpSecurityAttributes, CreationDistribution, FlagsAndAttributes, TemplateFile ); return (Handle); } VOID CloseDevice( HANDLE DeviceHandle ) { CloseHandle(DeviceHandle); } BOOLEAN CheckVersion( HANDLE DeviceHandle ) { ULONG Version; ULONG BytesReturned; if (!DeviceIoControl( DeviceHandle, ATMLANE_IOCTL_GET_INFO_VERSION, (PVOID)&Version, sizeof(Version), (PVOID)&Version, sizeof(Version), &BytesReturned, 0)) { DisplayMessage(FALSE, MSG_ERROR_GETTING_VERSION_INFO); return FALSE; } if (Version != ATMLANE_INFO_VERSION) { DisplayMessage(FALSE, MSG_ERROR_INVALID_INFO_VERSION); return FALSE; } return TRUE; } BOOLEAN GetAdapterList( HANDLE DeviceHandle ) { ULONG BytesReturned; BOOLEAN Result = FALSE; if (DeviceIoControl( DeviceHandle, ATMLANE_IOCTL_ENUM_ADAPTERS, (PVOID)pAdapterList, ADAPTER_LIST_BUFFER_SIZE, (PVOID)pAdapterList, ADAPTER_LIST_BUFFER_SIZE, &BytesReturned, 0)) { Result = TRUE; } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ADAPTER_LIST); } return Result; } BOOLEAN GetElanList( HANDLE DeviceHandle, PUNICODE_STRING pAdapterName ) { ULONG BytesReturned; BOOLEAN Result = FALSE; // // Copy adapter name in to buffer as input // memcpy(pElanList, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length); if (DeviceIoControl( DeviceHandle, ATMLANE_IOCTL_ENUM_ELANS, (PVOID)pElanList, sizeof(UNICODE_STRING)+pAdapterName->Length, (PVOID)pElanList, ELAN_LIST_BUFFER_SIZE, &BytesReturned, 0)) { Result = TRUE; } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_LIST); } return Result; } BOOLEAN GetElanInfo( HANDLE DeviceHandle, PUNICODE_STRING pAdapterName, PUNICODE_STRING pElanName ) { ULONG BytesReturned; BOOLEAN Result = FALSE; // // copy adapter name into buffer as input // memcpy(ElanInfoBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length); // // copy elan name in to buffer as input // memcpy(ElanInfoBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName, sizeof(UNICODE_STRING)+pElanName->Length); if (DeviceIoControl( DeviceHandle, ATMLANE_IOCTL_GET_ELAN_INFO, (PVOID)pElanInfo, sizeof(UNICODE_STRING)+pAdapterName->Length + sizeof(UNICODE_STRING)+pElanName->Length, (PVOID)pElanInfo, ELAN_INFO_BUFFER_SIZE, &BytesReturned, 0)) { Result = TRUE; } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_INFO); } return Result; } BOOLEAN GetElanArpTable( HANDLE DeviceHandle, PUNICODE_STRING pAdapterName, PUNICODE_STRING pElanName ) { ULONG BytesReturned; BOOLEAN Result = FALSE; // // copy adapter name into buffer as input // memcpy(ArpTableBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length); // // copy elan name in to buffer as input // memcpy(ArpTableBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName, sizeof(UNICODE_STRING)+pElanName->Length); if (DeviceIoControl( DeviceHandle, ATMLANE_IOCTL_GET_ELAN_ARP_TABLE, (PVOID)pArpTable, sizeof(UNICODE_STRING)+pAdapterName->Length + sizeof(UNICODE_STRING)+pElanName->Length, (PVOID)pArpTable, ARP_TABLE_BUFFER_SIZE, &BytesReturned, 0)) { Result = TRUE; } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_ARP_TABLE); } return Result; } BOOLEAN GetElanConnTable( HANDLE DeviceHandle, PUNICODE_STRING pAdapterName, PUNICODE_STRING pElanName ) { ULONG BytesReturned; BOOLEAN Result = FALSE; // // copy adapter name into buffer as input // memcpy(ConnTableBuffer, pAdapterName, sizeof(UNICODE_STRING)+pAdapterName->Length); // // copy elan name in to buffer as input // memcpy(ConnTableBuffer + sizeof(UNICODE_STRING)+pAdapterName->Length, pElanName, sizeof(UNICODE_STRING)+pElanName->Length); if (DeviceIoControl( DeviceHandle, ATMLANE_IOCTL_GET_ELAN_CONNECT_TABLE, (PVOID)pConnTable, sizeof(UNICODE_STRING)+pAdapterName->Length + sizeof(UNICODE_STRING)+pElanName->Length, (PVOID)pConnTable, CONN_TABLE_BUFFER_SIZE, &BytesReturned, 0)) { Result = TRUE; } else { DisplayMessage(FALSE, MSG_ERROR_GETTING_ELAN_CONN_TABLE); } return Result; } LPSTR ElanStateToString(ULONG In) { switch(In) { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: return (ElanState[In].String); default: return (ElanState[0].String); } } LPSTR ElanLanTypeToString(ULONG In) { switch(In) { case 0: return LanType[1].String; case 1: return LanType[2].String; case 2: return LanType[3].String; default: return LanType[0].String; } } LPSTR ElanMaxFrameSizeToString(ULONG In) { switch(In) { case 0: return Misc[3].String; case 1: return "1516"; case 2: return "4544"; case 3: return "9234"; case 4: return "18190"; default: return " ? "; } } LPSTR McastVcTypeToString(ULONG In) { switch(In) { case 0: return McastSendVcType[1].String; case 1: return McastSendVcType[2].String; case 2: return McastSendVcType[3].String; default: return McastSendVcType[0].String; } } PUCHAR MacAddrToString(PVOID In) { static UCHAR String[20]; static PUCHAR HexChars = "0123456789abcdef"; PUCHAR EthAddr = (PUCHAR) In; UINT i; PUCHAR s; for (i = 0, s = String; i < 6; i++, EthAddr++) { *s++ = HexChars[(*EthAddr)>>4]; *s++ = HexChars[(*EthAddr)&0xf]; *s++ = '.'; } *(--s) = '\0'; return String; } PUCHAR AtmAddrToString(PVOID In) { static UCHAR String[80]; static PUCHAR HexChars = "0123456789abcdef"; PUCHAR AtmAddr = (PUCHAR) In; UINT i; PUCHAR s = String; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 1 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 2 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 3 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 4 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 5 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 6 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 7 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 8 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 9 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 10 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 11 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 12 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 13 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 14 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 15 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 16 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 17 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 18 *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 19 *s++ = '.'; *s++ = HexChars[(*AtmAddr)>>4]; *s++ = HexChars[(*AtmAddr++)&0xf]; // 20 *s = '\0'; return String; } VOID DisplayElanInfo( VOID ) { DisplayMessage(FALSE, MSG_ELAN_NUMBER, pElanInfo->ElanNumber); DisplayMessage(FALSE, MSG_ELAN_STATE, ElanStateToString(pElanInfo->ElanState)); DisplayMessage(FALSE, MSG_C1, AtmAddrToString(&pElanInfo->AtmAddress)); DisplayMessage(FALSE, MSG_C2, ElanLanTypeToString(pElanInfo->LanType)); DisplayMessage(FALSE, MSG_C3, ElanMaxFrameSizeToString(pElanInfo->MaxFrameSizeCode)); DisplayMessage(FALSE, MSG_C4, Misc[1].String); // always off if (pElanInfo->ElanName[0] == '\0') { DisplayMessage(FALSE, MSG_C5, Misc[3].String); // unspecified } else { DisplayMessage(FALSE, MSG_C5, pElanInfo->ElanName); } DisplayMessage(FALSE, MSG_C6, MacAddrToString(&pElanInfo->MacAddress)); DisplayMessage(FALSE, MSG_C7, pElanInfo->ControlTimeout); DisplayMessage(FALSE, MSG_C8, Misc[0].String); DisplayMessage(FALSE, MSG_LECS_ADDR, AtmAddrToString(&pElanInfo->LecsAddress)); DisplayMessage(FALSE, MSG_C9, AtmAddrToString(&pElanInfo->LesAddress)); DisplayMessage(FALSE, MSG_BUS_ADDR, AtmAddrToString(&pElanInfo->BusAddress)); DisplayMessage(FALSE, MSG_C10, pElanInfo->MaxUnkFrameCount); DisplayMessage(FALSE, MSG_C11, pElanInfo->MaxUnkFrameTime); DisplayMessage(FALSE, MSG_C12, pElanInfo->VccTimeout); DisplayMessage(FALSE, MSG_C13, pElanInfo->MaxRetryCount); DisplayMessage(FALSE, MSG_C14, pElanInfo->LecId); DisplayMessage(FALSE, MSG_C15); DisplayMessage(FALSE, MSG_C16); DisplayMessage(FALSE, MSG_C17, pElanInfo->AgingTime); DisplayMessage(FALSE, MSG_C18, pElanInfo->ForwardDelayTime); DisplayMessage(FALSE, MSG_C19, pElanInfo->TopologyChange==0?Misc[1].String:Misc[2].String); DisplayMessage(FALSE, MSG_C20, pElanInfo->ArpResponseTime); DisplayMessage(FALSE, MSG_C21, pElanInfo->FlushTimeout); DisplayMessage(FALSE, MSG_C22, pElanInfo->PathSwitchingDelay); DisplayMessage(FALSE, MSG_C23, pElanInfo->LocalSegmentId); DisplayMessage(FALSE, MSG_C24, McastVcTypeToString(pElanInfo->McastSendVcType)); DisplayMessage(FALSE, MSG_C25, pElanInfo->McastSendVcAvgRate); DisplayMessage(FALSE, MSG_C26, pElanInfo->McastSendVcPeakRate); DisplayMessage(FALSE, MSG_C27, Misc[0].String); DisplayMessage(FALSE, MSG_C28, pElanInfo->ConnComplTimer); } VOID DisplayElanArpTable( VOID ) { PATMLANE_ARPENTRY pArpEntry; ULONG i; DisplayMessage(FALSE, MSG_C16_LE_ARP_CACHE); pArpEntry = (PATMLANE_ARPENTRY) (ArpTableBuffer + sizeof(ATMLANE_ARPTABLE)); for (i = 0; i < pArpTable->ArpEntriesReturned; i++) { DisplayMessage(FALSE, MSG_ARP_ENTRY, MacAddrToString(pArpEntry->MacAddress), AtmAddrToString(pArpEntry->AtmAddress)); pArpEntry++; } } VOID DisplayElanConnTable( VOID ) { PATMLANE_CONNECTENTRY pConnEntry; ULONG i; DisplayMessage(FALSE, MSG_CONN_CACHE); pConnEntry = (PATMLANE_CONNECTENTRY) (ConnTableBuffer + sizeof(ATMLANE_CONNECTTABLE)); for (i = 0; i < pConnTable->ConnectEntriesReturned; i++) { switch (pConnEntry->Type) { default: case 0: // peer DisplayMessage(FALSE, MSG_CONN_ENTRY, ConnType[0].String, AtmAddrToString(pConnEntry->AtmAddress), pConnEntry->Vc?VcType[1].String:Misc[4].String, TEXT("")); break; case 1: // lecs DisplayMessage(FALSE, MSG_CONN_ENTRY, ConnType[1].String, AtmAddrToString(pConnEntry->AtmAddress), pConnEntry->Vc?VcType[2].String:Misc[4].String, TEXT("")); break; case 2: // les DisplayMessage(FALSE, MSG_CONN_ENTRY, ConnType[2].String, AtmAddrToString(pConnEntry->AtmAddress), pConnEntry->Vc?VcType[3].String:Misc[4].String, pConnEntry->VcIncoming?VcType[4].String:TEXT("")); break; case 3: // bus DisplayMessage(FALSE, MSG_CONN_ENTRY, ConnType[3].String, AtmAddrToString(pConnEntry->AtmAddress), pConnEntry->Vc?VcType[5].String:Misc[4].String, pConnEntry->VcIncoming?VcType[6].String:TEXT("")); break; } pConnEntry++; } } VOID __cdecl main( INT argc, CHAR *argv[] ) { HANDLE DeviceHandle; PUNICODE_STRING pAdapterName; PUNICODE_STRING pElanName; ULONG i, j; BOOLEAN Result; DisplayMessage(FALSE, MSG_ATMLANE_BANNER); DeviceHandle = OpenDevice(pDeviceName); if (DeviceHandle == INVALID_HANDLE_VALUE) { DisplayMessage(FALSE, MSG_ERROR_OPENING_DEVICE); return; } // // First check the version // if (!CheckVersion(DeviceHandle)) { CloseDevice(DeviceHandle); return; } // // First get the list of available adapters // if (!GetAdapterList(DeviceHandle)) { CloseDevice(DeviceHandle); return; } // // Loop thru the adapters getting each adapter's elan list // pAdapterName = &pAdapterList->AdapterList; for (i = 0; i < pAdapterList->AdapterCountReturned; i++) { DisplayMessage(FALSE, MSG_ADAPTER, (PWSTR)((PUCHAR)pAdapterName + sizeof(UNICODE_STRING))); if (GetElanList(DeviceHandle, pAdapterName)) { // // Loop thru the elan list getting ELAN info // pElanName = &pElanList->ElanList; for (j = 0; j < pElanList->ElanCountReturned; j++) { DisplayMessage(FALSE, MSG_ELAN, (PWSTR)((PUCHAR)pElanName + sizeof(UNICODE_STRING))); if (GetElanInfo(DeviceHandle, pAdapterName, pElanName)) { DisplayElanInfo(); } if (GetElanArpTable(DeviceHandle, pAdapterName, pElanName)) { DisplayElanArpTable(); } if (GetElanConnTable(DeviceHandle, pAdapterName, pElanName)) { DisplayElanConnTable(); } // // next elan // pElanName = (PUNICODE_STRING)((PUCHAR)pElanName + sizeof(UNICODE_STRING) + pElanName->Length); } } // // next adapter // pAdapterName = (PUNICODE_STRING)((PUCHAR)pAdapterName + sizeof(UNICODE_STRING) + pAdapterName->Length); } CloseDevice(DeviceHandle); return; }