Beispiel #1
0
NTSTATUS STDCALL AoeBusAttachFdo(
    IN PDRIVER_OBJECT driver_obj,
    IN PDEVICE_OBJECT pdo
) {
    NTSTATUS status;

    DBG("Entry\n");
    /* Do we already have our main bus? */
    if (AoeBusMain.Pdo) {
        DBG("Already have the main bus.  Refusing.\n");
        status = STATUS_NOT_SUPPORTED;
        goto err_already_established;
    }
    /* Set associations for the bus, FDO, PDO. */
    AoeBusMain.Pdo = pdo;
    /* Attach the FDO to the PDO. */
    AoeBusMain.LowerDeviceObject = IoAttachDeviceToDeviceStack(
                                       AoeBusMain.Fdo,
                                       pdo
                                   );
    if (AoeBusMain.LowerDeviceObject == NULL) {
        status = STATUS_NO_SUCH_DEVICE;
        DBG("IoAttachDeviceToDeviceStack() failed!\n");
        goto err_attach;
    }

    /* Ok! */
    DBG("Exit\n");
    return STATUS_SUCCESS;

err_attach:

err_already_established:

    DBG("Exit with failure\n");
    return status;
}
Beispiel #2
0
// add device
NTSTATUS AddDevice(PDRIVER_OBJECT pDriver,PDEVICE_OBJECT pPhysicalDeviceObject)
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevice = NULL;
	PFdoExt pFdoExt = NULL;
	__try
	{
		UNICODE_STRING busFdoName;
		RtlInitUnicodeString(&busFdoName,BUS_FDO_NAME);
		status = IoCreateDevice(pDriver,sizeof(FdoExt),&busFdoName,FILE_DEVICE_BUS_EXTENDER,FILE_DEVICE_SECURE_OPEN,
								FALSE,&pDevice);

		if(!NT_SUCCESS(status))
			ExRaiseStatus(status);

		pFdoExt = static_cast<PFdoExt>(pDevice->DeviceExtension);
		RtlZeroMemory(pFdoExt,sizeof(FdoExt));

		status = IoRegisterDeviceInterface(pPhysicalDeviceObject,&GUID_TIAMO_BUS,NULL,&pFdoExt->m_symbolicName);
		if(!NT_SUCCESS(status))
			ExRaiseStatus(status);

		KeInitializeEvent(&pFdoExt->m_evRemove,SynchronizationEvent,FALSE);

		KeInitializeEvent(&pFdoExt->m_evStop,SynchronizationEvent,TRUE);

		ExInitializeFastMutex (&pFdoExt->m_mutexEnumPdo);

		pFdoExt->m_sysPowerState = PowerSystemWorking;
		pFdoExt->m_devPowerState = PowerDeviceD3;

		pFdoExt->m_bFdo = TRUE;
		pFdoExt->m_pPhysicalDevice = pPhysicalDeviceObject;

		pFdoExt->m_pLowerDevice = IoAttachDeviceToDeviceStack(pDevice,pPhysicalDeviceObject);

		pFdoExt->m_ulCurrentPnpState = -1;
		pFdoExt->m_ulPrevPnpState = -1;

		pFdoExt->m_ulOutstandingIO = 1;

		//pDevice->Flags |= DO_POWER_PAGABLE;

		POWER_STATE state;
		state.DeviceState = PowerDeviceD0;
		PoSetPowerState(pDevice,DevicePowerState,state);

		pDevice->Flags &= ~DO_DEVICE_INITIALIZING;

		devDebugPrint(DRIVER_NAME"*******AddDevice called,fdo createed.\n");
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		if(pFdoExt && pFdoExt->m_pLowerDevice)
		{
			IoDetachDevice(pFdoExt->m_pLowerDevice);
			RtlFreeUnicodeString(&pFdoExt->m_symbolicName);
		}

		if(pDevice)
		{
			IoDeleteDevice(pDevice);
		}
	}

	return status;
}
Beispiel #3
0
NTSTATUS
UDPFilter_Attach(
	IN PDRIVER_OBJECT	DriverObject,
	IN PUNICODE_STRING	RegistryPath
)
{
	NTSTATUS				status	= 0;
	UNICODE_STRING			uniNtNameString;
	PTDIH_DeviceExtension	pTDIH_DeviceExtension;
	PDEVICE_OBJECT			pFilterDeviceObject = NULL;
	PDEVICE_OBJECT			pTargetDeviceObject = NULL;
	PFILE_OBJECT			pTargetFileObject	= NULL;
	PDEVICE_OBJECT			pLowerDeviceObject	= NULL;

	DBGPRINT("UDPFilter_Attach.\n");

	RtlInitUnicodeString( &uniNtNameString, DD_UDP_DEVICE_NAME );

	status = IoGetDeviceObjectPointer(
               IN	&uniNtNameString,
               IN	FILE_READ_ATTRIBUTES,
               OUT	&pTargetFileObject,   
               OUT	&pTargetDeviceObject
               );
	if( !NT_SUCCESS(status) )
	{
		DBGPRINT(("UDPFilter_Attach: Couldn't get the UDP Device Object\n"));
		pTargetFileObject	= NULL;
		pTargetDeviceObject = NULL;
		return( status );
	}

	RtlInitUnicodeString( &uniNtNameString, TDIH_UDP_DEVICE_NAME );

	status = IoCreateDevice(
               IN	DriverObject,
               IN	sizeof( TDIH_DeviceExtension ),
               IN	&uniNtNameString,
               IN	pTargetDeviceObject->DeviceType,
               IN	pTargetDeviceObject->Characteristics,
               IN	FALSE,                 
               OUT	&pFilterDeviceObject
               );
	if( !NT_SUCCESS(status) )
	{
		DBGPRINT(("UDPFilter_Attach: Couldn't create the UDP Filter Device Object\n"));
		ObDereferenceObject( pTargetFileObject );
		pTargetFileObject = NULL;
		pTargetDeviceObject = NULL;
		return( status );
	}

	pLowerDeviceObject 
		= IoAttachDeviceToDeviceStack(pFilterDeviceObject,pTargetDeviceObject);
	if( !pLowerDeviceObject )
	{
		DBGPRINT(("UDPFilter_Attach: Couldn't attach to UDP Device Object\n"));
		IoDeleteDevice( pFilterDeviceObject );
		pFilterDeviceObject = NULL;
		ObDereferenceObject( pTargetFileObject );
		pTargetFileObject	= NULL;
		pTargetDeviceObject = NULL;
		return( status );
	}

	pTDIH_DeviceExtension 
		= (PTDIH_DeviceExtension )( pFilterDeviceObject->DeviceExtension );
	UDPFilter_InitDeviceExtension(
		IN	pTDIH_DeviceExtension,
		IN	pFilterDeviceObject,
		IN	pTargetDeviceObject,
		IN	pTargetFileObject,
		IN	pLowerDeviceObject
		);

	pFilterDeviceObject->Flags |= pTargetDeviceObject->Flags 
		& (DO_BUFFERED_IO | DO_DIRECT_IO);
	return status;
}
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{
    PAGED_CODE();

    UNICODE_STRING interfaceName;

    KdPrint((DRIVERNAME " - Entering AddDevice: DriverObject %8.8lX, pdo %8.8lX\n", DriverObject, pdo));

    NTSTATUS status;

    // Create a function device object to represent the hardware we're managing.

    PDEVICE_OBJECT fdo;
    
    ULONG dxsize = (sizeof(DEVICE_EXTENSION) + 7) & ~7;
    ULONG xsize = dxsize + GetSizeofGenericExtension();
    
    status = IoCreateDevice(DriverObject, 
                            xsize, 
                            NULL,
                            FILE_DEVICE_UNKNOWN, 
                            FILE_DEVICE_SECURE_OPEN, 
                            FALSE, 
                            &fdo);
    
    if(!NT_SUCCESS(status)){
        KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
        return status;
    }
    
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;

    pdx->operationsInterfaceName.Buffer = NULL;
    pdx->inquiriesInterfaceName .Buffer = NULL;

    RtlInitUnicodeString( &interfaceName, OperationInterface );
    
    status = IoRegisterDeviceInterface(pdo,
                                       &MfUsbGuidOperations,
                                       &interfaceName,
                                       &pdx->operationsInterfaceName);

    if(!NT_SUCCESS(status)){
        KdPrint((DRIVERNAME " - IoRegisterDeviceInterface failed for operations interface - %X\n", status));
        return status;
    }

    RtlInitUnicodeString( &interfaceName, InquiryInterface );
    
    status = IoRegisterDeviceInterface(pdo,
                                       &MfUsbGuidInquiries,
                                       &interfaceName,
                                       &pdx->inquiriesInterfaceName);

    if(!NT_SUCCESS(status)){
        KdPrint((DRIVERNAME " - IoRegisterDeviceInterface failed for inquiry interface - %X\n", status));
        return status;
    }

    // From this point forward, any error will have side effects that need to
    // be cleaned up. Using a do-once allows us to modify the program
    // easily without losing track of the side effects.

    do {
        pdx->DeviceObject = fdo;
        pdx->Pdo = pdo;

        pdx->handles              = 0;
        pdx->devHash              = NULL;        
        pdx->RecoveryThread       = NULL;
        pdx->PollingIrp           = NULL;
        pdx->LowerDeviceObject    = NULL;

        pdx->manufacturer.Buffer  = NULL;      
        pdx->product     .Buffer  = NULL;      
        pdx->serialNumber.Buffer  = NULL;      
        pdx->displayName .Buffer  = NULL;                     
        
        // Declare the buffering method we'll use for read/write requests
        fdo->Flags |= DO_BUFFERED_IO;

        // Initialize irp related locks
        KeInitializeSpinLock(&pdx->ReadIrpLock);
        KeInitializeSpinLock(&pdx->PollLock);

        // Initialize queued read list
        InitializeListHead(&pdx->ReadIrpList);
        
        // Initialize fifo
        KeInitializeSpinLock(&pdx->FifoLock);
        pdx->FifoReadPointer = pdx->FifoWritePointer = 0;

        // Link our device object into the stack leading to the PDO
        pdx->LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
        if(!pdx->LowerDeviceObject) {
            KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
            status = STATUS_DEVICE_REMOVED;
            break;
        }

        // allocate IRP for polling
        pdx->PollingIrp = IoAllocateIrp(pdx->LowerDeviceObject->StackSize, FALSE);

        if(!pdx->PollingIrp) {
            KdPrint((DRIVERNAME " - IoAllocateIrp failed\n"));
            status = STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        // Set power management flags in the device object
        fdo->Flags |= DO_POWER_PAGABLE;

        // Initialize to use the GENERIC.SYS library
        pdx->pgx = (PGENERIC_EXTENSION) ((PUCHAR) pdx + dxsize);

        GENERIC_INIT_STRUCT gis = {sizeof(GENERIC_INIT_STRUCT)};
        gis.DeviceObject = fdo;
        gis.Pdo = pdo;
        gis.Ldo = pdx->LowerDeviceObject;
        gis.RemoveLock = &pdx->RemoveLock;
        gis.StartDevice = StartDevice;
        gis.StopDevice = StopDevice;
        gis.RemoveDevice = RemoveDevice;
        gis.StartIo = StartIo;
        gis.DeviceQueue = &pdx->dqWrite;
        RtlInitUnicodeString(&gis.DebugName, LDRIVERNAME);
        gis.Flags = GENERIC_SURPRISE_REMOVAL_OK;

        status = InitializeGenericExtension(pdx->pgx, &gis);
        if(!NT_SUCCESS(status)) {
            KdPrint((DRIVERNAME " - InitializeGenericExtension failed - %X\n", status));
            break;
        }

        // Clear the "initializing" flag so that we can get IRPs
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;

        // Set up recovery thread
        pdx->RecoveryExit = FALSE;
        KeInitializeEvent(&pdx->RecoveryEvent, SynchronizationEvent, FALSE);

    } while (FALSE);

    if(!NT_SUCCESS(status)) 
    {

        if(pdx->PollingIrp)
        {
            IoFreeIrp(pdx->PollingIrp);

            pdx->PollingIrp = NULL;
        }

        if(pdx->operationsInterfaceName.Buffer)
        {
            RtlFreeUnicodeString(&pdx->operationsInterfaceName);
    
            pdx->operationsInterfaceName.Buffer = NULL;
        }

        if(pdx->inquiriesInterfaceName.Buffer)
        {
            RtlFreeUnicodeString(&pdx->inquiriesInterfaceName);
    
            pdx->inquiriesInterfaceName.Buffer = NULL;
        }

        if(pdx->LowerDeviceObject)
        {
            IoDetachDevice(pdx->LowerDeviceObject);

            pdx->LowerDeviceObject = NULL;
        }
        
        IoDeleteDevice(fdo);
    }

    return status;
}
Beispiel #5
0
NTSTATUS
Bus_AddDevice(
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++
Routine Description.

    Our Toaster bus has been found.  Attach our FDO to it.
    Allocate any required resources.  Set things up.
    And be prepared for the ``start device''

Arguments:

    DriverObject - pointer to driver object.

    PhysicalDeviceObject  - Device object representing the bus to which we
                            will attach a new FDO.

--*/
{
    NTSTATUS            status;
    PDEVICE_OBJECT      deviceObject = NULL;
    PFDO_DEVICE_DATA    deviceData = NULL;
    PWCHAR              deviceName = NULL;
    ULONG               nameLength;
    PKTIMER		timer;
    PKDPC		dpc;

    PAGED_CODE ();

    Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Add Device: 0x%p\n",
                                          PhysicalDeviceObject));

    status = IoCreateDevice (
                    DriverObject,               // our driver object
                    sizeof (FDO_DEVICE_DATA),   // device object extension size
                    NULL,                       // FDOs do not have names
                    FILE_DEVICE_BUS_EXTENDER,   // We are a bus
                    FILE_DEVICE_SECURE_OPEN,    //
                    TRUE,                       // our FDO is exclusive
                    &deviceObject);             // The device object created

    if (!NT_SUCCESS (status))
    {
        goto End;
    }

    deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
    RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));

    //
    // Set the initial state of the FDO
    //

    INITIALIZE_PNP_STATE(deviceData);

    deviceData->DebugLevel = BusEnumDebugLevel;

    deviceData->IsFDO = TRUE;

    deviceData->Self = deviceObject;

    ExInitializeFastMutex (&deviceData->Mutex);

    InitializeListHead (&deviceData->ListOfPDOs);

    // Set the PDO for use with PlugPlay functions

    deviceData->UnderlyingPDO = PhysicalDeviceObject;

    //
    // Set the initial powerstate of the FDO
    //

    deviceData->DevicePowerState = PowerDeviceUnspecified;
    deviceData->SystemPowerState = PowerSystemWorking;


    //
    // Biased to 1. Transition to zero during remove device
    // means IO is finished. Transition to 1 means the device
    // can be stopped.
    //

    deviceData->OutstandingIO = 1;

    //
    // Initialize the remove event to Not-Signaled.  This event
    // will be set when the OutstandingIO will become 0.
    //

    KeInitializeEvent(&deviceData->RemoveEvent,
                  SynchronizationEvent,
                  FALSE);
    //
    // Initialize the stop event to Signaled:
    // there are no Irps that prevent the device from being
    // stopped. This event will be set when the OutstandingIO
    // will become 0.
    //

    KeInitializeEvent(&deviceData->StopEvent,
                      SynchronizationEvent,
                      TRUE);

    deviceObject->Flags |= DO_POWER_PAGABLE|DO_BUFFERED_IO;

    //
    // Tell the Plug & Play system that this device will need a
    // device interface.
    //

    status = IoRegisterDeviceInterface (
                PhysicalDeviceObject,
                (LPGUID) &GUID_DEVINTERFACE_BUSENUM_TOASTER,
                NULL,
                &deviceData->InterfaceName);

    if (!NT_SUCCESS (status)) {
        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
                      ("AddDevice: IoRegisterDeviceInterface failed (%x)", status));
        goto End;
    }

    //
    // Attach our FDO to the device stack.
    // The return value of IoAttachDeviceToDeviceStack is the top of the
    // attachment chain.  This is where all the IRPs should be routed.
    //

    deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                    deviceObject,
                                    PhysicalDeviceObject);

    if (NULL == deviceData->NextLowerDriver) {

        status = STATUS_NO_SUCH_DEVICE;
        goto End;
    }


#if DBG
    //
    // We will demonstrate here the step to retrieve the name of the PDO
    //

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                                  DevicePropertyPhysicalDeviceObjectName,
                                  0,
                                  NULL,
                                  &nameLength);

    if (status != STATUS_BUFFER_TOO_SMALL)
    {
        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
                      ("AddDevice:IoGDP failed (0x%x)\n", status));
        goto End;
    }

    deviceName = ExAllocatePoolWithTag (NonPagedPool,
                            nameLength, BUSENUM_POOL_TAG);

    if (NULL == deviceName) {
        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
        ("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength));
        status =  STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                         DevicePropertyPhysicalDeviceObjectName,
                         nameLength,
                         deviceName,
                         &nameLength);

    if (!NT_SUCCESS (status)) {

        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
                      ("AddDevice:IoGDP(2) failed (0x%x)", status));
        goto End;
    }

    Bus_KdPrint (deviceData, BUS_DBG_SS_TRACE,
                  ("AddDevice: %p to %p->%p (%ws) \n",
                   deviceObject,
                   deviceData->NextLowerDriver,
                   PhysicalDeviceObject,
                   deviceName));

#endif

    //
    // We are done with initializing, so let's indicate that and return.
    // This should be the final step in the AddDevice process.
    //
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

End:
    if (deviceName){
        ExFreePool(deviceName);
    }

    if (!NT_SUCCESS(status) && deviceObject){
        if (deviceData && deviceData->NextLowerDriver){
            IoDetachDevice (deviceData->NextLowerDriver);
        }
        IoDeleteDevice (deviceObject);
    }

    return status;

}
Beispiel #6
0
extern "C" NTSTATUS DriverEntry (
			IN PDRIVER_OBJECT pDriverObject,
			IN PUNICODE_STRING pRegistryPath	) 
{
	NTSTATUS ntStatus;
	KdPrint(("DriverB:Enter B DriverEntry\n"));

	//注册其他驱动调用函数入口
	pDriverObject->DriverUnload = HelloDDKUnload;
	pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKCreate;
	pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKClose;
	pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
	pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;
	
	UNICODE_STRING DeviceName;
	RtlInitUnicodeString( &DeviceName, L"\\Device\\MyDDKDeviceA" );

	PDEVICE_OBJECT DeviceObject = NULL;
	PFILE_OBJECT FileObject = NULL;
	//寻找DriverA创建的设备对象
	ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject);

	if (!NT_SUCCESS(ntStatus))
	{
		KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
		return ntStatus;
	}

	//创建自己的驱动设备对象
	ntStatus = CreateDevice(pDriverObject);

	if ( !NT_SUCCESS( ntStatus ) )
	{
		ObDereferenceObject( FileObject );
		DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
		return ntStatus;
	}

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension;

	PDEVICE_OBJECT FilterDeviceObject = pdx->pDevice;

	//将自己的设备对象挂载在DriverA的设备对象上
	PDEVICE_OBJECT TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,
										  DeviceObject );
	//将底层设备对象记录下来
	pdx->TargetDevice = TargetDevice;
	
	if ( !TargetDevice )
	{
		ObDereferenceObject( FileObject );
		IoDeleteDevice( FilterDeviceObject );
		DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
	FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
	FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
														 DO_BUFFERED_IO ) );
	ObDereferenceObject( FileObject );

	KdPrint(("DriverB:B attached A successfully!\n"));
	
	KdPrint(("DriverB:Leave B DriverEntry\n"));
	return ntStatus;
}
//========================================================================================
// Function:	WDMAddDevice
// Purpose:
// Return Value:
//========================================================================================
NTSTATUS
WDMAddDevice(
	IN PDRIVER_OBJECT dro,
	IN PDEVICE_OBJECT pdo
	)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	PDEVICE_OBJECT fido = NULL;
	PDEVICE_EXTENSION dx;
	UNICODE_STRING devNameU;
	UNICODE_STRING win32NameU;

	PAGED_CODE();

	RtlInitUnicodeString(&devNameU, NT_DEVICE_NAME);

	// Note:
	//	It will crash the system if it has more than one PCI bus,
	//	device name should change to PciBusFilter01, 02, ... 
	ntStatus = IoCreateDevice(dro,
		sizeof(DEVICE_EXTENSION),
		&devNameU,
		FILE_DEVICE_UNKNOWN,
		FILE_DEVICE_SECURE_OPEN,
		FALSE,
		&fido);

	if (!NT_SUCCESS(ntStatus))
	{
		return ntStatus;
	}

	RtlInitUnicodeString(&win32NameU, DOS_DEVICE_NAME);

	ntStatus = IoCreateSymbolicLink(&win32NameU, &devNameU);
	if (!NT_SUCCESS(ntStatus))    // If we we couldn't create the link then abort installation.
	{
		IoDeleteDevice(fido);
		KdPrint(("<-- "__FUNCTION__"() IoCreateSymbolicLink() Status code: 0x%08x\n", ntStatus));
		return ntStatus;
	}

	dx = (PDEVICE_EXTENSION)fido->DeviceExtension;

	IoInitializeRemoveLock(&dx->rmLock, DEV_TAG, 1, 5);
	
	dx->lowerdo = IoAttachDeviceToDeviceStack(fido, pdo);	//attach to PCI bus driver
	if(dx->lowerdo == NULL)
	{
		//Failure for attachment is an indication of a broken plug & play system.
		IoDeleteDevice(fido);
		return STATUS_UNSUCCESSFUL;
	}

	//flags needs inherit from lower device object(pci bus driver)
	fido->Flags|=(dx->lowerdo->Flags & (DO_BUFFERED_IO|DO_DIRECT_IO|DO_POWER_PAGABLE));

	//update device type
	fido->DeviceType = dx->lowerdo->DeviceType;

	//update device characteristics
	fido->Characteristics = dx->lowerdo->Characteristics;

	//save physical device object
	dx->pdo = pdo;

	//set the initial state of the Filter DO
	INITIALIZE_PNP_STATE(dx);

	KdPrint(("PCI pdo=0x%x, fdo=0x%x, fido=0x%x", pdo, dx->lowerdo, fido));

	fido->Flags &= ~DO_DEVICE_INITIALIZING;
	return STATUS_SUCCESS;
}
Beispiel #8
0
NTSTATUS DDKAPI add_device(DRIVER_OBJECT *driver_object, 
                           DEVICE_OBJECT *physical_device_object)
{
  NTSTATUS status;
  DEVICE_OBJECT *device_object = NULL;
  libusb_device_t *dev;
  ULONG device_type;

  UNICODE_STRING nt_device_name;
  UNICODE_STRING symbolic_link_name;
  WCHAR tmp_name_0[128];
  WCHAR tmp_name_1[128];
  char id[256];
  int i;

  /* get the hardware ID from the registry */
  if(!reg_get_hardware_id(physical_device_object, id, sizeof(id)))
    {
      DEBUG_ERROR("add_device(): unable to read registry");
      return STATUS_SUCCESS;
    }

  /* only attach the (filter) driver to USB devices, skip hubs */
  /* and interfaces of composite devices */
  if(!strstr(id, "usb\\") || strstr(id, "hub"))
    {
      return STATUS_SUCCESS;
    }

  /* retrieve the type of the lower device object */
  device_object = IoGetAttachedDeviceReference(physical_device_object);

  if(device_object)
    {
      device_type = device_object->DeviceType;
      ObDereferenceObject(device_object);
    }
  else
    {
      device_type = FILE_DEVICE_UNKNOWN;
    }

  /* try to create a new device object */
  for(i = 1; i < LIBUSB_MAX_NUMBER_OF_DEVICES; i++)
    {
      /* initialize some unicode strings */
      _snwprintf(tmp_name_0, sizeof(tmp_name_0)/sizeof(WCHAR), L"%s%04d", 
                 LIBUSB_NT_DEVICE_NAME, i);
      _snwprintf(tmp_name_1, sizeof(tmp_name_1)/sizeof(WCHAR), L"%s%04d", 
                 LIBUSB_SYMBOLIC_LINK_NAME, i);

      RtlInitUnicodeString(&nt_device_name, tmp_name_0);  
      RtlInitUnicodeString(&symbolic_link_name, tmp_name_1);

      /* create the object */
      status = IoCreateDevice(driver_object, 
                              sizeof(libusb_device_t), 
                              &nt_device_name, device_type, 0, FALSE, 
                              &device_object);

      if(NT_SUCCESS(status))
        {
          DEBUG_MESSAGE("add_device(): device #%d created", i);
          break;
        }

      device_object = NULL;

      /* continue until an unused device name is found */
    }

  if(!device_object)
    {
      DEBUG_ERROR("add_device(): creating device failed");
      return status;
    }
      
  status = IoCreateSymbolicLink(&symbolic_link_name, &nt_device_name);
  
  if(!NT_SUCCESS(status))
    {
      DEBUG_ERROR("add_device(): creating symbolic link failed");
      IoDeleteDevice(device_object);
      return status;
    }

  /* setup the "device object" */
  dev = device_object->DeviceExtension;

  memset(dev, 0, sizeof(libusb_device_t));


  /* attach the newly created device object to the stack */
  dev->next_stack_device = 
    IoAttachDeviceToDeviceStack(device_object, physical_device_object);

  if(!dev->next_stack_device)
    {
      DEBUG_ERROR("add_device(): attaching to device stack failed");
      IoDeleteSymbolicLink(&symbolic_link_name);
      IoDeleteDevice(device_object);
      return STATUS_NO_SUCH_DEVICE;
    }

  dev->self = device_object;
  dev->physical_device_object = physical_device_object;
  dev->id = i;

  /* set initial power states */
  dev->power_state.DeviceState = PowerDeviceD0;
  dev->power_state.SystemState = PowerSystemWorking;

  /* get device properties from the registry */
  reg_get_properties(dev);

  if(dev->is_filter)
    {
      /* send all USB requests to the PDO in filter driver mode */
      dev->target_device = dev->physical_device_object;

      /* use the same flags as the underlying object */
      device_object->Flags |= dev->next_stack_device->Flags 
        & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
    }
  else
    {
      /* send all USB requests to the lower object in device driver mode */
      dev->target_device = dev->next_stack_device;

      device_object->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    }

  clear_pipe_info(dev);

  remove_lock_initialize(dev);

  device_object->Flags &= ~DO_DEVICE_INITIALIZING;

  return status;
}
Beispiel #9
0
NTSTATUS PPJoyBus_AddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
{
 NTSTATUS			ntStatus;
 PDEVICE_OBJECT		DeviceObject;
 PBUS_DEVICE_DATA	BusDeviceData;

 PAGED_CODE ();

 ntStatus= STATUS_SUCCESS;

 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_FENTRY, ("PPJoyBus_AddDevice(DriverObject=0x%p,FunctionalDeviceObject=0x%p)",DriverObject,PhysicalDeviceObject) );

 /* Create our FDO device */
 ntStatus= IoCreateDevice (DriverObject,sizeof(BUS_DEVICE_DATA),NULL,FILE_DEVICE_BUS_EXTENDER,FILE_DEVICE_SECURE_OPEN,TRUE,&DeviceObject);
 /* Check to see if we could create the device. If not, exit. */
 if (!NT_SUCCESS (ntStatus)) 
 {
  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORCREATINGBUS,&ntStatus,sizeof(ntStatus),L"");
  PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_ERROR, ("PPJoyBus_AddDevice: IoCreateDevice failed status= 0x%x)",ntStatus) );
  goto ExitNoDelete;
 }

 /* Setup our DeviceExtension */
 BusDeviceData= (PBUS_DEVICE_DATA) DeviceObject->DeviceExtension;
 RtlZeroMemory (BusDeviceData,sizeof(BUS_DEVICE_DATA));
 BusDeviceData->Flags|= PPJFLAGS_ISBUSDEV;

 /* Tell IOManager et al that we are pagable. */
 DeviceObject->Flags|= DO_POWER_PAGABLE;

 /* Attempt to register an interface for this DeviceObject. It will be */
 /* called by the configuration utility to add and remove joysticks.   */
 ntStatus= IoRegisterDeviceInterface (PhysicalDeviceObject,(LPGUID) &GUID_PPJOY_BUS,NULL,&BusDeviceData->InterfaceName);
 /* If we could not register the interface then we exit and delete the DO */
 if (!NT_SUCCESS (ntStatus))
 {
  PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_ERROR, ("PPJoyBus_AddDevice: IoRegisterDeviceInterface failed status= 0x%x)",ntStatus) );
  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORBUSIF,&ntStatus,sizeof(ntStatus),L"");
  goto ExitDeleteDevice;
 }

 PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_BABBLE2, ("PPJoyBus_AddDevice: IoRegisterDeviceInterface interface name= %S)",BusDeviceData->InterfaceName.Buffer) );
 
 /* Now attach ourselves to the device stack. The return value is the next */
 /* lower down Device Object. This is where all the IRPs should be routed. */
 BusDeviceData->NextLowerDriver= IoAttachDeviceToDeviceStack (DeviceObject,PhysicalDeviceObject);
 /* Test if our attach was successful, exit if not. */
 if(!BusDeviceData->NextLowerDriver)
 {
  PPJOY_DBGPRINT (FILE_PPJOYBUS|PPJOY_ERROR, ("PPJoyBus_AddDevice: IoAttachDeviceToDeviceStack failed status= 0x%x)",ntStatus) );
  ntStatus= STATUS_NO_SUCH_DEVICE;

  PPJoyBus_WriteEventLog (PPJ_MSG_ERRORBUSATTACH,&ntStatus,sizeof(ntStatus),L"");
  RtlFreeUnicodeString (&BusDeviceData->InterfaceName);
  goto ExitDeleteDevice;
 }

 /* Save important pointers in our DeviceExtenstion for later use. */
 BusDeviceData->DriverObject= DriverObject;
 BusDeviceData->Self= DeviceObject;
 BusDeviceData->UnderlyingPDO= PhysicalDeviceObject;

 /* Initialise per DeviceObject objects */
 InitializeListHead (&BusDeviceData->JoystickList);
 KeInitializeEvent (&BusDeviceData->RemoveEvent,SynchronizationEvent,FALSE);

 /* Read configuration options from the registry */
 PPJoyBus_ReadOptionsFromReg (DeviceObject);

 /* Read persistent joystick device data from the registry and create PDOs */
 /* This call can possibly move to the DriverEntry routine???              */
 PPJoyBus_CreateFromRegistry (DeviceObject);

 /* Done initializing, clear flag. Should be the final step in AddDevice.  */
 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 goto ExitNoDelete;

ExitDeleteDevice:
 IoDeleteDevice (DeviceObject);

ExitNoDelete:
 PPJOY_EXITPROC (FILE_PPJOYBUS|PPJOY_FEXIT_STATUSOK, "PPJoyBus_AddDevice",ntStatus);

 return ntStatus;
}
Beispiel #10
0
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) 
{
	for(int i_Dispatch = 0; i_Dispatch < IRP_MJ_MAXIMUM_FUNCTION; i_Dispatch++)
	{
		pDriverObject->MajorFunction[i_Dispatch] = DriverCommonDispatch;
	}
	pDriverObject->MajorFunction[IRP_MJ_POWER]			= DriverPower;
	pDriverObject->MajorFunction[IRP_MJ_PNP]			= DriverPNP;
	pDriverObject->MajorFunction[IRP_MJ_READ]			= DriverRead;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]	= DriverControl;

	pDriverObject->DriverUnload = DriverUnload;

	//打开kbdclass驱动对象
	PDRIVER_OBJECT tDriObjKdbclass;
	UNICODE_STRING tKbdclassName;
	RtlInitUnicodeString(&tKbdclassName,L"\\Driver\\Kbdclass");
	NTSTATUS tStatus = ObReferenceObjectByName(&tKbdclassName,OBJ_CASE_INSENSITIVE,0,FILE_ALL_ACCESS,IoDeviceObjectType,KernelMode,0,(PVOID*)&tDriObjKdbclass);
	if(false == NT_SUCCESS(tStatus))
	{
		return STATUS_UNSUCCESSFUL;
	}
	else
	{
		ObDereferenceObject(tDriObjKdbclass);
	}

	//创建并绑定设备
	bool tAttch = false;
	PDEVICE_OBJECT tTargetDevObj = tDriObjKdbclass->DeviceObject; //kbdclass下的设备对象
	while(0 != tTargetDevObj)
	{
		tAttch = true;
		PDEVICE_OBJECT tMyDeviceObject;
		tStatus = IoCreateDevice(pDriverObject,sizeof(MYDEVICE_EXTENSION),0,tTargetDevObj->DeviceType,tTargetDevObj->Characteristics,FALSE,&tMyDeviceObject);
		if(false == NT_SUCCESS(tStatus))
		{
			return STATUS_UNSUCCESSFUL; //之前的设备要不要删掉?
		}
		tMyDeviceObject->Flags |= tTargetDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);

		PMYDEVICE_EXTENSION tDevExtend = (PMYDEVICE_EXTENSION)tMyDeviceObject->DeviceExtension;
		tDevExtend->LowDeviceObj = IoAttachDeviceToDeviceStack(tMyDeviceObject,tTargetDevObj);
		if(0 == tDevExtend->LowDeviceObj)
		{
			IoDeleteDevice(tMyDeviceObject);
			return STATUS_UNSUCCESSFUL;
		}
		tMyDeviceObject->Flags = tMyDeviceObject->Flags & ~DO_DEVICE_INITIALIZING;

		tTargetDevObj = tTargetDevObj->NextDevice;
	}
	
	if(false == tAttch)
	{
		return STATUS_UNSUCCESSFUL;
	}

	//创建主控设备
	UNICODE_STRING tMasterDevObjName;
	RtlInitUnicodeString(&tMasterDevObjName,__T(DEVICE_NAME_KBDFILTER));
	tStatus = IoCreateDevice(pDriverObject,sizeof(MYDEVICE_EXTENSION),&tMasterDevObjName,FILE_DEVICE_UNKNOWN,0,FALSE,&g_MasterDeviceObj);
	if(false == NT_SUCCESS(tStatus))
	{
		return STATUS_UNSUCCESSFUL;
	}

	UNICODE_STRING tMasterDevObjSymbol;
	RtlInitUnicodeString(&tMasterDevObjSymbol,__T(DEVICE_NAME_KBDFILTER_SYMBOL));
	tStatus = IoCreateSymbolicLink(&tMasterDevObjSymbol,&tMasterDevObjName);
	if(false == NT_SUCCESS(tStatus))
	{
		return STATUS_UNSUCCESSFUL;
	}
	g_MasterDeviceObj->Flags |= (DO_BUFFERED_IO | DO_DIRECT_IO);
	return STATUS_SUCCESS;
}
Beispiel #11
0
NTSTATUS 
HotKeyKrnlAttachDevices( 
    IN PDRIVER_OBJECT   DriverObject, 
    IN PUNICODE_STRING  RegistryPath 
    ) 
{ 
    NTSTATUS status = 0; 
    UNICODE_STRING uniNtNameString; 
    PDEVICE_EXTENSION   devExt; 
    PDEVICE_OBJECT pFilterDeviceObject = NULL; 
    PDEVICE_OBJECT pTargetDeviceObject = NULL; 
    PDEVICE_OBJECT pLowerDeviceObject  = NULL; 
    PDRIVER_OBJECT KbdDriverObject     = NULL;
    extern POBJECT_TYPE *IoDriverObjectType;    // Exported by ntoskrnl.exe, shit !

    // ref kbdclass driver object
    RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME); 
    status = ObReferenceObjectByName(&uniNtNameString, OBJ_CASE_INSENSITIVE, NULL, 0, *IoDriverObjectType, KernelMode, NULL, &KbdDriverObject);
    if(!NT_SUCCESS(status))
    {
        KdPrint(("[shadow] ObReferenceObjectByName failed,cann't access Kbdclass.\n"));
        return status; 
    }
    else
    {
        ObDereferenceObject(KbdDriverObject);
    }

    // 绑定该驱动对象中的所有设备对象
    pTargetDeviceObject = KbdDriverObject->DeviceObject;
    while (pTargetDeviceObject) 
    {
        // 创建过滤设备
        status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, pTargetDeviceObject->DeviceType, pTargetDeviceObject->Characteristics, FALSE, &pFilterDeviceObject);
        if (!NT_SUCCESS(status)) 
        { 
            KdPrint(("[shadow] IoCreateDevice(filter device) failed.\n")); 
            return status; 
        } 
        // 绑定
        if(!(pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject)))
        { 
            KdPrint(("[shadow] IoAttachDeviceToDeviceStack failed.\n")); 
            IoDeleteDevice(pFilterDeviceObject);
            pFilterDeviceObject = NULL; 
            return status; 
        }

        devExt = (PDEVICE_EXTENSION)(pFilterDeviceObject->DeviceExtension); 
        RtlZeroMemory(devExt, sizeof(DEVICE_EXTENSION)); 
        devExt->NodeSize = sizeof(DEVICE_EXTENSION); 
        devExt->pFilterDeviceObject = pFilterDeviceObject;
        devExt->TargetDeviceObject = pTargetDeviceObject; 
        devExt->LowerDeviceObject = pLowerDeviceObject; 

        pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType; 
        pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics; 
        pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize+1; 
        pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE); 

        pTargetDeviceObject = pTargetDeviceObject->NextDevice;
    }
    return status; 
} 
Beispiel #12
0
NTSTATUS
NTAPI
USBSTOR_AddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject)
{
    NTSTATUS Status;
    PDEVICE_OBJECT DeviceObject;
    PFDO_DEVICE_EXTENSION DeviceExtension;

    //
    // lets create the device
    //
    Status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_EXTENSION), 0, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);

    //
    // check for success
    //
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("USBSTOR_AddDevice: Failed to create FDO Status %x\n", Status);
        return Status;
    }

    //
    // get device extension
    //
    DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    ASSERT(DeviceExtension);

    //
    // zero device extension
    //
    RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));

    //
    // initialize device extension
    //
    DeviceExtension->Common.IsFDO = TRUE;
    DeviceExtension->FunctionalDeviceObject = DeviceObject;
    DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
    DeviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);

    //
    // init timer
    //
    IoInitializeTimer(DeviceObject, USBSTOR_TimerRoutine, (PVOID)DeviceExtension);

    //
    // did attaching fail
    //
    if (!DeviceExtension->LowerDeviceObject)
    {
        //
        // device removed
        //
        IoDeleteDevice(DeviceObject);

        return STATUS_DEVICE_REMOVED;
    }

    //
    // set device flags
    //
    DeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;

    //
    // device is initialized
    //
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;


    //
    // done
    //
    return STATUS_SUCCESS;
}
Beispiel #13
0
NTSTATUS Bus_AddDevice(__in PDRIVER_OBJECT DriverObject, __in PDEVICE_OBJECT PhysicalDeviceObject)
{
    NTSTATUS            status;
    PDEVICE_OBJECT      deviceObject = NULL;
    PFDO_DEVICE_DATA    deviceData = NULL;
    PWCHAR              deviceName = NULL;
    ULONG               nameLength;

    UNREFERENCED_PARAMETER(nameLength);
    PAGED_CODE();

    Bus_KdPrint(("Add Device: 0x%p\n", PhysicalDeviceObject));

    status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_DATA), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &deviceObject);

    if (!NT_SUCCESS (status))
    {
        goto End;
    }

    deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
    RtlZeroMemory(deviceData, sizeof (FDO_DEVICE_DATA));

    INITIALIZE_PNP_STATE(deviceData);

    deviceData->IsFDO = TRUE;
    deviceData->Self  = deviceObject;

    ExInitializeFastMutex(&deviceData->Mutex);
    InitializeListHead(&deviceData->ListOfPDOs);

    deviceData->UnderlyingPDO = PhysicalDeviceObject;

    deviceData->DevicePowerState = PowerDeviceUnspecified;
    deviceData->SystemPowerState = PowerSystemWorking;
    deviceData->OutstandingIO = 1;

    KeInitializeEvent(&deviceData->RemoveEvent, SynchronizationEvent, FALSE);
    KeInitializeEvent(&deviceData->StopEvent,   SynchronizationEvent, TRUE);

    deviceObject->Flags |= DO_POWER_PAGABLE;

    status = IoRegisterDeviceInterface(PhysicalDeviceObject, (LPGUID) &GUID_DEVINTERFACE_SCPVBUS, NULL, &deviceData->InterfaceName);

    if (!NT_SUCCESS(status))
	{
        Bus_KdPrint(("AddDevice: IoRegisterDeviceInterface failed (%x)", status));
        goto End;
    }

    deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject);

    if (deviceData->NextLowerDriver == NULL)
	{
        status = STATUS_NO_SUCH_DEVICE;
        goto End;
    }

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

End:

    if (deviceName)
	{
        ExFreePool(deviceName);
    }

    if (!NT_SUCCESS(status) && deviceObject)
	{
        if (deviceData && deviceData->NextLowerDriver)
		{
            IoDetachDevice(deviceData->NextLowerDriver);
        }

        IoDeleteDevice(deviceObject);
    }

    return status;
}
Beispiel #14
0
NTSTATUS AddDevice(IN PDRIVER_OBJECT  DriverObject,IN PDEVICE_OBJECT  PhysicalDeviceObject)
{
	UNICODE_STRING symLinkName;
	ULONG DeviceExtensionSize;
	PDEVICE_EXTENSION p_DVCEXT;
	PDEVICE_OBJECT ptr_PDO;
	NTSTATUS status;
	//ULONG IdxPwrState;

	DbgPrint("In AddDevice : Begin\r\n");

	RtlInitUnicodeString(&Global_sz_DeviceName,L"\\Device\\MultiWDM");
	RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\MWDM"); 
	//Get DEVICE_EXTENSION required memory space
	DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
	
	status = IoCreateDevice(
		DriverObject,
		DeviceExtensionSize,
		&Global_sz_DeviceName,
		FILE_DEVICE_UNKNOWN, 
		0, 
		FALSE,
		&ptr_PDO
    );

	KdPrint(("AddDevice | IoCreateDevice Status: %d",status));

	if (NT_SUCCESS(status)) {
		//Set Device Object Flags
		//ptr_PDO->Flags &= ~DO_DEVICE_INITIALIZING;
		ptr_PDO->Flags |= DO_BUFFERED_IO;

		//Device Extension memory maps
		p_DVCEXT = ptr_PDO->DeviceExtension;
		p_DVCEXT->DeviceObject = ptr_PDO;
		
		//Initialize driver description string
		/*RtlInitUnicodeString(
			&p_DVCEXT->Device_Description,
			L"This is a Pseudo Device Driver\r\n"
			L"Created by Souri\r\n");*/
		/*IoInitializeRemoveLock(
			&p_DVCEXT->RemoveLock,
			'KCOL',
			0,
			0
		);*/
		status = IoCreateSymbolicLink(&symLinkName,&Global_sz_DeviceName);

		//Initialize driver power state
		//p_DVCEXT->SysPwrState = PowerSystemWorking;
		//p_DVCEXT->DevPwrState = PowerDeviceD0;
		//
		////Initialize device power information
		//Global_PowerInfo_Ptr = ExAllocatePool(
		//	NonPagedPool, sizeof(DEVICE_POWER_INFORMATION));
		//RtlZeroMemory(
		//	Global_PowerInfo_Ptr,
		//	sizeof(DEVICE_POWER_INFORMATION));
		//Global_PowerInfo_Ptr->SupportQueryCapability = FALSE;
		//Global_PowerInfo_Ptr->DeviceD1 = 0;
		//Global_PowerInfo_Ptr->DeviceD2 = 0;
		//Global_PowerInfo_Ptr->WakeFromD0 = 0;
		//Global_PowerInfo_Ptr->WakeFromD1 = 0;
		//Global_PowerInfo_Ptr->WakeFromD2 = 0;
		//Global_PowerInfo_Ptr->WakeFromD3 = 0;
		//Global_PowerInfo_Ptr->DeviceWake = 0;
		//Global_PowerInfo_Ptr->SystemWake = 0;
		//for (IdxPwrState = 0;
		//	IdxPwrState < PowerSystemMaximum;
		//	IdxPwrState++)
		//{
		//	Global_PowerInfo_Ptr->DeviceState[IdxPwrState] = 0;
		//}

		//Store next-layered device object
		//Attach device object to device stack
		p_DVCEXT->NextDeviceObject = NULL;
		p_DVCEXT->NextDeviceObject = IoAttachDeviceToDeviceStack(ptr_PDO, PhysicalDeviceObject);
		if(p_DVCEXT->NextDeviceObject != NULL){
			KdPrint(("p_DVCEXT->NextDeviceObject successfuly attached to stack\n"));
		}
	}

	KdPrint(("In AddDevice : End | Symlink Status: %d\r\n",status));


	return status;
}
Beispiel #15
0
//
//  Typically called by a driver's AddDevice function, which is set when
//  calling PcInitializeAdapterDriver. This performs some common driver
//  operations, such as creating a device extension.
//
//  The StartDevice parameter is a driver-supplied function which gets
//  called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
//
NTSTATUS
NTAPI
PcAddAdapterDevice(
    IN  PDRIVER_OBJECT DriverObject,
    IN  PDEVICE_OBJECT PhysicalDeviceObject,
    IN  PCPFNSTARTDEVICE StartDevice,
    IN  ULONG MaxObjects,
    IN  ULONG DeviceExtensionSize)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT fdo;
    PDEVICE_OBJECT PrevDeviceObject;
    PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;

    DPRINT("PcAddAdapterDevice called\n");
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!DriverObject || !PhysicalDeviceObject || !StartDevice)
    {
        return STATUS_INVALID_PARAMETER;
    }

    // check if the DeviceExtensionSize is provided
    if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
    {
        // driver does not need a device extension 
        if ( DeviceExtensionSize != 0 )
        {
            // DeviceExtensionSize must be zero
            return STATUS_INVALID_PARAMETER;
        }
        // set size to our extension size
        DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE;
    }

    // create the device
    status = IoCreateDevice(DriverObject,
                            DeviceExtensionSize,
                            NULL,
                            FILE_DEVICE_KS,
                            FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
                            FALSE,
                            &fdo);

    if (!NT_SUCCESS(status))
    {
        DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status);
        return status;
    }

    // Obtain the new device extension
    portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension;
    // initialize the device extension
    RtlZeroMemory(portcls_ext, DeviceExtensionSize);
    // allocate create item
    portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);

    if (!portcls_ext->CreateItems)
    {
        // not enough resources
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // store max subdevice count
    portcls_ext->MaxSubDevices = MaxObjects;
    // store the physical device object
    portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
    // set up the start device function
    portcls_ext->StartDevice = StartDevice;
    // initialize timer lock
    KeInitializeSpinLock(&portcls_ext->TimerListLock);
    // initialize timer list
    InitializeListHead(&portcls_ext->TimerList);
    // initialize io timer
    IoInitializeTimer(fdo, PcIoTimerRoutine, NULL);
    // start the io timer
    IoStartTimer(fdo);

    // set io flags
    fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    // clear initializing flag
    fdo->Flags &= ~ DO_DEVICE_INITIALIZING;

    // allocate the device header
    status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
    // did we succeed
    if (!NT_SUCCESS(status))
    {
        goto cleanup;
    }

    // attach device to device stack
    PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
    // did we succeed
    if (PrevDeviceObject)
    {
        // store the device object in the device header
        //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject);
        portcls_ext->PrevDeviceObject = PrevDeviceObject;
    }
    else
    {
        // return error code
        status = STATUS_UNSUCCESSFUL;
        goto cleanup;
    }

    // register shutdown notification
    IoRegisterShutdownNotification(PhysicalDeviceObject);

    return status;

cleanup:

    if (portcls_ext->KsDeviceHeader)
    {
        // free the device header
        KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
    }

    if (portcls_ext->CreateItems)
    {
        // free previously allocated create items
        FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
    }

    // delete created fdo
    IoDeleteDevice(fdo);


    return status;
}
Beispiel #16
0
NTSTATUS
BlkMovAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    NTSTATUS                status;
    IO_STATUS_BLOCK         ioStatus;
    PDEVICE_OBJECT          filterDeviceObject;
    PDEVICE_EXTENSION       deviceExtension;
    STRING                  ntNameString;
    UNICODE_STRING          ntUnicodeString;
    PIRP                    irp;
    STORAGE_DEVICE_NUMBER   number;
    ULONG                   registrationFlag = 0;
    PWMILIB_CONTEXT         wmilibContext;
    PCHAR                   buffer;
    ULONG                   buffersize;

    PAGED_CODE();

	if(PhysicalDeviceObject->DeviceType == FILE_DEVICE_MASS_STORAGE)
	{
		//
		// Create a filter device object for this device (partition).
		//

		DbgPrint("BLKMOVER:\tBlkMovAddDevice\n");

		status = IoCreateDevice(DriverObject,
								DEVICE_EXTENSION_SIZE,
								NULL,
								FILE_DEVICE_DISK,
								0,
								FALSE,
								&filterDeviceObject);

		if (!NT_SUCCESS(status)) {
		   return status;
		}

		filterDeviceObject->Flags |= DO_DIRECT_IO;

		deviceExtension = (PDEVICE_EXTENSION) filterDeviceObject->DeviceExtension;

		RtlZeroMemory(deviceExtension, DEVICE_EXTENSION_SIZE);
		//
		// Attaches the device object to the highest device object in the chain and
		// return the previously highest device object, which is passed to
		// IoCallDriver when pass IRPs down the device stack
		//

		deviceExtension->TargetDeviceObject =
			IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject);

		if (deviceExtension->TargetDeviceObject == NULL)
		{
			IoDeleteDevice(filterDeviceObject);
			return STATUS_NO_SUCH_DEVICE;
		}

		CreateThread(filterDeviceObject);
		//
		// Save the filter device object in the device extension
		//
		deviceExtension->DeviceObject = filterDeviceObject;

		//
		// default to DO_POWER_PAGABLE
		//

		filterDeviceObject->Flags |=  DO_POWER_PAGABLE;

		//
		// Clear the DO_DEVICE_INITIALIZING flag
		//

		filterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	}
    return STATUS_SUCCESS;

} // end BlkMovAddDevice()
Beispiel #17
0
NTSTATUS
PdoCreate(
    PXENFILT_FDO                    Fdo,
    PDEVICE_OBJECT                  PhysicalDeviceObject,
    XENFILT_EMULATED_OBJECT_TYPE    Type
    )
{
    PDEVICE_OBJECT                  LowerDeviceObject;
    ULONG                           DeviceType;
    PDEVICE_OBJECT                  FilterDeviceObject;
    PXENFILT_DX                     Dx;
    PXENFILT_PDO                    Pdo;
    NTSTATUS                        status;

    LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
    DeviceType = LowerDeviceObject->DeviceType;
    ObDereferenceObject(LowerDeviceObject);

#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
    status = IoCreateDevice(DriverGetDriverObject(),
                            sizeof(XENFILT_DX),
                            NULL,
                            DeviceType,
                            FILE_DEVICE_SECURE_OPEN,
                            FALSE,
                            &FilterDeviceObject);
    if (!NT_SUCCESS(status))
        goto fail1;

    Dx = (PXENFILT_DX)FilterDeviceObject->DeviceExtension;
    RtlZeroMemory(Dx, sizeof (XENFILT_DX));

    Dx->Type = PHYSICAL_DEVICE_OBJECT;
    Dx->DeviceObject = FilterDeviceObject;
    Dx->DevicePnpState = Present;
    Dx->SystemPowerState = PowerSystemShutdown;
    Dx->DevicePowerState = PowerDeviceD3;

    IoInitializeRemoveLock(&Dx->RemoveLock, PDO_TAG, 0, 0);

    Pdo = __PdoAllocate(sizeof (XENFILT_PDO));

    status = STATUS_NO_MEMORY;
    if (Pdo == NULL)
        goto fail2;

    LowerDeviceObject = IoAttachDeviceToDeviceStack(FilterDeviceObject,
                                                    PhysicalDeviceObject);

    status = STATUS_UNSUCCESSFUL;
    if (LowerDeviceObject == NULL)
        goto fail3;

    Pdo->Dx = Dx;
    Pdo->PhysicalDeviceObject = PhysicalDeviceObject;
    Pdo->LowerDeviceObject = LowerDeviceObject;

    status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
    if (!NT_SUCCESS(status))
        goto fail4;

    status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
    if (!NT_SUCCESS(status))
        goto fail5;

    Pdo->EmulatedInterface = FdoGetEmulatedInterface(Fdo);

    status = EmulatedAddObject(__PdoGetEmulatedInterface(Pdo),
                               Type,
                               FdoGetPrefix(Fdo),
                               Pdo->LowerDeviceObject,
                               &Pdo->EmulatedObject);
    if (!NT_SUCCESS(status))
        goto fail6;

    __PdoSetName(Pdo);

    Info("%p (%s)\n",
          FilterDeviceObject,
          __PdoGetName(Pdo));

    Dx->Pdo = Pdo;

#pragma prefast(suppress:28182) // Dereferencing NULL pointer
    FilterDeviceObject->DeviceType = LowerDeviceObject->DeviceType;
    FilterDeviceObject->Characteristics = LowerDeviceObject->Characteristics;

    FilterDeviceObject->Flags |= LowerDeviceObject->Flags;
    FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    __PdoLink(Pdo, Fdo);

    return STATUS_SUCCESS;

fail6:
    Error("fail6\n");

    ThreadAlert(Pdo->DevicePowerThread);
    ThreadJoin(Pdo->DevicePowerThread);
    Pdo->DevicePowerThread = NULL;

fail5:
    Error("fail5\n");

    ThreadAlert(Pdo->SystemPowerThread);
    ThreadJoin(Pdo->SystemPowerThread);
    Pdo->SystemPowerThread = NULL;

fail4:
    Error("fail4\n");

    Pdo->PhysicalDeviceObject = NULL;
    Pdo->LowerDeviceObject = NULL;
    Pdo->Dx = NULL;

    IoDetachDevice(LowerDeviceObject);

fail3:
    Error("fail3\n");

    ASSERT(IsZeroMemory(Pdo, sizeof (XENFILT_PDO)));
    __PdoFree(Pdo);

fail2:
    Error("fail2\n");

    IoDeleteDevice(FilterDeviceObject);

fail1:
    Error("fail1 (%08x)\n", status);

    return status;
}
Beispiel #18
0
NTSTATUS
FilterAddDevice(
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++

Routine Description:

    The Plug & Play subsystem is handing us a brand new PDO, for which we
    (by means of INF registration) have been asked to provide a driver.

    We need to determine if we need to be in the driver stack for the device.
    Create a function device object to attach to the stack
    Initialize that device object
    Return status success.

    Remember: We can NOT actually send ANY non pnp IRPS to the given driver
    stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

    DeviceObject - pointer to a device object.

    PhysicalDeviceObject -  pointer to a device object created by the
                            underlying bus driver.

Return Value:

    NT status code.

--*/
{
    NTSTATUS                status = STATUS_SUCCESS;
    PDEVICE_OBJECT          deviceObject = NULL;
    PDEVICE_EXTENSION       deviceExtension;
    ULONG                   deviceType = FILE_DEVICE_UNKNOWN;

    PAGED_CODE ();


    //
    // IoIsWdmVersionAvailable(1, 0x20) returns TRUE on os after Windows 2000.
    //
    if (RtlIsNtDdiVersionAvailable(NTDDI_WINXP)) {
        //
        // Win2K system bugchecks if the filter attached to a storage device
        // doesn't specify the same DeviceType as the device it's attaching
        // to. This bugcheck happens in the filesystem when you disable
        // the devicestack whose top level deviceobject doesn't have a VPB.
        // To workaround we will get the toplevel object's DeviceType and
        // specify that in IoCreateDevice.
        //
        deviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
        deviceType = deviceObject->DeviceType;
        ObDereferenceObject(deviceObject);
    }

    //
    // Create a filter device object.
    //

    status = IoCreateDevice (DriverObject,
                             sizeof (DEVICE_EXTENSION),
                             NULL,  // No Name
                             deviceType,
                             FILE_DEVICE_SECURE_OPEN,
                             FALSE,
                             &deviceObject);


    if (!NT_SUCCESS (status)) {
        //
        // 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.
        //
        return status;
    }

    DebugPrint (("AddDevice PDO (0x%p) FDO (0x%p)\n",
                    PhysicalDeviceObject, deviceObject));

    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;

    deviceExtension->Common.Type = DEVICE_TYPE_FIDO;

    deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                       deviceObject,
                                       PhysicalDeviceObject);
    //
    // Failure for attachment is an indication of a broken plug & play system.
    //

    if (NULL == deviceExtension->NextLowerDriver) {

        IoDeleteDevice(deviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags &
                            (DO_BUFFERED_IO | DO_DIRECT_IO |
                            DO_POWER_PAGABLE );


    deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType;

    deviceObject->Characteristics =
                          deviceExtension->NextLowerDriver->Characteristics;

    deviceExtension->Self = deviceObject;

    //
    // Let us use remove lock to keep count of IRPs so that we don't 
    // deteach and delete our deviceobject until all pending I/Os in our
    // devstack are completed. Remlock is required to protect us from
    // various race conditions where our driver can get unloaded while we
    // are still running dispatch or completion code.
    //
    
    IoInitializeRemoveLock (&deviceExtension->RemoveLock , 
                            POOL_TAG,
                            1, // MaxLockedMinutes 
                            100); // HighWatermark, this parameter is 
                                // used only on checked build. Specifies 
                                // the maximum number of outstanding 
                                // acquisitions allowed on the lock
                                

    //
    // Set the initial state of the Filter DO
    //

    INITIALIZE_PNP_STATE(deviceExtension);

    DebugPrint(("AddDevice: %p to %p->%p \n", deviceObject,
                       deviceExtension->NextLowerDriver,
                       PhysicalDeviceObject));

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;

}
Beispiel #19
0
NTSTATUS
NTAPI
Bus_AddDevice(
    PDRIVER_OBJECT DriverObject,
    PDEVICE_OBJECT PhysicalDeviceObject
    )

{
    NTSTATUS            status;
    PDEVICE_OBJECT      deviceObject = NULL;
    PFDO_DEVICE_DATA    deviceData = NULL;
    PWCHAR              deviceName = NULL;
#ifndef NDEBUG
    ULONG               nameLength;
#endif

    PAGED_CODE ();

    DPRINT("Add Device: 0x%p\n",  PhysicalDeviceObject);

    DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
    status = IoCreateDevice(DriverObject,
                      sizeof(FDO_DEVICE_DATA),
                      NULL,
                      FILE_DEVICE_ACPI,
                      FILE_DEVICE_SECURE_OPEN,
                      TRUE,
                      &deviceObject);
    if (!NT_SUCCESS(status))
    {
        DPRINT1("IoCreateDevice() failed with status 0x%X\n", status);
        goto End;
    }

    deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
    RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));

    //
    // Set the initial state of the FDO
    //

    INITIALIZE_PNP_STATE(deviceData->Common);

    deviceData->Common.IsFDO = TRUE;

    deviceData->Common.Self = deviceObject;

    ExInitializeFastMutex (&deviceData->Mutex);

    InitializeListHead (&deviceData->ListOfPDOs);

    // Set the PDO for use with PlugPlay functions

    deviceData->UnderlyingPDO = PhysicalDeviceObject;

    //
    // Set the initial powerstate of the FDO
    //

    deviceData->Common.DevicePowerState = PowerDeviceUnspecified;
    deviceData->Common.SystemPowerState = PowerSystemWorking;

    deviceObject->Flags |= DO_POWER_PAGABLE;

    //
    // Attach our FDO to the device stack.
    // The return value of IoAttachDeviceToDeviceStack is the top of the
    // attachment chain.  This is where all the IRPs should be routed.
    //

    deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                    deviceObject,
                                    PhysicalDeviceObject);

    if (NULL == deviceData->NextLowerDriver) {

        status = STATUS_NO_SUCH_DEVICE;
        goto End;
    }


#ifndef NDEBUG
    //
    // We will demonstrate here the step to retrieve the name of the PDO
    //

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                                  DevicePropertyPhysicalDeviceObjectName,
                                  0,
                                  NULL,
                                  &nameLength);

    if (status != STATUS_BUFFER_TOO_SMALL)
    {
        DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status);
        goto End;
    }

    deviceName = ExAllocatePoolWithTag (NonPagedPool,
                            nameLength, 'IPCA');

    if (NULL == deviceName) {
        DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
        status =  STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                         DevicePropertyPhysicalDeviceObjectName,
                         nameLength,
                         deviceName,
                         &nameLength);

    if (!NT_SUCCESS (status)) {

        DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status);
        goto End;
    }

    DPRINT("AddDevice: %p to %p->%p (%ws) \n",
                   deviceObject,
                   deviceData->NextLowerDriver,
                   PhysicalDeviceObject,
                   deviceName);

#endif

    //
    // We are done with initializing, so let's indicate that and return.
    // This should be the final step in the AddDevice process.
    //
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

End:
    if (deviceName){
        ExFreePool(deviceName);
    }
    if (!NT_SUCCESS(status) && deviceObject){
        if (deviceData && deviceData->NextLowerDriver){
            IoDetachDevice (deviceData->NextLowerDriver);
        }
        IoDeleteDevice (deviceObject);
    }
    return status;

}
Beispiel #20
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;
}
Beispiel #21
0
NTSTATUS
NTAPI
PciAddDevice(IN PDRIVER_OBJECT DriverObject,
             IN PDEVICE_OBJECT PhysicalDeviceObject)
{
    PCM_RESOURCE_LIST Descriptor;
    PDEVICE_OBJECT AttachedTo;
    PPCI_FDO_EXTENSION FdoExtension;
    PPCI_FDO_EXTENSION ParentExtension;
    PPCI_PDO_EXTENSION PdoExtension;
    PDEVICE_OBJECT DeviceObject;
    UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
    PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
    NTSTATUS Status;
    HANDLE KeyHandle;
    UNICODE_STRING ValueName;
    ULONG ResultLength;
    PAGED_CODE();
    DPRINT1("PCI - AddDevice (a new bus). PDO: %p (Driver: %wZ)\n",
            PhysicalDeviceObject, &PhysicalDeviceObject->DriverObject->DriverName);

    /* Zero out variables so failure path knows what to do */
    AttachedTo = NULL;
    FdoExtension = NULL;
    PdoExtension = NULL;
    DeviceObject = NULL;

    do
    {
        /* Check if there's already a device extension for this bus */
        ParentExtension = PciFindParentPciFdoExtension(PhysicalDeviceObject,
                                                       &PciGlobalLock);
        if (ParentExtension)
        {
            /* Make sure we find a real PDO */
            PdoExtension = PhysicalDeviceObject->DeviceExtension;
            ASSERT_PDO(PdoExtension);

            /* Make sure it's a PCI-to-PCI bridge */
            if ((PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) ||
                (PdoExtension->SubClass != PCI_SUBCLASS_BR_PCI_TO_PCI))
            {
                /* This should never happen */
                DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
                        "      Class %02x, SubClass %02x, will not add.\n",
                        PdoExtension->BaseClass,
                        PdoExtension->SubClass);
                ASSERT((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
                       (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI));

                /* Enter the failure path */
                Status = STATUS_INVALID_DEVICE_REQUEST;
                break;
            }

            /* Subordinate bus on the bridge */
            DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
                    ParentExtension->BaseBus);

            /* Make sure PCI bus numbers are configured */
            if (!PciAreBusNumbersConfigured(PdoExtension))
            {
                /* This is a critical failure */
                DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
                        ParentExtension->BaseBus,
                        PdoExtension->Slot.u.bits.DeviceNumber,
                        PdoExtension->Slot.u.bits.FunctionNumber);

                /* Enter the failure path */
                Status = STATUS_INVALID_DEVICE_REQUEST;
                break;
            }
        }

        /* Create the FDO for the bus */
        Status = IoCreateDevice(DriverObject,
                                sizeof(PCI_FDO_EXTENSION),
                                NULL,
                                FILE_DEVICE_BUS_EXTENDER,
                                0,
                                0,
                                &DeviceObject);
        if (!NT_SUCCESS(Status)) break;

        /* Initialize the extension for the FDO */
        FdoExtension = DeviceObject->DeviceExtension;
        PciInitializeFdoExtensionCommonFields(DeviceObject->DeviceExtension,
                                              DeviceObject,
                                              PhysicalDeviceObject);

        /* Attach to the root PDO */
        Status = STATUS_NO_SUCH_DEVICE;
        AttachedTo = IoAttachDeviceToDeviceStack(DeviceObject,
                                                 PhysicalDeviceObject);
        ASSERT(AttachedTo != NULL);
        if (!AttachedTo) break;
        FdoExtension->AttachedDeviceObject = AttachedTo;

        /* Check if this is a child bus, or the root */
        if (ParentExtension)
        {
            /* The child inherits root data */
            FdoExtension->BaseBus = PdoExtension->Dependent.type1.SecondaryBus;
            FdoExtension->BusRootFdoExtension = ParentExtension->BusRootFdoExtension;
            PdoExtension->BridgeFdoExtension = FdoExtension;
            FdoExtension->ParentFdoExtension = ParentExtension;
        }
        else
        {
            /* Query the boot configuration */
            Status = PciGetDeviceProperty(PhysicalDeviceObject,
                                          DevicePropertyBootConfiguration,
                                          (PVOID*)&Descriptor);
            if (!NT_SUCCESS(Status))
            {
                /* No configuration has been set */
                Descriptor = NULL;
            }
            else
            {
                /* Root PDO in ReactOS does not assign boot resources */
                UNIMPLEMENTED_DBGBREAK("Encountered during setup\n");
                Descriptor = NULL;
            }

            if (Descriptor)
            {
                /* Root PDO in ReactOS does not assign boot resources */
                UNIMPLEMENTED_DBGBREAK();
            }
            else
            {
                /* Default configuration isn't the normal path on Windows */
                if (PciBreakOnDefault)
                {
                    /* If a second bus is found and there's still no data, crash */
                    KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL,
                                 0xDEAD0010u,
                                 (ULONG_PTR)DeviceObject,
                                 0,
                                 0);
                }

                /* Warn that a default configuration will be used, and set bus 0 */
                DPRINT1("PCI   Will use default configuration.\n");
                PciBreakOnDefault = TRUE;
                FdoExtension->BaseBus = 0;
            }

            /* This is the root bus */
            FdoExtension->BusRootFdoExtension = FdoExtension;
        }

        /* Get the HAL or ACPI Bus Handler Callbacks for Configuration Access */
        Status = PciGetConfigHandlers(FdoExtension);
        if (!NT_SUCCESS(Status)) break;

        /* Initialize all the supported PCI arbiters */
        Status = PciInitializeArbiters(FdoExtension);
        if (!NT_SUCCESS(Status)) break;

        /* This is a real FDO, insert it into the list */
        FdoExtension->Fake = FALSE;
        PciInsertEntryAtTail(&PciFdoExtensionListHead,
                             FdoExtension,
                             &PciGlobalLock);

        /* Open the device registry key so that we can query the errata flags */
        IoOpenDeviceRegistryKey(DeviceObject,
                                PLUGPLAY_REGKEY_DEVICE,
                                KEY_ALL_ACCESS,
                                &KeyHandle),

        /* Open the value that contains errata flags for this bus instance */
        RtlInitUnicodeString(&ValueName, L"HackFlags");
        Status = ZwQueryValueKey(KeyHandle,
                                 &ValueName,
                                 KeyValuePartialInformation,
                                 ValueInfo,
                                 sizeof(Buffer),
                                 &ResultLength);
        ZwClose(KeyHandle);
        if (NT_SUCCESS(Status))
        {
            /* Make sure the data is of expected type and size */
            if ((ValueInfo->Type == REG_DWORD) &&
                (ValueInfo->DataLength == sizeof(ULONG)))
            {
                /* Read the flags for this bus */
                FdoExtension->BusHackFlags = *(PULONG)&ValueInfo->Data;
            }
        }

        /* Query ACPI for PCI HotPlug Support */
        PciGetHotPlugParameters(FdoExtension);

        /* The Bus FDO is now initialized */
        DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
        return STATUS_SUCCESS;
    } while (FALSE);

    /* This is the failure path */
    ASSERT(!NT_SUCCESS(Status));

    /* Check if the FDO extension exists */
    if (FdoExtension) DPRINT1("Should destroy secondaries\n");

    /* Delete device objects */
    if (AttachedTo) IoDetachDevice(AttachedTo);
    if (DeviceObject) IoDeleteDevice(DeviceObject);
    return Status;
}
Beispiel #22
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;

}
Beispiel #23
0
NTSTATUS NTAPI
AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
{
    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT Fdo;
    ULONG UsbDeviceNumber = 0;
    WCHAR CharDeviceName[64];
    WCHAR CharSymLinkName[64];
    UNICODE_STRING DeviceName;
    UNICODE_STRING SymLinkName;
    UNICODE_STRING InterfaceSymLinkName;
    ULONG BytesRead;
    PCI_COMMON_CONFIG PciConfig;

    PFDO_DEVICE_EXTENSION FdoDeviceExtension;

    DPRINT1("Ehci: AddDevice\n");

    /* Create the FDO with next available number */
    while (TRUE)
    {
        /* FIXME: Use safe string sprintf*/
        /* RtlStringCchPrintfW(CharDeviceName, 64, L"USBFDO-%d", UsbDeviceNumber); */
        swprintf(CharDeviceName, L"\\Device\\USBFDO-%d", UsbDeviceNumber);
        RtlInitUnicodeString(&DeviceName, CharDeviceName);
        DPRINT("DeviceName %wZ\n", &DeviceName);

        Status = IoCreateDevice(DriverObject,
                                sizeof(FDO_DEVICE_EXTENSION),
                                &DeviceName,
                                FILE_DEVICE_CONTROLLER,
                                0,
                                FALSE,
                                &Fdo);

        if (NT_SUCCESS(Status))
            break;

        if ((Status == STATUS_OBJECT_NAME_EXISTS) || (Status == STATUS_OBJECT_NAME_COLLISION))
        {
            /* Try the next name */
            UsbDeviceNumber++;
            continue;
        }

        /* Bail on any other error */
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("UsbEhci: Failed to create %wZ, Status %x\n", &DeviceName, Status);
            return Status;
        }
    }

    swprintf(CharSymLinkName, L"\\Device\\HCD%d", UsbDeviceNumber);
    RtlInitUnicodeString(&SymLinkName, CharSymLinkName);
    Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Warning: Unable to create symbolic link for ehci host controller!\n");
    }

    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension;
    RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));

    KeInitializeTimerEx(&FdoDeviceExtension->UpdateTimer, SynchronizationTimer);

    FdoDeviceExtension->Common.IsFdo = TRUE;
    FdoDeviceExtension->DeviceObject = Fdo;

    FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);

    if (FdoDeviceExtension->LowerDevice == NULL)
    {
        DPRINT1("UsbEhci: Failed to attach to device stack!\n");
        IoDeleteSymbolicLink(&SymLinkName);
        IoDeleteDevice(Fdo);

        return STATUS_NO_SUCH_DEVICE;
    }

    Fdo->Flags |= DO_BUFFERED_IO;// | DO_POWER_PAGABLE;

    ASSERT(FdoDeviceExtension->LowerDevice == Pdo);

    /* Get the EHCI Device ID and Vendor ID */
    Status = GetBusInterface(FdoDeviceExtension->LowerDevice, &FdoDeviceExtension->BusInterface);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("GetBusInterface() failed with %x\n", Status);
        IoDetachDevice(FdoDeviceExtension->LowerDevice);
        IoDeleteSymbolicLink(&SymLinkName);
        IoDeleteDevice(Fdo);
        return Status;
    }

    BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)(
        FdoDeviceExtension->BusInterface.Context,
        PCI_WHICHSPACE_CONFIG,
        &PciConfig,
        0,
        PCI_COMMON_HDR_LENGTH);


    if (BytesRead != PCI_COMMON_HDR_LENGTH)
    {
        DPRINT1("GetBusData failed!\n");
        IoDetachDevice(FdoDeviceExtension->LowerDevice);
        IoDeleteSymbolicLink(&SymLinkName);
        IoDeleteDevice(Fdo);
        return STATUS_UNSUCCESSFUL;
    }

    if (PciConfig.Command & PCI_ENABLE_IO_SPACE)
        DPRINT("PCI_ENABLE_IO_SPACE\n");

    if (PciConfig.Command & PCI_ENABLE_MEMORY_SPACE)
        DPRINT("PCI_ENABLE_MEMORY_SPACE\n");

    if (PciConfig.Command & PCI_ENABLE_BUS_MASTER)
        DPRINT("PCI_ENABLE_BUS_MASTER\n");

    DPRINT("BaseAddress[0] %x\n", PciConfig.u.type0.BaseAddresses[0]);
    DPRINT1("Vendor %x\n", PciConfig.VendorID);
    DPRINT1("Device %x\n", PciConfig.DeviceID);

    FdoDeviceExtension->VendorId = PciConfig.VendorID;
    FdoDeviceExtension->DeviceId = PciConfig.DeviceID;

    FdoDeviceExtension->DeviceState = DEVICEINTIALIZED;

    Status = IoRegisterDeviceInterface(Pdo, &GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, &InterfaceSymLinkName);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Unable to register device interface!\n");
        return Status;
    }
    else
    {
        Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
        DPRINT1("SetInterfaceState %x\n", Status);
        if (!NT_SUCCESS(Status))
            return Status;
    }
    Fdo->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;
}
Beispiel #24
0
NTSTATUS
FPFilterAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    NTSTATUS                status;
    PDEVICE_OBJECT          filterDeviceObject;
    ULONG                   registrationFlag = 0;
    PDEVICE_EXTENSION       pDevExtFilter;
    PDEVICE_OBJECT          controlDeviceObject;
    PDEVICE_EXTENSION2      pDevExtControl;
	WCHAR					deviceNamestr[32];
	WCHAR					linkNamestr[32];
	UNICODE_STRING			deviceName;
	UNICODE_STRING			linkName;
	ULONG					n;
    PDEVICE_OBJECT          TempDeviceObject;
	ULONG					DeviceType = FILE_DEVICE_UNKNOWN;


    KdPrint(("LPCFILTER: FPFilterAddDevice: Driver %p Device %p\n", DriverObject, PhysicalDeviceObject));


	//
	//  Create a single control device object. This can be opened by user mode apps to do usefull things with
	//

	if(gCtlDevNum == 0)
	{

		RtlStringCbPrintfW(deviceNamestr,   64, L"\\Device\\SFltrl%d", gCtlDevNum);  // the symbollic link that can be opened by CreateFile() in user mode.
		RtlStringCbPrintfW(linkNamestr,   64, L"\\DosDevices\\SFltrl%d", gCtlDevNum);

		RtlInitUnicodeString(&deviceName,	deviceNamestr);

		RtlInitUnicodeString(&linkName,	linkNamestr);

		gStatus = IoCreateDevice(DriverObject,
								sizeof(DEVICE_EXTENSION2), // this allocates a chunk of memory in the device obhect of this size
								&deviceName,
								FILE_DEVICE_UNKNOWN,
								0,
								FALSE,
								&controlDeviceObject);

		if (!NT_SUCCESS(gStatus))
		{
			KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create control DeviceObject\n"));
			goto EndCONTROLdeviceCreate;
		}


		// point our device extension to the chunk of memory allocated for us
		pDevExtControl					= (PDEVICE_EXTENSION2) controlDeviceObject->DeviceExtension;

		// and set up some usefull values in it...
		RtlZeroMemory(pDevExtControl, sizeof(PDEVICE_EXTENSION2));

		pDevExtControl->DeviceObject	= controlDeviceObject;

		pDevExtControl->Type			= CONTROL;

		pDevExtControl->DeviceObject->Flags |= DO_DIRECT_IO;

		pDevExtControl->DeviceObject->Flags  &= ~DO_POWER_PAGABLE;



		status = IoCreateSymbolicLink(&linkName, &deviceName);

		if (!NT_SUCCESS(status)) 
		{
			KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create symbolic link\n"));
			IoDeleteDevice(pDevExtControl->DeviceObject);
			goto EndCONTROLdeviceCreate;
		}


		RtlStringCbCopyW(pDevExtControl->linkNamestr, 64, linkNamestr);
		
		RtlInitUnicodeString(&pDevExtControl->linkName, pDevExtControl->linkNamestr);

		KeInitializeSpinLock(&pDevExtControl->AppLock);


		//
		// set some default values
		//

		pDevExtControl->Config.StayAliveFailureLimit	= 50;

		pDevExtControl->Config.ThreadDelay				= 20;

		pDevExtControl->Config.StatsSampleRate			= 1;  // basic sampling rate

		// KeQueryTimeIncrement returns the number of 100 nano seconds intervals per tick,
		// Convert it to milliseconds (normally about 15 ms per tick, but this can be adjusted)
		pDevExtControl->MillisPerTick =  KeQueryTimeIncrement() / 10000;
		

		KdPrint(("LPCFILTER: FPFilterAddDevice: control Device Object: 0x%X \n		Created device %S \n", controlDeviceObject, deviceNamestr));

		// Clear the DO_DEVICE_INITIALIZING flag, if you dont, you cant open the device from user mode.
		// Yep, how many times have I forgotten to do that.... :)
		CLEAR_FLAG(controlDeviceObject->Flags, DO_DEVICE_INITIALIZING);
	}
EndCONTROLdeviceCreate:

	


    //
    // Create a filter device object for this device.
	// This is the device that actually sits in the CPU stack.
	// Because declared this device as a lower filter to the normal CPU driver, 
	// ie, we are above acpi and below intelppmm when we cal IoAttachDeviceToDeviceStack() 
	// we get attached to acpi and get a pointer to its device object for the CPU (actually called a Physical Device Object) 
    //

	// get a temp ref to the lower device so we can copy the device type
	TempDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
    DeviceType = TempDeviceObject->DeviceType;
    ObDereferenceObject(TempDeviceObject);

	KdPrint(("LPCFILTER: FPFilterAddDevice: device type is %d\n", DeviceType));

    status = IoCreateDevice(DriverObject,
                            sizeof(DEVICE_EXTENSION),
                            NULL,
                            DeviceType,
                            0,
                            FALSE,
                            &filterDeviceObject);

    if (!NT_SUCCESS(status)) {
        KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create filterDeviceObject\n"));
		IoDeleteSymbolicLink(&linkName);
		IoDeleteDevice(controlDeviceObject);
        return status;
    }

    pDevExtFilter = (PDEVICE_EXTENSION) filterDeviceObject->DeviceExtension;

    RtlZeroMemory(pDevExtFilter, sizeof(DEVICE_EXTENSION));



    //
    // Attach the device object to the highest device object in the chain and
    // return the previously highest device object, which is passed to
    // IoCallDriver when we pass IRPs down the device stack
    //

	// we use TargetDeviceObject to send IOCTLs to  to get information on ACPI objects
    pDevExtFilter->TargetDeviceObject = IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject);

    if (pDevExtFilter->TargetDeviceObject == NULL) 
	{
 		IoDeleteSymbolicLink(&linkName);
		IoDeleteDevice(controlDeviceObject);
        IoDeleteDevice(filterDeviceObject);
        KdPrint(("LPCFILTER: FPFilterAddDevice: Unable to attach %X to target %X\n", filterDeviceObject, PhysicalDeviceObject));
        return STATUS_NO_SUCH_DEVICE;
    }

    // Save the filter device object in the device extension
    pDevExtFilter->DeviceObject = filterDeviceObject;

	pDevExtFilter->Type			= FILTER;

	// copy the flags and other stuff off the lower device 
	pDevExtFilter->DeviceObject->Flags |= 
					pDevExtFilter->TargetDeviceObject->Flags &
					(DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE );

	pDevExtFilter->DeviceObject->Characteristics	= pDevExtFilter->TargetDeviceObject->Characteristics;
	pDevExtFilter->DeviceObject->DeviceType			= pDevExtFilter->TargetDeviceObject->DeviceType;

	KdPrint(("LPCFILTER: FPFilterAddDevice: Lowerdo type is %d\n", pDevExtFilter->DeviceObject->DeviceType));
    KdPrint(("LPCFILTER: FPFilterAddDevice: Lowerdo flags are: 0x%X\n",  pDevExtFilter->DeviceObject->Flags));

    // if it is the first FILTER device we created and we sucessfully created a CONTROL device...
	if((gCtlDevNum == 0) && (NT_SUCCESS(gStatus)))
	{
		// reference each other device extensions
		// we do this so when the CONTROL device object gets caled frodm user mode we can interact with the acpi PhsicalDevice Object
		pDevExtControl->pOtherExt = pDevExtFilter;
		pDevExtFilter->pOtherExt = pDevExtControl;
	}
		
    //
    // Initialize the remove lock
    //
    IoInitializeRemoveLock(&pDevExtFilter->RemoveLock,
                           0,
                           0,
                           0);

    // Clear the DO_DEVICE_INITIALIZING flag
    CLEAR_FLAG(filterDeviceObject->Flags, DO_DEVICE_INITIALIZING);

	gCtlDevNum = 1; // we created our control device object, so even though AddDevice 
	// gets called again on a multi processor system, we set this so we dont create any more

    return STATUS_SUCCESS;
} 
Beispiel #25
0
NTSTATUS
NTAPI
StreamClassAddDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject)
{
    PSTREAM_CLASS_DRIVER_EXTENSION DriverObjectExtension;
    PDEVICE_OBJECT DeviceObject, LowerDeviceObject;
    PSTREAM_DEVICE_EXTENSION DeviceExtension;
    PKSOBJECT_CREATE_ITEM ItemList;
    NTSTATUS Status;

    /* Fetch driver object extension */
    DriverObjectExtension = IoGetDriverObjectExtension(DriverObject, (PVOID)StreamClassAddDevice);
    if (!DriverObjectExtension)
    {
        /* Failed to get driver extension */
        return STATUS_DEVICE_DOES_NOT_EXIST;
    }
    /* Allocate Create Item */
    ItemList = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
    if (!ItemList)
    {
        /* Failed to allocated Create Item */
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Create the FDO */
    Status = IoCreateDevice(DriverObject, DriverObjectExtension->Data.DeviceExtensionSize + sizeof(STREAM_DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, 0, &DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Failed to create the FDO */
        ExFreePool(ItemList);
        return Status;
    }

    /* Attach to device stack */
    LowerDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
    if (!LowerDeviceObject)
    {
        /* Failed to attach */
        IoDeleteDevice(DeviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    /* Zero Create item */
    RtlZeroMemory(ItemList, sizeof(KSOBJECT_CREATE_ITEM));
    /* Setup object class */
    RtlInitUnicodeString(&ItemList->ObjectClass, L"GLOBAL");
    /* Setup CreateDispatch routine */
    ItemList->Create = StreamClassCreateFilter;

    /* Get device extension */
    DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    /* Zero device extension */
    RtlZeroMemory(DeviceExtension, sizeof(STREAM_DEVICE_EXTENSION));
    /* Initialize Ks streaming */
    Status = KsAllocateDeviceHeader(&DeviceExtension->Header, 1, ItemList);
    if (!NT_SUCCESS(Status))
    {
        /* Cleanup resources */
        IoDetachDevice(LowerDeviceObject);
        IoDeleteDevice(DeviceObject);
        ExFreePool(ItemList);
        return Status;
    }

    /* Store lower device object */
    DeviceExtension->LowerDeviceObject = LowerDeviceObject;

    /* Store physical device object */
    DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
    /* Store driver object extension */
    DeviceExtension->DriverExtension = DriverObjectExtension;
    /* Initialize memory list */
    InitializeListHead(&DeviceExtension->MemoryResourceList);
    /* Setup device extension */
    DeviceExtension->DeviceExtension = (PVOID) (DeviceExtension + 1);
    /* Init interrupt dpc */
    KeInitializeDpc(&DeviceExtension->InterruptDpc, StreamClassInterruptDpc, (PVOID)DeviceExtension);

    /* Set device transfer method */
    DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    /* Clear init flag */
    DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;

    return Status;
}
Beispiel #26
0
NTSTATUS
DokanRegisterDeviceInterface(__in PDRIVER_OBJECT DriverObject,
                             __in PDEVICE_OBJECT DeviceObject,
                             __in PDokanDCB Dcb) {
  PDEVICE_OBJECT pnpDeviceObject = NULL;
  NTSTATUS status;

  status = IoReportDetectedDevice(DriverObject, InterfaceTypeUndefined, 0, 0,
                                  NULL, NULL, FALSE, &pnpDeviceObject);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoReportDetectedDevice success\n");
  } else {
    DDbgPrint("  IoReportDetectedDevice failed: 0x%x\n", status);
    return status;
  }

  if (IoAttachDeviceToDeviceStack(pnpDeviceObject, DeviceObject) != NULL) {
    DDbgPrint("  IoAttachDeviceToDeviceStack success\n");
  } else {
    DDbgPrint("  IoAttachDeviceToDeviceStack failed\n");
  }

  status = IoRegisterDeviceInterface(pnpDeviceObject, &GUID_DEVINTERFACE_DISK,
                                     NULL, &Dcb->DiskDeviceInterfaceName);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoRegisterDeviceInterface success: %wZ\n",
              &Dcb->DiskDeviceInterfaceName);
  } else {
    RtlInitUnicodeString(&Dcb->DiskDeviceInterfaceName, NULL);
    DDbgPrint("  IoRegisterDeviceInterface failed: 0x%x\n", status);
    return status;
  }

  status = IoSetDeviceInterfaceState(&Dcb->DiskDeviceInterfaceName, TRUE);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoSetDeviceInterfaceState success\n");
  } else {
    DDbgPrint("  IoSetDeviceInterfaceState failed: 0x%x\n", status);
    return status;
  }

  status =
      IoRegisterDeviceInterface(pnpDeviceObject, &MOUNTDEV_MOUNTED_DEVICE_GUID,
                                NULL, &Dcb->MountedDeviceInterfaceName);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoRegisterDeviceInterface success: %wZ\n",
              &Dcb->MountedDeviceInterfaceName);
  } else {
    DDbgPrint("  IoRegisterDeviceInterface failed: 0x%x\n", status);
    return status;
  }

  status = IoSetDeviceInterfaceState(&Dcb->MountedDeviceInterfaceName, TRUE);

  if (NT_SUCCESS(status)) {
    DDbgPrint("  IoSetDeviceInterfaceState success\n");
  } else {
    RtlInitUnicodeString(&Dcb->MountedDeviceInterfaceName, NULL);
    DDbgPrint("  IoSetDeviceInterfaceState failed: 0x%x\n", status);
    return status;
  }

  return status;
}
Beispiel #27
0
NTSTATUS AddDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject 
    )
{
	ULONG DeviceExtensionSize;
	PDEVICE_EXTENSION pCtx;
	PDEVICE_OBJECT ptr_PDO;
	NTSTATUS status;
	ULONG IdxPwrState;

	RtlInitUnicodeString(
		&Global_sz_DeviceName,
		L"\\DosDevices\\PSDOBUFDVC");
	//Get DEVICE_EXTENSION required memory space
	DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
	status = IoCreateDevice(
		DriverObject,
		DeviceExtensionSize,
		&Global_sz_DeviceName,
		FILE_DEVICE_UNKNOWN,
		FILE_DEVICE_SECURE_OPEN, 
		FALSE,
		&ptr_PDO
    );

	if (NT_SUCCESS(status)) {
		ptr_PDO->Flags &= ~DO_DEVICE_INITIALIZING;
		ptr_PDO->Flags |= DO_BUFFERED_IO;
		pCtx = ptr_PDO->DeviceExtension;
		pCtx->DeviceObject = ptr_PDO;
		RtlInitUnicodeString(
			&pCtx->Device_Description,
			L"This is a Buffered I/O Driver for Pseudo Device\r\n"
			L"Created by mjtsai 2003/8/1\r\n");
		IoInitializeRemoveLock(
			&pCtx->RemoveLock,
			'KCOL',
			0,
			0
		);
		pCtx->DataBuffer = ExAllocatePool(
			NonPagedPool, 1024);
		RtlZeroMemory(
			pCtx->DataBuffer,
			1024);
		//Initialize driver power state
		pCtx->SysPwrState = PowerSystemWorking;
		pCtx->DevPwrState = PowerDeviceD0;
		
		//Initialize device power information
		Global_PowerInfo_Ptr = ExAllocatePool(
			NonPagedPool, sizeof(DEVICE_POWER_INFORMATION));
		RtlZeroMemory(
			Global_PowerInfo_Ptr,
			sizeof(DEVICE_POWER_INFORMATION));
		Global_PowerInfo_Ptr->SupportQueryCapability = FALSE;
		Global_PowerInfo_Ptr->DeviceD1 = 0;
		Global_PowerInfo_Ptr->DeviceD2 = 0;
		Global_PowerInfo_Ptr->WakeFromD0 = 0;
		Global_PowerInfo_Ptr->WakeFromD1 = 0;
		Global_PowerInfo_Ptr->WakeFromD2 = 0;
		Global_PowerInfo_Ptr->WakeFromD3 = 0;
		Global_PowerInfo_Ptr->DeviceWake = 0;
		Global_PowerInfo_Ptr->SystemWake = 0;
		for (IdxPwrState = 0;
			IdxPwrState < PowerSystemMaximum;
			IdxPwrState++)
		{
			Global_PowerInfo_Ptr->DeviceState[IdxPwrState] = 0;
		}
		//Store next-layered device object
		//Attach device object to device stack
		pCtx->NextDeviceObject = 
			IoAttachDeviceToDeviceStack(ptr_PDO, PhysicalDeviceObject);
	}

	return status;
}
/**
 * Handle request from the Plug & Play subsystem.
 *
 * @returns NT status code
 * @param  pDrvObj   Driver object
 * @param  pDevObj   Device object
 */
static NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
{
    NTSTATUS rc;
    Log(("VBoxGuest::vboxguestwinGuestAddDevice\n"));

    /*
     * Create device.
     */
    PDEVICE_OBJECT pDeviceObject = NULL;
    PVBOXGUESTDEVEXT pDevExt = NULL;
    UNICODE_STRING devName;
    UNICODE_STRING win32Name;
    RtlInitUnicodeString(&devName, VBOXGUEST_DEVICE_NAME_NT);
    rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXT), &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
    if (NT_SUCCESS(rc))
    {
        /*
         * Create symbolic link (DOS devices).
         */
        RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
        rc = IoCreateSymbolicLink(&win32Name, &devName);
        if (NT_SUCCESS(rc))
        {
            /*
             * Setup the device extension.
             */
            pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
            RtlZeroMemory(pDevExt, sizeof(VBOXGUESTDEVEXT));

            KeInitializeSpinLock(&pDevExt->win.s.MouseEventAccessLock);

            pDevExt->win.s.pDeviceObject = pDeviceObject;
            pDevExt->win.s.prevDevState = STOPPED;
            pDevExt->win.s.devState = STOPPED;

            pDevExt->win.s.pNextLowerDriver = IoAttachDeviceToDeviceStack(pDeviceObject, pDevObj);
            if (pDevExt->win.s.pNextLowerDriver == NULL)
            {
                Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n"));
                rc = STATUS_DEVICE_NOT_CONNECTED;
            }
        }
        else
            Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoCreateSymbolicLink failed with rc=%#x!\n", rc));
    }
    else
        Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoCreateDevice failed with rc=%#x!\n", rc));

    if (NT_SUCCESS(rc))
    {
        /*
         * If we reached this point we're fine with the basic driver setup,
         * so continue to init our own things.
         */
#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
        vboxguestwinBugCheckCallback(pDevExt); /* Ignore failure! */
#endif
        /* VBoxGuestPower is pageable; ensure we are not called at elevated IRQL */
        pDeviceObject->Flags |= DO_POWER_PAGABLE;

        /* Driver is ready now. */
        pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    }

    /* Cleanup on error. */
    if (NT_ERROR(rc))
    {
        if (pDevExt)
        {
            if (pDevExt->win.s.pNextLowerDriver)
                IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
        }
        IoDeleteSymbolicLink(&win32Name);
        if (pDeviceObject)
            IoDeleteDevice(pDeviceObject);
    }

    Log(("VBoxGuest::vboxguestwinGuestAddDevice: returning with rc = 0x%x\n", rc));
    return rc;
}
NTSTATUS KBFAttachDevicesEx(IN PDRIVER_OBJECT aDriverObject, IN PUNICODE_STRING aRegistryPath)
{
    UNREFERENCED_PARAMETER(aDriverObject);
    UNREFERENCED_PARAMETER(aRegistryPath);

    NTSTATUS status = STATUS_SUCCESS;

    // 遍历所有键盘设备
    UNICODE_STRING nameString;
    static WCHAR name[32] = {0};
    ULONG index = 0;

    PDEVICE_OBJECT deviceObject = NULL;
    PFILE_OBJECT fileObject = NULL;

    // 第一个设备
    RtlZeroMemory(name, sizeof(WCHAR)*32);
    RtlStringCchPrintfW(name, 32, L"\\Device\\KeyboardClass%d", index);
    RtlInitUnicodeString(&nameString, name);

    // 打开设备对象
    status = IoGetDeviceObjectPointer(&nameString, FILE_ALL_ACCESS, &fileObject, &deviceObject);
    if (NT_SUCCESS(status))
        ObDereferenceObject(fileObject);

    while (deviceObject != NULL)
    {
        PDEVICE_OBJECT pFilterDeviceObject = NULL;
        PDEVICE_OBJECT pLowerDeviceObject = NULL;

        // 创建一个过滤设备
        status = IoCreateDevice(aDriverObject, sizeof(DEVICE_EXTENSION), NULL,
                                deviceObject->DeviceType, deviceObject->Characteristics, FALSE, &pFilterDeviceObject);

        if (!NT_SUCCESS(status))
        {
            KdPrint(("wykbflt.sys : KBFAttachDevices Couldn't create the Filter Device Object %d\n", index));
            break;
        }

        pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, deviceObject);
        if (!pLowerDeviceObject)
        {
            KdPrint(("wykbflt.sys : Couldn't attach to Device Object\n"));
            IoDeleteDevice(pFilterDeviceObject);
            pFilterDeviceObject = NULL;
            break;
        }

        // 设备扩展
        PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)pFilterDeviceObject->DeviceExtension;
        KBFInitDeviceExtension(deviceExtension, pFilterDeviceObject, deviceObject, pLowerDeviceObject);

        // 设置过滤操作
        pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType;	// 要过滤的设备类型跟物理设备类型一致
        pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics;
        pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize + 1;
        pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ;

        ++index;

        RtlZeroMemory(name, sizeof(WCHAR)*32);
        RtlStringCchPrintfW(name, 32, L"\\Device\\KeyboardClass%d", index);
        RtlInitUnicodeString(&nameString, name);

        // 打开设备对象
        status = IoGetDeviceObjectPointer(&nameString, FILE_ALL_ACCESS, &fileObject, &deviceObject);
        if (NT_SUCCESS(status))
            ObDereferenceObject(fileObject);
        else
            break;
    }

    return STATUS_SUCCESS;
}
Beispiel #30
0
static NTSTATUS
V4vAddDevice(PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
{
    NTSTATUS          status = STATUS_SUCCESS;
    UNICODE_STRING    deviceName;
    PDEVICE_OBJECT    fdo = NULL;
    PXENV4V_EXTENSION pde = NULL;
    LONG              val;
    BOOLEAN           symlink = FALSE;
    LARGE_INTEGER     seed;
    WCHAR            *szSddl = NULL;
    UNICODE_STRING    sddlString;
    CHAR             *szFpath = NULL;

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    // We only allow one instance of this device type. If more than on pdo is created we need
    val = InterlockedCompareExchange(&g_deviceCreated, 1, 0);
    if (val != 0) {
        TraceWarning(("cannot instantiate more that one v4v device node.\n"));
        return STATUS_UNSUCCESSFUL;
    }

    do {
        // Create our device
        RtlInitUnicodeString(&deviceName, V4V_DEVICE_NAME);
        szSddl = g_win5Sddl;
        RtlInitUnicodeString(&sddlString, szSddl);

        status = 
            IoCreateDeviceSecure(driverObject,
                                 sizeof(XENV4V_EXTENSION),
                                 &deviceName,
                                 FILE_DEVICE_UNKNOWN,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &sddlString,
                                 (LPCGUID)&GUID_SD_XENV4V_CONTROL_OBJECT,
                                 &fdo);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create device object - error: 0x%x\n", status));
            fdo = NULL;
            break;
        }

        pde = (PXENV4V_EXTENSION)fdo->DeviceExtension;
        RtlZeroMemory(pde, sizeof(XENV4V_EXTENSION));
        RtlStringCchCopyW(pde->symbolicLinkText, XENV4V_SYM_NAME_LEN, V4V_SYMBOLIC_NAME);
        RtlInitUnicodeString(&pde->symbolicLink, pde->symbolicLinkText);

        // Create our symbolic link
        status = IoCreateSymbolicLink(&pde->symbolicLink, &deviceName);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create symbolic - error: 0x%x\n", status));
            break;
        }
        symlink = TRUE;       

        // Get our xenstore path
        szFpath = xenbus_find_frontend(pdo);
        if (szFpath == NULL) {
            status = STATUS_NO_SUCH_DEVICE;
            TraceError(("failed to locate XenStore front end path\n"));
            break;
        }

        // Setup the extension
        pde->magic = XENV4V_MAGIC;
        pde->pdo = pdo;
        pde->fdo = fdo;
        IoInitializeRemoveLock(&pde->removeLock, 'v4vx', 0, 0);
        pde->frontendPath = szFpath;
        szFpath = NULL;
        pde->state = XENV4V_DEV_STOPPED; // wait for start
        pde->lastPoState = PowerSystemWorking;
        pde->virqPort = null_EVTCHN_PORT();
        KeInitializeDpc(&pde->virqDpc, V4vVirqNotifyDpc, fdo);
        KeInitializeSpinLock(&pde->virqLock);
        KeInitializeSpinLock(&pde->dpcLock);
        KeInitializeTimerEx(&pde->timer, NotificationTimer);
        KeInitializeDpc(&pde->timerDpc,
                        V4vConnectTimerDpc,
                        fdo);
        KeInitializeSpinLock(&pde->timerLock);
        pde->timerCounter = 0;
        InitializeListHead(&pde->contextList);
        KeInitializeSpinLock(&pde->contextLock);
        pde->contextCount = 0;
        InitializeListHead(&pde->ringList);
        KeInitializeSpinLock(&pde->ringLock);
        InitializeListHead(&pde->pendingIrpQueue);
        pde->pendingIrpCount = 0;
        KeInitializeSpinLock(&pde->queueLock);
        IoCsqInitializeEx(&pde->csqObject,
                          V4vCsqInsertIrpEx,
                          V4vCsqRemoveIrp,
                          V4vCsqPeekNextIrp,
                          V4vCsqAcquireLock,
                          V4vCsqReleaseLock,
                          V4vCsqCompleteCanceledIrp);
        InitializeListHead(&pde->destList);
        pde->destCount = 0;
        ExInitializeNPagedLookasideList(&pde->destLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(XENV4V_DESTINATION),
                                        XENV4V_TAG,
                                        0);
        KeQueryTickCount(&seed);
        pde->seed = seed.u.LowPart;

        // Now attach us to the stack
        pde->ldo = IoAttachDeviceToDeviceStack(fdo, pdo);
        if (pde->ldo == NULL) {
            TraceError(("failed to attach device to stack - error: 0x%x\n", status));
            status = STATUS_NO_SUCH_DEVICE;
            break;
        }

        // Use direct IO and let the IO manager directly map user buffers; clear the init flag
        fdo->Flags |= DO_DIRECT_IO;
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;        

        // Made it here, go to connected state to be consistent
        xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CONNECTED);
    } while (FALSE);

    if (!NT_SUCCESS(status)) {
        if (fdo != NULL) {         
            if ((pde != NULL)&&(pde->ldo != NULL)) {
                IoDetachDevice(pde->ldo);
            }
            if (szFpath != NULL) {
                XmFreeMemory(szFpath);
            }
            if (symlink) {
                IoDeleteSymbolicLink(&pde->symbolicLink);
            }
            IoDeleteDevice(fdo);
        }
    }

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));

    return status;
}