winhandl.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. * winhandl.c: Module to give Windows front ends the general
  3. * ability to deal with consoles, pipes, serial ports, or any other
  4. * type of data stream accessed through a Windows API HANDLE rather
  5. * than a WinSock SOCKET.
  6. *
  7. * We do this by spawning a subthread to continuously try to read
  8. * from the handle. Every time a read successfully returns some
  9. * data, the subthread sets an event object which is picked up by
  10. * the main thread, and the main thread then sets an event in
  11. * return to instruct the subthread to resume reading.
  12. *
  13. * Output works precisely the other way round, in a second
  14. * subthread. The output subthread should not be attempting to
  15. * write all the time, because it hasn't always got data _to_
  16. * write; so the output thread waits for an event object notifying
  17. * it to _attempt_ a write, and then it sets an event in return
  18. * when one completes.
  19. *
  20. * (It's terribly annoying having to spawn a subthread for each
  21. * direction of each handle. Technically it isn't necessary for
  22. * serial ports, since we could use overlapped I/O within the main
  23. * thread and wait directly on the event objects in the OVERLAPPED
  24. * structures. However, we can't use this trick for some types of
  25. * file handle at all - for some reason Windows restricts use of
  26. * OVERLAPPED to files which were opened with the overlapped flag -
  27. * and so we must use threads for those. This being the case, it's
  28. * simplest just to use threads for everything rather than trying
  29. * to keep track of multiple completely separate mechanisms.)
  30. */
  31. #include <assert.h>
  32. #include "putty.h"
  33. /* ----------------------------------------------------------------------
  34. * Generic definitions.
  35. */
  36. /*
  37. * Maximum amount of backlog we will allow to build up on an input
  38. * handle before we stop reading from it.
  39. */
  40. #define MAX_BACKLOG 32768
  41. struct handle_generic {
  42. /*
  43. * Initial fields common to both handle_input and handle_output
  44. * structures.
  45. *
  46. * The three HANDLEs are set up at initialisation time and are
  47. * thereafter read-only to both main thread and subthread.
  48. * `moribund' is only used by the main thread; `done' is
  49. * written by the main thread before signalling to the
  50. * subthread. `defunct' and `busy' are used only by the main
  51. * thread.
  52. */
  53. HANDLE h; /* the handle itself */
  54. HANDLE ev_to_main; /* event used to signal main thread */
  55. HANDLE ev_from_main; /* event used to signal back to us */
  56. int moribund; /* are we going to kill this soon? */
  57. int done; /* request subthread to terminate */
  58. int defunct; /* has the subthread already gone? */
  59. int busy; /* operation currently in progress? */
  60. void *privdata; /* for client to remember who they are */
  61. };
  62. /* ----------------------------------------------------------------------
  63. * Input threads.
  64. */
  65. /*
  66. * Data required by an input thread.
  67. */
  68. struct handle_input {
  69. /*
  70. * Copy of the handle_generic structure.
  71. */
  72. HANDLE h; /* the handle itself */
  73. HANDLE ev_to_main; /* event used to signal main thread */
  74. HANDLE ev_from_main; /* event used to signal back to us */
  75. int moribund; /* are we going to kill this soon? */
  76. int done; /* request subthread to terminate */
  77. int defunct; /* has the subthread already gone? */
  78. int busy; /* operation currently in progress? */
  79. void *privdata; /* for client to remember who they are */
  80. /*
  81. * Data set at initialisation and then read-only.
  82. */
  83. int flags;
  84. /*
  85. * Data set by the input thread before signalling ev_to_main,
  86. * and read by the main thread after receiving that signal.
  87. */
  88. char buffer[4096]; /* the data read from the handle */
  89. DWORD len; /* how much data that was */
  90. int readerr; /* lets us know about read errors */
  91. /*
  92. * Callback function called by this module when data arrives on
  93. * an input handle.
  94. */
  95. handle_inputfn_t gotdata;
  96. };
  97. /*
  98. * The actual thread procedure for an input thread.
  99. */
  100. static DWORD WINAPI handle_input_threadfunc(void *param)
  101. {
  102. struct handle_input *ctx = (struct handle_input *) param;
  103. OVERLAPPED ovl, *povl;
  104. HANDLE oev;
  105. int readret, readlen;
  106. if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
  107. povl = &ovl;
  108. oev = CreateEvent(NULL, TRUE, FALSE, NULL);
  109. } else {
  110. povl = NULL;
  111. }
  112. if (ctx->flags & HANDLE_FLAG_UNITBUFFER)
  113. readlen = 1;
  114. else
  115. readlen = sizeof(ctx->buffer);
  116. while (1) {
  117. if (povl) {
  118. memset(povl, 0, sizeof(OVERLAPPED));
  119. povl->hEvent = oev;
  120. }
  121. readret = ReadFile(ctx->h, ctx->buffer,readlen, &ctx->len, povl);
  122. if (!readret)
  123. ctx->readerr = GetLastError();
  124. else
  125. ctx->readerr = 0;
  126. if (povl && !readret && ctx->readerr == ERROR_IO_PENDING) {
  127. WaitForSingleObject(povl->hEvent, INFINITE);
  128. readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
  129. if (!readret)
  130. ctx->readerr = GetLastError();
  131. else
  132. ctx->readerr = 0;
  133. }
  134. if (!readret) {
  135. /*
  136. * Windows apparently sends ERROR_BROKEN_PIPE when a
  137. * pipe we're reading from is closed normally from the
  138. * writing end. This is ludicrous; if that situation
  139. * isn't a natural EOF, _nothing_ is. So if we get that
  140. * particular error, we pretend it's EOF.
  141. */
  142. if (ctx->readerr == ERROR_BROKEN_PIPE)
  143. ctx->readerr = 0;
  144. ctx->len = 0;
  145. }
  146. if (readret && ctx->len == 0 &&
  147. (ctx->flags & HANDLE_FLAG_IGNOREEOF))
  148. continue;
  149. SetEvent(ctx->ev_to_main);
  150. if (!ctx->len)
  151. break;
  152. WaitForSingleObject(ctx->ev_from_main, INFINITE);
  153. if (ctx->done)
  154. break; /* main thread told us to shut down */
  155. }
  156. if (povl)
  157. CloseHandle(oev);
  158. return 0;
  159. }
  160. /*
  161. * This is called after a succcessful read, or from the
  162. * `unthrottle' function. It decides whether or not to begin a new
  163. * read operation.
  164. */
  165. static void handle_throttle(struct handle_input *ctx, int backlog)
  166. {
  167. if (ctx->defunct)
  168. return;
  169. /*
  170. * If there's a read operation already in progress, do nothing:
  171. * when that completes, we'll come back here and be in a
  172. * position to make a better decision.
  173. */
  174. if (ctx->busy)
  175. return;
  176. /*
  177. * Otherwise, we must decide whether to start a new read based
  178. * on the size of the backlog.
  179. */
  180. if (backlog < MAX_BACKLOG) {
  181. SetEvent(ctx->ev_from_main);
  182. ctx->busy = TRUE;
  183. }
  184. }
  185. /* ----------------------------------------------------------------------
  186. * Output threads.
  187. */
  188. /*
  189. * Data required by an output thread.
  190. */
  191. struct handle_output {
  192. /*
  193. * Copy of the handle_generic structure.
  194. */
  195. HANDLE h; /* the handle itself */
  196. HANDLE ev_to_main; /* event used to signal main thread */
  197. HANDLE ev_from_main; /* event used to signal back to us */
  198. int moribund; /* are we going to kill this soon? */
  199. int done; /* request subthread to terminate */
  200. int defunct; /* has the subthread already gone? */
  201. int busy; /* operation currently in progress? */
  202. void *privdata; /* for client to remember who they are */
  203. /*
  204. * Data set at initialisation and then read-only.
  205. */
  206. int flags;
  207. /*
  208. * Data set by the main thread before signalling ev_from_main,
  209. * and read by the input thread after receiving that signal.
  210. */
  211. char *buffer; /* the data to write */
  212. DWORD len; /* how much data there is */
  213. /*
  214. * Data set by the input thread before signalling ev_to_main,
  215. * and read by the main thread after receiving that signal.
  216. */
  217. DWORD lenwritten; /* how much data we actually wrote */
  218. int writeerr; /* return value from WriteFile */
  219. /*
  220. * Data only ever read or written by the main thread.
  221. */
  222. bufchain queued_data; /* data still waiting to be written */
  223. enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
  224. /*
  225. * Callback function called when the backlog in the bufchain
  226. * drops.
  227. */
  228. handle_outputfn_t sentdata;
  229. };
  230. static DWORD WINAPI handle_output_threadfunc(void *param)
  231. {
  232. struct handle_output *ctx = (struct handle_output *) param;
  233. OVERLAPPED ovl, *povl;
  234. HANDLE oev;
  235. int writeret;
  236. if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
  237. povl = &ovl;
  238. oev = CreateEvent(NULL, TRUE, FALSE, NULL);
  239. } else {
  240. povl = NULL;
  241. }
  242. while (1) {
  243. WaitForSingleObject(ctx->ev_from_main, INFINITE);
  244. if (ctx->done) {
  245. SetEvent(ctx->ev_to_main);
  246. break;
  247. }
  248. if (povl) {
  249. memset(povl, 0, sizeof(OVERLAPPED));
  250. povl->hEvent = oev;
  251. }
  252. writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
  253. &ctx->lenwritten, povl);
  254. if (!writeret)
  255. ctx->writeerr = GetLastError();
  256. else
  257. ctx->writeerr = 0;
  258. if (povl && !writeret && GetLastError() == ERROR_IO_PENDING) {
  259. writeret = GetOverlappedResult(ctx->h, povl,
  260. &ctx->lenwritten, TRUE);
  261. if (!writeret)
  262. ctx->writeerr = GetLastError();
  263. else
  264. ctx->writeerr = 0;
  265. }
  266. SetEvent(ctx->ev_to_main);
  267. if (!writeret)
  268. break;
  269. }
  270. if (povl)
  271. CloseHandle(oev);
  272. return 0;
  273. }
  274. static void handle_try_output(struct handle_output *ctx)
  275. {
  276. void *senddata;
  277. int sendlen;
  278. if (!ctx->busy && bufchain_size(&ctx->queued_data)) {
  279. bufchain_prefix(&ctx->queued_data, &senddata, &sendlen);
  280. ctx->buffer = senddata;
  281. ctx->len = sendlen;
  282. SetEvent(ctx->ev_from_main);
  283. ctx->busy = TRUE;
  284. } else if (!ctx->busy && bufchain_size(&ctx->queued_data) == 0 &&
  285. ctx->outgoingeof == EOF_PENDING) {
  286. CloseHandle(ctx->h);
  287. ctx->h = INVALID_HANDLE_VALUE;
  288. ctx->outgoingeof = EOF_SENT;
  289. }
  290. }
  291. /* ----------------------------------------------------------------------
  292. * Unified code handling both input and output threads.
  293. */
  294. struct handle {
  295. int output;
  296. union {
  297. struct handle_generic g;
  298. struct handle_input i;
  299. struct handle_output o;
  300. } u;
  301. };
  302. static tree234 *handles_by_evtomain;
  303. static int handle_cmp_evtomain(void *av, void *bv)
  304. {
  305. struct handle *a = (struct handle *)av;
  306. struct handle *b = (struct handle *)bv;
  307. if ((unsigned)a->u.g.ev_to_main < (unsigned)b->u.g.ev_to_main)
  308. return -1;
  309. else if ((unsigned)a->u.g.ev_to_main > (unsigned)b->u.g.ev_to_main)
  310. return +1;
  311. else
  312. return 0;
  313. }
  314. static int handle_find_evtomain(void *av, void *bv)
  315. {
  316. HANDLE *a = (HANDLE *)av;
  317. struct handle *b = (struct handle *)bv;
  318. if ((unsigned)*a < (unsigned)b->u.g.ev_to_main)
  319. return -1;
  320. else if ((unsigned)*a > (unsigned)b->u.g.ev_to_main)
  321. return +1;
  322. else
  323. return 0;
  324. }
  325. struct handle *handle_input_new(HANDLE handle, handle_inputfn_t gotdata,
  326. void *privdata, int flags)
  327. {
  328. struct handle *h = snew(struct handle);
  329. DWORD in_threadid; /* required for Win9x */
  330. h->output = FALSE;
  331. h->u.i.h = handle;
  332. h->u.i.ev_to_main = CreateEvent(NULL, FALSE, FALSE, NULL);
  333. h->u.i.ev_from_main = CreateEvent(NULL, FALSE, FALSE, NULL);
  334. h->u.i.gotdata = gotdata;
  335. h->u.i.defunct = FALSE;
  336. h->u.i.moribund = FALSE;
  337. h->u.i.done = FALSE;
  338. h->u.i.privdata = privdata;
  339. h->u.i.flags = flags;
  340. if (!handles_by_evtomain)
  341. handles_by_evtomain = newtree234(handle_cmp_evtomain);
  342. add234(handles_by_evtomain, h);
  343. CreateThread(NULL, 0, handle_input_threadfunc,
  344. &h->u.i, 0, &in_threadid);
  345. h->u.i.busy = TRUE;
  346. return h;
  347. }
  348. struct handle *handle_output_new(HANDLE handle, handle_outputfn_t sentdata,
  349. void *privdata, int flags)
  350. {
  351. struct handle *h = snew(struct handle);
  352. DWORD out_threadid; /* required for Win9x */
  353. h->output = TRUE;
  354. h->u.o.h = handle;
  355. h->u.o.ev_to_main = CreateEvent(NULL, FALSE, FALSE, NULL);
  356. h->u.o.ev_from_main = CreateEvent(NULL, FALSE, FALSE, NULL);
  357. h->u.o.busy = FALSE;
  358. h->u.o.defunct = FALSE;
  359. h->u.o.moribund = FALSE;
  360. h->u.o.done = FALSE;
  361. h->u.o.privdata = privdata;
  362. bufchain_init(&h->u.o.queued_data);
  363. h->u.o.outgoingeof = EOF_NO;
  364. h->u.o.sentdata = sentdata;
  365. h->u.o.flags = flags;
  366. if (!handles_by_evtomain)
  367. handles_by_evtomain = newtree234(handle_cmp_evtomain);
  368. add234(handles_by_evtomain, h);
  369. CreateThread(NULL, 0, handle_output_threadfunc,
  370. &h->u.o, 0, &out_threadid);
  371. return h;
  372. }
  373. int handle_write(struct handle *h, const void *data, int len)
  374. {
  375. assert(h->output);
  376. assert(h->u.o.outgoingeof == EOF_NO);
  377. bufchain_add(&h->u.o.queued_data, data, len);
  378. handle_try_output(&h->u.o);
  379. return bufchain_size(&h->u.o.queued_data);
  380. }
  381. void handle_write_eof(struct handle *h)
  382. {
  383. /*
  384. * This function is called when we want to proactively send an
  385. * end-of-file notification on the handle. We can only do this by
  386. * actually closing the handle - so never call this on a
  387. * bidirectional handle if we're still interested in its incoming
  388. * direction!
  389. */
  390. assert(h->output);
  391. if (!h->u.o.outgoingeof == EOF_NO) {
  392. h->u.o.outgoingeof = EOF_PENDING;
  393. handle_try_output(&h->u.o);
  394. }
  395. }
  396. HANDLE *handle_get_events(int *nevents)
  397. {
  398. HANDLE *ret;
  399. struct handle *h;
  400. int i, n, size;
  401. /*
  402. * Go through our tree counting the handle objects currently
  403. * engaged in useful activity.
  404. */
  405. ret = NULL;
  406. n = size = 0;
  407. if (handles_by_evtomain) {
  408. for (i = 0; (h = index234(handles_by_evtomain, i)) != NULL; i++) {
  409. if (h->u.g.busy) {
  410. if (n >= size) {
  411. size += 32;
  412. ret = sresize(ret, size, HANDLE);
  413. }
  414. ret[n++] = h->u.g.ev_to_main;
  415. }
  416. }
  417. }
  418. *nevents = n;
  419. return ret;
  420. }
  421. static void handle_destroy(struct handle *h)
  422. {
  423. if (h->output)
  424. bufchain_clear(&h->u.o.queued_data);
  425. CloseHandle(h->u.g.ev_from_main);
  426. CloseHandle(h->u.g.ev_to_main);
  427. del234(handles_by_evtomain, h);
  428. sfree(h);
  429. }
  430. void handle_free(struct handle *h)
  431. {
  432. /*
  433. * If the handle is currently busy, we cannot immediately free
  434. * it. Instead we must wait until it's finished its current
  435. * operation, because otherwise the subthread will write to
  436. * invalid memory after we free its context from under it.
  437. */
  438. assert(h && !h->u.g.moribund);
  439. if (h->u.g.busy) {
  440. /*
  441. * Just set the moribund flag, which will be noticed next
  442. * time an operation completes.
  443. */
  444. h->u.g.moribund = TRUE;
  445. } else if (h->u.g.defunct) {
  446. /*
  447. * There isn't even a subthread; we can go straight to
  448. * handle_destroy.
  449. */
  450. handle_destroy(h);
  451. } else {
  452. /*
  453. * The subthread is alive but not busy, so we now signal it
  454. * to die. Set the moribund flag to indicate that it will
  455. * want destroying after that.
  456. */
  457. h->u.g.moribund = TRUE;
  458. h->u.g.done = TRUE;
  459. h->u.g.busy = TRUE;
  460. SetEvent(h->u.g.ev_from_main);
  461. }
  462. }
  463. #ifdef MPEXT
  464. int handle_got_event(HANDLE event)
  465. #else
  466. void handle_got_event(HANDLE event)
  467. #endif
  468. {
  469. struct handle *h;
  470. assert(handles_by_evtomain);
  471. h = find234(handles_by_evtomain, &event, handle_find_evtomain);
  472. if (!h) {
  473. /*
  474. * This isn't an error condition. If two or more event
  475. * objects were signalled during the same select operation,
  476. * and processing of the first caused the second handle to
  477. * be closed, then it will sometimes happen that we receive
  478. * an event notification here for a handle which is already
  479. * deceased. In that situation we simply do nothing.
  480. */
  481. #ifdef MPEXT
  482. return 0;
  483. #else
  484. return;
  485. #endif
  486. }
  487. if (h->u.g.moribund) {
  488. /*
  489. * A moribund handle is already treated as dead from the
  490. * external user's point of view, so do nothing with the
  491. * actual event. Just signal the thread to die if
  492. * necessary, or destroy the handle if not.
  493. */
  494. if (h->u.g.done) {
  495. handle_destroy(h);
  496. } else {
  497. h->u.g.done = TRUE;
  498. h->u.g.busy = TRUE;
  499. SetEvent(h->u.g.ev_from_main);
  500. }
  501. #ifdef MPEXT
  502. return 0;
  503. #else
  504. return;
  505. #endif
  506. }
  507. if (!h->output) {
  508. int backlog;
  509. h->u.i.busy = FALSE;
  510. /*
  511. * A signal on an input handle means data has arrived.
  512. */
  513. if (h->u.i.len == 0) {
  514. /*
  515. * EOF, or (nearly equivalently) read error.
  516. */
  517. h->u.i.gotdata(h, NULL, -h->u.i.readerr);
  518. h->u.i.defunct = TRUE;
  519. } else {
  520. backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len);
  521. handle_throttle(&h->u.i, backlog);
  522. }
  523. #ifdef MPEXT
  524. return 1;
  525. #endif
  526. } else {
  527. h->u.o.busy = FALSE;
  528. /*
  529. * A signal on an output handle means we have completed a
  530. * write. Call the callback to indicate that the output
  531. * buffer size has decreased, or to indicate an error.
  532. */
  533. if (h->u.o.writeerr) {
  534. /*
  535. * Write error. Send a negative value to the callback,
  536. * and mark the thread as defunct (because the output
  537. * thread is terminating by now).
  538. */
  539. h->u.o.sentdata(h, -h->u.o.writeerr);
  540. h->u.o.defunct = TRUE;
  541. } else {
  542. bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten);
  543. h->u.o.sentdata(h, bufchain_size(&h->u.o.queued_data));
  544. handle_try_output(&h->u.o);
  545. }
  546. #ifdef MPEXT
  547. return 0;
  548. #endif
  549. }
  550. }
  551. void handle_unthrottle(struct handle *h, int backlog)
  552. {
  553. assert(!h->output);
  554. handle_throttle(&h->u.i, backlog);
  555. }
  556. int handle_backlog(struct handle *h)
  557. {
  558. assert(h->output);
  559. return bufchain_size(&h->u.o.queued_data);
  560. }
  561. void *handle_get_privdata(struct handle *h)
  562. {
  563. return h->u.g.privdata;
  564. }