Leaked source code of windows server 2003
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.

606 lines
12 KiB

  1. /******************************************************************************\
  2. * This is a part of the Microsoft Source Code Samples.
  3. * Copyright 1995 - 1997 Microsoft Corporation.
  4. * All rights reserved.
  5. * This source code is only intended as a supplement to
  6. * Microsoft Development Tools and/or WinHelp documentation.
  7. * See these sources for detailed information regarding the
  8. * Microsoft samples programs.
  9. \******************************************************************************/
  10. /*++
  11. Copyright (c) 1997 Microsoft Corporation
  12. Module Name:
  13. Server.h
  14. Abstract:
  15. The server component of Remote, rewritten using
  16. ReadFileEx/WriteFileEx completion routines.
  17. Author:
  18. Dave Hart 30 May 1997
  19. Environment:
  20. Console App. User mode.
  21. Revision History:
  22. --*/
  23. #include <lm.h> // needed for NET_API_STATUS below
  24. #if !defined(SERVER_H_NOEXTERN)
  25. #define SRVEXTERN extern
  26. #else
  27. #define SRVEXTERN
  28. #endif
  29. #if DBG
  30. DWORD Trace; // bits set in here trigger trace printfs
  31. #define TR_SESSION (0x01)
  32. #define TR_CHILD (0x02)
  33. #define TR_SHAKE (0x04)
  34. #define TR_CONNECT (0x08)
  35. #define TR_QUERY (0x10)
  36. #define TR_COPYPIPE (0x20)
  37. #endif
  38. #if DBG
  39. #define TRACE(tracebit, printfargs) \
  40. ((Trace & (TR_##tracebit) \
  41. ? (printf printfargs, fflush(stdout), 0) \
  42. : 0))
  43. #else
  44. #define TRACE(tracebit, printfargs) (0)
  45. #endif
  46. #if defined(ASSERT)
  47. #undef ASSERT
  48. #endif
  49. #if DBG
  50. #define ASSERT(exp) ((exp) || (ErrorExit("Assertion failed in " __FILE__ ": " #exp ),0))
  51. #else
  52. #define ASSERT(exp) (0)
  53. #endif
  54. //
  55. // Size of transfer buffers
  56. //
  57. #define BUFFSIZE (4 * 1024)
  58. //
  59. // ServerFlags bit values in REMOTE_CLIENT below
  60. //
  61. #define SFLG_CLOSING 0x01
  62. #define SFLG_HANDSHAKING 0x02
  63. #define SFLG_READINGCOMMAND 0x04
  64. #define SFLG_LOCAL 0x08
  65. #define SFLG_VALID \
  66. (SFLG_CLOSING | \
  67. SFLG_HANDSHAKING | \
  68. SFLG_READINGCOMMAND | \
  69. SFLG_LOCAL)
  70. //
  71. // Per-client state
  72. //
  73. typedef struct tagREMOTE_CLIENT {
  74. LIST_ENTRY Links;
  75. DWORD dwID; // 1, 2, ...
  76. DWORD ServerFlags;
  77. DWORD Flag; //from Client's ClientToServerFlag
  78. DWORD cbWrite; //zero if no read temp/write client ops pending
  79. HANDLE PipeReadH; //Client sends its StdIn through this
  80. HANDLE PipeWriteH; //Client gets its StdOut through this
  81. DWORD dwFilePos; //offset of temp file where next read begins
  82. OVERLAPPED ReadOverlapped;
  83. OVERLAPPED WriteOverlapped;
  84. HANDLE rSaveFile; //Sessions read handle to SaveFile
  85. DWORD cbReadTempBuffer;
  86. DWORD cbWriteBuffer;
  87. DWORD cbCommandBuffer;
  88. char HexAsciiId[8]; // dwID as 8 hex chars -- no terminator
  89. char Name[HOSTNAMELEN]; //Name of client Machine;
  90. char UserName[16]; //Name of user on client machine.
  91. BYTE ReadBuffer[BUFFSIZE];
  92. BYTE ReadTempBuffer[BUFFSIZE];
  93. BYTE WriteBuffer[BUFFSIZE];
  94. BYTE CommandBuffer[BUFFSIZE];
  95. } REMOTE_CLIENT, *PREMOTE_CLIENT;
  96. //
  97. // Client lists, see srvlist.c
  98. //
  99. SRVEXTERN LIST_ENTRY HandshakingListHead;
  100. SRVEXTERN CRITICAL_SECTION csHandshakingList;
  101. SRVEXTERN LIST_ENTRY ClientListHead;
  102. SRVEXTERN CRITICAL_SECTION csClientList;
  103. SRVEXTERN LIST_ENTRY ClosingClientListHead;
  104. SRVEXTERN CRITICAL_SECTION csClosingClientList;
  105. SRVEXTERN DWORD dwNextClientID;
  106. SRVEXTERN LPSTR pszPipeName;
  107. SRVEXTERN HANDLE ChldProc;
  108. SRVEXTERN DWORD pidChild;
  109. SRVEXTERN HANDLE hWriteChildStdIn;
  110. SRVEXTERN BOOL bShuttingDownServer;
  111. SRVEXTERN HANDLE hHeap;
  112. SRVEXTERN volatile DWORD cPendingCtrlCEvents;
  113. SRVEXTERN OSVERSIONINFO OsVersionInfo;
  114. // File containing all that was output by child process.
  115. // Each connection opens a handle to this file
  116. // and sends its contents through PipeWriteH.
  117. SRVEXTERN HANDLE hWriteTempFile;
  118. SRVEXTERN char SaveFileName[MAX_PATH]; //Name of above file - all new sessions need
  119. //
  120. // Generic "wide-open" security descriptor as well
  121. // as the possibly-restricted pipe SD.
  122. //
  123. SRVEXTERN PSECURITY_DESCRIPTOR sdPublic;
  124. SRVEXTERN SECURITY_ATTRIBUTES saPublic;
  125. SRVEXTERN SECURITY_ATTRIBUTES saPipe;
  126. SRVEXTERN SECURITY_ATTRIBUTES saLocalNamedObjects ;
  127. extern BOOL SaveDaclToRegistry ;
  128. //
  129. // To minimize client "all pipe instances are busy" errors,
  130. // we wait on connection to several instances of the IN pipe,
  131. // the sole pipe used by single-pipe clients. Because of the
  132. // requirement to support two-pipe clients (old software as
  133. // well as new software on Win95), we cannot easily create
  134. // and wait for connection on several instances of the OUT pipe.
  135. // This is because two-pipe clients connect to both pipes before
  136. // handshaking commences, and they connect to OUT first. If we
  137. // had several OUT pipe instances waiting, when an IN pipe was
  138. // connected by the two-pipe client, we wouldn't know which of
  139. // the possibly several connected OUT pipe instances to pair
  140. // it with. With only one OUT pipe, at IN connect time we need
  141. // to distinguish two-pipe from one-pipe clients so a one-pipe
  142. // client doesn't sneak in between the OUT and IN connects of
  143. // a two-pipe client and wrongly be paired with the OUT pipe.
  144. // To do so we look at the first byte of the initial write
  145. // from the client (of the computername and magic value), if
  146. // it's a question mark we know we have a new client and won't
  147. // accidentally link it to a connected OUT instance.
  148. //
  149. #define CONNECT_COUNT 3
  150. SRVEXTERN DWORD cConnectIns;
  151. SRVEXTERN OVERLAPPED rgolConnectIn[CONNECT_COUNT];
  152. SRVEXTERN HANDLE rghPipeIn[CONNECT_COUNT];
  153. SRVEXTERN OVERLAPPED olConnectOut;
  154. SRVEXTERN BOOL bOutPipeConnected;
  155. SRVEXTERN HANDLE hPipeOut;
  156. SRVEXTERN HANDLE hConnectOutTimer;
  157. //
  158. // Indexes into rghWait array for multiple-wait
  159. //
  160. #define WAITIDX_CHILD_PROCESS 0
  161. #define WAITIDX_READ_STDIN_DONE 1
  162. #define WAITIDX_QUERYSRV_WAIT 2
  163. #define WAITIDX_PER_PIPE_EVENT 3
  164. #define WAITIDX_CONNECT_OUT 4
  165. #define WAITIDX_CONNECT_IN_BASE 5
  166. #define MAX_WAIT_HANDLES (WAITIDX_CONNECT_IN_BASE + CONNECT_COUNT)
  167. SRVEXTERN HANDLE rghWait[MAX_WAIT_HANDLES];
  168. SRVEXTERN OVERLAPPED ReadChildOverlapped;
  169. SRVEXTERN HANDLE hReadChildOutput;
  170. SRVEXTERN BYTE ReadChildBuffer[BUFFSIZE];
  171. SRVEXTERN PREMOTE_CLIENT pLocalClient;
  172. typedef struct tagCOPYPIPE {
  173. HANDLE hRead;
  174. HANDLE hWrite;
  175. } COPYPIPE, *PCOPYPIPE;
  176. SRVEXTERN COPYPIPE rgCopyPipe[2];
  177. SRVEXTERN volatile DWORD dwWriteFilePointer; // used by SrvCtrlHand (thread)
  178. SRVEXTERN OVERLAPPED QueryOverlapped;
  179. SRVEXTERN HANDLE hQPipe;
  180. SRVEXTERN OVERLAPPED olMainThread;
  181. BOOL
  182. APIENTRY
  183. MyCreatePipeEx(
  184. OUT LPHANDLE lpReadPipe,
  185. OUT LPHANDLE lpWritePipe,
  186. IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
  187. IN DWORD nSize,
  188. DWORD dwReadMode,
  189. DWORD dwWriteMode
  190. );
  191. DWORD
  192. WINAPI
  193. CopyPipeToPipe(
  194. LPVOID lpCopyPipeData
  195. );
  196. DWORD
  197. WINAPI
  198. CopyStdInToPipe(
  199. LPVOID lpCopyPipeData
  200. );
  201. VOID
  202. FASTCALL
  203. StartSession(
  204. PREMOTE_CLIENT pClient
  205. );
  206. VOID
  207. FASTCALL
  208. StartLocalSession(
  209. VOID
  210. );
  211. VOID
  212. FASTCALL
  213. StartReadClientInput(
  214. PREMOTE_CLIENT pClient
  215. );
  216. VOID
  217. WINAPI
  218. ReadClientInputCompleted(
  219. DWORD dwError,
  220. DWORD cbRead,
  221. LPOVERLAPPED lpO
  222. );
  223. VOID
  224. WINAPI
  225. WriteChildStdInCompleted(
  226. DWORD dwError,
  227. DWORD cbWritten,
  228. LPOVERLAPPED lpO
  229. );
  230. #define OUT_PIPE -1
  231. VOID
  232. FASTCALL
  233. CreatePipeAndIssueConnect(
  234. int nIndex // IN pipe index or OUT_PIPE
  235. );
  236. VOID
  237. FASTCALL
  238. HandleOutPipeConnected(
  239. VOID
  240. );
  241. VOID
  242. APIENTRY
  243. ConnectOutTimerFired(
  244. LPVOID pArg,
  245. DWORD dwTimerLo,
  246. DWORD dwTimerHi
  247. );
  248. VOID
  249. FASTCALL
  250. HandleInPipeConnected(
  251. int nIndex
  252. );
  253. VOID
  254. FASTCALL
  255. HandshakeWithRemoteClient(
  256. PREMOTE_CLIENT pClient
  257. );
  258. VOID
  259. FASTCALL
  260. StartChildOutPipeRead(
  261. VOID
  262. );
  263. VOID
  264. WINAPI
  265. ReadChildOutputCompleted(
  266. DWORD dwError,
  267. DWORD cbRead,
  268. LPOVERLAPPED lpO
  269. );
  270. VOID
  271. WINAPI
  272. WriteTempFileCompleted(
  273. DWORD dwError,
  274. DWORD cbWritten,
  275. LPOVERLAPPED lpO
  276. );
  277. VOID
  278. FASTCALL
  279. StartServerToClientFlow(
  280. VOID
  281. );
  282. VOID
  283. FASTCALL
  284. StartReadTempFile(
  285. PREMOTE_CLIENT pClient
  286. );
  287. VOID
  288. WINAPI
  289. ReadTempFileCompleted(
  290. DWORD dwError,
  291. DWORD cbRead,
  292. LPOVERLAPPED lpO
  293. );
  294. VOID
  295. FASTCALL
  296. StartWriteSessionOutput(
  297. PREMOTE_CLIENT pClient
  298. );
  299. BOOL
  300. FASTCALL
  301. WriteSessionOutputCompletedCommon(
  302. PREMOTE_CLIENT pClient,
  303. DWORD dwError,
  304. DWORD cbWritten,
  305. LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
  306. );
  307. VOID
  308. WINAPI
  309. WriteSessionOutputCompletedWriteNext(
  310. DWORD dwError,
  311. DWORD cbWritten,
  312. LPOVERLAPPED lpO
  313. );
  314. VOID
  315. WINAPI
  316. WriteSessionOutputCompletedReadNext(
  317. DWORD dwError,
  318. DWORD cbWritten,
  319. LPOVERLAPPED lpO
  320. );
  321. VOID
  322. FASTCALL
  323. HandshakeWithRemoteClient(
  324. PREMOTE_CLIENT pClient
  325. );
  326. VOID
  327. WINAPI
  328. ReadClientNameCompleted(
  329. DWORD dwError,
  330. DWORD cbRead,
  331. LPOVERLAPPED lpO
  332. );
  333. VOID
  334. WINAPI
  335. WriteServerReplyCompleted(
  336. DWORD dwError,
  337. DWORD cbWritten,
  338. LPOVERLAPPED lpO
  339. );
  340. VOID
  341. WINAPI
  342. ReadClientStartupInfoSizeCompleted(
  343. DWORD dwError,
  344. DWORD cbRead,
  345. LPOVERLAPPED lpO
  346. );
  347. VOID
  348. WINAPI
  349. ReadClientStartupInfoCompleted(
  350. DWORD dwError,
  351. DWORD cbRead,
  352. LPOVERLAPPED lpO
  353. );
  354. PCHAR
  355. GetFormattedTime(
  356. BOOL bDate
  357. );
  358. HANDLE
  359. ForkChildProcess( // Creates a new process
  360. char *cmd, // Redirects its stdin,stdout
  361. PHANDLE in, // and stderr - returns the
  362. PHANDLE out // corresponding pipe ends.
  363. );
  364. BOOL
  365. FilterCommand( //Filters input from client
  366. REMOTE_CLIENT *cl, //for commands intended for REMOTE
  367. char *buff,
  368. int dread
  369. );
  370. BOOL
  371. WINAPI
  372. SrvCtrlHand(
  373. DWORD event
  374. );
  375. DWORD
  376. WINAPI
  377. SendStatus(
  378. LPVOID lpSendStatusParm
  379. );
  380. DWORD
  381. WINAPI
  382. ShowPopup(
  383. void *vpArg
  384. );
  385. VOID
  386. RemoveInpMark(
  387. char* Buff,
  388. DWORD Size
  389. );
  390. VOID
  391. CloseClient(
  392. REMOTE_CLIENT *Client
  393. );
  394. PSECURITY_DESCRIPTOR
  395. FormatSecurityDescriptor(
  396. CHAR * * DenyNames,
  397. DWORD DenyCount,
  398. CHAR * * Names,
  399. DWORD Count
  400. );
  401. BOOL
  402. FASTCALL
  403. HandleSessionError(
  404. PREMOTE_CLIENT pClient,
  405. DWORD dwError
  406. );
  407. VOID
  408. FASTCALL
  409. CleanupTempFiles(
  410. PSZ pszTempDir
  411. );
  412. VOID
  413. FASTCALL
  414. SetupSecurityDescriptors(
  415. VOID
  416. );
  417. VOID
  418. FASTCALL
  419. InitializeClientLists(
  420. VOID
  421. );
  422. VOID
  423. FASTCALL
  424. AddClientToHandshakingList(
  425. PREMOTE_CLIENT pClient
  426. );
  427. VOID
  428. FASTCALL
  429. MoveClientToNormalList(
  430. PREMOTE_CLIENT pClient
  431. );
  432. VOID
  433. FASTCALL
  434. MoveClientToClosingList(
  435. PREMOTE_CLIENT pClient
  436. );
  437. PREMOTE_CLIENT
  438. FASTCALL
  439. RemoveFirstClientFromClosingList(
  440. VOID
  441. );
  442. VOID
  443. InitAd(
  444. BOOL IsAdvertise
  445. );
  446. VOID
  447. ShutAd(
  448. BOOL IsAdvertise
  449. );
  450. VOID
  451. APIENTRY
  452. AdvertiseTimerFired(
  453. LPVOID pArg,
  454. DWORD dwTimerLo,
  455. DWORD dwTimerHi
  456. );
  457. VOID
  458. WINAPI
  459. WriteMailslotCompleted(
  460. DWORD dwError,
  461. DWORD cbWritten,
  462. LPOVERLAPPED lpO
  463. );
  464. VOID
  465. FASTCALL
  466. InitializeQueryServer(
  467. VOID
  468. );
  469. VOID
  470. FASTCALL
  471. QueryWaitCompleted(
  472. VOID
  473. );
  474. VOID
  475. FASTCALL
  476. StartServingQueryPipe(
  477. VOID
  478. );
  479. DWORD
  480. WINAPI
  481. QueryHandlerThread(
  482. LPVOID lpUnused
  483. );
  484. BOOL
  485. CALLBACK
  486. EnumWindowProc(
  487. HWND hWnd,
  488. LPARAM lParam
  489. );