搞了半天,唉,还是读注册表获取网卡信息比较好,还有一个方式我也贴下面,关键是我还没弄明白
下面是我的代码:
PUNICODE_STRING uAdapName = Adapter->MyOpenBlock->RootDeviceName;
PWCHAR p = RVATOVA(uAdapName->Buffer, uAdapName->Length << 1);
UNICODE_STRING uName;
OBJECT_ATTRIBUTES obj;
HANDLE KeyHandle;
if (Adapter->Type != NdisMedium802_3) return;
while (*(p-1) != '\\') p--;
DbgPrint("Adap %ws %ws", p, Adapter->MyOpenBlock->BindDeviceName->Buffer);
swprintf(Name, L"\\registry\\machine\\system\\CurrentControlSet\\Services\\Tcpip\\Par ameters\\Interfaces\\%ws", p);
RtlInitUnicodeString(&uName, Name);
InitializeObjectAttributes(
&obj,
&uName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL
);
status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &obj);
if (NT_SUCCESS(status))
{
Adapter->IpAddress = ReadIpAddress(KeyHandle, L"IPAddress");
if (!Adapter->IpAddress)
{
Adapter->IpAddress = ReadIpAddress(KeyHandle, L"DhcpIPAddress");
DbgPrint("Get dhcp ip");
}
Adapter->SubnetMask = ReadIpAddress(KeyHandle, L"SubnetMask");
if (!Adapter->SubnetMask)
{
Adapter->SubnetMask = ReadIpAddress(KeyHandle, L"DhcpSubnetMask");
}
Adapter->Gateway = ReadIpAddress(KeyHandle, L"DefaultGateway");
ZwClose(KeyHandle);
}
ULONG
ReadIpAddress(
IN HANDLE KeyHandle,
IN PWCHAR ValName
)
{
UNICODE_STRING uName;
WCHAR Name[MAX_PATH];
PKEY_VALUE_PARTIAL_INFORMATION Info = (void*)&Name;
CHAR aName[MAX_PATH];
ULONG ResLen;
RtlInitUnicodeString(&uName, ValName);
ZwQueryValueKey(
KeyHandle,
&uName,
KeyValuePartialInformation,
Info,
sizeof(Name),
&ResLen
);
wcstombs(aName, (PWCHAR)&Info->Data, -1);
return inet_addr(aName);
}
u32_t inet_addr(const char *cp)
{
u32_t address;
u32_t shift;
u32_t sym;
address = 0;
shift = 0;
while (*cp)
{
sym = 0;
while ((*cp != '.') && (*cp != '\0'))
{
if ((*cp < '0') || (*cp > '9')) return 0;
sym = sym*10 + (u32_t)(*cp - '0');
++cp;
}
address += sym << shift;
shift += 8;
if (*cp++ == '\0') break;
}
return address;
}
来看看packet.sys是如何获取的:
typedef struct _OPEN_INSTANCE {
PDEVICE_OBJECT DeviceObject;
ULONG IrpCount;
NDIS_STRING AdapterName;
NDIS_STRING SymbolicLink;
NDIS_HANDLE AdapterHandle;
NDIS_HANDLE PacketPool;
KSPIN_LOCK RcvQSpinLock;
LIST_ENTRY RcvList;
NDIS_MEDIUM Medium;
KSPIN_LOCK ResetQueueLock;
LIST_ENTRY ResetIrpList;
NDIS_STATUS Status;
NDIS_EVENT Event;
NDIS_EVENT CleanupEvent;
//
// List entry to link to the other deviceobjects.
//
LIST_ENTRY AdapterListEntry;
BOOLEAN Bound; // Set to TRUE when OpenAdapter is complete
// Set to FALSE when CloseAdpater is complete
CHAR Filler[3];
} OPEN_INSTANCE, *POPEN_INSTANCE;
NTSTATUS
PacketGetAdapterList(
IN PVOID Buffer,
IN ULONG Length,
IN OUT PULONG DataLength
)
/*++
Routine Description:
This routine walks the adapter list and gets the symbolic
link and NIC description and fills it in the Buffer.
The format of the information is given below.
Arguments:
Return Value:
--*/
{
ULONG requiredLength = 0, numOfAdapters = 0;
KIRQL oldIrql;
PLIST_ENTRY thisEntry, listHead;
POPEN_INSTANCE open;
DebugPrint(("Enter PacketGetAdapterList\n"));
KeAcquireSpinLock(&Globals.GlobalLock, &oldIrql);
//
// Walks the list to find out total space required for AdapterName
// and Symbolic Link.
//
listHead = &Globals.AdapterList;
for(thisEntry = listHead->Flink;
thisEntry != listHead;
thisEntry = thisEntry->Flink)
{
open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry);
requiredLength += open->AdapterName.Length + sizeof(UNICODE_NULL);
requiredLength += open->SymbolicLink.Length + sizeof(UNICODE_NULL);
numOfAdapters++;
}
//
// We will return the data in the following format:
// numOfAdapters + One_Or_More("AdapterName\0" + "SymbolicLink\0") + UNICODE_NULL
// So let's include the numOfAdapters and UNICODE_NULL size
// to the total length.
//
requiredLength += sizeof(ULONG) + sizeof(UNICODE_NULL);
*DataLength = requiredLength;
if(requiredLength > Length) {
KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
return STATUS_BUFFER_TOO_SMALL;
}
*(PULONG)Buffer = numOfAdapters;
(PCHAR)Buffer += sizeof(ULONG);
//
// Copy the name and symbolic link of each adapter.
//
for(thisEntry = listHead->Flink;
thisEntry != listHead;
thisEntry = thisEntry->Flink)
{
open = CONTAINING_RECORD(thisEntry, OPEN_INSTANCE, AdapterListEntry);
RtlCopyMemory(Buffer, open->AdapterName.Buffer,
open->AdapterName.Length+sizeof(WCHAR));
(PCHAR)Buffer += open->AdapterName.Length+sizeof(WCHAR);
RtlCopyMemory(Buffer, open->SymbolicLink.Buffer,
open->SymbolicLink.Length+sizeof(WCHAR));
(PCHAR)Buffer += open->SymbolicLink.Length+sizeof(WCHAR);
}
*(PWCHAR)Buffer = UNICODE_NULL;
KeReleaseSpinLock(&Globals.GlobalLock, oldIrql);
return STATUS_SUCCESS;
}