精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● VFP>>〖外部引用〗>>实现WIN98与WIN2000关闭计算机的方法

主题:实现WIN98与WIN2000关闭计算机的方法
发信人: 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 

[关闭][返回]