* 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:
parent
558ab81ed1
commit
9ba913a56d
@ -1,3 +1,46 @@
|
|||||||
|
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>
|
2002-05-09 Christopher Faylor <cgf@redhat.com>
|
||||||
|
|
||||||
* syscalls.cc (_write): Change error to EBADF if attempt to write to a
|
* syscalls.cc (_write): Change error to EBADF if attempt to write to a
|
||||||
|
@ -381,6 +381,8 @@ LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
|
|||||||
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
|
LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
|
||||||
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
|
LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
|
||||||
LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
|
LoadDLLfuncEx (ZwQuerySystemInformation, 16, ntdll, 1)
|
||||||
|
LoadDLLfuncEx (ZwQueryInformationProcess, 20, ntdll, 1)
|
||||||
|
LoadDLLfuncEx (ZwQueryVirtualMemory, 24, ntdll, 1)
|
||||||
|
|
||||||
LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)
|
LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)
|
||||||
|
|
||||||
|
@ -1043,8 +1043,9 @@ class fhandler_virtual : public fhandler_base
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
char *filebuf;
|
char *filebuf;
|
||||||
int bufalloc, filesize;
|
size_t bufalloc, filesize;
|
||||||
__off32_t position;
|
__off64_t position;
|
||||||
|
int fileid; // unique within each class
|
||||||
public:
|
public:
|
||||||
|
|
||||||
fhandler_virtual (DWORD devtype);
|
fhandler_virtual (DWORD devtype);
|
||||||
@ -1053,16 +1054,17 @@ class fhandler_virtual : public fhandler_base
|
|||||||
virtual int exists(const char *path);
|
virtual int exists(const char *path);
|
||||||
DIR *opendir (path_conv& pc);
|
DIR *opendir (path_conv& pc);
|
||||||
__off64_t telldir (DIR *);
|
__off64_t telldir (DIR *);
|
||||||
void seekdir (DIR *, __off32_t);
|
void seekdir (DIR *, __off64_t);
|
||||||
void rewinddir (DIR *);
|
void rewinddir (DIR *);
|
||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
int write (const void *ptr, size_t len);
|
int write (const void *ptr, size_t len);
|
||||||
int __stdcall read (void *ptr, size_t len) __attribute__ ((regparm (3)));
|
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 dup (fhandler_base * child);
|
||||||
int open (path_conv *, int flags, mode_t mode = 0);
|
int open (path_conv *, int flags, mode_t mode = 0);
|
||||||
int close (void);
|
int close (void);
|
||||||
int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
|
int __stdcall fstat (struct stat *buf, path_conv *pc) __attribute__ ((regparm (3)));
|
||||||
|
virtual void fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_proc: public fhandler_virtual
|
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 open (path_conv *real_path, int flags, mode_t mode = 0);
|
||||||
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
|
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
|
||||||
|
void fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_registry: public fhandler_proc
|
class fhandler_registry: public fhandler_proc
|
||||||
@ -1085,23 +1088,29 @@ class fhandler_registry: public fhandler_proc
|
|||||||
int exists(const char *path);
|
int exists(const char *path);
|
||||||
struct dirent *readdir (DIR *);
|
struct dirent *readdir (DIR *);
|
||||||
__off64_t telldir (DIR *);
|
__off64_t telldir (DIR *);
|
||||||
void seekdir (DIR *, __off32_t);
|
void seekdir (DIR *, __off64_t);
|
||||||
void rewinddir (DIR *);
|
void rewinddir (DIR *);
|
||||||
int closedir (DIR *);
|
int closedir (DIR *);
|
||||||
|
|
||||||
int open (path_conv *real_path, int flags, mode_t mode = 0);
|
int open (path_conv *real_path, int flags, mode_t mode = 0);
|
||||||
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
|
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
|
||||||
HKEY open_key(const char *name, REGSAM access = KEY_READ, bool isValue = false);
|
HKEY open_key(const char *name, REGSAM access = KEY_READ, bool isValue = false);
|
||||||
|
void fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct _pinfo;
|
||||||
class fhandler_process: public fhandler_proc
|
class fhandler_process: public fhandler_proc
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
pid_t saved_pid;
|
||||||
|
_pinfo *saved_p;
|
||||||
public:
|
public:
|
||||||
fhandler_process ();
|
fhandler_process ();
|
||||||
int exists(const char *path);
|
int exists(const char *path);
|
||||||
struct dirent *readdir (DIR *);
|
struct dirent *readdir (DIR *);
|
||||||
int open (path_conv *real_path, int flags, mode_t mode = 0);
|
int open (path_conv *real_path, int flags, mode_t mode = 0);
|
||||||
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
|
int __stdcall fstat (struct __stat64 *buf, path_conv *) __attribute__ ((regparm (3)));
|
||||||
|
void fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -14,6 +14,7 @@ details. */
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
|
#include <ntdef.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
@ -24,20 +25,27 @@ details. */
|
|||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
#include "ntdll.h"
|
||||||
|
|
||||||
#define _COMPILING_NEWLIB
|
#define _COMPILING_NEWLIB
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
/* offsets in proc_listing */
|
/* offsets in proc_listing */
|
||||||
static const int PROC_REGISTRY = 2; // /proc/registry
|
static const int PROC_LOADAVG = 2; // /proc/loadavg
|
||||||
static const int PROC_VERSION = 3; // /proc/version
|
static const int PROC_MEMINFO = 3; // /proc/meminfo
|
||||||
static const int PROC_UPTIME = 4; // /proc/uptime
|
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 */
|
/* names of objects in /proc */
|
||||||
static const char *proc_listing[] = {
|
static const char *proc_listing[] = {
|
||||||
".",
|
".",
|
||||||
"..",
|
"..",
|
||||||
|
"loadavg",
|
||||||
|
"meminfo",
|
||||||
"registry",
|
"registry",
|
||||||
|
"stat",
|
||||||
"version",
|
"version",
|
||||||
"uptime",
|
"uptime",
|
||||||
NULL
|
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
|
/* FH_PROC in the table below means the file/directory is handles by
|
||||||
* fhandler_proc.
|
* fhandler_proc.
|
||||||
*/
|
*/
|
||||||
static const DWORD proc_fhandlers[] = {
|
static const DWORD proc_fhandlers[PROC_LINK_COUNT] = {
|
||||||
|
FH_PROC,
|
||||||
|
FH_PROC,
|
||||||
FH_PROC,
|
FH_PROC,
|
||||||
FH_PROC,
|
FH_PROC,
|
||||||
FH_REGISTRY,
|
FH_REGISTRY,
|
||||||
FH_PROC,
|
FH_PROC,
|
||||||
|
FH_PROC,
|
||||||
FH_PROC
|
FH_PROC
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,6 +71,10 @@ static const DWORD proc_fhandlers[] = {
|
|||||||
const char proc[] = "/proc";
|
const char proc[] = "/proc";
|
||||||
const int proc_len = sizeof (proc) - 1;
|
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
|
/* 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
|
* this is where it would be nice to have pattern matching in C - polymorphism
|
||||||
* just doesn't cut it
|
* just doesn't cut it
|
||||||
@ -291,33 +306,9 @@ fhandler_proc::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
res = 0;
|
res = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
switch (proc_file_no)
|
|
||||||
{
|
fileid = proc_file_no;
|
||||||
case PROC_VERSION:
|
fill_filebuf ();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & O_APPEND)
|
if (flags & O_APPEND)
|
||||||
position = filesize;
|
position = filesize;
|
||||||
@ -332,3 +323,197 @@ out:
|
|||||||
syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
|
||||||
return res;
|
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);
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@ details. */
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/cygwin.h>
|
#include <sys/cygwin.h>
|
||||||
|
#include <ntdef.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
@ -23,6 +24,7 @@ details. */
|
|||||||
#include "shared_info.h"
|
#include "shared_info.h"
|
||||||
#include "dtable.h"
|
#include "dtable.h"
|
||||||
#include "cygheap.h"
|
#include "cygheap.h"
|
||||||
|
#include "ntdll.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define _COMPILING_NEWLIB
|
#define _COMPILING_NEWLIB
|
||||||
@ -38,6 +40,8 @@ static const int PROCESS_GID = 8;
|
|||||||
static const int PROCESS_PGID = 9;
|
static const int PROCESS_PGID = 9;
|
||||||
static const int PROCESS_SID = 10;
|
static const int PROCESS_SID = 10;
|
||||||
static const int PROCESS_CTTY = 11;
|
static const int PROCESS_CTTY = 11;
|
||||||
|
static const int PROCESS_STAT = 12;
|
||||||
|
static const int PROCESS_STATM = 13;
|
||||||
|
|
||||||
static const char *process_listing[] = {
|
static const char *process_listing[] = {
|
||||||
".",
|
".",
|
||||||
@ -52,11 +56,20 @@ static const char *process_listing[] = {
|
|||||||
"pgid",
|
"pgid",
|
||||||
"sid",
|
"sid",
|
||||||
"ctty",
|
"ctty",
|
||||||
|
"stat",
|
||||||
|
"statm",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int PROCESS_LINK_COUNT = (sizeof(process_listing) / sizeof(const char *)) - 1;
|
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,
|
/* Returns 0 if path doesn't exist, >0 if path is a directory,
|
||||||
* <0 if path is a file.
|
* <0 if path is a file.
|
||||||
*/
|
*/
|
||||||
@ -84,8 +97,26 @@ fhandler_process::fhandler_process ():
|
|||||||
int
|
int
|
||||||
fhandler_process::fstat (struct __stat64 *buf, path_conv *pc)
|
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);
|
(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;
|
buf->st_mode &= ~_IFMT & NO_W;
|
||||||
|
|
||||||
switch (file_type)
|
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;
|
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
return 0;
|
return 0;
|
||||||
case 2:
|
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_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
|
||||||
buf->st_nlink = PROCESS_LINK_COUNT;
|
buf->st_nlink = PROCESS_LINK_COUNT;
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
case -1:
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,91 +235,10 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
res = 0;
|
res = 0;
|
||||||
goto out;
|
goto out;
|
||||||
found:
|
found:
|
||||||
switch (process_file_no)
|
fileid = process_file_no;
|
||||||
{
|
saved_pid = pid;
|
||||||
case PROCESS_UID:
|
saved_p = p;
|
||||||
case PROCESS_GID:
|
fill_filebuf ();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & O_APPEND)
|
if (flags & O_APPEND)
|
||||||
position = filesize;
|
position = filesize;
|
||||||
@ -297,3 +253,501 @@ out:
|
|||||||
syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
|
syscall_printf ("%d = fhandler_proc::open (%p, %d)", res, flags, mode);
|
||||||
return res;
|
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;
|
||||||
|
}
|
||||||
|
@ -292,7 +292,7 @@ fhandler_registry::telldir (DIR * dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
/* Unfortunately cannot simply set __d_position due to transition from sub-keys to
|
||||||
* values.
|
* values.
|
||||||
@ -490,6 +490,11 @@ out:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_registry::fill_filebuf ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/* Auxillary member function to open registry keys. */
|
/* Auxillary member function to open registry keys. */
|
||||||
HKEY
|
HKEY
|
||||||
fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)
|
fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)
|
||||||
|
@ -27,7 +27,8 @@ details. */
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
fhandler_virtual::fhandler_virtual (DWORD devtype):
|
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
|
void
|
||||||
fhandler_virtual::seekdir (DIR * dir, __off32_t loc)
|
fhandler_virtual::seekdir (DIR * dir, __off64_t loc)
|
||||||
{
|
{
|
||||||
dir->__d_position = loc;
|
dir->__d_position = loc;
|
||||||
return;
|
return;
|
||||||
@ -109,8 +110,13 @@ fhandler_virtual::closedir (DIR * dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
__off64_t
|
__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)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
@ -124,7 +130,7 @@ fhandler_virtual::lseek (__off32_t offset, int whence)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return (__off32_t) -1;
|
return (__off64_t) -1;
|
||||||
}
|
}
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
@ -214,3 +220,8 @@ fhandler_virtual::exists (const char *path)
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fhandler_virtual::fill_filebuf ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@ -10,11 +10,28 @@
|
|||||||
|
|
||||||
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
|
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
|
||||||
#define FILE_SYNCHRONOUS_IO_NONALERT 32
|
#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
|
typedef enum _SYSTEM_INFORMATION_CLASS
|
||||||
{
|
{
|
||||||
SystemBasicInformation = 0,
|
SystemBasicInformation = 0,
|
||||||
|
SystemPerformanceInformation = 2,
|
||||||
|
SystemTimeOfDayInformation = 3,
|
||||||
SystemProcessesAndThreadsInformation = 5,
|
SystemProcessesAndThreadsInformation = 5,
|
||||||
|
SystemProcessorTimes = 8,
|
||||||
/* There are a lot more of these... */
|
/* There are a lot more of these... */
|
||||||
} SYSTEM_INFORMATION_CLASS;
|
} SYSTEM_INFORMATION_CLASS;
|
||||||
|
|
||||||
@ -30,9 +47,19 @@ typedef struct _SYSTEM_BASIC_INFORMATION
|
|||||||
ULONG LowestUserAddress;
|
ULONG LowestUserAddress;
|
||||||
ULONG HighestUserAddress;
|
ULONG HighestUserAddress;
|
||||||
ULONG ActiveProcessors;
|
ULONG ActiveProcessors;
|
||||||
ULONG NumberProcessors;
|
UCHAR NumberProcessors;
|
||||||
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
|
} 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 LONG KPRIORITY;
|
||||||
typedef struct _VM_COUNTERS
|
typedef struct _VM_COUNTERS
|
||||||
{
|
{
|
||||||
@ -112,12 +139,13 @@ typedef struct _SYSTEM_THREADS
|
|||||||
ULONG ContextSwitchCount;
|
ULONG ContextSwitchCount;
|
||||||
THREAD_STATE State;
|
THREAD_STATE State;
|
||||||
KWAIT_REASON WaitReason;
|
KWAIT_REASON WaitReason;
|
||||||
|
DWORD Reserved;
|
||||||
} SYSTEM_THREADS, *PSYSTEM_THREADS;
|
} SYSTEM_THREADS, *PSYSTEM_THREADS;
|
||||||
|
|
||||||
typedef struct _SYSTEM_PROCESSES
|
typedef struct _SYSTEM_PROCESSES
|
||||||
{
|
{
|
||||||
ULONG NextEntryDelta;
|
ULONG NextEntryDelta;
|
||||||
ULONG Threadcount;
|
ULONG ThreadCount;
|
||||||
ULONG Reserved1[6];
|
ULONG Reserved1[6];
|
||||||
LARGE_INTEGER CreateTime;
|
LARGE_INTEGER CreateTime;
|
||||||
LARGE_INTEGER UserTime;
|
LARGE_INTEGER UserTime;
|
||||||
@ -139,6 +167,180 @@ typedef struct _IO_STATUS_BLOCK
|
|||||||
ULONG Information;
|
ULONG Information;
|
||||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
} 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
|
/* Function declarations for ntdll.dll. These don't appear in any
|
||||||
standard Win32 header. */
|
standard Win32 header. */
|
||||||
extern "C"
|
extern "C"
|
||||||
@ -162,4 +364,8 @@ extern "C"
|
|||||||
NTSTATUS NTAPI ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS,
|
NTSTATUS NTAPI ZwQuerySystemInformation (IN SYSTEM_INFORMATION_CLASS,
|
||||||
IN OUT PVOID, IN ULONG,
|
IN OUT PVOID, IN ULONG,
|
||||||
OUT PULONG);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ static NO_COPY wincaps wincap_unknown = {
|
|||||||
has_raw_devices:false,
|
has_raw_devices:false,
|
||||||
has_valid_processorlevel:false,
|
has_valid_processorlevel:false,
|
||||||
has_64bit_file_access:false,
|
has_64bit_file_access:false,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_95 = {
|
static NO_COPY wincaps wincap_95 = {
|
||||||
@ -83,6 +84,7 @@ static NO_COPY wincaps wincap_95 = {
|
|||||||
has_raw_devices:false,
|
has_raw_devices:false,
|
||||||
has_valid_processorlevel:false,
|
has_valid_processorlevel:false,
|
||||||
has_64bit_file_access:false,
|
has_64bit_file_access:false,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_95osr2 = {
|
static NO_COPY wincaps wincap_95osr2 = {
|
||||||
@ -120,6 +122,7 @@ static NO_COPY wincaps wincap_95osr2 = {
|
|||||||
has_raw_devices:false,
|
has_raw_devices:false,
|
||||||
has_valid_processorlevel:false,
|
has_valid_processorlevel:false,
|
||||||
has_64bit_file_access:false,
|
has_64bit_file_access:false,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_98 = {
|
static NO_COPY wincaps wincap_98 = {
|
||||||
@ -157,6 +160,7 @@ static NO_COPY wincaps wincap_98 = {
|
|||||||
has_raw_devices:false,
|
has_raw_devices:false,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:false,
|
has_64bit_file_access:false,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_98se = {
|
static NO_COPY wincaps wincap_98se = {
|
||||||
@ -194,6 +198,7 @@ static NO_COPY wincaps wincap_98se = {
|
|||||||
has_raw_devices:false,
|
has_raw_devices:false,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:false,
|
has_64bit_file_access:false,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_me = {
|
static NO_COPY wincaps wincap_me = {
|
||||||
@ -231,6 +236,7 @@ static NO_COPY wincaps wincap_me = {
|
|||||||
has_raw_devices:false,
|
has_raw_devices:false,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:false,
|
has_64bit_file_access:false,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt3 = {
|
static NO_COPY wincaps wincap_nt3 = {
|
||||||
@ -268,6 +274,7 @@ static NO_COPY wincaps wincap_nt3 = {
|
|||||||
has_raw_devices:true,
|
has_raw_devices:true,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:true,
|
has_64bit_file_access:true,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt4 = {
|
static NO_COPY wincaps wincap_nt4 = {
|
||||||
@ -305,6 +312,7 @@ static NO_COPY wincaps wincap_nt4 = {
|
|||||||
has_raw_devices:true,
|
has_raw_devices:true,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:true,
|
has_64bit_file_access:true,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt4sp4 = {
|
static NO_COPY wincaps wincap_nt4sp4 = {
|
||||||
@ -342,6 +350,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
|
|||||||
has_raw_devices:true,
|
has_raw_devices:true,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:true,
|
has_64bit_file_access:true,
|
||||||
|
has_process_io_counters:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_2000 = {
|
static NO_COPY wincaps wincap_2000 = {
|
||||||
@ -379,6 +388,7 @@ static NO_COPY wincaps wincap_2000 = {
|
|||||||
has_raw_devices:true,
|
has_raw_devices:true,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:true,
|
has_64bit_file_access:true,
|
||||||
|
has_process_io_counters:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_xp = {
|
static NO_COPY wincaps wincap_xp = {
|
||||||
@ -416,6 +426,7 @@ static NO_COPY wincaps wincap_xp = {
|
|||||||
has_raw_devices:true,
|
has_raw_devices:true,
|
||||||
has_valid_processorlevel:true,
|
has_valid_processorlevel:true,
|
||||||
has_64bit_file_access:true,
|
has_64bit_file_access:true,
|
||||||
|
has_process_io_counters:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc NO_COPY wincap;
|
wincapc NO_COPY wincap;
|
||||||
|
@ -47,6 +47,7 @@ struct wincaps
|
|||||||
unsigned has_raw_devices : 1;
|
unsigned has_raw_devices : 1;
|
||||||
unsigned has_valid_processorlevel : 1;
|
unsigned has_valid_processorlevel : 1;
|
||||||
unsigned has_64bit_file_access : 1;
|
unsigned has_64bit_file_access : 1;
|
||||||
|
unsigned has_process_io_counters : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
@ -99,6 +100,7 @@ public:
|
|||||||
bool IMPLEMENT (has_raw_devices)
|
bool IMPLEMENT (has_raw_devices)
|
||||||
bool IMPLEMENT (has_valid_processorlevel)
|
bool IMPLEMENT (has_valid_processorlevel)
|
||||||
bool IMPLEMENT (has_64bit_file_access)
|
bool IMPLEMENT (has_64bit_file_access)
|
||||||
|
bool IMPLEMENT (has_process_io_counters)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user