* autoload.cc (GetSecurityInfo): Define new autoload function.
(RegQueryInfoKeyA): Ditto. * fhandler.h (fhandler_virtual::fill_filebuf): Change return type to bool. (fhandler_proc::fill_filebuf): Ditto. (fhandler_registry::fill_filebuf): Ditto. (fhandler_process::fill_filebuf): Ditto. (fhandler_registry::value_name): Add new member. (fhandler_registry::close): Add new method. (fhandler_process::p): Remove member. * fhandler_proc.cc (fhandler_proc::open): Add set_nohandle after calling superclass method. Check return value of fill_filebuf. (fhandler_proc::fill_filebuf): Change return type to bool. Add return statement. * fhandler_process.cc (fhandler_process::open): Add set_nohandle after calling superclass method. Remove references to p. Check return value of fill_filebuf. (fhandler_process::fill_filebuf): Change return type to bool. Don't use dereference operator on p. Add return statement. (fhandler_process::format_process_stat): Fix typo. * fhandler_registry.cc: Add static open_key declaration. (fhandler_registry::exists): Assume path is already normalised. Try opening the path as a key in its own right first, before reverting to enumerating subkeys and values of the parent key. (fhandler_registry::fstat): Add additional code to return more relevant information about the registry key/value. (fhandler_registry::readdir): Explicitly set desired access when opening registry key. Remove output of buf from debug_printf format string. (fhandler_registry::open): Use set_io_handle to store registry key handle. Set value_name member. Move code to read a value from the registry to fill_filebuf. Add call to fill_filebuf. (fhandler_registry::close): New method. (fhandler_registry::fill_filebuf): Change return type to bool. Add code to read a value from registry. (fhandler_registry::open_key): Make function static. Use KEY_READ as desired access unless this is the last path component. Check the return value of RegOpenKeyEx for an error instead of hKey. * fhandler_virtual.cc (fhandler_virtual::lseek): Check the return value of fill_filebuf. (fhandler_virtual::open): Remove call to set_nohandle. (fhandler_virtual::fill_filebuf): Change return type to bool. Add return statement. * security.cc (get_nt_object_attribute): New function. (get_object_attribute): New function. * security.h (get_object_attribute): New function declaration.
This commit is contained in:
parent
cc81f456ac
commit
74fcdaec20
@ -1,4 +1,53 @@
|
|||||||
2002-07-01 Pierre Humblet <pierre.humblet@ieee.org>
|
2002-07-02 Christopher January <chris@atomice.net>
|
||||||
|
|
||||||
|
* autoload.cc (GetSecurityInfo): Define new autoload function.
|
||||||
|
(RegQueryInfoKeyA): Ditto.
|
||||||
|
* fhandler.h (fhandler_virtual::fill_filebuf): Change return type to
|
||||||
|
bool.
|
||||||
|
(fhandler_proc::fill_filebuf): Ditto.
|
||||||
|
(fhandler_registry::fill_filebuf): Ditto.
|
||||||
|
(fhandler_process::fill_filebuf): Ditto.
|
||||||
|
(fhandler_registry::value_name): Add new member.
|
||||||
|
(fhandler_registry::close): Add new method.
|
||||||
|
(fhandler_process::p): Remove member.
|
||||||
|
* fhandler_proc.cc (fhandler_proc::open): Add set_nohandle after
|
||||||
|
calling superclass method. Check return value of fill_filebuf.
|
||||||
|
(fhandler_proc::fill_filebuf): Change return type to bool. Add return
|
||||||
|
statement.
|
||||||
|
* fhandler_process.cc (fhandler_process::open): Add set_nohandle after
|
||||||
|
calling superclass method. Remove references to p. Check return value
|
||||||
|
of fill_filebuf.
|
||||||
|
(fhandler_process::fill_filebuf): Change return type to bool. Don't
|
||||||
|
use dereference operator on p. Add return statement.
|
||||||
|
(fhandler_process::format_process_stat): Fix typo.
|
||||||
|
* fhandler_registry.cc: Add static open_key declaration.
|
||||||
|
(fhandler_registry::exists): Assume path is already normalised. Try
|
||||||
|
opening the path as a key in its own right first, before reverting to
|
||||||
|
enumerating subkeys and values of the parent key.
|
||||||
|
(fhandler_registry::fstat): Add additional code to return more relevant
|
||||||
|
information about the registry key/value.
|
||||||
|
(fhandler_registry::readdir): Explicitly set desired access when
|
||||||
|
opening registry key. Remove output of buf from debug_printf format
|
||||||
|
string.
|
||||||
|
(fhandler_registry::open): Use set_io_handle to store registry key
|
||||||
|
handle. Set value_name member. Move code to read a value from the
|
||||||
|
registry to fill_filebuf. Add call to fill_filebuf.
|
||||||
|
(fhandler_registry::close): New method.
|
||||||
|
(fhandler_registry::fill_filebuf): Change return type to bool. Add
|
||||||
|
code to read a value from registry.
|
||||||
|
(fhandler_registry::open_key): Make function static. Use KEY_READ as
|
||||||
|
desired access unless this is the last path component. Check the
|
||||||
|
return value of RegOpenKeyEx for an error instead of hKey.
|
||||||
|
* fhandler_virtual.cc (fhandler_virtual::lseek): Check the return value
|
||||||
|
of fill_filebuf.
|
||||||
|
(fhandler_virtual::open): Remove call to set_nohandle.
|
||||||
|
(fhandler_virtual::fill_filebuf): Change return type to bool. Add
|
||||||
|
return statement.
|
||||||
|
* security.cc (get_nt_object_attribute): New function.
|
||||||
|
(get_object_attribute): New function.
|
||||||
|
* security.h (get_object_attribute): New function declaration.
|
||||||
|
|
||||||
|
2002-07-01 Pierre Humblet <pierre.humblet@ieee.org>
|
||||||
|
|
||||||
* syscalls.c (seteuid32): Do not return an error when the token cannot
|
* syscalls.c (seteuid32): Do not return an error when the token cannot
|
||||||
be created only because of a problem with the gid.
|
be created only because of a problem with the gid.
|
||||||
|
@ -326,6 +326,7 @@ LoadDLLfunc (GetLengthSid, 4, advapi32)
|
|||||||
LoadDLLfunc (GetSecurityDescriptorDacl, 16, advapi32)
|
LoadDLLfunc (GetSecurityDescriptorDacl, 16, advapi32)
|
||||||
LoadDLLfunc (GetSecurityDescriptorGroup, 12, advapi32)
|
LoadDLLfunc (GetSecurityDescriptorGroup, 12, advapi32)
|
||||||
LoadDLLfunc (GetSecurityDescriptorOwner, 12, advapi32)
|
LoadDLLfunc (GetSecurityDescriptorOwner, 12, advapi32)
|
||||||
|
LoadDLLfunc (GetSecurityInfo, 32, advapi32)
|
||||||
LoadDLLfunc (GetSidIdentifierAuthority, 4, advapi32)
|
LoadDLLfunc (GetSidIdentifierAuthority, 4, advapi32)
|
||||||
LoadDLLfunc (GetSidSubAuthority, 8, advapi32)
|
LoadDLLfunc (GetSidSubAuthority, 8, advapi32)
|
||||||
LoadDLLfunc (GetSidSubAuthorityCount, 4, advapi32)
|
LoadDLLfunc (GetSidSubAuthorityCount, 4, advapi32)
|
||||||
@ -358,6 +359,7 @@ LoadDLLfunc (RegLoadKeyA, 12, advapi32)
|
|||||||
LoadDLLfunc (RegEnumKeyExA, 32, advapi32)
|
LoadDLLfunc (RegEnumKeyExA, 32, advapi32)
|
||||||
LoadDLLfunc (RegEnumValueA, 32, advapi32)
|
LoadDLLfunc (RegEnumValueA, 32, advapi32)
|
||||||
LoadDLLfunc (RegOpenKeyExA, 20, advapi32)
|
LoadDLLfunc (RegOpenKeyExA, 20, advapi32)
|
||||||
|
LoadDLLfunc (RegQueryInfoKeyA, 48, advapi32)
|
||||||
LoadDLLfunc (RegQueryValueExA, 24, advapi32)
|
LoadDLLfunc (RegQueryValueExA, 24, advapi32)
|
||||||
LoadDLLfunc (RegSetValueExA, 24, advapi32)
|
LoadDLLfunc (RegSetValueExA, 24, advapi32)
|
||||||
LoadDLLfunc (RegisterEventSourceA, 8, advapi32)
|
LoadDLLfunc (RegisterEventSourceA, 8, advapi32)
|
||||||
|
@ -1090,7 +1090,7 @@ class fhandler_virtual : public fhandler_base
|
|||||||
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 ();
|
virtual bool fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_proc: public fhandler_virtual
|
class fhandler_proc: public fhandler_virtual
|
||||||
@ -1104,11 +1104,13 @@ 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 ();
|
bool fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
class fhandler_registry: public fhandler_proc
|
class fhandler_registry: public fhandler_proc
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
char *value_name;
|
||||||
public:
|
public:
|
||||||
fhandler_registry ();
|
fhandler_registry ();
|
||||||
int exists();
|
int exists();
|
||||||
@ -1120,22 +1122,21 @@ class fhandler_registry: public fhandler_proc
|
|||||||
|
|
||||||
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);
|
bool fill_filebuf ();
|
||||||
void fill_filebuf ();
|
int close (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class pinfo;
|
class pinfo;
|
||||||
class fhandler_process: public fhandler_proc
|
class fhandler_process: public fhandler_proc
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
pinfo *p;
|
|
||||||
public:
|
public:
|
||||||
fhandler_process ();
|
fhandler_process ();
|
||||||
int exists();
|
int exists();
|
||||||
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 ();
|
bool fill_filebuf ();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
@ -216,6 +216,8 @@ fhandler_proc::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
if (!res)
|
if (!res)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
set_nohandle (true);
|
||||||
|
|
||||||
const char *path;
|
const char *path;
|
||||||
|
|
||||||
path = get_name () + proc_len;
|
path = get_name () + proc_len;
|
||||||
@ -291,7 +293,11 @@ fhandler_proc::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileid = proc_file_no;
|
fileid = proc_file_no;
|
||||||
fill_filebuf ();
|
if (!fill_filebuf ())
|
||||||
|
{
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & O_APPEND)
|
if (flags & O_APPEND)
|
||||||
position = filesize;
|
position = filesize;
|
||||||
@ -307,7 +313,7 @@ out:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
fhandler_proc::fill_filebuf ()
|
fhandler_proc::fill_filebuf ()
|
||||||
{
|
{
|
||||||
switch (fileid)
|
switch (fileid)
|
||||||
@ -361,6 +367,7 @@ fhandler_proc::fill_filebuf ()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -41,7 +41,8 @@ static const int PROCESS_CTTY = 11;
|
|||||||
static const int PROCESS_STAT = 12;
|
static const int PROCESS_STAT = 12;
|
||||||
static const int PROCESS_STATM = 13;
|
static const int PROCESS_STATM = 13;
|
||||||
|
|
||||||
static const char *process_listing[] = {
|
static const char * const process_listing[] =
|
||||||
|
{
|
||||||
".",
|
".",
|
||||||
"..",
|
"..",
|
||||||
"ppid",
|
"ppid",
|
||||||
@ -59,14 +60,17 @@ static const char *process_listing[] = {
|
|||||||
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_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_status (_pinfo *p, char *destbuf, size_t maxsize);
|
||||||
static off_t format_process_statm (_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 int get_process_state (DWORD dwProcessId);
|
||||||
static bool get_mem_values(DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss, unsigned long *vmtext,
|
static bool get_mem_values(DWORD dwProcessId, unsigned long *vmsize,
|
||||||
unsigned long *vmdata, unsigned long *vmlib, unsigned long *vmshare);
|
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.
|
||||||
@ -159,6 +163,8 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
if (!res)
|
if (!res)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
set_nohandle (true);
|
||||||
|
|
||||||
const char *path;
|
const char *path;
|
||||||
path = get_name () + proc_len + 1;
|
path = get_name () + proc_len + 1;
|
||||||
pid = atoi (path);
|
pid = atoi (path);
|
||||||
@ -215,25 +221,17 @@ fhandler_process::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
pinfo p (pid);
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
set_errno (ENOENT);
|
|
||||||
res = 0;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileid = process_file_no;
|
fileid = process_file_no;
|
||||||
this->p = &p;
|
if (!fill_filebuf ())
|
||||||
fill_filebuf ();
|
{
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & O_APPEND)
|
if (flags & O_APPEND)
|
||||||
position = filesize;
|
position = filesize;
|
||||||
else
|
else
|
||||||
position = 0;
|
position = 0;
|
||||||
this->p = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
success:
|
success:
|
||||||
res = 1;
|
res = 1;
|
||||||
@ -244,20 +242,17 @@ out:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
fhandler_process::fill_filebuf ()
|
fhandler_process::fill_filebuf ()
|
||||||
{
|
{
|
||||||
pinfo pmaybe;
|
pinfo p (pid);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
pmaybe.init (pid);
|
set_errno (ENOENT);
|
||||||
p = &pmaybe;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (fileid)
|
switch (fileid)
|
||||||
{
|
{
|
||||||
case PROCESS_UID:
|
case PROCESS_UID:
|
||||||
@ -268,27 +263,27 @@ fhandler_process::fill_filebuf ()
|
|||||||
case PROCESS_PPID:
|
case PROCESS_PPID:
|
||||||
{
|
{
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
||||||
int num;
|
int num;
|
||||||
switch (fileid)
|
switch (fileid)
|
||||||
{
|
{
|
||||||
case PROCESS_PPID:
|
case PROCESS_PPID:
|
||||||
num = (*p)->ppid;
|
num = p->ppid;
|
||||||
break;
|
break;
|
||||||
case PROCESS_UID:
|
case PROCESS_UID:
|
||||||
num = (*p)->uid;
|
num = p->uid;
|
||||||
break;
|
break;
|
||||||
case PROCESS_PGID:
|
case PROCESS_PGID:
|
||||||
num = (*p)->pgid;
|
num = p->pgid;
|
||||||
break;
|
break;
|
||||||
case PROCESS_SID:
|
case PROCESS_SID:
|
||||||
num = (*p)->sid;
|
num = p->sid;
|
||||||
break;
|
break;
|
||||||
case PROCESS_GID:
|
case PROCESS_GID:
|
||||||
num = (*p)->gid;
|
num = p->gid;
|
||||||
break;
|
break;
|
||||||
case PROCESS_CTTY:
|
case PROCESS_CTTY:
|
||||||
num = (*p)->ctty;
|
num = p->ctty;
|
||||||
break;
|
break;
|
||||||
default: // what's this here for?
|
default: // what's this here for?
|
||||||
num = 0;
|
num = 0;
|
||||||
@ -301,12 +296,12 @@ fhandler_process::fill_filebuf ()
|
|||||||
case PROCESS_EXENAME:
|
case PROCESS_EXENAME:
|
||||||
{
|
{
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = MAX_PATH);
|
||||||
if ((*p)->process_state & (PID_ZOMBIE | PID_EXITED))
|
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
|
||||||
strcpy (filebuf, "<defunct>");
|
strcpy (filebuf, "<defunct>");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mount_table->conv_to_posix_path ((*p)->progname, filebuf, 1);
|
mount_table->conv_to_posix_path (p->progname, filebuf, 1);
|
||||||
int len = strlen (filebuf);
|
int len = strlen (filebuf);
|
||||||
if (len > 4)
|
if (len > 4)
|
||||||
{
|
{
|
||||||
@ -321,17 +316,17 @@ fhandler_process::fill_filebuf ()
|
|||||||
case PROCESS_WINPID:
|
case PROCESS_WINPID:
|
||||||
{
|
{
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 40);
|
||||||
__small_sprintf (filebuf, "%d\n", (*p)->dwProcessId);
|
__small_sprintf (filebuf, "%d\n", p->dwProcessId);
|
||||||
filesize = strlen (filebuf);
|
filesize = strlen (filebuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROCESS_WINEXENAME:
|
case PROCESS_WINEXENAME:
|
||||||
{
|
{
|
||||||
int len = strlen ((*p)->progname);
|
int len = strlen (p->progname);
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = (len + 2));
|
||||||
strcpy (filebuf, (*p)->progname);
|
strcpy (filebuf, p->progname);
|
||||||
filebuf[len] = '\n';
|
filebuf[len] = '\n';
|
||||||
filesize = len + 1;
|
filesize = len + 1;
|
||||||
break;
|
break;
|
||||||
@ -340,27 +335,26 @@ fhandler_process::fill_filebuf ()
|
|||||||
{
|
{
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||||
filesize = format_process_status ((*p), filebuf, bufalloc);
|
filesize = format_process_status (*p, filebuf, bufalloc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROCESS_STAT:
|
case PROCESS_STAT:
|
||||||
{
|
{
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||||
filesize = format_process_stat ((*p), filebuf, bufalloc);
|
filesize = format_process_stat (*p, filebuf, bufalloc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PROCESS_STATM:
|
case PROCESS_STATM:
|
||||||
{
|
{
|
||||||
if (!filebuf)
|
if (!filebuf)
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc = 2048);
|
||||||
filesize = format_process_statm ((*p), filebuf, bufalloc);
|
filesize = format_process_statm (*p, filebuf, bufalloc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == &pmaybe)
|
return true;
|
||||||
p = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -375,7 +369,7 @@ format_process_stat (_pinfo *p, char *destbuf, size_t maxsize)
|
|||||||
vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
|
vmsize = 0UL, vmrss = 0UL, vmmaxrss = 0UL;
|
||||||
int priority = 0;
|
int priority = 0;
|
||||||
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
|
if (p->process_state & (PID_ZOMBIE | PID_EXITED))
|
||||||
strcpy (cmd, "<defunct");
|
strcpy (cmd, "<defunct>");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
strcpy(cmd, p->progname);
|
strcpy(cmd, p->progname);
|
||||||
@ -598,11 +592,12 @@ static
|
|||||||
off_t
|
off_t
|
||||||
format_process_statm (_pinfo *p, char *destbuf, size_t maxsize)
|
format_process_statm (_pinfo *p, char *destbuf, size_t maxsize)
|
||||||
{
|
{
|
||||||
unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL, vmlib = 0UL,
|
unsigned long vmsize = 0UL, vmrss = 0UL, vmtext = 0UL, vmdata = 0UL,
|
||||||
vmshare = 0UL;
|
vmlib = 0UL, vmshare = 0UL;
|
||||||
if (wincap.is_winnt ())
|
if (wincap.is_winnt ())
|
||||||
{
|
{
|
||||||
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata, &vmlib, &vmshare))
|
if (!get_mem_values (p->dwProcessId, &vmsize, &vmrss, &vmtext, &vmdata,
|
||||||
|
&vmlib, &vmshare))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld",
|
return __small_sprintf (destbuf, "%ld %ld %ld %ld %ld %ld %ld",
|
||||||
|
@ -33,7 +33,7 @@ static const int registry_len = sizeof ("registry") - 1;
|
|||||||
* make up the value index if we are enuerating values.
|
* make up the value index if we are enuerating values.
|
||||||
*/
|
*/
|
||||||
static const __off32_t REG_ENUM_VALUES_MASK = 0x8000000;
|
static const __off32_t REG_ENUM_VALUES_MASK = 0x8000000;
|
||||||
static const __off32_t REG_POSITION_MASK = 0xffff;
|
static const __off32_t REG_POSITION_MASK = 0xffff;
|
||||||
|
|
||||||
/* List of root keys in /proc/registry.
|
/* List of root keys in /proc/registry.
|
||||||
* Possibly we should filter out those not relevant to the flavour of Windows
|
* Possibly we should filter out those not relevant to the flavour of Windows
|
||||||
@ -49,7 +49,7 @@ static const char *registry_listing[] =
|
|||||||
"HKEY_LOCAL_MACHINE",
|
"HKEY_LOCAL_MACHINE",
|
||||||
"HKEY_USERS",
|
"HKEY_USERS",
|
||||||
"HKEY_DYN_DATA", // 95/98/Me
|
"HKEY_DYN_DATA", // 95/98/Me
|
||||||
"HKEY_PERFOMANCE_DATA", // NT/2000/XP
|
"HKEY_PERFOMANCE_DATA", // NT/2000/XP
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ static const HKEY registry_keys[] =
|
|||||||
HKEY_PERFORMANCE_DATA
|
HKEY_PERFORMANCE_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int ROOT_KEY_COUNT = sizeof(registry_keys) / sizeof(HKEY);
|
static const int ROOT_KEY_COUNT = sizeof (registry_keys) / sizeof (HKEY);
|
||||||
|
|
||||||
/* These get added to each subdirectory in /proc/registry.
|
/* These get added to each subdirectory in /proc/registry.
|
||||||
* If we wanted to implement writing, we could maybe add a '.writable' entry or
|
* If we wanted to implement writing, we could maybe add a '.writable' entry or
|
||||||
@ -79,11 +79,14 @@ static const char *special_dot_files[] =
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int SPECIAL_DOT_FILE_COUNT = (sizeof(special_dot_files) / sizeof(const char *)) - 1;
|
static const int SPECIAL_DOT_FILE_COUNT =
|
||||||
|
(sizeof (special_dot_files) / sizeof (const char *)) - 1;
|
||||||
|
|
||||||
/* Name given to default values */
|
/* Name given to default values */
|
||||||
static const char *DEFAULT_VALUE_NAME = "@";
|
static const char *DEFAULT_VALUE_NAME = "@";
|
||||||
|
|
||||||
|
static HKEY open_key (const char *name, REGSAM access, bool isValue);
|
||||||
|
|
||||||
/* 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.
|
||||||
*
|
*
|
||||||
@ -103,10 +106,7 @@ fhandler_registry::exists ()
|
|||||||
|
|
||||||
const char *path = get_name ();
|
const char *path = get_name ();
|
||||||
debug_printf ("exists (%s)", path);
|
debug_printf ("exists (%s)", path);
|
||||||
path += proc_len + 1 + registry_len;
|
path += proc_len + registry_len + 2;
|
||||||
|
|
||||||
while (SLASH_P (*path))
|
|
||||||
path++;
|
|
||||||
if (*path == 0)
|
if (*path == 0)
|
||||||
{
|
{
|
||||||
file_type = 2;
|
file_type = 2;
|
||||||
@ -132,44 +132,52 @@ fhandler_registry::exists ()
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
hKey = open_key (path, KEY_READ, true);
|
hKey = open_key (path, KEY_READ, false);
|
||||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
if (hKey != (HKEY) INVALID_HANDLE_VALUE)
|
||||||
return 0;
|
file_type = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hKey = open_key (path, KEY_READ, true);
|
||||||
|
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
while (ERROR_SUCCESS ==
|
while (ERROR_SUCCESS ==
|
||||||
(error = RegEnumKeyEx (hKey, index++, buf, &buf_size, NULL, NULL,
|
(error = RegEnumKeyEx (hKey, index++, buf, &buf_size, NULL, NULL,
|
||||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
NULL, NULL))
|
||||||
{
|
|| (error == ERROR_MORE_DATA))
|
||||||
if (pathmatch (buf, file))
|
|
||||||
{
|
{
|
||||||
file_type = 1;
|
if (pathmatch (buf, file))
|
||||||
|
{
|
||||||
|
file_type = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
buf_size = MAX_PATH;
|
||||||
|
}
|
||||||
|
if (error != ERROR_NO_MORE_ITEMS)
|
||||||
|
{
|
||||||
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
index = 0;
|
||||||
buf_size = MAX_PATH;
|
buf_size = MAX_PATH;
|
||||||
}
|
while (ERROR_SUCCESS ==
|
||||||
if (error != ERROR_NO_MORE_ITEMS)
|
(error = RegEnumValue (hKey, index++, buf, &buf_size, NULL, NULL,
|
||||||
{
|
NULL, NULL))
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
|| (error == ERROR_MORE_DATA))
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
index = 0;
|
|
||||||
buf_size = MAX_PATH;
|
|
||||||
while (ERROR_SUCCESS ==
|
|
||||||
(error = RegEnumValue (hKey, index++, buf, &buf_size, NULL, NULL,
|
|
||||||
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
|
||||||
{
|
|
||||||
if (pathmatch (buf, file) || (buf[0] == '\0' &&
|
|
||||||
pathmatch (file, DEFAULT_VALUE_NAME)))
|
|
||||||
{
|
{
|
||||||
file_type = -1;
|
if (pathmatch (buf, file) || (buf[0] == '\0' &&
|
||||||
|
pathmatch (file, DEFAULT_VALUE_NAME)))
|
||||||
|
{
|
||||||
|
file_type = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
buf_size = MAX_PATH;
|
||||||
|
}
|
||||||
|
if (error != ERROR_NO_MORE_ITEMS)
|
||||||
|
{
|
||||||
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
buf_size = MAX_PATH;
|
|
||||||
}
|
|
||||||
if (error != ERROR_NO_MORE_ITEMS)
|
|
||||||
{
|
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (hKey != (HKEY) INVALID_HANDLE_VALUE)
|
if (hKey != (HKEY) INVALID_HANDLE_VALUE)
|
||||||
@ -178,12 +186,12 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fhandler_registry::fhandler_registry ():
|
fhandler_registry::fhandler_registry ():
|
||||||
fhandler_proc (FH_REGISTRY)
|
fhandler_proc (FH_REGISTRY)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_registry::fstat (struct __stat64 *buf, path_conv *pc)
|
fhandler_registry::fstat (struct __stat64 *buf, path_conv * pc)
|
||||||
{
|
{
|
||||||
this->fhandler_base::fstat (buf, pc);
|
this->fhandler_base::fstat (buf, pc);
|
||||||
buf->st_mode &= ~_IFMT & NO_W;
|
buf->st_mode &= ~_IFMT & NO_W;
|
||||||
@ -206,6 +214,61 @@ fhandler_registry::fstat (struct __stat64 *buf, path_conv *pc)
|
|||||||
buf->st_mode &= NO_X;
|
buf->st_mode &= NO_X;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (file_type != 0 && file_type != 2)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
const char *path = get_name () + proc_len + registry_len + 2;
|
||||||
|
hKey =
|
||||||
|
open_key (path, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE,
|
||||||
|
(file_type < 0) ? true : false);
|
||||||
|
|
||||||
|
if (hKey != (HKEY) INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
FILETIME ftLastWriteTime;
|
||||||
|
DWORD subkey_count;
|
||||||
|
if (ERROR_SUCCESS ==
|
||||||
|
RegQueryInfoKey (hKey, NULL, NULL, NULL, &subkey_count, NULL,
|
||||||
|
NULL, NULL, NULL, NULL, NULL,
|
||||||
|
&ftLastWriteTime))
|
||||||
|
{
|
||||||
|
to_timestruc_t (&ftLastWriteTime, &buf->st_mtim);
|
||||||
|
buf->st_ctim = buf->st_mtim;
|
||||||
|
time_as_timestruc_t (&buf->st_atim);
|
||||||
|
if (file_type > 0)
|
||||||
|
buf->st_nlink = subkey_count;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int pathlen = strlen (path);
|
||||||
|
const char *value_name = path + pathlen - 1;
|
||||||
|
if (SLASH_P (*value_name) && pathlen > 1)
|
||||||
|
value_name--;
|
||||||
|
while (!SLASH_P (*value_name))
|
||||||
|
value_name--;
|
||||||
|
value_name++;
|
||||||
|
DWORD dwSize;
|
||||||
|
if (ERROR_SUCCESS ==
|
||||||
|
RegQueryValueEx (hKey, value_name, NULL, NULL, NULL,
|
||||||
|
&dwSize))
|
||||||
|
buf->st_size = dwSize;
|
||||||
|
}
|
||||||
|
__uid32_t uid;
|
||||||
|
__gid32_t gid;
|
||||||
|
if (get_object_attribute
|
||||||
|
((HANDLE) hKey, SE_REGISTRY_KEY, &buf->st_mode, &uid,
|
||||||
|
&gid) == 0)
|
||||||
|
{
|
||||||
|
buf->st_uid = uid;
|
||||||
|
buf->st_gid = gid;
|
||||||
|
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||||
|
if (file_type > 0)
|
||||||
|
buf->st_mode |= S_IFDIR;
|
||||||
|
else
|
||||||
|
buf->st_mode &= NO_X;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegCloseKey (hKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,14 +293,15 @@ fhandler_registry::readdir (DIR * dir)
|
|||||||
if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE
|
if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE
|
||||||
&& dir->__d_position == 0)
|
&& dir->__d_position == 0)
|
||||||
{
|
{
|
||||||
handle = open_key (path + 1);
|
handle = open_key (path + 1, KEY_READ, false);
|
||||||
dir->__d_u.__d_data.__handle = handle;;
|
dir->__d_u.__d_data.__handle = handle;
|
||||||
}
|
}
|
||||||
if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)
|
if (dir->__d_u.__d_data.__handle == INVALID_HANDLE_VALUE)
|
||||||
goto out;
|
goto out;
|
||||||
if (dir->__d_position < SPECIAL_DOT_FILE_COUNT)
|
if (dir->__d_position < SPECIAL_DOT_FILE_COUNT)
|
||||||
{
|
{
|
||||||
strcpy (dir->__d_dirent->d_name, special_dot_files[dir->__d_position++]);
|
strcpy (dir->__d_dirent->d_name,
|
||||||
|
special_dot_files[dir->__d_position++]);
|
||||||
res = dir->__d_dirent;
|
res = dir->__d_dirent;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -252,7 +316,8 @@ retry:
|
|||||||
else
|
else
|
||||||
error =
|
error =
|
||||||
RegEnumKeyEx ((HKEY) dir->__d_u.__d_data.__handle, dir->__d_position -
|
RegEnumKeyEx ((HKEY) dir->__d_u.__d_data.__handle, dir->__d_position -
|
||||||
SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL, NULL);
|
SPECIAL_DOT_FILE_COUNT, buf, &buf_size, NULL, NULL, NULL,
|
||||||
|
NULL);
|
||||||
if (error == ERROR_NO_MORE_ITEMS
|
if (error == ERROR_NO_MORE_ITEMS
|
||||||
&& (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
|
&& (dir->__d_position & REG_ENUM_VALUES_MASK) == 0)
|
||||||
{
|
{
|
||||||
@ -280,7 +345,7 @@ retry:
|
|||||||
dir->__d_position += 0x10000;
|
dir->__d_position += 0x10000;
|
||||||
res = dir->__d_dirent;
|
res = dir->__d_dirent;
|
||||||
out:
|
out:
|
||||||
syscall_printf ("%p = readdir (%p) (%s)", &dir->__d_dirent, dir, buf);
|
syscall_printf ("%p = readdir (%p)", &dir->__d_dirent, dir);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,13 +394,11 @@ fhandler_registry::closedir (DIR * dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_registry::open (path_conv *pc, int flags, mode_t mode)
|
fhandler_registry::open (path_conv * pc, int flags, mode_t mode)
|
||||||
{
|
{
|
||||||
DWORD type, size;
|
|
||||||
LONG error;
|
|
||||||
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
|
||||||
int pathlen;
|
int pathlen;
|
||||||
const char *file;
|
const char *file;
|
||||||
|
HKEY handle;
|
||||||
|
|
||||||
int res = fhandler_virtual::open (pc, flags, mode);
|
int res = fhandler_virtual::open (pc, flags, mode);
|
||||||
if (!res)
|
if (!res)
|
||||||
@ -418,33 +481,88 @@ fhandler_registry::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
hKey = open_key (path, KEY_READ, true);
|
handle = open_key (path, KEY_READ, true);
|
||||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
if (handle == (HKEY) INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
res = 0;
|
res = 0;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (pathmatch (file, DEFAULT_VALUE_NAME))
|
|
||||||
file = "";
|
|
||||||
|
|
||||||
if (hKey != HKEY_PERFORMANCE_DATA)
|
set_io_handle (handle);
|
||||||
|
|
||||||
|
if (pathmatch (file, DEFAULT_VALUE_NAME))
|
||||||
|
value_name = cstrdup ("");
|
||||||
|
else
|
||||||
|
value_name = cstrdup (file);
|
||||||
|
|
||||||
|
if (!fill_filebuf ())
|
||||||
{
|
{
|
||||||
error = RegQueryValueEx (hKey, file, NULL, &type, NULL, &size);
|
RegCloseKey (handle);
|
||||||
|
res = 0;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & O_APPEND)
|
||||||
|
position = filesize;
|
||||||
|
else
|
||||||
|
position = 0;
|
||||||
|
|
||||||
|
success:
|
||||||
|
res = 1;
|
||||||
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
|
set_open_status ();
|
||||||
|
out:
|
||||||
|
syscall_printf ("%d = fhandler_registry::open (%p, %d)", res, flags, mode);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fhandler_registry::close ()
|
||||||
|
{
|
||||||
|
int res = fhandler_virtual::close ();
|
||||||
|
if (res != 0)
|
||||||
|
return res;
|
||||||
|
HKEY handle = (HKEY) get_handle ();
|
||||||
|
if (handle != (HKEY) INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (RegCloseKey (handle) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
res = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value_name)
|
||||||
|
cfree (value_name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fhandler_registry::fill_filebuf ()
|
||||||
|
{
|
||||||
|
DWORD type, size;
|
||||||
|
LONG error;
|
||||||
|
HKEY handle = (HKEY) get_handle ();
|
||||||
|
if (handle != HKEY_PERFORMANCE_DATA)
|
||||||
|
{
|
||||||
|
error = RegQueryValueEx (handle, value_name, NULL, &type, NULL, &size);
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
if (error != ERROR_FILE_NOT_FOUND)
|
||||||
res = -1;
|
{
|
||||||
goto out;
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
goto value_not_found;
|
||||||
}
|
}
|
||||||
bufalloc = size;
|
bufalloc = size;
|
||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||||
error =
|
error =
|
||||||
RegQueryValueEx (hKey, file, NULL, NULL, (BYTE *) filebuf, &size);
|
RegQueryValueEx (handle, value_name, NULL, NULL, (BYTE *) filebuf,
|
||||||
|
&size);
|
||||||
if (error != ERROR_SUCCESS)
|
if (error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
res = 0;
|
return true;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
filesize = size;
|
filesize = size;
|
||||||
}
|
}
|
||||||
@ -460,43 +578,49 @@ fhandler_registry::open (path_conv *pc, int flags, mode_t mode)
|
|||||||
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
filebuf = (char *) cmalloc (HEAP_BUF, bufalloc);
|
||||||
}
|
}
|
||||||
error =
|
error =
|
||||||
RegQueryValueEx (hKey, file, NULL, &type, (BYTE *) filebuf,
|
RegQueryValueEx (handle, value_name, NULL, &type,
|
||||||
&size);
|
(BYTE *) filebuf, &size);
|
||||||
if (error != ERROR_SUCCESS && res != ERROR_MORE_DATA)
|
if (error != ERROR_SUCCESS && error != ERROR_MORE_DATA)
|
||||||
{
|
{
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
if (error != ERROR_FILE_NOT_FOUND)
|
||||||
res = 0;
|
{
|
||||||
goto out;
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
goto value_not_found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (error == ERROR_MORE_DATA);
|
while (error == ERROR_MORE_DATA);
|
||||||
filesize = size;
|
filesize = size;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
if (flags & O_APPEND)
|
value_not_found:
|
||||||
position = filesize;
|
DWORD buf_size = MAX_PATH;
|
||||||
else
|
char buf[buf_size];
|
||||||
position = 0;
|
int index = 0;
|
||||||
|
while (ERROR_SUCCESS ==
|
||||||
success:
|
(error = RegEnumKeyEx (handle, index++, buf, &buf_size, NULL, NULL,
|
||||||
res = 1;
|
NULL, NULL)) || (error == ERROR_MORE_DATA))
|
||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
{
|
||||||
set_open_status ();
|
if (pathmatch (buf, value_name))
|
||||||
out:
|
{
|
||||||
if (hKey != (HKEY) INVALID_HANDLE_VALUE)
|
set_errno (EISDIR);
|
||||||
RegCloseKey (hKey);
|
return false;
|
||||||
syscall_printf ("%d = fhandler_registry::open (%p, %d)", res, flags, mode);
|
}
|
||||||
return res;
|
buf_size = MAX_PATH;
|
||||||
}
|
}
|
||||||
|
if (error != ERROR_NO_MORE_ITEMS)
|
||||||
void
|
{
|
||||||
fhandler_registry::fill_filebuf ()
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
{
|
return false;
|
||||||
|
}
|
||||||
|
set_errno (ENOENT);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Auxillary member function to open registry keys. */
|
/* Auxillary member function to open registry keys. */
|
||||||
HKEY
|
static HKEY
|
||||||
fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)
|
open_key (const char *name, REGSAM access, bool isValue)
|
||||||
{
|
{
|
||||||
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
HKEY hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
HKEY hParentKey = (HKEY) INVALID_HANDLE_VALUE;
|
HKEY hParentKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
@ -517,10 +641,15 @@ fhandler_registry::open_key (const char *name, REGSAM access, bool isValue)
|
|||||||
|
|
||||||
if (hParentKey != (HKEY) INVALID_HANDLE_VALUE)
|
if (hParentKey != (HKEY) INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
hKey = (HKEY) INVALID_HANDLE_VALUE;
|
REGSAM effective_access = KEY_READ;
|
||||||
LONG error = RegOpenKeyEx (hParentKey, component, 0, access, &hKey);
|
if ((strchr (name, '/') == NULL && isValue == true) || *name == 0)
|
||||||
if (hKey == (HKEY) INVALID_HANDLE_VALUE)
|
effective_access = access;
|
||||||
|
LONG
|
||||||
|
error =
|
||||||
|
RegOpenKeyEx (hParentKey, component, 0, effective_access, &hKey);
|
||||||
|
if (error != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
hKey = (HKEY) INVALID_HANDLE_VALUE;
|
||||||
seterrno_from_win_error (__FILE__, __LINE__, error);
|
seterrno_from_win_error (__FILE__, __LINE__, error);
|
||||||
return hKey;
|
return hKey;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,8 @@ fhandler_virtual::lseek (__off64_t offset, int whence)
|
|||||||
* On Linux, when you lseek within a /proc file,
|
* On Linux, when you lseek within a /proc file,
|
||||||
* the contents of the file are updated.
|
* the contents of the file are updated.
|
||||||
*/
|
*/
|
||||||
fill_filebuf ();
|
if (!fill_filebuf ())
|
||||||
|
return (__off64_t) -1;
|
||||||
switch (whence)
|
switch (whence)
|
||||||
{
|
{
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
@ -209,8 +210,6 @@ fhandler_virtual::open (path_conv *, int flags, mode_t mode)
|
|||||||
|
|
||||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||||
|
|
||||||
set_nohandle (true);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +219,8 @@ fhandler_virtual::exists ()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
fhandler_virtual::fill_filebuf ()
|
fhandler_virtual::fill_filebuf ()
|
||||||
{
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ details. */
|
|||||||
#include <wininet.h>
|
#include <wininet.h>
|
||||||
#include <ntsecapi.h>
|
#include <ntsecapi.h>
|
||||||
#include <subauth.h>
|
#include <subauth.h>
|
||||||
|
#include <aclapi.h>
|
||||||
#include "cygerrno.h"
|
#include "cygerrno.h"
|
||||||
#include "security.h"
|
#include "security.h"
|
||||||
#include "fhandler.h"
|
#include "fhandler.h"
|
||||||
@ -1301,6 +1302,174 @@ get_file_attribute (int use_ntsec, const char *file,
|
|||||||
return res > 0 ? 0 : -1;
|
return res > 0 ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_nt_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *attribute,
|
||||||
|
__uid32_t *uidret, __gid32_t *gidret)
|
||||||
|
{
|
||||||
|
if (!wincap.has_security ())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
PSECURITY_DESCRIPTOR psd = NULL;
|
||||||
|
PSID owner_sid;
|
||||||
|
PSID group_sid;
|
||||||
|
PACL acl;
|
||||||
|
|
||||||
|
if (ERROR_SUCCESS != GetSecurityInfo (handle, object_type,
|
||||||
|
DACL_SECURITY_INFORMATION |
|
||||||
|
GROUP_SECURITY_INFORMATION |
|
||||||
|
OWNER_SECURITY_INFORMATION,
|
||||||
|
&owner_sid,
|
||||||
|
&group_sid,
|
||||||
|
&acl,
|
||||||
|
NULL,
|
||||||
|
&psd))
|
||||||
|
{
|
||||||
|
__seterrno ();
|
||||||
|
debug_printf ("GetSecurityInfo %E");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__uid32_t uid = cygsid (owner_sid).get_uid ();
|
||||||
|
__gid32_t gid = cygsid (group_sid).get_gid ();
|
||||||
|
if (uidret)
|
||||||
|
*uidret = uid;
|
||||||
|
if (gidret)
|
||||||
|
*gidret = gid;
|
||||||
|
|
||||||
|
if (!attribute)
|
||||||
|
{
|
||||||
|
syscall_printf ("uid %d, gid %d", uid, gid);
|
||||||
|
LocalFree (psd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL grp_member = is_grp_member (uid, gid);
|
||||||
|
|
||||||
|
if (!acl)
|
||||||
|
{
|
||||||
|
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
|
syscall_printf ("No ACL = %x, uid %d, gid %d",
|
||||||
|
*attribute, uid, gid);
|
||||||
|
LocalFree (psd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ACCESS_ALLOWED_ACE *ace;
|
||||||
|
int allow = 0;
|
||||||
|
int deny = 0;
|
||||||
|
int *flags, *anti;
|
||||||
|
|
||||||
|
for (DWORD i = 0; i < acl->AceCount; ++i)
|
||||||
|
{
|
||||||
|
if (!GetAce (acl, i, (PVOID *) &ace))
|
||||||
|
continue;
|
||||||
|
if (ace->Header.AceFlags & INHERIT_ONLY_ACE)
|
||||||
|
continue;
|
||||||
|
switch (ace->Header.AceType)
|
||||||
|
{
|
||||||
|
case ACCESS_ALLOWED_ACE_TYPE:
|
||||||
|
flags = &allow;
|
||||||
|
anti = &deny;
|
||||||
|
break;
|
||||||
|
case ACCESS_DENIED_ACE_TYPE:
|
||||||
|
flags = &deny;
|
||||||
|
anti = &allow;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cygsid ace_sid ((PSID) &ace->SidStart);
|
||||||
|
if (owner_sid && ace_sid == owner_sid)
|
||||||
|
{
|
||||||
|
if (ace->Mask & FILE_READ_DATA)
|
||||||
|
*flags |= S_IRUSR;
|
||||||
|
if (ace->Mask & FILE_WRITE_DATA)
|
||||||
|
*flags |= S_IWUSR;
|
||||||
|
if (ace->Mask & FILE_EXECUTE)
|
||||||
|
*flags |= S_IXUSR;
|
||||||
|
}
|
||||||
|
else if (group_sid && ace_sid == group_sid)
|
||||||
|
{
|
||||||
|
if (ace->Mask & FILE_READ_DATA)
|
||||||
|
*flags |= S_IRGRP
|
||||||
|
| ((grp_member && !(*anti & S_IRUSR)) ? S_IRUSR : 0);
|
||||||
|
if (ace->Mask & FILE_WRITE_DATA)
|
||||||
|
*flags |= S_IWGRP
|
||||||
|
| ((grp_member && !(*anti & S_IWUSR)) ? S_IWUSR : 0);
|
||||||
|
if (ace->Mask & FILE_EXECUTE)
|
||||||
|
*flags |= S_IXGRP
|
||||||
|
| ((grp_member && !(*anti & S_IXUSR)) ? S_IXUSR : 0);
|
||||||
|
}
|
||||||
|
else if (ace_sid == well_known_world_sid)
|
||||||
|
{
|
||||||
|
if (ace->Mask & FILE_READ_DATA)
|
||||||
|
*flags |= S_IROTH
|
||||||
|
| ((!(*anti & S_IRGRP)) ? S_IRGRP : 0)
|
||||||
|
| ((!(*anti & S_IRUSR)) ? S_IRUSR : 0);
|
||||||
|
if (ace->Mask & FILE_WRITE_DATA)
|
||||||
|
*flags |= S_IWOTH
|
||||||
|
| ((!(*anti & S_IWGRP)) ? S_IWGRP : 0)
|
||||||
|
| ((!(*anti & S_IWUSR)) ? S_IWUSR : 0);
|
||||||
|
if (ace->Mask & FILE_EXECUTE)
|
||||||
|
{
|
||||||
|
*flags |= S_IXOTH
|
||||||
|
| ((!(*anti & S_IXGRP)) ? S_IXGRP : 0)
|
||||||
|
| ((!(*anti & S_IXUSR)) ? S_IXUSR : 0);
|
||||||
|
}
|
||||||
|
if ((*attribute & S_IFDIR) &&
|
||||||
|
(ace->Mask & (FILE_WRITE_DATA | FILE_EXECUTE | FILE_DELETE_CHILD))
|
||||||
|
== (FILE_WRITE_DATA | FILE_EXECUTE))
|
||||||
|
*flags |= S_ISVTX;
|
||||||
|
}
|
||||||
|
else if (ace_sid == well_known_null_sid)
|
||||||
|
{
|
||||||
|
/* Read SUID, SGID and VTX bits from NULL ACE. */
|
||||||
|
if (ace->Mask & FILE_READ_DATA)
|
||||||
|
*flags |= S_ISVTX;
|
||||||
|
if (ace->Mask & FILE_WRITE_DATA)
|
||||||
|
*flags |= S_ISGID;
|
||||||
|
if (ace->Mask & FILE_APPEND_DATA)
|
||||||
|
*flags |= S_ISUID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*attribute &= ~(S_IRWXU | S_IRWXG | S_IRWXO | S_ISVTX | S_ISGID | S_ISUID);
|
||||||
|
*attribute |= allow;
|
||||||
|
*attribute &= ~deny;
|
||||||
|
|
||||||
|
LocalFree (psd);
|
||||||
|
|
||||||
|
syscall_printf ("%x, uid %d, gid %d", *attribute, uid, gid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type,
|
||||||
|
int *attribute, __uid32_t *uidret, __gid32_t *gidret)
|
||||||
|
{
|
||||||
|
if (allow_ntsec)
|
||||||
|
{
|
||||||
|
int res = get_nt_object_attribute (handle, object_type, attribute, uidret, gidret);
|
||||||
|
if (attribute && (*attribute & S_IFLNK) == S_IFLNK)
|
||||||
|
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uidret)
|
||||||
|
*uidret = getuid32 ();
|
||||||
|
if (gidret)
|
||||||
|
*gidret = getgid32 ();
|
||||||
|
|
||||||
|
if (!attribute)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* symlinks are everything for everyone!*/
|
||||||
|
if ((*attribute & S_IFLNK) == S_IFLNK)
|
||||||
|
*attribute |= S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
add_access_allowed_ace (PACL acl, int offset, DWORD attributes,
|
add_access_allowed_ace (PACL acl, int offset, DWORD attributes,
|
||||||
PSID sid, size_t &len_add, DWORD inherit)
|
PSID sid, size_t &len_add, DWORD inherit)
|
||||||
|
@ -8,6 +8,7 @@ This software is a copyrighted work licensed under the terms of the
|
|||||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||||
details. */
|
details. */
|
||||||
|
|
||||||
|
#include <accctrl.h>
|
||||||
#define DONT_INHERIT (0)
|
#define DONT_INHERIT (0)
|
||||||
#define INHERIT_ALL (CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE)
|
#define INHERIT_ALL (CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE)
|
||||||
#define INHERIT_ONLY (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE)
|
#define INHERIT_ONLY (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|OBJECT_INHERIT_ACE)
|
||||||
@ -169,6 +170,8 @@ int __stdcall get_file_attribute (int, const char *, int *,
|
|||||||
__uid32_t * = NULL, __gid32_t * = NULL);
|
__uid32_t * = NULL, __gid32_t * = NULL);
|
||||||
int __stdcall set_file_attribute (int, const char *, int);
|
int __stdcall set_file_attribute (int, const char *, int);
|
||||||
int __stdcall set_file_attribute (int, const char *, __uid32_t, __gid32_t, int);
|
int __stdcall set_file_attribute (int, const char *, __uid32_t, __gid32_t, int);
|
||||||
|
int __stdcall get_object_attribute (HANDLE handle, SE_OBJECT_TYPE object_type, int *,
|
||||||
|
__uid32_t * = NULL, __gid32_t * = NULL);
|
||||||
LONG __stdcall read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size);
|
LONG __stdcall read_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, LPDWORD sd_size);
|
||||||
LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size);
|
LONG __stdcall write_sd(const char *file, PSECURITY_DESCRIPTOR sd_buf, DWORD sd_size);
|
||||||
BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
BOOL __stdcall add_access_allowed_ace (PACL acl, int offset, DWORD attributes, PSID sid, size_t &len_add, DWORD inherit);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user