diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/ecore/src/lib/ecore_con/ecore_con_local_win32.c | 769 |
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 | |||
16 | static int _ecore_con_local_init_count = 0; | ||
17 | |||
18 | int | ||
19 | ecore_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 | |||
27 | int | ||
28 | ecore_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 | |||
37 | static 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 | |||
92 | static 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 | |||
123 | static 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 | |||
153 | static 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 */ | ||
209 | static 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 */ | ||
248 | static 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 | |||
286 | static 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 | |||
384 | static 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 | |||
411 | Eina_Bool | ||
412 | ecore_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 | |||
497 | void | ||
498 | ecore_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 | |||
524 | void | ||
525 | ecore_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 | |||
551 | Eina_Bool | ||
552 | ecore_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 | |||
672 | Eina_Bool | ||
673 | ecore_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 | |||
720 | Eina_Bool | ||
721 | ecore_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 | } | ||