Yeah, I’d say that a corrupt stack sure looks likely:
ed8a5d44 805b1ce3 00000094 00000001 00000000 nt!string'+0x13 ed8a5d58 8053d648 00000094 0012f710 7c90e514 nt!
string’+0xb
mm
Yeah, I’d say that a corrupt stack sure looks likely:
ed8a5d44 805b1ce3 00000094 00000001 00000000 nt!string'+0x13 ed8a5d58 8053d648 00000094 0012f710 7c90e514 nt!
string’+0xb
mm
+1
[quote]
ed8a5ca4 805b21e0 863cc020 85c7d280 0012019f nt!CcLazyWriteScan+0x398
ed8a5cd4 805b1b0d 863cc020 00000001 867e9040 nt!pIoQueryBusDescription+0xda
[quote]
I’m thinking that a query bus description function doesn’t belong on your stack at all, and even if it does, I bet it doesn’t call anything in the cache manager.
Peter
OSR
Ok, I realised a problem with my MemDrvCleanup function, where I was using &devExt and I actually wanted to be using my edo extension. It hasn’t changed much though…
Here’s a bit of theory check: If my win app mallocs some memory, and passes that to my driver (the edo) with an IOCTL as follows:
DeviceIoControl(hMyDevice, IOCTL_MYIOCTL, NULL, 0, m_Buffer, m_BufSize, &junk, &DeviceIoOverlapped);
…where m_Buffer is the malloc’d memory. In my DeviceControl routine in the driver, I simply use:
switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_MYIOCTL:
…
if (Irp->MdlAddress != NULL)
{
mdl = Irp->MdlAddress;
//Get buffer address and length
buffLoc = (PCCHAR)MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
buffLen = MmGetMdlByteCount(Irp->MdlAddress);
…
IoSetCancelRoutine(Irp,CancelMemRoutine);
IoMarkIrpPending(Irp);
return STATUS_PENDING;
}
…
Do I actually NEED to have a MemDrvCleanup routine? As technically, all the memory management responsibilities lie with the win app that allocated the memory in the first place…?
Do I also need to worry about marking the IRP as pending? I only did this for my CancelMemRoutine, in order to perform some cleanup in the driver after the win app had exited.
Thanks,
Ben
To enable driver verifier, just open a command line windows and type
“verifier”. Verifier windows will show up. Then you can select custom
setting.
On Mon, Sep 21, 2009 at 11:41 AM, <ben.simpson> wrote:
> Michael, can you explain how to enable driver verifier, and ‘Special pool’
> etc, I’m not sure how to go about doing that.
>
> My code from MemDrvCleanup is as follows (as I said, exactly as-is from
> OSR’s example…)
>
> NTSTATUS MemDrvCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
> {
> PIO_STACK_LOCATION ioStackLocation;
> PDEVICE_EXTENSION devExt =
> (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
> PMEM_USER_ENTRY pEntry = NULL;
> NTSTATUS status = STATUS_SUCCESS;
>
> ioStackLocation = IoGetCurrentIrpStackLocation(Irp);
>
> //
> // Gain access to the MemUserList…
> //
> ExAcquireFastMutex(&devExt->MemUserListMutex);
>
> //
> // Check to see if there are any entries on the list…
> //
> if(!IsListEmpty(&devExt->MemUserList)) {
>
> //
> // Go thru the list and remove the entry whose file object matches
> the one contained in the
> // cleanup IRP.
> //
> PLIST_ENTRY pLentry;
> for(pLentry = devExt->MemUserList.Flink; pLentry !=
> &devExt->MemUserList; pLentry = pLentry->Flink) {
> pEntry = (PMEM_USER_ENTRY) pLentry;
> if(pEntry->FileObject == ioStackLocation->FileObject) {
> //
> // We have found a match, remove it from the list, unmap,
> free the memory, and then
> // deallocate the ENTRY from the list. We’re good after
> this…
> //
> RemoveEntryList(&pEntry->ListEntry);
> UnMapAndFreeMemory(pEntry->PMdl,pEntry->UserVaToReturn);
> ExFreePool(pEntry);
> break;
> }
> }
> }
>
> //
> // Release access to the list.
> //
> ExReleaseFastMutex(&devExt->MemUserListMutex);
>
> //
> // Gain access to the IRP queue…
> //
> ExAcquireFastMutex(&devExt->IrpQueueMutex);
>
> //
> // See if there are any hanging IOCTL_OSR_SETSHAREMEM Irps.
> //
>
> if(!IsListEmpty(&devExt->IrpQueue)) {
>
> //
> // The list is not empty… Go through the list looking for an entry
> with a File Object that
> // matches the one contained in the cleanup IRP.
> //
> PLIST_ENTRY pLentry;
> for(pLentry = devExt->IrpQueue.Flink; pLentry != &devExt->IrpQueue;
> pLentry = pLentry->Flink) {
> pEntry = (PMEM_USER_ENTRY) pLentry;
> if(pEntry->FileObject == ioStackLocation->FileObject) {
> //
> // We found a match, remove the entry from the list,
> // clear the cancel routine,
> // Set the status of the hung irp to cancel and complete
> // it. We’re done with this list…
> //
> RemoveEntryList(&pEntry->ListEntry);
> IoSetCancelRoutine(pEntry->Irp,NULL);
> pEntry->Irp->IoStatus.Status = STATUS_SUCCESS;
> pEntry->Irp->IoStatus.Information = 0;
> IoCompleteRequest(pEntry->Irp,IO_NO_INCREMENT);
> ExFreePool(pEntry);
> break;
> }
> }
> }
>
> //
> // Release access to the Irp Queue.
> //
> ExReleaseFastMutex(&devExt->IrpQueueMutex);
>
> Irp->IoStatus.Status = STATUS_SUCCESS;
> Irp->IoStatus.Information = 0;
>
> IoCompleteRequest(Irp, IO_NO_INCREMENT);
>
> return(STATUS_SUCCESS);
> }
>
> Ben
>
> —
> NTDEV is sponsored by OSR
>
> 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
></ben.simpson>
This has a bug:
IoSetCancelRoutine(Irp,CancelMemRoutine);
IoMarkIrpPending(Irp);
As soon as you set the cancel routine you must guard against it running. It could be invoked immediately and complete the irp which means the call to IoMarkIrpPending will be touching freed memory. Instead, mark the irp before setting the cancel routine. Also, I don’t see a check to Irp->Cancel. Even better, just use an IoCSQ and all of this is taken care of for you.
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of ben.simpson@hp.com
Sent: Monday, September 21, 2009 10:01 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating an extra device object
Ok, I realised a problem with my MemDrvCleanup function, where I was using &devExt and I actually wanted to be using my edo extension. It hasn’t changed much though…
Here’s a bit of theory check: If my win app mallocs some memory, and passes that to my driver (the edo) with an IOCTL as follows:
DeviceIoControl(hMyDevice, IOCTL_MYIOCTL, NULL, 0, m_Buffer, m_BufSize, &junk, &DeviceIoOverlapped);
…where m_Buffer is the malloc’d memory. In my DeviceControl routine in the driver, I simply use:
switch (currentIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_MYIOCTL:
…
if (Irp->MdlAddress != NULL)
{
mdl = Irp->MdlAddress;
//Get buffer address and length
buffLoc = (PCCHAR)MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority);
buffLen = MmGetMdlByteCount(Irp->MdlAddress);
…
IoSetCancelRoutine(Irp,CancelMemRoutine);
IoMarkIrpPending(Irp);
return STATUS_PENDING;
}
…
Do I actually NEED to have a MemDrvCleanup routine? As technically, all the memory management responsibilities lie with the win app that allocated the memory in the first place…?
Do I also need to worry about marking the IRP as pending? I only did this for my CancelMemRoutine, in order to perform some cleanup in the driver after the win app had exited.
Thanks,
Ben
NTDEV is sponsored by OSR
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
I certainly hope that your cancel routine does not attempt to acquire IrpQueueMutex since it will be operating at IRQL == DISPATCH_LEVEL. You should really use an IoCSQ and a spin lock for your irp queue
d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of ben.simpson@hp.com
Sent: Monday, September 21, 2009 8:41 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Creating an extra device object
Michael, can you explain how to enable driver verifier, and ‘Special pool’ etc, I’m not sure how to go about doing that.
My code from MemDrvCleanup is as follows (as I said, exactly as-is from OSR’s example…)
NTSTATUS MemDrvCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_EXTENSION devExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
PMEM_USER_ENTRY pEntry = NULL;
NTSTATUS status = STATUS_SUCCESS;
ioStackLocation = IoGetCurrentIrpStackLocation(Irp);
//
// Gain access to the MemUserList…
//
ExAcquireFastMutex(&devExt->MemUserListMutex);
//
// Check to see if there are any entries on the list…
//
if(!IsListEmpty(&devExt->MemUserList)) {
//
// Go thru the list and remove the entry whose file object matches the one contained in the
// cleanup IRP.
//
PLIST_ENTRY pLentry;
for(pLentry = devExt->MemUserList.Flink; pLentry != &devExt->MemUserList; pLentry = pLentry->Flink) {
pEntry = (PMEM_USER_ENTRY) pLentry;
if(pEntry->FileObject == ioStackLocation->FileObject) {
//
// We have found a match, remove it from the list, unmap, free the memory, and then
// deallocate the ENTRY from the list. We’re good after this…
//
RemoveEntryList(&pEntry->ListEntry);
UnMapAndFreeMemory(pEntry->PMdl,pEntry->UserVaToReturn);
ExFreePool(pEntry);
break;
}
}
}
//
// Release access to the list.
//
ExReleaseFastMutex(&devExt->MemUserListMutex);
//
// Gain access to the IRP queue…
//
ExAcquireFastMutex(&devExt->IrpQueueMutex);
//
// See if there are any hanging IOCTL_OSR_SETSHAREMEM Irps.
//
if(!IsListEmpty(&devExt->IrpQueue)) {
//
// The list is not empty… Go through the list looking for an entry with a File Object that
// matches the one contained in the cleanup IRP.
//
PLIST_ENTRY pLentry;
for(pLentry = devExt->IrpQueue.Flink; pLentry != &devExt->IrpQueue; pLentry = pLentry->Flink) {
pEntry = (PMEM_USER_ENTRY) pLentry;
if(pEntry->FileObject == ioStackLocation->FileObject) {
//
// We found a match, remove the entry from the list,
// clear the cancel routine,
// Set the status of the hung irp to cancel and complete
// it. We’re done with this list…
//
RemoveEntryList(&pEntry->ListEntry);
IoSetCancelRoutine(pEntry->Irp,NULL);
pEntry->Irp->IoStatus.Status = STATUS_SUCCESS;
pEntry->Irp->IoStatus.Information = 0;
IoCompleteRequest(pEntry->Irp,IO_NO_INCREMENT);
ExFreePool(pEntry);
break;
}
}
}
//
// Release access to the Irp Queue.
//
ExReleaseFastMutex(&devExt->IrpQueueMutex);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
Ben
NTDEV is sponsored by OSR
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
Well, that was what I asked you in my first post.
If you’re allocating memory for, or mapping memory into, your application’s address space, you’re going to need to UNdo that in your cleanup handler. If you’re not doing this, then you don’t need to.
Please don’t take this the wrong way, Ben… but from your questions, it sorta seems like you’re in a bit over your head in this. Driver development really isn’t the sort of thing that you can chainsaw your way to doing, like you can with a C#.Net application, for example. Not to make it more than it is, but it really DOES require a more-or-less thorough understanding of what both your driver and the system are doing. I’m not saying I won’t help you here on the forum, but, fixing your driver one problem at a time like this could take a really long time. You sure you don’t wanna hire somebody or take a seminar or something??
It would help ME, at least, if you’d answer the questions I posed a few notes back:
Peter
OSR
Ok, I’ve implemented a cancel-safe queue and removed the code I had previously as Doron suggested. I’m using Walt Oney’s ‘Programming The WDM’ book as a resource for this, it seems far simpler than what I was trying to do, so thanks for the suggestion Doron.
Peter - You’re right, I am a little in over my head. I had this all working fine as a standard filter driver, I thought using the same code for an edo would work fine, but it appears not Apologies for not answering your questions earlier, but here goes. I want the driver to store data blocks in the buffer allocated by the win app, so yes, I am mapping the buffer when the app opens my edo. I wasn’t trying to achieve this straight away in the code I posted originally, but I am now trying to achieve this. Sorry for the confusion. As you saw from the code I posted above, when DeviceControl receives the IOCTL for the edo, it marks the IRP as pending and returns STATUS_PENDING. Now that I’ve introduced the CSQ, I’m simply marking the IRP as pending, calling IoCsqInsertIrp and then returning STATUS_PENDING. However, this causes another BSOD which windbg suggests is caused by my return STATUS_PENDING line. So, is there any other processing I need to do on the IRP before returning pending?
Thanks,
Ben