static DECLSPEC_NOINLINE NTSTATUS PdoDispatchDefault( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { NTSTATUS status; status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); if (!NT_SUCCESS(status)) goto fail1; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, __PdoDispatchDefault, Pdo, TRUE, TRUE, TRUE); status = IoCallDriver(Pdo->LowerDeviceObject, Irp); return status; fail1: Error("fail1 (%08x)\n", status); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
NTSTATUS VolumeFilterDispatchIrp (PDEVICE_OBJECT DeviceObject, PIRP Irp) { VolumeFilterExtension *Extension = (VolumeFilterExtension *) DeviceObject->DeviceExtension; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (Irp); NTSTATUS status; ASSERT (!Extension->bRootDevice && Extension->IsVolumeFilterDevice); switch (irpSp->MajorFunction) { case IRP_MJ_DEVICE_CONTROL: return DispatchControl (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_PNP: return DispatchPnp (DeviceObject, Irp, Extension, irpSp); case IRP_MJ_POWER: return DispatchPower (DeviceObject, Irp, Extension, irpSp); default: status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; } }
//======================================================================================== // Function: PassIRP // Purpose: Free all the allocated resources, etc. // Return Value: // NT status code //======================================================================================== NTSTATUS PassIRP( IN PDEVICE_OBJECT fido, IN PIRP irp // Irp - pointer to an I/O Request Packet. ) { PDEVICE_EXTENSION dx; NTSTATUS ntStatus; dx = (PDEVICE_EXTENSION)fido->DeviceExtension; // acquire remove lock ntStatus = IoAcquireRemoveLock(&dx->rmLock, irp); if (!NT_SUCCESS(ntStatus)) { //complete irp if cannot acquire remove lock irp->IoStatus.Status=ntStatus; irp->IoStatus.Information=0; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } IoSkipCurrentIrpStackLocation(irp); ntStatus = IoCallDriver(dx->lowerdo, irp); IoReleaseRemoveLock(&dx->rmLock, irp); return ntStatus; }
NTSTATUS DkDefault(PDEVICE_OBJECT pDevObj, PIRP pIrp) { NTSTATUS ntStat = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt = NULL; PIO_STACK_LOCATION pStack = NULL; PDEVICE_OBJECT pNextDevObj = NULL; pDevExt = (PDEVICE_EXTENSION) pDevObj->DeviceExtension; ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp); if (!NT_SUCCESS(ntStat)) { DkDbgVal("Error acquire lock!", ntStat); DkCompleteRequest(pIrp, ntStat, 0); return ntStat; } pStack = IoGetCurrentIrpStackLocation(pIrp); DkDbgVal("DkDefault", pStack->MajorFunction); pNextDevObj = pDevExt->pNextDevObj; IoSkipCurrentIrpStackLocation(pIrp); ntStat = IoCallDriver(pNextDevObj, pIrp); IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp); return ntStat; }
NTSTATUS YtFilterShutdownFlush( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; NTSTATUS status; if (KeGetCurrentIrql() <= DISPATCH_LEVEL) { status = IoAcquireRemoveLock(&deviceExtension->RemoveLock, Irp); if(!NT_SUCCESS(status)) { Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } } /* DebugPrint(("YtFilterShutdownFlush: DeviceObject %X Irp %X\n", DeviceObject, Irp));*/ //Set current stack back one. Irp->CurrentLocation++, Irp->Tail.Overlay.CurrentStackLocation++; status = IoCallDriver(deviceExtension->TargetDeviceObject, Irp); if (KeGetCurrentIrql() <= DISPATCH_LEVEL) IoReleaseRemoveLock(&deviceExtension->RemoveLock, NULL); return status; }
NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // KdPrint((DRIVERNAME " - Enter DispatchForSCSI \n")); PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp); // Pass request down without additional processing NTSTATUS status; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, USBSCSICompletion, NULL, TRUE, TRUE, TRUE ); status = IoCallDriver(pdx->LowerDeviceObject, Irp); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; }
static DECLSPEC_NOINLINE NTSTATUS PdoSurpriseRemoval( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { NTSTATUS status; status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); if (!NT_SUCCESS(status)) goto fail1; __PdoSetDevicePnpState(Pdo, SurpriseRemovePending); Irp->IoStatus.Status = STATUS_SUCCESS; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, __PdoSurpriseRemoval, Pdo, TRUE, TRUE, TRUE); status = IoCallDriver(Pdo->LowerDeviceObject, Irp); return status; fail1: Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
NTSTATUS DiskDeviceControlWithLock(__in PDEVICE_OBJECT DeviceObject, __in PIRP Irp) { PDokanDCB dcb; NTSTATUS status = STATUS_NOT_IMPLEMENTED; dcb = DeviceObject->DeviceExtension; if (GetIdentifierType(dcb) != DCB) { PrintIdType(dcb); DDbgPrint(" Device is not dcb so go out here\n"); return STATUS_INVALID_PARAMETER; } status = IoAcquireRemoveLock(&dcb->RemoveLock, Irp); if (!NT_SUCCESS(status)) { DDbgPrint("IoAcquireRemoveLock failed with %#x", status); return STATUS_INSUFFICIENT_RESOURCES; } if (IsDeletePending(DeviceObject)) { DDbgPrint("Device is deleted, so go out here \n"); IoReleaseRemoveLock(&dcb->RemoveLock, Irp); return STATUS_NO_SUCH_DEVICE; } status = DiskDeviceControl(DeviceObject, Irp); IoReleaseRemoveLock(&dcb->RemoveLock, Irp); return status; }
static NTSTATUS NTAPI V4vDispatchWmi(PDEVICE_OBJECT fdo, PIRP irp) { NTSTATUS status; PXENV4V_EXTENSION pde = V4vGetDeviceExtension(fdo); TraceVerbose(("====> '%s'.\n", __FUNCTION__)); // We don't support WMI, so just pass it on down the stack status = IoAcquireRemoveLock(&pde->removeLock, irp); if (!NT_SUCCESS(status)) { TraceError(("failed to acquire IO lock - error: 0x%x\n", status)); return V4vSimpleCompleteIrp(irp, status); } IoSkipCurrentIrpStackLocation(irp); status = IoCallDriver(pde->ldo, irp); IoReleaseRemoveLock(&pde->removeLock, irp); TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return status; }
NTSTATUS YtDispatchFilterPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; NTSTATUS status; if (KeGetCurrentIrql() <= DISPATCH_LEVEL) { status = IoAcquireRemoveLock(&deviceExtension->RemoveLock, Irp); if(!NT_SUCCESS(status)) { Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } } PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(deviceExtension->TargetDeviceObject, Irp); if (KeGetCurrentIrql() <= DISPATCH_LEVEL) IoReleaseRemoveLock(&deviceExtension->RemoveLock, NULL); return status; }
//======================================================================================== // Function: DispatchPower // Purpose: This routine is the dispatch routine for power irps. // Does nothing except forwarding the IRP to the next device in the stack. // Return Value: // NT status code //======================================================================================== NTSTATUS DispatchPower( IN PDEVICE_OBJECT fido, // fido - Pointer to the device object. IN PIRP irp // Irp - Pointer to the request packet. ) { PDEVICE_EXTENSION dx; NTSTATUS ntStatus; dx = (PDEVICE_EXTENSION)fido->DeviceExtension; PoStartNextPowerIrp(irp); //acquire remove lock ntStatus=IoAcquireRemoveLock(&dx->rmLock, irp); if (!NT_SUCCESS(ntStatus)) { //complete irp if cannot acquire remove lock irp->IoStatus.Status=ntStatus; irp->IoStatus.Information=0; IoCompleteRequest(irp, IO_NO_INCREMENT); return ntStatus; } IoSkipCurrentIrpStackLocation(irp); ntStatus = PoCallDriver(dx->lowerdo, irp); IoReleaseRemoveLock(&dx->rmLock, irp); return ntStatus; }
NTSTATUS EncryptedIoQueueAddIrp (EncryptedIoQueue *queue, PIRP irp) { NTSTATUS status; InterlockedIncrement (&queue->OutstandingIoCount); if (queue->StopPending) { Dump ("STATUS_DEVICE_NOT_READY out=%d\n", queue->OutstandingIoCount); status = STATUS_DEVICE_NOT_READY; goto err; } status = IoAcquireRemoveLock (&queue->RemoveLock, irp); if (!NT_SUCCESS (status)) goto err; #ifdef TC_TRACE_IO_QUEUE { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation (irp); Dump ("* %I64d [%I64d] %c len=%d out=%d\n", irpSp->MajorFunction == IRP_MJ_WRITE ? irpSp->Parameters.Write.ByteOffset : irpSp->Parameters.Read.ByteOffset, GetElapsedTime (&queue->LastPerformanceCounter), irpSp->MajorFunction == IRP_MJ_WRITE ? 'W' : 'R', irpSp->MajorFunction == IRP_MJ_WRITE ? irpSp->Parameters.Write.Length : irpSp->Parameters.Read.Length, queue->OutstandingIoCount); } #endif IoMarkIrpPending (irp); ExInterlockedInsertTailList (&queue->MainThreadQueue, &irp->Tail.Overlay.ListEntry, &queue->MainThreadQueueLock); KeSetEvent (&queue->MainThreadQueueNotEmptyEvent, IO_DISK_INCREMENT, FALSE); return STATUS_PENDING; err: DecrementOutstandingIoCount (queue); return status; }
//======================================================================================== // Function: DispatchControl // Purpose: This routine is the dispatch handler for the driver. It is responsible // for processing the IRPs. // Return Value: // STATUS_SUCCESS if the IRP was processed successfully, otherwise an error // indicating the reason for failure. //======================================================================================== NTSTATUS DispatchControl( IN PDEVICE_OBJECT pDO, // pDO - Pointer to device object. IN PIRP pIrp // pIrp - Pointer to the current IRP. ) { PDEVICE_EXTENSION dx; PIO_STACK_LOCATION pIrpStack; NTSTATUS Status; PAGED_CODE(); pIrp->IoStatus.Information = 0; dx = (PDEVICE_EXTENSION)pDO->DeviceExtension; // Get local info struct KdPrint(("--> "__FUNCTION__"()\n")); Status = IoAcquireRemoveLock (&dx->rmLock, NULL); if (!NT_SUCCESS (Status)) { pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = Status; IoCompleteRequest (pIrp, IO_NO_INCREMENT); KdPrint(("<-- "__FUNCTION__"() IoAcquireRemoveLock() Status code: 0x%08x\n", Status)); return Status; } if (dx->DevicePnPState != Started) { // // We fail all the IRPs that arrive before the device is started. // pIrp->IoStatus.Status = Status = STATUS_DEVICE_NOT_READY; IoCompleteRequest(pIrp, IO_NO_INCREMENT ); IoReleaseRemoveLock(&dx->rmLock, NULL); KdPrint(("<-- "__FUNCTION__"() - STATUS_DEVICE_NOT_READY\n")); return Status; } pIrpStack = IoGetCurrentIrpStackLocation(pIrp); pIrp->IoStatus.Information = DispatchIOCTL( pIrpStack->Parameters.DeviceIoControl.IoControlCode, (PUCHAR)pIrp->AssociatedIrp.SystemBuffer, pIrpStack->Parameters.DeviceIoControl.InputBufferLength, (PUCHAR)pIrp->AssociatedIrp.SystemBuffer, pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, &Status ); // We're done with I/O request. Record the status of the I/O action. pIrp->IoStatus.Status = Status; // Don't boost priority when returning since this took little time. IoCompleteRequest(pIrp, IO_NO_INCREMENT); IoReleaseRemoveLock(&dx->rmLock, NULL); KdPrint(("<-- "__FUNCTION__"() Completion Status code: 0x%08x\n", Status)); return Status; }
NTSTATUS SwdmDispatchWrite( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PVOID Buf; //Buffer provided by user program ULONG BufLen; //Buffer length for user provided buffer LONGLONG Offset;//Buffer Offset PVOID DataBuf; //Buffer provided by Driver ULONG DataLen; //Buffer length for Driver Data Buffer ULONG ByteTransferred; PIO_STACK_LOCATION pStk; PDEVICE_EXTENSION pCtx; //NTSTATUS status; DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MJ_WRITE : Begin\r\n"); //Get I/o Stack Location & Device Extension pStk = IoGetCurrentIrpStackLocation(Irp); pCtx = DeviceObject->DeviceExtension; //Get User Input Buffer & Length BufLen = pStk->Parameters.Write.Length; Offset = pStk->Parameters.Read.ByteOffset.QuadPart; Buf = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer) + Offset; //Get Driver Data Buffer & Length DataBuf = pCtx->DataBuffer; DataLen = 1024; IoAcquireRemoveLock(&pCtx->RemoveLock, Irp); DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Input Buffer Length : %d\r\n", BufLen); DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "Driver Data Length : %d\r\n", DataLen); if (BufLen <= DataLen) { ByteTransferred = BufLen; } else { ByteTransferred = DataLen; } ByteTransferred = BufLen; RtlZeroMemory( pCtx->DataBuffer, 1024); RtlCopyMemory( DataBuf, Buf, ByteTransferred); IoReleaseRemoveLock(&pCtx->RemoveLock, Irp); CompleteRequest(Irp, STATUS_SUCCESS, ByteTransferred); DbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "IRP_MJ_WRITE : End\r\n"); return STATUS_SUCCESS; }
NTSTATUS DispatchAny(IN PDEVICE_OBJECT fido, IN PIRP Irp) { // DispatchAny PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); #if DBG static char* irpname[] = { "IRP_MJ_CREATE", "IRP_MJ_CREATE_NAMED_PIPE", "IRP_MJ_CLOSE", "IRP_MJ_READ", "IRP_MJ_WRITE", "IRP_MJ_QUERY_INFORMATION", "IRP_MJ_SET_INFORMATION", "IRP_MJ_QUERY_EA", "IRP_MJ_SET_EA", "IRP_MJ_FLUSH_BUFFERS", "IRP_MJ_QUERY_VOLUME_INFORMATION", "IRP_MJ_SET_VOLUME_INFORMATION", "IRP_MJ_DIRECTORY_CONTROL", "IRP_MJ_FILE_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CONTROL", "IRP_MJ_INTERNAL_DEVICE_CONTROL", "IRP_MJ_SHUTDOWN", "IRP_MJ_LOCK_CONTROL", "IRP_MJ_CLEANUP", "IRP_MJ_CREATE_MAILSLOT", "IRP_MJ_QUERY_SECURITY", "IRP_MJ_SET_SECURITY", "IRP_MJ_POWER", "IRP_MJ_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CHANGE", "IRP_MJ_QUERY_QUOTA", "IRP_MJ_SET_QUOTA", "IRP_MJ_PNP", }; UCHAR type = stack->MajorFunction; // if (type >= arraysize(irpname)) // KdPrint((DRIVERNAME " - Unknown IRP, major type %X\n", type)); // else // KdPrint((DRIVERNAME " - %s\n", irpname[type])); #endif // Pass request down without additional processing NTSTATUS status; status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if (!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; } // DispatchAny
NTSTATUS DispatchInternalControl(PDEVICE_OBJECT fdo, PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; NTSTATUS status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp); if(!NT_SUCCESS(status)) return CompleteRequest(Irp, status, 0); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(pdx->LowerDeviceObject, Irp); IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return status; }
static DECLSPEC_NOINLINE NTSTATUS PdoQueryInterface( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PIO_STACK_LOCATION StackLocation; const GUID *InterfaceType; struct _INTERFACE_ENTRY *Entry; NTSTATUS status; status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); if (!NT_SUCCESS(status)) goto fail1; if (Irp->IoStatus.Status != STATUS_NOT_SUPPORTED) goto done; StackLocation = IoGetCurrentIrpStackLocation(Irp); InterfaceType = StackLocation->Parameters.QueryInterface.InterfaceType; for (Entry = PdoInterfaceTable; Entry->Guid != NULL; Entry++) { if (IsEqualGUID(InterfaceType, Entry->Guid)) { Trace("%s: %s\n", __PdoGetName(Pdo), Entry->Name); Irp->IoStatus.Status = Entry->Handler(Pdo, Irp); goto done; } } done: IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, __PdoQueryInterface, Pdo, TRUE, TRUE, TRUE); status = IoCallDriver(Pdo->LowerDeviceObject, Irp); return status; fail1: Error("fail1 (%08x)\n", status); Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
static DECLSPEC_NOINLINE NTSTATUS PdoRemoveDevice( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { PXENFILT_FDO Fdo = __PdoGetFdo(Pdo); POWER_STATE PowerState; NTSTATUS status; status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); if (!NT_SUCCESS(status)) goto fail1; if (__PdoGetDevicePowerState(Pdo) != PowerDeviceD0) goto done; __PdoSetDevicePowerState(Pdo, PowerDeviceD3); __PdoSetSystemPowerState(Pdo, PowerSystemShutdown); PowerState.DeviceState = PowerDeviceD3; PoSetPowerState(Pdo->Dx->DeviceObject, DevicePowerState, PowerState); done: if (__PdoIsMissing(Pdo)) { __PdoSetDevicePnpState(Pdo, Deleted); IoReleaseRemoveLockAndWait(&Pdo->Dx->RemoveLock, Irp); } else { __PdoSetDevicePnpState(Pdo, Enumerated); IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); } status = PdoForwardIrpSynchronously(Pdo, Irp); IoCompleteRequest(Irp, IO_NO_INCREMENT); if (__PdoIsMissing(Pdo)) { FdoAcquireMutex(Fdo); PdoDestroy(Pdo); FdoReleaseMutex(Fdo); } return status; fail1: Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
NTSTATUS FilterPass ( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++ Routine Description: The default dispatch routine. If this driver does not recognize the IRP, then it should send it down, unmodified. If the device holds iris, this IRP must be queued in the device extension No completion routine is required. For demonstrative purposes only, we will pass all the (non-PnP) Irps down on the stack (as we are a filter driver). A real driver might choose to service some of these Irps. As we have NO idea which function we are happily passing on, we can make NO assumptions about whether or not it will be called at raised IRQL. For this reason, this function must be in put into non-paged pool (aka the default location). Arguments: DeviceObject - pointer to a device object. Irp - pointer to an I/O Request Packet. Return Value: NT status code --*/ { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp); if (!NT_SUCCESS (status)) { Irp->IoStatus.Status = status; IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } IoSkipCurrentIrpStackLocation (Irp); status = IoCallDriver (deviceExtension->NextLowerDriver, Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; }
NTSTATUS VBoxDrvAddDevice(IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO) { NTSTATUS rc; PDEVICE_OBJECT pDO, pDOParent; PVBOXMOUSE_DEVEXT pDevExt; PAGED_CODE(); LOGF_ENTER(); rc = IoCreateDevice(Driver, sizeof(VBOXMOUSE_DEVEXT), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &pDO); if (!NT_SUCCESS(rc)) { WARN(("IoCreateDevice failed with %#x", rc)); return rc; } pDevExt = (PVBOXMOUSE_DEVEXT) pDO->DeviceExtension; RtlZeroMemory(pDevExt, sizeof(VBOXMOUSE_DEVEXT)); IoInitializeRemoveLock(&pDevExt->RemoveLock, VBOXUSB_RLTAG, 1, 100); rc = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt); if (!NT_SUCCESS(rc)) { WARN(("IoAcquireRemoveLock failed with %#x", rc)); IoDeleteDevice(pDO); return rc; } pDOParent = IoAttachDeviceToDeviceStack(pDO, PDO); if (!pDOParent) { IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt); WARN(("IoAttachDeviceToDeviceStack failed")); IoDeleteDevice(pDO); return STATUS_DEVICE_NOT_CONNECTED; } pDevExt->pdoMain = PDO; pDevExt->pdoSelf = pDO; pDevExt->pdoParent = pDOParent; VBoxDeviceAdded(pDevExt); pDO->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE); pDO->Flags &= ~DO_DEVICE_INITIALIZING; LOGF_LEAVE(); return rc; }
static NTSTATUS DispatchPower (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status; PoStartNextPowerIrp (Irp); status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); IoSkipCurrentIrpStackLocation (Irp); status = PoCallDriver (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return status; }
NTSTATUS DispatchReadWriteFlush(PDEVICE_OBJECT fdo, PIRP Irp) { KIRQL OldIrql; ULONG count; PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation( Irp ); if(stack->MajorFunction == IRP_MJ_WRITE) { if(stack->Parameters.Write.Length == 0) { return CompleteRequest( Irp, STATUS_SUCCESS, 0 ); } // write IoMarkIrpPending(Irp); StartPacket( &pdx->dqWrite, fdo, Irp, OnCancelWrite ); } else if(stack->MajorFunction == IRP_MJ_READ) { if(stack->Parameters.Read.Length == 0) { return CompleteRequest( Irp, STATUS_SUCCESS, 0 ); } // read IoAcquireRemoveLock( &pdx->RemoveLock, Irp ); IoMarkIrpPending ( Irp ); IoSetCancelRoutine ( Irp, OnCancelQueuedRead ); KeAcquireSpinLock( &pdx->ReadIrpLock, &OldIrql ); InsertTailList ( &pdx->ReadIrpList, &Irp->Tail.Overlay.ListEntry ); KeReleaseSpinLock( &pdx->ReadIrpLock, OldIrql ); CompleteQueuedReads(pdx); } else { // flush IoMarkIrpPending( Irp ); StartPacket ( &pdx->dqWrite, fdo, Irp, OnCancelWrite ); } return STATUS_PENDING; }
static DECLSPEC_NOINLINE NTSTATUS PdoStopDevice( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { POWER_STATE PowerState; NTSTATUS status; status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); if (!NT_SUCCESS(status)) goto fail1; if (__PdoGetDevicePowerState(Pdo) != PowerDeviceD0) goto done; __PdoSetDevicePowerState(Pdo, PowerDeviceD3); __PdoSetSystemPowerState(Pdo, PowerSystemShutdown); PowerState.DeviceState = PowerDeviceD3; PoSetPowerState(Pdo->Dx->DeviceObject, DevicePowerState, PowerState); done: __PdoSetDevicePnpState(Pdo, Stopped); Irp->IoStatus.Status = STATUS_SUCCESS; IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, __PdoStopDevice, Pdo, TRUE, TRUE, TRUE); status = IoCallDriver(Pdo->LowerDeviceObject, Irp); return status; fail1: Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
static NTSTATUS DispatchPnp (PDEVICE_OBJECT DeviceObject, PIRP Irp, VolumeFilterExtension *Extension, PIO_STACK_LOCATION irpSp) { NTSTATUS status; status = IoAcquireRemoveLock (&Extension->Queue.RemoveLock, Irp); if (!NT_SUCCESS (status)) return TCCompleteIrp (Irp, status, 0); switch (irpSp->MinorFunction) { case IRP_MN_START_DEVICE: Dump ("IRP_MN_START_DEVICE volume pdo=%p\n", Extension->Pdo); return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnStartDeviceCompleted, Extension); case IRP_MN_DEVICE_USAGE_NOTIFICATION: { PDEVICE_OBJECT attachedDevice = IoGetAttachedDeviceReference (DeviceObject); if (attachedDevice == DeviceObject || (attachedDevice->Flags & DO_POWER_PAGABLE)) DeviceObject->Flags |= DO_POWER_PAGABLE; ObDereferenceObject (attachedDevice); } return PassFilteredIrp (Extension->LowerDeviceObject, Irp, OnDeviceUsageNotificationCompleted, Extension); case IRP_MN_REMOVE_DEVICE: Dump ("IRP_MN_REMOVE_DEVICE volume pdo=%p\n", Extension->Pdo); IoReleaseRemoveLockAndWait (&Extension->Queue.RemoveLock, Irp); status = PassIrp (Extension->LowerDeviceObject, Irp); IoDetachDevice (Extension->LowerDeviceObject); IoDeleteDevice (DeviceObject); return status; default: status = PassIrp (Extension->LowerDeviceObject, Irp); IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); } return status; }
NTSTATUS Serenum_Power ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ --*/ { #if DBG PIO_STACK_LOCATION irpStack; #endif NTSTATUS status; PCOMMON_DEVICE_DATA commonData; commonData = (PCOMMON_DEVICE_DATA) DeviceObject->DeviceExtension; status=IoAcquireRemoveLock(&commonData->RemoveLock,Irp); if(!NT_SUCCESS(status)){ Irp->IoStatus.Information=0; Irp->IoStatus.Status=status; IoCompleteRequest(Irp,IO_NO_INCREMENT); // The Device Object has been removed //PoStartNextPowerIrp(Irp); return status; } #if DBG irpStack = IoGetCurrentIrpStackLocation (Irp); ASSERT (IRP_MJ_POWER == irpStack->MajorFunction); #endif if (commonData->IsFDO) { status = Serenum_FDO_Power ((PFDO_DEVICE_DATA) DeviceObject->DeviceExtension, Irp); } else { status = Serenum_PDO_Power ((PPDO_DEVICE_DATA) DeviceObject->DeviceExtension, Irp); } return status; }
static DECLSPEC_NOINLINE NTSTATUS PdoStartDevice( IN PXENFILT_PDO Pdo, IN PIRP Irp ) { POWER_STATE PowerState; NTSTATUS status; status = IoAcquireRemoveLock(&Pdo->Dx->RemoveLock, Irp); if (!NT_SUCCESS(status)) goto fail1; status = PdoForwardIrpSynchronously(Pdo, Irp); if (!NT_SUCCESS(status)) goto fail2; __PdoSetSystemPowerState(Pdo, PowerSystemWorking); __PdoSetDevicePowerState(Pdo, PowerDeviceD0); PowerState.DeviceState = PowerDeviceD0; PoSetPowerState(Pdo->Dx->DeviceObject, DevicePowerState, PowerState); __PdoSetDevicePnpState(Pdo, Started); IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; fail2: IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); fail1: Irp->IoStatus.Status = status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; }
VOID USBPcapDeleteRootHubControlDevice(IN PDEVICE_OBJECT controlDevice) { UNICODE_STRING symbolicLinkName; PWCHAR symbolicNameBuffer[MAX_SYMBOLIC_LEN]; USHORT id; PDEVICE_EXTENSION pDevExt; NTSTATUS status; pDevExt = ((PDEVICE_EXTENSION)controlDevice->DeviceExtension); ASSERT(pDevExt->deviceMagic == USBPCAP_MAGIC_CONTROL); id = pDevExt->context.control.id; symbolicLinkName.Length = 0; symbolicLinkName.MaximumLength = MAX_SYMBOLIC_LEN; symbolicLinkName.Buffer = (PWSTR)symbolicNameBuffer; status = RtlUnicodeStringPrintf(&symbolicLinkName, SYMBOLIC_PREFIX L"%hu", id); IoAcquireRemoveLock(&pDevExt->removeLock, NULL); IoReleaseRemoveLockAndWait(&pDevExt->removeLock, NULL); IoReleaseRemoveLock(pDevExt->parentRemoveLock, NULL); ASSERT(NT_SUCCESS(status)); if (NT_SUCCESS(status)) { IoDeleteSymbolicLink(&symbolicLinkName); IoDeleteDevice(controlDevice); } else { /* Very bad */ KdPrint(("Failed to init symbolic link name\n")); pDevExt->context.control.pRootHubObject = NULL; } }
NTSTATUS FilterDispatchPower( PDEVICE_OBJECT DeviceObject, PIRP Irp ) /*++ Routine Description: This routine is the dispatch routine for power irps. Arguments: DeviceObject - Pointer to the device object. Irp - Pointer to the request packet. Return Value: NT Status code --*/ { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp); if (!NT_SUCCESS (status)) { // may be device is being removed. Irp->IoStatus.Status = status; PoStartNextPowerIrp(Irp); IoCompleteRequest (Irp, IO_NO_INCREMENT); return status; } PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); status = PoCallDriver(deviceExtension->NextLowerDriver, Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return status; }
NTSTATUS SwdmDispatchCreate( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PIO_STACK_LOCATION pStk; PDEVICE_EXTENSION pCtx; NTSTATUS status; pStk = IoGetCurrentIrpStackLocation(Irp); pCtx = DeviceObject->DeviceExtension; status = IoAcquireRemoveLock(&pCtx->RemoveLock, pStk->FileObject); if (NT_SUCCESS(status)) { CompleteRequest(Irp, STATUS_SUCCESS, 0); return STATUS_SUCCESS; } else { IoReleaseRemoveLock(&pCtx->RemoveLock, pStk->FileObject); CompleteRequest(Irp, status, 0); return status; } }
NTSTATUS DkPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp) { NTSTATUS ntStat = STATUS_SUCCESS; PDEVICE_EXTENSION pDevExt = NULL; PIO_STACK_LOCATION pStack = NULL; pDevExt = (PDEVICE_EXTENSION) pDevObj->DeviceExtension; pStack = IoGetCurrentIrpStackLocation(pIrp); if (pDevExt->deviceMagic == USBPCAP_MAGIC_ROOTHUB) { return DkHubFltPnP(pDevExt, pStack, pIrp); } else if (pDevExt->deviceMagic == USBPCAP_MAGIC_DEVICE) { return DkTgtPnP(pDevExt, pStack, pIrp); } else { // Do nothing } ntStat = IoAcquireRemoveLock(&pDevExt->removeLock, (PVOID) pIrp); if (!NT_SUCCESS(ntStat)) { DkDbgVal("Error acquire lock!", ntStat); DkCompleteRequest(pIrp, ntStat, 0); return ntStat; } IoSkipCurrentIrpStackLocation(pIrp); ntStat = IoCallDriver(pDevExt->pNextDevObj, pIrp); IoReleaseRemoveLock(&pDevExt->removeLock, (PVOID) pIrp); return ntStat; }