Bagaimana cara mengubah lokasi file hibernasi di Windows 7?

45

Saya tidak dapat mengaktifkan hibernasi di Windows 7 karena tidak ada cukup ruang di drive C: saya untuk membuat file hibernasi. Bagaimana saya bisa membuat Windows meletakkan file di tempat lain?

Phenom
sumber
Kamu tidak bisa Tetapi Anda dapat menonaktifkan hibernasi ( powercfg.exe -h off), dan kemudian menghapus file.
Ian Boyd

Jawaban:

42

Anda tidak bisa, itu harus di root boot drive (drive C: dalam kasus Anda).

Raymond Chen menjelaskan alasan mengapa dalam artikel Windows Confidential ini: The File System Paradox .

Hibernasi mengikuti pola yang sama. Hibernasi sistem operasi berarti membuang seluruh isi memori ke file hibernasi; memulihkan dari hibernasi berarti mengisap file itu kembali ke memori dan berpura-pura tidak ada yang terjadi. Sekali lagi, ini adalah masalah ayam dan telur: untuk memuat file hibernasi, Anda memerlukan driver sistem file, tetapi driver sistem file ada di file hibernasi. Jika Anda menyimpan file hibernasi di direktori root dari drive boot, driver sistem file miniatur dapat digunakan sebagai gantinya.

Snark
sumber
14
Untuk windows yang buruk tidak bisa menangani ini, saya benar-benar membutuhkannya untuk SSD saya. Saya berharap mereka memperbaikinya di masa depan sehingga Anda dapat memilih tempat untuk meletakkannya seperti di Mac OS X.
Hultner
5
Yah, menurut saya itu sedikit cacat desain. Bahkan jika sistem perlu boot dari drive utama, tidak ada alasan untuk harus menyimpan semua gigabyte informasi pada drive yang sama - file hibernasi dapat memuat dasar-dasar (misalnya akses drive) dan kemudian mencari drive lain untuk tambahan data. Sayangnya, mereka tidak mendesainnya untuk menangani case-yang berarti mereka tidak akan sampai OS baru ... jika pernah.
Namey
1
@Namey: Jika file hibernasi dapat memuat dasar-dasarnya, maka mungkin juga ditulis langsung ke boot loader di tempat pertama. Kemudian Anda membuka seluruh kaleng cacing. Di lain tidak, saya tidak akan menganggap itu cacat desain juga. Itu ditulis kembali pada zaman Windows NT I kira, di mana kecepatan, batas memori, dan daya CPU yang rendah adalah faktor besar, bukan drive SSD kecil. Heck, siapa yang akan memprediksi SSD begitu umum di tempat pertama ??
surfasb
1
Itu hanya kata-kata yang bagus tentang "ayam dan telur" yang tidak masalah: jika boot loader tahu cara memuat file hibernasi dari disk ke memori, tidak ada alasan untuk tidak memiliki driver sistem file di dalam boot loader.
Denis Barmenkov
3
Itu alasan bodoh dari microsoft. Bagaimana jika kedua disk berada pada controller yang sama - driver yang sama digunakan? bagaimana jika satu disk adalah SSD dan Anda tidak ingin memakainya dengan cepat?
NickSoft
6

Oke ada 2 hal yang harus dipecahkan untuk memindahkan hiberfil.sys

  1. Katakan 'ntoskrnl.exe' yang berjalan sebagai Proses 'Sistem' untuk membuka / menyimpan data hibernasi ke D: \ hiberfil.sys alih-alih C: \ -> belum terpecahkan!

  2. Untuk menerapkan kesempatan ini juga ke file Data konfigurasi boot (c: \ BOOT \ BCD) -> Ini relatif mudah dengan Alat-alat seperti VisualBCD https://www.boyans.net/DownloadVisualBCD.html -> Atau bahkan hanya menggunakan regedit mengedit HKLM \ BCD00000000 \ Objects {71575733-c376-11e4-80ea-806e6f6e6963} \ Elements \ 21000001 yang merupakan HiberFileDrive of the ResumeLoader Atau \ 22000002 HiberFilePath. Mungkin Anda perlu menggunakan 'File / Load hive' c: \ BOOT \ BCD untuk me-mount cabang 'BCD00000000'. (Kursor harus berada di HKLM, selain itu untuk item menu diklik) -> karena sepertinya ini sudah dilakukan oleh ntosknl.exe sehingga tidak perlu tidak digunakan dalam mengubah ini karena perubahan ya akan ditimpa.

Namun angka 1. adalah hal yang lebih buruk dan lebih sulit untuk diubah. Hmm mari kita memuat ntoskrnl.exe ke IDA dan menemukan fungsi yang berkaitan dengan /hiberfil.sys dan mendekompilasi untuk melihat apa yang sebenarnya terjadi di sana ...

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

Oke, singkatnya, pathnya dikodekan seperti ini: IoArcBootDeviceName + "\ hiberfil.sys" tanpa beberapa patch biner yang jahat tidak ada cara untuk mengubahnya. Selain menyentuh jendela suci grail yang menambal "ntoskernel" dapat mengakibatkan masalah seperti pembaruan membatalkan tambalan atau program Antivirus mungkin menjadi gila ... Namun, mari kita lihat referensi apa yang ada pada IoArcBootDeviceName:

IopLoadCrashdumpDriver PopDeleteHiberFile PopCreateHiberFile PopBcdSetupResumeObject PopBcdSetDefaultResumeObjectElements PopBcdSetPendingResume PopBcdRegenerateResumeObject PopBcdEstablishResumeObject PopAllocateHiberContext IopCreateArcNames PopBcdSetupResumeObject

Wow mengubah yang tampaknya baik-baik saja (satu-satunya hal yang berbunyi sedikit adalah IopLoadCrashdumpDriver System32 \ Drivers \ crashdmp.sys namun yang membutuhkan crashdump - tidak masalah jika kita memecahkan sesuatu di sana)

Jadi menambal IopCreateArcNames yang membuat ArcBootDeviceName akan baik-baik saja:

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 Saya menggunakan ntkrnlmp.exe 6.1.7601.19045 dari Win7 64 bit dan memeriksa kode ini terhadap ReactOS. (Namun bagian hibernasi belum diimplementasikan dalam sumber Reactos) Perhatikan bahwa ArcBootDeviceName akan menjadi sesuatu seperti: \ Device \ Harddisk1 \ Partition0

Hmm mari kita tambal ArcBootDeviceName (LoaderBlock + 0x78) ke ArcHalDeviceName (LoaderBlock + 0x80)

Jadi jika bootmgr loader berada di partisi yang berbeda dari windows semoga hibernate.sys dibuat adalah 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

Jadi di ntoskrnl.exe ganti 4C8B4B78 dengan 4C8B4B80 di dua lokasi. Jangan lupa untuk memperbaiki PE-Checksum sesudahnya.

Nadu
sumber
Bicara tentang jawaban samar tidak banyak yang bisa mengerti!
killjoy
Adakah yang mencoba menambal ntoskrnl.exe dengan cara ini? Apakah itu berhasil sesudahnya?
PF4Public