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.

1443 lines
36 KiB

  1. /*++
  2. Copyright (c) 1994 Microsoft Corporation
  3. Module Name:
  4. inetapiw.cxx
  5. Abstract:
  6. Contains the wide-character Internet APIs
  7. Contents:
  8. InternetCrackUrlW
  9. InternetCreateUrlW
  10. InternetCanonicalizeUrlW
  11. InternetCombineUrlW
  12. InternetOpenW
  13. InternetConnectW
  14. InternetOpenUrlW
  15. InternetReadFileExW
  16. InternetWriteFileExW
  17. InternetFindNextFileW
  18. InternetQueryOptionW
  19. InternetSetOptionW
  20. InternetGetLastResponseInfoW
  21. InternetSetStatusCallbackW
  22. Author:
  23. Richard L Firth (rfirth) 02-Mar-1995
  24. Environment:
  25. Win32(s) user-mode DLL
  26. Revision History:
  27. 02-Mar-1995 rfirth
  28. Created
  29. --*/
  30. #include <wininetp.h>
  31. // because wininet doesnt know about IStream
  32. #define NO_SHLWAPI_STREAM
  33. #include <shlwapi.h>
  34. #include <shlwapip.h>
  35. extern BOOL TransformFtpFindDataToW(LPWIN32_FIND_DATAA pfdA, LPWIN32_FIND_DATAW pfdW);
  36. extern BOOL TransformGopherFindDataToW(LPGOPHER_FIND_DATAA pgfdA, LPGOPHER_FIND_DATAW pgfdW);
  37. // -- FixStrings ------
  38. // Used in InternetCrackUrlW only.
  39. // Either
  40. // (a) If we have an ansi string, AND a unicode buffer, convert from ansi to unicode
  41. // (b) If we have an ansi string, but NO unicode buffer, determine where the ansi string
  42. // occurs in the unicode URL, and point the component there.
  43. VOID
  44. FixStrings(
  45. LPSTR& pszA,
  46. DWORD cbA,
  47. LPWSTR& pszW,
  48. DWORD& ccW,
  49. LPSTR pszUrlA,
  50. LPCWSTR pszUrlW)
  51. {
  52. if (!pszA)
  53. return;
  54. if (pszW)
  55. {
  56. ccW = MultiByteToWideChar(CP_ACP, 0, pszA, cbA+1, pszW, ccW) - 1;
  57. }
  58. else
  59. {
  60. pszW = (LPWSTR)(pszUrlW + MultiByteToWideChar(CP_ACP, 0,
  61. pszUrlA, (int) (pszA-pszUrlA), NULL, 0));
  62. ccW = MultiByteToWideChar(CP_ACP, 0, pszA, cbA, NULL, 0);
  63. }
  64. }
  65. //
  66. // functions
  67. //
  68. INTERNETAPI_(BOOL) InternetCrackUrlW(
  69. IN LPCWSTR pszUrlW,
  70. IN DWORD dwUrlLengthW,
  71. IN DWORD dwFlags,
  72. IN OUT LPURL_COMPONENTSW pUCW
  73. )
  74. /*++
  75. Routine Description:
  76. Cracks an URL into its constituent parts. Optionally escapes the url-path.
  77. We assume that the user has supplied large enough buffers for the various
  78. URL parts
  79. Arguments:
  80. pszUrl - pointer to URL to crack
  81. dwUrlLength - 0 if pszUrl is ASCIIZ string, else length of pszUrl
  82. dwFlags - flags controlling operation
  83. lpUrlComponents - pointer to URL_COMPONENTS
  84. Return Value:
  85. BOOL
  86. Success - TRUE
  87. Failure - FALSE. Call GetLastError() for more info
  88. --*/
  89. {
  90. DEBUG_ENTER_API((DBG_API,
  91. Bool,
  92. "InternetCrackUrlW",
  93. "%wq, %#x, %#x, %#x",
  94. pszUrlW,
  95. dwUrlLengthW,
  96. dwFlags,
  97. pUCW
  98. ));
  99. INET_ASSERT(pszUrlW);
  100. INET_ASSERT(pUCW);
  101. DWORD dwErr = ERROR_SUCCESS;
  102. BOOL fResult = FALSE;
  103. BOOL fContinue;
  104. DWORD c;
  105. MEMORYPACKET mpUrlA, mpHostName, mpUserName, mpScheme, mpPassword, mpUrlPath, mpExtraInfo;
  106. URL_COMPONENTSA UCA;
  107. if (!(pszUrlW && pUCW))
  108. {
  109. dwErr = ERROR_INVALID_PARAMETER;
  110. goto cleanup;
  111. }
  112. UCA.dwStructSize = sizeof(URL_COMPONENTSA);
  113. ALLOC_MB(pszUrlW, dwUrlLengthW, mpUrlA);
  114. if (!mpUrlA.psStr) {
  115. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  116. goto cleanup;
  117. }
  118. UNICODE_TO_ANSI(pszUrlW, mpUrlA);
  119. for (c=0; c<=5; c++) {
  120. LPWSTR pszWorker;
  121. DWORD ccLen;
  122. MEMORYPACKET* pmpWorker;
  123. switch(c)
  124. {
  125. case 0:
  126. pszWorker = pUCW->lpszScheme;
  127. ccLen = pUCW->dwSchemeLength;
  128. pmpWorker = &mpScheme;
  129. break;
  130. case 1:
  131. pszWorker = pUCW->lpszHostName;
  132. ccLen = pUCW->dwHostNameLength;
  133. pmpWorker = &mpHostName;
  134. break;
  135. case 2:
  136. pszWorker = pUCW->lpszUserName;
  137. ccLen = pUCW->dwUserNameLength;
  138. pmpWorker = &mpUserName;
  139. break;
  140. case 3:
  141. pszWorker = pUCW->lpszPassword;
  142. ccLen = pUCW->dwPasswordLength;
  143. pmpWorker = &mpPassword;
  144. break;
  145. case 4:
  146. pszWorker = pUCW->lpszUrlPath;
  147. ccLen = pUCW->dwUrlPathLength;
  148. pmpWorker = &mpUrlPath;
  149. break;
  150. case 5:
  151. pszWorker = pUCW->lpszExtraInfo;
  152. ccLen = pUCW->dwExtraInfoLength;
  153. pmpWorker = &mpExtraInfo;
  154. break;
  155. }
  156. if (pszWorker) {
  157. ALLOC_MB(pszWorker,ccLen,(*pmpWorker));
  158. if (!pmpWorker->psStr) {
  159. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  160. goto cleanup;
  161. }
  162. } else {
  163. pmpWorker->dwAlloc = ccLen;
  164. }
  165. };
  166. REASSIGN_ALLOC(mpScheme,UCA.lpszScheme,UCA.dwSchemeLength);
  167. REASSIGN_ALLOC(mpHostName, UCA.lpszHostName,UCA.dwHostNameLength);
  168. REASSIGN_ALLOC(mpUserName, UCA.lpszUserName,UCA.dwUserNameLength);
  169. REASSIGN_ALLOC(mpPassword,UCA.lpszPassword,UCA.dwPasswordLength);
  170. REASSIGN_ALLOC(mpUrlPath,UCA.lpszUrlPath,UCA.dwUrlPathLength);
  171. REASSIGN_ALLOC(mpExtraInfo,UCA.lpszExtraInfo,UCA.dwExtraInfoLength);
  172. fResult = InternetCrackUrlA(mpUrlA.psStr, mpUrlA.dwSize, dwFlags, &UCA);
  173. if (fResult) {
  174. FixStrings(UCA.lpszScheme, UCA.dwSchemeLength, pUCW->lpszScheme,
  175. pUCW->dwSchemeLength, mpUrlA.psStr, pszUrlW);
  176. FixStrings(UCA.lpszHostName, UCA.dwHostNameLength, pUCW->lpszHostName,
  177. pUCW->dwHostNameLength, mpUrlA.psStr, pszUrlW);
  178. FixStrings(UCA.lpszUserName, UCA.dwUserNameLength, pUCW->lpszUserName,
  179. pUCW->dwUserNameLength, mpUrlA.psStr, pszUrlW);
  180. FixStrings(UCA.lpszPassword, UCA.dwPasswordLength, pUCW->lpszPassword,
  181. pUCW->dwPasswordLength, mpUrlA.psStr, pszUrlW);
  182. FixStrings(UCA.lpszUrlPath, UCA.dwUrlPathLength, pUCW->lpszUrlPath,
  183. pUCW->dwUrlPathLength, mpUrlA.psStr, pszUrlW);
  184. FixStrings(UCA.lpszExtraInfo, UCA.dwExtraInfoLength, pUCW->lpszExtraInfo,
  185. pUCW->dwExtraInfoLength, mpUrlA.psStr, pszUrlW);
  186. pUCW->nScheme = UCA.nScheme;
  187. pUCW->nPort = UCA.nPort;
  188. pUCW->dwStructSize = sizeof(URL_COMPONENTSW);
  189. }
  190. cleanup:
  191. if (dwErr!=ERROR_SUCCESS) {
  192. SetLastError(dwErr);
  193. DEBUG_ERROR(API, dwErr);
  194. }
  195. DEBUG_LEAVE_API(fResult);
  196. return fResult;
  197. }
  198. INTERNETAPI_(BOOL) InternetCreateUrlW(
  199. IN LPURL_COMPONENTSW pUCW,
  200. IN DWORD dwFlags,
  201. OUT LPWSTR pszUrlW,
  202. IN OUT LPDWORD pdwUrlLengthW
  203. )
  204. /*++
  205. Routine Description:
  206. Creates an URL from its constituent parts
  207. Arguments:
  208. Return Value:
  209. BOOL
  210. Success - URL written to pszUrl
  211. Failure - call GetLastError() for more info
  212. --*/
  213. {
  214. DEBUG_ENTER_API((DBG_API,
  215. Bool,
  216. "InternetCreateUrlW",
  217. "%#x, %#x, %#x, %#x",
  218. pUCW,
  219. dwFlags,
  220. pszUrlW,
  221. pdwUrlLengthW
  222. ));
  223. // INET_ASSERT(pszUrlW);
  224. INET_ASSERT(pUCW);
  225. DWORD dwErr = ERROR_SUCCESS;
  226. BOOL fResult = FALSE;
  227. MEMORYPACKET mpUrlA, mpHostName, mpUserName, mpScheme, mpPassword, mpUrlPath, mpExtraInfo;
  228. URL_COMPONENTSA UCA;
  229. if (!pdwUrlLengthW
  230. || (pUCW==NULL)
  231. || IsBadWritePtr(pUCW, sizeof(*pUCW))
  232. || (pUCW->dwStructSize != sizeof(*pUCW))
  233. || (pszUrlW && IsBadWritePtr(pszUrlW, *pdwUrlLengthW*sizeof(WCHAR))))
  234. {
  235. dwErr = ERROR_INVALID_PARAMETER;
  236. goto cleanup;
  237. }
  238. if (pszUrlW)
  239. {
  240. ALLOC_MB(pszUrlW, *pdwUrlLengthW, mpUrlA);
  241. if (!mpUrlA.psStr)
  242. {
  243. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  244. goto cleanup;
  245. }
  246. }
  247. mpUrlA.dwSize = mpUrlA.dwAlloc;
  248. UCA.dwStructSize = sizeof(URL_COMPONENTSA);
  249. UCA.nScheme = pUCW->nScheme;
  250. UCA.nPort = pUCW->nPort;
  251. if (pUCW->lpszScheme)
  252. {
  253. ALLOC_MB(pUCW->lpszScheme, pUCW->dwSchemeLength, mpScheme);
  254. if (!mpScheme.psStr)
  255. {
  256. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  257. goto cleanup;
  258. }
  259. UNICODE_TO_ANSI(pUCW->lpszScheme, mpScheme);
  260. }
  261. REASSIGN_SIZE(mpScheme, UCA.lpszScheme, UCA.dwSchemeLength);
  262. if (pUCW->lpszHostName)
  263. {
  264. ALLOC_MB(pUCW->lpszHostName, pUCW->dwHostNameLength, mpHostName);
  265. if (!mpHostName.psStr)
  266. {
  267. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  268. goto cleanup;
  269. }
  270. UNICODE_TO_ANSI(pUCW->lpszHostName, mpHostName);
  271. }
  272. REASSIGN_SIZE(mpHostName, UCA.lpszHostName, UCA.dwHostNameLength);
  273. if (pUCW->lpszUserName)
  274. {
  275. ALLOC_MB(pUCW->lpszUserName, pUCW->dwUserNameLength, mpUserName);
  276. if (!mpUserName.psStr)
  277. {
  278. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  279. goto cleanup;
  280. }
  281. UNICODE_TO_ANSI(pUCW->lpszUserName, mpUserName);
  282. }
  283. REASSIGN_SIZE(mpUserName, UCA.lpszUserName, UCA.dwUserNameLength);
  284. if (pUCW->lpszPassword)
  285. {
  286. ALLOC_MB(pUCW->lpszPassword, pUCW->dwPasswordLength, mpPassword);
  287. if (!mpPassword.psStr)
  288. {
  289. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  290. goto cleanup;
  291. }
  292. UNICODE_TO_ANSI(pUCW->lpszPassword, mpPassword);
  293. }
  294. REASSIGN_SIZE(mpPassword, UCA.lpszPassword, UCA.dwPasswordLength);
  295. if (pUCW->lpszUrlPath)
  296. {
  297. ALLOC_MB(pUCW->lpszUrlPath, pUCW->dwUrlPathLength, mpUrlPath);
  298. if (!mpUrlPath.psStr)
  299. {
  300. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  301. goto cleanup;
  302. }
  303. UNICODE_TO_ANSI(pUCW->lpszUrlPath, mpUrlPath);
  304. }
  305. REASSIGN_SIZE(mpUrlPath, UCA.lpszUrlPath, UCA.dwUrlPathLength);
  306. if (pUCW->lpszExtraInfo)
  307. {
  308. ALLOC_MB(pUCW->lpszExtraInfo, pUCW->dwExtraInfoLength, mpExtraInfo);
  309. if (!mpExtraInfo.psStr)
  310. {
  311. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  312. goto cleanup;
  313. }
  314. UNICODE_TO_ANSI(pUCW->lpszExtraInfo, mpExtraInfo);
  315. }
  316. REASSIGN_SIZE(mpExtraInfo, UCA.lpszExtraInfo, UCA.dwExtraInfoLength);
  317. fResult = InternetCreateUrlA(&UCA, dwFlags, mpUrlA.psStr, &mpUrlA.dwSize);
  318. if (fResult)
  319. {
  320. MAYBE_COPY_ANSI(mpUrlA, pszUrlW, *pdwUrlLengthW);
  321. }
  322. else
  323. {
  324. *pdwUrlLengthW = mpUrlA.dwSize*sizeof(WCHAR);
  325. }
  326. cleanup:
  327. if (dwErr!=ERROR_SUCCESS) {
  328. SetLastError(dwErr);
  329. DEBUG_ERROR(API, dwErr);
  330. }
  331. DEBUG_LEAVE_API(fResult);
  332. return fResult;
  333. }
  334. // implemented in inetapia.cxx
  335. DWORD ICUHrToWin32Error(HRESULT);
  336. INTERNETAPI_(BOOL) InternetCanonicalizeUrlW(
  337. IN LPCWSTR pszUrl,
  338. OUT LPWSTR pszBuffer,
  339. IN OUT LPDWORD lpdwBufferLength,
  340. IN DWORD dwFlags
  341. )
  342. /*++
  343. Routine Description:
  344. Combines a relative URL with a base URL to form a new full URL.
  345. Arguments:
  346. pszUrl - pointer to URL to be canonicalize
  347. pszBuffer - pointer to buffer where new URL is written
  348. lpdwBufferLength - size of buffer on entry, length of new URL on exit
  349. dwFlags - flags controlling operation
  350. Return Value:
  351. BOOL - TRUE if successful, FALSE if not
  352. --*/
  353. {
  354. DEBUG_ENTER_API((DBG_API,
  355. Bool,
  356. "InternetCanonicalizeUrlW",
  357. "%wq, %#x, %#x [%d], %#x",
  358. pszUrl,
  359. pszBuffer,
  360. lpdwBufferLength,
  361. lpdwBufferLength ? *lpdwBufferLength : 0,
  362. dwFlags
  363. ));
  364. HRESULT hr ;
  365. BOOL bRet;
  366. // We don't need no stinkin asserts
  367. // INET_ASSERT(pszUrl);
  368. // INET_ASSERT(pszBuffer);
  369. // INET_ASSERT(lpdwBufferLength && (*lpdwBufferLength > 0));
  370. //
  371. // the flags for the Url* APIs in shlwapi should be the same
  372. // except that NO_ENCODE is on by default. so we need to flip it
  373. //
  374. dwFlags ^= ICU_NO_ENCODE;
  375. // Check for invalid parameters
  376. if (!pszUrl || !pszBuffer || !lpdwBufferLength
  377. || IsBadWritePtr(lpdwBufferLength, sizeof(lpdwBufferLength))
  378. || *lpdwBufferLength == 0
  379. || IsBadWritePtr(pszBuffer, *lpdwBufferLength*sizeof(WCHAR))
  380. || IsBadStringPtrW(pszUrl, INTERNET_MAX_URL_LENGTH))
  381. {
  382. hr = E_INVALIDARG;
  383. }
  384. else
  385. {
  386. hr = UrlCanonicalizeW(pszUrl, pszBuffer,
  387. lpdwBufferLength, dwFlags | URL_WININET_COMPATIBILITY);
  388. }
  389. if(FAILED(hr))
  390. {
  391. DWORD dw = ICUHrToWin32Error(hr);
  392. bRet = FALSE;
  393. DEBUG_ERROR(INET, dw);
  394. SetLastError(dw);
  395. }
  396. else
  397. bRet = TRUE;
  398. DEBUG_LEAVE_API(bRet);
  399. return bRet;
  400. }
  401. INTERNETAPI_(BOOL) InternetCombineUrlW(
  402. IN LPCWSTR pszBaseUrl,
  403. IN LPCWSTR pszRelativeUrl,
  404. OUT LPWSTR pszBuffer,
  405. IN OUT LPDWORD lpdwBufferLength,
  406. IN DWORD dwFlags
  407. )
  408. /*++
  409. Routine Description:
  410. Combines a relative URL with a base URL to form a new full URL.
  411. Arguments:
  412. pszBaseUrl - pointer to base URL
  413. pszRelativeUrl - pointer to relative URL
  414. pszBuffer - pointer to buffer where new URL is written
  415. lpdwBufferLength - size of buffer on entry, length of new URL on exit
  416. dwFlags - flags controlling operation
  417. Return Value:
  418. BOOL - TRUE if successful, FALSE if not
  419. --*/
  420. {
  421. DEBUG_ENTER_API((DBG_API,
  422. Bool,
  423. "InternetCombineUrlW",
  424. "%wq, %wq, %#x, %#x [%d], %#x",
  425. pszBaseUrl,
  426. pszRelativeUrl,
  427. pszBuffer,
  428. lpdwBufferLength,
  429. lpdwBufferLength ? *lpdwBufferLength : 0,
  430. dwFlags
  431. ));
  432. HRESULT hr ;
  433. BOOL bRet;
  434. // We don't need no stinkin' asserts
  435. // INET_ASSERT(pszBaseUrl);
  436. // INET_ASSERT(pszRelativeUrl);
  437. // INET_ASSERT(lpdwBufferLength);
  438. //
  439. // the flags for the Url* APIs in shlwapi should be the same
  440. // except that NO_ENCODE is on by default. so we need to flip it
  441. //
  442. dwFlags ^= ICU_NO_ENCODE;
  443. // Check for invalid parameters
  444. if (!pszBaseUrl || !pszRelativeUrl || !lpdwBufferLength
  445. || IsBadWritePtr(lpdwBufferLength, sizeof(*lpdwBufferLength))
  446. || (pszBuffer && IsBadWritePtr(pszBuffer, *lpdwBufferLength*sizeof(WCHAR)))
  447. || IsBadStringPtrW(pszBaseUrl, INTERNET_MAX_URL_LENGTH)
  448. || IsBadStringPtrW(pszRelativeUrl, INTERNET_MAX_URL_LENGTH))
  449. {
  450. hr = E_INVALIDARG;
  451. }
  452. else
  453. {
  454. hr = UrlCombineW(pszBaseUrl, pszRelativeUrl, pszBuffer,
  455. lpdwBufferLength, dwFlags | URL_WININET_COMPATIBILITY);
  456. }
  457. if(FAILED(hr))
  458. {
  459. DWORD dw = ICUHrToWin32Error(hr);
  460. bRet = FALSE;
  461. DEBUG_ERROR(INET, dw);
  462. SetLastError(dw);
  463. }
  464. else
  465. bRet = TRUE;
  466. DEBUG_LEAVE_API(bRet);
  467. return bRet;
  468. }
  469. INTERNETAPI_(HINTERNET) InternetOpenW(
  470. IN LPCWSTR pszAgentW,
  471. IN DWORD dwAccessType,
  472. IN LPCWSTR pszProxyW OPTIONAL,
  473. IN LPCWSTR pszProxyBypassW OPTIONAL,
  474. IN DWORD dwFlags
  475. )
  476. /*++
  477. Routine Description:
  478. description-of-function.
  479. Arguments:
  480. pszAgent -
  481. dwAccessType -
  482. pszProxy -
  483. pszProxyBypass -
  484. dwFlags -
  485. Return Value:
  486. HINTERNET
  487. --*/
  488. {
  489. DEBUG_ENTER_API((DBG_API,
  490. Handle,
  491. "InternetOpenW",
  492. "%wq, %s (%d), %wq, %wq, %#x",
  493. pszAgentW,
  494. InternetMapOpenType(dwAccessType),
  495. dwAccessType,
  496. pszProxyW,
  497. pszProxyBypassW,
  498. dwFlags
  499. ));
  500. DWORD dwErr = ERROR_SUCCESS;
  501. HINTERNET hInternet = NULL;
  502. MEMORYPACKET mpAgentA, mpProxyA, mpProxyBypassA;
  503. ALLOC_MB(pszAgentW,0,mpAgentA);
  504. if (!mpAgentA.psStr)
  505. {
  506. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  507. goto cleanup;
  508. }
  509. UNICODE_TO_ANSI(pszAgentW,mpAgentA);
  510. if (pszProxyW)
  511. {
  512. ALLOC_MB(pszProxyW,0,mpProxyA);
  513. if (!mpProxyA.psStr)
  514. {
  515. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  516. goto cleanup;
  517. }
  518. UNICODE_TO_ANSI(pszProxyW,mpProxyA);
  519. }
  520. if (pszProxyBypassW)
  521. {
  522. ALLOC_MB(pszProxyBypassW,0,mpProxyBypassA);
  523. if (!mpProxyBypassA.psStr)
  524. {
  525. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  526. goto cleanup;
  527. }
  528. UNICODE_TO_ANSI(pszProxyBypassW,mpProxyBypassA);
  529. }
  530. hInternet = InternetOpenA(mpAgentA.psStr, dwAccessType, mpProxyA.psStr,
  531. mpProxyBypassA.psStr, dwFlags);
  532. cleanup:
  533. if (dwErr!=ERROR_SUCCESS) {
  534. SetLastError(dwErr);
  535. DEBUG_ERROR(API, dwErr);
  536. }
  537. DEBUG_LEAVE_API(hInternet);
  538. return hInternet;
  539. }
  540. INTERNETAPI_(HINTERNET) InternetConnectW(
  541. IN HINTERNET hInternetSession,
  542. IN LPCWSTR pszServerNameW,
  543. IN INTERNET_PORT nServerPort,
  544. IN LPCWSTR pszUserNameW,
  545. IN LPCWSTR pszPasswordW,
  546. IN DWORD dwService,
  547. IN DWORD dwFlags,
  548. IN DWORD_PTR dwContext
  549. )
  550. /*++
  551. Routine Description:
  552. description-of-function.
  553. Arguments:
  554. hInternetSession -
  555. pszServerName -
  556. nServerPort -
  557. pszUserName -
  558. pszPassword -
  559. dwService -
  560. dwFlags -
  561. dwContext -
  562. Return Value:
  563. HINTERNET
  564. --*/
  565. {
  566. DEBUG_ENTER_API((DBG_API,
  567. Handle,
  568. "InternetConnectW",
  569. "%#x, %wq, %d, %wq, %wq, %s (%d), %#08x, %#x",
  570. hInternetSession,
  571. pszServerNameW,
  572. nServerPort,
  573. pszUserNameW,
  574. pszPasswordW,
  575. InternetMapService(dwService),
  576. dwService,
  577. dwFlags,
  578. dwContext
  579. ));
  580. DWORD dwErr = ERROR_SUCCESS;
  581. MEMORYPACKET mpServerNameA, mpUserNameA, mpPasswordA;
  582. HINTERNET hInternet = NULL;
  583. if (!pszServerNameW)
  584. {
  585. dwErr = ERROR_INVALID_PARAMETER;
  586. goto cleanup;
  587. }
  588. ALLOC_MB(pszServerNameW, 0, mpServerNameA);
  589. if (!mpServerNameA.psStr)
  590. {
  591. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  592. goto cleanup;
  593. }
  594. UNICODE_TO_ANSI(pszServerNameW, mpServerNameA);
  595. if (pszUserNameW)
  596. {
  597. ALLOC_MB(pszUserNameW, 0, mpUserNameA);
  598. if (!mpUserNameA.psStr)
  599. {
  600. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  601. goto cleanup;
  602. }
  603. UNICODE_TO_ANSI(pszUserNameW, mpUserNameA);
  604. }
  605. if (pszPasswordW)
  606. {
  607. ALLOC_MB(pszPasswordW, 0, mpPasswordA);
  608. if (!mpPasswordA.psStr)
  609. {
  610. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  611. goto cleanup;
  612. }
  613. UNICODE_TO_ANSI(pszPasswordW, mpPasswordA);
  614. }
  615. hInternet = InternetConnectA(hInternetSession, mpServerNameA.psStr, nServerPort,
  616. mpUserNameA.psStr, mpPasswordA.psStr, dwService, dwFlags, dwContext);
  617. cleanup:
  618. if (dwErr!=ERROR_SUCCESS) {
  619. SetLastError(dwErr);
  620. DEBUG_ERROR(API, dwErr);
  621. }
  622. DEBUG_LEAVE_API(hInternet);
  623. return hInternet;
  624. }
  625. INTERNETAPI_(HINTERNET) InternetOpenUrlW(
  626. IN HINTERNET hInternetSession,
  627. IN LPCWSTR pszUrlW,
  628. IN LPCWSTR pszHeadersW,
  629. IN DWORD dwHeadersLengthW,
  630. IN DWORD dwFlags,
  631. IN DWORD_PTR dwContext
  632. )
  633. /*++
  634. Routine Description:
  635. description-of-function.
  636. Arguments:
  637. hInternetSession -
  638. pszUrl -
  639. pszHeaders -
  640. dwHeadersLength -
  641. dwFlags -
  642. dwContext -
  643. Return Value:
  644. HINTERNET
  645. --*/
  646. {
  647. DEBUG_ENTER_API((DBG_API,
  648. Handle,
  649. "InternetOpenUrlW",
  650. "%#x, %wq, %.80wq, %d, %#08x, %#x",
  651. hInternetSession,
  652. pszUrlW,
  653. pszHeadersW,
  654. dwHeadersLengthW,
  655. dwFlags,
  656. dwContext
  657. ));
  658. DWORD dwErr = ERROR_SUCCESS;
  659. MEMORYPACKET mpHeadersA, mpUrlA;
  660. HINTERNET hInternet = NULL;
  661. if (!pszUrlW || (*pszUrlW==L'\0'))
  662. {
  663. dwErr = ERROR_INVALID_PARAMETER;
  664. goto cleanup;
  665. }
  666. ALLOC_MB(pszUrlW, 0, mpUrlA);
  667. if (!mpUrlA.psStr)
  668. {
  669. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  670. goto cleanup;
  671. }
  672. UNICODE_TO_ANSI(pszUrlW, mpUrlA);
  673. if (pszHeadersW)
  674. {
  675. ALLOC_MB(pszHeadersW, (dwHeadersLengthW==-1L? 0 : dwHeadersLengthW), mpHeadersA);
  676. if (!mpHeadersA.psStr)
  677. {
  678. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  679. goto cleanup;
  680. }
  681. UNICODE_TO_ANSI(pszHeadersW, mpHeadersA);
  682. }
  683. hInternet = InternetOpenUrlA(hInternetSession, mpUrlA.psStr, mpHeadersA.psStr,
  684. mpHeadersA.dwSize, dwFlags, dwContext);
  685. cleanup:
  686. if (dwErr!=ERROR_SUCCESS) {
  687. SetLastError(dwErr);
  688. DEBUG_ERROR(API, dwErr);
  689. }
  690. DEBUG_LEAVE_API(hInternet);
  691. return hInternet;
  692. }
  693. INTERNETAPI_(BOOL) InternetReadFileExW(
  694. IN HINTERNET hFile,
  695. OUT LPINTERNET_BUFFERSW lpBuffersOut,
  696. IN DWORD dwFlags,
  697. IN DWORD_PTR dwContext
  698. )
  699. {
  700. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  701. return FALSE;
  702. }
  703. INTERNETAPI_(BOOL) InternetWriteFileExW(
  704. IN HINTERNET hFile,
  705. IN LPINTERNET_BUFFERSW lpBuffersIn,
  706. IN DWORD dwFlags,
  707. IN DWORD_PTR dwContext
  708. )
  709. {
  710. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  711. return FALSE;
  712. }
  713. INTERNETAPI_(BOOL) InternetFindNextFileW(
  714. IN HINTERNET hFind,
  715. OUT LPVOID lpvFindData
  716. )
  717. /*++
  718. Routine Description:
  719. This function retrieves the next block of data from the server.
  720. Currently it supports the following protocol data :
  721. FtpFindNextFile
  722. GopherFindNext
  723. Arguments:
  724. hFind - handle that was obtained by a FindFirst call
  725. lpvFindData - pointer to buffer where the next block of data is copied
  726. Return Value:
  727. TRUE if the function successfully returns next block of data.
  728. FALSE otherwise. GetLastError() will return the error code.
  729. --*/
  730. {
  731. DEBUG_ENTER_API((DBG_API,
  732. Bool,
  733. "InternetFindNextFileW",
  734. "%#x, %#x",
  735. hFind,
  736. lpvFindData
  737. ));
  738. DWORD dwErr = ERROR_SUCCESS;
  739. HINTERNET hFindMapped;
  740. HINTERNET_HANDLE_TYPE handleType;
  741. BOOL fResult = FALSE;
  742. dwErr = MapHandleToAddress(hFind, (LPVOID *)&hFindMapped, FALSE);
  743. if (dwErr!=ERROR_SUCCESS)
  744. {
  745. goto cleanup;
  746. }
  747. dwErr = RGetHandleType(hFindMapped, &handleType);
  748. DereferenceObject(hFindMapped);
  749. if (dwErr!=ERROR_SUCCESS)
  750. {
  751. goto cleanup;
  752. }
  753. if ((handleType != TypeFtpFindHandle) && (handleType != TypeGopherFindHandle))
  754. {
  755. dwErr = ERROR_INTERNET_INVALID_OPERATION;
  756. goto cleanup;
  757. }
  758. if (handleType == TypeFtpFindHandle)
  759. {
  760. WIN32_FIND_DATAA fdA;
  761. dwErr = ProbeWriteBuffer(lpvFindData, sizeof(WIN32_FIND_DATAW));
  762. if (dwErr!=ERROR_SUCCESS)
  763. {
  764. goto cleanup;
  765. }
  766. if (InternetFindNextFileA(hFind,(LPVOID)&fdA))
  767. fResult = TransformFtpFindDataToW(&fdA,(LPWIN32_FIND_DATAW)lpvFindData);
  768. }
  769. else
  770. {
  771. GOPHER_FIND_DATAA gfdA;
  772. dwErr = ProbeWriteBuffer(lpvFindData, sizeof(GOPHER_FIND_DATAW));
  773. if (dwErr!=ERROR_SUCCESS)
  774. {
  775. goto cleanup;
  776. }
  777. if (InternetFindNextFileA(hFind,(LPVOID)&gfdA))
  778. fResult = TransformGopherFindDataToW(&gfdA,(LPGOPHER_FIND_DATAW)lpvFindData);
  779. }
  780. cleanup:
  781. if (dwErr!=ERROR_SUCCESS) {
  782. SetLastError(dwErr);
  783. DEBUG_ERROR(API, dwErr);
  784. }
  785. DEBUG_LEAVE_API(fResult);
  786. return fResult;
  787. }
  788. INTERNETAPI_(BOOL) InternetGetLastResponseInfoW(
  789. OUT LPDWORD lpdwErrorCategory,
  790. IN LPWSTR pszBufferW,
  791. IN OUT LPDWORD lpdwBufferLengthW
  792. )
  793. /*++
  794. Routine Description:
  795. description-of-function.
  796. Arguments:
  797. lpdwErrorCategory -
  798. pszBuffer -
  799. lpdwBufferLength -
  800. Return Value:
  801. BOOL
  802. --*/
  803. {
  804. DEBUG_ENTER_API((DBG_API,
  805. Bool,
  806. "InternetGetLastResponseInfoW",
  807. "%#x, %ws, %#x [%d]",
  808. lpdwErrorCategory,
  809. pszBufferW,
  810. lpdwBufferLengthW,
  811. lpdwBufferLengthW ? *lpdwBufferLengthW : 0
  812. ));
  813. DWORD dwErr = ERROR_SUCCESS;
  814. BOOL fResult = FALSE;
  815. MEMORYPACKET mpBufferA;
  816. if (pszBufferW)
  817. {
  818. ALLOC_MB(pszBufferW,*lpdwBufferLengthW,mpBufferA);
  819. if (!mpBufferA.psStr)
  820. {
  821. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  822. goto cleanup;
  823. }
  824. }
  825. mpBufferA.dwSize = mpBufferA.dwAlloc;
  826. fResult = InternetGetLastResponseInfoA(lpdwErrorCategory, mpBufferA.psStr,
  827. &mpBufferA.dwSize);
  828. if (fResult) {
  829. MAYBE_COPY_ANSI(mpBufferA, pszBufferW, *lpdwBufferLengthW);
  830. } else {
  831. *lpdwBufferLengthW = mpBufferA.dwSize*sizeof(WCHAR);
  832. }
  833. cleanup:
  834. if (dwErr!=ERROR_SUCCESS) {
  835. SetLastError(dwErr);
  836. DEBUG_ERROR(API, dwErr);
  837. }
  838. DEBUG_LEAVE_API(fResult);
  839. return fResult;
  840. }
  841. INTERNETAPI_(BOOL) InternetCheckConnectionW(
  842. IN LPCWSTR pszUrlW,
  843. IN DWORD dwFlags,
  844. IN DWORD dwReserved
  845. )
  846. /*++
  847. Routine Description:
  848. This routine tells the caller whether he can establish a connection to the
  849. network.
  850. Arguments:
  851. pszUrl this parameter is an indication to the API to attempt
  852. a specific host. The use of this parameter is based on the
  853. flags set in the dwFlags parameter
  854. dwFlags a bitwise OR of the following flags
  855. INTERNET_FLAG_ICC_FORCE_CONNECTION - force a connection if
  856. cannot find one already established
  857. INTERNET_FLAG_ICC_CONNECT_SPECIFIC_HOST - try the connection
  858. to the specific host. If this flag is not set then the
  859. host name is used if a quicker method is not avilable.
  860. dwReserved reserved
  861. Return Value:
  862. TRUE - Success
  863. FALSE - failure, GetLastError returns the error code
  864. --*/
  865. {
  866. DEBUG_ENTER_API((DBG_API,
  867. Bool,
  868. "InternetCheckConnectionW",
  869. "%ws %x",
  870. pszUrlW,
  871. dwFlags
  872. ));
  873. DWORD dwErr = ERROR_SUCCESS;
  874. MEMORYPACKET mpUrlA;
  875. BOOL fResult = FALSE;
  876. if (pszUrlW)
  877. {
  878. ALLOC_MB(pszUrlW,0,mpUrlA);
  879. if (!mpUrlA.psStr)
  880. {
  881. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  882. goto cleanup;
  883. }
  884. UNICODE_TO_ANSI(pszUrlW,mpUrlA);
  885. }
  886. fResult = InternetCheckConnectionA(mpUrlA.psStr, dwFlags, dwReserved);
  887. cleanup:
  888. if (dwErr!=ERROR_SUCCESS) {
  889. SetLastError(dwErr);
  890. DEBUG_ERROR(API, dwErr);
  891. }
  892. DEBUG_LEAVE_API(fResult);
  893. return fResult;
  894. }
  895. INTERNETAPI_(INTERNET_STATUS_CALLBACK) InternetSetStatusCallbackCore(
  896. IN HINTERNET hInternet,
  897. IN INTERNET_STATUS_CALLBACK lpfnInternetCallback,
  898. IN BOOL fType
  899. );
  900. INTERNETAPI_(INTERNET_STATUS_CALLBACK) InternetSetStatusCallbackW(
  901. IN HINTERNET hInternet,
  902. IN INTERNET_STATUS_CALLBACK lpfnInternetCallback
  903. )
  904. /*++
  905. Routine Description:
  906. Sets the status callback function for the DLL or the handle object
  907. Arguments:
  908. hInternet - handle of the object for which we wish to set the
  909. status callback
  910. lpfnInternetCallback - pointer to caller-supplied status function
  911. Return Value:
  912. FARPROC
  913. Success - previous status callback function address
  914. Failure - INTERNET_INVALID_STATUS_CALLBACK. Call GetLastErrorInfo() for
  915. more information:
  916. ERROR_INVALID_PARAMETER
  917. The callback function is invalid
  918. ERROR_INTERNET_INCORRECT_HANDLE_TYPE
  919. Cannot set the callback on the supplied handle (probably
  920. a NULL handle - per-process callbacks no longer
  921. supported)
  922. --*/
  923. {
  924. DEBUG_ENTER((DBG_INET,
  925. Pointer,
  926. "InternetSetStatusCallbackW",
  927. "%#x, %#x",
  928. hInternet,
  929. lpfnInternetCallback
  930. ));
  931. INTERNET_STATUS_CALLBACK pfn = InternetSetStatusCallbackCore(hInternet,lpfnInternetCallback,TRUE);
  932. DEBUG_LEAVE(pfn);
  933. return pfn;
  934. }
  935. #ifdef IGCURLW
  936. INTERNETAPI_(BOOL) InternetGetCertByURLW(
  937. IN LPWSTR lpszURL,
  938. IN OUT LPWSTR lpszCertText,
  939. OUT DWORD dwcbCertText
  940. )
  941. {
  942. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  943. return FALSE;
  944. return InternetGetCertByURLA(lpszURL,lpszCertText,dwcbCertText);
  945. }
  946. #endif
  947. INTERNETAPI_(BOOL) InternetShowSecurityInfoByURLW(
  948. IN LPWSTR pszUrlW,
  949. IN HWND hwndRootWindow
  950. )
  951. /*++
  952. Routine Description:
  953. Does a high-level lookup against the Certificate Cache.
  954. Searches by URL (broken down into hostname) for the Certificate,
  955. and returns it in a formatted (&localized) string.
  956. Arguments:
  957. lpszUrl - pointer to URL to crack
  958. lpszCertText - Output of formatted certifcate
  959. dwcbCertText - Size of lpszCertText
  960. Return Value:
  961. BOOL
  962. Success - TRUE
  963. Failure - FALSE. Call GetLastError() for more info
  964. --*/
  965. {
  966. DEBUG_ENTER_API((DBG_INET,
  967. Bool,
  968. "InternetShowSecurityInfoW",
  969. "%wq, %#x",
  970. pszUrlW,
  971. hwndRootWindow
  972. ));
  973. BOOL fResult = FALSE;
  974. DWORD dwErr = ERROR_SUCCESS;
  975. MEMORYPACKET mpUrlA;
  976. if (pszUrlW)
  977. {
  978. ALLOC_MB(pszUrlW,0,mpUrlA);
  979. if (!mpUrlA.psStr)
  980. {
  981. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  982. goto cleanup;
  983. }
  984. UNICODE_TO_ANSI(pszUrlW,mpUrlA);
  985. }
  986. fResult = InternetShowSecurityInfoByURLA(mpUrlA.psStr, hwndRootWindow);
  987. cleanup:
  988. if (dwErr!=ERROR_SUCCESS) {
  989. SetLastError(dwErr);
  990. DEBUG_ERROR(API, dwErr);
  991. }
  992. DEBUG_LEAVE_API(fResult);
  993. return fResult;
  994. }
  995. INTERNETAPI_(BOOL) InternetAlgIdToStringW(
  996. IN ALG_ID ai,
  997. IN LPWSTR lpstr,
  998. IN OUT LPDWORD lpdwstrLength,
  999. IN DWORD dwReserved /* Must be 0 */
  1000. )
  1001. /*++
  1002. Routine Description:
  1003. Converts a algid to a user-displayable string.
  1004. Arguments:
  1005. ai - Algorithm identifiers ( defined in wincrypt.h)
  1006. lpstr - Buffer to copy string into.
  1007. lpdwstrLength - pass in num of characters, return no of characters copied if successful,
  1008. else no of chars required (including null terminator)
  1009. dwReserved = Must be 0
  1010. Return Value:
  1011. DWORD
  1012. Win32 or WININET error code.
  1013. --*/
  1014. {
  1015. DEBUG_ENTER_API((DBG_API,
  1016. Bool,
  1017. "InternetAlgIdToStringW",
  1018. "%#x, %wq, %#x, %#x",
  1019. ai,
  1020. lpstr,
  1021. lpdwstrLength,
  1022. dwReserved
  1023. ));
  1024. DWORD dwErr = ERROR_SUCCESS;
  1025. MEMORYPACKET mpBuffer;
  1026. BOOL fResult = FALSE;
  1027. if (dwReserved!=0)
  1028. {
  1029. dwErr = ERROR_INVALID_PARAMETER;
  1030. goto cleanup;
  1031. }
  1032. if (lpstr)
  1033. {
  1034. mpBuffer.dwAlloc = mpBuffer.dwSize = *lpdwstrLength;
  1035. mpBuffer.psStr = (LPSTR)ALLOC_BYTES(mpBuffer.dwAlloc*sizeof(CHAR));
  1036. if (!mpBuffer.psStr)
  1037. {
  1038. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1039. goto cleanup;
  1040. }
  1041. }
  1042. if (InternetAlgIdToStringA(ai, (LPSTR)mpBuffer.psStr, &mpBuffer.dwSize, dwReserved))
  1043. {
  1044. *lpdwstrLength = MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1,
  1045. NULL, 0);
  1046. if (*lpdwstrLength*sizeof(WCHAR) <= mpBuffer.dwAlloc && lpstr)
  1047. {
  1048. MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1,
  1049. lpstr, *lpdwstrLength);
  1050. (*lpdwstrLength)--;
  1051. fResult = TRUE;
  1052. }
  1053. else
  1054. {
  1055. dwErr = ERROR_INSUFFICIENT_BUFFER;
  1056. }
  1057. }
  1058. else
  1059. {
  1060. dwErr = GetLastError();
  1061. if (dwErr == ERROR_INSUFFICIENT_BUFFER)
  1062. {
  1063. *lpdwstrLength = mpBuffer.dwSize * sizeof(WCHAR);
  1064. }
  1065. }
  1066. cleanup:
  1067. if (dwErr!=ERROR_SUCCESS) {
  1068. SetLastError(dwErr);
  1069. DEBUG_ERROR(API, dwErr);
  1070. }
  1071. DEBUG_LEAVE_API(fResult);
  1072. return fResult;
  1073. }
  1074. INTERNETAPI_(BOOL) InternetSecurityProtocolToStringW(
  1075. IN DWORD dwProtocol,
  1076. IN LPWSTR lpstr,
  1077. IN OUT LPDWORD lpdwstrLength,
  1078. IN DWORD dwReserved /* Must be 0 */
  1079. )
  1080. /*++
  1081. Routine Description:
  1082. Converts a security protocol to a user-displayable string.
  1083. Arguments:
  1084. dwProtocol - Security protocol identifier ( defined in wincrypt.h)
  1085. lpstr - Buffer to copy string into.
  1086. lpdwstrLength - pass in num of characters, return no of characters copied if successful,
  1087. else no of chars required (including null terminator)
  1088. dwReserved = Must be 0
  1089. Return Value:
  1090. DWORD
  1091. Win32 or WININET error code.
  1092. --*/
  1093. {
  1094. DEBUG_ENTER_API((DBG_API,
  1095. Bool,
  1096. "InternetSecurityProtocolToStringW",
  1097. "%d, %wq, %#x, %#x",
  1098. dwProtocol,
  1099. lpstr,
  1100. lpdwstrLength,
  1101. dwReserved
  1102. ));
  1103. DWORD dwErr = ERROR_SUCCESS;
  1104. MEMORYPACKET mpBuffer;
  1105. BOOL fResult = FALSE;
  1106. if (dwReserved!=0)
  1107. {
  1108. dwErr = ERROR_INVALID_PARAMETER;
  1109. goto cleanup;
  1110. }
  1111. if (lpstr)
  1112. {
  1113. mpBuffer.dwAlloc = mpBuffer.dwSize = *lpdwstrLength;
  1114. mpBuffer.psStr = (LPSTR)ALLOC_BYTES(mpBuffer.dwAlloc*sizeof(CHAR));
  1115. if (!mpBuffer.psStr)
  1116. {
  1117. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1118. goto cleanup;
  1119. }
  1120. }
  1121. if (InternetSecurityProtocolToStringA(dwProtocol, (LPSTR)mpBuffer.psStr, &mpBuffer.dwSize, dwReserved))
  1122. {
  1123. *lpdwstrLength = MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1,
  1124. NULL, 0);
  1125. if (*lpdwstrLength*sizeof(WCHAR) <= mpBuffer.dwAlloc && lpstr)
  1126. {
  1127. MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1,
  1128. lpstr, *lpdwstrLength);
  1129. (*lpdwstrLength)--;
  1130. fResult = TRUE;
  1131. }
  1132. else
  1133. {
  1134. dwErr = ERROR_INSUFFICIENT_BUFFER;
  1135. }
  1136. }
  1137. else
  1138. {
  1139. dwErr = GetLastError();
  1140. if (dwErr == ERROR_INSUFFICIENT_BUFFER)
  1141. {
  1142. *lpdwstrLength = mpBuffer.dwSize * sizeof(WCHAR);
  1143. }
  1144. }
  1145. cleanup:
  1146. if (dwErr!=ERROR_SUCCESS) {
  1147. SetLastError(dwErr);
  1148. DEBUG_ERROR(API, dwErr);
  1149. }
  1150. DEBUG_LEAVE_API(fResult);
  1151. return fResult;
  1152. }