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

Last change on this file since 2013 was 2013, checked in by achimha, 26 years ago

promoted new wsock32 as default

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 } else
418 {
419 dprintf(("WSOCK32:AsyncRelayWindowProc: Handle not found, message ignored\n"));
420 }
421
422 // default message processing
423 return WinDefWindowProc( hwnd, ulMsg, mp1, mp2 );
424}
425
426
427
428
429#if 0
430/*****************************************************************************
431 * Name :
432 * Purpose :
433 * Parameters:
434 * Variables :
435 * Result :
436 * Remark :
437 * Status :
438 *
439 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
440 *****************************************************************************/
441
442HWND RelayInitialize(HWND hwndPost)
443{
444 BOOL fSuccess;
445 HAB hab;
446 HWND hwnd;
447
448
449 // thread initialization
450 hab = WinQueryAnchorBlock(hwndPost);
451 if (hab == NULLHANDLE)
452 return NULLHANDLE;
453
454
455 // register relay window class
456 fSuccess = WinRegisterClass(hab,
457 ODIN_WSOCK_RELAY_CLASS,
458 (PFNWP)RelayWindowProc,
459 0,
460 0);
461 if (fSuccess == FALSE)
462 return NULLHANDLE;
463
464 hwnd = WinCreateWindow(HWND_OBJECT,
465 ODIN_WSOCK_RELAY_CLASS,
466 "ODIN WSock Relay",
467 0, 0, 0, 0, 0,
468 HWND_OBJECT,
469 HWND_BOTTOM,
470 0,
471 NULL,
472 NULL );
473
474 //WinDestroyWindow( pg->hwndObject );
475 return hwnd;
476}
477
478#else
479
480/*****************************************************************************
481 * Name :
482 * Purpose :
483 * Parameters:
484 * Variables :
485 * Result :
486 * Remark :
487 * Status :
488 *
489 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
490 *****************************************************************************/
491
492
493//----------------------------------------------------------------------
494// thread 2 entry point: gets and dispatches object window messages
495// _Optlink is an IBM C Set/2 function modifier
496void _Optlink RelayThreadMain(PVOID pParameter)
497{
498 BOOL fSuccess;
499 HAB hab;
500 HMQ hmq;
501 QMSG qmsg;
502
503 // thread initialization
504 hab = WinInitialize( 0 );
505 hmq = WinCreateMsgQueue( hab, 0 );
506
507 // prevent system from posting object window a WM_QUIT
508 // I'll post WM_QUIT when it's time.
509 fSuccess = WinCancelShutdown( hmq, TRUE );
510 if (fSuccess != TRUE)
511 {
512 dprintf(("WSOCK32:RelayWin: ERROR WinCancelShutdown failed\n"));
513 return;
514 }
515
516 // register relay window class
517 fSuccess = WinRegisterClass(hab,
518 ODIN_WSOCK_RELAY_CLASS,
519 (PFNWP)RelayWindowProc,
520 0,
521 0);
522 if (fSuccess == FALSE)
523 {
524 dprintf(("WSOCK32:RelayWin: ERROR WinRegisterClass failed\n"));
525 return;
526 }
527
528 hwndRelay = WinCreateWindow(HWND_OBJECT,
529 ODIN_WSOCK_RELAY_CLASS,
530 "ODIN WSock Relay",
531 0, 0, 0, 0, 0,
532 HWND_OBJECT,
533 HWND_BOTTOM,
534 0,
535 NULL,
536 NULL );
537 if (hwndRelay == NULLHANDLE)
538 {
539 dprintf(("WSOCK32:RelayWin: ERROR WinCreateWindow failed\n"));
540 return;
541 }
542
543 // get/dispatch messages; user messages, for the most part
544 while( WinGetMsg ( hab, &qmsg, 0, 0, 0 ))
545 {
546 WinDispatchMsg ( hab, &qmsg );
547 }
548
549 // clean up
550 WinDestroyWindow( hwndRelay );
551 WinDestroyMsgQueue( hmq );
552 WinTerminate( hab );
553
554 // reset relay window handle
555 hwndRelay = NULLHANDLE;
556 return;
557}
558
559
560/*****************************************************************************
561 * Name :
562 * Purpose :
563 * Parameters:
564 * Variables :
565 * Result :
566 * Remark :
567 * Status :
568 *
569 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
570 *****************************************************************************/
571
572HWND RelayInitialize(HWND hwndPost)
573{
574 int tidRelay; // thread identifier
575
576 if (hwndRelay != NULLHANDLE)
577 {
578 // relay thread has been initialized
579 return hwndRelay;
580 }
581
582 // else create new subsystem
583 // create thread
584#if defined(__IBMCPP__)
585 tidRelay = _beginthread(RelayThreadMain,
586 NULL,
587 16384,
588 (PVOID)0);
589#else
590 tidRelay = _beginthread(RelayThreadMain,
591 16384,
592 (PVOID)0);
593#endif
594
595 // wait for thread to come up and send valid HWND
596 // @@@PH this is an ugly hack
597 dprintf(("WSOCK32:RELAYWIN:RelayInitialize wait for window handle\n"));
598 while (hwndRelay == NULL)
599 {
600 DosSleep(10);
601 }
602 dprintf(("WSOCK32:RELAYWIN:RelayInitialize window handle = %08xh",
603 hwndRelay));
604
605 return hwndRelay;
606}
607
608#endif
609
610
611/*****************************************************************************
612 * Name :
613 * Purpose :
614 * Parameters:
615 * Variables :
616 * Result :
617 * Remark :
618 * Status :
619 *
620 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
621 *****************************************************************************/
622
623BOOL RelayTerminate(HWND hwndRelay)
624{
625 return WinDestroyWindow(hwndRelay);
626}
627
Note: See TracBrowser for help on using the repository browser.