SRVUTIL.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:31k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright 1995 - 1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /*++
- Copyright (c) 1997 Microsoft Corporation
- Module Name:
- SrvUtil.c
- Abstract:
- The server component of Remote. It spawns a child process
- and redirects the stdin/stdout/stderr of child to itself.
- Waits for connections from clients - passing the
- output of child process to client and the input from clients
- to child process.
- Author:
- Rajivendra Nath 2-Jan-1992
- Dave Hart 30 May 1997 split from Server.c
- Environment:
- Console App. User mode.
- Revision History:
- --*/
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <process.h>
- #include <io.h>
- #include <string.h>
- #include "Remote.h"
- #include "Server.h"
- #define COMMANDFORMAT "%c%-20s [%-12s %s]n%08x%c"
- #define CMDSTRING(OutBuff,OutSize,InpBuff,Client,szTime,ForceShow)
- {
- char *pch;
- for (pch = InpBuff;
- *pch;
- pch++) {
- if (ENDMARK == *pch ||
- BEGINMARK == *pch) {
- *pch = '`';
- }
- }
- OutSize =
- sprintf(
- (OutBuff),
- COMMANDFORMAT,
- BEGINMARK,
- (InpBuff),
- (Client)->Name,
- (szTime),
- (ForceShow) ? 0 : (Client)->dwID,
- ENDMARK
- );
- }
- /*************************************************************/
- // GetFormattedTime -- returns pointer to formatted time
- //
- // returns pointer to static buffer, only the main thread
- // should use this.
- //
- PCHAR
- GetFormattedTime(
- BOOL bDateToo
- )
- {
- static char szTime[64];
- int cch = 0;
- if (bDateToo) {
- cch =
- GetDateFormat(
- LOCALE_USER_DEFAULT,
- 0,
- NULL, // current date
- "ddd", // short day of week
- szTime,
- sizeof szTime
- );
- // cch includes null terminator, change it to
- // a space to separate from time.
- szTime[ cch - 1 ] = ' ';
- }
- //
- // Get time and format to characters
- //
- GetTimeFormat(
- LOCALE_USER_DEFAULT,
- TIME_NOSECONDS,
- NULL, // use current time
- NULL, // use default format
- szTime + cch,
- (sizeof szTime) - cch );
- return szTime;
- }
- /*************************************************************/
- BOOL
- FilterCommand(
- REMOTE_CLIENT *cl,
- char *buff,
- int dread
- )
- {
- char tmpchar;
- DWORD tmp;
- int len;
- DWORD ThreadID;
- char inp_buff[2048];
- char ch[3];
- if (dread==0)
- return(FALSE);
- buff[dread]=0;
- if (buff[0]==COMMANDCHAR)
- {
- switch(buff[1])
- {
- case 'k':
- case 'K':
- if (INVALID_HANDLE_VALUE != hWriteChildStdIn) {
- printf("Remote: killing child softly, @K again to be more convincing.n");
- CANCELIO( hWriteChildStdIn );
- CloseHandle( hWriteChildStdIn );
- hWriteChildStdIn = INVALID_HANDLE_VALUE;
- GenerateConsoleCtrlEvent(CTRL_CLOSE_EVENT, 0);
- SleepEx(200, TRUE);
- cPendingCtrlCEvents++;
- GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
- SleepEx(20, TRUE);
- GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
- } else {
- printf("Remote: Resorting to TerminateProcess.n");
- TerminateProcess(ChldProc, ERROR_PROCESS_ABORTED);
- }
- break;
- case 's':
- case 'S':
- CloseHandle( (HANDLE)
- _beginthreadex(
- NULL, // security
- 0, // default stack size
- SendStatus,
- (void *) cl->PipeWriteH,
- 0, // not suspended
- &ThreadID
- ));
- break;
- case 'p':
- case 'P':
- {
- char *msg;
- msg = HeapAlloc( // freed by ShowPopup
- hHeap,
- HEAP_ZERO_MEMORY,
- 4096
- );
- if ( ! msg) {
- break;
- }
- sprintf(msg,"From %s %s [%s]nn%sn",cl->Name,cl->UserName,GetFormattedTime(TRUE),&buff[2]);
- if (WriteFileSynch(hWriteTempFile,msg,strlen(msg),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- StartServerToClientFlow();
- }
- CloseHandle( (HANDLE)
- CreateThread( // no CRT for ShowPopup
- NULL, // security
- 0, // default stack size
- ShowPopup,
- (void *) msg,
- 0, // not suspended
- &ThreadID
- ));
- break;
- }
- case 'm':
- case 'M':
- buff[dread-2]=0;
- CMDSTRING(inp_buff,len,buff,cl,GetFormattedTime(TRUE),TRUE);
- if (WriteFileSynch(hWriteTempFile,inp_buff,len,&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- StartServerToClientFlow();
- }
- break;
- case '@':
- buff[dread-2]=0;
- CMDSTRING(inp_buff,len,&buff[1],cl,GetFormattedTime(FALSE),FALSE);
- if (WriteFileSynch(hWriteTempFile,inp_buff,len,&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- StartServerToClientFlow();
- }
- //
- // Remove the first @ sign
- //
- MoveMemory(buff,&buff[1],dread-1);
- buff[dread-1]=' ';
- return(FALSE); //Send it it to the chile process
- default :
- sprintf(inp_buff,"%s","** Unknown Command **n");
- if (WriteFileSynch(hWriteTempFile,inp_buff,strlen(inp_buff),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- // we do this below // StartServerToClientFlow();
- }
- case 'h':
- case 'H':
- sprintf(inp_buff,"%cM: To Send Messagen",COMMANDCHAR);
- if (WriteFileSynch(hWriteTempFile,inp_buff,strlen(inp_buff),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- }
- sprintf(inp_buff,"%cP: To Generate popupn",COMMANDCHAR);
- if (WriteFileSynch(hWriteTempFile,inp_buff,strlen(inp_buff),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- }
- sprintf(inp_buff,"%cK: To kill the servern",COMMANDCHAR);
- if (WriteFileSynch(hWriteTempFile,inp_buff,strlen(inp_buff),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- }
- sprintf(inp_buff,"%cH: This Helpn",COMMANDCHAR);
- if (WriteFileSynch(hWriteTempFile,inp_buff,strlen(inp_buff),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- }
- StartServerToClientFlow();
- break;
- }
- return(TRUE);
- }
- if ((buff[0]<26))
- {
- BOOL ret=FALSE;
- sprintf(ch, "^%c", buff[0] + 'A' - 1);
- if (buff[0]==CTRLC)
- {
- // show this even to this client
- CMDSTRING(inp_buff,len,ch,cl,GetFormattedTime(FALSE),TRUE);
- cPendingCtrlCEvents++;
- GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
- ret = TRUE; // Already sent to child
- } else {
- CMDSTRING(inp_buff,len,ch,cl,GetFormattedTime(FALSE),FALSE);
- }
- if (WriteFileSynch(hWriteTempFile,inp_buff,len,&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- StartServerToClientFlow();
- }
- return(ret); //FALSE:send it to child StdIn
- }
- tmpchar=buff[dread-2]; //must be 13;but just incase
- buff[dread-2]=0;
- CMDSTRING(inp_buff,len,buff,cl,GetFormattedTime(FALSE),FALSE);
- buff[dread-2]=tmpchar;
- if (WriteFileSynch(hWriteTempFile,inp_buff,len,&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- StartServerToClientFlow();
- }
- return(FALSE);
- }
- /*************************************************************/
- HANDLE
- ForkChildProcess( // Creates a new process
- char *cmd, // Redirects its stdin,stdout
- PHANDLE inH, // and stderr - returns the
- PHANDLE outH // corresponding pipe ends.
- )
- {
- SECURITY_ATTRIBUTES lsa;
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- HANDLE ChildIn;
- HANDLE ChildOut, ChildOutDup;
- HANDLE hWriteChild;
- HANDLE hReadChild;
- BOOL Success;
- BOOL // pipeex.c
- APIENTRY
- MyCreatePipeEx(
- OUT LPHANDLE lpReadPipe,
- OUT LPHANDLE lpWritePipe,
- IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
- IN DWORD nSize,
- DWORD dwReadMode,
- DWORD dwWriteMode
- );
- lsa.nLength=sizeof(SECURITY_ATTRIBUTES);
- lsa.lpSecurityDescriptor=NULL;
- lsa.bInheritHandle=TRUE;
- //
- // Create Parent_Write to ChildStdIn Pipe. Then
- // duplicate the parent copy to a noninheritable
- // handle and close the inheritable one so that
- // the child won't be holding open a handle to
- // the server end of its stdin pipe when we try
- // to nuke that pipe to close the child.
- //
- Success = MyCreatePipeEx(
- &ChildIn,
- &hWriteChild,
- &lsa,
- 0,
- 0,
- FILE_FLAG_OVERLAPPED) &&
- DuplicateHandle(
- GetCurrentProcess(),
- hWriteChild,
- GetCurrentProcess(),
- inH,
- 0, // ignored b/c SAME_ACCESS
- FALSE, // not inheritable
- DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE
- );
- if (!Success) {
- ErrorExit("Could Not Create Parent-->Child Pipe");
- }
- //
- //Create ChildStdOut/stderr to Parent_Read pipe
- //
- Success = MyCreatePipeEx(
- &hReadChild,
- &ChildOut,
- &lsa,
- 0,
- FILE_FLAG_OVERLAPPED,
- 0) &&
- DuplicateHandle(
- GetCurrentProcess(),
- hReadChild,
- GetCurrentProcess(),
- outH,
- 0, // ignored b/c SAME_ACCESS
- FALSE, // not inheritable
- DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE
- ) &&
- DuplicateHandle(
- GetCurrentProcess(),
- ChildOut,
- GetCurrentProcess(),
- &ChildOutDup,
- 0, // ignored b/c SAME_ACCESS
- TRUE, // inheritable
- DUPLICATE_SAME_ACCESS
- );
- if (!Success) {
- ErrorExit("Could Not Create Child-->Parent Pipe");
- }
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESTDHANDLES;
- si.hStdInput = ChildIn;
- si.hStdOutput = ChildOut;
- si.hStdError = ChildOutDup;
- si.wShowWindow = SW_SHOW;
- //
- // Create Child Process
- //
- if ( ! CreateProcess(
- NULL,
- cmd,
- NULL,
- NULL,
- TRUE,
- GetPriorityClass( GetCurrentProcess() ),
- NULL,
- NULL,
- &si,
- &pi)) {
- if (GetLastError()==2) {
- printf("Executable %s not foundn",cmd);
- } else {
- printf("CreateProcess(%s) failed, error %d.n", cmd, GetLastError());
- }
- ErrorExit("Could Not Create Child Process");
- }
- //
- // Close unneccesary Handles
- //
- CloseHandle(ChildIn);
- CloseHandle(ChildOut);
- CloseHandle(ChildOutDup);
- CloseHandle(pi.hThread);
- pidChild = pi.dwProcessId;
- return(pi.hProcess);
- }
- //
- // SendStatus runs as its own thread, with C runtime available.
- //
- DWORD
- WINAPI
- SendStatus(
- LPVOID lpSendStatusParm
- )
- {
- HANDLE hClientPipe = (HANDLE) lpSendStatusParm;
- char *pch;
- DWORD tmp;
- PREMOTE_CLIENT pClient;
- OVERLAPPED ol;
- char buff[2048];
- char szSep[] = " ------------------------------n";
- //
- // Since we're in our own thread we need our own
- // overlapped structure for our client pipe writes.
- //
- ZeroMemory(&ol, sizeof(ol));
- ol.hEvent =
- CreateEvent(
- NULL, // security
- TRUE, // auto-reset
- FALSE, // initially nonsignaled
- NULL // unnamed
- );
- //
- // Dump the closing client list
- //
- pch = buff;
- EnterCriticalSection(&csClosingClientList);
- for (pClient = (PREMOTE_CLIENT) ClosingClientListHead.Flink;
- pClient != (PREMOTE_CLIENT) &ClosingClientListHead;
- pClient = (PREMOTE_CLIENT) pClient->Links.Flink ) {
- if (pch + 60 > buff + sizeof(buff)) {
- break;
- }
- pch += sprintf(pch, "%d: %s %s (Disconnected)n", pClient->dwID, pClient->Name, pClient->UserName);
- }
- LeaveCriticalSection(&csClosingClientList);
- WriteFileSynch(hClientPipe, buff, pch - buff, &tmp, 0, &ol);
- WriteFileSynch(hClientPipe, szSep, sizeof(szSep) - 1, &tmp, 0, &ol);
- //
- // Dump the normal client list
- //
- pch = buff;
- EnterCriticalSection(&csClientList);
- for (pClient = (PREMOTE_CLIENT) ClientListHead.Flink;
- pClient != (PREMOTE_CLIENT) &ClientListHead;
- pClient = (PREMOTE_CLIENT) pClient->Links.Flink ) {
- if (pch + 60 > buff + sizeof(buff)) {
- break;
- }
- pch += sprintf(pch, "%d: %s %sn", pClient->dwID, pClient->Name, pClient->UserName);
- }
- LeaveCriticalSection(&csClientList);
- WriteFileSynch(hClientPipe, buff, pch - buff, &tmp, 0, &ol);
- WriteFileSynch(hClientPipe, szSep, sizeof(szSep) - 1, &tmp, 0, &ol);
- //
- // Dump the handshaking client list
- //
- pch = buff;
- EnterCriticalSection(&csHandshakingList);
- for (pClient = (PREMOTE_CLIENT) HandshakingListHead.Flink;
- pClient != (PREMOTE_CLIENT) &HandshakingListHead;
- pClient = (PREMOTE_CLIENT) pClient->Links.Flink ) {
- if (pch + 60 > buff + sizeof(buff)) {
- break;
- }
- pch += sprintf(pch, "%d: %s %s (Connecting)n", pClient->dwID, pClient->Name, pClient->UserName);
- }
- LeaveCriticalSection(&csHandshakingList);
- WriteFileSynch(hClientPipe, buff, pch - buff, &tmp, 0, &ol);
- WriteFileSynch(hClientPipe, szSep, sizeof(szSep) - 1, &tmp, 0, &ol);
- //
- // Dump summary information.
- //
- pch = buff;
- pch += sprintf(pch, "REMOTE /C %s %sn", HostName, PipeName);
- pch += sprintf(pch, "Command: %sn", ChildCmd);
- pch += sprintf(pch, "Windows NT %d.%d build %d n",
- OsVersionInfo.dwMajorVersion,
- OsVersionInfo.dwMinorVersion,
- OsVersionInfo.dwBuildNumber);
- WriteFileSynch(hClientPipe, buff, pch - buff, &tmp, 0, &ol);
- WriteFileSynch(hClientPipe, szSep, sizeof(szSep) - 1, &tmp, 0, &ol);
- CloseHandle(ol.hEvent);
- return 0;
- }
- /*************************************************************/
- DWORD // NO CRT for ShowPopup
- WINAPI
- ShowPopup(
- void *vpArg
- )
- {
- char *msg = (char *) vpArg;
- MessageBox(GetActiveWindow(),msg,"** REMOTE.EXE **",MB_OK|MB_SETFOREGROUND);
- HeapFree(hHeap, 0, msg);
- return(0);
- }
- /*************************************************************/
- //
- // SrvCtrlHand is the console event handler for the server side
- // of remote. If our stdin is a console handle, we've disabled
- // generation of ^C events by the console code. Therefore
- // any we see are either generated by us for the benefit of
- // our child processes sharing the console, or generated by
- // some other process. We want to ignore the ones we generate
- // (since we're already done with everything that needs to be
- // done at that point), and also ignore ^C's generated by
- // other processes since we don't need to do anything with those.
- // For example if someone runs:
- //
- // remote /s "remote /s cmd inner" outer
- //
- // Then local keyboard ^C's will be read by the outer remote.exe
- // from its stdin handle, then it will generate a CTRL_C_EVENT that
- // all processes in the console will see, including both remote.exe's
- // and the child cmd.exe. So the handler needs do nothing but indicate
- // the event was handled by returning TRUE so the default handler
- // won't kill us. For ^BREAK we want to specifically kill our child
- // process so that cmd.exe and others that ignore ^BREAK will go away.
- // Of course this won't kill our grandchildren and so on. Oh well.
- //
- // For all other events we return FALSE and let the default handler
- // have it.
- //
- BOOL
- WINAPI
- SrvCtrlHand(
- DWORD event
- )
- {
- BOOL bRet = FALSE;
- DWORD cb;
- DWORD dwTempFileOffset;
- OVERLAPPED ol;
- char szTime[64];
- char szCmd[128];
- if (event == CTRL_BREAK_EVENT) {
- TerminateProcess(ChldProc, 3);
- bRet = TRUE;
- } else if (event == CTRL_C_EVENT) {
- if ( ! cPendingCtrlCEvents ) {
- //
- // This came from the local keyboard or
- // was generated by another process in
- // this console. Echo it as a local
- // command. We have use GetTimeFormat
- // here not our GetFormattedTime since
- // the latter is for the use of the
- // main thread only.
- //
- GetTimeFormat(
- LOCALE_USER_DEFAULT,
- TIME_NOSECONDS,
- NULL, // use current time
- NULL, // use default format
- szTime,
- sizeof(szTime)
- );
- CMDSTRING(szCmd, cb, "^C", pLocalClient, szTime, TRUE);
- ZeroMemory(&ol, sizeof(ol));
- ol.hEvent =
- CreateEvent(
- NULL, // security
- TRUE, // auto-reset
- FALSE, // initially nonsignaled
- NULL // unnamed
- );
- //
- // Practically all writes to the tempfile are happening on
- // the primary server thread. We're on a Ctrl-C thread.
- // We can't start the server to client I/O going after
- // writing because we're on the wrong thread, so we
- // punt. To fix this we need an event we can signal
- // that causes the main thread to call StartServerToClientFlow.
- //
- dwTempFileOffset = dwWriteFilePointer;
- dwWriteFilePointer += cb;
- WriteFileSynch(hWriteTempFile, szCmd, cb, &cb, dwTempFileOffset, &ol);
- // wrong thread // StartServerToClientFlow();
- CloseHandle(ol.hEvent);
- } else {
- //
- // We generated this event in response to a ^C received from
- // a client, it's already been displayed to all clients.
- //
- cPendingCtrlCEvents--;
- }
- bRet = TRUE;
- }
- return bRet;
- }
- /*************************************************************/
- PSECURITY_DESCRIPTOR
- FormatSecurityDescriptor(
- CHAR * * DenyNames,
- DWORD DenyCount,
- CHAR * * Names,
- DWORD Count)
- {
- PSECURITY_DESCRIPTOR Sd;
- PACL Acl;
- DWORD i;
- PSID Sids;
- DWORD SidLength ;
- CHAR ReferencedDomain[ MAX_PATH ];
- UCHAR SidBuffer[ 8 * sizeof(DWORD) + 8 ];
- DWORD DomainLen ;
- SID_NAME_USE Use;
- DWORD SdLen;
- SdLen = sizeof(SECURITY_DESCRIPTOR) +
- DenyCount * (sizeof( ACCESS_DENIED_ACE ) ) +
- DenyCount * GetSidLengthRequired( 8 ) +
- Count * (sizeof( ACCESS_ALLOWED_ACE ) ) + sizeof(ACL) +
- (Count * GetSidLengthRequired( 8 ) );
- Sd = LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, SdLen );
- if ( !Sd )
- {
- ErrorExit("Could not allocate SD");
- }
- InitializeSecurityDescriptor( Sd, SECURITY_DESCRIPTOR_REVISION );
- Acl = (PACL)( (PUCHAR) Sd + sizeof( SECURITY_DESCRIPTOR) );
- InitializeAcl( Acl, SdLen - sizeof( SECURITY_DESCRIPTOR) ,
- ACL_REVISION );
- Sids = SidBuffer;
- for (i = 0 ; i < DenyCount ; i ++ )
- {
- SidLength = sizeof( SidBuffer );
- DomainLen = MAX_PATH ;
- if (! LookupAccountName(NULL,
- DenyNames[ i ],
- Sids,
- &SidLength,
- ReferencedDomain,
- &DomainLen,
- &Use ) )
- {
- _snprintf( ReferencedDomain, MAX_PATH, "Unable to find account %s", DenyNames[ i ]);
- ErrorExit( ReferencedDomain );
- }
- //
- // Got the sid. Now, add it as an access denied ace:
- //
- AddAccessDeniedAce( Acl,
- ACL_REVISION,
- FILE_GENERIC_READ |
- FILE_GENERIC_WRITE |
- FILE_CREATE_PIPE_INSTANCE,
- Sids );
- }
- for (i = 0 ; i < Count ; i ++ )
- {
- SidLength = sizeof( SidBuffer );
- DomainLen = MAX_PATH ;
- if (! LookupAccountName(NULL,
- Names[ i ],
- Sids,
- &SidLength,
- ReferencedDomain,
- &DomainLen,
- &Use ) )
- {
- _snprintf( ReferencedDomain, MAX_PATH, "Unable to find account %s", Names[ i ]);
- ErrorExit( ReferencedDomain );
- }
- //
- // Got the sid. Now, add it as an access allowed ace:
- //
- AddAccessAllowedAce(Acl,
- ACL_REVISION,
- FILE_GENERIC_READ |
- FILE_GENERIC_WRITE |
- FILE_CREATE_PIPE_INSTANCE,
- Sids );
- }
- //
- // Now the ACL should be complete, so set it into the SD and return:
- //
- SetSecurityDescriptorDacl( Sd, TRUE, Acl, FALSE );
- return Sd ;
- }
- /*************************************************************/
- VOID
- CloseClient(
- REMOTE_CLIENT *pClient
- )
- {
- DWORD tmp;
- char Buf[200];
- #if DBG
- if (pClient->ServerFlags & ~SFLG_VALID) {
- printf("pClient %x looks nasty in CloseClient.n", pClient);
- ErrorExit("REMOTE_CLIENT structure corrupt.");
- }
- #endif
- //
- // If we're still active (on the normal client list)
- // start tearing things down and move to the closing
- // list.
- //
- if (pClient->ServerFlags & SFLG_CLOSING) {
- return;
- }
- if (pClient->ServerFlags & SFLG_HANDSHAKING) {
- MoveClientToNormalList(pClient);
- }
- MoveClientToClosingList(pClient);
- pClient->ServerFlags |= SFLG_CLOSING;
- if (pClient->PipeWriteH != INVALID_HANDLE_VALUE) {
- TRACE(CONNECT, ("Disconnecting %d PipeWriteH (%x).n", pClient->dwID, pClient->PipeWriteH));
- CANCELIO(pClient->PipeWriteH);
- DisconnectNamedPipe(pClient->PipeWriteH);
- CloseHandle(pClient->PipeWriteH);
- }
- if (pClient->PipeReadH != INVALID_HANDLE_VALUE &&
- pClient->PipeReadH != pClient->PipeWriteH) {
- TRACE(CONNECT, ("Disconnecting %d PipeReadH (%x).n", pClient->dwID, pClient->PipeReadH));
- CANCELIO(pClient->PipeReadH);
- DisconnectNamedPipe(pClient->PipeReadH);
- CloseHandle(pClient->PipeReadH);
- }
- if (pClient->rSaveFile != INVALID_HANDLE_VALUE) {
- CANCELIO(pClient->rSaveFile);
- CloseHandle(pClient->rSaveFile);
- }
- pClient->rSaveFile =
- pClient->PipeWriteH =
- pClient->PipeReadH =
- INVALID_HANDLE_VALUE;
- if ( ! bShuttingDownServer ) {
- sprintf(Buf, "n**Remote: Disconnected from %s %s [%s]n", pClient->Name, pClient->UserName, GetFormattedTime(TRUE));
- if (WriteFileSynch(hWriteTempFile,Buf,strlen(Buf),&tmp,dwWriteFilePointer,&olMainThread)) {
- dwWriteFilePointer += tmp;
- StartServerToClientFlow();
- }
- }
- return;
- }
- BOOL
- FASTCALL
- HandleSessionError(
- PREMOTE_CLIENT pClient,
- DWORD dwError
- )
- {
- if (pClient->ServerFlags & SFLG_CLOSING) {
- return TRUE;
- }
- if (dwError) {
- if (ERROR_BROKEN_PIPE == dwError ||
- ERROR_OPERATION_ABORTED == dwError ||
- ERROR_NO_DATA == dwError ) {
- CloseClient(pClient);
- return TRUE;
- }
- SetLastError(dwError);
- ErrorExit("Unhandled session error.");
- }
- return FALSE;
- }
- VOID
- FASTCALL
- CleanupTempFiles(
- PSZ pszTempDir
- )
- {
- HANDLE hSearch;
- WIN32_FIND_DATA FindData;
- char szPath[MAX_PATH + 1];
- char szFile[MAX_PATH + 1];
- //
- // pszTempDir, from GetTempPath, has a trailing backslash.
- //
- sprintf(szPath, "%sREM*.tmp", pszTempDir);
- hSearch = FindFirstFile(
- szPath,
- &FindData
- );
- if (INVALID_HANDLE_VALUE != hSearch) {
- do {
- sprintf(szFile, "%s%s", pszTempDir, FindData.cFileName);
- DeleteFile(szFile);
- } while (FindNextFile(hSearch, &FindData));
- FindClose(hSearch);
- }
- }
- VOID
- FASTCALL
- SetupSecurityDescriptors(
- VOID
- )
- {
- int i;
- //
- // Initialize the wide-open security descriptor.
- //
- InitializeSecurityDescriptor(
- &sdPublic,
- SECURITY_DESCRIPTOR_REVISION
- );
- SetSecurityDescriptorDacl(
- &sdPublic,
- TRUE,
- NULL,
- FALSE
- );
- saPublic.nLength = sizeof(saPublic);
- saPublic.lpSecurityDescriptor = &sdPublic;
- //
- // if /u was specified once or more, build the security descriptor to
- // enforce it.
- //
- saPipe.nLength = sizeof(saPipe);
- if ( DaclNameCount || DaclDenyNameCount ) {
- saPipe.lpSecurityDescriptor =
- FormatSecurityDescriptor(
- DaclDenyNames,
- DaclDenyNameCount,
- DaclNames,
- DaclNameCount
- );
- if (DaclNameCount) {
- printf( "nProtected Server! Only the following users or groups can connect:n" );
- for (i = 0 ; i < (int) DaclNameCount ; i++) {
- printf( " %sn", DaclNames[i] );
- }
- }
- if (DaclDenyNameCount) {
- printf( "The following users or groups explicitly cannot connect:n" );
- for (i = 0 ; i < (int) DaclDenyNameCount ; i++) {
- printf(" %sn", DaclDenyNames[i] );
- }
- }
- } else {
- saPipe.lpSecurityDescriptor = &sdPublic;
- }
- }
- VOID
- FASTCALL
- RuntimeLinkAPIs(
- VOID
- )
- {
- HANDLE hmodKernel32;
- HANDLE hmodNetApi32;
- hmodKernel32 = LoadLibrary("kernel32");
- hmodNetApi32 = LoadLibrary("netapi32");
- pfnCreateWaitableTimer = (void *)
- GetProcAddress(
- hmodKernel32,
- "CreateWaitableTimerA"
- );
- pfnSetWaitableTimer = (void *)
- GetProcAddress(
- hmodKernel32,
- "SetWaitableTimer"
- );
- pfnCancelWaitableTimer = (void *)
- GetProcAddress(
- hmodKernel32,
- "CancelWaitableTimer"
- );
- pfnCancelIo = (void *)
- GetProcAddress(
- hmodKernel32,
- "CancelIo"
- );
- pfnNetWkstaGetInfo = (void *)
- GetProcAddress(
- hmodNetApi32,
- "NetWkstaGetInfo"
- );
- pfnNetApiBufferFree = (void *)
- GetProcAddress(
- hmodNetApi32,
- "NetApiBufferFree"
- );
- //
- // We do without Waitable Timers and CancelIo on 3.51
- //
- if (!pfnNetWkstaGetInfo ||
- !pfnNetApiBufferFree) {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- ErrorExit("Remote server requires Windows NT.");
- }
- }