Source code of Windows XP (NT5)
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.

656 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 SECURITY_DESCRIPTOR sdPublic;
  124. SRVEXTERN SECURITY_ATTRIBUTES saPublic;
  125. SRVEXTERN SECURITY_ATTRIBUTES saPipe;
  126. //
  127. // To minimize client "all pipe instances are busy" errors,
  128. // we wait on connection to several instances of the IN pipe,
  129. // the sole pipe used by single-pipe clients. Because of the
  130. // requirement to support two-pipe clients (old software as
  131. // well as new software on Win95), we cannot easily create
  132. // and wait for connection on several instances of the OUT pipe.
  133. // This is because two-pipe clients connect to both pipes before
  134. // handshaking commences, and they connect to OUT first. If we
  135. // had several OUT pipe instances waiting, when an IN pipe was
  136. // connected by the two-pipe client, we wouldn't know which of
  137. // the possibly several connected OUT pipe instances to pair
  138. // it with. With only one OUT pipe, at IN connect time we need
  139. // to distinguish two-pipe from one-pipe clients so a one-pipe
  140. // client doesn't sneak in between the OUT and IN connects of
  141. // a two-pipe client and wrongly be paired with the OUT pipe.
  142. // To do so we look at the first byte of the initial write
  143. // from the client (of the computername and magic value), if
  144. // it's a question mark we know we have a new client and won't
  145. // accidentally link it to a connected OUT instance.
  146. //
  147. #define CONNECT_COUNT 3
  148. SRVEXTERN DWORD cConnectIns;
  149. SRVEXTERN OVERLAPPED rgolConnectIn[CONNECT_COUNT];
  150. SRVEXTERN HANDLE rghPipeIn[CONNECT_COUNT];
  151. SRVEXTERN OVERLAPPED olConnectOut;
  152. SRVEXTERN BOOL bOutPipeConnected;
  153. SRVEXTERN HANDLE hPipeOut;
  154. SRVEXTERN HANDLE hConnectOutTimer;
  155. //
  156. // Indexes into rghWait array for multiple-wait
  157. //
  158. #define WAITIDX_CHILD_PROCESS 0
  159. #define WAITIDX_READ_STDIN_DONE 1
  160. #define WAITIDX_QUERYSRV_WAIT 2
  161. #define WAITIDX_PER_PIPE_EVENT 3
  162. #define WAITIDX_CONNECT_OUT 4
  163. #define WAITIDX_CONNECT_IN_BASE 5
  164. #define MAX_WAIT_HANDLES (WAITIDX_CONNECT_IN_BASE + CONNECT_COUNT)
  165. SRVEXTERN HANDLE rghWait[MAX_WAIT_HANDLES];
  166. SRVEXTERN OVERLAPPED ReadChildOverlapped;
  167. SRVEXTERN HANDLE hReadChildOutput;
  168. SRVEXTERN BYTE ReadChildBuffer[BUFFSIZE];
  169. SRVEXTERN PREMOTE_CLIENT pLocalClient;
  170. typedef struct tagCOPYPIPE {
  171. HANDLE hRead;
  172. HANDLE hWrite;
  173. } COPYPIPE, *PCOPYPIPE;
  174. SRVEXTERN COPYPIPE rgCopyPipe[2];
  175. SRVEXTERN volatile DWORD dwWriteFilePointer; // used by SrvCtrlHand (thread)
  176. SRVEXTERN OVERLAPPED QueryOverlapped;
  177. SRVEXTERN HANDLE hQPipe;
  178. SRVEXTERN OVERLAPPED olMainThread;
  179. BOOL
  180. APIENTRY
  181. MyCreatePipeEx(
  182. OUT LPHANDLE lpReadPipe,
  183. OUT LPHANDLE lpWritePipe,
  184. IN LPSECURITY_ATTRIBUTES lpPipeAttributes,
  185. IN DWORD nSize,
  186. DWORD dwReadMode,
  187. DWORD dwWriteMode
  188. );
  189. DWORD
  190. WINAPI
  191. CopyPipeToPipe(
  192. LPVOID lpCopyPipeData
  193. );
  194. DWORD
  195. WINAPI
  196. CopyStdInToPipe(
  197. LPVOID lpCopyPipeData
  198. );
  199. VOID
  200. FASTCALL
  201. StartSession(
  202. PREMOTE_CLIENT pClient
  203. );
  204. VOID
  205. FASTCALL
  206. StartLocalSession(
  207. VOID
  208. );
  209. VOID
  210. FASTCALL
  211. StartReadClientInput(
  212. PREMOTE_CLIENT pClient
  213. );
  214. VOID
  215. WINAPI
  216. ReadClientInputCompleted(
  217. DWORD dwError,
  218. DWORD cbRead,
  219. LPOVERLAPPED lpO
  220. );
  221. VOID
  222. WINAPI
  223. WriteChildStdInCompleted(
  224. DWORD dwError,
  225. DWORD cbWritten,
  226. LPOVERLAPPED lpO
  227. );
  228. #define OUT_PIPE -1
  229. VOID
  230. FASTCALL
  231. CreatePipeAndIssueConnect(
  232. int nIndex // IN pipe index or OUT_PIPE
  233. );
  234. VOID
  235. FASTCALL
  236. HandleOutPipeConnected(
  237. VOID
  238. );
  239. VOID
  240. APIENTRY
  241. ConnectOutTimerFired(
  242. LPVOID pArg,
  243. DWORD dwTimerLo,
  244. DWORD dwTimerHi
  245. );
  246. VOID
  247. FASTCALL
  248. HandleInPipeConnected(
  249. int nIndex
  250. );
  251. VOID
  252. FASTCALL
  253. HandshakeWithRemoteClient(
  254. PREMOTE_CLIENT pClient
  255. );
  256. VOID
  257. FASTCALL
  258. StartChildOutPipeRead(
  259. VOID
  260. );
  261. VOID
  262. WINAPI
  263. ReadChildOutputCompleted(
  264. DWORD dwError,
  265. DWORD cbRead,
  266. LPOVERLAPPED lpO
  267. );
  268. VOID
  269. WINAPI
  270. WriteTempFileCompleted(
  271. DWORD dwError,
  272. DWORD cbWritten,
  273. LPOVERLAPPED lpO
  274. );
  275. VOID
  276. FASTCALL
  277. StartServerToClientFlow(
  278. VOID
  279. );
  280. VOID
  281. FASTCALL
  282. StartReadTempFile(
  283. PREMOTE_CLIENT pClient
  284. );
  285. VOID
  286. WINAPI
  287. ReadTempFileCompleted(
  288. DWORD dwError,
  289. DWORD cbRead,
  290. LPOVERLAPPED lpO
  291. );
  292. VOID
  293. FASTCALL
  294. StartWriteSessionOutput(
  295. PREMOTE_CLIENT pClient
  296. );
  297. BOOL
  298. FASTCALL
  299. WriteSessionOutputCompletedCommon(
  300. PREMOTE_CLIENT pClient,
  301. DWORD dwError,
  302. DWORD cbWritten,
  303. LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
  304. );
  305. VOID
  306. WINAPI
  307. WriteSessionOutputCompletedWriteNext(
  308. DWORD dwError,
  309. DWORD cbWritten,
  310. LPOVERLAPPED lpO
  311. );
  312. VOID
  313. WINAPI
  314. WriteSessionOutputCompletedReadNext(
  315. DWORD dwError,
  316. DWORD cbWritten,
  317. LPOVERLAPPED lpO
  318. );
  319. VOID
  320. FASTCALL
  321. HandshakeWithRemoteClient(
  322. PREMOTE_CLIENT pClient
  323. );
  324. VOID
  325. WINAPI
  326. ReadClientNameCompleted(
  327. DWORD dwError,
  328. DWORD cbRead,
  329. LPOVERLAPPED lpO
  330. );
  331. VOID
  332. WINAPI
  333. WriteServerReplyCompleted(
  334. DWORD dwError,
  335. DWORD cbWritten,
  336. LPOVERLAPPED lpO
  337. );
  338. VOID
  339. WINAPI
  340. ReadClientStartupInfoSizeCompleted(
  341. DWORD dwError,
  342. DWORD cbRead,
  343. LPOVERLAPPED lpO
  344. );
  345. VOID
  346. WINAPI
  347. ReadClientStartupInfoCompleted(
  348. DWORD dwError,
  349. DWORD cbRead,
  350. LPOVERLAPPED lpO
  351. );
  352. PCHAR
  353. GetFormattedTime(
  354. BOOL bDate
  355. );
  356. HANDLE
  357. ForkChildProcess( // Creates a new process
  358. char *cmd, // Redirects its stdin,stdout
  359. PHANDLE in, // and stderr - returns the
  360. PHANDLE out // corresponding pipe ends.
  361. );
  362. BOOL
  363. FilterCommand( //Filters input from client
  364. REMOTE_CLIENT *cl, //for commands intended for REMOTE
  365. char *buff,
  366. int dread
  367. );
  368. BOOL
  369. WINAPI
  370. SrvCtrlHand(
  371. DWORD event
  372. );
  373. DWORD
  374. WINAPI
  375. SendStatus(
  376. LPVOID lpSendStatusParm
  377. );
  378. DWORD
  379. WINAPI
  380. ShowPopup(
  381. void *vpArg
  382. );
  383. VOID
  384. RemoveInpMark(
  385. char* Buff,
  386. DWORD Size
  387. );
  388. VOID
  389. CloseClient(
  390. REMOTE_CLIENT *Client
  391. );
  392. PSECURITY_DESCRIPTOR
  393. FormatSecurityDescriptor(
  394. CHAR * * DenyNames,
  395. DWORD DenyCount,
  396. CHAR * * Names,
  397. DWORD Count
  398. );
  399. BOOL
  400. FASTCALL
  401. HandleSessionError(
  402. PREMOTE_CLIENT pClient,
  403. DWORD dwError
  404. );
  405. VOID
  406. FASTCALL
  407. CleanupTempFiles(
  408. PSZ pszTempDir
  409. );
  410. VOID
  411. FASTCALL
  412. SetupSecurityDescriptors(
  413. VOID
  414. );
  415. VOID
  416. FASTCALL
  417. RuntimeLinkAPIs(
  418. VOID
  419. );
  420. VOID
  421. FASTCALL
  422. InitializeClientLists(
  423. VOID
  424. );
  425. VOID
  426. FASTCALL
  427. AddClientToHandshakingList(
  428. PREMOTE_CLIENT pClient
  429. );
  430. VOID
  431. FASTCALL
  432. MoveClientToNormalList(
  433. PREMOTE_CLIENT pClient
  434. );
  435. VOID
  436. FASTCALL
  437. MoveClientToClosingList(
  438. PREMOTE_CLIENT pClient
  439. );
  440. PREMOTE_CLIENT
  441. FASTCALL
  442. RemoveFirstClientFromClosingList(
  443. VOID
  444. );
  445. VOID
  446. InitAd(
  447. BOOL IsAdvertise
  448. );
  449. VOID
  450. ShutAd(
  451. BOOL IsAdvertise
  452. );
  453. VOID
  454. APIENTRY
  455. AdvertiseTimerFired(
  456. LPVOID pArg,
  457. DWORD dwTimerLo,
  458. DWORD dwTimerHi
  459. );
  460. VOID
  461. WINAPI
  462. WriteMailslotCompleted(
  463. DWORD dwError,
  464. DWORD cbWritten,
  465. LPOVERLAPPED lpO
  466. );
  467. VOID
  468. FASTCALL
  469. InitializeQueryServer(
  470. VOID
  471. );
  472. VOID
  473. FASTCALL
  474. QueryWaitCompleted(
  475. VOID
  476. );
  477. VOID
  478. FASTCALL
  479. StartServingQueryPipe(
  480. VOID
  481. );
  482. DWORD
  483. WINAPI
  484. QueryHandlerThread(
  485. LPVOID lpUnused
  486. );
  487. BOOL
  488. CALLBACK
  489. EnumWindowProc(
  490. HWND hWnd,
  491. LPARAM lParam
  492. );
  493. //
  494. // Declare pointers to runtime-linked functions
  495. //
  496. HANDLE
  497. (WINAPI *pfnCreateWaitableTimer)(
  498. LPSECURITY_ATTRIBUTES lpTimerAttributes,
  499. BOOL bManualReset,
  500. LPCSTR lpTimerName
  501. );
  502. BOOL
  503. (WINAPI *pfnSetWaitableTimer)(
  504. HANDLE hTimer,
  505. const LARGE_INTEGER *lpDueTime,
  506. LONG lPeriod,
  507. PTIMERAPCROUTINE pfnCompletionRoutine,
  508. LPVOID lpArgToCompletionRoutine,
  509. BOOL fResume
  510. );
  511. BOOL
  512. (WINAPI *pfnCancelWaitableTimer)(
  513. HANDLE hTimer
  514. );
  515. BOOL
  516. (WINAPI *pfnCancelIo)(
  517. HANDLE hFile
  518. );
  519. #define CANCELIO(hFile) (pfnCancelIo) ? ( pfnCancelIo(hFile) ) : 0;
  520. NET_API_STATUS
  521. (NET_API_FUNCTION *pfnNetWkstaGetInfo)(
  522. IN LPTSTR servername OPTIONAL,
  523. IN DWORD level,
  524. OUT LPBYTE *bufptr
  525. );
  526. NET_API_STATUS
  527. (NET_API_FUNCTION *pfnNetApiBufferFree)(
  528. IN LPVOID Buffer
  529. );