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.

424 lines
9.7 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. hOlEvent[i] = CreateEvent(
  197. NULL,
  198. TRUE,
  199. TRUE,
  200. NULL
  201. );
  202. if(hOlEvent[i] == NULL)
  203. {
  204. dwStatus = GetLastError();
  205. goto cleanup;
  206. }
  207. Pipe[i].ol.hEvent = hOlEvent[i];
  208. Pipe[i].hPipeInst = CreateNamedPipe(
  209. szPipeName,
  210. PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
  211. PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
  212. NAMEPIPE_INSTANCE,
  213. 0,
  214. NAMEPIPE_BUFFER_SIZE,
  215. NMPWAIT_USE_DEFAULT_WAIT,
  216. NULL // &SecurityAttributes
  217. );
  218. if(Pipe[i].hPipeInst == INVALID_HANDLE_VALUE)
  219. {
  220. dwStatus = GetLastError();
  221. goto cleanup;
  222. }
  223. //
  224. // Initiate connect
  225. //
  226. bResult = ConnectToNewClient(
  227. Pipe[i].hPipeInst,
  228. &(Pipe[i].ol)
  229. );
  230. if(bResult == FALSE)
  231. {
  232. dwStatus = GetLastError();
  233. goto cleanup;
  234. }
  235. }
  236. //
  237. // Signal we are ready
  238. //
  239. SetEvent(hReady);
  240. DBGPrintf(
  241. DBG_INFORMATION,
  242. DBG_FACILITY_INIT,
  243. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  244. _TEXT("NamedPipe : Ready...\n")
  245. );
  246. waitHandles[0] = GetServiceShutdownHandle();
  247. for(i=1; i <= NAMEPIPE_INSTANCE; i++)
  248. {
  249. waitHandles[i] = hOlEvent[i-1];
  250. }
  251. //
  252. // Forever loop
  253. //
  254. while(TRUE)
  255. {
  256. //
  257. // Wait for pipe or shutdown messages
  258. //
  259. dwStatus = WaitForMultipleObjects(
  260. sizeof(waitHandles)/sizeof(waitHandles[0]),
  261. waitHandles,
  262. FALSE,
  263. INFINITE
  264. );
  265. if(dwStatus == WAIT_FAILED)
  266. {
  267. SetLastError(dwStatus = TLS_E_INTERNAL);
  268. break;
  269. }
  270. if(dwStatus == WAIT_OBJECT_0)
  271. {
  272. //
  273. // shutdown
  274. //
  275. DBGPrintf(
  276. DBG_INFORMATION,
  277. DBG_FACILITY_INIT,
  278. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  279. _TEXT("NamedPipe : System Shutdown...\n")
  280. );
  281. dwStatus = ERROR_SUCCESS;
  282. break;
  283. }
  284. dwIndex = (dwStatus - 1) - WAIT_OBJECT_0;
  285. if(dwIndex > (NAMEPIPE_INSTANCE-1))
  286. {
  287. //
  288. // some internal error
  289. //
  290. SetLastError(dwStatus = TLS_E_INTERNAL);
  291. DBGPrintf(
  292. DBG_INFORMATION,
  293. DBG_FACILITY_INIT,
  294. DBGLEVEL_FUNCTION_DETAILSIMPLE,
  295. _TEXT("NamedPipe : Internal Error...\n")
  296. );
  297. break;
  298. }
  299. //
  300. // Read everything and discard it.
  301. //
  302. bResult = GetOverlappedResult(
  303. Pipe[dwIndex].hPipeInst,
  304. &(Pipe[dwIndex].ol),
  305. &cbToRead, // can't count on this value
  306. TRUE
  307. );
  308. if(bResult == TRUE)
  309. {
  310. //
  311. // Junk messages...
  312. //
  313. bResult = ReadFile(
  314. Pipe[dwIndex].hPipeInst,
  315. pbMessage,
  316. sizeof(pbMessage),
  317. &cbRead,
  318. &(Pipe[dwIndex].ol)
  319. );
  320. if(bResult == TRUE && cbRead != 0)
  321. continue;
  322. dwStatus = GetLastError();
  323. if(dwStatus == ERROR_IO_PENDING)
  324. continue;
  325. }
  326. //
  327. // Any error, just disconnect named pipe
  328. //
  329. DisconnectNamedPipe(Pipe[dwIndex].hPipeInst);
  330. ConnectToNewClient(
  331. Pipe[dwIndex].hPipeInst,
  332. &(Pipe[dwIndex].ol)
  333. );
  334. }
  335. cleanup:
  336. for(i = 0; i < NAMEPIPE_INSTANCE; i++)
  337. {
  338. if(Pipe[i].hPipeInst != INVALID_HANDLE_VALUE)
  339. {
  340. CloseHandle(Pipe[i].hPipeInst);
  341. }
  342. if(hOlEvent[i] != NULL)
  343. {
  344. CloseHandle(hOlEvent[i]);
  345. }
  346. }
  347. _endthreadex(dwStatus);
  348. return dwStatus;
  349. }