Як змінити розташування файлу сплячки в Windows 7?


45

Я не можу ввімкнути сплячку в Windows 7, оскільки на моєму диску C: недостатньо місця, щоб створити файл сплячки. Як змусити Windows помістити файл де-небудь ще?



Ви не можете. Але ви можете відключити сплячку ( powercfg.exe -h off), а потім видалити файл.
Ян Бойд

Відповіді:


42

Ви не можете, він повинен бути в корені завантажувального диска (диск C: у вашому випадку).

Реймонд Чен пояснив причини, чому в цій конфіденційній статті Windows: Парадокс файлової системи .

Зимова сплячка йде за подібною схемою. Зимування операційної системи означає скидання всього вмісту пам'яті у файл гібернації; відновлення після сплячки тягне за собою всмоктування цього файлу в пам'ять і прикидання, що нічого не сталося. Знову ж таки, ще одна проблема з куркою-яйцем: щоб завантажити файл сплячки, вам потрібен драйвер файлової системи, але драйвер файлової системи знаходиться у файлі сплячки. Якщо ви зберігаєте файл сплячки у кореневому каталозі завантажувального диска, замість нього може використовуватися мініатюрний драйвер файлової системи.


14
Щоб погані вікна не впоралися з цим, я дійсно знадобився б для мого SSD. Я сподіваюся, що вони це виправлять у майбутньому, тож ви можете вибрати, де його розмістити, як у Mac OS X.
Hultner

5
Так, на мою думку, це трохи вада дизайну. Навіть якщо системі потрібно завантажуватися з основного диска, просто немає причин зберігати всю гігабайт інформації на одному диску - файл гібернації може завантажувати основи (наприклад, доступ до диска), а потім шукати додатковий диск для додаткового дані. На жаль, вони не створили його для обробки цього випадку - це означає, що вони не отримають до нової ОС ... якщо ніколи.
Namey

1
@Namey: Якщо файл зі сплячки може завантажувати основи, то він також може бути записаний прямо в завантажувач. Тоді ви відкриєте цілу північну банку глистів. З іншого боку, я б також не вважав це недоліком дизайну. Це було написано ще за часів Windows NT, я припускаю, де швидкість, обмеження пам’яті та низька потужність процесора були великими факторами, а не маленькими накопичувачами SSD. Чорт забирай, хто б передбачив, що в першу чергу такі поширені SSD?
surfasb

1
Це просто гарні слова про "курку і яйця", що не має значення: якщо завантажувач знає, як завантажити сплячий файл з диска в пам'ять, немає ніяких причин не мати драйвера файлової системи всередині завантажувача.
Денис Барменков

3
Це дурне виправдання Microsoft. Що робити, якщо обидва диски на одному контролері - використовується один і той же драйвер? що робити, якщо на одному диску є ssd, і ви не хочете його швидко носити?
NickSoft

6

Гаразд, для переміщення hiberfil.sys потрібно вирішити дві речі

  1. Скажіть 'ntoskrnl.exe', який працює як процес 'Система', щоб відкрити / зберегти дані сплячки до D: \ hiberfil.sys замість C: \ -> ще нерозв’язано!

  2. Застосувати цей шанс також до файлу даних конфігурації завантаження (c: \ BOOT \ BCD) -> Це порівняно просто з такими інструментами, як VisualBCD https://www.boyans.net/DownloadVisualBCD.html -> Або навіть просто з використанням regedit редагування HKLM \ BCD00000000 \ Об'єкти {71575733-c376-11e4-80ea-806e6f6e6963} \ Elements \ 21000001 - це HiberFileDrive ResumeLoader Or \ 22000002 HiberFilePath. Можливо, вам потрібно використовувати "Файл / Завантажити вулик" c: \ BOOT \ BCD, щоб встановити гілку "BCD00000000". (Курсор повинен бути на HKLM, інакше, щоб пункт меню був сірим) -> як здається, це вже зроблено by ntosknl.exe, тому немає потреби в зміні цього, оскільки зміни ya будуть замінені.

Однак число 1. - гірше і важче змінити річ. Хм, давайте завантажимо ntoskrnl.exe в IDA і знайдемо функцію, яка працює з /hiberfil.sys, і декомпілюємо її, щоб побачити, що саме там відбувається ...

__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,
...

Гаразд, коротко, шлях жорстко кодується так : IoArcBootDeviceName + "\ hiberfil.sys" без якогось неприємного бінарного виправлення немає можливості змінити це. Окрім доторкання до святого грааля вікон, виправлення "ntoskernel" може призвести до таких проблем, як оновлення, скасування патча або антивірусні програми можуть звести з розуму ... Однак давайте подивимося, які посилання на IoArcBootDeviceName:

IopLoadCrashdumpDriver PopDeleteHiberFile PopCreateHiberFile PopBcdSetupResumeObject PopBcdSetDefaultResumeObjectElements PopBcdSetPendingResume PopBcdRegenerateResumeObject PopBcdEstabsteResumePesPecdePextPeestextPesPecideResumePesPecdePeSextResumePesumeCes

Нічого не змінюється, що здається нормальним (єдине, що трохи відходить - це IopLoadCrashdumpDriver System32 \ Drivers \ crashdmp.sys, кому потрібний краш-дамп - не має значення, якщо ми щось там зламаємо)

Отже, виправлення IopCreateArcNames, що створює ArcBootDeviceName, буде добре:

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 Я використовую ntkrnlmp.exe 6.1.7601.19045 з Win7 64 біт і перевірив цей код на ReactOS. (Однак зимувальна частина ще не реалізована в джерелах Reactos ) Зауважте, що ArcBootDeviceName буде чимось на зразок: \ Device \ Harddisk1 \ Partition0

Хм, давайте виправити ArcBootDeviceName (LoaderBlock + 0x78) на ArcHalDeviceName (LoaderBlock + 0x80)

Тож у випадку, якщо завантажувач завантажувача знаходиться на іншому розділі, ніж Windows, сподіваємось, hibernate.sys є створення було bootmgr є.

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

Тож у ntoskrnl.exe замініть 4C8B4B78 на 4C8B4B80 у двох місцях. Не забудьте потім виправити PE-Checksum.


Говорити про криптовану відповідь не багато хто може зрозуміти!
killjoy

Хтось намагався таким чином виправити ntoskrnl.exe? Це спрацювало згодом?
PF4Public
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.