//可以看到C写Win32 APIs Console 程序很方便
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma hdrstop
BOOL SetCurrentPrivilege( LPCTSTR Privilege, BOOL bEnablePrivilege );
void DisplayError( DWORD err );
int main( int argc, char * argv[] )
{
int i, errors = 0, local = 0, timeout = -1, force = 0, reboot = 0, oops = 0;
char *remote = NULL, *message = NULL;
BOOL rc;
if ( argc == 1 )
{
usage:
if ( errors )
putchar( '/n' );
puts( "reboot {-l | -s servername} [-m /"message/"] [-t timeout] [-f] [-r] [-oops]/n" );
puts( "-l reboot local machine" );
puts( "-s servername reboot named computer" );
puts( "-t timeout show a logoff dialog for <timeout> seconds; 0 suppresses it" );
puts( "-m /"message/" display /"message/" in that dialog" );
puts( "-f force apps closed" );
puts( "-r reboot after shutdown" );
puts( "-oops aborts a previous shutdown request (only -l, -s count)" );
return 1;
}
for ( i = 1; i < argc; i ++ )
{
if ( *argv[i] != '-' && *argv[i] != '/' )
{
printf( "/"%s/": switches must start with a '-' or '/' character./n", argv[i] );
errors ++;
continue;
}
++ argv[i];
switch ( *argv[i] )
{
case 'l':
if ( remote != NULL || local != 0 )
{
puts( "Only one of -l and -s may be used." );
++ errors;
}
else
++ local;
break;
case 's':
if ( remote != NULL || local != 0 )
{
puts( "Only one of -l and -s may be used." );
++ errors;
}
else if ( i == argc - 1 )
{
puts( "-s must be followed by the name of the server to shut down." );
++ errors;
}
else
{
++ i;
remote = argv[i];
}
break;
case 't':
if ( timeout != -1 )
{
puts( "Only one timeout may be used." );
++ errors;
}
else if ( i == argc - 1 )
{
puts( "-t must be followed by a timeout." );
++ errors;
}
else
{
++ i;
timeout = atoi( argv[i] );
}
break;
case 'm':
if ( message != NULL )
{
puts( "Only one message may be used." );
++ errors;
}
else if ( i == argc - 1 )
{
puts( "-m must be followed by the message text." );
++ errors;
}
else
{
++ i;
message = argv[i];
}
break;
case 'f':
if ( force )
{
puts( "-f may only be used once." );
++ errors;
}
else
++ force;
break;
case 'r':
if ( reboot )
{
puts( "-r may only be used once." );
++ errors;
}
else
++ reboot;
break;
case 'o':
++ oops;
break;
default:
printf( "/"%s/" is not a valid switch./n", argv[i] - 1 );
++ errors;
break;
}
}
if ( local == 0 && remote == NULL )
{
puts( "One of -l and -s must be used." );
++ errors;
}
if ( ! oops && timeout == -1 ) // no timeout used
{
puts( "Anti-goof feature: you must specify a timeout (0 seconds is OK)" );
++ errors;
}
if ( errors )
goto usage;
if ( local )
{
if ( ! SetCurrentPrivilege( SE_SHUTDOWN_NAME, TRUE ) )
{
DisplayError( GetLastError() );
return 2;
}
}
if ( oops )
{
printf( "/nTrying to abort the shutdown of %s ...", remote? remote: "this computer" );
rc = AbortSystemShutdown( remote );
}
else
{
printf( "/nTrying to shut down %s in %d seconds ...", remote? remote: "this computer", timeout );
rc = InitiateSystemShutdown( remote, message, (DWORD) timeout, force, reboot );
}
putchar( '/n' );
if ( ! rc )
{
DisplayError( GetLastError() );
return 1;
}
return 0;
}
BOOL SetCurrentPrivilege( LPCTSTR Privilege, BOOL bEnablePrivilege )
{
HANDLE hToken;
LUID luid;
TOKEN_PRIVILEGES tp, tpPrevious;
DWORD cbPrevious = sizeof( TOKEN_PRIVILEGES );
BOOL bSuccess = FALSE;
if ( ! LookupPrivilegeValue( NULL, Privilege, &luid ) )
return FALSE;
if( ! OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken ) )
return FALSE;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof( TOKEN_PRIVILEGES ), &tpPrevious, &cbPrevious );
if ( GetLastError() == ERROR_SUCCESS )
{
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
if ( bEnablePrivilege )
tpPrevious.Privileges[0].Attributes |= ( SE_PRIVILEGE_ENABLED );
else
tpPrevious.Privileges[0].Attributes &= ~( SE_PRIVILEGE_ENABLED );
AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL );
if ( GetLastError() == ERROR_SUCCESS )
bSuccess=TRUE;
}
CloseHandle( hToken );
return bSuccess;
}
void DisplayError( DWORD err )
{
char msgbuf[4096];
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT),
msgbuf, sizeof( msgbuf ), NULL );
printf( "Error %d: %s/n", err, msgbuf );
}