900 lines
24 KiB
C++
900 lines
24 KiB
C++
/*++
|
|
|
|
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 <WinHTTP.h>
|
|
*/
|
|
|
|
#define INTERNET_DEFAULT_HTTP_PORT 80
|
|
#define INTERNET_DEFAULT_HTTPS_PORT 443
|
|
#define WINHTTP_HEADER_NAME_BY_INDEX NULL
|
|
#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 0
|
|
#define INTERNET_OPEN_TYPE_PRECONFIG INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY
|
|
#define INTERNET_FLAG_NO_AUTO_REDIRECT 0x00200000
|
|
#define INTERNET_FLAG_NO_AUTH 0x00040000
|
|
#define HTTP_QUERY_FLAG_NUMBER 0x20000000
|
|
#define HTTP_QUERY_STATUS_CODE 19 // special: part of status line
|
|
#define HTTP_STATUS_REDIRECT 302 // object temporarily moved
|
|
#define HTTP_QUERY_WWW_AUTHENTICATE 40
|
|
|
|
typedef
|
|
VOID
|
|
(CALLBACK * WINHTTP_STATUS_CALLBACK)(
|
|
IN HINTERNET hInternet,
|
|
IN DWORD_PTR dwContext,
|
|
IN DWORD dwInternetStatus,
|
|
IN LPVOID lpvStatusInformation OPTIONAL,
|
|
IN DWORD dwStatusInformationLength
|
|
);
|
|
|
|
typedef enum
|
|
{
|
|
INTERNET_SCHEME_PARTIAL = -2,
|
|
INTERNET_SCHEME_UNKNOWN = -1,
|
|
INTERNET_SCHEME_DEFAULT = 0,
|
|
INTERNET_SCHEME_HTTP,
|
|
INTERNET_SCHEME_HTTPS,
|
|
INTERNET_SCHEME_FILE,
|
|
INTERNET_SCHEME_SOCKS,
|
|
INTERNET_SCHEME_RES,
|
|
INTERNET_SCHEME_FIRST = INTERNET_SCHEME_HTTP,
|
|
INTERNET_SCHEME_LAST = INTERNET_SCHEME_RES
|
|
} INTERNET_SCHEME, * LPINTERNET_SCHEME;
|
|
|
|
#include "session.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 DWORD dwFlags
|
|
);
|
|
|
|
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
|
|
);
|
|
|
|
typedef BOOL
|
|
(WINAPI * PFN_SEND_REQUEST)(
|
|
IN HINTERNET hRequest,
|
|
IN LPCWSTR lpwszHeaders OPTIONAL,
|
|
IN DWORD dwHeadersLength,
|
|
IN LPVOID lpOptional OPTIONAL,
|
|
IN DWORD dwOptionalLength,
|
|
IN DWORD dwTotalLength,
|
|
IN DWORD_PTR dwContext
|
|
);
|
|
|
|
typedef BOOL
|
|
(WINAPI * PFN_QUERY_INFO)(
|
|
IN HINTERNET hRequest,
|
|
IN DWORD dwInfoLevel,
|
|
IN LPCWSTR lpszName OPTIONAL,
|
|
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 struct {
|
|
DWORD dwStructSize; // size of this structure. Used in version check
|
|
LPWSTR lpszScheme; // pointer to scheme name
|
|
DWORD dwSchemeLength; // length of scheme name
|
|
INTERNET_SCHEME nScheme; // enumerated scheme type (if known)
|
|
LPWSTR lpszHostName; // pointer to host name
|
|
DWORD dwHostNameLength; // length of host name
|
|
INTERNET_PORT nPort; // converted port number
|
|
LPWSTR lpszUserName; // pointer to user name
|
|
DWORD dwUserNameLength; // length of user name
|
|
LPWSTR lpszPassword; // pointer to password
|
|
DWORD dwPasswordLength; // length of password
|
|
LPWSTR lpszUrlPath; // pointer to URL-path
|
|
DWORD dwUrlPathLength; // length of URL-path
|
|
LPWSTR lpszExtraInfo; // pointer to extra information (e.g. ?foo or #foo)
|
|
DWORD dwExtraInfoLength; // length of extra information
|
|
} URL_COMPONENTSW, * LPURL_COMPONENTSW;
|
|
|
|
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 WINHTTP_STATUS_CALLBACK
|
|
(WINAPI* PFN_STATUS_CALLBACK)(
|
|
IN HINTERNET hInternet,
|
|
IN WINHTTP_STATUS_CALLBACK lpfnInternetCallback,
|
|
IN DWORD dwNotificationFlags,
|
|
IN DWORD_PTR dwReserved
|
|
);
|
|
|
|
typedef BOOL
|
|
(WINAPI* PFN_ADD_HEADERS)(
|
|
IN HINTERNET hConnect,
|
|
IN LPCWSTR lpszHeaders,
|
|
IN DWORD dwHeadersLength,
|
|
IN DWORD dwModifiers
|
|
);
|
|
|
|
|
|
class WINHTTP_SESSION : public SESSION
|
|
{
|
|
protected:
|
|
WINHTTP_SESSION(void);
|
|
virtual ~WINHTTP_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)
|
|
{
|
|
return TRUE; // biaow: todo
|
|
}
|
|
|
|
|
|
#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;
|
|
|
|
friend class SESSION;
|
|
friend SESSION* CreateWinHttpSession(void);
|
|
};
|
|
|
|
SESSION* CreateWinHttpSession(void)
|
|
{
|
|
return new WINHTTP_SESSION();
|
|
}
|
|
|
|
//
|
|
// Implementation for WINHTTP_SESSION
|
|
//
|
|
|
|
// -----------------------------------------------------------------------------
|
|
WINHTTP_SESSION::WINHTTP_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;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
WINHTTP_SESSION::~WINHTTP_SESSION(void)
|
|
{
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
HINTERNET WINHTTP_SESSION::Connect(
|
|
LPCWSTR lpwszServerName,
|
|
INTERNET_PORT nPort)
|
|
{
|
|
PP_ASSERT(m_pfnConnect != NULL);
|
|
|
|
return (*m_pfnConnect)(m_hInternet,
|
|
lpwszServerName,
|
|
nPort,
|
|
0);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
HINTERNET WINHTTP_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);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
BOOL WINHTTP_SESSION::SendRequest(
|
|
HINTERNET hRequest,
|
|
LPCWSTR lpwszHeaders,
|
|
DWORD dwHeadersLength,
|
|
DWORD_PTR dwContext)
|
|
{
|
|
|
|
PP_ASSERT(m_pfnSendRequest != NULL);
|
|
|
|
return (*m_pfnSendRequest)(hRequest,
|
|
lpwszHeaders,
|
|
dwHeadersLength,
|
|
NULL,
|
|
0,
|
|
0, // optional total length
|
|
dwContext);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
BOOL WINHTTP_SESSION::QueryHeaders(
|
|
HINTERNET hRequest,
|
|
DWORD dwInfoLevel,
|
|
LPVOID lpvBuffer,
|
|
LPDWORD lpdwBufferLength,
|
|
LPDWORD lpdwIndex)
|
|
{
|
|
PP_ASSERT(m_pfnQueryInfo != NULL);
|
|
|
|
return (*m_pfnQueryInfo)(hRequest,
|
|
dwInfoLevel,
|
|
WINHTTP_HEADER_NAME_BY_INDEX,
|
|
lpvBuffer,
|
|
lpdwBufferLength,
|
|
lpdwIndex);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
BOOL WINHTTP_SESSION::CloseHandle(
|
|
IN HINTERNET hInternet)
|
|
{
|
|
PP_ASSERT(m_pfnCloseHandle != NULL);
|
|
|
|
return (*m_pfnCloseHandle)(hInternet);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
BOOL WINHTTP_SESSION::QueryOption(
|
|
HINTERNET hInternet,
|
|
DWORD dwOption,
|
|
LPVOID lpBuffer,
|
|
LPDWORD lpdwBufferLength)
|
|
{
|
|
PP_ASSERT(m_pfnQueryOption != NULL);
|
|
|
|
return (*m_pfnQueryOption)(hInternet,
|
|
dwOption,
|
|
lpBuffer,
|
|
lpdwBufferLength
|
|
);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
BOOL WINHTTP_SESSION::SetOption(
|
|
HINTERNET hInternet,
|
|
DWORD dwOption,
|
|
LPVOID lpBuffer,
|
|
DWORD dwBufferLength)
|
|
{
|
|
PP_ASSERT(m_pfnSetOption != NULL);
|
|
|
|
return (*m_pfnSetOption)(hInternet,
|
|
dwOption,
|
|
lpBuffer,
|
|
dwBufferLength);
|
|
}
|
|
|
|
// -----------------------------------------------------------------------------
|
|
HINTERNET WINHTTP_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 WINHTTP_SESSION::ReadFile(
|
|
HINTERNET hFile,
|
|
LPVOID lpBuffer,
|
|
DWORD dwNumberOfBytesToRead,
|
|
LPDWORD lpdwNumberOfBytesRead)
|
|
{
|
|
PP_ASSERT(m_pfnReadFile != NULL);
|
|
|
|
return (*m_pfnReadFile)(
|
|
hFile,
|
|
lpBuffer,
|
|
dwNumberOfBytesToRead,
|
|
lpdwNumberOfBytesRead);
|
|
}
|
|
|
|
BOOL WINHTTP_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 WINHTTP_SESSION::SetStatusCallback(
|
|
HINTERNET hInternet,
|
|
PVOID lpfnCallback
|
|
)
|
|
{
|
|
return (*m_pfnStatusCallback)(hInternet,
|
|
(WINHTTP_STATUS_CALLBACK)lpfnCallback,
|
|
0,
|
|
0);
|
|
|
|
}
|
|
|
|
BOOL WINHTTP_SESSION::AddHeaders(
|
|
HINTERNET hConnect,
|
|
LPCWSTR lpszHeaders,
|
|
DWORD dwHeadersLength,
|
|
DWORD dwModifiers
|
|
)
|
|
{
|
|
PP_ASSERT(m_pfnAddHeaders != NULL);
|
|
|
|
return (*m_pfnAddHeaders)(hConnect,
|
|
lpszHeaders,
|
|
dwHeadersLength,
|
|
dwModifiers
|
|
);
|
|
}
|
|
|
|
BOOL WINHTTP_SESSION::InitHttpApi(PFN_INTERNET_OPEN* ppfnInternetOpen)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
m_pfnCloseHandle =
|
|
reinterpret_cast<PFN_CLOSE_HANDLE>(::GetProcAddress(m_hHttpStack, "WinHttpCloseHandle"));
|
|
if (m_pfnCloseHandle == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpCloseHandle not found");
|
|
goto exit;
|
|
}
|
|
|
|
*ppfnInternetOpen =
|
|
reinterpret_cast<PFN_INTERNET_OPEN>(::GetProcAddress(m_hHttpStack, "WinHttpOpen"));
|
|
if (*ppfnInternetOpen == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpOpen not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnConnect =
|
|
reinterpret_cast<PFN_INTERNET_CONNECT>(::GetProcAddress(m_hHttpStack, "WinHttpConnect"));
|
|
if (m_pfnConnect == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpConnect not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnOpenRequest =
|
|
reinterpret_cast<PFN_OPEN_REQUEST>(::GetProcAddress(m_hHttpStack, "WinHttpOpenRequest"));
|
|
if (m_pfnOpenRequest == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpOpenRequest not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnSendRequest =
|
|
reinterpret_cast<PFN_SEND_REQUEST>(::GetProcAddress(m_hHttpStack, "WinHttpSendRequest"));
|
|
if (m_pfnSendRequest == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpSendRequest not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnQueryInfo =
|
|
reinterpret_cast<PFN_QUERY_INFO>(::GetProcAddress(m_hHttpStack, "WinHttpQueryHeaders"));
|
|
if (m_pfnQueryInfo == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpQueryHeaders not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnSetOption =
|
|
reinterpret_cast<PFN_SET_OPTION>(::GetProcAddress(m_hHttpStack, "WinHttpSetOption"));
|
|
if (m_pfnSetOption == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpSetOption not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnOpenUrl =
|
|
reinterpret_cast<PFN_OPEN_URL>(::GetProcAddress(m_hHttpStack, "WinHttpOpenUrl"));
|
|
if (m_pfnOpenUrl == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpOpenUrl not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnQueryOption =
|
|
reinterpret_cast<PFN_QUERY_OPTION>(::GetProcAddress(m_hHttpStack, "WinHttpQueryOption"));
|
|
if (m_pfnQueryOption == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpQueryOption not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnCrack =
|
|
reinterpret_cast<PFN_CRACK_URL>(::GetProcAddress(m_hHttpStack, "WinHttpCrackUrl"));
|
|
if (m_pfnCrack == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpCrackUrl not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnReadFile =
|
|
reinterpret_cast<PFN_READ_FILE>(::GetProcAddress(m_hHttpStack, "WinHttpReadData"));
|
|
if (m_pfnReadFile == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpReadData not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnStatusCallback =
|
|
reinterpret_cast<PFN_STATUS_CALLBACK>(::GetProcAddress(m_hHttpStack, "WinHttpSetStatusCallback"));
|
|
if (m_pfnStatusCallback == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpSetStatusCallback not found");
|
|
goto exit;
|
|
}
|
|
|
|
m_pfnAddHeaders =
|
|
reinterpret_cast<PFN_ADD_HEADERS>(::GetProcAddress(m_hHttpStack, "WinHttpAddRequestHeaders"));
|
|
if (m_pfnAddHeaders == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR, "function entry point WinHttpAddRequestHeaders not found");
|
|
goto exit;
|
|
}
|
|
|
|
fRet = TRUE;
|
|
|
|
exit:
|
|
return fRet;
|
|
}
|
|
|
|
BOOL WINHTTP_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 WinHttp Passport Authentication Service 1.4",
|
|
INTERNET_OPEN_TYPE_PRECONFIG, // ? name didn't get changed yet
|
|
NULL,
|
|
NULL,
|
|
0 /*WINHTTP_FLAG_ASYNC*/ // biaow-todo: use async
|
|
);
|
|
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 WINHTTP_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 WINHTTP_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,
|
|
"WINHTTP_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,
|
|
0);
|
|
if (hConnect == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR,
|
|
"WINHTTP_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);
|
|
if (hRequest == NULL)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR,
|
|
"WINHTTP_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,
|
|
0,
|
|
0) == FALSE)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR,
|
|
"WINHTTP_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,
|
|
"WINHTTP_SESSION::ContactPartner() failed; can not query status code");
|
|
goto exit;
|
|
}
|
|
|
|
if (dwStatus != HTTP_STATUS_REDIRECT)
|
|
{
|
|
DoTraceMessage(PP_LOG_ERROR,
|
|
"WINHTTP_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,
|
|
"WINHTTP_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
|