This article contributes from: Bugfree / 9CBS, reference: www.codeguru.com platform: VC6 Windows XP (other platforms are not debugged)
Below I have made a brief description of the function that implements the remote shutdown, the type check is made, detail later, for details. Function specific information can be found in 9CBS explanation.
// Use parameter description / / =============== CHAR * PNAME; // User name char * pdomain; // domain name or remote computer name (empty-to-local machine) char * ppasswd; // password uint m_timeout; // Take the second number of seconds
/ * How to achieve remote shutdown * / // ==========================================================================================================================================================================================================================================================================00 & hLogonToken); // copy the access token DuplicateTokenEx (hLogonToken, TOKEN_ALL_ACCESS, NULL, SecurityIdentification, TokenPrimary, & hAdminToken); ImpersonateLoggedOnUser (hAdminToken); // open the access token associated with a thread OpenThreadToken (GetCurrentThread (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE , & hThreadToken); // get the SE_SHUTDOWN_NAME LUID LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, & tkp.Privileges [0] .Luid); // set the access token property tkp.PrivilegeCount = 1; tkp.Privileges [0] .Attributes = SE_PRIVILEGE_ENABLED // In this process, you can get a shutdown privilege AdjustTokenPrivilege, 0, (ptoken_privileges) null, 0); // Perform shutdown Command INITIATESYSTEMSHUTDOWN (Premotename, PMessage, M_Timeout, False, False);
Realization: (Reference to www.codeguru.com) ================================= 1. Created The application of the dialog box 2. Add CWINTHREAD * m_pthread; // for the storage thread char * pdomain; // dominad name or remote computer name in the constructor. Empty to the local machine) char * ppasswd; // Password uint m_timeout; // That is 3. Add a button on the dialog box, add code: m_pthread = AFXBEGINTHREAD (ShutdowNThread, this); 4. Add thread The actual code as follows: UINT AFX_CDECL CShutDWNDlg :: (LPVOID lpParam) {HANDLE hLogonToken ShutDownThread; HANDLE hAdminToken; HANDLE hThreadToken; TOKEN_PRIVILEGES tkp; if (FALSE == LogonUser (pName, pDomain, pPasswd, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, & hLogonToken)) {ASSERT ( 0);} if (false == duplicatetokenex (Hlogontoken, Token_all_Access, Null, Security, & Hadmintoken) ASSERT (0);
IF (false == impersonateloggedonuser (Hadmintoken) ASSERT (0);
if (FALSE == OpenThreadToken (GetCurrentThread (), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, TRUE, & hThreadToken)) {RevertToSelf (); ASSERT (0);} LookupPrivilegeValue (NULL, SE_SHUTDOWN_NAME, & tkp.Privileges [0] .Luid); tkp.PrivilegeCount = 1; tkp.Privileges [0] .Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges (hThreadToken, FALSE, & tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); if (! GetLastError () = ERROR_SUCCESS) {RevertToSelf (); ASSERT (0) ;} If (false == initiatesystemshutdown (premotename, pimentage, pdlg-> m_timeout, false, false) {repertself (); assert (0);}}