source: trunk/src/wsock32/new/relaywin.cpp@ 1952

Last change on this file since 1952 was 1952, checked in by phaller, 26 years ago

Add: created separate thread and message queue for WSOCK processign

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