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

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

changed setsockopt bugfix

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