get BSOD

the incorrect code:

NTSTATUS
PCI_WRITE_LONG(PDEVICE_OBJECT device, ULONG offset, LONG data)
{
NTSTATUS status = STATUS_SUCCESS;
PIRP irp;
IO_STATUS_BLOCK ioStatusBlock;
PIO_STACK_LOCATION irpStack;
KEVENT event;
PDEVICE_OBJECT targetObject;

DebugPrint ((“[write]Device: %p, offset: 0x%.2x, data: 0x%.8x”, device, offset, data));

KeInitializeEvent( &event, NotificationEvent, FALSE );

targetObject = IoGetAttachedDeviceReference( device );

irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
targetObject,
NULL,
0,
NULL,
&event,
&ioStatusBlock );

if (irp == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
goto l_end;
}

irpStack = IoGetNextIrpStackLocation( irp );
irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
irpStack->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
irpStack->Parameters.ReadWriteConfig.Buffer = &data;
irpStack->Parameters.ReadWriteConfig.Offset = offset;
irpStack->Parameters.ReadWriteConfig.Length = sizeof(LONG);

//
// Initialize the status to error in case the bus driver does not
// set it correctly.
//

irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;

status = IoCallDriver( targetObject, irp );

if (status == STATUS_PENDING) {

KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
status = ioStatusBlock.Status;
}

l_end:
ObDereferenceObject( targetObject );
return status;
}

ExAcquireFastMutex (&deviceExtension->ListMutex);

for (pLink = deviceExtension->DeviceListHead.Flink;
pLink !=(PLIST_ENTRY) &deviceExtension->DeviceListHead;
pLink = pLink->Flink)
{
pList = CONTAINING_RECORD(pLink, DEVICE_INFO, ListEntry);
if (pList->Pdo == config->device) {
status = PCI_WRITE_LONG(config->device, config->offset, config->data);
}
}

ExReleaseFastMutex (&deviceExtension->ListMutex); <— BSOD, 0xc0000005, ListMutex is corrupt.

so, I fix it as follow, and it works fine

ExAcquireFastMutex (&deviceExtension->ListMutex);

for (pLink = deviceExtension->DeviceListHead.Flink;
pLink !=(PLIST_ENTRY) &deviceExtension->DeviceListHead;
pLink = pLink->Flink)
{
pList = CONTAINING_RECORD(pLink, DEVICE_INFO, ListEntry);
if (pList->Pdo == config->device) {
find = 1;
break;
}
}

ExReleaseFastMutex (&deviceExtension->ListMutex);

if (find) {
status = PCI_WRITE_LONG(config->device, config->offset, config->data);
} else {
status = STATUS_INVALID_PARAMETER;
}

but I don’t know why I get BSOD.

please tell me, thank you

Just read the documentation for fast mutexes on MSDN and you will see what
can go wrong.
Start from ExAcquirefastmutex page , see APCs,etc…
On Apr 18, 2015 5:35 PM, <pccq_2002> wrote:

> the incorrect code:
>
> NTSTATUS
> PCI_WRITE_LONG(PDEVICE_OBJECT device, ULONG offset, LONG data)
> {
> NTSTATUS status = STATUS_SUCCESS;
> PIRP irp;
> IO_STATUS_BLOCK ioStatusBlock;
> PIO_STACK_LOCATION irpStack;
> KEVENT event;
> PDEVICE_OBJECT targetObject;
>
> DebugPrint ((“[write]Device: %p, offset: 0x%.2x, data: 0x%.8x”,
> device, offset, data));
>
> KeInitializeEvent( &event, NotificationEvent, FALSE );
>
> targetObject = IoGetAttachedDeviceReference( device );
>
> irp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP,
> targetObject,
> NULL,
> 0,
> NULL,
> &event,
> &ioStatusBlock );
>
> if (irp == NULL) {
> status = STATUS_INSUFFICIENT_RESOURCES;
> goto l_end;
> }
>
> irpStack = IoGetNextIrpStackLocation( irp );
> irpStack->MinorFunction = IRP_MN_WRITE_CONFIG;
> irpStack->Parameters.ReadWriteConfig.WhichSpace =
> PCI_WHICHSPACE_CONFIG;
> irpStack->Parameters.ReadWriteConfig.Buffer = &data;
> irpStack->Parameters.ReadWriteConfig.Offset = offset;
> irpStack->Parameters.ReadWriteConfig.Length = sizeof(LONG);
>
> //
> // Initialize the status to error in case the bus driver does not
> // set it correctly.
> //
>
> irp->IoStatus.Status = STATUS_NOT_SUPPORTED ;
>
> status = IoCallDriver( targetObject, irp );
>
> if (status == STATUS_PENDING) {
>
> KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL
> );
> status = ioStatusBlock.Status;
> }
>
> l_end:
> ObDereferenceObject( targetObject );
> return status;
> }
>
> ExAcquireFastMutex (&deviceExtension->ListMutex);
>
> for (pLink = deviceExtension->DeviceListHead.Flink;
> pLink !=(PLIST_ENTRY) &deviceExtension->DeviceListHead;
> pLink = pLink->Flink)
> {
> pList = CONTAINING_RECORD(pLink, DEVICE_INFO, ListEntry);
> if (pList->Pdo == config->device) {
> status = PCI_WRITE_LONG(config->device,
> config->offset, config->data);
> }
> }
>
> ExReleaseFastMutex (&deviceExtension->ListMutex); <— BSOD, 0xc0000005,
> ListMutex is corrupt.
>
> so, I fix it as follow, and it works fine
>
> ExAcquireFastMutex (&deviceExtension->ListMutex);
>
> for (pLink = deviceExtension->DeviceListHead.Flink;
> pLink !=(PLIST_ENTRY) &deviceExtension->DeviceListHead;
> pLink = pLink->Flink)
> {
> pList = CONTAINING_RECORD(pLink, DEVICE_INFO, ListEntry);
> if (pList->Pdo == config->device) {
> find = 1;
> break;
> }
> }
>
> ExReleaseFastMutex (&deviceExtension->ListMutex);
>
> if (find) {
> status = PCI_WRITE_LONG(config->device, config->offset,
> config->data);
> } else {
> status = STATUS_INVALID_PARAMETER;
> }
>
> but I don’t know why I get BSOD.
>
> please tell me, thank you
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
></pccq_2002>

Thanks for your reply

It says that ExAcquireFastMutex sets the IRQL to APC_LEVEL, and the caller continues to run at APC_LEVEL after ExAcquireFastMutex returns.

but I want to know why can’t use KeWaitForSingleObject when acquire fast mutex