• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 201
  • Last Modified:

WIndows NT restart

I would really appreciate some code to Restart my PC using Delphi 5 on Windows NT 4 SP6.
0
skymag
Asked:
skymag
1 Solution
 
JaymolCommented:
I'll give you this code, but the best I've ever had out of it is logging out.  Hope it helps anyway.

procedure CloseWindows(ShutDownType: DWord);
var
  hToken    : THandle;
  tkp, Newt : TTokenPrivileges;
  retlength : DWORD;
begin
  if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
    if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) = False then begin
      tkp.PrivilegeCount:=1;
      tkp.Privileges[0].Attributes:=SE_PRIVILEGE_ENABLED;
      AdjustTokenPrivileges(hToken, False, tkp, SizeOf(TTokenPrivileges), Newt, retlength);
    end;
  ExitWindowsEx(ShutDownType, 0);
end;

If you don't have any luck, shout the magic word......madshi.

Ta,

John.
0
 
MadshiCommented:
Oops... I didn't know that "madshi" is a magic word, is it really?   :-))

Well, what I have looks quite similar to John's code, but perhaps there's a small difference somewhere. At least shutting down and restarting works with my code - as long as you've the nessecary rights...

function AddPrivilege(privilegeName: string) : boolean;
type TPCardinal = ^cardinal;
var c1,c2   : cardinal;
    i64     : int64;
    tp1,tp2 : TTokenPrivileges;
begin
  result:=false;
  if OpenProcessToken(windows.GetCurrentProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,c1) then
    try
      if LookupPrivilegeValue(nil,pchar(privilegeName),i64) then begin
        tp1.PrivilegeCount:=1;
        tp1.Privileges[0].Luid:=i64;
        tp1.Privileges[0].Attributes:=0;
        if AdjustTokenPrivileges(c1,false,tp1,sizeOf(TTokenPrivileges),tp2,c2) then begin
          if (c2=sizeOf(TTokenPrivileges)) and (tp2.PrivilegeCount=1) and (tp2.Privileges[0].Luid=i64) then
            tp1.Privileges[0].Attributes:=tp2.Privileges[0].Attributes;
          tp1.Privileges[0].Attributes:=tp1.Privileges[0].Attributes or SE_PRIVILEGE_ENABLED;
          result:=AdjustTokenPrivileges(c1,false,tp1,sizeOf(TTokenPrivileges),PTokenPrivileges(nil)^,TPCardinal(nil)^);
        end;
      end;
    finally CloseHandle(c1) end;
end;

AddPrivilege('SeShutdownPrivilege');
ExitWindowsEx(EWX_REBOOT, 0);

Regards, Madshi.
0
 
schutnikCommented:
You're in luck, I just wrote a program to do that.

Check it out....

program Restart;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Windows,
  ActiveX;

type
  PCardinal = ^Cardinal;

const
  SE_REMOTE_SHUTDOWN_NAME: PChar = 'SeRemoteShutdownPrivilege';
  SE_SHUTDOWN_NAME: PChar = 'SeShutdownPrivilege';

procedure printAuthor;
begin
  WriteLn('Restart -- Kelly Leahy (01/03/2000)');
  WriteLn('  Restarts the specified host if user has proper privileges');
  WriteLn;
end;

procedure printUsage(doHalt: Boolean);
begin
  WriteLn('Usage:');
  WriteLn('       restart [/h]                                     (show this screen)');
  WriteLn('       restart [/y] [/t:<timeout>] [/p] [hostname]');
  WriteLn;
  WriteLn('Params:');
  WriteLn('  /h            Show help screen');
  WriteLn('  /y            Do not prompt                           (dangerous)');
  WriteLn('  /p            Do not force shutdown of programs');
  WriteLn('  /t:<timeout>  Wait <timeout> seconds before shutdown  (default 5)');
  WriteLn('  hostname      Name of host to reboot                  (nothing for local)');
  WriteLn;
  if doHalt then halt(0);
end;

procedure printParamError(Index: Integer);
begin
  printUsage(false);
  WriteLn('Error: Unknown parameter ''' + paramStr(Index) + '''');
  WriteLn;
  halt(2);
end;

procedure printHostError(host1, host2: String);
begin
  printUsage(false);
  WriteLn('Error: Only one hostname allowed (see next line)');
  WriteLn('  Host1: '''+host1+''', Host2: '''+host2+'''');
  Writeln;
  Halt(3);
end;

function ErrMsg(ErrNo: Integer): String;
var p: PChar;
begin
  FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ALLOCATE_BUFFER,
    nil, ErrNo, 0, PChar(@p), 0, nil);
  Result := String(p);
  LocalFree(HLOCAL(p));
end;

procedure printWindowsError(Action: String; ErrNo: Integer);
begin
  Writeln('Error during action: '''+Action+'''');
  Writeln('Windows error number: 0x'+IntToHex(ErrNo,8));
  Writeln('Error Message: '+ErrMsg(ErrNo));
  Writeln;
  Halt(4);
end;

procedure getTimeout(param: String; var timeOut: Integer);
var
  tmp: Integer;
begin
  try
    tmp := StrToInt(copy(param, 4, length(param) - 3));
    if (tmp < 0) or (tmp > 60) then raise Exception.Create('Dummy');
    timeOut := tmp;
  except
    WriteLn('Invalid timeout: using default of ',timeOut);
    WriteLn;
  end;
end;

var
  // multi purpose variables
  i: Integer;
  // param variables
  noPrompt: Boolean = False;
  hostName: String = '';
  param: String;
  timeOut: Integer = 5;
  forceShutdown: Boolean = True;
  // program variables
  luid : int64;         // luid for security privilege name
  hTok : THandle;       // handle for process token (this process)
  pPrivs : ^TOKEN_PRIVILEGES;
  prompt : String = 'Y';

begin
  // name string
  printAuthor;

  // handle params
  for i := 1 to ParamCount do
  begin
    param := lowerCase(ParamStr(i));
    if param = '/h' then printUsage(true)
    else if param = '/y' then noPrompt := true
    else if param = '/p' then forceShutdown := false
    else if copy(param,1,3) = '/t:' then getTimeout(param, timeOut)
    else if copy(param,1,1) = '/' then printParamError(i)
    else if hostName = '' then hostName := param // set only if first hostname
    else printHostError(hostName, ParamStr(i));  // not allowing 2 or more hosts
  end;
  // only get here if params are ok

  if not noPrompt then begin
    if hostName = '' then
      write('Are you sure you want to reboot this machine (Y/N)?: ')
    else
      write('Are you sure you want to reboot the host ''' + hostname
        + ''' (Y/N)?: ');
    readln(prompt);
  end;

  prompt := LowerCase(Trim(prompt));
  if prompt <> 'y' then
  begin
    writeLn('Action cancelled');
    halt(1);
  end;

  // begin code
  if hostName <> '' then
  begin
    if not LookupPrivilegeValue(PChar(hostName), SE_REMOTE_SHUTDOWN_NAME, luid) then
      printWindowsError('LookupPrivilegeValue',GetLastError);
  end
  else
  begin
    if not LookupPrivilegeValue(nil, SE_SHUTDOWN_NAME, luid) then
      printWindowsError('LookupPrivilegeValue',GetLastError);
  end;
  // if we get here, we have a valid luid for the SHUTDOWN request.

  // try getting the process token
  if not OpenProcessToken(GetCurrentProcess, TOKEN_ALL_ACCESS, hTok) then
    printWindowsError('OpenProcessToken',GetLastError);
  // if we get here, we have a valid process security token

  // try setting the privileges
  Pointer(pPrivs) := CoTaskMemAlloc(4 + sizeof(LUID_AND_ATTRIBUTES));
  pPrivs.PrivilegeCount := 1;
  pPrivs.Privileges[0].Luid := luid;
  pPrivs.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
  if not AdjustTokenPrivileges(hTok, false, pPrivs^, 0, nil, PCardinal(nil)^) then
    printWindowsError('AdjustTokenPrivileges',GetLastError);
  // if we get here, we have successfully adjusted the privileges

  // try to shutdown the specified machine
  if hostName <> '' then begin
    if not InitiateSystemShutdown(PChar(hostname),
      'the application ''Restart'' has initiated a shutdown of this machine',
      timeOut, forceShutdown, true) then
        printWindowsError('InitiateSystemShutdown', GetLastError);
  end
  else begin
    if InitiateSystemShutdown(nil,
      'the application ''Restart'' has initiated a shutdown of this machine',
      timeOut, forceShutdown, true) then
        printWindowsError('InitiateSystemShutdown', GetLastError);
  end;
  WriteLn('System shutdown in progress');
  CloseHandle(hTok);
  CoTaskMemFree(Pointer(pPrivs));
end.


0
 
skymagAuthor Commented:
Thanx for the help guys!
0
 
skymagAuthor Commented:
Thanx for the help guys!
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now