回 帖 发 新 帖 刷新版面

主题:[讨论]~~惊!惊!惊!~~ExitWindowsEx函数该何去何从?

我已经从其他高手那里得来一个纯VB编写的关机库样例!
但是有点不懂!因为我太懂得编写类库..DLL文件!
而之前我试用过利用ExitWindowsEx函数来实现关机!
我的系统是XP的!试过之后发现无论设置如何!都只能注销机器!
而XP下原本默认是可以利用系统system32文件下自带的一个shutdown.exe外部文件来实现shutdown外部命令关机,即shutdown -s -t 0
但在使用2000系统的时候却惊奇的发现,2000系统默认没有shutdown.exe这个文件!所以我根本无法使用shutdown -s -t 0来关机!
后来在网上查看一下,发现还需要其他的几种API函数进行提权!
那段话是这么说的:"退出操作系统可以调用Windows API的ExitWindowsEx函数。在Win9x下,只要简单地调用ExitWindowsEx函数就可以实现关机或者重新启动。但是在Win 2000/XP下调用ExitWindowsEx函数时,还需要先调用AdjustTokenPrivileges函数。"
而我在查询电子书API手册的时候,却发现里面根本找不到AdjustTokenPrivileges函数的定义!于是就此郁闷!辗转反侧!特向高手求救!
不胜感激.....

回复列表 (共3个回复)

沙发

你的电子 API 手册不全。

建议你使用《Win32 Programmer's Reference》或者《MSDN Library》

以下是 AdjustTokenPrivileges 的介绍:
[quote]
The AdjustTokenPrivileges function enables or disables privileges in the specified access token. Enabling or disabling privileges in an access token requires TOKEN_ADJUST_PRIVILEGES access. 

BOOL AdjustTokenPrivileges(

    HANDLE TokenHandle,    // handle to token that contains privileges
    BOOL DisableAllPrivileges,    // flag for disabling all privileges
    PTOKEN_PRIVILEGES NewState,    // pointer to new privilege information
    DWORD BufferLength,    // size, in bytes, of the PreviousState buffer
    PTOKEN_PRIVILEGES PreviousState,    // receives original state of changed privileges
    PDWORD ReturnLength     // receives required size of the PreviousState buffer
   );    
 

Parameters

TokenHandle

Identifies the access token that contains the privileges to be modified. 

DisableAllPrivileges

Specifies whether the function disables all of the token's privileges. If this value is TRUE, the function disables all privileges and ignores the NewState parameter. If it is FALSE, the function modifies privileges based on the information pointed to by the NewState parameter. 

NewState

Pointer to a TOKEN_PRIVILEGES structure that specifies an array of privileges and their attributes. If the DisableAllPrivileges parameter is FALSE, AdjustTokenPrivileges enables or disables these privileges for the token. If you set the SE_PRIVILEGE_ENABLED attribute for a privilege, the function enables that privilege; otherwise, it disables the privilege. 
If DisableAllPrivileges is TRUE, the function ignores this parameter. 

BufferLength

Specifies the size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if the 
PreviousState parameter is NULL. 

PreviousState

Pointer to a buffer that the function fills with a TOKEN_PRIVILEGES structure containing the previous state of any privileges the function modifies. The token must be open for TOKEN_QUERY access to use this parameter. This parameter can be NULL. 
If you specify a buffer that is too small to receive the complete list of modified privileges, the function fails and does not adjust any privileges. In this case, the function sets the variable pointed to by the ReturnLength parameter to the number of bytes required to hold the complete list of modified privileges. 

ReturnLength

Pointer to a variable that receives the required size, in bytes, of the buffer pointed to by the PreviousState parameter. This parameter can be NULL if PreviousState is NULL. 

 

Return Values

If the function succeeds, the return value is nonzero. To determine whether the function adjusted all of the specified privileges, call GetLastError, which returns one of the following values when the function succeeds:

Value    Description
ERROR_SUCCESS    The function adjusted all specified privileges.
ERROR_NOT_ALL_ASSIGNED    The token does not have one or more of the privileges specified in the NewState parameter. The function may succeed with this error value even if no privileges were adjusted. The PreviousState parameter indicates the privileges that were adjusted.

If the function fails, the return value is zero. To get extended error information, call GetLastError. 
[/quote]

可能你还需要一个 LookupPrivilegeValue 和 OpenProcessToken

我就不帖了,给你一个汇编的例子:
[quote]RebootPC Proc
  Local stOSVer : OSVERSIONINFO
  Local stTokenP : TOKEN_PRIVILEGES
  Local hToken :DWORD
  Local t:DWORD
  mov hToken , 0
  invoke memfill , addr stOSVer , SIZEOF OSVERSIONINFO , 0
  invoke memfill , addr stTokenP , SIZEOF TOKEN_PRIVILEGES , 0
  mov stOSVer.dwOSVersionInfoSize , SIZEOF OSVERSIONINFO
  invoke GetVersionEx , addr stOSVer
  .If stOSVer.dwPlatformId == VER_PLATFORM_WIN32_NT ; Windows NT
    invoke GetCurrentProcess
    mov t , eax
    invoke OpenProcessToken , t , TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY , addr hToken
    invoke LookupPrivilegeValue , NULL , SADD("SeShutdownPrivilege") , addr stTokenP.Privileges.Luid
    mov stTokenP.PrivilegeCount , 1
    mov stTokenP.Privileges.Attributes , SE_PRIVILEGE_ENABLED
    invoke AdjustTokenPrivileges , hToken , FALSE , addr stTokenP , 0 , NULL , 0
  .EndIf
  invoke ExitWindowsEx , EWX_REBOOT, 0
  ret
RebootPC EndP[/quote]

板凳

《MSDN Library》里面有一个例子:How to Shut Down the System

[quote]BOOL MySystemShutdown()
{
   HANDLE hToken; 
   TOKEN_PRIVILEGES tkp; 
 
   // Get a token for this process. 
 
   if (!OpenProcessToken(GetCurrentProcess(), 
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
      return( FALSE ); 
 
   // 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_UPDATE |
               SHTDN_REASON_FLAG_PLANNED)) 
      return FALSE; 

   return TRUE;
}
[/quote]

3 楼

谢谢~~
太感激了!
我自己再琢磨一下!

我来回复

您尚未登录,请登录后再回复。点此登录或注册