You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3582 lines
90 KiB
3582 lines
90 KiB
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
inetdbg.cxx
|
|
|
|
Abstract:
|
|
|
|
Debugging functions for internet DLL
|
|
|
|
Contents:
|
|
InternetDebugInitialize
|
|
InternetDebugTerminate
|
|
InternetGetDebugInfo
|
|
InternetSetDebugInfo
|
|
InternetOpenDebugFile
|
|
InternetReopenDebugFile
|
|
InternetCloseDebugFile
|
|
InternetFlushDebugFile
|
|
InternetDebugSetControlFlags
|
|
InternetDebugResetControlFlags
|
|
InternetDebugEnter
|
|
InternetDebugLeave
|
|
InternetDebugError
|
|
InternetDebugPrint
|
|
(InternetDebugPrintString)
|
|
InternetDebugPrintf
|
|
InternetDebugOut
|
|
InternetDebugDump
|
|
InternetDebugDumpFormat
|
|
InternetAssert
|
|
InternetGetDebugVariable
|
|
(InternetGetDebugVariableString)
|
|
InternetMapError
|
|
InternetMapStatus
|
|
InternetMapOption
|
|
InternetMapHttpOption
|
|
InternetMapHttpState
|
|
InternetMapHttpStateFlag
|
|
InternetMapAsyncRequest
|
|
InternetMapHandleType
|
|
InternetMapScheme
|
|
InternetMapOpenType
|
|
InternetMapService
|
|
(ExtractFileName)
|
|
(SetDebugPrefix)
|
|
SourceFilename
|
|
InitSymLib
|
|
TermSymLib
|
|
GetDebugSymbol
|
|
x86SleazeCallStack
|
|
x86SleazeCallersAddress
|
|
|
|
Author:
|
|
|
|
Richard L Firth (rfirth) 13-Feb-1995
|
|
|
|
Environment:
|
|
|
|
Win32(s) user-mode DLL
|
|
|
|
Revision History:
|
|
|
|
13-Feb-1995 rfirth
|
|
Created
|
|
|
|
--*/
|
|
|
|
#include <wininetp.h>
|
|
#include <ntverp.h>
|
|
|
|
#ifdef WINHTTP_FOR_MSMXL
|
|
#include <ieverp.h>
|
|
#endif
|
|
|
|
#include "rprintf.h"
|
|
#include <imagehlp.h>
|
|
|
|
#ifdef ENABLE_DEBUG
|
|
|
|
//
|
|
// private manifests
|
|
//
|
|
|
|
#define SWITCH_VARIABLE_NAME "WinHttpDebugging"
|
|
#define CONTROL_VARIABLE_NAME "WinHttpControl"
|
|
#define CATEGORY_VARIABLE_NAME "WinHttpCategory"
|
|
#define ERROR_VARIABLE_NAME "WinHttpError"
|
|
#define BREAK_VARIABLE_NAME "WinHttpBreak"
|
|
//#define DEFAULT_LOG_VARIABLE_NAME "WinHttpxLog"
|
|
#define CHECK_LIST_VARIABLE_NAME "WinHttpCheckSerializedList"
|
|
#define LOG_FILE_VARIABLE_NAME "WinHttpLogFile"
|
|
#define INDENT_VARIABLE_NAME "WinHttpLogIndent"
|
|
|
|
#define DEFAULT_LOG_FILE_NAME "WINHTTP5.LOG"
|
|
|
|
#define ENVIRONMENT_VARIABLE_BUFFER_LENGTH 80
|
|
|
|
#define PRINTF_STACK_BUFFER_LENGTH (4 K)
|
|
|
|
//
|
|
// private macros
|
|
//
|
|
|
|
#define CASE_OF(constant) case constant: return # constant
|
|
|
|
//
|
|
// private prototypes
|
|
//
|
|
|
|
PRIVATE
|
|
VOID
|
|
InternetDebugPrintString(
|
|
IN LPSTR String
|
|
);
|
|
|
|
PRIVATE
|
|
VOID
|
|
InternetGetDebugVariableString(
|
|
IN LPSTR lpszVariableName,
|
|
OUT LPSTR lpszVariable,
|
|
IN DWORD dwVariableLen
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
ExtractFileName(
|
|
IN LPSTR Module,
|
|
OUT LPSTR Buf
|
|
);
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
SetDebugPrefix(
|
|
IN LPSTR Buffer
|
|
);
|
|
//
|
|
//
|
|
// these variables are employed in macros, so must be public
|
|
//
|
|
|
|
PUBLIC DWORD InternetDebugErrorLevel = DBG_ERROR;
|
|
PUBLIC DWORD InternetDebugControlFlags = DBG_NO_DEBUG;
|
|
PUBLIC DWORD InternetDebugCategoryFlags = 0;
|
|
PUBLIC DWORD InternetDebugBreakFlags = 0;
|
|
|
|
//
|
|
// these variables are only accessed in this module, so can be private
|
|
//
|
|
|
|
PRIVATE int InternetDebugIndentIncrement = 2;
|
|
PRIVATE HANDLE InternetDebugFileHandle = INVALID_HANDLE_VALUE;
|
|
PRIVATE char InternetDebugFilename[MAX_PATH + 1] = DEFAULT_LOG_FILE_NAME;
|
|
PRIVATE BOOL InternetDebugEnabled = TRUE;
|
|
PRIVATE DWORD InternetDebugStartTime = 0;
|
|
|
|
extern "C" {
|
|
BOOL UrlcacheDebugEnabled = FALSE;
|
|
#if defined(UNIX) && defined(ux10)
|
|
/* Temporary fix for Apogee Compiler bug on HP only */
|
|
extern BOOL fCheckEntryOnList;
|
|
#else
|
|
BOOL fCheckEntryOnList;
|
|
#endif /* UNIX */
|
|
}
|
|
|
|
//
|
|
// high frequency performance counter globals
|
|
//
|
|
|
|
|
|
PRIVATE LONGLONG ftInit; // initial local time
|
|
PRIVATE LONGLONG pcInit; // initial perf counter
|
|
PRIVATE LONGLONG pcFreq; // perf counter frequency
|
|
|
|
//
|
|
// functions
|
|
//
|
|
|
|
|
|
VOID
|
|
InternetDebugInitialize(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
reads environment INETDBG flags and opens debug log file if required
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
#ifndef WININET_SERVER_CORE
|
|
//
|
|
// ensure registry key open (normally done in GlobalDataInitialize() later)
|
|
//
|
|
|
|
#endif //!WININET_SERVER_CORE
|
|
|
|
OpenInternetSettingsKey();
|
|
|
|
//
|
|
// record the starting tick count for cumulative deltas
|
|
//
|
|
|
|
InternetDebugStartTime = GetTickCountWrap();
|
|
|
|
if (QueryPerformanceFrequency ((LARGE_INTEGER *) &pcFreq) && pcFreq) {
|
|
|
|
QueryPerformanceCounter ((LARGE_INTEGER *) &pcInit);
|
|
SYSTEMTIME st;
|
|
GetLocalTime (&st);
|
|
SystemTimeToFileTime (&st, (FILETIME *) &ftInit);
|
|
}
|
|
|
|
//
|
|
// check see if there are any debug variable overrides in the environment
|
|
// or the registry. If "WinHttpLog=<!0>" is set then we use the flags that
|
|
// are most commonly used to generate WININET.LOG, with no console or
|
|
// debugger output. We allow the other variables to be overridden
|
|
//
|
|
|
|
char WinHttpVer[16] = {0};
|
|
BOOL defaultDebugVariables = FALSE;
|
|
rsprintf(WinHttpVer,
|
|
"WinHttp%dLog",
|
|
InternetVersionInfo.dwMajorVersion);
|
|
|
|
|
|
InternetGetDebugVariable(WinHttpVer, (LPDWORD)&defaultDebugVariables);
|
|
if (!defaultDebugVariables)
|
|
{
|
|
InternetGetDebugVariable(SWITCH_VARIABLE_NAME, (LPDWORD)&defaultDebugVariables);
|
|
}
|
|
|
|
if (defaultDebugVariables) {
|
|
InternetDebugEnabled = TRUE;
|
|
InternetDebugControlFlags = INTERNET_DEBUG_CONTROL_DEFAULT;
|
|
InternetDebugCategoryFlags = INTERNET_DEBUG_CATEGORY_DEFAULT;
|
|
InternetDebugErrorLevel = INTERNET_DEBUG_ERROR_LEVEL_DEFAULT;
|
|
InternetDebugBreakFlags = 0;
|
|
}
|
|
|
|
// InternetGetDebugVariable(SWITCH_VARIABLE_NAME, (LPDWORD)&InternetDebugEnabled);
|
|
InternetGetDebugVariable(CONTROL_VARIABLE_NAME, &InternetDebugControlFlags);
|
|
InternetGetDebugVariable(CATEGORY_VARIABLE_NAME, &InternetDebugCategoryFlags);
|
|
InternetGetDebugVariable(ERROR_VARIABLE_NAME, &InternetDebugErrorLevel);
|
|
InternetGetDebugVariable(BREAK_VARIABLE_NAME, &InternetDebugBreakFlags);
|
|
InternetGetDebugVariable(CHECK_LIST_VARIABLE_NAME, (LPDWORD)&fCheckEntryOnList);
|
|
InternetGetDebugVariable(INDENT_VARIABLE_NAME, (LPDWORD)&InternetDebugIndentIncrement);
|
|
InternetGetDebugVariableString(LOG_FILE_VARIABLE_NAME,
|
|
InternetDebugFilename,
|
|
sizeof(InternetDebugFilename)
|
|
);
|
|
|
|
UrlcacheDebugEnabled = InternetDebugEnabled &&
|
|
(InternetDebugCategoryFlags & DBG_CACHE);
|
|
|
|
if ((InternetDebugIndentIncrement < 0) || (InternetDebugIndentIncrement > 32)) {
|
|
InternetDebugIndentIncrement = 2;
|
|
}
|
|
|
|
//
|
|
// quit now if debugging is disabled
|
|
//
|
|
|
|
if (!InternetDebugEnabled) {
|
|
InternetDebugControlFlags |= (DBG_NO_DEBUG | DBG_NO_DATA_DUMP);
|
|
return;
|
|
}
|
|
|
|
//
|
|
// if we want to write debug output to file, open WININET.LOG in the current
|
|
// directory. Open it in text mode, for write-only (by this process)
|
|
//
|
|
|
|
if (InternetDebugControlFlags & DBG_TO_FILE) {
|
|
if (!InternetReopenDebugFile(InternetDebugFilename)) {
|
|
InternetDebugControlFlags &= ~DBG_TO_FILE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// install the debug exception handler
|
|
//
|
|
|
|
SetExceptionHandler();
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugTerminate(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Performs any required debug termination
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugControlFlags & DBG_TO_FILE) {
|
|
InternetCloseDebugFile();
|
|
}
|
|
InternetDebugControlFlags = DBG_NO_DEBUG;
|
|
|
|
CloseInternetSettingsKey();
|
|
}
|
|
|
|
DWORD
|
|
InternetGetDebugInfo(
|
|
OUT LPINTERNET_DEBUG_INFO lpBuffer,
|
|
IN OUT LPDWORD lpdwBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Returns the internal debug variables
|
|
|
|
Arguments:
|
|
|
|
lpBuffer - pointer to structure that receives the variables
|
|
|
|
lpdwBufferLength - IN: Length of buffer
|
|
OUT: length of returned data if successful, else
|
|
required length of buffer
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
Success - ERROR_SUCCESS;
|
|
|
|
Failure - ERROR_INSUFFICIENT_BUFFER
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD requiredLength;
|
|
DWORD error;
|
|
int filenameLength;
|
|
|
|
filenameLength = ((InternetDebugFileHandle != INVALID_HANDLE_VALUE)
|
|
? strlen(InternetDebugFilename) : 0) + 1;
|
|
|
|
requiredLength = sizeof(*lpBuffer) + filenameLength;
|
|
if ((lpBuffer != NULL) && (*lpdwBufferLength >= requiredLength)) {
|
|
lpBuffer->ErrorLevel = InternetDebugErrorLevel;
|
|
lpBuffer->ControlFlags = InternetDebugControlFlags;
|
|
lpBuffer->CategoryFlags = InternetDebugCategoryFlags;
|
|
lpBuffer->BreakFlags = InternetDebugBreakFlags;
|
|
lpBuffer->IndentIncrement = InternetDebugIndentIncrement;
|
|
if (InternetDebugFileHandle != INVALID_HANDLE_VALUE) {
|
|
memcpy(lpBuffer->Filename, InternetDebugFilename, filenameLength);
|
|
} else {
|
|
lpBuffer->Filename[0] = '\0';
|
|
}
|
|
error = ERROR_SUCCESS;
|
|
} else {
|
|
error = ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
*lpdwBufferLength = requiredLength;
|
|
return error;
|
|
}
|
|
|
|
|
|
DWORD
|
|
InternetSetDebugInfo(
|
|
IN LPINTERNET_DEBUG_INFO lpBuffer,
|
|
IN DWORD dwBufferLength
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets the internal debugging variables to the values in the buffer. To make
|
|
incrmental changes, the caller must first read the variables, change the
|
|
bits they're interested in, then change the whole lot at one go
|
|
|
|
Arguments:
|
|
|
|
lpBuffer - pointer to structure that contains the variables
|
|
|
|
dwBufferLength - size of lpBuffer. Ignored
|
|
|
|
Return Value:
|
|
|
|
DWORD
|
|
Success - ERROR_SUCCESS
|
|
|
|
Failure -
|
|
|
|
--*/
|
|
|
|
{
|
|
InternetDebugErrorLevel = lpBuffer->ErrorLevel;
|
|
InternetDebugCategoryFlags = lpBuffer->CategoryFlags;
|
|
InternetDebugControlFlags = lpBuffer->ControlFlags;
|
|
InternetDebugBreakFlags = lpBuffer->BreakFlags;
|
|
InternetDebugIndentIncrement = lpBuffer->IndentIncrement;
|
|
|
|
//
|
|
// handle the debug file. If we get an empty string, then (if we are logging
|
|
// to a file), close the file.
|
|
//
|
|
// If the filename is exactly the same as we're already using, then the
|
|
// caller doesn't want to change the log file
|
|
//
|
|
// If the filename is different, then we are being asked to create a new log
|
|
// file: close the old and open the new. If we cannot open the new file then
|
|
// set the filename to the NUL string in the debug buffer
|
|
//
|
|
|
|
if (lpBuffer->Filename[0]) {
|
|
if (strcmp(InternetDebugFilename, lpBuffer->Filename) != 0) {
|
|
InternetCloseDebugFile();
|
|
InternetReopenDebugFile(lpBuffer->Filename);
|
|
if (InternetDebugFileHandle != INVALID_HANDLE_VALUE) {
|
|
strcpy(InternetDebugFilename, lpBuffer->Filename);
|
|
} else {
|
|
lpBuffer->Filename[0] = '\0';
|
|
}
|
|
}
|
|
} else {
|
|
InternetCloseDebugFile();
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
BOOL
|
|
InternetOpenDebugFile(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Opens debug filename if not already open. Use InternetDebugFilename
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
BOOL
|
|
TRUE - file was opened
|
|
|
|
FALSE - file not opened (already open or error)
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugFileHandle == INVALID_HANDLE_VALUE) {
|
|
InternetDebugFileHandle = CreateFile(
|
|
InternetDebugFilename,
|
|
GENERIC_WRITE,
|
|
FILE_SHARE_READ,
|
|
NULL, // lpSecurityAttributes
|
|
(InternetDebugControlFlags & DBG_APPEND_FILE)
|
|
? OPEN_ALWAYS
|
|
: CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL
|
|
| FILE_FLAG_SEQUENTIAL_SCAN
|
|
| ((InternetDebugControlFlags & DBG_FLUSH_OUTPUT)
|
|
? FILE_FLAG_WRITE_THROUGH
|
|
: 0),
|
|
NULL
|
|
);
|
|
return InternetDebugFileHandle != INVALID_HANDLE_VALUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
InternetReopenDebugFile(
|
|
IN LPSTR Filename
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
(Re)opens a debug log file. Closes the current one if it is open
|
|
|
|
Arguments:
|
|
|
|
Filename - new file to open
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugFileHandle != INVALID_HANDLE_VALUE) {
|
|
InternetCloseDebugFile();
|
|
}
|
|
if (Filename && *Filename) {
|
|
InternetDebugFileHandle = CreateFile(
|
|
Filename,
|
|
GENERIC_WRITE,
|
|
FILE_SHARE_READ,
|
|
NULL, // lpSecurityAttributes
|
|
(InternetDebugControlFlags & DBG_APPEND_FILE)
|
|
? OPEN_ALWAYS
|
|
: CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL
|
|
| FILE_FLAG_SEQUENTIAL_SCAN
|
|
| ((InternetDebugControlFlags & DBG_FLUSH_OUTPUT)
|
|
? FILE_FLAG_WRITE_THROUGH
|
|
: 0),
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// put our start info in the log file. Mainly useful when we're
|
|
// appending to the file
|
|
//
|
|
|
|
if (InternetDebugFileHandle != INVALID_HANDLE_VALUE) {
|
|
|
|
SYSTEMTIME currentTime;
|
|
char filespec[MAX_PATH + 1];
|
|
LPSTR filename;
|
|
|
|
if (GetModuleFileName(NULL, filespec, sizeof(filespec))) {
|
|
filename = strrchr(filespec, '\\');
|
|
if (filename != NULL) {
|
|
++filename;
|
|
} else {
|
|
filename = filespec;
|
|
}
|
|
} else {
|
|
filename = "";
|
|
}
|
|
|
|
InternetDebugGetLocalTime(¤tTime, NULL);
|
|
|
|
InternetDebugPrintf("\n"
|
|
">>>> WinHttpX Version %d.%d Build %s.%d " __DATE__ " " __TIME__ "\n"
|
|
">>>> Process %s [%d (%#x)] started at %02d:%02d:%02d.%03d %02d/%02d/%d\n",
|
|
InternetVersionInfo.dwMajorVersion,
|
|
InternetVersionInfo.dwMinorVersion,
|
|
#ifdef WINHTTP_FOR_MSXML // fix MSXML build
|
|
"5.00",
|
|
#else
|
|
VER_PRODUCTVERSION_STRING,
|
|
#endif
|
|
InternetBuildNumber,
|
|
filename,
|
|
GetCurrentProcessId(),
|
|
GetCurrentProcessId(),
|
|
currentTime.wHour,
|
|
currentTime.wMinute,
|
|
currentTime.wSecond,
|
|
currentTime.wMilliseconds,
|
|
currentTime.wMonth,
|
|
currentTime.wDay,
|
|
currentTime.wYear
|
|
);
|
|
|
|
InternetDebugPrintf(">>>> Command line = %q\n", GetCommandLine());
|
|
|
|
InternetDebugPrintf("\n"
|
|
" InternetDebugErrorLevel = %s [%d]\n"
|
|
" InternetDebugControlFlags = %#08x\n"
|
|
" InternetDebugCategoryFlags = %#08x\n"
|
|
" InternetDebugBreakFlags = %#08x\n"
|
|
" InternetDebugIndentIncrement = %d\n"
|
|
"\n",
|
|
(InternetDebugErrorLevel == DBG_INFO) ? "Info"
|
|
: (InternetDebugErrorLevel == DBG_WARNING) ? "Warning"
|
|
: (InternetDebugErrorLevel == DBG_ERROR) ? "Error"
|
|
: (InternetDebugErrorLevel == DBG_FATAL) ? "Fatal"
|
|
: (InternetDebugErrorLevel == DBG_ALWAYS) ? "Always"
|
|
: "?",
|
|
InternetDebugErrorLevel,
|
|
InternetDebugControlFlags,
|
|
InternetDebugCategoryFlags,
|
|
InternetDebugBreakFlags,
|
|
InternetDebugIndentIncrement
|
|
);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetCloseDebugFile(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Closes the current debug log file
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugFileHandle != INVALID_HANDLE_VALUE) {
|
|
if (InternetDebugControlFlags & DBG_FLUSH_OUTPUT) {
|
|
InternetFlushDebugFile();
|
|
}
|
|
CloseHandle(InternetDebugFileHandle);
|
|
InternetDebugFileHandle = INVALID_HANDLE_VALUE;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetFlushDebugFile(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
description-of-function.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugFileHandle != INVALID_HANDLE_VALUE) {
|
|
FlushFileBuffers(InternetDebugFileHandle);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugSetControlFlags(
|
|
IN DWORD dwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets debug control flags
|
|
|
|
Arguments:
|
|
|
|
dwFlags - flags to set
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
InternetDebugControlFlags |= dwFlags;
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugResetControlFlags(
|
|
IN DWORD dwFlags
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Resets debug control flags
|
|
|
|
Arguments:
|
|
|
|
dwFlags - flags to reset
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
InternetDebugControlFlags &= ~dwFlags;
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugEnter(
|
|
IN DWORD Category,
|
|
IN DEBUG_FUNCTION_RETURN_TYPE ReturnType,
|
|
IN LPCSTR Function,
|
|
IN LPCSTR ParameterList OPTIONAL,
|
|
IN ...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Creates an INTERNET_DEBUG_RECORD for the current function and adds it to
|
|
the per-thread (debug) call-tree
|
|
|
|
Arguments:
|
|
|
|
Category - category flags, e.g. DBG_FTP
|
|
|
|
ReturnType - type of data it returns
|
|
|
|
Function - name of the function. Must be global, static string
|
|
|
|
ParameterList - string describing parameters to function, or NULL if none
|
|
|
|
... - parameters to function
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPINTERNET_THREAD_INFO pThreadInfo;
|
|
LPINTERNET_DEBUG_RECORD pRecord;
|
|
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
pThreadInfo = InternetGetThreadInfo();
|
|
|
|
//INET_ASSERT(pThreadInfo != NULL);
|
|
|
|
if (!pThreadInfo) {
|
|
return;
|
|
}
|
|
|
|
pRecord = NEW(INTERNET_DEBUG_RECORD);
|
|
|
|
//INET_ASSERT(pRecord != NULL);
|
|
|
|
if (!pRecord) {
|
|
return;
|
|
}
|
|
|
|
pRecord->Stack = pThreadInfo->Stack;
|
|
pRecord->Category = Category;
|
|
pRecord->ReturnType = ReturnType;
|
|
pRecord->Function = Function;
|
|
pRecord->LastTime = GetTickCountWrap();
|
|
pThreadInfo->Stack = pRecord;
|
|
++pThreadInfo->CallDepth;
|
|
|
|
//
|
|
// if the function's category (FTP, GOPHER, HTTP) is selected in the
|
|
// category flags, then we dump the function entry information
|
|
//
|
|
|
|
if (InternetDebugCategoryFlags & Category) {
|
|
|
|
char buf[4096];
|
|
LPSTR bufptr;
|
|
|
|
bufptr = buf;
|
|
bufptr += rsprintf(bufptr, "%s(", Function);
|
|
if (ARGUMENT_PRESENT(ParameterList)) {
|
|
|
|
va_list parms;
|
|
|
|
va_start(parms, ParameterList);
|
|
bufptr += _sprintf(bufptr, (char*)ParameterList, parms);
|
|
va_end(parms);
|
|
}
|
|
rsprintf(bufptr, ")\n");
|
|
InternetDebugPrintString(buf);
|
|
|
|
//
|
|
// only increase the indentation if we will display debug information
|
|
// for this category
|
|
//
|
|
|
|
pThreadInfo->IndentIncrement += InternetDebugIndentIncrement;
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugLeave(
|
|
IN DWORD_PTR Variable,
|
|
IN LPCSTR Filename,
|
|
IN DWORD LineNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destroys the INTERNET_DEBUG_RECORD for the current function and dumps info
|
|
about what the function is returning, if requested to do so
|
|
|
|
Arguments:
|
|
|
|
Variable - variable containing value being returned by function
|
|
|
|
Filename - name of file where DEBUG_LEAVE() invoked
|
|
|
|
LineNumber - and line number in Filename
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPINTERNET_THREAD_INFO pThreadInfo;
|
|
LPINTERNET_DEBUG_RECORD pRecord;
|
|
LPSTR format;
|
|
LPSTR errstr;
|
|
BOOL noVar;
|
|
char formatBuf[128];
|
|
DWORD lastError;
|
|
char hexnumBuf[15];
|
|
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// seems that something in this path can nuke the last error, so we must
|
|
// refresh it
|
|
//
|
|
|
|
lastError = GetLastError();
|
|
|
|
pThreadInfo = InternetGetThreadInfo();
|
|
|
|
//INET_ASSERT(pThreadInfo != NULL);
|
|
|
|
if (!pThreadInfo) {
|
|
return;
|
|
}
|
|
|
|
pRecord = pThreadInfo->Stack;
|
|
|
|
//INET_ASSERT(pRecord != NULL);
|
|
|
|
if (!pRecord) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// we are about to output a diagnostic message to the debug log, debugger,
|
|
// or console. First check that we are required to display messages at
|
|
// this level. The level for function ENTER and LEAVE is INFO
|
|
//
|
|
|
|
if (InternetDebugErrorLevel <= DBG_INFO) {
|
|
|
|
//
|
|
// only display the string and reduce the indent if we are requested
|
|
// for information about this category
|
|
//
|
|
|
|
errstr = NULL;
|
|
noVar = FALSE;
|
|
if (InternetDebugCategoryFlags & pRecord->Category) {
|
|
switch (pRecord->ReturnType) {
|
|
case None:
|
|
format = "%s() returning VOID";
|
|
noVar = TRUE;
|
|
break;
|
|
|
|
case Bool:
|
|
Variable = (DWORD_PTR)(Variable ? "TRUE" : "FALSE");
|
|
|
|
//
|
|
// *** FALL THROUGH ***
|
|
//
|
|
|
|
case String:
|
|
format = "%s() returning %s";
|
|
break;
|
|
|
|
case Int:
|
|
format = "%s() returning %d";
|
|
break;
|
|
|
|
case Dword:
|
|
format = "%s() returning %u";
|
|
errstr = InternetMapError((DWORD)Variable);
|
|
if (errstr != NULL) {
|
|
if (*errstr == '?') {
|
|
rsprintf(hexnumBuf, "%#x", Variable);
|
|
errstr = hexnumBuf;
|
|
format = "%s() returning %u [?] (%s)";
|
|
} else {
|
|
format = "%s() returning %u [%s]";
|
|
}
|
|
}
|
|
break;
|
|
|
|
case Handle:
|
|
case Pointer:
|
|
if (Variable == 0) {
|
|
format = "%s() returning NULL";
|
|
noVar = TRUE;
|
|
} else {
|
|
if (pRecord->ReturnType == Handle) {
|
|
format = "%s() returning handle %#x";
|
|
} else {
|
|
format = "%s() returning %#x";
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
INET_ASSERT(FALSE);
|
|
|
|
break;
|
|
}
|
|
|
|
pThreadInfo->IndentIncrement -= InternetDebugIndentIncrement;
|
|
if (pThreadInfo->IndentIncrement < 0) {
|
|
pThreadInfo->IndentIncrement = 0;
|
|
}
|
|
|
|
//
|
|
// add line number info, if requested
|
|
//
|
|
|
|
strcpy(formatBuf, format);
|
|
if (!(InternetDebugControlFlags & DBG_NO_LINE_NUMBER)) {
|
|
strcat(formatBuf, " (line %d)");
|
|
}
|
|
strcat(formatBuf, "\n");
|
|
|
|
//
|
|
// output an empty line if we are required to separate API calls in
|
|
// the log. Only do this if this is an API level function, and it
|
|
// is the top-level function
|
|
//
|
|
|
|
if ((InternetDebugControlFlags & DBG_SEPARATE_APIS)
|
|
&& (pRecord->Stack == NULL)) {
|
|
strcat(formatBuf, "\n");
|
|
}
|
|
|
|
//
|
|
// dump the line, depending on requirements and number of arguments
|
|
//
|
|
|
|
if (noVar) {
|
|
InternetDebugPrint(formatBuf,
|
|
pRecord->Function,
|
|
LineNumber
|
|
);
|
|
} else if (errstr != NULL) {
|
|
InternetDebugPrint(formatBuf,
|
|
pRecord->Function,
|
|
Variable,
|
|
errstr,
|
|
LineNumber
|
|
);
|
|
} else {
|
|
InternetDebugPrint(formatBuf,
|
|
pRecord->Function,
|
|
Variable,
|
|
LineNumber
|
|
);
|
|
}
|
|
/*
|
|
//
|
|
// output an empty line if we are required to separate API calls in
|
|
// the log. Only do this if this is an API level function, and it
|
|
// is the top-level function
|
|
//
|
|
|
|
if ((InternetDebugControlFlags & DBG_SEPARATE_APIS)
|
|
&& (pRecord->Stack == NULL)) {
|
|
|
|
//
|
|
// don't call InternetDebugPrint - we don't need timing, thread,
|
|
// level etc. information just for the separator
|
|
//
|
|
|
|
InternetDebugOut("\n", FALSE);
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
//
|
|
// regardless of whether we are outputting debug info for this category,
|
|
// remove the debug record and reduce the call-depth
|
|
//
|
|
|
|
--pThreadInfo->CallDepth;
|
|
pThreadInfo->Stack = pRecord->Stack;
|
|
|
|
DEL(pRecord);
|
|
|
|
//
|
|
// refresh the last error, in case it was nuked
|
|
//
|
|
|
|
SetLastError(lastError);
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugError(
|
|
IN DWORD Error
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Used to display that a function is returning an error. We try to display a
|
|
symbolic name for the error too (as when we are returning a DWORD from a
|
|
function, using DEBUG_LEAVE)
|
|
|
|
Displays a string of the form:
|
|
|
|
Foo() returning error 87 [ERROR_INVALID_PARAMETER]
|
|
|
|
Arguments:
|
|
|
|
Error - the error code
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPINTERNET_THREAD_INFO pThreadInfo;
|
|
LPINTERNET_DEBUG_RECORD pRecord;
|
|
LPSTR errstr;
|
|
DWORD lastError;
|
|
char hexnumBuf[15];
|
|
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// seems that something in this path can nuke the last error, so we must
|
|
// refresh it
|
|
//
|
|
|
|
lastError = GetLastError();
|
|
|
|
pThreadInfo = InternetGetThreadInfo();
|
|
|
|
//INET_ASSERT(pThreadInfo != NULL);
|
|
INET_ASSERT(GetLastError() == lastError);
|
|
|
|
if (pThreadInfo == NULL) {
|
|
return;
|
|
}
|
|
|
|
pRecord = pThreadInfo->Stack;
|
|
|
|
//INET_ASSERT(pRecord != NULL);
|
|
|
|
if (pRecord == NULL) {
|
|
return;
|
|
}
|
|
|
|
errstr = InternetMapError(Error);
|
|
if ((errstr == NULL) || (*errstr == '?')) {
|
|
rsprintf(hexnumBuf, "%#x", Error);
|
|
errstr = hexnumBuf;
|
|
}
|
|
InternetDebugPrint("%s() returning %d [%s]\n",
|
|
pRecord->Function,
|
|
Error,
|
|
errstr
|
|
);
|
|
|
|
//
|
|
// refresh the last error, in case it was nuked
|
|
//
|
|
|
|
SetLastError(lastError);
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugPrint(
|
|
IN LPSTR Format,
|
|
...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Internet equivalent of printf()
|
|
|
|
Arguments:
|
|
|
|
Format - printf format string
|
|
|
|
... - any extra args
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
char buf[PRINTF_STACK_BUFFER_LENGTH];
|
|
LPSTR bufptr;
|
|
|
|
bufptr = SetDebugPrefix(buf);
|
|
if (bufptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// now append the string that the DEBUG_PRINT originally gave us
|
|
//
|
|
|
|
va_list list;
|
|
|
|
va_start(list, Format);
|
|
_sprintf(bufptr, Format, list);
|
|
va_end(list);
|
|
|
|
InternetDebugOut(buf, FALSE);
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugPrintValist(
|
|
IN LPSTR Format,
|
|
va_list list
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Internet equivalent of printf(), but takes valist as the args
|
|
|
|
Arguments:
|
|
|
|
Format - printf format string
|
|
|
|
list - stack frame of variable arguments
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
char buf[PRINTF_STACK_BUFFER_LENGTH];
|
|
LPSTR bufptr;
|
|
|
|
bufptr = SetDebugPrefix(buf);
|
|
if (bufptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
_sprintf(bufptr, Format, list);
|
|
|
|
InternetDebugOut(buf, FALSE);
|
|
}
|
|
|
|
|
|
PRIVATE
|
|
VOID
|
|
InternetDebugPrintString(
|
|
IN LPSTR String
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Same as InternetDebugPrint(), except we perform no expansion on the string
|
|
|
|
Arguments:
|
|
|
|
String - already formatted string (may contain %s)
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
char buf[PRINTF_STACK_BUFFER_LENGTH];
|
|
LPSTR bufptr;
|
|
|
|
bufptr = SetDebugPrefix(buf);
|
|
if (bufptr == NULL) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// now append the string that the DEBUG_PRINT originally gave us
|
|
//
|
|
|
|
strcpy(bufptr, String);
|
|
|
|
InternetDebugOut(buf, FALSE);
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugPrintf(
|
|
IN LPSTR Format,
|
|
IN ...
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Same as InternetDebugPrint(), but we don't access the per-thread info
|
|
(because we may not have any)
|
|
|
|
Arguments:
|
|
|
|
Format - printf format string
|
|
|
|
... - any extra args
|
|
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (InternetDebugControlFlags & DBG_NO_DEBUG) {
|
|
return;
|
|
}
|
|
|
|
va_list list;
|
|
char buf[PRINTF_STACK_BUFFER_LENGTH];
|
|
|
|
va_start(list, Format);
|
|
_sprintf(buf, Format, list);
|
|
va_end(list);
|
|
|
|
InternetDebugOut(buf, FALSE);
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugOut(
|
|
IN LPSTR Buffer,
|
|
IN BOOL Assert
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Writes a string somewhere - to the debug log file, to the console, or via
|
|
the debugger, or any combination
|
|
|
|
Arguments:
|
|
|
|
Buffer - pointer to formatted buffer to write
|
|
|
|
Assert - TRUE if this function is being called from InternetAssert(), in
|
|
which case we *always* write to the debugger. Of course, there
|
|
may be no debugger attached, in which case no action is taken
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
int buflen;
|
|
DWORD written;
|
|
|
|
buflen = strlen(Buffer);
|
|
if ((InternetDebugControlFlags & DBG_TO_FILE)
|
|
&& (InternetDebugFileHandle != INVALID_HANDLE_VALUE)) {
|
|
WriteFile(InternetDebugFileHandle, Buffer, buflen, &written, NULL);
|
|
if (InternetDebugControlFlags & DBG_FLUSH_OUTPUT) {
|
|
InternetFlushDebugFile();
|
|
}
|
|
}
|
|
|
|
if (InternetDebugControlFlags & DBG_TO_CONSOLE) {
|
|
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
|
|
Buffer,
|
|
buflen,
|
|
&written,
|
|
0
|
|
);
|
|
}
|
|
|
|
if (Assert || (InternetDebugControlFlags & DBG_TO_DEBUGGER)) {
|
|
OutputDebugString(Buffer);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetDebugDump(
|
|
IN LPSTR Text,
|
|
IN LPBYTE Address,
|
|
IN DWORD Size
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps Size bytes at Address, in the time-honoured debug tradition
|
|
|
|
Arguments:
|
|
|
|
Text - to display before dumping data
|
|
|
|
Address - start of buffer
|
|
|
|
Size - number of bytes
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// if flags say no data dumps then quit
|
|
//
|
|
|
|
if (InternetDebugControlFlags & (DBG_NO_DEBUG | DBG_NO_DATA_DUMP)) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
// display the introduction text, if any
|
|
//
|
|
|
|
if (Text) {
|
|
if (InternetDebugControlFlags & DBG_INDENT_DUMP) {
|
|
InternetDebugPrint(Text);
|
|
} else {
|
|
InternetDebugOut(Text, FALSE);
|
|
}
|
|
}
|
|
|
|
char buf[128];
|
|
|
|
//
|
|
// display a line telling us how much data there is, if requested to
|
|
//
|
|
|
|
if (InternetDebugControlFlags & DBG_DUMP_LENGTH) {
|
|
rsprintf(buf, "%d (%#x) bytes @ %#x\n", Size, Size, Address);
|
|
if (InternetDebugControlFlags & DBG_INDENT_DUMP) {
|
|
InternetDebugPrintString(buf);
|
|
} else {
|
|
InternetDebugOut(buf, FALSE);
|
|
}
|
|
}
|
|
|
|
//
|
|
// dump out the data, debug style
|
|
//
|
|
|
|
while (Size) {
|
|
|
|
int len = InternetDebugDumpFormat(Address, Size, sizeof(BYTE), buf);
|
|
|
|
//
|
|
// if we are to indent the data to the current level, then display the
|
|
// buffer via InternetDebugPrint() which will apply all the thread id,
|
|
// indentation, and other options selected, else just display the data
|
|
// via InternetDebugOut(), which will simply send it to the output media
|
|
//
|
|
|
|
if (InternetDebugControlFlags & DBG_INDENT_DUMP) {
|
|
InternetDebugPrintString(buf);
|
|
} else {
|
|
InternetDebugOut(buf, FALSE);
|
|
}
|
|
|
|
Address += len;
|
|
Size -= len;
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
InternetDebugDumpFormat(
|
|
IN LPBYTE Address,
|
|
IN DWORD Size,
|
|
IN DWORD ElementSize,
|
|
OUT LPSTR Buffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Formats Size bytes at Address, in the time-honoured debug tradition, for
|
|
data dump purposes
|
|
|
|
Arguments:
|
|
|
|
Address - start of buffer
|
|
|
|
Size - number of bytes
|
|
|
|
ElementSize - size of each word element in bytes
|
|
|
|
Buffer - pointer to output buffer, assumed to be large enough
|
|
|
|
Return Value:
|
|
|
|
DWORD - number of bytes formatted
|
|
|
|
--*/
|
|
|
|
{
|
|
//
|
|
// we (currently) only understand DWORD, WORD and BYTE dumps
|
|
//
|
|
|
|
if ((ElementSize != sizeof(DWORD)) && (ElementSize != sizeof(WORD))) {
|
|
ElementSize = sizeof(BYTE);
|
|
}
|
|
|
|
static char spaces[] = " "; // 15 * 3 + 2
|
|
int i, len;
|
|
|
|
len = min(Size, 16);
|
|
rsprintf(Buffer, "%08x ", Address);
|
|
|
|
//
|
|
// dump the hex representation of each character or word - up to 16 per line
|
|
//
|
|
|
|
DWORD offset = 10;
|
|
|
|
for (i = 0; i < len; i += ElementSize) {
|
|
|
|
DWORD value;
|
|
LPSTR formatString;
|
|
|
|
switch (ElementSize) {
|
|
case 4:
|
|
formatString = "%08x ";
|
|
value = *(LPDWORD)&Address[i];
|
|
break;
|
|
|
|
case 2:
|
|
formatString = "%04x ";
|
|
value = *(LPWORD)&Address[i] & 0xffff;
|
|
break;
|
|
|
|
default:
|
|
formatString = ((i & 15) == 7) ? "%02.2x-" : "%02.2x ";
|
|
value = Address[i] & 0xff;
|
|
break;
|
|
}
|
|
rsprintf(&Buffer[offset], formatString, value);
|
|
offset += ElementSize * 2 + 1;
|
|
}
|
|
|
|
//
|
|
// write as many spaces as required to tab to ASCII field
|
|
//
|
|
|
|
memcpy(&Buffer[offset], spaces, (16 - len) * 3 + 2);
|
|
offset += (16 - len) * 3 + 2;
|
|
|
|
//
|
|
// dump ASCII representation of each character
|
|
//
|
|
|
|
for (i = 0; i < len; ++i) {
|
|
|
|
char ch;
|
|
|
|
ch = Address[i];
|
|
Buffer[offset + i] = ((ch < 32) || (ch > 127)) ? '.' : ch;
|
|
}
|
|
|
|
Buffer[offset + i++] = '\r';
|
|
Buffer[offset + i++] = '\n';
|
|
Buffer[offset + i] = '\0';
|
|
|
|
return len;
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetAssert(
|
|
IN LPSTR Assertion,
|
|
IN LPSTR FileName,
|
|
IN DWORD LineNumber
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
displays assertion message at debugger and raised breakpoint exception
|
|
|
|
Arguments:
|
|
|
|
Assertion - string describing assertion which failed
|
|
|
|
FileName - module where assertion failure occurred
|
|
|
|
LineNumber - at this line number
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
char buffer[512];
|
|
|
|
rsprintf(buffer,
|
|
"\n"
|
|
"*** WinHttp Assertion failed: %s\n"
|
|
"*** Source file: %s\n"
|
|
"*** Source line: %d\n"
|
|
"*** Thread %08x\n"
|
|
"\n",
|
|
Assertion,
|
|
FileName,
|
|
LineNumber,
|
|
GetCurrentThreadId()
|
|
);
|
|
InternetDebugOut(buffer, TRUE);
|
|
|
|
//
|
|
// break to the debugger, unless it is requested that we don't
|
|
//
|
|
|
|
if (!(InternetDebugControlFlags & DBG_NO_ASSERT_BREAK)) {
|
|
DebugBreak();
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
InternetGetDebugVariable(
|
|
IN LPSTR lpszVariableName,
|
|
OUT LPDWORD lpdwVariable
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get debug variable. First examine environment, then registry
|
|
|
|
Arguments:
|
|
|
|
lpszVariableName - variable name
|
|
|
|
lpdwVariable - returned variable
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD len;
|
|
char varbuf[ENVIRONMENT_VARIABLE_BUFFER_LENGTH];
|
|
|
|
//
|
|
// get the debug variables first from the environment, then - if not there -
|
|
// from the registry
|
|
//
|
|
|
|
len = GetEnvironmentVariable(lpszVariableName, varbuf, sizeof(varbuf));
|
|
if (len && len < sizeof(varbuf)) {
|
|
*lpdwVariable = (DWORD)strtoul(varbuf, NULL, 0);
|
|
} else {
|
|
InternetReadRegistryDword(lpszVariableName, lpdwVariable);
|
|
}
|
|
}
|
|
|
|
|
|
PRIVATE
|
|
VOID
|
|
InternetGetDebugVariableString(
|
|
IN LPSTR lpszVariableName,
|
|
OUT LPSTR lpszVariable,
|
|
IN DWORD dwVariableLen
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get debug variable string. First examine environment, then registry
|
|
|
|
Arguments:
|
|
|
|
lpszVariableName - variable name
|
|
|
|
lpszVariable - returned string variable
|
|
|
|
dwVariableLen - size of buffer
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
if (GetEnvironmentVariable(lpszVariableName, lpszVariable, dwVariableLen) == 0) {
|
|
|
|
char buf[MAX_PATH + 1];
|
|
DWORD len = min(sizeof(buf), dwVariableLen);
|
|
|
|
if (InternetReadRegistryString(lpszVariableName, buf, &len) == ERROR_SUCCESS) {
|
|
memcpy(lpszVariable, buf, len + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
LPSTR
|
|
InternetMapChunkToken(
|
|
IN CHUNK_TOKEN_VALUE eToken
|
|
)
|
|
{
|
|
switch(eToken)
|
|
{
|
|
CASE_OF(CHUNK_TOKEN_DIGIT);
|
|
CASE_OF(CHUNK_TOKEN_DATA);
|
|
CASE_OF(CHUNK_TOKEN_COLON);
|
|
CASE_OF(CHUNK_TOKEN_CR);
|
|
CASE_OF(CHUNK_TOKEN_LF);
|
|
|
|
default:
|
|
return "?";
|
|
|
|
}
|
|
}
|
|
|
|
LPSTR
|
|
InternetMapChunkState(
|
|
IN CHUNK_DECODE_STATE eState
|
|
)
|
|
{
|
|
switch(eState)
|
|
{
|
|
CASE_OF(CHUNK_DECODE_STATE_START);
|
|
CASE_OF(CHUNK_DECODE_STATE_SIZE);
|
|
CASE_OF(CHUNK_DECODE_STATE_SIZE_CRLF);
|
|
CASE_OF(CHUNK_DECODE_STATE_EXT);
|
|
CASE_OF(CHUNK_DECODE_STATE_DATA);
|
|
CASE_OF(CHUNK_DECODE_STATE_DATA_CRLF);
|
|
CASE_OF(CHUNK_DECODE_STATE_FOOTER_NAME);
|
|
CASE_OF(CHUNK_DECODE_STATE_FOOTER_VALUE);
|
|
CASE_OF(CHUNK_DECODE_STATE_FINAL_CRLF);
|
|
CASE_OF(CHUNK_DECODE_STATE_ERROR);
|
|
|
|
default:
|
|
return "?";
|
|
|
|
}
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapError(
|
|
IN DWORD Error
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Map error code to string. Try to get all errors that might ever be returned
|
|
by an Internet function
|
|
|
|
Arguments:
|
|
|
|
Error - code to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR - pointer to symbolic error name
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Error) {
|
|
|
|
//
|
|
// WINERROR errors
|
|
//
|
|
|
|
CASE_OF(ERROR_SUCCESS);
|
|
CASE_OF(ERROR_INVALID_FUNCTION);
|
|
CASE_OF(ERROR_FILE_NOT_FOUND);
|
|
CASE_OF(ERROR_PATH_NOT_FOUND);
|
|
CASE_OF(ERROR_TOO_MANY_OPEN_FILES);
|
|
CASE_OF(ERROR_ACCESS_DENIED);
|
|
CASE_OF(ERROR_INVALID_HANDLE);
|
|
CASE_OF(ERROR_ARENA_TRASHED);
|
|
CASE_OF(ERROR_NOT_ENOUGH_MEMORY);
|
|
CASE_OF(ERROR_INVALID_BLOCK);
|
|
CASE_OF(ERROR_BAD_ENVIRONMENT);
|
|
CASE_OF(ERROR_BAD_FORMAT);
|
|
CASE_OF(ERROR_INVALID_ACCESS);
|
|
CASE_OF(ERROR_INVALID_DATA);
|
|
CASE_OF(ERROR_OUTOFMEMORY);
|
|
CASE_OF(ERROR_INVALID_DRIVE);
|
|
CASE_OF(ERROR_CURRENT_DIRECTORY);
|
|
CASE_OF(ERROR_NOT_SAME_DEVICE);
|
|
CASE_OF(ERROR_NO_MORE_FILES);
|
|
CASE_OF(ERROR_WRITE_PROTECT);
|
|
CASE_OF(ERROR_BAD_UNIT);
|
|
CASE_OF(ERROR_NOT_READY);
|
|
CASE_OF(ERROR_BAD_COMMAND);
|
|
CASE_OF(ERROR_CRC);
|
|
CASE_OF(ERROR_BAD_LENGTH);
|
|
CASE_OF(ERROR_SEEK);
|
|
CASE_OF(ERROR_NOT_DOS_DISK);
|
|
CASE_OF(ERROR_SECTOR_NOT_FOUND);
|
|
CASE_OF(ERROR_OUT_OF_PAPER);
|
|
CASE_OF(ERROR_WRITE_FAULT);
|
|
CASE_OF(ERROR_READ_FAULT);
|
|
CASE_OF(ERROR_GEN_FAILURE);
|
|
CASE_OF(ERROR_SHARING_VIOLATION);
|
|
CASE_OF(ERROR_LOCK_VIOLATION);
|
|
CASE_OF(ERROR_WRONG_DISK);
|
|
CASE_OF(ERROR_SHARING_BUFFER_EXCEEDED);
|
|
CASE_OF(ERROR_HANDLE_EOF);
|
|
CASE_OF(ERROR_HANDLE_DISK_FULL);
|
|
CASE_OF(ERROR_NOT_SUPPORTED);
|
|
CASE_OF(ERROR_REM_NOT_LIST);
|
|
CASE_OF(ERROR_DUP_NAME);
|
|
CASE_OF(ERROR_BAD_NETPATH);
|
|
CASE_OF(ERROR_NETWORK_BUSY);
|
|
CASE_OF(ERROR_DEV_NOT_EXIST);
|
|
CASE_OF(ERROR_TOO_MANY_CMDS);
|
|
CASE_OF(ERROR_ADAP_HDW_ERR);
|
|
CASE_OF(ERROR_BAD_NET_RESP);
|
|
CASE_OF(ERROR_UNEXP_NET_ERR);
|
|
CASE_OF(ERROR_BAD_REM_ADAP);
|
|
CASE_OF(ERROR_PRINTQ_FULL);
|
|
CASE_OF(ERROR_NO_SPOOL_SPACE);
|
|
CASE_OF(ERROR_PRINT_CANCELLED);
|
|
CASE_OF(ERROR_NETNAME_DELETED);
|
|
CASE_OF(ERROR_NETWORK_ACCESS_DENIED);
|
|
CASE_OF(ERROR_BAD_DEV_TYPE);
|
|
CASE_OF(ERROR_BAD_NET_NAME);
|
|
CASE_OF(ERROR_TOO_MANY_NAMES);
|
|
CASE_OF(ERROR_TOO_MANY_SESS);
|
|
CASE_OF(ERROR_SHARING_PAUSED);
|
|
CASE_OF(ERROR_REQ_NOT_ACCEP);
|
|
CASE_OF(ERROR_REDIR_PAUSED);
|
|
CASE_OF(ERROR_FILE_EXISTS);
|
|
CASE_OF(ERROR_CANNOT_MAKE);
|
|
CASE_OF(ERROR_FAIL_I24);
|
|
CASE_OF(ERROR_OUT_OF_STRUCTURES);
|
|
CASE_OF(ERROR_ALREADY_ASSIGNED);
|
|
CASE_OF(ERROR_INVALID_PASSWORD);
|
|
CASE_OF(ERROR_INVALID_PARAMETER);
|
|
CASE_OF(ERROR_NET_WRITE_FAULT);
|
|
CASE_OF(ERROR_NO_PROC_SLOTS);
|
|
CASE_OF(ERROR_TOO_MANY_SEMAPHORES);
|
|
CASE_OF(ERROR_EXCL_SEM_ALREADY_OWNED);
|
|
CASE_OF(ERROR_SEM_IS_SET);
|
|
CASE_OF(ERROR_TOO_MANY_SEM_REQUESTS);
|
|
CASE_OF(ERROR_INVALID_AT_INTERRUPT_TIME);
|
|
CASE_OF(ERROR_SEM_OWNER_DIED);
|
|
CASE_OF(ERROR_SEM_USER_LIMIT);
|
|
CASE_OF(ERROR_DISK_CHANGE);
|
|
CASE_OF(ERROR_DRIVE_LOCKED);
|
|
CASE_OF(ERROR_BROKEN_PIPE);
|
|
CASE_OF(ERROR_OPEN_FAILED);
|
|
CASE_OF(ERROR_BUFFER_OVERFLOW);
|
|
CASE_OF(ERROR_DISK_FULL);
|
|
CASE_OF(ERROR_NO_MORE_SEARCH_HANDLES);
|
|
CASE_OF(ERROR_INVALID_TARGET_HANDLE);
|
|
CASE_OF(ERROR_INVALID_CATEGORY);
|
|
CASE_OF(ERROR_INVALID_VERIFY_SWITCH);
|
|
CASE_OF(ERROR_BAD_DRIVER_LEVEL);
|
|
CASE_OF(ERROR_CALL_NOT_IMPLEMENTED);
|
|
CASE_OF(ERROR_SEM_TIMEOUT);
|
|
CASE_OF(ERROR_INSUFFICIENT_BUFFER);
|
|
CASE_OF(ERROR_INVALID_NAME);
|
|
CASE_OF(ERROR_INVALID_LEVEL);
|
|
CASE_OF(ERROR_NO_VOLUME_LABEL);
|
|
CASE_OF(ERROR_MOD_NOT_FOUND);
|
|
CASE_OF(ERROR_PROC_NOT_FOUND);
|
|
CASE_OF(ERROR_WAIT_NO_CHILDREN);
|
|
CASE_OF(ERROR_CHILD_NOT_COMPLETE);
|
|
CASE_OF(ERROR_DIRECT_ACCESS_HANDLE);
|
|
CASE_OF(ERROR_NEGATIVE_SEEK);
|
|
CASE_OF(ERROR_SEEK_ON_DEVICE);
|
|
CASE_OF(ERROR_DIR_NOT_ROOT);
|
|
CASE_OF(ERROR_DIR_NOT_EMPTY);
|
|
CASE_OF(ERROR_PATH_BUSY);
|
|
CASE_OF(ERROR_SYSTEM_TRACE);
|
|
CASE_OF(ERROR_INVALID_EVENT_COUNT);
|
|
CASE_OF(ERROR_TOO_MANY_MUXWAITERS);
|
|
CASE_OF(ERROR_INVALID_LIST_FORMAT);
|
|
CASE_OF(ERROR_BAD_ARGUMENTS);
|
|
CASE_OF(ERROR_BAD_PATHNAME);
|
|
CASE_OF(ERROR_BUSY);
|
|
CASE_OF(ERROR_CANCEL_VIOLATION);
|
|
CASE_OF(ERROR_ALREADY_EXISTS);
|
|
CASE_OF(ERROR_FILENAME_EXCED_RANGE);
|
|
CASE_OF(ERROR_LOCKED);
|
|
CASE_OF(ERROR_NESTING_NOT_ALLOWED);
|
|
CASE_OF(ERROR_BAD_PIPE);
|
|
CASE_OF(ERROR_PIPE_BUSY);
|
|
CASE_OF(ERROR_NO_DATA);
|
|
CASE_OF(ERROR_PIPE_NOT_CONNECTED);
|
|
CASE_OF(ERROR_MORE_DATA);
|
|
CASE_OF(ERROR_NO_MORE_ITEMS);
|
|
CASE_OF(ERROR_NOT_OWNER);
|
|
CASE_OF(ERROR_PARTIAL_COPY);
|
|
CASE_OF(ERROR_MR_MID_NOT_FOUND);
|
|
CASE_OF(ERROR_INVALID_ADDRESS);
|
|
CASE_OF(ERROR_PIPE_CONNECTED);
|
|
CASE_OF(ERROR_PIPE_LISTENING);
|
|
CASE_OF(ERROR_OPERATION_ABORTED);
|
|
CASE_OF(ERROR_IO_INCOMPLETE);
|
|
CASE_OF(ERROR_IO_PENDING);
|
|
CASE_OF(ERROR_NOACCESS);
|
|
CASE_OF(ERROR_STACK_OVERFLOW);
|
|
CASE_OF(ERROR_INVALID_FLAGS);
|
|
CASE_OF(ERROR_NO_TOKEN);
|
|
CASE_OF(ERROR_BADDB);
|
|
CASE_OF(ERROR_BADKEY);
|
|
CASE_OF(ERROR_CANTOPEN);
|
|
CASE_OF(ERROR_CANTREAD);
|
|
CASE_OF(ERROR_CANTWRITE);
|
|
CASE_OF(ERROR_REGISTRY_RECOVERED);
|
|
CASE_OF(ERROR_REGISTRY_CORRUPT);
|
|
CASE_OF(ERROR_REGISTRY_IO_FAILED);
|
|
CASE_OF(ERROR_NOT_REGISTRY_FILE);
|
|
CASE_OF(ERROR_KEY_DELETED);
|
|
CASE_OF(ERROR_CIRCULAR_DEPENDENCY);
|
|
CASE_OF(ERROR_SERVICE_NOT_ACTIVE);
|
|
CASE_OF(ERROR_DLL_INIT_FAILED);
|
|
CASE_OF(ERROR_CANCELLED);
|
|
CASE_OF(ERROR_BAD_USERNAME);
|
|
CASE_OF(ERROR_LOGON_FAILURE);
|
|
|
|
CASE_OF(WAIT_FAILED);
|
|
//CASE_OF(WAIT_ABANDONED_0);
|
|
CASE_OF(WAIT_TIMEOUT);
|
|
CASE_OF(WAIT_IO_COMPLETION);
|
|
//CASE_OF(STILL_ACTIVE);
|
|
|
|
CASE_OF(RPC_S_INVALID_STRING_BINDING);
|
|
CASE_OF(RPC_S_WRONG_KIND_OF_BINDING);
|
|
CASE_OF(RPC_S_INVALID_BINDING);
|
|
CASE_OF(RPC_S_PROTSEQ_NOT_SUPPORTED);
|
|
CASE_OF(RPC_S_INVALID_RPC_PROTSEQ);
|
|
CASE_OF(RPC_S_INVALID_STRING_UUID);
|
|
CASE_OF(RPC_S_INVALID_ENDPOINT_FORMAT);
|
|
CASE_OF(RPC_S_INVALID_NET_ADDR);
|
|
CASE_OF(RPC_S_NO_ENDPOINT_FOUND);
|
|
CASE_OF(RPC_S_INVALID_TIMEOUT);
|
|
CASE_OF(RPC_S_OBJECT_NOT_FOUND);
|
|
CASE_OF(RPC_S_ALREADY_REGISTERED);
|
|
CASE_OF(RPC_S_TYPE_ALREADY_REGISTERED);
|
|
CASE_OF(RPC_S_ALREADY_LISTENING);
|
|
CASE_OF(RPC_S_NO_PROTSEQS_REGISTERED);
|
|
CASE_OF(RPC_S_NOT_LISTENING);
|
|
CASE_OF(RPC_S_UNKNOWN_MGR_TYPE);
|
|
CASE_OF(RPC_S_UNKNOWN_IF);
|
|
CASE_OF(RPC_S_NO_BINDINGS);
|
|
CASE_OF(RPC_S_NO_PROTSEQS);
|
|
CASE_OF(RPC_S_CANT_CREATE_ENDPOINT);
|
|
CASE_OF(RPC_S_OUT_OF_RESOURCES);
|
|
CASE_OF(RPC_S_SERVER_UNAVAILABLE);
|
|
CASE_OF(RPC_S_SERVER_TOO_BUSY);
|
|
CASE_OF(RPC_S_INVALID_NETWORK_OPTIONS);
|
|
CASE_OF(RPC_S_NO_CALL_ACTIVE);
|
|
CASE_OF(RPC_S_CALL_FAILED);
|
|
CASE_OF(RPC_S_CALL_FAILED_DNE);
|
|
CASE_OF(RPC_S_PROTOCOL_ERROR);
|
|
CASE_OF(RPC_S_UNSUPPORTED_TRANS_SYN);
|
|
CASE_OF(RPC_S_UNSUPPORTED_TYPE);
|
|
CASE_OF(RPC_S_INVALID_TAG);
|
|
CASE_OF(RPC_S_INVALID_BOUND);
|
|
CASE_OF(RPC_S_NO_ENTRY_NAME);
|
|
CASE_OF(RPC_S_INVALID_NAME_SYNTAX);
|
|
CASE_OF(RPC_S_UNSUPPORTED_NAME_SYNTAX);
|
|
CASE_OF(RPC_S_UUID_NO_ADDRESS);
|
|
CASE_OF(RPC_S_DUPLICATE_ENDPOINT);
|
|
CASE_OF(RPC_S_UNKNOWN_AUTHN_TYPE);
|
|
CASE_OF(RPC_S_MAX_CALLS_TOO_SMALL);
|
|
CASE_OF(RPC_S_STRING_TOO_LONG);
|
|
CASE_OF(RPC_S_PROTSEQ_NOT_FOUND);
|
|
CASE_OF(RPC_S_PROCNUM_OUT_OF_RANGE);
|
|
CASE_OF(RPC_S_BINDING_HAS_NO_AUTH);
|
|
CASE_OF(RPC_S_UNKNOWN_AUTHN_SERVICE);
|
|
CASE_OF(RPC_S_UNKNOWN_AUTHN_LEVEL);
|
|
CASE_OF(RPC_S_INVALID_AUTH_IDENTITY);
|
|
CASE_OF(RPC_S_UNKNOWN_AUTHZ_SERVICE);
|
|
CASE_OF(EPT_S_INVALID_ENTRY);
|
|
CASE_OF(EPT_S_CANT_PERFORM_OP);
|
|
CASE_OF(EPT_S_NOT_REGISTERED);
|
|
CASE_OF(RPC_S_NOTHING_TO_EXPORT);
|
|
CASE_OF(RPC_S_INCOMPLETE_NAME);
|
|
CASE_OF(RPC_S_INVALID_VERS_OPTION);
|
|
CASE_OF(RPC_S_NO_MORE_MEMBERS);
|
|
CASE_OF(RPC_S_NOT_ALL_OBJS_UNEXPORTED);
|
|
CASE_OF(RPC_S_INTERFACE_NOT_FOUND);
|
|
CASE_OF(RPC_S_ENTRY_ALREADY_EXISTS);
|
|
CASE_OF(RPC_S_ENTRY_NOT_FOUND);
|
|
CASE_OF(RPC_S_NAME_SERVICE_UNAVAILABLE);
|
|
CASE_OF(RPC_S_INVALID_NAF_ID);
|
|
CASE_OF(RPC_S_CANNOT_SUPPORT);
|
|
CASE_OF(RPC_S_NO_CONTEXT_AVAILABLE);
|
|
CASE_OF(RPC_S_INTERNAL_ERROR);
|
|
CASE_OF(RPC_S_ZERO_DIVIDE);
|
|
CASE_OF(RPC_S_ADDRESS_ERROR);
|
|
CASE_OF(RPC_S_FP_DIV_ZERO);
|
|
CASE_OF(RPC_S_FP_UNDERFLOW);
|
|
CASE_OF(RPC_S_FP_OVERFLOW);
|
|
CASE_OF(RPC_X_NO_MORE_ENTRIES);
|
|
CASE_OF(RPC_X_SS_CHAR_TRANS_OPEN_FAIL);
|
|
CASE_OF(RPC_X_SS_CHAR_TRANS_SHORT_FILE);
|
|
CASE_OF(RPC_X_SS_IN_NULL_CONTEXT);
|
|
CASE_OF(RPC_X_SS_CONTEXT_DAMAGED);
|
|
CASE_OF(RPC_X_SS_HANDLES_MISMATCH);
|
|
CASE_OF(RPC_X_SS_CANNOT_GET_CALL_HANDLE);
|
|
CASE_OF(RPC_X_NULL_REF_POINTER);
|
|
CASE_OF(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
|
|
CASE_OF(RPC_X_BYTE_COUNT_TOO_SMALL);
|
|
CASE_OF(RPC_X_BAD_STUB_DATA);
|
|
|
|
|
|
//
|
|
// WINHTTP errors
|
|
//
|
|
|
|
CASE_OF(ERROR_WINHTTP_OUT_OF_HANDLES);
|
|
CASE_OF(ERROR_WINHTTP_TIMEOUT);
|
|
CASE_OF(ERROR_WINHTTP_INTERNAL_ERROR);
|
|
CASE_OF(ERROR_WINHTTP_INVALID_URL);
|
|
CASE_OF(ERROR_WINHTTP_UNRECOGNIZED_SCHEME);
|
|
CASE_OF(ERROR_WINHTTP_NAME_NOT_RESOLVED);
|
|
CASE_OF(ERROR_WINHTTP_INVALID_OPTION);
|
|
CASE_OF(ERROR_WINHTTP_OPTION_NOT_SETTABLE);
|
|
CASE_OF(ERROR_WINHTTP_SHUTDOWN);
|
|
CASE_OF(ERROR_WINHTTP_INCORRECT_PASSWORD);
|
|
CASE_OF(ERROR_WINHTTP_LOGIN_FAILURE);
|
|
CASE_OF(ERROR_WINHTTP_OPERATION_CANCELLED);
|
|
CASE_OF(ERROR_WINHTTP_INCORRECT_HANDLE_TYPE);
|
|
CASE_OF(ERROR_WINHTTP_INCORRECT_HANDLE_STATE);
|
|
CASE_OF(ERROR_WINHTTP_CANNOT_CONNECT);
|
|
CASE_OF(ERROR_WINHTTP_CONNECTION_ERROR);
|
|
CASE_OF(ERROR_WINHTTP_FORCE_RETRY);
|
|
CASE_OF(ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED);
|
|
CASE_OF(ERROR_WINHTTP_NOT_INITIALIZED);
|
|
CASE_OF(ERROR_WINHTTP_SECURE_FAILURE);
|
|
|
|
CASE_OF(ERROR_HTTP_HEADER_NOT_FOUND);
|
|
CASE_OF(ERROR_HTTP_INVALID_SERVER_RESPONSE);
|
|
CASE_OF(ERROR_HTTP_INVALID_QUERY_REQUEST);
|
|
CASE_OF(ERROR_HTTP_HEADER_ALREADY_EXISTS);
|
|
CASE_OF(ERROR_HTTP_REDIRECT_FAILED);
|
|
CASE_OF(ERROR_HTTP_NOT_REDIRECTED);
|
|
|
|
//
|
|
// SSPI errors
|
|
//
|
|
|
|
CASE_OF(SEC_E_INSUFFICIENT_MEMORY);
|
|
CASE_OF(SEC_E_INVALID_HANDLE);
|
|
CASE_OF(SEC_E_UNSUPPORTED_FUNCTION);
|
|
CASE_OF(SEC_E_TARGET_UNKNOWN);
|
|
CASE_OF(SEC_E_INTERNAL_ERROR);
|
|
CASE_OF(SEC_E_SECPKG_NOT_FOUND);
|
|
CASE_OF(SEC_E_NOT_OWNER);
|
|
CASE_OF(SEC_E_CANNOT_INSTALL);
|
|
CASE_OF(SEC_E_INVALID_TOKEN);
|
|
CASE_OF(SEC_E_CANNOT_PACK);
|
|
CASE_OF(SEC_E_QOP_NOT_SUPPORTED);
|
|
CASE_OF(SEC_E_NO_IMPERSONATION);
|
|
CASE_OF(SEC_E_LOGON_DENIED);
|
|
CASE_OF(SEC_E_UNKNOWN_CREDENTIALS);
|
|
CASE_OF(SEC_E_NO_CREDENTIALS);
|
|
CASE_OF(SEC_E_MESSAGE_ALTERED);
|
|
CASE_OF(SEC_E_OUT_OF_SEQUENCE);
|
|
CASE_OF(SEC_E_NO_AUTHENTICATING_AUTHORITY);
|
|
CASE_OF(SEC_I_CONTINUE_NEEDED);
|
|
CASE_OF(SEC_I_COMPLETE_NEEDED);
|
|
CASE_OF(SEC_I_COMPLETE_AND_CONTINUE);
|
|
CASE_OF(SEC_I_LOCAL_LOGON);
|
|
CASE_OF(SEC_E_BAD_PKGID);
|
|
CASE_OF(SEC_E_CONTEXT_EXPIRED);
|
|
CASE_OF(SEC_E_INCOMPLETE_MESSAGE);
|
|
|
|
|
|
//
|
|
// WINSOCK errors
|
|
//
|
|
|
|
CASE_OF(WSAEINTR);
|
|
CASE_OF(WSAEBADF);
|
|
CASE_OF(WSAEACCES);
|
|
CASE_OF(WSAEFAULT);
|
|
CASE_OF(WSAEINVAL);
|
|
CASE_OF(WSAEMFILE);
|
|
CASE_OF(WSAEWOULDBLOCK);
|
|
CASE_OF(WSAEINPROGRESS);
|
|
CASE_OF(WSAEALREADY);
|
|
CASE_OF(WSAENOTSOCK);
|
|
CASE_OF(WSAEDESTADDRREQ);
|
|
CASE_OF(WSAEMSGSIZE);
|
|
CASE_OF(WSAEPROTOTYPE);
|
|
CASE_OF(WSAENOPROTOOPT);
|
|
CASE_OF(WSAEPROTONOSUPPORT);
|
|
CASE_OF(WSAESOCKTNOSUPPORT);
|
|
CASE_OF(WSAEOPNOTSUPP);
|
|
CASE_OF(WSAEPFNOSUPPORT);
|
|
CASE_OF(WSAEAFNOSUPPORT);
|
|
CASE_OF(WSAEADDRINUSE);
|
|
CASE_OF(WSAEADDRNOTAVAIL);
|
|
CASE_OF(WSAENETDOWN);
|
|
CASE_OF(WSAENETUNREACH);
|
|
CASE_OF(WSAENETRESET);
|
|
CASE_OF(WSAECONNABORTED);
|
|
CASE_OF(WSAECONNRESET);
|
|
CASE_OF(WSAENOBUFS);
|
|
CASE_OF(WSAEISCONN);
|
|
CASE_OF(WSAENOTCONN);
|
|
CASE_OF(WSAESHUTDOWN);
|
|
CASE_OF(WSAETOOMANYREFS);
|
|
CASE_OF(WSAETIMEDOUT);
|
|
CASE_OF(WSAECONNREFUSED);
|
|
CASE_OF(WSAELOOP);
|
|
CASE_OF(WSAENAMETOOLONG);
|
|
CASE_OF(WSAEHOSTDOWN);
|
|
CASE_OF(WSAEHOSTUNREACH);
|
|
CASE_OF(WSAENOTEMPTY);
|
|
CASE_OF(WSAEPROCLIM);
|
|
CASE_OF(WSAEUSERS);
|
|
CASE_OF(WSAEDQUOT);
|
|
CASE_OF(WSAESTALE);
|
|
CASE_OF(WSAEREMOTE);
|
|
CASE_OF(WSAEDISCON);
|
|
CASE_OF(WSASYSNOTREADY);
|
|
CASE_OF(WSAVERNOTSUPPORTED);
|
|
CASE_OF(WSANOTINITIALISED);
|
|
CASE_OF(WSAHOST_NOT_FOUND);
|
|
CASE_OF(WSATRY_AGAIN);
|
|
CASE_OF(WSANO_RECOVERY);
|
|
CASE_OF(WSANO_DATA);
|
|
|
|
#if 0
|
|
//
|
|
// RAS errors
|
|
//
|
|
|
|
CASE_OF(PENDING);
|
|
CASE_OF(ERROR_INVALID_PORT_HANDLE);
|
|
CASE_OF(ERROR_PORT_ALREADY_OPEN);
|
|
CASE_OF(ERROR_BUFFER_TOO_SMALL);
|
|
CASE_OF(ERROR_WRONG_INFO_SPECIFIED);
|
|
CASE_OF(ERROR_CANNOT_SET_PORT_INFO);
|
|
CASE_OF(ERROR_PORT_NOT_CONNECTED);
|
|
CASE_OF(ERROR_EVENT_INVALID);
|
|
CASE_OF(ERROR_DEVICE_DOES_NOT_EXIST);
|
|
CASE_OF(ERROR_BUFFER_INVALID);
|
|
CASE_OF(ERROR_ROUTE_NOT_AVAILABLE);
|
|
CASE_OF(ERROR_ROUTE_NOT_ALLOCATED);
|
|
CASE_OF(ERROR_INVALID_COMPRESSION_SPECIFIED);
|
|
CASE_OF(ERROR_OUT_OF_BUFFERS);
|
|
CASE_OF(ERROR_PORT_NOT_FOUND);
|
|
CASE_OF(ERROR_ASYNC_REQUEST_PENDING);
|
|
CASE_OF(ERROR_ALREADY_DISCONNECTING);
|
|
CASE_OF(ERROR_PORT_NOT_OPEN);
|
|
CASE_OF(ERROR_PORT_DISCONNECTED);
|
|
CASE_OF(ERROR_NO_ENDPOINTS);
|
|
CASE_OF(ERROR_CANNOT_OPEN_PHONEBOOK);
|
|
CASE_OF(ERROR_CANNOT_LOAD_PHONEBOOK);
|
|
CASE_OF(ERROR_CANNOT_FIND_PHONEBOOK_ENTRY);
|
|
CASE_OF(ERROR_CANNOT_WRITE_PHONEBOOK);
|
|
CASE_OF(ERROR_CORRUPT_PHONEBOOK);
|
|
CASE_OF(ERROR_CANNOT_LOAD_STRING);
|
|
CASE_OF(ERROR_KEY_NOT_FOUND);
|
|
CASE_OF(ERROR_DISCONNECTION);
|
|
CASE_OF(ERROR_REMOTE_DISCONNECTION);
|
|
CASE_OF(ERROR_HARDWARE_FAILURE);
|
|
CASE_OF(ERROR_USER_DISCONNECTION);
|
|
CASE_OF(ERROR_INVALID_SIZE);
|
|
CASE_OF(ERROR_PORT_NOT_AVAILABLE);
|
|
CASE_OF(ERROR_CANNOT_PROJECT_CLIENT);
|
|
CASE_OF(ERROR_UNKNOWN);
|
|
CASE_OF(ERROR_WRONG_DEVICE_ATTACHED);
|
|
CASE_OF(ERROR_BAD_STRING);
|
|
CASE_OF(ERROR_REQUEST_TIMEOUT);
|
|
CASE_OF(ERROR_CANNOT_GET_LANA);
|
|
CASE_OF(ERROR_NETBIOS_ERROR);
|
|
CASE_OF(ERROR_SERVER_OUT_OF_RESOURCES);
|
|
CASE_OF(ERROR_NAME_EXISTS_ON_NET);
|
|
CASE_OF(ERROR_SERVER_GENERAL_NET_FAILURE);
|
|
CASE_OF(WARNING_MSG_ALIAS_NOT_ADDED);
|
|
CASE_OF(ERROR_AUTH_INTERNAL);
|
|
CASE_OF(ERROR_RESTRICTED_LOGON_HOURS);
|
|
CASE_OF(ERROR_ACCT_DISABLED);
|
|
CASE_OF(ERROR_PASSWD_EXPIRED);
|
|
CASE_OF(ERROR_NO_DIALIN_PERMISSION);
|
|
CASE_OF(ERROR_SERVER_NOT_RESPONDING);
|
|
CASE_OF(ERROR_FROM_DEVICE);
|
|
CASE_OF(ERROR_UNRECOGNIZED_RESPONSE);
|
|
CASE_OF(ERROR_MACRO_NOT_FOUND);
|
|
CASE_OF(ERROR_MACRO_NOT_DEFINED);
|
|
CASE_OF(ERROR_MESSAGE_MACRO_NOT_FOUND);
|
|
CASE_OF(ERROR_DEFAULTOFF_MACRO_NOT_FOUND);
|
|
CASE_OF(ERROR_FILE_COULD_NOT_BE_OPENED);
|
|
CASE_OF(ERROR_DEVICENAME_TOO_LONG);
|
|
CASE_OF(ERROR_DEVICENAME_NOT_FOUND);
|
|
CASE_OF(ERROR_NO_RESPONSES);
|
|
CASE_OF(ERROR_NO_COMMAND_FOUND);
|
|
CASE_OF(ERROR_WRONG_KEY_SPECIFIED);
|
|
CASE_OF(ERROR_UNKNOWN_DEVICE_TYPE);
|
|
CASE_OF(ERROR_ALLOCATING_MEMORY);
|
|
CASE_OF(ERROR_PORT_NOT_CONFIGURED);
|
|
CASE_OF(ERROR_DEVICE_NOT_READY);
|
|
CASE_OF(ERROR_READING_INI_FILE);
|
|
CASE_OF(ERROR_NO_CONNECTION);
|
|
CASE_OF(ERROR_BAD_USAGE_IN_INI_FILE);
|
|
CASE_OF(ERROR_READING_SECTIONNAME);
|
|
CASE_OF(ERROR_READING_DEVICETYPE);
|
|
CASE_OF(ERROR_READING_DEVICENAME);
|
|
CASE_OF(ERROR_READING_USAGE);
|
|
CASE_OF(ERROR_READING_MAXCONNECTBPS);
|
|
CASE_OF(ERROR_READING_MAXCARRIERBPS);
|
|
CASE_OF(ERROR_LINE_BUSY);
|
|
CASE_OF(ERROR_VOICE_ANSWER);
|
|
CASE_OF(ERROR_NO_ANSWER);
|
|
CASE_OF(ERROR_NO_CARRIER);
|
|
CASE_OF(ERROR_NO_DIALTONE);
|
|
CASE_OF(ERROR_IN_COMMAND);
|
|
CASE_OF(ERROR_WRITING_SECTIONNAME);
|
|
CASE_OF(ERROR_WRITING_DEVICETYPE);
|
|
CASE_OF(ERROR_WRITING_DEVICENAME);
|
|
CASE_OF(ERROR_WRITING_MAXCONNECTBPS);
|
|
CASE_OF(ERROR_WRITING_MAXCARRIERBPS);
|
|
CASE_OF(ERROR_WRITING_USAGE);
|
|
CASE_OF(ERROR_WRITING_DEFAULTOFF);
|
|
CASE_OF(ERROR_READING_DEFAULTOFF);
|
|
CASE_OF(ERROR_EMPTY_INI_FILE);
|
|
CASE_OF(ERROR_AUTHENTICATION_FAILURE);
|
|
CASE_OF(ERROR_PORT_OR_DEVICE);
|
|
CASE_OF(ERROR_NOT_BINARY_MACRO);
|
|
CASE_OF(ERROR_DCB_NOT_FOUND);
|
|
CASE_OF(ERROR_STATE_MACHINES_NOT_STARTED);
|
|
CASE_OF(ERROR_STATE_MACHINES_ALREADY_STARTED);
|
|
CASE_OF(ERROR_PARTIAL_RESPONSE_LOOPING);
|
|
CASE_OF(ERROR_UNKNOWN_RESPONSE_KEY);
|
|
CASE_OF(ERROR_RECV_BUF_FULL);
|
|
CASE_OF(ERROR_CMD_TOO_LONG);
|
|
CASE_OF(ERROR_UNSUPPORTED_BPS);
|
|
CASE_OF(ERROR_UNEXPECTED_RESPONSE);
|
|
CASE_OF(ERROR_INTERACTIVE_MODE);
|
|
CASE_OF(ERROR_BAD_CALLBACK_NUMBER);
|
|
CASE_OF(ERROR_INVALID_AUTH_STATE);
|
|
CASE_OF(ERROR_WRITING_INITBPS);
|
|
CASE_OF(ERROR_X25_DIAGNOSTIC);
|
|
CASE_OF(ERROR_ACCT_EXPIRED);
|
|
CASE_OF(ERROR_CHANGING_PASSWORD);
|
|
CASE_OF(ERROR_OVERRUN);
|
|
CASE_OF(ERROR_RASMAN_CANNOT_INITIALIZE);
|
|
CASE_OF(ERROR_BIPLEX_PORT_NOT_AVAILABLE);
|
|
CASE_OF(ERROR_NO_ACTIVE_ISDN_LINES);
|
|
CASE_OF(ERROR_NO_ISDN_CHANNELS_AVAILABLE);
|
|
CASE_OF(ERROR_TOO_MANY_LINE_ERRORS);
|
|
CASE_OF(ERROR_IP_CONFIGURATION);
|
|
CASE_OF(ERROR_NO_IP_ADDRESSES);
|
|
CASE_OF(ERROR_PPP_TIMEOUT);
|
|
CASE_OF(ERROR_PPP_REMOTE_TERMINATED);
|
|
CASE_OF(ERROR_PPP_NO_PROTOCOLS_CONFIGURED);
|
|
CASE_OF(ERROR_PPP_NO_RESPONSE);
|
|
CASE_OF(ERROR_PPP_INVALID_PACKET);
|
|
CASE_OF(ERROR_PHONE_NUMBER_TOO_LONG);
|
|
CASE_OF(ERROR_IPXCP_NO_DIALOUT_CONFIGURED);
|
|
CASE_OF(ERROR_IPXCP_NO_DIALIN_CONFIGURED);
|
|
CASE_OF(ERROR_IPXCP_DIALOUT_ALREADY_ACTIVE);
|
|
CASE_OF(ERROR_ACCESSING_TCPCFGDLL);
|
|
CASE_OF(ERROR_NO_IP_RAS_ADAPTER);
|
|
CASE_OF(ERROR_SLIP_REQUIRES_IP);
|
|
CASE_OF(ERROR_PROJECTION_NOT_COMPLETE);
|
|
CASE_OF(ERROR_PROTOCOL_NOT_CONFIGURED);
|
|
CASE_OF(ERROR_PPP_NOT_CONVERGING);
|
|
CASE_OF(ERROR_PPP_CP_REJECTED);
|
|
CASE_OF(ERROR_PPP_LCP_TERMINATED);
|
|
CASE_OF(ERROR_PPP_REQUIRED_ADDRESS_REJECTED);
|
|
CASE_OF(ERROR_PPP_NCP_TERMINATED);
|
|
CASE_OF(ERROR_PPP_LOOPBACK_DETECTED);
|
|
CASE_OF(ERROR_PPP_NO_ADDRESS_ASSIGNED);
|
|
CASE_OF(ERROR_CANNOT_USE_LOGON_CREDENTIALS);
|
|
CASE_OF(ERROR_TAPI_CONFIGURATION);
|
|
CASE_OF(ERROR_NO_LOCAL_ENCRYPTION);
|
|
CASE_OF(ERROR_NO_REMOTE_ENCRYPTION);
|
|
CASE_OF(ERROR_REMOTE_REQUIRES_ENCRYPTION);
|
|
CASE_OF(ERROR_IPXCP_NET_NUMBER_CONFLICT);
|
|
CASE_OF(ERROR_INVALID_SMM);
|
|
CASE_OF(ERROR_SMM_UNINITIALIZED);
|
|
CASE_OF(ERROR_NO_MAC_FOR_PORT);
|
|
CASE_OF(ERROR_SMM_TIMEOUT);
|
|
CASE_OF(ERROR_BAD_PHONE_NUMBER);
|
|
CASE_OF(ERROR_WRONG_MODULE);
|
|
CASE_OF(ERROR_INVALID_CALLBACK_NUMBER);
|
|
CASE_OF(ERROR_SCRIPT_SYNTAX);
|
|
#endif // 0
|
|
default:
|
|
return "?";
|
|
}
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapStatus(
|
|
IN DWORD Status
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert WINHTTP_CALLBACK_STATUS_ value to symbolic name
|
|
|
|
Arguments:
|
|
|
|
Status - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR - pointer to symbolic name, or "?" if unknown
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Status) {
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_RESOLVING_NAME);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_NAME_RESOLVED);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_SENDING_REQUEST);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_REQUEST_SENT);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_HANDLE_CREATED);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_REQUEST_COMPLETE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_REDIRECT);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_READ_COMPLETE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE);
|
|
CASE_OF(WINHTTP_CALLBACK_STATUS_REQUEST_ERROR);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapSSPIError(
|
|
IN DWORD Status
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert a SSL/PCT SSPI Error Code to a string.
|
|
|
|
Arguments:
|
|
|
|
Status - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR - pointer to symbolic name, or "?" if unknown
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Status) {
|
|
|
|
CASE_OF(STATUS_SUCCESS);
|
|
CASE_OF(SEC_E_INSUFFICIENT_MEMORY );
|
|
CASE_OF(SEC_E_INVALID_HANDLE );
|
|
CASE_OF(SEC_E_UNSUPPORTED_FUNCTION );
|
|
CASE_OF(SEC_E_TARGET_UNKNOWN );
|
|
CASE_OF(SEC_E_INTERNAL_ERROR );
|
|
CASE_OF(SEC_E_SECPKG_NOT_FOUND );
|
|
CASE_OF(SEC_E_NOT_OWNER );
|
|
CASE_OF(SEC_E_CANNOT_INSTALL );
|
|
CASE_OF(SEC_E_INVALID_TOKEN );
|
|
CASE_OF(SEC_E_CANNOT_PACK );
|
|
CASE_OF(SEC_E_QOP_NOT_SUPPORTED );
|
|
CASE_OF(SEC_E_NO_IMPERSONATION );
|
|
CASE_OF(SEC_E_LOGON_DENIED );
|
|
CASE_OF(SEC_E_UNKNOWN_CREDENTIALS );
|
|
CASE_OF(SEC_E_NO_CREDENTIALS );
|
|
CASE_OF(SEC_E_MESSAGE_ALTERED );
|
|
CASE_OF(SEC_E_OUT_OF_SEQUENCE );
|
|
CASE_OF(SEC_E_NO_AUTHENTICATING_AUTHORITY);
|
|
CASE_OF(SEC_I_CONTINUE_NEEDED );
|
|
CASE_OF(SEC_I_COMPLETE_NEEDED );
|
|
CASE_OF(SEC_I_COMPLETE_AND_CONTINUE );
|
|
CASE_OF(SEC_I_LOCAL_LOGON );
|
|
CASE_OF(SEC_E_BAD_PKGID );
|
|
CASE_OF(SEC_E_CONTEXT_EXPIRED );
|
|
CASE_OF(SEC_E_INCOMPLETE_MESSAGE );
|
|
// CASE_OF(SEC_E_NO_SPM );
|
|
// CASE_OF(SEC_E_NOT_SUPPORTED );
|
|
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
|
|
|
|
LPSTR
|
|
InternetMapHttpOption(
|
|
IN DWORD Option
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert HTTP_QUERY_ option value to symbolic name
|
|
|
|
Arguments:
|
|
|
|
Option - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR - pointer to symbolic name, or "?" if unknown
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Option) {
|
|
CASE_OF(HTTP_QUERY_MIME_VERSION); // 0
|
|
CASE_OF(HTTP_QUERY_CONTENT_TYPE); // 1
|
|
CASE_OF(HTTP_QUERY_CONTENT_TRANSFER_ENCODING); // 2
|
|
CASE_OF(HTTP_QUERY_CONTENT_ID); // 3
|
|
CASE_OF(HTTP_QUERY_CONTENT_DESCRIPTION); // 4
|
|
CASE_OF(HTTP_QUERY_CONTENT_LENGTH); // 5
|
|
CASE_OF(HTTP_QUERY_CONTENT_LANGUAGE); // 6
|
|
CASE_OF(HTTP_QUERY_ALLOW); // 7
|
|
CASE_OF(HTTP_QUERY_PUBLIC); // 8
|
|
CASE_OF(HTTP_QUERY_DATE); // 9
|
|
CASE_OF(HTTP_QUERY_EXPIRES); // 10
|
|
CASE_OF(HTTP_QUERY_LAST_MODIFIED); // 11
|
|
CASE_OF(HTTP_QUERY_MESSAGE_ID); // 12
|
|
CASE_OF(HTTP_QUERY_URI); // 13
|
|
CASE_OF(HTTP_QUERY_DERIVED_FROM); // 14
|
|
CASE_OF(HTTP_QUERY_COST); // 15
|
|
CASE_OF(HTTP_QUERY_LINK); // 16
|
|
CASE_OF(HTTP_QUERY_PRAGMA); // 17
|
|
CASE_OF(HTTP_QUERY_VERSION); // 18
|
|
CASE_OF(HTTP_QUERY_STATUS_CODE); // 19
|
|
CASE_OF(HTTP_QUERY_STATUS_TEXT); // 20
|
|
CASE_OF(HTTP_QUERY_RAW_HEADERS); // 21
|
|
CASE_OF(HTTP_QUERY_RAW_HEADERS_CRLF); // 22
|
|
CASE_OF(HTTP_QUERY_CONNECTION); // 23
|
|
CASE_OF(HTTP_QUERY_ACCEPT); // 24
|
|
CASE_OF(HTTP_QUERY_ACCEPT_CHARSET); // 25
|
|
CASE_OF(HTTP_QUERY_ACCEPT_ENCODING); // 26
|
|
CASE_OF(HTTP_QUERY_ACCEPT_LANGUAGE); // 27
|
|
CASE_OF(HTTP_QUERY_AUTHORIZATION); // 28
|
|
CASE_OF(HTTP_QUERY_CONTENT_ENCODING); // 29
|
|
CASE_OF(HTTP_QUERY_FORWARDED); // 30
|
|
CASE_OF(HTTP_QUERY_FROM); // 31
|
|
CASE_OF(HTTP_QUERY_IF_MODIFIED_SINCE); // 32
|
|
CASE_OF(HTTP_QUERY_LOCATION); // 33
|
|
CASE_OF(HTTP_QUERY_ORIG_URI); // 34
|
|
CASE_OF(HTTP_QUERY_REFERER); // 35
|
|
CASE_OF(HTTP_QUERY_RETRY_AFTER); // 36
|
|
CASE_OF(HTTP_QUERY_SERVER); // 37
|
|
CASE_OF(HTTP_QUERY_TITLE); // 38
|
|
CASE_OF(HTTP_QUERY_USER_AGENT); // 39
|
|
CASE_OF(HTTP_QUERY_WWW_AUTHENTICATE); // 40
|
|
CASE_OF(HTTP_QUERY_PROXY_AUTHENTICATE); // 41
|
|
CASE_OF(HTTP_QUERY_ACCEPT_RANGES); // 42
|
|
CASE_OF(HTTP_QUERY_SET_COOKIE); // 43
|
|
CASE_OF(HTTP_QUERY_COOKIE); // 44
|
|
CASE_OF(HTTP_QUERY_REQUEST_METHOD); // 45
|
|
CASE_OF(HTTP_QUERY_REFRESH); // 46
|
|
CASE_OF(HTTP_QUERY_CONTENT_DISPOSITION); // 47
|
|
CASE_OF(HTTP_QUERY_AGE); // 48
|
|
CASE_OF(HTTP_QUERY_CACHE_CONTROL); // 49
|
|
CASE_OF(HTTP_QUERY_CONTENT_BASE); // 50
|
|
CASE_OF(HTTP_QUERY_CONTENT_LOCATION); // 51
|
|
CASE_OF(HTTP_QUERY_CONTENT_MD5); // 52
|
|
CASE_OF(HTTP_QUERY_CONTENT_RANGE); // 53
|
|
CASE_OF(HTTP_QUERY_ETAG); // 54
|
|
CASE_OF(HTTP_QUERY_HOST); // 55
|
|
CASE_OF(HTTP_QUERY_IF_MATCH); // 56
|
|
CASE_OF(HTTP_QUERY_IF_NONE_MATCH); // 57
|
|
CASE_OF(HTTP_QUERY_IF_RANGE); // 58
|
|
CASE_OF(HTTP_QUERY_IF_UNMODIFIED_SINCE); // 59
|
|
CASE_OF(HTTP_QUERY_MAX_FORWARDS); // 60
|
|
CASE_OF(HTTP_QUERY_PROXY_AUTHORIZATION); // 61
|
|
CASE_OF(HTTP_QUERY_RANGE); // 62
|
|
CASE_OF(HTTP_QUERY_TRANSFER_ENCODING); // 63
|
|
CASE_OF(HTTP_QUERY_UPGRADE); // 64
|
|
CASE_OF(HTTP_QUERY_VARY); // 65
|
|
CASE_OF(HTTP_QUERY_VIA); // 66
|
|
CASE_OF(HTTP_QUERY_WARNING); // 67
|
|
CASE_OF(HTTP_QUERY_EXPECT); // 68
|
|
CASE_OF(HTTP_QUERY_PROXY_CONNECTION); // 69
|
|
CASE_OF(HTTP_QUERY_UNLESS_MODIFIED_SINCE); // 70
|
|
CASE_OF(HTTP_QUERY_ECHO_REQUEST); // 71
|
|
CASE_OF(HTTP_QUERY_ECHO_REPLY); // 72
|
|
CASE_OF(HTTP_QUERY_ECHO_HEADERS); // 73
|
|
CASE_OF(HTTP_QUERY_ECHO_HEADERS_CRLF); // 74
|
|
CASE_OF(HTTP_QUERY_CUSTOM); // 65535
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapHttpState(
|
|
IN WORD State
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert HTTPREQ_STATE_ to symbolic name
|
|
|
|
Arguments:
|
|
|
|
State - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (State & ~HTTPREQ_FLAG_MASK)
|
|
{
|
|
CASE_OF(HttpRequestStateCreating);
|
|
CASE_OF(HttpRequestStateOpen);
|
|
CASE_OF(HttpRequestStateRequest);
|
|
CASE_OF(HttpRequestStateResponse);
|
|
CASE_OF(HttpRequestStateObjectData);
|
|
CASE_OF(HttpRequestStateError);
|
|
CASE_OF(HttpRequestStateClosing);
|
|
CASE_OF(HttpRequestStateReopen);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
LPSTR
|
|
InternetMapHttpStateFlag(
|
|
IN WORD Flag
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert HTTPREQ_STATE_ flag to symbolic name
|
|
|
|
Arguments:
|
|
|
|
Flag - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Flag & ~HTTPREQ_FLAG_MASK)
|
|
{
|
|
case HTTPREQ_STATE_ANYTHING_OK:
|
|
return "ANYTHING";
|
|
|
|
case HTTPREQ_STATE_CLOSE_OK:
|
|
return "CLOSE";
|
|
|
|
case HTTPREQ_STATE_ADD_OK:
|
|
return "ADD";
|
|
|
|
case HTTPREQ_STATE_SEND_OK:
|
|
return "SEND";
|
|
|
|
case HTTPREQ_STATE_READ_OK:
|
|
return "READ";
|
|
|
|
case HTTPREQ_STATE_QUERY_REQUEST_OK:
|
|
return "QUERY_REQUEST";
|
|
|
|
case HTTPREQ_STATE_QUERY_RESPONSE_OK:
|
|
return "QUERY_RESPONSE";
|
|
|
|
case HTTPREQ_STATE_REUSE_OK:
|
|
return "REUSE";
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapAsyncRequest(
|
|
IN AR_TYPE Type
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert AR_TYPE to symbolic name
|
|
|
|
Arguments:
|
|
|
|
Type - Async request type
|
|
|
|
Return Value:
|
|
|
|
LPSTR - pointer to symbolic name, or "?" if unknown
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Type) {
|
|
CASE_OF(AR_INTERNET_CONNECT);
|
|
CASE_OF(AR_INTERNET_OPEN_URL);
|
|
CASE_OF(AR_INTERNET_READ_FILE);
|
|
CASE_OF(AR_INTERNET_WRITE_FILE);
|
|
CASE_OF(AR_INTERNET_QUERY_DATA_AVAILABLE);
|
|
CASE_OF(AR_INTERNET_FIND_NEXT_FILE);
|
|
CASE_OF(AR_FTP_FIND_FIRST_FILE);
|
|
CASE_OF(AR_FTP_GET_FILE);
|
|
CASE_OF(AR_FTP_PUT_FILE);
|
|
CASE_OF(AR_FTP_DELETE_FILE);
|
|
CASE_OF(AR_FTP_RENAME_FILE);
|
|
CASE_OF(AR_FTP_OPEN_FILE);
|
|
CASE_OF(AR_FTP_CREATE_DIRECTORY);
|
|
CASE_OF(AR_FTP_REMOVE_DIRECTORY);
|
|
CASE_OF(AR_FTP_SET_CURRENT_DIRECTORY);
|
|
CASE_OF(AR_FTP_GET_CURRENT_DIRECTORY);
|
|
CASE_OF(AR_GOPHER_FIND_FIRST_FILE);
|
|
CASE_OF(AR_GOPHER_OPEN_FILE);
|
|
CASE_OF(AR_GOPHER_GET_ATTRIBUTE);
|
|
CASE_OF(AR_HTTP_SEND_REQUEST);
|
|
CASE_OF(AR_HTTP_BEGIN_SEND_REQUEST);
|
|
CASE_OF(AR_HTTP_END_SEND_REQUEST);
|
|
CASE_OF(AR_READ_PREFETCH);
|
|
CASE_OF(AR_SYNC_EVENT);
|
|
CASE_OF(AR_TIMER_EVENT);
|
|
CASE_OF(AR_HTTP_REQUEST1);
|
|
CASE_OF(AR_FILE_IO);
|
|
CASE_OF(AR_INTERNET_READ_FILE_EX);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapHandleType(
|
|
IN DWORD HandleType
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Map handle type to symbolic name
|
|
|
|
Arguments:
|
|
|
|
HandleType - from handle object
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (HandleType) {
|
|
CASE_OF(TypeGenericHandle);
|
|
CASE_OF(TypeInternetHandle);
|
|
CASE_OF(TypeFtpConnectHandle);
|
|
CASE_OF(TypeFtpFindHandle);
|
|
CASE_OF(TypeFtpFindHandleHtml);
|
|
CASE_OF(TypeFtpFileHandle);
|
|
CASE_OF(TypeFtpFileHandleHtml);
|
|
CASE_OF(TypeGopherConnectHandle);
|
|
CASE_OF(TypeGopherFindHandle);
|
|
CASE_OF(TypeGopherFindHandleHtml);
|
|
CASE_OF(TypeGopherFileHandle);
|
|
CASE_OF(TypeGopherFileHandleHtml);
|
|
CASE_OF(TypeHttpConnectHandle);
|
|
CASE_OF(TypeHttpRequestHandle);
|
|
CASE_OF(TypeFileRequestHandle);
|
|
CASE_OF(TypeWildHandle);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapScheme(
|
|
IN INTERNET_SCHEME Scheme
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Maps INTERNET_SCHEME_ to symbolic name
|
|
|
|
Arguments:
|
|
|
|
Scheme - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Scheme) {
|
|
CASE_OF(INTERNET_SCHEME_UNKNOWN);
|
|
CASE_OF(INTERNET_SCHEME_DEFAULT);
|
|
CASE_OF(INTERNET_SCHEME_HTTP);
|
|
CASE_OF(INTERNET_SCHEME_HTTPS);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapOpenType(
|
|
IN DWORD OpenType
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Maps INTERNET_OPEN_TYPE_ to symbolic name
|
|
|
|
Arguments:
|
|
|
|
OpenType - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (OpenType) {
|
|
CASE_OF(INTERNET_OPEN_TYPE_DIRECT);
|
|
CASE_OF(INTERNET_OPEN_TYPE_PROXY);
|
|
CASE_OF(INTERNET_OPEN_TYPE_PRECONFIG);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
|
|
LPSTR
|
|
InternetMapService(
|
|
IN DWORD Service
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Maps INTERNET_SERVICE_ to symbolic name
|
|
|
|
Arguments:
|
|
|
|
Service - to map
|
|
|
|
Return Value:
|
|
|
|
LPSTR
|
|
|
|
--*/
|
|
|
|
{
|
|
switch (Service)
|
|
{
|
|
CASE_OF(INTERNET_SERVICE_HTTP);
|
|
}
|
|
return "?";
|
|
}
|
|
|
|
//
|
|
// private functions
|
|
//
|
|
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
ExtractFileName(
|
|
IN LPSTR Module,
|
|
OUT LPSTR Buf
|
|
)
|
|
{
|
|
LPSTR filename;
|
|
LPSTR extension;
|
|
int len;
|
|
|
|
filename = strrchr(Module, '\\');
|
|
extension = strrchr(Module, '.');
|
|
if (filename) {
|
|
++filename;
|
|
} else {
|
|
filename = Module;
|
|
}
|
|
if (!extension) {
|
|
extension = filename + strlen(filename);
|
|
}
|
|
len = (int) (extension - filename);
|
|
memcpy(Buf, filename, len);
|
|
Buf[len] = '\0';
|
|
return Buf;
|
|
}
|
|
|
|
|
|
PRIVATE
|
|
LPSTR
|
|
SetDebugPrefix(
|
|
IN LPSTR Buffer
|
|
)
|
|
{
|
|
LPINTERNET_THREAD_INFO lpThreadInfo = InternetGetThreadInfo();
|
|
|
|
//INET_ASSERT(lpThreadInfo != NULL);
|
|
|
|
if (!lpThreadInfo) {
|
|
return NULL;
|
|
}
|
|
|
|
LPINTERNET_DEBUG_RECORD lpRecord;
|
|
|
|
lpRecord = lpThreadInfo->Stack;
|
|
|
|
if (InternetDebugControlFlags & DBG_ENTRY_TIME) {
|
|
if ((InternetDebugControlFlags & (DBG_DELTA_TIME | DBG_CUMULATIVE_TIME))
|
|
&& lpRecord) {
|
|
|
|
DWORD ticks;
|
|
DWORD ticksNow;
|
|
|
|
ticksNow = GetTickCountWrap();
|
|
ticks = ticksNow - ((InternetDebugControlFlags & DBG_CUMULATIVE_TIME)
|
|
? InternetDebugStartTime
|
|
: lpRecord->LastTime);
|
|
|
|
Buffer += rsprintf(Buffer,
|
|
"% 5d.%3d ",
|
|
ticks / 1000,
|
|
ticks % 1000
|
|
);
|
|
if (InternetDebugControlFlags & DBG_DELTA_TIME) {
|
|
lpRecord->LastTime = ticksNow;
|
|
}
|
|
} else {
|
|
|
|
SYSTEMTIME timeNow;
|
|
|
|
InternetDebugGetLocalTime(&timeNow, NULL);
|
|
|
|
Buffer += rsprintf(Buffer,
|
|
"%02d:%02d:%02d.%03d ",
|
|
timeNow.wHour,
|
|
timeNow.wMinute,
|
|
timeNow.wSecond,
|
|
timeNow.wMilliseconds
|
|
);
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (InternetDebugControlFlags & DBG_LEVEL_INDICATOR) {
|
|
Buffer += rsprintf(Buffer, );
|
|
}
|
|
*/
|
|
|
|
if (InternetDebugControlFlags & DBG_THREAD_INFO) {
|
|
|
|
//
|
|
// thread id
|
|
//
|
|
|
|
Buffer += rsprintf(Buffer, "%08x", lpThreadInfo->ThreadId);
|
|
|
|
//
|
|
// INTERNET_THREAD_INFO address
|
|
//
|
|
|
|
if (InternetDebugControlFlags & DBG_THREAD_INFO_ADR) {
|
|
Buffer += rsprintf(Buffer, ":%08x", lpThreadInfo);
|
|
}
|
|
|
|
//
|
|
// ARB address
|
|
//
|
|
|
|
//if (InternetDebugControlFlags & DBG_ARB_ADDR) {
|
|
// Buffer += rsprintf(Buffer, ":%08x", lpThreadInfo->lpArb);
|
|
//}
|
|
|
|
//
|
|
// FIBER address
|
|
//
|
|
|
|
//if (InternetDebugControlFlags & DBG_FIBER_INFO) {
|
|
//
|
|
// LPVOID p;
|
|
//
|
|
// p = (lpThreadInfo->lpArb != NULL)
|
|
// ? lpThreadInfo->lpArb->Header.lpFiber
|
|
// : NULL
|
|
// ;
|
|
// Buffer += rsprintf(Buffer, ":%08x", p);
|
|
//}
|
|
|
|
//
|
|
// async ID
|
|
//
|
|
|
|
if (InternetDebugControlFlags & DBG_ASYNC_ID) {
|
|
if (lpThreadInfo->IsAsyncWorkerThread) {
|
|
Buffer += rsprintf(Buffer, ":<--->");
|
|
} else if (lpThreadInfo->InCallback) {
|
|
|
|
//
|
|
// async worker thread calling back into the app; any WinInet
|
|
// API requests during this time treated as though from the
|
|
// app context
|
|
//
|
|
|
|
Buffer += rsprintf(Buffer, ":<c-b>");
|
|
}
|
|
else
|
|
{
|
|
|
|
//
|
|
// this is an app thread
|
|
//
|
|
|
|
Buffer += rsprintf(Buffer, ":<app>");
|
|
}
|
|
}
|
|
|
|
//
|
|
// request handle
|
|
//
|
|
|
|
if (InternetDebugControlFlags & DBG_REQUEST_HANDLE) {
|
|
Buffer += rsprintf(Buffer, ":%6X", lpThreadInfo->hObject);
|
|
}
|
|
|
|
*Buffer++ = ' ';
|
|
}
|
|
|
|
if (InternetDebugControlFlags & DBG_CALL_DEPTH) {
|
|
Buffer += rsprintf(Buffer, "%03d ", lpThreadInfo->CallDepth);
|
|
}
|
|
|
|
for (int i = 0; i < lpThreadInfo->IndentIncrement; ++i) {
|
|
*Buffer++ = ' ';
|
|
}
|
|
|
|
//
|
|
// if we are not debugging the category - i.e we got here via a requirement
|
|
// to display an error, or we are in a function that does not have a
|
|
// DEBUG_ENTER - then prefix the string with the current function name
|
|
// (obviously misleading if the function doesn't have a DEBUG_ENTER)
|
|
//
|
|
|
|
if (lpRecord != NULL) {
|
|
if (!(lpRecord->Category & InternetDebugCategoryFlags)) {
|
|
Buffer += rsprintf(Buffer, "%s(): ", lpRecord->Function);
|
|
}
|
|
}
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
int dprintf(char * format, ...) {
|
|
|
|
va_list args;
|
|
char buf[PRINTF_STACK_BUFFER_LENGTH];
|
|
int n;
|
|
|
|
va_start(args, format);
|
|
n = _sprintf(buf, format, args);
|
|
va_end(args);
|
|
OutputDebugString(buf);
|
|
|
|
return n;
|
|
}
|
|
|
|
|
|
LPSTR
|
|
SourceFilename(
|
|
LPSTR Filespec
|
|
)
|
|
{
|
|
if (!Filespec) {
|
|
return "?";
|
|
}
|
|
|
|
LPSTR p;
|
|
|
|
if (p = strrchr(Filespec, '\\')) {
|
|
|
|
//
|
|
// we want e.g. common\debugmem.cxx, but get
|
|
// common\..\win32\debugmem.cxx. Bah!
|
|
//
|
|
|
|
//LPSTR q;
|
|
//
|
|
//if (q = strrchr(p - 1, '\\')) {
|
|
// p = q;
|
|
//}
|
|
}
|
|
return p ? p + 1 : Filespec;
|
|
}
|
|
|
|
typedef BOOL (* SYMINITIALIZE)(HANDLE, LPSTR, BOOL);
|
|
typedef BOOL (* SYMLOADMODULE)(HANDLE, HANDLE, PSTR, PSTR, DWORD, DWORD);
|
|
typedef BOOL (* SYMGETSYMFROMADDR)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
|
|
typedef BOOL (* SYMCLEANUP)(HANDLE);
|
|
|
|
PRIVATE HMODULE hSymLib = NULL;
|
|
PRIVATE SYMINITIALIZE pSymInitialize = NULL;
|
|
PRIVATE SYMLOADMODULE pSymLoadModule = NULL;
|
|
PRIVATE SYMGETSYMFROMADDR pSymGetSymFromAddr = NULL;
|
|
PRIVATE SYMCLEANUP pSymCleanup = NULL;
|
|
|
|
|
|
VOID
|
|
InitSymLib(
|
|
VOID
|
|
)
|
|
{
|
|
if (hSymLib == NULL) {
|
|
hSymLib = LoadLibrary("IMAGEHLP.DLL");
|
|
if (hSymLib != NULL) {
|
|
pSymInitialize = (SYMINITIALIZE)GetProcAddress(hSymLib,
|
|
"SymInitialize"
|
|
);
|
|
pSymLoadModule = (SYMLOADMODULE)GetProcAddress(hSymLib,
|
|
"SymLoadModule"
|
|
);
|
|
pSymGetSymFromAddr = (SYMGETSYMFROMADDR)GetProcAddress(hSymLib,
|
|
"SymGetSymFromAddr"
|
|
);
|
|
pSymCleanup = (SYMCLEANUP)GetProcAddress(hSymLib,
|
|
"SymCleanup"
|
|
);
|
|
if (!pSymInitialize
|
|
|| !pSymLoadModule
|
|
|| !pSymGetSymFromAddr
|
|
|| !pSymCleanup) {
|
|
FreeLibrary(hSymLib);
|
|
hSymLib = NULL;
|
|
pSymInitialize = NULL;
|
|
pSymLoadModule = NULL;
|
|
pSymGetSymFromAddr = NULL;
|
|
pSymCleanup = NULL;
|
|
return;
|
|
}
|
|
}
|
|
pSymInitialize(GetCurrentProcess(), NULL, FALSE);
|
|
//SymInitialize(GetCurrentProcess(), NULL, TRUE);
|
|
pSymLoadModule(GetCurrentProcess(), NULL, "WININET.DLL", "WININET", 0, 0);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
TermSymLib(
|
|
VOID
|
|
)
|
|
{
|
|
if (pSymCleanup) {
|
|
pSymCleanup(GetCurrentProcess());
|
|
FreeLibrary(hSymLib);
|
|
}
|
|
}
|
|
|
|
|
|
LPSTR
|
|
GetDebugSymbol(
|
|
DWORD Address,
|
|
LPDWORD Offset
|
|
)
|
|
{
|
|
*Offset = Address;
|
|
if (!pSymGetSymFromAddr) {
|
|
return "";
|
|
}
|
|
|
|
//
|
|
// BUGBUG - only one caller at a time please
|
|
//
|
|
|
|
static char symBuf[512];
|
|
|
|
//((PIMAGEHLP_SYMBOL)symBuf)->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
|
|
((PIMAGEHLP_SYMBOL)symBuf)->SizeOfStruct = sizeof(symBuf);
|
|
((PIMAGEHLP_SYMBOL)symBuf)->MaxNameLength = sizeof(symBuf) - sizeof(IMAGEHLP_SYMBOL);
|
|
if (!pSymGetSymFromAddr(GetCurrentProcess(),
|
|
Address,
|
|
Offset,
|
|
(PIMAGEHLP_SYMBOL)symBuf)) {
|
|
((PIMAGEHLP_SYMBOL)symBuf)->Name[0] = '\0';
|
|
}
|
|
return ((PIMAGEHLP_SYMBOL)symBuf)->Name;
|
|
}
|
|
|
|
#ifndef DONT_RIP
|
|
BOOL fRip = TRUE;
|
|
#else
|
|
BOOL fRip = FALSE;
|
|
#endif
|
|
|
|
#define _TEXTW(x) L##x
|
|
#define TEXTW(x) _TEXTW(x)
|
|
#define SZ_MODULE "WINHTTP5"
|
|
#define ARRAYSIZE(pArray) (sizeof(pArray)/sizeof(pArray[0]))
|
|
EXTERN_C const CHAR FAR c_szRipNoFn[] = SZ_MODULE " RIP at %s, line %d: (%s)\r\n";
|
|
EXTERN_C const WCHAR FAR c_wszRipNoFn[] = TEXTW(SZ_MODULE) L" RIP at %s, line %d: (%s)\r\n";
|
|
|
|
|
|
|
|
static
|
|
LPCSTR
|
|
_PathFindFileNameA(
|
|
LPCSTR pPath)
|
|
{
|
|
LPCSTR pT;
|
|
|
|
for (pT = pPath; *pPath; pPath = CharNextA(pPath)) {
|
|
if ((pPath[0] == '\\' || pPath[0] == ':' || pPath[0] == '/')
|
|
&& pPath[1] && pPath[1] != '\\' && pPath[1] != '/')
|
|
pT = pPath + 1;
|
|
}
|
|
|
|
return pT;
|
|
}
|
|
|
|
|
|
static
|
|
LPCWSTR
|
|
_PathFindFileNameW(
|
|
LPCWSTR pPath)
|
|
{
|
|
LPCWSTR pT;
|
|
|
|
for (pT = pPath; *pPath; pPath++) {
|
|
if ((pPath[0] == TEXTW('\\') || pPath[0] == TEXTW(':') || pPath[0] == TEXTW('/'))
|
|
&& pPath[1] && pPath[1] != TEXTW('\\') && pPath[1] != TEXTW('/'))
|
|
pT = pPath + 1;
|
|
}
|
|
|
|
return pT;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: This function converts a multi-byte string to a
|
|
wide-char string.
|
|
|
|
If pszBuf is non-NULL and the converted string can fit in
|
|
pszBuf, then *ppszWide will point to the given buffer.
|
|
Otherwise, this function will allocate a buffer that can
|
|
hold the converted string.
|
|
|
|
If pszAnsi is NULL, then *ppszWide will be freed. Note
|
|
that pszBuf must be the same pointer between the call
|
|
that converted the string and the call that frees the
|
|
string.
|
|
|
|
Returns: TRUE
|
|
FALSE (if out of memory)
|
|
|
|
*/
|
|
BOOL
|
|
UnicodeFromAnsi(
|
|
LPWSTR * ppwszWide,
|
|
LPCSTR pszAnsi, // NULL to clean up
|
|
LPWSTR pwszBuf,
|
|
int cchBuf)
|
|
{
|
|
BOOL bRet;
|
|
|
|
// Convert the string?
|
|
if (pszAnsi)
|
|
{
|
|
// Yes; determine the converted string length
|
|
int cch;
|
|
LPWSTR pwsz;
|
|
int cchAnsi = lstrlenA(pszAnsi)+1;
|
|
|
|
cch = MultiByteToWideChar(CP_ACP, 0, pszAnsi, cchAnsi, NULL, 0);
|
|
|
|
// String too big, or is there no buffer?
|
|
if (cch > cchBuf || NULL == pwszBuf)
|
|
{
|
|
// Yes; allocate space
|
|
cchBuf = cch + 1;
|
|
pwsz = (LPWSTR)LocalAlloc(LPTR, ((cchBuf)*sizeof(WCHAR)));
|
|
}
|
|
else
|
|
{
|
|
// No; use the provided buffer
|
|
pwsz = pwszBuf;
|
|
}
|
|
|
|
if (pwsz)
|
|
{
|
|
// Convert the string
|
|
cch = MultiByteToWideChar(CP_ACP, 0, pszAnsi, cchAnsi, pwsz, cchBuf);
|
|
bRet = (0 < cch);
|
|
}
|
|
else
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
*ppwszWide = pwsz;
|
|
}
|
|
else
|
|
{
|
|
// No; was this buffer allocated?
|
|
if (*ppwszWide && pwszBuf != *ppwszWide)
|
|
{
|
|
// Yes; clean up
|
|
LocalFree((HLOCAL)*ppwszWide);
|
|
*ppwszWide = NULL;
|
|
}
|
|
bRet = TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Displays a RIP string.
|
|
|
|
Returns: TRUE to debugbreak
|
|
*/
|
|
BOOL
|
|
CcshellRipA(
|
|
LPCSTR pszFile,
|
|
int line,
|
|
LPCSTR pszEval,
|
|
BOOL bBreakInside)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
LPCSTR psz;
|
|
CHAR ach[256];
|
|
|
|
psz = _PathFindFileNameA(pszFile);
|
|
wsprintfA(ach, c_szRipNoFn, psz, line, pszEval);
|
|
OutputDebugStringA(ach);
|
|
|
|
if (fRip)
|
|
{
|
|
if (bBreakInside)
|
|
{
|
|
// !!! RIP !!!! RIP !!!! RIP !!!
|
|
|
|
// MSDEV USERS: This is not the real RIP. Hit
|
|
// Shift-F11 to jump back to the caller.
|
|
SH_DEBUG_BREAK; // ASSERT
|
|
|
|
// !!! RIP !!!! RIP !!!! RIP !!!
|
|
}
|
|
else
|
|
bRet = TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/*----------------------------------------------------------
|
|
Purpose: Displays a RIP string.
|
|
|
|
*/
|
|
BOOL
|
|
CcshellRipW(
|
|
LPCWSTR pszFile,
|
|
int line,
|
|
LPCWSTR pszEval,
|
|
BOOL bBreakInside)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
LPCWSTR psz;
|
|
WCHAR ach[256];
|
|
|
|
psz = _PathFindFileNameW(pszFile);
|
|
|
|
// If psz == NULL, CharPrevW failed which implies we are running on Win95.
|
|
// We can get this if we get an assert in some of the W functions in
|
|
// shlwapi... Call the A version of assert...
|
|
if (!psz)
|
|
{
|
|
char szFile[MAX_PATH];
|
|
char szEval[256]; // since the total output is thhis size should be enough...
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, pszFile, -1, szFile, ARRAYSIZE(szFile), NULL, NULL);
|
|
WideCharToMultiByte(CP_ACP, 0, pszEval, -1, szEval, ARRAYSIZE(szEval), NULL, NULL);
|
|
return CcshellRipA(szFile, line, szEval, bBreakInside);
|
|
}
|
|
|
|
wsprintfW(ach, c_wszRipNoFn, psz, line, pszEval);
|
|
OutputDebugStringW(ach);
|
|
|
|
if (fRip)
|
|
{
|
|
if (bBreakInside)
|
|
{
|
|
// !!! RIP !!!! RIP !!!! RIP !!!
|
|
|
|
// MSDEV USERS: This is not the real assert. Hit
|
|
// Shift-F11 to jump back to the caller.
|
|
SH_DEBUG_BREAK; // ASSERT
|
|
|
|
// !!! RIP !!!! RIP !!!! RIP !!!
|
|
}
|
|
else
|
|
bRet = TRUE;
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
EXTERN_C const CHAR FAR c_szRipMsg[] = SZ_MODULE " RIP: ";
|
|
EXTERN_C const CHAR FAR c_szNewline[] = "\n";
|
|
|
|
BOOL
|
|
__cdecl
|
|
CcshellRipMsgA(
|
|
BOOL f,
|
|
LPCSTR pszMsg, ...)
|
|
{
|
|
CHAR ach[1024+40];
|
|
va_list vArgs;
|
|
|
|
if (!f)
|
|
{
|
|
OutputDebugStringA(c_szRipMsg);
|
|
|
|
va_start(vArgs, pszMsg);
|
|
wvsprintfA(ach, pszMsg, vArgs);
|
|
va_end(vArgs);
|
|
OutputDebugStringA(ach);
|
|
|
|
OutputDebugStringA(c_szNewline);
|
|
|
|
if (fRip)
|
|
{
|
|
// MSDEV USERS: This is not the real assert. Hit
|
|
// Shift-F11 to jump back to the caller.
|
|
SH_DEBUG_BREAK; // ASSERT
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
__cdecl
|
|
CcshellRipMsgW(
|
|
BOOL f,
|
|
LPCSTR pszMsg, ...) // (this is deliberately CHAR)
|
|
{
|
|
WCHAR ach[1024+40];
|
|
va_list vArgs;
|
|
|
|
if (!f)
|
|
{
|
|
LPWSTR pwsz;
|
|
WCHAR wszBuf[128];
|
|
OutputDebugStringA(c_szRipMsg);
|
|
|
|
// (We convert the string, rather than simply input an
|
|
// LPCWSTR parameter, so the caller doesn't have to wrap
|
|
// all the string constants with the TEXT() macro.)
|
|
|
|
ach[0] = L'\0'; // In case this fails
|
|
if (UnicodeFromAnsi(&pwsz, pszMsg, wszBuf, ARRAYSIZE(wszBuf)))
|
|
{
|
|
va_start(vArgs, pszMsg);
|
|
wvsprintfW(ach, pwsz, vArgs);
|
|
va_end(vArgs);
|
|
UnicodeFromAnsi(&pwsz, NULL, wszBuf, 0);
|
|
}
|
|
|
|
OutputDebugStringW(ach);
|
|
OutputDebugStringA(c_szNewline);
|
|
|
|
if (fRip)
|
|
{
|
|
// MSDEV USERS: This is not the real assert. Hit
|
|
// Shift-F11 to jump back to the caller.
|
|
SH_DEBUG_BREAK; // ASSERT
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
#if defined(i386)
|
|
|
|
|
|
VOID
|
|
x86SleazeCallStack(
|
|
OUT LPVOID * lplpvStack,
|
|
IN DWORD dwStackCount,
|
|
IN LPVOID * Ebp
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Similar to x86SleazeCallersAddress but gathers a variable number of return
|
|
addresses. We assume all functions have stack frame
|
|
|
|
Arguments:
|
|
|
|
lplpvStack - pointer to returned array of caller's addresses
|
|
|
|
dwStackCount - number of elements in lplpvStack
|
|
|
|
Ebp - starting Ebp if not 0, else use current stack
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD my_esp;
|
|
|
|
_asm mov my_esp, esp;
|
|
|
|
__try {
|
|
if (Ebp == 0) {
|
|
Ebp = (LPVOID *)(&lplpvStack - 2);
|
|
}
|
|
while (dwStackCount--) {
|
|
if (((DWORD)Ebp > my_esp + 0x10000) || ((DWORD)Ebp < my_esp - 0x10000)) {
|
|
break;
|
|
}
|
|
*lplpvStack++ = *(Ebp + 1);
|
|
Ebp = (LPVOID *)*Ebp;
|
|
if (((DWORD)Ebp <= 0x10000)
|
|
|| ((DWORD)Ebp >= 0x80000000)
|
|
|| ((DWORD)Ebp & 3)
|
|
|| ((DWORD)Ebp > my_esp + 0x10000)
|
|
|| ((DWORD)Ebp < my_esp - 0x10000)) {
|
|
break;
|
|
}
|
|
}
|
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
x86SleazeCallersAddress(
|
|
LPVOID* pCaller,
|
|
LPVOID* pCallersCaller
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is a sleazy function that reads return addresses out of the stack/
|
|
frame pointer (ebp). We pluck out the return address of the function
|
|
that called THE FUNCTION THAT CALLED THIS FUNCTION, and the caller of
|
|
that function. Returning the return address of the function that called
|
|
this function is not interesting to that caller (almost worthy of Sir
|
|
Humphrey Appleby isn't it?)
|
|
|
|
Assumes:
|
|
|
|
my ebp => | caller's ebp |
|
|
| caller's eip |
|
|
| arg #1 | (pCaller)
|
|
| arg #2 | (pCallersCaller
|
|
|
|
Arguments:
|
|
|
|
pCaller - place where we return addres of function that called
|
|
the function that called this function
|
|
pCallersCaller - place where we return caller of above
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
//
|
|
// this only works on x86 and only if not fpo functions!
|
|
//
|
|
|
|
LPVOID* ebp;
|
|
|
|
ebp = (PVOID*)&pCaller - 2; // told you it was sleazy
|
|
ebp = (PVOID*)*(PVOID*)ebp;
|
|
*pCaller = *(ebp + 1);
|
|
ebp = (PVOID*)*(PVOID*)ebp;
|
|
*pCallersCaller = *(ebp + 1);
|
|
}
|
|
|
|
#endif // defined(i386)
|
|
|
|
#endif // ENABLE_DEBUG
|
|
|
|
INTERNETAPI
|
|
BOOL
|
|
WINAPI
|
|
InternetDebugGetLocalTime(
|
|
OUT SYSTEMTIME * pstLocalTime,
|
|
OUT DWORD * pdwMicroSec
|
|
)
|
|
{
|
|
#ifndef ENABLE_DEBUG
|
|
// QUICK HACK TO KEEP THINGS CLEAN AND STILL MEASURE WITH HIGH PERFORMANCE
|
|
// COUNTER
|
|
|
|
static BOOL pcTested = FALSE;
|
|
static LONGLONG ftInit; // initial local time
|
|
static LONGLONG pcInit; // initial perf counter
|
|
static LONGLONG pcFreq; // perf counter frequency
|
|
|
|
if (!pcTested)
|
|
{
|
|
pcTested = TRUE;
|
|
if (QueryPerformanceFrequency ((LARGE_INTEGER *) &pcFreq) && pcFreq)
|
|
{
|
|
QueryPerformanceCounter ((LARGE_INTEGER *) &pcInit);
|
|
SYSTEMTIME st;
|
|
GetLocalTime (&st);
|
|
SystemTimeToFileTime (&st, (FILETIME *) &ftInit);
|
|
}
|
|
}
|
|
|
|
if (!pcFreq)
|
|
GetLocalTime (pstLocalTime);
|
|
else
|
|
{
|
|
LONGLONG pcCurrent, ftCurrent;
|
|
QueryPerformanceCounter ((LARGE_INTEGER *) &pcCurrent);
|
|
ftCurrent = ftInit + ((10000000 * (pcCurrent - pcInit)) / pcFreq);
|
|
FileTimeToSystemTime ((FILETIME *) &ftCurrent, pstLocalTime);
|
|
}
|
|
|
|
return TRUE;
|
|
#else
|
|
if (!pcFreq)
|
|
GetLocalTime (pstLocalTime);
|
|
else
|
|
{
|
|
LONGLONG pcCurrent, ftCurrent;
|
|
QueryPerformanceCounter ((LARGE_INTEGER *) &pcCurrent);
|
|
ftCurrent = ftInit + ((10000000 * (pcCurrent - pcInit)) / pcFreq);
|
|
FileTimeToSystemTime ((FILETIME *) &ftCurrent, pstLocalTime);
|
|
}
|
|
|
|
return TRUE;
|
|
#endif // ENABLE_DEBUG
|
|
}
|