2012年7月5日星期四

InitiateSystemShutdown.Cpp


//本文整理自msdn.
#include <windows.h>

//关机的方法一:
BOOL MySystemShutdown()
{    
    HANDLE hToken; // Get a token for this process. 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return( FALSE ); 
    
    TOKEN_PRIVILEGES tkp; // Get the LUID for the shutdown privilege. 
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 

    tkp.PrivilegeCount = 1;  // one privilege to set    
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    // Get the shutdown privilege for this process. 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 
    if (GetLastError() != ERROR_SUCCESS) return FALSE; 

    // Shut down the system and force all applications to close. 
    if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE | SHTDN_REASON_FLAG_PLANNED)) return FALSE; 
    
    return TRUE;//shutdown was successful
}

//带提示的关机。
BOOL MySystemShutdown_with_dialogbox( LPTSTR lpMsg ) 
{
    HANDLE hToken;              // handle to process token 
    // Get the current process token handle so we can get shutdown privilege. 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE; 

    TOKEN_PRIVILEGES tkp;       // pointer to token structure 
    // Get the LUID for shutdown privilege. 
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 

    tkp.PrivilegeCount = 1;  // one privilege to set    
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    // Get shutdown privilege for this process. 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); 

    // Cannot test the return value of AdjustTokenPrivileges. 
    if (GetLastError() != ERROR_SUCCESS) return FALSE; 

    BOOL fResult;               // system shutdown flag 
    // Display the shutdown dialog box and start the countdown. 
    fResult = InitiateSystemShutdown( NULL,    // shut down local computer 
        lpMsg,   // message for user
        30,      // time-out period, in seconds 
        FALSE,   // ask user to close apps 
        TRUE);   // reboot after shutdown 
    if (!fResult) return FALSE; 

    // Disable shutdown privilege. 
    tkp.Privileges[0].Attributes = 0; 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); 

    return TRUE; 
}

//阻止关机。
BOOL PreventSystemShutdown()
{
    HANDLE hToken;              // handle to process token 
    // Get the current process token handle  so we can get shutdown privilege. 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE; 

    TOKEN_PRIVILEGES tkp;       // pointer to token structure 
    // Get the LUID for shutdown privilege. 
    LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); 
    tkp.PrivilegeCount = 1;  // one privilege to set    
    tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 

    // Get shutdown privilege for this process. 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); 
    if (GetLastError() != ERROR_SUCCESS) return FALSE; 

    if ( !AbortSystemShutdown(NULL) ) return FALSE; // Prevent the system from shutting down. 
    
    tkp.Privileges[0].Attributes = 0; // Disable shutdown privilege. 
    AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); 

    return TRUE;
}

int __cdecl wmain()
{
    //锁定计算机
    int r = MessageBox(NULL,(LPCWSTR)L"要锁定计算机吗?",(LPCWSTR)L"锁定计算机测试",MB_YESNO); 
    if (r == IDYES) LockWorkStation();

    //注销当前用户的方法一:
    r = MessageBox(NULL,(LPCWSTR)L"要注销当前用户吗?",(LPCWSTR)L"注销当前用户测试一",MB_YESNO); 
    if (r == IDYES) ExitWindows(0, 0);

    //注销当前用户的方法二:
    r = MessageBox(NULL,(LPCWSTR)L"要注销当前用户吗?",(LPCWSTR)L"注销当前用户测试二",MB_YESNO); 
    if (r == IDYES) ExitWindowsEx(EWX_LOGOFF, 0);

    /*在应用(界面)程序中阻止注销的办法:就是返回失败。
    case WM_QUERYENDSESSION:  
    { 
    int r = MessageBox(NULL,(LPCWSTR)L"End the session?",(LPCWSTR)L"WM_QUERYENDSESSION",MB_YESNO); 
    return r == IDYES; // Return TRUE to continue, FALSE to stop. 
    break; 
    }
    */

    //关机测试一:
    r = MessageBox(NULL,(LPCWSTR)L"要关机吗?",(LPCWSTR)L"关机测试一",MB_YESNO); 
    if (r == IDYES) MySystemShutdown();//已经开始关机,后面用sleep,本人想也没有用。

    //经测试,上面的关机,很难取消,不知用消息能否拦截。hook ExitWindowsEx是可以的。
    //即使能运行下面的取消关机函数,也无济于事。
    /*取消关机    
    r = MessageBox(NULL,(LPCWSTR)L"要取消关机吗?",(LPCWSTR)L"取消关机",MB_YESNO); 
    if (r == IDYES) PreventSystemShutdown();
    */

    //关机测试二:
    r = MessageBox(NULL,(LPCWSTR)L"要关机吗?",(LPCWSTR)L"关机测试二",MB_YESNO); 
    if (r == IDYES)MySystemShutdown_with_dialogbox( L"made by correy" );//在xp下就是弹出那个经典的消息框,Win 7下也弹出消息。

    //取消关机
    r = MessageBox(NULL,(LPCWSTR)L"要取消关机吗?",(LPCWSTR)L"取消关机",MB_YESNO); 
    if (r == IDYES) PreventSystemShutdown();//相当于shutdon -a

    //重启的就不说了,别的函数也能实现。

    return 0;    
}

没有评论:

发表评论