lws-plat-win.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
  2. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  3. #endif
  4. #include "core/private.h"
  5. void lws_plat_apply_FD_CLOEXEC(int n)
  6. {
  7. }
  8. int
  9. lws_plat_socket_offset(void)
  10. {
  11. return 0;
  12. }
  13. int
  14. lws_plat_pipe_create(struct lws *wsi)
  15. {
  16. return 1;
  17. }
  18. int
  19. lws_plat_pipe_signal(struct lws *wsi)
  20. {
  21. struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi];
  22. WSASetEvent(pt->events[0]); /* trigger the cancel event */
  23. return 0;
  24. }
  25. void
  26. lws_plat_pipe_close(struct lws *wsi)
  27. {
  28. }
  29. unsigned long long
  30. time_in_microseconds()
  31. {
  32. #ifndef DELTA_EPOCH_IN_MICROSECS
  33. #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
  34. #endif
  35. FILETIME filetime;
  36. ULARGE_INTEGER datetime;
  37. #ifdef _WIN32_WCE
  38. GetCurrentFT(&filetime);
  39. #else
  40. GetSystemTimeAsFileTime(&filetime);
  41. #endif
  42. /*
  43. * As per Windows documentation for FILETIME, copy the resulting
  44. * FILETIME structure to a ULARGE_INTEGER structure using memcpy
  45. * (using memcpy instead of direct assignment can prevent alignment
  46. * faults on 64-bit Windows).
  47. */
  48. memcpy(&datetime, &filetime, sizeof(datetime));
  49. /* Windows file times are in 100s of nanoseconds. */
  50. return (datetime.QuadPart / 10) - DELTA_EPOCH_IN_MICROSECS;
  51. }
  52. #ifdef _WIN32_WCE
  53. time_t time(time_t *t)
  54. {
  55. time_t ret = time_in_microseconds() / 1000000;
  56. if(t != NULL)
  57. *t = ret;
  58. return ret;
  59. }
  60. #endif
  61. /* file descriptor hash management */
  62. struct lws *
  63. wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd)
  64. {
  65. int h = LWS_FD_HASH(fd);
  66. int n = 0;
  67. for (n = 0; n < context->fd_hashtable[h].length; n++)
  68. if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd)
  69. return context->fd_hashtable[h].wsi[n];
  70. return NULL;
  71. }
  72. int
  73. insert_wsi(struct lws_context *context, struct lws *wsi)
  74. {
  75. int h = LWS_FD_HASH(wsi->desc.sockfd);
  76. if (context->fd_hashtable[h].length == (getdtablesize() - 1)) {
  77. lwsl_err("hash table overflow\n");
  78. return 1;
  79. }
  80. context->fd_hashtable[h].wsi[context->fd_hashtable[h].length++] = wsi;
  81. return 0;
  82. }
  83. int
  84. delete_from_fd(struct lws_context *context, lws_sockfd_type fd)
  85. {
  86. int h = LWS_FD_HASH(fd);
  87. int n = 0;
  88. for (n = 0; n < context->fd_hashtable[h].length; n++)
  89. if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd) {
  90. while (n < context->fd_hashtable[h].length) {
  91. context->fd_hashtable[h].wsi[n] =
  92. context->fd_hashtable[h].wsi[n + 1];
  93. n++;
  94. }
  95. context->fd_hashtable[h].length--;
  96. return 0;
  97. }
  98. lwsl_err("Failed to find fd %d requested for "
  99. "delete in hashtable\n", fd);
  100. return 1;
  101. }
  102. LWS_VISIBLE int
  103. lws_get_random(struct lws_context *context, void *buf, int len)
  104. {
  105. int n;
  106. char *p = (char *)buf;
  107. for (n = 0; n < len; n++)
  108. p[n] = (unsigned char)rand();
  109. return n;
  110. }
  111. LWS_VISIBLE int
  112. lws_send_pipe_choked(struct lws *wsi)
  113. { struct lws *wsi_eff = wsi;
  114. #if defined(LWS_WITH_HTTP2)
  115. wsi_eff = lws_get_network_wsi(wsi);
  116. #endif
  117. /* the fact we checked implies we avoided back-to-back writes */
  118. wsi_eff->could_have_pending = 0;
  119. /* treat the fact we got a truncated send pending as if we're choked */
  120. if (wsi_eff->trunc_len)
  121. return 1;
  122. return (int)wsi_eff->sock_send_blocking;
  123. }
  124. LWS_VISIBLE int
  125. lws_poll_listen_fd(struct lws_pollfd *fd)
  126. {
  127. fd_set readfds;
  128. struct timeval tv = { 0, 0 };
  129. assert((fd->events & LWS_POLLIN) == LWS_POLLIN);
  130. FD_ZERO(&readfds);
  131. FD_SET(fd->fd, &readfds);
  132. return select(((int)fd->fd) + 1, &readfds, NULL, NULL, &tv);
  133. }
  134. LWS_VISIBLE void
  135. lwsl_emit_syslog(int level, const char *line)
  136. {
  137. lwsl_emit_stderr(level, line);
  138. }
  139. LWS_VISIBLE LWS_EXTERN int
  140. _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi)
  141. {
  142. struct lws_context_per_thread *pt;
  143. WSANETWORKEVENTS networkevents;
  144. struct lws_pollfd *pfd;
  145. struct lws *wsi;
  146. unsigned int i;
  147. DWORD ev;
  148. int n, m;
  149. /* stay dead once we are dead */
  150. if (context == NULL || !context->vhost_list)
  151. return 1;
  152. pt = &context->pt[tsi];
  153. if (!context->service_tid_detected) {
  154. struct lws _lws;
  155. memset(&_lws, 0, sizeof(_lws));
  156. _lws.context = context;
  157. context->service_tid_detected = context->vhost_list->
  158. protocols[0].callback(&_lws, LWS_CALLBACK_GET_THREAD_ID,
  159. NULL, NULL, 0);
  160. context->service_tid = context->service_tid_detected;
  161. context->service_tid_detected = 1;
  162. }
  163. if (timeout_ms < 0) {
  164. if (lws_service_flag_pending(context, tsi)) {
  165. /* any socket with events to service? */
  166. for (n = 0; n < (int)pt->fds_count; n++) {
  167. if (!pt->fds[n].revents)
  168. continue;
  169. m = lws_service_fd_tsi(context, &pt->fds[n], tsi);
  170. if (m < 0)
  171. return -1;
  172. /* if something closed, retry this slot */
  173. if (m)
  174. n--;
  175. }
  176. }
  177. return 0;
  178. }
  179. if (context->event_loop_ops->run_pt)
  180. context->event_loop_ops->run_pt(context, tsi);
  181. for (i = 0; i < pt->fds_count; ++i) {
  182. pfd = &pt->fds[i];
  183. if (!(pfd->events & LWS_POLLOUT))
  184. continue;
  185. wsi = wsi_from_fd(context, pfd->fd);
  186. if (!wsi || wsi->listener)
  187. continue;
  188. if (wsi->sock_send_blocking)
  189. continue;
  190. pfd->revents = LWS_POLLOUT;
  191. n = lws_service_fd(context, pfd);
  192. if (n < 0)
  193. return -1;
  194. /* Force WSAWaitForMultipleEvents() to check events and then return immediately. */
  195. timeout_ms = 0;
  196. /* if something closed, retry this slot */
  197. if (n)
  198. i--;
  199. }
  200. /*
  201. * is there anybody with pending stuff that needs service forcing?
  202. */
  203. if (!lws_service_adjust_timeout(context, 1, tsi)) {
  204. /* -1 timeout means just do forced service */
  205. _lws_plat_service_tsi(context, -1, pt->tid);
  206. /* still somebody left who wants forced service? */
  207. if (!lws_service_adjust_timeout(context, 1, pt->tid))
  208. /* yes... come back again quickly */
  209. timeout_ms = 0;
  210. }
  211. if (timeout_ms) {
  212. lws_usec_t t;
  213. lws_pt_lock(pt, __func__);
  214. /* don't stay in poll wait longer than next hr timeout */
  215. t = __lws_hrtimer_service(pt);
  216. if ((lws_usec_t)timeout_ms * 1000 > t)
  217. timeout_ms = (int)(t / 1000);
  218. lws_pt_unlock(pt);
  219. }
  220. ev = WSAWaitForMultipleEvents(1, pt->events, FALSE, timeout_ms, FALSE);
  221. if (ev == WSA_WAIT_EVENT_0) {
  222. unsigned int eIdx, err;
  223. WSAResetEvent(pt->events[0]);
  224. if (pt->context->tls_ops &&
  225. pt->context->tls_ops->fake_POLLIN_for_buffered)
  226. pt->context->tls_ops->fake_POLLIN_for_buffered(pt);
  227. for (eIdx = 0; eIdx < pt->fds_count; ++eIdx) {
  228. if (WSAEnumNetworkEvents(pt->fds[eIdx].fd, 0,
  229. &networkevents) == SOCKET_ERROR) {
  230. lwsl_err("WSAEnumNetworkEvents() failed "
  231. "with error %d\n", LWS_ERRNO);
  232. return -1;
  233. }
  234. pfd = &pt->fds[eIdx];
  235. pfd->revents = (short)networkevents.lNetworkEvents;
  236. err = networkevents.iErrorCode[FD_CONNECT_BIT];
  237. if ((networkevents.lNetworkEvents & FD_CONNECT) &&
  238. err && err != LWS_EALREADY &&
  239. err != LWS_EINPROGRESS && err != LWS_EWOULDBLOCK &&
  240. err != WSAEINVAL) {
  241. lwsl_debug("Unable to connect errno=%d\n", err);
  242. pfd->revents |= LWS_POLLHUP;
  243. }
  244. if (pfd->revents & LWS_POLLOUT) {
  245. wsi = wsi_from_fd(context, pfd->fd);
  246. if (wsi)
  247. wsi->sock_send_blocking = 0;
  248. }
  249. /* if something closed, retry this slot */
  250. if (pfd->revents & LWS_POLLHUP)
  251. --eIdx;
  252. if (pfd->revents) {
  253. recv(pfd->fd, NULL, 0, 0);
  254. lws_service_fd_tsi(context, pfd, tsi);
  255. }
  256. }
  257. }
  258. context->service_tid = 0;
  259. if (ev == WSA_WAIT_TIMEOUT)
  260. lws_service_fd(context, NULL);
  261. return 0;
  262. }
  263. LWS_VISIBLE int
  264. lws_plat_service(struct lws_context *context, int timeout_ms)
  265. {
  266. return _lws_plat_service_tsi(context, timeout_ms, 0);
  267. }
  268. LWS_VISIBLE int
  269. lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd)
  270. {
  271. int optval = 1;
  272. int optlen = sizeof(optval);
  273. u_long optl = 1;
  274. DWORD dwBytesRet;
  275. struct tcp_keepalive alive;
  276. int protonbr;
  277. #ifndef _WIN32_WCE
  278. struct protoent *tcp_proto;
  279. #endif
  280. if (vhost->ka_time) {
  281. /* enable keepalive on this socket */
  282. optval = 1;
  283. if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
  284. (const char *)&optval, optlen) < 0)
  285. return 1;
  286. alive.onoff = TRUE;
  287. alive.keepalivetime = vhost->ka_time;
  288. alive.keepaliveinterval = vhost->ka_interval;
  289. if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
  290. NULL, 0, &dwBytesRet, NULL, NULL))
  291. return 1;
  292. }
  293. /* Disable Nagle */
  294. optval = 1;
  295. #ifndef _WIN32_WCE
  296. tcp_proto = getprotobyname("TCP");
  297. if (!tcp_proto) {
  298. lwsl_err("getprotobyname() failed with error %d\n", LWS_ERRNO);
  299. return 1;
  300. }
  301. protonbr = tcp_proto->p_proto;
  302. #else
  303. protonbr = 6;
  304. #endif
  305. setsockopt(fd, protonbr, TCP_NODELAY, (const char *)&optval, optlen);
  306. /* We are nonblocking... */
  307. ioctlsocket(fd, FIONBIO, &optl);
  308. return 0;
  309. }
  310. LWS_VISIBLE void
  311. lws_plat_drop_app_privileges(const struct lws_context_creation_info *info)
  312. {
  313. }
  314. LWS_VISIBLE int
  315. lws_plat_context_early_init(void)
  316. {
  317. WORD wVersionRequested;
  318. WSADATA wsaData;
  319. int err;
  320. /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */
  321. wVersionRequested = MAKEWORD(2, 2);
  322. err = WSAStartup(wVersionRequested, &wsaData);
  323. if (!err)
  324. return 0;
  325. /*
  326. * Tell the user that we could not find a usable
  327. * Winsock DLL
  328. */
  329. lwsl_err("WSAStartup failed with error: %d\n", err);
  330. return 1;
  331. }
  332. LWS_VISIBLE void
  333. lws_plat_context_early_destroy(struct lws_context *context)
  334. {
  335. struct lws_context_per_thread *pt = &context->pt[0];
  336. int n = context->count_threads;
  337. while (n--) {
  338. if (pt->events) {
  339. WSACloseEvent(pt->events[0]);
  340. lws_free(pt->events);
  341. }
  342. pt++;
  343. }
  344. }
  345. LWS_VISIBLE void
  346. lws_plat_context_late_destroy(struct lws_context *context)
  347. {
  348. int n;
  349. for (n = 0; n < FD_HASHTABLE_MODULUS; n++) {
  350. if (context->fd_hashtable[n].wsi)
  351. lws_free(context->fd_hashtable[n].wsi);
  352. }
  353. WSACleanup();
  354. }
  355. LWS_VISIBLE LWS_EXTERN int
  356. lws_interface_to_sa(int ipv6,
  357. const char *ifname, struct sockaddr_in *addr, size_t addrlen)
  358. {
  359. #ifdef LWS_WITH_IPV6
  360. struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
  361. if (ipv6) {
  362. if (lws_plat_inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1) {
  363. return LWS_ITOSA_USABLE;
  364. }
  365. }
  366. #endif
  367. long long address = inet_addr(ifname);
  368. if (address == INADDR_NONE) {
  369. struct hostent *entry = gethostbyname(ifname);
  370. if (entry)
  371. address = ((struct in_addr *)entry->h_addr_list[0])->s_addr;
  372. }
  373. if (address == INADDR_NONE)
  374. return LWS_ITOSA_NOT_EXIST;
  375. addr->sin_addr.s_addr = (unsigned long)(lws_intptr_t)address;
  376. return LWS_ITOSA_USABLE;
  377. }
  378. LWS_VISIBLE void
  379. lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi)
  380. {
  381. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  382. pt->fds[pt->fds_count++].revents = 0;
  383. pt->events[pt->fds_count] = pt->events[0];
  384. WSAEventSelect(wsi->desc.sockfd, pt->events[0],
  385. LWS_POLLIN | LWS_POLLHUP | FD_CONNECT);
  386. }
  387. LWS_VISIBLE void
  388. lws_plat_delete_socket_from_fds(struct lws_context *context,
  389. struct lws *wsi, int m)
  390. {
  391. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  392. pt->events[m + 1] = pt->events[pt->fds_count--];
  393. }
  394. LWS_VISIBLE void
  395. lws_plat_service_periodic(struct lws_context *context)
  396. {
  397. }
  398. LWS_VISIBLE int
  399. lws_plat_check_connection_error(struct lws *wsi)
  400. {
  401. int optVal;
  402. int optLen = sizeof(int);
  403. if (getsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_ERROR,
  404. (char*)&optVal, &optLen) != SOCKET_ERROR && optVal &&
  405. optVal != LWS_EALREADY && optVal != LWS_EINPROGRESS &&
  406. optVal != LWS_EWOULDBLOCK && optVal != WSAEINVAL) {
  407. lwsl_debug("Connect failed SO_ERROR=%d\n", optVal);
  408. return 1;
  409. }
  410. return 0;
  411. }
  412. LWS_VISIBLE int
  413. lws_plat_change_pollfd(struct lws_context *context,
  414. struct lws *wsi, struct lws_pollfd *pfd)
  415. {
  416. struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
  417. long networkevents = LWS_POLLHUP | FD_CONNECT;
  418. if ((pfd->events & LWS_POLLIN))
  419. networkevents |= LWS_POLLIN;
  420. if ((pfd->events & LWS_POLLOUT))
  421. networkevents |= LWS_POLLOUT;
  422. if (WSAEventSelect(wsi->desc.sockfd,
  423. pt->events[0],
  424. networkevents) != SOCKET_ERROR)
  425. return 0;
  426. lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO);
  427. return 1;
  428. }
  429. LWS_VISIBLE const char *
  430. lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt)
  431. {
  432. WCHAR *buffer;
  433. DWORD bufferlen = cnt;
  434. BOOL ok = FALSE;
  435. buffer = lws_malloc(bufferlen * 2, "inet_ntop");
  436. if (!buffer) {
  437. lwsl_err("Out of memory\n");
  438. return NULL;
  439. }
  440. if (af == AF_INET) {
  441. struct sockaddr_in srcaddr;
  442. bzero(&srcaddr, sizeof(srcaddr));
  443. srcaddr.sin_family = AF_INET;
  444. memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr));
  445. if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
  446. ok = TRUE;
  447. #ifdef LWS_WITH_IPV6
  448. } else if (af == AF_INET6) {
  449. struct sockaddr_in6 srcaddr;
  450. bzero(&srcaddr, sizeof(srcaddr));
  451. srcaddr.sin6_family = AF_INET6;
  452. memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr));
  453. if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen))
  454. ok = TRUE;
  455. #endif
  456. } else
  457. lwsl_err("Unsupported type\n");
  458. if (!ok) {
  459. int rv = WSAGetLastError();
  460. lwsl_err("WSAAddressToString() : %d\n", rv);
  461. } else {
  462. if (WideCharToMultiByte(CP_ACP, 0, buffer, bufferlen, dst, cnt, 0, NULL) <= 0)
  463. ok = FALSE;
  464. }
  465. lws_free(buffer);
  466. return ok ? dst : NULL;
  467. }
  468. LWS_VISIBLE int
  469. lws_plat_inet_pton(int af, const char *src, void *dst)
  470. {
  471. WCHAR *buffer;
  472. DWORD bufferlen = (int)strlen(src) + 1;
  473. BOOL ok = FALSE;
  474. buffer = lws_malloc(bufferlen * 2, "inet_pton");
  475. if (!buffer) {
  476. lwsl_err("Out of memory\n");
  477. return -1;
  478. }
  479. if (MultiByteToWideChar(CP_ACP, 0, src, bufferlen, buffer, bufferlen) <= 0) {
  480. lwsl_err("Failed to convert multi byte to wide char\n");
  481. lws_free(buffer);
  482. return -1;
  483. }
  484. if (af == AF_INET) {
  485. struct sockaddr_in dstaddr;
  486. int dstaddrlen = sizeof(dstaddr);
  487. bzero(&dstaddr, sizeof(dstaddr));
  488. dstaddr.sin_family = AF_INET;
  489. if (!WSAStringToAddressW(buffer, af, 0, (struct sockaddr *) &dstaddr, &dstaddrlen)) {
  490. ok = TRUE;
  491. memcpy(dst, &dstaddr.sin_addr, sizeof(dstaddr.sin_addr));
  492. }
  493. #ifdef LWS_WITH_IPV6
  494. } else if (af == AF_INET6) {
  495. struct sockaddr_in6 dstaddr;
  496. int dstaddrlen = sizeof(dstaddr);
  497. bzero(&dstaddr, sizeof(dstaddr));
  498. dstaddr.sin6_family = AF_INET6;
  499. if (!WSAStringToAddressW(buffer, af, 0, (struct sockaddr *) &dstaddr, &dstaddrlen)) {
  500. ok = TRUE;
  501. memcpy(dst, &dstaddr.sin6_addr, sizeof(dstaddr.sin6_addr));
  502. }
  503. #endif
  504. } else
  505. lwsl_err("Unsupported type\n");
  506. if (!ok) {
  507. int rv = WSAGetLastError();
  508. lwsl_err("WSAAddressToString() : %d\n", rv);
  509. }
  510. lws_free(buffer);
  511. return ok ? 1 : -1;
  512. }
  513. LWS_VISIBLE lws_fop_fd_t
  514. _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
  515. const char *vpath, lws_fop_flags_t *flags)
  516. {
  517. HANDLE ret;
  518. WCHAR buf[MAX_PATH];
  519. lws_fop_fd_t fop_fd;
  520. FILE_STANDARD_INFO fInfo = {0};
  521. MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, LWS_ARRAY_SIZE(buf));
  522. #if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602 // Windows 8 (minimum when UWP_ENABLED, but can be used in Windows builds)
  523. CREATEFILE2_EXTENDED_PARAMETERS extParams = {0};
  524. extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
  525. if (((*flags) & 7) == _O_RDONLY) {
  526. ret = CreateFile2(buf, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extParams);
  527. } else {
  528. ret = CreateFile2(buf, GENERIC_WRITE, 0, CREATE_ALWAYS, &extParams);
  529. }
  530. #else
  531. if (((*flags) & 7) == _O_RDONLY) {
  532. ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ,
  533. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  534. } else {
  535. ret = CreateFileW(buf, GENERIC_WRITE, 0, NULL,
  536. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  537. }
  538. #endif
  539. if (ret == LWS_INVALID_FILE)
  540. goto bail;
  541. fop_fd = malloc(sizeof(*fop_fd));
  542. if (!fop_fd)
  543. goto bail;
  544. fop_fd->fops = fops;
  545. fop_fd->fd = ret;
  546. fop_fd->filesystem_priv = NULL; /* we don't use it */
  547. fop_fd->flags = *flags;
  548. fop_fd->len = 0;
  549. if(GetFileInformationByHandleEx(ret, FileStandardInfo, &fInfo, sizeof(fInfo)))
  550. fop_fd->len = fInfo.EndOfFile.QuadPart;
  551. fop_fd->pos = 0;
  552. return fop_fd;
  553. bail:
  554. return NULL;
  555. }
  556. LWS_VISIBLE int
  557. _lws_plat_file_close(lws_fop_fd_t *fop_fd)
  558. {
  559. HANDLE fd = (*fop_fd)->fd;
  560. free(*fop_fd);
  561. *fop_fd = NULL;
  562. CloseHandle((HANDLE)fd);
  563. return 0;
  564. }
  565. LWS_VISIBLE lws_fileofs_t
  566. _lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
  567. {
  568. LARGE_INTEGER l;
  569. l.QuadPart = offset;
  570. return SetFilePointerEx((HANDLE)fop_fd->fd, l, NULL, FILE_CURRENT);
  571. }
  572. LWS_VISIBLE int
  573. _lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
  574. uint8_t *buf, lws_filepos_t len)
  575. {
  576. DWORD _amount;
  577. if (!ReadFile((HANDLE)fop_fd->fd, buf, (DWORD)len, &_amount, NULL)) {
  578. *amount = 0;
  579. return 1;
  580. }
  581. fop_fd->pos += _amount;
  582. *amount = (unsigned long)_amount;
  583. return 0;
  584. }
  585. LWS_VISIBLE int
  586. _lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
  587. uint8_t* buf, lws_filepos_t len)
  588. {
  589. DWORD _amount;
  590. if (!WriteFile((HANDLE)fop_fd->fd, buf, (DWORD)len, &_amount, NULL)) {
  591. *amount = 0;
  592. return 1;
  593. }
  594. fop_fd->pos += _amount;
  595. *amount = (unsigned long)_amount;
  596. return 0;
  597. }
  598. LWS_VISIBLE int
  599. lws_plat_init(struct lws_context *context,
  600. const struct lws_context_creation_info *info)
  601. {
  602. struct lws_context_per_thread *pt = &context->pt[0];
  603. int i, n = context->count_threads;
  604. for (i = 0; i < FD_HASHTABLE_MODULUS; i++) {
  605. context->fd_hashtable[i].wsi =
  606. lws_zalloc(sizeof(struct lws*) * context->max_fds, "win hashtable");
  607. if (!context->fd_hashtable[i].wsi)
  608. return -1;
  609. }
  610. while (n--) {
  611. pt->events = lws_malloc(sizeof(WSAEVENT) *
  612. (context->fd_limit_per_thread + 1), "event table");
  613. if (pt->events == NULL) {
  614. lwsl_err("Unable to allocate events array for %d connections\n",
  615. context->fd_limit_per_thread + 1);
  616. return 1;
  617. }
  618. pt->fds_count = 0;
  619. pt->events[0] = WSACreateEvent(); /* the cancel event */
  620. pt++;
  621. }
  622. context->fd_random = 0;
  623. #ifdef LWS_WITH_PLUGINS
  624. if (info->plugin_dirs)
  625. lws_plat_plugins_init(context, info->plugin_dirs);
  626. #endif
  627. return 0;
  628. }
  629. int kill(int pid, int sig)
  630. {
  631. lwsl_err("Sorry Windows doesn't support kill().");
  632. exit(0);
  633. }
  634. int fork(void)
  635. {
  636. lwsl_err("Sorry Windows doesn't support fork().");
  637. exit(0);
  638. }
  639. LWS_VISIBLE int
  640. lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf,
  641. int len)
  642. {
  643. int n;
  644. n = write(fd, buf, len);
  645. lseek(fd, 0, SEEK_SET);
  646. return n != len;
  647. }
  648. LWS_VISIBLE int
  649. lws_plat_write_file(const char *filename, void *buf, int len)
  650. {
  651. int m, fd;
  652. fd = lws_open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
  653. if (fd == -1)
  654. return -1;
  655. m = write(fd, buf, len);
  656. close(fd);
  657. return m != len;
  658. }
  659. LWS_VISIBLE int
  660. lws_plat_read_file(const char *filename, void *buf, int len)
  661. {
  662. int n, fd = lws_open(filename, O_RDONLY);
  663. if (fd == -1)
  664. return -1;
  665. n = read(fd, buf, len);
  666. close(fd);
  667. return n;
  668. }
  669. LWS_VISIBLE int
  670. lws_plat_recommended_rsa_bits(void)
  671. {
  672. return 4096;
  673. }