中止系统关机






2.94/5 (6投票s)
2005年6月6日
1分钟阅读

81871

1427
停止已启动的系统关机,无需下载平台 SDK。
引言
AbortSystemShutdown
函数停止使用 InitiateSystemShutdown
函数启动的系统关机。InitiateSystemShutdown
函数启动指定计算机的关机和可选重启(见下图)。
还有另一种方式可以收到此对话框(见下图):如果您的计算机感染了 Blaster 蠕虫或其变种,例如 W32.Blaster.Worm、W32.Blaster.C.Worm、W32.Blaster.B.Worm、W32.Randex.E (赛门铁克)、W32/Lovsan.worm (McAfee)、WORM_MSBLAST.A (趋势科技) 和 Win32.Posa.Worm (Computer Associates)。
代码解释
AbortSystemShutdown
函数需要 Windows NT 3.1 或更高版本。因此,使用 Windows 版本要求宏很有用。您可以在此 文章中找到更多信息。
#define WinVerMajor() LOBYTE(LOWORD(GetVersion())) #define IsWinVerNTs() (GetVersion() < 0x80000000) #define IsWinVerNT351Plus() (IsWinVerNTs() && WinVerMajor() >= 3)
要停止本地计算机关机,调用进程必须具有 SE_SHUTDOWN_NAME
权限。这就是我们使用 AdjustTokenPrivileges
函数的原因。
此示例还说明了加载时动态链接。如果 DLL 不可用,则使用加载时动态链接的应用程序必须简单地终止。但是,运行时动态链接示例可以响应错误。
代码已为 UNICODE 准备就绪。如果您想创建 UNICODE 版本,请将 UNICODE 添加到预处理器定义中。
FormatMessage
函数可用于获取 GetLastError
返回的系统错误代码的错误消息字符串。
#include <windows.h> #define WinVerMajor() LOBYTE(LOWORD(GetVersion())) #define IsWinVerNTs() (GetVersion() < 0x80000000) #define IsWinVerNT351Plus() (IsWinVerNTs() && WinVerMajor() >= 3) #define ERR_MSG TEXT("This program requires Windows NT version 3.1 or later!") BOOL (__stdcall * MyAbortSystemShutdown)(LPTSTR); BOOL fAbortSystemShutdown(LPTSTR lpMachineName); BOOL PreventSystemShutdown(void); int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (IsWinVerNT351Plus()) { PreventSystemShutdown(); } else { MessageBox(NULL, ERR_MSG, TEXT("Abort System Shutdown"), MB_OK); } return (0); } /* * AbortSystemShutdown * * The AbortSystemShutdown function stops a system shutdown started by using * the InitiateSystemShutdown function. */ BOOL fAbortSystemShutdown(LPTSTR lpMachineName) { HINSTANCE hinstLib; BOOL result = FALSE; if (IsWinVerNT351Plus()) { hinstLib = LoadLibrary(TEXT("Advapi32.dll")); if (hinstLib) { if (MyAbortSystemShutdown = (BOOL (__stdcall *)(LPTSTR)) #ifdef UNICODE GetProcAddress(hinstLib, "AbortSystemShutdownW")) #else GetProcAddress(hinstLib, "AbortSystemShutdownA")) #endif // !UNICODE { result = (MyAbortSystemShutdown)(lpMachineName); } } FreeLibrary(hinstLib); } return (result); } BOOL PreventSystemShutdown(void) { HANDLE hToken; // handle to process token TOKEN_PRIVILEGES tkp; // pointer to token structure // Get the current process token // handle so we can get shutdown privilege. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { return (FALSE); } // 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); } // Prevent the system from shutting down. if (! fAbortSystemShutdown(NULL)) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); // Display the string. MessageBox(NULL, (LPCTSTR) lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION); // Free the buffer. LocalFree(lpMsgBuf); return (FALSE); } // Disable shutdown privilege. tkp.Privileges[0].Attributes = 0; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); return (TRUE); }
您可以通过使用参数 -a 执行 Windows XP shutdown.exe 实用程序来获得相同的结果。您还可以使用 shutdown -s -t 60 -c "bye-bye" 命令来调用系统关机对话框。