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; }
// 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
// // 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; }
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()
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; }
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; }
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; }
NTSTATUS MobiUsb_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) /*++ Description: Arguments: DriverObject - Store the pointer to the object representing us. PhysicalDeviceObject - Pointer to the device object created by the undelying bus driver. Return: STATUS_SUCCESS - if successful STATUS_UNSUCCESSFUL - otherwise --*/ { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; POWER_STATE state; KIRQL oldIrql; MobiUsb_DbgPrint(3, ("file mobiusb: MobiUsb_AddDevice - begins\n")); deviceObject = NULL; ntStatus = IoCreateDevice( DriverObject, // our driver object sizeof(DEVICE_EXTENSION), // extension size for us NULL, // name for this device FILE_DEVICE_UNKNOWN, FILE_AUTOGENERATED_DEVICE_NAME, // device characteristics FALSE, // Not exclusive &deviceObject); // Our device object if(!NT_SUCCESS(ntStatus)) { // // returning failure here prevents the entire stack from functioning, // but most likely the rest of the stack will not be able to create // device objects either, so it is still OK. // MobiUsb_DbgPrint(1, ("file mobiusb: Failed to create device object\n")); return ntStatus; } // // Initialize the device extension // deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->FunctionalDeviceObject = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; #ifdef MOBI_DIRECT_IO deviceObject->Flags |= DO_DIRECT_IO; #else deviceObject->Flags |= DO_BUFFERED_IO; #endif // // initialize the device state lock and set the device state // KeInitializeSpinLock(&deviceExtension->DevStateLock); INITIALIZE_PNP_STATE(deviceExtension); // //initialize OpenHandleCount // deviceExtension->OpenHandleCount = 0; // // Initialize the selective suspend variables // KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); deviceExtension->IdleReqPend = 0; deviceExtension->PendingIdleIrp = NULL; // // Initialize the vendor command semaphore // KeInitializeSemaphore(&deviceExtension->CallUSBSemaphore, 1, 1); // // Hold requests until the device is started // deviceExtension->QueueState = HoldRequests; // // Initialize the queue and the queue spin lock // InitializeListHead(&deviceExtension->NewRequestsQueue); KeInitializeSpinLock(&deviceExtension->QueueLock); // // Initialize the remove event to not-signaled. // KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); // // Initialize the stop event to signaled. // This event is signaled when the OutstandingIO becomes 1 // KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); // // OutstandingIo count biased to 1. // Transition to 0 during remove device means IO is finished. // Transition to 1 means the device can be stopped // deviceExtension->OutStandingIO = 1; KeInitializeSpinLock(&deviceExtension->IOCountLock); // // Delegating to WMILIB // ntStatus = MobiUsb_WmiRegistration(deviceExtension); if(!NT_SUCCESS(ntStatus)) { MobiUsb_DbgPrint(1, ("file mobiusb: MobiUsb_WmiRegistration failed with %X\n", ntStatus)); IoDeleteDevice(deviceObject); return ntStatus; } // // set the flags as underlying PDO // if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) { deviceObject->Flags |= DO_POWER_PAGABLE; } // // Typically, the function driver for a device is its // power policy owner, although for some devices another // driver or system component may assume this role. // Set the initial power state of the device, if known, by calling // PoSetPowerState. // deviceExtension->DevPower = PowerDeviceD0; deviceExtension->SysPower = PowerSystemWorking; state.DeviceState = PowerDeviceD0; PoSetPowerState(deviceObject, DevicePowerState, state); // // attach our driver to device stack // The return value of IoAttachDeviceToDeviceStack is the top of the // attachment chain. This is where all the IRPs should be routed. // deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if(NULL == deviceExtension->TopOfStackDeviceObject) { MobiUsb_WmiDeRegistration(deviceExtension); IoDeleteDevice(deviceObject); return STATUS_NO_SUCH_DEVICE; } // // Register device interfaces // ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, &GUID_CLASS_VCMOBI_MOBI, NULL, &deviceExtension->InterfaceName); if(!NT_SUCCESS(ntStatus)) { MobiUsb_WmiDeRegistration(deviceExtension); IoDetachDevice(deviceExtension->TopOfStackDeviceObject); IoDeleteDevice(deviceObject); return ntStatus; } //MobiUsb_DbgPrint(3, ("file mobiusb: interfacename: Filename = %ws nameLength = %d\n", deviceExtension->InterfaceName.Buffer, deviceExtension->InterfaceName.Length / sizeof(WCHAR))); if(IoIsWdmVersionAvailable(1, 0x20)) { deviceExtension->WdmVersion = WinXpOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x10)) { deviceExtension->WdmVersion = Win2kOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x5)) { deviceExtension->WdmVersion = WinMeOrBetter; } else if(IoIsWdmVersionAvailable(1, 0x0)) { deviceExtension->WdmVersion = Win98OrBetter; } MobiUsb_DbgPrint(3, ("file mobiusb: WdmVersion = %d\n", deviceExtension->WdmVersion)); deviceExtension->SSRegistryEnable = 0; deviceExtension->SSEnable = 0; // // WinXP only // check the registry flag - // whether the device should selectively // suspend when idle // if(WinXpOrBetter == deviceExtension->WdmVersion) { MobiUsb_GetRegistryDword(MOBIUSB_REGISTRY_PARAMETERS_PATH, L"VCMobiEnable", &deviceExtension->SSRegistryEnable); if(deviceExtension->SSRegistryEnable) { // // initialize DPC // KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); // // initialize the timer. // the DPC and the timer in conjunction, // monitor the state of the device to // selectively suspend the device. // KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); // // Initialize the NoDpcWorkItemPendingEvent to signaled state. // This event is cleared when a Dpc is fired and signaled // on completion of the work-item. // KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); // // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. // KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); } } // // Clear the DO_DEVICE_INITIALIZING flag. // Note: Do not clear this flag until the driver has set the // device power state and the power DO flags. // deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; MobiUsb_DbgPrint(3, ("file mobiusb: MobiUsb_AddDevice - ends\n")); return ntStatus; }
NTSTATUS 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; }
// AddDevice, called when an instance of our supported hardware is found // Returning anything other than NT_SUCCESS here causes the device to fail // to initialise NTSTATUS NTAPI FreeBT_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS ntStatus; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION deviceExtension; POWER_STATE state; KIRQL oldIrql; UNICODE_STRING uniDeviceName; WCHAR wszDeviceName[255]={0}; UNICODE_STRING uniDosDeviceName; LONG instanceNumber=0; FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Entered\n")); deviceObject = NULL; swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); RtlInitUnicodeString(&uniDeviceName, wszDeviceName); ntStatus=STATUS_OBJECT_NAME_COLLISION; while (instanceNumber<99 && !NT_SUCCESS(ntStatus)) { swprintf(wszDeviceName, L"\\Device\\FbtUsb%02d", instanceNumber); uniDeviceName.Length = wcslen(wszDeviceName) * sizeof(WCHAR); FreeBT_DbgPrint(1, ("FBTUSB: Attempting to create device %ws\n", wszDeviceName)); ntStatus = IoCreateDevice( DriverObject, // our driver object sizeof(DEVICE_EXTENSION), // extension size for us &uniDeviceName, // name for this device FILE_DEVICE_UNKNOWN, 0, // device characteristics FALSE, // Not exclusive &deviceObject); // Our device object if (!NT_SUCCESS(ntStatus)) instanceNumber++; } if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: Failed to create device object\n")); return ntStatus; } FreeBT_DbgPrint(1, ("FBTUSB: Created device %ws\n", wszDeviceName)); deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->FunctionalDeviceObject = deviceObject; deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; deviceObject->Flags |= DO_DIRECT_IO; swprintf(deviceExtension->wszDosDeviceName, L"\\DosDevices\\FbtUsb%02d", instanceNumber); RtlInitUnicodeString(&uniDosDeviceName, deviceExtension->wszDosDeviceName); ntStatus=IoCreateSymbolicLink(&uniDosDeviceName, &uniDeviceName); if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: Failed to create symbolic link %ws to %ws, status=0x%08x\n", deviceExtension->wszDosDeviceName, wszDeviceName, ntStatus)); IoDeleteDevice(deviceObject); return ntStatus; } FreeBT_DbgPrint(1, ("FBTUSB: Created symbolic link %ws\n", deviceExtension->wszDosDeviceName)); KeInitializeSpinLock(&deviceExtension->DevStateLock); INITIALIZE_PNP_STATE(deviceExtension); deviceExtension->OpenHandleCount = 0; // Initialize the selective suspend variables KeInitializeSpinLock(&deviceExtension->IdleReqStateLock); deviceExtension->IdleReqPend = 0; deviceExtension->PendingIdleIrp = NULL; // Hold requests until the device is started deviceExtension->QueueState = HoldRequests; // Initialize the queue and the queue spin lock InitializeListHead(&deviceExtension->NewRequestsQueue); KeInitializeSpinLock(&deviceExtension->QueueLock); // Initialize the remove event to not-signaled. KeInitializeEvent(&deviceExtension->RemoveEvent, SynchronizationEvent, FALSE); // Initialize the stop event to signaled. // This event is signaled when the OutstandingIO becomes 1 KeInitializeEvent(&deviceExtension->StopEvent, SynchronizationEvent, TRUE); // OutstandingIo count biased to 1. // Transition to 0 during remove device means IO is finished. // Transition to 1 means the device can be stopped deviceExtension->OutStandingIO = 1; KeInitializeSpinLock(&deviceExtension->IOCountLock); #ifdef ENABLE_WMI // Delegating to WMILIB ntStatus = FreeBT_WmiRegistration(deviceExtension); if (!NT_SUCCESS(ntStatus)) { FreeBT_DbgPrint(1, ("FBTUSB: FreeBT_WmiRegistration failed with %X\n", ntStatus)); IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return ntStatus; } #endif // Set the flags as underlying PDO if (PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) { deviceObject->Flags |= DO_POWER_PAGABLE; } // Typically, the function driver for a device is its // power policy owner, although for some devices another // driver or system component may assume this role. // Set the initial power state of the device, if known, by calling // PoSetPowerState. deviceExtension->DevPower = PowerDeviceD0; deviceExtension->SysPower = PowerSystemWorking; state.DeviceState = PowerDeviceD0; PoSetPowerState(deviceObject, DevicePowerState, state); // attach our driver to device stack // The return value of IoAttachDeviceToDeviceStack is the top of the // attachment chain. This is where all the IRPs should be routed. deviceExtension->TopOfStackDeviceObject = IoAttachDeviceToDeviceStack(deviceObject, PhysicalDeviceObject); if (NULL == deviceExtension->TopOfStackDeviceObject) { #ifdef ENABLE_WMI FreeBT_WmiDeRegistration(deviceExtension); #endif IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return STATUS_NO_SUCH_DEVICE; } // Register device interfaces ntStatus = IoRegisterDeviceInterface(deviceExtension->PhysicalDeviceObject, &GUID_CLASS_FREEBT_USB, NULL, &deviceExtension->InterfaceName); if (!NT_SUCCESS(ntStatus)) { #ifdef ENABLE_WMI FreeBT_WmiDeRegistration(deviceExtension); #endif IoDetachDevice(deviceExtension->TopOfStackDeviceObject); IoDeleteDevice(deviceObject); IoDeleteSymbolicLink(&uniDosDeviceName); return ntStatus; } if (IoIsWdmVersionAvailable(1, 0x20)) { deviceExtension->WdmVersion = WinXpOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x10)) { deviceExtension->WdmVersion = Win2kOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x5)) { deviceExtension->WdmVersion = WinMeOrBetter; } else if (IoIsWdmVersionAvailable(1, 0x0)) { deviceExtension->WdmVersion = Win98OrBetter; } deviceExtension->SSRegistryEnable = 0; deviceExtension->SSEnable = 0; // WinXP only: check the registry flag indicating whether // the device should selectively suspend when idle if (WinXpOrBetter == deviceExtension->WdmVersion) { FreeBT_GetRegistryDword(FREEBT_REGISTRY_PARAMETERS_PATH, L"BulkUsbEnable", (PULONG)(&deviceExtension->SSRegistryEnable)); if (deviceExtension->SSRegistryEnable) { // initialize DPC KeInitializeDpc(&deviceExtension->DeferredProcCall, DpcRoutine, deviceObject); // initialize the timer. // the DPC and the timer in conjunction, // monitor the state of the device to // selectively suspend the device. KeInitializeTimerEx(&deviceExtension->Timer, NotificationTimer); // Initialize the NoDpcWorkItemPendingEvent to signaled state. // This event is cleared when a Dpc is fired and signaled // on completion of the work-item. KeInitializeEvent(&deviceExtension->NoDpcWorkItemPendingEvent, NotificationEvent, TRUE); // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. KeInitializeEvent(&deviceExtension->NoIdleReqPendEvent, NotificationEvent, TRUE); } } // Initialize the NoIdleReqPendEvent to ensure that the idle request // is indeed complete before we unload the drivers. KeInitializeEvent(&deviceExtension->DelayEvent, NotificationEvent, FALSE); // Clear the DO_DEVICE_INITIALIZING flag. // Note: Do not clear this flag until the driver has set the // device power state and the power DO flags. deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; InterlockedIncrement(&instanceNumber); FreeBT_DbgPrint(3, ("FBTUSB: FreeBT_AddDevice: Leaving\n")); return ntStatus; }
NTSTATUS 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; }
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; }
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; }
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; }
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; }
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; }