VOID DriverUnload(PDRIVER_OBJECT driver) { ULONG majorVersion, minorVersion , Address; Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase; DbgPrint("SSDTTalbe -> %08X",(ULONG)Address); /////////////////////////////////////////////////////////////////////////////// PsGetVersion( &majorVersion, &minorVersion, NULL, NULL ); if (majorVersion == 5 && minorVersion == 1) { DbgPrint("Windows XP"); Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x2B*4; EnableRW(); *((ULONG*)Address) = (ULONG)BACKUP; DisableRW(); } else if (majorVersion == 6 && minorVersion == 1) { DbgPrint("Windows 7"); Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x4A*4; EnableRW(); *((ULONG*)Address) = (ULONG)BACKUP; DisableRW(); } DbgPrint("DriveUnload."); }
//根据操作系统来确定具体函数的服务号 VOID InitCallNumber() { ULONG majorVersion, minorVersion; PsGetVersion( &majorVersion, &minorVersion, NULL, NULL ); if ( majorVersion == 5 && minorVersion == 2 ) { DbgPrint("comint32: Running on Windows 2003"); NtUserFindWindowEx_callnumber = 0x179; NtUserGetForegroundWindow_callnumber = 0x193; NtUserBuildHwndList_callnumber = 0x137; NtUserQueryWindow_callnumber = 0x1E1; NtUserWindowFromPoint_callnumber = 0x24C; } else if ( majorVersion == 5 && minorVersion == 1 ) { DbgPrint("comint32: Running on Windows XP"); NtUserFindWindowEx_callnumber = 0x17A; NtUserGetForegroundWindow_callnumber = 0x194; NtUserBuildHwndList_callnumber = 0x138; NtUserQueryWindow_callnumber = 0x1E3; NtUserWindowFromPoint_callnumber = 0x250; } else if ( majorVersion == 5 && minorVersion == 0 ) { DbgPrint("comint32: Running on Windows 2000"); NtUserFindWindowEx_callnumber = 0x170; NtUserGetForegroundWindow_callnumber = 0x189; NtUserBuildHwndList_callnumber = 0x12E; NtUserQueryWindow_callnumber = 0x1D2; NtUserWindowFromPoint_callnumber = 0x238; } }
/* attach to GUI process. */ NTSTATUS AttachGuiProcess( PKAPC_STATE pApcStatus ) { NTSTATUS status=STATUS_SUCCESS; ULONG osMajor = 0; PEPROCESS csrssEproc; //获取os主板本号 status = PsGetVersion( &osMajor, NULL, NULL, NULL ); if ( NT_SUCCESS(status) ) { //vista以上不兼容 if (osMajor != 6) { //获取Csrss.exe进程EPROCESS status=PsLookupProcessByProcessId( (PVOID)GetCsrssPid(), &csrssEproc); if ( !NT_SUCCESS(status) ) { KdPrint(("attach to GUI process failed!\n")); return STATUS_UNSUCCESSFUL; } } } // StackAttach(guiEproc, ApcStatus) KeStackAttachProcess(csrssEproc, pApcStatus); return status; }
VOID LoadDynamicFunction() { NDIS_STRING CancelSendPackets,GetPoolFromPacket,IMGetCurrentPacketStack,IMNotifyPnPEvent; PVOID pNdisBaseAddress = NULL; PsGetVersion(&gSfOsMajorVersion,&gSfOsMinorVersion,NULL,NULL); // 为了兼容没有SP补丁的Windows 2000 系统, // 我们使用 自定义的函数取代 NdisGetRoutineAddress函数功能 if( IS_NDIS51() ) { RtlInitUnicodeString(&CancelSendPackets,L"NdisCancelSendPackets"); MyNdisCancelSendPackets = (NDISCANCELSENDPACKETS)NdisGetRoutineAddress(&CancelSendPackets); RtlInitUnicodeString(&GetPoolFromPacket,L"NdisGetPoolFromPacket"); MyNdisGetPoolFromPacket = (NDISGETPOOLFROMPACKET)NdisGetRoutineAddress(&GetPoolFromPacket); RtlInitUnicodeString(&IMGetCurrentPacketStack,L"NdisIMGetCurrentPacketStack"); MyNdisIMGetCurrentPacketStack = (NDISIMGETCURRENTPACKETSTACK)NdisGetRoutineAddress(&IMGetCurrentPacketStack); RtlInitUnicodeString(&IMNotifyPnPEvent,L"NdisIMNotifyPnPEvent"); MyNdisIMNotifyPnPEvent = (NDISIMNOTIFYPNPEVENT)NdisGetRoutineAddress(&IMNotifyPnPEvent); } }
/** * Determines the NT kernel verison information. * * @param pOsVerInfo Where to return the version information. * * @remarks pOsVerInfo->fSmp is only definitive if @c true. * @remarks pOsVerInfo->uCsdNo is set to MY_NIL_CSD if it cannot be determined. */ static void rtR0NtGetOsVersionInfo(PRTNTSDBOSVER pOsVerInfo) { ULONG ulMajorVersion = 0; ULONG ulMinorVersion = 0; ULONG ulBuildNumber = 0; pOsVerInfo->fChecked = PsGetVersion(&ulMajorVersion, &ulMinorVersion, &ulBuildNumber, NULL) == TRUE; pOsVerInfo->uMajorVer = (uint8_t)ulMajorVersion; pOsVerInfo->uMinorVer = (uint8_t)ulMinorVersion; pOsVerInfo->uBuildNo = ulBuildNumber; #define MY_NIL_CSD 0x3f pOsVerInfo->uCsdNo = MY_NIL_CSD; if (g_pfnrtRtlGetVersion) { RTL_OSVERSIONINFOEXW VerInfo; RT_ZERO(VerInfo); VerInfo.dwOSVersionInfoSize = sizeof(VerInfo); NTSTATUS rcNt = g_pfnrtRtlGetVersion(&VerInfo); if (NT_SUCCESS(rcNt)) pOsVerInfo->uCsdNo = VerInfo.wServicePackMajor; } /* Note! We cannot quite say if something is MP or UNI. So, fSmp is redefined to indicate that it must be MP. */ pOsVerInfo->fSmp = RTMpGetCount() > 1 || ulMajorVersion >= 6; /* Vista and later has no UNI kernel AFAIK. */ }
/*Returns the windows version we're running on*/ vboxWinVersion_t VBoxQueryWinVersion() { ULONG major, minor, build; BOOLEAN checkedBuild; static vboxWinVersion_t s_WinVersion = WINVERSION_UNKNOWN; if (s_WinVersion != WINVERSION_UNKNOWN) return s_WinVersion; checkedBuild = PsGetVersion(&major, &minor, &build, NULL); LOG(("running on version %d.%d, build %d(checked=%d)", major, minor, build, (int)checkedBuild)); if (major == 6) { if (minor >= 4) s_WinVersion = WINVERSION_10; else if (minor == 3) s_WinVersion = WINVERSION_81; else if (minor == 2) s_WinVersion = WINVERSION_8; else if (minor == 1) s_WinVersion = WINVERSION_7; else if (minor == 0) s_WinVersion = WINVERSION_VISTA; /* Or Windows Server 2008. */ } else if (major == 5) s_WinVersion = (minor>=1) ? WINVERSION_XP: WINVERSION_2K; else if (major == 4) s_WinVersion = WINVERSION_NT4; else WARN(("NT4 required!")); return s_WinVersion; }
// Win32 driver entry point NDIS_STATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath) { NDIS_MINIPORT_CHARACTERISTICS miniport; ULONG os_major_ver = 0, os_minor_ver = 0; // Initialize the Neo library if (NeoInit() == FALSE) { // Initialization Failed return STATUS_UNSUCCESSFUL; } g_is_win8 = false; #ifndef NDIS30_MINIPORT // Get the OS version PsGetVersion(&os_major_ver, &os_minor_ver, NULL, NULL); if (os_major_ver >= 7 || (os_major_ver == 6 && os_minor_ver >= 2)) { // Windows 8 g_is_win8 = true; } #endif // NDIS30_MINIPORT // Initialize the NDIS wrapper NdisMInitializeWrapper(&ctx->NdisWrapper, DriverObject, RegistryPath, NULL); ndis_wrapper_handle = ctx->NdisWrapper; // Register a NDIS miniport driver NeoZero(&miniport, sizeof(NDIS_MINIPORT_CHARACTERISTICS)); miniport.MajorNdisVersion = NEO_NDIS_MAJOR_VERSION; miniport.MinorNdisVersion = NEO_NDIS_MINOR_VERSION; // Register the handler miniport.InitializeHandler = NeoNdisInit; miniport.HaltHandler = NeoNdisHalt; miniport.QueryInformationHandler = NeoNdisQuery; miniport.ResetHandler = NeoNdisReset; miniport.SetInformationHandler = NeoNdisSet; #ifndef NDIS30_MINIPORT miniport.SendPacketsHandler = NeoNdisSendPackets; #else // NDIS30_MINIPORT miniport.SendHandler = NULL; #endif // NDIS30_MINIPORT if (NG(NdisMRegisterMiniport(ctx->NdisWrapper, &miniport, sizeof(NDIS_MINIPORT_CHARACTERISTICS)))) { // Registration failure return STATUS_UNSUCCESSFUL; } // Initialization success return STATUS_SUCCESS; }
static void rtR0MemObjNtResolveDynamicApis(void) { ULONG uBuildNumber = 0; PsGetVersion(&g_uMajorVersion, &g_uMinorVersion, &uBuildNumber, NULL); #ifndef IPRT_TARGET_NT4 /* MmGetSystemRoutineAddress was introduced in w2k. */ UNICODE_STRING RoutineName; RtlInitUnicodeString(&RoutineName, L"MmProtectMdlSystemAddress"); g_pfnMmProtectMdlSystemAddress = (decltype(MmProtectMdlSystemAddress) *)MmGetSystemRoutineAddress(&RoutineName); #endif ASMCompilerBarrier(); g_fResolvedDynamicApis = true; }
int SSDTHook() { ULONG majorVersion, minorVersion , Address; Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase; DbgPrint("SSDTTalbe -> %08X",(ULONG)Address); /////////////////////////////////////////////////////////////////////////////// PsGetVersion( &majorVersion, &minorVersion, NULL, NULL ); if (majorVersion == 5 && minorVersion == 1) { DbgPrint("Windows XP"); Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x2B*4; } else if (majorVersion == 6 && minorVersion == 1) { DbgPrint("Windows 7"); Address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x4A*4; } else { DbgPrint("Unknown Windows"); return 0; } RealNtCreateMutant = (NTCREATEMUTANT)*(ULONG*)Address; BACKUP = *(ULONG*)Address; EnableRW(); *((ULONG*)Address) = (ULONG)MyNtCreateMutant; DisableRW(); return 1; }
BOOLEAN GetServicesFunction() { ULONG buildNo; ULONG ZwTerminateThreadNo; ULONG ZwTerminateProcessNo; PsGetVersion(NULL, NULL, &buildNo, NULL); switch(buildNo) { case 2600: //winxp ZwTerminateProcessNo = 0x101; ZwTerminateThreadNo = 0x102; break; } *(PULONG)(&NtTerminateThread) = KeServiceDescriptorTable.ServiceTable[ZwTerminateThreadNo]; *(PULONG)(&NtTerminateProcess) = KeServiceDescriptorTable.ServiceTable[ZwTerminateProcessNo]; return TRUE; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PEPROCESS Process; DWORD BuildNum;//系统版本 // // Create dispatch points for device control, create, close. // DriverObject->MajorFunction[IRP_MJ_CREATE] = SuperhidedllDispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = SuperhidedllDispatchClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SuperhidedllDispatchDeviceControl; DriverObject->DriverUnload = SuperhidedllUnload; PsGetVersion(NULL,NULL,&BuildNum,NULL); if (BuildNum!=2600) { DbgPrint("Sorry,This driver only supported on Windows XP!\n"); return STATUS_SUCCESS; } Process=GetProcessByName("explorer.exe"); if (Process) { // //简单测试,隐藏Explorer.exe中的kernel32.dll // HideDllFromProcess(Process,"kernel32.dll"); } else{ DbgPrint("Could not found target process.\n"); } return STATUS_SUCCESS; }
NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath) { UNREFERENCED_PARAMETER(registryPath); TraceVerbose(("====> '%s'.\n", __FUNCTION__)); PsGetVersion(&g_osMajorVersion, &g_osMinorVersion, NULL, NULL); if ((g_osMajorVersion < 5)||((g_osMajorVersion == 5)&&(g_osMinorVersion < 1))) { TraceWarning(("Windows XP or later operating systems supported!\n")); return STATUS_UNSUCCESSFUL; } TraceInfo(("Starting driver...\n")); driverObject->DriverUnload = V4vDriverUnload; driverObject->DriverExtension->AddDevice = V4vAddDevice; driverObject->MajorFunction[IRP_MJ_CREATE] = V4vDispatchCreate; driverObject->MajorFunction[IRP_MJ_CLEANUP] = V4vDispatchCleanup; driverObject->MajorFunction[IRP_MJ_CLOSE] = V4vDispatchClose; driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = V4vDispatchDeviceControl; driverObject->MajorFunction[IRP_MJ_READ] = V4vDispatchRead; driverObject->MajorFunction[IRP_MJ_WRITE] = V4vDispatchWrite; driverObject->MajorFunction[IRP_MJ_PNP] = V4vDispatchPnP; driverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = V4vDispatchWmi; driverObject->MajorFunction[IRP_MJ_POWER] = V4vDispatchPower; // The rest can be handled by the system not supported routine TraceVerbose(("DriverEntry returning successfully\n")); TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return STATUS_SUCCESS; }
// // Driver entry point // NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING ) { DriverObject->DriverUnload = DriverUnload; KdPrint(("[~] DriverEntry()\n")); PsGetVersion (&MajorVersion, &MinorVersion, 0, 0); if (MajorVersion >= 6) { KdPrint(("Windows Vista and later are not supported yet\n")); return STATUS_NOT_SUPPORTED; } if (MajorVersion < 5 || MinorVersion == 0) { KdPrint(("Windows NT and 2000 are not supported\n")); return STATUS_NOT_SUPPORTED; } ASSERT (MajorVersion == 5); ASSERT (MinorVersion >= 1 && MinorVersion <= 2); if (MinorVersion == 1) { KdPrint(("Running on Windows XP\n")); } else { KdPrint(("Running on Windows 2003 Server\n")); } if (KeNumberProcessors > 1) { KdPrint(("Loading on multiprocessor system (NumberProcessors %d)\n", KeNumberProcessors)); } else { KdPrint(("Loading on uniprocessor system\n")); } KdPrint (("First hello from nt\n")); if(!NT_SUCCESS(W32FindAndSwapIAT ())) { KdPrint(("could not swap import\n")); return STATUS_INVALID_FILE_FOR_SECTION; } // import something from W32k EngPrint ("Second hello from win32k\n"); HANDLE hCsrProcess; NTSTATUS Status; Status = ObOpenObjectByPointer ( CsrProcess, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, &hCsrProcess ); if (!NT_SUCCESS(Status)) { KdPrint(("ObOpenObjectByPointer failed with status %X\n", Status)); W32ReleaseCall(); return Status; } KdPrint(("csr opened, handle %X\n", hCsrProcess)); // // EngLoadImage uses KeAttachProcess/KeDetachProcess to attach to csrss process // KeDetachProcess detaches to thread's original process, but our thread's // original process is System! (because we are running in the context of system // worker thread that loads a driver). // ( // | fucken windows programmers could not call KeStackAttachProcess // | instead of KeAttachProcess :( // ) // So we have to run our function in the context of csrss.exe // HANDLE ThreadHandle; CLIENT_ID ClientId; OBJECT_ATTRIBUTES Oa; InitializeObjectAttributes (&Oa, NULL, OBJ_KERNEL_HANDLE, 0, 0); Status = PsCreateSystemThread ( &ThreadHandle, THREAD_ALL_ACCESS, &Oa, hCsrProcess, &ClientId, REINITIALIZE_ADAPTER, NULL ); if (!NT_SUCCESS(Status)) { KdPrint(("PsCreateSystemThread failed with status %X\n", Status)); ZwClose (hCsrProcess); W32ReleaseCall(); return Status; } KdPrint(("thread created, handle %X\n", ThreadHandle)); PETHREAD Thread; Status = ObReferenceObjectByHandle( ThreadHandle, THREAD_ALL_ACCESS, *PsThreadType, KernelMode, (PVOID*) &Thread, NULL ); if (!NT_SUCCESS(Status)) { KdPrint(("ObReferenceObjectByHandle failed with status %X\n", Status)); // cannot unload because thread is running KeBugCheck (0); } KdPrint(("thread referenced to %X\n", Thread)); KeWaitForSingleObject (Thread, Executive, KernelMode, FALSE, NULL); KdPrint(("Thread terminated\n")); ZwClose (hCsrProcess); ObDereferenceObject (Thread); ZwClose (ThreadHandle); KdPrint(("success\n", hCsrProcess)); if (!pDrvCopyBits) { KdPrint(("Could not find DrvCopyBits\n")); W32ReleaseCall(); return STATUS_UNSUCCESSFUL; } // // Query keyboard LEDs // if(!NT_SUCCESS(KbdWinQueryLeds())) { W32ReleaseCall(); return STATUS_UNSUCCESSFUL; } PSHARED_DISP_DATA disp = GetSharedData(); if (!disp) { EngPrint ("ngvid: could not get shared data\n"); W32ReleaseCall(); return STATUS_UNSUCCESSFUL; } if (disp->Signature != SHARED_SIGNATURE) { EngPrint ("ngvid: Damaged shared block %X signature %X should be %X\n", disp, disp->Signature, SHARED_SIGNATURE); //__asm int 3 W32ReleaseCall(); return STATUS_UNSUCCESSFUL; } KdPrint (("Got shared %X Sign %X Surf %X\n", disp, disp->Signature, disp->pPrimarySurf)); #if 0 // // Temporarily hook DrvCopyBits // pDrvCopyBits = disp->pDrvCopyBits; #endif if (!disp->pPrimarySurf) { KdPrint(("DrvCopyBits %X\n", pDrvCopyBits)); KeInitializeEvent (&SynchEvent, SynchronizationEvent, FALSE); if (SpliceFunctionStart (pDrvCopyBits, NewDrvCopyBits, SplicingBuffer, sizeof(SplicingBuffer), BackupBuffer, &BackupWritten, FALSE)) { KdPrint(("SpliceFunctionStart FAILED!!!\n")); W32ReleaseCall(); return STATUS_UNSUCCESSFUL; } KdPrint(("Now you have to move mouse pointer across the display ...\n")); KeWaitForSingleObject (&SynchEvent, Executive, KernelMode, FALSE, NULL); UnspliceFunctionStart (pDrvCopyBits, BackupBuffer, FALSE); KdPrint(("Wait succeeded, so got primary surf %X\n", pPrimarySurf)); disp->pPrimarySurf = pPrimarySurf; } else { KdPrint(("Already have primary surface\n")); pPrimarySurf = disp->pPrimarySurf; } // Hook kbd & mouse #if KBD_HOOK_ISR OldKbd = GetIOAPICIntVector (1); *(PVOID*)&OldISR = IoHookInterrupt ( (UCHAR)OldKbd, InterruptService); #else CreateTrampoline(); //I8042HookKeyboard ((PI8042_KEYBOARD_ISR) IsrHookRoutine); #endif MouseInitialize (StateChangeCallbackRoutine); KdPrint(("Keyboard & mouse hooked\n")); // Initialize reset DPC KeInitializeDpc (&HotkeyResetStateDpc, HotkeyResetStateDeferredRoutine, NULL); // // Perform multiprocessor initialization // DbgHalInitializeMP (); /// Worker(); /// W32ReleaseCall(); DbgInitialize (); KdPrint(("[+] Driver initialization successful\n")); return STATUS_SUCCESS; }
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: Initialize the driver dispatch table. Arguments: DriverObject - pointer to the driver object RegistryPath - pointer to a unicode string representing the path, to driver-specific key in the registry. Return Value: NT Status Code --*/ { NTSTATUS status; ULONG tempUlong; Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("%s, %s\n", __DATE__, __TIME__)); // // Save the RegistryPath for WMI. // Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); Globals.RegistryPath.Length = RegistryPath->Length; Globals.RegistryPath.Buffer = ExAllocatePoolWithTag( PagedPool, Globals.RegistryPath.MaximumLength, BUSENUM_POOL_TAG_DRIVER_REGISTRYPATH ); if (!Globals.RegistryPath.Buffer) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath); // // Query OS Versions // Globals.bCheckVersion = PsGetVersion( &Globals.MajorVersion, &Globals.MinorVersion, &Globals.BuildNumber, NULL ); if(Globals.bCheckVersion == TRUE) { Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("Checkd Build, Major Ver %d, Minor Ver %d, Build %d\n", Globals.MajorVersion, Globals.MinorVersion, Globals.BuildNumber)); } else { Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("Free Build, Major Ver %d, Minor Ver %d, Build %d\n", Globals.MajorVersion, Globals.MinorVersion, Globals.BuildNumber)); } // // Set entry points into the driver // DriverObject->MajorFunction [IRP_MJ_CREATE] = DriverObject->MajorFunction [IRP_MJ_CLOSE] = Bus_CreateClose; DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP; DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power; DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = Bus_IoCtl; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Bus_SystemControl; DriverObject->DriverUnload = Bus_DriverUnload; DriverObject->DriverExtension->AddDevice = Bus_AddDevice; // // Init mutex // ExInitializeFastMutex(&Globals.Mutex); // // Default setting // Globals.PersistentPdo = TRUE; Globals.LfsFilterInstalled = FALSE; // // Read options in the registry // // Disable persistent PDO option status = DrReadKeyValueInstantly( RegistryPath, BUSENUM_DRVREG_DISABLE_PERSISTENTPDO, REG_DWORD, &tempUlong, sizeof(tempUlong), NULL); if(NT_SUCCESS(status) && tempUlong != 0) { Globals.PersistentPdo = FALSE; Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("Persistent PDO option disabled.\n")); } // // Check to see if LFS filter is installed. // status = LfsFiltDriverServiceExist(); if(NT_SUCCESS(status)) { Globals.LfsFilterInstalled = TRUE; Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("LFS Filter is detected.\n")); } else { Globals.LfsFilterInstalled = FALSE; Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("LFS Filter is not detected. STATUS=%08lx\n", status)); } return STATUS_SUCCESS; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: This is the initialization routine for the Fat file system device driver. This routine creates the device object for the FileSystem device and performs all other driver initialization. Arguments: DriverObject - Pointer to driver object created by the system. Return Value: NTSTATUS - The function value is the final status from the initialization operation. --*/ { USHORT MaxDepth; NTSTATUS Status; UNICODE_STRING UnicodeString; FS_FILTER_CALLBACKS FilterCallbacks; UNICODE_STRING ValueName; ULONG Value; #if __NDAS_FAT__ UNICODE_STRING linkString; UNICODE_STRING functionName; UNICODE_STRING tempUnicode; #endif #if DBG DbgPrint( "NdasFat DriverEntry %s %s\n", __DATE__, __TIME__ ); #endif #if __NDAS_FAT_DBG__ FatDebugTraceLevel |= DEBUG_TRACE_ERROR; FatDebugTraceLevel |= DEBUG_TRACE_CLEANUP; FatDebugTraceLevel |= DEBUG_TRACE_CLOSE; FatDebugTraceLevel |= DEBUG_TRACE_CREATE; FatDebugTraceLevel |= DEBUG_TRACE_DIRCTRL; FatDebugTraceLevel |= DEBUG_TRACE_EA; FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO; FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL; FatDebugTraceLevel |= DEBUG_TRACE_LOCKCTRL; FatDebugTraceLevel |= DEBUG_TRACE_READ; FatDebugTraceLevel |= DEBUG_TRACE_VOLINFO; FatDebugTraceLevel |= DEBUG_TRACE_WRITE; FatDebugTraceLevel |= DEBUG_TRACE_DEVCTRL; FatDebugTraceLevel |= DEBUG_TRACE_FLUSH; FatDebugTraceLevel |= DEBUG_TRACE_PNP; FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN; FatDebugTraceLevel = 0x00000009; //FatDebugTraceLevel |= DEBUG_TRACE_FSCTRL; //FatDebugTraceLevel |= DEBUG_INFO_DEVCTRL; FatDebugTraceLevel |= DEBUG_INFO_FSCTRL; FatDebugTraceLevel |= DEBUG_INFO_READ; FatDebugTraceLevel |= DEBUG_INFO_SECONDARY; //FatDebugTraceLevel |= DEBUG_INFO_PRIMARY; FatDebugTraceLevel |= DEBUG_INFO_FILOBSUP; FatDebugTraceLevel |= DEBUG_TRACE_PNP; FatDebugTraceLevel |= DEBUG_TRACE_SHUTDOWN; FatDebugTraceLevel |= DEBUG_INFO_FILEINFO; FatDebugTraceLevel |= DEBUG_INFO_CREATE; FatDebugTraceLevel |= DEBUG_INFO_STRUCSUP; FatDebugTraceLevel |= DEBUG_INFO_CLEANUP; FatDebugTraceLevel |= DEBUG_INFO_CLOSE; FatDebugTraceLevel |= DEBUG_INFO_ALL; FatDebugTraceLevel |= DEBUG_INFO_WRITE; //FatDebugTraceLevel |= DEBUG_TRACE_WRITE; FatDebugTraceLevel &= ~DEBUG_TRACE_UNWIND; //FatDebugTraceLevel = 0xFFFFFFFFFFFFFFFF; //FatDebugTraceLevel |= DEBUG_TRACE_STRUCSUP; FatDebugTraceLevel |= DEBUG_INFO_FILEINFO; //FatDebugTraceLevel |= DEBUG_TRACE_FILEINFO; DebugTrace2( 0, DEBUG_INFO_ALL, ("sizeof(NDFS_WINXP_REPLY_HEADER) = %d\n", sizeof(NDFS_WINXP_REPLY_HEADER)) ); #endif #if __NDAS_FAT_WIN2K_SUPPORT__ PsGetVersion( &gOsMajorVersion, &gOsMinorVersion, NULL, NULL ); RtlInitUnicodeString( &functionName, L"SeFilterToken" ); NdasFatSeFilterToken = MmGetSystemRoutineAddress( &functionName ); if (IS_WINDOWSXP_OR_LATER()) { // to prevent incomprehensible error RtlInitUnicodeString( &functionName, L"CcMdlWriteAbort" ); NdasFatCcMdlWriteAbort = MmGetSystemRoutineAddress( &functionName ); } RtlInitUnicodeString( &functionName, L"KeAreApcsDisabled" ); NdasFatKeAreApcsDisabled = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"KeAreAllApcsDisabled" ); NdasFatKeAreAllApcsDisabled = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"FsRtlRegisterFileSystemFilterCallbacks" ); NdasFatFsRtlRegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"FsRtlAreVolumeStartupApplicationsComplete" ); NdasFatFsRtlAreVolumeStartupApplicationsComplete = MmGetSystemRoutineAddress( &functionName ); RtlInitUnicodeString( &functionName, L"MmDoesFileHaveUserWritableReferences" ); NdasFatMmDoesFileHaveUserWritableReferences = MmGetSystemRoutineAddress( &functionName ); #endif #if __NDAS_FAT__ RtlInitUnicodeString( &UnicodeString, NDAS_FAT_CONTROL_DEVICE_NAME ); Status = IoCreateDevice( DriverObject, 0, // has no device extension &UnicodeString, FILE_DEVICE_NULL, 0, FALSE, &FatControlDeviceObject ); if (!NT_SUCCESS( Status )) { return Status; } RtlInitUnicodeString( &linkString, NDAS_FAT_CONTROL_LINK_NAME ); Status = IoCreateSymbolicLink( &linkString, &UnicodeString ); if (!NT_SUCCESS(Status)) { IoDeleteDevice( FatControlDeviceObject ); return Status; } #endif #if __NDAS_FAT__ RtlInitUnicodeString( &UnicodeString, NDAS_FAT_DEVICE_NAME ); Status = IoCreateDevice( DriverObject, sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT), &UnicodeString, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &FatDiskFileSystemDeviceObject ); if (!NT_SUCCESS(Status)) { IoDeleteSymbolicLink( &linkString ); IoDeleteDevice( FatControlDeviceObject ); return Status; } RtlZeroMemory( (PUCHAR)FatDiskFileSystemDeviceObject+sizeof(DEVICE_OBJECT), sizeof(VOLUME_DEVICE_OBJECT)-sizeof(DEVICE_OBJECT) ); #else // // Create the device object for disks. To avoid problems with filters who // know this name, we must keep it. // RtlInitUnicodeString( &UnicodeString, L"\\Fat" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, &FatDiskFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { return Status; } #endif #if !__NDAS_FAT__ // // Create the device object for "cdroms". // RtlInitUnicodeString( &UnicodeString, L"\\FatCdrom" ); Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_CD_ROM_FILE_SYSTEM, 0, FALSE, &FatCdromFileSystemDeviceObject ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject); return Status; } #endif DriverObject->DriverUnload = FatUnload; // // Note that because of the way data caching is done, we set neither // the Direct I/O or Buffered I/O bit in DeviceObject->Flags. If // data is not in the cache, or the request is not buffered, we may, // set up for Direct I/O by hand. // // // Initialize the driver object with this driver's entry points. // DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)FatFsdCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)FatFsdClose; DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)FatFsdRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)FatFsdWrite; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)FatFsdSetInformation; DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = (PDRIVER_DISPATCH)FatFsdQueryEa; DriverObject->MajorFunction[IRP_MJ_SET_EA] = (PDRIVER_DISPATCH)FatFsdSetEa; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = (PDRIVER_DISPATCH)FatFsdFlushBuffers; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)FatFsdSetVolumeInformation; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)FatFsdCleanup; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = (PDRIVER_DISPATCH)FatFsdDirectoryControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)FatFsdFileSystemControl; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = (PDRIVER_DISPATCH)FatFsdLockControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)FatFsdDeviceControl; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = (PDRIVER_DISPATCH)FatFsdShutdown; DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH)FatFsdPnp; DriverObject->FastIoDispatch = &FatFastIoDispatch; RtlZeroMemory(&FatFastIoDispatch, sizeof(FatFastIoDispatch)); FatFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); FatFastIoDispatch.FastIoCheckIfPossible = FatFastIoCheckIfPossible; // CheckForFastIo FatFastIoDispatch.FastIoRead = FsRtlCopyRead; // Read FatFastIoDispatch.FastIoWrite = FsRtlCopyWrite; // Write FatFastIoDispatch.FastIoQueryBasicInfo = FatFastQueryBasicInfo; // QueryBasicInfo FatFastIoDispatch.FastIoQueryStandardInfo = FatFastQueryStdInfo; // QueryStandardInfo FatFastIoDispatch.FastIoLock = FatFastLock; // Lock FatFastIoDispatch.FastIoUnlockSingle = FatFastUnlockSingle; // UnlockSingle FatFastIoDispatch.FastIoUnlockAll = FatFastUnlockAll; // UnlockAll FatFastIoDispatch.FastIoUnlockAllByKey = FatFastUnlockAllByKey; // UnlockAllByKey FatFastIoDispatch.FastIoQueryNetworkOpenInfo = FatFastQueryNetworkOpenInfo; FatFastIoDispatch.AcquireForCcFlush = FatAcquireForCcFlush; FatFastIoDispatch.ReleaseForCcFlush = FatReleaseForCcFlush; FatFastIoDispatch.MdlRead = FsRtlMdlReadDev; FatFastIoDispatch.MdlReadComplete = FsRtlMdlReadCompleteDev; FatFastIoDispatch.PrepareMdlWrite = FsRtlPrepareMdlWriteDev; FatFastIoDispatch.MdlWriteComplete = FsRtlMdlWriteCompleteDev; #if __NDAS_FAT_SECONDARY__ RtlZeroMemory(&FatFastIoDispatch, sizeof(FAST_IO_DISPATCH)); FatFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); //FatFastIoDispatch.FastIoCheckIfPossible = FatFastIoCheckIfPossible; // CheckForFastIo //FatFastIoDispatch.AcquireForModWrite = FatAcquireFileForModWrite; //FatFastIoDispatch.AcquireFileForNtCreateSection = FatAcquireForCreateSection; //FatFastIoDispatch.ReleaseFileForNtCreateSection = FatReleaseForCreateSection; FatFastIoDispatch.AcquireForCcFlush = FatAcquireForCcFlush; FatFastIoDispatch.ReleaseForCcFlush = FatReleaseForCcFlush; #endif // // Initialize the filter callbacks we use. // #if __NDAS_FAT__ if (IS_WINDOWSVISTA_OR_LATER()) { #if __NDAS_FAT_WIN2K_SUPPORT__ if (NdasFatFsRtlRegisterFileSystemFilterCallbacks) { RtlZeroMemory( &FilterCallbacks, sizeof(FS_FILTER_CALLBACKS) ); FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection; Status = NdasFatFsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FilterCallbacks ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject ); IoDeleteDevice( FatCdromFileSystemDeviceObject ); return Status; } } #else RtlZeroMemory( &FilterCallbacks, sizeof(FS_FILTER_CALLBACKS) ); FilterCallbacks.SizeOfFsFilterCallbacks = sizeof(FS_FILTER_CALLBACKS); FilterCallbacks.PreAcquireForSectionSynchronization = FatFilterCallbackAcquireForCreateSection; Status = FsRtlRegisterFileSystemFilterCallbacks( DriverObject, &FilterCallbacks ); if (!NT_SUCCESS( Status )) { IoDeleteDevice( FatDiskFileSystemDeviceObject ); IoDeleteDevice( FatCdromFileSystemDeviceObject ); return Status; } #endif } #endif // // Initialize the global data structures // // // The FatData record // RtlZeroMemory( &FatData, sizeof(FAT_DATA)); FatData.NodeTypeCode = FAT_NTC_DATA_HEADER; FatData.NodeByteSize = sizeof(FAT_DATA); InitializeListHead(&FatData.VcbQueue); FatData.DriverObject = DriverObject; FatData.DiskFileSystemDeviceObject = FatDiskFileSystemDeviceObject; FatData.CdromFileSystemDeviceObject = FatCdromFileSystemDeviceObject; // // This list head keeps track of closes yet to be done. // InitializeListHead( &FatData.AsyncCloseList ); InitializeListHead( &FatData.DelayedCloseList ); FatData.FatCloseItem = IoAllocateWorkItem( FatDiskFileSystemDeviceObject); if (FatData.FatCloseItem == NULL) { IoDeleteDevice (FatDiskFileSystemDeviceObject); #if __NDAS_FAT__ if (FatCdromFileSystemDeviceObject) #endif IoDeleteDevice (FatCdromFileSystemDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } // // Now initialize our general purpose spinlock (gag) and figure out how // deep and wide we want our delayed lists (along with fooling ourselves // about the lookaside depths). // KeInitializeSpinLock( &FatData.GeneralSpinLock ); switch ( MmQuerySystemSize() ) { case MmSmallSystem: MaxDepth = 4; FatMaxDelayedCloseCount = FAT_MAX_DELAYED_CLOSES; break; case MmMediumSystem: MaxDepth = 8; FatMaxDelayedCloseCount = 4 * FAT_MAX_DELAYED_CLOSES; break; case MmLargeSystem: MaxDepth = 16; FatMaxDelayedCloseCount = 16 * FAT_MAX_DELAYED_CLOSES; break; } // // Initialize the cache manager callback routines // FatData.CacheManagerCallbacks.AcquireForLazyWrite = &FatAcquireFcbForLazyWrite; FatData.CacheManagerCallbacks.ReleaseFromLazyWrite = &FatReleaseFcbFromLazyWrite; FatData.CacheManagerCallbacks.AcquireForReadAhead = &FatAcquireFcbForReadAhead; FatData.CacheManagerCallbacks.ReleaseFromReadAhead = &FatReleaseFcbFromReadAhead; FatData.CacheManagerNoOpCallbacks.AcquireForLazyWrite = &FatNoOpAcquire; FatData.CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &FatNoOpRelease; FatData.CacheManagerNoOpCallbacks.AcquireForReadAhead = &FatNoOpAcquire; FatData.CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &FatNoOpRelease; // // Set up global pointer to our process. // FatData.OurProcess = PsGetCurrentProcess(); // // Read the registry to determine if we are in ChicagoMode. // ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME; ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME); Status = FatGetCompatibilityModeValue( &ValueName, &Value ); if (NT_SUCCESS(Status) && FlagOn(Value, 1)) { FatData.ChicagoMode = FALSE; } else { FatData.ChicagoMode = TRUE; } // // Read the registry to determine if we are going to generate LFNs // for valid 8.3 names with extended characters. // ValueName.Buffer = CODE_PAGE_INVARIANCE_VALUE_NAME; ValueName.Length = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME) - sizeof(WCHAR); ValueName.MaximumLength = sizeof(CODE_PAGE_INVARIANCE_VALUE_NAME); Status = FatGetCompatibilityModeValue( &ValueName, &Value ); if (NT_SUCCESS(Status) && FlagOn(Value, 1)) { FatData.CodePageInvariant = FALSE; } else { FatData.CodePageInvariant = TRUE; } // // Initialize our global resource and fire up the lookaside lists. // ExInitializeResourceLite( &FatData.Resource ); ExInitializeNPagedLookasideList( &FatIrpContextLookasideList, NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(IRP_CONTEXT), TAG_IRP_CONTEXT, MaxDepth ); ExInitializeNPagedLookasideList( &FatNonPagedFcbLookasideList, NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(NON_PAGED_FCB), TAG_FCB_NONPAGED, MaxDepth ); ExInitializeNPagedLookasideList( &FatEResourceLookasideList, NULL, NULL, POOL_RAISE_IF_ALLOCATION_FAILURE, sizeof(ERESOURCE), TAG_ERESOURCE, MaxDepth ); ExInitializeSListHead( &FatCloseContextSList ); ExInitializeFastMutex( &FatCloseQueueMutex ); KeInitializeEvent( &FatReserveEvent, SynchronizationEvent, TRUE ); // // Register the file system with the I/O system // IoRegisterFileSystem(FatDiskFileSystemDeviceObject); ObReferenceObject (FatDiskFileSystemDeviceObject); #if __NDAS_FAT__ if (FatCdromFileSystemDeviceObject) { IoRegisterFileSystem(FatCdromFileSystemDeviceObject); ObReferenceObject (FatCdromFileSystemDeviceObject); } #else IoRegisterFileSystem(FatCdromFileSystemDeviceObject); ObReferenceObject (FatCdromFileSystemDeviceObject); #endif #if __NDAS_FAT__ FatData.FileSystemRegistered = TRUE; RtlInitEmptyUnicodeString( &FatData.Root, FatData.RootBuffer, sizeof(FatData.RootBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\" ); RtlCopyUnicodeString( &FatData.Root, &tempUnicode ); RtlInitEmptyUnicodeString( &FatData.MountMgrRemoteDatabase, FatData.MountMgrRemoteDatabaseBuffer, sizeof(FatData.MountMgrRemoteDatabaseBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\:$MountMgrRemoteDatabase" ); RtlCopyUnicodeString( &FatData.MountMgrRemoteDatabase, &tempUnicode ); RtlInitEmptyUnicodeString( &FatData.ExtendReparse, FatData.ExtendReparseBuffer, sizeof(FatData.ExtendReparseBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\$Extend\\$Reparse:$R:$INDEX_ALLOCATION" ); RtlCopyUnicodeString( &FatData.ExtendReparse, &tempUnicode ); RtlInitEmptyUnicodeString( &FatData.MountPointManagerRemoteDatabase, FatData.MountPointManagerRemoteDatabaseBuffer, sizeof(FatData.MountPointManagerRemoteDatabaseBuffer) ); RtlInitUnicodeString( &tempUnicode, L"\\System Volume Information\\MountPointManagerRemoteDatabase" ); RtlCopyUnicodeString( &FatData.MountPointManagerRemoteDatabase, &tempUnicode ); #endif // // Find out if we are running an a FujitsuFMR machine. // FatData.FujitsuFMR = FatIsFujitsuFMR(); #if __NDAS_FAT__ // // Check to see if new kernel is present to decide if we want // to support advance fcb headers // RtlInitUnicodeString( &UnicodeString, L"FsRtlTeardownPerStreamContexts" ); FatFsRtlTeardownPerStreamContexts = MmGetSystemRoutineAddress( &UnicodeString ); #endif // // And return to our caller // return( STATUS_SUCCESS ); }
//初始化一些偏移量 BOOLEAN EnviromentInitialize(PDRIVER_OBJECT DriverObject) { ULONG buildNo; PsGetVersion(NULL, NULL, &buildNo, NULL); switch(buildNo) { case 2600: //winxp EProcessUniqueProcessIdOffset = 0x084; EProcessActiveProcessLinksOffset = 0x088; EProcessObjectTableOffset = 0x0c4; EProcessSectionObjectOffset = 0x138; EProcessImageFileNameOffset = 0x174; EProcessThreadListHeadOffset = 0x190; EProcessObjectTableOffset = 0x0c4; EProcessPebOffset = 0x1b0; EProcessCreateTimeOffset = 0x070; EProcessDebugPortOffset = 0x0bc; EProcessInheritedFromUniqueProcessIdOffset = 0x14c; EThreadCidOffset = 0x1ec; EThreadApcStateProcessOffset = 0x044; EThreadThreadListEntryOffset = 0x22c; EThreadStartAddressOffset = 0x224; EThreadWin32StartAddressOffset = 0x228; KThreadBasePriorityOffset = 0x6c; KThreadContextSwitchesOffset = 0x04c; KThreadStateOffset = 0x02d; KThreadPreviousModeOffset = 0x140; KProcessBasePriorityOffset = 0x062; KProcessStateOffset = 0x065; HandleTableHandleTableListOffset = 0x01c; HandleTableQuotaProcessOffset = 0x004; HandleTableUniqueProcessIdOffset = 0x08; HandleTableHandleCountOffset = 0x03c; SectionObjectSegmentOffset = 0x014; SegmentObjectSubSecOffset = 0x01c; ControlAreaFilePointerOffset = 0x024; break; default: return FALSE; } //获得System进程 SystemProcess = PsGetCurrentProcess(); //获得未导出的函数 if(GetServicesFunction() == FALSE) return FALSE; //获得PsLoadedModuleList地址和内核基址、大小 if(GetPsLoadedModuleListHead(DriverObject) == FALSE) return FALSE; //获得ActiveProcessLinks头 if(GetActiveProcessLinksHead() == FALSE) return FALSE; //获得HandleTableList头 if(GetHandleTableListHead() == FALSE) return FALSE; //获得PspCidTable地址 if(GetPspCidTableAddress() == FALSE) return FALSE; if(ProtectInitialize() == FALSE) return FALSE; return TRUE; }
////////////////////////////////////////////////////////////////////////// // InitSSDTData BOOL InitSSDTData() { BOOL bRet = FALSE; do { if(!GetSSDTFunctions()) { break; } GET_FUNC_INDEX(ZwCreateKey); GET_FUNC_INDEX(ZwQueryValueKey); GET_FUNC_INDEX(ZwDeleteKey); GET_FUNC_INDEX(ZwDeleteValueKey); GET_FUNC_INDEX(ZwSetValueKey); GET_FUNC_INDEX(ZwCreateFile); GET_FUNC_INDEX(ZwSetInformationFile); GET_FUNC_INDEX(ZwWriteFile); GET_FUNC_INDEX(ZwOpenThread); GET_FUNC_INDEX(ZwDeleteFile); GET_FUNC_INDEX(ZwOpenFile); GET_FUNC_INDEX(ZwTerminateProcess); GET_FUNC_INDEX(ZwSetInformationThread); GET_FUNC_INDEX(ZwRequestWaitReplyPort); GET_FUNC_INDEX(ZwCreateSection); GET_FUNC_INDEX(ZwOpenSection); GET_FUNC_INDEX(ZwCreateSymbolicLinkObject); GET_FUNC_INDEX(ZwOpenSymbolicLinkObject); GET_FUNC_INDEX(ZwLoadDriver); GET_FUNC_INDEX(ZwUnloadDriver); GET_FUNC_INDEX(ZwQuerySystemInformation); GET_FUNC_INDEX(ZwSetSystemInformation); GET_FUNC_INDEX(ZwOpenProcess); GET_FUNC_INDEX(ZwDeviceIoControlFile); GET_FUNC_INDEX(ZwOpenKey); GET_FUNC_INDEX(ZwDuplicateObject); GET_FUNC_INDEX(ZwFsControlFile); GET_FUNC_INDEX(ZwReplaceKey); GET_FUNC_INDEX(ZwRestoreKey); GET_FUNC_INDEX(ZwAdjustPrivilegesToken); GET_FUNC_INDEX(ZwUnmapViewOfSection); GET_FUNC_INDEX(ZwSetSystemTime); GET_FUNC_INDEX(ZwSetSecurityObject); GET_FUNC_INDEX(ZwAllocateVirtualMemory); GET_FUNC_INDEX(ZwFreeVirtualMemory); GET_FUNC_INDEX(ZwEnumerateValueKey); GET_FUNC_INDEX(ZwQueryKey); GET_FUNC_INDEX(ZwEnumerateKey); GET_FUNC_INDEX(ZwConnectPort); // 特殊处理 ULONG ulMajorVersion, ulMinorVersion, ulBuildNumber; ulMajorVersion = ulMinorVersion = ulBuildNumber = 0; PsGetVersion(&ulMajorVersion, &ulMinorVersion, &ulBuildNumber, NULL); g_dwZwSecureConnectPortIndex = 1000; if(0 == g_dwZwSecureConnectPortAddr) { if(5 == ulMajorVersion) { if(0 == ulMinorVersion) { g_dwZwSecureConnectPortIndex = 184; } else if(1 == ulMinorVersion) { g_dwZwSecureConnectPortIndex = 210; } } } else { if(0xb8 == *(BYTE*)g_dwZwSecureConnectPortAddr) { g_dwZwSecureConnectPortIndex = *(DWORD*)(g_dwZwSecureConnectPortAddr + 1); } if(g_dwZwSecureConnectPortIndex >= 1000) { g_dwZwSecureConnectPortIndex = 1000; } } KdPrint(("[InitSSDTData]ZwSecureConnectPort Index: %d.\n", g_dwZwSecureConnectPortIndex)); g_dwZwAlpcConnectPortIndex = 1000; if(g_dwZwAlpcConnectPortAddr != 0) { GET_FUNC_INDEX(ZwAlpcConnectPort); } else { KdPrint(("[InitSSDTData]ZwAlpcConnectPort Index: 1000.\n")); } GET_FUNC_INDEX(ZwSetTimer); GET_FUNC_INDEX(ZwSetInformationProcess); GET_FUNC_INDEX(ZwMapViewOfSection); // TODO: 其它SSDT Index bRet = TRUE; } while (0); return bRet; }
NTSTATUS GetWindowsVersion() { UNICODE_STRING ustrFuncName = { 0 }; RTL_OSVERSIONINFOEXW osverinfo = { sizeof(osverinfo) }; PFN_RtlGetVersion pfnRtlGetVersion = NULL; g_WindowsVersion= WINDOWS_VERSION_NONE; //获取 RtlGetVersion 函数的地址 RtlInitUnicodeString(&ustrFuncName, L"RtlGetVersion"); pfnRtlGetVersion = MmGetSystemRoutineAddress(&ustrFuncName); //如果获取到 RtlGetVersion 函数的地址 则直接调用该函数 if (pfnRtlGetVersion) { DbgPrint("[GetWindowsVersion] Using \"RtlGetVersion\"\n"); if (!NT_SUCCESS(pfnRtlGetVersion((PRTL_OSVERSIONINFOW)&osverinfo))) return STATUS_UNSUCCESSFUL; } //否则调用 PsGetVersion 函数来获取操作系统版本信息 else { DbgPrint("[GetWindowsVersion] Using \"PsGetVersion\"\n"); if(!PsGetVersion(&osverinfo.dwMajorVersion, &osverinfo.dwMinorVersion, &osverinfo.dwBuildNumber, NULL)) return STATUS_UNSUCCESSFUL; } //打印操作系统版本信息 DbgPrint( "[GetWindowsVersion] OS Version: NT %d.%d.%d sp%d.%d\n", osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber, osverinfo.wServicePackMajor, osverinfo.wServicePackMinor ); //保存操作系统版本到 全局变量 g_WindowsVersion //5.0 = 2k if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0) { g_WindowsVersion= WINDOWS_VERSION_2K; } //5.1 = xp else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1) { g_WindowsVersion= WINDOWS_VERSION_XP; } //5.2 = 2k3 else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2) { if (osverinfo.wServicePackMajor==0) { g_WindowsVersion= WINDOWS_VERSION_2K3; } else { g_WindowsVersion= WINDOWS_VERSION_2K3_SP1_SP2; } } //6.0 = vista else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0) { g_WindowsVersion= WINDOWS_VERSION_VISTA; } //7.0 = win7 else if (osverinfo.dwMajorVersion == 7 && osverinfo.dwMinorVersion == 0) { g_WindowsVersion= WINDOWS_VERSION_7; } //保存操作系统的Build Number到全局变量g_WindowsBuildNumber g_WindowsBuildNumber=osverinfo.dwBuildNumber; return STATUS_SUCCESS; }
// // Packet Driver's entry routine. // NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NDIS_PROTOCOL_CHARACTERISTICS ProtocolChar; PDEVICE_OBJECT DeviceObject = NULL; PDEVICE_EXTENSION DeviceExtension = NULL; NTSTATUS Status = STATUS_SUCCESS; NTSTATUS ErrorCode = STATUS_SUCCESS; NDIS_STRING ProtoName = NDIS_STRING_CONST("PacketDriver"); ULONG DevicesCreated=0; NDIS_HANDLE NdisProtocolHandle; WCHAR* bindT; PKEY_VALUE_PARTIAL_INFORMATION tcpBindingsP; UNICODE_STRING macName; ULONG OsMajorVersion, OsMinorVersion; PsGetVersion(&OsMajorVersion, &OsMinorVersion, NULL, NULL); // // Define the correct flag to skip the loopback packets, according to the OS // if((OsMajorVersion == 5) && (OsMinorVersion == 0)) { // Windows 2000 wants both NDIS_FLAGS_DONT_LOOPBACK and NDIS_FLAGS_SKIP_LOOPBACK g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK | NDIS_FLAGS_SKIP_LOOPBACK_W2K; } else { // Windows XP, 2003 and following want only NDIS_FLAGS_DONT_LOOPBACK g_SendPacketFlags = NDIS_FLAGS_DONT_LOOPBACK; } if (((OsMajorVersion == 6) && (OsMinorVersion >= 1)) || (OsMajorVersion >= 7)) { // Use KeQueryActiveProcessors to get the number of CPUs in Windows 7 or later KAFFINITY cpus = KeQueryActiveProcessors(); NCpu = 0; while (cpus) { if (cpus % 2) { NCpu++; } cpus = cpus / 2; } } else { // Use NdisSystemProcessorCount in Windows Vista or earlier NCpu = NdisSystemProcessorCount(); } ReadTimeStampModeFromRegistry(RegistryPath); IF_LOUD(DbgPrint("%ws",RegistryPath->Buffer);)
NTSTATUS LpxRegisterProtocol ( IN PUNICODE_STRING NameString ) /*++ Routine Description: This routine introduces this transport to the NDIS interface. Arguments: Irp - Pointer to the request packet representing the I/O request. Return Value: The function value is the status of the operation. STATUS_SUCCESS if all goes well, Failure status if we tried to register and couldn't, STATUS_INSUFFICIENT_RESOURCES if we couldn't even try to register. --*/ { NDIS_STATUS ndisStatus; UNICODE_STRING functionName; PNDIS_PROTOCOL_CHARACTERISTICS ProtChars; UINT ProtCharsLen; ULONG lpxMajorVersion; ULONG lpxMinorVersion; NTSTATUS (*GetVersion) (PRTL_OSVERSIONINFOW); RtlInitUnicodeString( &functionName, L"RtlGetVersion" ); GetVersion = MmGetSystemRoutineAddress( &functionName ); if (GetVersion != NULL) { NTSTATUS status; RTL_OSVERSIONINFOW versionInfo; versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); status = GetVersion(&versionInfo); NDAS_ASSERT( NT_SUCCESS(status) ); lpxMajorVersion = versionInfo.dwMajorVersion; lpxMinorVersion = versionInfo.dwMinorVersion; } else { PsGetVersion( &lpxMajorVersion, &lpxMinorVersion, NULL, NULL ); } // Set up the characteristics of this protocol // NDIS 3.0 field if (1) { //if (lpxMajorVersion == 5 && lpxMinorVersion >= 1 || lpxMajorVersion > 5) { ProtChars = (PNDIS_PROTOCOL_CHARACTERISTICS)&Ndis50ProtChars; ProtCharsLen = sizeof(Ndis50ProtChars); ProtChars->MajorNdisVersion = 4; ProtChars->MinorNdisVersion = 0; } else { ProtChars = (PNDIS_PROTOCOL_CHARACTERISTICS)&Ndis40ProtChars; ProtCharsLen = sizeof(Ndis40ProtChars); ProtChars->MajorNdisVersion = 4; ProtChars->MinorNdisVersion = 0; } ProtChars->Filler; ProtChars->Flags; ProtChars->OpenAdapterCompleteHandler = LpxOpenAdapterComplete; ProtChars->CloseAdapterCompleteHandler = LpxCloseAdapterComplete; #ifdef LPX_LOCKS ProtChars->SendCompleteHandler = LpxFakeSendCompletionHandler; ProtChars->TransferDataCompleteHandler = LpxFakeTransferDataComplete; #else ProtChars->SendCompleteHandler = LpxSendCompletionHandler; ProtChars->TransferDataCompleteHandler = LpxTransferDataComplete; #endif ProtChars->ResetCompleteHandler = LpxResetComplete; ProtChars->RequestCompleteHandler = LpxRequestComplete; ProtChars->ReceiveHandler = LpxReceiveIndication; ProtChars->ReceiveCompleteHandler = LpxReceiveComplete; ProtChars->StatusHandler = LpxStatusIndication; ProtChars->StatusCompleteHandler = LpxStatusComplete; ProtChars->Name.Length = NameString->Length; ProtChars->Name.MaximumLength = NameString->MaximumLength; ProtChars->Name.Buffer = NameString->Buffer; // NDIS 4.0 fields ProtChars->ReceivePacketHandler = LpxProtocolReceivePacket; ProtChars->BindAdapterHandler = LpxProtocolBindAdapter; ProtChars->UnbindAdapterHandler = LpxProtocolUnbindAdapter; ProtChars->PnPEventHandler = LpxProtocolPnPEventHandler; ProtChars->UnloadHandler; #if (defined(NDIS50) || defined(NDIS51)) if (1) { //if (ProtChars->MajorNdisVersion == 5) { // Start of NDIS 5.0 extensions. ProtChars->ReservedHandlers; ProtChars->CoSendCompleteHandler = LpxCoSendCompleteHandler; ProtChars->CoStatusHandler = LpxCoStatusHandler; ProtChars->CoReceivePacketHandler = LpxCoReceivePacketHandler; ProtChars->CoAfRegisterNotifyHandler = LpxCoAfRegisterNotifyHandler; } #endif //NDAS_ASSERT( ProtChars->CoSendCompleteHandler == LpxCoSendCompleteHandler ); NdisRegisterProtocol( &ndisStatus, &LpxNdisProtocolHandle, ProtChars, ProtCharsLen ); if (ndisStatus != NDIS_STATUS_SUCCESS) { NDAS_ASSERT(FALSE); #if DBG IF_LPXDBG (LPX_DEBUG_RESOURCE) { LpxPrint1( "LpxInitialize: NdisRegisterProtocol failed: %s\n", LpxGetNdisStatus(ndisStatus) ); } #endif return (NTSTATUS)ndisStatus; }
NTSTATUS DriverEntry ( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath ) { NTSTATUS status; HANDLE event; BOOLEAN clean = FALSE; PDEVICE_OBJECT devobj; ULONG maver, miver, phase; UNICODE_STRING dn; OBJECT_ATTRIBUTES oa; RtlInitUnicodeString(&dn, MU_EVENTNAME_BOOTSYNC); InitializeObjectAttributes(&oa, &dn, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status = ZwOpenEvent(&event, EVENT_ALL_ACCESS, &oa); if (NT_SUCCESS(status)) { ZwSetEvent(event, NULL); ZwClose(event); } RtlInitUnicodeString(&dn, MU_DEVNAME_HOST_CONTROL); phase = PHASE_CREATE_DEVICE; status = IoCreateDevice(DriverObject, 0, &dn, FILE_DEVICE_UNKNOWN, 0, FALSE, &devobj); if (NT_SUCCESS(status)) { PsGetVersion(&maver, &miver, NULL, NULL); OsVersion = (maver << 16) | miver; OsVersion |= MmIsThisAnNtAsSystem() ? 0x80000000 : 0; phase = PHASE_CHECK_OS_VERSION; switch (OsVersion) { case VER_WINXP: case VER_WIN2K3: case VER_WIN7: break; case VER_WIN2K8R2: case VER_WIN2K8: case VER_VISTA: //break; default: goto MuDriverEntry_Failure; } MuInitializeGlobalData(&g_GlobalData); phase = PHASE_LOAD_DATABASE; status = MuLoadDatabase(&g_GlobalData); if (!NT_SUCCESS(status)) goto MuDriverEntry_Failure; phase = PHASE_INIT_KERNEL_HOOK; status = MuInitializeKernelHook(&g_GlobalData); if (!NT_SUCCESS(status)) goto MuDriverEntry_Failure; phase = PHASE_SET_NOTIFY; status = PsSetCreateProcessNotifyRoutine(MuCreateProcessNotify, FALSE); if (!NT_SUCCESS(status)) goto MuDriverEntry_Failure; clean = TRUE; phase = PHASE_INIT_HELPER; status = MuInitializeUserModeHelper(&g_GlobalData); if (!NT_SUCCESS(status)) goto MuDriverEntry_Failure; DriverObject->MajorFunction[IRP_MJ_CREATE] = MuDispatchCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = MuDispatchCreateClose; DriverObject->MajorFunction[IRP_MJ_POWER] = MuDispatchPower; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MuDispatchDeviceControl; goto MuDriverEntry_End; MuDriverEntry_Failure: if (clean) PsSetCreateProcessNotifyRoutine(MuCreateProcessNotify, TRUE); IoDeleteDevice(devobj); } MuDriverEntry_End: RegistryPath->Buffer[RegistryPath->Length / sizeof(WCHAR)] = 0; if (NT_SUCCESS(status)) MuDeleteRegistryValue(RegistryPath->Buffer, MU_REGVAL_LAST_ERROR); else MuSetErrorCode(RegistryPath, phase, status); if (phase > PHASE_INIT_KERNEL_HOOK) return STATUS_SUCCESS; return status; }
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: Initialize the driver dispatch table. Arguments: DriverObject - pointer to the driver object RegistryPath - pointer to a unicode string representing the path, to driver-specific key in the registry. Return Value: NT Status Code --*/ { Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("%s, %s\n", __DATE__, __TIME__)); // // Save the RegistryPath for WMI. // Globals.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); Globals.RegistryPath.Length = RegistryPath->Length; Globals.RegistryPath.Buffer = ExAllocatePoolWithTag( PagedPool, Globals.RegistryPath.MaximumLength, BUSENUM_POOL_TAG ); if (!Globals.RegistryPath.Buffer) { return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyUnicodeString(&Globals.RegistryPath, RegistryPath); // Added by jgahn. // Get OS Version. Globals.bCheckVersion = PsGetVersion( &Globals.MajorVersion, &Globals.MinorVersion, &Globals.BuildNumber, NULL ); if(Globals.bCheckVersion == TRUE) { Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("Checkd Build, Major Ver %d, Minor Ver %d, Build %d\n", Globals.MajorVersion, Globals.MinorVersion, Globals.BuildNumber)); } else { Bus_KdPrint_Def (BUS_DBG_SS_INFO, ("Free Build, Major Ver %d, Minor Ver %d, Build %d\n", Globals.MajorVersion, Globals.MinorVersion, Globals.BuildNumber)); } // // Set entry points into the driver // DriverObject->MajorFunction [IRP_MJ_CREATE] = DriverObject->MajorFunction [IRP_MJ_CLOSE] = Bus_CreateClose; DriverObject->MajorFunction [IRP_MJ_PNP] = Bus_PnP; DriverObject->MajorFunction [IRP_MJ_POWER] = Bus_Power; DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = Bus_IoCtl; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Bus_SystemControl; DriverObject->DriverUnload = Bus_DriverUnload; DriverObject->DriverExtension->AddDevice = Bus_AddDevice; return STATUS_SUCCESS; }
/** * Driver entry point. * * @returns appropriate status code. * @param pDrvObj Pointer to driver object. * @param pRegPath Registry base path. */ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath) { NTSTATUS rc = STATUS_SUCCESS; Log(("VBoxGuest::DriverEntry. Driver built: %s %s\n", __DATE__, __TIME__)); ULONG majorVersion; ULONG minorVersion; ULONG buildNumber; BOOLEAN bCheckedBuild = PsGetVersion(&majorVersion, &minorVersion, &buildNumber, NULL); Log(("VBoxGuest::DriverEntry: Running on Windows NT version %d.%d, build %d\n", majorVersion, minorVersion, buildNumber)); if (bCheckedBuild) Log(("VBoxGuest::DriverEntry: Running on a Windows checked build (debug)!\n")); #ifdef DEBUG vboxguestwinDoTests(); #endif switch (majorVersion) { case 6: /* Windows Vista or Windows 7 (based on minor ver) */ switch (minorVersion) { case 0: /* Note: Also could be Windows 2008 Server! */ g_winVersion = WINVISTA; break; case 1: /* Note: Also could be Windows 2008 Server R2! */ g_winVersion = WIN7; break; case 2: g_winVersion = WIN8; break; default: Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n", majorVersion, minorVersion)); rc = STATUS_DRIVER_UNABLE_TO_LOAD; break; } break; case 5: switch (minorVersion) { case 2: g_winVersion = WIN2K3; break; case 1: g_winVersion = WINXP; break; case 0: g_winVersion = WIN2K; break; default: Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n", majorVersion, minorVersion)); rc = STATUS_DRIVER_UNABLE_TO_LOAD; } break; case 4: g_winVersion = WINNT4; break; default: Log(("VBoxGuest::DriverEntry: At least Windows NT4 required!\n")); rc = STATUS_DRIVER_UNABLE_TO_LOAD; } if (NT_SUCCESS(rc)) { /* * Setup the driver entry points in pDrvObj. */ pDrvObj->DriverUnload = vboxguestwinUnload; pDrvObj->MajorFunction[IRP_MJ_CREATE] = vboxguestwinCreate; pDrvObj->MajorFunction[IRP_MJ_CLOSE] = vboxguestwinClose; pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxguestwinIOCtl; pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinInternalIOCtl; pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN] = vboxguestwinShutdown; pDrvObj->MajorFunction[IRP_MJ_READ] = vboxguestwinNotSupportedStub; pDrvObj->MajorFunction[IRP_MJ_WRITE] = vboxguestwinNotSupportedStub; #ifdef TARGET_NT4 rc = vboxguestwinnt4CreateDevice(pDrvObj, NULL /* pDevObj */, pRegPath); #else pDrvObj->MajorFunction[IRP_MJ_PNP] = vboxguestwinPnP; pDrvObj->MajorFunction[IRP_MJ_POWER] = vboxguestwinPower; pDrvObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxguestwinSystemControl; pDrvObj->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)vboxguestwinAddDevice; #endif } Log(("VBoxGuest::DriverEntry returning %#x\n", rc)); return rc; }
// Win32 driver entry point NDIS_STATUS DriverEntry(DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath) { NDIS_MINIPORT_DRIVER_CHARACTERISTICS miniport; ULONG os_major_ver = 0, os_minor_ver = 0; NDIS_STATUS ret; // Initialize the Neo library if (NeoInit() == FALSE) { // Initialization Failed return STATUS_UNSUCCESSFUL; } g_is_win8 = false; // Get the OS version PsGetVersion(&os_major_ver, &os_minor_ver, NULL, NULL); if (os_major_ver >= 7 || (os_major_ver == 6 && os_minor_ver >= 2)) { // Windows 8 g_is_win8 = true; } // Register a NDIS miniport driver NeoZero(&miniport, sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS)); miniport.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; miniport.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; miniport.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_2; miniport.MajorNdisVersion = NEO_NDIS_MAJOR_VERSION; miniport.MinorNdisVersion = NEO_NDIS_MINOR_VERSION; // Register the handler miniport.InitializeHandlerEx = NeoNdisInitEx; miniport.HaltHandlerEx = NeoNdisHaltEx; miniport.OidRequestHandler = NeoNdisOidRequest; miniport.ResetHandlerEx = NeoNdisResetEx; miniport.CheckForHangHandlerEx = NeoNdisCheckForHangEx; miniport.UnloadHandler = NeoNdisDriverUnload; miniport.SendNetBufferListsHandler = NeoNdisSendNetBufferLists; miniport.SetOptionsHandler = NeoNdisSetOptions; miniport.PauseHandler = NeoNdisPause; miniport.RestartHandler = NeoNdisRestart; miniport.ReturnNetBufferListsHandler = NeoNdisReturnNetBufferLists; miniport.CancelSendHandler = NeoNdisCancelSend; miniport.DevicePnPEventNotifyHandler = NeoNdisDevicePnPEventNotify; miniport.ShutdownHandlerEx = NeoNdisShutdownEx; miniport.CancelOidRequestHandler = NeoNdisCancelOidRequest; ret = NdisMRegisterMiniportDriver(DriverObject, RegistryPath, NULL, &miniport, &ndis_miniport_driver_handle); if (NG(ret)) { // Registration failure return STATUS_UNSUCCESSFUL; } // Initialization success return STATUS_SUCCESS; }