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

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

WSAAsyncSelect fix

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