如果想要在一個Storage上啟用HORM的功能,且同時可以保存另一個partition的資料,可參考以下做法:
1.使用VS2005/2008 --> 開新專案-->選擇主控台應用程式。
2.於project 屬性頁面-->Link-->加入powrprof.lib檔(很多錯誤都是因為沒有include這個檔案)。
3.貼入下方頁面的程式碼,接著build出來即可。
/******************************************************************************
*
* File: dismount_all_in_one.cpp
* Copyright: (c) Microsoft Corporation 2005
*
* Purpose: This sample application accompanies the Windows XP Embedded white
* paper called 'Dismounting Volumes in a Hibernate Once/Resume Many Configuration.'
*
* Description: This is a command-line application that:
*
* - Receives input from the command line specifying one or more volumes to be dismounted
* - Tests to see if hibernation is enabled
* - Locks the specified volumes
* - Dismounts the specified volumes
* - Causes the system to sleep before hibernation to show screen messages
* - Causes the system to hibernate for about 20 seconds
* - Uses a waitable timer to cause the system to resume from hibernation
* - Unlocks the volumes that were locked
*
* Requirements:
*
* - Windows XP Professional or a Windows XP Embedded-based run-time image
* that includes the required dependencies
* - Hibernation must be enabled
* - The powrprof.lib library must be added to the project
* - Early versions of the powrprof.h header file had problems that can
* prevent it being included in a .cpp file or included multiple times.
* Typically, early versions of the powrprof.h header file must be modified
* to resolve this problem; however, this file uses a #ifdef directive that
* resolves this problem without modification of the powrprof.h header file.
* For more information about problems with the powrprof.h header file,
* see the Power Schemes topic in the Power Management SDK documentation
* at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/power/base/power_schemes.asp
*
*****************************************************************************/
/******************************************************************************
* C O N S T A N T S A N D M A C R O S
******************************************************************************/
# define _WIN32_WINNT 0x0501
# define WINVER 0x0501
# define MAX_ARRAY_SIZE 26
/******************************************************************************
* I N C L U D E D I R E C T I V E S
******************************************************************************/
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <powrprof.h>
#ifdef __cplusplus
}
#endif
#include <winioctl.h>
#include <tchar.h>
#include <strsafe.h>
#include <string.h>
#include <stdio.h>
/******************************************************************************
* P R I N T U S A G E
******************************************************************************/
void PrintUsage()
{
_tprintf( _T("usage: dismount.exe <volume-path-list>\n"));
_tprintf( _T("For example: d: f:\n") );
}
/******************************************************************************
* M A I N
******************************************************************************/
int _cdecl _tmain( int argc, TCHAR * argv[] )
{
_TCHAR szNtDosVolume[7] = _T("\\\\.\\A:");
DWORD cbReturned;
int iCounter;
int iVolume;
int iNumberOfVolumes;
TCHAR * psz;
BOOLEAN Hibernate = TRUE;
BOOLEAN ForceCritical = TRUE;
BOOLEAN DisableWakeEvent = FALSE;
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime = {0};
DWORD TimeToSleep = 5000;
HANDLE lpHandles[MAX_ARRAY_SIZE];
BOOLEAN Passed = FALSE;
liDueTime.QuadPart = -200000000;
// Initialize the array that will hold the handles to the volumes to be dismounted.
for (iVolume = 0; iVolume < MAX_ARRAY_SIZE; iVolume++)
{
lpHandles[iVolume] = INVALID_HANDLE_VALUE;
}
// Determine whether the operating system supports hibernation.
// If hibernation is not enabled, print an error to the screen and exit.
if ( !IsPwrHibernateAllowed() )
{
_tprintf( _T( "This system does not support hibernation. Exiting. \n" ) );
goto done;
}
// Check to ensure that the count of arguments is correct.
if ( argc < 2 )
{
// Provide usage information.
PrintUsage();
goto done;
}
// Begin loop to get drive letter identifiers, open and validate handles
// for each volume, and lock and dismount volumes.
iVolume = 0;
for ( iCounter = 1; iCounter < argc; iCounter++ )
{
psz = argv[iCounter];
if ( * psz == _T('/') || * psz == _T('-') )
{
psz++;
if ( * psz == _T('?') )
{
PrintUsage();
goto done;
}
}
szNtDosVolume[4] = psz[0];
// Retrieve a handle to the volume to be locked.
lpHandles[iVolume] = CreateFile( szNtDosVolume,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
NULL );
// Test for an invalid handle.
// If the handle is invalid, print an error to screen and exit.
if ( lpHandles[iVolume] == INVALID_HANDLE_VALUE )
{
_tprintf( _T( "Failed to open the volume %s with error %ld\n" ), psz, GetLastError() );
goto done;
}
// Use the FSCTL_LOCK_VOLUME control code to lock the volume.
// If the volume cannot be locked, print an error to the screen and exit.
if ( !DeviceIoControl( lpHandles[iVolume],
FSCTL_LOCK_VOLUME,
NULL,
0,
NULL,
0,
&cbReturned,
NULL ) )
{
_tprintf( _T( "Failed to lock the volume %s with error %ld\n" ), psz, GetLastError() );
goto done;
}
// If the volume lock is successful, print a status message to the screen.
else
{
_tprintf( _T( "Locked %s\n" ), psz );
}
// Use the FSCTL_DISMOUNT_VOLUME control code to dismount the volume.
// If the volume cannot be dismounted, print an error to the screen and exit.
if ( !DeviceIoControl( lpHandles[iVolume],
FSCTL_DISMOUNT_VOLUME,
NULL,
0,
NULL,
0,
&cbReturned,
NULL ) )
{
_tprintf( _T( "Failed to dismount the volume %s with error %ld\n" ), psz, GetLastError() );
goto done;
}
// If the volume dismount is successful, print a status message to the screen.
else
{
_tprintf( _T( "Dismounted %s\n" ), psz );
iVolume++;
}
}
// Pause the thread by sleeping for 5000ms (5 seconds) to give time to display screen messages.
Sleep(TimeToSleep);
// Create a waitable timer to time the wake-up from hibernation.
// The first parameter receives NULL, which gives the timer object a deafult security descriptor.
// The second parameter receives FALSE, which creates a synchronization timer instead of a
// manual reset notification timer.
// TimeToResume is the name of the timer.
hTimer = CreateWaitableTimer( NULL,
FALSE,
"TimeToResume"
);
// If CreateWaitableTimer fails, it returns NULL.
// If CreateWaitableTimer fails, print a failure message to the screen and exit.
if ( hTimer == NULL )
{
_tprintf( _T( "CreateWaitableTimer failed. %ld\n" ), GetLastError() );
goto done;
}
// Set the timer to wait for 20 seconds.
if (!SetWaitableTimer( hTimer,
&liDueTime,
0,
NULL,
NULL,
TRUE ) )
{
_tprintf( _T("SetWaitableTimer failed. %ld\n" ), GetLastError() );
goto done;
}
// Set the suspend state. Here Hibernate is true, ForceCritical is true,
// and DisableWakeEvent is false.
// If the suspend state cannot be successfully set, print a failure message to the screen and exit.
if ( !SetSuspendState ( Hibernate,
ForceCritical,
DisableWakeEvent ) )
{
_tprintf( _T("Failed to set the suspend state with error %ld\n" ), GetLastError() );
goto done;
}
// Save the count of valid handles to volumes and use it in the second loop.
iNumberOfVolumes = iVolume;
// Begin new loop to iterate through the array of handles to volumes
// and unlock each volume.
for ( iVolume = 0; iVolume < iNumberOfVolumes; iVolume++ )
{
// Use the FSCTL_UNLOCK_VOLUME control code to unlock the volume.
// If the volume cannot be unlocked, print an error to the screen and exit.
if ( !DeviceIoControl( lpHandles[iVolume],
FSCTL_UNLOCK_VOLUME,
NULL,
0,
NULL,
0,
&cbReturned,
NULL ) )
{
_tprintf( _T("Failed to unlock the volume %s with error %ld\n" ), argv[ iVolume + 1], GetLastError() );
goto done;
}
// If the volume is unlocked, print a status message to the screen
else
{
_tprintf( _T("Unlocked %s\n"), argv[ iVolume + 1] );
}
}
Passed = TRUE;
done:
// Close handle to the timer.
if ( ( hTimer != NULL ) )
{
if ( !CloseHandle( hTimer ) )
{
_tprintf( _T("Failed to close the handle to the waitable timer with error %ld\n"), GetLastError() );
}
}
for ( iVolume = 0; iVolume < MAX_ARRAY_SIZE; iVolume++ )
{
// Close all valid handles contained in the array of handles.
if ( lpHandles[iVolume] != INVALID_HANDLE_VALUE )
{
if ( !CloseHandle( lpHandles[iVolume] ))
{
_tprintf( _T("Failed to close a handle to a volume with error %ld\n"), GetLastError() );
}
}
}
return Passed ? 0 : 1;
}
參考資源:http://msdn.microsoft.com/en-us/library/dd143253.aspx