2012年10月8日 星期一
Use Macro to dynamically load wininet.dll
#ifndef WININETMANAGER_H
#define WININETMANAGER_H
#include <WinInet.h>
#define DECLARE_FUNCTION(functionName, resultType, callingConvention, parameterDeclarations) \
static resultType functionName parameterDeclarations ;
#define DEFINE_FUNCTION(functionName, resultType, callingConvention, parameterDeclarations, parameterNames) \
resultType WinInetManager::##functionName parameterDeclarations \
{\
resultType (callingConvention*softLink##functionName) parameterDeclarations; \
softLink##functionName = reinterpret_cast<resultType (callingConvention*) parameterDeclarations>(GetProcAddress(WinInetManager::instance().getDllHandle(), L#functionName)); \
return softLink##functionName parameterNames; \
}
namespace WebCore
{
class String;
class WinInetManager
{
public:
static WinInetManager& instance();
HRESULT freeLibrary();
const HMODULE& getDllHandle();
HRESULT setCookieCacheFolder(const String& location);
HRESULT setCookieCacheFullPath(const String& path);
HRESULT cacheReserveSize(DWORD *size);
HRESULT setCacheReserveSize(DWORD size);
~WinInetManager();
DECLARE_FUNCTION(InternetOpenUrlW,HINTERNET ,WINAPI, (HINTERNET hInternet,LPCWSTR lpszUrl,LPCWSTR lpszHeaders,DWORD dwHeadersLength,DWORD dwFlags,DWORD_PTR dwContext))
DECLARE_FUNCTION(InternetCloseHandle, BOOL, WINAPI, (HINTERNET hInternet))
DECLARE_FUNCTION(DeleteUrlCacheEntryW,BOOL,WINAPI, (LPCWSTR lpszUrlName))
DECLARE_FUNCTION(InternetSetStatusCallbackW, INTERNET_STATUS_CALLBACK, WINAPI, (HINTERNET hInternet,INTERNET_STATUS_CALLBACK lpfnInternetCallback))
DECLARE_FUNCTION(InternetGetLastResponseInfoW, BOOL, WINAPI, (LPDWORD lpdwError,LPWSTR lpszBuffer,LPDWORD lpdwBufferLength))
DECLARE_FUNCTION(InternetErrorDlg, DWORD, WINAPI, (HWND hWnd,HINTERNET hRequest,DWORD dwError,DWORD dwFlags,LPVOID * lppvData))
DECLARE_FUNCTION(InternetReadFileExA, BOOL, WINAPI, (HINTERNET hFile,LPINTERNET_BUFFERSA lpBuffersOut,DWORD dwFlags,DWORD_PTR dwContext))
DECLARE_FUNCTION(InternetWriteFile, BOOL, WINAPI, (HINTERNET hFile,LPCVOID lpBuffer,DWORD dwNumberOfBytesToWrite,LPDWORD lpdwNumberOfBytesWritten))
DECLARE_FUNCTION(InternetConnectW, HINTERNET, WINAPI, (HINTERNET hInternet,LPCWSTR lpszServerName,INTERNET_PORT nServerPort,LPCWSTR lpszUserName,LPCWSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext))
DECLARE_FUNCTION(HttpOpenRequestW, HINTERNET, WINAPI, (HINTERNET hConnect,LPCWSTR lpszVerb,LPCWSTR lpszObjectName,LPCWSTR lpszVersion,LPCWSTR lpszReferrer,LPCWSTR FAR * lplpszAcceptTypes,DWORD dwFlags,DWORD_PTR dwContext))
DECLARE_FUNCTION(HttpSendRequestExW, BOOL, WINAPI, (HINTERNET hRequest,LPINTERNET_BUFFERSW lpBuffersIn,LPINTERNET_BUFFERSW lpBuffersOut,DWORD dwFlags,DWORD_PTR dwContext))
DECLARE_FUNCTION(HttpEndRequestW, BOOL, WINAPI, (HINTERNET hRequest,LPINTERNET_BUFFERSW lpBuffersOut,DWORD dwFlags,DWORD_PTR dwContext))
DECLARE_FUNCTION(ResumeSuspendedDownload, BOOL, WINAPI, (HINTERNET hRequest,DWORD dwResultCode))
DECLARE_FUNCTION(HttpQueryInfoW, BOOL, WINAPI, (HINTERNET hRequest,DWORD dwInfoLevel,LPVOID lpBuffer,LPDWORD lpdwBufferLength,LPDWORD lpdwIndex))
DECLARE_FUNCTION(InternetOpenW, HINTERNET, WINAPI, (LPCWSTR lpszAgent,DWORD dwAccessType,LPCWSTR lpszProxy,LPCWSTR lpszProxyBypass,DWORD dwFlags))
DECLARE_FUNCTION(InternetQueryOptionW, BOOL, WINAPI, (HINTERNET hInternet,DWORD dwOption,LPVOID lpBuffer,LPDWORD lpdwBufferLength))
DECLARE_FUNCTION(InternetSetOptionW, BOOL, WINAPI, (HINTERNET hInternet,DWORD dwOption,LPVOID lpBuffer,DWORD dwBufferLength))
DECLARE_FUNCTION(InternetSetCookieW,BOOL,WINAPI, (LPCWSTR lpszUrl,LPCWSTR lpszCookieName,LPCWSTR lpszCookieData))
DECLARE_FUNCTION(InternetGetCookieW,BOOL,WINAPI, (LPCWSTR lpszUrl,LPCWSTR lpszCookieName,LPCWSTR lpszCookieData,LPDWORD lpdwSize))
DECLARE_FUNCTION(FindFirstUrlCacheEntryW,HINTERNET,WINAPI, (LPCWSTR lpszUrlSearchPattern,LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo,LPDWORD lpcbCacheEntryInfo))
DECLARE_FUNCTION(FindNextUrlCacheEntryW,BOOL,WINAPI, (HANDLE hEnumHandle,LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo,LPDWORD lpcbCacheEntryInfo))
DECLARE_FUNCTION(GetUrlCacheEntryInfoW,BOOL,WINAPI, (LPCWSTR lpszUrlName,LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,LPDWORD lpcbCacheEntryInfo))
private:
HRESULT setUserName(const String& name);
HRESULT setCookieDirectory(HKEY key, const String& dir);
HRESULT setCacheDirectory(HKEY key, const String& dir);
HRESULT setHistoryDirectory(HKEY key, const String& dir);
WinInetManager();
private:
HMODULE m_module;
};
}
#endif //WININETMANAGER_H
#include "config.h"
#include "WinInetManager.h"
#include "FileSystem.h"
#include "WTFString.h"
namespace WebCore
{
static const WCHAR* const WININET_DLL_NAME = L"wininet.dll";
static const WCHAR* const REGISTRY_SHELL_FOLDERS = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
static const WCHAR* const BASE_DIRECTORY = L"\\Windows\\Profiles\\";
static const WCHAR* const TEMP_FILE_DIRECTORY = L"\\Temporary Internet Files";
static const WCHAR* const COOKIE_DIRECTORY = L"\\Cookies";
static const WCHAR* const HISTORY_DIRECTORY = L"\\History";
static const WCHAR* const KEY_USER_NAME = L"Username";
static const WCHAR* const KEY_CACHE = L"Cache";
static const WCHAR* const KEY_COOKIE = L"Cookies";
static const WCHAR* const KEY_HISTORY = L"History";
static const WCHAR* const KEY_IDENT = L"Ident";
static const WCHAR* const REGISTRY_CACHE_CONTENT = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\5.0\\Cache\\Content";
static const WCHAR* const KEY_CACHE_LIMIT = L"CacheLimit";
static const WCHAR* const PATH_SEPARATOR = L"\\";
DEFINE_FUNCTION(InternetOpenUrlW,HINTERNET ,WINAPI, (HINTERNET hInternet,LPCWSTR lpszUrl,LPCWSTR lpszHeaders,DWORD dwHeadersLength,DWORD dwFlags,DWORD_PTR dwContext), (hInternet,lpszUrl,lpszHeaders,dwHeadersLength,dwFlags,dwContext))
DEFINE_FUNCTION(InternetCloseHandle, BOOL, WINAPI, (HINTERNET hInternet), (hInternet))
DEFINE_FUNCTION(InternetSetStatusCallbackW, INTERNET_STATUS_CALLBACK, WINAPI, (HINTERNET hInternet,INTERNET_STATUS_CALLBACK lpfnInternetCallback),(hInternet,lpfnInternetCallback))
DEFINE_FUNCTION(InternetGetLastResponseInfoW, BOOL, WINAPI, (LPDWORD lpdwError,LPWSTR lpszBuffer,LPDWORD lpdwBufferLength), (lpdwError,lpszBuffer,lpdwBufferLength))
DEFINE_FUNCTION(InternetErrorDlg, DWORD, WINAPI, (HWND hWnd,HINTERNET hRequest,DWORD dwError,DWORD dwFlags,LPVOID * lppvData), (hWnd,hRequest,dwError,dwFlags,lppvData))
DEFINE_FUNCTION(InternetReadFileExA, BOOL, WINAPI, (HINTERNET hFile,LPINTERNET_BUFFERSA lpBuffersOut,DWORD dwFlags,DWORD_PTR dwContext), (hFile,lpBuffersOut,dwFlags,dwContext))
DEFINE_FUNCTION(InternetWriteFile, BOOL, WINAPI, (HINTERNET hFile,LPCVOID lpBuffer,DWORD dwNumberOfBytesToWrite,LPDWORD lpdwNumberOfBytesWritten), (hFile,lpBuffer,dwNumberOfBytesToWrite,lpdwNumberOfBytesWritten))
DEFINE_FUNCTION(InternetConnectW, HINTERNET, WINAPI, (HINTERNET hInternet,LPCWSTR lpszServerName,INTERNET_PORT nServerPort,LPCWSTR lpszUserName,LPCWSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext), (hInternet,lpszServerName,nServerPort,lpszUserName,lpszPassword,dwService,dwFlags,dwContext))
DEFINE_FUNCTION(HttpOpenRequestW, HINTERNET, WINAPI, (HINTERNET hConnect,LPCWSTR lpszVerb,LPCWSTR lpszObjectName,LPCWSTR lpszVersion,LPCWSTR lpszReferrer,LPCWSTR FAR * lplpszAcceptTypes,DWORD dwFlags,DWORD_PTR dwContext), (hConnect,lpszVerb,lpszObjectName,lpszVersion,lpszReferrer,lplpszAcceptTypes,dwFlags,dwContext))
DEFINE_FUNCTION(HttpSendRequestExW, BOOL, WINAPI, (HINTERNET hRequest,LPINTERNET_BUFFERSW lpBuffersIn,LPINTERNET_BUFFERSW lpBuffersOut,DWORD dwFlags,DWORD_PTR dwContext), (hRequest,lpBuffersIn,lpBuffersOut,dwFlags,dwContext))
DEFINE_FUNCTION(HttpEndRequestW, BOOL, WINAPI, (HINTERNET hRequest,LPINTERNET_BUFFERSW lpBuffersOut,DWORD dwFlags,DWORD_PTR dwContext), (hRequest,lpBuffersOut,dwFlags,dwContext))
DEFINE_FUNCTION(ResumeSuspendedDownload, BOOL, WINAPI, (HINTERNET hRequest,DWORD dwResultCode),(hRequest,dwResultCode))
DEFINE_FUNCTION(HttpQueryInfoW, BOOL, WINAPI, (HINTERNET hRequest,DWORD dwInfoLevel,LPVOID lpBuffer,LPDWORD lpdwBufferLength,LPDWORD lpdwIndex),(hRequest,dwInfoLevel,lpBuffer,lpdwBufferLength,lpdwIndex))
DEFINE_FUNCTION(InternetOpenW, HINTERNET, WINAPI, (LPCWSTR lpszAgent,DWORD dwAccessType,LPCWSTR lpszProxy,LPCWSTR lpszProxyBypass,DWORD dwFlags),(lpszAgent,dwAccessType,lpszProxy,lpszProxyBypass,dwFlags))
DEFINE_FUNCTION(InternetQueryOptionW, BOOL, WINAPI, (HINTERNET hInternet,DWORD dwOption,LPVOID lpBuffer,LPDWORD lpdwBufferLength),(hInternet,dwOption,lpBuffer,lpdwBufferLength))
DEFINE_FUNCTION(InternetSetOptionW, BOOL, WINAPI, (HINTERNET hInternet,DWORD dwOption,LPVOID lpBuffer,DWORD dwBufferLength),(hInternet,dwOption,lpBuffer,dwBufferLength))
DEFINE_FUNCTION(InternetSetCookieW,BOOL,WINAPI, (LPCWSTR lpszUrl,LPCWSTR lpszCookieName,LPCWSTR lpszCookieData), (lpszUrl,lpszCookieName,lpszCookieData))
DEFINE_FUNCTION(InternetGetCookieW,BOOL,WINAPI, (LPCWSTR lpszUrl,LPCWSTR lpszCookieName,LPCWSTR lpszCookieData,LPDWORD lpdwSize), (lpszUrl,lpszCookieName,lpszCookieData,lpdwSize))
DEFINE_FUNCTION(DeleteUrlCacheEntryW,BOOL,WINAPI, (LPCWSTR lpszUrlName), (lpszUrlName))
DEFINE_FUNCTION(FindFirstUrlCacheEntryW,HINTERNET,WINAPI, (LPCWSTR lpszUrlSearchPattern,LPINTERNET_CACHE_ENTRY_INFOW lpFirstCacheEntryInfo,LPDWORD lpcbCacheEntryInfo), (lpszUrlSearchPattern,lpFirstCacheEntryInfo,lpcbCacheEntryInfo))
DEFINE_FUNCTION(FindNextUrlCacheEntryW,BOOL,WINAPI, (HANDLE hEnumHandle,LPINTERNET_CACHE_ENTRY_INFOW lpNextCacheEntryInfo,LPDWORD lpcbCacheEntryInfo), (hEnumHandle,lpNextCacheEntryInfo,lpcbCacheEntryInfo))
DEFINE_FUNCTION(GetUrlCacheEntryInfoW,BOOL,WINAPI, (LPCWSTR lpszUrlName,LPINTERNET_CACHE_ENTRY_INFOW lpCacheEntryInfo,LPDWORD lpcbCacheEntryInfo), (lpszUrlName,lpCacheEntryInfo,lpcbCacheEntryInfo))
WinInetManager::WinInetManager()
:m_module(NULL)
{
}
WinInetManager::~WinInetManager()
{
}
WinInetManager& WinInetManager::instance()
{
static WinInetManager manager;
return manager;
}
HRESULT WinInetManager::freeLibrary()
{
HMODULE hModule = ::GetModuleHandle(WININET_DLL_NAME);
///Strange! I just called the LoadLibrary("wininet.dll") one time.
///But I cann't really free the library until call the FreeLibrary three times.
int leftTimes = 20;
while (hModule != NULL && leftTimes > 0)
{
::FreeLibrary(hModule);
hModule = ::GetModuleHandle(WININET_DLL_NAME);
-- leftTimes;
}
HRESULT res = S_OK;
if (hModule != NULL)
{
DEBUGMSG(0, (L"WinInetManager::freeLibrary Failed \n"));
res = S_FALSE;
}
m_module = NULL;
return res;
}
const HMODULE& WinInetManager::getDllHandle()
{
if(NULL == m_module)
{
m_module = ::LoadLibraryW(WININET_DLL_NAME);
}
return m_module;
}
static bool makeDirectory(const String& location)
{
String path(BASE_DIRECTORY);
path.append(location);
return makeAllDirectories(path);
}
static HRESULT setStringValue(HKEY hKey, const String& key, const String& value)
{
String tempKey = key;
String tempValue = value;
int valueSize = value.length() * sizeof(TCHAR);
const BYTE* valueStr = (const BYTE*)tempValue.charactersWithNullTermination();
HRESULT result = RegSetValueEx(hKey, tempKey.charactersWithNullTermination(), 0, REG_SZ, valueStr, valueSize);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager setStringValue error \n"));
}
return result;
}
static HRESULT setIntegerValue(HKEY hKey, const String& key, const DWORD& value)
{
String tempKey = key;
HRESULT result = HRESULT_FROM_WIN32(RegSetValueEx(hKey, tempKey.charactersWithNullTermination(), 0, REG_DWORD, (BYTE*)(&value), sizeof(value)));
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager setIntegerValue error \n"));
}
return result;
}
static HRESULT integerValueForKey(HKEY hKey, const String& key, DWORD* value)
{
String tempKey = key;
DWORD dwData = 0;
DWORD dwSize = sizeof(DWORD);
HRESULT result = E_FAIL;
if(ERROR_SUCCESS == RegQueryValueEx(hKey, tempKey.charactersWithNullTermination(), NULL, NULL, (BYTE*)(&dwData), &dwSize))
{
*value = dwData;
result = S_OK;
}
else
DEBUGMSG(result, (L"WinInetManager integerValueForKey error \n"));
return result;
}
HRESULT WinInetManager::setCookieCacheFolder(const String& location)
{
if (!makeDirectory(location))
{
DEBUGMSG(0, (L"WinInetManager::setCookieCacheFolder makeDirectory error \n"));
return E_INVALIDARG;
}
LONG result = setUserName(location);
if(FAILED(result))
{
DEBUGMSG(0, (L"WinInetManager::setCookieCacheFolder setUserName error \n"));
return result;
}
HKEY hKey = NULL;
result = RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_SHELL_FOLDERS, 0, KEY_WRITE, &hKey);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setCookieCacheFolder RegOpenKeyEx error \n"));
return result;
}
result = setCacheDirectory(hKey, location);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setCookieCacheFolder setCacheDirectory error \n"));
return result;
}
result = setCookieDirectory(hKey, location);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setCookieCacheFolder setCookieDirectory error \n"));
return result;
}
result = setHistoryDirectory(hKey, location);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setCookieCacheFolder setHistoryDirectory error \n"));
return result;
}
return RegCloseKey(hKey);
}
static HRESULT setDirectoryValue(HKEY hKey, const String& key, const String& basePath, const String& subPath)
{
if(basePath.endsWith(PATH_SEPARATOR))
{
return S_FALSE;
}
return setStringValue(hKey, key, basePath + subPath);
}
HRESULT WinInetManager::setCookieCacheFullPath(const String& path)
{
if (!makeAllDirectories(path))
{
DEBUGMSG(1, (L"WinInetManager::setCookieCacheFullPath makeAllDirectories error \n"));
return E_FAIL;
}
HKEY hKey = NULL;
LONG result = RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_SHELL_FOLDERS, 0, KEY_WRITE, &hKey);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setCookieCacheFullPath RegOpenKeyEx error \n"));
return result;
}
result = setDirectoryValue(hKey, KEY_CACHE, path, TEMP_FILE_DIRECTORY);
if(FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setDirectoryValue TEMP_FILE_DIRECTORY error \n"));
goto FAIL;
}
result = setDirectoryValue(hKey, KEY_COOKIE, path, COOKIE_DIRECTORY);
if(FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setDirectoryValue COOKIE_DIRECTORY error \n"));
goto FAIL;
}
result = setDirectoryValue(hKey, KEY_HISTORY, path, HISTORY_DIRECTORY);
if(FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setDirectoryValue HISTORY_DIRECTORY error \n"));
goto FAIL;
}
FAIL:
RegCloseKey(hKey);
return result;
}
HRESULT WinInetManager::setUserName(const String& name)
{
HKEY hKey;
HRESULT result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KEY_IDENT, 0, KEY_WRITE, &hKey);
if(FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setUserName RegOpenKeyEx error \n"));
return result;
}
String key(KEY_USER_NAME);
if (FAILED(setStringValue(hKey, key, name)))
{
DEBUGMSG(result, (L"WinInetManager::setUserName setStringValue error \n"));
return result;
}
return RegCloseKey(hKey);
}
HRESULT WinInetManager::setCacheDirectory(HKEY hKey, const String& location)
{
// change Cache directory
String value(BASE_DIRECTORY);
value = value + location + TEMP_FILE_DIRECTORY;
return setStringValue(hKey, KEY_CACHE, value);
}
HRESULT WinInetManager::setCookieDirectory(HKEY hKey, const String& location)
{
// change cookies directory
String value(BASE_DIRECTORY);
value = value + location + COOKIE_DIRECTORY;
return setStringValue(hKey, KEY_COOKIE, value);
}
HRESULT WinInetManager::setHistoryDirectory(HKEY hKey, const String& location)
{
// change history directory
String value(BASE_DIRECTORY);
value = value + location + HISTORY_DIRECTORY;
return setStringValue(hKey, KEY_HISTORY, value);
}
HRESULT WinInetManager::cacheReserveSize(DWORD *size)
{
HKEY hKey = NULL;
HRESULT result = E_FAIL;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_CACHE_CONTENT, 0, KEY_READ, &hKey))
{
DEBUGMSG(result, (L"WinInetManager::cacheReserveSize RegOpenKeyEx error \n"));
return result;
}
String key(KEY_CACHE_LIMIT);
DWORD regSize = 0;
result = integerValueForKey(hKey, key, ®Size);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::cacheReserveSize integerValueForKey error \n"));
*size = 0;
}
else
*size = regSize * 1024;
RegCloseKey(hKey);
return S_OK;
}
HRESULT WinInetManager::setCacheReserveSize(DWORD size)
{
HKEY hKey = NULL;
HRESULT result = E_FAIL;
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, REGISTRY_CACHE_CONTENT, 0, KEY_WRITE, &hKey))
{
DEBUGMSG(result, (L"WinInetManager::setCacheReserveSize RegOpenKeyEx error \n"));
return result;
}
String key(KEY_CACHE_LIMIT);
result = setIntegerValue(hKey, key, size/1024);
if (FAILED(result))
{
DEBUGMSG(result, (L"WinInetManager::setCacheReserveSize setIntegerValue error \n"));
}
RegCloseKey(hKey);
return result;
}
}
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言