source: trunk/src/wsock32/relaywin.cpp@ 3171

Last change on this file since 3171 was 3171, checked in by sandervl, 25 years ago

relay bugfixes

File size: 17.9 KB
Line 
1/*
2 *
3 * Project Odin Software License can be found in LICENSE.TXT
4 *
5 * Win32 SOCK32 for OS/2
6 *
7 * Copyright (C) 1999 Patrick Haller <phaller@gmx.net>
8 *
9 */
10
11/* Remark:
12 * - this is an object window that acts as "relay", this is
13 * it receives WSAAsyncSelect()'s messages and redirects
14 * them to the appropriate PostMessageA function of USER32.
15 */
16
17
18/*****************************************************************************
19 * Includes *
20 *****************************************************************************/
21
22/* object.c: the object window procedure on thread 2 */
23// os2 includes
24#define INCL_DOSPROCESS
25#define INCL_WIN
26#include <os2.h>
27// crt includes
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include <odin.h>
33#include <odinwrap.h>
34#include <misc.h>
35
36#include "relaywin.h"
37
38#include <pmwsock.h>
39#include <os2sel.h>
40#include <wprocess.h>
41#include <heapstring.h>
42#include <win32api.h>
43#include "wsock32.h"
44#include <vmutex.h>
45
46#define DBG_LOCALLOG DBG_relaywin
47#include "dbglocal.h"
48
49ODINDEBUGCHANNEL(WSOCK32-RELAYWIN)
50
51
52/*****************************************************************************
53 * Structures *
54 *****************************************************************************/
55
56#define MAX_ASYNC_SOCKETS 64
57
58// static table for id / hwnd-msg translation
59static HWNDMSGPAIR arrHwndMsgPair[MAX_ASYNC_SOCKETS] = {0};
60static char* ODIN_WSOCK_RELAY_CLASS = "ODIN_WSOCK_RELAY";
61static HWND hwndRelay = NULLHANDLE;
62static HAB hab;
63static VMutex relayMutex;
64
65/*****************************************************************************
66 * Name :
67 * Purpose :
68 * Parameters:
69 * Variables :
70 * Result :
71 * Remark :
72 * Status :
73 *
74 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
75 *****************************************************************************/
76
77ULONG RelayAlloc(HWND hwnd,
78 ULONG ulMsg,
79 ULONG ulRequestType,
80 ULONG socket,
81 BOOL fSingleRequestPerWindow,
82 PVOID pvUserData1,
83 PVOID pvUserData2,
84 PVOID pvUserData3)
85{
86 ULONG ulCounter;
87
88 relayMutex.enter();
89 for(ulCounter = 0; ulCounter < MAX_ASYNC_SOCKETS; ulCounter++)
90 {
91 if ( (arrHwndMsgPair[ulCounter].hwnd == 0) || // slot free?
92 ( (fSingleRequestPerWindow == TRUE) && // more than one request per window?
93 (arrHwndMsgPair[ulCounter].hwnd == hwnd) ) ) // same window?
94 {
95 // occupy slot
96 arrHwndMsgPair[ulCounter].hwnd = hwnd;
97 arrHwndMsgPair[ulCounter].ulMsg = ulMsg;
98 arrHwndMsgPair[ulCounter].ulRequestType = ulRequestType;
99 arrHwndMsgPair[ulCounter].socket = socket;
100 arrHwndMsgPair[ulCounter].pvUserData1 = pvUserData1;
101 arrHwndMsgPair[ulCounter].pvUserData2 = pvUserData2;
102 arrHwndMsgPair[ulCounter].pvUserData3 = pvUserData3;
103 relayMutex.leave();
104 return ulCounter + 1; // return "id"
105 }
106 }
107 relayMutex.leave();
108 return -1; // not found
109}
110
111
112/*****************************************************************************
113 * Name :
114 * Purpose :
115 * Parameters:
116 * Variables :
117 * Result :
118 * Remark :
119 * Status :
120 *
121 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
122 *****************************************************************************/
123
124ULONG RelayFree(ULONG ulID)
125{
126 if ( (ulID < 1) || // check range
127 (ulID > MAX_ASYNC_SOCKETS) )
128 return -1; // error
129
130 relayMutex.enter();
131 arrHwndMsgPair[ulID-1].hwnd = 0; // mark free
132 arrHwndMsgPair[ulID-1].ulMsg = 0;
133 arrHwndMsgPair[ulID-1].ulRequestType = 0;
134 arrHwndMsgPair[ulID-1].socket = 0;
135 arrHwndMsgPair[ulID-1].pvUserData1 = 0;
136 arrHwndMsgPair[ulID-1].pvUserData2 = 0;
137 arrHwndMsgPair[ulID-1].pvUserData3 = 0;
138 relayMutex.leave();
139
140 return 0; // OK
141}
142
143
144/*****************************************************************************
145 * Name :
146 * Purpose :
147 * Parameters:
148 * Variables :
149 * Result :
150 * Remark :
151 * Status :
152 *
153 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
154 *****************************************************************************/
155
156ULONG RelayFreeByHwnd(ULONG socket, HWND hwnd)
157{
158 ULONG ulCounter;
159
160 relayMutex.enter();
161 for(ulCounter = 0; ulCounter < MAX_ASYNC_SOCKETS; ulCounter++)
162 {
163 if (arrHwndMsgPair[ulCounter].hwnd == hwnd &&
164 arrHwndMsgPair[ulCounter].socket == socket) // same window && socket?
165 {
166 arrHwndMsgPair[ulCounter].hwnd = 0; // free slot
167 arrHwndMsgPair[ulCounter].ulMsg = 0;
168 arrHwndMsgPair[ulCounter].ulRequestType = 0;
169 arrHwndMsgPair[ulCounter].socket = 0;
170 arrHwndMsgPair[ulCounter].pvUserData1 = 0;
171 arrHwndMsgPair[ulCounter].pvUserData2 = 0;
172 arrHwndMsgPair[ulCounter].pvUserData3 = 0;
173 relayMutex.leave();
174 return 0; // OK
175 }
176 }
177 relayMutex.leave();
178 dprintf(("RelayFreeByHwnd: window %x not found!", hwnd));
179 return -1; // not found
180}
181
182
183/*****************************************************************************
184 * Name :
185 * Purpose :
186 * Parameters:
187 * Variables :
188 * Result :
189 * Remark :
190 * Status :
191 *
192 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
193 *****************************************************************************/
194
195PHWNDMSGPAIR RelayQuery(ULONG ulID)
196{
197 if ( (ulID < 1) || // check range
198 (ulID > MAX_ASYNC_SOCKETS) )
199 return NULL; // error
200
201 if (arrHwndMsgPair[ulID-1].hwnd == 0)
202 return NULL; // error, free entry
203 else
204 return (&arrHwndMsgPair[ulID-1]);
205}
206
207
208/*****************************************************************************
209 * Name :
210 * Purpose :
211 * Parameters:
212 * Variables :
213 * Result :
214 * Remark :
215 * Status :
216 *
217 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
218 *****************************************************************************/
219
220MRESULT EXPENTRY RelayWindowProc(HWND hwnd,
221 ULONG ulMsg,
222 MPARAM mp1,
223 MPARAM mp2)
224{
225 PHWNDMSGPAIR pHM;
226 int rc;
227
228 // termination flag handling?
229 // if (fTerminate)
230 // WinDefWindowProc()
231
232 /* find registered message */
233 pHM = RelayQuery(ulMsg);
234 /* message pair found */
235 if (pHM != NULL)
236 {
237 rc = SHORT1FROMMP(mp2); /* asynchronous operation result */
238
239// dprintf(("WSOCK32: RelayWindowProc, message %x for window %x with "
240// "mp1 = %d and mp2 = %d (rc = %d) (time = %x) received\n",
241// ulMsg, hwnd, mp1, mp2, rc, WinQueryMsgTime(hab)));
242
243 /* check request type for special handling */
244 switch (pHM->ulRequestType)
245 {
246 /**********
247 * SELECT *
248 **********/
249 case ASYNCREQUEST_SELECT:
250 {
251 dprintf(("WSOCK32:RelayWindowProc, AsyncSelect notification %x %x (%x,%x) time %x\n", pHM->hwnd, pHM->ulMsg, mp1, mp2, WinQueryMsgTime(hab)));
252 if(SHORT2FROMMP(mp2) == WSAECONNREFUSED) {
253 mp2 = (MPARAM)((WSAENOTCONN << 16) | 0x10);
254 }
255 break;
256 }
257
258
259 /*****************
260 * GETHOSTBYNAME *
261 *****************/
262 case ASYNCREQUEST_GETHOSTBYNAME:
263 {
264 dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
265 "WSAAyncGetHostByName\n"));
266
267 /* is there a valid result ? */
268 if (rc == 0)
269 {
270 /* we need to convert the hostent structure here */
271 Whostent *WinHostent = (Whostent*)pHM->pvUserData1;
272 hostent *OS2Hostent = (hostent*)pHM->pvUserData1;
273
274 short h_addrtype = (short)OS2Hostent->h_addrtype;
275 WinHostent->h_addrtype = h_addrtype;
276 short h_length = (short)OS2Hostent->h_length;
277 WinHostent->h_length = h_length;
278 char **h_addr_list = OS2Hostent->h_addr_list;
279 WinHostent->h_addr_list = h_addr_list;
280 //TODO: the size of OS/2 hostent is 4 bytes bigger
281 // so the original buffer *might* be too small
282 }
283 break;
284 }
285
286
287 /*****************
288 * GETHOSTBYADDR *
289 *****************/
290 case ASYNCREQUEST_GETHOSTBYADDR:
291 {
292 dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
293 "WSAAyncGetHostByAddr\n"));
294
295 if (rc == 0)
296 {
297 dprintf(("WSOCK32:RelayWindowProc, hostent buffer: %d\n", pHM->pvUserData1));
298 /* we need to convert the hostent structure here */
299 Whostent *WinHostent = (Whostent*)pHM->pvUserData1;
300 hostent *OS2Hostent = (hostent*)pHM->pvUserData1;
301
302 short h_addrtype = (short)OS2Hostent->h_addrtype;
303 WinHostent->h_addrtype = h_addrtype;
304 short h_length = (short)OS2Hostent->h_length;
305 WinHostent->h_length = h_length;
306 char **h_addr_list = OS2Hostent->h_addr_list;
307 WinHostent->h_addr_list = h_addr_list;
308 //TODO: the size of OS/2 hostent is 4 bytes bigger
309 // so the original buffer *might* be too small
310 }
311 break;
312 }
313
314
315 /*****************
316 * GETSERVBYNAME *
317 *****************/
318 case ASYNCREQUEST_GETSERVBYNAME:
319 {
320 dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
321 "WSAAyncGetServByName\n"));
322
323 if (rc == 0)
324 {
325 /* we need to convert the servent structure here */
326 Wservent *WinServent = (Wservent*)pHM->pvUserData1;
327 servent *OS2Servent = (servent*)pHM->pvUserData1;
328
329 WinServent->s_port = OS2Servent->s_port;
330 WinServent->s_proto = OS2Servent->s_proto;
331 //TODO: the size of OS/2 servent is 2 bytes bigger
332 // so the original buffer *might* be too small
333 }
334 break;
335 }
336
337
338 /*****************
339 * GETSERVBYPORT *
340 *****************/
341 case ASYNCREQUEST_GETSERVBYPORT:
342 {
343 dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
344 "WSAAyncGetServByPort\n"));
345
346 if (rc == 0)
347 {
348 /* we need to convert the servent structure here */
349 Wservent *WinServent = (Wservent*)pHM->pvUserData1;
350 servent *OS2Servent = (servent*)pHM->pvUserData1;
351
352 WinServent->s_port = OS2Servent->s_port;
353 WinServent->s_proto = OS2Servent->s_proto;
354 //TODO: the size of OS/2 servent is 2 bytes bigger
355 // so the original buffer *might* be too small
356 }
357 break;
358 }
359
360
361 /******************
362 * GETPROTOBYNAME *
363 ******************/
364 case ASYNCREQUEST_GETPROTOBYNAME:
365 {
366 dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
367 "WSAAyncGetProtoByName\n"));
368
369 if (rc == 0)
370 {
371 /* we need to convert the protoent structure here */
372 Wprotoent *WinProtoent = (Wprotoent*)pHM->pvUserData1;
373 protoent *OS2Protoent = (protoent*)pHM->pvUserData1;
374
375 WinProtoent->p_proto = OS2Protoent->p_proto;
376
377 //TODO: the size of OS/2 hostent is 2 bytes bigger
378 // so the original buffer *might* be too small
379 }
380 break;
381 }
382
383
384 /********************
385 * GETPROTOBYNUMBER *
386 ********************/
387 case ASYNCREQUEST_GETPROTOBYNUMBER:
388 {
389 dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
390 "WSAAyncGetProtoByNumber\n"));
391
392 if (rc == 0)
393 {
394 /* we need to convert the protoent structure here */
395 Wprotoent *WinProtoent = (Wprotoent*)pHM->pvUserData1;
396 protoent *OS2Protoent = (protoent*)pHM->pvUserData1;
397
398 WinProtoent->p_proto = OS2Protoent->p_proto;
399
400 //TODO: the size of OS/2 hostent is 2 bytes bigger
401 // so the original buffer *might* be too small
402 }
403 break;
404 }
405
406 default:
407 {
408 dprintf(("WSOCK32:RelayWindowProc, Unknown request type!!!"
409 "window: %d, msg: %d, mp1 %d, mp2%d\n", pHM->hwnd,
410 pHM->ulMsg, mp1, mp2));
411 break;
412 }
413 }
414
415
416// dprintf(("WSOCK32:RelayWinProc, Posting hwnd=%08xh, msg=%08xh, w=%08xh, l=%08xh\n",
417// pHM->hwnd,
418// pHM->ulMsg,
419// mp1,
420// mp2));
421
422 PostMessageA(pHM->hwnd,
423 pHM->ulMsg,
424 (ULONG)mp1,
425 (ULONG)mp2);
426
427 // if socket close or non-select call, free entry
428 // @@@PH
429 if (pHM->ulRequestType != ASYNCREQUEST_SELECT)
430 {
431 dprintf(("WSOCK32:RelayWindowProc, Free handle %d\n", pHM->ulMsg));
432 RelayFree(pHM->ulMsg);
433 }
434
435 return FALSE; // OK, message sent
436 }
437 else
438 {
439 dprintf(("WSOCK32:AsyncRelayWindowProc: Handle not found, message ignored %x %x %x %x", hwnd, ulMsg, mp1, mp2));
440 }
441
442 // default message processing
443 return WinDefWindowProc( hwnd, ulMsg, mp1, mp2 );
444}
445
446
447
448
449#if 0
450/*****************************************************************************
451 * Name :
452 * Purpose :
453 * Parameters:
454 * Variables :
455 * Result :
456 * Remark :
457 * Status :
458 *
459 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
460 *****************************************************************************/
461
462HWND RelayInitialize(HWND hwndPost)
463{
464 BOOL fSuccess;
465 HWND hwnd;
466
467
468 // thread initialization
469 hab = WinQueryAnchorBlock(hwndPost);
470 if (hab == NULLHANDLE)
471 return NULLHANDLE;
472
473
474 // register relay window class
475 fSuccess = WinRegisterClass(hab,
476 ODIN_WSOCK_RELAY_CLASS,
477 (PFNWP)RelayWindowProc,
478 0,
479 0);
480 if (fSuccess == FALSE)
481 return NULLHANDLE;
482
483 hwnd = WinCreateWindow(HWND_OBJECT,
484 ODIN_WSOCK_RELAY_CLASS,
485 "ODIN WSock Relay",
486 0, 0, 0, 0, 0,
487 HWND_OBJECT,
488 HWND_BOTTOM,
489 0,
490 NULL,
491 NULL );
492
493 //WinDestroyWindow( pg->hwndObject );
494 return hwnd;
495}
496
497#else
498
499/*****************************************************************************
500 * Name :
501 * Purpose :
502 * Parameters:
503 * Variables :
504 * Result :
505 * Remark :
506 * Status :
507 *
508 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
509 *****************************************************************************/
510
511
512//----------------------------------------------------------------------
513// thread 2 entry point: gets and dispatches object window messages
514// _Optlink is an IBM C Set/2 function modifier
515void _Optlink RelayThreadMain(PVOID pParameter)
516{
517 BOOL fSuccess;
518 HAB hab;
519 HMQ hmq;
520 QMSG qmsg;
521
522 // thread initialization
523 hab = WinInitialize( 0 );
524 hmq = WinCreateMsgQueue( hab, 0 );
525
526 // prevent system from posting object window a WM_QUIT
527 // I'll post WM_QUIT when it's time.
528 fSuccess = WinCancelShutdown( hmq, TRUE );
529 if (fSuccess != TRUE)
530 {
531 dprintf(("WSOCK32:RelayWin: ERROR WinCancelShutdown failed\n"));
532 return;
533 }
534
535 // register relay window class
536 fSuccess = WinRegisterClass(hab,
537 ODIN_WSOCK_RELAY_CLASS,
538 (PFNWP)RelayWindowProc,
539 0,
540 0);
541 if (fSuccess == FALSE)
542 {
543 dprintf(("WSOCK32:RelayWin: ERROR WinRegisterClass failed\n"));
544 return;
545 }
546
547 hwndRelay = WinCreateWindow(HWND_OBJECT,
548 ODIN_WSOCK_RELAY_CLASS,
549 "ODIN WSock Relay",
550 0, 0, 0, 0, 0,
551 HWND_OBJECT,
552 HWND_BOTTOM,
553 0,
554 NULL,
555 NULL );
556 if (hwndRelay == NULLHANDLE)
557 {
558 dprintf(("WSOCK32:RelayWin: ERROR WinCreateWindow failed\n"));
559 return;
560 }
561
562 // get/dispatch messages; user messages, for the most part
563 while( WinGetMsg ( hab, &qmsg, 0, 0, 0 ))
564 {
565 WinDispatchMsg ( hab, &qmsg );
566 }
567
568 // clean up
569 WinDestroyWindow( hwndRelay );
570 WinDestroyMsgQueue( hmq );
571 WinTerminate( hab );
572
573 // reset relay window handle
574 hwndRelay = NULLHANDLE;
575 return;
576}
577
578
579/*****************************************************************************
580 * Name :
581 * Purpose :
582 * Parameters:
583 * Variables :
584 * Result :
585 * Remark :
586 * Status :
587 *
588 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
589 *****************************************************************************/
590
591HWND RelayInitialize(HWND hwndPost)
592{
593 int tidRelay; // thread identifier
594
595 if (hwndRelay != NULLHANDLE)
596 {
597 // relay thread has been initialized
598 return hwndRelay;
599 }
600
601 // else create new subsystem
602 // create thread
603#if defined(__IBMCPP__)
604 tidRelay = _beginthread(RelayThreadMain,
605 NULL,
606 16384,
607 (PVOID)0);
608#else
609 tidRelay = _beginthread(RelayThreadMain,
610 16384,
611 (PVOID)0);
612#endif
613
614 // wait for thread to come up and send valid HWND
615 // @@@PH this is an ugly hack
616 dprintf(("WSOCK32:RELAYWIN:RelayInitialize wait for window handle\n"));
617 while (hwndRelay == NULL)
618 {
619 DosSleep(10);
620 }
621 dprintf(("WSOCK32:RELAYWIN:RelayInitialize window handle = %08xh",
622 hwndRelay));
623
624 return hwndRelay;
625}
626
627#endif
628
629
630/*****************************************************************************
631 * Name :
632 * Purpose :
633 * Parameters:
634 * Variables :
635 * Result :
636 * Remark :
637 * Status :
638 *
639 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
640 *****************************************************************************/
641
642BOOL RelayTerminate(HWND hwndRelay)
643{
644 return WinDestroyWindow(hwndRelay);
645}
646
Note: See TracBrowser for help on using the repository browser.