|
|
1.1 ! root 1: /****************************** Module Header ******************************\ ! 2: * Module Name: rcmdsrv.c ! 3: * ! 4: * Copyright (c) 1991, Microsoft Corporation ! 5: * ! 6: * Remote shell server main module ! 7: * ! 8: * History: ! 9: * 06-29-92 Davidc Created. ! 10: \***************************************************************************/ ! 11: ! 12: #include "rcmdsrv.h" ! 13: ! 14: #define PIPE_NAME TEXT("\\\\.\\pipe\\rshell") ! 15: ! 16: // ! 17: // Number of pipe instances ! 18: // ! 19: ! 20: #define MAX_SESSIONS PIPE_UNLIMITED_INSTANCES ! 21: ! 22: ! 23: // ! 24: // Define pipe timeout (ms) ! 25: // Only used by WaitNamedPipe ! 26: // ! 27: ! 28: #define PIPE_TIMEOUT 1000 ! 29: ! 30: ! 31: ! 32: // ! 33: // Ctrl-C handler routine ! 34: // ! 35: ! 36: BOOL ! 37: CtrlHandler( ! 38: DWORD CtrlType ! 39: ) ! 40: { ! 41: // ! 42: // We'll handle Ctrl-C events ! 43: // ! 44: ! 45: return (CtrlType == CTRL_C_EVENT); ! 46: } ! 47: ! 48: ! 49: ! 50: // ! 51: // Main ! 52: // ! 53: ! 54: int ! 55: _CRTAPI1 main( ! 56: int argc, ! 57: char **argv ! 58: ) ! 59: { ! 60: SECURITY_ATTRIBUTES SecurityAttributes; ! 61: SECURITY_DESCRIPTOR SecurityDescriptor; ! 62: BOOL Result; ! 63: DWORD WaitResult; ! 64: HANDLE SessionHandle = NULL; ! 65: ! 66: // ! 67: // Set the error mode so we don't generate popups ! 68: // ! 69: ! 70: SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); ! 71: ! 72: // ! 73: // Install a handler for Ctrl-C ! 74: // ! 75: ! 76: if (!SetConsoleCtrlHandler((PHANDLER_ROUTINE) &CtrlHandler, TRUE)) { ! 77: printf("Failed to install control-C handler, error = %d\n", GetLastError()); ! 78: return(1); ! 79: } ! 80: ! 81: ! 82: // ! 83: // Setup the security descriptor to put on the named pipe. ! 84: // For now give world access. ! 85: // ! 86: ! 87: Result = InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION); ! 88: assert(Result); ! 89: ! 90: Result = SetSecurityDescriptorDacl(&SecurityDescriptor, FALSE, NULL, FALSE); ! 91: assert(Result); ! 92: ! 93: SecurityAttributes.nLength = sizeof(SecurityAttributes); ! 94: SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor; ! 95: SecurityAttributes.bInheritHandle = FALSE; ! 96: ! 97: ! 98: // ! 99: // Tell the user what's happening ! 100: // ! 101: ! 102: printf("Remote command shell running.\n"); ! 103: printf("Use Ctrl-Break to terminate\n\n"); ! 104: ! 105: ! 106: // ! 107: // Do loop inside try-finally so we always delete any session on exit ! 108: // ! 109: ! 110: try { ! 111: ! 112: BOOL Done = FALSE; ! 113: ! 114: // ! 115: // Loop waiting for a client to connect. ! 116: // ! 117: ! 118: while (!Done) { ! 119: ! 120: HANDLE ConnectHandle; ! 121: SESSION_DISCONNECT_CODE DisconnectCode; ! 122: HANDLE PipeHandle; ! 123: ! 124: // ! 125: // Create an instance of the named pipe ! 126: // ! 127: ! 128: PipeHandle = CreateNamedPipe(PIPE_NAME, ! 129: PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, ! 130: PIPE_TYPE_BYTE | PIPE_WAIT, ! 131: MAX_SESSIONS, // Number of pipes ! 132: 0, // Default out buffer size ! 133: 0, // Default in buffer size ! 134: PIPE_TIMEOUT, // Timeout in ms ! 135: &SecurityAttributes ! 136: ); ! 137: ! 138: if (PipeHandle == INVALID_HANDLE_VALUE ) { ! 139: printf("Failed to create named pipe instance, error = %d\n", GetLastError()); ! 140: break; // out of while ! 141: } ! 142: ! 143: ! 144: // ! 145: // Wait for a client to connect ! 146: // ! 147: ! 148: printf("Waiting for client connect\n"); ! 149: ! 150: ! 151: Result = ConnectNamedPipe(PipeHandle, NULL); ! 152: ! 153: if (!Result) { ! 154: ! 155: DWORD Error = GetLastError(); ! 156: ! 157: if (Error == ERROR_PIPE_CONNECTED) { ! 158: ! 159: // ! 160: // The client has already connected (fast work!) ! 161: // ! 162: ! 163: } else { ! 164: ! 165: printf("Connect named pipe failed, error = %d\n", GetLastError()); ! 166: MyCloseHandle(PipeHandle, "client pipe"); ! 167: break; ! 168: } ! 169: } ! 170: ! 171: ! 172: printf("Client connected\n"); ! 173: ! 174: ! 175: // ! 176: // Create a new session if necessary ! 177: // ! 178: ! 179: if (SessionHandle == NULL) { ! 180: ! 181: SessionHandle = CreateSession(); ! 182: ! 183: if (SessionHandle == NULL) { ! 184: printf("Failed to create session\n"); ! 185: MyCloseHandle(PipeHandle, "client pipe"); ! 186: break; ! 187: } ! 188: } ! 189: ! 190: ! 191: // ! 192: // Connect the pipe to our session ! 193: // ! 194: ! 195: ConnectHandle = ConnectSession(SessionHandle, PipeHandle); ! 196: if (ConnectHandle == NULL) { ! 197: MyCloseHandle(PipeHandle, "client pipe"); ! 198: printf("Failed to connect session\n"); ! 199: break; ! 200: } ! 201: ! 202: // ! 203: // Wait for session disconnect ! 204: // ! 205: ! 206: WaitResult = WaitForSingleObject(ConnectHandle, INFINITE); ! 207: if (WaitResult != 0) { ! 208: printf("Unexpected result from wait on connect handle, result = %d\n", WaitResult); ! 209: } ! 210: ! 211: // ! 212: // Disconnect the session to find out why it happened ! 213: // ! 214: ! 215: DisconnectCode = DisconnectSession(SessionHandle); ! 216: ! 217: switch (DisconnectCode) { ! 218: ! 219: case ShellEnded: ! 220: ! 221: // ! 222: // The shell ended, delete the session ! 223: // ! 224: ! 225: printf("Shell terminated\n"); ! 226: ! 227: DeleteSession(SessionHandle); ! 228: SessionHandle = NULL; ! 229: break; // out of switch ! 230: ! 231: case ClientDisconnected: ! 232: ! 233: // ! 234: // The client disconnected, keep the session and go wait ! 235: // for another client to connect to it. ! 236: // ! 237: ! 238: printf("Client disconnected\n"); ! 239: ! 240: // ............... bug workaround ............. ! 241: // To work around async read bug with exitted thread, ! 242: // always kill off the shell and start a new one ! 243: DeleteSession(SessionHandle); ! 244: SessionHandle = NULL; ! 245: // ............................................ ! 246: ! 247: break; ! 248: ! 249: case ConnectError: ! 250: case DisconnectError: ! 251: default: ! 252: ! 253: printf("Disconnect session returned unexpected code : %d\n", DisconnectCode); ! 254: Done = TRUE; ! 255: break; // out of switch ! 256: } ! 257: ! 258: ! 259: // ! 260: // Go back and wait for a client to connect ! 261: // ! 262: ! 263: } ! 264: ! 265: ! 266: } finally { ! 267: ! 268: DbgPrint("Finally being called\n"); ! 269: ! 270: // ! 271: // Delete any existing session ! 272: // ! 273: ! 274: if (SessionHandle != NULL) { ! 275: DeleteSession(SessionHandle); ! 276: } ! 277: ! 278: } ! 279: ! 280: return(0); ! 281: } ! 282:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.