aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c')
-rw-r--r--libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c769
1 files changed, 769 insertions, 0 deletions
diff --git a/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c b/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
new file mode 100644
index 0000000..858daa5
--- /dev/null
+++ b/libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c
@@ -0,0 +1,769 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <process.h>
6
7#include <Evil.h>
8#include <Ecore.h>
9
10#include "Ecore_Con.h"
11#include "ecore_con_private.h"
12
13#define BUFSIZE 512
14
15
16static int _ecore_con_local_init_count = 0;
17
18int
19ecore_con_local_init(void)
20{
21 if (++_ecore_con_local_init_count != 1)
22 return _ecore_con_local_init_count;
23
24 return _ecore_con_local_init_count;
25}
26
27int
28ecore_con_local_shutdown(void)
29{
30 if (--_ecore_con_local_init_count != 0)
31 return _ecore_con_local_init_count;
32
33 return _ecore_con_local_init_count;
34}
35
36
37static Eina_Bool
38_ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handler *wh)
39{
40 Ecore_Con_Client *cl;
41 void *buf;
42 DWORD n;
43 Eina_Bool broken_pipe = EINA_FALSE;
44
45 cl = (Ecore_Con_Client *)data;
46
47 if (!ResetEvent(cl->host_server->event_read))
48 return ECORE_CALLBACK_RENEW;
49
50 buf = malloc(cl->host_server->nbr_bytes);
51 if (!buf)
52 return ECORE_CALLBACK_RENEW;
53
54 if (ReadFile(cl->host_server->pipe, buf, cl->host_server->nbr_bytes, &n, NULL))
55 {
56 if (!cl->delete_me)
57 ecore_con_event_client_data(cl, buf, cl->host_server->nbr_bytes, EINA_FALSE);
58 cl->host_server->want_write = 1;
59 }
60 else
61 {
62 if (GetLastError() == ERROR_BROKEN_PIPE)
63 broken_pipe = EINA_TRUE;
64 }
65
66 if (broken_pipe)
67 {
68#if 0
69 char *msg;
70
71 msg = evil_last_error_get();
72 if (msg)
73 {
74 ecore_con_event_client_error(cl, msg);
75 free(msg);
76 }
77#endif
78 if (!cl->delete_me)
79 ecore_con_event_client_del(cl);
80 cl->dead = EINA_TRUE;
81 return ECORE_CALLBACK_CANCEL;
82 }
83
84 if (cl->host_server->want_write)
85 ecore_con_local_win32_client_flush(cl);
86
87 ecore_main_win32_handler_del(wh);
88
89 return ECORE_CALLBACK_DONE;
90}
91
92static Eina_Bool
93_ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh)
94{
95 Ecore_Con_Client *cl;
96#if 0
97 char *msg;
98#endif
99
100 cl = (Ecore_Con_Client *)data;
101
102 if (!ResetEvent(cl->host_server->event_peek))
103 return ECORE_CALLBACK_RENEW;
104
105#if 0
106 msg = evil_last_error_get();
107 if (msg)
108 {
109 ecore_con_event_server_error(cl->host_server, msg);
110 free(msg);
111 }
112#endif
113 if (!cl->host_server->delete_me)
114 ecore_con_event_server_del(cl->host_server);
115 cl->host_server->dead = EINA_TRUE;
116 return ECORE_CALLBACK_CANCEL;
117
118 ecore_main_win32_handler_del(wh);
119
120 return ECORE_CALLBACK_DONE;
121}
122
123static Eina_Bool
124_ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh)
125{
126 Ecore_Con_Server *svr;
127#if 0
128 char *msg;
129#endif
130
131 svr = (Ecore_Con_Server *)data;
132
133 if (!ResetEvent(svr->event_peek))
134 return ECORE_CALLBACK_RENEW;
135#if 0
136 msg = evil_last_error_get();
137 if (msg)
138 {
139 ecore_con_event_server_error(svr, msg);
140 free(msg);
141 }
142#endif
143 if (!svr->delete_me)
144 ecore_con_event_server_del(svr);
145 svr->dead = EINA_TRUE;
146 return ECORE_CALLBACK_CANCEL;
147
148 ecore_main_win32_handler_del(wh);
149
150 return ECORE_CALLBACK_DONE;
151}
152
153static Eina_Bool
154_ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh)
155{
156 Ecore_Con_Server *svr;
157 void *buf;
158 DWORD n;
159 Eina_Bool broken_pipe = EINA_FALSE;
160
161 svr = (Ecore_Con_Server *)data;
162
163 if (!ResetEvent(svr->event_read))
164 return ECORE_CALLBACK_RENEW;
165
166 buf = malloc(svr->nbr_bytes);
167 if (!buf)
168 return ECORE_CALLBACK_RENEW;
169
170 if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL))
171 {
172 if (!svr->delete_me)
173 ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE);
174 svr->want_write = 1;
175 }
176 else
177 {
178 if (GetLastError() == ERROR_BROKEN_PIPE)
179 broken_pipe = EINA_TRUE;
180 }
181
182 if (broken_pipe)
183 {
184#if 0
185 char *msg;
186
187 msg = evil_last_error_get();
188 if (msg)
189 {
190 ecore_con_event_server_error(svr, msg);
191 free(msg);
192 }
193#endif
194 if (!svr->delete_me)
195 ecore_con_event_server_del(svr);
196 svr->dead = EINA_TRUE;
197 return ECORE_CALLBACK_CANCEL;
198 }
199
200 if (svr->want_write)
201 ecore_con_local_win32_server_flush(svr);
202
203 ecore_main_win32_handler_del(wh);
204
205 return ECORE_CALLBACK_DONE;
206}
207
208/* thread to read data sent by the server to the client */
209static unsigned int __stdcall
210_ecore_con_local_win32_client_read_server_thread(void *data)
211{
212 Ecore_Con_Server *svr;
213 DWORD nbr_bytes = 0;
214
215 svr = (Ecore_Con_Server *)data;
216
217 svr->read_stopped = EINA_FALSE;
218
219 while (!svr->read_stop)
220 {
221 if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL))
222 {
223 if (nbr_bytes <= 0)
224 continue;
225
226 svr->nbr_bytes = nbr_bytes;
227 if (!SetEvent(svr->event_read))
228 continue;
229 }
230 else
231 {
232 if (GetLastError() == ERROR_BROKEN_PIPE)
233 {
234 if (!SetEvent(svr->event_peek))
235 continue;
236 break;
237 }
238 }
239 }
240
241 printf(" ### %s\n", __FUNCTION__);
242 svr->read_stopped = EINA_TRUE;
243 _endthreadex(0);
244 return 0;
245}
246
247/* thread to read data sent by the client to the server */
248static unsigned int __stdcall
249_ecore_con_local_win32_server_read_client_thread(void *data)
250{
251 Ecore_Con_Client *cl;
252 DWORD nbr_bytes = 0;
253
254 cl = (Ecore_Con_Client *)data;
255
256 cl->host_server->read_stopped = EINA_FALSE;
257
258 while (!cl->host_server->read_stop)
259 {
260 if (PeekNamedPipe(cl->host_server->pipe, NULL, 0, NULL, &nbr_bytes, NULL))
261 {
262 if (nbr_bytes <= 0)
263 continue;
264
265 cl->host_server->nbr_bytes = nbr_bytes;
266 if (!SetEvent(cl->host_server->event_read))
267 continue;
268 }
269 else
270 {
271 if (GetLastError() == ERROR_BROKEN_PIPE)
272 {
273 if (!SetEvent(cl->host_server->event_peek))
274 continue;
275 break;
276 }
277 }
278 }
279
280 printf(" ### %s\n", __FUNCTION__);
281 cl->host_server->read_stopped = EINA_TRUE;
282 _endthreadex(0);
283 return 0;
284}
285
286static Eina_Bool
287_ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh)
288{
289 Ecore_Con_Client *cl = NULL;
290 Ecore_Con_Server *svr;
291 Ecore_Win32_Handler *handler_read;
292 Ecore_Win32_Handler *handler_peek;
293
294 svr = (Ecore_Con_Server *)data;
295
296 if (!svr->pipe)
297 return ECORE_CALLBACK_CANCEL;
298
299 if (svr->dead)
300 return ECORE_CALLBACK_CANCEL;
301
302 if (svr->delete_me)
303 return ECORE_CALLBACK_CANCEL;
304
305 if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) &&
306 (svr->client_count >= (unsigned int)svr->client_limit))
307 return ECORE_CALLBACK_CANCEL;
308
309 cl = calloc(1, sizeof(Ecore_Con_Client));
310 if (!cl)
311 {
312 ERR("allocation failed");
313 return ECORE_CALLBACK_CANCEL;
314 }
315
316 cl->host_server = svr;
317 ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT);
318
319 cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
320 if (!cl->host_server->event_read)
321 {
322 ERR("Can not create event read");
323 goto free_cl;
324 }
325
326 handler_read = ecore_main_win32_handler_add(cl->host_server->event_read,
327 _ecore_con_local_win32_server_read_client_handler,
328 cl);
329 if (!handler_read)
330 {
331 ERR("Can not create handler read");
332 goto close_event_read;
333 }
334
335 cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL);
336 if (!cl->host_server->event_peek)
337 {
338 ERR("Can not create event peek");
339 goto del_handler_read;
340 }
341
342 handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek,
343 _ecore_con_local_win32_server_peek_client_handler,
344 cl);
345 if (!handler_peek)
346 {
347 ERR("Can not create handler peek");
348 goto close_event_peek;
349 }
350
351 cl->host_server->read_stopped = EINA_TRUE;
352 cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL);
353 if (!cl->host_server->thread_read)
354 {
355 ERR("Can not launch thread");
356 goto del_handler_peek;
357 }
358
359 svr->clients = eina_list_append(svr->clients, cl);
360 svr->client_count++;
361
362 if (!cl->delete_me)
363 ecore_con_event_client_add(cl);
364
365 ecore_main_win32_handler_del(wh);
366
367 ResumeThread(cl->host_server->thread_read);
368 return ECORE_CALLBACK_DONE;
369
370 del_handler_peek:
371 ecore_main_win32_handler_del(handler_peek);
372 close_event_peek:
373 CloseHandle(cl->host_server->event_peek);
374 del_handler_read:
375 ecore_main_win32_handler_del(handler_read);
376 close_event_read:
377 CloseHandle(cl->host_server->event_read);
378 free_cl:
379 free(cl);
380
381 return ECORE_CALLBACK_CANCEL;
382}
383
384static unsigned int __stdcall
385_ecore_con_local_win32_listening(void *data)
386{
387 Ecore_Con_Server *svr;
388 BOOL res;
389
390 svr = (Ecore_Con_Server *)data;
391
392 while (1)
393 {
394 res = ConnectNamedPipe(svr->pipe, NULL);
395 if (!res)
396 {
397 ERR("Opening the connection to the client failed");
398 CloseHandle(svr->pipe);
399 svr->pipe = NULL;
400 }
401 break;
402 }
403
404 DBG("Client connected");
405
406 printf(" ### %s\n", __FUNCTION__);
407 _endthreadex(0);
408 return 0;
409}
410
411Eina_Bool
412ecore_con_local_listen(Ecore_Con_Server *svr)
413{
414 char buf[256];
415 HANDLE thread_listening;
416 Ecore_Win32_Handler *handler;
417
418 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
419 {
420 ERR("Your system does not support abstract sockets!");
421 return EINA_FALSE;
422 }
423
424 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
425 snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name);
426 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
427 {
428 const char *computername;
429
430 computername = getenv("CoMPUTERNAME");
431 snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name);
432 }
433
434 svr->path = strdup(buf);
435 if (!svr->path)
436 {
437 ERR("Allocation failed");
438 return EINA_FALSE;
439 }
440
441 /*
442 * synchronuous
443 * block mode
444 * wait mode
445 */
446 svr->pipe = CreateNamedPipe(svr->path,
447 PIPE_ACCESS_DUPLEX,
448 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
449 PIPE_UNLIMITED_INSTANCES,
450 BUFSIZE,
451 BUFSIZE,
452 5000,
453 NULL);
454 if (svr->pipe == INVALID_HANDLE_VALUE)
455 {
456 ERR("Creation of the named pipe failed");
457 goto free_path;
458 }
459
460 /*
461 * We use ConnectNamedPipe() to wait for a client to connect.
462 * As the function is blocking, to let the main loop continuing
463 * its iterations, we call ConnectNamedPipe() in a thread
464 */
465 thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL);
466 if (!thread_listening)
467 {
468 ERR("Creation of the listening thread failed");
469 goto close_pipe;
470 }
471
472 handler = ecore_main_win32_handler_add(thread_listening,
473 _ecore_con_local_win32_client_add,
474 svr);
475 if (!handler)
476 {
477 ERR("Creation of the client add handler failed");
478 goto del_handler;
479 }
480
481 svr->read_stopped = EINA_TRUE;
482 ResumeThread(thread_listening);
483
484 return EINA_TRUE;
485
486 del_handler:
487 ecore_main_win32_handler_del(handler);
488 close_pipe:
489 CloseHandle(svr->pipe);
490 free_path:
491 free(svr->path);
492 svr->path = NULL;
493
494 return EINA_FALSE;
495}
496
497void
498ecore_con_local_win32_server_del(Ecore_Con_Server *svr)
499{
500 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
501 return;
502
503 if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
504 ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
505 return;
506
507 svr->read_stop = 1;
508 while (!svr->read_stopped)
509 Sleep(100);
510
511 if (svr->event_peek)
512 CloseHandle(svr->event_peek);
513 svr->event_peek = NULL;
514 if (svr->event_read)
515 CloseHandle(svr->event_read);
516 svr->event_read = NULL;
517 free(svr->path);
518 svr->path = NULL;
519 if (svr->pipe)
520 CloseHandle(svr->pipe);
521 svr->pipe = NULL;
522}
523
524void
525ecore_con_local_win32_client_del(Ecore_Con_Client *cl)
526{
527 if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
528 return;
529
530 if (((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
531 ((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
532 return;
533
534 cl->host_server->read_stop = 1;
535 while (!cl->host_server->read_stopped)
536 Sleep(100);
537
538 if (cl->host_server->event_peek)
539 CloseHandle(cl->host_server->event_peek);
540 cl->host_server->event_peek = NULL;
541 if (cl->host_server->event_read)
542 CloseHandle(cl->host_server->event_read);
543 cl->host_server->event_read = NULL;
544 free(cl->host_server->path);
545 cl->host_server->path = NULL;
546 if (cl->host_server->pipe)
547 CloseHandle(cl->host_server->pipe);
548 cl->host_server->pipe = NULL;
549}
550
551Eina_Bool
552ecore_con_local_connect(Ecore_Con_Server *svr,
553 Eina_Bool (*cb_done)(void *data,
554 Ecore_Fd_Handler *fd_handler))
555{
556 char buf[256];
557 Ecore_Win32_Handler *handler_read;
558 Ecore_Win32_Handler *handler_peek;
559
560 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
561 {
562 ERR("Your system does not support abstract sockets!");
563 return EINA_FALSE;
564 }
565
566 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER)
567 snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name);
568 else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM)
569 {
570 const char *computername;
571
572 computername = getenv("COMPUTERNAME");
573 snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name);
574 }
575
576 while (1)
577 {
578 svr->pipe = CreateFile(buf,
579 GENERIC_READ | GENERIC_WRITE,
580 0,
581 NULL,
582 OPEN_EXISTING,
583 0,
584 NULL);
585 if (svr->pipe != INVALID_HANDLE_VALUE)
586 break;
587
588 /* if pipe not busy, we exit */
589 if (GetLastError() != ERROR_PIPE_BUSY)
590 {
591 ERR("Connection to a server failed");
592 return EINA_FALSE;
593 }
594
595 /* pipe busy, so we wait for it */
596 if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER))
597 {
598 ERR("Can not wait for a server");
599 goto close_pipe;
600 }
601 }
602
603 svr->path = strdup(buf);
604 if (!svr->path)
605 {
606 ERR("Allocation failed");
607 goto close_pipe;
608 }
609
610 svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL);
611 if (!svr->event_read)
612 {
613 ERR("Can not create event read");
614 goto free_path;
615 }
616
617 handler_read = ecore_main_win32_handler_add(svr->event_read,
618 _ecore_con_local_win32_client_read_server_handler,
619 svr);
620 if (!handler_read)
621 {
622 ERR("Can not create handler read");
623 goto close_event_read;
624 }
625
626 svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL);
627 if (!svr->event_peek)
628 {
629 ERR("Can not create event peek");
630 goto del_handler_read;
631 }
632
633 handler_peek = ecore_main_win32_handler_add(svr->event_peek,
634 _ecore_con_local_win32_client_peek_server_handler,
635 svr);
636 if (!handler_peek)
637 {
638 ERR("Can not create handler peek");
639 goto close_event_peek;
640 }
641
642 svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL);
643 if (!svr->thread_read)
644 {
645 ERR("Can not launch thread");
646 goto del_handler_peek;
647 }
648
649 if (!svr->delete_me) ecore_con_event_server_add(svr);
650
651 ResumeThread(svr->thread_read);
652
653 return EINA_TRUE;
654
655 del_handler_peek:
656 ecore_main_win32_handler_del(handler_peek);
657 close_event_peek:
658 CloseHandle(svr->event_peek);
659 del_handler_read:
660 ecore_main_win32_handler_del(handler_read);
661 close_event_read:
662 CloseHandle(svr->event_read);
663 free_path:
664 free(svr->path);
665 svr->path = NULL;
666 close_pipe:
667 CloseHandle(svr->pipe);
668
669 return EINA_FALSE;
670}
671
672Eina_Bool
673ecore_con_local_win32_server_flush(Ecore_Con_Server *svr)
674{
675 int num;
676 BOOL res;
677 DWORD written;
678
679 /* This check should never be true */
680 if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT)
681 return EINA_TRUE;
682
683 if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) &&
684 ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM))
685 return EINA_FALSE;
686
687 num = eina_binbuf_length_get(svr->buf) - svr->write_buf_offset;
688 if (num <= 0) return EINA_TRUE;
689
690 res = WriteFile(svr->pipe, eina_binbuf_string_get(svr->buf) + svr->write_buf_offset, num, &written, NULL);
691 if (!res)
692 {
693 char *msg;
694
695 msg = evil_last_error_get();
696 if (msg)
697 {
698 ecore_con_event_server_error(svr, msg);
699 free(msg);
700 }
701 if (!svr->delete_me)
702 ecore_con_event_server_del(svr);
703 svr->dead = EINA_TRUE;
704 }
705
706 svr->write_buf_offset += written;
707 if (svr->write_buf_offset >= eina_binbuf_length_get(svr->buf))
708 {
709 svr->write_buf_offset = 0;
710 eina_binbuf_free(svr->buf);
711 svr->buf = NULL;
712 svr->want_write = 0;
713 }
714 else if (written < (DWORD)num)
715 svr->want_write = 1;
716
717 return EINA_TRUE;
718}
719
720Eina_Bool
721ecore_con_local_win32_client_flush(Ecore_Con_Client *cl)
722{
723 Ecore_Con_Type type;
724 int num;
725 BOOL res;
726 DWORD written;
727
728 type = cl->host_server->type & ECORE_CON_TYPE;
729
730 /* This check should never be true */
731 if (type == ECORE_CON_LOCAL_ABSTRACT)
732 return EINA_TRUE;
733
734 if ((type != ECORE_CON_LOCAL_USER) &&
735 (type != ECORE_CON_LOCAL_SYSTEM))
736 return EINA_FALSE;
737
738 num = eina_binbuf_length_get(cl->buf) - cl->buf_offset;
739 if (num <= 0) return EINA_TRUE;
740
741 res = WriteFile(cl->host_server->pipe, eina_binbuf_string_get(cl->buf) + cl->buf_offset, num, &written, NULL);
742 if (!res)
743 {
744 char *msg;
745
746 msg = evil_last_error_get();
747 if (msg)
748 {
749 ecore_con_event_client_error(cl, msg);
750 free(msg);
751 }
752 if (!cl->delete_me)
753 ecore_con_event_client_del(cl);
754 cl->dead = EINA_TRUE;
755 }
756
757 cl->buf_offset += written;
758 if (cl->buf_offset >= eina_binbuf_length_get(cl->buf))
759 {
760 cl->buf_offset = 0;
761 eina_binbuf_free(cl->buf);
762 cl->buf = NULL;
763 cl->host_server->want_write = 0;
764 }
765 else if (written < (DWORD)num)
766 cl->host_server->want_write = 1;
767
768 return EINA_TRUE;
769}