3200 lines
98 KiB
C++
3200 lines
98 KiB
C++
/*++
|
||
|
||
Copyright (c) 1994-98 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
options.cxx
|
||
|
||
Abstract:
|
||
|
||
Contains the Internet*Option APIs
|
||
|
||
Contents:
|
||
InternetQueryOptionA
|
||
InternetSetOptionA
|
||
InternetSetOptionExA
|
||
InternetQueryOptionW
|
||
InternetSetOptionW
|
||
InternetSetOptionExW
|
||
(FValidCacheHandleType)
|
||
|
||
Author:
|
||
|
||
Richard L Firth (rfirth) 02-Mar-1995
|
||
|
||
Environment:
|
||
|
||
Win32 user-mode DLL
|
||
|
||
Revision History:
|
||
|
||
02-Mar-1995 rfirth
|
||
Created
|
||
|
||
07-Mar-1995 madana
|
||
|
||
07-Jul-1998 Forked by akabir
|
||
|
||
--*/
|
||
|
||
#include <wininetp.h>
|
||
#include <perfdiag.hxx>
|
||
#include "inetapiu.h"
|
||
#include "autodial.h"
|
||
#include "msident.h"
|
||
#include "secinit.h"
|
||
|
||
|
||
extern HANDLE g_hDialEvent;
|
||
|
||
//
|
||
// private macros
|
||
//
|
||
|
||
//
|
||
// IS_PER_THREAD_OPTION - options applicable to the thread (HINTERNET is NULL).
|
||
// Subset of IS_VALID_OPTION()
|
||
//
|
||
|
||
//#define IS_PER_THREAD_OPTION(option) \
|
||
// (( ((option) == INTERNET_OPTION_SERVER_ERROR_CALLBACK) \
|
||
// || ((option) == INTERNET_OPTION_ASYNC_ID) \
|
||
// || ((option) == INTERNET_OPTION_EXTENDED_ERROR) \
|
||
// ) ? TRUE : FALSE)
|
||
|
||
#define IS_PER_THREAD_OPTION(option) \
|
||
(( ((option) == INTERNET_OPTION_ASYNC_ID) \
|
||
|| ((option) == INTERNET_OPTION_EXTENDED_ERROR) \
|
||
|| ((option) == INTERNET_OPTION_PER_CONNECTION_OPTION) \
|
||
) ? TRUE : FALSE)
|
||
|
||
//
|
||
// IS_PER_PROCESS_OPTION - options applicable to the process (HINTERNET is NULL).
|
||
// Subset of IS_VALID_OPTION()
|
||
//
|
||
|
||
#define IS_PER_PROCESS_OPTION(option) \
|
||
(( ((option) == INTERNET_OPTION_GET_DEBUG_INFO) \
|
||
|| ((option) == INTERNET_OPTION_SET_DEBUG_INFO) \
|
||
|| ((option) == INTERNET_OPTION_GET_HANDLE_COUNT) \
|
||
|| ((option) == INTERNET_OPTION_CONNECT_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_CONNECT_RETRIES) \
|
||
|| ((option) == INTERNET_OPTION_CONNECT_BACKOFF) \
|
||
|| ((option) == INTERNET_OPTION_SEND_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_RECEIVE_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_DATA_SEND_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_DATA_RECEIVE_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_FROM_CACHE_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_REFRESH) \
|
||
|| ((option) == INTERNET_OPTION_PROXY) \
|
||
|| ((option) == INTERNET_OPTION_SETTINGS_CHANGED) \
|
||
|| ((option) == INTERNET_OPTION_PROXY_SETTINGS_CHANGED) \
|
||
|| ((option) == INTERNET_OPTION_VERSION) \
|
||
|| ((option) == INTERNET_OPTION_END_BROWSER_SESSION) \
|
||
|| ((option) == INTERNET_OPTION_RESET_URLCACHE_SESSION) \
|
||
|| ((option) == INTERNET_OPTION_OFFLINE_TIMEOUT) \
|
||
|| ((option) == INTERNET_OPTION_LINE_STATE) \
|
||
|| ((option) == INTERNET_OPTION_IDLE_STATE) \
|
||
|| ((option) == INTERNET_OPTION_OFFLINE_SEMANTICS) \
|
||
|| ((option) == INTERNET_OPTION_HTTP_VERSION) \
|
||
|| ((option) == INTERNET_OPTION_BYPASS_EDITED_ENTRY) \
|
||
|| ((option) == INTERNET_OPTION_MAX_CONNS_PER_SERVER) \
|
||
|| ((option) == INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER) \
|
||
|| ((option) == INTERNET_OPTION_DIGEST_AUTH_UNLOAD) \
|
||
|| ((option) == INTERNET_OPTION_IDENTITY) \
|
||
|| ((option) == INTERNET_OPTION_REMOVE_IDENTITY) \
|
||
|| ((option) == INTERNET_OPTION_ALTER_IDENTITY) \
|
||
|| ((option) == INTERNET_OPTION_SUPPRESS_BEHAVIOR) \
|
||
|| ((option) == INTERNET_OPTION_PER_CONNECTION_OPTION) \
|
||
|| ((option) == INTERNET_OPTION_AUTODIAL_CONNECTION) \
|
||
|| ((option) == INTERNET_OPTION_AUTODIAL_MODE) \
|
||
|| ((option) == INTERNET_OPTION_USERNAME) \
|
||
|| ((option) == INTERNET_OPTION_PASSWORD) \
|
||
|| ((option) == INTERNET_OPTION_HIBERNATE_INACTIVE_WORKER_THREADS) \
|
||
|| ((option) == INTERNET_OPTION_ACTIVATE_WORKER_THREADS) \
|
||
|| ((option) == INTERNET_OPTION_RESTORE_WORKER_THREAD_DEFAULTS) \
|
||
) ? TRUE : FALSE)
|
||
|
||
//
|
||
// IS_DEBUG_OPTION - the set of debug-specific options
|
||
//
|
||
|
||
#define IS_DEBUG_OPTION(option) \
|
||
(( ((option) >= INTERNET_FIRST_DEBUG_OPTION) \
|
||
&& ((option) <= INTERNET_LAST_DEBUG_OPTION) \
|
||
) ? TRUE : FALSE)
|
||
|
||
//
|
||
// IS_VALID_OPTION - the set of known option values, for a HINTERNET, thread, or
|
||
// process. In the retail version, debug options are invalid
|
||
//
|
||
|
||
#if INET_DEBUG
|
||
|
||
#define IS_VALID_OPTION(option) \
|
||
(((((option) >= INTERNET_FIRST_OPTION) \
|
||
&& ((option) <= INTERNET_LAST_OPTION_INTERNAL)) \
|
||
|| IS_DEBUG_OPTION(option) \
|
||
) ? TRUE : FALSE)
|
||
|
||
#else
|
||
|
||
#define IS_VALID_OPTION(option) \
|
||
(((((option) >= INTERNET_FIRST_OPTION) \
|
||
&& ((option) <= INTERNET_LAST_OPTION_INTERNAL)) \
|
||
) ? TRUE : FALSE)
|
||
|
||
#endif // INET_DEBUG
|
||
|
||
//
|
||
// IS_CONNECT_HANDLE_TYPE - TRUE if handle type contains INTERNET_CONNECT_HANDLE_OBJECT
|
||
//
|
||
|
||
#define IS_CONNECT_HANDLE_TYPE(handleType) \
|
||
((handleType == TypeHttpRequestHandle) \
|
||
|| (handleType == TypeHttpConnectHandle) \
|
||
|| (handleType == TypeFtpConnectHandle) \
|
||
|| (handleType == TypeFtpFileHandle) \
|
||
|| (handleType == TypeFtpFindHandle) \
|
||
|| (handleType == TypeFtpFileHandleHtml) \
|
||
|| (handleType == TypeFtpFindHandleHtml) \
|
||
|| (handleType == TypeGopherConnectHandle) \
|
||
|| (handleType == TypeGopherFileHandle) \
|
||
|| (handleType == TypeGopherFindHandle) \
|
||
|| (handleType == TypeGopherFileHandleHtml) \
|
||
|| (handleType == TypeGopherFindHandleHtml))
|
||
|
||
//
|
||
// private prototypes
|
||
//
|
||
|
||
PRIVATE
|
||
BOOL
|
||
FValidCacheHandleType(
|
||
HINTERNET_HANDLE_TYPE hType
|
||
);
|
||
|
||
PRIVATE
|
||
VOID
|
||
InitIPCOList(LPINTERNET_PER_CONN_OPTION_LISTW plistW, LPINTERNET_PER_CONN_OPTION_LISTA plistA)
|
||
{
|
||
plistA->dwSize = sizeof(INTERNET_PER_CONN_OPTION_LISTA);
|
||
plistA->dwOptionCount = plistW->dwOptionCount;
|
||
if (plistW->pszConnection && *plistW->pszConnection)
|
||
{
|
||
SHUnicodeToAnsi(plistW->pszConnection, plistA->pszConnection, RAS_MaxEntryName + 1);
|
||
}
|
||
else
|
||
{
|
||
plistA->pszConnection = NULL;
|
||
}
|
||
}
|
||
|
||
//
|
||
// functions
|
||
//
|
||
|
||
|
||
INTERNETAPI_(BOOL) InternetQueryOptionA(
|
||
IN HINTERNET hInternet OPTIONAL,
|
||
IN DWORD dwOption,
|
||
OUT LPVOID lpBuffer OPTIONAL,
|
||
IN OUT LPDWORD lpdwBufferLength
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Returns information about various handle-specific variables
|
||
|
||
Arguments:
|
||
|
||
hInternet - handle of object for which information will be
|
||
returned
|
||
|
||
dwOption - the handle-specific INTERNET_OPTION to query
|
||
|
||
lpBuffer - pointer to a buffer which will receive results
|
||
|
||
lpdwBufferLength - IN: number of bytes available in lpBuffer
|
||
OUT: number of bytes returned in lpBuffer
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
Success - TRUE
|
||
|
||
Failure - FALSE. Call GetLastError() for more info:
|
||
ERROR_INVALID_HANDLE
|
||
hInternet does not identify a valid Internet handle
|
||
object
|
||
|
||
ERROR_INTERNET_INTERNAL_ERROR
|
||
Shouldn't see this?
|
||
|
||
ERROR_INVALID_PARAMETER
|
||
One of the parameters was bad
|
||
|
||
ERROR_INSUFFICIENT_BUFFER
|
||
lpBuffer is not large enough to hold the requested
|
||
information; *lpdwBufferLength contains the number of
|
||
bytes needed
|
||
|
||
ERROR_INTERNET_INCORRECT_HANDLE_TYPE
|
||
The handle is the wrong type for the requested option
|
||
|
||
ERROR_INTERNET_INVALID_OPTION
|
||
The option is unrecognized
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER_API((DBG_API,
|
||
Bool,
|
||
"InternetQueryOptionA",
|
||
"%#x, %s (%d), %#x, %#x [%d]",
|
||
hInternet,
|
||
InternetMapOption(dwOption),
|
||
dwOption,
|
||
lpBuffer,
|
||
lpdwBufferLength,
|
||
lpdwBufferLength
|
||
? (!IsBadReadPtr(lpdwBufferLength, sizeof(DWORD))
|
||
? *lpdwBufferLength
|
||
: 0)
|
||
: 0
|
||
));
|
||
|
||
DWORD error;
|
||
BOOL success;
|
||
HINTERNET_HANDLE_TYPE handleType;
|
||
LPINTERNET_THREAD_INFO lpThreadInfo;
|
||
DWORD requiredSize = 0;
|
||
LPVOID lpSource;
|
||
DWORD dwValue;
|
||
DWORD_PTR dwPtrValue;
|
||
HANDLE hValue;
|
||
HINTERNET hObjectMapped = NULL;
|
||
INTERNET_CONNECT_HANDLE_OBJECT * lphRequest;
|
||
BOOL isString = FALSE;
|
||
INTERNET_DIAGNOSTIC_SOCKET_INFO socketInfo;
|
||
|
||
if (!GlobalDataInitialized) {
|
||
error = GlobalDataInitialize();
|
||
if (error != ERROR_SUCCESS) {
|
||
goto done;
|
||
}
|
||
}
|
||
|
||
lpThreadInfo = InternetGetThreadInfo();
|
||
if (lpThreadInfo == NULL) {
|
||
error = ERROR_INTERNET_INTERNAL_ERROR;
|
||
goto done;
|
||
}
|
||
|
||
//
|
||
// validate parameters
|
||
//
|
||
|
||
if (!ARGUMENT_PRESENT(lpdwBufferLength)) {
|
||
error = ERROR_INVALID_PARAMETER;
|
||
goto done;
|
||
}
|
||
|
||
if (!ARGUMENT_PRESENT(lpBuffer)) {
|
||
*lpdwBufferLength = 0;
|
||
}
|
||
|
||
//
|
||
// validate the handle and get its type
|
||
//
|
||
|
||
HINTERNET hOriginal;
|
||
|
||
hOriginal = hInternet;
|
||
if (ARGUMENT_PRESENT(hInternet)) {
|
||
|
||
//
|
||
// map the handle
|
||
//
|
||
|
||
error = MapHandleToAddress(hInternet, (LPVOID *)&hInternet, FALSE);
|
||
if (error == ERROR_SUCCESS) {
|
||
hObjectMapped = hInternet;
|
||
lphRequest = (INTERNET_CONNECT_HANDLE_OBJECT *)hInternet;
|
||
error = RGetHandleType(hInternet, &handleType);
|
||
}
|
||
} else if (IS_PER_THREAD_OPTION(dwOption)) {
|
||
|
||
//
|
||
// this option updates the per-thread information block, so this is a
|
||
// good point at which to get it
|
||
//
|
||
|
||
if (lpThreadInfo != NULL) {
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
|
||
DEBUG_PRINT(INET,
|
||
ERROR,
|
||
("InternetGetThreadInfo() returns NULL\n"
|
||
));
|
||
|
||
//
|
||
// we never expect this - ERROR_INTERNET_SPANISH_INQUISITION
|
||
//
|
||
|
||
INET_ASSERT(FALSE);
|
||
|
||
error = ERROR_INTERNET_INTERNAL_ERROR;
|
||
}
|
||
} else if (IS_PER_PROCESS_OPTION(dwOption)) {
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
|
||
//
|
||
// catch any invalid options for the NULL handle. If the option is valid
|
||
// then it is incorrect for this handle type, otherwise its an invalid
|
||
// option, period
|
||
//
|
||
|
||
error = IS_VALID_OPTION(dwOption)
|
||
? ERROR_INTERNET_INCORRECT_HANDLE_TYPE
|
||
: ERROR_INTERNET_INVALID_OPTION
|
||
;
|
||
}
|
||
|
||
//
|
||
// if the option and handle combination is valid then query the option value
|
||
//
|
||
|
||
if (error != ERROR_SUCCESS) {
|
||
goto quit;
|
||
}
|
||
switch (dwOption) {
|
||
case INTERNET_OPTION_CALLBACK:
|
||
requiredSize = sizeof(INTERNET_STATUS_CALLBACK);
|
||
if (hInternet != NULL) {
|
||
error = RGetStatusCallback(hInternet,
|
||
(LPINTERNET_STATUS_CALLBACK)&dwValue
|
||
);
|
||
lpSource = (LPVOID)&dwValue;
|
||
} else {
|
||
error = ERROR_INVALID_HANDLE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_CONNECT_TIMEOUT:
|
||
case INTERNET_OPTION_CONNECT_RETRIES:
|
||
case INTERNET_OPTION_CONNECT_BACKOFF:
|
||
case INTERNET_OPTION_SEND_TIMEOUT:
|
||
case INTERNET_OPTION_RECEIVE_TIMEOUT:
|
||
case INTERNET_OPTION_DATA_SEND_TIMEOUT:
|
||
case INTERNET_OPTION_DATA_RECEIVE_TIMEOUT:
|
||
case INTERNET_OPTION_FROM_CACHE_TIMEOUT:
|
||
requiredSize = sizeof(DWORD);
|
||
|
||
//
|
||
// remember hInternet in the INTERNET_THREAD_INFO then call
|
||
// GetTimeoutValue(). If hInternet refers to a valid Internet
|
||
// object handle, then the relevant timeout value will be
|
||
// returned from that, else we will return the global value
|
||
// corresponding to the requested option
|
||
//
|
||
|
||
InternetSetObjectHandle(hOriginal, hInternet);
|
||
dwValue = GetTimeoutValue(dwOption);
|
||
lpSource = (LPVOID)&dwValue;
|
||
break;
|
||
|
||
case INTERNET_OPTION_HANDLE_TYPE:
|
||
requiredSize = sizeof(dwValue);
|
||
switch (handleType) {
|
||
case TypeInternetHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_INTERNET;
|
||
break;
|
||
|
||
case TypeFtpConnectHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_CONNECT_FTP;
|
||
break;
|
||
|
||
case TypeFtpFindHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_FTP_FIND;
|
||
break;
|
||
|
||
case TypeFtpFindHandleHtml:
|
||
dwValue = INTERNET_HANDLE_TYPE_FTP_FIND_HTML;
|
||
break;
|
||
|
||
case TypeFtpFileHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_FTP_FILE;
|
||
break;
|
||
|
||
case TypeFtpFileHandleHtml:
|
||
dwValue = INTERNET_HANDLE_TYPE_FTP_FILE_HTML;
|
||
break;
|
||
|
||
case TypeGopherConnectHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_CONNECT_GOPHER;
|
||
break;
|
||
|
||
case TypeGopherFindHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_GOPHER_FIND;
|
||
break;
|
||
|
||
case TypeGopherFindHandleHtml:
|
||
dwValue = INTERNET_HANDLE_TYPE_GOPHER_FIND_HTML;
|
||
break;
|
||
|
||
case TypeGopherFileHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_GOPHER_FILE;
|
||
break;
|
||
|
||
case TypeGopherFileHandleHtml:
|
||
dwValue = INTERNET_HANDLE_TYPE_GOPHER_FILE_HTML;
|
||
break;
|
||
|
||
case TypeHttpConnectHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_CONNECT_HTTP;
|
||
break;
|
||
|
||
case TypeHttpRequestHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_HTTP_REQUEST;
|
||
break;
|
||
|
||
case TypeFileRequestHandle:
|
||
dwValue = INTERNET_HANDLE_TYPE_FILE_REQUEST;
|
||
break;
|
||
|
||
default:
|
||
error = ERROR_INTERNET_INTERNAL_ERROR;
|
||
break;
|
||
}
|
||
lpSource = (LPVOID)&dwValue;
|
||
break;
|
||
|
||
case INTERNET_OPTION_CONTEXT_VALUE:
|
||
case INTERNET_OPTION_CONTEXT_VALUE_OLD: // see InternetSetOption
|
||
requiredSize = sizeof(DWORD_PTR);
|
||
error = RGetContext(hInternet, &dwPtrValue);
|
||
lpSource = (LPVOID)&dwPtrValue;
|
||
break;
|
||
|
||
//case INTERNET_OPTION_NAME_RES_THREAD:
|
||
// requiredSize = sizeof(BOOL);
|
||
// lpSource = (LPVOID)&MultiThreadedNameResolution;
|
||
// break;
|
||
|
||
case INTERNET_OPTION_READ_BUFFER_SIZE:
|
||
case INTERNET_OPTION_WRITE_BUFFER_SIZE:
|
||
if (IS_CONNECT_HANDLE_TYPE(handleType)) {
|
||
requiredSize = sizeof(DWORD);
|
||
error = RGetBufferSize(hInternet, dwOption, &dwValue);
|
||
lpSource = (LPVOID)&dwValue;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
//case INTERNET_OPTION_GATEWAY_NAME:
|
||
// error = ERROR_CALL_NOT_IMPLEMENTED;
|
||
// break;
|
||
|
||
case INTERNET_OPTION_ASYNC_ID:
|
||
error = ERROR_CALL_NOT_IMPLEMENTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_ASYNC_PRIORITY:
|
||
error = ERROR_CALL_NOT_IMPLEMENTED;
|
||
break;
|
||
|
||
//case INTERNET_OPTION_ASYNC_REQUEST_COUNT:
|
||
// requiredSize = sizeof(dwValue);
|
||
// error = RGetAsyncRequestCount(hInternet, &dwValue);
|
||
// lpSource = (LPVOID)&dwValue;
|
||
// break;
|
||
|
||
case INTERNET_OPTION_PARENT_HANDLE:
|
||
hInternet = ((HANDLE_OBJECT *)hInternet)->GetParent();
|
||
if (hInternet != NULL) {
|
||
hInternet = ((HANDLE_OBJECT *)hInternet)->GetPseudoHandle();
|
||
}
|
||
requiredSize = sizeof(hInternet);
|
||
lpSource = (LPVOID)&hInternet;
|
||
break;
|
||
|
||
case INTERNET_OPTION_KEEP_CONNECTION:
|
||
if (handleType == TypeHttpConnectHandle) {
|
||
requiredSize = sizeof(BOOL);
|
||
|
||
//
|
||
// we return TRUE or FALSE based on whether the connect
|
||
// object believes the server supports Keep-Alive
|
||
//
|
||
|
||
//dwValue = RGetKeepAliveState(hInternet);
|
||
lpSource = (LPVOID)&dwValue;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_REQUEST_FLAGS:
|
||
requiredSize = sizeof(dwValue);
|
||
if (FValidCacheHandleType(handleType)) {
|
||
dwValue = 0;
|
||
if (lphRequest->IsFromCache()) {
|
||
dwValue |= INTERNET_REQFLAG_FROM_CACHE;
|
||
if (lphRequest->IsNetFailed()) {
|
||
dwValue |= INTERNET_REQFLAG_NET_TIMEOUT;
|
||
}
|
||
}
|
||
if (lphRequest->IsViaProxy()) {
|
||
dwValue |= INTERNET_REQFLAG_VIA_PROXY;
|
||
}
|
||
if (lphRequest->IsNoHeaders()) {
|
||
dwValue |= INTERNET_REQFLAG_NO_HEADERS;
|
||
}
|
||
if (lphRequest->IsCacheWriteDisabled()) {
|
||
dwValue |= INTERNET_REQFLAG_CACHE_WRITE_DISABLED;
|
||
}
|
||
lpSource = (LPVOID)&dwValue;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_EXTENDED_ERROR:
|
||
requiredSize = sizeof(lpThreadInfo->dwMappedErrorCode);
|
||
lpSource = (LPVOID)&lpThreadInfo->dwMappedErrorCode;
|
||
break;
|
||
|
||
case INTERNET_OPTION_OFFLINE_MODE:
|
||
error = ERROR_CALL_NOT_IMPLEMENTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_CACHE_STREAM_HANDLE:
|
||
requiredSize = sizeof(HANDLE);
|
||
if (FValidCacheHandleType(handleType)) {
|
||
error = lphRequest->GetCacheStream((LPBYTE)&hValue,
|
||
sizeof(hValue)
|
||
);
|
||
lpSource = (LPVOID)&hValue;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
BOOL fUser, fProxy;
|
||
|
||
case INTERNET_OPTION_USERNAME:
|
||
fUser = IS_USER;
|
||
fProxy = IS_SERVER;
|
||
goto callGetUserOrPass;
|
||
|
||
case INTERNET_OPTION_PASSWORD:
|
||
fUser = IS_PASS;
|
||
fProxy = IS_SERVER;
|
||
goto callGetUserOrPass;
|
||
|
||
case INTERNET_OPTION_PROXY_USERNAME:
|
||
fUser = IS_USER;
|
||
fProxy = IS_PROXY;
|
||
goto callGetUserOrPass;
|
||
|
||
case INTERNET_OPTION_PROXY_PASSWORD:
|
||
fUser = IS_PASS;
|
||
fProxy = IS_PROXY;
|
||
goto callGetUserOrPass;
|
||
|
||
callGetUserOrPass:
|
||
|
||
if (hInternet && (handleType != TypeInternetHandle)
|
||
&& (handleType != TypeFileRequestHandle)) {
|
||
lpSource = lphRequest->GetUserOrPass(fUser, fProxy);
|
||
isString = TRUE;
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
|
||
case INTERNET_OPTION_ASYNC:
|
||
error = ERROR_CALL_NOT_IMPLEMENTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_IDENTITY:
|
||
lpSource = (LPVOID)&GlobalIdentityGuid;
|
||
requiredSize = sizeof(GlobalIdentityGuid);
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECURITY_FLAGS:
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else
|
||
{
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
|
||
requiredSize = sizeof(dwValue);
|
||
dwValue = 0;
|
||
lpSource = (LPVOID)&dwValue;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
|
||
dwValue = lphHttpRqst->GetSecureFlags();
|
||
|
||
DEBUG_PRINT(INET,
|
||
INFO,
|
||
("SECURITY_FLAGS: %X\n",
|
||
dwValue
|
||
));
|
||
|
||
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case INTERNET_OPTION_DATAFILE_NAME:
|
||
if ((handleType == TypeHttpRequestHandle)
|
||
|| (handleType == TypeFtpFindHandle)
|
||
|| (handleType == TypeFtpFindHandleHtml)
|
||
|| (handleType == TypeFtpFileHandle)
|
||
|| (handleType == TypeFtpFileHandleHtml)
|
||
|| (handleType == TypeGopherFindHandle)
|
||
|| (handleType == TypeGopherFindHandleHtml)
|
||
|| (handleType == TypeGopherFileHandle)
|
||
|| (handleType == TypeGopherFileHandleHtml)
|
||
|| (handleType == TypeFileRequestHandle )) {
|
||
|
||
//
|
||
// DATAFILE_NAME is slightly different from the other string
|
||
// options: if the name is not present then we return an error
|
||
// to the effect that we couldn't find it. The others just
|
||
// return an empty string
|
||
//
|
||
|
||
if ( handleType != TypeFileRequestHandle ) {
|
||
lpSource = lphRequest->GetDataFileName();
|
||
}
|
||
else {
|
||
lpSource =
|
||
((INTERNET_FILE_HANDLE_OBJECT *)lphRequest)->GetDataFileName();
|
||
}
|
||
|
||
if (lpSource != NULL) {
|
||
isString = TRUE;
|
||
|
||
INET_ASSERT(error == ERROR_SUCCESS);
|
||
|
||
} else {
|
||
error = ERROR_INTERNET_ITEM_NOT_FOUND;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_URL:
|
||
|
||
//
|
||
// return the URL associated with the request handle. This may be
|
||
// different from the original URL due to redirections
|
||
//
|
||
|
||
if ((handleType == TypeHttpRequestHandle)
|
||
|| (handleType == TypeFtpFindHandle)
|
||
|| (handleType == TypeFtpFindHandleHtml)
|
||
|| (handleType == TypeFtpFileHandle)
|
||
|| (handleType == TypeFtpFileHandleHtml)
|
||
|| (handleType == TypeGopherFindHandle)
|
||
|| (handleType == TypeGopherFindHandleHtml)
|
||
|| (handleType == TypeGopherFileHandle)
|
||
|| (handleType == TypeGopherFileHandleHtml)) {
|
||
|
||
//
|
||
// only these handle types (retrieved object handles) can have
|
||
// associated URLs
|
||
//
|
||
|
||
lpSource = lphRequest->GetURL();
|
||
isString = TRUE;
|
||
|
||
INET_ASSERT(error == ERROR_SUCCESS);
|
||
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
case INTERNET_OPTION_SECURITY_CERTIFICATE:
|
||
|
||
if (handleType != TypeHttpRequestHandle) {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
} else {
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
INTERNET_SECURITY_INFO siInfo;
|
||
INTERNET_CERTIFICATE_INFO ciInfo;
|
||
DWORD dwciInfoSize = sizeof(INTERNET_CERTIFICATE_INFO);
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
|
||
if (ERROR_SUCCESS == lphHttpRqst->GetSecurityInfo(&siInfo))
|
||
{
|
||
error = ConvertSecurityInfoIntoCertInfoStruct(&siInfo, &ciInfo, &dwciInfoSize);
|
||
if(siInfo.pCertificate)
|
||
{
|
||
CertFreeCertificateContext(siInfo.pCertificate);
|
||
}
|
||
|
||
if ( error == ERROR_SUCCESS )
|
||
{
|
||
LPTSTR szResult = NULL;
|
||
DWORD cchNeedLen = 0;
|
||
|
||
|
||
szResult = FormatCertInfo(
|
||
&ciInfo
|
||
);
|
||
|
||
if (NULL == szResult)
|
||
{
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
goto secOptEnd;
|
||
}
|
||
|
||
cchNeedLen = lstrlen(szResult) + 1;
|
||
if (*lpdwBufferLength < cchNeedLen)
|
||
{
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
goto secOptEnd;
|
||
}
|
||
|
||
if (ARGUMENT_PRESENT(lpBuffer))
|
||
{
|
||
memcpy(
|
||
lpBuffer,
|
||
szResult,
|
||
(cchNeedLen) * sizeof(TCHAR));
|
||
cchNeedLen--;
|
||
}
|
||
|
||
secOptEnd:
|
||
if (NULL != szResult) {
|
||
FREE_MEMORY(szResult);
|
||
}
|
||
if (NULL != ciInfo.lpszSubjectInfo) {
|
||
LocalFree(ciInfo.lpszSubjectInfo);
|
||
}
|
||
if (NULL != ciInfo.lpszIssuerInfo) {
|
||
LocalFree(ciInfo.lpszIssuerInfo);
|
||
}
|
||
if (NULL != ciInfo.lpszSignatureAlgName) {
|
||
LocalFree(ciInfo.lpszSignatureAlgName);
|
||
}
|
||
if (NULL != ciInfo.lpszEncryptionAlgName) {
|
||
LocalFree(ciInfo.lpszEncryptionAlgName);
|
||
}
|
||
if (NULL != ciInfo.lpszProtocolName) {
|
||
LocalFree(ciInfo.lpszProtocolName);
|
||
}
|
||
|
||
*lpdwBufferLength = cchNeedLen;
|
||
requiredSize = *lpdwBufferLength;
|
||
}
|
||
|
||
goto quit;
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECURITY_CONNECTION_INFO:
|
||
//
|
||
// Caller is expected to pass in an INTERNET_SECURITY_CONNECTION_INFO structure.
|
||
|
||
if (handleType != TypeHttpRequestHandle) {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
} else if (*lpdwBufferLength < (DWORD)sizeof(INTERNET_SECURITY_CONNECTION_INFO)) {
|
||
requiredSize = sizeof(INTERNET_SECURITY_CONNECTION_INFO);
|
||
*lpdwBufferLength = requiredSize;
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
} else {
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
LPINTERNET_SECURITY_CONNECTION_INFO lpSecConnInfo;
|
||
INTERNET_SECURITY_INFO ciInfo;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *)hInternet;
|
||
lpSecConnInfo = (LPINTERNET_SECURITY_CONNECTION_INFO)lpBuffer;
|
||
requiredSize = sizeof(INTERNET_SECURITY_CONNECTION_INFO);
|
||
|
||
if ((error = lphHttpRqst->GetSecurityInfo(&ciInfo)) == ERROR_SUCCESS) {
|
||
// Set up that data members in the structure passed in.
|
||
lpSecConnInfo->fSecure = TRUE;
|
||
|
||
lpSecConnInfo->dwProtocol = ciInfo.dwProtocol;
|
||
lpSecConnInfo->aiCipher = ciInfo.aiCipher;
|
||
lpSecConnInfo->dwCipherStrength = ciInfo.dwCipherStrength;
|
||
lpSecConnInfo->aiHash = ciInfo.aiHash;
|
||
lpSecConnInfo->dwHashStrength = ciInfo.dwHashStrength;
|
||
lpSecConnInfo->aiExch = ciInfo.aiExch;
|
||
lpSecConnInfo->dwExchStrength = ciInfo.dwExchStrength;
|
||
|
||
if (ciInfo.pCertificate)
|
||
{
|
||
CertFreeCertificateContext(ciInfo.pCertificate);
|
||
}
|
||
|
||
} else if (error == ERROR_INTERNET_INTERNAL_ERROR) {
|
||
// This implies we are not secure.
|
||
error = ERROR_SUCCESS;
|
||
lpSecConnInfo->fSecure = FALSE;
|
||
}
|
||
|
||
lpSecConnInfo->dwSize = requiredSize;
|
||
*lpdwBufferLength = requiredSize;
|
||
}
|
||
|
||
goto quit;
|
||
|
||
|
||
case INTERNET_OPTION_SECURITY_CERTIFICATE_STRUCT:
|
||
|
||
//
|
||
// Allocates memory that caller is expected to free.
|
||
//
|
||
|
||
if (handleType != TypeHttpRequestHandle) {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
} else {
|
||
LPTSTR szResult = NULL;
|
||
DWORD cchNeedLen = 0;
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
INTERNET_SECURITY_INFO cInfo;
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
requiredSize = sizeof(INTERNET_CERTIFICATE_INFO);
|
||
|
||
if (ERROR_SUCCESS == lphHttpRqst->GetSecurityInfo(&cInfo))
|
||
{
|
||
error = ConvertSecurityInfoIntoCertInfoStruct(&cInfo, (LPINTERNET_CERTIFICATE_INFO)lpBuffer, lpdwBufferLength);
|
||
if(cInfo.pCertificate)
|
||
{
|
||
CertFreeCertificateContext(cInfo.pCertificate);
|
||
}
|
||
goto quit;
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECURITY_KEY_BITNESS:
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else
|
||
{
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
INTERNET_SECURITY_INFO secInfo;
|
||
|
||
requiredSize = sizeof(dwValue);
|
||
dwValue = 0;
|
||
lpSource = (LPVOID)&dwValue;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
if (ERROR_SUCCESS != lphHttpRqst->GetSecurityInfo(&secInfo)) {
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
} else {
|
||
dwValue = secInfo.dwCipherStrength;
|
||
CertFreeCertificateContext(secInfo.pCertificate);
|
||
|
||
INET_ASSERT (error == ERROR_SUCCESS);
|
||
|
||
DEBUG_PRINT(INET,
|
||
INFO,
|
||
("SECURITY_KEY_BITNESS: %X\n",
|
||
dwValue
|
||
));
|
||
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
case INTERNET_OPTION_PROXY:
|
||
if (!ARGUMENT_PRESENT(hInternet)) {
|
||
|
||
if (!GlobalProxyInfo.IsModifiedInProcess())
|
||
{
|
||
FixProxySettingsForCurrentConnection(
|
||
FALSE
|
||
);
|
||
}
|
||
|
||
error = GlobalProxyInfo.GetProxyStringInfo(lpBuffer, lpdwBufferLength);
|
||
requiredSize = *lpdwBufferLength;
|
||
goto quit;
|
||
} else if (handleType == TypeInternetHandle) {
|
||
|
||
//
|
||
// GetProxyInfo() will return the data, or calculate the buffer
|
||
// length required
|
||
//
|
||
|
||
error = ((INTERNET_HANDLE_OBJECT *)hInternet)->GetProxyStringInfo(
|
||
lpBuffer,
|
||
lpdwBufferLength
|
||
);
|
||
requiredSize = *lpdwBufferLength;
|
||
goto quit;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_VERSION:
|
||
requiredSize = sizeof(InternetVersionInfo);
|
||
lpSource = (LPVOID)&InternetVersionInfo;
|
||
break;
|
||
|
||
case INTERNET_OPTION_USER_AGENT:
|
||
if (handleType == TypeInternetHandle) {
|
||
lpSource = ((INTERNET_HANDLE_OBJECT *)hInternet)->GetUserAgent();
|
||
isString = TRUE;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_LINE_STATE:
|
||
|
||
if(InternetSettingsChanged())
|
||
{
|
||
ChangeGlobalSettings(); // refreshes GlobalDllState
|
||
}
|
||
|
||
requiredSize = sizeof(DWORD);
|
||
lpSource = (LPVOID)&dwValue;
|
||
dwValue = GlobalDllState
|
||
& (INTERNET_LINE_STATE_MASK | INTERNET_STATE_OFFLINE_USER);
|
||
break;
|
||
|
||
case INTERNET_OPTION_IDLE_STATE:
|
||
requiredSize = sizeof(DWORD);
|
||
lpSource = (LPVOID)&dwValue;
|
||
dwValue = GlobalDllState & INTERNET_STATE_IDLE;
|
||
break;
|
||
|
||
case INTERNET_OPTION_OFFLINE_SEMANTICS:
|
||
requiredSize = sizeof(DWORD);
|
||
dwValue = FALSE;
|
||
lpSource = (LPVOID)&dwValue;
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECONDARY_CACHE_KEY:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
lphRequest = (INTERNET_CONNECT_HANDLE_OBJECT *)hInternet;
|
||
lpSource = lphRequest->GetSecondaryCacheKey();
|
||
isString = TRUE;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_CALLBACK_FILTER:
|
||
error = ERROR_NOT_SUPPORTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_CONNECT_TIME:
|
||
error = ERROR_NOT_SUPPORTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_SEND_THROUGHPUT:
|
||
error = ERROR_NOT_SUPPORTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_RECEIVE_THROUGHPUT:
|
||
error = ERROR_NOT_SUPPORTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_REQUEST_PRIORITY:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
requiredSize = sizeof(dwValue);
|
||
dwValue = ((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->GetPriority();
|
||
lpSource = (LPVOID)&dwValue;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_HTTP_VERSION:
|
||
requiredSize = sizeof(HttpVersionInfo);
|
||
lpSource = (LPVOID)&HttpVersionInfo;
|
||
break;
|
||
|
||
case INTERNET_OPTION_NET_SPEED:
|
||
break;
|
||
|
||
case INTERNET_OPTION_BYPASS_EDITED_ENTRY:
|
||
requiredSize = sizeof(BOOL);
|
||
dwValue = GlobalBypassEditedEntry;
|
||
lpSource = (LPVOID)&dwValue;
|
||
break;
|
||
|
||
case INTERNET_OPTION_DIAGNOSTIC_SOCKET_INFO:
|
||
|
||
//
|
||
// internal option
|
||
//
|
||
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
requiredSize = sizeof(socketInfo);
|
||
lpSource = (LPVOID)&socketInfo;
|
||
|
||
HTTP_REQUEST_HANDLE_OBJECT * pReq;
|
||
|
||
pReq = (HTTP_REQUEST_HANDLE_OBJECT *)hInternet;
|
||
socketInfo.Socket = pReq->GetSocket();
|
||
socketInfo.SourcePort = pReq->GetSourcePort();
|
||
socketInfo.DestPort = pReq->GetDestPort();
|
||
socketInfo.Flags = (pReq->FromKeepAlivePool()
|
||
? IDSI_FLAG_KEEP_ALIVE : 0)
|
||
| (pReq->IsSecure()
|
||
? IDSI_FLAG_SECURE : 0)
|
||
| (pReq->IsRequestUsingProxy()
|
||
? IDSI_FLAG_PROXY : 0)
|
||
| (pReq->IsTunnel()
|
||
? IDSI_FLAG_TUNNEL : 0);
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_CACHE_TIMESTAMPS:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
if (*lpdwBufferLength == sizeof(INTERNET_CACHE_TIMESTAMPS)) {
|
||
INTERNET_CACHE_TIMESTAMPS* ts =
|
||
(INTERNET_CACHE_TIMESTAMPS*)lpBuffer;
|
||
BOOL bU1;
|
||
BOOL bU2;
|
||
BOOL bU3;
|
||
FILETIME ftPostCheck;
|
||
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->
|
||
GetTimeStampsForCache(
|
||
&(ts->ftExpires),
|
||
&(ts->ftLastModified),
|
||
&ftPostCheck,
|
||
&bU1, &bU2, &bU3 );
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
goto quit;
|
||
break;
|
||
|
||
case INTERNET_OPTION_DISABLE_AUTODIAL:
|
||
error = ERROR_NOT_SUPPORTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_AUTODIAL_MODE:
|
||
requiredSize = sizeof(DWORD);
|
||
dwValue = GetAutodialMode();
|
||
lpSource = (LPVOID)&dwValue;
|
||
break;
|
||
|
||
case INTERNET_OPTION_AUTODIAL_CONNECTION:
|
||
error = GetAutodialConnection((LPSTR)lpBuffer, *lpdwBufferLength);
|
||
isString = TRUE;
|
||
lpSource = lpBuffer;
|
||
requiredSize = *lpdwBufferLength;
|
||
break;
|
||
|
||
// IE5 #23845: Wininet: Various auth related feature requests for FP
|
||
// This will return TRUE if post data will be sent on a request.
|
||
case INTERNET_OPTION_DETECT_POST_SEND:
|
||
if (handleType == TypeHttpRequestHandle)
|
||
{
|
||
requiredSize = sizeof(DWORD);
|
||
lpSource = (LPVOID)&dwValue;
|
||
HTTP_REQUEST_HANDLE_OBJECT *pRequest;
|
||
pRequest = (HTTP_REQUEST_HANDLE_OBJECT*) hInternet;
|
||
|
||
if (pRequest->GetAuthState() == AUTHSTATE_NEGOTIATE
|
||
&& !((PLUG_CTX*)(pRequest->GetAuthCtx()))->_fNTLMProxyAuth
|
||
&& !(pRequest->GetAuthCtx()->GetSchemeType() == AUTHCTX::SCHEME_DPA))
|
||
{
|
||
dwValue = 0;
|
||
}
|
||
else
|
||
{
|
||
dwValue = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
|
||
if( !hInternet ) {
|
||
requiredSize = sizeof(dwValue);
|
||
dwValue = 0;
|
||
lpSource = (LPVOID)&dwValue;
|
||
dwValue = GlobalMaxConnectionsPerServer;
|
||
}
|
||
else
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
|
||
if( !hInternet ) {
|
||
requiredSize = sizeof(dwValue);
|
||
dwValue = 0;
|
||
lpSource = (LPVOID)&dwValue;
|
||
dwValue = GlobalMaxConnectionsPer1_0Server;
|
||
}
|
||
else
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_PER_CONNECTION_OPTION:
|
||
{
|
||
if (handleType != TypeInternetHandle) {
|
||
hInternet = NULL;
|
||
}
|
||
|
||
error = QueryPerConnOptions(hInternet,
|
||
lpThreadInfo->IsAutoProxyProxyThread,
|
||
(LPINTERNET_PER_CONN_OPTION_LIST)lpBuffer);
|
||
|
||
requiredSize = *lpdwBufferLength;
|
||
goto quit;
|
||
}
|
||
|
||
case INTERNET_OPTION_COOKIES_3RD_PARTY:
|
||
if (handleType == TypeHttpRequestHandle)
|
||
{
|
||
requiredSize = sizeof(DWORD);
|
||
lpSource = (LPVOID)&dwValue;
|
||
dwValue = (DWORD) ((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->Is3rdPartyCookies();
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
#if INET_DEBUG
|
||
|
||
case INTERNET_OPTION_GET_DEBUG_INFO:
|
||
error = InternetGetDebugInfo((LPINTERNET_DEBUG_INFO)lpBuffer,
|
||
lpdwBufferLength
|
||
);
|
||
|
||
//
|
||
// everything updated, so quit without going through common buffer
|
||
// processing
|
||
//
|
||
|
||
goto quit;
|
||
break;
|
||
|
||
case INTERNET_OPTION_GET_HANDLE_COUNT:
|
||
requiredSize = sizeof(DWORD);
|
||
dwValue = InternetHandleCount();
|
||
lpSource = (LPVOID)&dwValue;
|
||
break;
|
||
|
||
#endif // INET_DEBUG
|
||
|
||
default:
|
||
requiredSize = 0;
|
||
error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
//
|
||
// if we have a buffer and enough space, then copy the data
|
||
//
|
||
|
||
if (error == ERROR_SUCCESS) {
|
||
|
||
//
|
||
// if we are returning a string, calculate the amount of space
|
||
// required to hold it
|
||
//
|
||
|
||
if (isString) {
|
||
if (lpSource != NULL) {
|
||
requiredSize = lstrlen((LPCSTR)lpSource) + 1;
|
||
} else {
|
||
|
||
//
|
||
// option string is NULL: return an empty string
|
||
//
|
||
|
||
lpSource = "";
|
||
requiredSize = 1;
|
||
}
|
||
}
|
||
|
||
INET_ASSERT(lpSource != NULL);
|
||
|
||
if ((*lpdwBufferLength >= requiredSize)
|
||
&& ARGUMENT_PRESENT(lpBuffer)) {
|
||
memcpy(lpBuffer, lpSource, requiredSize);
|
||
if (isString) {
|
||
|
||
//
|
||
// string copied successfully. Returned length is string
|
||
// length, not buffer length, i.e. drop 1 for '\0'
|
||
//
|
||
|
||
--requiredSize;
|
||
}
|
||
} else {
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
}
|
||
|
||
quit:
|
||
|
||
//
|
||
// return the amount the app needs to supply, or the amount of data in the
|
||
// buffer, depending on success/failure status
|
||
//
|
||
|
||
*lpdwBufferLength = requiredSize;
|
||
|
||
if (hObjectMapped != NULL) {
|
||
DereferenceObject((LPVOID)hObjectMapped);
|
||
}
|
||
|
||
done:
|
||
|
||
if (error == ERROR_SUCCESS) {
|
||
success = TRUE;
|
||
|
||
IF_DEBUG(API) {
|
||
|
||
if (isString) {
|
||
|
||
DEBUG_PRINT_API(API,
|
||
INFO,
|
||
("returning %q (%d chars)\n",
|
||
lpBuffer,
|
||
requiredSize
|
||
));
|
||
|
||
} else {
|
||
|
||
DEBUG_DUMP_API(API,
|
||
"option data:\n",
|
||
lpBuffer,
|
||
requiredSize
|
||
);
|
||
|
||
}
|
||
}
|
||
} else {
|
||
|
||
DEBUG_ERROR(API, error);
|
||
|
||
IF_DEBUG(API) {
|
||
|
||
if (error == ERROR_INSUFFICIENT_BUFFER) {
|
||
|
||
DEBUG_PRINT_API(API,
|
||
INFO,
|
||
("*lpdwBufferLength (%#x)= %d\n",
|
||
lpdwBufferLength,
|
||
*lpdwBufferLength
|
||
));
|
||
|
||
}
|
||
}
|
||
|
||
SetLastError(error);
|
||
success = FALSE;
|
||
}
|
||
|
||
DEBUG_LEAVE_API(success);
|
||
|
||
return success;
|
||
}
|
||
|
||
|
||
INTERNETAPI_(BOOL) InternetQueryOptionW(
|
||
IN HINTERNET hInternet OPTIONAL,
|
||
IN DWORD dwOption,
|
||
OUT LPVOID lpBuffer OPTIONAL,
|
||
IN OUT LPDWORD lpdwBufferLength
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
description-of-function.
|
||
|
||
Arguments:
|
||
|
||
hInternet -
|
||
|
||
dwOption -
|
||
|
||
lpBuffer -
|
||
|
||
lpdwBufferLength -
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER_API((DBG_API,
|
||
Bool,
|
||
"InternetQueryOptionW",
|
||
"%#x, %s (%d), %#x, %#x [%d]",
|
||
hInternet,
|
||
InternetMapOption(dwOption),
|
||
dwOption,
|
||
lpBuffer,
|
||
lpdwBufferLength,
|
||
lpdwBufferLength
|
||
? (!IsBadReadPtr(lpdwBufferLength, sizeof(DWORD))
|
||
? *lpdwBufferLength
|
||
: 0)
|
||
: 0
|
||
));
|
||
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
BOOL fResult = FALSE;
|
||
MEMORYPACKET mpBuffer;
|
||
|
||
switch (dwOption)
|
||
{
|
||
case INTERNET_OPTION_USERNAME:
|
||
case INTERNET_OPTION_PASSWORD:
|
||
case INTERNET_OPTION_DATAFILE_NAME:
|
||
case INTERNET_OPTION_URL:
|
||
case INTERNET_OPTION_USER_AGENT:
|
||
case INTERNET_OPTION_PROXY_USERNAME:
|
||
case INTERNET_OPTION_PROXY_PASSWORD:
|
||
case INTERNET_OPTION_SECONDARY_CACHE_KEY:
|
||
case INTERNET_OPTION_AUTODIAL_CONNECTION:
|
||
if (lpBuffer)
|
||
{
|
||
mpBuffer.dwAlloc = mpBuffer.dwSize = *lpdwBufferLength;
|
||
mpBuffer.psStr = (LPSTR)ALLOC_BYTES(mpBuffer.dwAlloc*sizeof(CHAR));
|
||
if (!mpBuffer.psStr)
|
||
{
|
||
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
||
break;
|
||
}
|
||
}
|
||
fResult = InternetQueryOptionA(hInternet,
|
||
dwOption,
|
||
(LPVOID)mpBuffer.psStr,
|
||
&mpBuffer.dwSize
|
||
);
|
||
if (fResult)
|
||
{
|
||
*lpdwBufferLength = MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize + 1,
|
||
NULL, 0);
|
||
if (*lpdwBufferLength*sizeof(WCHAR)<=mpBuffer.dwAlloc && lpBuffer)
|
||
{
|
||
MultiByteToWideChar(CP_ACP, 0, mpBuffer.psStr, mpBuffer.dwSize+1,
|
||
(LPWSTR)lpBuffer, *lpdwBufferLength);
|
||
(*lpdwBufferLength)--;
|
||
}
|
||
else
|
||
{
|
||
*lpdwBufferLength *= sizeof(WCHAR);
|
||
fResult = FALSE;
|
||
dwErr = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
|
||
{
|
||
*lpdwBufferLength = mpBuffer.dwSize*sizeof(WCHAR);
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_PER_CONNECTION_OPTION:
|
||
{
|
||
if (!lpBuffer)
|
||
{
|
||
dwErr = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
|
||
INTERNET_PER_CONN_OPTION_LISTA listA;
|
||
LPINTERNET_PER_CONN_OPTION_LISTW plistW = (LPINTERNET_PER_CONN_OPTION_LISTW)lpBuffer;
|
||
CHAR szEntryA[RAS_MaxEntryName + 1];
|
||
listA.pszConnection = szEntryA;
|
||
|
||
InitIPCOList(plistW, &listA);
|
||
listA.pOptions = (LPINTERNET_PER_CONN_OPTIONA)_alloca(sizeof(INTERNET_PER_CONN_OPTIONA)*listA.dwOptionCount);
|
||
|
||
for (DWORD i=0; i<listA.dwOptionCount; i++)
|
||
{
|
||
listA.pOptions[i].dwOption = plistW->pOptions[i].dwOption;
|
||
listA.pOptions[i].Value.pszValue = NULL;
|
||
plistW->pOptions[i].Value.pszValue = NULL;
|
||
}
|
||
|
||
fResult = InternetQueryOptionA(hInternet,
|
||
dwOption,
|
||
(PVOID)&listA,
|
||
lpdwBufferLength);
|
||
|
||
// Now, convert from ansi to unicode
|
||
|
||
if (fResult)
|
||
{
|
||
for (DWORD i=0; i<listA.dwOptionCount; i++)
|
||
{
|
||
switch (listA.pOptions[i].dwOption)
|
||
{
|
||
case INTERNET_PER_CONN_FLAGS:
|
||
case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
|
||
plistW->pOptions[i].Value.dwValue = listA.pOptions[i].Value.dwValue;
|
||
break;
|
||
|
||
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
|
||
plistW->pOptions[i].Value.ftValue = listA.pOptions[i].Value.ftValue;
|
||
break;
|
||
|
||
case INTERNET_PER_CONN_PROXY_SERVER:
|
||
case INTERNET_PER_CONN_PROXY_BYPASS:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_URL:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
|
||
if (listA.pOptions[i].Value.pszValue && *listA.pOptions[i].Value.pszValue)
|
||
{
|
||
DWORD cc = MultiByteToWideChar(CP_ACP,
|
||
0,
|
||
listA.pOptions[i].Value.pszValue,
|
||
-1,
|
||
NULL,
|
||
0);
|
||
plistW->pOptions[i].Value.pszValue = (PWSTR)GlobalAlloc(GPTR, cc*sizeof(WCHAR));
|
||
if (!plistW->pOptions[i].Value.pszValue)
|
||
{
|
||
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
||
goto iopco_cleanup;
|
||
}
|
||
MultiByteToWideChar(CP_ACP,
|
||
0,
|
||
listA.pOptions[i].Value.pszValue,
|
||
-1,
|
||
plistW->pOptions[i].Value.pszValue,
|
||
cc);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
INET_ASSERT(FALSE);
|
||
dwErr = ERROR_INVALID_PARAMETER;
|
||
goto iopco_cleanup;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
plistW->dwOptionError = listA.dwOptionError;
|
||
}
|
||
|
||
iopco_cleanup:
|
||
// Free all the allocated buffers
|
||
for (i=0; i<listA.dwOptionCount; i++)
|
||
{
|
||
switch (listA.pOptions[i].dwOption)
|
||
{
|
||
case INTERNET_PER_CONN_PROXY_SERVER:
|
||
case INTERNET_PER_CONN_PROXY_BYPASS:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_URL:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
|
||
// These should have been converted from ansi to unicode
|
||
// and can be freed now
|
||
if (listA.pOptions[i].Value.pszValue)
|
||
{
|
||
GlobalFree(listA.pOptions[i].Value.pszValue);
|
||
}
|
||
// No point in passing back buffers in the event of an error
|
||
// condition
|
||
if (dwErr && plistW->pOptions[i].Value.pszValue)
|
||
{
|
||
GlobalFree(plistW->pOptions[i].Value.pszValue);
|
||
}
|
||
break;
|
||
|
||
default:
|
||
// No need to do anything
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
default:
|
||
fResult = InternetQueryOptionA(hInternet,
|
||
dwOption,
|
||
lpBuffer,
|
||
lpdwBufferLength
|
||
);
|
||
}
|
||
|
||
if (dwErr!=ERROR_SUCCESS)
|
||
{
|
||
SetLastError(dwErr);
|
||
DEBUG_ERROR(INET, dwErr);
|
||
}
|
||
DEBUG_LEAVE_API(fResult);
|
||
return fResult;
|
||
}
|
||
|
||
|
||
INTERNETAPI_(BOOL) InternetSetOptionA(
|
||
IN HINTERNET hInternet OPTIONAL,
|
||
IN DWORD dwOption,
|
||
IN LPVOID lpBuffer,
|
||
IN DWORD dwBufferLength
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets a handle-specific variable, or a per-thread variable
|
||
|
||
Arguments:
|
||
|
||
hInternet - handle of object for which information will be set,
|
||
or NULL if the option defines a per-thread variable
|
||
|
||
dwOption - the handle-specific INTERNET_OPTION to set
|
||
|
||
lpBuffer - pointer to a buffer containing value to set
|
||
|
||
dwBufferLength - size of lpBuffer
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
Success - TRUE
|
||
|
||
Failure - FALSE. Call GetLastError() for more info:
|
||
ERROR_INVALID_HANDLE
|
||
hInternet does not identify a valid Internet handle
|
||
object
|
||
|
||
ERROR_INTERNET_INTERNAL_ERROR
|
||
Shouldn't see this?
|
||
|
||
ERROR_INVALID_PARAMETER
|
||
One of the parameters was bad
|
||
|
||
ERROR_INTERNET_INVALID_OPTION
|
||
The requested option cannot be set
|
||
|
||
ERROR_INTERNET_OPTION_NOT_SETTABLE
|
||
Can't set this option, only query it
|
||
|
||
ERROR_INTERNET_BAD_OPTION_LENGTH
|
||
The dwBufferLength parameter is incorrect for the
|
||
expected type of the option
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER_API((DBG_API,
|
||
Bool,
|
||
"InternetSetOptionA",
|
||
"%#x, %s (%d), %#x [%#x], %d",
|
||
hInternet,
|
||
InternetMapOption(dwOption),
|
||
dwOption,
|
||
lpBuffer,
|
||
lpBuffer
|
||
? (!IsBadReadPtr(lpBuffer, sizeof(DWORD))
|
||
? *(LPDWORD)lpBuffer
|
||
: 0)
|
||
: 0,
|
||
dwBufferLength
|
||
));
|
||
|
||
DWORD error;
|
||
BOOL success = TRUE;
|
||
HINTERNET_HANDLE_TYPE handleType;
|
||
LPINTERNET_THREAD_INFO lpThreadInfo = NULL;
|
||
DWORD requiredSize;
|
||
HINTERNET hObjectMapped = NULL;
|
||
INTERNET_CONNECT_HANDLE_OBJECT *lphRequest;
|
||
|
||
//
|
||
// Auth code can query on connect handle by walking up from request handle,
|
||
// unbeknownst to the client, who might try to set the option concurrently.
|
||
// Ideally access would be serialized only for the four combinations of
|
||
// {user,pass} and {server,proxy}, but unconditional keeps the code simple.
|
||
//
|
||
|
||
//AuthLock();
|
||
|
||
//
|
||
// validate parameters
|
||
//
|
||
|
||
if ((dwBufferLength == 0) || IsBadReadPtr(lpBuffer, dwBufferLength)) {
|
||
|
||
|
||
switch (dwOption) {
|
||
|
||
//
|
||
// these options don't require a buffer - don't fail request because
|
||
// no buffer supplied
|
||
//
|
||
|
||
case INTERNET_OPTION_SETTINGS_CHANGED:
|
||
case INTERNET_OPTION_PROXY_SETTINGS_CHANGED:
|
||
case INTERNET_OPTION_END_BROWSER_SESSION:
|
||
case INTERNET_OPTION_RESET_URLCACHE_SESSION:
|
||
case INTERNET_OPTION_REFRESH:
|
||
case INTERNET_OPTION_DIGEST_AUTH_UNLOAD:
|
||
case INTERNET_OPTION_IGNORE_OFFLINE:
|
||
case INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT:
|
||
case INTERNET_OPTION_DISABLE_PASSPORT_AUTH:
|
||
case INTERNET_OPTION_ENABLE_PASSPORT_AUTH:
|
||
case INTERNET_OPTION_HIBERNATE_INACTIVE_WORKER_THREADS:
|
||
case INTERNET_OPTION_ACTIVATE_WORKER_THREADS:
|
||
case INTERNET_OPTION_RESTORE_WORKER_THREAD_DEFAULTS:
|
||
break;
|
||
|
||
default:
|
||
error = ERROR_INVALID_PARAMETER;
|
||
goto quit;
|
||
}
|
||
}
|
||
|
||
if (!GlobalDataInitialized) {
|
||
error = GlobalDataInitialize();
|
||
if (error != ERROR_SUCCESS) {
|
||
goto done;
|
||
}
|
||
}
|
||
|
||
//
|
||
// validate the handle and get its type
|
||
//
|
||
|
||
if (ARGUMENT_PRESENT(hInternet)) {
|
||
|
||
//
|
||
// map the handle
|
||
//
|
||
|
||
error = MapHandleToAddress(hInternet, (LPVOID *)&hInternet, FALSE);
|
||
if (error == ERROR_SUCCESS) {
|
||
hObjectMapped = hInternet;
|
||
error = RGetHandleType(hInternet, &handleType);
|
||
}
|
||
} else if (IS_PER_THREAD_OPTION(dwOption)) {
|
||
|
||
//
|
||
// this option updates the per-thread information block, so this is a
|
||
// good point at which to get it
|
||
//
|
||
|
||
lpThreadInfo = InternetGetThreadInfo();
|
||
if (lpThreadInfo != NULL) {
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
|
||
DEBUG_PRINT(INET,
|
||
ERROR,
|
||
("InternetGetThreadInfo() returns NULL\n"
|
||
));
|
||
|
||
//
|
||
// we never expect this - ERROR_INTERNET_SPANISH_INQUISITION
|
||
//
|
||
|
||
INET_ASSERT(FALSE);
|
||
|
||
error = ERROR_INTERNET_INTERNAL_ERROR;
|
||
}
|
||
} else if (IS_PER_PROCESS_OPTION(dwOption)) {
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
|
||
//
|
||
// catch any invalid options for the NULL handle. If the option is valid
|
||
// then it is incorrect for this handle type, otherwise its an invalid
|
||
// option, period
|
||
//
|
||
|
||
error = IS_VALID_OPTION(dwOption)
|
||
? ERROR_INTERNET_INCORRECT_HANDLE_TYPE
|
||
: ERROR_INTERNET_INVALID_OPTION
|
||
;
|
||
}
|
||
|
||
if (error != ERROR_SUCCESS) {
|
||
goto quit;
|
||
}
|
||
|
||
//
|
||
// if the option and handle combination is valid then set the option value
|
||
//
|
||
|
||
switch (dwOption) {
|
||
case INTERNET_OPTION_CALLBACK:
|
||
case INTERNET_OPTION_HANDLE_TYPE:
|
||
//case INTERNET_OPTION_GATEWAY_NAME:
|
||
case INTERNET_OPTION_KEEP_CONNECTION:
|
||
case INTERNET_OPTION_ASYNC_ID:
|
||
case INTERNET_OPTION_ASYNC_REQUEST_COUNT:
|
||
case INTERNET_OPTION_ASYNC_QUEUE_DEPTH:
|
||
case INTERNET_OPTION_WORKER_THREAD_TIMEOUT:
|
||
case INTERNET_OPTION_IDLE_STATE:
|
||
case INTERNET_OPTION_CONNECT_TIME:
|
||
case INTERNET_OPTION_SEND_THROUGHPUT:
|
||
case INTERNET_OPTION_RECEIVE_THROUGHPUT:
|
||
case INTERNET_OPTION_NET_SPEED:
|
||
|
||
//
|
||
// these options cannot be set by this function
|
||
//
|
||
|
||
error = ERROR_INTERNET_OPTION_NOT_SETTABLE;
|
||
break;
|
||
|
||
case INTERNET_OPTION_HIBERNATE_INACTIVE_WORKER_THREADS:
|
||
|
||
if (!g_bDisableHibernation)
|
||
{
|
||
g_bHibernating = TRUE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_ACTIVATE_WORKER_THREADS:
|
||
|
||
if (g_bHibernating)
|
||
{
|
||
InterruptSelect();
|
||
GlobalProxyInfo.ActivateAutoproxyThread();
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_RESTORE_WORKER_THREAD_DEFAULTS:
|
||
|
||
if (g_bHibernating)
|
||
{
|
||
g_bHibernating = FALSE;
|
||
InterruptSelect();
|
||
GlobalProxyInfo.ActivateAutoproxyThread();
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_BYPASS_EDITED_ENTRY:
|
||
requiredSize = sizeof(BOOL);
|
||
if (dwBufferLength != requiredSize) {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
break;
|
||
}
|
||
// Only support global, not per handle yet
|
||
if (hInternet != NULL) {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
break;
|
||
}
|
||
|
||
// Made it this far, so buffer is right size and handle is NULL
|
||
GlobalBypassEditedEntry = *(LPBOOL)lpBuffer;
|
||
break;
|
||
|
||
|
||
case INTERNET_OPTION_CONNECT_TIMEOUT:
|
||
case INTERNET_OPTION_CONNECT_RETRIES:
|
||
case INTERNET_OPTION_CONNECT_BACKOFF:
|
||
case INTERNET_OPTION_SEND_TIMEOUT:
|
||
case INTERNET_OPTION_RECEIVE_TIMEOUT:
|
||
case INTERNET_OPTION_DATA_SEND_TIMEOUT:
|
||
case INTERNET_OPTION_DATA_RECEIVE_TIMEOUT:
|
||
case INTERNET_OPTION_FROM_CACHE_TIMEOUT:
|
||
requiredSize = sizeof(DWORD);
|
||
if (dwBufferLength != requiredSize) {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
break;
|
||
}
|
||
|
||
//
|
||
// if hInternet is NULL then the app is requesting that we set the
|
||
// global timeout values, not handle-specific ones
|
||
//
|
||
|
||
if (hInternet == NULL) {
|
||
switch (dwOption) {
|
||
case INTERNET_OPTION_CONNECT_TIMEOUT:
|
||
GlobalConnectTimeout = *(LPDWORD)lpBuffer;
|
||
break;
|
||
|
||
case INTERNET_OPTION_CONNECT_RETRIES:
|
||
GlobalConnectRetries = *(LPDWORD)lpBuffer;
|
||
break;
|
||
|
||
case INTERNET_OPTION_SEND_TIMEOUT:
|
||
GlobalSendTimeout = *(LPDWORD)lpBuffer;
|
||
break;
|
||
|
||
case INTERNET_OPTION_RECEIVE_TIMEOUT:
|
||
GlobalReceiveTimeout = *(LPDWORD)lpBuffer;
|
||
break;
|
||
|
||
case INTERNET_OPTION_DATA_SEND_TIMEOUT:
|
||
GlobalDataSendTimeout = *(LPDWORD)lpBuffer;
|
||
break;
|
||
|
||
case INTERNET_OPTION_DATA_RECEIVE_TIMEOUT:
|
||
GlobalDataReceiveTimeout = *(LPDWORD)lpBuffer;
|
||
break;
|
||
|
||
case INTERNET_OPTION_FROM_CACHE_TIMEOUT:
|
||
GlobalFromCacheTimeout = *(LPDWORD)lpBuffer;
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
|
||
//
|
||
// we have a non-NULL context handle: the app wants to set specific
|
||
// protocol timeouts
|
||
//
|
||
|
||
switch (handleType) {
|
||
case TypeInternetHandle:
|
||
case TypeFtpConnectHandle:
|
||
case TypeFtpFindHandle:
|
||
case TypeFtpFindHandleHtml:
|
||
case TypeFtpFileHandle:
|
||
case TypeFtpFileHandleHtml:
|
||
case TypeGopherConnectHandle:
|
||
case TypeGopherFindHandle:
|
||
case TypeGopherFindHandleHtml:
|
||
case TypeGopherFileHandle:
|
||
case TypeGopherFileHandleHtml:
|
||
case TypeHttpConnectHandle:
|
||
case TypeHttpRequestHandle:
|
||
|
||
//
|
||
// N.B. For some of these handle types, setting a timeout etc.
|
||
// value will have absolutely no affect (we have already gotten
|
||
// the information after connecting, sending etc.), but we'll
|
||
// allow the app to go ahead anyway (its benign)
|
||
//
|
||
|
||
error = RSetTimeout(hInternet,
|
||
dwOption,
|
||
*(LPDWORD)lpBuffer
|
||
);
|
||
break;
|
||
|
||
default:
|
||
|
||
//
|
||
// any other handle type (?) cannot have timeouts set for it
|
||
//
|
||
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_CONTEXT_VALUE:
|
||
|
||
//
|
||
// BUGBUG - can't change context if async operation is pending
|
||
//
|
||
|
||
if (dwBufferLength == sizeof(lpThreadInfo->Context)) {
|
||
error = RSetContext(hInternet, *((DWORD*) lpBuffer));
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_NAME_RES_THREAD:
|
||
//if (dwBufferLength == sizeof(MultiThreadedNameResolution)) {
|
||
// MultiThreadedNameResolution = (BOOL)(*(LPDWORD)lpBuffer != 0);
|
||
//} else {
|
||
// error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
//}
|
||
break;
|
||
|
||
case INTERNET_OPTION_READ_BUFFER_SIZE:
|
||
case INTERNET_OPTION_WRITE_BUFFER_SIZE:
|
||
if (IS_CONNECT_HANDLE_TYPE(handleType)) {
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
|
||
DWORD bufferSize;
|
||
|
||
bufferSize = *(LPDWORD)lpBuffer;
|
||
if (bufferSize > 0) {
|
||
error = RSetBufferSize(hInternet, dwOption, bufferSize);
|
||
} else {
|
||
|
||
//
|
||
// the read/write buffer size cannot be set to 0
|
||
//
|
||
|
||
error = ERROR_INVALID_PARAMETER;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
BOOL fUser, fProxy;
|
||
|
||
case INTERNET_OPTION_ASYNC_PRIORITY:
|
||
error = ERROR_CALL_NOT_IMPLEMENTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_AUTH_FLAGS:
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else if (dwBufferLength < sizeof(DWORD))
|
||
{
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
else
|
||
{
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
|
||
lphHttpRqst->SetAuthFlag(*(LPDWORD)lpBuffer);
|
||
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_USERNAME:
|
||
fUser = IS_USER;
|
||
fProxy = IS_SERVER;
|
||
goto callSetUserOrPass;
|
||
|
||
|
||
case INTERNET_OPTION_PASSWORD:
|
||
fUser = IS_PASS;
|
||
fProxy = IS_SERVER;
|
||
goto callSetUserOrPass;
|
||
|
||
case INTERNET_OPTION_PROXY_USERNAME:
|
||
fUser = IS_USER;
|
||
fProxy = IS_PROXY;
|
||
goto callSetUserOrPass;
|
||
|
||
case INTERNET_OPTION_PROXY_PASSWORD:
|
||
fUser = IS_PASS;
|
||
fProxy = IS_PROXY;
|
||
goto callSetUserOrPass;
|
||
|
||
|
||
callSetUserOrPass:
|
||
|
||
if (hInternet == 0)
|
||
{
|
||
if (!fProxy)
|
||
{
|
||
AuthLock();
|
||
SetUserOrPass ((LPSTR)lpBuffer, fUser);
|
||
TimeStampCreds();
|
||
AuthUnlock();
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INVALID_PARAMETER;
|
||
}
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
else if (handleType != TypeInternetHandle) {
|
||
AuthLock();
|
||
lphRequest = (INTERNET_CONNECT_HANDLE_OBJECT *)hInternet;
|
||
lphRequest->SetUserOrPass ((LPSTR)lpBuffer, fUser, fProxy);
|
||
lphRequest->TimeStampCreds();
|
||
AuthUnlock();
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_DISABLE_PASSPORT_AUTH:
|
||
if (handleType != TypeInternetHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else
|
||
{
|
||
((INTERNET_HANDLE_OBJECT *)hInternet)->DisableTweener();
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_ENABLE_PASSPORT_AUTH:
|
||
if (handleType != TypeInternetHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else
|
||
{
|
||
((INTERNET_HANDLE_OBJECT *)hInternet)->EnableTweener();
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_EXEMPT_CONNECTION_LIMIT:
|
||
if (handleType != TypeInternetHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else
|
||
{
|
||
((INTERNET_HANDLE_OBJECT *)hInternet)->ExemptConnLimit();
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_CLIENT_CERT_CONTEXT:
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else if (dwBufferLength < sizeof(CERT_CONTEXT))
|
||
{
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
else
|
||
{
|
||
HTTP_REQUEST_HANDLE_OBJECT *pRequest =
|
||
(HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
CERT_CONTEXT_ARRAY* pArray = pRequest->GetCertContextArray();
|
||
if (!pArray)
|
||
{
|
||
pArray = new CERT_CONTEXT_ARRAY;
|
||
pRequest->SetCertContextArray(pArray);
|
||
}
|
||
|
||
if (!pArray)
|
||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||
else
|
||
{
|
||
error = LoadSecurity();
|
||
if (ERROR_SUCCESS == error)
|
||
{
|
||
pArray->Reset();
|
||
pArray->AddCertContext((PCCERT_CONTEXT) lpBuffer);
|
||
pArray->SelectCertContext(0);
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
pRequest->SetCertContextArray(NULL);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECURITY_SELECT_CLIENT_CERT:
|
||
|
||
// This option sets an index into an internal wininet structure.
|
||
// This is worthless to apps because there is no way to guarantee
|
||
// they enum the cert store the same as wininet, especially if the
|
||
// server returns a list of acceptable CA to filter by. This has
|
||
// been superseded by INTERNET_OPTION_CLIENT_CERT_CONTEXT above.
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else if (dwBufferLength < sizeof(DWORD))
|
||
{
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
else
|
||
{
|
||
CERT_CONTEXT_ARRAY* pCertContextArray;
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
|
||
pCertContextArray =
|
||
lphHttpRqst->GetCertContextArray();
|
||
|
||
if ( ! pCertContextArray )
|
||
{
|
||
error = ERROR_INTERNET_CLIENT_AUTH_NOT_SETUP;
|
||
}
|
||
else
|
||
{
|
||
|
||
if ( (*((LPINT)lpBuffer) < (INT) pCertContextArray->GetArraySize() )
|
||
|| *((LPINT)lpBuffer) == -1 )
|
||
{
|
||
pCertContextArray->SelectCertContext( *((LPDWORD)lpBuffer) );
|
||
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INVALID_PARAMETER;
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECURITY_FLAGS:
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else if (dwBufferLength < sizeof(DWORD))
|
||
{
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
else
|
||
{
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
|
||
lphHttpRqst->SetSecureFlags(*(LPDWORD)lpBuffer);
|
||
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_REFRESH:
|
||
|
||
//
|
||
// BUGBUG - can only accept global or InternetOpen() handles currently
|
||
//
|
||
|
||
if (!ARGUMENT_PRESENT(hInternet)) {
|
||
if (!GlobalProxyInfo.IsModifiedInProcess()) {
|
||
FixProxySettingsForCurrentConnection(TRUE);
|
||
error = ERROR_SUCCESS;
|
||
} else {
|
||
INET_ASSERT(error == ERROR_SUCCESS);
|
||
}
|
||
} else if (handleType == TypeInternetHandle) {
|
||
error = ((INTERNET_HANDLE_OBJECT *)hInternet)->Refresh(0);
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_PROXY:
|
||
if ((handleType == TypeInternetHandle) || !ARGUMENT_PRESENT(hInternet)) {
|
||
|
||
LPINTERNET_PROXY_INFO lpInfo = (LPINTERNET_PROXY_INFO)lpBuffer;
|
||
|
||
//
|
||
// validate parameters
|
||
//
|
||
|
||
if (dwBufferLength != sizeof(*lpInfo)) {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
} else if (!((lpInfo->dwAccessType == INTERNET_OPEN_TYPE_DIRECT)
|
||
|| (lpInfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
|
||
|| (lpInfo->dwAccessType == INTERNET_OPEN_TYPE_PRECONFIG))
|
||
|| ((lpInfo->dwAccessType == INTERNET_OPEN_TYPE_PROXY)
|
||
&& ((lpInfo->lpszProxy == NULL) || (*lpInfo->lpszProxy == '\0')))) {
|
||
error = ERROR_INVALID_PARAMETER;
|
||
} else {
|
||
if (!ARGUMENT_PRESENT(hInternet)) {
|
||
|
||
INTERNET_PROXY_INFO_EX info;
|
||
memset(&info, 0, sizeof(info));
|
||
info.dwFlags = PROXY_TYPE_DIRECT;
|
||
|
||
|
||
switch (lpInfo->dwAccessType) {
|
||
case INTERNET_OPEN_TYPE_PRECONFIG:
|
||
FixProxySettingsForCurrentConnection(TRUE);
|
||
error = ERROR_SUCCESS;
|
||
goto quit;
|
||
case INTERNET_OPEN_TYPE_DIRECT:
|
||
info.dwFlags |= PROXY_TYPE_DIRECT;
|
||
break;
|
||
case INTERNET_OPEN_TYPE_PROXY:
|
||
info.dwFlags |= PROXY_TYPE_PROXY;
|
||
info.lpszProxy = lpInfo->lpszProxy;
|
||
info.lpszProxyBypass = lpInfo->lpszProxyBypass;
|
||
break;
|
||
}
|
||
GlobalProxyInfo.SetProxySettings(&info, TRUE );
|
||
|
||
} else {
|
||
error = ((INTERNET_HANDLE_OBJECT *)hInternet)->SetProxyInfo(
|
||
lpInfo->dwAccessType,
|
||
lpInfo->lpszProxy,
|
||
lpInfo->lpszProxyBypass
|
||
);
|
||
}
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SETTINGS_CHANGED:
|
||
{
|
||
DWORD dwVer;
|
||
|
||
IncrementCurrentSettingsVersion(&dwVer);
|
||
// eat the update settings for this process,
|
||
// since calling ChangeGlobalSettings should suffice
|
||
InternetSettingsChanged();
|
||
ChangeGlobalSettings();
|
||
PurgeKeepAlives(PKA_NOW);
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_PROXY_SETTINGS_CHANGED:
|
||
{
|
||
DWORD dwVer;
|
||
|
||
IncrementCurrentSettingsVersion(&dwVer);
|
||
// eat the update settings for this process,
|
||
// since calling ChangeGlobalSettings should suffice
|
||
InternetSettingsChanged();
|
||
ChangeGlobalSettings();
|
||
// PurgeKeepAlives(PKA_NOW);
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_USER_AGENT:
|
||
if (*(LPSTR)lpBuffer == '\0') {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
} else {
|
||
if (handleType == TypeInternetHandle) {
|
||
((INTERNET_HANDLE_OBJECT *)hInternet)->SetUserAgent((LPSTR)lpBuffer);
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_END_BROWSER_SESSION:
|
||
|
||
//
|
||
// Flush the in-memory password cache and drop any keep-alive
|
||
// sockets which had authorization (IIS retains the credentials.
|
||
//
|
||
|
||
AuthFlush();
|
||
PurgeKeepAlives (PKA_AUTH_FAILED);
|
||
|
||
if(g_hDialEvent)
|
||
{
|
||
WaitForSingleObject(g_hDialEvent, INFINITE);
|
||
CloseHandle(g_hDialEvent);
|
||
}
|
||
|
||
//
|
||
// Empty the content cache if registry key is set.
|
||
//
|
||
|
||
UrlCacheFlush();
|
||
|
||
//
|
||
// Flush session cookies.
|
||
//
|
||
|
||
PurgeCookieJarOfStaleCookies();
|
||
|
||
//
|
||
// Purge Proxy Script Cache
|
||
//
|
||
|
||
UPDATE_GLOBAL_PROXY_VERSION();
|
||
|
||
//
|
||
// Flush all cached SSL Certificates.
|
||
//
|
||
|
||
//GlobalCertCache.ClearList();
|
||
|
||
//
|
||
// Need to close global keys
|
||
//
|
||
ResetAutodialModule();
|
||
CloseInternetSettingsKey();
|
||
|
||
//
|
||
// Make sure cert key is reset, too
|
||
//
|
||
CloseMyCertStore();
|
||
|
||
// Look out: intentional fall through.
|
||
|
||
case INTERNET_OPTION_RESET_URLCACHE_SESSION:
|
||
|
||
// Look out: intentional fall through.
|
||
|
||
//
|
||
// Restart the session used for cache syncmode.
|
||
//
|
||
|
||
GetCurrentGmtTime ((LPFILETIME)&dwdwSessionStartTime);
|
||
dwdwSessionStartTime -= dwdwSessionStartTimeDefaultDelta;
|
||
|
||
error = ERROR_SUCCESS;
|
||
break;
|
||
|
||
case INTERNET_OPTION_DIGEST_AUTH_UNLOAD:
|
||
if (DIGEST_CTX::g_pFuncTbl)
|
||
{
|
||
DIGEST_CTX::Logoff();
|
||
DIGEST_CTX::g_pFuncTbl = NULL;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_LINE_STATE:
|
||
if (dwBufferLength == sizeof(INTERNET_ONLINE_OFFLINE_INFO)) {
|
||
|
||
LPINTERNET_ONLINE_OFFLINE_INFO lpInfo;
|
||
DWORD state;
|
||
|
||
lpInfo = (LPINTERNET_ONLINE_OFFLINE_INFO)lpBuffer;
|
||
state = lpInfo->dwOfflineState;
|
||
|
||
//
|
||
// we allow app to pass in INTERNET_STATE_OFFLINE_USER and interpret
|
||
// it as same as INTERNET_STATE_OFFLINE
|
||
//
|
||
|
||
if (state == INTERNET_STATE_OFFLINE_USER) {
|
||
state = INTERNET_STATE_OFFLINE;
|
||
}
|
||
if (((state == INTERNET_STATE_ONLINE)
|
||
|| (state == INTERNET_STATE_OFFLINE))
|
||
&& ((lpInfo->dwFlags & ~ISO_FORCE_OFFLINE) == 0)) {
|
||
error = SetOfflineUserState(state,
|
||
(lpInfo->dwFlags & ISO_FORCE_OFFLINE)
|
||
? TRUE
|
||
: FALSE
|
||
);
|
||
|
||
// update registry value
|
||
InternetWriteRegistryDword("GlobalUserOffline",
|
||
((state == INTERNET_STATE_ONLINE) ? 0 : 1));
|
||
|
||
// notification
|
||
DWORD dwOp = CACHE_NOTIFY_SET_OFFLINE;
|
||
if( state == INTERNET_STATE_ONLINE )
|
||
{
|
||
dwOp = CACHE_NOTIFY_SET_ONLINE;
|
||
}
|
||
|
||
UrlCacheSendNotification(dwOp);
|
||
|
||
// invalidate global info so other instances pick it up
|
||
DWORD dwVer;
|
||
IncrementCurrentSettingsVersion(&dwVer);
|
||
|
||
} else {
|
||
error = ERROR_INVALID_PARAMETER;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_OFFLINE_SEMANTICS:
|
||
break;
|
||
|
||
case INTERNET_OPTION_SECONDARY_CACHE_KEY:
|
||
if( handleType == TypeHttpRequestHandle ) {
|
||
lphRequest = (INTERNET_CONNECT_HANDLE_OBJECT *)hInternet;
|
||
if (!lphRequest->SetSecondaryCacheKey((LPSTR) lpBuffer)) {
|
||
error = ERROR_NOT_ENOUGH_MEMORY;
|
||
} else {
|
||
INET_ASSERT (error == ERROR_SUCCESS);
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_CALLBACK_FILTER:
|
||
error = ERROR_NOT_SUPPORTED;
|
||
break;
|
||
|
||
case INTERNET_OPTION_REQUEST_PRIORITY:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
if (dwBufferLength == sizeof(LONG)) {
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->
|
||
SetPriority(*(LPLONG)lpBuffer);
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_HTTP_VERSION:
|
||
if (dwBufferLength == sizeof(HTTP_VERSION_INFO)) {
|
||
HttpVersionInfo = *(LPHTTP_VERSION_INFO)lpBuffer;
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_ERROR_MASK:
|
||
lphRequest = (INTERNET_CONNECT_HANDLE_OBJECT *)hInternet;
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
if ( *((LPDWORD) lpBuffer) & ~(INTERNET_ERROR_MASK_INSERT_CDROM |
|
||
INTERNET_ERROR_MASK_COMBINED_SEC_CERT |
|
||
INTERNET_ERROR_MASK_LOGIN_FAILURE_DISPLAY_ENTITY_BODY)) {
|
||
|
||
error = ERROR_INVALID_PARAMETER;
|
||
} else {
|
||
lphRequest->SetErrorMask(*(LPDWORD) lpBuffer);
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_CODEPAGE:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->
|
||
SetCodePage(*(LPDWORD)lpBuffer);
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SEND_UTF8_SERVERNAME_TO_PROXY:
|
||
if (!GlobalSendUTF8ServerToProxy)
|
||
{
|
||
error = ERROR_INTERNET_INVALID_OPTION;
|
||
}
|
||
else if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else if (dwBufferLength != sizeof(DWORD))
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
else
|
||
{
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->
|
||
SetSendUTF8ServerNameToProxy(*(LPDWORD)lpBuffer);
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_DISABLE_AUTODIAL:
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
|
||
DWORD dwValue = *(LPDWORD)lpBuffer;
|
||
|
||
SetAutodialEnable(dwValue == 0);
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_AUTODIAL_MODE:
|
||
if(dwBufferLength == sizeof(DWORD))
|
||
{
|
||
SetAutodialMode(*(LPDWORD)lpBuffer);
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_AUTODIAL_CONNECTION:
|
||
if(dwBufferLength > 0)
|
||
{
|
||
SetAutodialConnection((LPSTR)lpBuffer);
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
// Override to disable NTLM preauth.
|
||
case INTERNET_OPTION_DISABLE_NTLM_PREAUTH:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->
|
||
SetDisableNTLMPreauth(*(LPDWORD)lpBuffer);
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_MAX_CONNS_PER_SERVER:
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
DWORD dwValue = *(LPDWORD)lpBuffer;
|
||
|
||
if( !hInternet )
|
||
{
|
||
GlobalMaxConnectionsPerServer = dwValue;
|
||
// begin a-thkesa:
|
||
// Using NULL should affect the whole process.
|
||
// As per the bug, its not affecting the visited sites.
|
||
// so browse through the server info and set the new limits to all server.
|
||
// WindSE BUG: 243039 & Windows 612742
|
||
CServerInfo * lpServerInfo;
|
||
LockSerializedList(&GlobalServerInfoList);
|
||
for (lpServerInfo = (CServerInfo *)HeadOfSerializedList(&GlobalServerInfoList);
|
||
lpServerInfo != (CServerInfo *)SlSelf(&GlobalServerInfoList);
|
||
lpServerInfo = lpServerInfo->Next())
|
||
{
|
||
lpServerInfo->SetNewLimit(dwValue);
|
||
}
|
||
UnlockSerializedList(&GlobalServerInfoList);
|
||
//end: a-thkesa.
|
||
}
|
||
else
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
|
||
break;
|
||
case INTERNET_OPTION_MAX_CONNS_PER_1_0_SERVER:
|
||
if (dwBufferLength == sizeof(DWORD)) {
|
||
DWORD dwValue = *(LPDWORD)lpBuffer;
|
||
|
||
if( !hInternet )
|
||
{
|
||
GlobalMaxConnectionsPer1_0Server = dwValue;
|
||
// begin a-thkesa:
|
||
// Using NULL should affect the whole process.
|
||
// As per the bug, its not affecting the visited sites.
|
||
// so browse through the server info and set the new limits to all server.
|
||
// WindSE BUG: 243039 & Windows 612742
|
||
CServerInfo * lpServerInfo;
|
||
LockSerializedList(&GlobalServerInfoList);
|
||
for (lpServerInfo = (CServerInfo *)HeadOfSerializedList(&GlobalServerInfoList);
|
||
lpServerInfo != (CServerInfo *)SlSelf(&GlobalServerInfoList);
|
||
lpServerInfo = lpServerInfo->Next())
|
||
{
|
||
lpServerInfo->SetNewLimit(dwValue);
|
||
}
|
||
UnlockSerializedList(&GlobalServerInfoList);
|
||
//end: a-thkesa.
|
||
}
|
||
else
|
||
error = ERROR_INTERNET_INVALID_OPERATION;
|
||
|
||
} else {
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
|
||
break;
|
||
|
||
case INTERNET_OPTION_PER_CONNECTION_OPTION:
|
||
{
|
||
if (handleType != TypeInternetHandle) {
|
||
hInternet = NULL;
|
||
}
|
||
|
||
error = SetPerConnOptions(hInternet,
|
||
lpThreadInfo? lpThreadInfo->IsAutoProxyProxyThread : FALSE,
|
||
(LPINTERNET_PER_CONN_OPTION_LIST)lpBuffer);
|
||
break;
|
||
}
|
||
|
||
case INTERNET_OPTION_IGNORE_OFFLINE:
|
||
if (handleType == TypeHttpRequestHandle) {
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->SetIgnoreOffline();
|
||
} else {
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_IDENTITY:
|
||
if (dwBufferLength==sizeof(IUserIdentity2 *))
|
||
{
|
||
error = ERROR_INVALID_PARAMETER;
|
||
}
|
||
else if (dwBufferLength==sizeof(GUID))
|
||
{
|
||
error = SwitchIdentity((GUID*)lpBuffer);
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_REMOVE_IDENTITY:
|
||
if (dwBufferLength==sizeof(GUID))
|
||
{
|
||
error = RemoveIdentity((GUID*)lpBuffer);
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_ALTER_IDENTITY:
|
||
if (dwBufferLength==sizeof(DWORD))
|
||
{
|
||
error = AlterIdentity(*(LPDWORD)lpBuffer);
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SUPPRESS_BEHAVIOR:
|
||
if (dwBufferLength==sizeof(DWORD))
|
||
{
|
||
error = ERROR_SUCCESS;
|
||
switch (*(LPDWORD)lpBuffer)
|
||
{
|
||
case INTERNET_SUPPRESS_RESET_ALL:
|
||
GlobalSuppressCookiesPolicy = FALSE;
|
||
break;
|
||
|
||
case INTERNET_SUPPRESS_COOKIE_POLICY:
|
||
GlobalSuppressCookiesPolicy = TRUE;
|
||
break;
|
||
|
||
case INTERNET_SUPPRESS_COOKIE_POLICY_RESET:
|
||
GlobalSuppressCookiesPolicy = FALSE;
|
||
break;
|
||
|
||
default:
|
||
error = ERROR_INVALID_PARAMETER;
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_COOKIES_3RD_PARTY:
|
||
if(handleType == TypeHttpRequestHandle)
|
||
{
|
||
if(sizeof(DWORD) == dwBufferLength)
|
||
{
|
||
BOOL f3rdParty = *(BOOL *)lpBuffer;
|
||
|
||
((HTTP_REQUEST_HANDLE_OBJECT *)hInternet)->Set3rdPartyCookies(f3rdParty);
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_BAD_OPTION_LENGTH;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
break;
|
||
|
||
case INTERNET_OPTION_SOCKET_SEND_BUFFER_LENGTH:
|
||
|
||
if (handleType != TypeHttpRequestHandle)
|
||
{
|
||
error = ERROR_INTERNET_INCORRECT_HANDLE_TYPE;
|
||
}
|
||
else if (dwBufferLength < sizeof(DWORD))
|
||
{
|
||
error = ERROR_INSUFFICIENT_BUFFER;
|
||
}
|
||
else
|
||
{
|
||
HTTP_REQUEST_HANDLE_OBJECT *lphHttpRqst;
|
||
|
||
lphHttpRqst = (HTTP_REQUEST_HANDLE_OBJECT *) hInternet;
|
||
|
||
lphHttpRqst->SetSocketSendBufferLength(*(LPDWORD)lpBuffer);
|
||
|
||
error = ERROR_SUCCESS;
|
||
}
|
||
|
||
break;
|
||
|
||
|
||
#if INET_DEBUG
|
||
case INTERNET_OPTION_SET_DEBUG_INFO:
|
||
error = InternetSetDebugInfo((LPINTERNET_DEBUG_INFO)lpBuffer,
|
||
dwBufferLength
|
||
);
|
||
break;
|
||
|
||
#endif // INET_DEBUG
|
||
|
||
default:
|
||
|
||
//
|
||
// this option is not recognized
|
||
//
|
||
|
||
error = ERROR_INTERNET_INVALID_OPTION;
|
||
}
|
||
|
||
quit:
|
||
|
||
//AuthUnlock();
|
||
|
||
if (hObjectMapped != NULL) {
|
||
DereferenceObject((LPVOID)hObjectMapped);
|
||
}
|
||
|
||
done:
|
||
|
||
if (error != ERROR_SUCCESS) {
|
||
|
||
DEBUG_ERROR(API, error);
|
||
|
||
SetLastError(error);
|
||
success = FALSE;
|
||
}
|
||
|
||
DEBUG_LEAVE_API(success);
|
||
|
||
return success;
|
||
}
|
||
|
||
|
||
INTERNETAPI_(BOOL) InternetSetOptionW(
|
||
IN HINTERNET hInternet OPTIONAL,
|
||
IN DWORD dwOption,
|
||
IN LPVOID lpBuffer,
|
||
IN DWORD dwBufferLength
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
description-of-function.
|
||
|
||
Arguments:
|
||
|
||
hInternet -
|
||
|
||
dwOption -
|
||
|
||
lpBuffer -
|
||
|
||
dwBufferLength -
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER_API((DBG_API,
|
||
Bool,
|
||
"InternetSetOptionW",
|
||
"%#x, %s (%d), %#x [%#x], %d",
|
||
hInternet,
|
||
InternetMapOption(dwOption),
|
||
dwOption,
|
||
lpBuffer,
|
||
lpBuffer
|
||
? (!IsBadReadPtr(lpBuffer, sizeof(DWORD))
|
||
? *(LPDWORD)lpBuffer
|
||
: 0)
|
||
: 0,
|
||
dwBufferLength
|
||
));
|
||
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
MEMORYPACKET mpBuffer;
|
||
BOOL fResult = FALSE;
|
||
|
||
switch (dwOption)
|
||
{
|
||
case INTERNET_OPTION_USERNAME:
|
||
case INTERNET_OPTION_PASSWORD:
|
||
case INTERNET_OPTION_DATAFILE_NAME:
|
||
case INTERNET_OPTION_URL:
|
||
case INTERNET_OPTION_USER_AGENT:
|
||
case INTERNET_OPTION_PROXY_USERNAME:
|
||
case INTERNET_OPTION_PROXY_PASSWORD:
|
||
case INTERNET_OPTION_SECONDARY_CACHE_KEY:
|
||
case INTERNET_OPTION_AUTODIAL_CONNECTION:
|
||
ALLOC_MB((LPWSTR)lpBuffer, dwBufferLength, mpBuffer);
|
||
if (!mpBuffer.psStr)
|
||
{
|
||
dwErr = ERROR_NOT_ENOUGH_MEMORY;
|
||
goto cleanup;
|
||
}
|
||
UNICODE_TO_ANSI((LPWSTR)lpBuffer, mpBuffer);
|
||
fResult = InternetSetOptionA(hInternet,
|
||
dwOption,
|
||
mpBuffer.psStr,
|
||
mpBuffer.dwSize
|
||
);
|
||
break;
|
||
|
||
case INTERNET_OPTION_PER_CONNECTION_OPTION:
|
||
{
|
||
if (!lpBuffer)
|
||
{
|
||
dwErr = ERROR_INVALID_PARAMETER;
|
||
goto cleanup;
|
||
}
|
||
|
||
INTERNET_PER_CONN_OPTION_LISTA listA;
|
||
LPINTERNET_PER_CONN_OPTION_LISTW plistW = (LPINTERNET_PER_CONN_OPTION_LISTW)lpBuffer;
|
||
CHAR szEntryA[RAS_MaxEntryName + 1];
|
||
listA.pszConnection = szEntryA;
|
||
|
||
InitIPCOList(plistW, &listA);
|
||
listA.pOptions = (LPINTERNET_PER_CONN_OPTIONA)_alloca(sizeof(INTERNET_PER_CONN_OPTIONA)*listA.dwOptionCount);
|
||
|
||
for (DWORD i=0; i<listA.dwOptionCount; i++)
|
||
{
|
||
listA.pOptions[i].dwOption = plistW->pOptions[i].dwOption;
|
||
|
||
switch (listA.pOptions[i].dwOption)
|
||
{
|
||
case INTERNET_PER_CONN_FLAGS:
|
||
case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
|
||
listA.pOptions[i].Value.dwValue = plistW->pOptions[i].Value.dwValue;
|
||
break;
|
||
|
||
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME:
|
||
listA.pOptions[i].Value.ftValue = plistW->pOptions[i].Value.ftValue;
|
||
break;
|
||
|
||
case INTERNET_PER_CONN_PROXY_SERVER:
|
||
case INTERNET_PER_CONN_PROXY_BYPASS:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_URL:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
|
||
case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL:
|
||
if (plistW->pOptions[i].Value.pszValue && *plistW->pOptions[i].Value.pszValue)
|
||
{
|
||
// ** WARNING ** NO UTF8 ENCODING HERE
|
||
DWORD cb = WideCharToMultiByte(CP_ACP,
|
||
0,
|
||
plistW->pOptions[i].Value.pszValue,
|
||
-1,
|
||
0,
|
||
0,
|
||
NULL,
|
||
NULL);
|
||
listA.pOptions[i].Value.pszValue = (PSTR)_alloca(cb);
|
||
WideCharToMultiByte(CP_ACP,
|
||
0,
|
||
plistW->pOptions[i].Value.pszValue,
|
||
-1,
|
||
listA.pOptions[i].Value.pszValue,
|
||
cb,
|
||
NULL,
|
||
NULL);
|
||
}
|
||
else
|
||
{
|
||
listA.pOptions[i].Value.pszValue = NULL;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
dwErr = ERROR_INVALID_PARAMETER;
|
||
goto cleanup;
|
||
break;
|
||
}
|
||
}
|
||
fResult = InternetSetOptionA(hInternet,
|
||
dwOption,
|
||
(PVOID)&listA,
|
||
dwBufferLength);
|
||
plistW->dwOptionError = listA.dwOptionError;
|
||
}
|
||
break;
|
||
|
||
default:
|
||
fResult = InternetSetOptionA(hInternet,
|
||
dwOption,
|
||
lpBuffer,
|
||
dwBufferLength
|
||
);
|
||
}
|
||
|
||
cleanup:
|
||
if (dwErr!=ERROR_SUCCESS)
|
||
{
|
||
SetLastError(dwErr);
|
||
DEBUG_ERROR(INET, dwErr);
|
||
}
|
||
DEBUG_LEAVE_API(fResult);
|
||
return fResult;
|
||
}
|
||
|
||
|
||
INTERNETAPI_(BOOL) InternetSetOptionExA(
|
||
IN HINTERNET hInternet OPTIONAL,
|
||
IN DWORD dwOption,
|
||
IN LPVOID lpBuffer,
|
||
IN DWORD dwBufferLength,
|
||
IN DWORD dwFlags
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Sets a handle-specific variable, or a per-thread variable
|
||
|
||
Arguments:
|
||
|
||
hInternet - handle of object for which information will be set,
|
||
or NULL if the option defines a per-thread variable
|
||
|
||
dwOption - the handle-specific INTERNET_OPTION to set
|
||
|
||
lpBuffer - pointer to a buffer containing value to set
|
||
|
||
dwBufferLength - size of lpBuffer
|
||
|
||
dwFlags - flags controlling operation. Possible values are:
|
||
|
||
ISO_GLOBAL - set this option globally. The
|
||
shared Wininet data segment will
|
||
be updated with this value
|
||
|
||
ISO_REGISTRY - this value will be written to the
|
||
registry for the corresponding
|
||
entry
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
Success - TRUE
|
||
|
||
Failure - FALSE. Call GetLastError() for more info:
|
||
ERROR_INVALID_HANDLE
|
||
hInternet does not identify a valid Internet handle
|
||
object
|
||
|
||
ERROR_INTERNET_INTERNAL_ERROR
|
||
Shouldn't see this?
|
||
|
||
ERROR_INVALID_PARAMETER
|
||
One of the parameters was bad
|
||
|
||
ERROR_INTERNET_INVALID_OPTION
|
||
The requested option cannot be set
|
||
|
||
ERROR_INTERNET_OPTION_NOT_SETTABLE
|
||
Can't set this option, only query it
|
||
|
||
ERROR_INTERNET_BAD_OPTION_LENGTH
|
||
The dwBufferLength parameter is incorrect for the
|
||
expected type of the option
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER_API((DBG_API,
|
||
Bool,
|
||
"InternetSetOptionExA",
|
||
"%#x, %s (%d), %#x [%#x], %d, %#x",
|
||
hInternet,
|
||
InternetMapOption(dwOption),
|
||
dwOption,
|
||
lpBuffer,
|
||
lpBuffer
|
||
? (!IsBadReadPtr(lpBuffer, sizeof(DWORD))
|
||
? *(LPDWORD)lpBuffer
|
||
: 0)
|
||
: 0,
|
||
dwBufferLength,
|
||
dwFlags
|
||
));
|
||
|
||
BOOL success;
|
||
|
||
//
|
||
// validate parameters
|
||
//
|
||
|
||
//
|
||
// currently, dwFlags MBZ
|
||
//
|
||
|
||
if (dwFlags == 0) {
|
||
success = InternetSetOptionA(hInternet,
|
||
dwOption,
|
||
lpBuffer,
|
||
dwBufferLength
|
||
);
|
||
} else {
|
||
DEBUG_ERROR(INET, ERROR_INVALID_PARAMETER);
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
success = FALSE;
|
||
}
|
||
|
||
DEBUG_LEAVE_API(success);
|
||
return success;
|
||
}
|
||
|
||
|
||
INTERNETAPI_(BOOL) InternetSetOptionExW(
|
||
IN HINTERNET hInternet OPTIONAL,
|
||
IN DWORD dwOption,
|
||
IN LPVOID lpBuffer,
|
||
IN DWORD dwBufferLength,
|
||
IN DWORD dwFlags
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
description-of-function.
|
||
|
||
Arguments:
|
||
|
||
hInternet -
|
||
|
||
dwOption -
|
||
|
||
lpBuffer -
|
||
|
||
dwBufferLength -
|
||
|
||
dwFlags -
|
||
|
||
Return Value:
|
||
|
||
BOOL
|
||
|
||
--*/
|
||
|
||
{
|
||
DEBUG_ENTER_API((DBG_API,
|
||
Bool,
|
||
"InternetSetOptionExW",
|
||
"%#x, %s (%d), %#x [%#x], %d, %#x",
|
||
hInternet,
|
||
InternetMapOption(dwOption),
|
||
dwOption,
|
||
lpBuffer,
|
||
lpBuffer
|
||
? (!IsBadReadPtr(lpBuffer, sizeof(DWORD))
|
||
? *(LPDWORD)lpBuffer
|
||
: 0)
|
||
: 0,
|
||
dwBufferLength,
|
||
dwFlags
|
||
));
|
||
|
||
BOOL fResult = FALSE;
|
||
|
||
if (dwFlags)
|
||
{
|
||
DEBUG_ERROR(INET, ERROR_INVALID_PARAMETER);
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
}
|
||
else
|
||
{
|
||
fResult = InternetSetOptionW(hInternet,
|
||
dwOption,
|
||
lpBuffer,
|
||
dwBufferLength
|
||
);
|
||
}
|
||
|
||
DEBUG_LEAVE_API(fResult);
|
||
return fResult;
|
||
}
|
||
|
||
|
||
PRIVATE
|
||
BOOL
|
||
FValidCacheHandleType(
|
||
HINTERNET_HANDLE_TYPE hType
|
||
)
|
||
{
|
||
return ((hType != TypeInternetHandle) &&
|
||
(hType != TypeFtpConnectHandle) &&
|
||
(hType != TypeGopherConnectHandle) &&
|
||
(hType != TypeFileRequestHandle) &&
|
||
(hType != TypeHttpConnectHandle));
|
||
}
|
||
|