|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
psxsrv.h
Abstract:
Main include file for POSIX Subsystem Server
Author:
Steve Wood (stevewo) 22-Aug-1989
Revision History:
Ellen Aycock-Wright 15-Jul-91 Modify for POSIX subsystem --*/
#ifndef _PSXP_
#define _PSXP_
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <types.h>
#include <string.h>
#include <limits.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys\wait.h>
#include <ntsm.h>
#include "psxmsg.h"
#if DBG
#define PSX_DEBUG_INIT 0x0000001
#define PSX_DEBUG_LPC 0x0000002
#define PSX_DEBUG_MSGDUMP 0x0000004
#define PSX_DEBUG_EXEC 0x0000008
extern ULONG PsxDebug; #define IF_PSX_DEBUG(ComponentFlag ) \
if (PsxDebug & (PSX_DEBUG_ ## ComponentFlag)) #else
#define IF_PSX_DEBUG( ComponentFlag ) if (FALSE)
#endif //DBG
BOOLEAN PsxpDebuggerActive; HANDLE PsxpDebugPort; ULONG PsxpApiMsgSize;
int __NullPosixApi();
VOID Panic( IN PSZ PanicString );
//
// Constants for Posix ID / Sid mapping
//
#define SHARE_ALL (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
//
// This is the name of the directory used to store open files that have
// been unlinked.
//
#define PSX_JUNK_DIR L"$$psxjunk"
//
// Posix Process types constants and data structures
//
#define CIDHASHSIZE 256
#define CIDTOHASHINDEX(pcid) (ULONG)(\
((ULONG_PTR)((pcid)->UniqueProcess))&(CIDHASHSIZE-1))
#define PIDINDEXBITS 0xffff
#define PIDSEQSHIFT 16
#define SPECIALPID 1
// #define SPECIALPID 0xff000000
#define PIDTOPROCESS(pid) \
&FirstProcess[(pid) & PIDINDEXBITS]
#define MAKEPID(pid,seq,index) \
(pid) = (seq) & 0xff;\ (pid) <<= PIDSEQSHIFT;\ (pid) |= ((index)&PIDINDEXBITS)
#define ISFILEDESINRANGE(fd) (\
( (ULONG)(fd) < OPEN_MAX ) )
typedef struct _FILEDESCRIPTOR { struct _SYSTEMOPENFILE *SystemOpenFileDesc; ULONG Flags; // descriptor flags (FD_CLOEXEC)
} FILEDESCRIPTOR; typedef FILEDESCRIPTOR *PFILEDESCRIPTOR;
//
// Flags for FILEDESCRIPTOR.Flags
//
#define PSX_FD_CLOSE_ON_EXEC 0x00000001
typedef enum _PSX_INTERRUPTREASON { SignalInterrupt, WaitSatisfyInterrupt, IoCompletionInterrupt, SleepComplete } PSX_INTERRUPTREASON;
struct _PSX_PROCESS; //Make mips compiler happy
struct _INTCB;
typedef void (* INTHANDLER)( IN struct _PSX_PROCESS *p, IN struct _INTCB *IntControlBlock, IN PSX_INTERRUPTREASON InterruptReason, IN int Signal );
typedef struct _INTCB { INTHANDLER IntHandler; PPSX_API_MSG IntMessage; PVOID IntContext; LIST_ENTRY Links; } INTCB, *PINTCB;
#define _SIGNULLSET 0x0
#define _SIGFULLSET 0x7ffff // ((1<<SIGTTOU) - 1)
#define _SIGMAXSIGNO SIGTTOU
#define _SIGSTOPSIGNALS ((1l<<SIGSTOP) | (1l<<SIGTSTP) | (1l<<SIGTTIN)| (1l<<SIGTTOU) )
#define SIGEMPTYSET(set) \
*(set) = _SIGNULLSET
#define SIGFILLSET(set) \
*(set) = _SIGFULLSET
#define SIGADDSET(set, signo) \
*(set) |= ( (1l << (ULONG)((signo)-1)) & _SIGFULLSET )
#define SIGDELSET(set, signo) \
*(set) &= ~( (1l << (ULONG)((signo)-1)) & _SIGFULLSET )
#define SIGISMEMBER(set, signo) \
( *(set) & ( (1l << (ULONG)((signo)-1)) & _SIGFULLSET ) )
#define ISSIGNOINRANGE(signo) \
( (signo) <= _SIGMAXSIGNO )
typedef struct sigaction SIGACTION; typedef SIGACTION *PSIGACTION;
//
// Each signal has an associated signal disposition.
// when a handler is dispatched, the blocked signal mask
// of the process is saved (as part of signal dispatch), and
// a new mask is calculated by oring in the BlockMask bits. When
// (if) the signal handler returns, the previous block mask is restored.
//
typedef struct sigaction SIGDISP; typedef SIGDISP *PSIGDISP;
//
// Each process has a signal database. The process lock of the
// owning process must be held to change information in the
// signal database
//
typedef struct _SIGDB { sigset_t BlockedSignalMask; sigset_t PendingSignalMask; sigset_t SigSuspendMask; SIGDISP SignalDisposition[_SIGMAXSIGNO]; } SIGDB; typedef SIGDB *PSIGDB;
typedef enum _PSX_PROCESSSTATE { Unconnected, Active, Stopped, Exited, Waiting } PSX_PROCESSSTATE;
typedef struct _PSX_CONTROLLING_TTY { LIST_ENTRY Links; RTL_CRITICAL_SECTION Lock;
//
// There is a reference to this terminal for every file descriptor
// that is open on it and every session that has it as a controlling
// tty.
ULONG ReferenceCount; pid_t ForegroundProcessGroup; HANDLE ConsolePort; HANDLE ConsoleCommPort; ULONG UniqueId; PVOID IoBuffer; // mapped in server addr space
struct _PSX_SESSION *Session; } PSX_CONTROLLING_TTY, *PPSX_CONTROLLING_TTY;
typedef struct _PSX_SESSION { ULONG ReferenceCount; PPSX_CONTROLLING_TTY Terminal; pid_t SessionLeader; } PSX_SESSION, *PPSX_SESSION;
#define IS_DIRECTORY_PREFIX_REMOTE(p) ( (ULONG_PTR)(p) & 0x1 )
#define MAKE_DIRECTORY_PREFIX_REMOTE(p) ( (PPSX_DIRECTORY_PREFIX)((ULONG_PTR)(p) | 0x1) )
#define MAKE_DIRECTORY_PREFIX_VALID(p) ( (PPSX_DIRECTORY_PREFIX)((ULONG_PTR)(p) & ~0x1) )
typedef struct _PSX_PROCESS { LIST_ENTRY ClientIdHashLinks;
ULONG Flags;
HANDLE Process; HANDLE Thread; HANDLE AlarmTimer;
PSIGNALDELIVERER SignalDeliverer; PNULLAPICALLER NullApiCaller; PPSX_DIRECTORY_PREFIX DirectoryPrefix;
ULONG ExitStatus; mode_t FileModeCreationMask; FILEDESCRIPTOR ProcessFileTable[OPEN_MAX]; RTL_CRITICAL_SECTION ProcessLock; PSX_PROCESSSTATE State;
//
// InPsx is a count of the number of times *this* process is in
// the subsystem. For instance, if he calls sigsuspend and blocks,
// the count should be 1. If he then executes a signal handler as
// a result of a signal, and the signal handler makes a syscall, the
// count gets bumped to 2.
//
ULONG InPsx;
PINTCB IntControlBlock; ULONG SequenceNumber;
uid_t EffectiveUid; uid_t RealUid;
gid_t EffectiveGid; gid_t RealGid;
pid_t Pid; pid_t ParentPid; pid_t ProcessGroupId; LIST_ENTRY GroupLinks; PPSX_SESSION PsxSession;
HANDLE ClientPort; PCH ClientViewBase; PCH ClientViewBounds; CLIENT_ID ClientId; PEB_PSX_DATA InitialPebPsxData;
BOOLEAN ProcessIsBeingDebugged; CLIENT_ID DebugUiClientId;
SIGDB SignalDataBase;
struct tms ProcessTimes;
//
// When the posix server needs to make a call on behalf of a client
// that could block, we create a thread to endure the blocking for
// us. This happens when we've execed a windows program and we want
// to know when he exits, and for some blocking sockets calls.
//
HANDLE BlockingThread;
} PSX_PROCESS; typedef PSX_PROCESS *PPSX_PROCESS;
//
// Valid bits for the PSX_PROCESS 'Flags' word:
//
#define P_FREE 0x00000001 // process slot is free
#define P_HAS_EXECED 0x00000002 // process successfully execed
#define P_FOREIGN_EXEC 0x00000004 // this is a windows program
#define P_SOCKET_BLOCK 0x00000008 // called blocking sockets call
#define P_WAITED 0x00000010 // process has been waited on
#define P_NO_FORK 0x00000020 // process fork forbidden
#define AcquireProcessLock( p ) RtlEnterCriticalSection( &(p)->ProcessLock )
#define ReleaseProcessLock( p ) RtlLeaveCriticalSection( &(p)->ProcessLock )
//
// Process is stoppable if it is not part of an orphaned process group.
//
#define ISPROCESSSTOPABLE(p) (TRUE)
#define ISPOINTERVALID_CLIENT(pprocess, p, length) \
(((ULONG_PTR)(p) >= (ULONG_PTR)(pprocess)->ClientViewBase) && \ ((char *)(p) + (length)) < (pprocess)->ClientViewBounds)
LIST_ENTRY DefaultBlockList; RTL_CRITICAL_SECTION BlockLock;
//
// The process Table.
//
// This table contains the array of processes. The array is dynamically
// allocated at PSX initialization time. very few operations use a table scan
// to locate processes. Since pids direct map to a process, and since ClientIds
// hash to a process, table scans are only needed to locate groups of processes.
//
// A single lock (PsxProcessStructureLock) guards the process table and
// ClientIdHashTable. This lock is needed to add or delete an entry in the
// PsxProcessTable or ClientIdHashTable.
//
PSX_PROCESS PsxProcessTable[32]; PPSX_PROCESS FirstProcess,LastProcess;
//
// Client Id Hash Table.
//
// Given a client id, the corresponding process is located by indexing into this
// table and then searching the list head at the index.
//
LIST_ENTRY ClientIdHashTable[CIDHASHSIZE];
RTL_CRITICAL_SECTION PsxProcessStructureLock; #define AcquireProcessStructureLock() RtlEnterCriticalSection( &PsxProcessStructureLock )
#define ReleaseProcessStructureLock() RtlLeaveCriticalSection( &PsxProcessStructureLock )
typedef struct _PSX_EXEC_INFO { ANSI_STRING Path; ANSI_STRING CWD; ANSI_STRING Argv; ANSI_STRING Envp; ANSI_STRING LibPath; } PSX_EXEC_INFO; typedef PSX_EXEC_INFO *PPSX_EXEC_INFO;
//
// Routines defined in process.c
//
NTSTATUS PsxInitializeProcess( IN PPSX_PROCESS NewProcess, IN PPSX_PROCESS ForkProcess OPTIONAL, IN ULONG SessionId, IN HANDLE ProcessHandle, IN HANDLE ThreadHandle, IN PPSX_SESSION Session OPTIONAL );
NTSTATUS PsxInitializeProcessStructure( VOID );
PPSX_PROCESS PsxAllocateProcess ( IN PCLIENT_ID ClientId );
BOOLEAN PsxCreateProcess( IN PPSX_EXEC_INFO ExecInfo, OUT PPSX_PROCESS *NewProcess, IN HANDLE ParentProc, IN PPSX_SESSION Session );
PPSX_PROCESS PsxLocateProcessByClientId ( IN PCLIENT_ID ClientId );
PPSX_PROCESS PsxLocateProcessBySession( IN PPSX_SESSION Session );
PPSX_SESSION PsxLocateSessionByUniqueId( IN ULONG UniqueId );
BOOLEAN PsxStopProcess( IN PPSX_PROCESS p, IN PPSX_API_MSG m, IN ULONG Signal, IN sigset_t *RestoreBlockSigset OPTIONAL );
VOID PsxStopProcessHandler( IN PPSX_PROCESS p, IN PINTCB IntControlBlock, IN PSX_INTERRUPTREASON InterruptReason, IN int Signal );
BOOLEAN PsxInitializeDirectories( IN PPSX_PROCESS Process, IN PANSI_STRING pCwd );
BOOLEAN PsxPropagateDirectories( IN PPSX_PROCESS Process );
//
// Routines defined in procblk.c
//
NTSTATUS BlockProcess( IN PPSX_PROCESS p, IN PVOID Context, IN INTHANDLER Handler, IN PPSX_API_MSG m, IN PLIST_ENTRY BlockList OPTIONAL, IN PRTL_CRITICAL_SECTION CriticalSectionToRelease OPTIONAL );
BOOLEAN UnblockProcess( IN PPSX_PROCESS p, IN PSX_INTERRUPTREASON InterruptReason, IN BOOLEAN BlockLockHeld, IN int Signal // or 0 if not awakened by signal
);
//
// Routines defined in srvinit.c
//
NTSTATUS PsxInitializeIO( VOID );
//
// Routines defined in sigsup.c
//
int PsxCheckPendingSignals( IN PPSX_PROCESS p );
VOID PsxTerminateProcessBySignal( IN PPSX_PROCESS p, IN PPSX_API_MSG m, IN ULONG Signal );
VOID PsxDeliverSignal( IN PPSX_PROCESS p, IN ULONG Signal, IN sigset_t *RestoreBlockSigset OPTIONAL );
VOID PsxSigSuspendHandler( IN PPSX_PROCESS p, IN PINTCB IntControlBlock, IN PSX_INTERRUPTREASON InterruptReason, IN int Signal );
VOID PsxSignalProcess( IN PPSX_PROCESS p, IN ULONG Signal );
VOID Exit ( IN PPSX_PROCESS p, IN ULONG ExitStatus );
//
// Psx Session Primitives
//
PPSX_SESSION PsxAllocateSession( IN PPSX_CONTROLLING_TTY Terminal OPTIONAL, IN pid_t SessionLeader );
VOID PsxDeallocateSession( IN PPSX_SESSION Session );
//
// Psx Session Macros
//
#define REFERENCE_PSX_SESSION(ppsxsession) \
RtlEnterCriticalSection(&PsxNtSessionLock); \ (ppsxsession)->ReferenceCount++; \ RtlLeaveCriticalSection(&PsxNtSessionLock)
//
// Dereferences the session. If reference count goes to zero, the session
// is deallocated.
//
#define DEREFERENCE_PSX_SESSION(ppsxsession, status) \
RtlEnterCriticalSection(&PsxNtSessionLock); \ if (--((ppsxsession)->ReferenceCount) == 0) { \ PsxTerminateConSession((ppsxsession), (status));\ PsxDeallocateSession((ppsxsession)); \ } else { \ RtlLeaveCriticalSection(&PsxNtSessionLock); \ }
//
// Routines defined in sbapi.c
//
BOOLEAN PsxSbCreateSession( IN PSBAPIMSG Msg );
BOOLEAN PsxSbTerminateSession( IN PSBAPIMSG Msg );
BOOLEAN PsxSbForeignSessionComplete( IN PSBAPIMSG Msg );
//
// Routines defined in sbinit.c
//
NTSTATUS PsxSbApiPortInitialize ( VOID );
//
// Routines defined in sbreqst.c
//
typedef BOOLEAN (*PSB_API_ROUTINE)( IN PSBAPIMSG SbApiMsg );
NTSTATUS PsxSbApiRequestThread( IN PVOID Parameter );
//
// Routines defined in coninit.c
//
NTSTATUS PsxInitializeConsolePort( VOID );
NTSTATUS PsxCreateDirectoryObject( PUNICODE_STRING pUnicodeDirectoryName );
//
// Routines defined in conthrds.c
//
NTSTATUS PsxSessionRequestThread( IN PVOID Parameter );
//
// Routines defined in concreat.c
//
VOID SetDefaultLibPath( OUT PANSI_STRING LibPath, IN PCHAR EnvStrings );
NTSTATUS PsxCreateConSession( IN OUT PVOID RequestMsg );
//
// Routines defined in consignl.c
//
NTSTATUS PsxCtrlSignalHandler( IN OUT PVOID RequestMsg );
NTSTATUS PsxTerminateConSession( IN PPSX_SESSION Session, IN ULONG ExitStatus );
//
// Routines defined in session.c
//
RTL_CRITICAL_SECTION PsxNtSessionLock;
#define LockNtSessionList() RtlEnterCriticalSection( &PsxNtSessionLock )
#define UnlockNtSessionList() RtlLeaveCriticalSection( &PsxNtSessionLock )
NTSTATUS PsxInitializeNtSessionList( VOID );
//
// Routines defined in apiinit.c
//
NTSTATUS PsxApiPortInitialize ( VOID );
//
// Global data accessed by Client-Server Runtime Server
//
PVOID PsxHeap;
#define PSX_SS_ROOT_OBJECT_DIRECTORY L"\\PSXSS"
#define PSX_SS_SBAPI_PORT_NAME L"\\PSXSS\\SbApiPort"
UNICODE_STRING PsxApiPortName; ANSI_STRING PsxSbApiPortName; UNICODE_STRING PsxSbApiPortName_U;
STRING PsxRootDirectoryName; HANDLE PsxRootDirectory;
HANDLE PsxApiPort; HANDLE PsxSbApiPort; HANDLE PsxSmApiPort;
ULONG PsxNumberApiRequestThreads;
/*
* Port and threads for Console Session globals. */ HANDLE PsxSessionPort;
HANDLE PsxSessionRequestThreadHandle;
#define PSX_SS_SBAPI_REQUEST_THREAD 0
#define PSX_SS_FIRST_API_REQUEST_THREAD 1
#define PSX_SS_MAX_THREADS 64
HANDLE PsxServerThreadHandles[ PSX_SS_MAX_THREADS ]; CLIENT_ID PsxServerThreadClientIds[ PSX_SS_MAX_THREADS ];
//
// file descriptor IO types constants and data structures
//
#define IONODEHASHSIZE 256
#define SERIALNUMBERTOHASHINDEX(DeviceSerialNumber,FileSerialNumber) (\
(FileSerialNumber) & (IONODEHASHSIZE-1) )
//
// IoRoutines
//
//
// This function is called when a new handle is created as a result of
// an open
//
typedef BOOLEAN (*PPSXOPEN_NEW_HANDLE_ROUTINE) ( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd, IN PPSX_API_MSG m );
//
// This function is called when a new handle is created as a result of
// a pipe, dup, or fork
//
typedef VOID (*PPSXNEW_HANDLE_ROUTINE) ( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd );
//
// This function is called whever a handle is closed (close, exec, _exit)
//
typedef VOID (*PPSXCLOSE_ROUTINE) ( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd );
typedef VOID (*PPSXLAST_CLOSE_ROUTINE) ( IN PPSX_PROCESS p, IN struct _SYSTEMOPENFILE *SystemOpenFile );
struct _IONODE; typedef VOID (*PPSXIONODE_CLOSE_ROUTINE) ( IN struct _IONODE *IoNode );
//
// This function is called to do a read
//
typedef BOOLEAN (*PPSXREAD_ROUTINE) ( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd );
//
// This function is called to do a write
//
typedef BOOLEAN (*PPSXWRITE_ROUTINE) ( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd );
//
// This function is called to do a dup or dup2
//
typedef BOOLEAN (*PPSXDUP_ROUTINE) ( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd, IN PFILEDESCRIPTOR FdDup );
//
// This function is called to do a Lseek
//
typedef BOOLEAN (*PPSXLSEEK_ROUTINE) ( IN PPSX_PROCESS p, IN OUT PPSX_API_MSG m, IN PFILEDESCRIPTOR Fd );
//
// This function is called to fill in an Ionode so that a call to
// stat or fstat can be completed.
//
typedef BOOLEAN (*PPSXSTAT_ROUTINE) ( IN struct _IONODE *IoNode, IN HANDLE FileHandle, OUT struct stat *StatBuf, OUT NTSTATUS *pStatus );
typedef struct _PSXIO_VECTORS { PPSXOPEN_NEW_HANDLE_ROUTINE OpenNewHandleRoutine; PPSXNEW_HANDLE_ROUTINE NewHandleRoutine; PPSXCLOSE_ROUTINE CloseRoutine; PPSXLAST_CLOSE_ROUTINE LastCloseRoutine; PPSXIONODE_CLOSE_ROUTINE IoNodeCloseRoutine; PPSXREAD_ROUTINE ReadRoutine; PPSXWRITE_ROUTINE WriteRoutine; PPSXDUP_ROUTINE DupRoutine; PPSXLSEEK_ROUTINE LseekRoutine; PPSXSTAT_ROUTINE StatRoutine; } PSXIO_VECTORS, *PPSXIO_VECTORS;
BOOLEAN IoOpenNewHandle ( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd, IN PPSX_API_MSG m );
VOID IoNewHandle ( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd );
VOID IoClose ( IN PPSX_PROCESS p, IN PFILEDESCRIPTOR Fd );
VOID IoLastClose ( IN PPSX_PROCESS p, IN struct _SYSTEMOPENFILE *SystemOpenFile );
//
// Each unique open file in the system results in the creation of an Input
// Output Node (IONODE). Multiple opens in the same file may result in
// different file descriptors and system open files, but as long as they refer
// to the same file, only one IONODE will be created. IONODES track the the
// status of a file and keep track of its owner, mode, times. A single lock
// (IoNodeLock) guards all reference count operations on IONODES. A hash table
// IoNodeHashTable is capable of locating an IONODE based on the device and
// inode number of the file the IONODE is refered to. IONODEs are created on
// file open. Once the file is opened, a query of the file is made to
// determine its device and inode number. An IONODE is searched for in the
// InNodeHashTable, if one is found, then its reference count is incremented,
// otherwise one is created and initialized.
//
typedef struct _IONODE { LIST_ENTRY IoNodeHashLinks; RTL_CRITICAL_SECTION IoNodeLock; ULONG ReferenceCount;
//
// The file mode is created during file open.
// The protection portion of the mode is created by reading the file's
// SECURITY_DESCRIPTOR and collapsing it into POSIX rwxrwxrwx values.
//
// The file type portion is created using the file attributes, device type,
// and extended attributes of a file
//
mode_t Mode;
//
// For regular files,
// DeviceSerialNumber == Counter. Per filesystem number that does
// not conflict w/ device type.
// FileSerialNumber == IndexNumber
// For device files
// DeviceSerialNumber == DeviceType
// FileSerialNumber == Device Object Address (IndexNumber ?)
//
dev_t DeviceSerialNumber; ULONG_PTR FileSerialNumber;
uid_t OwnerId; gid_t GroupId;
//
// The time fields are magical. When the file is opened, the access time
// and modified times returned from the file system are stored in the
// IONODE. The change time is set equal to the modified time. Each Psx
// IONODE operation sets the appropriate time fields.
//
time_t AccessDataTime; time_t ModifyDataTime; time_t ModifyIoNodeTime;
//
// The Io Vectors
//
PVOID Context; PPSXIO_VECTORS IoVectors;
//
// File record locks, sorted by the starting position of the lock.
// See fcntl(). And a list of those processes blocked while locking
// a region (with F_SETLKW).
//
LIST_ENTRY Flocks; LIST_ENTRY Waiters;
// Length of path to ionode, if applicable. For fpathconf(PATH_MAX).
ULONG PathLength;
//
// If the file has been unlinked or renamed over while still open,
// we move it to the junkyard and set the "junked" flag. When the
// last close occurs for this file, it should be deleted.
//
BOOLEAN Junked;
} IONODE, *PIONODE;
//
// Each unique open of a file results in the creation of a system open file.
// These descriptors are dynamically allocated. There is no limit on the number
// of these in the system. Dups of file descriptors, or forking result in a
// reference count increment, not a new system open file. Only explicit opens,
// creates, or pipe() calls result in a new system open file. A global lock
// (SystemOpenFileLock) guards all reference count adjustments. As long as a
// reference exists, all fields in this structure can be used without any
// locking.
//
typedef struct _SYSTEMOPENFILE { ULONG HandleCount; ULONG ReadHandleCount; ULONG WriteHandleCount; HANDLE NtIoHandle; PIONODE IoNode; ULONG Flags; // file description flags
//
// If a file descriptor is open on a console, we need to keep a
// reference to that console so we can do io even if the process
// changes sessions. 'Terminal' is the reference.
//
PPSX_CONTROLLING_TTY Terminal;
} SYSTEMOPENFILE; typedef SYSTEMOPENFILE *PSYSTEMOPENFILE;
//
// Flags for SYSTEMOPENFILE.Flags
//
#define PSX_FD_READ 0x00000001
#define PSX_FD_WRITE 0x00000002
#define PSX_FD_NOBLOCK 0x00000004
#define PSX_FD_APPEND 0x00000008
extern RTL_CRITICAL_SECTION SystemOpenFileLock; extern RTL_CRITICAL_SECTION IoNodeHashTableLock; extern LIST_ENTRY IoNodeHashTable[];
//
// IoNode Primitives
//
BOOLEAN ReferenceOrCreateIoNode ( IN dev_t DeviceSerialNumber, IN ULONG_PTR FileSerialNumber, IN BOOLEAN FindOnly, OUT PIONODE *IoNode );
BOOLEAN LocateIoNode ( IN HANDLE FileHandle, OUT PIONODE *IoNode );
VOID DereferenceIoNode ( IN PIONODE IoNode );
//
// Fd Primitives
//
PFILEDESCRIPTOR AllocateFd( IN PPSX_PROCESS p, IN ULONG Start, OUT PULONG Index );
BOOLEAN DeallocateFd( IN PPSX_PROCESS p, IN ULONG Index );
PFILEDESCRIPTOR FdIndexToFd( IN PPSX_PROCESS p, IN ULONG Index );
//
// System Open File Primitives
//
PSYSTEMOPENFILE AllocateSystemOpenFile();
VOID DeallocateSystemOpenFile( IN PPSX_PROCESS p, IN PSYSTEMOPENFILE SystemOpenFile );
//
// System Open File Macros
//
#define REFERENCE_SYSTEMOPENFILE(systemopenfile) \
RtlEnterCriticalSection(&SystemOpenFileLock); \ (systemopenfile)->HandleCount++; \ RtlLeaveCriticalSection(&SystemOpenFileLock)
VOID ForkProcessFileTable( IN PPSX_PROCESS ForkProcess, IN PPSX_PROCESS NewProcess );
VOID ExecProcessFileTable( IN PPSX_PROCESS p );
VOID CloseProcessFileTable( IN PPSX_PROCESS p );
//
// Per-Device Type Io structures, types... Filesystems
// are numbered 'A'..'Z'.
//
#define PSX_LOCAL_PIPE 1
#define PSX_CONSOLE_DEV 2
#define PSX_NULL_DEV 3
//
// Local Pipes
//
typedef struct _LOCAL_PIPE { ULONG ReadHandleCount; ULONG WriteHandleCount; LIST_ENTRY WaitingWriters; LIST_ENTRY WaitingReaders; RTL_CRITICAL_SECTION CriticalSection; LONG BufferSize; LONG DataInPipe; PUCHAR WritePointer; PUCHAR ReadPointer; UCHAR Buffer[PIPE_BUF]; } LOCAL_PIPE, *PLOCAL_PIPE;
extern PSXIO_VECTORS LocalPipeVectors; extern PSXIO_VECTORS NamedPipeVectors;
VOID InitializeLocalPipe( IN PLOCAL_PIPE Pipe );
//
// Files
//
extern PSXIO_VECTORS FileVectors;
//
// Console
//
extern PSXIO_VECTORS ConVectors;
//
// Null device
//
extern PSXIO_VECTORS NullVectors;
NTSTATUS PsxApiHandleConnectionRequest( IN PPSX_API_MSG Message );
BOOLEAN PendingSignalHandledInside( IN PPSX_PROCESS p, IN PPSX_API_MSG m, IN sigset_t *RestoreBlockSigset OPTIONAL );
NTSTATUS PsxApiRequestThread( IN PVOID ThreadParameter );
VOID ApiReply( IN PPSX_PROCESS p, IN PPSX_API_MSG m, IN sigset_t *RestoreBlockSigset OPTIONAL );
ULONG PsxDetermineFileClass( IN HANDLE FileHandle );
ULONG PsxStatusToErrno( IN NTSTATUS Status );
ULONG PsxStatusToErrnoPath( IN PUNICODE_STRING Path );
//
// Stuff for file record locking
//
typedef struct _SYSFLOCK { LIST_ENTRY Links; SHORT Type; // F_RDLCK or F_WRLCK
SHORT Whence; // SEEK_SET, etc.
off_t Start; // Starting offset
off_t Len; // Length of region
pid_t Pid; // Pid of lock owner
} SYSFLOCK, *PSYSFLOCK;
//
// hack types
//
typedef struct _SYSTEMMSG { LIST_ENTRY Links; PORT_MESSAGE PortMsg; } SYSTEMMSG, *PSYSTEMMSG;
typedef BOOLEAN (* PPSX_API_ROUTINE)( IN PPSX_PROCESS p, IN PPSX_API_MSG m ); //
// Api Prototypes
//
BOOLEAN PsxFork( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxExec( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxWaitPid( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxExit( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxKill( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSigAction( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSigProcMask( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSigPending( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSigSuspend( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxAlarm( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSleep( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetIds( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSetUid( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSetGid( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetGroups( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetLogin( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxCUserId( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSetSid( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSetPGroupId( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxUname( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTime( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetProcessTimes( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTtyName( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxIsatty( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSysconf( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxOpenDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxReadDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxRewindDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxCloseDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxChDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetCwd( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxOpen( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxCreat( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxUmask( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxLink( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxMkDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxMkFifo( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxRmDir( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxRename( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxStat( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxFStat( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxAccess( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxChmod( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxChown( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxUtime( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxPathConf( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxFPathConf( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxPipe( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxClose( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxRead( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxWrite( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxFcntl( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxDup( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxDup2( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxLseek( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcGetAttr( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcSetAttr( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcSendBreak( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcDrain( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcFlush( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcFlow( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcGetPGrp( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxTcSetPGrp( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetPwUid( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetPwNam( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetGrGid( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetGrNam( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxUnlink( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxFtruncate( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxNull( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
#ifdef PSX_SOCKET
BOOLEAN PsxSocket( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxAccept( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxBind( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxConnect( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetPeerName( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetSockName( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxGetSockOpt( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxListen( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxRecv( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxRecvFrom( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSend( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSendTo( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxSetSockOpt( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
BOOLEAN PsxShutdown( IN PPSX_PROCESS p, IN PPSX_API_MSG m );
#endif // PSX_SOCKET
PVOID PsxViewSessionData( IN ULONG SessionId, OUT PHANDLE Section );
ULONG GetOffsetBySid( PSID Sid );
PSID GetSidByOffset( ULONG Offset );
VOID MapSidToOffset( PSID Sid, ULONG Offset );
VOID InitSidList( VOID );
VOID ModeToAccessMask( mode_t Mode, PACCESS_MASK UserAccess, PACCESS_MASK GroupAccess, PACCESS_MASK OtherAccess );
mode_t AccessMaskToMode( ACCESS_MASK UserAccess, ACCESS_MASK GroupAccess, ACCESS_MASK OtherAccess );
VOID AlarmThreadRoutine( VOID );
HANDLE AlarmThreadHandle;
PSID MakeSid( PSID DomainSid, ULONG RelativeId );
VOID EndImpersonation( VOID );
uid_t MakePosixId( PSID Sid );
NTSTATUS RtlInterpretPosixAcl( IN ULONG AclRevision, IN PSID UserSid, IN PSID GroupSid, IN PACL Acl, OUT PACCESS_MASK UserAccess, OUT PACCESS_MASK GroupAccess, OUT PACCESS_MASK OtherAccess );
NTSTATUS RtlMakePosixAcl( IN ULONG AclRevision, IN PSID UserSid, IN PSID GroupSid, IN ACCESS_MASK UserAccess, IN ACCESS_MASK GroupAccess, IN ACCESS_MASK OtherAccess, IN ULONG AclLength, OUT PACL Acl, OUT PULONG ReturnLength );
VOID ReleaseFlocksByPid( PIONODE IoNode, pid_t pid );
BOOLEAN DoFlockStuff( PPSX_PROCESS Proc, PPSX_API_MSG m, int command, IN PFILEDESCRIPTOR Fd, IN OUT struct flock *new, OUT int *error );
#if DBG
VOID DumpFlockList( PIONODE IoNode ); #endif // DBG
NTSTATUS InitConnectingTerminalList( VOID );
NTSTATUS AddConnectingTerminal( int Id, HANDLE CommPort, HANDLE ReqPort );
PPSX_CONTROLLING_TTY GetConnectingTerminal( int Id );
ULONG OpenTty( PPSX_PROCESS p, PFILEDESCRIPTOR Fd, ULONG DesiredAccess, ULONG Flags, BOOLEAN NewOpen );
ULONG OpenDevNull( PPSX_PROCESS p, PFILEDESCRIPTOR Fd, ULONG DesiredAccess, ULONG Flags );
dev_t GetFileDeviceNumber( PUNICODE_STRING Path );
NTSTATUS InitSecurityDescriptor( IN OUT PSECURITY_DESCRIPTOR pSD, IN PUNICODE_STRING pFileName, IN HANDLE Process, IN mode_t Mode, OUT PVOID *pvSaveMem );
VOID DeInitSecurityDescriptor( IN PSECURITY_DESCRIPTOR pSD, IN PVOID *pvSaveMem );
BOOLEAN IsGroupOrphaned( IN pid_t ProcessGroup );
NTSTATUS ExecForeignImage( PPSX_PROCESS p, PPSX_API_MSG m, PUNICODE_STRING Image, PUNICODE_STRING CurDir );
#endif // _PSXP_
|