* autoload.cc: Add dynamic load statements for 'ZwQueryInformationProcess' and

'ZwQueryVirtualMemory'.
* fhandler.h: Change type of bufalloc and filesize members of fhandler_virtual
from int to size_t.  Change type of position member from __off32_t to
__off64_t.  Add new fileid member to fhandler_virtual class.  Make seekdir take
an __off64_t argument.  Make lseek take an __off64_t argument.  Add
fill_filebuf method to fhandler_virtual.  Add fill_filebuf method to
fhandler_proc.  Add fill_filebuf method to fhandler_registry.  Add fill_filebuf
method to fhandler_process.  Add saved_pid and saved_p members to
fhandler_process.
* fhandler_proc.cc (proc_listing_array): Add 'loadavg', 'meminfo', and 'stat'.
(proc_fhandlers array): Ditto.
(fhandler_proc::open): Use fill_filebuf to flesh out the file contents.
(fhandler_proc::fill_filebuf): New method.
(fhandler_proc::format_proc_meminfo): Ditto.
(fhandler_proc::format_proc_stat): Ditto.
(fhandler_proc::format_proc_uptime): Ditto.
* fhandler_process.cc (process_listing): Add 'stat' and 'statm'.
(fhandler_process::fstat): Find the _pinfo structure for the process named in
the filename.  Return ENOENT if the process is no longer around.  Set the gid
and uid fields of the stat structure.
(fhandler_process::open): Store pid and pointer to _pinfo structure in
saved_pid and saved_p respectively.  Use fill_filebuf to flesh out file
contents.
(fhandler_proc::fill_filebuf): New method.
(format_process_stat): New function.
(format_process_status): Ditto.
(format_process_statm): Ditto.
(get_process_state): Ditto.
(get_mem_values): Ditto.
* fhandler_registry.cc (fhandler_registry::seekdir): Change argument type from
__off32_t to __off64_t.
(fhandler_registry::fill_filebuf): New method.
* fhandler_virtual.cc (fhandler_virtual::seekdir): Change argument type from
__off32_t to __off64_t.
(fhandler_virtual::lseek): Ditto.
(fhandler_virtual::fill_filebuf): New method.
(fhandler_virtual::fhandler_virtual): Initialise fileid to -1.
* wincap.cc: Set flag has_process_io_counters appropriately.
* wincap.h: Add flag has_process_io_counters.
This commit is contained in:
Christopher Faylor 2002-05-12 01:37:48 +00:00
parent 558ab81ed1
commit 9ba913a56d
10 changed files with 1059 additions and 131 deletions

View File

@ -1,4 +1,47 @@
2002-05-09 Christopher Faylor <cgf@redhat.com>
2002-05-10 Christopher January <chris@atomice.net>
* autoload.cc: Add dynamic load statements for
'ZwQueryInformationProcess' and 'ZwQueryVirtualMemory'.
* fhandler.h: Change type of bufalloc and filesize members of
fhandler_virtual from int to size_t. Change type of position member
from __off32_t to __off64_t. Add new fileid member to fhandler_virtual
class. Make seekdir take an __off64_t argument. Make lseek take an
__off64_t argument. Add fill_filebuf method to fhandler_virtual. Add
fill_filebuf method to fhandler_proc. Add fill_filebuf method to
fhandler_registry. Add fill_filebuf method to fhandler_process. Add
saved_pid and saved_p members to fhandler_process.
* fhandler_proc.cc (proc_listing_array): Add 'loadavg', 'meminfo', and 'stat'.
(proc_fhandlers array): Ditto.
(fhandler_proc::open): Use fill_filebuf to flesh out the file contents.
(fhandler_proc::fill_filebuf): New method.
(fhandler_proc::format_proc_meminfo): Ditto.
(fhandler_proc::format_proc_stat): Ditto.
(fhandler_proc::format_proc_uptime): Ditto.
* fhandler_process.cc (process_listing): Add 'stat' and 'statm'.
(fhandler_process::fstat): Find the _pinfo structure for the process
named in the filename. Return ENOENT if the process is no longer
around. Set the gid and uid fields of the stat structure.
(fhandler_process::open): Store pid and pointer to _pinfo structure in
saved_pid and saved_p respectively. Use fill_filebuf to flesh out file
contents.
(fhandler_proc::fill_filebuf): New method.
(format_process_stat): New function.
(format_process_status): Ditto.
(format_process_statm): Ditto.
(get_process_state): Ditto.
(get_mem_values): Ditto.
* fhandler_registry.cc (fhandler_registry::seekdir): Change argument
type from __off32_t to __off64_t.
(fhandler_registry::fill_filebuf): New method.
* fhandler_virtual.cc (fhandler_virtual::seekdir): Change argument type
from __off32_t to __off64_t.
(fhandler_virtual::lseek): Ditto.
(fhandler_virtual::fill_filebuf): New method.
(fhandler_virtual::fhandler_virtual): Initialise fileid to -1.
* wincap.cc: Set flag has_process_io_counters appropriately.
* wincap.h: Add flag has_process_io_counters.
2002-05-09 Christopher Faylor <cgf@redhat.com>
* syscalls.cc (_write): Change error to EBADF if attempt to write to a
non-writable fd.

View File

@ -381,6 +381,8 @@ LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
LoadDLLfuncEx (ZwQueryInformationProcess, 20, ntdll, 1)
LoadDLLfuncEx (ZwQueryVirtualMemory, 24, ntdll, 1)
LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)

View File

@ -1043,8 +1043,9 @@ class fhandler_virtual : public fhandler_base
{
protected:
char *filebuf;
int bufalloc, filesize;
__off32_t position;
size_t bufalloc, filesize;
__off64_t position;
int fileid; // unique within each class
public:
fhandler_virtual (DWORD devtype);
@ -1053,16 +1054,17 @@ class fhandler_virtual : public fhandler_base
virtual int exists(const char *path);
DIR *opendir (path_conv& pc);
__off64_t telldir (DIR *);
void seekdir (DIR *, __off32_t);
void seekdir (DIR *, __off64_t);
void rewinddir (DIR *);
int closedir (DIR *);
int write (const void *ptr, size_t len);
int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
__off64_t lseek (__off32_t, int);
__off64_t lseek (__off64_t, int);
int dup (fhandler_base * child);
int open (path_conv *, int flags, mode_t mode = 0);
int close (void);
int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
virtual void fill_filebuf ();
};
class fhandler_proc: public fhandler_virtual
@ -1076,6 +1078,7 @@ class fhandler_proc: public fhandler_virtual
int open (path_conv *real_path, int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
void fill_filebuf ();
};
class fhandler_registry: public fhandler_proc
@ -1085,23 +1088,29 @@ class fhandler_registry: public fhandler_proc
int exists(const char *path);
struct dirent *readdir (DIR *);
__off64_t telldir (DIR *);
void seekdir (DIR *, __off32_t);
void seekdir (DIR *, __off64_t);
void rewinddir (DIR *);
int closedir (DIR *);
int open (path_conv *real_path, int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
HKEY open_key(const char *name, REGSAM access = KEY_READ, bool isValue = false);
void fill_filebuf ();
};
struct _pinfo;
class fhandler_process: public fhandler_proc
{
private:
pid_t saved_pid;
_pinfo *saved_p;
public:
fhandler_process ();
int exists(const char *path);
struct dirent *readdir (DIR *);
int open (path_conv *real_path, int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
void fill_filebuf ();
};
typedef union

View File

@ -14,6 +14,7 @@ details. */
#include <unistd.h>
#include <stdlib.h>
#include <sys/cygwin.h>
#include <ntdef.h>
#include "cygerrno.h"
#include "security.h"
#include "fhandler.h"
@ -24,20 +25,27 @@ details. */
#include "cygheap.h"
#include <assert.h>
#include <sys/utsname.h>
#include "ntdll.h"
#define _COMPILING_NEWLIB
#include <dirent.h>
/* offsets in proc_listing */
static const int PROC_REGISTRY = 2; // /proc/registry
static const int PROC_VERSION = 3; // /proc/version
static const int PROC_UPTIME = 4; // /proc/uptime
static const int PROC_LOADAVG = 2; // /proc/loadavg
static const int PROC_MEMINFO = 3; // /proc/meminfo
static const int PROC_REGISTRY = 4; // /proc/registry
static const int PROC_STAT = 5; // /proc/stat
static const int PROC_VERSION = 6; // /proc/version
static const int PROC_UPTIME = 7; // /proc/uptime
/* names of objects in /proc */
static const char *proc_listing[] = {
".",
"..",
"loadavg",
"meminfo",
"registry",
"stat",
"version",
"uptime",
NULL
@ -48,11 +56,14 @@ static const int PROC_LINK_COUNT = (sizeof(proc_listing) / sizeof(const char *))
/* FH_PROC in the table below means the file/directory is handles by
* fhandler_proc.
*/
static const DWORD proc_fhandlers[] = {
static const DWORD proc_fhandlers[PROC_LINK_COUNT] = {
FH_PROC,
FH_PROC,
FH_PROC,
FH_PROC,
FH_REGISTRY,
FH_PROC,
FH_PROC,
FH_PROC
};
@ -60,6 +71,10 @@ static const DWORD proc_fhandlers[] = {
const char proc[] = "/proc";
const int proc_len = sizeof (proc) - 1;
static off_t format_proc_meminfo (char *destbuf, size_t maxsize);
static off_t format_proc_stat (char *destbuf, size_t maxsize);
static off_t format_proc_uptime (char *destbuf, size_t maxsize);
/* auxillary function that returns the fhandler associated with the given path
* this is where it would be nice to have pattern matching in C - polymorphism
* just doesn't cut it
@ -291,33 +306,9 @@ fhandler_proc::open (path_conv *pc, int flags, mode_t mode)
res = 0;
goto out;
}
switch (proc_file_no)
{
case PROC_VERSION:
{
struct utsname uts_name;
uname (&uts_name);
filesize = bufalloc = strlen (uts_name.sysname) + 1 +
strlen (uts_name.release) + 1 + strlen (uts_name.version) + 2;
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
__small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
uts_name.release, uts_name.version);
break;
}
case PROC_UPTIME:
{
/* GetTickCount() wraps after 49 days - on WinNT/2000/XP, should use
* perfomance counters but I don't know Redhat's policy on
* NT only dependancies.
*/
DWORD ticks = GetTickCount ();
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
__small_sprintf (filebuf, "%d.%02d\n", ticks / 1000,
(ticks / 10) % 100);
filesize = strlen (filebuf);
break;
}
}
fileid = proc_file_no;
fill_filebuf ();
if (flags & O_APPEND)
position = filesize;
@ -332,3 +323,197 @@ out:
syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
return res;
}
void
fhandler_proc::fill_filebuf ()
{
switch (fileid)
{
case PROC_VERSION:
{
if (!filebuf)
{
struct utsname uts_name;
uname (&uts_name);
bufalloc = strlen (uts_name.sysname) + 1 + strlen (uts_name.release) +
1 + strlen (uts_name.version) + 2;
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
filesize = __small_sprintf (filebuf, "%s %s %s\n", uts_name.sysname,
uts_name.release, uts_name.version);
}
break;
}
case PROC_UPTIME:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 80);
filesize = format_proc_uptime (filebuf, bufalloc);
break;
}
case PROC_STAT:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
filesize = format_proc_stat (filebuf, bufalloc);
break;
}
case PROC_LOADAVG:
{
/*
* not really supported - Windows doesn't keep track of these values
* Windows 95/98/me does have the KERNEL/CPUUsage performance counter
* which is similar.
*/
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 16);
filesize = __small_sprintf (filebuf, "%u.%02u %u.%02u %u.%02u\n",
0, 0, 0, 0, 0, 0);
break;
}
case PROC_MEMINFO:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
filesize = format_proc_meminfo (filebuf, bufalloc);
break;
}
}
}
static
off_t
format_proc_meminfo (char *destbuf, size_t maxsize)
{
unsigned long mem_total = 0UL, mem_free = 0UL, swap_total = 0UL,
swap_free = 0UL;
MEMORYSTATUS memory_status;
GlobalMemoryStatus (&memory_status);
mem_total = memory_status.dwTotalPhys;
mem_free = memory_status.dwAvailPhys;
swap_total = memory_status.dwTotalPageFile;
swap_free = memory_status.dwAvailPageFile;
return __small_sprintf (destbuf, " total: used: free:\n"
"Mem: %10lu %10lu %10lu\n"
"Swap: %10lu %10lu %10lu\n"
"MemTotal: %10lu kB\n"
"MemFree: %10lu kB\n"
"MemShared: 0 kB\n"
"HighTotal: 0 kB\n"
"HighFree: 0 kB\n"
"LowTotal: %10lu kB\n"
"LowFree: %10lu kB\n"
"SwapTotal: %10lu kB\n"
"SwapFree: %10lu kB\n",
mem_total, mem_total - mem_free, mem_free,
swap_total, swap_total - swap_free, swap_free,
mem_total >> 10, mem_free >> 10,
mem_total >> 10, mem_free >> 10,
swap_total >> 10, swap_free >> 10);
}
static
off_t
format_proc_uptime (char *destbuf, size_t maxsize)
{
unsigned long long uptime = 0ULL, idle_time = 0ULL;
SYSTEM_PROCESSOR_TIMES spt;
NTSTATUS ret = ZwQuerySystemInformation (SystemProcessorTimes, (PVOID) &spt,
sizeof spt, NULL);
if (!ret && GetLastError () == ERROR_PROC_NOT_FOUND)
uptime = GetTickCount() / 10;
else if (ret != STATUS_SUCCESS)
{
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
debug_printf("NtQuerySystemInformation: ret = %d, "
"Dos(ret) = %d",
ret, RtlNtStatusToDosError (ret));
return 0;
}
else
{
idle_time = spt.IdleTime.QuadPart / 100000ULL;
uptime = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
spt.DpcTime.QuadPart) / 100000ULL;
}
return __small_sprintf (destbuf, "%U.%02u %U.%02u\n",
uptime / 100, long (uptime % 100),
idle_time / 100, long (idle_time % 100));
}
static
off_t
format_proc_stat (char *destbuf, size_t maxsize)
{
unsigned long long user_time = 0ULL, kernel_time = 0ULL, idle_time = 0ULL;
unsigned long pages_in = 0UL, pages_out = 0UL, interrupt_count = 0UL,
context_switches = 0UL, swap_in = 0UL, swap_out = 0UL;
time_t boot_time = 0;
if (wincap.is_winnt ())
{
NTSTATUS ret;
SYSTEM_PROCESSOR_TIMES spt;
SYSTEM_PERFORMANCE_INFORMATION spi;
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
ret = ZwQuerySystemInformation (SystemProcessorTimes,
(PVOID) &spt,
sizeof spt, NULL);
if (ret == STATUS_SUCCESS)
ret = ZwQuerySystemInformation (SystemPerformanceInformation,
(PVOID) &spi,
sizeof spi, NULL);
if (ret == STATUS_SUCCESS)
ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
(PVOID) &stodi,
sizeof stodi, NULL);
if (ret != STATUS_SUCCESS)
{
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
debug_printf("NtQuerySystemInformation: ret = %d, "
"Dos(ret) = %d",
ret, RtlNtStatusToDosError (ret));
return 0;
}
kernel_time = (spt.KernelTime.QuadPart + spt.InterruptTime.QuadPart + spt.DpcTime.QuadPart) / 100000ULL;
user_time = spt.UserTime.QuadPart / 100000ULL;
idle_time = spt.IdleTime.QuadPart / 100000ULL;
interrupt_count = spt.InterruptCount;
pages_in = spi.PagesRead;
pages_out = spi.PagefilePagesWritten + spi.MappedFilePagesWritten;
/*
* Note: there is no distinction made in this structure between pages
* read from the page file and pages read from mapped files, but there
* is such a distinction made when it comes to writing. Goodness knows
* why. The value of swap_in, then, will obviously be wrong but its our
* best guess.
*/
swap_in = spi.PagesRead;
swap_out = spi.PagefilePagesWritten;
context_switches = spi.ContextSwitches;
boot_time = to_time_t ((FILETIME *) &stodi.BootTime.QuadPart);
}
/*
* else
* {
* There are only two relevant performance counters on Windows 95/98/me,
* VMM/cPageIns and VMM/cPageOuts. The extra effort needed to read these
* counters is by no means worth it.
* }
*/
return __small_sprintf (destbuf, "cpu %U %U %U %U\n"
"page %u %u\n"
"swap %u %u\n"
"intr %u\n"
"ctxt %u\n"
"btime %u\n",
user_time, 0ULL,
kernel_time, idle_time,
pages_in, pages_out,
swap_in, swap_out,
interrupt_count,
context_switches,
boot_time);
}

View File

@ -14,6 +14,7 @@ details. */
#include <unistd.h>
#include <stdlib.h>
#include <sys/cygwin.h>
#include <ntdef.h>
#include "cygerrno.h"
#include "security.h"
#include "fhandler.h"
@ -23,6 +24,7 @@ details. */
#include "shared_info.h"
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
#include <assert.h>
#define _COMPILING_NEWLIB
@ -38,6 +40,8 @@ static const int PROCESS_GID = 8;
static const int PROCESS_PGID = 9;
static const int PROCESS_SID = 10;
static const int PROCESS_CTTY = 11;
static const int PROCESS_STAT = 12;
static const int PROCESS_STATM = 13;
static const char *process_listing[] = {
".",
@ -52,11 +56,20 @@ static const char *process_listing[] = {
"pgid",
"sid",
"ctty",
"stat",
"statm",
NULL
};
static const int PROCESS_LINK_COUNT = (sizeof(process_listing) / sizeof(const char *)) - 1;
static off_t format_process_stat (_pinfo *p, char *destbuf, size_t maxsize);
static off_t format_process_status (_pinfo *p, char *destbuf, size_t maxsize);
static off_t format_process_statm (_pinfo *p, char *destbuf, size_t maxsize);
static int get_process_state (DWORD dwProcessId);
static bool get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare);
/* Returns 0 if path doesn't exist, >0 if path is a directory,
* <0 if path is a file.
*/
@ -84,8 +97,26 @@ fhandler_process::fhandler_process ():
int
fhandler_process::fstat (struct __stat64 *buf, path_conv *pc)
{
int file_type = exists (get_name ());
const char *path = get_name ();
int file_type = exists (path);
(void) fhandler_base::fstat (buf, pc);
path += proc_len + 1;
int pid = atoi (path);
winpids pids;
_pinfo *p;
for (unsigned i = 0; i < pids.npids; i++)
{
p = pids[i];
if (!proc_exists (p))
continue;
if (p->pid == pid)
goto found;
}
set_errno(ENOENT);
return -1;
found:
buf->st_mode &= ~_IFMT & NO_W;
switch (file_type)
@ -97,12 +128,18 @@ fhandler_process::fstat (struct __stat64 *buf, path_conv *pc)
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
return 0;
case 2:
buf->st_ctime = buf->st_mtime = p->start_time;
buf->st_atime = time(NULL);
buf->st_uid = p->uid;
buf->st_gid = p->gid;
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
buf->st_nlink = PROCESS_LINK_COUNT;
return 0;
default:
case -1:
buf->st_mode |= S_IFREG;
buf->st_uid = p->uid;
buf->st_gid = p->gid;
buf->st_mode |= S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
return 0;
}
}
@ -198,91 +235,10 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
res = 0;
goto out;
found:
switch (process_file_no)
{
case PROCESS_UID:
case PROCESS_GID:
case PROCESS_PGID:
case PROCESS_SID:
case PROCESS_CTTY:
case PROCESS_PPID:
{
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
int num;
switch (process_file_no)
{
case PROCESS_PPID:
num = p->ppid;
break;
case PROCESS_UID:
num = p->uid;
break;
case PROCESS_PGID:
num = p->pgid;
break;
case PROCESS_SID:
num = p->sid;
break;
default:
case PROCESS_CTTY:
num = p->ctty;
break;
}
__small_sprintf (filebuf, "%d\n", num);
filesize = strlen (filebuf);
break;
}
case PROCESS_EXENAME:
{
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
strcpy (filebuf, "<defunct>");
else
{
mount_table->conv_to_posix_path (p->progname, filebuf, 1);
int len = strlen (filebuf);
if (len > 4)
{
char *s = filebuf + len - 4;
if (strcasecmp (s, ".exe") == 0)
*s = 0;
}
}
filesize = strlen (filebuf);
break;
}
case PROCESS_WINPID:
{
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
__small_sprintf (filebuf, "%d\n", p->dwProcessId);
filesize = strlen (filebuf);
break;
}
case PROCESS_WINEXENAME:
{
int len = strlen (p->progname);
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
strcpy (filebuf, p->progname);
filebuf[len] = '\n';
filesize = len + 1;
break;
}
case PROCESS_STATUS:
{
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 3);
filebuf[0] = ' ';
filebuf[1] = '\n';
filebuf[2] = 0;
if (p->process_state & PID_STOPPED)
filebuf[0] = 'S';
else if (p->process_state & PID_TTYIN)
filebuf[0] = 'I';
else if (p->process_state & PID_TTYOU)
filebuf[0] = 'O';
filesize = 2;
break;
}
}
fileid = process_file_no;
saved_pid = pid;
saved_p = p;
fill_filebuf ();
if (flags & O_APPEND)
position = filesize;
@ -297,3 +253,501 @@ out:
syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
return res;
}
void
fhandler_process::fill_filebuf ()
{
// has this process gone away?
if (!proc_exists (saved_p) || saved_p->pid != saved_pid)
{
if (filebuf)
cfree(filebuf);
filesize = 0; bufalloc = (size_t) -1;
}
switch (fileid)
{
case PROCESS_UID:
case PROCESS_GID:
case PROCESS_PGID:
case PROCESS_SID:
case PROCESS_CTTY:
case PROCESS_PPID:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
int num;
switch (fileid)
{
case PROCESS_PPID:
num = saved_p->ppid;
break;
case PROCESS_UID:
num = saved_p->uid;
break;
case PROCESS_PGID:
num = saved_p->pgid;
break;
case PROCESS_SID:
num = saved_p->sid;
break;
case PROCESS_GID:
num = saved_p->gid;
break;
case PROCESS_CTTY:
num = saved_p->ctty;
break;
default: // what's this here for?
num = 0;
break;
}
__small_sprintf (filebuf, "%d\n", num);
filesize = strlen (filebuf);
break;
}
case PROCESS_EXENAME:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
if (saved_p->process_state & (PID_ZOMBIE | PID_EXITED))
strcpy (filebuf, "<defunct>");
else
{
mount_table->conv_to_posix_path (saved_p->progname, filebuf, 1);
int len = strlen (filebuf);
if (len > 4)
{
char *s = filebuf + len - 4;
if (strcasecmp (s, ".exe") == 0)
*s = 0;
}
}
filesize = strlen (filebuf);
break;
}
case PROCESS_WINPID:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
__small_sprintf (filebuf, "%d\n", saved_p->dwProcessId);
filesize = strlen (filebuf);
break;
}
case PROCESS_WINEXENAME:
{
int len = strlen (saved_p->progname);
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
strcpy (filebuf, saved_p->progname);
filebuf[len] = '\n';
filesize = len + 1;
break;
}
case PROCESS_STATUS:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
filesize = format_process_status (saved_p, filebuf, bufalloc);
break;
}
case PROCESS_STAT:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
filesize = format_process_stat (saved_p, filebuf, bufalloc);
break;
}
case PROCESS_STATM:
{
if (!filebuf)
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
filesize = format_process_statm (saved_p, filebuf, bufalloc);
break;
}
}
}
static
off_t
format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
{
char cmd[MAX_PATH];
int state = 'R';
unsigned long fault_count = 0UL,
utime = 0UL, stime = 0UL,
start_time = 0UL,
vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
int priority = 0;
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
strcpy (cmd, "<defunct");
else
{
strcpy(cmd, p->progname);
char *last_slash = strrchr (cmd, '\\');
if (last_slash != NULL)
strcpy (cmd, last_slash + 1);
int len = strlen (cmd);
if (len > 4)
{
char *s = cmd + len - 4;
if (strcasecmp (s, ".exe") == 0)
*s = 0;
}
}
/*
* Note: under Windows, a _process_ is always running - it's only _threads_
* that get suspended. Therefore the default state is R (runnable).
*/
if (p->process_state & PID_ZOMBIE)
state = 'Z';
else if (p->process_state & PID_STOPPED)
state = 'T';
else if (wincap.is_winnt ())
state = get_process_state (p->dwProcessId);
if (wincap.is_winnt ())
{
NTSTATUS ret;
HANDLE hProcess;
VM_COUNTERS vmc;
KERNEL_USER_TIMES put;
PROCESS_BASIC_INFORMATION pbi;
QUOTA_LIMITS ql;
SYSTEM_TIME_OF_DAY_INFORMATION stodi;
SYSTEM_PROCESSOR_TIMES spt;
hProcess = OpenProcess (PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
FALSE, p->dwProcessId);
if (hProcess != NULL)
{
ret = ZwQueryInformationProcess (hProcess,
ProcessVmCounters,
(PVOID) &vmc,
sizeof vmc, NULL);
if (ret == STATUS_SUCCESS)
ret = ZwQueryInformationProcess (hProcess,
ProcessTimes,
(PVOID) &put,
sizeof put, NULL);
if (ret == STATUS_SUCCESS)
ret = ZwQueryInformationProcess (hProcess,
ProcessBasicInformation,
(PVOID) &pbi,
sizeof pbi, NULL);
if (ret == STATUS_SUCCESS)
ret = ZwQueryInformationProcess (hProcess,
ProcessQuotaLimits,
(PVOID) &ql,
sizeof ql, NULL);
CloseHandle (hProcess);
}
else
{
DWORD error = GetLastError ();
__seterrno_from_win_error (error);
debug_printf("OpenProcess: ret = %d",
error);
return 0;
}
if (ret == STATUS_SUCCESS)
ret = ZwQuerySystemInformation (SystemTimeOfDayInformation,
(PVOID) &stodi,
sizeof stodi, NULL);
if (ret == STATUS_SUCCESS)
ret = ZwQuerySystemInformation (SystemProcessorTimes,
(PVOID) &spt,
sizeof spt, NULL);
if (ret != STATUS_SUCCESS)
{
__seterrno_from_win_error (RtlNtStatusToDosError (ret));
debug_printf("NtQueryInformationProcess: ret = %d, "
"Dos(ret) = %d",
ret, RtlNtStatusToDosError (ret));
return 0;
}
fault_count = vmc.PageFaultCount;
utime = put.UserTime.QuadPart / 100000ULL;
stime = put.KernelTime.QuadPart / 100000ULL;
if (stodi.CurrentTime.QuadPart > put.CreateTime.QuadPart)
start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
spt.DpcTime.QuadPart - stodi.CurrentTime.QuadPart +
put.CreateTime.QuadPart) / 100000ULL;
else
/*
* sometimes stodi.CurrentTime is a bit behind
* Note: some older versions of procps are broken and can't cope
* with process start times > time(NULL).
*/
start_time = (spt.InterruptTime.QuadPart + spt.KernelTime.QuadPart +
spt.IdleTime.QuadPart + spt.UserTime.QuadPart +
spt.DpcTime.QuadPart) / 100000ULL;
priority = pbi.BasePriority;
unsigned page_size = getpagesize();
vmsize = vmc.VirtualSize;
vmrss = vmc.WorkingSetSize / page_size;
vmmaxrss = ql.MaximumWorkingSetSize / page_size;
}
else
{
start_time = (GetTickCount() / 1000 - time(NULL) + p->start_time) * 100;
}
return __small_sprintf (destbuf, "%d (%s) %c "
"%d %d %d %d %d "
"%lu %lu %lu %lu %lu %lu %lu "
"%ld %ld %ld %ld %ld %ld "
"%lu %lu "
"%ld "
"%lu",
p->pid, cmd,
state,
p->ppid, p->pgid, p->sid, p->ctty, -1,
0, fault_count, fault_count, 0, 0, utime, stime,
utime, stime, priority, 0, 0, 0,
start_time, vmsize,
vmrss, vmmaxrss
);
}
static
off_t
format_process_status (_pinfo *p, char *destbuf, size_t maxsize)
{
char cmd[MAX_PATH];
int state = 'R';
const char *state_str = "unknown";
unsigned long vmsize = 0UL, vmrss = 0UL, vmdata = 0UL, vmlib = 0UL, vmtext = 0UL,
vmshare = 0UL;
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
strcpy (cmd, "<defunct>");
else
{
strcpy(cmd, p->progname);
char *last_slash = strrchr (cmd, '\\');
if (last_slash != NULL)
strcpy (cmd, last_slash + 1);
int len = strlen (cmd);
if (len > 4)
{
char *s = cmd + len - 4;
if (strcasecmp (s, ".exe") == 0)
*s = 0;
}
}
/*
* Note: under Windows, a _process_ is always running - it's only _threads_
* that get suspended. Therefore the default state is R (runnable).
*/
if (p->process_state & PID_ZOMBIE)
state = 'Z';
else if (p->process_state & PID_STOPPED)
state = 'T';
else if (wincap.is_winnt ())
state = get_process_state (p->dwProcessId);
switch (state)
{
case 'O':
state_str = "running";
break;
case 'D':
case 'S':
state_str = "sleeping";
break;
case 'R':
state_str = "runnable";
break;
case 'Z':
state_str = "zombie";
break;
case 'T':
state_str = "stopped";
break;
}
if (wincap.is_winnt ())
{
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
return 0;
unsigned page_size = getpagesize();
vmsize *= page_size; vmrss *= page_size; vmdata *= page_size;
vmtext *= page_size; vmlib *= page_size;
}
return __small_sprintf (destbuf, "Name: %s\n"
"State: %c (%s)\n"
"Tgid: %d\n"
"Pid: %d\n"
"PPid: %d\n"
"Uid: %d %d %d %d\n"
"Gid: %d %d %d %d\n"
"VmSize: %8d kB\n"
"VmLck: %8d kB\n"
"VmRSS: %8d kB\n"
"VmData: %8d kB\n"
"VmStk: %8d kB\n"
"VmExe: %8d kB\n"
"VmLib: %8d kB\n"
"SigPnd: %016x\n"
"SigBlk: %016x\n"
"SigIgn: %016x\n",
cmd,
state, state_str,
p->pgid,
p->pid,
p->ppid,
p->uid, cygheap->user.real_uid, cygheap->user.real_uid, p->uid,
p->gid, cygheap->user.real_gid, cygheap->user.real_gid, p->gid,
vmsize >> 10, 0, vmrss >> 10, vmdata >> 10, 0, vmtext >> 10, vmlib >> 10,
0, 0, p->getsigmask ()
);
}
static
off_t
format_process_statm (_pinfo *p, char *destbuf, size_t maxsize)
{
unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL, vmlib = 0UL,
vmshare = 0UL;
if (wincap.is_winnt ())
{
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
return 0;
}
return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld",
vmsize, vmrss, vmshare, vmtext, vmlib, vmdata, 0
);
}
static
int
get_process_state (DWORD dwProcessId)
{
/*
* This isn't really heavy magic - just go through the processes'
* threads one by one and return a value accordingly
* Errors are silently ignored.
*/
NTSTATUS ret;
SYSTEM_PROCESSES *sp;
ULONG n = 0x1000;
PULONG p = new ULONG[n];
int state =' ';
while (STATUS_INFO_LENGTH_MISMATCH ==
(ret = ZwQuerySystemInformation (SystemProcessesAndThreadsInformation,
(PVOID) p,
n * sizeof *p, NULL)))
delete [] p, p = new ULONG[n *= 2];
if (ret != STATUS_SUCCESS)
{
debug_printf("NtQuerySystemInformation: ret = %d, "
"Dos(ret) = %d",
ret, RtlNtStatusToDosError (ret));
goto out;
}
state = 'Z';
sp = (SYSTEM_PROCESSES *) p;
for (;;)
{
if (sp->ProcessId == dwProcessId)
{
SYSTEM_THREADS *st;
if (wincap.has_process_io_counters ())
/*
* Windows 2000 and XP have an extra member in SYSTEM_PROCESSES
* which means the offset of the first SYSTEM_THREADS entry is
* different on these operating systems compared to NT 4.
*/
st = &sp->Threads[0];
else
/*
* 136 is the offset of the first SYSTEM_THREADS entry on
* Windows NT 4.
*/
st = (SYSTEM_THREADS *) ((char *) sp + 136);
state = 'S';
for (unsigned i = 0; i < sp->ThreadCount; i++)
{
if (st->State == StateRunning ||
st->State == StateReady)
{
state = 'R';
goto out;
}
st++;
}
break;
}
if (!sp->NextEntryDelta)
break;
sp = (SYSTEM_PROCESSES *) ((char *) sp + sp->NextEntryDelta);
}
out:
delete [] p;
return state;
}
static
bool
get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare)
{
bool res = true;
NTSTATUS ret;
HANDLE hProcess;
VM_COUNTERS vmc;
MEMORY_WORKING_SET_LIST *mwsl;
ULONG n = 0x1000, length;
PULONG p = new ULONG[n];
unsigned page_size = getpagesize();
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION,
FALSE, dwProcessId);
if (hProcess == NULL)
{
DWORD error = GetLastError();
__seterrno_from_win_error (error);
debug_printf("OpenProcess: ret = %d",
error);
return false;
}
while ((ret = ZwQueryVirtualMemory (hProcess, 0,
MemoryWorkingSetList,
(PVOID) p,
n * sizeof *p, &length)),
(ret == STATUS_SUCCESS || ret == STATUS_INFO_LENGTH_MISMATCH) &&
length >= n * sizeof *p)
delete [] p, p = new ULONG[n *= 2];
if (ret != STATUS_SUCCESS)
{
debug_printf("NtQueryVirtualMemory: ret = %d, "
"Dos(ret) = %d",
ret, RtlNtStatusToDosError (ret));
res = false;
goto out;
}
mwsl = (MEMORY_WORKING_SET_LIST *) p;
for (unsigned long i = 0; i < mwsl->NumberOfPages; i++)
{
++*vmrss;
unsigned flags = mwsl->WorkingSetList[i] & 0x0FFF;
if (flags & (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE) == (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE))
++*vmlib;
else if (flags & WSLE_PAGE_SHAREABLE)
++*vmshare;
else if (flags & WSLE_PAGE_EXECUTE)
++*vmtext;
else
++*vmdata;
}
ret = ZwQueryInformationProcess (hProcess,
ProcessVmCounters,
(PVOID) &vmc,
sizeof vmc, NULL);
if (ret != STATUS_SUCCESS)
{
debug_printf("NtQueryInformationProcess: ret = %d, "
"Dos(ret) = %d",
ret, RtlNtStatusToDosError (ret));
res = false;
goto out;
}
*vmsize = vmc.VirtualSize / page_size;
out:
delete [] p;
CloseHandle (hProcess);
return res;
}

View File

@ -292,7 +292,7 @@ fhandler_registry::telldir (DIR * dir)
}
void
fhandler_registry::seekdir (DIR * dir, __off32_t loc)
fhandler_registry::seekdir (DIR * dir, __off64_t loc)
{
/* Unfortunately cannot simply set __d_position due to transition from sub-keys to
* values.
@ -490,6 +490,11 @@ out:
return res;
}
void
fhandler_registry::fill_filebuf ()
{
}
/* Auxillary member function to open registry keys. */
HKEY
fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)

View File

@ -27,7 +27,8 @@ details. */
#include <dirent.h>
fhandler_virtual::fhandler_virtual (DWORD devtype):
fhandler_base (devtype), filebuf (NULL), bufalloc (-1)
fhandler_base (devtype), filebuf (NULL), bufalloc ((size_t) -1),
fileid (-1)
{
}
@ -89,7 +90,7 @@ __off64_t fhandler_virtual::telldir (DIR * dir)
}
void
fhandler_virtual::seekdir (DIR * dir, __off32_t loc)
fhandler_virtual::seekdir (DIR * dir, __off64_t loc)
{
dir->__d_position = loc;
return;
@ -109,8 +110,13 @@ fhandler_virtual::closedir (DIR * dir)
}
__off64_t
fhandler_virtual::lseek (__off32_t offset, int whence)
fhandler_virtual::lseek (__off64_t offset, int whence)
{
/*
* On Linux, when you lseek within a /proc file,
* the contents of the file are updated.
*/
fill_filebuf ();
switch (whence)
{
case SEEK_SET:
@ -124,7 +130,7 @@ fhandler_virtual::lseek (__off32_t offset, int whence)
break;
default:
set_errno (EINVAL);
return (__off32_t) -1;
return (__off64_t) -1;
}
return position;
}
@ -214,3 +220,8 @@ fhandler_virtual::exists (const char *path)
{
return 0;
}
void
fhandler_virtual::fill_filebuf ()
{
}

View File

@ -10,11 +10,28 @@
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
#define FILE_SYNCHRONOUS_IO_NONALERT 32
#define PDI_MODULES 0x01
#define PDI_HEAPS 0x04
#define LDRP_IMAGE_DLL 0x00000004
#define WSLE_PAGE_READONLY 0x001
#define WSLE_PAGE_EXECUTE 0x002
#define WSLE_PAGE_EXECUTE_READ 0x003
#define WSLE_PAGE_READWRITE 0x004
#define WSLE_PAGE_WRITECOPY 0x005
#define WSLE_PAGE_EXECUTE_READWRITE 0x006
#define WSLE_PAGE_EXECUTE_WRITECOPY 0x007
#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
#define WSLE_PAGE_SHAREABLE 0x100
typedef ULONG KAFFINITY;
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation = 0,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3,
SystemProcessesAndThreadsInformation = 5,
SystemProcessorTimes = 8,
/* There are a lot more of these... */
} SYSTEM_INFORMATION_CLASS;
@ -30,9 +47,19 @@ typedef struct _SYSTEM_BASIC_INFORMATION
ULONG LowestUserAddress;
ULONG HighestUserAddress;
ULONG ActiveProcessors;
ULONG NumberProcessors;
UCHAR NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
typedef struct _SYSTEM_PROCESSOR_TIMES
{
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_TIMES, *PSYSTEM_PROCESSOR_TIMES;
typedef LONG KPRIORITY;
typedef struct _VM_COUNTERS
{
@ -112,12 +139,13 @@ typedef struct _SYSTEM_THREADS
ULONG ContextSwitchCount;
THREAD_STATE State;
KWAIT_REASON WaitReason;
DWORD Reserved;
} SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG Threadcount;
ULONG ThreadCount;
ULONG Reserved1[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
@ -139,6 +167,180 @@ typedef struct _IO_STATUS_BLOCK
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
LARGE_INTEGER IdleTime;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
ULONG ReadOperationCount;
ULONG WriteOperationCount;
ULONG OtherOperationCount;
ULONG AvailablePages;
ULONG TotalCommittedPages;
ULONG TotalCommitLimit;
ULONG PeakCommitment;
ULONG PageFaults;
ULONG WriteCopyFaults;
ULONG TransitionFaults;
ULONG Reserved1;
ULONG DemandZeroFaults;
ULONG PagesRead;
ULONG PageReadIos;
ULONG Reserved2[2];
ULONG PagefilePagesWritten;
ULONG PagefilePageWriteIos;
ULONG MappedFilePagesWritten;
ULONG MappedFilePageWriteIos;
ULONG PagedPoolUsage;
ULONG NonPagedPoolUsage;
ULONG PagedPoolAllocs;
ULONG PagedPoolFrees;
ULONG NonPagedPoolAllocs;
ULONG NonPagedPoolFrees;
ULONG TotalFreeSystemPtes;
ULONG SystemCodePage;
ULONG TotalSystemDriverPages;
ULONG TotalSystemCodePages;
ULONG SmallNonPagedLookasideListAllocateHits;
ULONG SmallPagedLookasideListAllocateHits;
ULONG Reserved3;
ULONG MmSystemCachePage;
ULONG PagedPoolPage;
ULONG SystemDriverPage;
ULONG FastReadNoWait;
ULONG FastReadWait;
ULONG FastReadResourceMiss;
ULONG FastReadNotPossible;
ULONG FastMdlReadNoWait;
ULONG FastMdlReadWait;
ULONG FastMdlReadResourceMiss;
ULONG FastMdlReadNotPossible;
ULONG MapDataNoWait;
ULONG MapDataWait;
ULONG MapDataNoWaitMiss;
ULONG MapDataWaitMiss;
ULONG PinMappedDataCount;
ULONG PinReadNoWait;
ULONG PinReadWait;
ULONG PinReadNoWaitMiss;
ULONG PinReadWaitMiss;
ULONG CopyReadNoWait;
ULONG CopyReadWait;
ULONG CopyReadNoWaitMiss;
ULONG CopyReadWaitMiss;
ULONG MdlReadNoWait;
ULONG MdlReadWait;
ULONG MdlReadNoWaitMiss;
ULONG MdlReadWaitMiss;
ULONG ReadAheadIos;
ULONG LazyWriteIos;
ULONG LazyWritePages;
ULONG DataFlushes;
ULONG DataPages;
ULONG ContextSwitches;
ULONG FirstLevelTbFills;
ULONG SecondLevelTbFills;
ULONG SystemCalls;
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_TIME_OF_DAY_INFORMATION
{
LARGE_INTEGER BootTime;
LARGE_INTEGER CurrentTime;
LARGE_INTEGER TimeZoneBias;
ULONG CurrentTimeZoneId;
} SYSTEM_TIME_OF_DAY_INFORMATION, *PSYSTEM_TIME_OF_DAY_INFORMATION;
typedef enum _PROCESSINFOCLASS
{
ProcessBasicInformation = 0,
ProcessQuotaLimits = 1,
ProcessVmCounters = 3,
ProcessTimes =4,
} PROCESSINFOCLASS;
typedef struct _DEBUG_BUFFER
{
HANDLE SectionHandle;
PVOID SectionBase;
PVOID RemoteSectionBase;
ULONG SectionBaseDelta;
HANDLE EventPairHandle;
ULONG Unknown[2];
HANDLE RemoteThreadHandle;
ULONG InfoClassMask;
ULONG SizeOfInfo;
ULONG AllocatedSize;
ULONG SectionSize;
PVOID ModuleInformation;
PVOID BackTraceInformation;
PVOID HeapInformation;
PVOID LockInformation;
PVOID Reserved[9];
} DEBUG_BUFFER, *PDEBUG_BUFFER;
typedef struct _DEBUG_HEAP_INFORMATION
{
ULONG Base;
ULONG Flags;
USHORT Granularity;
USHORT Unknown;
ULONG Allocated;
ULONG Committed;
ULONG TagCount;
ULONG BlockCount;
ULONG Reserved[7];
PVOID Tags;
PVOID Blocks;
} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
typedef struct _DEBUG_MODULE_INFORMATION
{
ULONG Reserved[2];
ULONG Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;
typedef struct _KERNEL_USER_TIMES
{
LARGE_INTEGER CreateTime;
LARGE_INTEGER ExitTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;
typedef void *PPEB;
typedef struct _PROCESS_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
KAFFINITY AffinityMask;
KPRIORITY BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName,
MemoryBaiscVlmInformation
} MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_WORKING_SET_LIST {
ULONG NumberOfPages;
ULONG WorkingSetList[1];
} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;
/* Function declarations for ntdll.dll. These don't appear in any
standard Win32 header. */
extern "C"
@ -162,4 +364,8 @@ extern "C"
NTSTATUS NTAPI ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS,
IN OUT PVOID, IN ULONG,
OUT PULONG);
NTSTATUS NTAPI ZwQueryInformationProcess (IN HANDLE, IN PROCESSINFOCLASS,
OUT PVOID, IN ULONG, OUT PULONG);
NTSTATUS NTAPI ZwQueryVirtualMemory (IN HANDLE, IN PVOID, IN MEMORY_INFORMATION_CLASS,
OUT PVOID, IN ULONG, OUT PULONG);
}

View File

@ -46,6 +46,7 @@ static NO_COPY wincaps wincap_unknown = {
has_raw_devices:false,
has_valid_processorlevel:false,
has_64bit_file_access:false,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_95 = {
@ -83,6 +84,7 @@ static NO_COPY wincaps wincap_95 = {
has_raw_devices:false,
has_valid_processorlevel:false,
has_64bit_file_access:false,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_95osr2 = {
@ -120,6 +122,7 @@ static NO_COPY wincaps wincap_95osr2 = {
has_raw_devices:false,
has_valid_processorlevel:false,
has_64bit_file_access:false,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_98 = {
@ -157,6 +160,7 @@ static NO_COPY wincaps wincap_98 = {
has_raw_devices:false,
has_valid_processorlevel:true,
has_64bit_file_access:false,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_98se = {
@ -194,6 +198,7 @@ static NO_COPY wincaps wincap_98se = {
has_raw_devices:false,
has_valid_processorlevel:true,
has_64bit_file_access:false,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_me = {
@ -231,6 +236,7 @@ static NO_COPY wincaps wincap_me = {
has_raw_devices:false,
has_valid_processorlevel:true,
has_64bit_file_access:false,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_nt3 = {
@ -268,6 +274,7 @@ static NO_COPY wincaps wincap_nt3 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_nt4 = {
@ -305,6 +312,7 @@ static NO_COPY wincaps wincap_nt4 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_nt4sp4 = {
@ -342,6 +350,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
has_process_io_counters:false,
};
static NO_COPY wincaps wincap_2000 = {
@ -379,6 +388,7 @@ static NO_COPY wincaps wincap_2000 = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
has_process_io_counters:true,
};
static NO_COPY wincaps wincap_xp = {
@ -416,6 +426,7 @@ static NO_COPY wincaps wincap_xp = {
has_raw_devices:true,
has_valid_processorlevel:true,
has_64bit_file_access:true,
has_process_io_counters:true,
};
wincapc NO_COPY wincap;

View File

@ -47,6 +47,7 @@ struct wincaps
unsigned has_raw_devices : 1;
unsigned has_valid_processorlevel : 1;
unsigned has_64bit_file_access : 1;
unsigned has_process_io_counters : 1;
};
class wincapc
@ -99,6 +100,7 @@ public:
bool IMPLEMENT (has_raw_devices)
bool IMPLEMENT (has_valid_processorlevel)
bool IMPLEMENT (has_64bit_file_access)
bool IMPLEMENT (has_process_io_counters)
#undef IMPLEMENT
};