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

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

setsockopt bugfix (SO_LINGER)

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