Windows USB- |
for ( ULONG i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++ ) {
DriverObject->MajorFunction[i] = DispatchCommon;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DispatchCleanup;
DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = DispatchAddDevice;
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath );
NTSTATUS Dispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp );
NTSTATUS DispatchAddDevice(
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject
);
NTSTATUS UsbCreateAndAttachFilter(
PDEVICE_OBJECT PhysicalDeviceObject,
bool UpperFilter
) {
SUSBDevice* USBDevice;
PDEVICE_OBJECT USBDeviceObject = nullptr;
ULONG Flags;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
for ( ;; ) {
// ,
if ( !UpperFilter ) {
USBDeviceObject = PhysicalDeviceObject;
while ( USBDeviceObject->AttachedDevice ) {
if ( USBDeviceObject->DriverObject == g_DriverObject ) {
return STATUS_SUCCESS;
}
USBDeviceObject = USBDeviceObject->AttachedDevice;
}
}
//
Status = IoCreateDevice(
g_DriverObject,
sizeof( SUSBDevice ),
nullptr,
PhysicalDeviceObject->DeviceType,
PhysicalDeviceObject->Characteristics,
false,
&USBDeviceObject
);
if ( !NT_SUCCESS( Status ) ) {
break;
}
// ,
//
Flags = PhysicalDeviceObject->Flags &
(DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
USBDeviceObject->Flags |= Flags;
//
USBDevice = (SUSBDevice*)USBDeviceObject->DeviceExtension;
//
USBDevice->DeleteDevice = DetachAndDeleteDevice;
//
for ( ULONG i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++ ) {
USBDevice->MajorFunction[i] = UsbDispatchCommon;
}
USBDevice->MajorFunction[IRP_MJ_PNP] = UsbDispatchPnp;
USBDevice->MajorFunction[IRP_MJ_POWER] = UsbDispatchPower;
//
IoInitializeRemoveLock(
&USBDevice->Lock,
USBDEVICE_REMOVE_LOCK_TAG,
0,
0
);
//
USBDevice->SelfDevice = USBDeviceObject;
USBDevice->BaseDevice = PhysicalDeviceObject;
USBDevice->UpperFilter = UpperFilter;
// paging
USBDevice->PagingCount = 0;
KeInitializeEvent( &USBDevice->PagingLock, SynchronizationEvent, true );
// PDO
USBDevice->LowerDevice = IoAttachDeviceToDeviceStack(
USBDeviceObject,
PhysicalDeviceObject
);
if ( !USBDevice->LowerDevice ) {
Status = STATUS_NO_SUCH_DEVICE;
break;
}
break;
}
//
if ( !NT_SUCCESS( Status ) ) {
//
if ( USBDeviceObject ) {
IoDeleteDevice( USBDeviceObject );
}
} else {
//
USBDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
return Status;
}
static NTSTATUS DispatchAddDevice(
PDRIVER_OBJECT DriverObject,
PDEVICE_OBJECT PhysicalDeviceObject
) {
UNREFERENCED_PARAMETER( DriverObject );
return UsbCreateAndAttachFilter( PhysicalDeviceObject, true );
}
static NTSTATUS UsbDispatchPnpStartDevice( SUSBDevice* USBDevice, PIRP Irp ) {
bool HubOrComposite;
NTSTATUS Status;
PAGED_CODE();
for ( ;; ) {
// , ,
// ,
Status = UsbIsDeviceAllowedToWork( &HubOrComposite, USBDevice );
if ( !NT_SUCCESS( Status ) ) {
break;
}
USBDevice->HubOrComposite = HubOrComposite;
//
Status = ForwardIrpSynchronously( USBDevice->LowerDevice, Irp );
if ( !NT_SUCCESS( Status ) ) {
break;
}
break;
}
//
Irp->IoStatus.Status = Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
//
IoReleaseRemoveLock( &USBDevice->Lock, Irp );
return Status;
}