¿Cómo cambiar la ubicación del archivo de hibernación en Windows 7?

45

No puedo habilitar la hibernación en Windows 7 porque no hay suficiente espacio en mi unidad C: para crear el archivo de hibernación. ¿Cómo puedo hacer que Windows coloque el archivo en otro lugar?

Fenom
fuente
No puedes Pero puede deshabilitar la hibernación ( powercfg.exe -h off) y luego eliminar el archivo.
Ian Boyd

Respuestas:

42

No puede, tiene que estar en la raíz de la unidad de arranque (la unidad C: en su caso).

Raymond Chen explicó las razones por las cuales en este artículo confidencial de Windows: La paradoja del sistema de archivos .

La hibernación sigue un patrón similar. Hibernar el sistema operativo significa descargar todo el contenido de la memoria en el archivo de hibernación; La restauración de la hibernación implica volver a guardar ese archivo en la memoria y fingir que no pasó nada. Nuevamente, es otro problema de huevo y gallina: para cargar el archivo de hibernación, necesita el controlador del sistema de archivos, pero el controlador del sistema de archivos está en el archivo de hibernación. Si mantiene el archivo de hibernación en el directorio raíz de la unidad de arranque, se puede utilizar el controlador del sistema de archivos en miniatura.

Snark
fuente
14
Para mal Windows no puede manejar esto, realmente lo necesito para mi SSD. Espero que lo arreglen en el futuro para que pueda elegir dónde colocarlo como en Mac OS X.
Hultner
55
Sí, en mi opinión, es un defecto de diseño. Incluso si el sistema necesita arrancar desde la unidad principal, simplemente no hay razón para tener que almacenar todos los gigabytes de información en la misma unidad: el archivo de hibernación podría cargar los elementos básicos (por ejemplo, acceso a la unidad) y luego buscar otra unidad para obtener más información. datos. Desafortunadamente, no lo diseñaron para manejar ese caso, lo que significa que no lo harán hasta un nuevo sistema operativo ... si es que lo hacen.
Namey
1
@ Namey: si el archivo de hibernación podría cargar los elementos básicos, entonces también podría escribirse directamente en el cargador de arranque en primer lugar. Luego abres otra lata de gusanos. Por otro lado, tampoco lo consideraría un defecto de diseño. Fue escrito en los días de Windows NT, supongo, donde la velocidad, los límites de memoria y la baja potencia de la CPU fueron los grandes factores, no las pequeñas unidades SSD. Heck, ¿quién habría predicho que las SSD eran tan comunes en primer lugar?
surfasb
1
Son solo palabras bonitas sobre "pollo y huevos" lo que no importa: si el cargador de arranque sabe cómo cargar el archivo de hibernación desde el disco a la memoria, no hay razón para no tener el controlador del sistema de archivos dentro del cargador de arranque.
Denis Barmenkov
3
Esa es una estúpida excusa de Microsoft. ¿Qué sucede si ambos discos están en el mismo controlador, se usa el mismo controlador? ¿Qué pasa si un disco es SSD y no quieres usarlo rápido?
NickSoft
6

De acuerdo, hay 2 cosas que resolver para mover hiberfil.sys

  1. ¡Indique a 'ntoskrnl.exe' que se ejecuta como Proceso 'Sistema' que abra / guarde los datos de hibernación en D: \ hiberfil.sys en lugar de C: \ -> sin resolver todavía!

  2. Para aplicar esta oportunidad también al archivo de datos de configuración de arranque (c: \ BOOT \ BCD) -> Esto es relativamente fácil con herramientas como VisualBCD https://www.boyans.net/DownloadVisualBCD.html -> O incluso simplemente usando regedit editando HKLM \ BCD00000000 \ Objects {71575733-c376-11e4-80ea-806e6f6e6963} \ Elements \ 21000001 que es el HiberFileDrive del ResumeLoader o \ 22000002 HiberFilePath. Tal vez necesite usar 'Archivo / Cargar sección' c: \ BOOT \ BCD para montar la rama 'BCD00000000' (El cursor debe estar en HKLM, de lo contrario, el elemento del menú está atenuado) -> ya que parece que esto ya está hecho por ntosknl.exe, por lo que no hay necesidad de cambiar esto ya que los cambios se sobrescribirán.

Sin embargo, el número 1. es lo peor y más difícil de cambiar. Hmm, carguemos ntoskrnl.exe en IDA y localice la función que trata con /hiberfil.sys y descompílelo para ver qué está sucediendo exactamente allí ...

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

En resumen, la ruta está codificada de esta manera: IoArcBootDeviceName + "\ hiberfil.sys" sin algunos parches binarios desagradables, no hay forma de cambiar eso. Bueno, además de tocar el santo grial de Windows, parchear el "ntoskernel" podría dar lugar a problemas como actualizaciones que deshacen el parche o los programas antivirus pueden volverse locos ... Sin embargo, veamos qué referencias son a IoArcBootDeviceName:

IopLoadCrashdumpDriver PopDeleteHiberFile PopCreateHiberFile PopBcdSetupResumeObject PopBcdSetDefaultResumeObjectElements PopBcdSetPendingResume PopBcdRegenerateResumeObject PopBcdEstablishResumeObject PopAllocotear

Wow cambiar eso parece estar bien (lo único que se dispara un poco es IopLoadCrashdumpDriver System32 \ Drivers \ crashdmp.sys, sin embargo, quién necesita crashdump, no importa si rompemos algo allí)

Entonces, parchear IopCreateArcNames que crea ArcBootDeviceName estará bien:

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 por cierto estoy usando ntkrnlmp.exe 6.1.7601.19045 de Win7 64 bit y verifiqué este código con ReactOS. (Sin embargo, la parte de hibernación aún no está implementada en las fuentes de Reactos) Tenga en cuenta que ArcBootDeviceName será algo así como: \ Device \ Harddisk1 \ Partition0

Hmm vamos a parchar ArcBootDeviceName (LoaderBlock + 0x78) a ArcHalDeviceName (LoaderBlock + 0x80)

Entonces, en caso de que el cargador bootmgr esté en una partición diferente a la de Windows, hibernate.sys se crea donde está 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

Entonces, en ntoskrnl.exe, reemplace 4C8B4B78 con 4C8B4B80 en dos ubicaciones. No olvides arreglar PE-Checksum después.

Nadu
fuente
¡Hable acerca de una respuesta críptica que no muchos pueden entender!
killjoy
¿Alguien intentó parchear ntoskrnl.exe de esta manera? ¿Funcionó después?
PF4Public