mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
719 lines
14 KiB
719 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ntslm.h
|
|
|
|
Author:
|
|
|
|
Steven R. Wood (stevewo) 31-Dec-1990
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <io.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <share.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <process.h>
|
|
#include <malloc.h>
|
|
#include <time.h>
|
|
#include <conio.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
|
|
#ifdef TOOL
|
|
#define NTSLM_PIPE_TIMEOUT 30000L
|
|
|
|
#include <signal.h>
|
|
#define INCL_BASE
|
|
#include <os2.h>
|
|
#include <netcons.h>
|
|
#include <neterr.h>
|
|
#include <server.h>
|
|
#include <wksta.h>
|
|
#include <use.h>
|
|
|
|
//
|
|
// Can't use the following with bsedos.h so cheat.
|
|
// #include <nmpipe.h>
|
|
//
|
|
|
|
/*
|
|
* 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 <windows.h>
|
|
#include <lm.h>
|
|
#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 );
|