发信人: dark_hu()
整理人: hunter__fox(2002-03-16 21:48:54), 站内信件
|
*-- Winnt.h 中的定义
#DEFINE TOKEN_ADJUST_PRIVILEGES 0x0020
#DEFINE TOKEN_QUERY 0x0008
#DEFINE SE_PRIVILEGE_ENABLED 2
*-- Winbase.h 中的定义
#DEFINE VER_PLATFORM_WIN32s 0
#DEFINE VER_PLATFORM_WIN32_WINDOWS 1
#DEFINE VER_PLATFORM_WIN32_NT 2
*-- WinUser.h 中的定义
#DEFINE EWX_LOGOFF 0 && 调用 ExitWindowsEx 函数,
&& 在安全相关进程下, 关闭所有运行的进程.
&& 然后它登录用户离开.
#DEFINE EWX_SHUTDOWN 1 && 安全关闭电源. 所有文件缓存已经写入磁盘,
&& 且所有运行着的进程被停止.
&& Windows NT/2000: 调用进程必须具有 SE_SHUTDOWN_NAME
&& 权限.
#DEFINE EWX_REBOOT 2 && 关闭并重启系统.
&& Windows NT/2000: 调用进程必须具有 SE_SHUTDOWN_NAME
&& 权限.
#DEFINE EWX_POWEROFF 8 && 关闭系统并关掉电源. 系统必须支持关电源功能.
&& Windows NT/2000: 调用进程必须具有 SE_SHUTDOWN_NAME
&& 权限.
*-- 修改 EWX_SHUTDOWN 到任何上面的 #define 值来注销, 关闭, 重启或关掉电源.
DO ExitWindowsFox WITH EWX_SHUTDOWN
*----------------------------------
PROCEDURE ExitWindowsFox
*----------------------------------
PARAMETERS ExitMode
LOCAL iRc
iRc = 0
DECLARE ExitWindowsEx IN Win32Api INTEGER, INTEGER
*-- 检查操作系统版本, 如果是 NT/Win2K 还要调用 SetPrivilege 函数
liPlatform = GetPlatform()
IF liPlatform != VER_PLATFORM_WIN32_NT && 我们可以做我们想做的事
&& 而不用担心安全
iRc = ExitWindowsEx(ExitMode, 0)
IF ExitMode = EWX_LOGOFF OR ExitMode = EWX_POWEROFF
*-- 必须的, 因为在 Win9x 下任何一个这些参数 VFP 将不会退出.
QUIT
ENDIF
ELSE && 我们必须设置进程安全
iRc = SetProcPrivilege()
IF iRc <> 0
iRc = ExitWindowsEx(ExitMode, 0)
ENDIF
ENDIF
*----------------------------------
PROCEDURE SetProcPrivilege
*-- 设置适当的进程特权来允许关闭 NT/Win2K
*----------------------------------
*-- 定义获取当前 Process ID, 需要打开进程来取得进程令牌.
LOCAL iRc
iRc = 0
DECLARE INTEGER GetCurrentProcessId IN kernel32.DLL
DECLARE INTEGER OpenProcess IN Kernel32.DLL INTEGER, ;
INTEGER, ;
INTEGER
DECLARE INTEGER OpenProcessToken IN AdvApi32.DLL INTEGER, ;
INTEGER, ;
INTEGER@
*-- 定义为必要的安全特权获取一个 LUID 的函数.
DECLARE INTEGER LookupPrivilegeValue IN AdvApi32.DLL STRING, ;
STRING, ;
INTEGER@ lsLuid
*-- 定义调整进程令牌特权的函数, 这样我们可以关闭 NT/Windows 2000
DECLARE INTEGER AdjustTokenPrivileges IN AdvApi32.DLL INTEGER, ;
INTEGER, ;
STRING@ lsNewState, ;
INTEGER, ;
INTEGER, ;
INTEGER
liAccessToken = 0 && 访问我们要改变特权的令牌的占位符
lsLuidBuffer = SPACE(8) && 用于改变访问特权的 LUID 的占位符
lsName = SPACE(15) && 计算机名字占位符
liBufferLen = 15 && 计算机名字缓存长度占位符
liLuid = 0
liProc = 0
liProc = GetCurrentProcessId()
hProc = OpenProcess(2035711, 0, liProc)
iRc = OpenProcessToken(hProc, BITOR(TOKEN_ADJUST_PRIVILEGES, TOKEN_QUERY), @liAccessToken)
IF iRc <> 0
IF iRc <> 0
*-- "SeShutdownPrivilege" 是 SE_SHUTDOWN_NAME 值的串值.
LookupPrivilegeValue("", "SeShutdownPrivilege", @liLuid)
lsLuidBuffer = LongToStr(liLuid) + CHR(0) + CHR(0) + CHR(0) + CHR(0)
*-- 定义一个串来保存 TOKEN_PRIVILEGES 结构
lsNewState = SPACE(16)
*-- 填充结构
lsNewState = LongToStr(1) + lsLuidBuffer + LongToStr(SE_PRIVILEGE_ENABLED)
iRc = AdjustTokenPrivileges(liAccessToken, 0, @lsNewState, LEN(lsNewState), 0, 0)
RETURN iRc
ELSE
RETURN iRc
ENDIF
ELSE
RETURN iRc
ENDIF
ENDPROC
*----------------------------------
PROCEDURE GetPlatform
*----------------------------------
LOCAL liPlatform, iRc
liPlatform = 0
iRc = 0
DECLARE INTEGER GetVersionEx IN Win32Api STRING@
*-- 定义保存 OSVERSIONINFO 结构的串
lsOSVersionInfo = LongToStr(148) + SPACE(144)
iRc = GetVersionEx(@lsOSVersionInfo)
liPlatform = StrToLong(SUBSTR(lsOSVersionInfo, 17, 4))
RETURN liPlatform
ENDPROC
*-- 以下函数转换长整型到一个代表传递值的低高格式的 ASCII 字符串.
*----------------------------------
FUNCTION LongToStr
*----------------------------------
* Passed : 32-bit non-negative numeric value (lnLongval)
* Returns : ascii character representation of passed value in low-high
* format (lcRetstr)
* Example :
* m.long = "999999"
* m.longstr = long2str(m.long)
PARAMETERS lnLongval
PRIVATE i, lcRetstr
lcRetstr = ""
FOR i = 24 TO 0 STEP -8
lcRetstr = CHR(INT(lnLongval/(2^i))) + lcRetstr
lnLongval = MOD(lnLongval, (2^i))
NEXT
RETURN lcRetstr
*-- 以下函数转换一个低高格式串为长整型.
*----------------------------------
FUNCTION StrToLong
*----------------------------------
* Passed: 4-byte character string (lcLongstr) in low-high ASCII format
* Returns: long integer value
* Example:
* m.longstr = "1111"
* m.longval = str2long(m.longstr)
PARAMETERS lcLongstr
PRIVATE i, lnRetval
lnRetval = 0
FOR i = 0 TO 24 STEP 8
lnRetval = lnRetval + (ASC(lcLongstr) * (2^i))
lcLongstr = RIGHT(lcLongstr, LEN(lcLongstr) - 1)
NEXT
RETURN lnRetval |
|