Hi all.
I develop file system filter driver, legacy model.
There is control object, and it has CSQ to manage control IRPs from my app.
It seems that all works fine, but I get BSOD when trying to unload driver (via SC).
I need unloadable driver mainly for testing and developing, but I cant be sure driver is generally OK until it gives such BSODs.
I have removed any usage of CSQ, and now driver is just like a sample with control object, but with initializing of CSQ in DriverEntry. It still gives BSOD with this on unload, and without initializing of CSQ all works fine.
May be driver with CSQ could not be unloadable at all?
*****************************************************
NTSTATUS DriverEntry(
__inout PDRIVER_OBJECT DriverObject,
__in PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = STATUS_SUCCESS;
ULONG i = 0;
//ASSERT(FALSE); // This will break to debugger
// Store our driver object.
g_fsFilterDriverObject = DriverObject;
// Initialize the driver object dispatch table.
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
DriverObject->MajorFunction[i] = FsFilterDispatchPassThrough;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsFilterDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FsFilterDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsFilterDispatchClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsFilterDispatchCleanup;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsFilterDispatchFileSystemControl;
// Set fast-io dispatch table.
DriverObject->FastIoDispatch = &g_fastIoDispatch;
// Registered callback routine for file system changes.
status = IoRegisterFsRegistrationChange(DriverObject, FsFilterNotificationCallback);
if (!NT_SUCCESS(status))
{
return status;
}
// Set driver unload routine (debug purpose only).
DriverObject->DriverUnload = FsFilterUnload;
// Create control object
FilterCreateControlObject(DriverObject);
return STATUS_SUCCESS;
}
***********************************************
NTSTATUS FilterCreateControlObject(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING ntDeviceName;
UNICODE_STRING symbolicLinkName;
PDEVICE_EXTENSION devExtension;
NTSTATUS status, status1;
// Initialize the unicode strings
RtlInitUnicodeString(&ntDeviceName, NTDEVICE_NAME_STRING);
RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING);
// Create a named deviceobject so that applications or drivers
// can directly talk to us without going throuhg the entire stack.
// This call could fail if there are not enough resources or
// another deviceobject of same name exists (name collision).
status = IoCreateDevice(DriverObject,
sizeof(PDEVICE_EXTENSION),
&ntDeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&ControlDeviceObject);
DbgPrint(“Creating IoCreateDevice \n”);
if (NT_SUCCESS( status ))
{
ControlDeviceObject->Flags |= DO_BUFFERED_IO;
status = IoCreateSymbolicLink( &symbolicLinkName, &ntDeviceName );
if ( !NT_SUCCESS( status ))
{
IoDeleteDevice(ControlDeviceObject);
DbgPrint(“IoCreateSymbolicLink failed \n”);
return status;
}
devExtension = ControlDeviceObject->DeviceExtension;
ControlDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
KeInitializeSpinLock(&devExtension->QueueLock);
InitializeListHead(&devExtension->PendingIrpQueue);
status1 = IoCsqInitializeEx(&devExtension->CancelSafeQueue,
CsampInsertIrp,
CsampRemoveIrp,
CsampPeekNextIrp,
CsampAcquireLock,
CsampReleaseLock,
CsampCompleteCanceledIrp);
if ( !NT_SUCCESS( status1 ))
{
IoDeleteDevice(ControlDeviceObject);
DbgPrint(“Initializing CSQ failed!\n”);
return status;
}
}
else
{
DbgPrint(“IoCreateDevice failed \n”);
}
return status;
}
**************************************************