2025-04-27 07:49:33 -04:00

1373 lines
32 KiB
C

/*++
Copyright (c) 1998-1999 Microsoft Corporation
Module Name:
ulutil.c
Abstract:
General utility functions shared by the various UL test apps.
Author:
Keith Moore (keithmo) 19-Aug-1998
Revision History:
--*/
#include "precomp.h"
#define MAX_VERB_LENGTH 16
#define MAX_HEADER_LENGTH 256
#define MAX_URL_LENGTH 256
#define READ_STRING( localaddr, locallen, remoteaddr, remotelen ) \
do \
{ \
ULONG _len; \
RtlZeroMemory( (localaddr), (locallen) ); \
_len = min( (locallen), (remotelen) + sizeof(WCHAR) ); \
RtlCopyMemory( \
(PVOID)(localaddr), \
(PVOID)(remoteaddr), \
_len \
); \
} while (FALSE)
typedef struct _HEADER_PAIR
{
HTTP_HEADER_ID HeaderId;
PSTR HeaderName;
} HEADER_PAIR, *PHEADER_PAIR;
#define MAKE_HEADER_PAIR( name ) \
{ \
HttpHeader ## name, \
#name \
}
HEADER_PAIR g_HeaderPairs[] =
{
MAKE_HEADER_PAIR( Accept ),
MAKE_HEADER_PAIR( AcceptLanguage ),
MAKE_HEADER_PAIR( AcceptEncoding ),
MAKE_HEADER_PAIR( AcceptCharset ),
MAKE_HEADER_PAIR( Authorization ),
MAKE_HEADER_PAIR( Allow ),
MAKE_HEADER_PAIR( Connection ),
MAKE_HEADER_PAIR( CacheControl ),
MAKE_HEADER_PAIR( Cookie ),
MAKE_HEADER_PAIR( ContentLength ),
MAKE_HEADER_PAIR( ContentType ),
MAKE_HEADER_PAIR( ContentEncoding ),
MAKE_HEADER_PAIR( ContentLanguage ),
MAKE_HEADER_PAIR( ContentLocation ),
MAKE_HEADER_PAIR( ContentMd5 ),
MAKE_HEADER_PAIR( ContentRange ),
MAKE_HEADER_PAIR( Date ),
MAKE_HEADER_PAIR( Etag ),
MAKE_HEADER_PAIR( Expect ),
MAKE_HEADER_PAIR( Expires ),
MAKE_HEADER_PAIR( From ),
MAKE_HEADER_PAIR( Host ),
MAKE_HEADER_PAIR( IfModifiedSince ),
MAKE_HEADER_PAIR( IfNoneMatch ),
MAKE_HEADER_PAIR( IfMatch ),
MAKE_HEADER_PAIR( IfUnmodifiedSince ),
MAKE_HEADER_PAIR( IfRange ),
MAKE_HEADER_PAIR( LastModified ),
MAKE_HEADER_PAIR( MaxForwards ),
MAKE_HEADER_PAIR( Pragma ),
MAKE_HEADER_PAIR( ProxyAuthorization ),
MAKE_HEADER_PAIR( Referer ),
MAKE_HEADER_PAIR( Range ),
MAKE_HEADER_PAIR( Trailer ),
MAKE_HEADER_PAIR( TransferEncoding ),
MAKE_HEADER_PAIR( Te ),
MAKE_HEADER_PAIR( Upgrade ),
MAKE_HEADER_PAIR( UserAgent ),
MAKE_HEADER_PAIR( Via ),
MAKE_HEADER_PAIR( Warning )
};
#define NUM_HEADER_PAIRS (sizeof(g_HeaderPairs) / sizeof(g_HeaderPairs[0]))
PSID g_pSystemSid;
PSID g_pAdminSid;
PSID g_pCurrentUserSid;
PSID g_pWorldSid;
PWSTR
IpAddrToString(
IN ULONG IpAddress,
IN PWSTR String
)
{
wsprintf(
String,
L"%u.%u.%u.%u",
(IpAddress >> 24) & 0xFF,
(IpAddress >> 16) & 0xFF,
(IpAddress >> 8) & 0xFF,
(IpAddress >> 0) & 0xFF
);
return String;
} // IpAddrToString
BOOL
ParseCommandLine(
IN INT argc,
IN PWSTR argv[]
)
{
INT i;
PWSTR arg;
//
// Establish defaults.
//
g_Options.Verbose = FALSE;
g_Options.EnableBreak = FALSE;
//
// Scan the arguments.
//
for (i = 1 ; i < argc ; i++)
{
arg = argv[i];
if (!_wcsicmp(arg, L"Verbose"))
{
g_Options.Verbose = TRUE;
}
else if (!_wcsicmp(arg, L"EnableBreak"))
{
g_Options.EnableBreak = TRUE;
}
else
{
wprintf(
L"invalid option %s\n"
L"\n"
L"valid options are:\n"
L"\n"
L" Verbose - Enable verbose output\n"
L" EnableBreak - Enable debug breaks\n",
arg
);
return FALSE;
}
}
return TRUE;
} // ParseCommandLine
ULONG
CommonInit(
VOID
)
{
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
SID_IDENTIFIER_AUTHORITY worldAuthority = SECURITY_WORLD_SID_AUTHORITY;
HANDLE token;
PTOKEN_USER pTokenInfo;
ULONG length;
ULONG err;
BOOL status;
//
// Setup so we know how to cleanup on exit.
//
g_pSystemSid = NULL;
g_pAdminSid = NULL;
g_pCurrentUserSid = NULL;
g_pWorldSid = NULL;
pTokenInfo = NULL;
//
// Nuke stdio buffering.
//
setvbuf( stdin, NULL, _IONBF, 0 );
setvbuf( stdout, NULL, _IONBF, 0 );
//
// This makes it a bit easier to find this process in the
// kernel debugger...
//
wprintf( L"PID = 0x%lx\n", GetCurrentProcessId() );
//
// Create the standard SIDs.
//
status = AllocateAndInitializeSid(
&ntAuthority,
1,
SECURITY_LOCAL_SYSTEM_RID,
0,
0,
0,
0,
0,
0,
0,
&g_pSystemSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
status = AllocateAndInitializeSid(
&ntAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0,
0,
0,
0,
0,
0,
&g_pAdminSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
status = AllocateAndInitializeSid(
&worldAuthority,
1,
SECURITY_WORLD_RID,
0,
0,
0,
0,
0,
0,
0,
&g_pWorldSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
status = OpenProcessToken(
GetCurrentProcess(),
TOKEN_READ,
&token
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
GetTokenInformation(
token,
TokenUser,
NULL,
0,
&length
);
pTokenInfo = ALLOC( length );
if (pTokenInfo == NULL)
{
err = GetLastError();
goto cleanup;
}
status = GetTokenInformation(
token,
TokenUser,
pTokenInfo,
length,
&length
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
g_pCurrentUserSid = pTokenInfo->User.Sid;
//
// Success!
//
err = NO_ERROR;
cleanup:
if (err != NO_ERROR)
{
if (g_pSystemSid != NULL)
{
FreeSid( g_pSystemSid );
g_pSystemSid = NULL;
}
if (g_pAdminSid != NULL)
{
FreeSid( g_pAdminSid );
g_pAdminSid = NULL;
}
if (g_pWorldSid != NULL)
{
FreeSid( g_pWorldSid );
g_pWorldSid = NULL;
}
if (pTokenInfo != NULL)
{
FREE( pTokenInfo );
}
}
return err;
} // CommonInit
ULONG
InitUlStuff(
OUT PHANDLE pControlChannel,
OUT PHANDLE pAppPool,
OUT PHANDLE pFilterChannel,
OUT PHTTP_CONFIG_GROUP_ID pConfigGroup,
IN BOOL AllowSystem,
IN BOOL AllowAdmin,
IN BOOL AllowCurrentUser,
IN BOOL AllowWorld,
IN ULONG AppPoolOptions,
IN BOOL EnableSsl,
IN BOOL EnableRawFilters
)
{
ULONG result;
HANDLE controlChannel;
HANDLE appPool;
HANDLE filterChannel;
HTTP_CONFIG_GROUP_ID configId;
HTTP_CONFIG_GROUP_APP_POOL configAppPool;
HTTP_CONFIG_GROUP_STATE configState;
HTTP_ENABLED_STATE controlState;
HTTP_CONFIG_GROUP_SITE configSite;
BOOL initDone;
SECURITY_ATTRIBUTES securityAttributes;
//
// Setup locals so we know how to cleanup on exit.
//
initDone = FALSE;
controlChannel = NULL;
appPool = NULL;
filterChannel = NULL;
HTTP_SET_NULL_ID( &configId );
//
// Initialize the security attributes.
//
result = InitSecurityAttributes(
&securityAttributes,
AllowSystem,
AllowAdmin,
AllowCurrentUser,
AllowWorld
);
if (result != NO_ERROR)
{
wprintf( L"InitSecurityAttributes() failed, error %lu\n", result );
goto cleanup;
}
//
// Initialize the UL interface.
//
result = HttpInitialize( 0 );
if (result != NO_ERROR)
{
wprintf( L"HttpInitialize() failed, error %lu\n", result );
goto cleanup;
}
initDone = TRUE;
//
// Open a control channel to the driver.
//
result = HttpOpenControlChannel(
&controlChannel,
0
);
if (result != NO_ERROR)
{
wprintf( L"HttpOpenControlChannel() failed, error %lu\n", result );
goto cleanup;
}
//
// Create a filter channel.
//
if (EnableSsl || EnableRawFilters)
{
HTTP_CONTROL_CHANNEL_FILTER controlFilter;
//
// Create the filter.
//
result = HttpCreateFilter(
&filterChannel, // filter handle
L"TestFilter", // filter name
NULL, // security attributes
HTTP_OPTION_OVERLAPPED // options
);
if (result == NO_ERROR)
{
//
// Attach the filter to the control channel.
//
RtlZeroMemory(&controlFilter, sizeof(controlFilter));
controlFilter.Flags.Present = 1;
controlFilter.FilterHandle = filterChannel;
controlFilter.FilterOnlySsl = !EnableRawFilters;
result = HttpSetControlChannelInformation(
controlChannel,
HttpControlChannelFilterInformation,
&controlFilter,
sizeof(controlFilter)
);
if (result != NO_ERROR)
{
CloseHandle(filterChannel);
filterChannel = NULL;
}
}
}
//
// Create an application pool.
//
result = HttpCreateAppPool(
&appPool,
APP_POOL_NAME,
&securityAttributes,
AppPoolOptions
);
if (result != NO_ERROR)
{
wprintf( L"HttpCreateAppPool() failed, error %lu\n", result );
goto cleanup;
}
//
// Create a configuration group.
//
result = HttpCreateConfigGroup(
controlChannel,
&configId
);
if (result != NO_ERROR)
{
wprintf( L"HttpCreateConfigGroup() failed, error %lu\n", result );
goto cleanup;
}
//
// Add a URL to the configuration group.
//
result = HttpAddUrlToConfigGroup(
controlChannel,
configId,
URL_NAME,
0
);
if (result != NO_ERROR)
{
wprintf( L"HttpAddUrlToConfigGroup(1) failed, error %lu\n", result );
goto cleanup;
}
//
// Add a secure URL to the configuration group.
//
if (EnableSsl)
{
result = HttpAddUrlToConfigGroup(
controlChannel,
configId,
SECURE_URL_NAME,
1
);
if (result != NO_ERROR)
{
wprintf( L"HttpAddUrlToConfigGroup(2) failed, error %lu\n", result );
goto cleanup;
}
}
//
// Associate the configuration group with the application pool.
//
configAppPool.Flags.Present = 1;
configAppPool.AppPoolHandle = appPool;
result = HttpSetConfigGroupInformation(
controlChannel,
configId,
HttpConfigGroupAppPoolInformation,
&configAppPool,
sizeof(configAppPool)
);
if (result != NO_ERROR)
{
wprintf( L"HttpSetConfigGroupInformation(1) failed, error %lu\n", result );
goto cleanup;
}
//
// Set the config group state.
//
configState.Flags.Present = 1;
configState.State = HttpEnabledStateActive; // not really necessary
result = HttpSetConfigGroupInformation(
controlChannel,
configId,
HttpConfigGroupStateInformation,
&configState,
sizeof(configState)
);
if (result != NO_ERROR)
{
wprintf( L"HttpSetConfigGroupInformation(2) failed, error %lu\n", result );
goto cleanup;
}
//
// Set the Site ID on the Root Config Group object
//
configSite.SiteId = (ULONG) configId;
result = HttpSetConfigGroupInformation(
controlChannel,
configId,
HttpConfigGroupSiteInformation,
&configSite,
sizeof(configSite)
);
if (result != NO_ERROR)
{
wprintf( L"HttpSetConfigGroupInformation(3) failed, error 0x%08X\n", result);
// NOTE: continue on; site-id not essential.
}
//
// Throw the big switch.
//
controlState = HttpEnabledStateActive;
result = HttpSetControlChannelInformation(
controlChannel,
HttpControlChannelStateInformation,
&controlState,
sizeof(controlState)
);
if (result != NO_ERROR)
{
wprintf( L"HttpSetControlChannelInformation() failed, error %lu\n", result );
goto cleanup;
}
//
// Success!
//
*pControlChannel = controlChannel;
*pAppPool = appPool;
if (EnableSsl || EnableRawFilters)
{
*pFilterChannel = filterChannel;
}
*pConfigGroup = configId;
return NO_ERROR;
cleanup:
if (!HTTP_IS_NULL_ID( &configId ))
{
ULONG result2;
result2 = HttpDeleteConfigGroup(
controlChannel,
configId
);
if (result2 != NO_ERROR)
{
wprintf( L"HttpDeleteConfigGroup() failed, error %lu\n", result2 );
}
}
if (appPool != NULL)
{
CloseHandle( appPool );
}
if (controlChannel != NULL)
{
CloseHandle( controlChannel );
}
if (initDone)
{
HttpTerminate();
}
return result;
} // InitUlStuff
VOID
DumpHttpRequest(
IN PHTTP_REQUEST pRequest
)
{
PCHAR pBuffer;
ULONG BufferLength;
pBuffer = NULL;
BufferLength = 0;
for (;;)
{
if (pBuffer != NULL)
{
FREE( pBuffer );
}
BufferLength += 1024;
pBuffer = ALLOC( BufferLength );
if (pBuffer == NULL)
{
wprintf( L"out of memory\n" );
return;
}
if (RenderHttpRequest( pRequest, pBuffer, BufferLength ))
{
break;
}
}
wprintf( L"%hs\n", pBuffer );
FREE( pBuffer );
} // DumpHttpRequest
PSTR
VerbToString(
IN HTTP_VERB Verb
)
{
PSTR result;
switch (Verb)
{
case HttpVerbUnparsed:
result = "UnparsedVerb";
break;
case HttpVerbGET:
result = "GET";
break;
case HttpVerbPUT:
result = "PUT";
break;
case HttpVerbHEAD:
result = "HEAD";
break;
case HttpVerbPOST:
result = "POST";
break;
case HttpVerbDELETE:
result = "DELETE";
break;
case HttpVerbTRACE:
result = "TRACE";
break;
case HttpVerbOPTIONS:
result = "OPTIONS";
break;
case HttpVerbMOVE:
result = "MOVE";
break;
case HttpVerbCOPY:
result = "COPY";
break;
case HttpVerbPROPFIND:
result = "PROPFIND";
break;
case HttpVerbPROPPATCH:
result = "PROPPATCH";
break;
case HttpVerbMKCOL:
result = "MKCOL";
break;
case HttpVerbLOCK:
result = "LOCK";
break;
case HttpVerbUnknown:
result = "UnknownVerb";
break;
case HttpVerbInvalid:
result = "InvalidVerb";
break;
default:
result = "INVALID";
break;
}
return result;
} // VerbToString
PSTR
VersionToString(
IN HTTP_VERSION Version
)
{
PSTR result;
if (HTTP_EQUAL_VERSION(Version, 0, 0))
{
result = "Unknown";
}
else
if (HTTP_EQUAL_VERSION(Version, 0, 9))
{
result = "HTTP/0.9";
}
else
if (HTTP_EQUAL_VERSION(Version, 1, 0))
{
result = "HTTP/1.0";
}
else
if (HTTP_EQUAL_VERSION(Version, 1, 1))
{
result = "HTTP/1.1";
}
else
{
result = "INVALID";
}
return result;
} // VersionToString
PSTR
HeaderIdToString(
IN HTTP_HEADER_ID HeaderId
)
{
INT i;
PSTR result;
result = "INVALID";
for (i = 0 ; i < NUM_HEADER_PAIRS ; i++)
{
if (g_HeaderPairs[i].HeaderId == HeaderId)
{
result = g_HeaderPairs[i].HeaderName;
break;
}
}
return result;
} // HeaderIdToString
ULONG
InitSecurityAttributes(
OUT PSECURITY_ATTRIBUTES pSecurityAttributes,
IN BOOL AllowSystem,
IN BOOL AllowAdmin,
IN BOOL AllowCurrentUser,
IN BOOL AllowWorld
)
{
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
PSECURITY_DESCRIPTOR pSecurityDescriptor;
PACL pDacl;
ULONG daclSize;
ULONG err;
BOOL status;
//
// Setup locals so we know how to cleanup on exit.
//
pSecurityDescriptor = NULL;
pDacl = NULL;
//
// Initialize the easy parts.
//
ZeroMemory( pSecurityAttributes, sizeof(*pSecurityAttributes) );
pSecurityAttributes->nLength = sizeof(*pSecurityAttributes);
pSecurityAttributes->bInheritHandle = FALSE;
pSecurityAttributes->lpSecurityDescriptor = NULL;
//
// Allocate and initialize the security descriptor.
//
pSecurityDescriptor = ALLOC( sizeof(SECURITY_DESCRIPTOR) );
if (pSecurityDescriptor == NULL)
{
err = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
status = InitializeSecurityDescriptor(
pSecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
//
// Allocate the DACL containing one access-allowed ACE for each
// SID requested.
//
daclSize = sizeof(ACL);
if (AllowSystem)
{
daclSize +=
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid( g_pSystemSid );
}
if (AllowAdmin)
{
daclSize +=
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid( g_pAdminSid );
}
if (AllowCurrentUser)
{
daclSize +=
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid( g_pCurrentUserSid );
}
if (AllowWorld)
{
daclSize +=
sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid( g_pWorldSid );
}
pDacl = ALLOC( daclSize );
if (pDacl == NULL)
{
err = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
status = InitializeAcl(
pDacl,
daclSize,
ACL_REVISION
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
//
// Add the ACEs.
//
if (AllowSystem)
{
status = AddAccessAllowedAce(
pDacl,
ACL_REVISION,
FILE_ALL_ACCESS,
g_pSystemSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
}
if (AllowAdmin)
{
status = AddAccessAllowedAce(
pDacl,
ACL_REVISION,
FILE_ALL_ACCESS,
g_pAdminSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
}
if (AllowCurrentUser)
{
status = AddAccessAllowedAce(
pDacl,
ACL_REVISION,
FILE_ALL_ACCESS,
g_pCurrentUserSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
}
if (AllowWorld)
{
status = AddAccessAllowedAce(
pDacl,
ACL_REVISION,
FILE_ALL_ACCESS,
g_pWorldSid
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
}
//
// Set the DACL into the security descriptor.
//
status = SetSecurityDescriptorDacl(
pSecurityDescriptor,
TRUE,
pDacl,
FALSE
);
if (!status)
{
err = GetLastError();
goto cleanup;
}
//
// Attach the security descriptor to the security attributes.
//
pSecurityAttributes->lpSecurityDescriptor = pSecurityDescriptor;
//
// Success!
//
err = NO_ERROR;
cleanup:
if (err != NO_ERROR)
{
if (pDacl != NULL)
{
FREE( pDacl );
}
if (pSecurityDescriptor != NULL)
{
FREE( pSecurityDescriptor );
}
}
return err;
} // InitSecurityAttributes
BOOLEAN
RenderHttpRequest(
IN PHTTP_REQUEST pRequest,
OUT PCHAR pBuffer,
IN ULONG BufferLength
)
{
PHTTP_KNOWN_HEADER pKnownHeader;
PHTTP_UNKNOWN_HEADER pUnknownHeader;
PHTTP_NETWORK_ADDRESS_IPV4 pNetAddr;
ULONG i;
INT len;
CHAR verbBuffer[MAX_VERB_LENGTH];
CHAR headerBuffer[MAX_HEADER_LENGTH];
CHAR headerNameBuffer[MAX_HEADER_LENGTH];
WCHAR urlBuffer[MAX_URL_LENGTH];
CHAR rawUrlBuffer[MAX_URL_LENGTH];
WCHAR ipAddrBuffer[sizeof("123.123.123.123")];
if (pBuffer == NULL || BufferLength == 0)
{
return FALSE;
}
//
// Read the raw verb, raw url, and url buffers.
//
if (pRequest->Verb == HttpVerbUnknown)
{
READ_STRING(
verbBuffer,
sizeof(verbBuffer),
pRequest->pUnknownVerb,
pRequest->UnknownVerbLength
);
}
else
{
verbBuffer[0] = '\0';
}
READ_STRING(
rawUrlBuffer,
sizeof(rawUrlBuffer),
pRequest->pRawUrl,
pRequest->RawUrlLength
);
READ_STRING(
urlBuffer,
sizeof(urlBuffer),
pRequest->CookedUrl.pFullUrl,
pRequest->CookedUrl.FullUrlLength
);
//
// Render the header.
//
len = _snprintf(
pBuffer,
BufferLength,
"HTTP_REQUEST:\n"
" ConnectionId = %016I64x\n"
" RequestId = %016I64x\n"
" UrlContext = %016I64x\n"
" Version = %s\n"
" Verb = %s\n",
pRequest->ConnectionId,
pRequest->RequestId,
pRequest->UrlContext,
VersionToString( pRequest->Version ),
VerbToString( pRequest->Verb )
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
len = _snprintf(
pBuffer,
BufferLength,
" UnknownVerbLength = %lu\n"
" pUnknownVerb = %p (%ws)\n"
" RawUrlLength = %lu\n"
" pRawUrl = %p (%ws)\n"
" FullUrlLength = %lu\n"
" pFullUrl = %p (%ws)\n",
pRequest->UnknownVerbLength,
pRequest->pUnknownVerb,
verbBuffer,
pRequest->RawUrlLength,
pRequest->pRawUrl,
rawUrlBuffer,
pRequest->CookedUrl.FullUrlLength,
pRequest->CookedUrl.pFullUrl,
urlBuffer
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
len = _snprintf(
pBuffer,
BufferLength,
" Headers.UnknownHeaderCount = %lu\n"
" Headers.pUnknownHeaders = %p\n"
" EntityBodyLength = %lu\n"
" pEntityBody = %p\n",
pRequest->Headers.UnknownHeaderCount,
pRequest->Headers.pUnknownHeaders,
(pRequest->pEntityChunks ? pRequest->pEntityChunks[0].FromMemory.BufferLength : 0),
(pRequest->pEntityChunks ? pRequest->pEntityChunks[0].FromMemory.pBuffer : 0)
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
pNetAddr = pRequest->Address.pRemoteAddress;
len = _snprintf(
pBuffer,
BufferLength,
" RemoteAddressLength = %u\n"
" RemoteAddressType = %u\n"
" pRemoteAddress = %p (%ws:%u)\n",
pRequest->Address.RemoteAddressLength,
pRequest->Address.RemoteAddressType,
pRequest->Address.pRemoteAddress,
IpAddrToString( pNetAddr->IpAddress, ipAddrBuffer ),
pNetAddr->Port
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
pNetAddr = pRequest->Address.pLocalAddress;
len = _snprintf(
pBuffer,
BufferLength,
" LocalAddressLength = %u\n"
" LocalAddressType = %u\n"
" pLocalAddress = %p (%ws:%u)\n",
pRequest->Address.LocalAddressLength,
pRequest->Address.LocalAddressType,
pRequest->Address.pLocalAddress,
IpAddrToString( pNetAddr->IpAddress, ipAddrBuffer ),
pNetAddr->Port
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
//
// Render the known headers.
//
pKnownHeader = pRequest->Headers.pKnownHeaders;
for (i = 0 ; i < HttpHeaderRequestMaximum ; i++)
{
if (pKnownHeader->pRawValue != NULL)
{
READ_STRING(
headerBuffer,
sizeof(headerBuffer),
pKnownHeader->pRawValue,
pKnownHeader->RawValueLength
);
len = _snprintf(
pBuffer,
BufferLength,
" HTTP_HEADER[%lu]:\n"
" HeaderId = %s\n"
" RawValueLength = %lu\n"
" pRawValue = %p (%s)\n",
i,
HeaderIdToString( (HTTP_HEADER_ID)i ),
pKnownHeader->RawValueLength,
pKnownHeader->pRawValue,
headerBuffer
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
}
pKnownHeader++;
}
//
// Render the unknown headers.
//
pUnknownHeader = pRequest->Headers.pUnknownHeaders;
for (i = 0 ; i < pRequest->Headers.UnknownHeaderCount ; i++)
{
READ_STRING(
headerNameBuffer,
sizeof(headerNameBuffer),
pUnknownHeader->pName,
pUnknownHeader->NameLength
);
READ_STRING(
headerBuffer,
sizeof(headerBuffer),
pUnknownHeader->pRawValue,
pUnknownHeader->RawValueLength
);
len = _snprintf(
pBuffer,
BufferLength,
" HTTP_UNKNOWN_HEADER[%lu]:\n"
" NameLength = %lu\n"
" NameOffset = %p (%s)\n"
" ValueLength = %lu\n"
" ValueOffset = %p (%s)\n",
i,
pUnknownHeader->NameLength,
pUnknownHeader->pName,
headerNameBuffer,
pUnknownHeader->RawValueLength,
pUnknownHeader->pRawValue,
headerBuffer
);
if (len < 0)
{
return FALSE;
}
BufferLength -= (ULONG)len;
pBuffer += len;
pUnknownHeader++;
}
return TRUE;
} // RenderHttpRequest