/* 功能:获取域名的IP地址。 made by correy made at 2017.06.01 http://correy.webs.com */ #include <ntddk.h> #include <wsk.h> #include <ws2def.h> #pragma warning(disable:4201) // nameless struct/union #pragma warning(disable:4214) // bit field types other than int #pragma warning(disable:4100) // 未引用的形参 #pragma warning(disable:4101) // 未引用的局部变量 #pragma warning(disable:4189) // 局部变量已初始化但不引用 const WSK_CLIENT_DISPATCH WskAppDispatch = { MAKE_WSK_VERSION(1,0), // Use WSK version 1.0 0, // Reserved NULL // WskClientEvent callback not required for WSK version 1.0 }; WSK_REGISTRATION WskRegistration; NTSTATUS SyncIrpCompletionRoutine( __in PDEVICE_OBJECT Reserved, __in PIRP Irp, __in PVOID Context ) { PKEVENT compEvent = (PKEVENT)Context; UNREFERENCED_PARAMETER(Reserved); UNREFERENCED_PARAMETER(Irp); KeSetEvent(compEvent, 2, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS KernelNameResolutionSample( __in PCWSTR NodeName, __in_opt PCWSTR ServiceName, __in_opt PADDRINFOEXW Hints, __in PWSK_PROVIDER_NPI WskProviderNpi ) //https://docs.microsoft.com/en-us/windows-hardware/drivers/network/resolving-host-names-and-ip-addresses { NTSTATUS status; PIRP irp; KEVENT completionEvent; UNICODE_STRING uniNodeName, uniServiceName, *uniServiceNamePtr; PADDRINFOEXW results; SOCKADDR_IN * psi = NULL; wchar_t buffer[64] = {0}; PWSTR p = NULL; UNICODE_STRING ip = {0}; const struct in_addr * temp = NULL; PAGED_CODE(); RtlInitUnicodeString(&uniNodeName, NodeName);// Initialize UNICODE_STRING structures for NodeName and ServiceName if(ServiceName == NULL) { uniServiceNamePtr = NULL; } else { RtlInitUnicodeString(&uniServiceName, ServiceName); uniServiceNamePtr = &uniServiceName; } KeInitializeEvent(&completionEvent, SynchronizationEvent, FALSE);// Use an event object to synchronously wait for the WskGetAddressInfo request to be completed. // Allocate an IRP for the WskGetAddressInfo request, and set the IRP completion routine, which will signal the completionEvent when the request is completed. irp = IoAllocateIrp(1, FALSE); if(irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } IoSetCompletionRoutine(irp, SyncIrpCompletionRoutine, &completionEvent, TRUE, TRUE, TRUE); // Make the WskGetAddressInfo request. WskProviderNpi->Dispatch->WskGetAddressInfo ( WskProviderNpi->Client, &uniNodeName, uniServiceNamePtr, NS_ALL, NULL, // Provider Hints, &results, NULL, // OwningProcess NULL, // OwningThread irp); // Wait for completion. // Note that processing of name resolution results can also be handled directly within the IRP completion routine, // but for simplicity, this example shows how to wait synchronously for completion. KeWaitForSingleObject(&completionEvent, Executive, KernelMode, FALSE, NULL); status = irp->IoStatus.Status; IoFreeIrp(irp); if(!NT_SUCCESS(status)) { return status; } // Process the name resolution results by iterating through the addresses within the returned ADDRINFOEXW structure. //results; // your code here psi = (SOCKADDR_IN *)results->ai_addr;//注意:这一行很重要。有时要该为IPV6版本的。 temp = (const struct in_addr *)&psi->sin_addr; p = RtlIpv4AddressToString(temp, buffer); ASSERT(p); RtlInitUnicodeString(&ip, buffer); KdPrint(("ipv4:%wZ.\r\n", &ip)); WskProviderNpi->Dispatch->WskFreeAddressInfo(WskProviderNpi->Client, results);// Release the returned ADDRINFOEXW structure when no longer needed. return status; } VOID Unload(_In_ PDRIVER_OBJECT DriverObject) { UNREFERENCED_PARAMETER(DriverObject); PAGED_CODE(); WskDeregister(&WskRegistration); } NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { NTSTATUS Status = STATUS_SUCCESS; WSK_CLIENT_NPI wskClientNpi; WSK_PROVIDER_NPI wskProviderNpi; //UNICODE_STRING test = RTL_CONSTANT_STRING(L"DESKTOP-SQRJ1QU"); UNREFERENCED_PARAMETER(RegistryPath); PAGED_CODE(); KdBreakPoint(); DriverObject->DriverUnload = Unload; wskClientNpi.ClientContext = NULL; wskClientNpi.Dispatch = &WskAppDispatch; Status = WskRegister(&wskClientNpi, &WskRegistration); ASSERT(NT_SUCCESS(Status)); Status = WskCaptureProviderNPI(&WskRegistration, WSK_INFINITE_WAIT, &wskProviderNpi); ASSERT(NT_SUCCESS(Status)); /* 做一些事情。 */ Status = KernelNameResolutionSample(L"www.baidu.com", NULL, NULL, &wskProviderNpi); ASSERT(NT_SUCCESS(Status)); WskReleaseProviderNPI(&WskRegistration); return Status; }
2017年6月2日星期五
驱动中获取域名的IP地址
订阅:
博文评论 (Atom)
没有评论:
发表评论