Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

893 lines
23 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Wsraw.h
  5. Abstract:
  6. Support for extended winsock calls for WOW.
  7. Author:
  8. David Treadwell (davidtr) 02-Oct-1992
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #include "wsdynmc.h"
  14. DLLENTRYPOINTS wsockapis[WOW_WSOCKAPI_COUNT] = {
  15. (char *) 1, NULL,
  16. (char *) 2, NULL,
  17. (char *) 3, NULL,
  18. (char *) 4, NULL,
  19. (char *) 5, NULL,
  20. (char *) 6, NULL,
  21. (char *) 7, NULL,
  22. (char *) 8, NULL,
  23. (char *) 9, NULL,
  24. (char *) 10, NULL,
  25. (char *) 11, NULL,
  26. (char *) 12, NULL,
  27. (char *) 13, NULL,
  28. (char *) 14, NULL,
  29. (char *) 15, NULL,
  30. (char *) 16, NULL,
  31. (char *) 17, NULL,
  32. (char *) 18, NULL,
  33. (char *) 19, NULL,
  34. (char *) 20, NULL,
  35. (char *) 21, NULL,
  36. (char *) 22, NULL,
  37. (char *) 23, NULL,
  38. (char *) 51, NULL,
  39. (char *) 52, NULL,
  40. (char *) 53, NULL,
  41. (char *) 54, NULL,
  42. (char *) 55, NULL,
  43. (char *) 56, NULL,
  44. (char *) 57, NULL,
  45. (char *) 101, NULL,
  46. (char *) 102, NULL,
  47. (char *) 103, NULL,
  48. (char *) 104, NULL,
  49. (char *) 105, NULL,
  50. (char *) 106, NULL,
  51. (char *) 107, NULL,
  52. (char *) 108, NULL,
  53. (char *) 109, NULL,
  54. (char *) 110, NULL,
  55. (char *) 111, NULL,
  56. (char *) 112, NULL,
  57. (char *) 113, NULL,
  58. (char *) 114, NULL,
  59. (char *) 115, NULL,
  60. (char *) 116, NULL,
  61. (char *) 151, NULL,
  62. (char *) 1000, NULL,
  63. (char *) 1107, NULL};
  64. DWORD WWS32TlsSlot = 0xFFFFFFFF;
  65. RTL_CRITICAL_SECTION WWS32CriticalSection;
  66. BOOL WWS32Initialized = FALSE;
  67. LIST_ENTRY WWS32AsyncContextBlockListHead;
  68. WORD WWS32AsyncTaskHandleCounter;
  69. DWORD WWS32ThreadSerialNumberCounter;
  70. HINSTANCE hInstWSOCK32;
  71. DWORD
  72. WWS32CallBackHandler (
  73. VOID
  74. );
  75. BOOL
  76. WWS32DefaultBlockingHook (
  77. VOID
  78. );
  79. /*++
  80. GENERIC FUNCTION PROTOTYPE:
  81. ==========================
  82. ULONG FASTCALL WWS32<function name>(PVDMFRAME pFrame)
  83. {
  84. ULONG ul;
  85. register P<function name>16 parg16;
  86. GETARGPTR(pFrame, sizeof(<function name>16), parg16);
  87. <get any other required pointers into 16 bit space>
  88. ALLOCVDMPTR
  89. GETVDMPTR
  90. GETMISCPTR
  91. et cetera
  92. <copy any complex structures from 16 bit -> 32 bit space>
  93. <ALWAYS use the FETCHxxx macros>
  94. ul = GET<return type>16(<function name>(parg16->f1,
  95. :
  96. :
  97. parg16->f<n>);
  98. <copy any complex structures from 32 -> 16 bit space>
  99. <ALWAYS use the STORExxx macros>
  100. <free any pointers to 16 bit space you previously got>
  101. <flush any areas of 16 bit memory if they were written to>
  102. FLUSHVDMPTR
  103. FREEARGPTR(parg16);
  104. RETURN(ul);
  105. }
  106. NOTE:
  107. The VDM frame is automatically set up, with all the function parameters
  108. available via parg16->f<number>.
  109. Handles must ALWAYS be mapped for 16 -> 32 -> 16 space via the mapping tables
  110. laid out in WALIAS.C.
  111. Any storage you allocate must be freed (eventually...).
  112. Further to that - if a thunk which allocates memory fails in the 32 bit call
  113. then it must free that memory.
  114. Also, never update structures in 16 bit land if the 32 bit call fails.
  115. Be aware that the GETxxxPTR macros return the CURRENT selector-to-flat_memory
  116. mapping. Calls to some 32-bit functions may indirectly cause callbacks into
  117. 16-bit code. These may cause 16-bit memory to move due to allocations
  118. made in 16-bit land. If the 16-bit memory does move, the corresponding 32-bit
  119. ptr in WOW32 needs to be refreshed to reflect the NEW selector-to-flat_memory
  120. mapping.
  121. --*/
  122. ULONG FASTCALL WWS32WSAAsyncSelect(PVDMFRAME pFrame)
  123. {
  124. ULONG ul;
  125. register PWSAASYNCSELECT16 parg16;
  126. SOCKET s32;
  127. if ( !WWS32IsThreadInitialized ) {
  128. SetLastError( WSANOTINITIALISED );
  129. RETURN((ULONG)SOCKET_ERROR);
  130. }
  131. GETARGPTR(pFrame, sizeof(WSAASYNCSELECT16), parg16);
  132. //
  133. // Find the 32-bit socket handle.
  134. //
  135. s32 = GetWinsock32( parg16->hSocket );
  136. if ( s32 == INVALID_SOCKET ) {
  137. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOTSOCK );
  138. ul = (ULONG)GETWORD16( SOCKET_ERROR );
  139. } else {
  140. ul = GETWORD16( (*wsockapis[WOW_WSAASYNCSELECT].lpfn)(
  141. s32,
  142. (HWND)HWND32(parg16->hWnd),
  143. (parg16->wMsg << 16) | WWS32_MESSAGE_ASYNC_SELECT,
  144. parg16->lEvent
  145. ));
  146. }
  147. FREEARGPTR(parg16);
  148. RETURN(ul);
  149. } // WWS32WSAAsyncSelect
  150. ULONG FASTCALL WWS32WSASetBlockingHook(PVDMFRAME pFrame)
  151. {
  152. ULONG ul;
  153. VPWNDPROC vpBlockFunc;
  154. //FARPROC previousHook;
  155. register PWSASETBLOCKINGHOOK16 parg16;
  156. GETARGPTR(pFrame, sizeof(WSASETBLOCKINGHOOK16), parg16);
  157. vpBlockFunc = parg16->lpBlockFunc;
  158. if ( !WWS32IsThreadInitialized ) {
  159. SetLastError( WSANOTINITIALISED );
  160. RETURN((ULONG)NULL);
  161. }
  162. if ( (*wsockapis[WOW_WSAISBLOCKING].lpfn)( ) ) {
  163. SetLastError( WSAEINPROGRESS );
  164. RETURN((ULONG)NULL);
  165. }
  166. ul = WWS32vBlockingHook;
  167. WWS32vBlockingHook = vpBlockFunc;
  168. FREEARGPTR( parg16 );
  169. RETURN(ul);
  170. } // WWS32WSASetBlockingHook
  171. ULONG FASTCALL WWS32WSAUnhookBlockingHook(PVDMFRAME pFrame)
  172. {
  173. if ( !WWS32IsThreadInitialized ) {
  174. SetLastError( WSANOTINITIALISED );
  175. RETURN((ULONG)SOCKET_ERROR);
  176. }
  177. if ( (*wsockapis[WOW_WSAISBLOCKING].lpfn)() ) {
  178. SetLastError( WSAEINPROGRESS );
  179. RETURN((ULONG)SOCKET_ERROR);
  180. }
  181. WWS32vBlockingHook = WWS32_DEFAULT_BLOCKING_HOOK;
  182. RETURN(0);
  183. } // WWS32WSAUnhookBlockingHook
  184. ULONG FASTCALL WWS32WSAGetLastError(PVDMFRAME pFrame)
  185. {
  186. ULONG ul;
  187. ul = GETWORD16( (*wsockapis[WOW_WSAGETLASTERROR].lpfn)( ) );
  188. RETURN(ul);
  189. } // WWS32WSAGetLastError
  190. ULONG FASTCALL WWS32WSASetLastError(PVDMFRAME pFrame)
  191. {
  192. register PWSASETLASTERROR16 parg16;
  193. GETARGPTR(pFrame, sizeof(WSASETLASTERROR16), parg16);
  194. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( FETCHWORD( parg16->Error ) );
  195. FREEARGPTR(parg16);
  196. RETURN(0);
  197. } // WWS32WSASetLastError
  198. ULONG FASTCALL WWS32WSACancelBlockingCall(PVDMFRAME pFrame)
  199. {
  200. ULONG ul;
  201. if ( !WWS32IsThreadInitialized ) {
  202. SetLastError( WSANOTINITIALISED );
  203. RETURN((ULONG)SOCKET_ERROR);
  204. }
  205. ul = GETWORD16((*wsockapis[WOW_WSACANCELBLOCKINGCALL].lpfn)( ));
  206. RETURN(ul);
  207. } // WWS32WSACancelBlockingCall
  208. ULONG FASTCALL WWS32WSAIsBlocking(PVDMFRAME pFrame)
  209. {
  210. ULONG ul;
  211. if ( !WWS32IsThreadInitialized ) {
  212. SetLastError( WSANOTINITIALISED );
  213. RETURN((ULONG)FALSE);
  214. }
  215. ul = GETWORD16((*wsockapis[WOW_WSAISBLOCKING].lpfn)( ));
  216. RETURN(ul);
  217. } // WWS32WSAIsBlocking
  218. ULONG FASTCALL WWS32WSAStartup(PVDMFRAME pFrame)
  219. {
  220. ULONG ul = 0;
  221. register PWSASTARTUP16 parg16;
  222. PWSADATA16 wsaData16;
  223. PWINSOCK_THREAD_DATA data;
  224. NTSTATUS status;
  225. FARPROC previousHook;
  226. PSZ description;
  227. PSZ systemStatus;
  228. WORD versionRequested;
  229. VPWSADATA16 vpwsaData16;
  230. GETARGPTR(pFrame, sizeof(WSASTARTUP16), parg16);
  231. vpwsaData16 = parg16->lpWSAData;
  232. versionRequested = INT32(parg16->wVersionRequired);
  233. //
  234. // If winsock has not yet been initialized, initialize data structures
  235. // now.
  236. //
  237. if ( !WWS32Initialized ) {
  238. WSADATA wsaData;
  239. InitializeListHead( &WWS32AsyncContextBlockListHead );
  240. InitializeListHead( &WWS32SocketHandleListHead );
  241. WWS32AsyncTaskHandleCounter = 1;
  242. WWS32SocketHandleCounter = 1;
  243. WWS32SocketHandleCounterWrapped = FALSE;
  244. WWS32ThreadSerialNumberCounter = 1;
  245. //
  246. // Load WSOCK32.DLL and initialize all the entry points.
  247. //
  248. if (!LoadLibraryAndGetProcAddresses ("WSOCK32.DLL", wsockapis, WOW_WSOCKAPI_COUNT)) {
  249. LOGDEBUG (LOG_ALWAYS, ("WOW::WWS32WSAStartup: LoadLibrary failed\n"));
  250. ul = GETWORD16(WSAENOBUFS);
  251. return (ul);
  252. }
  253. //
  254. // Initialize the ntvdm process to the 32-bit Windows Sockets
  255. // DLL.
  256. //
  257. ul = (*wsockapis[WOW_WSASTARTUP].lpfn)( MAKEWORD( 1, 1 ), &wsaData );
  258. if ( ul != NO_ERROR ) {
  259. RETURN(ul);
  260. }
  261. //
  262. // Initialize the critical section we'll use for synchronizing
  263. // async requests.
  264. //
  265. status = RtlInitializeCriticalSection( &WWS32CriticalSection );
  266. if ( !NT_SUCCESS(status) ) {
  267. ul = GETWORD16(WSAENOBUFS);
  268. RETURN(ul);
  269. }
  270. //
  271. // Get a slot in TLS.
  272. //
  273. WWS32TlsSlot = TlsAlloc( );
  274. if ( WWS32TlsSlot == 0xFFFFFFFF ) {
  275. RtlDeleteCriticalSection( &WWS32CriticalSection );
  276. ul = GETWORD16(WSAENOBUFS);
  277. RETURN(ul);
  278. }
  279. WWS32Initialized = TRUE;
  280. }
  281. //
  282. // Make sure that we're not in a blocking call.
  283. //
  284. if ( (*wsockapis[WOW_WSAISBLOCKING].lpfn)( ) ) {
  285. RETURN((ULONG)WSAEINPROGRESS);
  286. }
  287. //
  288. // If this thread has not already had a WSAStartup() call, allocate
  289. // and initialize per-thread data.
  290. //
  291. if ( !WWS32IsThreadInitialized ) {
  292. //
  293. // We support versions 1.0 and 1.1 of the Windows Sockets
  294. // specification. If the requested version is below that, fail.
  295. //
  296. if ( LOBYTE(versionRequested) < 1 ) {
  297. ul = WSAVERNOTSUPPORTED;
  298. RETURN(ul);
  299. }
  300. //
  301. // Allocate space for the per-thread data that we need. Note that
  302. // we set the value in the TSL slot regardless of whether we actually
  303. // managed to allocate the memory--this is because we want NULL
  304. // in the TLS slot if we couldn't properly allocate the storage.
  305. //
  306. data = malloc_w( sizeof(*data) );
  307. if ( !TlsSetValue( WWS32TlsSlot, (LPVOID)data ) || data == NULL ) {
  308. ul = GETWORD16(WSAENOBUFS);
  309. if ( data != NULL ) {
  310. free_w( (PVOID)data );
  311. }
  312. FREEARGPTR( parg16 );
  313. RETURN(ul);
  314. }
  315. //
  316. // Initialize the blocking hook.
  317. //
  318. WWS32vBlockingHook = WWS32_DEFAULT_BLOCKING_HOOK;
  319. //
  320. // Allocate the individual data objects we need for this task.
  321. //
  322. data->vIpAddress = GlobalAllocLock16( GMEM_MOVEABLE, 256, NULL );
  323. if ( data->vIpAddress == 0 ) {
  324. free_w( (PVOID)data );
  325. TlsSetValue( WWS32TlsSlot, NULL );
  326. FREEARGPTR( parg16 );
  327. RETURN(ul);
  328. }
  329. data->vHostent = GlobalAllocLock16( GMEM_MOVEABLE, MAXGETHOSTSTRUCT, NULL );
  330. if ( data->vHostent == 0 ) {
  331. GlobalUnlockFree16( data->vIpAddress );
  332. free_w( (PVOID)data );
  333. TlsSetValue( WWS32TlsSlot, NULL );
  334. FREEARGPTR( parg16 );
  335. RETURN(ul);
  336. }
  337. data->vServent = GlobalAllocLock16( GMEM_MOVEABLE, MAXGETHOSTSTRUCT, NULL );
  338. if ( data->vServent == 0 ) {
  339. GlobalUnlockFree16( data->vIpAddress );
  340. GlobalUnlockFree16( data->vHostent );
  341. free_w( (PVOID)data );
  342. TlsSetValue( WWS32TlsSlot, NULL );
  343. FREEARGPTR( parg16 );
  344. RETURN(ul);
  345. }
  346. data->vProtoent = GlobalAllocLock16( GMEM_MOVEABLE, MAXGETHOSTSTRUCT, NULL );
  347. if ( data->vProtoent == 0 ) {
  348. GlobalUnlockFree16( data->vIpAddress );
  349. GlobalUnlockFree16( data->vHostent );
  350. GlobalUnlockFree16( data->vServent );
  351. free_w( (PVOID)data );
  352. TlsSetValue( WWS32TlsSlot, NULL );
  353. FREEARGPTR( parg16 );
  354. RETURN(ul);
  355. }
  356. //
  357. // Initialize other per-thread data.
  358. //
  359. WWS32ThreadSerialNumber = WWS32ThreadSerialNumberCounter++;
  360. WWS32ThreadStartupCount = 1;
  361. //
  362. // If they requested version 1.0, give them 1.0. If they
  363. // requested anything else (has to be higher than 1.0 due to
  364. // above test), then give them 1.1. We only support 1.0
  365. // and 1.1. If they can't handle 1.1, they will call
  366. // WSAStartup() and fail.
  367. //
  368. if ( versionRequested == 0x0001 ) {
  369. WWS32ThreadVersion = 0x0001;
  370. } else {
  371. WWS32ThreadVersion = 0x0101;
  372. }
  373. //
  374. // Set up the blocking hook. We always use this blocking hook,
  375. // even for the default case.
  376. //
  377. previousHook = (FARPROC) (*wsockapis[WOW_WSASETBLOCKINGHOOK].lpfn)( (FARPROC)WWS32CallBackHandler );
  378. //
  379. // Set up the routine we'll use in leiu of wsock32.dll posting
  380. // messages directly to the application. We need to intervene
  381. // on all posts because we need to convert 32-bit arguments to
  382. // 16-bit.
  383. //
  384. (*wsockapis[WOW_WSAPSETPOSTROUTINE].lpfn)( WWS32DispatchPostMessage );
  385. } else {
  386. //
  387. // This thread has already had a WSAStartup() call. Make sure
  388. // that they're requesting the same version as before.
  389. //
  390. if ( versionRequested != WWS32ThreadVersion ) {
  391. ul = WSAVERNOTSUPPORTED;
  392. RETURN(ul);
  393. }
  394. //
  395. // Increment the count of WSAStartup() calls for the thread.
  396. //
  397. WWS32ThreadStartupCount++;
  398. }
  399. //
  400. // Get a 32-bit pointer to the 16-bit WSADATA structure and
  401. // initialize the caller's WSAData structure.
  402. //
  403. GETVDMPTR( vpwsaData16, sizeof(WSADATA16), wsaData16 );
  404. STOREWORD( wsaData16->wVersion, WWS32ThreadVersion );
  405. STOREWORD( wsaData16->wHighVersion, MAKEWORD(1, 1) );
  406. description = "16-bit Windows Sockets";
  407. RtlCopyMemory( wsaData16->szDescription,
  408. description,
  409. strlen(description) + 1 );
  410. systemStatus = "Running.";
  411. RtlCopyMemory( wsaData16->szSystemStatus,
  412. systemStatus,
  413. strlen(systemStatus) + 1 );
  414. STOREWORD( wsaData16->iMaxSockets, 0xFFFF );
  415. STOREWORD( wsaData16->iMaxUdpDg, 8096 );
  416. STOREDWORD( wsaData16->lpVendorInfo, 0 );
  417. FLUSHVDMPTR( vpwsaData16, sizeof(WSADATA16), wsaData16 );
  418. FREEVDMPTR( wsaData16 );
  419. FREEARGPTR( parg16 );
  420. RETURN(ul);
  421. } // WWS32WSAStartup
  422. ULONG FASTCALL WWS32WSACleanup(PVDMFRAME pFrame)
  423. {
  424. ULONG ul = 0;
  425. if ( !WWS32IsThreadInitialized ) {
  426. SetLastError( WSANOTINITIALISED );
  427. RETURN((ULONG)SOCKET_ERROR);
  428. }
  429. if ( (*wsockapis[WOW_WSAISBLOCKING].lpfn)( ) ) {
  430. SetLastError( WSAEINPROGRESS );
  431. RETURN((ULONG)SOCKET_ERROR);
  432. }
  433. WWS32ThreadStartupCount--;
  434. if ( WWS32ThreadStartupCount == 0 ) {
  435. WWS32TaskCleanup( );
  436. }
  437. RETURN(ul);
  438. } // WWS32WSACleanup
  439. VOID
  440. WWS32TaskCleanup(
  441. VOID
  442. )
  443. {
  444. LIST_ENTRY listHead;
  445. PWINSOCK_THREAD_DATA data;
  446. PLIST_ENTRY listEntry;
  447. PWINSOCK_SOCKET_INFO socketInfo;
  448. struct linger lingerInfo;
  449. int err;
  450. //
  451. // Get a pointer to the thread's data and set the TLS slot for
  452. // this thread to NULL so that we know that the thread is no
  453. // longer initialized.
  454. //
  455. data = TlsGetValue( WWS32TlsSlot );
  456. ASSERT( data != NULL );
  457. TlsSetValue( WWS32TlsSlot, NULL );
  458. //
  459. // Free thread data user for the database calls.
  460. //
  461. GlobalUnlockFree16( data->vIpAddress );
  462. GlobalUnlockFree16( data->vHostent );
  463. GlobalUnlockFree16( data->vServent );
  464. GlobalUnlockFree16( data->vProtoent );
  465. //
  466. // Close all sockets that the thread has opened. We first find
  467. // all the sockets for this thread, remove them from the global
  468. // list, and place them onto a local list. Then we close each
  469. // socket. We do this as two steps because we can't hold the
  470. // critical section while calling wsock32 in order to avoid
  471. // deadlocks.
  472. //
  473. RtlEnterCriticalSection( &WWS32CriticalSection );
  474. InitializeListHead( &listHead );
  475. for ( listEntry = WWS32SocketHandleListHead.Flink;
  476. listEntry != &WWS32SocketHandleListHead;
  477. listEntry = listEntry->Flink ) {
  478. socketInfo = CONTAINING_RECORD(
  479. listEntry,
  480. WINSOCK_SOCKET_INFO,
  481. GlobalSocketListEntry
  482. );
  483. if ( socketInfo->ThreadSerialNumber == data->ThreadSerialNumber ) {
  484. //
  485. // The socket was opened by this thread. We need to
  486. // first remove the entry from the global list, but
  487. // maintain the listEntry local variable so that we can
  488. // still walk the list.
  489. //
  490. listEntry = socketInfo->GlobalSocketListEntry.Blink;
  491. RemoveEntryList( &socketInfo->GlobalSocketListEntry );
  492. //
  493. // Now insert the entry on our local list.
  494. //
  495. InsertTailList( &listHead, &socketInfo->GlobalSocketListEntry );
  496. }
  497. }
  498. RtlLeaveCriticalSection( &WWS32CriticalSection );
  499. //
  500. // Walk through the sockets opened by this thread and close them
  501. // abortively.
  502. //
  503. for ( listEntry = listHead.Flink;
  504. listEntry != &listHead;
  505. listEntry = listEntry->Flink ) {
  506. //
  507. // Close it abortively and free the handle.
  508. //
  509. socketInfo = CONTAINING_RECORD(
  510. listEntry,
  511. WINSOCK_SOCKET_INFO,
  512. GlobalSocketListEntry
  513. );
  514. lingerInfo.l_onoff = 1;
  515. lingerInfo.l_linger = 0;
  516. err = (*wsockapis[WOW_SETSOCKOPT].lpfn)(
  517. socketInfo->SocketHandle32,
  518. SOL_SOCKET,
  519. SO_LINGER,
  520. (char *)&lingerInfo,
  521. sizeof(lingerInfo)
  522. );
  523. //ASSERT( err == NO_ERROR );
  524. err = (*wsockapis[WOW_CLOSESOCKET].lpfn)( socketInfo->SocketHandle32 );
  525. ASSERT( err == NO_ERROR );
  526. //
  527. // When we free the handle the socketInfo structure will
  528. // also be freed. Set the list pointer to the entry
  529. // prior to this one so that we can successfully walk
  530. // the list.
  531. //
  532. listEntry = socketInfo->GlobalSocketListEntry.Blink;
  533. RemoveEntryList( &socketInfo->GlobalSocketListEntry );
  534. free_w( (PVOID)socketInfo );
  535. }
  536. //
  537. // Set the TLS slot for this thread to NULL so that we know
  538. // that the thread is not initialized.
  539. //
  540. err = TlsSetValue( WWS32TlsSlot, NULL );
  541. ASSERT( err );
  542. //
  543. // Free the structure that holds thread information.
  544. //
  545. free_w( (PVOID)data );
  546. } // WWS32TaskCleanup
  547. ULONG FASTCALL WWS32__WSAFDIsSet(PVDMFRAME pFrame)
  548. {
  549. ULONG ul;
  550. register P__WSAFDISSET16 parg16;
  551. PFD_SET16 fdSet16;
  552. PFD_SET fdSet32;
  553. if ( !WWS32IsThreadInitialized ) {
  554. SetLastError( WSANOTINITIALISED );
  555. RETURN((ULONG)FALSE);
  556. }
  557. GETARGPTR( pFrame, sizeof(__WSAFDISSET16), parg16 );
  558. GETVDMPTR( parg16->Set, sizeof(FD_SET16), fdSet16 );
  559. fdSet32 = AllocateFdSet32( fdSet16 );
  560. if ( fdSet32 != NULL ) {
  561. ConvertFdSet16To32( fdSet16, fdSet32 );
  562. ul = (*wsockapis[WOW_WSAFDISSET].lpfn)( GetWinsock32( parg16->hSocket ), fdSet32 );
  563. free_w( (PVOID)fdSet32 );
  564. } else {
  565. ul = 0;
  566. }
  567. FREEARGPTR(parg16);
  568. RETURN(ul);
  569. } // WWS32__WSAFDIsSet
  570. PWINSOCK_POST_ROUTINE WWS32PostDispatchTable[] =
  571. {
  572. WWS32PostAsyncSelect,
  573. WWS32PostAsyncGetHost,
  574. WWS32PostAsyncGetProto,
  575. WWS32PostAsyncGetServ
  576. };
  577. BOOL
  578. WWS32DispatchPostMessage (
  579. HWND hWnd,
  580. UINT Msg,
  581. WPARAM wParam,
  582. LPARAM lParam
  583. )
  584. {
  585. ASSERT( WWS32PostDispatchTable[WWS32_MESSAGE_ASYNC_SELECT] ==
  586. WWS32PostAsyncSelect );
  587. ASSERT( WWS32PostDispatchTable[WWS32_MESSAGE_ASYNC_GETHOST] ==
  588. WWS32PostAsyncGetHost );
  589. ASSERT( WWS32PostDispatchTable[WWS32_MESSAGE_ASYNC_GETPROTO] ==
  590. WWS32PostAsyncGetProto );
  591. ASSERT( WWS32PostDispatchTable[WWS32_MESSAGE_ASYNC_GETSERV] ==
  592. WWS32PostAsyncGetServ );
  593. ASSERT( (Msg & 0xFFFF) <= WWS32_MESSAGE_ASYNC_GETSERV );
  594. //
  595. // Call the routine that will handle the message. The low word
  596. // of Msg specifies the routine, the high word of Msg is the
  597. // 16-bit message that that routine will post.
  598. //
  599. return WWS32PostDispatchTable[Msg & 0xFFFF](
  600. hWnd,
  601. Msg,
  602. wParam,
  603. lParam
  604. );
  605. } // WWS32DispatchPostMessage
  606. BOOL
  607. WWS32PostAsyncSelect (
  608. HWND hWnd,
  609. UINT Msg,
  610. WPARAM wParam,
  611. LPARAM lParam
  612. )
  613. {
  614. HAND16 h16;
  615. h16 = GetWinsock16( wParam, 0 );
  616. if( h16 == 0 ) {
  617. return TRUE;
  618. }
  619. return PostMessage(
  620. hWnd,
  621. Msg >> 16,
  622. h16,
  623. lParam
  624. );
  625. } // WWS32PostAsyncSelect
  626. DWORD
  627. WWS32CallBackHandler (
  628. VOID
  629. )
  630. {
  631. VPVOID ret;
  632. //
  633. // If the default blocking hook is in force, use it. Otherwise,
  634. // call back into the application's blocking hook.
  635. //
  636. if ( WWS32vBlockingHook == WWS32_DEFAULT_BLOCKING_HOOK ) {
  637. return WWS32DefaultBlockingHook( );
  638. }
  639. (VOID)CallBack16( RET_WINSOCKBLOCKHOOK, NULL, WWS32vBlockingHook, &ret );
  640. return ret & 0xFF;
  641. } // WWS32CallBackHandler
  642. BOOL
  643. WWS32DefaultBlockingHook (
  644. VOID
  645. )
  646. {
  647. MSG msg;
  648. BOOL retrievedMessage;
  649. //
  650. // Get the next message for this thread, if any.
  651. //
  652. retrievedMessage = PeekMessage( &msg, NULL, 0, 0, PM_REMOVE );
  653. //
  654. // Process the message if we got one.
  655. //
  656. if ( retrievedMessage ) {
  657. TranslateMessage( (CONST MSG *)&msg );
  658. DispatchMessage( (CONST MSG *)&msg );
  659. }
  660. //
  661. // If we got a message, indicate that we want to be called again.
  662. //
  663. return retrievedMessage;
  664. } // WWS32DefaultBlockingHook