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.

431 lines
10 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1996
  5. //
  6. // File: npipe.c
  7. //
  8. // Contents:
  9. //
  10. // History: 12-09-98 HueiWang Created
  11. //
  12. // Note:
  13. //---------------------------------------------------------------------------
  14. #include "pch.cpp"
  15. #include <tchar.h>
  16. #include <process.h>
  17. #include "server.h"
  18. #include "lscommon.h"
  19. #include "globals.h"
  20. #include "debug.h"
  21. #define NAMEPIPE_BUFFER_SIZE 512
  22. #define NAMEPIPE_INSTANCE 2
  23. unsigned int WINAPI
  24. NamedPipeThread(
  25. void* ptr
  26. );
  27. //---------------------------------------------------------------------
  28. DWORD
  29. InitNamedPipeThread()
  30. /*++
  31. ++*/
  32. {
  33. HANDLE hThread = NULL;
  34. unsigned int dwThreadId;
  35. HANDLE hEvent = NULL;
  36. DWORD dwStatus = ERROR_SUCCESS;
  37. HANDLE waithandles[2];
  38. //
  39. // Create a event for namedpipe thread to signal it is ready.
  40. //
  41. hEvent = CreateEvent(
  42. NULL,
  43. FALSE,
  44. FALSE, // non-signal
  45. NULL
  46. );
  47. if(hEvent == NULL)
  48. {
  49. dwStatus = GetLastError();
  50. goto cleanup;
  51. }
  52. hThread = (HANDLE)_beginthreadex(
  53. NULL,
  54. 0,
  55. NamedPipeThread,
  56. hEvent,
  57. 0,
  58. &dwThreadId
  59. );
  60. if(hThread == NULL)
  61. {
  62. dwStatus = GetLastError();
  63. goto cleanup;
  64. }
  65. waithandles[0] = hEvent;
  66. waithandles[1] = hThread;
  67. //
  68. // Wait 30 second for thread to complet initialization
  69. //
  70. dwStatus = WaitForMultipleObjects(
  71. sizeof(waithandles)/sizeof(waithandles[0]),
  72. waithandles,
  73. FALSE,
  74. 30*1000
  75. );
  76. if(dwStatus == WAIT_OBJECT_0)
  77. {
  78. //
  79. // thread is ready
  80. //
  81. dwStatus = ERROR_SUCCESS;
  82. }
  83. else
  84. {
  85. if(dwStatus == (WAIT_OBJECT_0 + 1))
  86. {
  87. //
  88. // Thread terminate abnormally
  89. //
  90. GetExitCodeThread(
  91. hThread,
  92. &dwStatus
  93. );
  94. }
  95. else
  96. {
  97. dwStatus = TLS_E_SERVICE_STARTUP_CREATE_THREAD;
  98. }
  99. }
  100. cleanup:
  101. if(hEvent != NULL)
  102. {
  103. CloseHandle(hEvent);
  104. }
  105. if(hThread != NULL)
  106. {
  107. CloseHandle(hThread);
  108. }
  109. return dwStatus;
  110. }
  111. //------------------------------------------------------------------------
  112. typedef struct {
  113. OVERLAPPED ol;
  114. HANDLE hPipeInst;
  115. } PIPEINST, *LPPIPEINST;
  116. //------------------------------------------------------------------------
  117. BOOL
  118. ConnectToNewClient(
  119. HANDLE hPipe,
  120. LPOVERLAPPED lpo
  121. )
  122. /*++
  123. ++*/
  124. {
  125. BOOL bSuccess = FALSE;
  126. // Start an overlapped connection for this pipe instance.
  127. bSuccess = ConnectNamedPipe(hPipe, lpo);
  128. //
  129. // Overlapped ConnectNamedPipe should return zero.
  130. //
  131. if(bSuccess == TRUE)
  132. {
  133. return FALSE;
  134. }
  135. switch (GetLastError())
  136. {
  137. // The overlapped connection in progress.
  138. case ERROR_IO_PENDING:
  139. bSuccess = TRUE;
  140. break;
  141. // Client is already connected, so signal an event.
  142. case ERROR_PIPE_CONNECTED:
  143. bSuccess = TRUE;
  144. // If an error occurs during the connect operation...
  145. if(SetEvent(lpo->hEvent))
  146. break;
  147. default:
  148. bSuccess = FALSE;
  149. }
  150. return bSuccess;
  151. }
  152. //------------------------------------------------------------------------
  153. unsigned int WINAPI
  154. NamedPipeThread(
  155. void* ptr
  156. )
  157. /*++
  158. ++*/
  159. {
  160. DWORD dwStatus=ERROR_SUCCESS;
  161. DWORD dwIndex;
  162. HANDLE hReady = (HANDLE)ptr;
  163. TCHAR szPipeName[MAX_PATH+1];
  164. PIPEINST Pipe[NAMEPIPE_INSTANCE];
  165. HANDLE hOlEvent[NAMEPIPE_INSTANCE];
  166. DWORD cbMessage, cbRead, cbToRead, cMessages;
  167. BYTE pbMessage[NAMEPIPE_BUFFER_SIZE+1];
  168. HANDLE waitHandles[NAMEPIPE_INSTANCE+1];
  169. BOOL bResult=TRUE;
  170. //SECURITY_ATTRIBUTES SecurityAttributes;
  171. //SECURITY_DESCRIPTOR SecurityDescriptor;
  172. int i;
  173. //------------------------------------------------
  174. ZeroMemory(Pipe, sizeof(Pipe));
  175. ZeroMemory(hOlEvent, sizeof(hOlEvent));
  176. //
  177. // Create a inbound name pipe, server only listen.
  178. //
  179. wsprintf(
  180. szPipeName,
  181. _TEXT("\\\\.\\pipe\\%s"),
  182. _TEXT(SZSERVICENAME)
  183. );
  184. //
  185. // init values
  186. //
  187. for(i = 0; i < NAMEPIPE_INSTANCE; i++)
  188. {
  189. Pipe[i].hPipeInst = INVALID_HANDLE_VALUE;
  190. }
  191. //
  192. // Create namedpipe
  193. //
  194. for(i=0; i < NAMEPIPE_INSTANCE; i++)
  195. {
  196. DWORD dwOpenMode = PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED;
  197. hOlEvent[i] = CreateEvent(
  198. NULL,
  199. TRUE,
  200. TRUE,
  201. NULL
  202. );
  203. if(hOlEvent[i] == NULL)
  204. {
  205. dwStatus = GetLastError();
  206. goto cleanup;
  207. }
  208. if (i == 0)
  209. {
  210. dwOpenMode |= FILE_FLAG_FIRST_PIPE_INSTANCE;
  211. }
  212. Pipe[i].ol.hEvent = hOlEvent[i];
  213. Pipe[i].hPipeInst = CreateNamedPipe(
  214. szPipeName,
  215. dwOpenMode,
  216. PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
  217. NAMEPIPE_INSTANCE,
  218. 0,
  219. NAMEPIPE_BUFFER_SIZE,
  220. NMPWAIT_USE_DEFAULT_WAIT,
  221. NULL // &SecurityAttributes
  222. );
  223. if(Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)
  224. {
  225. dwStatus = GetLastError();
  226. goto cleanup;
  227. }
  228. //
  229. // Initiate connect
  230. //
  231. bResult = ConnectToNewClient(
  232. Pipe[i].hPipeInst,
  233. &(Pipe[i].ol)
  234. );
  235. if(bResult == FALSE)
  236. {
  237. dwStatus = GetLastError();
  238. goto cleanup;
  239. }
  240. }
  241. //
  242. // Signal we are ready
  243. //
  244. SetEvent(hReady);
  245. DBGPrintf(
  246. DBG_INFORMATION,
  247. DBG_FACILITY_INIT,
  248. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  249. _TEXT("NamedPipe : Ready...\n")
  250. );
  251. waitHandles[0] = GetServiceShutdownHandle();
  252. for(i=1; i <= NAMEPIPE_INSTANCE; i++)
  253. {
  254. waitHandles[i] = hOlEvent[i-1];
  255. }
  256. //
  257. // Forever loop
  258. //
  259. while(TRUE)
  260. {
  261. //
  262. // Wait for pipe or shutdown messages
  263. //
  264. dwStatus = WaitForMultipleObjects(
  265. sizeof(waitHandles)/sizeof(waitHandles[0]),
  266. waitHandles,
  267. FALSE,
  268. INFINITE
  269. );
  270. if(dwStatus == WAIT_FAILED)
  271. {
  272. SetLastError(dwStatus = TLS_E_INTERNAL);
  273. break;
  274. }
  275. if(dwStatus == WAIT_OBJECT_0)
  276. {
  277. //
  278. // shutdown
  279. //
  280. DBGPrintf(
  281. DBG_INFORMATION,
  282. DBG_FACILITY_INIT,
  283. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  284. _TEXT("NamedPipe : System Shutdown...\n")
  285. );
  286. dwStatus = ERROR_SUCCESS;
  287. break;
  288. }
  289. dwIndex = (dwStatus - 1) - WAIT_OBJECT_0;
  290. if(dwIndex > (NAMEPIPE_INSTANCE-1))
  291. {
  292. //
  293. // some internal error
  294. //
  295. SetLastError(dwStatus = TLS_E_INTERNAL);
  296. DBGPrintf(
  297. DBG_INFORMATION,
  298. DBG_FACILITY_INIT,
  299. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  300. _TEXT("NamedPipe : Internal Error...\n")
  301. );
  302. break;
  303. }
  304. //
  305. // Read everything and discard it.
  306. //
  307. bResult = GetOverlappedResult(
  308. Pipe[dwIndex].hPipeInst,
  309. &(Pipe[dwIndex].ol),
  310. &cbToRead, // can't count on this value
  311. TRUE
  312. );
  313. if(bResult == TRUE)
  314. {
  315. //
  316. // Junk messages...
  317. //
  318. bResult = ReadFile(
  319. Pipe[dwIndex].hPipeInst,
  320. pbMessage,
  321. sizeof(pbMessage),
  322. &cbRead,
  323. &(Pipe[dwIndex].ol)
  324. );
  325. if(bResult == TRUE && cbRead != 0)
  326. continue;
  327. dwStatus = GetLastError();
  328. if(dwStatus == ERROR_IO_PENDING)
  329. continue;
  330. }
  331. //
  332. // Any error, just disconnect named pipe
  333. //
  334. DisconnectNamedPipe(Pipe[dwIndex].hPipeInst);
  335. ConnectToNewClient(
  336. Pipe[dwIndex].hPipeInst,
  337. &(Pipe[dwIndex].ol)
  338. );
  339. }
  340. cleanup:
  341. for(i = 0; i < NAMEPIPE_INSTANCE; i++)
  342. {
  343. if(Pipe[i].hPipeInst != INVALID_HANDLE_VALUE)
  344. {
  345. CloseHandle(Pipe[i].hPipeInst);
  346. }
  347. if(hOlEvent[i] != NULL)
  348. {
  349. CloseHandle(hOlEvent[i]);
  350. }
  351. }
  352. _endthreadex(dwStatus);
  353. return dwStatus;
  354. }