ToolWiz BHORM
It is known Windows hibernation is an excellent function, the user can switch off the power supply, the next time when you start the computer, it will still stay in the last status, it will take only 20 seconds to start the computer in this way. It is pity there is a problem with this function of Windows, that is, the retention time for hibernation is so long, in addition, it can only hibernate one time, and it will disappear after you start the computer, you must restart it if you want to make it sleep once again. ToolWiz BHORM can make the system hibernate one time and keep it forever, no matter you close down the computer at other times and pull out the power supply, the computer will be started from hibernation in the next time, so it will take a much shorter time to start the computer, the master hands can play with it to try the feeling of the fact that it will take 20 seconds to start the computer, this software is free and without any restriction. Please pay attention that this software should only be used by Windows Geeks as it will take over the MBR of your system while installing, but it will help you recover while it is uninstalled.
Latest Version: 1.5 Operating System:Windows XP/Vista/7/8 Category:System Utilities File Size:2.3 M
(下载 | скачать | скачати| baixar | descargar | scaricare | Télécharger | डाउनलोड)
This following text is only for the tech experts who want to know more about BHORM
ToolWiz BHorm is a simple implementation for Hibernation Once and Resume Many Time. It replaces your MBR and installs a INT13/INT15/INT19 Hook which will take the control of Disk/RAM/BOOT when system is booing in the real mode. Also it installs a disk filter driver which will take the control of all disk access when Windows is loading. While there is any writing operation(IRP_WRITE) sending to the disk, it will redirect the operation to a cache place. This is a standard disk virtualization model. We just make a very smart engine to hold the access to hibernation file only and it really works evry well in XP, Vista, Win7, Win8 in our Lab.
Toolwiz BHORM is a open source project now. You can click here to download the source code for BHORM driver. Download
Here is the current MBR code it is using:
_data segment public
assume cs:_data, ds:_data, es:_data
org 0100h
main:
jmp start
start:
cli
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,STACK_BASE
sti
call ReadDiskEx
jmp InstallFilter
InstallFilter:
;call DisplayEnter
;jmp InstallFilter
cli
mov ax,FILTER_SEG
mov ds,ax
mov es,ax
mov ss,ax
mov sp,STACK_BASE
sti
db 0EAh ;jmp FILTER_SEG:FILTER_OFFSET
dw FILTER_OFFSET,FILTER_SEG
InitDap:
ret
DiskAddressPacket:
PacketSize db 16
Reserved db 0
BlockCount dw 20 ;sector number
PacketOffset dw FILTER_OFFSET ;offset
PacketSegment dw FILTER_SEG ;segment
LbaLow dd 2 ;LBA.LOW
LbaHigh dd 0 ;LBA.HIGH
ReadDiskEx:
mov si,offset DiskAddressPacket
add si,ADJUST
mov ah,42h ;read
mov dl,80h ;driver
int 13h
jc ReadDiskError
ret
ReadDiskError:
jmp $
DisplayEnter:
push bp
mov si,offset BootInfo ;display info
add si,ADJUST
mov bp,[si]
mov cx,14
mov ax,1301h
mov bx,000ch
mov dx,0h
int 10h
pop bp
ret
BootInfo db 'hook PBT',13,10
org (100h + 1FEh)
db 55h,0aah
_data ends
end main
Here is the code in the driver to process the IRP_WRITE operation.
//-----------------------------------------------------------------------------------------------------------
static NTSTATUS DFWrite (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
PFDO_EXTENSION FdoExtension = DeviceObject->DeviceExtension;
PGLOBAL_DATA gData = &FdoExtension->gData;
IO_STATUS_BLOCK IoStatus = {0};
PIO_STACK_LOCATION IoStack = NULL;
LARGE_INTEGER ByteOffset = {0};
ULONG32 ByteLength = 0;
PUCHAR tmpBuffer = NULL;
PUCHAR WriteBuffer = NULL;
PUCHAR ReadBlock = NULL;
ULONG64 WriteSectorOffset = 0;
ULONG64 WriteSectorLength = 0;
ULONG64 PermitRWSectorOffset;
ULONG64 PermitRWSectorCount;
ULONG32 MapNode;
ULONG64 tmpUsed = 0;
ULONG64 tmpData;
IoStack = IoGetCurrentIrpStackLocation (Irp);
WriteBuffer = (PUCHAR)MmGetSystemAddressForMdlSafe (Irp->MdlAddress,NormalPagePriority );
WriteSectorLength = IoStack->Parameters.Read.Length / SECTOR_SIZE ;
WriteSectorOffset = IoStack->Parameters.Read.ByteOffset.QuadPart / SECTOR_SIZE ;
if (DFReadWritePass (FdoExtension,WriteSectorOffset,WriteSectorLength) == TRUE)
{
return SMPassIrp (DeviceObject,Irp);
}
Status = IoAcquireRemoveLock (&FdoExtension->RemoveLock,Irp);
if (!NT_SUCCESS (Status ))
{
ERROR ("DF %08x",Status);
SMCompleteIrp (Irp,Status,0);
return Status;
}
if (WriteSectorLength == 0)
{
Status = STATUS_SUCCESS;
ERROR ("DF %08x",Status);
goto Done;
}
ByteLength =IoStack->Parameters.Write.Length ;
tmpBuffer = (PUCHAR)DFalloc (ByteLength);
if (tmpBuffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ERROR ("DF %08x",Status);
goto Done;
}
memcpy (tmpBuffer,WriteBuffer,ByteLength);
ReadBlock = (PUCHAR)DFalloc (MAX_MAPBLOCK_SIZE_B);
if (ReadBlock == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ERROR ("DF %08x",Status);
goto Done;
}
tmpUsed = 0;
while (WriteSectorLength)
{
MapNode = DFBreakDownReadWriteBlock (DeviceObject,&WriteSectorOffset,&WriteSectorLength,&PermitRWSectorOffset,&PermitRWSectorCount,&IoStatus);
if (!NT_SUCCESS (IoStatus.Status))
{
Status = IoStatus.Status;
ERROR ("DF %08x",Status);
goto Done;
}
if (MapNode != 0) //...map
{
ByteOffset.QuadPart = 1LL * PermitRWSectorOffset * SECTOR_SIZE;
ByteLength = (ULONG32)(PermitRWSectorCount * SECTOR_SIZE);
Status = SMReadWriteDisk (FALSE,FdoExtension->TagertDO,ByteOffset,ByteLength,(PUCHAR)tmpBuffer + tmpUsed,&IoStatus);
if (!NT_SUCCESS (Status)|| IoStatus.Information != ByteLength)
{
ERROR ("DF %08x",Status);
goto Done;
}
}
else
{
ULONG *nodeIndex;
ULONGLONG BreakDownIntOFReadFile;
ULONGLONG BreakDownOffsetOfReadFile;
ULONGLONG BreakDownIntPartOfSectorStart;
ULONGLONG BreakDownOffsetPartOfSectorStart;
BreakDownIntPartOfSectorStart = PermitRWSectorOffset / MAX_MAPBLOCK_SIZE_S;
BreakDownOffsetPartOfSectorStart = PermitRWSectorOffset % MAX_MAPBLOCK_SIZE_S;
BreakDownIntOFReadFile = BreakDownIntPartOfSectorStart / ( SECTOR_SIZE / MAX_BITMAPBLOCK_SIZE ) ;
BreakDownOffsetOfReadFile = BreakDownIntPartOfSectorStart % (SECTOR_SIZE / MAX_BITMAPBLOCK_SIZE);
if (BreakDownIntOFReadFile > (gData->BitmapDistance.End - gData->BitmapDistance.Start + 1) )
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ERROR ("DF %08x",Status);
goto Done;
}
if (gData->UsedCacheIndex >= (gData->DataDistance.End - gData->DataDistance.Start + 1) / MAX_MAPBLOCK_SIZE_S)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
ERROR ("DF %08x - %08x - %08x ",Status,gData->UsedCacheIndex,(gData->DataDistance.End - gData->DataDistance.Start + 1) / MAX_MAPBLOCK_SIZE_S);
goto Done;
}
if (PermitRWSectorCount < MAX_MAPBLOCK_SIZE_S)
{
ByteOffset.QuadPart = 1LL * ((PermitRWSectorOffset / MAX_MAPBLOCK_SIZE_S) * MAX_MAPBLOCK_SIZE_S) * 512;
Status = SMReadWriteDisk (TRUE,FdoExtension->TagertDO,ByteOffset,MAX_MAPBLOCK_SIZE_B,ReadBlock,&IoStatus);
if (!NT_SUCCESS (Status ) || IoStatus.Information != MAX_MAPBLOCK_SIZE_B )
{
ERROR ("DF %08x",Status);
goto Done;
}
}
memcpy (ReadBlock + BreakDownOffsetPartOfSectorStart * SECTOR_SIZE, (PUCHAR)tmpBuffer + tmpUsed,(ULONG32)(PermitRWSectorCount * SECTOR_SIZE));
tmpData = gData->CacheDistance.Start + gData->DataDistance.Start;
tmpData = tmpData * SECTOR_SIZE;
tmpData = tmpData + (ULONG64)(gData->UsedCacheIndex * MAX_MAPBLOCK_SIZE_B);
ByteOffset.QuadPart = tmpData;
Status = SMReadWriteDisk (FALSE,FdoExtension->TagertDO,ByteOffset,MAX_MAPBLOCK_SIZE_B,ReadBlock,&IoStatus);
if (!NT_SUCCESS (Status ) || IoStatus.Information != MAX_MAPBLOCK_SIZE_B )
{
ERROR ("DF %08x",Status);
goto Done;
}
//ByteOffset.QuadPart = 1LL * ( BreakDownIntOFReadFile + gData->CacheDistance.Start + gData->BitmapDistance.Start) * SECTOR_SIZE ;
tmpData = BreakDownIntOFReadFile + gData->CacheDistance.Start + gData->BitmapDistance.Start;
tmpData = tmpData * SECTOR_SIZE;
ByteOffset.QuadPart = tmpData;
Status = SMReadWriteDisk (TRUE,FdoExtension->TagertDO,ByteOffset,SECTOR_SIZE,ReadBlock,&IoStatus);
if (!NT_SUCCESS (Status) || IoStatus.Information != SECTOR_SIZE)
{
ERROR ("DF %08x",Status);
goto Done;
}
nodeIndex = ( PULONG )ReadBlock;
nodeIndex += (ULONG)BreakDownOffsetOfReadFile;
*nodeIndex = (ULONG32)(gData->UsedCacheIndex * MAX_MAPBLOCK_SIZE_S);
Status = SMReadWriteDisk (FALSE,FdoExtension->TagertDO,ByteOffset,SECTOR_SIZE,ReadBlock,&IoStatus);
if (!NT_SUCCESS (Status) || IoStatus.Information != SECTOR_SIZE)
{
ERROR ("DF %08x",Status);
goto Done;
}
gData->UsedCacheIndex = gData->UsedCacheIndex + 1;
}
tmpUsed += PermitRWSectorCount * SECTOR_SIZE;
}
Done:
if (ReadBlock != NULL)
{
KFfree (ReadBlock);
ReadBlock = NULL;
}
if (NT_SUCCESS (Status))
{
SMCompleteIrp (Irp,Status,IoStack->Parameters.Write.Length);
}
else
{
SMCompleteIrp(Irp,Status,0);
}
if (tmpBuffer != NULL)
{
KFfree (tmpBuffer);
tmpBuffer = NULL;
}
IoReleaseRemoveLock (&FdoExtension->RemoveLock,Irp);
return Status;
}
Operating Systems Supported:
- Microsoft Windows 8 (32-bit and 64-bit)
- Microsoft Windows 7 (32-bit and 64-bit)
- Microsoft Windows Vista (32-bit and 64-bit)
- Microsoft Windows XP (32-bit)
Hardware Requirements
- 500 MHz processor or faster processor
- 512MB of RAM
- 2GB of hard disk space
V 1.5.0.0 (Nov. 26 , 2012)
- Add Command line support, user can call ToolwizBhorm.exe /enterhorm to enter the HORM Mode
V 1.3.0.0 (Jan. 15 , 2012)
- Changed the product name from Btows to ToolWiz
V 1.2 (Nov. 1, 2011)
- Initial Release

