Win32API システム時刻を設定する
システムの時刻を設定するためには、SetSystemTime関数を用いる。SetSystemTime関数を用いるためには、SE_SYSTEMTIME_NAME特権を有効にしておく必要がある。
システム時刻を「今日」の零時に設定する
手順としては、まずEnablePrivileges関数にて、AdjustTokenPrivileges関数でSE_SYSTEMTIME_NAME特権を有効にしてから、SetSystemTime関数を呼び出す。
SetSystemTime関数の引数であるLPSYSTEMTIME型には、UTCを設定する必要がある。そのため、まずGetLocalTime関数でローカルタイムを取得し、wHour、wMinute、wSecond、wMilliseconds各メンバに「0」をセットする。その後、ローカルタイムをUTCに変換してからSetSystemTime関数を呼び出している。
#include <windows.h> #include <stdio.h> BOOL EnablePrivileges(LPTSTR lpPrivilegeName, BOOL bEnable) { HANDLE hToken; LUID luid; TOKEN_PRIVILEGES tokenPrivileges; BOOL bRet; //1.OpenProcessToken関数で、プロセストークンを取得する bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); if (!bRet) { return FALSE; } //2.LookupPrivilegeValue関数で、特権に対応するLUID(ローカル一意識別子)を取得する bRet = LookupPrivilegeValue(NULL, lpPrivilegeName, &luid); if (bRet) { //3.TOKEN_PRIVILEGES型のオブジェクトに、LUID(ローカル一意識別子)と特権の属性(有効にするか無効にするか)を指定する tokenPrivileges.PrivilegeCount = 1; tokenPrivileges.Privileges[0].Luid = luid; tokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; //4.AdjustTokenPrivileges関数で、特権を有効にする AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, 0, 0, 0); bRet = GetLastError() == ERROR_SUCCESS; } CloseHandle(hToken); return bRet; } int main() { //SE_SHUTDOWN_NAME(シャットダウン特権) を有効にする if ( !EnablePrivileges(SE_SYSTEMTIME_NAME, TRUE) ) { puts("EnablePrivileges failed"); return 1; } FILETIME localFileTime, utcFileTime; SYSTEMTIME localTime, utcTime; //ローカルタイムを取得 GetLocalTime(&localTime); //時刻を零時に設定する localTime.wHour = 0; localTime.wMinute = 0; localTime.wSecond = 0; localTime.wMilliseconds = 0; //////////////////////////////////////////////// //ローカルタイムをUTCをに変換する //SYSTEMTIME構造体をFILETIME構造体へ変換 SystemTimeToFileTime(&localTime, &localFileTime); //FILETIME構造体に変換されたUTCをローカルタイムに変換 LocalFileTimeToFileTime(&localFileTime, &utcFileTime); //FileTimeToLocalFileTime(&utcFileTime, &localFileTime); //ロールタイムに変換されたFILETIME構造体をSYSTEMTIME構造体に変換 FileTimeToSystemTime(&utcFileTime, &utcTime); // //////////////////////////////////////////////// //システム時刻を設定する if (SetSystemTime(&utcTime)) { puts("SetSystemTime succeeded!"); } else { puts("SetSystemTime failed"); } return 0; }
このプログラムを実行を成功させるためには、プロセスに対して、SE_SYSTEMTIME_NAME特権が有効になっていなければならない。
拙者の実行環境であるWindows Vistaは、ユーザー権限で実行した場合は、SE_SYSTEMTIME_NAME特権が元々割当てられていなかったため、SE_SYSTEMTIME_NAME特権を有効にすることが出来なかった。
管理者権限で実行した場合は、SE_SYSTEMTIME_NAME特権が割当てられているが、無効になっていたため、EnablePrivileges関数でSE_SYSTEMTIME_NAME特権を有効にして、プログラムの実行を成功させることができた。
参考
http://msdn.microsoft.com/ja-jp/library/cc429943.aspx
http://support.microsoft.com/kb/245786/ja
http://d.hatena.ne.jp/s-kita/20110409/1302337508