首页  编辑  

重新启动Windows

Tags: /超级猛料/API.Windows应用程序接口/其他相关/   Date Created:

重新启动Windows,不是重新启动机器!包含Thunk技术。

感谢http://www.experts-exchange.com/Q.10115419, 以下代码RestartWindows可以实现:

{$StackFrames On}  //QT_Thunk needs a stack frame, Thunking call to 16-bit USER.EXE. The ThunkTrash argument allocates space on the stack for QT_Thunk

function LoadLibrary16(LibraryName: PChar): THandle; stdcall; external kernel32 index 35;

procedure FreeLibrary16(HInstance: THandle); stdcall; external kernel32 index 36;

function GetProcAddress16(Hinstance: THandle; ProcName: PChar): Pointer; stdcall; external kernel32 index 37;

procedure QT_Thunk; cdecl; external kernel32 name 'QT_Thunk';

var

 hInst16: THandle;

 GFSR: Pointer;

function RestartWindows: WordBool;

var

 ThunkTrash: array[0..$20] of Word;

 dw: DWord;

 w: Word;

begin

 if Win32Platform = VER_PLATFORM_WIN32_NT then

 begin

   Result := False;

   Exit;

 end;

 ThunkTrash[0] := hInst16; //Prevent the optimizer from getting rid of ThunkTrash

 hInst16 := LoadLibrary16('user.exe');

 if hInst16 < 32 then

   raise Exception.Create('Cannot load USER.EXE');

 FreeLibrary16(hInst16); //Decrement the usage count. This doesn't really free the library, since USER.EXE is always loaded

 GFSR := GetProcAddress16(hInst16, 'ExitWindows'); //Get the function pointer for the 16-bit function in USER.EXE

 if GFSR = nil then

   raise Exception.Create('Cannot get address of ExitWindows');

 dw := EW_RestartWindows;

 w  := 0;

 asm  //Thunk down to USER.EXE

   push dw           { push arguments }

   push w

   mov edx, GFSR     { load 16-bit procedure pointer }

   call QT_Thunk     { call thunk }

   mov Result, ax    { save the result }

 end;

end;

{$StackFrames Off}