hibernation related questions;

I 'm trying to copy hiberfile onto my own storage device (which is not the boot device). I’m planning to hook my driver hiber_MyDriver in the hiber stack but there are few questions I need answers for:

Q1. is it safe to assume that all the runtime drivers including my own run time driver for all the storage devices are still alive during hibernation? If I makes call to these driver’s functions from my hiber_MyDriver - is it OK?

Q2. I also do something during hibernation time with the device objects created during normal runtime by some driver in the storage stack - are these device objects still valid?

Q3. When does hiber_* drivers gets loaded in the system? Is it when the user clicks on “Hibernate” or is it immediately after boot time?

Q4. How can I make system not move my storage device (non boot device) to hibernate (shutdown) state before complete hiberfile is written? Is responding to IRP_MN_DEVICE_USAGE_NOTIFICATION with proper response enough? Can there be multiple device claiming that they can support hibernation file? Or only one device can claim that it has hiberfile? Does the associated run time drivers (not the hiber_*) of the device in the hiber path stay loaded untill the hibernation completes?

Thanks in anticipation.

  1. they will only be alive if you are directly importing from them via an IAT. If there is a “soft” link created at runtime, these other runtime drivers are not accessible. The hiber_yourdriver.sys is a completely different image with its own set of globals and state that are entirely separate from yourdriver.sys.

Why would you want to hook hiber_yourdriver? It is your driver, you can do whatever the heck you want with it

  1. nope, even if you could get the pointers, the device objects would be powered down and will not process io

  2. why does it matter? They exist before the machine goes into a hibernated state. Hint: the crash dump path uses the same drivers

  3. no drivers are unloaded during hiber, just the other hiber_xxx drivers are initialized and run. They run at DIRQL without interrupts or DPCs. One step to make this work you need to make sure your devobj does not set DO_POWER_PAGABLE and then when you get an Sx/Hibernate irp, you do not power down the device. Any other drivers you depend on (let’s say the usb core or an SD reader or the networking stack) have to be aware of this and also not power down. If they support usage notification/hibernate that should do it.

…but this all boils down to hibernation is not very well documented and getting it to work without explicit msft support is going to be very very hard for you. What are you really trying to do/enable?

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@yahoo.com
Sent: Wednesday, January 28, 2009 10:47 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] hibernation related questions;

I 'm trying to copy hiberfile onto my own storage device (which is not the boot device). I’m planning to hook my driver hiber_MyDriver in the hiber stack but there are few questions I need answers for:

Q1. is it safe to assume that all the runtime drivers including my own run time driver for all the storage devices are still alive during hibernation? If I makes call to these driver’s functions from my hiber_MyDriver - is it OK?

Q2. I also do something during hibernation time with the device objects created during normal runtime by some driver in the storage stack - are these device objects still valid?

Q3. When does hiber_* drivers gets loaded in the system? Is it when the user clicks on “Hibernate” or is it immediately after boot time?

Q4. How can I make system not move my storage device (non boot device) to hibernate (shutdown) state before complete hiberfile is written? Is responding to IRP_MN_DEVICE_USAGE_NOTIFICATION with proper response enough? Can there be multiple device claiming that they can support hibernation file? Or only one device can claim that it has hiberfile? Does the associated run time drivers (not the hiber_*) of the device in the hiber path stay loaded untill the hibernation completes?

Thanks in anticipation.


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

Thank you Doron for such detailed responses:

> Why would you want to hook hiber_yourdriver? It is your driver, you can do whatever the heck you want with it

Sorry I think I didn’t put it correctly. I want put my driver (hiber_mydriver) in the hiber stack.

So since the drivers are not getting unloaded, it means from my hiber_mydriver I can call the functions in the normal run time drivers (no io processing, just the function calls to do something like accessing deviceExtensions or making some kernel function calls)???

> why does it matter? They exist before the machine goes into a hibernated state.
I was just thinking that if DriverEntry of my hiber_myfilter gets loaded before other run time drivers gets unloaded I can get some private information from them before they stop processing io.

> Hint: the crash dump path uses the same drivers
I didn’t get much from this hint as I think copies are different - dump_* and hiber_* :frowning:

> One step to make this work you need to make sure your devobj does not set DO_POWER_PAGABLE and then when you get an Sx/Hibernate irp, you do not power down the device. Any other drivers you depend on (let’s say the usb core or an SD reader or the networking stack) have to be aware of this and also not power down. If they support usage notification/hibernate that should do it.

I think in vista if any one driver sets DO_POWER_ PAGABLE then the whole stack is pageable? How will I know if any driver in the storage stack is doing that?

> What are you really trying to do/enable?
I’m trying to write hiber file at two places - one the usual boot device and the other my own storage device when the system is going to hibernatation.

> …but this all boils down to hibernation is not very well documented and getting it to work without explicit msft support is going to be very very hard for you.

somebody very kind called Doron (from msft) is already helping me :slight_smile:

>

I 'm trying to copy hiberfile onto my own storage device (which is
not
the boot device). I’m planning to hook my driver hiber_MyDriver in the
hiber stack but there are few questions I need answers for:

Q1. is it safe to assume that all the runtime drivers including my own
run
time driver for all the storage devices are still alive during
hibernation? If I makes call to these driver’s functions from my
hiber_MyDriver - is it OK?

In order for my Xen block device drivers to work, they must:
. make a call back to the bus driver to notify Xen/Dom0 that a disk
request has been put on the ring
. receive an interrupt via the bus driver logic (actually I have a
sneaking suspicion that this is incorrect - it appears that the ISR is
called not as a result of receiving a hardware interrupt but just at
regular intervals on a timer).

It works for me anyway, so the code I call is still loaded in memory at
the same place. See below though.

I save my state (or pointers to it) in my resource memory area in the
real device, and the dump_ and hiber_ devices are handed the same
physical resources (blindly I assume), so I can get at the bus call
table and the ring state from there.

The only routine in my call table that is called in dump mode is very
very simple (almost purely a hypercall).

Q2. I also do something during hibernation time with the device
objects
created during normal runtime by some driver in the storage stack -
are
these device objects still valid?

Probably not, although if they are in memory and you have saved a
pointer to them in a way that is accessible to the hibernation driver
then it may ‘work’ (for certain values of the work ‘work’). Don’t expect
any of the IRP handling code to work.

I’m writing from experience with making my xen driver work in ‘dump’
mode though, and dump mode is a little different as you can make very
little assumption about the state of the system (eg for all I know it
was my xen bus driver that caused the crash in the first place, so
involving it is probably a bad idea). In hibernation mode you can
probably be a little more certain about the state of the system,
although the idea is that everything else is frozen in a state that is
ready to be dumped to disk, so it’s probably a good idea not to tinker
with it too much. Your driver in hibernation/dump mode is kind of
operating ‘outside’ the system, which is why it is so constrained in
what it is allowed to do.

Q3. When does hiber_* drivers gets loaded in the system? Is it when
the
user clicks on “Hibernate” or is it immediately after boot time?

For the dump driver, it is definitely only loaded at crash time, so I
assume the same would apply to the hibernation driver.

You could verify this easily enough using the debugger - put a print
statement in your driver entry that fires when you detect you are being
invoked as a hibernation driver (how to detect this is well documented).

James

>For the dump driver, it is definitely only loaded at crash time

IIRC loaded to memory at boot time, but DriverEntry called at crash time.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>

>For the dump driver, it is definitely only loaded at crash time

IIRC loaded to memory at boot time, but DriverEntry called at crash
time.

That makes sense… it couldn’t really be any other way could it?

James

BTW - there was some open-source full disk encryption project (forgot the name - TrueCrypt?) which hooked the dump path to encrypt the hiberfil. They actually added the dump path filter by swapping the function pointers in the table.

The source is downloadable, and clearly displays the dump path initialization. I remember they use Ps’s load image notify callback to be notified on dump_xxx and hiber_xxx image loads.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
>I 'm trying to copy hiberfile onto my own storage device (which is not the boot device). I’m planning to hook my driver hiber_MyDriver in the hiber stack but there are few questions I need answers for:
>
> Q1. is it safe to assume that all the runtime drivers including my own run time driver for all the storage devices are still alive during hibernation? If I makes call to these driver’s functions from my hiber_MyDriver - is it OK?
>
> Q2. I also do something during hibernation time with the device objects created during normal runtime by some driver in the storage stack - are these device objects still valid?
>
> Q3. When does hiber_* drivers gets loaded in the system? Is it when the user clicks on “Hibernate” or is it immediately after boot time?
>
> Q4. How can I make system not move my storage device (non boot device) to hibernate (shutdown) state before complete hiberfile is written? Is responding to IRP_MN_DEVICE_USAGE_NOTIFICATION with proper response enough? Can there be multiple device claiming that they can support hibernation file? Or only one device can claim that it has hiberfile? Does the associated run time drivers (not the hiber_*) of the device in the hiber path stay loaded untill the hibernation completes?
>
> Thanks in anticipation.
>
>
>

There is no such thing as the “hibernation stack.” It’s just one storage
miniport driver re-instantiated at boot time, waiting to be needed. When
the hibernation file is written, it is done by calling the functions in this
driver directly, without IRPs. (A stack implies something that can pass
requests up and down it.) This second instantiation of the driver is never
pageable, though that’s moot since the boot driver is never pageable.


Jake Oshins
Hyper-V I/O Architect
Windows Kernel Team

This post implies no warranties and confers no rights.


wrote in message news:xxxxx@ntdev…
> Thank you Doron for such detailed responses:
>
>>> Why would you want to hook hiber_yourdriver? It is your driver, you can
>>> do whatever the heck you want with it
>
> Sorry I think I didn’t put it correctly. I want put my driver
> (hiber_mydriver) in the hiber stack.
>
> So since the drivers are not getting unloaded, it means from my
> hiber_mydriver I can call the functions in the normal run time drivers (no
> io processing, just the function calls to do something like accessing
> deviceExtensions or making some kernel function calls)???
>
>
>>> why does it matter? They exist before the machine goes into a hibernated
>>> state.
> I was just thinking that if DriverEntry of my hiber_myfilter gets loaded
> before other run time drivers gets unloaded I can get some private
> information from them before they stop processing io.
>
>>> Hint: the crash dump path uses the same drivers
> I didn’t get much from this hint as I think copies are different - dump_*
> and hiber_* :frowning:
>
>>> One step to make this work you need to make sure your devobj does not
>>> set DO_POWER_PAGABLE and then when you get an Sx/Hibernate irp, you do
>>> not power down the device. Any other drivers you depend on (let’s say
>>> the usb core or an SD reader or the networking stack) have to be aware
>>> of this and also not power down. If they support usage
>>> notification/hibernate that should do it.
>
> I think in vista if any one driver sets DO_POWER_ PAGABLE then the whole
> stack is pageable? How will I know if any driver in the storage stack is
> doing that?
>
>>> What are you really trying to do/enable?
> I’m trying to write hiber file at two places - one the usual boot device
> and the other my own storage device when the system is going to
> hibernatation.
>
>>> …but this all boils down to hibernation is not very well documented
>>> and getting it to work without explicit msft support is going to be very
>>> very hard for you.
>
> somebody very kind called Doron (from msft) is already helping me :slight_smile:
>
>

@Maxim S. Shatskih

Yeah I have looked at that code but what is different there is that at the end they are writing to the same boot device while in my case I’m writing to some other non-boot storage device. They are just modifying the data, replacing the original MDL with theirs and then continue calling the original driver in the dump/hibernation path.

???

What problem is it that you’re trying to solve?

I seem to recall, in a land far far away, answering these questions for you and in some detail, the answers to which were informed by multiple actual working implementations.

So, can you tell us specifically what the actual problem is that you’re having, so maybe we have a chance of answering your question in a useful way?

Peter
OSR

I am just curious reading this thread, if the problem to be solved is trying to figure out to write the hiberfile to some other non-boot device at hibernation time, how exactly would one go about building a scatter/gather list for a DMA operation for a device on a secondary adapter in the system?

Seems like hiber_MyDriver would need to get a DMA_ADAPTER object for the bus-master adapter his device is attached to in order to access GetScatterGatherList (or BuildScatterGatherList)
to translate MDLs into adapter specific SG List for his device.

Seems further that hiber_MyDriver could have his run-time copy of his driver (MyDriver) either use IoGetDmaAdapter or query for the BUS_INTERFACE_STANDARD using IRP_MN_QUERY_INTERFACE to obtain the DmaAdapter object for him during run-time and then at hiber time, hiber_MyDriver could query the still-loaded-in-memory MyDriver for this information.

Then perhaphs hiber_MyDriver would be able to build IO requests to send to his secondary device, with the help of the DmaAdapter object associated with the bus-master adapter controlling his device, a DmaAdapter object that was created by the original (run-time) port driver though

I am wondering if that DmaAdapter object would still be valid from the point of view of the kernel/HAL when it receives GetScatterGatherList requests on its behalf at hibernation time even though it was created by a now-frozen copy of a port driver?

If, as the system is preparing for hibernation, the original miniport driver (ScsiPort, Storport, or AtaPort??) refuses to power down the adapter that secondary device is attached to, would that be enough to keep the DmaAdapter object valid and available for future use during hibernation?

I don’t get the sense that the defunct copy of the port driver would ever be involved in calls to the functions pointed to in the DmaAdapter structure - only the kernel would receive those calls.

I apologize in advance if I am confused on how this all would work and also for jumping into someone else’s thread - again, I am just curious about how this particular aspect of the problem would be solved.

Judy