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

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

* empty log message *

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