#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winperf.h>
#include <tlhelp32.h>
#include <sh.h>
#include <errno.h>
#define REGKEY_PERF "software\\microsoft\\windows nt\\currentversion\\perflib"
#define REGSUBKEY_COUNTERS "Counters"
#define PROCESS_COUNTER "process"
#define PROCESSID_COUNTER "id process"
typedef struct _pslist {
DWORD pid;
HANDLE hwnd;
char exename[MAX_PATH];
char title[80];
}pslist;
typedef BOOL (WINAPI *walker)(HANDLE,LPPROCESSENTRY32);
typedef HANDLE (WINAPI *create_snapshot)(DWORD,DWORD);
static walker proc32First;
static walker proc32Next;
static create_snapshot createSnapshot;
typedef BOOL (WINAPI *enumproc)(DWORD *,DWORD,DWORD *);
typedef BOOL (WINAPI *enummod)(HANDLE,HMODULE*,DWORD,DWORD*);
typedef DWORD(WINAPI *getfilename_ex)(HANDLE,HANDLE , char*,DWORD);
typedef DWORD (WINAPI *getbasename)(HANDLE,HMODULE,char*,DWORD);
static enumproc enum_processes;
static enummod enum_process_modules;
static getfilename_ex getfilenameex;
static getbasename GetModuleBaseNameA;
typedef DWORD (*plist_proc)(void);
DWORD Win95Lister(void);
DWORD NTLister(void);
plist_proc ProcessListFunc;
pslist *processlist;
static unsigned long numprocs, g_dowindows;
static HMODULE hlib;
extern DWORD gdwPlatform;
extern void make_err_str(int,char *,int);
BOOL CALLBACK enum_wincb(HWND hwnd,LPARAM nump) {
unsigned int i;
DWORD pid = 0;
if (!GetWindowThreadProcessId(hwnd,&pid))
return TRUE;
for (i =0;i < nump;i++) {
if (processlist[i].pid == pid){
processlist[i].hwnd = hwnd;
if (processlist[i].title[0] !=0)
break;;
GetWindowText(hwnd,processlist[i].title,
sizeof(processlist[i].title));
break;
}
}
return TRUE;
}
static HWND ghwndtokillbywm_close;
BOOL CALLBACK enum_wincb2(HWND hwnd,LPARAM pidtokill) {
DWORD pid = 0;
if (!GetWindowThreadProcessId(hwnd,&pid))
return TRUE;
if (pid == (DWORD)pidtokill){
ghwndtokillbywm_close = hwnd;
PostMessage( hwnd, WM_CLOSE, 0, 0 );
return TRUE;
}
return TRUE;
}
int kill_by_wm_close(int pid) {
EnumWindows(enum_wincb2,(LPARAM)pid);
if (!ghwndtokillbywm_close)
return -1;
ghwndtokillbywm_close = NULL;
return 0;
}
DWORD Win95Lister(void) {
HANDLE hsnap;
PROCESSENTRY32 pe;
unsigned long nump =0;
hsnap = createSnapshot(TH32CS_SNAPPROCESS,0);
if (hsnap == INVALID_HANDLE_VALUE)
return 0;
pe.dwSize = sizeof(PROCESSENTRY32);
if (proc32First(hsnap,&pe) ) {
processlist = heap_alloc(100*sizeof(pslist));
if (!processlist)
goto done;
do {
StringCbCopy(processlist[nump].exename,
sizeof(processlist[nump].exename),pe.szExeFile);
processlist[nump].title[0] = 0;
processlist[nump].pid = pe.th32ProcessID;
nump++;
}while(proc32Next(hsnap,&pe));
}
done:
CloseHandle(hsnap);
if (g_dowindows) {
EnumWindows(enum_wincb,(LPARAM)nump);
}
return nump;
}
DWORD NTLister(void) {
DWORD procs[200],dummy,ignore;
HANDLE hproc;
HMODULE hmod;
unsigned int i;
if (!enum_processes(procs,sizeof(procs),&dummy) ) {
return 0;
}
dummy = dummy/sizeof(DWORD);
processlist = heap_alloc(dummy*sizeof(pslist));
if (!processlist){
return 0;
}
for(i=0 ; i< dummy;i++) {
processlist[i].pid = procs[i];
processlist[i].title[0] = 0;
hproc = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,
FALSE,procs[i]);
if (hproc) {
if (enum_process_modules(hproc,&hmod,sizeof(hmod),&ignore)) {
GetModuleBaseNameA(hproc,hmod, processlist[i].exename,MAX_PATH);
}
else
StringCbCopy(processlist[i].exename,
sizeof(processlist[i].exename),"(unknown)");
CloseHandle(hproc);
}
else
StringCbCopy(processlist[i].exename,
sizeof(processlist[i].exename),"(unknown)");
}
if (g_dowindows) {
EnumWindows(enum_wincb,(LPARAM)dummy);
}
return dummy;
}
void init_plister(void) {
hlib = LoadLibrary("kernel32.dll");
if (!hlib)
return ;
ProcessListFunc = Win95Lister;
proc32First = (walker)GetProcAddress(hlib,"Process32First");
proc32Next = (walker)GetProcAddress(hlib,"Process32Next");
createSnapshot= (create_snapshot)GetProcAddress(hlib,
"CreateToolhelp32Snapshot");
FreeLibrary(hlib);
if (!proc32First || !proc32Next || !createSnapshot) {
ProcessListFunc = NULL;
}
}
void dops(Char ** vc, struct command *c) {
DWORD nump;
unsigned int i,k;
char **v;
UNREFERENCED_PARAMETER(c);
if (!ProcessListFunc)
return;
vc = glob_all_or_error(vc);
v = short2blk(vc);
blkfree(vc);
for (k = 0; v[k] != NULL ; k++){
if ( v[k][0] == '-' ) {
if( (v[k][1] == 'W') || (v[k][1] == 'w'))
g_dowindows = 1;
}
}
blkfree((Char**)v);
nump = ProcessListFunc();
for(i=0; i< nump; i++) {
if (gdwPlatform == VER_PLATFORM_WIN32_NT)
xprintf("%6u %-20s %-30s\n",processlist[i].pid,
processlist[i].exename,
g_dowindows?processlist[i].title:"");
else
xprintf("0x%08x %-20s %-30s\n",processlist[i].pid,
processlist[i].exename,
g_dowindows?processlist[i].title:"");
}
g_dowindows =0;
if (processlist)
heap_free(processlist);
}
static char shutdown_usage[]= {"shutdown -[r|l][f] now\n-r reboots, -l logs\
off the current user\n-f forces termination of running applications.\n\
The default action is to shutdown without a reboot.\n\"now\" must be \
specified to actually shutdown or reboot\n"};
void doshutdown(Char **vc, struct command *c) {
unsigned int flags = 0;
unsigned char reboot,shutdown,logoff,shutdown_ok;
char **v;
char *ptr;
char errbuf[128];
int k;
HANDLE hToken;
TOKEN_PRIVILEGES tp,tpPrevious;
LUID luid;
DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
UNREFERENCED_PARAMETER(c);
if (gdwPlatform != VER_PLATFORM_WIN32_NT) {
stderror(ERR_SYSTEM,"shutdown","Sorry,not supported on win95");
}
shutdown_ok = reboot = shutdown = logoff = 0;
vc = glob_all_or_error(vc);
v = short2blk(vc);
blkfree(vc);
cleanup_push((Char **)v, blk_cleanup);
for (k = 0; v[k] != NULL ; k++){
if ( v[k][0] == '-' ) {
ptr = v[k];
ptr++;
while( ptr && *ptr) {
if (*ptr == 'f')
flags |= EWX_FORCE;
if (*ptr == 'r')
reboot =1;
else if (*ptr == 'l')
logoff =1;
else
stderror(ERR_SYSTEM,"Usage",shutdown_usage);
ptr++;
}
}
else if (!_stricmp(v[k],"now")) {
shutdown_ok = 1;
}
}
if (k == 0)
stderror(ERR_SYSTEM,"Usage",shutdown_usage);
if (!reboot && !logoff){
flags |= EWX_SHUTDOWN;
shutdown = 1;
}
if (reboot && logoff )
stderror(ERR_SYSTEM,"Usage",shutdown_usage);
if (reboot)
flags |= EWX_REBOOT;
if (logoff)
flags |= EWX_LOGOFF;
if ((reboot || shutdown) && (!shutdown_ok) )
stderror(ERR_SYSTEM,"shutdown","Specify \"now\" to really shutdown");
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY,
&hToken) ){
make_err_str(GetLastError(),errbuf,128);
stderror(ERR_SYSTEM,"shutdown failed",errbuf);
}
if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid)) {
make_err_str(GetLastError(),errbuf,128);
stderror(ERR_SYSTEM,"shutdown failed",errbuf);
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = 0;
if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),&tpPrevious,
&cbPrevious)){
make_err_str(GetLastError(),errbuf,128);
stderror(ERR_SYSTEM,"shutdown failed",errbuf);
}
tpPrevious.PrivilegeCount = 1;
tpPrevious.Privileges[0].Luid = luid;
tpPrevious.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken,FALSE,&tpPrevious,cbPrevious,NULL,
NULL)){
make_err_str(GetLastError(),errbuf,128);
stderror(ERR_SYSTEM,"shutdown failed",errbuf);
}
if ( !ExitWindowsEx(flags,0) ) {
make_err_str(GetLastError(),errbuf,128);
stderror(ERR_SYSTEM,"shutdown failed",errbuf);
}
cleanup_until((Char **)v);
}