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.

358 lines
7.5 KiB

  1. //
  2. // DWINSOCK.C Dynamic WinSock
  3. //
  4. // Functions for dynamically linking to
  5. // best available WinSock.
  6. //
  7. // Dynamically links to WS2_32.DLL or
  8. // if WinSock 2 isn't available, it
  9. // dynamically links to WSOCK32.DLL.
  10. //
  11. //
  12. #include "dnwsocki.h"
  13. #if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
  14. //
  15. // Globals
  16. //
  17. HINSTANCE g_hWinSock2 = NULL;
  18. //
  19. // Declare global function pointers
  20. //
  21. #define DWINSOCK_GLOBAL
  22. #include "dwnsock2.inc"
  23. #endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
  24. //
  25. // Internal Functions and data
  26. //
  27. #ifndef DPNBUILD_NOWINSOCK2
  28. static BOOL MapWinsock2FunctionPointers(void);
  29. #endif // ! DPNBUILD_NOWINSOCK2
  30. #ifndef DPNBUILD_NOIPX
  31. static char NibbleToHex(BYTE b);
  32. static void BinToHex(PBYTE pBytes, int nNbrBytes, LPSTR lpStr);
  33. static int IPXAddressToString(LPSOCKADDR_IPX pAddr,
  34. DWORD dwAddrLen,
  35. LPTSTR lpAddrStr,
  36. LPDWORD pdwStrLen);
  37. #endif // ! DPNBUILD_NOIPX
  38. ////////////////////////////////////////////////////////////
  39. #undef DPF_MODNAME
  40. #define DPF_MODNAME "DWSInitWinSock"
  41. int DWSInitWinSock( void )
  42. {
  43. WORD wVersionRequested;
  44. WSADATA wsaData;
  45. int iReturn;
  46. #ifdef DPNBUILD_ONLYWINSOCK2
  47. //
  48. // Use Winsock 2.
  49. //
  50. wVersionRequested = MAKEWORD(2, 2);
  51. #else // ! DPNBUILD_ONLYWINSOCK2
  52. //
  53. // Assume we will use Winsock 1.
  54. //
  55. wVersionRequested = MAKEWORD(1, 1);
  56. #ifndef DPNBUILD_NOWINSOCK2
  57. //
  58. // Try to load Winsock 2 if allowed.
  59. //
  60. #ifndef DPNBUILD_NOREGISTRY
  61. if (g_dwWinsockVersion != 1)
  62. #endif // ! DPNBUILD_NOREGISTRY
  63. {
  64. #ifdef WIN95
  65. OSVERSIONINFO osvi;
  66. memset(&osvi, 0, sizeof(osvi));
  67. osvi.dwOSVersionInfoSize = sizeof(osvi);
  68. if ((g_dwWinsockVersion == 2) || // if we explicitly are supposed to use WS2, or
  69. (! GetVersionEx(&osvi)) || // if we can't get the OS information, or
  70. (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) || // if it's not Win9x, or
  71. (HIBYTE(HIWORD(osvi.dwBuildNumber)) != 4) || // it's not the Win98 major version number, or
  72. (LOBYTE(HIWORD(osvi.dwBuildNumber)) != 10)) // it's not Win98's minor version number (Gold = build 1998, SE = build 2222)
  73. #endif // WIN95
  74. {
  75. g_hWinSock2 = LoadLibrary(TEXT("WS2_32.DLL"));
  76. if (g_hWinSock2 != NULL)
  77. {
  78. //
  79. // Use GetProcAddress to initialize
  80. // the function pointers
  81. //
  82. if (!MapWinsock2FunctionPointers())
  83. {
  84. iReturn = -1;
  85. goto Failure;
  86. }
  87. wVersionRequested = MAKEWORD(2, 2);
  88. }
  89. }
  90. }
  91. #endif // ! DPNBUILD_NOWINSOCK2
  92. #endif // ! DPNBUILD_ONLYWINSOCK2
  93. //
  94. // Call WSAStartup()
  95. //
  96. iReturn = WSAStartup(wVersionRequested, &wsaData);
  97. if (iReturn != 0)
  98. {
  99. goto Failure;
  100. }
  101. DPFX(DPFPREP, 3, "Using WinSock version %i.%i",
  102. LOBYTE( wsaData.wVersion ), HIBYTE( wsaData.wVersion ) );
  103. if (wVersionRequested != wsaData.wVersion)
  104. {
  105. DPFX(DPFPREP, 0, "WinSock version %i.%i in use doesn't match version requested %i.%i!",
  106. LOBYTE( wsaData.wVersion ), HIBYTE( wsaData.wVersion ),
  107. LOBYTE( wVersionRequested ), HIBYTE( wVersionRequested ) );
  108. iReturn = -1;
  109. goto Failure;
  110. }
  111. DNASSERT(iReturn == 0);
  112. Exit:
  113. return iReturn;
  114. Failure:
  115. #if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
  116. if (g_hWinSock2 != NULL)
  117. {
  118. FreeLibrary(g_hWinSock2);
  119. g_hWinSock2 = NULL;
  120. }
  121. #endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
  122. DNASSERT(iReturn != 0);
  123. goto Exit;
  124. }
  125. #undef DPF_MODNAME
  126. ////////////////////////////////////////////////////////////
  127. void DWSFreeWinSock(void)
  128. {
  129. WSACleanup();
  130. #if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
  131. if (g_hWinSock2 != NULL)
  132. {
  133. FreeLibrary(g_hWinSock2);
  134. g_hWinSock2 = NULL;
  135. }
  136. #endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
  137. }
  138. #if ((! defined(DPNBUILD_ONLYWINSOCK2)) && (! defined(DPNBUILD_NOWINSOCK2)))
  139. //**********************************************************************
  140. // ------------------------------
  141. // GetWinsockVersion - get the version of Winsock
  142. //
  143. // Entry: Nothing
  144. //
  145. // Exit: Winsock version
  146. // ------------------------------
  147. #undef DPF_MODNAME
  148. #define DPF_MODNAME "GetWinsockVersion"
  149. int GetWinsockVersion( void )
  150. {
  151. return ((g_hWinSock2 != NULL) ? 2 : 1);
  152. }
  153. //**********************************************************************
  154. #endif // ! DPNBUILD_ONLYWINSOCK2 and ! DPNBUILD_NOWINSOCK2
  155. #ifndef DPNBUILD_NOIPX
  156. //
  157. // Workaround for WSAAddressToString()/IPX bug
  158. //
  159. int IPXAddressToStringNoSocket(LPSOCKADDR pSAddr,
  160. DWORD dwAddrLen,
  161. LPSTR lpAddrStr,
  162. LPDWORD pdwStrLen)
  163. {
  164. char szAddr[32];
  165. char szTmp[20];
  166. LPSOCKADDR_IPX pAddr = (LPSOCKADDR_IPX) pSAddr;
  167. //
  168. // Check destination length
  169. //
  170. if (*pdwStrLen < 27)
  171. {
  172. WSASetLastError(WSAEINVAL);
  173. return SOCKET_ERROR;
  174. }
  175. //
  176. // Convert network number
  177. //
  178. BinToHex((PBYTE)&pAddr->sa_netnum, 4, szTmp);
  179. strcpy(szAddr, szTmp);
  180. strcat(szAddr, ",");
  181. // Node Number
  182. BinToHex((PBYTE)&pAddr->sa_nodenum, 6, szTmp);
  183. strcat(szAddr, szTmp);
  184. strcpy(lpAddrStr, szAddr);
  185. *pdwStrLen = strlen(szAddr);
  186. return 0;
  187. }
  188. ////////////////////////////////////////////////////////////
  189. char NibbleToHex(BYTE b)
  190. {
  191. if (b < 10)
  192. return (b + '0');
  193. return (b - 10 + 'A');
  194. }
  195. void BinToHex(PBYTE pBytes, int nNbrBytes, LPSTR lpStr)
  196. {
  197. BYTE b;
  198. while(nNbrBytes--)
  199. {
  200. // High order nibble first
  201. b = (*pBytes >> 4);
  202. *lpStr = NibbleToHex(b);
  203. lpStr++;
  204. // Then low order nibble
  205. b = (*pBytes & 0x0F);
  206. *lpStr = NibbleToHex(b);
  207. lpStr++;
  208. pBytes++;
  209. }
  210. *lpStr = '\0';
  211. }
  212. ////////////////////////////////////////////////////////////
  213. //
  214. // Workaround for WSAAddressToString()/IPX bug
  215. //
  216. int IPXAddressToString(LPSOCKADDR_IPX pAddr,
  217. DWORD dwAddrLen,
  218. LPTSTR lpAddrStr,
  219. LPDWORD pdwStrLen)
  220. {
  221. char szAddr[32];
  222. char szTmp[20];
  223. //
  224. // Check destination length
  225. //
  226. if (*pdwStrLen < 27)
  227. {
  228. WSASetLastError(WSAEINVAL);
  229. return SOCKET_ERROR;
  230. }
  231. //
  232. // Convert network number
  233. //
  234. BinToHex((PBYTE)&pAddr->sa_netnum, 4, szTmp);
  235. strcpy(szAddr, szTmp);
  236. strcat(szAddr, ",");
  237. // Node Number
  238. BinToHex((PBYTE)&pAddr->sa_nodenum, 6, szTmp);
  239. strcat(szAddr, szTmp);
  240. strcat(szAddr, ":");
  241. // IPX Address Socket number
  242. BinToHex((PBYTE)&pAddr->sa_socket, 2, szTmp);
  243. strcat(szAddr, szTmp);
  244. #ifdef UNICODE
  245. //
  246. // Convert inet_ntoa string to wide char
  247. //
  248. int nRet = MultiByteToWideChar(CP_ACP,
  249. 0,
  250. szAddr,
  251. -1,
  252. lpAddrStr,
  253. *pdwStrLen);
  254. if (nRet == 0)
  255. {
  256. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  257. {
  258. WSASetLastError(WSAEFAULT);
  259. }
  260. else
  261. {
  262. WSASetLastError(WSAEINVAL);
  263. }
  264. return SOCKET_ERROR;
  265. }
  266. #else
  267. //
  268. // ANSI -- Check the string length
  269. //
  270. if (strlen(szAddr) > *pdwStrLen)
  271. {
  272. WSASetLastError(WSAEFAULT);
  273. *pdwStrLen = strlen(szAddr);
  274. return SOCKET_ERROR;
  275. }
  276. strcpy(lpAddrStr, szAddr);
  277. *pdwStrLen = strlen(szAddr);
  278. #endif // UNICODE
  279. return 0;
  280. }
  281. #endif DPNBUILD_NOIPX
  282. ////////////////////////////////////////////////////////////
  283. #ifndef DPNBUILD_NOWINSOCK2
  284. BOOL MapWinsock2FunctionPointers(void)
  285. {
  286. //
  287. // This variable must be declared
  288. // with this name in order to use
  289. // #define DWINSOCK_GETPROCADDRESS
  290. //
  291. BOOL fOK = TRUE;
  292. #define DWINSOCK_GETPROCADDRESS
  293. #include "dwnsock2.inc"
  294. return fOK;
  295. }
  296. #endif // DPNBUILD_NOWINSOCK2