=====================窗体====================
Private Sub Command1_Click()
Unhook
End
End SubPrivate Sub Form_Load()
SDAttempted = 0
Me.Width = Screen.Width
lblStaticText.Left = Me.Width / 2 - lblStaticText.Width / 2
lblSDs.Left = Me.Width / 2 - lblSDs.Width / 2
gHW = Me.hwnd
Hook
End SubPrivate Sub Form_Unload(Cancel As Integer)
Cancel = True
End Sub==================模块==================
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetMessage Lib "user32" Alias "GetMessageA" (lpMsg As MSG, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long) As LongType POINTAPI
        x As Long
        y As Long
End TypeType MSG
    hwnd As Long
    message As Long
    wParam As Long
    lParam As Long
    time As Long
    pt As POINTAPI
End TypePublic Const GWL_WNDPROC = -4
Public Const WM_QUERYENDSESSION = &H11
Global Const WM_CANCELMODE = &H1FPublic SDAttempted As Long
Global lpPrevWndProc As Long
Global gHW As LongPublic Sub Hook()
    lpPrevWndProc = SetWindowLong(gHW, GWL_WNDPROC, AddressOf WindowProc)
End SubPublic Sub Unhook()
    Dim temp As Long
    temp = SetWindowLong(gHW, GWL_WNDPROC, lpPrevWndProc)
End Sub
Function WindowProc(ByVal hw As Long, ByVal uMsg As _
Long, ByVal wParam As Long, ByVal lParam As Long) As _
Long
Dim a As Long
    If uMsg = WM_QUERYENDSESSION Then
            SDAttempted = SDAttempted + 1
            frmMain.lblSDs.Caption = SDAttempted & " Time(s)."
            WindowProc = CallWindowProc(lpPrevWndProc, hw, _
            WM_CANCELMODE, wParam, wParam)
            Exit Function
    End If
    WindowProc = CallWindowProc(lpPrevWndProc, hw, _
    uMsg, wParam, lParam)
End Function
-----------------------------------------------------------
以上这段代码是用来反系统关机的,很成功。可是用以下C语言代码却可以让系统关机,不知怎样才可以完全做到反系统关机(断电除外:)),难道要hook api?哪位高人能给些思路,谢谢!
#include "stdio.h"
#include "windows.h"
int main()
{
LPSTR msg="Reboot Tool By Lion Hook\nhttp://www.xici.net";
if(ExitWindowsEx(EWX_REBOOT,0))
return TRUE;
if(ExitWindowsEx(EWX_REBOOT|EWX_FORCE,0))
return TRUE;
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
return FALSE;
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
if(!(GetVersion()&0x80000000))
InitiateSystemShutdown(NULL,msg,20,TRUE,TRUE);
else if (!ExitWindowsEx(EWX_REBOOT,0))
if(!ExitWindowsEx(EWX_REBOOT|EWX_FORCE,0))
return FALSE;
 return TRUE;
}

解决方案 »

  1.   

    可以参考我的文章:写了个禁止关闭计算机的模块http://blog.csdn.net/tanaya/archive/2005/05/29/383602.aspx 
      

  2.   

    楼主不知道注意没,AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);这句代码是什么意思呢。好象这个C程序权限比楼主你写的那个高那么点。如果你的权限和他相同或者高那么一点点。。测试一下,一点想法而已。
    提升权限我用的是下面的代码:楼主稍加修改就可以了,或者WMI。
    '*****************************************************************************************Public Declare Function GetCurrentProcess Lib "kernel32" () As Long
    Public Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LUID) As Long
    Public Declare Function AdjustTokenPrivileges Lib "advapi32.dll" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, PreviousState As TOKEN_PRIVILEGES, ReturnLength As Long) As Long
    Public Declare Function OpenProcessToken Lib "advapi32.dll" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, TokenHandle As Long) As LongPublic Const STANDARD_RIGHTS_REQUIRED = &HF0000
    Public Const TOKEN_ASSIGN_PRIMARY = &H1
    Public Const TOKEN_DUPLICATE = (&H2)
    Public Const TOKEN_IMPERSONATE = (&H4)
    Public Const TOKEN_QUERY = (&H8)
    Public Const TOKEN_QUERY_SOURCE = (&H10)
    Public Const TOKEN_ADJUST_PRIVILEGES = (&H20)
    Public Const TOKEN_ADJUST_GROUPS = (&H40)
    Public Const TOKEN_ADJUST_DEFAULT = (&H80)
    Public Const TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or TOKEN_ASSIGN_PRIMARY Or _
    TOKEN_DUPLICATE Or TOKEN_IMPERSONATE Or TOKEN_QUERY Or TOKEN_QUERY_SOURCE Or _
    TOKEN_ADJUST_PRIVILEGES Or TOKEN_ADJUST_GROUPS Or TOKEN_ADJUST_DEFAULT)
    Public Const SE_PRIVILEGE_ENABLED = &H2
    Public Const ANYSIZE_ARRAY = 1Public Type LUID
    lowpart As Long
    highpart As Long
    End TypePublic Type LUID_AND_ATTRIBUTES
    pLuid As LUID
    Attributes As Long
    End TypePublic Type TOKEN_PRIVILEGES
    PrivilegeCount As Long
    Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
    End TypePublic Function RaiseRight() As Boolean
    Dim hdlProcessHandle As Long
    Dim hdlTokenHandle As Long
    Dim tmpLuid As LUID
    Dim tkp As TOKEN_PRIVILEGES
    Dim tkpNewButIgnored As TOKEN_PRIVILEGES
    Dim lBufferNeeded As Long
    Dim lP As Long
    hdlProcessHandle = GetCurrentProcess()
    lP = OpenProcessToken(hdlProcessHandle, TOKEN_ALL_ACCESS, hdlTokenHandle)
    lP = LookupPrivilegeValue("", "SeDebugPrivilege", tmpLuid)
    tkp.PrivilegeCount = 1
    tkp.Privileges(0).pLuid = tmpLuid
    tkp.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
    lP = AdjustTokenPrivileges(hdlTokenHandle, False, tkp, Len(tkpNewButIgnored), tkpNewButIgnored, lBufferNeeded)
    RaiseRight = lP
    End Function
      

  3.   

    http://www.vbaccelerator.com/home/vb/Tips/Preventing_Logoff_or_Shutdown/article.asp
      

  4.   

    //http://www.vbaccelerator.com/home/vb/Tips/Preventing_Logoff_or_Shutdown/article.asp试了,也不符合要求。
      

  5.   

    我把程序提升到DEBUG权限还是没法做到防止那个C的程序关机,看来走提升权限的路是行不同啊,各位能提供些别的思路吗?
      

  6.   

    要禁止关机很简单,把Winlogon.exe进程挂起就可以了。
    也可以把Winlogon.exe的几个特定的线程杀了就可以了。
      

  7.   

    楼上方法可能可以,可是有没有哪位高手告诉我怎么把Winlogon.exe进程挂起,怎么得到线程ID,怎么杀线程,查了好久资料,没查到。解决后再加分....
      

  8.   

    Winlogon.exe的几个特定的线程杀了?系统不崩溃吗?
      

  9.   

    这个问题怎么又翻出来了。最近读了几个关于WINDOWS自带工具的文章,发现关机的方法实在是太多了。。呵呵呵呵,呵呵。
    就WINDOWS所带工具能关机的方法就不下5种,
    不过就问题本身来说,一般情况下拦截消息就可以了,但是有个问题,有些关机方法是强制的,VB也可以做,关机非常快,但是再启动就是非法关机,也就是说消息并没有传递给系统或者没有经过系统处理。
    那怎么办呢,想完全防止,开来还是HOOK,到底HOOK谁啊,不仅Winlogon,我刚才也说了,N多WINDOWS工具都能关机,还有就是这么一个问题,那天我搞了几个API,一不小心把我的XP给挂了,直接挂到无法启动,哎。。百思不得解啊,建议楼主还是去MS网站上看看那些高手们怎么说吧,
    我正在哭中
      

  10.   

    //Winlogon.exe的几个特定的线程杀了?
    //系统不崩溃吗?我将Winlogon.exe挂起(用一个工具),发现系统几乎运行正常。to zcsor我将Winlogon.exe挂起后用了好多种方法关机,都关不了,包括上面那个C程序。虽然将Winlogon.exe挂起不是最好的方法,但在没有更好的办法,就用它了,所以想请教一下,怎么将将Winlogon.exe挂起。
    http://community.csdn.net/Expert/topic/4855/4855405.xml?temp=.4438593
    问题解决后,再加分。
      

  11.   

    Winlogon.exe挂起
    Winlogon.exe的几个特定的线程杀了
    不是一会事阿
    挂起是挂起
      

  12.   

    http://www.csdn.net/develop/article/11/11776.shtm
      

  13.   

    要挂起简单,枚举线程,再把线程SuspendThread就可以了。
    Winlogon.exe是用来管理用户管理,机器开关之类的。停了也不好。其中它有几个线程是专门用来管关机和重启的,你用工具试试。
      

  14.   

    要关机的,可以把自己的程序权限设置为SYSTEM级别,然后关闭所有枚举的进程.最后运行关闭计算机函数.
      

  15.   

    //要关机的,可以把自己的程序权限设置为SYSTEM级别,然后关闭所有枚举的进程.最后运行关闭计算机函数.请看清楚标题,谢谢