📄 charsample.c
字号:
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
CharSampleDebugPrint(DBG_CREATECLOSE, DBG_WARN, __FUNCTION__"$$--. IRP %p, STATUS %x", Irp, status);
return status;
}
// increment open count
InterlockedIncrement(&deviceExtension->OpenHandleCount);
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
CharSampleReleaseRemoveLock(deviceExtension);
CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleCloseDispatch
// Dispatch routine for IRP_MJ_CLOSE requests.
//
// Arguments:
// IN DeviceObject
// pointer to the device object for our device
//
// IN Irp
// the close IRP
//
// Return Value:
// NT status code.
//
NTSTATUS CharSampleCloseDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PCHARSAMPLE_DEVICE_EXTENSION deviceExtension;
NTSTATUS status;
CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);
deviceExtension = (PCHARSAMPLE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
InterlockedDecrement(&deviceExtension->OpenHandleCount);
CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleUnload
// Driver Unload routine.
//
// Arguments:
// IN DriverObject
// pointer to the driver object
//
// Return Value:
// none
//
VOID CharSampleUnload(
IN PDRIVER_OBJECT DriverObject
)
{
CharSampleDebugPrint(DBG_UNLOAD, DBG_TRACE, __FUNCTION__"++");
// The device object(s) should be NULL now
// (since we unload, all the devices objects associated with this
// driver must be deleted.
ASSERT(DriverObject->DeviceObject == NULL);
// We should not be unloaded until all the devices we control
// have been removed from our queue.
// release memory block allocated for registry path
if (g_Data.RegistryPath.Buffer != NULL)
{
ExFreePool(g_Data.RegistryPath.Buffer);
g_Data.RegistryPath.Buffer = NULL;
}
CharSampleDebugPrint(DBG_UNLOAD, DBG_TRACE, __FUNCTION__"--");
#ifdef CHARSAMPLE_WMI_TRACE
WPP_CLEANUP(DriverObject);
#endif
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleIsStoppable
// This routine determines whether the device can be safely stopped.
// In our particular case, we'll assume we can always stop the device.
// A device might fail the request if it doesn't have a queue for the
// requests that might come or if it was notified that it is in the
// paging path.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// returns TRUE if the device is stoppable, FALSE otherwise
//
BOOLEAN CharSampleIsStoppable(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleIsRemovable
// This routine determines whether the device can be safely removed.
// A device shouldn't be removed if, for example, it has open handles or
// removing the device could result in losing data (plus the reasons
// mentioned in the CharSampleIsStoppable function comments). The PnP manager on
// Windows 2000 fails on its own any attempt to remove, if there any
// open handles to the device. However on Win9x, the driver must keep
// count of open handles and fail QueryRemove if there are any open
// handles.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// returns TRUE if the device is stoppable, FALSE otherwise
//
BOOLEAN CharSampleIsRemovable(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleSubmitIrpSyncComplete
// Completion routine for sync IRP requests.
//
// Arguments:
// IN DeviceObject
// pointer to our device object
//
// IN Irp
// pointer to the PnP IRP
//
// IN Context
// our event used to signal IRP completion
//
// Return Value:
// STATUS_MORE_PROCESSING_REQUIRED
//
NTSTATUS CharSampleSubmitIrpSyncComplete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PKEVENT event = (PKEVENT)Context;
// If the lower driver didn't return STATUS_PENDING, we don't need to
// set the event because we won't be waiting on it.
if (Irp->PendingReturned)
{
KeSetEvent(event, IO_NO_INCREMENT, FALSE);
}
return STATUS_MORE_PROCESSING_REQUIRED;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleSubmitIrpSync
// Sends the given IRP down the stack to the next lower driver and
// waits in a synchronous fashion for the IRP to complete
//
// Arguments:
// IN DeviceObject
// Pointer to device object for our device
//
// IN Irp
// IRP to send down
//
// Return Value:
// NT status code
//
NTSTATUS CharSampleSubmitIrpSync(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
KEVENT event;
NTSTATUS status;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(
Irp,
CharSampleSubmitIrpSyncComplete,
&event,
TRUE,
TRUE,
TRUE
);
status = IoCallDriver(DeviceObject, Irp);
// Wait for lower drivers to be done with the Irp.
// Important thing to note here is when you allocate
// memory for an event in the stack you must do a
// KernelMode wait instead of UserMode to prevent
// the stack from getting paged out.
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(
&event,
Executive,
KernelMode,
FALSE,
NULL
);
status = Irp->IoStatus.Status;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleAcquireRemoveLock
// Acquires remove lock.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// FALSE if remove device pending, TRUE otherwise.
//
BOOLEAN CharSampleAcquireRemoveLock(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
LONG count;
count = InterlockedIncrement(&DeviceExtension->RemoveCount);
ASSERT(count > 0);
if (DeviceExtension->PnpState == PnpStateRemoved)
{
CharSampleReleaseRemoveLock(DeviceExtension);
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleReleaseRemoveLock
// Releases remove lock.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// None.
//
VOID CharSampleReleaseRemoveLock(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
LONG count;
count = InterlockedDecrement(&DeviceExtension->RemoveCount);
ASSERT(count >= 0);
if (count == 0)
{
KeSetEvent(&DeviceExtension->RemoveEvent, IO_NO_INCREMENT, FALSE);
}
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleWaitForSafeRemove
// Waits for all remove locks to be released
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// None.
//
// Comment:
// This routine should be called with no remove locks held
// by the calling thread
//
VOID CharSampleWaitForSafeRemove(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
DeviceExtension->PnpState = PnpStateRemoved;
CharSampleReleaseRemoveLock(DeviceExtension);
KeWaitForSingleObject(
&DeviceExtension->RemoveEvent,
Executive,
KernelMode,
FALSE,
NULL
);
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleStallQueues
// Pauses all of the queues, and waits for them to get to paused state.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// none
//
VOID CharSampleStallQueues(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
ULONG index;
CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++");
// stall IRP processing
CharSampleLockIo(&DeviceExtension->IoLock);
CharSampleWaitForStopIo(&DeviceExtension->IoLock);
CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleRestartQueues
// Restarts all paused queues.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// none
//
VOID CharSampleRestartQueues(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
ULONG index;
CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++");
CharSampleUnlockIo(&DeviceExtension->IoLock);
CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");
return;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleFlushQueues
// Flush oustanding IRPs for closed file object.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// IN FileObject
// about to be closed file object
//
// Return Value:
// none
//
VOID CharSampleFlushQueues(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension,
IN PFILE_OBJECT FileObject
)
{
ULONG index;
CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++");
CharSampleFlushPendingIo(&DeviceExtension->IoLock, FileObject);
CharSampleDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--");
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -