/*++ Copyright (c) 1989 Microsoft Corporation Module Name: ntslm.h Author: Steven R. Wood (stevewo) 31-Dec-1990 Revision History: --*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef TOOL #define NTSLM_PIPE_TIMEOUT 30000L #include #define INCL_BASE #include #include #include #include #include #include // // Can't use the following with bsedos.h so cheat. // #include // /* * Values for named pipe state */ #define NP_DISCONNECTED 1 /* after pipe creation or Disconnect */ #define NP_LISTENING 2 /* after DosNmPipeConnect */ #define NP_CONNECTED 3 /* after Client open */ #define NP_CLOSING 4 /* after Client or Server close */ /* DosMakeNmPipe open modes */ #define NP_ACCESS_INBOUND 0x0000 #define NP_ACCESS_OUTBOUND 0x0001 #define NP_ACCESS_DUPLEX 0x0002 #define NP_INHERIT 0x0000 #define NP_NOINHERIT 0x0080 #define NP_WRITEBEHIND 0x0000 #define NP_NOWRITEBEHIND 0x4000 /* DosMakeNmPipe and DosQNmPHandState state */ #define NP_READMODE_BYTE 0x0000 #define NP_READMODE_MESSAGE 0x0100 #define NP_TYPE_BYTE 0x0000 #define NP_TYPE_MESSAGE 0x0400 #define NP_END_CLIENT 0x0000 #define NP_END_SERVER 0x4000 #define NP_WAIT 0x0000 #define NP_NOWAIT 0x8000 #define NP_UNLIMITED_INSTANCES 0x00FF #define Sleep DosSleep #define MAX_PATH CCHMAXPATH typedef SHANDLE HANDLE; #define VOID void typedef VOID far *LPVOID; typedef LPVOID LPOVERLAPPED; typedef ULONG DWORD; typedef DWORD far *LPDWORD; typedef char far *LPSTR; DWORD GetLastError( VOID ); typedef VOID (*PHANDLER_ROUTINE)( DWORD CtrlType ); #define CTRL_C_EVENT 0 #define CTRL_BREAK_EVENT 1 BOOL SetConsoleCtrlHandler( PHANDLER_ROUTINE HandlerRoutine, BOOL Add ); VOID APIENTRY ExitProcess( DWORD dwExitCode ); DWORD GetFileAttributes( LPSTR lpFileName ); BOOL SetFileAttributes( LPSTR lpFileName, DWORD dwAttributes ); #define FILE_ATTRIBUTE_READONLY 0x00000001 #define FILE_ATTRIBUTE_HIDDEN 0x00000002 #define FILE_ATTRIBUTE_SYSTEM 0x00000004 #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 #define FILE_ATTRIBUTE_ARCHIVE 0x00000020 BOOL DeleteFile( LPSTR lpFileName ); BOOL CreateDirectory( LPSTR lpPathName, LPVOID lpSecurityAttributes ); BOOL SetCurrentDirectory( LPSTR lpPathName ); DWORD GetCurrentDirectory( DWORD nBufferLength, LPSTR lpBuffer ); BOOL ConnectNamedPipe( HANDLE PipeHandle, LPOVERLAPPED lpOverlapped ); BOOL DisconnectNamedPipe( HANDLE PipeHandle ); BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped ); BOOL WriteFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped ); BOOL CloseHandle( HANDLE Handle ); typedef DWORD (*PTHREAD_START_ROUTINE)( LPVOID lpThreadParameter ); typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; #else #define NTSLM_PIPE_TIMEOUT 30000 #include #include #endif #ifdef _ALPHA_ #undef GetUserName #endif // // Public data types for the Server process // #define NTSLM_SERVER "STEVEWO_DEC" #define NTSLM_MSG_PIPENAME "NTSLM" #define NTSLM_STOP_PIPENAME "NTSLM.STP" #define NTSLM_PROJECTS_FILENAME "NTSLM.PRO" #define NTSLM_BEG_FREE_FOR_ALL 11 #define NTSLM_END_FREE_FOR_ALL 15 #define NTSLM_BEG_SAFE_SYNC 16 #define NTSLM_END_SAFE_SYNC 18 #define CMDLEN 9 typedef struct _LOCK_MESSAGE { struct _LOCK_MESSAGE *Next; // [Server use only] HANDLE PipeHandle; // [server use only] time_t TimeOfRequest; time_t CurrentTime; char PipeName[ 9+1 ]; char UserName[ CNLEN+1 ]; char SLMCommand[ CMDLEN+1]; char ProjectName[ CNLEN+1 ]; char RequestType; // See below char WriteLock; // '0' for Read Locks or '1` for Write Locks char OwnerFlag; // '0' if waiting for lock or '1` if owner of // a lock char ErrorFlag; // '0' if request okay or '1' if an error } LOCK_MESSAGE, *LPLOCK_MESSAGE; #define LOCK_REQUEST_DISPLAY 'D' #define LOCK_REQUEST_ACQUIRELOCK 'A' #define LOCK_REQUEST_RELEASELOCK 'R' #define LOCK_REQUEST_ENUM_PROJECTS 'E' #define LOCK_REQUEST_PROGRESS 'P' #define LOCK_REQUEST_TERMINATE 'X' typedef struct _PROJECT_MESSAGE { char Name[ CNLEN+1 ]; char Server[ RMLEN ]; char Directory[ MAX_PATH ]; } PROJECT_MESSAGE, *LPPROJECT_MESSAGE; // // Global variables. The comment for each variable identifies whether it // is valid in either the NTSLM server process, an NTSLM client process // or both. // // // The following variable identifies which mode the current NTSLM process // is running in. IsServerProcess is TRUE if this is the server process running // on the SLM Source Server, managing the read/write lock queue. It is FALSE // if this is a client process requesting a read/write lock. // BOOL IsServerProcess; // [Client and Server] // // The following variable is TRUE for debugging output. Set by the -d // command line switch. // BOOL DebugFlag; // [Client and Server] // // The following variable is TRUE whenever a client attempts to connect to // the NTSLM_STOP_PIPENAME pipe. It causes the ServerThread to break // out of its loop and return. // BOOL ServerStopFlag; // [Server] // // This is the fully qualified UNC named pipe path name string. This name // has the following formats: // // \Pipe\ShareName [Server] // \\ServerName\Pipe\ShareName [Client] // char PipePathName[ MAX_PATH ]; // [Client and Server] // // This is the handle to the named pipe that the client opens. Needed by // control C handler. // HANDLE ClientPipeHandle; // [Client only] // // This is the client workstation name. It is either the value of the // LOGNAME environment variable or the workstation name from Lan Manager // char *LogName; // [Client only] // // This variable is set to TRUE when a Control-Break interrupt occurs. // It will cause the client side to stop when it reaches the next SLM // project. // BOOL ClientAbortCommand; // // This variable is set to TRUE if the user is unlock all locks for a // particular name. // BOOL ClientUnlockAll; // // This is the message structure that the client passes to the server and // the server returns to the client. // LOCK_MESSAGE Message; // [Client and Server] struct tm MessageTime; // // This is the head of the list of client messages waiting for a lock. // LPLOCK_MESSAGE WaitingForWriteLock; // [Server only] LPLOCK_MESSAGE WaitingForReadLock; // [Server only] // // The following serial number is used to generate unique pipe names for // clients to create and wait on. // USHORT ServerPipeSerialNumber; // [Server only] // // This is the head of the list of client messages that own a lock. For // Write locks, this list will contain only a single message. For read // locks, it will contain multiple messages. // LPLOCK_MESSAGE OwnedLocks; // [Server only] // // This variable contains the list of SLM projects that are being managed // by this version of NTSLM. On the server side, this list is initialized // when NTSLM starts up with the contents of the NTSLM.SLM file. // On the client side, this list is initialized from project names specified // on the command line. // typedef struct _SLM_PROJECT_INFO { struct _SLM_PROJECT_INFO *Next; char Name[ CNLEN+1 ]; char Server[ RMLEN ]; char *Directory; BOOL RequestedByUser; BOOL ClientEnlisted; } SLM_PROJECT_INFO, *LPSLM_PROJECT_INFO; LPSLM_PROJECT_INFO SlmProjects; // [Client and Server] BOOL OnlyRequestedProjects; BOOL LocalSlmProjectsModified; // // // // // // typedef void (*POUTPUT_FILTER_ROUTINE) ( char *LineBuffer ); typedef struct _NTSLM_COMMAND_INFO { int Command; char *ClientKeyword; char *ClientExeCmd; char *ClientEnvName; char *ClientExeMsg; POUTPUT_FILTER_ROUTINE ClientFilter; } NTSLM_COMMAND_INFO, *PNTSLM_COMMAND_INFO; #define NTSLM_COMMAND_SERVER 0 #define NTSLM_COMMAND_STOPSRV 1 #define NTSLM_COMMAND_DISPLAY 2 #define NTSLM_COMMAND_LOCK 3 #define NTSLM_COMMAND_UNLOCK 4 #define NTSLM_COMMAND_SLMCK 5 #define NTSLM_COMMAND_STATUS 6 #define NTSLM_COMMAND_SSYNC 7 #define NTSLM_COMMAND_LOG 8 #define NTSLM_COMMAND_DEFECT 9 #define NTSLM_COMMAND_ENLIST 10 #define NTSLM_COMMAND_DELED 11 #define NTSLM_COMMAND_TIDY 12 #define NTSLM_COMMAND_NONE 13 void SSyncFilter( char *LineBuffer ); void StatusFilter( char *LineBuffer ); void PassThroughFilter( char *LineBuffer ); NTSLM_COMMAND_INFO CommandInfo[] = { {NTSLM_COMMAND_SERVER, "server", NULL, NULL, NULL, NULL }, {NTSLM_COMMAND_STOPSRV, "stopserver", NULL, NULL, NULL, NULL }, {NTSLM_COMMAND_DISPLAY, "display", NULL, NULL, NULL, NULL }, {NTSLM_COMMAND_LOCK, "lock", NULL, NULL, NULL, NULL }, {NTSLM_COMMAND_UNLOCK, "unlock", NULL, NULL, NULL, NULL }, {NTSLM_COMMAND_SLMCK, "slmck", "slmck -fir %s -s %s -p %s", "_NTSLMCK_FLAGS", "Running SLMCK on the %s project", PassThroughFilter }, {NTSLM_COMMAND_STATUS, "status", "status -a %s", "_NTSTAT_FLAGS", "Checking status for the %s project", StatusFilter }, {NTSLM_COMMAND_SSYNC, "ssync", "ssync -a %s", "_NTSYNC_FLAGS", "Syncing the %s project", SSyncFilter }, {NTSLM_COMMAND_LOG, "log", "log -a %s", "_NTLOG_FLAGS", "Log of the %s project", PassThroughFilter }, {NTSLM_COMMAND_DEFECT, "defect", "defect %s", "_NTDEFECT_FLAGS", "Defecting from the %s project", PassThroughFilter }, {NTSLM_COMMAND_ENLIST, "enlist", "enlist -v %s -s %s -p %s", "_NTENLIST_FLAGS", "Enlisting in the %s project", PassThroughFilter }, {NTSLM_COMMAND_DELED, "s deled", "sadmin deled -vr %s -s %s -p %s", "_NTDELED_FLAGS", "Manually removing enlistment from %s project", PassThroughFilter }, {NTSLM_COMMAND_TIDY, "s tidy", "sadmin tidy -vr %s -p %s -s %s", "_NTTIDY_FLAGS", "Tidying %s project", PassThroughFilter }, {NTSLM_COMMAND_NONE, NULL, NULL, NULL, NULL, NULL } }; // // This variable contains a pointer to the above structure that describes the // SLM command that is to be executed for each NT SLM project that the client // is enlisted in. // PNTSLM_COMMAND_INFO ClientCommand; // [Client only] // // The following typedef is for the process termination codes returned by the // NTSLM program. // typedef unsigned short EXIT_CODE; #define EXIT_CODE_SUCCESS 0 #define EXIT_CODE_DENIED 1 #define EXIT_CODE_ERROR 2 #define EXIT_CODE_STOPPED 3 #define EXIT_CODE_ABORTED 4 void Usage( void ); HANDLE ServerInitialize( int argc, char **argv ); EXIT_CODE ServerStopThread( HANDLE StopPipeHandle ); EXIT_CODE ServerThread( IN HANDLE PipeHandle ); BOOL ServerDumpSlmProjects( HANDLE PipeHandle ); void ServerUpdateLock( IN HANDLE PipeHandle ); void ServerProcessLockMessage( void ); BOOL ServerReleaseLock( LPLOCK_MESSAGE *pp ); BOOL ServerReleaseClient( LPLOCK_MESSAGE Msg ); void ServerDisplayLocks( IN HANDLE PipeHandle ); BOOL ServerLoadProjects( void ); BOOL ClientControlHandler( DWORD ControlType ); VOID ClientInterruptHandler( BOOL ControlBreak ); HANDLE ClientInitialize( int argc, char **argv ); BOOL MyGetUserName( void ); BOOL ClientValidateEnvironment( HANDLE PipeHandle ); EXIT_CODE ClientThread( IN HANDLE PipeHandle ); EXIT_CODE ClientProcessLockMessage( IN HANDLE PipeHandle ); EXIT_CODE ClientWaitForLock( LPLOCK_MESSAGE Msg ); char * ClientTimeDuration( time_t secs ); void ClientDisplayLocks( IN HANDLE PipeHandle ); BOOL ClientQueryEnlist( LPSLM_PROJECT_INFO p, BOOL DefaultAnswer ); void ClientInvokeCommand( void ); BOOL AddSlmProject( BOOL Enlisted, char *Name, char *Server, char *Directory ); LPSLM_PROJECT_INFO FindSlmProject( char *Name ); void MyBeep( void ); HANDLE MakeNamedPipe( char *PipeName, char *PathName, BOOL MessagePipe ); HANDLE OpenNamedPipe( char *ServerName, char *PipeName, char *PathName ); BOOL MyCallNamedPipe( char *ServerName, char *PipeName, LPLOCK_MESSAGE Msg ); DWORD ServerCreateThread( LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter ); VOID ClientInitializeInterrupts( VOID );