windows-nt/Source/XPSP1/NT/base/subsys/posix/inc/psxsrv.h
2020-09-26 16:20:57 +08:00

1880 lines
32 KiB
C

/*++
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_