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

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

extended relay structure

File size: 16.4 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 pHM = RelayQuery(ulMsg); // find registered message
217 if (pHM != NULL) // message pair found
218 {
219 rc = SHORT1FROMMP(mp2); /* asynchronous operation result */
220
221 /* check request type for special handling */
222 switch (pHM->ulRequestType)
223 {
224 /**********
225 * SELECT *
226 **********/
227 case ASYNCREQUEST_SELECT:
228 {
229 dprintf(("WSOCK32:RelayWindowProc, AsyncSelect notification\n"));
230 break;
231 }
232
233
234 /*****************
235 * GETHOSTBYNAME *
236 *****************/
237 case ASYNCREQUEST_GETHOSTBYNAME:
238 {
239 dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
240 "WSAAyncGetHostByName\n"));
241
242 /* is there a valid result ? */
243 if (rc == 0)
244 {
245 /* we need to convert the hostent structure here */
246 Whostent *WinHostent = (Whostent*)pHM->pvUserData1;
247 hostent *OS2Hostent = (hostent*)pHM->pvUserData1;
248
249 short h_addrtype = (short)OS2Hostent->h_addrtype;
250 WinHostent->h_addrtype = h_addrtype;
251 short h_length = (short)OS2Hostent->h_length;
252 WinHostent->h_length = h_length;
253 char **h_addr_list = OS2Hostent->h_addr_list;
254 WinHostent->h_addr_list = h_addr_list;
255 //TODO: the size of OS/2 hostent is 4 bytes bigger
256 // so the original buffer *might* be too small
257 }
258 break;
259 }
260
261
262 /*****************
263 * GETHOSTBYADDR *
264 *****************/
265 case ASYNCREQUEST_GETHOSTBYADDR:
266 {
267 dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
268 "WSAAyncGetHostByAddr\n"));
269
270 if (rc == 0)
271 {
272 /* we need to convert the hostent structure here */
273 Whostent *WinHostent = (Whostent*)pHM->pvUserData1;
274 hostent *OS2Hostent = (hostent*)pHM->pvUserData1;
275
276 short h_addrtype = (short)OS2Hostent->h_addrtype;
277 WinHostent->h_addrtype = h_addrtype;
278 short h_length = (short)OS2Hostent->h_length;
279 WinHostent->h_length = h_length;
280 char **h_addr_list = OS2Hostent->h_addr_list;
281 WinHostent->h_addr_list = h_addr_list;
282 //TODO: the size of OS/2 hostent is 4 bytes bigger
283 // so the original buffer *might* be too small
284 }
285 break;
286 }
287
288
289 /*****************
290 * GETSERVBYNAME *
291 *****************/
292 case ASYNCREQUEST_GETSERVBYNAME:
293 {
294 dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
295 "WSAAyncGetServByName\n"));
296
297 if (rc == 0)
298 {
299 /* we need to convert the servent structure here */
300 Wservent *WinServent = (Wservent*)pHM->pvUserData1;
301 servent *OS2Servent = (servent*)pHM->pvUserData1;
302
303 WinServent->s_port = OS2Servent->s_port;
304 WinServent->s_proto = OS2Servent->s_proto;
305 //TODO: the size of OS/2 servent is 2 bytes bigger
306 // so the original buffer *might* be too small
307 }
308 break;
309 }
310
311
312 /*****************
313 * GETSERVBYPORT *
314 *****************/
315 case ASYNCREQUEST_GETSERVBYPORT:
316 {
317 dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
318 "WSAAyncGetServByPort\n"));
319
320 if (rc == 0)
321 {
322 /* we need to convert the servent structure here */
323 Wservent *WinServent = (Wservent*)pHM->pvUserData1;
324 servent *OS2Servent = (servent*)pHM->pvUserData1;
325
326 WinServent->s_port = OS2Servent->s_port;
327 WinServent->s_proto = OS2Servent->s_proto;
328 //TODO: the size of OS/2 servent is 2 bytes bigger
329 // so the original buffer *might* be too small
330 }
331 break;
332 }
333
334
335 /******************
336 * GETPROTOBYNAME *
337 ******************/
338 case ASYNCREQUEST_GETPROTOBYNAME:
339 {
340 dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
341 "WSAAyncGetProtoByName\n"));
342
343 if (rc == 0)
344 {
345 /* we need to convert the protoent structure here */
346 Wprotoent *WinProtoent = (Wprotoent*)pHM->pvUserData1;
347 protoent *OS2Protoent = (protoent*)pHM->pvUserData1;
348
349 WinProtoent->p_proto = OS2Protoent->p_proto;
350
351 //TODO: the size of OS/2 hostent is 2 bytes bigger
352 // so the original buffer *might* be too small
353 }
354 break;
355 }
356
357
358 /********************
359 * GETPROTOBYNUMBER *
360 ********************/
361 case ASYNCREQUEST_GETPROTOBYNUMBER:
362 {
363 dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
364 "WSAAyncGetProtoByNumber\n"));
365
366 if (rc == 0)
367 {
368 /* we need to convert the protoent structure here */
369 Wprotoent *WinProtoent = (Wprotoent*)pHM->pvUserData1;
370 protoent *OS2Protoent = (protoent*)pHM->pvUserData1;
371
372 WinProtoent->p_proto = OS2Protoent->p_proto;
373
374 //TODO: the size of OS/2 hostent is 2 bytes bigger
375 // so the original buffer *might* be too small
376 }
377 break;
378 }
379 }
380
381
382 dprintf(("WSOCK32:RelayWinProc, Posting hwnd=%08xh, msg=%08xh, w=%08xh, l=%08xh\n",
383 pHM->hwnd,
384 pHM->ulMsg,
385 mp1,
386 mp2));
387
388 PostMessageA(pHM->hwnd,
389 pHM->ulMsg,
390 (ULONG)mp1,
391 (ULONG)mp2);
392
393 // if socket close or non-select call, free entry
394 // @@@PH
395 if (pHM->ulRequestType != ASYNCREQUEST_SELECT)
396 RelayFree(pHM->ulMsg);
397
398 return FALSE; // OK, message sent
399 }
400
401 // default message processing
402 return WinDefWindowProc( hwnd, ulMsg, mp1, mp2 );
403}
404
405
406
407
408#if 0
409/*****************************************************************************
410 * Name :
411 * Purpose :
412 * Parameters:
413 * Variables :
414 * Result :
415 * Remark :
416 * Status :
417 *
418 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
419 *****************************************************************************/
420
421HWND RelayInitialize(HWND hwndPost)
422{
423 BOOL fSuccess;
424 HAB hab;
425 HWND hwnd;
426
427
428 // thread initialization
429 hab = WinQueryAnchorBlock(hwndPost);
430 if (hab == NULLHANDLE)
431 return NULLHANDLE;
432
433
434 // register relay window class
435 fSuccess = WinRegisterClass(hab,
436 ODIN_WSOCK_RELAY_CLASS,
437 (PFNWP)RelayWindowProc,
438 0,
439 0);
440 if (fSuccess == FALSE)
441 return NULLHANDLE;
442
443 hwnd = WinCreateWindow(HWND_OBJECT,
444 ODIN_WSOCK_RELAY_CLASS,
445 "ODIN WSock Relay",
446 0, 0, 0, 0, 0,
447 HWND_OBJECT,
448 HWND_BOTTOM,
449 0,
450 NULL,
451 NULL );
452
453 //WinDestroyWindow( pg->hwndObject );
454 return hwnd;
455}
456
457#else
458
459/*****************************************************************************
460 * Name :
461 * Purpose :
462 * Parameters:
463 * Variables :
464 * Result :
465 * Remark :
466 * Status :
467 *
468 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
469 *****************************************************************************/
470
471
472//----------------------------------------------------------------------
473// thread 2 entry point: gets and dispatches object window messages
474// _Optlink is an IBM C Set/2 function modifier
475void _Optlink RelayThreadMain(PVOID pParameter)
476{
477 BOOL fSuccess;
478 HAB hab;
479 HMQ hmq;
480 QMSG qmsg;
481
482 // thread initialization
483 hab = WinInitialize( 0 );
484 hmq = WinCreateMsgQueue( hab, 0 );
485
486 // prevent system from posting object window a WM_QUIT
487 // I'll post WM_QUIT when it's time.
488 fSuccess = WinCancelShutdown( hmq, TRUE );
489 if (fSuccess != TRUE)
490 {
491 dprintf(("WSOCK32:RelayWin: ERROR WinCancelShutdown failed\n"));
492 return;
493 }
494
495 // register relay window class
496 fSuccess = WinRegisterClass(hab,
497 ODIN_WSOCK_RELAY_CLASS,
498 (PFNWP)RelayWindowProc,
499 0,
500 0);
501 if (fSuccess == FALSE)
502 {
503 dprintf(("WSOCK32:RelayWin: ERROR WinRegisterClass failed\n"));
504 return;
505 }
506
507 hwndRelay = WinCreateWindow(HWND_OBJECT,
508 ODIN_WSOCK_RELAY_CLASS,
509 "ODIN WSock Relay",
510 0, 0, 0, 0, 0,
511 HWND_OBJECT,
512 HWND_BOTTOM,
513 0,
514 NULL,
515 NULL );
516 if (hwndRelay == NULLHANDLE)
517 {
518 dprintf(("WSOCK32:RelayWin: ERROR WinCreateWindow failed\n"));
519 return;
520 }
521
522 // get/dispatch messages; user messages, for the most part
523 while( WinGetMsg ( hab, &qmsg, 0, 0, 0 ))
524 {
525 WinDispatchMsg ( hab, &qmsg );
526 }
527
528 // clean up
529 WinDestroyWindow( hwndRelay );
530 WinDestroyMsgQueue( hmq );
531 WinTerminate( hab );
532
533 // reset relay window handle
534 hwndRelay = NULLHANDLE;
535 return;
536}
537
538
539/*****************************************************************************
540 * Name :
541 * Purpose :
542 * Parameters:
543 * Variables :
544 * Result :
545 * Remark :
546 * Status :
547 *
548 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
549 *****************************************************************************/
550
551HWND RelayInitialize(HWND hwndPost)
552{
553 int tidRelay; // thread identifier
554
555 if (hwndRelay != NULLHANDLE)
556 {
557 // relay thread has been initialized
558 return hwndRelay;
559 }
560
561 // else create new subsystem
562 // create thread
563#if defined(__IBMCPP__)
564 tidRelay = _beginthread(RelayThreadMain,
565 NULL,
566 16384,
567 (PVOID)0);
568#else
569 tidRelay = _beginthread(RelayThreadMain,
570 16384,
571 (PVOID)0);
572#endif
573
574 // wait for thread to come up and send valid HWND
575 // @@@PH this is an ugly hack
576 dprintf(("WSOCK32:RELAYWIN:RelayInitialize wait for window handle\n"));
577 while (hwndRelay == NULL)
578 {
579 DosSleep(10);
580 }
581 dprintf(("WSOCK32:RELAYWIN:RelayInitialize window handle = %08xh",
582 hwndRelay));
583
584 return hwndRelay;
585}
586
587#endif
588
589
590/*****************************************************************************
591 * Name :
592 * Purpose :
593 * Parameters:
594 * Variables :
595 * Result :
596 * Remark :
597 * Status :
598 *
599 * Author : Patrick Haller [Tue, 1999/11/30 23:00]
600 *****************************************************************************/
601
602BOOL RelayTerminate(HWND hwndRelay)
603{
604 return WinDestroyWindow(hwndRelay);
605}
606
Note: See TracBrowser for help on using the repository browser.