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.

898 lines
28 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1995 - 1996
  6. //
  7. // File: turlread.cpp
  8. //
  9. // Contents: Read the specified URL using the wininet APIs
  10. //
  11. // See Usage() for a list of test options.
  12. //
  13. //
  14. // Functions: main
  15. //
  16. // History: 26-Feb-96 philh created
  17. //
  18. //--------------------------------------------------------------------------
  19. #include <windows.h>
  20. #include <assert.h>
  21. #include <wininet.h>
  22. #ifndef MAX_CACHE_ENTRY_INFO_SIZE
  23. # include <winineti.h>
  24. #endif
  25. #include <sensapi.h>
  26. #include "wincrypt.h"
  27. #include "crypthlp.h"
  28. #include "cryptnet.h"
  29. #include "certtest.h"
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <malloc.h>
  34. #include <memory.h>
  35. #include <time.h>
  36. // Fix for SP4, where ICU_BROWSER_MODE isn't defined
  37. #ifndef ICU_BROWSER_MODE
  38. #define ICU_BROWSER_MODE ICU_ENCODE_SPACES_ONLY
  39. #endif
  40. static void Usage(void)
  41. {
  42. printf("Usage: turlread [options] <URL>\n");
  43. printf("Options are:\n");
  44. printf(" -d - Delete cached URL\n");
  45. printf(" -i - Get cached URL information\n");
  46. printf(" -o - Offline only\n");
  47. printf(" -w - Wire only\n");
  48. printf(" -cBrowser - Canonicalize => Browser (default)\n");
  49. printf(" -cNone - Canonicalize => None\n");
  50. printf(" -cSpaces - Canonicalize => Spaces\n");
  51. printf(" -cAll - Canonicalize => All\n");
  52. printf(" -U - Unicode\n");
  53. printf(" -s - Get internet state\n");
  54. printf(" -n - Get host Name from URL\n");
  55. printf(" -S<number> - SyncTime delta seconds\n");
  56. printf(" -h - This message\n");
  57. printf("\n");
  58. }
  59. static void DisplayCacheEntryInfoA(
  60. LPSTR pszUrl
  61. )
  62. {
  63. BOOL fResult;
  64. DWORD cbCachEntryInfo;
  65. BYTE rgbCachEntryInfo[MAX_CACHE_ENTRY_INFO_SIZE];
  66. LPINTERNET_CACHE_ENTRY_INFOA pCacheEntryInfo =
  67. (LPINTERNET_CACHE_ENTRY_INFOA) &rgbCachEntryInfo[0];
  68. DWORD dwEntryType;
  69. cbCachEntryInfo = sizeof(rgbCachEntryInfo);
  70. fResult = GetUrlCacheEntryInfoA(
  71. pszUrl,
  72. pCacheEntryInfo,
  73. &cbCachEntryInfo);
  74. if (!fResult)
  75. PrintLastError("GetUrlCachEntryInfo");
  76. else if (cbCachEntryInfo == 0)
  77. printf("GetUrlCachEntryInfo returned no bytes\n");
  78. else {
  79. printf("UrlCachEntryInfo (%d bytes)::\n", cbCachEntryInfo);
  80. printf(" StructSize: %d\n", pCacheEntryInfo->dwStructSize);
  81. printf(" SourceUrlName: %s\n", pCacheEntryInfo->lpszSourceUrlName);
  82. printf(" LocalFileName: %s\n", pCacheEntryInfo->lpszLocalFileName);
  83. printf(" FileExtension: %s\n", pCacheEntryInfo->lpszFileExtension);
  84. dwEntryType = pCacheEntryInfo->CacheEntryType;
  85. printf(" CacheEntryType: 0x%x", dwEntryType);
  86. if (dwEntryType & NORMAL_CACHE_ENTRY)
  87. printf(" NORMAL");
  88. if (dwEntryType & STICKY_CACHE_ENTRY)
  89. printf(" STICKY");
  90. if (dwEntryType & EDITED_CACHE_ENTRY)
  91. printf(" EDITED");
  92. if (dwEntryType & TRACK_OFFLINE_CACHE_ENTRY)
  93. printf(" TRACK_OFFLINE");
  94. if (dwEntryType & TRACK_ONLINE_CACHE_ENTRY)
  95. printf(" TRACK_ONLINE");
  96. if (dwEntryType & SPARSE_CACHE_ENTRY)
  97. printf(" SPARSE");
  98. if (dwEntryType & COOKIE_CACHE_ENTRY)
  99. printf(" COOKIE");
  100. if (dwEntryType & URLHISTORY_CACHE_ENTRY)
  101. printf(" URLHISTORY");
  102. printf("\n");
  103. printf(" UseCount: %d\n", pCacheEntryInfo->dwUseCount);
  104. printf(" HitRate: %d\n", pCacheEntryInfo->dwHitRate);
  105. printf(" FileSize: %d\n", pCacheEntryInfo->dwSizeLow);
  106. printf(" LastModifiedTime:: %s\n",
  107. FileTimeText(&pCacheEntryInfo->LastModifiedTime));
  108. printf(" ExpireTime:: %s\n",
  109. FileTimeText(&pCacheEntryInfo->ExpireTime));
  110. printf(" LastAccessTime:: %s\n",
  111. FileTimeText(&pCacheEntryInfo->LastAccessTime));
  112. printf(" LastSyncTime:: %s\n",
  113. FileTimeText(&pCacheEntryInfo->LastSyncTime));
  114. printf(" ExemptDelta:: %d\n", pCacheEntryInfo->dwExemptDelta);
  115. if (pCacheEntryInfo->dwHeaderInfoSize) {
  116. printf(" HeaderInfo::\n");
  117. PrintBytes(" ", (BYTE *) pCacheEntryInfo->lpHeaderInfo,
  118. pCacheEntryInfo->dwHeaderInfoSize);
  119. }
  120. }
  121. }
  122. static void DisplayCacheEntryInfoW(
  123. LPWSTR pwszUrl
  124. )
  125. {
  126. BOOL fResult;
  127. char szUrl[_MAX_PATH + 1];
  128. DWORD cbCachEntryInfo;
  129. BYTE rgbCachEntryInfo[MAX_CACHE_ENTRY_INFO_SIZE];
  130. LPINTERNET_CACHE_ENTRY_INFOW pCacheEntryInfo =
  131. (LPINTERNET_CACHE_ENTRY_INFOW) &rgbCachEntryInfo[0];
  132. WideCharToMultiByte(
  133. CP_ACP,
  134. 0, // dwFlags
  135. pwszUrl,
  136. -1, // Null terminated
  137. szUrl,
  138. sizeof(szUrl),
  139. NULL, // lpDefaultChar
  140. NULL // lpfUsedDefaultChar
  141. );
  142. cbCachEntryInfo = sizeof(rgbCachEntryInfo);
  143. #if 0
  144. // BUG the signature of the following API was changed around 1804.
  145. // Changed from szUrl to wszUrl
  146. fResult = GetUrlCacheEntryInfoW(
  147. szUrl,
  148. pCacheEntryInfo,
  149. &cbCachEntryInfo);
  150. #else
  151. fResult = FALSE;
  152. SetLastError((DWORD) E_NOTIMPL);
  153. #endif
  154. if (!fResult)
  155. PrintLastError("GetUrlCachEntryInfo");
  156. else if (cbCachEntryInfo == 0)
  157. printf("GetUrlCachEntryInfo returned no bytes\n");
  158. else {
  159. printf("UrlCachEntryInfo (%d bytes)::\n", cbCachEntryInfo);
  160. printf(" SourceUrlName: %s\n", pCacheEntryInfo->lpszSourceUrlName);
  161. printf(" LocalFileName: %S\n", pCacheEntryInfo->lpszLocalFileName);
  162. printf(" UseCount: %d\n", pCacheEntryInfo->dwUseCount);
  163. printf(" HitRate: %d\n", pCacheEntryInfo->dwHitRate);
  164. printf(" FileSize: %d\n", pCacheEntryInfo->dwSizeLow);
  165. printf(" LastModifiedTime:: %s\n",
  166. FileTimeText(&pCacheEntryInfo->LastModifiedTime));
  167. printf(" ExpireTime:: %s\n",
  168. FileTimeText(&pCacheEntryInfo->ExpireTime));
  169. printf(" LastAccessTime:: %s\n",
  170. FileTimeText(&pCacheEntryInfo->LastAccessTime));
  171. printf(" LastSyncTime:: %s\n",
  172. FileTimeText(&pCacheEntryInfo->LastSyncTime));
  173. }
  174. }
  175. static void SetSyncTime(
  176. LPSTR pszUrl,
  177. LONG lDeltaSeconds
  178. )
  179. {
  180. DWORD dwFieldControl = CACHE_ENTRY_SYNCTIME_FC;
  181. INTERNET_CACHE_ENTRY_INFOA CacheEntry;
  182. FILETIME CurrentTime;
  183. BOOL fResult;
  184. memset(&CacheEntry, 0, sizeof(CacheEntry));
  185. CacheEntry.dwStructSize = sizeof(CacheEntry);
  186. GetSystemTimeAsFileTime(&CurrentTime);
  187. if (lDeltaSeconds >= 0)
  188. I_CryptIncrementFileTimeBySeconds(
  189. &CurrentTime,
  190. (DWORD) lDeltaSeconds,
  191. &CacheEntry.LastSyncTime
  192. );
  193. else
  194. I_CryptDecrementFileTimeBySeconds(
  195. &CurrentTime,
  196. (DWORD) -lDeltaSeconds,
  197. &CacheEntry.LastSyncTime
  198. );
  199. fResult = SetUrlCacheEntryInfoA( pszUrl, &CacheEntry, dwFieldControl );
  200. if (!fResult)
  201. PrintLastError("SetUrlCacheEntryInfoA");
  202. }
  203. #if 0
  204. static void DisplayDestinationReachableA(
  205. LPSTR pszUrl
  206. )
  207. {
  208. BOOL fResult;
  209. QOCINFO qocInfo;
  210. memset(&qocInfo, 0, sizeof(qocInfo));
  211. qocInfo.dwSize = sizeof(qocInfo);
  212. fResult = IsDestinationReachableA(pszUrl, &qocInfo);
  213. if (fResult) {
  214. printf("Url is reachable, InSpeed: %d OutSpeed: %d dwFlags: 0x%x\n",
  215. qocInfo.dwInSpeed, qocInfo.dwOutSpeed, qocInfo.dwFlags);
  216. } else
  217. PrintLastError("IsDestinationReachable");
  218. }
  219. #endif
  220. static void ReadUrl(
  221. HINTERNET hInternetFile
  222. )
  223. {
  224. BOOL fResult;
  225. DWORD cb;
  226. DWORD cbTotal;
  227. cb = 0;
  228. fResult = InternetQueryDataAvailable(
  229. hInternetFile,
  230. &cb,
  231. 0, // dwFlags
  232. 0 // dwContext
  233. );
  234. if (!fResult)
  235. PrintLastError("InternetQueryDataAvailable");
  236. else
  237. printf("NumberOfBytesAvailable: %d\n", cb);
  238. cbTotal = 0;
  239. while (TRUE) {
  240. BYTE rgb[512];
  241. memset(rgb, 0, sizeof(rgb));
  242. DWORD cbRead = 0;
  243. fResult = InternetReadFile(
  244. hInternetFile,
  245. rgb,
  246. sizeof(rgb),
  247. &cbRead);
  248. if (cbRead) {
  249. cbTotal += cbRead;
  250. if (!fResult)
  251. PrintLastError("InternetReadFile(cbRead != 0)");
  252. printf("Bytes read from URL::\n");
  253. PrintBytes(" ", rgb, cbRead);
  254. } else {
  255. if (!fResult)
  256. PrintLastError("InternetReadFile(cbRead == 0)");
  257. break;
  258. }
  259. }
  260. printf("Total number of bytes read: %d\n", cbTotal);
  261. }
  262. static void OfflineUrlA(
  263. LPSTR pszUrl
  264. )
  265. {
  266. HINTERNET hInternetSession = NULL;
  267. HINTERNET hInternetFile = NULL;
  268. DWORD dwFlags;
  269. printf("**** OFFLINE ****\n");
  270. dwFlags = INTERNET_FLAG_OFFLINE;
  271. hInternetSession = InternetOpenA(
  272. "CRL Agent", // lpszAgent
  273. INTERNET_OPEN_TYPE_PRECONFIG, // dwAccessType
  274. NULL, // lpszProxy
  275. NULL, // lpszProxyBypass
  276. dwFlags
  277. );
  278. if (NULL == hInternetSession) {
  279. PrintLastError("InternetOpen");
  280. goto CommonReturn;
  281. }
  282. hInternetFile = InternetOpenUrlA(
  283. hInternetSession,
  284. pszUrl,
  285. "Accept: */*\r\n", // lpszHeaders
  286. (DWORD) -1L, // dwHeadersLength
  287. // INTERNET_FLAG_RELOAD, // dwFlags
  288. INTERNET_FLAG_IGNORE_CERT_CN_INVALID,
  289. 0 // dwContext
  290. );
  291. if (NULL == hInternetFile) {
  292. PrintLastError("InternetOpenUrl");
  293. goto CommonReturn;
  294. }
  295. DisplayCacheEntryInfoA(pszUrl);
  296. ReadUrl(hInternetFile);
  297. CommonReturn:
  298. if (hInternetFile) {
  299. if (!InternetCloseHandle(hInternetFile))
  300. PrintLastError("InternetCloseHandle(File)");
  301. }
  302. if (hInternetSession) {
  303. if (!InternetCloseHandle(hInternetSession))
  304. PrintLastError("InternetCloseHandle(Session)");
  305. }
  306. }
  307. static void OfflineUrlW(
  308. LPWSTR pwszUrl
  309. )
  310. {
  311. HINTERNET hInternetSession = NULL;
  312. HINTERNET hInternetFile = NULL;
  313. DWORD dwFlags;
  314. printf("**** OFFLINE ****\n");
  315. dwFlags = INTERNET_FLAG_OFFLINE;
  316. hInternetSession = InternetOpenW(
  317. L"CRL Agent", // lpszAgent
  318. INTERNET_OPEN_TYPE_PRECONFIG, // dwAccessType
  319. NULL, // lpszProxy
  320. NULL, // lpszProxyBypass
  321. dwFlags
  322. );
  323. if (NULL == hInternetSession) {
  324. PrintLastError("InternetOpenW");
  325. goto CommonReturn;
  326. }
  327. hInternetFile = InternetOpenUrlW(
  328. hInternetSession,
  329. pwszUrl,
  330. L"Accept: */*\r\n", // lpszHeaders
  331. (DWORD) -1L, // dwHeadersLength
  332. // INTERNET_FLAG_RELOAD, // dwFlags
  333. INTERNET_FLAG_IGNORE_CERT_CN_INVALID,
  334. 0 // dwContext
  335. );
  336. if (NULL == hInternetFile) {
  337. PrintLastError("InternetOpenUrlW");
  338. goto CommonReturn;
  339. }
  340. DisplayCacheEntryInfoW(pwszUrl);
  341. ReadUrl(hInternetFile);
  342. CommonReturn:
  343. if (hInternetFile) {
  344. if (!InternetCloseHandle(hInternetFile))
  345. PrintLastError("InternetCloseHandle(File)");
  346. }
  347. if (hInternetSession) {
  348. if (!InternetCloseHandle(hInternetSession))
  349. PrintLastError("InternetCloseHandle(Session)");
  350. }
  351. }
  352. typedef struct _QUERY_INFO {
  353. LPSTR pszInfo;
  354. DWORD dwInfo;
  355. } QUERY_INFO, *PQUERY_INFO;
  356. static QUERY_INFO rgQueryInfo[] = {
  357. #if 0
  358. "HTTP_QUERY_MIME_VERSION-Req",
  359. HTTP_QUERY_MIME_VERSION | HTTP_QUERY_FLAG_REQUEST_HEADERS,
  360. "HTTP_QUERY_CONTENT_TYPE-Req",
  361. HTTP_QUERY_CONTENT_TYPE | HTTP_QUERY_FLAG_REQUEST_HEADERS,
  362. "HTTP_QUERY_CONTENT_TRANSFER_ENCODING-Req",
  363. HTTP_QUERY_CONTENT_TRANSFER_ENCODING | HTTP_QUERY_FLAG_REQUEST_HEADERS,
  364. "HTTP_QUERY_CONTENT_LENGTH-Req",
  365. HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_REQUEST_HEADERS,
  366. #endif
  367. "Request WINHTTP_QUERY_RAW_HEADERS_CRLF",
  368. HTTP_QUERY_RAW_HEADERS_CRLF | HTTP_QUERY_FLAG_REQUEST_HEADERS,
  369. "HTTP_QUERY_MIME_VERSION", HTTP_QUERY_MIME_VERSION,
  370. "HTTP_QUERY_CONTENT_TYPE", HTTP_QUERY_CONTENT_TYPE,
  371. "HTTP_QUERY_CONTENT_TRANSFER_ENCODING",
  372. HTTP_QUERY_CONTENT_TRANSFER_ENCODING,
  373. "HTTP_QUERY_CONTENT_LENGTH", HTTP_QUERY_CONTENT_LENGTH,
  374. "HTTP_QUERY_CONTENT_LENGTH-Num",
  375. HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
  376. "HTTP_QUERY_VERSION", HTTP_QUERY_VERSION,
  377. "HTTP_QUERY_STATUS_CODE", HTTP_QUERY_STATUS_CODE,
  378. "HTTP_QUERY_STATUS_CODE-Num",
  379. HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
  380. "HTTP_QUERY_STATUS_TEXT", HTTP_QUERY_STATUS_TEXT,
  381. "HTTP_QUERY_RAW_HEADERS", HTTP_QUERY_RAW_HEADERS,
  382. "HTTP_QUERY_RAW_HEADERS_CRLF", HTTP_QUERY_RAW_HEADERS_CRLF,
  383. "HTTP_QUERY_CONTENT_ENCODING", HTTP_QUERY_CONTENT_ENCODING,
  384. "HTTP_QUERY_LOCATION", HTTP_QUERY_LOCATION,
  385. "HTTP_QUERY_ORIG_URI", HTTP_QUERY_ORIG_URI,
  386. "HTTP_QUERY_REQUEST_METHOD", HTTP_QUERY_REQUEST_METHOD,
  387. "HTTP_QUERY_DATE",
  388. HTTP_QUERY_DATE | HTTP_QUERY_FLAG_SYSTEMTIME,
  389. "HTTP_QUERY_EXPIRES",
  390. HTTP_QUERY_EXPIRES | HTTP_QUERY_FLAG_SYSTEMTIME,
  391. "HTTP_QUERY_LAST_MODIFIED",
  392. HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME,
  393. };
  394. #define NQUERYINFO (sizeof(rgQueryInfo)/sizeof(rgQueryInfo[0]))
  395. static void DisplayQueryInfo(IN HINTERNET hInternetFile, IN BOOL fUnicode)
  396. {
  397. DWORD i;
  398. for (i = 0; i < NQUERYINFO; i++) {
  399. DWORD dwIndex;
  400. BOOL fFirst;
  401. fFirst = TRUE;
  402. dwIndex = 0;
  403. while (TRUE) {
  404. BYTE rgbBuf[4096];
  405. DWORD cbBuf;
  406. DWORD dwThisIndex = dwIndex;
  407. BOOL fResult;
  408. DWORD dwValue;
  409. SYSTEMTIME st;
  410. memset(rgbBuf, 0, sizeof(rgbBuf));
  411. cbBuf = sizeof(rgbBuf);
  412. if (rgQueryInfo[i].dwInfo & HTTP_QUERY_FLAG_NUMBER) {
  413. dwValue = 0x183679;
  414. cbBuf = sizeof(dwValue);
  415. fResult = HttpQueryInfoA(
  416. hInternetFile,
  417. rgQueryInfo[i].dwInfo,
  418. &dwValue,
  419. &cbBuf,
  420. &dwIndex);
  421. } else if (rgQueryInfo[i].dwInfo & HTTP_QUERY_FLAG_SYSTEMTIME) {
  422. cbBuf = sizeof(st);
  423. fResult = HttpQueryInfoA(
  424. hInternetFile,
  425. rgQueryInfo[i].dwInfo,
  426. &st,
  427. &cbBuf,
  428. &dwIndex);
  429. } else if (fUnicode)
  430. fResult = HttpQueryInfoW(
  431. hInternetFile,
  432. rgQueryInfo[i].dwInfo,
  433. rgbBuf,
  434. &cbBuf,
  435. &dwIndex);
  436. else
  437. fResult = HttpQueryInfoA(
  438. hInternetFile,
  439. rgQueryInfo[i].dwInfo,
  440. rgbBuf,
  441. &cbBuf,
  442. &dwIndex);
  443. if (!fResult) {
  444. DWORD dwErr = GetLastError();
  445. if (fFirst || ERROR_HTTP_HEADER_NOT_FOUND != dwErr)
  446. printf("HttpQueryInfo(%s) failed => 0x%x (%d) \n",
  447. rgQueryInfo[i].pszInfo, dwErr, dwErr);
  448. break;
  449. } else if (rgQueryInfo[i].dwInfo & HTTP_QUERY_FLAG_NUMBER) {
  450. printf("%s[%d]:: 0x%x (%d)\n",
  451. rgQueryInfo[i].pszInfo, dwThisIndex, dwValue, dwValue);
  452. } else if (rgQueryInfo[i].dwInfo & HTTP_QUERY_FLAG_SYSTEMTIME) {
  453. FILETIME ft;
  454. if (!SystemTimeToFileTime(&st, &ft)) {
  455. DWORD dwErr = GetLastError();
  456. printf("SystemTimeToFileTime(%s) failed => 0x%x (%d) \n",
  457. rgQueryInfo[i].pszInfo, dwErr, dwErr);
  458. } else
  459. printf("%s[%d]:: %s\n", rgQueryInfo[i].pszInfo,
  460. dwThisIndex, FileTimeText(&ft));
  461. } else {
  462. printf("%s[%d]::\n",
  463. rgQueryInfo[i].pszInfo, dwThisIndex);
  464. PrintBytes(" ", rgbBuf, cbBuf);
  465. }
  466. fFirst = FALSE;
  467. if (dwThisIndex == dwIndex) {
  468. #if 0
  469. printf("HttpQueryInfo(%s) dwIndex not advanced\n",
  470. rgQueryInfo[i].pszInfo);
  471. #endif
  472. break;
  473. }
  474. }
  475. }
  476. }
  477. static void OnlineUrlA(
  478. LPSTR pszUrl
  479. )
  480. {
  481. HINTERNET hInternetSession = NULL;
  482. HINTERNET hInternetFile = NULL;
  483. DWORD dwFlags;
  484. printf("**** ONLINE ****\n");
  485. #if 0
  486. DisplayDestinationReachableA(pszUrl);
  487. #endif
  488. dwFlags = 0;
  489. hInternetSession = InternetOpenA(
  490. "CRL Agent", // lpszAgent
  491. INTERNET_OPEN_TYPE_PRECONFIG, // dwAccessType
  492. NULL, // lpszProxy
  493. NULL, // lpszProxyBypass
  494. dwFlags
  495. );
  496. if (NULL == hInternetSession) {
  497. PrintLastError("InternetOpen");
  498. goto CommonReturn;
  499. }
  500. hInternetFile = InternetOpenUrlA(
  501. hInternetSession,
  502. pszUrl,
  503. "Accept: */*\r\n", // lpszHeaders
  504. (DWORD) -1L, // dwHeadersLength
  505. INTERNET_FLAG_RELOAD | INTERNET_FLAG_IGNORE_CERT_CN_INVALID,
  506. 0 // dwContext
  507. );
  508. if (NULL == hInternetFile) {
  509. PrintLastError("InternetOpenUrl");
  510. goto CommonReturn;
  511. }
  512. DisplayQueryInfo(hInternetFile, FALSE);
  513. ReadUrl(hInternetFile);
  514. DisplayCacheEntryInfoA(pszUrl);
  515. CommonReturn:
  516. if (hInternetFile) {
  517. if (!InternetCloseHandle(hInternetFile))
  518. PrintLastError("InternetCloseHandle(File)");
  519. }
  520. if (hInternetSession) {
  521. if (!InternetCloseHandle(hInternetSession))
  522. PrintLastError("InternetCloseHandle(Session)");
  523. }
  524. }
  525. static void OnlineUrlW(
  526. LPWSTR pwszUrl
  527. )
  528. {
  529. HINTERNET hInternetSession = NULL;
  530. HINTERNET hInternetFile = NULL;
  531. DWORD dwFlags;
  532. printf("**** ONLINE ****\n");
  533. dwFlags = 0;
  534. hInternetSession = InternetOpenW(
  535. L"CRL Agent", // lpszAgent
  536. INTERNET_OPEN_TYPE_PRECONFIG, // dwAccessType
  537. NULL, // lpszProxy
  538. NULL, // lpszProxyBypass
  539. dwFlags
  540. );
  541. if (NULL == hInternetSession) {
  542. PrintLastError("InternetOpenW");
  543. goto CommonReturn;
  544. }
  545. hInternetFile = InternetOpenUrlW(
  546. hInternetSession,
  547. pwszUrl,
  548. L"Accept: */*\r\n", // lpszHeaders
  549. (DWORD) -1L, // dwHeadersLength
  550. INTERNET_FLAG_RELOAD | INTERNET_FLAG_IGNORE_CERT_CN_INVALID,
  551. 0 // dwContext
  552. );
  553. if (NULL == hInternetFile) {
  554. PrintLastError("InternetOpenUrlW");
  555. goto CommonReturn;
  556. }
  557. DisplayQueryInfo(hInternetFile, TRUE);
  558. ReadUrl(hInternetFile);
  559. DisplayCacheEntryInfoW(pwszUrl);
  560. CommonReturn:
  561. if (hInternetFile) {
  562. if (!InternetCloseHandle(hInternetFile))
  563. PrintLastError("InternetCloseHandle(File)");
  564. }
  565. if (hInternetSession) {
  566. if (!InternetCloseHandle(hInternetSession))
  567. PrintLastError("InternetCloseHandle(Session)");
  568. }
  569. }
  570. void DisplayInternetState()
  571. {
  572. DWORD dwFlags = 0;
  573. BOOL fResult;
  574. fResult = InternetGetConnectedState(&dwFlags, 0);
  575. if (!fResult)
  576. printf("NO ");
  577. printf("Internet Connection, dwFlags: 0x%x", dwFlags);
  578. if (dwFlags & INTERNET_CONNECTION_MODEM)
  579. printf(" MODEM");
  580. if (dwFlags & INTERNET_CONNECTION_LAN)
  581. printf(" LAN");
  582. if (dwFlags & INTERNET_CONNECTION_PROXY)
  583. printf(" PROXY");
  584. if (dwFlags & INTERNET_CONNECTION_MODEM_BUSY)
  585. printf(" MODEM_BUSY");
  586. if (dwFlags & INTERNET_RAS_INSTALLED)
  587. printf(" RAS_INSTALLED");
  588. if (dwFlags & INTERNET_CONNECTION_OFFLINE)
  589. printf(" OFFLINE");
  590. if (dwFlags & INTERNET_CONNECTION_CONFIGURED)
  591. printf(" CONFIGURED");
  592. printf("\n");
  593. dwFlags = 0;
  594. fResult = IsNetworkAlive(&dwFlags);
  595. if (fResult) {
  596. printf("Network Alive, dwFlags: 0x%x", dwFlags);
  597. if (dwFlags & NETWORK_ALIVE_LAN)
  598. printf(" LAN");
  599. if (dwFlags & NETWORK_ALIVE_WAN)
  600. printf(" WAN");
  601. if (dwFlags & NETWORK_ALIVE_AOL)
  602. printf(" AOL");
  603. printf("\n");
  604. } else {
  605. DWORD dwErr = GetLastError();
  606. printf("Network disconnected, 0x%x (%d)\n", dwErr, dwErr);
  607. }
  608. }
  609. int _cdecl main(int argc, char * argv[])
  610. {
  611. BOOL fResult;
  612. LPSTR pszUrl = NULL;
  613. WCHAR wszUrl[_MAX_PATH + 1];
  614. LPWSTR pwszUrl = NULL;
  615. BOOL fUnicode = FALSE;
  616. char szCanonicalizedUrl[_MAX_PATH + 1];
  617. WCHAR wszCanonicalizedUrl[_MAX_PATH + 1];
  618. DWORD cb;
  619. BOOL fDelete = FALSE;
  620. BOOL fCacheInfo = FALSE;
  621. BOOL fOfflineOnly = FALSE;
  622. BOOL fWireOnly = FALSE;
  623. #define NO_CANONICALIZE 0xFFFFFFFF
  624. DWORD dwCanonicalizeFlags = ICU_BROWSER_MODE;
  625. BOOL fSyncTime = FALSE;
  626. LONG lSyncTimeDeltaSeconds = 0;
  627. BOOL fHostName = FALSE;
  628. WCHAR wszHostName[_MAX_PATH + 1];
  629. while (--argc>0)
  630. {
  631. if (**++argv == '-')
  632. {
  633. switch(argv[0][1])
  634. {
  635. case 'U':
  636. fUnicode = TRUE;
  637. break;
  638. case 'd':
  639. fDelete = TRUE;
  640. break;
  641. case 'i':
  642. fCacheInfo = TRUE;
  643. break;
  644. case 'o':
  645. fOfflineOnly = TRUE;
  646. break;
  647. case 'w':
  648. fWireOnly = TRUE;
  649. break;
  650. case 'c':
  651. if (argv[0][2]) {
  652. if (0 == _stricmp(argv[0]+2, "None"))
  653. dwCanonicalizeFlags = NO_CANONICALIZE;
  654. else if (0 == _stricmp(argv[0]+2, "Spaces"))
  655. dwCanonicalizeFlags = ICU_ENCODE_SPACES_ONLY;
  656. else if (0 == _stricmp(argv[0]+2, "Browser"))
  657. dwCanonicalizeFlags = ICU_BROWSER_MODE;
  658. else if (0 == _stricmp(argv[0]+2, "All"))
  659. dwCanonicalizeFlags = 0;
  660. else {
  661. printf("Need to specify -cNone | -cSpaces | -cBrowser | -cAll\n");
  662. goto BadUsage;
  663. }
  664. } else {
  665. printf("Need to specify -cNone | -cSpaces | -cBrowser | -cAll\n");
  666. goto BadUsage;
  667. }
  668. break;
  669. case 's':
  670. DisplayInternetState();
  671. goto CommonReturn;
  672. case 'n':
  673. fHostName = TRUE;
  674. break;
  675. case 'S':
  676. fSyncTime = TRUE;
  677. lSyncTimeDeltaSeconds = strtol(argv[0]+2, NULL, 0);
  678. break;
  679. case 'h':
  680. default:
  681. goto BadUsage;
  682. }
  683. } else
  684. pszUrl = argv[0];
  685. }
  686. if (pszUrl == NULL) {
  687. printf("missing URL\n");
  688. goto BadUsage;
  689. }
  690. printf("command line: %s\n", GetCommandLine());
  691. if (fHostName) {
  692. MultiByteToWideChar(
  693. CP_ACP,
  694. 0, // dwFlags
  695. pszUrl,
  696. -1, // null terminated
  697. wszUrl,
  698. sizeof(wszUrl) / sizeof(wszUrl[0]));
  699. wszHostName[0] = L'\0';
  700. fResult = I_CryptNetGetHostNameFromUrl (
  701. wszUrl,
  702. sizeof(wszHostName) / sizeof(wszHostName[0]),
  703. wszHostName
  704. );
  705. if (!fResult)
  706. PrintLastError("I_CryptNetGetHostNameFromUrl");
  707. else
  708. printf("HostName :: %S\n", wszHostName);
  709. goto CommonReturn;
  710. }
  711. if (fUnicode) {
  712. MultiByteToWideChar(
  713. CP_ACP,
  714. 0, // dwFlags
  715. pszUrl,
  716. -1, // null terminated
  717. wszUrl,
  718. sizeof(wszUrl) / sizeof(wszUrl[0]));
  719. if (NO_CANONICALIZE == dwCanonicalizeFlags) {
  720. pwszUrl = wszUrl;
  721. printf("Unicode Url:: %S\n", pwszUrl);
  722. } else {
  723. cb = sizeof(wszCanonicalizedUrl);
  724. fResult = InternetCanonicalizeUrlW(
  725. wszUrl,
  726. wszCanonicalizedUrl,
  727. &cb,
  728. dwCanonicalizeFlags
  729. );
  730. if (!fResult) {
  731. PrintLastError("InternetCanonicalizeUrlW");
  732. goto CommonReturn;
  733. } else if (cb) {
  734. printf("Unicode CanonicalizedUrl:: %S\n", wszCanonicalizedUrl);
  735. pwszUrl = wszCanonicalizedUrl;
  736. } else {
  737. printf("Unicode CanonicalizedUrl:: returned empty string\n");
  738. goto CommonReturn;
  739. }
  740. }
  741. if (fDelete) {
  742. printf("Unicode DeleteUrlCacheEntry not supported\n");
  743. } else if (fSyncTime) {
  744. printf("Unicode SyncTime not supported\n");
  745. } else if (fCacheInfo) {
  746. DisplayCacheEntryInfoW(pwszUrl);
  747. } else if (fOfflineOnly) {
  748. OfflineUrlW(pwszUrl);
  749. } else if (fWireOnly) {
  750. OnlineUrlW(pwszUrl);
  751. } else {
  752. OfflineUrlW(pwszUrl);
  753. OnlineUrlW(pwszUrl);
  754. }
  755. } else {
  756. if (NO_CANONICALIZE == dwCanonicalizeFlags) {
  757. printf("Url:: %s\n", pszUrl);
  758. } else {
  759. cb = sizeof(szCanonicalizedUrl);
  760. fResult = InternetCanonicalizeUrlA(
  761. pszUrl,
  762. szCanonicalizedUrl,
  763. &cb,
  764. dwCanonicalizeFlags
  765. );
  766. if (!fResult) {
  767. PrintLastError("InternetCanonicalizeUrlA");
  768. goto CommonReturn;
  769. } else if (cb) {
  770. printf("CanonicalizedUrl:: %s\n", szCanonicalizedUrl);
  771. pszUrl = szCanonicalizedUrl;
  772. } else {
  773. printf("CanonicalizedUrl:: returned empty string\n");
  774. goto CommonReturn;
  775. }
  776. }
  777. if (fDelete) {
  778. if (!DeleteUrlCacheEntry(pszUrl)) {
  779. if (ERROR_FILE_NOT_FOUND != GetLastError())
  780. PrintLastError("DeleteUrlCacheEntry");
  781. }
  782. } else if (fSyncTime) {
  783. SetSyncTime(pszUrl, lSyncTimeDeltaSeconds);
  784. } else if (fCacheInfo) {
  785. DisplayCacheEntryInfoA(pszUrl);
  786. } else if (fOfflineOnly) {
  787. OfflineUrlA(pszUrl);
  788. } else if (fWireOnly) {
  789. OnlineUrlA(pszUrl);
  790. } else {
  791. OfflineUrlA(pszUrl);
  792. OnlineUrlA(pszUrl);
  793. }
  794. }
  795. CommonReturn:
  796. return 0;
  797. BadUsage:
  798. Usage();
  799. goto CommonReturn;
  800. }