This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Rebooting a windows 2000 box


On Thu, Aug 09, 2001 at 03:01:00PM +0200, Norbert Fischer wrote:
> Corinna Vinschen wrote:
> 
> > I wrote the following tiny code in 1998. If you call it `shutdown.exe'
> > it will shutdown, call it `reboot.exe' and it will reboot. Otherwise
> > use the flags.
> 
> Did you write it especially for WinNT/2000 ?

Yes.

> Is it complicated to rewrite it for Win98 ?

No. Try this:

================================================================================
/*
 * shutdown.c: implementation of shutdown(1) as part of a Cygwin environment
 *
 * Copyright 1998,2001  Corinna Vinschen,
 * bug reports to  cygwin@cygwin.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <getopt.h>

#include <windows.h>

static char *SCCSid = "@(#)shutdown V1.1, Corinna Vinschen, " __DATE__ "\n";

char *myname;

int usage(void)
{
	fprintf(stderr, "usage: %s [-fr] secs|\"now\"\n", myname);
	return 1;
}

BOOL (*openprocesstoken)(HANDLE,DWORD,PHANDLE);
BOOL (*adjusttokenprivileges)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
BOOL (*lookupprivilegevalue)(LPCTSTR,LPCTSTR,PLUID);

int setprivs(void)
{
	HANDLE token;
	TOKEN_PRIVILEGES privs;
	HMODULE adv;

	/* Privileges are not supported on 9x/ME. */
	if (GetVersion () >= 0x80000000L)
		return 0;

	if (! (adv = LoadLibrary ("advapi32.dll"))) {
		int ret = GetLastError();
		fprintf(stderr, "%s: can't load advapi32.dll\n", myname);
		return 1;
	}
	if (! (lookupprivilegevalue = (BOOL(*)(LPCTSTR,LPCTSTR,PLUID))
			      GetProcAddress (adv, "LookupPrivilegeValueA"))) {
		int ret = GetLastError();
		fprintf(stderr, "%s: can't load symbol from advapi32.dll\n",
			myname);
		return 1;
	}
	if (! (openprocesstoken = (BOOL(*)(HANDLE,DWORD,PHANDLE))
			      GetProcAddress (adv, "OpenProcessToken"))) {
		int ret = GetLastError();
		fprintf(stderr, "%s: can't load symbol from advapi32.dll\n",
			myname);
		return 1;
	}
	if (! (adjusttokenprivileges = (BOOL(*)(HANDLE,BOOL,PTOKEN_PRIVILEGES,
						DWORD,PTOKEN_PRIVILEGES,PDWORD))
			      GetProcAddress (adv, "AdjustTokenPrivileges"))) {
		int ret = GetLastError();
		fprintf(stderr, "%s: can't load symbol from advapi32.dll\n",
			myname);
		return 1;
	}

	privs.PrivilegeCount = 1;
	lookupprivilegevalue(NULL, SE_SHUTDOWN_NAME, &privs.Privileges[0].Luid);
	privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	if (! openprocesstoken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
			       &token)) {
		int ret = GetLastError();
		fprintf(stderr, "%s: insufficient privileges\n", myname);
		return 1;
	}
	if (! adjusttokenprivileges(token, FALSE, &privs, 0, NULL, NULL)) {
		fprintf(stderr, "%s: insufficient privileges\n", myname);
		return 1;
	}
	return 0;
}

int main(int argc, char **argv)
{
	int c;
	unsigned int secs;
	int action = EWX_POWEROFF;
	int force = 0;


	if ((myname = strrchr(argv[0], '/')) ||
		(myname = strrchr(argv[0], '\\')))
		++myname;
	else
		myname = argv[0];
	if (strrchr(myname, '.'))
		*strrchr(myname, '.') = '\0';
	if (! strcmp(myname, "reboot"))
		action = EWX_REBOOT;
	while ((c = getopt(argc, argv, "fr")) != EOF)
		switch (c) {
		case 'f':
			/* EWX_FORCE doesn't work correctly on 9x/ME. */
			if (GetVersion () < 0x80000000L)
				force = EWX_FORCE;
			break;
		case 'r':
			action = EWX_REBOOT;
			break;
		default:
			return usage();
		}
	if (optind >= argc)
		return usage();
	if (! strcmp(argv[optind], "now"))
		secs = 0;
	else if (! isdigit(argv[optind][0])) {
		usage();
		fprintf(stderr, "%s: secs must be numerical or the word \"now\"\n",
						myname);
		return 2;
	} else
		secs = atoi(argv[optind]);

	if (setprivs())
		return 3;

	printf("WARNING!!! System is going down ");
	if (secs)
		printf("in %d seconds\n", secs);
	else
		printf("NOW\n");
	while (secs)
		secs = sleep(secs);
	if (! ExitWindowsEx(action | force, 0)) {
		fprintf(stderr, "%s: insufficient privileges\n", myname);
		return 3;
	}
	return 0;
}
================================================================================

Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Developer                                mailto:cygwin@cygwin.com
Red Hat, Inc.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]