NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ustrLinkName; UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj; pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; pDriverObj->DriverUnload = DriverUnload; RtlInitUnicodeString(&ustrDevName, DEVICE_NAME); status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj); if(!NT_SUCCESS(status)) return status; if(IoIsWdmVersionAvailable(1, 0x10)) RtlInitUnicodeString(&ustrLinkName, LINK_GLOBAL_NAME); else RtlInitUnicodeString(&ustrLinkName, LINK_NAME); status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); if(!NT_SUCCESS(status)) { IoDeleteDevice(pDevObj); return status; } //test KeServiceDescriptorTableShadow = (PSYSTEM_SERVICE_TABLE)GetKeServiceDescriptorTableShadow64(); //DbgPrint("SSSDT: %llx[TA's method]",(ULONG64)KeServiceDescriptorTableShadow); //test return STATUS_SUCCESS; }
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ustrLinkName; UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj; pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; pDriverObj->DriverUnload = DriverUnload; RtlInitUnicodeString(&ustrDevName, DEVICE_NAME); status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj); if(!NT_SUCCESS(status)) return status; if(IoIsWdmVersionAvailable(1, 0x10)) RtlInitUnicodeString(&ustrLinkName, LINK_GLOBAL_NAME); else RtlInitUnicodeString(&ustrLinkName, LINK_NAME); status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); if(!NT_SUCCESS(status)) { IoDeleteDevice(pDevObj); return status; } //独占“程序兼容性助手”防弹框 OccupyTaskhost(); //初始化反汇编引擎 LDE_init(); return STATUS_SUCCESS; }
GENERICAPI BOOLEAN IsWin98() { // IsWin98 #ifdef _X86_ return !IoIsWdmVersionAvailable(1, 0x10); #else return FALSE; #endif // _X86_ } // IsWin98
// todo(chencai): 改成传递操作系统型号的接口形式 NTSTATUS CheckWDMVersion() { // Determine OS version through WDM version information // If some operations are not supported in all versions of windows, // handle that carefully here. if (IoIsWdmVersionAvailable(0x01, 0x10) == FALSE) { if (IoIsWdmVersionAvailable(0x01, 0x00) == TRUE) { DbgPrint("OS supports WDM 1.0 (Windows 98)\n"); } else { DbgPrint("WARNING - OS does not support WDM 1.0\n"); } } else { DbgPrint("OS supports WDM 1.10 (Windows 2000 or above)\n"); } return STATUS_SUCCESS; }
/******************************************************************************* * * 函 数 名 : DriverUnload * 功能描述 : DriverUnload * 参数列表 : pDriverObj -- * 说 明 : * 返回结果 : * *******************************************************************************/ VOID DriverUnload(IN PDRIVER_OBJECT pDriverObj) { UNICODE_STRING strLink; PDEVICE_EXTENSION pde = (PDEVICE_EXTENSION)pDriverObj->DeviceObject->DeviceExtension ; // Unloading - no resources to free so just return. dprintf("Unloading...\r\n"); // // TODO: Add uninstall code here. // if (pde->bIsSetCreateProcessNotifyRoutine) { PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE) ; } // 如果挂钩了NtOpenProcess if (pde->bIsHookNtOpenProcess) { UnHookNtOpenProcess(pDriverObj->DeviceObject) ; } // 如果挂钩了NtQuerySystemInformation if (pde->bIsHookNtQuerySystemInformation) { UnHookNtQuerySystemInformation(pDriverObj->DeviceObject) ; } // Delete the symbolic link if(IoIsWdmVersionAvailable(1,0x10)) { //如果是支持符号链接用户相关性的系统 RtlInitUnicodeString(&strLink, SYMBOLIC_LINK_GLOBAL_NAME); } else { //不支持 RtlInitUnicodeString(&strLink, SYMBOLIC_LINK_NAME); } IoDeleteSymbolicLink(&strLink); // Delete the DeviceObject IoDeleteDevice(pDriverObj->DeviceObject); ReleaseKernelUserManage() ; dprintf("Unloaded Success\r\n"); return; }
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { KdPrint((DRIVERNAME " - Entering DriverEntry: DriverObject %8.8lX\n", DriverObject)); // Insist that OS support at least the WDM level of the DDK we use if(!IoIsWdmVersionAvailable(1, 0)) { KdPrint((DRIVERNAME " - Expected version of WDM (%d.%2.2d) not available\n", 1, 0)); return STATUS_UNSUCCESSFUL; } // See if we're running under Win98 or NT: win98 = IsWin98(); if(win98) KdPrint((DRIVERNAME " - Running under Windows 98\n")); else KdPrint((DRIVERNAME " - Running under NT\n")); // Initialize function pointers DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = AddDevice; DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; DriverObject->MajorFunction[IRP_MJ_READ] = DispatchReadWriteFlush; DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchReadWriteFlush; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DispatchReadWriteFlush; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup; DriverObject->MajorFunction[IRP_MJ_POWER] = DispatchPower; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = DispatchInternalControl; DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = DispatchWmi; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceIoControl; return STATUS_SUCCESS; }
/******************************************************************************* * * 函 数 名 : DriverEntry * 功能描述 : D R I V E R E N T R Y P O I N T * 参数列表 : pDriverObj -- * pRegistryString * 说 明 : * 返回结果 : * *******************************************************************************/ NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ustrLinkName; UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pde = NULL ; int i = 0; dprintf("ProcessManageSys Driver\r\n" "Compiled %s %s\r\nIn DriverEntry : %wZ\r\n", __DATE__, __TIME__, pRegistryString); // Register dispatch routines /* for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { pDriverObj->MajorFunction[i] = DispatchCommon; } */ pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; // Dispatch routine for communications pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; // Unload routine pDriverObj->DriverUnload = DriverUnload; // Initialize the device name. RtlInitUnicodeString(&ustrDevName, NT_DEVICE_NAME); // Create the device object and device extension status = IoCreateDevice(pDriverObj, sizeof(DEVICE_EXTENSION), &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj); if(!NT_SUCCESS(status)) { dprintf("Error, IoCreateDevice = 0x%x\r\n", status); return status; } //// Get a pointer to our device extension //deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; pde = (PDEVICE_EXTENSION)(pDevObj->DeviceExtension) ; g_pde = pde ; //// Save a pointer to the device object //deviceExtension->DeviceObject = deviceObject; if(IoIsWdmVersionAvailable(1,0x10)) { //如果是支持符号链接用户相关性的系统 RtlInitUnicodeString(&ustrLinkName, SYMBOLIC_LINK_GLOBAL_NAME); } else { //不支持 RtlInitUnicodeString(&ustrLinkName, SYMBOLIC_LINK_NAME); } // Create a symbolic link to allow USER applications to access it. status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); if(!NT_SUCCESS(status)) { dprintf("Error, IoCreateSymbolicLink = 0x%x\r\n", status); IoDeleteDevice(pDevObj); return status; } // // TODO: Add initialization code here. // // 成功之后就开始初始化我们的设备扩展结构体了 InitlizedDeviceExtension(pde) ; // 这里也可以用来监控 //if(NT_SUCCESS(PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE))) //{ // // 这里做标记 // pde->bIsSetCreateProcessNotifyRoutine = true ; //} // 挂钩NtOpenProcess if(HookNtOpenProcess(pDevObj)) { pde->bIsHookNtOpenProcess = true ; } // 挂钩NtQuerySystemInformation if(HookNtQuerySystemInformation(pDevObj)) { pde->bIsHookNtQuerySystemInformation = true ; } //// Tell the I/O Manger to do BUFFERED IO // 读写操作使用缓冲区方式访问用户模式数据 // 一次只允许一个线程打开设备句柄 pDevObj->Flags |= DO_BUFFERED_IO | DO_EXCLUSIVE ; // 移除初始标志 pDevObj->Flags &= ~DO_DEVICE_INITIALIZING ; //// Save the DeviveObject InitializeKernelUserManage() ; Test() ; dprintf("DriverEntry Success\r\n"); return STATUS_SUCCESS; }
// AddDevice, called when an instance of our supported hardware is found // Returning anything other than NT_SUCCESS here causes the device to fail // to initialise NTSTATUS NTAPI FreeBT_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; POWER_STATE state; KIRQL oldIrql; UNICODE_STRING uniDeviceName; WCHAR wszDeviceName[255]={0}; UNICODE_STRING uniDosDeviceName; LONG instanceNumber=0; FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Entered\n")); deviceObject = NULL; swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); RtlInitUnicodeString(&uniDeviceName, wszDeviceName); ntStatus=STATUS_OBJECT_NAME_COLLISION; while (instanceNumber<99 && !NT_SUCCESS(ntStatus)) { swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); uniDeviceName.Length = wcslen(wszDeviceName) * sizeof(WCHAR); FreeBT_DbgPrint(1, ("FBTUSB: Attempting to create device %ws\n", wszDeviceName)); ntStatus = IoCreateDevice( DriverObject, // our driver object sizeof(DEVICE_EXTENSION), // extension size for us &uniDeviceName, // name for this device FILE_DEVICE_UNKNOWN, 0, // device characteristics FALSE, // Not exclusive &deviceObject); // Our device object if (!NT_SUCCESS(ntStatus)) instanceNumber++; } if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: Failed to create device object\n")); return ntStatus; } FreeBT_DbgPrint(1, ("FBTUSB: Created device %ws\n", wszDeviceName)); deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->FunctionalDeviceObject = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; deviceObject->Flags |= DO_DIRECT_IO; swprintf(deviceExtension->wszDosDeviceName, L"\\DosDevices\\FbtUsb%02d", instanceNumber); RtlInitUnicodeString(&uniDosDeviceName, deviceExtension->wszDosDeviceName); ntStatus=IoCreateSymbolicLink(&uniDosDeviceName, &uniDeviceName); if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: Failed to create symbolic link %ws to %ws, status=0x%08x\n", deviceExtension->wszDosDeviceName, wszDeviceName, ntStatus)); IoDeleteDevice(deviceObject); return ntStatus; } FreeBT_DbgPrint(1, ("FBTUSB: Created symbolic link %ws\n", deviceExtension->wszDosDeviceName)); KeInitializeSpinLock(&deviceExtension->DevStateLock); INITIALIZE_PNP_STATE(deviceExtension); deviceExtension->OpenHandleCount = 0; // Initialize the selective suspend variables KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); deviceExtension->IdleReqPend = 0; deviceExtension->PendingIdleIrp = NULL; // Hold requests until the device is started deviceExtension->QueueState = HoldRequests; // Initialize the queue and the queue spin lock InitializeListHead(&deviceExtension->NewRequestsQueue); KeInitializeSpinLock(&deviceExtension->QueueLock); // Initialize the remove event to not-signaled. KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); // Initialize the stop event to signaled. // This event is signaled when the OutstandingIO becomes 1 KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); // OutstandingIo count biased to 1. // Transition to 0 during remove device means IO is finished. // Transition to 1 means the device can be stopped deviceExtension->OutStandingIO = 1; KeInitializeSpinLock(&deviceExtension->IOCountLock); #ifdef ENABLE_WMI // Delegating to WMILIB ntStatus = FreeBT_WmiRegistration(deviceExtension); if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WmiRegistration failed with %X\n", ntStatus)); IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return ntStatus; } #endif // Set the flags as underlying PDO if (PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) { deviceObject->Flags |= DO_POWER_PAGABLE; } // Typically, the function driver for a device is its // power policy owner, although for some devices another // driver or system component may assume this role. // Set the initial power state of the device, if known, by calling // PoSetPowerState. deviceExtension->DevPower = PowerDeviceD0; deviceExtension->SysPower = PowerSystemWorking; state.DeviceState = PowerDeviceD0; PoSetPowerState(deviceObject, DevicePowerState, state); // attach our driver to device stack // The return value of IoAttachDeviceToDeviceStack is the top of the // attachment chain. This is where all the IRPs should be routed. deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if (NULL == deviceExtension->TopOfStackDeviceObject) { #ifdef ENABLE_WMI FreeBT_WmiDeRegistration(deviceExtension); #endif IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return STATUS_NO_SUCH_DEVICE; } // Register device interfaces ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, &GUID_CLASS_FREEBT_USB, NULL, &deviceExtension->InterfaceName); if (!NT_SUCCESS(ntStatus)) { #ifdef ENABLE_WMI FreeBT_WmiDeRegistration(deviceExtension); #endif IoDetachDevice(deviceExtension->TopOfStackDeviceObject); IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return ntStatus; } if (IoIsWdmVersionAvailable(1, 0x20)) { deviceExtension->WdmVersion = WinXpOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x10)) { deviceExtension->WdmVersion = Win2kOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x5)) { deviceExtension->WdmVersion = WinMeOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x0)) { deviceExtension->WdmVersion = Win98OrBetter; } deviceExtension->SSRegistryEnable = 0; deviceExtension->SSEnable = 0; // WinXP only: check the registry flag indicating whether // the device should selectively suspend when idle if (WinXpOrBetter == deviceExtension->WdmVersion) { FreeBT_GetRegistryDword(FREEBT_REGISTRY_PARAMETERS_PATH, L"BulkUsbEnable", (PULONG)(&deviceExtension->SSRegistryEnable)); if (deviceExtension->SSRegistryEnable) { // initialize DPC KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); // initialize the timer. // the DPC and the timer in conjunction, // monitor the state of the device to // selectively suspend the device. KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); // Initialize the NoDpcWorkItemPendingEvent to signaled state. // This event is cleared when a Dpc is fired and signaled // on completion of the work-item. KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); } } // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. KeInitializeEvent(&deviceExtension->DelayEvent, NotificationEvent, FALSE); // Clear the DO_DEVICE_INITIALIZING flag. // Note: Do not clear this flag until the driver has set the // device power state and the power DO flags. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; InterlockedIncrement(&instanceNumber); FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Leaving\n")); return ntStatus; }
NTSTATUS MobiUsb_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) /*++ Description: Arguments: DriverObject - Store the pointer to the object representing us. PhysicalDeviceObject - Pointer to the device object created by the undelying bus driver. Return: STATUS_SUCCESS - if successful STATUS_UNSUCCESSFUL - otherwise --*/ { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; POWER_STATE state; KIRQL oldIrql; MobiUsb_DbgPrint(3, ("file mobiusb: MobiUsb_AddDevice - begins\n")); deviceObject = NULL; ntStatus = IoCreateDevice( DriverObject, // our driver object sizeof(DEVICE_EXTENSION), // extension size for us NULL, // name for this device FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics FALSE, // Not exclusive &deviceObject); // Our device object if(!NT_SUCCESS(ntStatus)) { // // returning failure here prevents the entire stack from functioning, // but most likely the rest of the stack will not be able to create // device objects either, so it is still OK. // MobiUsb_DbgPrint(1, ("file mobiusb: Failed to create device object\n")); return ntStatus; } // // Initialize the device extension // deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->FunctionalDeviceObject = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; #ifdef MOBI_DIRECT_IO deviceObject->Flags |= DO_DIRECT_IO; #else deviceObject->Flags |= DO_BUFFERED_IO; #endif // // initialize the device state lock and set the device state // KeInitializeSpinLock(&deviceExtension->DevStateLock); INITIALIZE_PNP_STATE(deviceExtension); // //initialize OpenHandleCount // deviceExtension->OpenHandleCount = 0; // // Initialize the selective suspend variables // KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); deviceExtension->IdleReqPend = 0; deviceExtension->PendingIdleIrp = NULL; // // Initialize the vendor command semaphore // KeInitializeSemaphore(&deviceExtension->CallUSBSemaphore, 1, 1); // // Hold requests until the device is started // deviceExtension->QueueState = HoldRequests; // // Initialize the queue and the queue spin lock // InitializeListHead(&deviceExtension->NewRequestsQueue); KeInitializeSpinLock(&deviceExtension->QueueLock); // // Initialize the remove event to not-signaled. // KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); // // Initialize the stop event to signaled. // This event is signaled when the OutstandingIO becomes 1 // KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); // // OutstandingIo count biased to 1. // Transition to 0 during remove device means IO is finished. // Transition to 1 means the device can be stopped // deviceExtension->OutStandingIO = 1; KeInitializeSpinLock(&deviceExtension->IOCountLock); // // Delegating to WMILIB // ntStatus = MobiUsb_WmiRegistration(deviceExtension); if(!NT_SUCCESS(ntStatus)) { MobiUsb_DbgPrint(1, ("file mobiusb: MobiUsb_WmiRegistration failed with %X\n", ntStatus)); IoDeleteDevice(deviceObject); return ntStatus; } // // set the flags as underlying PDO // if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) { deviceObject->Flags |= DO_POWER_PAGABLE; } // // Typically, the function driver for a device is its // power policy owner, although for some devices another // driver or system component may assume this role. // Set the initial power state of the device, if known, by calling // PoSetPowerState. // deviceExtension->DevPower = PowerDeviceD0; deviceExtension->SysPower = PowerSystemWorking; state.DeviceState = PowerDeviceD0; PoSetPowerState(deviceObject, DevicePowerState, state); // // attach our driver to device stack // The return value of IoAttachDeviceToDeviceStack is the top of the // attachment chain. This is where all the IRPs should be routed. // deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if(NULL == deviceExtension->TopOfStackDeviceObject) { MobiUsb_WmiDeRegistration(deviceExtension); IoDeleteDevice(deviceObject); return STATUS_NO_SUCH_DEVICE; } // // Register device interfaces // ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, &GUID_CLASS_VCMOBI_MOBI, NULL, &deviceExtension->InterfaceName); if(!NT_SUCCESS(ntStatus)) { MobiUsb_WmiDeRegistration(deviceExtension); IoDetachDevice(deviceExtension->TopOfStackDeviceObject); IoDeleteDevice(deviceObject); return ntStatus; } //MobiUsb_DbgPrint(3, ("file mobiusb: interfacename: Filename = %ws nameLength = %d\n", deviceExtension->InterfaceName.Buffer, deviceExtension->InterfaceName.Length / sizeof(WCHAR))); if(IoIsWdmVersionAvailable(1, 0x20)) { deviceExtension->WdmVersion = WinXpOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x10)) { deviceExtension->WdmVersion = Win2kOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x5)) { deviceExtension->WdmVersion = WinMeOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x0)) { deviceExtension->WdmVersion = Win98OrBetter; } MobiUsb_DbgPrint(3, ("file mobiusb: WdmVersion = %d\n", deviceExtension->WdmVersion)); deviceExtension->SSRegistryEnable = 0; deviceExtension->SSEnable = 0; // // WinXP only // check the registry flag - // whether the device should selectively // suspend when idle // if(WinXpOrBetter == deviceExtension->WdmVersion) { MobiUsb_GetRegistryDword(MOBIUSB_REGISTRY_PARAMETERS_PATH, L"VCMobiEnable", &deviceExtension->SSRegistryEnable); if(deviceExtension->SSRegistryEnable) { // // initialize DPC // KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); // // initialize the timer. // the DPC and the timer in conjunction, // monitor the state of the device to // selectively suspend the device. // KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); // // Initialize the NoDpcWorkItemPendingEvent to signaled state. // This event is cleared when a Dpc is fired and signaled // on completion of the work-item. // KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); // // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. // KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); } } // // Clear the DO_DEVICE_INITIALIZING flag. // Note: Do not clear this flag until the driver has set the // device power state and the power DO flags. // deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; MobiUsb_DbgPrint(3, ("file mobiusb: MobiUsb_AddDevice - ends\n")); return ntStatus; }
NTSTATUS FileDiskInitializeLogicalUnit( __in PNDAS_LOGICALUNIT_DESCRIPTOR LogicalUnitDescriptor, __in PNDAS_LOGICALUNIT_EXTENSION LogicalUnitExtension) { NTSTATUS status; PFILEDISK_EXTENSION fileDiskExtension; PFILEDISK_DESCRIPTOR fileDiskDescriptor; size_t dataFilePathLength; BOOLEAN newDataFileCreated; PAGED_CODE(); fileDiskExtension = FileDiskGetExtension(LogicalUnitExtension); if (sizeof(NDAS_LOGICALUNIT_DESCRIPTOR) != LogicalUnitDescriptor->Version) { NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL, "LogicalUnitDescriptor version is invalid. Version=%d, Expected=%d\n", LogicalUnitDescriptor->Version, sizeof(NDAS_LOGICALUNIT_DESCRIPTOR)); return STATUS_INVALID_PARAMETER; } if (LogicalUnitDescriptor->Size < FIELD_OFFSET(FILEDISK_DESCRIPTOR, FilePath)) { NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL, "FileDiskDescriptor Size is invalid. Size=%d, Expected=%d\n", LogicalUnitDescriptor->Size, sizeof(FILEDISK_DESCRIPTOR)); return STATUS_INVALID_PARAMETER; } NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL, "Initializing FileDisk Logical Unit\n"); fileDiskDescriptor = (PFILEDISK_DESCRIPTOR) LogicalUnitDescriptor; fileDiskExtension->FileDiskFlags = fileDiskDescriptor->FileDiskFlags; status = RtlStringCbLengthW( fileDiskDescriptor->FilePath, LogicalUnitDescriptor->Size - FIELD_OFFSET(FILEDISK_DESCRIPTOR, FilePath), &dataFilePathLength); if (!NT_SUCCESS(status)) { NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_FATAL, "FileDiskDescriptor FilePath length is invalid. Status=%08X\n", status); return status; } NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_INFORMATION, "FilePath=%ws\n", fileDiskDescriptor->FilePath); dataFilePathLength += sizeof(WCHAR); // additional NULL fileDiskExtension->FilePath.Buffer = (PWSTR) ExAllocatePoolWithTag( NonPagedPool, dataFilePathLength, FILEDISK_EXT_TAG); if (NULL == fileDiskExtension->FilePath.Buffer) { NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_WARNING, "Memory allocation failed for data file path (%d bytes).\n", dataFilePathLength); return STATUS_INSUFFICIENT_RESOURCES; } RtlCopyMemory( fileDiskExtension->FilePath.Buffer, fileDiskDescriptor->FilePath, dataFilePathLength); fileDiskExtension->FilePath.Length = dataFilePathLength - sizeof(WCHAR); fileDiskExtension->FilePath.MaximumLength = (USHORT)dataFilePathLength; fileDiskExtension->LogicalUnitAddress = LogicalUnitDescriptor->Address.Address; fileDiskExtension->LogicalBlockAddress.QuadPart = fileDiskDescriptor->LogicalBlockAddress.QuadPart; fileDiskExtension->BytesPerBlock = fileDiskDescriptor->BytesPerBlock; fileDiskExtension->ThreadShouldStop = FALSE; KeInitializeEvent( &fileDiskExtension->ThreadNotificationEvent, NotificationEvent, FALSE); KeInitializeEvent( &fileDiskExtension->ThreadCompleteEvent, NotificationEvent, FALSE); FileDiskInitializeIoScsiCapabilities(fileDiskExtension); FileDiskInitializeInquiryData(fileDiskExtension); fileDiskExtension->StorageBusType = BusTypeScsi; fileDiskExtension->StorageBusMajorVersion = 2; fileDiskExtension->StorageBusMinorVersion = 0; status = FileDiskCreateDataFile( fileDiskExtension, &fileDiskExtension->FilePath, &newDataFileCreated); if (!NT_SUCCESS(status)) { NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_WARNING, "FileDiskCreateDataFile failed, Status=%08X\n", status); goto error1; } // // For Windows 2000, PsCreateSystemThread should be called // from the system process context. // if (IoIsWdmVersionAvailable(0x01, 0x20)) { FileDiskCreateThreadWorkItemRoutine(NULL, fileDiskExtension); } else { PIO_WORKITEM workItem; workItem = NdasPortExAllocateWorkItem(LogicalUnitExtension); if (NULL == workItem) { NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_WARNING, "NdasPortExAllocateWorkItem failed with out of resource error.\n"); status = STATUS_INSUFFICIENT_RESOURCES; goto error2; } IoQueueWorkItem( workItem, FileDiskCreateThreadWorkItemRoutine, DelayedWorkQueue, fileDiskExtension); KeWaitForSingleObject( &fileDiskExtension->ThreadCompleteEvent, Executive, KernelMode, FALSE, NULL); IoFreeWorkItem(workItem); } if (!NT_SUCCESS(fileDiskExtension->ThreadStatus)) { status = fileDiskExtension->ThreadStatus; NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_INFORMATION, "FileDisk file creation failed, Status=%08X\n", status); goto error3; } NdasPortTrace(FILEDISK_INIT, TRACE_LEVEL_INFORMATION, "FileDisk created successfully at LogicalUnitAddress=%08X.\n", fileDiskExtension->LogicalUnitAddress); return STATUS_SUCCESS; error3: error2: FileDiskCloseDataFile(fileDiskExtension); if (newDataFileCreated) { FileDiskDeleteDataFile(&fileDiskExtension->FilePath); } error1: ExFreePoolWithTag( fileDiskExtension->FilePath.Buffer, FILEDISK_EXT_TAG); fileDiskExtension->FilePath.Buffer = NULL; fileDiskExtension->FilePath.Length = 0; fileDiskExtension->FilePath.MaximumLength = 0; return status; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObj, IN PUNICODE_STRING pRegistryString) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING ustrLinkName; UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj; int i = 0; DbgPrint("Hello, Driver By VS2010\r\n"); // 添加 INT 3 系统中断 #ifdef _AMD64_ int_3(); // x64系统只能调用 *.asm 汇编文件中声明的函数 #else __asm { int 3 } // x86系统可以直接使用内联汇编 #endif DbgPrint("Goodbye, Driver By VS2010\r\n"); dprintf("EasySys Sample Driver\r\n" "Compiled %s %s\r\nIn DriverEntry : %wZ\r\n", __DATE__, __TIME__, pRegistryString); // Register dispatch routines /* for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) { pDriverObj->MajorFunction[i] = DispatchCommon; } */ pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; // Dispatch routine for communications pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; // Unload routine pDriverObj->DriverUnload = DriverUnload; // Initialize the device name. RtlInitUnicodeString(&ustrDevName, NT_DEVICE_NAME); // Create the device object and device extension status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj); if(!NT_SUCCESS(status)) { dprintf("Error, IoCreateDevice = 0x%x\r\n", status); return status; } //// Get a pointer to our device extension //deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; //// Save a pointer to the device object //deviceExtension->DeviceObject = deviceObject; if(IoIsWdmVersionAvailable(1,0x10)) { //如果是支持符号链接用户相关性的系统 RtlInitUnicodeString(&ustrLinkName, SYMBOLIC_LINK_GLOBAL_NAME); } else { //不支持 RtlInitUnicodeString(&ustrLinkName, SYMBOLIC_LINK_NAME); } // Create a symbolic link to allow USER applications to access it. status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); if(!NT_SUCCESS(status)) { dprintf("Error, IoCreateSymbolicLink = 0x%x\r\n", status); IoDeleteDevice(pDevObj); return status; } // // TODO: Add initialization code here. // //// Tell the I/O Manger to do BUFFERED IO //deviceObject->Flags |= DO_BUFFERED_IO; //// Save the DeviveObject //deviceExtension->DeviceObject = deviceObject; dprintf("DriverEntry Success\r\n"); return STATUS_SUCCESS; }