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; }
//======================================================================================== // 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; }
VOID IoReleaseRemoveLockAndWait(PIO_REMOVE_LOCK lock, PVOID tag) { // PAGED_CODE(); lock->removing = TRUE; IoReleaseRemoveLock(lock, tag); IoReleaseRemoveLock(lock, NULL); KeWaitForSingleObject(&lock->evRemove, Executive, KernelMode, FALSE, NULL); }
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; }
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; }
//======================================================================================== // Function: CompletionRoutineStartDevice of DispatchPnp // Purpose: The completion routine for plug & play irps that needs to be // processed first by the lower drivers. // Return Value: // NT status code //======================================================================================== NTSTATUS CompletionRoutineStartDevice( IN PDEVICE_OBJECT fido, // fido - pointer to a device object. IN PIRP irp, // irp - pointer to an I/O Request Packet. IN PVOID Context // Context - pointer to an event object. ) { PDEVICE_EXTENSION dx; UNREFERENCED_PARAMETER(Context); dx = (PDEVICE_EXTENSION)fido->DeviceExtension; //Must do this if we don't return STATUS_MORE_PROCESSING_REQUIRED if (irp->PendingReturned) IoMarkIrpPending(irp); if (NT_SUCCESS(irp->IoStatus.Status)) { //As we are successfully now back, we will //first set our state to Started. SET_NEW_PNP_STATE(dx, Started); //On the way up inherit FILE_REMOVABLE_MEDIA during Start. //This characteristic is available only after the driver stack is started!. if (dx->lowerdo->Characteristics & FILE_REMOVABLE_MEDIA) { fido->Characteristics |= FILE_REMOVABLE_MEDIA; } } IoReleaseRemoveLock(&dx->rmLock, irp); return STATUS_SUCCESS; }
//======================================================================================== // Function: CompletionRoutineStartDevice of DispatchPnp // Purpose: PNP DEVICE USAGE NOTIFICATION irp completion routine // Return Value: // NT status code //======================================================================================== NTSTATUS CompletionRoutineDevUsgNotify( IN PDEVICE_OBJECT fido, // fido - pointer to a device object. IN PIRP irp, // irp - pointer to an I/O Request Packet. IN PVOID Context // Context - pointer to an event object. ) { PDEVICE_EXTENSION dx; UNREFERENCED_PARAMETER(Context); dx = (PDEVICE_EXTENSION)fido->DeviceExtension; if (irp->PendingReturned) IoMarkIrpPending(irp); //On the way up, pagable might become clear. Mimic the driver below us. if (!(dx->lowerdo->Flags & DO_POWER_PAGABLE)) { fido->Flags &= ~DO_POWER_PAGABLE; } IoReleaseRemoveLock(&dx->rmLock, irp); return STATUS_SUCCESS; }
//======================================================================================== // 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; }
//======================================================================================== // 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 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 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 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; } }
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; }
VOID OnCancelWrite(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension; CancelRequest( &pdx->dqWrite, Irp ); IoReleaseRemoveLock( &pdx->RemoveLock, Irp ); }
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; }
static NTSTATUS PdoSystemPower( IN PXENFILT_THREAD Self, IN PVOID Context ) { PXENFILT_PDO Pdo = Context; PKEVENT Event; Event = ThreadGetEvent(Self); for (;;) { PIRP Irp; PIO_STACK_LOCATION StackLocation; UCHAR MinorFunction; if (Pdo->SystemPowerIrp == NULL) { (VOID) KeWaitForSingleObject(Event, Executive, KernelMode, FALSE, NULL); KeClearEvent(Event); } if (ThreadIsAlerted(Self)) break; Irp = Pdo->SystemPowerIrp; if (Irp == NULL) continue; Pdo->SystemPowerIrp = NULL; KeMemoryBarrier(); StackLocation = IoGetCurrentIrpStackLocation(Irp); MinorFunction = StackLocation->MinorFunction; switch (StackLocation->MinorFunction) { case IRP_MN_SET_POWER: (VOID) __PdoSetSystemPower(Pdo, Irp); break; case IRP_MN_QUERY_POWER: (VOID) __PdoQuerySystemPower(Pdo, Irp); break; default: ASSERT(FALSE); break; } IoReleaseRemoveLock(&Pdo->Dx->RemoveLock, Irp); } return STATUS_SUCCESS; }
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; }
NTSTATUS dc_forward_irp(dev_hook *hook, PIRP irp) { NTSTATUS status; IoSkipCurrentIrpStackLocation(irp); status = IoCallDriver(hook->orig_dev, irp); IoReleaseRemoveLock(&hook->remv_lock, irp); return status; }
NTSTATUS UsageNotificationCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx) { // UsageNotificationCompletionRoutine if (Irp->PendingReturned) IoMarkIrpPending(Irp); // If lower driver cleared pageable flag, we must do the same if (!(pdx->LowerDeviceObject->Flags & DO_POWER_PAGABLE)) fido->Flags &= ~DO_POWER_PAGABLE; IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return STATUS_SUCCESS; } // UsageNotificationCompletionRoutine
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 NTSTATUS OnDeviceUsageNotificationCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP Irp, VolumeFilterExtension *Extension) { if (Irp->PendingReturned) IoMarkIrpPending (Irp); if (!(Extension->LowerDeviceObject->Flags & DO_POWER_PAGABLE)) filterDeviceObject->Flags &= ~DO_POWER_PAGABLE; IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return STATUS_CONTINUE_COMPLETION; }
static NTSTATUS OnStartDeviceCompleted (PDEVICE_OBJECT filterDeviceObject, PIRP Irp, VolumeFilterExtension *Extension) { if (Irp->PendingReturned) IoMarkIrpPending (Irp); if (Extension->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) filterDeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA; IoReleaseRemoveLock (&Extension->Queue.RemoveLock, Irp); return STATUS_CONTINUE_COMPLETION; }
NTSTATUS StartDeviceCompletionRoutine(PDEVICE_OBJECT fido, PIRP Irp, PDEVICE_EXTENSION pdx) { // StartDeviceCompletionRoutine if (Irp->PendingReturned) IoMarkIrpPending(Irp); // Inherit FILE_REMOVABLE_MEDIA flag from lower object. This is necessary // for a disk filter, but it isn't available until start-device time. Drivers // above us may examine the flag as part of their own start-device processing, too. if (pdx->LowerDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) fido->Characteristics |= FILE_REMOVABLE_MEDIA; IoReleaseRemoveLock(&pdx->RemoveLock, Irp); return STATUS_SUCCESS; } // StartDeviceCompletionRoutine
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; }
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; }
static NTSTATUS dc_process_power_irp(dev_hook *hook, PIRP irp) { NTSTATUS status; PIO_STACK_LOCATION irp_sp; int no_pass = 0; irp_sp = IoGetCurrentIrpStackLocation(irp); if ( (irp_sp->MinorFunction == IRP_MN_SET_POWER) && (irp_sp->Parameters.Power.Type == SystemPowerState) ) { wait_object_infinity(&hook->busy_lock); if (irp_sp->Parameters.Power.State.SystemState == PowerSystemHibernate) { /* prevent device encryption to sync device and memory state */ hook->flags |= F_PREVENT_ENC; dc_send_sync_packet(hook->dev_name, S_OP_SYNC, 0); } if (irp_sp->Parameters.Power.State.SystemState == PowerSystemWorking) { /* allow encryption requests */ hook->flags &= ~F_PREVENT_ENC; } KeReleaseMutex(&hook->busy_lock, FALSE); } if ( (irp_sp->MinorFunction == IRP_MN_QUERY_POWER) && (irp_sp->Parameters.Power.Type == SystemPowerState) && (irp_sp->Parameters.Power.State.SystemState == PowerSystemHibernate) ) { if ( (dc_is_vista_or_later == 0) && (dump_is_pverent_hibernate() != 0) ) { PoStartNextPowerIrp(irp); status = dc_complete_irp(irp, STATUS_UNSUCCESSFUL, 0); no_pass = 1; } } if (no_pass == 0) { PoStartNextPowerIrp(irp); IoSkipCurrentIrpStackLocation(irp); status = PoCallDriver(hook->orig_dev, irp); } IoReleaseRemoveLock(&hook->remv_lock, irp); return status; }
VOID CleanupReads( PDEVICE_EXTENSION pdx, PFILE_OBJECT pfo, NTSTATUS status ) { PIO_STACK_LOCATION ReadStack; PLIST_ENTRY head, next, current; LIST_ENTRY CancelList; PIRP ReadIrp; KIRQL OldIrql; // manually cancel all pending reads that match this file handle InitializeListHead( &CancelList ); KeAcquireSpinLock (&pdx->ReadIrpLock, &OldIrql ); head = &pdx->ReadIrpList; for( next=head->Flink; next != head; ) { ReadIrp = CONTAINING_RECORD( next, IRP, Tail.Overlay.ListEntry ); ReadStack = IoGetCurrentIrpStackLocation( ReadIrp ); // advance next pointer now, as we want to muck with it current = next; next = next->Flink; // skip IRPs that do not match // if pfo == NULL, then don't skip anything if(pfo && pfo != ReadStack->FileObject ) { KdPrint((DRIVERNAME " - Skipping IRP, it belongs to a different handle\n")); continue; } // add it to the cancel list RemoveEntryList( current ); InsertTailList ( &CancelList, current ); } KeReleaseSpinLock( &pdx->ReadIrpLock, OldIrql ); // now complete the IRPs we cancelled while (!IsListEmpty(&CancelList)) { next = RemoveHeadList( &CancelList ); ReadIrp = CONTAINING_RECORD(next, IRP, Tail.Overlay.ListEntry); IoSetCancelRoutine ( ReadIrp, NULL ); IoReleaseRemoveLock( &pdx->RemoveLock, ReadIrp ); CompleteRequest ( ReadIrp, status, 0 ); } }
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 FilterDeviceUsageNotificationCompletionRoutine( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) /*++ Routine Description: A completion routine for use when calling the lower device objects to which our filter deviceobject is attached. Arguments: DeviceObject - Pointer to deviceobject Irp - Pointer to a PnP Irp. Context - NULL Return Value: NT Status is returned. --*/ { PDEVICE_EXTENSION deviceExtension; UNREFERENCED_PARAMETER(Context); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; if (Irp->PendingReturned) { IoMarkIrpPending(Irp); } // // On the way up, pagable might become clear. Mimic the driver below us. // if (!(deviceExtension->NextLowerDriver->Flags & DO_POWER_PAGABLE)) { DeviceObject->Flags &= ~DO_POWER_PAGABLE; } IoReleaseRemoveLock(&deviceExtension->RemoveLock, Irp); return STATUS_CONTINUE_COMPLETION; }