home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / remote / server.h < prev    next >
C/C++ Source or Header  |  1997-10-12  |  13KB  |  657 lines

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