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

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

put back old wsock32

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 if((ULONG)mp2 == 0x20) {
248 DebugInt3();
249 }
250 break;
251 }
252
253
254 /*****************
255 * GETHOSTBYNAME *
256 *****************/
257 case ASYNCREQUEST_GETHOSTBYNAME:
258 {
259 dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
260 "WSAAyncGetHostByName\n"));
261
262 /* is there a valid result ? */
263 if (rc == 0)
264 {
265 /* we need to convert the hostent structure here */
266 Whostent *WinHostent = (Whostent*)pHM->pvUserData1;
267 hostent *OS2Hostent = (hostent*)pHM->pvUserData1;
268
269 short h_addrtype = (short)OS2Hostent->h_addrtype;
270 WinHostent->h_addrtype = h_addrtype;
271 short h_length = (short)OS2Hostent->h_length;
272 WinHostent->h_length = h_length;
273 char **h_addr_list = OS2Hostent->h_addr_list;
274 WinHostent->h_addr_list = h_addr_list;
275 //TODO: the size of OS/2 hostent is 4 bytes bigger
276 // so the original buffer *might* be too small
277 }
278 break;
279 }
280
281
282 /*****************
283 * GETHOSTBYADDR *
284 *****************/
285 case ASYNCREQUEST_GETHOSTBYADDR:
286 {
287 dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
288 "WSAAyncGetHostByAddr\n"));
289
290 if (rc == 0)
291 {
292 dprintf(("WSOCK32:RelayWindowProc, hostent buffer: %d\n", pHM->pvUserData1));
293 /* we need to convert the hostent structure here */
294 Whostent *WinHostent = (Whostent*)pHM->pvUserData1;
295 hostent *OS2Hostent = (hostent*)pHM->pvUserData1;
296
297 short h_addrtype = (short)OS2Hostent->h_addrtype;
298 WinHostent->h_addrtype = h_addrtype;
299 short h_length = (short)OS2Hostent->h_length;
300 WinHostent->h_length = h_length;
301 char **h_addr_list = OS2Hostent->h_addr_list;
302 WinHostent->h_addr_list = h_addr_list;
303 //TODO: the size of OS/2 hostent is 4 bytes bigger
304 // so the original buffer *might* be too small
305 }
306 break;
307 }
308
309
310 /*****************
311 * GETSERVBYNAME *
312 *****************/
313 case ASYNCREQUEST_GETSERVBYNAME:
314 {
315 dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
316 "WSAAyncGetServByName\n"));
317
318 if (rc == 0)
319 {
320 /* we need to convert the servent structure here */
321 Wservent *WinServent = (Wservent*)pHM->pvUserData1;
322 servent *OS2Servent = (servent*)pHM->pvUserData1;
323
324 WinServent->s_port = OS2Servent->s_port;
325 WinServent->s_proto = OS2Servent->s_proto;
326 //TODO: the size of OS/2 servent is 2 bytes bigger
327 // so the original buffer *might* be too small
328 }
329 break;
330 }
331
332
333 /*****************
334 * GETSERVBYPORT *
335 *****************/
336 case ASYNCREQUEST_GETSERVBYPORT:
337 {
338 dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
339 "WSAAyncGetServByPort\n"));
340
341 if (rc == 0)
342 {
343 /* we need to convert the servent structure here */
344 Wservent *WinServent = (Wservent*)pHM->pvUserData1;
345 servent *OS2Servent = (servent*)pHM->pvUserData1;
346
347 WinServent->s_port = OS2Servent->s_port;
348 WinServent->s_proto = OS2Servent->s_proto;
349 //TODO: the size of OS/2 servent is 2 bytes bigger
350 // so the original buffer *might* be too small
351 }
352 break;
353 }
354
355
356 /******************
357 * GETPROTOBYNAME *
358 ******************/
359 case ASYNCREQUEST_GETPROTOBYNAME:
360 {
361 dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
362 "WSAAyncGetProtoByName\n"));
363
364 if (rc == 0)
365 {
366 /* we need to convert the protoent structure here */
367 Wprotoent *WinProtoent = (Wprotoent*)pHM->pvUserData1;
368 protoent *OS2Protoent = (protoent*)pHM->pvUserData1;
369
370 WinProtoent->p_proto = OS2Protoent->p_proto;
371
372 //TODO: the size of OS/2 hostent is 2 bytes bigger
373 // so the original buffer *might* be too small
374 }
375 break;
376 }
377
378
379 /********************
380 * GETPROTOBYNUMBER *
381 ********************/
382 case ASYNCREQUEST_GETPROTOBYNUMBER:
383 {
384 dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
385 "WSAAyncGetProtoByNumber\n"));
386
387 if (rc == 0)
388 {
389 /* we need to convert the protoent structure here */
390 Wprotoent *WinProtoent = (Wprotoent*)pHM->pvUserData1;
391 protoent *OS2Protoent = (protoent*)pHM->pvUserData1;
392
393 WinProtoent->p_proto = OS2Protoent->p_proto;
394
395 //TODO: the size of OS/2 hostent is 2 bytes bigger
396 // so the original buffer *might* be too small
397 }
398 break;
399 }
400
401 default:
402 {
403 dprintf(("WSOCK32:RelayWindowProc, Unknown request type!!!"
404 "window: %d, msg: %d, mp1 %d, mp2%d\n", pHM->hwnd,
405 pHM->ulMsg, mp1, mp2));
406 break;
407 }
408 }
409
410
411// dprintf(("WSOCK32:RelayWinProc, Posting hwnd=%08xh, msg=%08xh, w=%08xh, l=%08xh\n",
412// pHM->hwnd,
413// pHM->ulMsg,
414// mp1,
415// mp2));
416
417 PostMessageA(pHM->hwnd,
418 pHM->ulMsg,
419 (ULONG)mp1,
420 (ULONG)mp2);
421
422 // if socket close or non-select call, free entry
423 // @@@PH
424 if (pHM->ulRequestType != ASYNCREQUEST_SELECT)
425 {
426 dprintf(("WSOCK32:RelayWindowProc, Free handle %d\n", pHM->ulMsg));
427 RelayFree(pHM->ulMsg);
428 }
429
430 return FALSE; // OK, message sent
431 }
432 else
433 {
434 dprintf(("WSOCK32:AsyncRelayWindowProc: Handle not found, message ignored %x %x %x %x", hwnd, ulMsg, mp1, mp2));
435 }
436
437 // default message processing
438 return WinDefWindowProc( hwnd, ulMsg, mp1, mp2 );
439}
440
441
442
443
444#if 0
445/*****************************************************************************
446 * Name :
447 * Purpose :
448 * Parameters:
449 * Variables :
450 * Result :
451 * Remark :
452 * Status :
453 *
454 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
455 *****************************************************************************/
456
457HWND RelayInitialize(HWND hwndPost)
458{
459 BOOL fSuccess;
460 HWND hwnd;
461
462
463 // thread initialization
464 hab = WinQueryAnchorBlock(hwndPost);
465 if (hab == NULLHANDLE)
466 return NULLHANDLE;
467
468
469 // register relay window class
470 fSuccess = WinRegisterClass(hab,
471 ODIN_WSOCK_RELAY_CLASS,
472 (PFNWP)RelayWindowProc,
473 0,
474 0);
475 if (fSuccess == FALSE)
476 return NULLHANDLE;
477
478 hwnd = WinCreateWindow(HWND_OBJECT,
479 ODIN_WSOCK_RELAY_CLASS,
480 "ODIN WSock Relay",
481 0, 0, 0, 0, 0,
482 HWND_OBJECT,
483 HWND_BOTTOM,
484 0,
485 NULL,
486 NULL );
487
488 //WinDestroyWindow( pg->hwndObject );
489 return hwnd;
490}
491
492#else
493
494/*****************************************************************************
495 * Name :
496 * Purpose :
497 * Parameters:
498 * Variables :
499 * Result :
500 * Remark :
501 * Status :
502 *
503 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
504 *****************************************************************************/
505
506
507//----------------------------------------------------------------------
508// thread 2 entry point: gets and dispatches object window messages
509// _Optlink is an IBM C Set/2 function modifier
510void _Optlink RelayThreadMain(PVOID pParameter)
511{
512 BOOL fSuccess;
513 HAB hab;
514 HMQ hmq;
515 QMSG qmsg;
516
517 // thread initialization
518 hab = WinInitialize( 0 );
519 hmq = WinCreateMsgQueue( hab, 0 );
520
521 // prevent system from posting object window a WM_QUIT
522 // I'll post WM_QUIT when it's time.
523 fSuccess = WinCancelShutdown( hmq, TRUE );
524 if (fSuccess != TRUE)
525 {
526 dprintf(("WSOCK32:RelayWin: ERROR WinCancelShutdown failed\n"));
527 return;
528 }
529
530 // register relay window class
531 fSuccess = WinRegisterClass(hab,
532 ODIN_WSOCK_RELAY_CLASS,
533 (PFNWP)RelayWindowProc,
534 0,
535 0);
536 if (fSuccess == FALSE)
537 {
538 dprintf(("WSOCK32:RelayWin: ERROR WinRegisterClass failed\n"));
539 return;
540 }
541
542 hwndRelay = WinCreateWindow(HWND_OBJECT,
543 ODIN_WSOCK_RELAY_CLASS,
544 "ODIN WSock Relay",
545 0, 0, 0, 0, 0,
546 HWND_OBJECT,
547 HWND_BOTTOM,
548 0,
549 NULL,
550 NULL );
551 if (hwndRelay == NULLHANDLE)
552 {
553 dprintf(("WSOCK32:RelayWin: ERROR WinCreateWindow failed\n"));
554 return;
555 }
556
557 // get/dispatch messages; user messages, for the most part
558 while( WinGetMsg ( hab, &qmsg, 0, 0, 0 ))
559 {
560 WinDispatchMsg ( hab, &qmsg );
561 }
562
563 // clean up
564 WinDestroyWindow( hwndRelay );
565 WinDestroyMsgQueue( hmq );
566 WinTerminate( hab );
567
568 // reset relay window handle
569 hwndRelay = NULLHANDLE;
570 return;
571}
572
573
574/*****************************************************************************
575 * Name :
576 * Purpose :
577 * Parameters:
578 * Variables :
579 * Result :
580 * Remark :
581 * Status :
582 *
583 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
584 *****************************************************************************/
585
586HWND RelayInitialize(HWND hwndPost)
587{
588 int tidRelay; // thread identifier
589
590 if (hwndRelay != NULLHANDLE)
591 {
592 // relay thread has been initialized
593 return hwndRelay;
594 }
595
596 // else create new subsystem
597 // create thread
598#if defined(__IBMCPP__)
599 tidRelay = _beginthread(RelayThreadMain,
600 NULL,
601 16384,
602 (PVOID)0);
603#else
604 tidRelay = _beginthread(RelayThreadMain,
605 16384,
606 (PVOID)0);
607#endif
608
609 // wait for thread to come up and send valid HWND
610 // @@@PH this is an ugly hack
611 dprintf(("WSOCK32:RELAYWIN:RelayInitialize wait for window handle\n"));
612 while (hwndRelay == NULL)
613 {
614 DosSleep(10);
615 }
616 dprintf(("WSOCK32:RELAYWIN:RelayInitialize window handle = %08xh",
617 hwndRelay));
618
619 return hwndRelay;
620}
621
622#endif
623
624
625/*****************************************************************************
626 * Name :
627 * Purpose :
628 * Parameters:
629 * Variables :
630 * Result :
631 * Remark :
632 * Status :
633 *
634 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
635 *****************************************************************************/
636
637BOOL RelayTerminate(HWND hwndRelay)
638{
639 return WinDestroyWindow(hwndRelay);
640}
641
Note: See TracBrowser for help on using the repository browser.