用程序重启动NT时出现的问题(100分)

  • 主题发起人 主题发起人 dereck
  • 开始时间 开始时间
D

dereck

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟想通过编程实现NT的重启动。<br>在“大富翁”论坛中查找了多篇文章,尝试了多位专家的代码,但都未获成功。<br>问题都是出现在调用AdjustTokenPrivileges时,用GetLastError出现以下提示信息:<br>“AdjustTokenPrivileges failed with code 1300”。<br>曾经看过一位专家说过常量"SeShutdownPrivilege"在delphi中是没有声明的,是不是<br>需要在unit头Include某些文件,如winnt.h呢?<br>请各位英雄赐教!
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=820757<br>記得給分喲。
 
用dadabox提供的链接中"吴辽"的代码进行试验,结果错误依然.而且我发现其实错误在调用<br>LookupPrivilegeValue时就已经出现,其错误代码是"203",可能还是"SeShutdownPrivilege"<br>的问题.<br>大家快help me!
 
试试看下面的代码看看行不行。<br>procedure TfrmMain.ExitWindowsNT(uFlags: Integer);<br>var<br>&nbsp; &nbsp; hToken: THandle;<br>&nbsp; &nbsp; tkp,tkDumb: TTokenPrivileges;<br>&nbsp; &nbsp; DumbInt: DWORD;<br>begin<br>&nbsp; &nbsp; FillChar(tkp,sizeof(tkp),0);<br>&nbsp; &nbsp; if not (OpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,hToken)) then<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid);<br>&nbsp; &nbsp; tkp.PrivilegeCount:=1;<br>&nbsp; &nbsp; tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;<br><br>&nbsp; &nbsp; AdjustTokenPrivileges(hToken,False,tkp,sizeof(tkDumb),tkDumb,DumbInt);<br>&nbsp; &nbsp; if GetLastError &lt;&gt; ERROR_SUCCESS then<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>&nbsp; &nbsp; if not ExitWindowsEx(uFlags,0) then<br>&nbsp; &nbsp; &nbsp; &nbsp; Exit;<br>end;
 
亲爱的"飘摇客",很遗憾地告诉你,错误依旧!
 
我收集的四个重新启动/关闭WinNT/2000的代码,没有实验过,灌水喽[:D][:D][:D]<br>{-------------------------------------------------------------------------}<br>procedure ReBootWinNT;<br>var<br>&nbsp; &nbsp;currToken:THandle;<br>&nbsp; &nbsp;prevState,newState:TTokenPrivileges;<br>&nbsp; &nbsp;prevStateLen:DWORD;<br>&nbsp; &nbsp;uid:TLargeInteger;<br>begin<br>&nbsp; &nbsp; // Set the privledges so we CAN reboot...<br>&nbsp; &nbsp;OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, currToken);<br>&nbsp; &nbsp;LookupPrivilegeValue(nil, 'SeShutdownPrivilege',uid);<br>&nbsp; &nbsp;newState.PrivilegeCount:=1;<br>&nbsp; &nbsp;newState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; &nbsp;newState.Privileges[0].Luid := uid;<br>&nbsp; &nbsp;AdjustTokenPrivileges(currToken, False, newState, sizeof(TTokenPrivileges),prevState, prevStateLen);<br>&nbsp; // Go ahead and reboot...<br>&nbsp; &nbsp;ExitWindowsEX(EWX_REBOOT, 0);<br>end;<br>{-------------------------------------------------------------------------}<br><br>function ShutDown(uFlags: Cardinal):boolean;<br>const<br>&nbsp; ADJUST_PRIV = TOKEN_QUERY or TOKEN_ADJUST_PRIVILEGES;<br>&nbsp; SHTDWN_PRIV = 'SeShutdownPrivilege';<br>&nbsp; PRIV_SIZE &nbsp; = sizeOf(TTokenPrivileges);<br>var<br>&nbsp; Len: DWORD;<br>&nbsp; TokenPriv, Dummy: TTokenPrivileges;<br>&nbsp; Token: THandle;<br>&nbsp; Error:integer;<br>begin<br>&nbsp; error:=0;<br>&nbsp; // 设置特权<br>&nbsp; if not OpenProcessToken(GetCurrentProcess(), ADJUST_PRIV, Token) then<br>&nbsp; &nbsp; &nbsp; Error := Error or 4;<br>&nbsp; if not LookupPrivilegeValue(nil, SHTDWN_PRIV,TokenPriv.Privileges[0].Luid) then<br>&nbsp; &nbsp; Error := Error or 8;<br>&nbsp; TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; TokenPriv.PrivilegeCount := 1; &nbsp;// One privilege to set<br>&nbsp; if not AdjustTokenPrivileges(Token, false, TokenPriv, PRIV_SIZE,Dummy, Len) then<br>&nbsp; &nbsp; Error:=Error or 16;<br>&nbsp; ExitWindowsEx(uFlags, 0);<br>&nbsp; Result := (Error=0);<br>end;<br><br><br>procedure TForm1.BitBtn1Click(Sender: TObject);<br>begin<br>&nbsp;ShutDown(EWX_POWEROFF + EWX_FORCE);<br>end;<br>{--------------------------------------------------------------------------}<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; AdjustToken;<br>&nbsp; ExitWindowsEx(EWX_SHUTDOWN, 0);<br>end;<br><br>//获取NT系统的操作权限<br>procedure AdjustToken();<br>var<br>&nbsp; hdlProcessHandle : Cardinal;<br>&nbsp; hdlTokenHandle &nbsp; : Cardinal;<br>&nbsp; tmpLuid &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Int64;<br>&nbsp; tkp &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: TOKEN_PRIVILEGES;<br>&nbsp; tkpNewButIgnored : TOKEN_PRIVILEGES;<br>&nbsp; lBufferNeeded &nbsp; &nbsp;: Cardinal;<br>&nbsp; Privilege &nbsp; &nbsp; &nbsp; &nbsp;: array[0..0] of _LUID_AND_ATTRIBUTES;<br>begin<br>&nbsp; hdlProcessHandle := GetCurrentProcess;<br>&nbsp; OpenProcessToken(hdlProcessHandle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hdlTokenHandle);<br>&nbsp; // Get the LUID for shutdown privilege.<br>&nbsp; LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);<br>&nbsp; Privilege[0].Luid := tmpLuid;<br>&nbsp; Privilege[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; tkp.PrivilegeCount := 1; &nbsp; // One privilege to set<br>&nbsp; tkp.Privileges[0] := Privilege[0];<br>&nbsp; // Enable the shutdown privilege in the access token of this process.<br>&nbsp; AdjustTokenPrivileges(hdlTokenHandle,False,tkp,Sizeof(tkpNewButIgnored),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tkpNewButIgnored,lBufferNeeded);<br>end;<br>{---------------------------------------------------------------------------}<br>&nbsp;function GetWinVersion: String;<br>&nbsp; var<br>&nbsp; VersionInfo : TOSVersionInfo;<br>&nbsp; OSName : String;<br>&nbsp; begin<br>&nbsp; // set the size of the record<br>&nbsp; VersionInfo.dwOSVersionInfoSize := SizeOf( TOSVersionInfo );<br>&nbsp; if Windows.GetVersionEx( VersionInfo ) then<br>&nbsp; begin<br>&nbsp; with VersionInfo do<br>&nbsp; begin<br>&nbsp; case dwPlatformId of<br>&nbsp; VER_PLATFORM_WIN32s : OSName := 'Win32s';<br>&nbsp; VER_PLATFORM_WIN32_WINDOWS : OSName := 'Windows 95';<br>&nbsp; VER_PLATFORM_WIN32_NT : OSName := 'Windows NT';<br>&nbsp; end; // case dwPlatformId<br>&nbsp; Result := OSName + ' Version ' + IntToStr( dwMajorVersion ) + '.' + IntToStr( dwMinorVersion ) + #13#10' (Build ' + IntToStr( dwBuildNumber ) + ': ' + szCSDVersion + ')';<br>&nbsp; end; // with VersionInfo<br>&nbsp; end // if GetVersionEx<br>&nbsp; else<br>&nbsp; Result := '';<br>&nbsp; end;<br><br>&nbsp; procedure ShutDown;<br>&nbsp; const<br>&nbsp; SE_SHUTDOWN_NAME = 'SeShutdownPrivilege'; // Borland forgot this declaration<br>&nbsp; var<br>&nbsp; hToken : THandle;<br>&nbsp; tkp : TTokenPrivileges;<br>&nbsp; tkpo : TTokenPrivileges;<br>&nbsp; zero : DWORD;<br>&nbsp; begin<br>&nbsp; if Pos( 'Windows NT', GetWinVersion) = 1 then // we've got to do a whole buch of things<br>&nbsp; begin<br>&nbsp; zero := 0;<br>&nbsp; if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then<br>&nbsp; begin<br>&nbsp; MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );<br>&nbsp; Exit;<br>&nbsp; end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)<br><br>&nbsp; if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then<br><br>&nbsp; begin<br><br>&nbsp; MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );<br><br>&nbsp; Exit;<br><br>&nbsp; end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)<br><br><br><br>&nbsp; // SE_SHUTDOWN_NAME<br><br>&nbsp; if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[ 0 ].Luid ) then<br><br>&nbsp; begin<br><br>&nbsp; MessageBox( 0, 'Exit Error', 'LookupPrivilegeValue() Failed', MB_OK );<br><br>&nbsp; Exit;<br><br>&nbsp; end; // if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[0].Luid )<br><br>&nbsp; tkp.PrivilegeCount := 1;<br><br>&nbsp; tkp.Privileges[ 0 ].Attributes := SE_PRIVILEGE_ENABLED;<br><br><br>&nbsp; AdjustTokenPrivileges( hToken, False, tkp, SizeOf( TTokenPrivileges ), tkpo, zero );<br><br>&nbsp; if Boolean( GetLastError() ) then<br><br>&nbsp; begin<br><br>&nbsp; MessageBox( 0, 'Exit Error', 'AdjustTokenPrivileges() Failed', MB_OK );<br><br>&nbsp; Exit;<br><br>&nbsp; end // if Boolean( GetLastError() )<br><br>&nbsp; else<br><br>&nbsp; ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );<br><br>&nbsp; end // if OSVersion = 'Windows NT'<br><br>&nbsp; else<br><br>&nbsp; begin // just shut the machine down<br><br>&nbsp; ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );<br><br>&nbsp; end; // else<br><br>&nbsp; end;<br><br>这个程序适用于所有Windows版本 <br><br><br><br>另给出调整关机权限:<br>procedure TForm1.AdjustToken();<br>var<br>&nbsp; hdlProcessHandle : Cardinal;<br>&nbsp; hdlTokenHandle : Cardinal;<br>&nbsp; tmpLuid : Int64;<br>&nbsp; tkpPrivilegeCount : Int64;<br>&nbsp; tkp : TOKEN_PRIVILEGES;<br>&nbsp; tkpNewButIgnored : TOKEN_PRIVILEGES;<br>&nbsp; lBufferNeeded : Cardinal;<br>&nbsp; Privilege : array[0..0] of _LUID_AND_ATTRIBUTES;<br>begin<br>&nbsp; &nbsp; &nbsp; &nbsp; hdlProcessHandle := GetCurrentProcess;<br>&nbsp; &nbsp; &nbsp; &nbsp; OpenProcessToken(hdlProcessHandle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hdlTokenHandle);<br><br>&nbsp; &nbsp; &nbsp; &nbsp; // Get the LUID for shutdown privilege.<br>&nbsp; &nbsp; &nbsp; &nbsp; LookupPrivilegeValue('', 'SeShutdownPrivilege', tmpLuid);<br>&nbsp; &nbsp; &nbsp; &nbsp; Privilege[0].Luid := tmpLuid;<br>&nbsp; &nbsp; &nbsp; &nbsp; Privilege[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; &nbsp; &nbsp; &nbsp; tkp.PrivilegeCount := 1; &nbsp;// One privilege to set<br>&nbsp; &nbsp; &nbsp; &nbsp; tkp.Privileges[0] := Privilege[0];<br>&nbsp; &nbsp; &nbsp; &nbsp; // Enable the shutdown privilege in the access token of this<br>&nbsp; &nbsp; &nbsp; &nbsp; // process.<br>&nbsp; &nbsp; &nbsp; &nbsp; AdjustTokenPrivileges(hdlTokenHandle,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; False,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tkp,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Sizeof(tkpNewButIgnored),<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tkpNewButIgnored,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; lBufferNeeded);<br><br>end;<br>
 
试了yzhshi的部分代码,尤其是shutdown过程,曾经使我眼前一亮,其中有这么一个常量<br>定义:<br>const<br>&nbsp; SE_SHUTDOWN_NAME = 'SeShutdownPrivilege'; // Borland forgot this declaration<br>但在执行到AdjustTokenPrivileges时还是出错![:(]<br><br>先谢谢前面几位朋友的热心帮助,希望有经过试验成功的高手把所有的原代码都发给我<br>(包括常量和变量的定义等)。<br><br>大家快帮帮我吧
 
我的全部已经拿出来了,看别人的吧[:(],对了,是否是你的计算机的问题?[:D]
 
亲爱的yzhshi,我在两台NT上都试过了,就是不行![?]
 
去找我问过的问题,上面有详细的说明
 
到我的站上下载我个人写的Windows小工具看看,看看在NT下能不能使NT重新启动。<br>下载地址:http://wolfsoft.nugoo.com/download.asp?flag=2&amp;fl1=14&amp;id=1482&amp;keyword=个人程序<br>我试过了可以重起NT,如需要源代码可以给我写信,注明DFW。
 
亲爱的“yylg",我查看了你问过的问题,但似乎你的代码是连编译也没有通过,但我的情况<br>是编译通过,而程序执行起来不见效果。<br>我试了“飘摇客”的小程序,果真能够重启动NT,看来非得向”飘摇客”讨源代码了!<br>
 
我再次阅读了YYLG所提过的问题,然后再试后,果然成功了,真的是版本问题!<br>谢谢各位了,现在开始发分了,请笑纳!
 
后退
顶部