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.

480 lines
12 KiB

  1. // --------------------------------------------------------------------------------
  2. // Utility.cpp
  3. // Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  4. // --------------------------------------------------------------------------------
  5. #include "pch.hxx"
  6. #include "imnxport.h"
  7. #include "dllmain.h"
  8. #include "ixputil.h"
  9. #include <demand.h>
  10. #include <shlwapi.h>
  11. // --------------------------------------------------------------------------------
  12. // HrInitializeWinsock
  13. // --------------------------------------------------------------------------------
  14. HRESULT HrInitializeWinsock(void)
  15. {
  16. // Locals
  17. HRESULT hr=S_OK;
  18. int err;
  19. WSADATA wsaData;
  20. // Thread Safety
  21. EnterCriticalSection(&g_csDllMain);
  22. // If Already Initialized...
  23. if (g_fWinsockInit)
  24. goto exit;
  25. // Do Startup
  26. err = WSAStartup(MAKEWORD(1,1), &wsaData);
  27. // Start up Windows Sockets DLL
  28. if (!err)
  29. {
  30. // Check WinSock version
  31. if ((LOBYTE(wsaData.wVersion) == 1) && (HIBYTE(wsaData.wVersion) == 1))
  32. {
  33. g_fWinsockInit = TRUE;
  34. goto exit;
  35. }
  36. else
  37. {
  38. DebugTrace("Winsock version %d.%d not supported", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));
  39. hr = TrapError(IXP_E_WINSOCK_WSAVERNOTSUPPORTED);
  40. goto exit;
  41. }
  42. }
  43. // Otherwise, map the error
  44. else
  45. {
  46. DebugTrace("WSAStartup failed: %d\n", err);
  47. switch(err)
  48. {
  49. case WSASYSNOTREADY:
  50. hr = TrapError(IXP_E_WINSOCK_WSASYSNOTREADY);
  51. break;
  52. case WSAVERNOTSUPPORTED:
  53. hr = TrapError(IXP_E_WINSOCK_WSAVERNOTSUPPORTED);
  54. break;
  55. case WSAEINPROGRESS:
  56. hr = TrapError(IXP_E_WINSOCK_WSAEINPROGRESS);
  57. break;
  58. case WSAEPROCLIM:
  59. hr = TrapError(IXP_E_WINSOCK_WSAEPROCLIM);
  60. break;
  61. case WSAEFAULT:
  62. hr = TrapError(IXP_E_WINSOCK_WSAEFAULT);
  63. break;
  64. default:
  65. hr = TrapError(IXP_E_WINSOCK_FAILED_WSASTARTUP);
  66. break;
  67. }
  68. }
  69. exit:
  70. // Thread Safety
  71. LeaveCriticalSection(&g_csDllMain);
  72. // Done
  73. return hr;
  74. }
  75. // --------------------------------------------------------------------------------
  76. // UnInitializeWinsock
  77. // --------------------------------------------------------------------------------
  78. void UnInitializeWinsock(void)
  79. {
  80. // Locals
  81. int err;
  82. // Thread Safety
  83. EnterCriticalSection(&g_csDllMain);
  84. // Has been initialized ?
  85. if (g_fWinsockInit)
  86. {
  87. // Shutdown Winsock
  88. err = WSACleanup();
  89. if (err)
  90. DebugTrace("WSACleanup failed: %d\n", WSAGetLastError());
  91. // Not initialized
  92. else
  93. g_fWinsockInit = FALSE;
  94. }
  95. // Thread Safety
  96. LeaveCriticalSection(&g_csDllMain);
  97. // Done
  98. return;
  99. }
  100. // --------------------------------------------------------------------------------
  101. // PszGetDomainName
  102. // --------------------------------------------------------------------------------
  103. LPSTR PszGetDomainName(void)
  104. {
  105. // pszHost
  106. LPSTR pszHost = SzGetLocalHostNameForID();
  107. // Set pszDomain
  108. LPSTR pszDomain = pszHost;
  109. // Strip Off Host Name?
  110. while (*pszHost)
  111. {
  112. // Skip DBCS Characters
  113. if (IsDBCSLeadByte(*pszHost))
  114. {
  115. // Skip DBCS Char
  116. pszHost+=2;
  117. // Goto next
  118. continue;
  119. }
  120. // Otherwise, test for @ sign
  121. else if (*pszHost == '.' && *(pszHost + 1) != '\0')
  122. {
  123. // Set pszDomain
  124. pszDomain = pszHost + 1;
  125. // We are Done
  126. break;
  127. }
  128. // Increment
  129. pszHost++;
  130. }
  131. // Return pszDomain
  132. return pszDomain;
  133. }
  134. // --------------------------------------------------------------------------------
  135. // SzGetLocalHostNameForID
  136. // --------------------------------------------------------------------------------
  137. LPSTR SzGetLocalHostNameForID(void)
  138. {
  139. // Locals
  140. static char s_szLocalHostId[255] = {0};
  141. // Gets local host name from socket library
  142. if (*s_szLocalHostId == 0)
  143. {
  144. // Locals
  145. LPHOSTENT pHost;
  146. LPSTR pszLocalHost;
  147. // Use gethostbyname
  148. pHost = gethostbyname(SzGetLocalHostName());
  149. // Failure ?
  150. if (pHost && pHost->h_name)
  151. pszLocalHost = pHost->h_name;
  152. else
  153. pszLocalHost = SzGetLocalHostName();
  154. // Strip illegals
  155. StripIllegalHostChars(pszLocalHost, s_szLocalHostId, ARRAYSIZE(s_szLocalHostId));
  156. // if we stripped out everything, then just copy in something
  157. if (*s_szLocalHostId == 0)
  158. StrCpyNA(s_szLocalHostId, "LocalHost", ARRAYSIZE(s_szLocalHostId));
  159. }
  160. // Done
  161. return s_szLocalHostId;
  162. }
  163. // --------------------------------------------------------------------------------
  164. // SzGetLocalPackedIP
  165. // --------------------------------------------------------------------------------
  166. LPSTR SzGetLocalPackedIP(void)
  167. {
  168. // Locals
  169. static CHAR s_szLocalPackedIP[255] = "";
  170. // Init WinSock...
  171. HrInitializeWinsock();
  172. // Gets local host name from socket library
  173. if (*s_szLocalPackedIP == '\0')
  174. {
  175. LPHOSTENT hp = NULL;
  176. hp = gethostbyname(SzGetLocalHostName());
  177. if (hp != NULL)
  178. wnsprintf(s_szLocalPackedIP, ARRAYSIZE(s_szLocalPackedIP), "%08x", *(long *)hp->h_addr);
  179. else
  180. {
  181. // $REVIEW - What should i do if this fails ???
  182. Assert (FALSE);
  183. DebugTrace("gethostbyname failed: WSAGetLastError: %ld\n", WSAGetLastError());
  184. StrCpyNA(s_szLocalPackedIP, "LocalHost", ARRAYSIZE(s_szLocalPackedIP));
  185. }
  186. }
  187. // Done
  188. return s_szLocalPackedIP;
  189. }
  190. // --------------------------------------------------------------------------------
  191. // SzGetLocalHostName
  192. // --------------------------------------------------------------------------------
  193. LPSTR SzGetLocalHostName(void)
  194. {
  195. // Locals
  196. static char s_szLocalHost[255] = {0};
  197. // Init WinSock...
  198. HrInitializeWinsock();
  199. // Gets local host name from socket library
  200. if (*s_szLocalHost == 0)
  201. {
  202. if (gethostname (s_szLocalHost, sizeof (s_szLocalHost)) == SOCKET_ERROR)
  203. {
  204. // $REVIEW - What should i do if this fails ???
  205. Assert (FALSE);
  206. DebugTrace ("gethostname failed: WSAGetLastError: %ld\n", WSAGetLastError ());
  207. StrCpyNA(s_szLocalHost, "LocalHost", ARRAYSIZE(s_szLocalHost));
  208. }
  209. }
  210. // Done
  211. return s_szLocalHost;
  212. }
  213. // --------------------------------------------------------------------------------
  214. // StripIllegalHostChars
  215. // --------------------------------------------------------------------------------
  216. void StripIllegalHostChars(LPSTR pszSrc, LPSTR pszDst, DWORD cchSize)
  217. {
  218. // Locals
  219. LPSTR pszT;
  220. CHAR ch;
  221. ULONG cchDst=0;
  222. if (cchSize == 0)
  223. return;
  224. // Setup pszT
  225. pszT = pszDst;
  226. // Loop through the Source
  227. while('\0' != *pszSrc)
  228. {
  229. // Set ch
  230. ch = *pszSrc++;
  231. // A-Z, a-z, 0-9, no trailing dots
  232. if (cchSize > 0)
  233. {
  234. if ('.' == ch || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))
  235. {
  236. // Store the Character
  237. *pszT++ = ch;
  238. cchSize--;
  239. // Increment Size
  240. cchDst++;
  241. }
  242. }
  243. }
  244. // Null terminate pszT
  245. if (cchSize == 0)
  246. {
  247. //have to truncate, caller didn't give us enough room
  248. pszT--;
  249. }
  250. *pszT = '\0';
  251. // Strip Trailing dots...
  252. while (cchDst > 0)
  253. {
  254. // Last char is a dot
  255. if ('.' != pszDst[cchDst - 1])
  256. break;
  257. // Strip It
  258. pszDst[cchDst - 1] = '\0';
  259. // Decrement cchDst
  260. cchDst--;
  261. }
  262. // Nothing Left ?
  263. if (0 == cchDst)
  264. StrCpyNA(pszDst, "LocalHost", cchSize);
  265. }
  266. // ------------------------------------------------------------------------------------
  267. // FEndRetrRecvBody
  268. // ------------------------------------------------------------------------------------
  269. BOOL FEndRetrRecvBody(LPSTR pszLines, ULONG cbRead, ULONG *pcbSubtract)
  270. {
  271. // Loop the data until we hit the end of the data (i.e. '.') or there is no more data
  272. if (cbRead >= 5 &&
  273. pszLines[cbRead - 1] == '\n' &&
  274. pszLines[cbRead - 2] == '\r' &&
  275. pszLines[cbRead - 3] == '.' &&
  276. pszLines[cbRead - 4] == '\n' &&
  277. pszLines[cbRead - 5] == '\r')
  278. {
  279. *pcbSubtract = 5;
  280. return TRUE;
  281. }
  282. // If Last Line Ended with a CRLF, then lets just check for a .CRLF
  283. else if (cbRead >= 3 &&
  284. // m_rInfo.rFetch.fLastLineCRLF &&
  285. pszLines[0] == '.' &&
  286. pszLines[1] == '\r' &&
  287. pszLines[2] == '\n')
  288. {
  289. *pcbSubtract = 3;
  290. return TRUE;
  291. }
  292. // Not done yet
  293. return FALSE;
  294. }
  295. BOOL FEndRetrRecvBodyNews(LPSTR pszLines, ULONG cbRead, ULONG *pcbSubtract)
  296. {
  297. DWORD dwIndex = 0;
  298. BOOL fRet = FALSE;
  299. // If we have at least 5 characters...
  300. if (cbRead >= 5)
  301. {
  302. //[shaheedp] Bug# 85807
  303. for (dwIndex = 0; dwIndex <= (cbRead - 5); dwIndex++)
  304. {
  305. if ((pszLines[dwIndex] == '\r') &&
  306. (pszLines[dwIndex + 1] == '\n') &&
  307. (pszLines[dwIndex + 2] == '.') &&
  308. (pszLines[dwIndex + 3] == '\r') &&
  309. (pszLines[dwIndex + 4] == '\n'))
  310. {
  311. *pcbSubtract = (cbRead - dwIndex);
  312. fRet = TRUE;
  313. break;
  314. }
  315. }
  316. }
  317. //If we didn't find CRLF.CRLF, then lets find .CRLF at the beginning of the line.
  318. if (!fRet)
  319. {
  320. if ((cbRead >= 3) &&
  321. (pszLines[0] == '.') &&
  322. (pszLines[1] == '\r') &&
  323. (pszLines[2] == '\n'))
  324. {
  325. *pcbSubtract = cbRead;
  326. fRet = TRUE;
  327. }
  328. }
  329. return fRet;
  330. }
  331. // ------------------------------------------------------------------------------------
  332. // UnStuffDotsFromLines
  333. // ------------------------------------------------------------------------------------
  334. void UnStuffDotsFromLines(LPSTR pszBuffer, INT *pcchBuffer)
  335. {
  336. // Locals
  337. ULONG iIn=0;
  338. ULONG iOut=0;
  339. CHAR chPrev='\0';
  340. CHAR chNext;
  341. CHAR chT;
  342. ULONG cchBuffer=(*pcchBuffer);
  343. // Invalid Args
  344. Assert(pszBuffer && pcchBuffer);
  345. // Loop
  346. while(iIn < cchBuffer)
  347. {
  348. // Get Current Char
  349. chT = pszBuffer[iIn++];
  350. // Validate
  351. Assert(chT);
  352. // Leading dot
  353. if ('.' == chT && ('\0' == chPrev || '\n' == chPrev || '\r' == chPrev) && iIn < cchBuffer)
  354. {
  355. // Compute chNext
  356. chNext = pszBuffer[iIn];
  357. // Valid to strip ?
  358. if ('\r' != chNext && '\n' != chNext)
  359. {
  360. // Next Character
  361. chT = pszBuffer[iIn++];
  362. // Set chPrev
  363. chPrev = '.';
  364. }
  365. // Save Previous
  366. else
  367. chPrev = chT;
  368. }
  369. // Save Previous
  370. else
  371. chPrev = chT;
  372. // Set the character
  373. pszBuffer[iOut++] = chT;
  374. }
  375. // Reset pcchBuffer
  376. *pcchBuffer = iOut;
  377. // Done
  378. return;
  379. }
  380. // =============================================================================================
  381. // SkipWhitespace
  382. // Assumes piString points to character boundary
  383. // =============================================================================================
  384. void SkipWhitespace (LPCTSTR lpcsz, ULONG *pi)
  385. {
  386. if (!lpcsz || !pi)
  387. {
  388. Assert (FALSE);
  389. return;
  390. }
  391. #ifdef DEBUG
  392. Assert (*pi <= (ULONG)lstrlen (lpcsz)+1);
  393. #endif
  394. LPTSTR lpsz = (LPTSTR)(lpcsz + *pi);
  395. while (*lpsz != '\0')
  396. {
  397. if (!IsSpace(lpsz))
  398. break;
  399. lpsz++;
  400. (*pi)+=1;
  401. }
  402. return;
  403. }