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.

1548 lines
44 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. InetSess.cpp
  5. Abstract:
  6. Implements the Passport Session that uses WinInet as the underlying transport.
  7. Author:
  8. Biao Wang (biaow) 01-Oct-2000
  9. --*/
  10. #include "PPdefs.h"
  11. #ifdef HINTERNET
  12. #undef HINTERNET
  13. #endif
  14. #ifdef INTERNET_PORT
  15. #undef INTERNET_PORT
  16. #endif
  17. #include <WinInet.h>
  18. #include "session.h"
  19. // #include "inetsess.tmh"
  20. //
  21. // func pointer decl for WinInet
  22. //
  23. typedef HINTERNET
  24. (WINAPI * PFN_INTERNET_OPEN)(
  25. IN LPCWSTR lpwszAgent,
  26. IN DWORD dwAccessType,
  27. IN LPCWSTR lpwszProxy OPTIONAL,
  28. IN LPCWSTR lpwszProxyBypass OPTIONAL,
  29. IN DWORD dwFlags
  30. );
  31. typedef HINTERNET
  32. (WINAPI * PFN_INTERNET_CONNECT)(
  33. IN HINTERNET hInternet,
  34. IN LPCWSTR lpwszServerName,
  35. IN INTERNET_PORT nServerPort,
  36. IN LPCWSTR lpwszUserName OPTIONAL,
  37. IN LPCWSTR lpwszPassword OPTIONAL,
  38. IN DWORD dwService,
  39. IN DWORD dwFlags,
  40. IN DWORD_PTR dwContext
  41. );
  42. typedef HINTERNET
  43. (WINAPI * PFN_OPEN_REQUEST)(
  44. IN HINTERNET hConnect,
  45. IN LPCWSTR lpwszVerb,
  46. IN LPCWSTR lpwszObjectName,
  47. IN LPCWSTR lpwszVersion,
  48. IN LPCWSTR lpwszReferrer OPTIONAL,
  49. IN LPCWSTR FAR * lplpwszAcceptTypes OPTIONAL,
  50. IN DWORD dwFlags,
  51. IN DWORD_PTR dwContext
  52. );
  53. typedef BOOL
  54. (WINAPI * PFN_SEND_REQUEST)(
  55. IN HINTERNET hRequest,
  56. IN LPCWSTR lpwszHeaders OPTIONAL,
  57. IN DWORD dwHeadersLength,
  58. IN LPVOID lpOptional OPTIONAL,
  59. IN DWORD dwOptionalLength
  60. );
  61. typedef BOOL
  62. (WINAPI * PFN_QUERY_INFO)(
  63. IN HINTERNET hRequest,
  64. IN DWORD dwInfoLevel,
  65. IN LPVOID lpvBuffer,
  66. IN LPDWORD lpdwBufferLength,
  67. IN OUT LPDWORD lpdwIndex
  68. );
  69. typedef BOOL
  70. (WINAPI* PFN_CLOSE_HANDLE)(
  71. IN HINTERNET hInternet
  72. );
  73. typedef BOOL
  74. (WINAPI* PFN_SET_OPTION)(
  75. IN HINTERNET hInternet,
  76. IN DWORD dwOption,
  77. IN LPVOID lpBuffer,
  78. IN DWORD dwBufferLength
  79. );
  80. typedef BOOL
  81. (WINAPI* PFN_QUERY_OPTION)(
  82. IN HINTERNET hInternet,
  83. IN DWORD dwOption,
  84. OUT LPVOID lpBuffer,
  85. IN OUT LPDWORD lpdwBufferLength
  86. );
  87. typedef HINTERNET
  88. (WINAPI* PFN_OPEN_URL)(
  89. IN HINTERNET hInternet,
  90. IN LPCWSTR lpwszUrl,
  91. IN LPCWSTR lpwszHeaders,
  92. IN DWORD dwHeadersLength,
  93. IN DWORD dwFlags,
  94. IN DWORD_PTR dwContext
  95. );
  96. typedef BOOL
  97. (WINAPI* PFN_CRACK_URL)(
  98. IN LPCWSTR lpszUrl,
  99. IN DWORD dwUrlLength,
  100. IN DWORD dwFlags,
  101. IN OUT PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents
  102. );
  103. typedef BOOL
  104. (WINAPI* PFN_READ_FILE)(
  105. IN HINTERNET hFile,
  106. IN LPVOID lpBuffer,
  107. IN DWORD dwNumberOfBytesToRead,
  108. OUT LPDWORD lpdwNumberOfBytesRead
  109. );
  110. typedef INTERNET_STATUS_CALLBACK
  111. (WINAPI* PFN_STATUS_CALLBACK)(
  112. IN HINTERNET hInternet,
  113. IN INTERNET_STATUS_CALLBACK lpfnInternetCallback
  114. );
  115. typedef BOOL
  116. (WINAPI* PFN_ADD_HEADERS)(
  117. IN HINTERNET hConnect,
  118. IN LPCWSTR lpszHeaders,
  119. IN DWORD dwHeadersLength,
  120. IN DWORD dwModifiers
  121. );
  122. class WININET_SESSION : public SESSION
  123. {
  124. protected:
  125. WININET_SESSION(void);
  126. virtual ~WININET_SESSION(void);
  127. virtual BOOL Open(PCWSTR pwszHttpStack, HINTERNET);
  128. virtual void Close(void);
  129. protected:
  130. virtual HINTERNET Connect(
  131. LPCWSTR lpwszServerName,
  132. INTERNET_PORT
  133. );
  134. virtual HINTERNET OpenRequest(
  135. HINTERNET hConnect,
  136. LPCWSTR lpwszVerb,
  137. LPCWSTR lpwszObjectName,
  138. DWORD dwFlags,
  139. DWORD_PTR dwContext = 0);
  140. virtual BOOL SendRequest(
  141. HINTERNET hRequest,
  142. LPCWSTR lpwszHeaders,
  143. DWORD dwHeadersLength,
  144. DWORD_PTR dwContext = 0);
  145. virtual BOOL QueryHeaders(
  146. HINTERNET hRequest,
  147. DWORD dwInfoLevel,
  148. LPVOID lpvBuffer,
  149. LPDWORD lpdwBufferLength,
  150. LPDWORD lpdwIndex = NULL);
  151. virtual BOOL CloseHandle(
  152. IN HINTERNET hInternet);
  153. virtual BOOL QueryOption(
  154. HINTERNET hInternet,
  155. DWORD dwOption,
  156. LPVOID lpBuffer,
  157. LPDWORD lpdwBufferLength);
  158. virtual BOOL SetOption(
  159. HINTERNET hInternet,
  160. DWORD dwOption,
  161. LPVOID lpBuffer,
  162. DWORD dwBufferLength);
  163. virtual HINTERNET OpenUrl(
  164. LPCWSTR lpwszUrl,
  165. LPCWSTR lpwszHeaders,
  166. DWORD dwHeadersLength,
  167. DWORD dwFlags);
  168. virtual BOOL ReadFile(
  169. HINTERNET hFile,
  170. LPVOID lpBuffer,
  171. DWORD dwNumberOfBytesToRead,
  172. LPDWORD lpdwNumberOfBytesRead);
  173. virtual BOOL CrackUrl(
  174. LPCWSTR lpszUrl,
  175. DWORD dwUrlLength,
  176. DWORD dwFlags,
  177. PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents);
  178. virtual PVOID SetStatusCallback(
  179. HINTERNET hInternet,
  180. PVOID lpfnCallback
  181. );
  182. virtual BOOL AddHeaders(
  183. HINTERNET hConnect,
  184. LPCWSTR lpszHeaders,
  185. DWORD dwHeadersLength,
  186. DWORD dwModifiers
  187. );
  188. #ifdef PP_DEMO
  189. virtual BOOL ContactPartner(PCWSTR pwszPartnerUrl,
  190. PCWSTR pwszVerb,
  191. PCWSTR pwszHeaders,
  192. PWSTR pwszData,
  193. PDWORD pdwDataLength
  194. );
  195. #endif // PP_DEMO
  196. BOOL InitHttpApi(PFN_INTERNET_OPEN*);
  197. protected:
  198. HINTERNET m_hInternet;
  199. PFN_INTERNET_CONNECT m_pfnConnect;
  200. PFN_OPEN_REQUEST m_pfnOpenRequest;
  201. PFN_SEND_REQUEST m_pfnSendRequest;
  202. PFN_QUERY_INFO m_pfnQueryInfo;
  203. PFN_CLOSE_HANDLE m_pfnCloseHandle;
  204. PFN_SET_OPTION m_pfnSetOption;
  205. PFN_OPEN_URL m_pfnOpenUrl;
  206. PFN_QUERY_OPTION m_pfnQueryOption;
  207. PFN_CRACK_URL m_pfnCrack;
  208. PFN_READ_FILE m_pfnReadFile;
  209. PFN_STATUS_CALLBACK m_pfnStatusCallback;
  210. PFN_ADD_HEADERS m_pfnAddHeaders;
  211. friend class SESSION;
  212. };
  213. //
  214. // Implementation for SESSION
  215. //
  216. SESSION* CreateWinHttpSession(void);
  217. // -----------------------------------------------------------------------------
  218. BOOL SESSION::CreateObject(PCWSTR pwszHttpStack, HINTERNET hSession, SESSION*& pSess)
  219. {
  220. PP_ASSERT(pwszHttpStack != NULL);
  221. pSess = NULL;
  222. if (!::_wcsicmp(pwszHttpStack, L"WinInet.dll") ||
  223. !::_wcsicmp(pwszHttpStack, L"WinInet"))
  224. {
  225. pSess = new WININET_SESSION();
  226. }
  227. else
  228. {
  229. pSess = ::CreateWinHttpSession();
  230. }
  231. if (pSess)
  232. {
  233. return pSess->Open(pwszHttpStack, hSession);
  234. }
  235. else
  236. {
  237. DoTraceMessage(PP_LOG_ERROR, "CreateObject() failed; not enough memory");
  238. return FALSE;
  239. }
  240. }
  241. // -----------------------------------------------------------------------------
  242. SESSION::SESSION(void)
  243. {
  244. m_hHttpStack = 0;
  245. m_hCredUI = 0;
  246. m_RefCount = 0;
  247. m_pfnReadDomainCred = NULL;
  248. m_pfnCredFree = NULL;
  249. m_hKeyLM = NULL;
  250. m_hKeyCU = NULL;
  251. m_hKeyDAMap = NULL;
  252. m_fLogout = FALSE;
  253. m_LastNexusDownloadTime = 0xFFFFFFFF;
  254. }
  255. // -----------------------------------------------------------------------------
  256. SESSION::~SESSION(void)
  257. {
  258. }
  259. BOOL SESSION::GetDAInfoFromPPNexus(
  260. IN PWSTR pwszRegUrl, // user supplied buffer ...
  261. IN OUT PDWORD pdwRegUrlLen, // ... and length (will be updated to actual length
  262. // on successful return)
  263. IN PWSTR pwszRealm, // user supplied buffer ...
  264. IN OUT PDWORD pdwRealmLen // ... and length (will be updated to actual length
  265. // on successful return)
  266. )
  267. {
  268. BOOL fRetVal = FALSE;
  269. HINTERNET hRequest = NULL;
  270. HINTERNET hConnect = NULL;
  271. DWORD dwError;
  272. #ifdef DBG
  273. WCHAR wNexusHost[512] = L"nexus.msn.pp.test.microsoft.com";
  274. #else
  275. WCHAR wNexusHost[512] = L"nexus.passport.com";
  276. #endif
  277. DWORD dwHostLen = sizeof(wNexusHost); // note: size of the buffer, not # of UNICODE characters
  278. #ifdef DBG
  279. WCHAR wNexusObj[512] = L"sprdr/pprdr.asp";
  280. #else
  281. WCHAR wNexusObj[512] = L"rdr/pprdr.asp";
  282. #endif
  283. DWORD dwObjLen = sizeof(wNexusObj);
  284. WCHAR wPassportUrls[1024];
  285. DWORD dwUrlsLen = ARRAYSIZE(wPassportUrls);
  286. DWORD dwValueType;
  287. WCHAR Delimiters[] = L",";
  288. PWSTR Token = NULL;
  289. // we allow only one Nexus contact per session to avoid infinite loop due to Nexus misconfiguration
  290. DWORD dwCurrentTime = ::GetTickCount();
  291. if ((dwCurrentTime >= m_LastNexusDownloadTime) &&
  292. (dwCurrentTime - m_LastNexusDownloadTime < 5*60*1000)) // 5 minutes
  293. {
  294. DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() failed: Nexus info already downloaded");
  295. goto exit;
  296. }
  297. // biaow-todo: when the Passport Team gives us THE final Nexus name, we'll then hard-code it here. And
  298. // there will be no need to query registry here by then.
  299. if (m_hKeyLM)
  300. {
  301. dwError = ::RegQueryValueExW(m_hKeyLM,
  302. L"NexusHost",
  303. 0,
  304. &dwValueType,
  305. reinterpret_cast<LPBYTE>(wNexusHost),
  306. &dwHostLen);
  307. PP_ASSERT(!(dwError == ERROR_MORE_DATA));
  308. // PP_ASSERT(dwValueType == REG_SZ); BVT Break!!!
  309. dwError = ::RegQueryValueExW(m_hKeyLM,
  310. L"NexusObj",
  311. 0,
  312. &dwValueType,
  313. reinterpret_cast<LPBYTE>(wNexusObj),
  314. &dwObjLen);
  315. PP_ASSERT(!(dwError == ERROR_MORE_DATA));
  316. // PP_ASSERT(dwValueType == REG_SZ); BVT Break!!!
  317. }
  318. hConnect = Connect(wNexusHost,
  319. #ifdef DISABLE_SSL
  320. INTERNET_DEFAULT_HTTP_PORT
  321. #else
  322. INTERNET_DEFAULT_HTTPS_PORT
  323. #endif
  324. );
  325. if (hConnect == NULL)
  326. {
  327. DWORD dwErrorCode = ::GetLastError();
  328. DoTraceMessage(PP_LOG_ERROR,
  329. "SESSION::GetDAInfoFromPPNexus(): failed to connect to %ws; Error = %d",
  330. wNexusHost, dwErrorCode);
  331. goto exit;
  332. }
  333. hRequest = OpenRequest(hConnect,
  334. NULL,
  335. wNexusObj,
  336. #ifdef DISABLE_SSL
  337. 0
  338. #else
  339. INTERNET_FLAG_SECURE
  340. #endif
  341. );
  342. if (hRequest == NULL)
  343. {
  344. DWORD dwErrorCode = ::GetLastError();
  345. DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus() failed; OpenRequest() to %ws failed, Error Code = %d",
  346. wNexusObj, dwErrorCode);
  347. goto exit;
  348. }
  349. if (!SendRequest(hRequest, NULL, 0))
  350. {
  351. DWORD dwErrorCode = ::GetLastError();
  352. #ifdef BAD_CERT_OK
  353. if (dwErrorCode == ERROR_INTERNET_INVALID_CA)
  354. {
  355. DWORD dwSecFlags;
  356. DWORD dwSecurityFlagsSize = sizeof(dwSecFlags);
  357. if (!QueryOption(hRequest,
  358. INTERNET_OPTION_SECURITY_FLAGS,
  359. &dwSecFlags,
  360. &dwSecurityFlagsSize))
  361. {
  362. dwSecFlags = 0;
  363. }
  364. else
  365. {
  366. dwSecFlags |= SECURITY_SET_MASK;
  367. }
  368. if (!SetOption(hRequest,
  369. INTERNET_OPTION_SECURITY_FLAGS,
  370. &dwSecFlags,
  371. dwSecurityFlagsSize))
  372. {
  373. PP_ASSERT(TRUE); // shouldn't reach here
  374. goto exit;
  375. }
  376. else
  377. {
  378. if (!SendRequest(hRequest, NULL, 0))
  379. {
  380. DWORD dwErrorCode = ::GetLastError();
  381. DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus(): SendRequest() failed");
  382. goto exit;
  383. }
  384. }
  385. }
  386. #else
  387. DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus(): failed");
  388. goto exit;
  389. #endif // BAD_CERT_OK
  390. }
  391. if (QueryHeaders(hRequest,
  392. HTTP_QUERY_PASSPORT_URLS,
  393. wPassportUrls,
  394. &dwUrlsLen) == FALSE)
  395. {
  396. DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus() failed; PassportUrls header not found");
  397. goto exit;
  398. }
  399. Token = ::wcstok(wPassportUrls, Delimiters);
  400. while (Token != NULL)
  401. {
  402. // skip leading white spaces
  403. while (*Token == (L" ")[0]) { ++Token; }
  404. if (Token == NULL)
  405. {
  406. DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no text in between commas");
  407. goto next_token;
  408. }
  409. // find DALocation
  410. if (!::_wcsnicmp(Token, L"DALogin", ::wcslen(L"DALogin")))
  411. {
  412. PWSTR pwszDAUrl = ::wcsstr(Token, L"=");
  413. if (pwszDAUrl == NULL)
  414. {
  415. DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after DALocation");
  416. goto exit;
  417. }
  418. pwszDAUrl++; // skip "="
  419. while (*pwszDAUrl == (L" ")[0]) { ++pwszDAUrl; } // skip leading white spaces
  420. ::wcscpy(m_wDefaultDAUrl, L"https://");
  421. ::wcscat(m_wDefaultDAUrl, pwszDAUrl);
  422. if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM,
  423. L"LoginServerUrl",
  424. 0,
  425. REG_SZ,
  426. reinterpret_cast<const LPBYTE>(m_wDefaultDAUrl),
  427. ::wcslen(m_wDefaultDAUrl) * sizeof(WCHAR)) != ERROR_SUCCESS)
  428. {
  429. if (m_hKeyCU)
  430. {
  431. ::RegSetValueExW(m_hKeyCU,
  432. L"LoginServerUrl",
  433. 0,
  434. REG_SZ,
  435. reinterpret_cast<const LPBYTE>(m_wDefaultDAUrl),
  436. ::wcslen(m_wDefaultDAUrl) * sizeof(WCHAR));
  437. }
  438. }
  439. m_LastNexusDownloadTime = ::GetTickCount();
  440. fRetVal = TRUE;
  441. DoTraceMessage(PP_LOG_INFO, "DALocation URL %ws found", m_wDefaultDAUrl);
  442. }
  443. else if (!::_wcsnicmp(Token, L"DARealm", ::wcslen(L"DARealm")))
  444. {
  445. PWSTR pwszDARealm = ::wcsstr(Token, L"=");
  446. if (pwszDARealm == NULL)
  447. {
  448. DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after DARealm");
  449. goto exit;
  450. }
  451. pwszDARealm++; // skip "="
  452. while (*pwszDARealm == (L" ")[0]) { ++pwszDARealm; } // skip leading white spaces
  453. if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM,
  454. L"LoginServerRealm",
  455. 0,
  456. REG_SZ,
  457. reinterpret_cast<const LPBYTE>(pwszDARealm),
  458. ::wcslen(pwszDARealm) * sizeof(WCHAR)) != ERROR_SUCCESS)
  459. {
  460. if (m_hKeyCU)
  461. {
  462. ::RegSetValueExW(m_hKeyCU,
  463. L"LoginServerRealm",
  464. 0,
  465. REG_SZ,
  466. reinterpret_cast<const LPBYTE>(pwszDARealm),
  467. ::wcslen(pwszDARealm) * sizeof(WCHAR));
  468. }
  469. }
  470. if (pwszRealm)
  471. {
  472. if (*pdwRealmLen < ::wcslen(pwszDARealm) + 1)
  473. {
  474. *pdwRealmLen = ::wcslen(pwszDARealm) + 1;
  475. fRetVal = FALSE;
  476. goto exit;
  477. }
  478. else
  479. {
  480. ::wcscpy(pwszRealm, pwszDARealm);
  481. *pdwRealmLen = ::wcslen(pwszDARealm) + 1;
  482. }
  483. }
  484. DoTraceMessage(PP_LOG_INFO, "DALocation URL %ws found", m_wDefaultDAUrl);
  485. }
  486. else if (!::_wcsnicmp(Token, L"DAReg", ::wcslen(L"DAReg")))
  487. {
  488. PWSTR pwszDAReg = ::wcsstr(Token, L"=");
  489. if (pwszDAReg == NULL)
  490. {
  491. DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after DAReg");
  492. goto exit;
  493. }
  494. pwszDAReg++; // skip "="
  495. while (*pwszDAReg == (L" ")[0]) { ++pwszDAReg; } // skip leading white spaces
  496. if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM,
  497. L"RegistrationUrl",
  498. 0,
  499. REG_SZ,
  500. reinterpret_cast<const LPBYTE>(pwszDAReg),
  501. ::wcslen(pwszDAReg) * sizeof(WCHAR)) != ERROR_SUCCESS)
  502. {
  503. if (m_hKeyCU)
  504. {
  505. ::RegSetValueExW(m_hKeyCU,
  506. L"RegistrationUrl",
  507. 0,
  508. REG_SZ,
  509. reinterpret_cast<const LPBYTE>(pwszDAReg),
  510. ::wcslen(pwszDAReg) * sizeof(WCHAR));
  511. }
  512. }
  513. if (pwszRegUrl)
  514. {
  515. if (*pdwRegUrlLen < ::wcslen(pwszDAReg) + 1)
  516. {
  517. *pdwRegUrlLen = ::wcslen(pwszDAReg) + 1;
  518. fRetVal = FALSE;
  519. goto exit;
  520. }
  521. else
  522. {
  523. ::wcscpy(pwszRegUrl, pwszDAReg);
  524. *pdwRegUrlLen = ::wcslen(pwszDAReg) + 1;
  525. }
  526. }
  527. DoTraceMessage(PP_LOG_INFO, "DALocation URL %ws found", m_wDefaultDAUrl);
  528. }
  529. next_token:
  530. Token = ::wcstok(NULL, Delimiters);
  531. }
  532. exit:
  533. if (hRequest)
  534. {
  535. CloseHandle(hRequest);
  536. }
  537. if (hConnect)
  538. {
  539. CloseHandle(hConnect);
  540. }
  541. return fRetVal;
  542. }
  543. BOOL SESSION::UpdateDAInfo(
  544. PCWSTR pwszSignIn,
  545. PCWSTR pwszDAUrl
  546. )
  547. {
  548. if (pwszSignIn)
  549. {
  550. LPCWSTR pwszDomain = ::wcsstr(pwszSignIn, L"@");
  551. if (pwszDomain && m_hKeyDAMap)
  552. {
  553. DWORD dwError = ::RegSetValueExW(m_hKeyDAMap,
  554. pwszDomain,
  555. 0,
  556. REG_SZ,
  557. reinterpret_cast<const LPBYTE>(const_cast<PWSTR>(pwszDAUrl)),
  558. ::wcslen(pwszDAUrl) * sizeof(WCHAR));
  559. if (dwError == ERROR_SUCCESS)
  560. {
  561. return TRUE;
  562. }
  563. }
  564. }
  565. return FALSE;
  566. }
  567. BOOL SESSION::GetDAInfo(PCWSTR pwszSignIn,
  568. LPWSTR pwszDAHostName,
  569. DWORD HostNameLen,
  570. LPWSTR pwszDAHostObj,
  571. DWORD HostObjLen)
  572. {
  573. LPCWSTR pwszDAUrl = m_wDefaultDAUrl;
  574. WCHAR wDomainDAUrl[1024];
  575. DWORD dwDomainUrlLen = sizeof(wDomainDAUrl);
  576. if (pwszSignIn)
  577. {
  578. LPCWSTR pwszDomain = ::wcsstr(pwszSignIn, L"@");
  579. if (pwszDomain && m_hKeyDAMap)
  580. {
  581. DWORD dwValueType;
  582. DWORD dwError = ::RegQueryValueExW(m_hKeyDAMap,
  583. pwszDomain,
  584. 0,
  585. &dwValueType,
  586. reinterpret_cast<LPBYTE>(wDomainDAUrl),
  587. &dwDomainUrlLen);
  588. PP_ASSERT(!(dwError == ERROR_MORE_DATA));
  589. // PP_ASSERT(dwValueType == REG_SZ);
  590. if (dwError == ERROR_SUCCESS)
  591. {
  592. pwszDAUrl = wDomainDAUrl;
  593. }
  594. }
  595. }
  596. URL_COMPONENTSW UrlComps;
  597. ::memset(&UrlComps, 0, sizeof(UrlComps));
  598. UrlComps.dwStructSize = sizeof(UrlComps);
  599. UrlComps.lpszHostName = pwszDAHostName;
  600. UrlComps.dwHostNameLength = HostNameLen;
  601. UrlComps.lpszUrlPath = pwszDAHostObj;
  602. UrlComps.dwUrlPathLength = HostObjLen;
  603. if (CrackUrl(pwszDAUrl,
  604. 0,
  605. 0,
  606. &UrlComps) == FALSE)
  607. {
  608. DoTraceMessage(PP_LOG_ERROR,
  609. "WININET_SESSION::GetDAInfo() failed; can not crack the URL %ws",
  610. pwszDAUrl);
  611. return FALSE;
  612. }
  613. return TRUE;
  614. }
  615. BOOL SESSION::Open(PCWSTR /*pwszHttpStack*/, HINTERNET)
  616. {
  617. BOOL fRetVal = FALSE;
  618. DWORD dwError;
  619. DWORD dwValueType;
  620. DWORD dwUrlLen = sizeof(m_wDefaultDAUrl); // note: size of the buffer, not # of UNICODE characters
  621. BOOL fDAInfoCached = FALSE; // assume NO DA info's cached locally
  622. dwError = ::RegCreateKeyExW(HKEY_LOCAL_MACHINE,
  623. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport",
  624. 0,
  625. NULL,
  626. REG_OPTION_NON_VOLATILE,
  627. KEY_READ | KEY_WRITE,
  628. NULL,
  629. &m_hKeyLM,
  630. NULL);
  631. if (dwError != ERROR_SUCCESS)
  632. {
  633. DoTraceMessage(PP_LOG_ERROR,
  634. "SESSION::Open() failed; can not create/open the Passport key; Error = %d", dwError);
  635. // we can't open the Passport key for read & write, let's try open it for read only
  636. ::RegCreateKeyExW(HKEY_LOCAL_MACHINE,
  637. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport",
  638. 0,
  639. NULL,
  640. REG_OPTION_NON_VOLATILE,
  641. KEY_READ,
  642. NULL,
  643. &m_hKeyLM,
  644. NULL);
  645. // if we still can't open it for read, we are still fine since we can download the info from the
  646. // Nexus server. *NOTE* m_hKeyLM could be NULL from this point on.
  647. }
  648. dwError = ::RegCreateKeyExW(HKEY_CURRENT_USER,
  649. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport",
  650. 0,
  651. NULL,
  652. REG_OPTION_NON_VOLATILE,
  653. KEY_READ | KEY_WRITE,
  654. NULL,
  655. &m_hKeyCU,
  656. NULL);
  657. if (dwError != ERROR_SUCCESS)
  658. {
  659. DoTraceMessage(PP_LOG_ERROR,
  660. "SESSION::Open() failed; can not create/open the Passport key; Error = %d", dwError);
  661. ::RegCreateKeyExW(HKEY_CURRENT_USER,
  662. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport",
  663. 0,
  664. NULL,
  665. REG_OPTION_NON_VOLATILE,
  666. KEY_READ,
  667. NULL,
  668. &m_hKeyCU,
  669. NULL);
  670. }
  671. if (m_hKeyCU)
  672. {
  673. dwError = ::RegCreateKeyExW(m_hKeyCU,
  674. L"DAMap",
  675. 0,
  676. NULL,
  677. REG_OPTION_NON_VOLATILE,
  678. KEY_READ | KEY_WRITE,
  679. NULL,
  680. &m_hKeyDAMap,
  681. NULL);
  682. if (dwError != ERROR_SUCCESS)
  683. {
  684. DoTraceMessage(PP_LOG_ERROR,
  685. "SESSION::Open() failed; can not create/open the Passport key; Error = %d", dwError);
  686. ::RegCreateKeyExW(m_hKeyCU,
  687. L"DAMap",
  688. 0,
  689. NULL,
  690. REG_OPTION_NON_VOLATILE,
  691. KEY_READ,
  692. NULL,
  693. &m_hKeyDAMap,
  694. NULL);
  695. }
  696. }
  697. if (m_hKeyCU == NULL || ::RegQueryValueExW(m_hKeyCU,
  698. L"LoginServerUrl",
  699. 0,
  700. &dwValueType,
  701. reinterpret_cast<LPBYTE>(m_wDefaultDAUrl),
  702. &dwUrlLen) != ERROR_SUCCESS)
  703. {
  704. if (m_hKeyLM && ::RegQueryValueExW(m_hKeyLM,
  705. L"LoginServerUrl",
  706. 0,
  707. &dwValueType,
  708. reinterpret_cast<LPBYTE>(m_wDefaultDAUrl),
  709. &dwUrlLen) == ERROR_SUCCESS)
  710. {
  711. fDAInfoCached = TRUE;
  712. }
  713. }
  714. else
  715. {
  716. fDAInfoCached = TRUE;
  717. }
  718. PP_ASSERT(!(dwError == ERROR_MORE_DATA));
  719. // PP_ASSERT(dwValueType == REG_SZ); BVT break!!!
  720. if (!fDAInfoCached || (::wcslen(m_wDefaultDAUrl) == ::wcslen(L"")))
  721. {
  722. if (GetDAInfoFromPPNexus(NULL, 0, NULL, 0) == FALSE)
  723. {
  724. goto exit;
  725. }
  726. }
  727. else
  728. {
  729. /*
  730. URL_COMPONENTSW UrlComps;
  731. ::memset(&UrlComps, 0, sizeof(UrlComps));
  732. UrlComps.dwStructSize = sizeof(UrlComps) / sizeof(WCHAR);
  733. UrlComps.lpszHostName = m_wDAHostName;
  734. UrlComps.dwHostNameLength = ARRAYSIZE(m_wDAHostName);
  735. UrlComps.lpszUrlPath = m_wDATargetObj;
  736. UrlComps.dwUrlPathLength = ARRAYSIZE(m_wDATargetObj);
  737. if (CrackUrl(m_wDefaultDAUrl,
  738. 0,
  739. 0,
  740. &UrlComps) == FALSE)
  741. {
  742. DoTraceMessage(PP_LOG_ERROR,
  743. "WININET_SESSION::Open() failed; can not crack the URL %ws",
  744. m_wDefaultDAUrl);
  745. goto exit;
  746. }
  747. */
  748. }
  749. /*
  750. DWORD dwRegUrlLen = sizeof(m_wRegistrationUrl);
  751. dwError = ::RegQueryValueExW(m_hKeyLM,
  752. L"RegistrationUrl",
  753. 0,
  754. &dwValueType,
  755. reinterpret_cast<LPBYTE>(m_wRegistrationUrl),
  756. &dwRegUrlLen);
  757. PP_ASSERT(!(dwError == ERROR_MORE_DATA));
  758. */
  759. m_hCredUI = ::LoadLibraryW(L"advapi32.dll");
  760. if (m_hCredUI)
  761. {
  762. m_pfnReadDomainCred =
  763. reinterpret_cast<PFN_READ_DOMAIN_CRED_W>(::GetProcAddress(m_hCredUI, "CredReadDomainCredentialsW"));
  764. if (m_pfnReadDomainCred == NULL)
  765. {
  766. DoTraceMessage(PP_LOG_WARNING, "failed to bind to CredReadDomainCredentialsW()");
  767. }
  768. m_pfnCredFree =
  769. reinterpret_cast<PFN_CRED_FREE>(::GetProcAddress(m_hCredUI, "CredFree"));
  770. if (m_pfnCredFree == NULL)
  771. {
  772. DoTraceMessage(PP_LOG_WARNING, "failed to bind to CredFree()");
  773. }
  774. }
  775. fRetVal = TRUE;
  776. exit:
  777. return fRetVal;
  778. }
  779. void SESSION::Logout(void)
  780. {
  781. if (!m_fLogout)
  782. {
  783. m_fLogout = TRUE;
  784. ::GetSystemTime(&m_LogoutTimeStamp);
  785. }
  786. }
  787. BOOL SESSION::IsLoggedOut(void) const
  788. {
  789. return m_fLogout;
  790. }
  791. void SESSION::ResetLogoutFlag(void)
  792. {
  793. m_fLogout = FALSE;
  794. }
  795. const SYSTEMTIME* SESSION::GetLogoutTimeStamp(void) const
  796. {
  797. return &m_LogoutTimeStamp;
  798. }
  799. void SESSION::Close(void)
  800. {
  801. if (m_hCredUI)
  802. {
  803. ::FreeLibrary(m_hCredUI);
  804. m_hCredUI = NULL;
  805. }
  806. if (m_hKeyDAMap)
  807. {
  808. ::RegCloseKey(m_hKeyDAMap);
  809. }
  810. if (m_hKeyCU)
  811. {
  812. ::RegCloseKey(m_hKeyCU);
  813. }
  814. if (m_hKeyLM)
  815. {
  816. ::RegCloseKey(m_hKeyLM);
  817. }
  818. }
  819. //
  820. // Implementation for WININET_SESSION
  821. //
  822. // -----------------------------------------------------------------------------
  823. WININET_SESSION::WININET_SESSION(void)
  824. {
  825. m_hInternet = NULL;
  826. m_pfnConnect = NULL;
  827. m_pfnOpenRequest = NULL;
  828. m_pfnSendRequest = NULL;
  829. m_pfnQueryInfo = NULL;
  830. m_pfnCloseHandle = NULL;
  831. m_pfnSetOption = NULL;
  832. m_pfnOpenUrl = NULL;
  833. m_pfnQueryOption = NULL;
  834. m_pfnCrack = NULL;
  835. m_pfnReadFile = NULL;
  836. }
  837. // -----------------------------------------------------------------------------
  838. WININET_SESSION::~WININET_SESSION(void)
  839. {
  840. }
  841. // -----------------------------------------------------------------------------
  842. HINTERNET WININET_SESSION::Connect(
  843. LPCWSTR lpwszServerName,
  844. INTERNET_PORT nPort)
  845. {
  846. PP_ASSERT(m_pfnConnect != NULL);
  847. return (*m_pfnConnect)(m_hInternet,
  848. lpwszServerName,
  849. nPort,
  850. NULL,
  851. NULL,
  852. INTERNET_SERVICE_HTTP,
  853. 0,
  854. 0);
  855. }
  856. // -----------------------------------------------------------------------------
  857. HINTERNET WININET_SESSION::OpenRequest(
  858. HINTERNET hConnect,
  859. LPCWSTR lpwszVerb,
  860. LPCWSTR lpwszObjectName,
  861. DWORD dwFlags,
  862. DWORD_PTR dwContext)
  863. {
  864. PP_ASSERT(m_pfnOpenRequest != NULL);
  865. return (*m_pfnOpenRequest)(hConnect,
  866. lpwszVerb,
  867. lpwszObjectName,
  868. L"HTTP/1.1",
  869. NULL,
  870. NULL,
  871. dwFlags,
  872. dwContext);
  873. }
  874. // -----------------------------------------------------------------------------
  875. BOOL WININET_SESSION::SendRequest(
  876. HINTERNET hRequest,
  877. LPCWSTR lpwszHeaders,
  878. DWORD dwHeadersLength,
  879. DWORD_PTR dwContext)
  880. {
  881. PP_ASSERT(m_pfnSendRequest != NULL);
  882. return (*m_pfnSendRequest)(hRequest,
  883. lpwszHeaders,
  884. dwHeadersLength,
  885. NULL,
  886. 0);
  887. }
  888. // -----------------------------------------------------------------------------
  889. BOOL WININET_SESSION::QueryHeaders(
  890. HINTERNET hRequest,
  891. DWORD dwInfoLevel,
  892. LPVOID lpvBuffer,
  893. LPDWORD lpdwBufferLength,
  894. LPDWORD lpdwIndex)
  895. {
  896. PP_ASSERT(m_pfnQueryInfo != NULL);
  897. return (*m_pfnQueryInfo)(hRequest,
  898. dwInfoLevel,
  899. lpvBuffer,
  900. lpdwBufferLength,
  901. lpdwIndex);
  902. }
  903. // -----------------------------------------------------------------------------
  904. BOOL WININET_SESSION::CloseHandle(
  905. IN HINTERNET hInternet)
  906. {
  907. PP_ASSERT(m_pfnCloseHandle != NULL);
  908. return (*m_pfnCloseHandle)(hInternet);
  909. }
  910. // -----------------------------------------------------------------------------
  911. BOOL WININET_SESSION::QueryOption(
  912. HINTERNET hInternet,
  913. DWORD dwOption,
  914. LPVOID lpBuffer,
  915. LPDWORD lpdwBufferLength)
  916. {
  917. PP_ASSERT(m_pfnQueryOption != NULL);
  918. return (*m_pfnQueryOption)(hInternet,
  919. dwOption,
  920. lpBuffer,
  921. lpdwBufferLength
  922. );
  923. }
  924. // -----------------------------------------------------------------------------
  925. BOOL WININET_SESSION::SetOption(
  926. HINTERNET hInternet,
  927. DWORD dwOption,
  928. LPVOID lpBuffer,
  929. DWORD dwBufferLength)
  930. {
  931. PP_ASSERT(m_pfnSetOption != NULL);
  932. return (*m_pfnSetOption)(hInternet,
  933. dwOption,
  934. lpBuffer,
  935. dwBufferLength);
  936. }
  937. // -----------------------------------------------------------------------------
  938. HINTERNET WININET_SESSION::OpenUrl(
  939. LPCWSTR lpwszUrl,
  940. LPCWSTR lpwszHeaders,
  941. DWORD dwHeadersLength,
  942. DWORD dwFlags)
  943. {
  944. PP_ASSERT(m_pfnOpenUrl != NULL);
  945. return (*m_pfnOpenUrl)(m_hInternet,
  946. lpwszUrl,
  947. lpwszHeaders,
  948. dwHeadersLength,
  949. dwFlags,
  950. 0);
  951. }
  952. // -----------------------------------------------------------------------------
  953. BOOL WININET_SESSION::ReadFile(
  954. HINTERNET hFile,
  955. LPVOID lpBuffer,
  956. DWORD dwNumberOfBytesToRead,
  957. LPDWORD lpdwNumberOfBytesRead)
  958. {
  959. PP_ASSERT(m_pfnReadFile != NULL);
  960. return (*m_pfnReadFile)(
  961. hFile,
  962. lpBuffer,
  963. dwNumberOfBytesToRead,
  964. lpdwNumberOfBytesRead);
  965. }
  966. BOOL WININET_SESSION::CrackUrl(
  967. LPCWSTR lpszUrl,
  968. DWORD dwUrlLength,
  969. DWORD dwFlags,
  970. PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents)
  971. {
  972. PP_ASSERT (m_pfnCrack != NULL);
  973. return (*m_pfnCrack)(lpszUrl,
  974. dwUrlLength,
  975. dwFlags,
  976. lpUrlComponents);
  977. }
  978. PVOID WININET_SESSION::SetStatusCallback(
  979. HINTERNET hInternet,
  980. PVOID lpfnCallback
  981. )
  982. {
  983. PP_ASSERT (m_pfnStatusCallback != NULL);
  984. return (*m_pfnStatusCallback)(hInternet,
  985. (INTERNET_STATUS_CALLBACK)lpfnCallback);
  986. }
  987. BOOL WININET_SESSION::AddHeaders(
  988. HINTERNET hConnect,
  989. LPCWSTR lpszHeaders,
  990. DWORD dwHeadersLength,
  991. DWORD dwModifiers
  992. )
  993. {
  994. PP_ASSERT(m_pfnAddHeaders != NULL);
  995. return (*m_pfnAddHeaders)(hConnect,
  996. lpszHeaders,
  997. dwHeadersLength,
  998. dwModifiers
  999. );
  1000. }
  1001. BOOL WININET_SESSION::InitHttpApi(PFN_INTERNET_OPEN* ppfnInternetOpen)
  1002. {
  1003. BOOL fRet = FALSE;
  1004. m_pfnCloseHandle =
  1005. reinterpret_cast<PFN_CLOSE_HANDLE>(::GetProcAddress(m_hHttpStack, "InternetCloseHandle"));
  1006. if (m_pfnCloseHandle == NULL)
  1007. {
  1008. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetCloseHandle not found");
  1009. goto exit;
  1010. }
  1011. *ppfnInternetOpen =
  1012. reinterpret_cast<PFN_INTERNET_OPEN>(::GetProcAddress(m_hHttpStack, "InternetOpenW"));
  1013. if (*ppfnInternetOpen == NULL)
  1014. {
  1015. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetOpenW not found");
  1016. goto exit;
  1017. }
  1018. m_pfnConnect =
  1019. reinterpret_cast<PFN_INTERNET_CONNECT>(::GetProcAddress(m_hHttpStack, "InternetConnectW"));
  1020. if (m_pfnConnect == NULL)
  1021. {
  1022. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetConnectW not found");
  1023. goto exit;
  1024. }
  1025. m_pfnOpenRequest =
  1026. reinterpret_cast<PFN_OPEN_REQUEST>(::GetProcAddress(m_hHttpStack, "HttpOpenRequestW"));
  1027. if (m_pfnOpenRequest == NULL)
  1028. {
  1029. DoTraceMessage(PP_LOG_ERROR, "function entry point HttpOpenRequestW not found");
  1030. goto exit;
  1031. }
  1032. m_pfnSendRequest =
  1033. reinterpret_cast<PFN_SEND_REQUEST>(::GetProcAddress(m_hHttpStack, "HttpSendRequestW"));
  1034. if (m_pfnSendRequest == NULL)
  1035. {
  1036. DoTraceMessage(PP_LOG_ERROR, "function entry point HttpSendRequestW not found");
  1037. goto exit;
  1038. }
  1039. m_pfnQueryInfo =
  1040. reinterpret_cast<PFN_QUERY_INFO>(::GetProcAddress(m_hHttpStack, "HttpQueryInfoW"));
  1041. if (m_pfnQueryInfo == NULL)
  1042. {
  1043. DoTraceMessage(PP_LOG_ERROR, "function entry point HttpQueryInfoW not found");
  1044. goto exit;
  1045. }
  1046. m_pfnSetOption =
  1047. reinterpret_cast<PFN_SET_OPTION>(::GetProcAddress(m_hHttpStack, "InternetSetOptionW"));
  1048. if (m_pfnSetOption == NULL)
  1049. {
  1050. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetSetOptionW not found");
  1051. goto exit;
  1052. }
  1053. m_pfnOpenUrl =
  1054. reinterpret_cast<PFN_OPEN_URL>(::GetProcAddress(m_hHttpStack, "InternetOpenUrlW"));
  1055. if (m_pfnOpenUrl == NULL)
  1056. {
  1057. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetOpenUrlW not found");
  1058. goto exit;
  1059. }
  1060. m_pfnQueryOption =
  1061. reinterpret_cast<PFN_QUERY_OPTION>(::GetProcAddress(m_hHttpStack, "InternetQueryOptionW"));
  1062. if (m_pfnQueryOption == NULL)
  1063. {
  1064. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetQueryOptionW not found");
  1065. goto exit;
  1066. }
  1067. m_pfnCrack =
  1068. reinterpret_cast<PFN_CRACK_URL>(::GetProcAddress(m_hHttpStack, "InternetCrackUrlW"));
  1069. if (m_pfnCrack == NULL)
  1070. {
  1071. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetCrackUrlW not found");
  1072. goto exit;
  1073. }
  1074. m_pfnReadFile =
  1075. reinterpret_cast<PFN_READ_FILE>(::GetProcAddress(m_hHttpStack, "InternetReadFile"));
  1076. if (m_pfnReadFile == NULL)
  1077. {
  1078. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetReadFile not found");
  1079. goto exit;
  1080. }
  1081. m_pfnStatusCallback =
  1082. reinterpret_cast<PFN_STATUS_CALLBACK>(::GetProcAddress(m_hHttpStack, "InternetSetStatusCallbackW"));
  1083. if (m_pfnStatusCallback == NULL)
  1084. {
  1085. DoTraceMessage(PP_LOG_ERROR, "function entry point InternetSetStatusCallback not found");
  1086. goto exit;
  1087. }
  1088. m_pfnAddHeaders =
  1089. reinterpret_cast<PFN_ADD_HEADERS>(::GetProcAddress(m_hHttpStack, "HttpAddRequestHeadersW"));
  1090. if (m_pfnAddHeaders == NULL)
  1091. {
  1092. DoTraceMessage(PP_LOG_ERROR, "function entry point HttpAddRequestHeaders not found");
  1093. goto exit;
  1094. }
  1095. fRet = TRUE;
  1096. exit:
  1097. return fRet;
  1098. }
  1099. BOOL WININET_SESSION::Open(
  1100. PCWSTR pwszHttpStack,
  1101. HINTERNET hInternet
  1102. )
  1103. {
  1104. PP_ASSERT(pwszHttpStack != NULL);
  1105. DWORD dwErrorCode;
  1106. BOOL fRet = FALSE;
  1107. PFN_INTERNET_OPEN pfnInternetOpen = NULL;
  1108. PP_ASSERT(m_hHttpStack == 0);
  1109. m_hHttpStack = ::LoadLibraryW(pwszHttpStack);
  1110. if (m_hHttpStack == NULL)
  1111. {
  1112. dwErrorCode = ::GetLastError();
  1113. DoTraceMessage(PP_LOG_ERROR, "failed to load library %ws; error = %d", pwszHttpStack, dwErrorCode);
  1114. goto exit;
  1115. }
  1116. if (InitHttpApi(&pfnInternetOpen) == FALSE)
  1117. {
  1118. goto exit;
  1119. }
  1120. if (hInternet)
  1121. {
  1122. m_hInternet = hInternet;
  1123. m_fOwnedSession = FALSE;
  1124. }
  1125. else
  1126. {
  1127. m_hInternet = (*pfnInternetOpen)(
  1128. L"Microsoft.NET-Passport-Authentication-Service/1.4",
  1129. INTERNET_OPEN_TYPE_PRECONFIG,
  1130. NULL,
  1131. NULL,
  1132. 0 /*INTERNET_FLAG_ASYNC*/ // biaow-todo: use async
  1133. );
  1134. m_fOwnedSession = TRUE;
  1135. }
  1136. if (m_hInternet == NULL)
  1137. {
  1138. dwErrorCode = ::GetLastError();
  1139. DoTraceMessage(PP_LOG_ERROR, "failed to open an HTTP session through %ws; error = %d",
  1140. pwszHttpStack, dwErrorCode);
  1141. goto exit;
  1142. }
  1143. if (SESSION::Open(pwszHttpStack, hInternet) == FALSE)
  1144. {
  1145. goto exit;
  1146. }
  1147. fRet = TRUE;
  1148. DoTraceMessage(PP_LOG_INFO, "WinInet Http Session opened");
  1149. exit:
  1150. if (!fRet)
  1151. {
  1152. if (m_hInternet && m_fOwnedSession)
  1153. {
  1154. (*m_pfnCloseHandle)(m_hInternet);
  1155. m_hInternet = NULL;
  1156. }
  1157. if (m_hHttpStack)
  1158. {
  1159. ::FreeLibrary(m_hHttpStack);
  1160. m_hHttpStack = NULL;
  1161. }
  1162. DoTraceMessage(PP_LOG_ERROR, "WinInet Http Session failed");
  1163. }
  1164. return fRet;
  1165. }
  1166. void WININET_SESSION::Close(void)
  1167. {
  1168. PP_ASSERT(m_pfnCloseHandle);
  1169. if (m_hInternet && m_fOwnedSession)
  1170. {
  1171. (*m_pfnCloseHandle)(m_hInternet);
  1172. m_pfnCloseHandle = NULL;
  1173. }
  1174. if (m_hHttpStack)
  1175. {
  1176. ::FreeLibrary(m_hHttpStack);
  1177. m_hHttpStack = NULL;
  1178. }
  1179. SESSION::Close();
  1180. DoTraceMessage(PP_LOG_INFO, "WinInet Http Session closed");
  1181. }
  1182. #ifdef PP_DEMO
  1183. BOOL WININET_SESSION::ContactPartner(PCWSTR pwszPartnerUrl,
  1184. PCWSTR pwszVerb,
  1185. PCWSTR pwszHeaders,
  1186. PWSTR pwszData,
  1187. PDWORD pdwDataLength
  1188. )
  1189. {
  1190. BOOL fRet = FALSE;
  1191. HINTERNET hConnect = NULL;
  1192. HINTERNET hRequest = NULL;
  1193. WCHAR ServerName[128];
  1194. WCHAR ObjectPath[1024];
  1195. URL_COMPONENTSW UrlComps;
  1196. ::memset(&UrlComps, 0, sizeof(UrlComps));
  1197. UrlComps.dwStructSize = sizeof(UrlComps) / sizeof(WCHAR);
  1198. UrlComps.lpszHostName = ServerName;
  1199. UrlComps.dwHostNameLength = ARRAYSIZE(ServerName);
  1200. UrlComps.lpszUrlPath = ObjectPath;
  1201. UrlComps.dwUrlPathLength = ARRAYSIZE(ObjectPath);
  1202. PP_ASSERT(m_pfnCrack != NULL);
  1203. if ((*m_pfnCrack)(pwszPartnerUrl,
  1204. 0,
  1205. 0,
  1206. &UrlComps) == FALSE)
  1207. {
  1208. DoTraceMessage(PP_LOG_ERROR,
  1209. "WININET_SESSION::ContactPartner() failed; can not crack the URL %ws",
  1210. pwszPartnerUrl);
  1211. goto exit;
  1212. }
  1213. PP_ASSERT(m_pfnConnect != NULL);
  1214. hConnect = (*m_pfnConnect)(m_hInternet,
  1215. UrlComps.lpszHostName,
  1216. UrlComps.nPort,
  1217. NULL,
  1218. NULL,
  1219. INTERNET_SERVICE_HTTP,
  1220. 0,
  1221. 0);
  1222. if (hConnect == NULL)
  1223. {
  1224. DoTraceMessage(PP_LOG_ERROR,
  1225. "WININET_SESSION::ContactPartner() failed; can not open an HTTP sesstion to %ws:%d",
  1226. UrlComps.lpszHostName, UrlComps.nPort);
  1227. goto exit;
  1228. }
  1229. PP_ASSERT(m_pfnOpenRequest != NULL);
  1230. hRequest = (*m_pfnOpenRequest)(hConnect,
  1231. pwszVerb,
  1232. UrlComps.lpszUrlPath,
  1233. L"HTTP/1.1",
  1234. NULL,
  1235. NULL,
  1236. INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_NO_AUTH,
  1237. 0);
  1238. if (hRequest == NULL)
  1239. {
  1240. DoTraceMessage(PP_LOG_ERROR,
  1241. "WININET_SESSION::ContactPartner() failed; can not open an HTTP request to %ws:(%ws)",
  1242. UrlComps.lpszUrlPath, pwszVerb);
  1243. goto exit;
  1244. }
  1245. PP_ASSERT(m_pfnSendRequest != NULL);
  1246. if ((*m_pfnSendRequest)(hRequest,
  1247. pwszHeaders,
  1248. 0,
  1249. NULL,
  1250. 0) == FALSE)
  1251. {
  1252. DoTraceMessage(PP_LOG_ERROR,
  1253. "WININET_SESSION::ContactPartner() failed; can not send an HTTP request");
  1254. goto exit;
  1255. }
  1256. if (pwszData == NULL)
  1257. {
  1258. fRet = TRUE;
  1259. goto exit;
  1260. }
  1261. DWORD dwStatus, dwStatusLen;
  1262. dwStatusLen = sizeof(dwStatus);
  1263. if (!QueryHeaders(hRequest,
  1264. HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
  1265. &dwStatus,
  1266. &dwStatusLen))
  1267. {
  1268. DoTraceMessage(PP_LOG_ERROR,
  1269. "WININET_SESSION::ContactPartner() failed; can not query status code");
  1270. goto exit;
  1271. }
  1272. if (dwStatus != HTTP_STATUS_REDIRECT)
  1273. {
  1274. DoTraceMessage(PP_LOG_ERROR,
  1275. "WININET_SESSION::ContactPartner() failed; expecting %d but get %d",
  1276. HTTP_STATUS_REDIRECT, dwStatus);
  1277. goto exit;
  1278. }
  1279. ::wcscpy(pwszData, L"WWW-Authenticate: ");
  1280. if(!QueryHeaders(hRequest,
  1281. HTTP_QUERY_WWW_AUTHENTICATE,
  1282. (LPVOID)(pwszData + ::wcslen(L"WWW-Authenticate: ")),
  1283. pdwDataLength))
  1284. {
  1285. DoTraceMessage(PP_LOG_ERROR,
  1286. "WININET_SESSION::ContactPartner() failed; no auth headers found");
  1287. goto exit;
  1288. }
  1289. (*m_pfnCloseHandle)(hRequest);
  1290. hRequest = NULL;
  1291. (*m_pfnCloseHandle)(hConnect);
  1292. hConnect = NULL;
  1293. fRet = TRUE;
  1294. exit:
  1295. if (hRequest)
  1296. {
  1297. (*m_pfnCloseHandle)(hRequest);
  1298. hRequest = NULL;
  1299. }
  1300. if (hConnect)
  1301. {
  1302. (*m_pfnCloseHandle)(hConnect);
  1303. hConnect = NULL;
  1304. }
  1305. return fRet;
  1306. }
  1307. #endif // PP_DEMO