Leaked source code of windows server 2003
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.

1889 lines
47 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Wsraw.h
  5. Abstract:
  6. Support for database 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. #define FIND_16_OFFSET_FROM_32(base16, base32, actual32) \
  15. ( (DWORD)base16 + ( (DWORD)actual32 - (DWORD)base32 ) )
  16. DWORD
  17. BytesInHostent32 (
  18. PHOSTENT Hostent32
  19. );
  20. DWORD
  21. CopyHostent32To16 (
  22. PHOSTENT16 Hostent16,
  23. VPHOSTENT16 VHostent16,
  24. int BufferLength,
  25. PHOSTENT Hostent32
  26. );
  27. DWORD
  28. BytesInProtoent32 (
  29. PPROTOENT Protoent32
  30. );
  31. DWORD
  32. CopyProtoent32To16 (
  33. PPROTOENT16 Protoent16,
  34. VPPROTOENT16 VProtoent16,
  35. int BufferLength,
  36. PPROTOENT Protoent32
  37. );
  38. DWORD
  39. BytesInServent32 (
  40. PSERVENT Servent32
  41. );
  42. DWORD
  43. CopyServent32To16 (
  44. PSERVENT16 Servent16,
  45. VPSERVENT16 VServent16,
  46. int BufferLength,
  47. PSERVENT Servent32
  48. );
  49. /*++
  50. GENERIC FUNCTION PROTOTYPE:
  51. ==========================
  52. ULONG FASTCALL WWS32<function name>(PVDMFRAME pFrame)
  53. {
  54. ULONG ul;
  55. register P<function name>16 parg16;
  56. GETARGPTR(pFrame, sizeof(<function name>16), parg16);
  57. <get any other required pointers into 16 bit space>
  58. ALLOCVDMPTR
  59. GETVDMPTR
  60. GETMISCPTR
  61. et cetera
  62. <copy any complex structures from 16 bit -> 32 bit space>
  63. <ALWAYS use the FETCHxxx macros>
  64. ul = GET<return type>16(<function name>(parg16->f1,
  65. :
  66. :
  67. parg16->f<n>);
  68. <copy any complex structures from 32 -> 16 bit space>
  69. <ALWAYS use the STORExxx macros>
  70. <free any pointers to 16 bit space you previously got>
  71. <flush any areas of 16 bit memory if they were written to>
  72. FLUSHVDMPTR
  73. FREEARGPTR(parg16);
  74. RETURN(ul);
  75. }
  76. NOTE:
  77. The VDM frame is automatically set up, with all the function parameters
  78. available via parg16->f<number>.
  79. Handles must ALWAYS be mapped for 16 -> 32 -> 16 space via the mapping tables
  80. laid out in WALIAS.C.
  81. Any storage you allocate must be freed (eventually...).
  82. Further to that - if a thunk which allocates memory fails in the 32 bit call
  83. then it must free that memory.
  84. Also, never update structures in 16 bit land if the 32 bit call fails.
  85. Be aware that the GETxxxPTR macros return the CURRENT selector-to-flat_memory
  86. mapping. Calls to some 32-bit functions may indirectly cause callbacks into
  87. 16-bit code. These may cause 16-bit memory to move due to allocations
  88. made in 16-bit land. If the 16-bit memory does move, the corresponding 32-bit
  89. ptr in WOW32 needs to be refreshed to reflect the NEW selector-to-flat_memory
  90. mapping.
  91. --*/
  92. ULONG FASTCALL WWS32gethostbyaddr(PVDMFRAME pFrame)
  93. {
  94. ULONG ul;
  95. register PGETHOSTBYADDR16 parg16;
  96. PDWORD paddr16;
  97. PHOSTENT hostent32;
  98. PHOSTENT16 hostent16;
  99. DWORD bytesRequired;
  100. DWORD addr32; // address must be in PF_INET format (length == 4 bytes)
  101. if ( !WWS32IsThreadInitialized ) {
  102. SetLastError( WSANOTINITIALISED );
  103. RETURN((ULONG)NULL);
  104. }
  105. GETARGPTR( pFrame, sizeof(GETHOSTBYADDR16), parg16 );
  106. GETVDMPTR( parg16->Address, sizeof(DWORD), paddr16 );
  107. addr32 = *paddr16; // copy the 4-byte address
  108. hostent32 = (PHOSTENT) (*wsockapis[WOW_GETHOSTBYADDR].lpfn)((CHAR *)&addr32,
  109. parg16->Length,
  110. parg16->Type);
  111. // Note: 16-bit callbacks resulting from above function
  112. // call may have caused 16-bit memory movement
  113. FREEVDMPTR(paddr16);
  114. FREEARGPTR(parg16);
  115. if ( hostent32 != NULL ) {
  116. GETVDMPTR( WWS32vHostent, MAXGETHOSTSTRUCT, hostent16 );
  117. bytesRequired = CopyHostent32To16(
  118. hostent16,
  119. WWS32vHostent,
  120. MAXGETHOSTSTRUCT,
  121. hostent32
  122. );
  123. ASSERT( bytesRequired < MAXGETHOSTSTRUCT );
  124. FLUSHVDMPTR( WWS32vHostent, (USHORT) bytesRequired, hostent16 );
  125. FREEVDMPTR( hostent16 );
  126. ul = WWS32vHostent;
  127. } else {
  128. ul = 0;
  129. }
  130. FREEVDMPTR( paddr16 );
  131. FREEARGPTR(parg16);
  132. RETURN(ul);
  133. } // WWS32gethostbyaddr
  134. ULONG FASTCALL WWS32gethostbyname(PVDMFRAME pFrame)
  135. {
  136. ULONG ul;
  137. register PGETHOSTBYNAME16 parg16;
  138. PHOSTENT hostent32 = NULL;
  139. PHOSTENT16 hostent16;
  140. PSZ name32 = NULL;
  141. PSZ name16;
  142. DWORD bytesRequired;
  143. if ( !WWS32IsThreadInitialized ) {
  144. SetLastError( WSANOTINITIALISED );
  145. RETURN((ULONG)NULL);
  146. }
  147. GETARGPTR( pFrame, sizeof(GETHOSTBYNAME16), parg16 );
  148. GETVDMPTR( parg16->Name, 32, name16 );
  149. if(name16) {
  150. name32 = malloc_w(strlen(name16)+1);
  151. if ( name32 ) {
  152. strcpy(name32, name16);
  153. hostent32 = (PHOSTENT) (*wsockapis[WOW_GETHOSTBYNAME].lpfn)( name32 );
  154. free_w(name32);
  155. }
  156. }
  157. // Note: 16-bit callbacks resulting from above function
  158. // call may have caused 16-bit memory movement
  159. FREEVDMPTR(name16);
  160. FREEARGPTR(parg16);
  161. if ( hostent32 != NULL ) {
  162. GETVDMPTR( WWS32vHostent, MAXGETHOSTSTRUCT, hostent16 );
  163. bytesRequired = CopyHostent32To16(
  164. hostent16,
  165. WWS32vHostent,
  166. MAXGETHOSTSTRUCT,
  167. hostent32
  168. );
  169. ASSERT( bytesRequired < MAXGETHOSTSTRUCT );
  170. FLUSHVDMPTR( WWS32vHostent, (USHORT) bytesRequired, hostent16 );
  171. FREEVDMPTR( hostent16 );
  172. ul = WWS32vHostent;
  173. } else {
  174. ul = 0;
  175. }
  176. RETURN(ul);
  177. } // WWS32gethostbyname
  178. ULONG FASTCALL WWS32gethostname(PVDMFRAME pFrame)
  179. {
  180. int len;
  181. ULONG ul;
  182. register PGETHOSTNAME16 parg16;
  183. PCHAR name32 = NULL;
  184. PCHAR name16;
  185. INT NameLength;
  186. VPSZ vpszName;
  187. if ( !WWS32IsThreadInitialized ) {
  188. SetLastError( WSANOTINITIALISED );
  189. RETURN((ULONG)NULL);
  190. }
  191. GETARGPTR( pFrame, sizeof(GETHOSTNAME16), parg16 );
  192. vpszName = FETCHDWORD(parg16->Name);
  193. NameLength = INT32(parg16->NameLength);
  194. if(vpszName) {
  195. name32 = malloc_w(NameLength);
  196. }
  197. ul = GETWORD16( (*wsockapis[WOW_GETHOSTNAME].lpfn)( name32, NameLength ) );
  198. // Note: 16-bit callbacks resulting from above function
  199. // call may have caused 16-bit memory movement
  200. FREEVDMPTR(name16);
  201. FREEARGPTR(parg16);
  202. GETVDMPTR( vpszName, NameLength, name16 );
  203. if(name16 && name32) {
  204. len = strlen(name32) + 1;
  205. len = min(len, NameLength);
  206. strncpy(name16, name32, len);
  207. name16[len-1] = '\0';
  208. }
  209. FLUSHVDMPTR( vpszName, NameLength, name16 );
  210. FREEVDMPTR( name16 );
  211. FREEARGPTR(parg16);
  212. RETURN(ul);
  213. } // WWS32gethostname
  214. ULONG FASTCALL WWS32WSAAsyncGetHostByAddr(PVDMFRAME pFrame)
  215. {
  216. ULONG ul;
  217. register PWSAASYNCGETHOSTBYADDR16 parg16;
  218. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  219. PVOID buffer32;
  220. PDWORD paddr16;
  221. if ( !WWS32IsThreadInitialized ) {
  222. SetLastError( WSANOTINITIALISED );
  223. RETURN(0);
  224. }
  225. GETARGPTR( pFrame, sizeof(WSAASYNCGETHOSTBYADDR16), parg16 );
  226. GETVDMPTR( parg16->Address, sizeof(DWORD), paddr16 );
  227. //
  228. // Set up locals so we know how to clean up on exit.
  229. //
  230. context = NULL;
  231. buffer32 = NULL;
  232. ul = 0;
  233. //
  234. // Allocate a context block and 32-bit buffer to use for the request.
  235. //
  236. context = malloc_w( sizeof(*context) );
  237. if ( context == NULL ) {
  238. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  239. goto exit;
  240. }
  241. buffer32 = malloc_w( MAXGETHOSTSTRUCT );
  242. if ( context == NULL ) {
  243. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  244. goto exit;
  245. }
  246. //
  247. // Fill in entries in the context buffer.
  248. //
  249. context->Buffer32 = buffer32;
  250. context->vBuffer16 = parg16->Buffer;
  251. context->Buffer16Length = parg16->BufferLength;
  252. //
  253. // Enter a critical section to synchronize access to the context block
  254. // and their global list.
  255. //
  256. RtlEnterCriticalSection( &WWS32CriticalSection );
  257. context->AsyncTaskHandle32 = (HANDLE) (*wsockapis[WOW_WSAASYNCGETHOSTBYADDR].lpfn)(
  258. (HWND)HWND32(parg16->hWnd),
  259. (parg16->wMsg << 16) |
  260. WWS32_MESSAGE_ASYNC_GETHOST,
  261. (char *)paddr16,
  262. parg16->Length,
  263. parg16->Type,
  264. buffer32,
  265. MAXGETHOSTSTRUCT);
  266. if ( context->AsyncTaskHandle32 != 0 ) {
  267. //
  268. // The call succeeded so get a 16-bit task handle for this
  269. // request and place the context block on the global list. The
  270. // resources will be freed by WWS32PostAsyncGetHost.
  271. //
  272. ul = WWS32GetAsyncTaskHandle16( );
  273. context->AsyncTaskHandle16 = (HAND16)ul;
  274. InsertTailList(
  275. &WWS32AsyncContextBlockListHead,
  276. &context->ContextBlockListEntry
  277. );
  278. }
  279. RtlLeaveCriticalSection( &WWS32CriticalSection );
  280. exit:
  281. if ( ul == 0 ) {
  282. if ( context != NULL ) {
  283. free_w( (PVOID)context );
  284. }
  285. if ( buffer32 != NULL ) {
  286. free_w( buffer32 );
  287. }
  288. }
  289. FREEVDMPTR( paddr16 );
  290. FREEARGPTR( parg16 );
  291. RETURN(ul);
  292. } // WWS32WSAAsyncGetHostByAddr
  293. ULONG FASTCALL WWS32WSAAsyncGetHostByName(PVDMFRAME pFrame)
  294. {
  295. ULONG ul;
  296. register PWSAASYNCGETHOSTBYNAME16 parg16;
  297. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  298. PVOID buffer32;
  299. PCHAR name32;
  300. if ( !WWS32IsThreadInitialized ) {
  301. SetLastError( WSANOTINITIALISED );
  302. RETURN(0);
  303. }
  304. GETARGPTR( pFrame, sizeof(WSAASYNCGETHOSTBYNAME16), parg16 );
  305. GETVDMPTR( parg16->Name, 32, name32 );
  306. //
  307. // Set up locals so we know how to clean up on exit.
  308. //
  309. context = NULL;
  310. buffer32 = NULL;
  311. ul = 0;
  312. //
  313. // Allocate a context block and 32-bit buffer to use for the request.
  314. //
  315. context = malloc_w( sizeof(*context) );
  316. if ( context == NULL ) {
  317. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  318. goto exit;
  319. }
  320. buffer32 = malloc_w( MAXGETHOSTSTRUCT );
  321. if ( context == NULL ) {
  322. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  323. goto exit;
  324. }
  325. //
  326. // Fill in entries in the context buffer.
  327. //
  328. context->Buffer32 = buffer32;
  329. context->vBuffer16 = parg16->Buffer;
  330. context->Buffer16Length = parg16->BufferLength;
  331. //
  332. // Enter a critical section to synchronize access to the context block
  333. // and their global list.
  334. //
  335. RtlEnterCriticalSection( &WWS32CriticalSection );
  336. context->AsyncTaskHandle32 = (HANDLE) (*wsockapis[WOW_WSAASYNCGETHOSTBYNAME].lpfn)(
  337. (HWND)HWND32(parg16->hWnd),
  338. (parg16->wMsg << 16) |
  339. WWS32_MESSAGE_ASYNC_GETHOST,
  340. name32,
  341. buffer32,
  342. MAXGETHOSTSTRUCT
  343. );
  344. if ( context->AsyncTaskHandle32 != 0 ) {
  345. //
  346. // The call succeeded so get a 16-bit task handle for this
  347. // request and place the context block on the global list. The
  348. // resources will be freed by WWS32PostAsyncGetHost.
  349. //
  350. ul = WWS32GetAsyncTaskHandle16( );
  351. context->AsyncTaskHandle16 = (HAND16)ul;
  352. InsertTailList(
  353. &WWS32AsyncContextBlockListHead,
  354. &context->ContextBlockListEntry
  355. );
  356. }
  357. RtlLeaveCriticalSection( &WWS32CriticalSection );
  358. exit:
  359. if ( ul == 0 ) {
  360. if ( context != NULL ) {
  361. free_w( (PVOID)context );
  362. }
  363. if ( buffer32 != NULL ) {
  364. free_w( buffer32 );
  365. }
  366. }
  367. FREEVDMPTR( name32 );
  368. FREEARGPTR( parg16 );
  369. RETURN(ul);
  370. } // WWS32WSAAsyncGetHostByName
  371. BOOL
  372. WWS32PostAsyncGetHost (
  373. HWND hWnd,
  374. UINT Msg,
  375. WPARAM wParam,
  376. LPARAM lParam
  377. )
  378. {
  379. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  380. BOOL ret = FALSE;
  381. PVOID buffer16;
  382. DWORD bytesRequired;
  383. context = WWS32FindAndRemoveAsyncContext( (HANDLE)wParam );
  384. if ( NULL == context || NULL == context->Buffer32 ) {
  385. ASSERT( context && context->Buffer32 );
  386. return FALSE;
  387. }
  388. //
  389. // If the call was successful, copy the 32-bit buffer to the
  390. // 16-bit buffer specified by the application.
  391. //
  392. if ( WSAGETASYNCERROR( lParam ) == 0 ) {
  393. //
  394. // Copy the 32-bit structure to 16-bit buffer.
  395. //
  396. GETVDMPTR( context->vBuffer16, context->Buffer16Length, buffer16 );
  397. bytesRequired = CopyHostent32To16(
  398. buffer16,
  399. context->vBuffer16,
  400. context->Buffer16Length,
  401. context->Buffer32
  402. );
  403. //
  404. // If the application's buffer was too small, return an error
  405. // and information aqbout the buffer size required.
  406. //
  407. if ( bytesRequired > context->Buffer16Length ) {
  408. lParam = WSAMAKEASYNCREPLY( (WORD)bytesRequired, WSAENOBUFS );
  409. }
  410. }
  411. //
  412. // Post the completion message to the 16-bit application.
  413. //
  414. ret = PostMessage(
  415. hWnd,
  416. Msg >> 16,
  417. context->AsyncTaskHandle16,
  418. lParam
  419. );
  420. //
  421. // Free resources and return.
  422. //
  423. free_w( context->Buffer32 );
  424. free_w( (PVOID)context );
  425. return ret;
  426. } // WWS32PostAsyncGetHost
  427. DWORD
  428. CopyHostent32To16 (
  429. PHOSTENT16 Hostent16,
  430. VPHOSTENT16 VHostent16,
  431. int BufferLength,
  432. PHOSTENT Hostent32
  433. )
  434. {
  435. DWORD requiredBufferLength;
  436. DWORD bytesFilled;
  437. PCHAR currentLocation = (PCHAR)Hostent16;
  438. DWORD aliasCount;
  439. DWORD addressCount;
  440. DWORD i;
  441. VPBYTE *addrList16;
  442. VPSZ *aliases16;
  443. //
  444. // Determine how many bytes are needed to fully copy the structure.
  445. //
  446. requiredBufferLength = BytesInHostent32( Hostent32 );
  447. //
  448. // Copy over the hostent structure if it fits.
  449. //
  450. bytesFilled = sizeof(*Hostent32);
  451. if ( bytesFilled > (DWORD)BufferLength ) {
  452. return requiredBufferLength;
  453. }
  454. STOREWORD( Hostent16->h_addrtype, Hostent32->h_addrtype );
  455. STOREWORD( Hostent16->h_length, Hostent32->h_length );
  456. currentLocation = (PCHAR)Hostent16 + bytesFilled;
  457. //
  458. // Count the host's aliases and set up an array to hold pointers to
  459. // them.
  460. //
  461. for ( aliasCount = 0;
  462. Hostent32->h_aliases[aliasCount] != NULL;
  463. aliasCount++ );
  464. bytesFilled += (aliasCount+1) * sizeof(char FAR *);
  465. if ( bytesFilled > (DWORD)BufferLength ) {
  466. Hostent32->h_aliases = NULL;
  467. return requiredBufferLength;
  468. }
  469. Hostent16->h_aliases =
  470. FIND_16_OFFSET_FROM_32( VHostent16, Hostent16, currentLocation );
  471. aliases16 = (VPSZ *)currentLocation;
  472. currentLocation = (PCHAR)Hostent16 + bytesFilled;
  473. //
  474. // Count the host's addresses and set up an array to hold pointers to
  475. // them.
  476. //
  477. for ( addressCount = 0;
  478. Hostent32->h_addr_list[addressCount] != NULL;
  479. addressCount++ );
  480. bytesFilled += (addressCount+1) * sizeof(void FAR *);
  481. if ( bytesFilled > (DWORD)BufferLength ) {
  482. Hostent32->h_addr_list = NULL;
  483. return requiredBufferLength;
  484. }
  485. Hostent16->h_addr_list =
  486. FIND_16_OFFSET_FROM_32( VHostent16, Hostent16, currentLocation );
  487. addrList16 = (VPBYTE *)currentLocation;
  488. currentLocation = (PCHAR)Hostent16 + bytesFilled;
  489. //
  490. // Start filling in addresses. Do addresses before filling in the
  491. // host name and aliases in order to avoid alignment problems.
  492. //
  493. for ( i = 0; i < addressCount; i++ ) {
  494. bytesFilled += Hostent32->h_length;
  495. if ( bytesFilled > (DWORD)BufferLength ) {
  496. STOREDWORD( addrList16[i], 0 );
  497. return requiredBufferLength;
  498. }
  499. STOREDWORD(
  500. addrList16[i],
  501. FIND_16_OFFSET_FROM_32( VHostent16, Hostent16, currentLocation )
  502. );
  503. RtlMoveMemory(
  504. currentLocation,
  505. Hostent32->h_addr_list[i],
  506. Hostent32->h_length
  507. );
  508. currentLocation = (PCHAR)Hostent16 + bytesFilled;
  509. }
  510. STOREDWORD( addrList16[i], 0 );
  511. //
  512. // Copy the host name if it fits.
  513. //
  514. bytesFilled += strlen( Hostent32->h_name ) + 1;
  515. if ( bytesFilled > (DWORD)BufferLength ) {
  516. return requiredBufferLength;
  517. }
  518. Hostent16->h_name =
  519. FIND_16_OFFSET_FROM_32( VHostent16, Hostent16, currentLocation );
  520. RtlMoveMemory( currentLocation, Hostent32->h_name, strlen( Hostent32->h_name ) + 1 );
  521. currentLocation = (PCHAR)Hostent16 + bytesFilled;
  522. //
  523. // Start filling in aliases.
  524. //
  525. for ( i = 0; i < aliasCount; i++ ) {
  526. bytesFilled += strlen( Hostent32->h_aliases[i] ) + 1;
  527. if ( bytesFilled > (DWORD)BufferLength ) {
  528. STOREDWORD( aliases16[i], 0 );
  529. return requiredBufferLength;
  530. }
  531. STOREDWORD(
  532. aliases16[i],
  533. FIND_16_OFFSET_FROM_32( VHostent16, Hostent16, currentLocation )
  534. );
  535. RtlMoveMemory(
  536. currentLocation,
  537. Hostent32->h_aliases[i],
  538. strlen( Hostent32->h_aliases[i] ) + 1
  539. );
  540. currentLocation = (PCHAR)Hostent16 + bytesFilled;
  541. }
  542. STOREDWORD( aliases16[i], 0 );
  543. return requiredBufferLength;
  544. } // CopyHostentToBuffer
  545. DWORD
  546. BytesInHostent32 (
  547. PHOSTENT Hostent32
  548. )
  549. {
  550. DWORD total;
  551. int i;
  552. total = sizeof(HOSTENT);
  553. total += strlen( Hostent32->h_name ) + 1;
  554. total += sizeof(char *) + sizeof(char *);
  555. for ( i = 0; Hostent32->h_aliases[i] != NULL; i++ ) {
  556. total += strlen( Hostent32->h_aliases[i] ) + 1 + sizeof(char *);
  557. }
  558. for ( i = 0; Hostent32->h_addr_list[i] != NULL; i++ ) {
  559. total += Hostent32->h_length + sizeof(char *);
  560. }
  561. return total;
  562. } // BytesInHostent
  563. ULONG FASTCALL WWS32getprotobyname(PVDMFRAME pFrame)
  564. {
  565. ULONG ul;
  566. register PGETPROTOBYNAME16 parg16;
  567. PPROTOENT protoent32 = NULL;
  568. PPROTOENT16 protoent16;
  569. PSZ name32 = NULL;
  570. PBYTE name16;
  571. DWORD bytesRequired;
  572. if ( !WWS32IsThreadInitialized ) {
  573. SetLastError( WSANOTINITIALISED );
  574. RETURN((ULONG)NULL);
  575. }
  576. GETARGPTR( pFrame, sizeof(GETPROTOBYNAME16), parg16 );
  577. GETVDMPTR( parg16->Name, 32, name16 );
  578. if(name16) {
  579. name32 = malloc_w(strlen(name16)+1);
  580. if ( name32 ) {
  581. strcpy(name32, name16);
  582. protoent32 = (PPROTOENT) (*wsockapis[WOW_GETPROTOBYNAME].lpfn)( name32 );
  583. free_w( name32 );
  584. }
  585. }
  586. // Note: 16-bit callbacks resulting from above function
  587. // call may have caused 16-bit memory movement
  588. FREEVDMPTR(name16);
  589. FREEARGPTR(parg16);
  590. if ( protoent32 != NULL ) {
  591. GETVDMPTR( WWS32vProtoent, MAXGETHOSTSTRUCT, protoent16 );
  592. bytesRequired = CopyProtoent32To16(
  593. protoent16,
  594. WWS32vProtoent,
  595. MAXGETHOSTSTRUCT,
  596. protoent32
  597. );
  598. ASSERT( bytesRequired < MAXGETHOSTSTRUCT );
  599. FLUSHVDMPTR( WWS32vProtoent, (USHORT) bytesRequired, protoent16 );
  600. FREEVDMPTR( protoent16 );
  601. ul = WWS32vProtoent;
  602. } else {
  603. ul = 0;
  604. }
  605. RETURN(ul);
  606. } // WWS32getprotobyname
  607. ULONG FASTCALL WWS32getprotobynumber(PVDMFRAME pFrame)
  608. {
  609. ULONG ul;
  610. register PGETPROTOBYNUMBER16 parg16;
  611. PPROTOENT protoent32;
  612. PPROTOENT16 protoent16;
  613. DWORD bytesRequired;
  614. if ( !WWS32IsThreadInitialized ) {
  615. SetLastError( WSANOTINITIALISED );
  616. RETURN((ULONG)NULL);
  617. }
  618. GETARGPTR( pFrame, sizeof(GETPROTOBYNUMBER16), parg16 );
  619. protoent32 = (PPROTOENT) (*wsockapis[WOW_GETPROTOBYNUMBER].lpfn)( parg16->Protocol );
  620. if ( protoent32 != NULL ) {
  621. GETVDMPTR( WWS32vProtoent, MAXGETHOSTSTRUCT, protoent16 );
  622. bytesRequired = CopyProtoent32To16(
  623. protoent16,
  624. WWS32vProtoent,
  625. MAXGETHOSTSTRUCT,
  626. protoent32
  627. );
  628. ASSERT( bytesRequired < MAXGETHOSTSTRUCT );
  629. FLUSHVDMPTR( WWS32vProtoent, (USHORT) bytesRequired, protoent16 );
  630. FREEVDMPTR( protoent16 );
  631. ul = WWS32vProtoent;
  632. } else {
  633. ul = 0;
  634. }
  635. FREEARGPTR(parg16);
  636. RETURN(ul);
  637. } // WWS32getprotobynumber
  638. ULONG FASTCALL WWS32WSAAsyncGetProtoByName(PVDMFRAME pFrame)
  639. {
  640. ULONG ul;
  641. register PWSAASYNCGETPROTOBYNAME16 parg16;
  642. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  643. PVOID buffer32;
  644. PSZ name32;
  645. if ( !WWS32IsThreadInitialized ) {
  646. SetLastError( WSANOTINITIALISED );
  647. RETURN(0);
  648. }
  649. GETARGPTR( pFrame, sizeof(WSAASYNCGETPROTOBYNAME16), parg16 );
  650. GETVDMPTR( parg16->Name, 32, name32 );
  651. //
  652. // Set up locals so we know how to clean up on exit.
  653. //
  654. context = NULL;
  655. buffer32 = NULL;
  656. ul = 0;
  657. //
  658. // Allocate a context block and 32-bit buffer to use for the request.
  659. //
  660. context = malloc_w( sizeof(*context) );
  661. if ( context == NULL ) {
  662. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  663. goto exit;
  664. }
  665. buffer32 = malloc_w( MAXGETHOSTSTRUCT );
  666. if ( context == NULL ) {
  667. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  668. goto exit;
  669. }
  670. //
  671. // Fill in entries in the context buffer.
  672. //
  673. context->Buffer32 = buffer32;
  674. context->vBuffer16 = parg16->Buffer;
  675. context->Buffer16Length = parg16->BufferLength;
  676. //
  677. // Enter a critical section to synchronize access to the context block
  678. // and their global list.
  679. //
  680. RtlEnterCriticalSection( &WWS32CriticalSection );
  681. context->AsyncTaskHandle32 = (HANDLE) (*wsockapis[WOW_WSAASYNCGETPROTOBYNAME].lpfn)(
  682. (HWND)HWND32(parg16->hWnd),
  683. (parg16->wMsg << 16) |
  684. WWS32_MESSAGE_ASYNC_GETPROTO,
  685. name32,
  686. buffer32,
  687. MAXGETHOSTSTRUCT
  688. );
  689. if ( context->AsyncTaskHandle32 != 0 ) {
  690. //
  691. // The call succeeded so get a 16-bit task handle for this
  692. // request and place the context block on the global list. The
  693. // resources will be freed by WWS32PostAsyncGetProto.
  694. //
  695. ul = WWS32GetAsyncTaskHandle16( );
  696. context->AsyncTaskHandle16 = (HAND16)ul;
  697. InsertTailList(
  698. &WWS32AsyncContextBlockListHead,
  699. &context->ContextBlockListEntry
  700. );
  701. }
  702. RtlLeaveCriticalSection( &WWS32CriticalSection );
  703. exit:
  704. if ( ul == 0 ) {
  705. if ( context != NULL ) {
  706. free_w( (PVOID)context );
  707. }
  708. if ( buffer32 != NULL ) {
  709. free_w( buffer32 );
  710. }
  711. }
  712. FREEARGPTR( name32 );
  713. FREEARGPTR( parg16 );
  714. RETURN(ul);
  715. } // WWS32WSAAsyncGetProtoByName
  716. ULONG FASTCALL WWS32WSAAsyncGetProtoByNumber(PVDMFRAME pFrame)
  717. {
  718. ULONG ul;
  719. register PWSAASYNCGETPROTOBYNUMBER16 parg16;
  720. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  721. PVOID buffer32;
  722. if ( !WWS32IsThreadInitialized ) {
  723. SetLastError( WSANOTINITIALISED );
  724. RETURN(0);
  725. }
  726. GETARGPTR( pFrame, sizeof(WSAASYNCGETPROTOBYNUMBER16), parg16 );
  727. //
  728. // Set up locals so we know how to clean up on exit.
  729. //
  730. context = NULL;
  731. buffer32 = NULL;
  732. ul = 0;
  733. //
  734. // Allocate a context block and 32-bit buffer to use for the request.
  735. //
  736. context = malloc_w( sizeof(*context) );
  737. if ( context == NULL ) {
  738. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  739. goto exit;
  740. }
  741. buffer32 = malloc_w( MAXGETHOSTSTRUCT );
  742. if ( context == NULL ) {
  743. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  744. goto exit;
  745. }
  746. //
  747. // Fill in entries in the context buffer.
  748. //
  749. context->Buffer32 = buffer32;
  750. context->vBuffer16 = parg16->Buffer;
  751. context->Buffer16Length = parg16->BufferLength;
  752. //
  753. // Enter a critical section to synchronize access to the context block
  754. // and their global list.
  755. //
  756. RtlEnterCriticalSection( &WWS32CriticalSection );
  757. context->AsyncTaskHandle32 = (HANDLE) (*wsockapis[WOW_WSAASYNCGETPROTOBYNUMBER].lpfn)(
  758. (HWND)HWND32(parg16->hWnd),
  759. (parg16->wMsg << 16) |
  760. WWS32_MESSAGE_ASYNC_GETPROTO,
  761. parg16->Number,
  762. buffer32,
  763. MAXGETHOSTSTRUCT
  764. );
  765. if ( context->AsyncTaskHandle32 != 0 ) {
  766. //
  767. // The call succeeded so get a 16-bit task handle for this
  768. // request and place the context block on the global list. The
  769. // resources will be freed by WWS32PostAsyncGetProto.
  770. //
  771. ul = WWS32GetAsyncTaskHandle16( );
  772. context->AsyncTaskHandle16 = (HAND16)ul;
  773. InsertTailList(
  774. &WWS32AsyncContextBlockListHead,
  775. &context->ContextBlockListEntry
  776. );
  777. }
  778. RtlLeaveCriticalSection( &WWS32CriticalSection );
  779. exit:
  780. if ( ul == 0 ) {
  781. if ( context != NULL ) {
  782. free_w( (PVOID)context );
  783. }
  784. if ( buffer32 != NULL ) {
  785. free_w( buffer32 );
  786. }
  787. }
  788. FREEARGPTR( parg16 );
  789. RETURN(ul);
  790. } // WWS32WSAAsyncGetProtoByNumber
  791. BOOL
  792. WWS32PostAsyncGetProto (
  793. HWND hWnd,
  794. UINT Msg,
  795. WPARAM wParam,
  796. LPARAM lParam
  797. )
  798. {
  799. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  800. BOOL ret;
  801. PVOID buffer16;
  802. DWORD bytesRequired;
  803. context = WWS32FindAndRemoveAsyncContext( (HANDLE)wParam );
  804. if( NULL == context ) {
  805. ASSERT( context != NULL );
  806. return FALSE;
  807. }
  808. //
  809. // If the call was successful, copy the 32-bit buffer to the
  810. // 16-bit buffer specified by the application.
  811. //
  812. if ( WSAGETASYNCERROR( lParam ) == 0 ) {
  813. //
  814. // Copy the 32-bit structure to 16-bit buffer.
  815. //
  816. GETVDMPTR( context->vBuffer16, context->Buffer16Length, buffer16 );
  817. bytesRequired = CopyProtoent32To16(
  818. buffer16,
  819. context->vBuffer16,
  820. context->Buffer16Length,
  821. context->Buffer32
  822. );
  823. //
  824. // If the application's buffer was too small, return an error
  825. // and information aqbout the buffer size required.
  826. //
  827. if ( bytesRequired > context->Buffer16Length ) {
  828. lParam = WSAMAKEASYNCREPLY( (WORD)bytesRequired, WSAENOBUFS );
  829. }
  830. }
  831. //
  832. // Post the completion message to the 16-bit application.
  833. //
  834. ret = PostMessage(
  835. hWnd,
  836. Msg >> 16,
  837. context->AsyncTaskHandle16,
  838. lParam
  839. );
  840. //
  841. // Free resources and return.
  842. //
  843. free_w( context->Buffer32 );
  844. free_w( (PVOID)context );
  845. return ret;
  846. } // WWS32PostAsyncGetProto
  847. /*
  848. NOTE: This assumes that Protoent16 & Protoent32 are not null.
  849. */
  850. DWORD
  851. CopyProtoent32To16 (
  852. PPROTOENT16 Protoent16,
  853. VPPROTOENT16 VProtoent16,
  854. int BufferLength,
  855. PPROTOENT Protoent32
  856. )
  857. {
  858. DWORD requiredBufferLength;
  859. DWORD bytesFilled;
  860. PCHAR currentLocation = (PCHAR)Protoent16;
  861. DWORD aliasCount;
  862. DWORD i;
  863. VPBYTE *aliases16;
  864. //
  865. // Determine how many bytes are needed to fully copy the structure.
  866. //
  867. requiredBufferLength = BytesInProtoent32( Protoent32 );
  868. //
  869. // Copy over the protoent structure if it fits.
  870. //
  871. bytesFilled = sizeof(*Protoent16);
  872. if ( bytesFilled > (DWORD)BufferLength ) {
  873. return requiredBufferLength;
  874. }
  875. STOREWORD( Protoent16->p_proto, Protoent32->p_proto );
  876. currentLocation = (PCHAR)Protoent16 + bytesFilled;
  877. //
  878. // Count the protocol's aliases and set up an array to hold pointers to
  879. // them.
  880. //
  881. for ( aliasCount = 0;
  882. Protoent32->p_aliases[aliasCount] != NULL;
  883. aliasCount++ );
  884. bytesFilled += (aliasCount+1) * sizeof(char FAR *);
  885. if ( bytesFilled > (DWORD)BufferLength ) {
  886. Protoent16->p_aliases = 0;
  887. return requiredBufferLength;
  888. }
  889. Protoent16->p_aliases =
  890. FIND_16_OFFSET_FROM_32( VProtoent16, Protoent16, currentLocation );
  891. aliases16 = (VPBYTE *)currentLocation;
  892. currentLocation = (PCHAR)Protoent16 + bytesFilled;
  893. //
  894. // Copy the protocol name if it fits.
  895. //
  896. bytesFilled += strlen( Protoent32->p_name ) + 1;
  897. if ( bytesFilled > (DWORD)BufferLength ) {
  898. return requiredBufferLength;
  899. }
  900. Protoent16->p_name =
  901. FIND_16_OFFSET_FROM_32( VProtoent16, Protoent16, currentLocation );
  902. RtlMoveMemory( currentLocation, Protoent32->p_name, strlen( Protoent32->p_name ) + 1 );
  903. currentLocation = (PCHAR)Protoent16 + bytesFilled;
  904. //
  905. // Start filling in aliases.
  906. //
  907. for ( i = 0; i < aliasCount; i++ ) {
  908. bytesFilled += strlen( Protoent32->p_aliases[i] ) + 1;
  909. if ( bytesFilled > (DWORD)BufferLength ) {
  910. STOREDWORD( aliases16[i], 0 );
  911. return requiredBufferLength;
  912. }
  913. STOREDWORD(
  914. aliases16[i],
  915. FIND_16_OFFSET_FROM_32( VProtoent16, Protoent16, currentLocation )
  916. );
  917. RtlMoveMemory(
  918. currentLocation,
  919. Protoent32->p_aliases[i],
  920. strlen( Protoent32->p_aliases[i] ) + 1
  921. );
  922. currentLocation = (PCHAR)Protoent16 + bytesFilled;
  923. }
  924. STOREDWORD( aliases16[i], 0 );
  925. return requiredBufferLength;
  926. } // CopyProtoent32To16
  927. DWORD
  928. BytesInProtoent32 (
  929. PPROTOENT Protoent32
  930. )
  931. {
  932. DWORD total;
  933. int i;
  934. total = sizeof(PROTOENT);
  935. total += strlen( Protoent32->p_name ) + 1;
  936. total += sizeof(char *);
  937. for ( i = 0; Protoent32->p_aliases[i] != NULL; i++ ) {
  938. total += strlen( Protoent32->p_aliases[i] ) + 1 + sizeof(char *);
  939. }
  940. return total;
  941. } // BytesInProtoent32
  942. ULONG FASTCALL WWS32getservbyname(PVDMFRAME pFrame)
  943. {
  944. ULONG ul;
  945. register PGETSERVBYNAME16 parg16;
  946. PSERVENT servent32;
  947. PSERVENT16 servent16;
  948. PSZ name32;
  949. PSZ protocol32;
  950. DWORD bytesRequired;
  951. if ( !WWS32IsThreadInitialized ) {
  952. SetLastError( WSANOTINITIALISED );
  953. RETURN((ULONG)NULL);
  954. }
  955. GETARGPTR( pFrame, sizeof(GETSERVBYNAME16), parg16 );
  956. GETVDMPTR( parg16->Name, 32, name32 );
  957. GETVDMPTR( parg16->Protocol, 32, protocol32 );
  958. servent32 = (PSERVENT) (*wsockapis[WOW_GETSERVBYNAME].lpfn)( name32, protocol32 );
  959. if ( servent32 != NULL ) {
  960. GETVDMPTR( WWS32vServent, MAXGETHOSTSTRUCT, servent16 );
  961. bytesRequired = CopyServent32To16(
  962. servent16,
  963. WWS32vServent,
  964. MAXGETHOSTSTRUCT,
  965. servent32
  966. );
  967. ASSERT( bytesRequired < MAXGETHOSTSTRUCT );
  968. FLUSHVDMPTR( WWS32vServent, (USHORT) bytesRequired, servent16 );
  969. FREEVDMPTR( servent16 );
  970. ul = WWS32vServent;
  971. } else {
  972. ul = 0;
  973. }
  974. FREEVDMPTR( name32 );
  975. FREEVDMPTR( protocol32 );
  976. FREEARGPTR(parg16);
  977. RETURN(ul);
  978. } // WWS32getservbyname
  979. ULONG FASTCALL WWS32getservbyport(PVDMFRAME pFrame)
  980. {
  981. ULONG ul;
  982. register PGETSERVBYPORT16 parg16;
  983. PSERVENT servent32;
  984. PSERVENT16 servent16;
  985. PSZ protocol32;
  986. DWORD bytesRequired;
  987. if ( !WWS32IsThreadInitialized ) {
  988. SetLastError( WSANOTINITIALISED );
  989. RETURN((ULONG)NULL);
  990. }
  991. GETARGPTR( pFrame, sizeof(GETSERVBYPORT16), parg16 );
  992. GETVDMPTR( parg16->Protocol, 32, protocol32 );
  993. servent32 = (PSERVENT) (*wsockapis[WOW_GETSERVBYPORT].lpfn)( parg16->Port, protocol32 );
  994. if ( servent32 != NULL ) {
  995. GETVDMPTR( WWS32vServent, MAXGETHOSTSTRUCT, servent16 );
  996. bytesRequired = CopyServent32To16(
  997. servent16,
  998. WWS32vServent,
  999. MAXGETHOSTSTRUCT,
  1000. servent32
  1001. );
  1002. ASSERT( bytesRequired < MAXGETHOSTSTRUCT );
  1003. FLUSHVDMPTR( WWS32vServent, (USHORT) bytesRequired, servent16 );
  1004. FREEVDMPTR( servent16 );
  1005. ul = WWS32vServent;
  1006. } else {
  1007. ul = 0;
  1008. }
  1009. FREEVDMPTR( protocol32 );
  1010. FREEARGPTR(parg16);
  1011. RETURN(ul);
  1012. } // WWS32getservbyport
  1013. ULONG FASTCALL WWS32WSAAsyncGetServByPort(PVDMFRAME pFrame)
  1014. {
  1015. ULONG ul;
  1016. register PWSAASYNCGETSERVBYPORT16 parg16;
  1017. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  1018. PVOID buffer32;
  1019. PSZ proto32;
  1020. if ( !WWS32IsThreadInitialized ) {
  1021. SetLastError( WSANOTINITIALISED );
  1022. RETURN((ULONG)0);
  1023. }
  1024. GETARGPTR( pFrame, sizeof(WSAASYNCGETSERVBYPORT16), parg16 );
  1025. GETVDMPTR( parg16->Protocol, 32, proto32 );
  1026. //
  1027. // Set up locals so we know how to clean up on exit.
  1028. //
  1029. context = NULL;
  1030. buffer32 = NULL;
  1031. ul = 0;
  1032. //
  1033. // Allocate a context block and 32-bit buffer to use for the request.
  1034. //
  1035. context = malloc_w( sizeof(*context) );
  1036. if ( context == NULL ) {
  1037. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  1038. goto exit;
  1039. }
  1040. buffer32 = malloc_w( MAXGETHOSTSTRUCT );
  1041. if ( context == NULL ) {
  1042. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  1043. goto exit;
  1044. }
  1045. //
  1046. // Fill in entries in the context buffer.
  1047. //
  1048. context->Buffer32 = buffer32;
  1049. context->vBuffer16 = parg16->Buffer;
  1050. context->Buffer16Length = parg16->BufferLength;
  1051. //
  1052. // Enter a critical section to synchronize access to the context block
  1053. // and their global list.
  1054. //
  1055. RtlEnterCriticalSection( &WWS32CriticalSection );
  1056. context->AsyncTaskHandle32 = (HANDLE) (*wsockapis[WOW_WSAASYNCGETSERVBYPORT].lpfn)(
  1057. (HWND)HWND32(parg16->hWnd),
  1058. (parg16->wMsg << 16) |
  1059. WWS32_MESSAGE_ASYNC_GETSERV,
  1060. parg16->Port,
  1061. proto32,
  1062. buffer32,
  1063. MAXGETHOSTSTRUCT
  1064. );
  1065. if ( context->AsyncTaskHandle32 != 0 ) {
  1066. //
  1067. // The call succeeded so get a 16-bit task handle for this
  1068. // request and place the context block on the global list. The
  1069. // resources will be freed by WWS32PostAsyncGetServ.
  1070. //
  1071. ul = WWS32GetAsyncTaskHandle16( );
  1072. context->AsyncTaskHandle16 = (HAND16)ul;
  1073. InsertTailList(
  1074. &WWS32AsyncContextBlockListHead,
  1075. &context->ContextBlockListEntry
  1076. );
  1077. }
  1078. RtlLeaveCriticalSection( &WWS32CriticalSection );
  1079. exit:
  1080. if ( ul == 0 ) {
  1081. if ( context != NULL ) {
  1082. free_w( (PVOID)context );
  1083. }
  1084. if ( buffer32 != NULL ) {
  1085. free_w( buffer32 );
  1086. }
  1087. }
  1088. FREEARGPTR( proto32 );
  1089. FREEARGPTR( parg16 );
  1090. RETURN(ul);
  1091. } // WWS32WSAAsyncGetServByPort
  1092. ULONG FASTCALL WWS32WSAAsyncGetServByName(PVDMFRAME pFrame)
  1093. {
  1094. ULONG ul;
  1095. register PWSAASYNCGETSERVBYNAME16 parg16;
  1096. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  1097. PVOID buffer32;
  1098. PSZ name32;
  1099. PSZ proto32;
  1100. if ( !WWS32IsThreadInitialized ) {
  1101. SetLastError( WSANOTINITIALISED );
  1102. RETURN((ULONG)0);
  1103. }
  1104. GETARGPTR( pFrame, sizeof(WSAASYNCGETSERVBYNAME16), parg16 );
  1105. GETVDMPTR( parg16->Name, 32, name32 );
  1106. GETVDMPTR( parg16->Protocol, 32, proto32 );
  1107. //
  1108. // Set up locals so we know how to clean up on exit.
  1109. //
  1110. context = NULL;
  1111. buffer32 = NULL;
  1112. ul = 0;
  1113. //
  1114. // Allocate a context block and 32-bit buffer to use for the request.
  1115. //
  1116. context = malloc_w( sizeof(*context) );
  1117. if ( context == NULL ) {
  1118. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  1119. goto exit;
  1120. }
  1121. buffer32 = malloc_w( MAXGETHOSTSTRUCT );
  1122. if ( context == NULL ) {
  1123. (*wsockapis[WOW_WSASETLASTERROR].lpfn)( WSAENOBUFS );
  1124. goto exit;
  1125. }
  1126. //
  1127. // Fill in entries in the context buffer.
  1128. //
  1129. context->Buffer32 = buffer32;
  1130. context->vBuffer16 = parg16->Buffer;
  1131. context->Buffer16Length = parg16->BufferLength;
  1132. //
  1133. // Enter a critical section to synchronize access to the context block
  1134. // and their global list.
  1135. //
  1136. RtlEnterCriticalSection( &WWS32CriticalSection );
  1137. context->AsyncTaskHandle32 = (HANDLE) (*wsockapis[WOW_WSAASYNCGETSERVBYNAME].lpfn)(
  1138. (HWND)HWND32(parg16->hWnd),
  1139. (parg16->wMsg << 16) |
  1140. WWS32_MESSAGE_ASYNC_GETSERV,
  1141. name32,
  1142. proto32,
  1143. buffer32,
  1144. MAXGETHOSTSTRUCT
  1145. );
  1146. if ( context->AsyncTaskHandle32 != 0 ) {
  1147. //
  1148. // The call succeeded so get a 16-bit task handle for this
  1149. // request and place the context block on the global list. The
  1150. // resources will be freed by WWS32PostAsyncGetServ.
  1151. //
  1152. ul = WWS32GetAsyncTaskHandle16( );
  1153. context->AsyncTaskHandle16 = (HAND16)ul;
  1154. InsertTailList(
  1155. &WWS32AsyncContextBlockListHead,
  1156. &context->ContextBlockListEntry
  1157. );
  1158. }
  1159. RtlLeaveCriticalSection( &WWS32CriticalSection );
  1160. exit:
  1161. if ( ul == 0 ) {
  1162. if ( context != NULL ) {
  1163. free_w( (PVOID)context );
  1164. }
  1165. if ( buffer32 != NULL ) {
  1166. free_w( buffer32 );
  1167. }
  1168. }
  1169. FREEARGPTR( proto32 );
  1170. FREEARGPTR( name32 );
  1171. FREEARGPTR( parg16 );
  1172. RETURN(ul);
  1173. } // WWS32WSAAsyncGetServByName
  1174. BOOL
  1175. WWS32PostAsyncGetServ (
  1176. HWND hWnd,
  1177. UINT Msg,
  1178. WPARAM wParam,
  1179. LPARAM lParam
  1180. )
  1181. {
  1182. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  1183. BOOL ret;
  1184. PVOID buffer16;
  1185. DWORD bytesRequired;
  1186. context = WWS32FindAndRemoveAsyncContext( (HANDLE)wParam );
  1187. if( NULL == context ) {
  1188. ASSERT( context != NULL );
  1189. return FALSE;
  1190. }
  1191. //
  1192. // If the call was successful, copy the 32-bit buffer to the
  1193. // 16-bit buffer specified by the application.
  1194. //
  1195. if ( WSAGETASYNCERROR( lParam ) == 0 ) {
  1196. //
  1197. // Copy the 32-bit structure to 16-bit buffer.
  1198. //
  1199. GETVDMPTR( context->vBuffer16, context->Buffer16Length, buffer16 );
  1200. bytesRequired = CopyServent32To16(
  1201. buffer16,
  1202. context->vBuffer16,
  1203. context->Buffer16Length,
  1204. context->Buffer32
  1205. );
  1206. //
  1207. // If the application's buffer was too small, return an error
  1208. // and information aqbout the buffer size required.
  1209. //
  1210. if ( bytesRequired > context->Buffer16Length ) {
  1211. lParam = WSAMAKEASYNCREPLY( (WORD)bytesRequired, WSAENOBUFS );
  1212. }
  1213. }
  1214. //
  1215. // Post the completion message to the 16-bit application.
  1216. //
  1217. ret = PostMessage(
  1218. hWnd,
  1219. Msg >> 16,
  1220. context->AsyncTaskHandle16,
  1221. lParam
  1222. );
  1223. //
  1224. // Free resources and return.
  1225. //
  1226. free_w( context->Buffer32 );
  1227. free_w( (PVOID)context );
  1228. return ret;
  1229. } // WWS32PostAsyncGetServ
  1230. /*
  1231. NOTE: both Servent16 & Servent32 are assumed to be non-NULL
  1232. */
  1233. DWORD
  1234. CopyServent32To16 (
  1235. PSERVENT16 Servent16,
  1236. VPSERVENT16 VServent16,
  1237. int BufferLength,
  1238. PSERVENT Servent32
  1239. )
  1240. {
  1241. DWORD requiredBufferLength;
  1242. DWORD bytesFilled;
  1243. PCHAR currentLocation = (PCHAR)Servent16;
  1244. DWORD aliasCount;
  1245. DWORD i;
  1246. VPBYTE *aliases16;
  1247. //
  1248. // Determine how many bytes are needed to fully copy the structure.
  1249. //
  1250. requiredBufferLength = BytesInServent32( Servent32 );
  1251. //
  1252. // Copy over the servent structure if it fits.
  1253. //
  1254. bytesFilled = sizeof(*Servent16);
  1255. if ( bytesFilled > (DWORD)BufferLength ) {
  1256. return requiredBufferLength;
  1257. }
  1258. STOREWORD( Servent16->s_port, Servent32->s_port );
  1259. currentLocation = (PCHAR)Servent16 + bytesFilled;
  1260. //
  1261. // Count the service's aliases and set up an array to hold pointers to
  1262. // them.
  1263. //
  1264. for ( aliasCount = 0;
  1265. Servent32->s_aliases[aliasCount] != NULL;
  1266. aliasCount++ );
  1267. bytesFilled += (aliasCount+1) * sizeof(char FAR *);
  1268. if ( bytesFilled > (DWORD)BufferLength ) {
  1269. STOREDWORD( Servent32->s_aliases, 0 );
  1270. return requiredBufferLength;
  1271. }
  1272. Servent16->s_aliases =
  1273. FIND_16_OFFSET_FROM_32( VServent16, Servent16, currentLocation );
  1274. aliases16 = (VPBYTE *)currentLocation;
  1275. currentLocation = (PCHAR)Servent16 + bytesFilled;
  1276. //
  1277. // Copy the service name if it fits.
  1278. //
  1279. bytesFilled += strlen( Servent32->s_name ) + 1;
  1280. if ( bytesFilled > (DWORD)BufferLength ) {
  1281. return requiredBufferLength;
  1282. }
  1283. Servent16->s_name =
  1284. FIND_16_OFFSET_FROM_32( VServent16, Servent16, currentLocation );
  1285. RtlMoveMemory( currentLocation, Servent32->s_name, strlen( Servent32->s_name ) + 1 );
  1286. currentLocation = (PCHAR)Servent16 + bytesFilled;
  1287. //
  1288. // Copy the protocol name if it fits.
  1289. //
  1290. bytesFilled += strlen( Servent32->s_proto ) + 1;
  1291. if ( bytesFilled > (DWORD)BufferLength ) {
  1292. return requiredBufferLength;
  1293. }
  1294. Servent16->s_proto =
  1295. FIND_16_OFFSET_FROM_32( VServent16, Servent16, currentLocation );
  1296. RtlMoveMemory( currentLocation, Servent32->s_proto, strlen( Servent32->s_proto ) + 1 );
  1297. currentLocation = (PCHAR)Servent16 + bytesFilled;
  1298. //
  1299. // Start filling in aliases.
  1300. //
  1301. for ( i = 0; i < aliasCount; i++ ) {
  1302. bytesFilled += strlen( Servent32->s_aliases[i] ) + 1;
  1303. if ( bytesFilled > (DWORD)BufferLength ) {
  1304. STOREDWORD( aliases16[i], NULL );
  1305. return requiredBufferLength;
  1306. }
  1307. STOREDWORD(
  1308. aliases16[i],
  1309. FIND_16_OFFSET_FROM_32( VServent16, Servent16, currentLocation )
  1310. );
  1311. RtlMoveMemory(
  1312. currentLocation,
  1313. Servent32->s_aliases[i],
  1314. strlen( Servent32->s_aliases[i] ) + 1
  1315. );
  1316. currentLocation = (PCHAR)Servent16 + bytesFilled;
  1317. }
  1318. STOREDWORD( aliases16[i], NULL );
  1319. return requiredBufferLength;
  1320. } // CopyServent32To16
  1321. DWORD
  1322. BytesInServent32 (
  1323. IN PSERVENT Servent32
  1324. )
  1325. {
  1326. DWORD total;
  1327. int i;
  1328. total = sizeof(SERVENT);
  1329. total += strlen( Servent32->s_name ) + 1;
  1330. total += strlen( Servent32->s_proto ) + 1;
  1331. total += sizeof(char *);
  1332. for ( i = 0; Servent32->s_aliases[i] != NULL; i++ ) {
  1333. total += strlen( Servent32->s_aliases[i] ) + 1 + sizeof(char *);
  1334. }
  1335. return total;
  1336. } // BytesInServent32
  1337. ULONG FASTCALL WWS32WSACancelAsyncRequest(PVDMFRAME pFrame)
  1338. {
  1339. ULONG ul;
  1340. register PWSACANCELASYNCREQUEST16 parg16;
  1341. if ( !WWS32IsThreadInitialized ) {
  1342. SetLastError( WSANOTINITIALISED );
  1343. RETURN((ULONG)SOCKET_ERROR);
  1344. }
  1345. GETARGPTR(pFrame, sizeof(WSACANCELASYNCREQUEST16), parg16);
  1346. //ul = GETWORD16((*wsockapis[WOW_WSACANCELASYNCREQUEST].lpfn)(
  1347. // ));
  1348. FREEARGPTR(parg16);
  1349. ul = (ULONG) SOCKET_ERROR;
  1350. SetLastError( WSAEINVAL );
  1351. RETURN(ul);
  1352. } // WWS32WSACancelAsyncRequest
  1353. PWINSOCK_ASYNC_CONTEXT_BLOCK
  1354. WWS32FindAndRemoveAsyncContext (
  1355. IN HANDLE AsyncTaskHandle32
  1356. )
  1357. {
  1358. PWINSOCK_ASYNC_CONTEXT_BLOCK context;
  1359. PLIST_ENTRY listEntry;
  1360. RtlEnterCriticalSection( &WWS32CriticalSection );
  1361. //
  1362. // Walk the global list of async context blocks, looking for
  1363. // one that matches the specified task handle.
  1364. //
  1365. for ( listEntry = WWS32AsyncContextBlockListHead.Flink;
  1366. listEntry != &WWS32AsyncContextBlockListHead;
  1367. listEntry = listEntry->Flink ) {
  1368. context = CONTAINING_RECORD(
  1369. listEntry,
  1370. WINSOCK_ASYNC_CONTEXT_BLOCK,
  1371. ContextBlockListEntry
  1372. );
  1373. if ( context && context->AsyncTaskHandle32 == AsyncTaskHandle32 ) {
  1374. //
  1375. // Found a match. Remove it from the global list, leave
  1376. // the critical section, and return the context block.
  1377. //
  1378. RemoveEntryList( &context->ContextBlockListEntry );
  1379. RtlLeaveCriticalSection( &WWS32CriticalSection );
  1380. return context;
  1381. }
  1382. }
  1383. //
  1384. // A matching context block was not found on the list.
  1385. //
  1386. RtlLeaveCriticalSection( &WWS32CriticalSection );
  1387. return NULL;
  1388. } // WWS32FindAndRemoveAsyncContext
  1389. HAND16
  1390. WWS32GetAsyncTaskHandle16 (
  1391. VOID
  1392. )
  1393. {
  1394. HAND16 asyncTaskHandle16;
  1395. // *** this routine *must* be called from within the WWS32 critical
  1396. // section!
  1397. ASSERT( WWS32AsyncTaskHandleCounter != 0 );
  1398. asyncTaskHandle16 = (HAND16)WWS32AsyncTaskHandleCounter;
  1399. WWS32AsyncTaskHandleCounter++;
  1400. //
  1401. // 0 is an invalid task handle value; if the counter has wrapped to
  1402. // zero, set it to 1.
  1403. //
  1404. if ( WWS32AsyncTaskHandleCounter == 0 ) {
  1405. WWS32AsyncTaskHandleCounter = 1;
  1406. }
  1407. return WWS32AsyncTaskHandleCounter;
  1408. } // WWS32GetAsyncTaskHandle16