예제 #1
0
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;
}
예제 #2
0
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
예제 #4
0
// 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;
}
예제 #6
0
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;
}
예제 #8
0
// 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;

}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}