|
|
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.