84c7d40932
the changes below. Redefine process structure to avoid a fixed size table. Redefine pinfo/_pinfo classes. Use these throughout. * dcrt0.cc (dll_crt0_1): Accomodate set_myself argument change. (__api_fatal): Accomodate _pinfo::record_death argument change. * exceptions.cc (really_exit): Ditto. (sig_handle_tty_stop): Use pinfo constructor to access process info. (events_init): Don't create pinfo_mutex since it is no longer required. * external.cc (fillout_pinfo): Use winpids class to iterate over all system pids. (cygwin_internal): lock_pinfo_for_update and unlock_pinfo are now noops. * fhandler_termios.cc (fhandler_termios::set_ctty): Use pinfo constructor to access process info. * fork.cc (fork): Reorganize to initialize child info after the child has started since that is when we know the child's winpid, which is necessary to allocate the pinfo shared memory. * mmap.cc (recreate_mmaps_after_fork): Change arg type to _pinfo. * pinfo.cc: Rename pinfo methods to _pinfo throughout. Eliminate pinfo_list stuff. (set_myself): Accept a pid argument now. Call pinfo initializer to initialize myself. Detect when this is an "execed" process and create an "indirect" pid block. (pinfo_init): Accomodate set_myself arg change. (procinfo): Remove. (pinfo::lock_pinfo): Remove. (pinfo::unlock_pinfo): Remove. (pinfo::init): New method. Allocates shared memory space for process pinfo structure. (pinfo::record_death): Don't call locking functions. (cygwin_winpid_to_pid): Simplify by using new pinfo constructor. (EnumProcessesW95): New function for iterating over processes on Windows 95. (winpids::winpids): New constructor for winpids class. Sets up a list of process ids. (enum_init): Initialize w95/wnt pid enumerators. * shared.cc (shared-info::initialize): Remove pid initialization. * shared.h: Move pinfo stuff into pinfo.h. (class shared_info): Remove pinfo_list element. * signal.cc (kill_worker): Use pinfo constructor to access process info. (kill_pgrp): Ditto. Use winpids methods to access list of processes. * sigproc.cc: Throughout, modify to use _pinfo where appropriate. (proc_exists (pid_t)): New function. Determines if a process exists based on the pid. (proc_exists (_pinfo *p): Use new proc_exists function above. (proc_subproc): Copy pinfo stuff around rather than _pinfo pointers. Try to be careful about releasing shared memory when we don't need it anymore. Remove pinfo locks. (remove_zombies): Remove pinfo memory when zombie is going away. * sigproc.h: Reflect _pinfo/pinfo changes in sigproc.cc. * spawn.cc (spawn_guts): Eliminate pinfo *child argument. Reorganize to only initialize child pinfo after process has been started and we know the windows pid. (_spawnve): Reflect spawn_guts changes. * syscalls.cc (setpgid): Use pinfo constructor to access process info. (getpgid): Ditto. (internal_getlogin): Use _pinfo. * winsup.h: Eliminate pinfo_mutex. Eliminate spawn_guts declaration since it is static now. Reflect set_myself argument change. * include/sys/cygwin.h: Add some PID_* enums to accomodate new pinfo stuff. * include/cygwin/version.h: Update minor version for cygdrive changes below.
335 lines
8.3 KiB
C++
335 lines
8.3 KiB
C++
/* ntea.cc: code for manipulating NTEA information
|
|
|
|
Copyright 1997, 1998, 2000 Cygnus Solutions.
|
|
|
|
Written by Sergey S. Okhapkin (sos@prospect.com.ru)
|
|
|
|
This file is part of Cygwin.
|
|
|
|
This software is a copyrighted work licensed under the terms of the
|
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
details. */
|
|
|
|
#include <winsup.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
/* Default to not using NTEA information */
|
|
BOOL allow_ntea = FALSE;
|
|
|
|
/*
|
|
From Windows NT DDK:
|
|
|
|
FILE_FULL_EA_INFORMATION provides extended attribute information.
|
|
This structure is used primarily by network drivers.
|
|
|
|
Members
|
|
|
|
NextEntryOffset
|
|
The offset of the next FILE_FULL_EA_INFORMATION-type entry. This member is
|
|
zero if no other entries follow this one.
|
|
|
|
Flags
|
|
Can be zero or can be set with FILE_NEED_EA, indicating that the file to which
|
|
the EA belongs cannot be interpreted without understanding the associated
|
|
extended attributes.
|
|
|
|
EaNameLength
|
|
The length in bytes of the EaName array. This value does not include a
|
|
zero-terminator to EaName.
|
|
|
|
EaValueLength
|
|
The length in bytes of each EA value in the array.
|
|
|
|
EaName
|
|
An array of characters naming the EA for this entry.
|
|
|
|
Comments
|
|
This structure is longword-aligned. If a set of FILE_FULL_EA_INFORMATION
|
|
entries is buffered, NextEntryOffset value in each entry, except the last,
|
|
falls on a longword boundary.
|
|
The value(s) associated with each entry follows the EaName array. That is, an
|
|
EA's values are located at EaName + (EaNameLength + 1).
|
|
*/
|
|
|
|
typedef struct _FILE_FULL_EA_INFORMATION {
|
|
ULONG NextEntryOffset;
|
|
UCHAR Flags;
|
|
UCHAR EaNameLength;
|
|
USHORT EaValueLength;
|
|
CHAR EaName[1];
|
|
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;
|
|
|
|
/* Functions prototypes */
|
|
|
|
int NTReadEA (const char *file, const char *attrname, char *buf, int len);
|
|
static PFILE_FULL_EA_INFORMATION NTReadEARaw (HANDLE file, int *len);
|
|
BOOL NTWriteEA(const char *file, const char *attrname, char *buf, int len);
|
|
|
|
/*
|
|
* NTReadEA - read file's Extended Attribute.
|
|
*
|
|
* Parameters:
|
|
* file - pointer to filename
|
|
* attrname- pointer to EA name (case insensitivy. EAs are sored in upper
|
|
* case).
|
|
* attrbuf - pointer to buffer to store EA's value.
|
|
* len - length of attrbuf.
|
|
* Return value:
|
|
* 0 - if file or attribute "attrname" not found.
|
|
* N - number of bytes stored in attrbuf if succes.
|
|
* -1 - attrbuf too small for EA value.
|
|
*/
|
|
|
|
int __stdcall
|
|
NTReadEA (const char *file, const char *attrname, char *attrbuf, int len)
|
|
{
|
|
/* return immediately if NTEA usage is turned off */
|
|
if (! allow_ntea)
|
|
return FALSE;
|
|
|
|
HANDLE hFileSource;
|
|
int eafound = 0;
|
|
PFILE_FULL_EA_INFORMATION ea, sea;
|
|
int easize;
|
|
|
|
hFileSource = CreateFile (file, FILE_READ_EA,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
&sec_none_nih, // sa
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_BACKUP_SEMANTICS,
|
|
NULL
|
|
);
|
|
|
|
if (hFileSource == INVALID_HANDLE_VALUE)
|
|
return 0;
|
|
|
|
/* Read in raw array of EAs */
|
|
ea = sea = NTReadEARaw (hFileSource, &easize);
|
|
|
|
/* Search for requested attribute */
|
|
while (sea)
|
|
{
|
|
if (strcasematch (ea->EaName, attrname)) /* EA found */
|
|
{
|
|
if (ea->EaValueLength > len)
|
|
{
|
|
eafound = -1; /* buffer too small */
|
|
break;
|
|
}
|
|
memcpy (attrbuf, ea->EaName + (ea->EaNameLength + 1),
|
|
ea->EaValueLength);
|
|
eafound = ea->EaValueLength;
|
|
break;
|
|
}
|
|
if ((ea->NextEntryOffset == 0) || ((int) ea->NextEntryOffset > easize))
|
|
break;
|
|
ea = (PFILE_FULL_EA_INFORMATION) ((char *) ea + ea->NextEntryOffset);
|
|
}
|
|
|
|
if (sea)
|
|
free (sea);
|
|
CloseHandle (hFileSource);
|
|
|
|
return eafound;
|
|
}
|
|
|
|
/*
|
|
* NTReadEARaw - internal routine to read EAs array to malloced buffer. The
|
|
* caller should free this buffer after usage.
|
|
* Parameters:
|
|
* hFileSource - handle to file. This handle should have FILE_READ_EA
|
|
* rights.
|
|
* len - pointer to int variable where length of buffer will
|
|
* be stored.
|
|
* Return value:
|
|
* pointer to buffer with file's EAs, or NULL if any error occured.
|
|
*/
|
|
|
|
static
|
|
PFILE_FULL_EA_INFORMATION
|
|
NTReadEARaw (HANDLE hFileSource, int *len)
|
|
{
|
|
WIN32_STREAM_ID StreamId;
|
|
DWORD dwBytesWritten;
|
|
LPVOID lpContext;
|
|
DWORD StreamSize;
|
|
PFILE_FULL_EA_INFORMATION eafound = NULL;
|
|
|
|
lpContext = NULL;
|
|
StreamSize = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**);
|
|
|
|
/* Read the WIN32_STREAM_ID in */
|
|
|
|
while (BackupRead (hFileSource, (LPBYTE) &StreamId, StreamSize,
|
|
&dwBytesWritten,
|
|
FALSE, // don't abort yet
|
|
FALSE, // don't process security
|
|
&lpContext))
|
|
{
|
|
DWORD sl,sh;
|
|
|
|
if (dwBytesWritten == 0) /* No more Stream IDs */
|
|
break;
|
|
/* skip StreamName */
|
|
if (StreamId.dwStreamNameSize)
|
|
{
|
|
unsigned char *buf;
|
|
buf = (unsigned char *) malloc (StreamId.dwStreamNameSize);
|
|
|
|
if (buf == NULL)
|
|
break;
|
|
|
|
if (!BackupRead (hFileSource, buf, // buffer to read
|
|
StreamId.dwStreamNameSize, // num bytes to read
|
|
&dwBytesWritten,
|
|
FALSE, // don't abort yet
|
|
FALSE, // don't process security
|
|
&lpContext)) // Stream name read error
|
|
{
|
|
free (buf);
|
|
break;
|
|
}
|
|
free (buf);
|
|
}
|
|
|
|
/* Is it EA stream? */
|
|
if (StreamId.dwStreamId == BACKUP_EA_DATA)
|
|
{
|
|
unsigned char *buf;
|
|
buf = (unsigned char *) malloc (StreamId.Size.LowPart);
|
|
|
|
if (buf == NULL)
|
|
break;
|
|
if (!BackupRead (hFileSource, buf, // buffer to read
|
|
StreamId.Size.LowPart, // num bytes to write
|
|
&dwBytesWritten,
|
|
FALSE, // don't abort yet
|
|
FALSE, // don't process security
|
|
&lpContext))
|
|
{
|
|
free (buf); /* EA read error */
|
|
break;
|
|
}
|
|
eafound = (PFILE_FULL_EA_INFORMATION) buf;
|
|
*len = StreamId.Size.LowPart;
|
|
break;
|
|
}
|
|
/* Skip current stream */
|
|
if (!BackupSeek (hFileSource,
|
|
StreamId.Size.LowPart,
|
|
StreamId.Size.HighPart,
|
|
&sl,
|
|
&sh,
|
|
&lpContext))
|
|
break;
|
|
}
|
|
|
|
/* free context */
|
|
BackupRead (
|
|
hFileSource,
|
|
NULL, // buffer to write
|
|
0, // number of bytes to write
|
|
&dwBytesWritten,
|
|
TRUE, // abort
|
|
FALSE, // don't process security
|
|
&lpContext);
|
|
|
|
return eafound;
|
|
}
|
|
|
|
/*
|
|
* NTWriteEA - write file's Extended Attribute.
|
|
*
|
|
* Parameters:
|
|
* file - pointer to filename
|
|
* attrname- pointer to EA name (case insensitivy. EAs are sored in upper
|
|
* case).
|
|
* buf - pointer to buffer with EA value.
|
|
* len - length of buf.
|
|
* Return value:
|
|
* TRUE if success, FALSE otherwice.
|
|
* Note: if len=0 given EA will be deleted.
|
|
*/
|
|
|
|
BOOL __stdcall
|
|
NTWriteEA (const char *file, const char *attrname, char *buf, int len)
|
|
{
|
|
/* return immediately if NTEA usage is turned off */
|
|
if (! allow_ntea)
|
|
return TRUE;
|
|
|
|
HANDLE hFileSource;
|
|
WIN32_STREAM_ID StreamId;
|
|
DWORD dwBytesWritten;
|
|
LPVOID lpContext;
|
|
DWORD StreamSize, easize;
|
|
BOOL bSuccess=FALSE;
|
|
PFILE_FULL_EA_INFORMATION ea;
|
|
|
|
hFileSource = CreateFile (file, FILE_WRITE_EA,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
&sec_none_nih, // sa
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_BACKUP_SEMANTICS,
|
|
NULL);
|
|
|
|
if (hFileSource == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
|
|
lpContext = NULL;
|
|
StreamSize = sizeof (WIN32_STREAM_ID) - sizeof (WCHAR**);
|
|
|
|
/* FILE_FULL_EA_INFORMATION structure is longword-aligned */
|
|
easize = sizeof (*ea) - sizeof (WCHAR**) + strlen (attrname) + 1 + len
|
|
+ (sizeof (DWORD) - 1);
|
|
easize &= ~(sizeof (DWORD) - 1);
|
|
|
|
if ((ea = (PFILE_FULL_EA_INFORMATION) malloc (easize)) == NULL)
|
|
goto cleanup;
|
|
|
|
memset (ea, 0, easize);
|
|
ea->EaNameLength = strlen (attrname);
|
|
ea->EaValueLength = len;
|
|
strcpy (ea->EaName, attrname);
|
|
memcpy (ea->EaName + (ea->EaNameLength + 1), buf, len);
|
|
|
|
StreamId.dwStreamId = BACKUP_EA_DATA;
|
|
StreamId.dwStreamAttributes = 0;
|
|
StreamId.Size.HighPart = 0;
|
|
StreamId.Size.LowPart = easize;
|
|
StreamId.dwStreamNameSize = 0;
|
|
|
|
if (!BackupWrite (hFileSource, (LPBYTE) &StreamId, StreamSize,
|
|
&dwBytesWritten,
|
|
FALSE, // don't abort yet
|
|
FALSE, // don't process security
|
|
&lpContext))
|
|
goto cleanup;
|
|
|
|
if (!BackupWrite (hFileSource, (LPBYTE) ea, easize,
|
|
&dwBytesWritten,
|
|
FALSE, // don't abort yet
|
|
FALSE, // don't process security
|
|
&lpContext))
|
|
goto cleanup;
|
|
|
|
bSuccess = TRUE;
|
|
/* free context */
|
|
|
|
cleanup:
|
|
BackupRead (hFileSource,
|
|
NULL, // buffer to write
|
|
0, // number of bytes to write
|
|
&dwBytesWritten,
|
|
TRUE, // abort
|
|
FALSE, // don't process security
|
|
&lpContext);
|
|
|
|
CloseHandle (hFileSource);
|
|
if (ea)
|
|
free (ea);
|
|
|
|
return bSuccess;
|
|
}
|