Link to home
Start Free TrialLog in
Avatar of rpetruni
rpetruni

asked on

InitiateSystemShutdown

How to use this API?
It only works on NT - i know that...
I need to reboot NT from computer on network...
What i don't know is how to set privileges (SE_REMOTE_SHUTDOWN_NAME)

NetworkComp:=\\xxxxx;
if InitiateSystemShutdown(PChar(NetworkComp), nil, 0, true, true)=true then
else ShowMessage('No privileges');
HOW to set SE_REMOTE_SHUTDOWN_NAME so i could reboot this machine?
Avatar of inthe
inthe

hi,
try this one:

SE_SHUTDOWN_NAME is pchar('SeShutdownPrivilege')



   
procedure ExitWindowsNT(uFlags : integer);
var
  hToken : THANDLE;
  tkp, tkDumb : TTokenPrivileges;
  DumbInt : integer;
begin
  FillChar(tkp, sizeof(tkp), 0);
  // Get a token for this process
  if not (OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)) then
     raise Exception.create('OpenProcessToken failed with code '+inttostr(GetLastError));

  // Get the LUID for the Shutdown privilege
  LookupPrivilegeValue(nil, pchar('SeShutdownPrivilege'), tkp.Privileges[0].Luid);

  tkp.PrivilegeCount := 1; // one privilege to set
  tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;

  // Get the shutdown provolege for this process
  AdjustTokenPrivileges(hToken, false, tkp, sizeof(tkDumb), tkDumb, DumbInt);

  // Cannot test the return value of AdjustTokenPrivileges
  if GetLastError <> ERROR_SUCCESS then
     Raise Exception.create('AdjustTokenPrivileges failed with code '+inttostr(GetLastError));

  // shut down the system and for all applications to close
  if not ExitWindowsEx(uFlags, 0) then
     Raise Exception.create('ExitWindowsEx failed with code '+inttostr(GetLastError));
end;


Regards Barry
or this one ive tested on nt a while ago:

uses Windows;
 
procedure XSForceShutdown;
procedure XSForceReboot;
 
implementation
 
type
  XSPriv = packed record
    Count :LongInt;
    Luid :Int64;
    Attr :LongInt;
  end;
 
procedure TurnOnShutDownPrivilege; var Token :Cardinal;  NewPrivilege
:_TOKEN_PRIVILEGES;  OldPrivilege :_TOKEN_PRIVILEGES;  OldLen :DWord;  Priv
:XSPriv absolute NewPrivilege; begin  OpenProcessToken(GetCurrentProcess,
TOKEN_ALL_ACCESS or TOKEN_WRITE, Token);  Priv.Count := 1;
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', Priv.Luid);  Priv.Attr := SE_PRIVILEGE_ENABLED;  AdjustTokenPrivileges(Token, false, NewPrivilege, SizeOf(OldPrivilege), OldPrivilege, OldLen); end;
 
procedure XSForceShutdown;
begin
  TurnOnShutDownPrivilege;
  ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE, 0);
end;
 
procedure XSForceReboot;
begin
  TurnOnShutDownPrivilege;
  ExitWindowsEx(EWX_REBOOT or EWX_FORCE, 0);
end;
 
end.

Regards Barry
or if you like components this one is for win9* and nt:

http://www.torry.webnorth.com/vcl/system/wreboot.zip 


Avatar of rpetruni

ASKER

Inthe,

what i need to do is to reboot WINNT machine from WIN95 workstation....
ExitWindows, and ExitWindowsEx, work only on local machine...
I wil not reject your answer yet, but  i really need something what is working....
I tryed to use your code, and it workes ON LOCAL MACHINE, then i replaced exitWindowsEx with InitiateSystemShutDown, and nothing happens, neither on local machine, neither from WS...
                                                           Robert
im sorry i thought you were using nt - nt not win95 - nt
InitiateSystemShutDown wont work on win95 even though you are sending the message to nt ,win95 doesnt know what it is.
instead of "else ShowMessage('No privileges');"
try doing this:
showmessage(SysErrorMessage(getlasterror())+'!');
and you'll get error 120 which is not a privelege problem but something like not valid win32 opeation..
i really dont think what you are after is possible but you are welcome to reject and see if anyone else says different..but i think they will say the same.
Regards Barry


Yes the code number is 120...
I also tryed to run the program ON NT server, and it returned false on InitiateSystemShutDown function...
This is what i don't understand, because, no error before that...

Does anybody know how to (if possible) reboot NT from Win95 WS?
for testing the function on nt leave the lpmachinename(first parameter) as ''(empty string) and this should cause the local machine to shutdown.
PLEASE SEE:
http://www.jumpingarmadillo.co.uk/RemoteShutdown/faq.htm

WELL THIS IS IMPORTANT BIT:

START QUOTE"
question:
Why does RemoteShutdown say "Windows 95 does not support shutting down remote workstations. It can only be done with WindowsNT" when I select the "remote" tab under Windows95? Can't you sort it out so that it works with Windows95?

answer:
The Win32 SDK function that we use to do remote shutdowns is only supported by Windows NT. This is because Windows95 does not support Remote Procedure Calls (RPCs).

We can think of ways of getting round this (by writing a client-server application that requires the target workstation to be running the client), but we can't see that it would help that many people and it would be a lot of work for us to do it.  It would only really be of use when you have complete control over both machines (for example, the target machine being an unattended remote outstation that you have set up and then left running).  If you're going to run in that kind of configuration for business-critical stuff, you should be running NT anyway.  
"END QUOTE.
Delphi does not have the SE_REMOTE_SHUTDOWN_NAME under its windows.pas declarations either...

Ok, Inthe...
Answer the Q again so i could give you the points :o)
>for testing the function on nt leave the machinename(first parameter) as ''(empty string) and this should cause the local machine to shutdown.


I was passing nil - that was probably the mistake...
ASKER CERTIFIED SOLUTION
Avatar of inthe
inthe

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks...

I just thought I would post this in case you are interested.  I have a small client/server program I wrote a while back that shuts down a remote windows 95/98/NT machine from any other machine on the network.  It is a small command line utility that uses mailslots to send "shutdown" messages to any other computer also running this utility.  I wrote it primarily to allow me to do a "broadcast" shutdown of ALL client machines on the network at one time.  But it has the same problems mentioned in inthe's comment, it must be installed on ALL machines on the network for it to work.  It does work well though.  You type something like "NETSHUTDOWN BOB /Restart /Force" which would restart the machine called "Bob" and have it do a forced restart (ignoring open file messages).  Or you can do "NETSHUTDOWN * /Shutdown" which would shutdown ALL machines on the network running the utility.  It consists of 2 exe files, a sending program (NETSHUTDOWN) and a recieving program (NETSDSRV) which runs as a service in 95/98.  Let me know if you are interested in using it.

Heath
thats good of you heath
cheers for the clarification and  
offering to help rpetruni

:-)
Hi, heathprovost...

you could send me some demo version(like working two days or so), then i will see if i could use it  :o)

rpetruni@zg.tel.hr
I will send it to you sometime this week.  Probably day after tomorrow.  I am out of town right now, so I cant send it till I get back.  Anyway, it isnt a commercial app, no need for the demo stuff.  I dont want anything for it or anything (most of my software I have written for my personal use, and generally consider it freeware if anyone wants copies).  Hell, I will send you the source in case you want to modify it or something.  It really isnt very compicated.

Heath
Thanks heathprovost