|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
InetSess.cpp
Abstract:
Implements the Passport Session that uses WinInet as the underlying transport.
Author:
Biao Wang (biaow) 01-Oct-2000
--*/
#include "PPdefs.h"
#ifdef HINTERNET
#undef HINTERNET
#endif
#ifdef INTERNET_PORT
#undef INTERNET_PORT
#endif
#include <WinInet.h>
#include "session.h"
#include <wchar.h>
#include "passport.h"
#include <sensapi.h>
// #include "inetsess.tmh"
//
// func pointer decl for WinInet
//
typedef HINTERNET (WINAPI * PFN_INTERNET_OPEN)( IN LPCWSTR lpwszAgent, IN DWORD dwAccessType, IN LPCWSTR lpwszProxy OPTIONAL, IN LPCWSTR lpwszProxyBypass OPTIONAL, IN DWORD dwFlags );
typedef HINTERNET (WINAPI * PFN_INTERNET_CONNECT)( IN HINTERNET hInternet, IN LPCWSTR lpwszServerName, IN INTERNET_PORT nServerPort, IN LPCWSTR lpwszUserName OPTIONAL, IN LPCWSTR lpwszPassword OPTIONAL, IN DWORD dwService, IN DWORD dwFlags, IN DWORD_PTR dwContext );
typedef HINTERNET (WINAPI * PFN_OPEN_REQUEST)( IN HINTERNET hConnect, IN LPCWSTR lpwszVerb, IN LPCWSTR lpwszObjectName, IN LPCWSTR lpwszVersion, IN LPCWSTR lpwszReferrer OPTIONAL, IN LPCWSTR FAR * lplpwszAcceptTypes OPTIONAL, IN DWORD dwFlags, IN DWORD_PTR dwContext );
typedef BOOL (WINAPI * PFN_SEND_REQUEST)( IN HINTERNET hRequest, IN LPCWSTR lpwszHeaders OPTIONAL, IN DWORD dwHeadersLength, IN LPVOID lpOptional OPTIONAL, IN DWORD dwOptionalLength );
typedef BOOL (WINAPI * PFN_QUERY_INFO)( IN HINTERNET hRequest, IN DWORD dwInfoLevel, IN LPVOID lpvBuffer, IN LPDWORD lpdwBufferLength, IN OUT LPDWORD lpdwIndex );
typedef BOOL (WINAPI* PFN_CLOSE_HANDLE)( IN HINTERNET hInternet );
typedef BOOL (WINAPI* PFN_SET_OPTION)( IN HINTERNET hInternet, IN DWORD dwOption, IN LPVOID lpBuffer, IN DWORD dwBufferLength );
typedef BOOL (WINAPI* PFN_QUERY_OPTION)( IN HINTERNET hInternet, IN DWORD dwOption, OUT LPVOID lpBuffer, IN OUT LPDWORD lpdwBufferLength );
typedef HINTERNET (WINAPI* PFN_OPEN_URL)( IN HINTERNET hInternet, IN LPCWSTR lpwszUrl, IN LPCWSTR lpwszHeaders, IN DWORD dwHeadersLength, IN DWORD dwFlags, IN DWORD_PTR dwContext );
typedef BOOL (WINAPI* PFN_CRACK_URL)( IN LPCWSTR lpszUrl, IN DWORD dwUrlLength, IN DWORD dwFlags, IN OUT PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents );
typedef BOOL (WINAPI* PFN_READ_FILE)( IN HINTERNET hFile, IN LPVOID lpBuffer, IN DWORD dwNumberOfBytesToRead, OUT LPDWORD lpdwNumberOfBytesRead );
typedef INTERNET_STATUS_CALLBACK (WINAPI* PFN_STATUS_CALLBACK)( IN HINTERNET hInternet, IN INTERNET_STATUS_CALLBACK lpfnInternetCallback );
typedef BOOL (WINAPI* PFN_ADD_HEADERS)( IN HINTERNET hConnect, IN LPCWSTR lpszHeaders, IN DWORD dwHeadersLength, IN DWORD dwModifiers );
typedef BOOL (WINAPI* PFN_IS_HOST_BYPASS_PROXY)( IN INTERNET_SCHEME tScheme, IN LPCSTR pszHost, IN DWORD cchHost);
class WININET_SESSION : public SESSION { protected: WININET_SESSION(void); virtual ~WININET_SESSION(void);
virtual BOOL Open(PCWSTR pwszHttpStack, HINTERNET); virtual void Close(void);
protected: virtual HINTERNET Connect( LPCWSTR lpwszServerName, INTERNET_PORT );
virtual HINTERNET OpenRequest( HINTERNET hConnect, LPCWSTR lpwszVerb, LPCWSTR lpwszObjectName, DWORD dwFlags, DWORD_PTR dwContext = 0);
virtual BOOL SendRequest( HINTERNET hRequest, LPCWSTR lpwszHeaders, DWORD dwHeadersLength, DWORD_PTR dwContext = 0);
virtual BOOL QueryHeaders( HINTERNET hRequest, DWORD dwInfoLevel, LPVOID lpvBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex = NULL);
virtual BOOL CloseHandle( IN HINTERNET hInternet);
virtual BOOL QueryOption( HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength); virtual BOOL SetOption( HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength);
virtual HINTERNET OpenUrl( LPCWSTR lpwszUrl, LPCWSTR lpwszHeaders, DWORD dwHeadersLength, DWORD dwFlags);
virtual BOOL ReadFile( HINTERNET hFile, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead);
virtual BOOL CrackUrl( LPCWSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents);
virtual PVOID SetStatusCallback( HINTERNET hInternet, PVOID lpfnCallback );
virtual BOOL AddHeaders( HINTERNET hConnect, LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwModifiers );
virtual BOOL IsHostBypassProxy( INTERNET_SCHEME tScheme, LPCSTR pszHost, DWORD cchHost);
#ifdef PP_DEMO
virtual BOOL ContactPartner(PCWSTR pwszPartnerUrl, PCWSTR pwszVerb, PCWSTR pwszHeaders, PWSTR pwszData, PDWORD pdwDataLength ); #endif // PP_DEMO
BOOL InitHttpApi(PFN_INTERNET_OPEN*);
protected: HINTERNET m_hInternet;
PFN_INTERNET_CONNECT m_pfnConnect; PFN_OPEN_REQUEST m_pfnOpenRequest; PFN_SEND_REQUEST m_pfnSendRequest; PFN_QUERY_INFO m_pfnQueryInfo; PFN_CLOSE_HANDLE m_pfnCloseHandle; PFN_SET_OPTION m_pfnSetOption; PFN_OPEN_URL m_pfnOpenUrl; PFN_QUERY_OPTION m_pfnQueryOption; PFN_CRACK_URL m_pfnCrack; PFN_READ_FILE m_pfnReadFile; PFN_STATUS_CALLBACK m_pfnStatusCallback; PFN_ADD_HEADERS m_pfnAddHeaders; PFN_IS_HOST_BYPASS_PROXY m_pfnIsHostBypassProxy;
friend class SESSION; };
//
// Implementation for SESSION
//
SESSION* CreateWinHttpSession(void);
// -----------------------------------------------------------------------------
BOOL SESSION::CreateObject(PCWSTR pwszHttpStack, HINTERNET hSession, SESSION*& pSess) { PP_ASSERT(pwszHttpStack != NULL); pSess = NULL;
if (!::_wcsicmp(pwszHttpStack, L"WinInet.dll") || !::_wcsicmp(pwszHttpStack, L"WinInet")) { pSess = new WININET_SESSION(); } else { pSess = ::CreateWinHttpSession(); }
if (pSess) { return pSess->Open(pwszHttpStack, hSession); } else { DoTraceMessage(PP_LOG_ERROR, "CreateObject() failed; not enough memory"); return FALSE; } }
// -----------------------------------------------------------------------------
SESSION::SESSION(void) { m_hHttpStack = 0; m_hCredUI = 0; m_RefCount = 0;
m_pfnReadDomainCred = NULL; m_pfnCredFree = NULL;
m_hKeyLM = NULL; m_hKeyCU = NULL; m_hKeyDAMap = NULL;
m_wCurrentDAUrl[0] = 0;
m_LastNexusDownloadTime = 0xFFFFFFFF; }
// -----------------------------------------------------------------------------
SESSION::~SESSION(void) { }
BOOL SESSION::GetDAInfoFromPPNexus( IN BOOL fForce, // ignored for now, always assumes TRUE regardless of actual value
IN PWSTR pwszRegUrl, // user supplied buffer ...
IN OUT PDWORD pdwRegUrlLen, // ... and length (will be updated to actual length
// on successful return)
IN PWSTR pwszRealm, // user supplied buffer ...
IN OUT PDWORD pdwRealmLen // ... and length (will be updated to actual length
// on successful return)
) { BOOL fRetVal = FALSE; HINTERNET hRequest = NULL; HINTERNET hConnect = NULL; DWORD dwError; WCHAR wNexusHost[128] = L"nexus.passport.com"; DWORD dwHostLen = sizeof(wNexusHost); // note: size of the buffer, not # of UNICODE characters
WCHAR wNexusObj[128] = L"rdr/pprdr.asp"; DWORD dwObjLen = sizeof(wNexusObj); PWSTR pwszPassportUrls = NULL; DWORD dwUrlsLen = 0; DWORD dwValueType;
WCHAR Delimiters[] = L","; PWSTR Token = NULL; // we allow only one Nexus contact per session to avoid infinite loop due to Nexus misconfiguration
DWORD dwCurrentTime = ::GetTickCount();
if ((dwCurrentTime >= m_LastNexusDownloadTime) && (dwCurrentTime - m_LastNexusDownloadTime < 5*60*1000)) // 5 minutes
{ DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() failed: Nexus info already downloaded"); goto exit; }
// biaow-todo: when the Passport Team gives us THE final Nexus name, we'll then hard-code it here. And
// there will be no need to query registry here by then.
if (m_hKeyLM) { dwError = ::RegQueryValueExW(m_hKeyLM, L"NexusHost", 0, &dwValueType, reinterpret_cast<LPBYTE>(wNexusHost), &dwHostLen);
PP_ASSERT(!(dwError == ERROR_MORE_DATA)); // PP_ASSERT(dwValueType == REG_SZ); BVT Break!!!
dwError = ::RegQueryValueExW(m_hKeyLM, L"NexusObj", 0, &dwValueType, reinterpret_cast<LPBYTE>(wNexusObj), &dwObjLen);
PP_ASSERT(!(dwError == ERROR_MORE_DATA)); // PP_ASSERT(dwValueType == REG_SZ); BVT Break!!!
}
CHAR NexusHost[128]; ::WideCharToMultiByte (CP_ACP, 0, wNexusHost, -1, NexusHost, 128, NULL, NULL);
hConnect = Connect(wNexusHost, #ifdef DISABLE_SSL
INTERNET_DEFAULT_HTTP_PORT #else
INTERNET_DEFAULT_HTTPS_PORT #endif
); if (hConnect == NULL) { DWORD dwErrorCode = ::GetLastError(); DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus(): failed to connect to %ws; Error = %d", wNexusHost, dwErrorCode); goto exit; }
hRequest = OpenRequest(hConnect, NULL, wNexusObj, #ifdef DISABLE_SSL
0 #else
INTERNET_FLAG_SECURE #endif
);
if (hRequest == NULL)
{ DWORD dwErrorCode = ::GetLastError(); DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus() failed; OpenRequest() to %ws failed, Error Code = %d", wNexusObj, dwErrorCode); goto exit; }
if (!SendRequest(hRequest, NULL, 0)) { DWORD dwErrorCode = ::GetLastError();
#ifdef BAD_CERT_OK
if (dwErrorCode == ERROR_INTERNET_INVALID_CA) { DWORD dwSecFlags; DWORD dwSecurityFlagsSize = sizeof(dwSecFlags);
if (!QueryOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwSecFlags, &dwSecurityFlagsSize)) { dwSecFlags = 0; } else { dwSecFlags |= SECURITY_SET_MASK; }
if (!SetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS, &dwSecFlags, dwSecurityFlagsSize)) { PP_ASSERT(TRUE); // shouldn't reach here
goto exit; } else { if (!SendRequest(hRequest, NULL, 0)) { DWORD dwErrorCode = ::GetLastError(); DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus(): SendRequest() failed"); goto exit; } } } #else
DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus(): failed"); goto exit; #endif // BAD_CERT_OK
}
if (QueryHeaders(hRequest, HTTP_QUERY_PASSPORT_URLS, 0, &dwUrlsLen) == FALSE) { if ((::GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwUrlsLen == 0)) { DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus() failed; PassportUrls header not found"); goto exit; } } else { PP_ASSERT(TRUE); // should not reach here
} pwszPassportUrls = new WCHAR[dwUrlsLen]; if (pwszPassportUrls == NULL) { DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus() failed; insufficient memory"); goto exit; } if (QueryHeaders(hRequest, HTTP_QUERY_PASSPORT_URLS, pwszPassportUrls, &dwUrlsLen) == FALSE) { DoTraceMessage(PP_LOG_ERROR, "SESSION::GetDAInfoFromPPNexus() failed; PassportUrls header not found"); goto exit; }
Token = ::wcstok(pwszPassportUrls, Delimiters); while (Token != NULL) { // skip leading white spaces
while (*Token == (L" ")[0]) { ++Token; } if (Token == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no text in between commas"); goto next_token; }
// find DALocation
if (!::_wcsnicmp(Token, L"DALogin", ::wcslen(L"DALogin"))) { PWSTR pwszDAUrl = ::wcsstr(Token, L"="); if (pwszDAUrl == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after DALocation"); goto exit; } pwszDAUrl++; // skip "="
while (*pwszDAUrl == (L" ")[0]) { ++pwszDAUrl; } // skip leading white spaces
::wcscpy(m_wDefaultDAUrl, L"https://"); ::wcscat(m_wDefaultDAUrl, pwszDAUrl);
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"LoginServerUrl", 0, REG_SZ, reinterpret_cast<const LPBYTE>(m_wDefaultDAUrl), ::wcslen(m_wDefaultDAUrl) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"LoginServerUrl", 0, REG_SZ, reinterpret_cast<const LPBYTE>(m_wDefaultDAUrl), ::wcslen(m_wDefaultDAUrl) * sizeof(WCHAR)); } }
m_LastNexusDownloadTime = ::GetTickCount(); fRetVal = TRUE;
DoTraceMessage(PP_LOG_INFO, "DALocation URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"DARealm", ::wcslen(L"DARealm"))) { PWSTR pwszDARealm = ::wcsstr(Token, L"="); if (pwszDARealm == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after DARealm"); goto exit; }
pwszDARealm++; // skip "="
while (*pwszDARealm == (L" ")[0]) { ++pwszDARealm; } // skip leading white spaces
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"LoginServerRealm", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszDARealm), ::wcslen(pwszDARealm) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"LoginServerRealm", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszDARealm), ::wcslen(pwszDARealm) * sizeof(WCHAR)); } }
if (pwszRealm) { if (*pdwRealmLen < ::wcslen(pwszDARealm) + 1) { *pdwRealmLen = ::wcslen(pwszDARealm) + 1; fRetVal = FALSE; goto exit; } else { ::wcscpy(pwszRealm, pwszDARealm); *pdwRealmLen = ::wcslen(pwszDARealm) + 1; } } DoTraceMessage(PP_LOG_INFO, "DARealm URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"DAReg", ::wcslen(L"DAReg"))) { PWSTR pwszDAReg = ::wcsstr(Token, L"="); if (pwszDAReg == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after DAReg"); goto exit; }
pwszDAReg++; // skip "="
while (*pwszDAReg == (L" ")[0]) { ++pwszDAReg; } // skip leading white spaces
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"RegistrationUrl", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszDAReg), ::wcslen(pwszDAReg) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"RegistrationUrl", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszDAReg), ::wcslen(pwszDAReg) * sizeof(WCHAR)); } }
if (pwszRegUrl) { if (*pdwRegUrlLen < ::wcslen(pwszDAReg) + 1) { *pdwRegUrlLen = ::wcslen(pwszDAReg) + 1; fRetVal = FALSE; goto exit; } else { ::wcscpy(pwszRegUrl, pwszDAReg); *pdwRegUrlLen = ::wcslen(pwszDAReg) + 1; } }
DoTraceMessage(PP_LOG_INFO, "DAReg URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"ConfigVersion", ::wcslen(L"ConfigVersion"))) { PWSTR pwszConfigVersion = ::wcsstr(Token, L"="); if (pwszConfigVersion == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after ConfigVersion"); goto exit; }
pwszConfigVersion++; // skip "="
while (*pwszConfigVersion == (L" ")[0]) { ++pwszConfigVersion; } // skip leading white spaces
DWORD dwVersion = _wtoi(pwszConfigVersion);
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"ConfigVersion", 0, REG_DWORD, reinterpret_cast<const LPBYTE>(&dwVersion), sizeof(DWORD)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"ConfigVersion", 0, REG_DWORD, reinterpret_cast<const LPBYTE>(&dwVersion), sizeof(DWORD)); } }
DoTraceMessage(PP_LOG_INFO, "ConfigVersion URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"Help", ::wcslen(L"Help"))) { PWSTR pwszHelp = ::wcsstr(Token, L"="); if (pwszHelp == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after Help"); goto exit; }
pwszHelp++; // skip "="
while (*pwszHelp == (L" ")[0]) { ++pwszHelp; } // skip leading white spaces
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"Help", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszHelp), ::wcslen(pwszHelp) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"Help", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszHelp), ::wcslen(pwszHelp) * sizeof(WCHAR)); } }
DoTraceMessage(PP_LOG_INFO, "Help URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"Privacy", ::wcslen(L"Privacy"))) { PWSTR pwszPrivacy = ::wcsstr(Token, L"="); if (pwszPrivacy == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after Privacy"); goto exit; }
pwszPrivacy++; // skip "="
while (*pwszPrivacy == (L" ")[0]) { ++pwszPrivacy; } // skip leading white spaces
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"Privacy", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszPrivacy), ::wcslen(pwszPrivacy) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"Privacy", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszPrivacy), ::wcslen(pwszPrivacy) * sizeof(WCHAR)); } }
DoTraceMessage(PP_LOG_INFO, "Privacy URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"Properties", ::wcslen(L"Properties"))) { PWSTR pwszProperties = ::wcsstr(Token, L"="); if (pwszProperties == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after Properties"); goto exit; }
pwszProperties++; // skip "="
while (*pwszProperties == (L" ")[0]) { ++pwszProperties; } // skip leading white spaces
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"Properties", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszProperties), ::wcslen(pwszProperties) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"Properties", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszProperties), ::wcslen(pwszProperties) * sizeof(WCHAR)); } }
DoTraceMessage(PP_LOG_INFO, "Properties URL %ws found", m_wDefaultDAUrl); } else if (!::_wcsnicmp(Token, L"GeneralRedir", ::wcslen(L"GeneralRedir"))) { PWSTR pwszGeneralRedir = ::wcsstr(Token, L"="); if (pwszGeneralRedir == NULL) { DoTraceMessage(PP_LOG_WARNING, "SESSION::GetDAInfoFromPPNexus() : no = after GeneralRedir"); goto exit; }
pwszGeneralRedir++; // skip "="
while (*pwszGeneralRedir == (L" ")[0]) { ++pwszGeneralRedir; } // skip leading white spaces
if (m_hKeyLM == NULL || ::RegSetValueExW(m_hKeyLM, L"GeneralRedir", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszGeneralRedir), ::wcslen(pwszGeneralRedir) * sizeof(WCHAR)) != ERROR_SUCCESS) { if (m_hKeyCU) { ::RegSetValueExW(m_hKeyCU, L"GeneralRedir", 0, REG_SZ, reinterpret_cast<const LPBYTE>(pwszGeneralRedir), ::wcslen(pwszGeneralRedir) * sizeof(WCHAR)); } }
DoTraceMessage(PP_LOG_INFO, "GeneralRedir URL %ws found", m_wDefaultDAUrl); }
next_token:
Token = ::wcstok(NULL, Delimiters); }
exit: if (pwszPassportUrls) { delete [] pwszPassportUrls; } if (hRequest) { CloseHandle(hRequest); } if (hConnect) { CloseHandle(hConnect); }
return fRetVal; }
BOOL SESSION::GetRealm( PWSTR pwszRealm, // user supplied buffer ...
PDWORD pdwRealmLen // ... and length (will be updated to actual length
// on successful return)
) const { WCHAR wRealm[64]; DWORD RealmLen = sizeof(wRealm); DWORD dwValueType; BOOL fRealmFound = FALSE;
if (m_hKeyCU == NULL || ::RegQueryValueExW(m_hKeyCU, L"LoginServerRealm", 0, &dwValueType, reinterpret_cast<LPBYTE>(&wRealm), &RealmLen) != ERROR_SUCCESS) { if (m_hKeyLM && ::RegQueryValueExW(m_hKeyLM, L"LoginServerRealm", 0, &dwValueType, reinterpret_cast<LPBYTE>(&wRealm), &RealmLen) == ERROR_SUCCESS) { fRealmFound = TRUE; } } else { fRealmFound = TRUE; }
if (!fRealmFound) { *pdwRealmLen = 0; return FALSE; } if (!pwszRealm) { *pdwRealmLen = ::wcslen(wRealm) + 1; return FALSE; } if (*pdwRealmLen < ::wcslen(wRealm) + 1) { *pdwRealmLen = ::wcslen(wRealm) + 1; return FALSE; } ::wcscpy(pwszRealm, wRealm); *pdwRealmLen = ::wcslen(wRealm) + 1;
return TRUE; }
DWORD SESSION::GetNexusVersion(void) { DWORD dwVersion = 0; DWORD dwValueType; DWORD dwVerLen = sizeof(dwVersion); BOOL fVersionFound = FALSE;
if (m_hKeyCU == NULL || ::RegQueryValueExW(m_hKeyCU, L"ConfigVersion", 0, &dwValueType, reinterpret_cast<LPBYTE>(&dwVersion), &dwVerLen) != ERROR_SUCCESS) { if (m_hKeyLM && ::RegQueryValueExW(m_hKeyLM, L"ConfigVersion", 0, &dwValueType, reinterpret_cast<LPBYTE>(&dwVersion), &dwVerLen) == ERROR_SUCCESS) { fVersionFound = TRUE; } } else { fVersionFound = TRUE; }
if (fVersionFound) { return dwVersion; } else { return 0; } }
BOOL SESSION::UpdateDAInfo( PCWSTR pwszSignIn, PCWSTR pwszDAUrl ) { if (pwszSignIn) { LPCWSTR pwszDomain = ::wcsstr(pwszSignIn, L"@"); if (pwszDomain && m_hKeyDAMap) { DWORD dwError = ::RegSetValueExW(m_hKeyDAMap, pwszDomain, 0, REG_SZ, reinterpret_cast<const LPBYTE>(const_cast<PWSTR>(pwszDAUrl)), ::wcslen(pwszDAUrl) * sizeof(WCHAR)); if (dwError == ERROR_SUCCESS) { return TRUE; } } }
return FALSE; }
BOOL SESSION::PurgeDAInfo(PCWSTR pwszSignIn) { if (pwszSignIn == NULL) { return TRUE; }
LPCWSTR pwszDomain = ::wcsstr(pwszSignIn, L"@"); if (pwszDomain && m_hKeyDAMap) { ::RegDeleteValueW(m_hKeyDAMap, pwszDomain); return TRUE; }
return FALSE; }
BOOL SESSION::GetDAInfo(PCWSTR pwszSignIn, LPWSTR pwszDAHostName, DWORD HostNameLen, LPWSTR pwszDAHostObj, DWORD HostObjLen) { LPCWSTR pwszDAUrl = m_wDefaultDAUrl;
PWSTR pwszDomainDAUrl = NULL;
if (pwszSignIn) { LPCWSTR pwszDomain = ::wcsstr(pwszSignIn, L"@"); if (pwszDomain && m_hKeyDAMap) { pwszDomainDAUrl = new WCHAR[512]; if (pwszDomainDAUrl == NULL) { return FALSE; }
DWORD dwDomainUrlLen = 512 * sizeof(sizeof(WCHAR)); DWORD dwValueType; DWORD dwError = ::RegQueryValueExW(m_hKeyDAMap, pwszDomain, 0, &dwValueType, reinterpret_cast<LPBYTE>(pwszDomainDAUrl), &dwDomainUrlLen); PP_ASSERT(!(dwError == ERROR_MORE_DATA)); // PP_ASSERT(dwValueType == REG_SZ);
if (dwError == ERROR_SUCCESS) { pwszDAUrl = pwszDomainDAUrl; } } }
::wcscpy(m_wCurrentDAUrl, pwszDAUrl);
URL_COMPONENTSW UrlComps; ::memset(&UrlComps, 0, sizeof(UrlComps));
UrlComps.dwStructSize = sizeof(UrlComps) / sizeof(WCHAR);
UrlComps.lpszHostName = pwszDAHostName; UrlComps.dwHostNameLength = HostNameLen;
UrlComps.lpszUrlPath = pwszDAHostObj; UrlComps.dwUrlPathLength = HostObjLen;
if (CrackUrl(pwszDAUrl, 0, 0, &UrlComps) == FALSE) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::GetDAInfo() failed; can not crack the URL %ws", pwszDAUrl); delete [] pwszDomainDAUrl; return FALSE; }
delete [] pwszDomainDAUrl; return TRUE; }
BOOL SESSION::GetCachedCreds( PCWSTR pwszRealm, PCWSTR pwszTarget, PCREDENTIALW** pppCreds, DWORD* pdwCreds ) { *pppCreds = NULL; *pdwCreds = 0;
if (m_pfnReadDomainCred == NULL) { return FALSE; }
ULONG CredTypes = CRED_TYPE_DOMAIN_VISIBLE_PASSWORD; DWORD dwFlags = CRED_CACHE_TARGET_INFORMATION; CREDENTIAL_TARGET_INFORMATIONW TargetInfo;
memset ( (void*)&TargetInfo, 0, sizeof(CREDENTIAL_TARGET_INFORMATIONW));
TargetInfo.TargetName = const_cast<PWSTR>(pwszTarget); TargetInfo.DnsDomainName = const_cast<PWSTR>(pwszRealm); TargetInfo.PackageName = L"Passport1.4";
TargetInfo.Flags = 0; TargetInfo.CredTypeCount = 1; TargetInfo.CredTypes = &CredTypes;
if ((*m_pfnReadDomainCred)(&TargetInfo, dwFlags, pdwCreds, pppCreds ) != TRUE) { *pppCreds = NULL; *pdwCreds = 0; }
// check to see if we've been told to ignore cached creds
if ( g_fIgnoreCachedCredsForPassport ) { if ( *pppCreds != NULL ) { if (m_pfnCredFree) { m_pfnCredFree(*pppCreds); } }
*pppCreds = NULL; *pdwCreds = 0; }
return (*pppCreds != NULL ); }
BOOL SESSION::Open(PCWSTR /*pwszHttpStack*/, HINTERNET) { BOOL fRetVal = FALSE; DWORD dwError; DWORD dwValueType; DWORD dwUrlLen = sizeof(m_wDefaultDAUrl); // note: size of the buffer, not # of UNICODE characters
BOOL fDAInfoCached = FALSE; // assume NO DA info's cached locally
dwError = ::RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &m_hKeyLM, NULL);
if (dwError != ERROR_SUCCESS) { DoTraceMessage(PP_LOG_ERROR, "SESSION::Open() failed; can not create/open the Passport key; Error = %d", dwError); // we can't open the Passport key for read & write, let's try open it for read only
::RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &m_hKeyLM, NULL);
// if we still can't open it for read, we are still fine since we can download the info from the
// Nexus server. *NOTE* m_hKeyLM could be NULL from this point on.
}
dwError = ::RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &m_hKeyCU, NULL);
if (dwError != ERROR_SUCCESS) { DoTraceMessage(PP_LOG_ERROR, "SESSION::Open() failed; can not create/open the Passport key; Error = %d", dwError);
::RegCreateKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Passport", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &m_hKeyCU, NULL); }
if (m_hKeyCU) { dwError = ::RegCreateKeyExW(m_hKeyCU, L"DAMap", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &m_hKeyDAMap, NULL);
if (dwError != ERROR_SUCCESS) { DoTraceMessage(PP_LOG_ERROR, "SESSION::Open() failed; can not create/open the Passport key; Error = %d", dwError); ::RegCreateKeyExW(m_hKeyCU, L"DAMap", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &m_hKeyDAMap, NULL); } } if (m_hKeyCU == NULL || ::RegQueryValueExW(m_hKeyCU, L"LoginServerUrl", 0, &dwValueType, reinterpret_cast<LPBYTE>(m_wDefaultDAUrl), &dwUrlLen) != ERROR_SUCCESS) { if (m_hKeyLM && ::RegQueryValueExW(m_hKeyLM, L"LoginServerUrl", 0, &dwValueType, reinterpret_cast<LPBYTE>(m_wDefaultDAUrl), &dwUrlLen) == ERROR_SUCCESS) { fDAInfoCached = TRUE; } } else { fDAInfoCached = TRUE; }
PP_ASSERT(!(dwError == ERROR_MORE_DATA)); // PP_ASSERT(dwValueType == REG_SZ); BVT break!!!
if (!fDAInfoCached || (::wcslen(m_wDefaultDAUrl) == ::wcslen(L""))) { if (GetDAInfoFromPPNexus(FALSE, // don't force connection establishment if nexus not reachable
NULL, 0, NULL, 0) == FALSE) { goto exit; } } else { /*
URL_COMPONENTSW UrlComps; ::memset(&UrlComps, 0, sizeof(UrlComps));
UrlComps.dwStructSize = sizeof(UrlComps) / sizeof(WCHAR);
UrlComps.lpszHostName = m_wDAHostName; UrlComps.dwHostNameLength = ARRAYSIZE(m_wDAHostName);
UrlComps.lpszUrlPath = m_wDATargetObj; UrlComps.dwUrlPathLength = ARRAYSIZE(m_wDATargetObj);
if (CrackUrl(m_wDefaultDAUrl, 0, 0, &UrlComps) == FALSE) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::Open() failed; can not crack the URL %ws", m_wDefaultDAUrl); goto exit; } */ }
/*
DWORD dwRegUrlLen = sizeof(m_wRegistrationUrl); dwError = ::RegQueryValueExW(m_hKeyLM, L"RegistrationUrl", 0, &dwValueType, reinterpret_cast<LPBYTE>(m_wRegistrationUrl), &dwRegUrlLen);
PP_ASSERT(!(dwError == ERROR_MORE_DATA)); */
m_hCredUI = ::LoadLibraryW(L"advapi32.dll"); if (m_hCredUI) { m_pfnReadDomainCred = reinterpret_cast<PFN_READ_DOMAIN_CRED_W>(::GetProcAddress(m_hCredUI, "CredReadDomainCredentialsW")); if (m_pfnReadDomainCred == NULL) { DoTraceMessage(PP_LOG_WARNING, "failed to bind to CredReadDomainCredentialsW()"); }
m_pfnCredFree = reinterpret_cast<PFN_CRED_FREE>(::GetProcAddress(m_hCredUI, "CredFree")); if (m_pfnCredFree == NULL) { DoTraceMessage(PP_LOG_WARNING, "failed to bind to CredFree()"); } }
fRetVal = TRUE;
exit:
return fRetVal; }
void SESSION::Close(void) { if (m_hCredUI) { ::FreeLibrary(m_hCredUI); m_hCredUI = NULL; }
if (m_hKeyDAMap) { ::RegCloseKey(m_hKeyDAMap); }
if (m_hKeyCU) { ::RegCloseKey(m_hKeyCU); } if (m_hKeyLM) { ::RegCloseKey(m_hKeyLM); } }
//
// Implementation for WININET_SESSION
//
// -----------------------------------------------------------------------------
WININET_SESSION::WININET_SESSION(void) { m_hInternet = NULL;
m_pfnConnect = NULL; m_pfnOpenRequest = NULL; m_pfnSendRequest = NULL; m_pfnQueryInfo = NULL; m_pfnCloseHandle = NULL; m_pfnSetOption = NULL; m_pfnOpenUrl = NULL; m_pfnQueryOption = NULL; m_pfnCrack = NULL; m_pfnReadFile = NULL; m_pfnStatusCallback = NULL; m_pfnAddHeaders = NULL; m_pfnIsHostBypassProxy = NULL; }
// -----------------------------------------------------------------------------
WININET_SESSION::~WININET_SESSION(void) { }
// -----------------------------------------------------------------------------
HINTERNET WININET_SESSION::Connect( LPCWSTR lpwszServerName, INTERNET_PORT nPort) { PP_ASSERT(m_pfnConnect != NULL);
return (*m_pfnConnect)(m_hInternet, lpwszServerName, nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); }
// -----------------------------------------------------------------------------
HINTERNET WININET_SESSION::OpenRequest( HINTERNET hConnect, LPCWSTR lpwszVerb, LPCWSTR lpwszObjectName, DWORD dwFlags, DWORD_PTR dwContext) { PP_ASSERT(m_pfnOpenRequest != NULL);
return (*m_pfnOpenRequest)(hConnect, lpwszVerb, lpwszObjectName, L"HTTP/1.1", NULL, NULL, dwFlags, dwContext); }
// -----------------------------------------------------------------------------
BOOL WININET_SESSION::SendRequest( HINTERNET hRequest, LPCWSTR lpwszHeaders, DWORD dwHeadersLength, DWORD_PTR dwContext) {
PP_ASSERT(m_pfnSendRequest != NULL);
return (*m_pfnSendRequest)(hRequest, lpwszHeaders, dwHeadersLength, NULL, 0); }
// -----------------------------------------------------------------------------
BOOL WININET_SESSION::QueryHeaders( HINTERNET hRequest, DWORD dwInfoLevel, LPVOID lpvBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex) { PP_ASSERT(m_pfnQueryInfo != NULL);
return (*m_pfnQueryInfo)(hRequest, dwInfoLevel, lpvBuffer, lpdwBufferLength, lpdwIndex); }
// -----------------------------------------------------------------------------
BOOL WININET_SESSION::CloseHandle( IN HINTERNET hInternet) { PP_ASSERT(m_pfnCloseHandle != NULL);
return (*m_pfnCloseHandle)(hInternet); }
// -----------------------------------------------------------------------------
BOOL WININET_SESSION::QueryOption( HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength) { PP_ASSERT(m_pfnQueryOption != NULL);
return (*m_pfnQueryOption)(hInternet, dwOption, lpBuffer, lpdwBufferLength ); }
// -----------------------------------------------------------------------------
BOOL WININET_SESSION::SetOption( HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, DWORD dwBufferLength) { PP_ASSERT(m_pfnSetOption != NULL);
return (*m_pfnSetOption)(hInternet, dwOption, lpBuffer, dwBufferLength); }
// -----------------------------------------------------------------------------
HINTERNET WININET_SESSION::OpenUrl( LPCWSTR lpwszUrl, LPCWSTR lpwszHeaders, DWORD dwHeadersLength, DWORD dwFlags) { PP_ASSERT(m_pfnOpenUrl != NULL);
return (*m_pfnOpenUrl)(m_hInternet, lpwszUrl, lpwszHeaders, dwHeadersLength, dwFlags, 0); }
// -----------------------------------------------------------------------------
BOOL WININET_SESSION::ReadFile( HINTERNET hFile, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead) { PP_ASSERT(m_pfnReadFile != NULL);
return (*m_pfnReadFile)( hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead); }
BOOL WININET_SESSION::CrackUrl( LPCWSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, PVOID/*LPURL_COMPONENTSW*/ lpUrlComponents) { PP_ASSERT (m_pfnCrack != NULL);
return (*m_pfnCrack)(lpszUrl, dwUrlLength, dwFlags, lpUrlComponents); }
PVOID WININET_SESSION::SetStatusCallback( HINTERNET hInternet, PVOID lpfnCallback ) { PP_ASSERT (m_pfnStatusCallback != NULL);
return (*m_pfnStatusCallback)(hInternet, (INTERNET_STATUS_CALLBACK)lpfnCallback);
}
BOOL WININET_SESSION::AddHeaders( HINTERNET hConnect, LPCWSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwModifiers ) { PP_ASSERT(m_pfnAddHeaders != NULL);
return (*m_pfnAddHeaders)(hConnect, lpszHeaders, dwHeadersLength, dwModifiers ); }
BOOL WININET_SESSION::IsHostBypassProxy( INTERNET_SCHEME tScheme, LPCSTR pszHost, DWORD cchHost) { PP_ASSERT(m_pfnIsHostBypassProxy != NULL);
return (*m_pfnIsHostBypassProxy)(tScheme, pszHost, cchHost); }
BOOL WININET_SESSION::InitHttpApi(PFN_INTERNET_OPEN* ppfnInternetOpen) { BOOL fRet = FALSE;
m_pfnCloseHandle = reinterpret_cast<PFN_CLOSE_HANDLE>(::GetProcAddress(m_hHttpStack, "InternetCloseHandle")); if (m_pfnCloseHandle == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetCloseHandle not found"); goto exit; }
*ppfnInternetOpen = reinterpret_cast<PFN_INTERNET_OPEN>(::GetProcAddress(m_hHttpStack, "InternetOpenW")); if (*ppfnInternetOpen == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetOpenW not found"); goto exit; }
m_pfnConnect = reinterpret_cast<PFN_INTERNET_CONNECT>(::GetProcAddress(m_hHttpStack, "InternetConnectW")); if (m_pfnConnect == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetConnectW not found"); goto exit; }
m_pfnOpenRequest = reinterpret_cast<PFN_OPEN_REQUEST>(::GetProcAddress(m_hHttpStack, "HttpOpenRequestW")); if (m_pfnOpenRequest == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point HttpOpenRequestW not found"); goto exit; }
m_pfnSendRequest = reinterpret_cast<PFN_SEND_REQUEST>(::GetProcAddress(m_hHttpStack, "HttpSendRequestW")); if (m_pfnSendRequest == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point HttpSendRequestW not found"); goto exit; }
m_pfnQueryInfo = reinterpret_cast<PFN_QUERY_INFO>(::GetProcAddress(m_hHttpStack, "HttpQueryInfoW")); if (m_pfnQueryInfo == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point HttpQueryInfoW not found"); goto exit; } m_pfnSetOption = reinterpret_cast<PFN_SET_OPTION>(::GetProcAddress(m_hHttpStack, "InternetSetOptionW")); if (m_pfnSetOption == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetSetOptionW not found"); goto exit; }
m_pfnOpenUrl = reinterpret_cast<PFN_OPEN_URL>(::GetProcAddress(m_hHttpStack, "InternetOpenUrlW")); if (m_pfnOpenUrl == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetOpenUrlW not found"); goto exit; }
m_pfnQueryOption = reinterpret_cast<PFN_QUERY_OPTION>(::GetProcAddress(m_hHttpStack, "InternetQueryOptionW")); if (m_pfnQueryOption == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetQueryOptionW not found"); goto exit; }
m_pfnCrack = reinterpret_cast<PFN_CRACK_URL>(::GetProcAddress(m_hHttpStack, "InternetCrackUrlW")); if (m_pfnCrack == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetCrackUrlW not found"); goto exit; }
m_pfnReadFile = reinterpret_cast<PFN_READ_FILE>(::GetProcAddress(m_hHttpStack, "InternetReadFile")); if (m_pfnReadFile == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetReadFile not found"); goto exit; }
m_pfnStatusCallback = reinterpret_cast<PFN_STATUS_CALLBACK>(::GetProcAddress(m_hHttpStack, "InternetSetStatusCallbackW")); if (m_pfnStatusCallback == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point InternetSetStatusCallback not found"); goto exit; }
m_pfnAddHeaders = reinterpret_cast<PFN_ADD_HEADERS>(::GetProcAddress(m_hHttpStack, "HttpAddRequestHeadersW")); if (m_pfnAddHeaders == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point HttpAddRequestHeaders not found"); goto exit; }
m_pfnIsHostBypassProxy = reinterpret_cast<PFN_IS_HOST_BYPASS_PROXY>(::GetProcAddress(m_hHttpStack, "IsHostInProxyBypassList")); if (m_pfnIsHostBypassProxy == NULL) { DoTraceMessage(PP_LOG_ERROR, "function entry point IsHostInProxyBypassList not found"); goto exit; }
fRet = TRUE;
exit: return fRet; }
BOOL WININET_SESSION::Open( PCWSTR pwszHttpStack, HINTERNET hInternet ) { PP_ASSERT(pwszHttpStack != NULL);
DWORD dwErrorCode; BOOL fRet = FALSE; PFN_INTERNET_OPEN pfnInternetOpen = NULL;
PP_ASSERT(m_hHttpStack == 0); m_hHttpStack = ::LoadLibraryW(pwszHttpStack); if (m_hHttpStack == NULL) { dwErrorCode = ::GetLastError(); DoTraceMessage(PP_LOG_ERROR, "failed to load library %ws; error = %d", pwszHttpStack, dwErrorCode); goto exit; }
if (InitHttpApi(&pfnInternetOpen) == FALSE) { goto exit; }
if (hInternet) { m_hInternet = hInternet; m_fOwnedSession = FALSE; } else { m_hInternet = (*pfnInternetOpen)( L"Microsoft.NET-Passport-Authentication-Service/1.4; Q312461", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 /*INTERNET_FLAG_ASYNC*/ // biaow-todo: use async
); (*m_pfnSetOption)(m_hInternet, INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT, NULL, 0);
m_fOwnedSession = TRUE; } if (m_hInternet == NULL) { dwErrorCode = ::GetLastError(); DoTraceMessage(PP_LOG_ERROR, "failed to open an HTTP session through %ws; error = %d", pwszHttpStack, dwErrorCode); goto exit; }
if (SESSION::Open(pwszHttpStack, hInternet) == FALSE) { goto exit; } fRet = TRUE;
DoTraceMessage(PP_LOG_INFO, "WinInet Http Session opened");
exit: if (!fRet) { if (m_hInternet && m_fOwnedSession) { (*m_pfnCloseHandle)(m_hInternet); m_hInternet = NULL; } if (m_hHttpStack) { ::FreeLibrary(m_hHttpStack); m_hHttpStack = NULL; } DoTraceMessage(PP_LOG_ERROR, "WinInet Http Session failed"); }
return fRet; }
void WININET_SESSION::Close(void) { PP_ASSERT(m_pfnCloseHandle); if (m_hInternet && m_fOwnedSession) { (*m_pfnCloseHandle)(m_hInternet); m_pfnCloseHandle = NULL; }
if (m_hHttpStack) { ::FreeLibrary(m_hHttpStack); m_hHttpStack = NULL; }
SESSION::Close();
DoTraceMessage(PP_LOG_INFO, "WinInet Http Session closed"); }
#ifdef PP_DEMO
BOOL WININET_SESSION::ContactPartner(PCWSTR pwszPartnerUrl, PCWSTR pwszVerb, PCWSTR pwszHeaders, PWSTR pwszData, PDWORD pdwDataLength ) { BOOL fRet = FALSE; HINTERNET hConnect = NULL; HINTERNET hRequest = NULL;
WCHAR ServerName[128]; WCHAR ObjectPath[1024];
URL_COMPONENTSW UrlComps; ::memset(&UrlComps, 0, sizeof(UrlComps)); UrlComps.dwStructSize = sizeof(UrlComps) / sizeof(WCHAR); UrlComps.lpszHostName = ServerName; UrlComps.dwHostNameLength = ARRAYSIZE(ServerName);
UrlComps.lpszUrlPath = ObjectPath; UrlComps.dwUrlPathLength = ARRAYSIZE(ObjectPath);
PP_ASSERT(m_pfnCrack != NULL);
if ((*m_pfnCrack)(pwszPartnerUrl, 0, 0, &UrlComps) == FALSE) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; can not crack the URL %ws", pwszPartnerUrl); goto exit; }
PP_ASSERT(m_pfnConnect != NULL);
hConnect = (*m_pfnConnect)(m_hInternet, UrlComps.lpszHostName, UrlComps.nPort, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); if (hConnect == NULL) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; can not open an HTTP sesstion to %ws:%d", UrlComps.lpszHostName, UrlComps.nPort); goto exit; }
PP_ASSERT(m_pfnOpenRequest != NULL);
hRequest = (*m_pfnOpenRequest)(hConnect, pwszVerb, UrlComps.lpszUrlPath, L"HTTP/1.1", NULL, NULL, INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_NO_AUTH, 0); if (hRequest == NULL) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; can not open an HTTP request to %ws:(%ws)", UrlComps.lpszUrlPath, pwszVerb); goto exit; }
PP_ASSERT(m_pfnSendRequest != NULL);
if ((*m_pfnSendRequest)(hRequest, pwszHeaders, 0, NULL, 0) == FALSE) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; can not send an HTTP request");
goto exit; }
if (pwszData == NULL) { fRet = TRUE; goto exit; } DWORD dwStatus, dwStatusLen; dwStatusLen = sizeof(dwStatus); if (!QueryHeaders(hRequest, HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, &dwStatus, &dwStatusLen)) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; can not query status code"); goto exit; }
if (dwStatus != HTTP_STATUS_REDIRECT) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; expecting %d but get %d", HTTP_STATUS_REDIRECT, dwStatus); goto exit; }
::wcscpy(pwszData, L"WWW-Authenticate: "); if(!QueryHeaders(hRequest, HTTP_QUERY_WWW_AUTHENTICATE, (LPVOID)(pwszData + ::wcslen(L"WWW-Authenticate: ")), pdwDataLength)) { DoTraceMessage(PP_LOG_ERROR, "WININET_SESSION::ContactPartner() failed; no auth headers found"); goto exit; }
(*m_pfnCloseHandle)(hRequest); hRequest = NULL; (*m_pfnCloseHandle)(hConnect); hConnect = NULL; fRet = TRUE;
exit: if (hRequest) { (*m_pfnCloseHandle)(hRequest); hRequest = NULL; }
if (hConnect) { (*m_pfnCloseHandle)(hConnect); hConnect = NULL; }
return fRet; } #endif // PP_DEMO
|