IODeleteDevice and my unload routine?

I am writing my first wdm driver and one thing confuses me. I call IodeleteDevice when I get a critical error from within DriverEntry and somehow this IODeleteDevice makes a call to my unload routine. (I use Softice to debug and set a breakpoint in my unload routine.). And from an example of Art Baker's book , " the Windows NT Device Driver Book",
the IoDeleteDevice gets called from the unload routine, will this create a recursive call between IoDeleteDevice and XXUnload? I guess not. But I don't know the relationship between them. Is the call to the unload routine because there is no more device connecting to the driver? Can
you give me an idea? Or where can I find the answer?
In my driver I need to do some cleaning job in the unload routine and I need reference from deviceExtension, but after Iodeletedevice, everything is gone and I get the blue screen.
Thanks
danli020797Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

tflaiCommented:
Does your DriverEntry() look something like this?

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
 
    PDEVICE_OBJECT deviceObject = NULL;
    NTSTATUS status;
    UNICODE_STRING uniNtNameString;
    UNICODE_STRING uniWin32NameString;
 
    KdPrint( ("LDUNLD: Entered the Load/Unload driver!\n") );
 
    //
    // Create counted string version of our device name.
    //
 
    RtlInitUnicodeString( &uniNtNameString, NT_DEVICE_NAME );
 
    //
    // Create the device object
    //
 
    status = IoCreateDevice(
                 DriverObject,
                 0,                     // We don't use a device extension
                 &uniNtNameString,
                 FILE_DEVICE_UNKNOWN,
                 0,                     // No standard device characteristics
                 FALSE,                 // This isn't an exclusive device
                 &deviceObject
                 );
 
    if ( NT_SUCCESS(status) )
    {
 
        //
        // Create dispatch points for create/open, close, unload.
        //
 
        DriverObject->MajorFunction[IRP_MJ_CREATE] = LdUnldOpen;
        DriverObject->MajorFunction[IRP_MJ_CLOSE] = LdUnldClose;
        DriverObject->DriverUnload = LdUnldUnload;
 
        KdPrint( ("LDUNLD: just about ready!\n") );
 
        //
        // Create counted string version of our Win32 device name.
        //
     
        RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
     
        //
        // Create a link from our device name to a name in the Win32 namespace.
        //
         
        status = IoCreateSymbolicLink( &uniWin32NameString, &uniNtNameString );
 
        if (!NT_SUCCESS(status))
        {
            KdPrint( ("LDUNLD: Couldn't create the symbolic link\n") );
 
            IoDeleteDevice( DriverObject->DeviceObject );
        }
        else
        {
            KdPrint( ("LDUNLD: All initialized!\n") );
        }
    }
    else
    {
        KdPrint( ("LDUNLD: Couldn't create the device\n") );
    }
    return status;
}

0
tflaiCommented:
If you hadn't successfully called IoCreateDevice(), you cannot call IoDeleteDevice().  Is that what you did?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
danli020797Author Commented:
My DriverEntry is almost same as yours. IOCreateDevice and IOCreateUnprotectedSymbolicLink are run successfully. Afterwards, I allocate memory for my device and I call the IODeleteDevice while I can't allocate the memory for whatever reason. The pointer to these memory will be stored in deviceExtension so I need the deviceExtension in my unload routine.
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

tflaiCommented:
Why don't you have a global context pointer instead of putting everything in the device object structure?  Something like a pMyDriverContext that pointing to a MY_DRIVER_CONTEXT created during DriverEntry().
0
danli020797Author Commented:
I know I can use a global pointer.
But what I need is more of the general understanding of the wdm driver. Such as, why a IODeleteDevice(..) call will invoke My_Unload(..) from DriverEntry and not from My_Unload(..)?
0
tflaiCommented:
On your previous question about why crashing:
A driver must release certain resources for which the driver supplied storage in its device extension before it calls IoDeleteDevice. For example, if the driver stores the pointer to its interrupt object(s) in the device extension, it must call IoDisconnectInterrupt before IoDeleteDevice.
When IoDeleteDevice is called, there cannot be any outstanding references to the device being deleted nor any attached devices. If there are, a system erorr occurs.
On you question about why:
What type of driver are you talking about?  If it's network, only NDIS will call your My_Unload(...).
0
tflaiCommented:
danli,
After some more looking up, I believe I was wrong about IoDeleteDevice().  It does not call the unload function.  Maybe you should try something like marshalling IRP to it with major function UNLOAD.  Let me know about your progress.  Thanks.
0
danli020797Author Commented:
I believe IoDeleteDevice() shouldn't call My_Unload(). But to verify that, I tested the sample program came with the WDMDDK beta3, under ..\src\wdm\sys\, I force the Drvshell_createobject() return an error(put ntStatus = STATUS_INSUFFICIENT_RESOURCES before return ntStatus). And I put a breakpoint in My_Unload(), I use SoftIce 3.2. After I executed the IoDeleteDevice(), the debugger jumped into My_Unload(). Strange, isn't it. Since I added more condition checking in My_Unload(), it wouldn't crash there. Maybe the SoftIce can not handle the debugging of new Window 98 WDM stuff yet. Also, returning an error from my driver's DriverEntry() shouldn't prevend the booting of the system, but it failed to boot whenever DriverEntry() returned an error. Do you think the value of the error has anything to do with this?
BTW, I heard that Fraser, Goldberg and Hanrahan had a book about NT driver, do you know if it's available?
Thanks
0
tflaiCommented:
Hmm...  You should talk to people at NuMega see if SoftIce 3.2 can handle WDM drivers.  I think it should though...

About failing DriverEntry:
"A DriverEntry routine that will fail initialization must free any NT objects, system resources, and registry resources it has already set up before it returns control. It should reset the driver's Dispatch entry points in the driver object for IRP_MJ_FLUSH_BUFFERS and/or IRP_MJ_SHUTDOWN to NULL if the driver supports these requests. If it already called IoRegisterShutdownNotification, the DriverEntry routine must call IoUnregisterShutdownNotification before it fails initialization.
If a driver will fail initialization, the DriverEntry routine also should log an error or have IoReportResourceUsage log a hardware resource conflict error on a device driver's behalf before DriverEntry returns control."

The book, it haven't came out the last time I checked.  You can go to AMAZON.COM to check for the latest availability.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.