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?
2 Answers
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.
-
15To 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.– HultnerJun 29, 2011 at 11:41
-
5Yah, 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.– NameySep 21, 2011 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??– surfasbOct 27, 2011 at 6:31
-
3That'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?– NickSoftOct 4, 2013 at 12:01
-
2@NickSoft, Exactly. Nothing is stopping the "miniature file system driver" from being able to recognize other disk drives. Nothing, except for pure lazyness and the typical Microsoft cost-cutting approach to maximize Micro$oft returns.– PacerierOct 24, 2015 at 0:21
Okay there are 2 thing to solve to move hiberfil.sys
Tell 'ntoskrnl.exe' that runs as Process 'System' to open/save hibernation data to D:\hiberfil.sys instead of C:\ ->unsolved yet !
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.
-
-
Did anyone try to patch ntoskrnl.exe this way? Did it work afterwards? Oct 25, 2019 at 19:48
-
So, disabling Default/Administrative share c$ didn't work, disabling
powercfg
and linking didn't work either. BCD change is applied. How do I apply this patch the same way? (6.1.7601.24545)– Mark CDec 27, 2021 at 9:06 -
2Oh dear changing this is far away from being 'userfriendly'. Even I by myself did not fully tested this. Maybe there was some problem in the way like the need to also patch bootmgr or some signature check that was triggered by patching ntioskrnl or bootmgr that I couldn't find and disarm. However I was just fascinated by the challenge and just for fund went into Windows Internals. These are my 'findings'.– NaduJan 22, 2022 at 20:00
-
There are multiple integrity checks of the kernel binary, the PE checksum is only the beginning.– Milind RAug 20 at 21:09
powercfg.exe -h off
), and then delete the file.