Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I can't enable hibernation in Windows 7 because there is not enough room on my C: drive to create the hibernation file. How can I make Windows put the file somewhere else?

share|improve this question

migrated from stackoverflow.com Dec 19 '09 at 13:06

This question came from our site for professional and enthusiast programmers.

up vote 37 down vote accepted

You can't, it has to be in the root of the boot drive (the C: drive in your case).

Raymond Chen explained the reasons why in this Windows Confidential article: The File System Paradox.

Hibernation follows a similar pattern. Hibernating the operating system means dumping the entire contents of memory into the hibernation file; restoring from hibernation entails sucking that file back into memory and pretending nothing happened. Again, it's another chicken-and-egg problem: to load the hibernation file, you need the file system driver, but the file system driver is in the hibernation file. If you keep the hibernation file in the root directory of the boot drive, the miniature file system driver can be used instead.

share|improve this answer
11  
To bad windows can't handle this, I'd really need it for my SSD. I hope that they fix it in the future so you can choose where to put it like in Mac OS X. – Hultner Jun 29 '11 at 11:41
4  
Yah, in my opinion it's a bit of a design flaw. Even if the system needs to boot from the main drive, there's just no reason to have to store all the gigabytes of information on the same drive- the hibernation file could load the basics (e.g. drive access) and then look to another drive for additional data. Unfortunately, they didn't design it to handle that case- which means they won't until a new OS... if ever. – Namey Sep 21 '11 at 16:19
1  
@Namey: If the hibernation file could load the basics, then it might as well be written straight into the boot loader in the first place. Then you open up a whole nother can of worms. On another not, I wouldn't consider it a design flaw either. It was written back in the days of Windows NT I presume, where speed, memory limits, and low CPU power were the big factors, not small SSD drives. Heck, who would of predicted SSDs being so common in the first place?? – surfasb Oct 27 '11 at 6:31
1  
It's just pretty words about "chicken and eggs" which doesn't matter: if boot loader knows how to load hibernate file from disk to memory, there is no reason for not to have file system driver inside boot loader. – Denis Barmenkov Jan 10 '12 at 14:06
2  
That's a stupid excuse of microsoft. What if both disks are on the same controller - same driver is used? what if one disk is ssd and you don't want to wear it fast? – NickSoft Oct 4 '13 at 12:01

Okay there are 2 thing to solve to move hiberfil.sys

  1. Tell 'ntoskrnl.exe' that runs as Process 'System' to open/save hibernation data to D:\hiberfil.sys instead of C:\ ->unsolved yet !

  2. To apply this chance also to the boot configuration Data file (c:\BOOT\BCD) -> This is relatively easy with Tools like the VisualBCD https://www.boyans.net/DownloadVisualBCD.html -> Or even just using regedit editing HKLM\BCD00000000\Objects{71575733-c376-11e4-80ea-806e6f6e6963}\Elements\21000001 that is the HiberFileDrive of the ResumeLoader Or \22000002 HiberFilePath. Maybe you need to use 'File/Load hive' c:\BOOT\BCD to mount the 'BCD00000000' branch.(Cursor needs to be on HKLM, else to menu item is greyed out) -> as it seem this is already done by ntosknl.exe so there is no need no use in changing this since ya changes will be overwritten.

However number 1. is the worse and more hard to change thing. Hmm let's load ntoskrnl.exe into IDA and located the function that deals with /hiberfil.sys and decompile it to see what exactly is going on there...

__int64 __fastcall PopCreateHiberFile(LARGE_INTEGER *a1)
{
...
 RtlInitUnicodeString(&Source, L"\\hiberfil.sys");
...
  RtlAppendUnicodeStringToString(&Destination, &IoArcBootDeviceName);
  RtlAppendUnicodeStringToString(&Destination, &Source);
...
  ObjectAttributes.RootDirectory = 0i64;
  ObjectAttributes.Attributes = 576;
  ObjectAttributes.ObjectName = &Destination;
  ObjectAttributes.SecurityDescriptor = v5;
  ObjectAttributes.SecurityQualityOfService = 0i64;
  ret_2 = IoCreateFile(
            &FileHandle,
            0x100003u,
            &ObjectAttributes,
...

Okay in short the path is hardcoded like this: IoArcBootDeviceName + "\hiberfil.sys" without some nasty binary patching there is no way to change that. Well beside touching the holy windows grail patching the "ntoskernel" might result in problems like updates undo the patch or Antivirus programs might get crazy... However let's see what references are the to IoArcBootDeviceName:

IopLoadCrashdumpDriver PopDeleteHiberFile PopCreateHiberFile PopBcdSetupResumeObject PopBcdSetDefaultResumeObjectElements PopBcdSetPendingResume PopBcdRegenerateResumeObject PopBcdEstablishResumeObject PopAllocateHiberContext IopCreateArcNames PopBcdSetupResumeObject

Wow changing that seem to be fine (only thing that goes off a little is IopLoadCrashdumpDriver System32\Drivers\crashdmp.sys however who needs crashdump - doesn't matter if we break something there)

So patching IopCreateArcNames that creates ArcBootDeviceName will be fine:

NTSTATUS INIT_FUNCTION NTAPI IopCreateArcNames  (   IN PLOADER_PARAMETER_BLOCK  LoaderBlock )   
...
   /* Create the global system partition name */
   63     sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
   64     RtlInitAnsiString(&ArcString, Buffer);
   65     RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, TRUE);
   66 
   67     /* Allocate memory for the string */
   68     Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL);
   69     IoLoaderArcBootDeviceName = ExAllocatePoolWithTag(PagedPool,
   70                                                       Length,
   71                                                       TAG_IO);
   72     if (IoLoaderArcBootDeviceName)
   73     {
   74         /* Copy the name */
   75         RtlCopyMemory(IoLoaderArcBootDeviceName,
   76                       LoaderBlock->ArcBootDeviceName,
   77                       Length);
   78     }

...

https://doxygen.reactos.org/d3/d82/ntoskrnl_2io_2iomgr_2arcname_8c.html btw I'm using ntkrnlmp.exe 6.1.7601.19045 from Win7 64 bit and checked this code against ReactOS. (However the hibernating part is yet not implemented in the Reactos sources) Note that ArcBootDeviceName will be something like: \Device\Harddisk1\Partition0

Hmm let's patch ArcBootDeviceName(LoaderBlock + 0x78) to ArcHalDeviceName(LoaderBlock + 0x80)

So in case the bootmgr loader is on a different partition than windows hopefully hibernate.sys is creates were bootmgr is.

1405A9C15 4C 8B 4B 78                    mov     r9, [rbx+78h]
Patch #1           80

1405A9C19 4C 8D 05 30 06+                lea     r8, aArcnameS   ; "\\ArcName\\%s"
1405A9C20 48 8D 4C 24 40                 lea     rcx, [rsp+0D8h+pszDest] ; pszDest
1405A9C25 48 8B D7                       mov     rdx, rdi        ; cchDest
1405A9C28 E8 E3 AE B6 FF                 call    RtlStringCchPrintfA

...
1405A9C41 48 8D 0D C0 E7+                lea     rcx, IoArcBootDeviceName ; DestinationString
1405A9C48 41 B0 01                       mov     r8b, 1          ; AllocateDestinationString
1405A9C4B E8 60 13 DB FF                 call    RtlAnsiStringToUnicodeString
1405A9C50 48 8B 7B 78                    mov     rdi, [rbx+78h]
Patch #2           80

So in ntoskrnl.exe replace 4C8B4B78 with 4C8B4B80 at two locations. Don't forget to fix PE-Checksum afterwards.

share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .