3219 lines
85 KiB
C
3219 lines
85 KiB
C
/*++
|
|
|
|
Copyright (c) 1998-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dumpers.c
|
|
|
|
Abstract:
|
|
|
|
Dump routines for various structures.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 31-Jul-1998
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
#define MAX_NSGO_NAME_BUFFER 256
|
|
#define MAX_URL_PREFIX_BUFFER 256
|
|
#define MAX_RAW_VERB_BUFFER 16
|
|
#define MAX_RAW_URL_BUFFER 256
|
|
#define MAX_URL_BUFFER 256
|
|
#define MAX_HEADER_BUFFER 256
|
|
#define MAX_FILE_NAME_BUFFER 256
|
|
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
BOOLEAN
|
|
DumpUnknownHeadersCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
DumpUriEntryCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
DumpApoolCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
#define ENDPOINT_GLOBAL_CALLBACK_CONTEXT_SIGNATURE ((ULONG) 'xGPE')
|
|
|
|
typedef struct _ENDPOINT_GLOBAL_CALLBACK_CONTEXT
|
|
{
|
|
ULONG Signature;
|
|
PSTR Prefix;
|
|
ENDPOINT_CONNS Verbosity;
|
|
} ENDPOINT_GLOBAL_CALLBACK_CONTEXT, *PENDPOINT_GLOBAL_CALLBACK_CONTEXT;
|
|
|
|
BOOLEAN
|
|
DumpEndpointCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
IrpListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
ProcListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
RequestListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
DumpKQueueEntriesCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
FiltProcListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
DumpUlActiveConnectionCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
DumpUlIdleConnectionCallback(
|
|
IN PSINGLE_LIST_ENTRY RemoteSListEntry,
|
|
IN PVOID Context
|
|
);
|
|
|
|
typedef struct _CONN_CALLBACK_CONTEXT
|
|
{
|
|
ULONG Signature;
|
|
LONG Index;
|
|
LONG SubIndex;
|
|
ENDPOINT_CONNS Verbosity;
|
|
PSTR Prefix;
|
|
} CONN_CALLBACK_CONTEXT, *PCONN_CALLBACK_CONTEXT;
|
|
|
|
#define CONN_CALLBACK_CONTEXT_SIGNATURE ((ULONG) 'xCcC')
|
|
|
|
|
|
//
|
|
// Private globals.
|
|
//
|
|
|
|
PSTR
|
|
g_RequestHeaderIDs[] =
|
|
{
|
|
"CacheControl",
|
|
"Connection",
|
|
"Date",
|
|
"KeepAlive",
|
|
"Pragma",
|
|
"Trailer",
|
|
"TransferEncoding",
|
|
"Upgrade",
|
|
"Via",
|
|
"Warning",
|
|
"Allow",
|
|
"ContentLength",
|
|
"ContentType",
|
|
"ContentEncoding",
|
|
"ContentLanguage",
|
|
"ContentLocation",
|
|
"ContentMd5",
|
|
"ContentRange",
|
|
"Expires",
|
|
"LastModified",
|
|
"Accept",
|
|
"AcceptCharset",
|
|
"AcceptEncoding",
|
|
"AcceptLanguage",
|
|
"Authorization",
|
|
"Cookie",
|
|
"Expect",
|
|
"From",
|
|
"Host",
|
|
"IfMatch",
|
|
"IfModifiedSince",
|
|
"IfNoneMatch",
|
|
"IfRange",
|
|
"IfUnmodifiedSince",
|
|
"MaxForwards",
|
|
"ProxyAuthorization",
|
|
"Referer",
|
|
"Range",
|
|
"Te",
|
|
"UserAgent"
|
|
};
|
|
|
|
PSTR
|
|
g_ResponseHeaderIDs[] =
|
|
{
|
|
"CacheControl",
|
|
"Connection",
|
|
"Date",
|
|
"KeepAlive",
|
|
"Pragma",
|
|
"Trailer",
|
|
"TransferEncoding",
|
|
"Upgrade",
|
|
"Via",
|
|
"Warning",
|
|
"Allow",
|
|
"ContentLength",
|
|
"ContentType",
|
|
"ContentEncoding",
|
|
"ContentLanguage",
|
|
"ContentLocation",
|
|
"ContentMd5",
|
|
"ContentRange",
|
|
"Expires",
|
|
"LastModified",
|
|
"AcceptRanges",
|
|
"Age",
|
|
"Etag",
|
|
"Location",
|
|
"ProxyAuthenticate",
|
|
"RetryAfter",
|
|
"Server",
|
|
"SetCookie",
|
|
"Vary",
|
|
"WwwAuthenticate"
|
|
};
|
|
|
|
VECTORMAP
|
|
g_MdlFlagVector[] =
|
|
{
|
|
VECTORMAP_ENTRY( MDL_MAPPED_TO_SYSTEM_VA ),
|
|
VECTORMAP_ENTRY( MDL_PAGES_LOCKED ),
|
|
VECTORMAP_ENTRY( MDL_SOURCE_IS_NONPAGED_POOL),
|
|
VECTORMAP_ENTRY( MDL_ALLOCATED_FIXED_SIZE ),
|
|
VECTORMAP_ENTRY( MDL_PARTIAL ),
|
|
VECTORMAP_ENTRY( MDL_PARTIAL_HAS_BEEN_MAPPED),
|
|
VECTORMAP_ENTRY( MDL_IO_PAGE_READ ),
|
|
VECTORMAP_ENTRY( MDL_WRITE_OPERATION ),
|
|
VECTORMAP_ENTRY( MDL_PARENT_MAPPED_SYSTEM_VA),
|
|
VECTORMAP_ENTRY( MDL_LOCK_HELD ),
|
|
VECTORMAP_ENTRY( MDL_PHYSICAL_VIEW ),
|
|
VECTORMAP_ENTRY( MDL_IO_SPACE ),
|
|
VECTORMAP_ENTRY( MDL_NETWORK_HEADER ),
|
|
VECTORMAP_ENTRY( MDL_MAPPING_CAN_FAIL ),
|
|
VECTORMAP_ENTRY( MDL_ALLOCATED_MUST_SUCCEED ),
|
|
VECTORMAP_END
|
|
};
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
// If you modify DumpUlConnection, you may need to modify DumpUlConnectionLite
|
|
|
|
VOID
|
|
DumpUlConnection(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_CONNECTION LocalConnection
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
//
|
|
// Dump it.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sUL_CONNECTION @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s ReferenceCount = %lu\n"
|
|
"%s ConnectionFlags = %08lx\n"
|
|
"%s AcceptPending = %ld\n"
|
|
"%s AcceptComplete = %ld\n"
|
|
"%s DisconnectPending = %ld\n"
|
|
"%s DisconnectComplete = %ld\n"
|
|
"%s AbortPending = %ld\n"
|
|
"%s AbortComplete = %ld\n"
|
|
"%s DisconnectIndicated = %ld\n"
|
|
"%s AbortIndicated = %ld\n"
|
|
"%s CleanupBegun = %ld\n"
|
|
"%s FinalReferenceRemoved = %ld\n"
|
|
#if REFERENCE_DEBUG
|
|
"%s pTraceLog = %p\n"
|
|
#endif // REFERENCE_DEBUG
|
|
"%s IdleSListEntry @ %p (%p)\n"
|
|
"%s ActiveListEntry @ %p (%p)\n"
|
|
"%s ConnectionObject @ %p\n"
|
|
"%s Handle = %p\n"
|
|
"%s pFileObject = %p\n"
|
|
"%s pDeviceObject = %p\n"
|
|
"%s pConnectionContext = %p\n"
|
|
"%s pOwningEndpoint = %p\n"
|
|
"%s WorkItem @ %p\n"
|
|
"%s LocalAddress = %x\n" // IPv6
|
|
"%s LocalPort = %d\n"
|
|
"%s RemoteAddress = %x\n" // IPv6
|
|
"%s RemotePort = %d\n"
|
|
"%s ConnectionId = %I64x\n"
|
|
"%s pFilterChannel = %p\n"
|
|
"%s ChannelEntry @ %p\n"
|
|
"%s FilterConnState = %ld\n"
|
|
"%s ConnectionDelivered = %ld\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalConnection->Signature,
|
|
SignatureToString(
|
|
LocalConnection->Signature,
|
|
UL_CONNECTION_SIGNATURE,
|
|
UL_CONNECTION_SIGNATURE_X,
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalConnection->ReferenceCount,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.Value,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.AcceptPending,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.AcceptComplete,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.DisconnectPending,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.DisconnectComplete,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.AbortPending,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.AbortComplete,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.DisconnectIndicated,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.AbortIndicated,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.CleanupBegun,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.FinalReferenceRemoved,
|
|
#if REFERENCE_DEBUG
|
|
Prefix,
|
|
LocalConnection->pTraceLog,
|
|
#endif // REFERENCE_DEBUG
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, IdleSListEntry ),
|
|
LocalConnection->IdleSListEntry.Next,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, ActiveListEntry ),
|
|
LocalConnection->ActiveListEntry.Flink,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, ConnectionObject ),
|
|
Prefix,
|
|
LocalConnection->ConnectionObject.Handle,
|
|
Prefix,
|
|
LocalConnection->ConnectionObject.pFileObject,
|
|
Prefix,
|
|
LocalConnection->ConnectionObject.pDeviceObject,
|
|
Prefix,
|
|
LocalConnection->pConnectionContext,
|
|
Prefix,
|
|
LocalConnection->pOwningEndpoint,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, WorkItem ),
|
|
Prefix,
|
|
LocalConnection->LocalAddress,
|
|
Prefix,
|
|
LocalConnection->LocalPort,
|
|
Prefix,
|
|
LocalConnection->RemoteAddress,
|
|
Prefix,
|
|
LocalConnection->RemotePort,
|
|
Prefix,
|
|
LocalConnection->FilterInfo.ConnectionId,
|
|
Prefix,
|
|
LocalConnection->FilterInfo.pFilterChannel,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, FilterInfo.ChannelEntry ),
|
|
Prefix,
|
|
(int) LocalConnection->FilterInfo.ConnState,
|
|
Prefix,
|
|
LocalConnection->FilterInfo.ConnectionDelivered
|
|
);
|
|
} // DumpUlConnection
|
|
|
|
|
|
VOID
|
|
DumpUlConnectionLite(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_CONNECTION LocalConnection
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
//
|
|
// Dump it.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sUL_CONNECTION @ %p\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress
|
|
);
|
|
|
|
if (LocalConnection->Signature != UL_CONNECTION_SIGNATURE)
|
|
{
|
|
dprintf(
|
|
"%s Signature = %08lx (%s)\n",
|
|
Prefix,
|
|
LocalConnection->Signature,
|
|
SignatureToString(
|
|
LocalConnection->Signature,
|
|
UL_CONNECTION_SIGNATURE,
|
|
UL_CONNECTION_SIGNATURE_X,
|
|
strSignature
|
|
)
|
|
);
|
|
}
|
|
|
|
dprintf(
|
|
"%s ReferenceCount = %lu\n"
|
|
"%s ConnectionFlags = %08lx\n",
|
|
Prefix,
|
|
LocalConnection->ReferenceCount,
|
|
Prefix,
|
|
LocalConnection->ConnectionFlags.Value
|
|
);
|
|
|
|
if (! HTTP_IS_NULL_ID(&LocalConnection->FilterInfo.ConnectionId))
|
|
{
|
|
dprintf(
|
|
"%s ConnectionId = %I64x\n",
|
|
Prefix,
|
|
LocalConnection->FilterInfo.ConnectionId
|
|
);
|
|
}
|
|
|
|
if (LocalConnection->ActiveListEntry.Flink != NULL)
|
|
{
|
|
dprintf(
|
|
"%s ActiveListEntry @ %p (%p)\n",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, ActiveListEntry ),
|
|
LocalConnection->ActiveListEntry.Flink
|
|
);
|
|
}
|
|
else
|
|
{
|
|
dprintf(
|
|
"%s IdleSListEntry @ %p (%p)\n",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_CONNECTION, IdleSListEntry ),
|
|
LocalConnection->IdleSListEntry.Next
|
|
);
|
|
}
|
|
|
|
} // DumpUlConnectionLite
|
|
|
|
VOID
|
|
DumpHttpConnection(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_HTTP_CONNECTION LocalConnection
|
|
)
|
|
{
|
|
CHAR resourceState[MAX_RESOURCE_STATE_LENGTH];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
//
|
|
// Dump the easy parts.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sUL_HTTP_CONNECTION @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s ConnectionId = %I64x\n"
|
|
"%s WorkItem @ %p\n"
|
|
"%s RefCount = %lu\n"
|
|
"%s NextRecvNumber = %lu\n"
|
|
"%s NextBufferNumber = %lu\n"
|
|
"%s NextBufferToParse = %lu\n"
|
|
"%s pConnection = %p\n"
|
|
"%s pRequest = %p\n"
|
|
"%s Resource @ %p (%s)\n"
|
|
"%s BufferHead @ %p%s\n"
|
|
"%s BindingHead @ %p%s\n"
|
|
"%s pCurrentBuffer = %p\n"
|
|
"%s NeedMoreData = %lu\n"
|
|
"%s UlconnDestroyed = %lu\n"
|
|
"%s WaitingForResponse = %lu\n"
|
|
"%s WaitForDisconnectHead @ %p\n"
|
|
"%s DisconnectFlag = %s\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalConnection->Signature,
|
|
SignatureToString(
|
|
LocalConnection->Signature,
|
|
UL_HTTP_CONNECTION_POOL_TAG,
|
|
0,
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalConnection->ConnectionId,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_CONNECTION, WorkItem ),
|
|
Prefix,
|
|
LocalConnection->RefCount,
|
|
Prefix,
|
|
LocalConnection->NextRecvNumber,
|
|
Prefix,
|
|
LocalConnection->NextBufferNumber,
|
|
Prefix,
|
|
LocalConnection->NextBufferToParse,
|
|
Prefix,
|
|
LocalConnection->pConnection,
|
|
Prefix,
|
|
LocalConnection->pRequest,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_CONNECTION, Resource ),
|
|
BuildResourceState( &LocalConnection->Resource, resourceState ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_CONNECTION, BufferHead ),
|
|
IS_LIST_EMPTY(
|
|
LocalConnection,
|
|
RemoteAddress,
|
|
UL_HTTP_CONNECTION,
|
|
BufferHead,
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_CONNECTION, BindingHead ),
|
|
IS_LIST_EMPTY(
|
|
LocalConnection,
|
|
RemoteAddress,
|
|
UL_HTTP_CONNECTION,
|
|
BindingHead,
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
LocalConnection->pCurrentBuffer,
|
|
Prefix,
|
|
LocalConnection->NeedMoreData,
|
|
Prefix,
|
|
LocalConnection->UlconnDestroyed,
|
|
Prefix,
|
|
LocalConnection->WaitingForResponse,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_CONNECTION, WaitForDisconnectHead ),
|
|
Prefix,
|
|
LocalConnection->DisconnectFlag ? "TRUE" : "FALSE"
|
|
);
|
|
|
|
#if REFERENCE_DEBUG
|
|
dprintf(
|
|
"%s pTraceLog = %p\n",
|
|
Prefix,
|
|
LocalConnection->pTraceLog
|
|
);
|
|
#endif
|
|
|
|
dprintf( "\n" );
|
|
|
|
} // DumpHttpConnection
|
|
|
|
VOID
|
|
DumpHttpRequest(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_INTERNAL_REQUEST LocalRequest
|
|
)
|
|
{
|
|
UCHAR rawVerbBuffer[MAX_RAW_VERB_BUFFER];
|
|
UCHAR rawURLBuffer[MAX_RAW_URL_BUFFER];
|
|
UCHAR urlBuffer[MAX_URL_BUFFER];
|
|
CHAR resourceState[MAX_RESOURCE_STATE_LENGTH];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
ULONG i;
|
|
|
|
//
|
|
// Try to read the raw verb, raw url, and url buffers.
|
|
//
|
|
|
|
READ_REMOTE_STRING(
|
|
rawVerbBuffer,
|
|
sizeof(rawVerbBuffer),
|
|
LocalRequest->pRawVerb,
|
|
LocalRequest->RawVerbLength
|
|
);
|
|
|
|
READ_REMOTE_STRING(
|
|
rawURLBuffer,
|
|
sizeof(rawURLBuffer),
|
|
LocalRequest->RawUrl.pUrl,
|
|
LocalRequest->RawUrl.Length
|
|
);
|
|
|
|
READ_REMOTE_STRING(
|
|
urlBuffer,
|
|
sizeof(urlBuffer),
|
|
LocalRequest->CookedUrl.pUrl,
|
|
LocalRequest->CookedUrl.Length
|
|
);
|
|
|
|
//
|
|
// Dump the easy parts.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sHTTP_REQUEST @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s RefCount = %lu\n"
|
|
"%s RequestId = %I64x\n"
|
|
"%s ConnectionId = %I64x\n"
|
|
"%s pHttpConn = %p\n"
|
|
"%s WorkItem @ %p\n"
|
|
"%s AppPool.QueueState = %s\n"
|
|
"%s AppPool.pProcess = %p\n"
|
|
"%s AppPool.AppPoolEntry @ %p\n"
|
|
"%s pConfigInfo = %p\n"
|
|
"%s RecvNumber = %lu\n"
|
|
"%s ParseState = %d (%s)\n"
|
|
"%s ErrorCode = %lu\n"
|
|
"%s TotalRequestSize = %lu\n"
|
|
"%s UnknownHeaderCount = %lu\n"
|
|
"%s Verb = %s\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalRequest->Signature,
|
|
SignatureToString(
|
|
LocalRequest->Signature,
|
|
UL_INTERNAL_REQUEST_POOL_TAG,
|
|
0,
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalRequest->RefCount,
|
|
Prefix,
|
|
LocalRequest->RequestId,
|
|
Prefix,
|
|
LocalRequest->ConnectionId,
|
|
Prefix,
|
|
LocalRequest->pHttpConn,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, WorkItem ),
|
|
Prefix,
|
|
QueueStateToString( LocalRequest->AppPool.QueueState ),
|
|
Prefix,
|
|
LocalRequest->AppPool.pProcess,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, AppPool.AppPoolEntry ),
|
|
Prefix,
|
|
&LocalRequest->ConfigInfo,
|
|
Prefix,
|
|
LocalRequest->RecvNumber,
|
|
Prefix,
|
|
LocalRequest->ParseState,
|
|
ParseStateToString( LocalRequest->ParseState ),
|
|
Prefix,
|
|
LocalRequest->ErrorCode,
|
|
Prefix,
|
|
LocalRequest->TotalRequestSize,
|
|
Prefix,
|
|
LocalRequest->UnknownHeaderCount,
|
|
Prefix,
|
|
VerbToString( LocalRequest->Verb )
|
|
);
|
|
|
|
dprintf(
|
|
"%s pRawVerb = %p (%s)\n"
|
|
"%s RawVerbLength = %lu\n"
|
|
"%s RawUrl.pUrl = %p (%s)\n"
|
|
"%s RawUrl.pHost = %p\n"
|
|
"%s RawUrl.pAbsPath = %p\n"
|
|
"%s RawUrl.Length = %lu\n"
|
|
"%s CookedUrl.pUrl = %p (%ws)\n"
|
|
"%s CookedUrl.pHost = %p\n"
|
|
"%s CookedUrl.pAbsPath = %p\n"
|
|
"%s CookedUrl.pQueryString = %p\n"
|
|
"%s CookedUrl.Length = %lu\n"
|
|
"%s CookedUrl.Hash = %08lx\n"
|
|
"%s Version = %s\n"
|
|
"%s Headers @ %p\n"
|
|
"%s UnknownHeaderList @ %p%s\n",
|
|
Prefix,
|
|
LocalRequest->pRawVerb,
|
|
rawVerbBuffer,
|
|
Prefix,
|
|
LocalRequest->RawVerbLength,
|
|
Prefix,
|
|
LocalRequest->RawUrl.pUrl,
|
|
rawURLBuffer,
|
|
Prefix,
|
|
LocalRequest->RawUrl.pHost,
|
|
Prefix,
|
|
LocalRequest->RawUrl.pAbsPath,
|
|
Prefix,
|
|
LocalRequest->RawUrl.Length,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.pUrl,
|
|
urlBuffer,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.pHost,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.pAbsPath,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.pQueryString,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.Length,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.Hash,
|
|
Prefix,
|
|
VersionToString( LocalRequest->Version ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, Headers ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, UnknownHeaderList ),
|
|
IS_LIST_EMPTY(
|
|
LocalRequest,
|
|
RemoteAddress,
|
|
UL_INTERNAL_REQUEST,
|
|
UnknownHeaderList
|
|
) ? " (EMPTY)" : ""
|
|
);
|
|
|
|
dprintf(
|
|
"%s ContentLength = %I64u\n"
|
|
"%s ChunkBytesToParse = %I64u\n"
|
|
"%s ChunkBytesParsed = %I64u\n"
|
|
"%s ChunkBytesToRead = %I64u\n"
|
|
"%s ChunkBytesRead = %I64u\n"
|
|
"%s Chunked = %lu\n"
|
|
"%s ParsedFirstChunk = %lu\n"
|
|
"%s SentResponse = %lu\n"
|
|
"%s SentLast = %lu\n"
|
|
"%s pHeaderBuffer = %p\n"
|
|
"%s pLastHeaderBuffer = %p\n"
|
|
"%s IrpHead @ %p%s\n"
|
|
"%s pChunkBuffer = %p\n"
|
|
"%s pChunkLocation = %p\n",
|
|
Prefix,
|
|
LocalRequest->ContentLength,
|
|
Prefix,
|
|
LocalRequest->ChunkBytesToParse,
|
|
Prefix,
|
|
LocalRequest->ChunkBytesParsed,
|
|
Prefix,
|
|
LocalRequest->ChunkBytesToRead,
|
|
Prefix,
|
|
LocalRequest->ChunkBytesRead,
|
|
Prefix,
|
|
LocalRequest->Chunked,
|
|
Prefix,
|
|
LocalRequest->ParsedFirstChunk,
|
|
Prefix,
|
|
LocalRequest->SentResponse,
|
|
Prefix,
|
|
LocalRequest->SentLast,
|
|
Prefix,
|
|
LocalRequest->pHeaderBuffer,
|
|
Prefix,
|
|
LocalRequest->pLastHeaderBuffer,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, IrpHead ),
|
|
IS_LIST_EMPTY(
|
|
LocalRequest,
|
|
RemoteAddress,
|
|
UL_INTERNAL_REQUEST,
|
|
IrpHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
LocalRequest->pChunkBuffer,
|
|
Prefix,
|
|
LocalRequest->pChunkLocation
|
|
);
|
|
|
|
#if REFERENCE_DEBUG
|
|
dprintf(
|
|
"%s pTraceLog = %p\n",
|
|
Prefix,
|
|
LocalRequest->pTraceLog
|
|
);
|
|
#endif
|
|
|
|
//
|
|
// Dump the known headers.
|
|
//
|
|
|
|
for (i = 0 ; i < HttpHeaderRequestMaximum ; i++)
|
|
{
|
|
if (LocalRequest->HeaderValid[i])
|
|
{
|
|
DumpHttpHeader(
|
|
Prefix,
|
|
"",
|
|
(ULONG_PTR)REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, Headers[i] ),
|
|
&LocalRequest->Headers[i],
|
|
i,
|
|
g_RequestHeaderIDs
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Dump the unknown headers.
|
|
//
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY)REMOTE_OFFSET( RemoteAddress, UL_INTERNAL_REQUEST, UnknownHeaderList ),
|
|
&DumpUnknownHeadersCallback,
|
|
Prefix
|
|
);
|
|
|
|
} // DumpHttpRequest
|
|
|
|
VOID
|
|
DumpHttpResponse(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_INTERNAL_RESPONSE LocalResponse
|
|
)
|
|
{
|
|
ULONG i;
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
//
|
|
// Dump the easy parts.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sUL_INTERNAL_RESPONSE @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s ReferenceCount = %d\n"
|
|
"%s CompleteIrpEarly = %d\n"
|
|
"%s ContentLengthSpecified = %d\n"
|
|
"%s ChunkedSpecified = %d\n"
|
|
"%s StatusCode = %lu\n"
|
|
"%s Verb = %s\n"
|
|
"%s HeaderLength = %u\n"
|
|
"%s pHeaders = %p\n"
|
|
"%s AuxBufferLength = %u\n"
|
|
"%s pAuxiliaryBuffer = %p\n"
|
|
"%s MaxFileSystemStackSize = %d\n"
|
|
"%s ResponseLength = %I64u\n"
|
|
"%s ChunkCount = %d\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalResponse->Signature,
|
|
SignatureToString(
|
|
LocalResponse->Signature,
|
|
UL_INTERNAL_RESPONSE_POOL_TAG,
|
|
MAKE_FREE_TAG( UL_INTERNAL_RESPONSE_POOL_TAG ),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalResponse->ReferenceCount,
|
|
Prefix,
|
|
LocalResponse->CompleteIrpEarly,
|
|
Prefix,
|
|
LocalResponse->ContentLengthSpecified,
|
|
Prefix,
|
|
LocalResponse->ChunkedSpecified,
|
|
Prefix,
|
|
(ULONG)LocalResponse->StatusCode,
|
|
Prefix,
|
|
VerbToString( LocalResponse->Verb ),
|
|
Prefix,
|
|
LocalResponse->HeaderLength,
|
|
Prefix,
|
|
LocalResponse->pHeaders,
|
|
Prefix,
|
|
LocalResponse->AuxBufferLength,
|
|
Prefix,
|
|
LocalResponse->pAuxiliaryBuffer,
|
|
Prefix,
|
|
LocalResponse->MaxFileSystemStackSize,
|
|
Prefix,
|
|
LocalResponse->ResponseLength,
|
|
Prefix,
|
|
LocalResponse->ChunkCount
|
|
);
|
|
|
|
//
|
|
// Dump the chunks
|
|
//
|
|
for (i = 0; i < LocalResponse->ChunkCount; i++) {
|
|
UL_INTERNAL_DATA_CHUNK chunk;
|
|
ULONG_PTR address;
|
|
ULONG result;
|
|
|
|
address = (ULONG_PTR)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_INTERNAL_RESPONSE,
|
|
pDataChunks
|
|
) + (i * sizeof(UL_INTERNAL_DATA_CHUNK));
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&chunk,
|
|
sizeof(chunk),
|
|
&result
|
|
))
|
|
{
|
|
dprintf(
|
|
"%s: cannot read UL_INTERNAL_DATA_CHUNK @ %p\n",
|
|
CommandName,
|
|
address
|
|
);
|
|
break;
|
|
}
|
|
|
|
DumpDataChunk(
|
|
" ",
|
|
CommandName,
|
|
address,
|
|
&chunk
|
|
);
|
|
}
|
|
|
|
} // DumpHttpResponse
|
|
|
|
VOID
|
|
DumpDataChunk(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_INTERNAL_DATA_CHUNK Chunk
|
|
)
|
|
{
|
|
dprintf("%s%sUL_INTERNAL_DATA_CHUNK @ %p\n", Prefix, CommandName, RemoteAddress);
|
|
|
|
switch (Chunk->ChunkType) {
|
|
case HttpDataChunkFromMemory:
|
|
dprintf(
|
|
"%s ChunkType = HttpDataChunkFromMemory\n"
|
|
"%s pMdl = %p\n"
|
|
"%s pCopiedBuffer = %p\n"
|
|
"%s pUserBuffer = %p\n"
|
|
"%s BufferLength = %u\n",
|
|
Prefix,
|
|
Prefix,
|
|
Chunk->FromMemory.pMdl,
|
|
Prefix,
|
|
Chunk->FromMemory.pCopiedBuffer,
|
|
Prefix,
|
|
Chunk->FromMemory.pUserBuffer,
|
|
Prefix,
|
|
Chunk->FromMemory.BufferLength
|
|
);
|
|
break;
|
|
|
|
case HttpDataChunkFromFileName:
|
|
dprintf(
|
|
"%s ChunkType = HttpDataChunkFromFileName\n"
|
|
"%s ByteRange = [offset %I64d, len %I64d]\n"
|
|
"%s FileName = %ws\n"
|
|
"%s pFileCacheEntry = %p\n",
|
|
Prefix,
|
|
Prefix,
|
|
Chunk->FromFile.ByteRange.StartingOffset.QuadPart,
|
|
Chunk->FromFile.ByteRange.Length.QuadPart,
|
|
Prefix,
|
|
Chunk->FromFile.FileName.Buffer,
|
|
Prefix,
|
|
Chunk->FromFile.pFileCacheEntry
|
|
);
|
|
break;
|
|
|
|
case HttpDataChunkFromFileHandle:
|
|
dprintf(
|
|
"%s ChunkType = HttpDataChunkFromFileHandle\n"
|
|
"%s ByteRange = [offset %I64d, len %I64d]\n"
|
|
"%s FileHandle = %p\n"
|
|
"%s pFileCacheEntry = %p\n",
|
|
Prefix,
|
|
Prefix,
|
|
Chunk->FromFile.ByteRange.StartingOffset.QuadPart,
|
|
Chunk->FromFile.ByteRange.Length.QuadPart,
|
|
Prefix,
|
|
Chunk->FromFile.FileHandle,
|
|
Prefix,
|
|
Chunk->FromFile.pFileCacheEntry
|
|
);
|
|
break;
|
|
|
|
default:
|
|
dprintf(
|
|
"%s ChunkType = <Invalid>\n",
|
|
Prefix
|
|
);
|
|
break;
|
|
}
|
|
} // DumpDataChunk
|
|
|
|
|
|
VOID
|
|
DumpReceiveBuffer(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_RECEIVE_BUFFER LocalBuffer
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_RECEIVE_BUFFER @ %p\n"
|
|
"%s LookasideEntry @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s pIrp = %p\n"
|
|
"%s pMdl = %p\n"
|
|
"%s pPartialMdl = %p\n"
|
|
"%s pDataArea = %p\n"
|
|
"%s pConnection = %p\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_RECEIVE_BUFFER, LookasideEntry ),
|
|
Prefix,
|
|
LocalBuffer->Signature,
|
|
SignatureToString(
|
|
LocalBuffer->Signature,
|
|
UL_RECEIVE_BUFFER_SIGNATURE,
|
|
UL_RECEIVE_BUFFER_SIGNATURE_X,
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalBuffer->pIrp,
|
|
Prefix,
|
|
LocalBuffer->pMdl,
|
|
Prefix,
|
|
LocalBuffer->pPartialMdl,
|
|
Prefix,
|
|
LocalBuffer->pDataArea,
|
|
Prefix,
|
|
LocalBuffer->pConnectionContext
|
|
);
|
|
|
|
} // DumpReceiveBuffer
|
|
|
|
|
|
VOID
|
|
DumpRequestBuffer(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_REQUEST_BUFFER LocalBuffer
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_REQUEST_BUFFER @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s ListEntry @ %p\n"
|
|
"%s pConnection = %p\n"
|
|
"%s WorkItem @ %p\n"
|
|
"%s UsedBytes = %lu\n"
|
|
"%s AllocBytes = %lu\n"
|
|
"%s ParsedBytes = %lu\n"
|
|
"%s BufferNumber = %lu\n"
|
|
"%s JumboBuffer = %lu\n"
|
|
"%s pBuffer @ %p\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalBuffer->Signature,
|
|
SignatureToString(
|
|
LocalBuffer->Signature,
|
|
UL_REQUEST_BUFFER_POOL_TAG,
|
|
MAKE_FREE_TAG( UL_REQUEST_BUFFER_POOL_TAG ),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_REQUEST_BUFFER, ListEntry ),
|
|
Prefix,
|
|
LocalBuffer->pConnection,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_REQUEST_BUFFER, WorkItem ),
|
|
Prefix,
|
|
LocalBuffer->UsedBytes,
|
|
Prefix,
|
|
LocalBuffer->AllocBytes,
|
|
Prefix,
|
|
LocalBuffer->ParsedBytes,
|
|
Prefix,
|
|
LocalBuffer->BufferNumber,
|
|
Prefix,
|
|
LocalBuffer->JumboBuffer,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_REQUEST_BUFFER, pBuffer )
|
|
);
|
|
|
|
} // DumpRequestBuffer
|
|
|
|
|
|
VOID
|
|
DumpUlEndpoint(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_ENDPOINT LocalEndpoint,
|
|
IN ENDPOINT_CONNS Verbosity
|
|
)
|
|
{
|
|
PTRANSPORT_ADDRESS pTransportAddress;
|
|
UCHAR addressBuffer[MAX_TRANSPORT_ADDRESS_LENGTH];
|
|
CHAR connectionRequestSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR connectionCompleteSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR connectionDisconnectSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR connectionDestroyedSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR dataReceiveSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR tmpSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
ULONG offset;
|
|
ULONG result;
|
|
BOOLEAN NoActiveConns;
|
|
int i;
|
|
|
|
//
|
|
// Read the local address if it fits into our stack buffer.
|
|
//
|
|
|
|
pTransportAddress = NULL;
|
|
|
|
if (LocalEndpoint->LocalAddressLength <= sizeof(addressBuffer))
|
|
{
|
|
if (ReadMemory(
|
|
(ULONG_PTR)LocalEndpoint->pLocalAddress,
|
|
addressBuffer,
|
|
LocalEndpoint->LocalAddressLength,
|
|
&result
|
|
))
|
|
{
|
|
pTransportAddress = (PTRANSPORT_ADDRESS)addressBuffer;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Try to resolve the callback symbols.
|
|
//
|
|
|
|
BuildSymbol(
|
|
LocalEndpoint->pConnectionRequestHandler,
|
|
connectionRequestSymbol
|
|
);
|
|
|
|
BuildSymbol(
|
|
LocalEndpoint->pConnectionCompleteHandler,
|
|
connectionCompleteSymbol
|
|
);
|
|
|
|
BuildSymbol(
|
|
LocalEndpoint->pConnectionDisconnectHandler,
|
|
connectionDisconnectSymbol
|
|
);
|
|
|
|
BuildSymbol(
|
|
LocalEndpoint->pConnectionDestroyedHandler,
|
|
connectionDestroyedSymbol
|
|
);
|
|
|
|
BuildSymbol(
|
|
LocalEndpoint->pDataReceiveHandler,
|
|
dataReceiveSymbol
|
|
);
|
|
|
|
NoActiveConns = TRUE;
|
|
|
|
for (i = 0; i < DEFAULT_MAX_CONNECTION_ACTIVE_LISTS; ++i)
|
|
{
|
|
NoActiveConns &= IS_LIST_EMPTY(
|
|
LocalEndpoint,
|
|
RemoteAddress,
|
|
UL_ENDPOINT,
|
|
ActiveConnectionListHead[i]
|
|
);
|
|
}
|
|
|
|
//
|
|
// Dump it.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sUL_ENDPOINT @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s ReferenceCount = %ld\n"
|
|
"%s UsageCount = %ld\n"
|
|
"%s GlobalEndpointListEntry @ %p%s\n"
|
|
"%s IdleConnectionSListHead @ %p (%hd entries)\n"
|
|
"%s ActiveConnectionListHead @ %p%s\n"
|
|
"%s EndpointSpinLock @ %p (%s)\n"
|
|
"%s AddressObject @ %p\n"
|
|
"%s Handle = %p\n"
|
|
"%s pFileObject = %p\n"
|
|
"%s pDeviceObject = %p\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalEndpoint->Signature,
|
|
SignatureToString(
|
|
LocalEndpoint->Signature,
|
|
UL_ENDPOINT_SIGNATURE,
|
|
UL_ENDPOINT_SIGNATURE_X,
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalEndpoint->ReferenceCount,
|
|
Prefix,
|
|
LocalEndpoint->UsageCount,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, GlobalEndpointListEntry ),
|
|
LocalEndpoint->GlobalEndpointListEntry.Flink == NULL
|
|
? " (DISCONNECTED)"
|
|
: "",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, IdleConnectionSListHead ),
|
|
SLIST_HEADER_DEPTH(&LocalEndpoint->IdleConnectionSListHead),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, ActiveConnectionListHead ),
|
|
NoActiveConns ? " (EMPTY)" : "",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, EndpointSpinLock ),
|
|
GetSpinlockState( &LocalEndpoint->EndpointSpinLock ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, AddressObject ),
|
|
Prefix,
|
|
LocalEndpoint->AddressObject.Handle,
|
|
Prefix,
|
|
LocalEndpoint->AddressObject.pFileObject,
|
|
Prefix,
|
|
LocalEndpoint->AddressObject.pDeviceObject
|
|
);
|
|
|
|
dprintf(
|
|
"%s pConnectionRequestHandler = %p %s\n"
|
|
"%s pConnectionCompleteHandler = %p %s\n"
|
|
"%s pConnectionDisconnectHandler = %p %s\n"
|
|
"%s pConnectionDestroyedHandler = %p %s\n"
|
|
"%s pDataReceiveHandler = %p %s\n"
|
|
"%s pListeningContext = %p\n"
|
|
"%s pLocalAddress = %p\n"
|
|
"%s LocalAddressLength = %lu\n",
|
|
Prefix,
|
|
LocalEndpoint->pConnectionRequestHandler,
|
|
connectionRequestSymbol,
|
|
Prefix,
|
|
LocalEndpoint->pConnectionCompleteHandler,
|
|
connectionCompleteSymbol,
|
|
Prefix,
|
|
LocalEndpoint->pConnectionDisconnectHandler,
|
|
connectionDisconnectSymbol,
|
|
Prefix,
|
|
LocalEndpoint->pConnectionDestroyedHandler,
|
|
connectionDestroyedSymbol,
|
|
Prefix,
|
|
LocalEndpoint->pDataReceiveHandler,
|
|
dataReceiveSymbol,
|
|
Prefix,
|
|
LocalEndpoint->pListeningContext,
|
|
Prefix,
|
|
LocalEndpoint->pLocalAddress,
|
|
Prefix,
|
|
LocalEndpoint->LocalAddressLength
|
|
);
|
|
|
|
if (pTransportAddress != NULL)
|
|
{
|
|
CHAR newPrefix[256];
|
|
|
|
sprintf( newPrefix, "%s ", Prefix );
|
|
|
|
DumpTransportAddress(
|
|
newPrefix,
|
|
pTransportAddress,
|
|
(ULONG_PTR)LocalEndpoint->pLocalAddress
|
|
);
|
|
}
|
|
|
|
dprintf(
|
|
#if ENABLE_OWNER_REF_TRACE
|
|
"%s pOwnerRefTraceLog = %p\n"
|
|
#endif
|
|
"%s WorkItem @ %p\n"
|
|
"%s EndpointSynch @ %p\n"
|
|
"%s ReplenishScheduled = %d\n"
|
|
"%s IdleConnections = %d\n"
|
|
"\n",
|
|
#if ENABLE_OWNER_REF_TRACE
|
|
Prefix,
|
|
LocalEndpoint->pOwnerRefTraceLog,
|
|
#endif
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, WorkItem ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_ENDPOINT, EndpointSynch ),
|
|
Prefix,
|
|
LocalEndpoint->EndpointSynch.ReplenishScheduled,
|
|
Prefix,
|
|
LocalEndpoint->EndpointSynch.IdleConnections
|
|
);
|
|
|
|
if (Verbosity != ENDPOINT_NO_CONNS)
|
|
{
|
|
CONN_CALLBACK_CONTEXT ConnContext;
|
|
|
|
ConnContext.Signature = CONN_CALLBACK_CONTEXT_SIGNATURE;
|
|
ConnContext.Index = 0;
|
|
ConnContext.SubIndex = 0;
|
|
ConnContext.Verbosity = Verbosity;
|
|
ConnContext.Prefix = "";
|
|
|
|
if (! NoActiveConns)
|
|
{
|
|
dprintf(
|
|
"\n"
|
|
"%s Active Connections\n",
|
|
Prefix);
|
|
|
|
for (i = 0; i < DEFAULT_MAX_CONNECTION_ACTIVE_LISTS; ++i)
|
|
{
|
|
if (! IS_LIST_EMPTY(LocalEndpoint,
|
|
RemoteAddress,
|
|
UL_ENDPOINT,
|
|
ActiveConnectionListHead[i]))
|
|
{
|
|
CHAR newPrefix[256];
|
|
|
|
sprintf( newPrefix, "%s %2d ", Prefix, i );
|
|
|
|
dprintf(
|
|
"\n"
|
|
"%s Active Connections[%d]\n",
|
|
Prefix);
|
|
|
|
ConnContext.Index = i;
|
|
ConnContext.SubIndex = 0;
|
|
ConnContext.Prefix = newPrefix;
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY) REMOTE_OFFSET(RemoteAddress, UL_ENDPOINT,
|
|
ActiveConnectionListHead[i]),
|
|
&DumpUlActiveConnectionCallback,
|
|
&ConnContext
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SLIST_HEADER_NEXT(&LocalEndpoint->IdleConnectionSListHead) != NULL)
|
|
{
|
|
dprintf(
|
|
"\n"
|
|
"%s Idle Connections, slist depth = %hd\n",
|
|
Prefix,
|
|
SLIST_HEADER_DEPTH(&LocalEndpoint->IdleConnectionSListHead)
|
|
);
|
|
|
|
ConnContext.Index = 0;
|
|
ConnContext.SubIndex = 0;
|
|
ConnContext.Prefix = Prefix;
|
|
|
|
EnumSList(
|
|
(PSLIST_HEADER) REMOTE_OFFSET(RemoteAddress, UL_ENDPOINT,
|
|
IdleConnectionSListHead),
|
|
&DumpUlIdleConnectionCallback,
|
|
&ConnContext
|
|
);
|
|
}
|
|
}
|
|
#ifdef _WIN64
|
|
else
|
|
{
|
|
dprintf("\n"
|
|
" Cannot enumerate Idle Connections SList on Win64 :-(\n");
|
|
}
|
|
#endif // _WIN64
|
|
|
|
} // DumpUlEndpoint
|
|
|
|
|
|
VOID
|
|
DumpAllEndpoints(
|
|
IN ENDPOINT_CONNS Verbosity
|
|
)
|
|
{
|
|
ULONG_PTR address = GetExpression("&http!g_TdiEndpointListHead");
|
|
ENDPOINT_GLOBAL_CALLBACK_CONTEXT Context;
|
|
|
|
if (!address) {
|
|
dprintf(
|
|
"!endp *: cannot find symbol for http!g_TdiEndpointListHead\n"
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
Context.Signature = ENDPOINT_GLOBAL_CALLBACK_CONTEXT_SIGNATURE ;
|
|
Context.Verbosity = Verbosity;
|
|
Context.Prefix = "";
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY) address,
|
|
&DumpEndpointCallback,
|
|
&Context
|
|
);
|
|
}
|
|
|
|
VOID
|
|
DumpUlRequest(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PHTTP_REQUEST LocalRequest
|
|
)
|
|
{
|
|
UCHAR rawVerbBuffer[MAX_RAW_VERB_BUFFER];
|
|
UCHAR rawURLBuffer[MAX_RAW_URL_BUFFER];
|
|
UCHAR urlBuffer[MAX_URL_BUFFER];
|
|
|
|
//
|
|
// Try to read the raw verb, raw url, and url buffers.
|
|
//
|
|
|
|
READ_REMOTE_STRING(
|
|
rawVerbBuffer,
|
|
sizeof(rawVerbBuffer),
|
|
LocalRequest->pUnknownVerb,
|
|
LocalRequest->UnknownVerbLength
|
|
);
|
|
|
|
READ_REMOTE_STRING(
|
|
rawURLBuffer,
|
|
sizeof(rawURLBuffer),
|
|
LocalRequest->pRawUrl,
|
|
LocalRequest->RawUrlLength
|
|
);
|
|
|
|
READ_REMOTE_STRING(
|
|
urlBuffer,
|
|
sizeof(urlBuffer),
|
|
LocalRequest->CookedUrl.pFullUrl,
|
|
LocalRequest->CookedUrl.FullUrlLength
|
|
);
|
|
|
|
//
|
|
// Dump the easy parts.
|
|
//
|
|
|
|
dprintf(
|
|
"%s%sHTTP_REQUEST @ %p:\n"
|
|
"%s ConnectionId = %I64x\n"
|
|
"%s RequestId = %I64x\n"
|
|
"%s Verb = %s\n"
|
|
"%s VerbLength = %lu\n"
|
|
"%s VerbOffset = %p (%S)\n"
|
|
"%s RawUrlLength = %lu\n"
|
|
"%s RawUrlOffset = %p (%S)\n"
|
|
"%s UrlLength = %lu\n"
|
|
"%s UrlOffset = %p (%S)\n"
|
|
"%s UnknownHeaderCount = %lu\n"
|
|
"%s UnknownHeaderOffset = %p\n"
|
|
"%s EntityBodyLength = %lu\n"
|
|
"%s EntityBodyOffset = %p\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalRequest->ConnectionId,
|
|
Prefix,
|
|
LocalRequest->RequestId,
|
|
Prefix,
|
|
VerbToString( LocalRequest->Verb ),
|
|
Prefix,
|
|
LocalRequest->UnknownVerbLength,
|
|
Prefix,
|
|
LocalRequest->pUnknownVerb,
|
|
rawVerbBuffer,
|
|
Prefix,
|
|
LocalRequest->RawUrlLength,
|
|
Prefix,
|
|
LocalRequest->pRawUrl,
|
|
rawURLBuffer,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.FullUrlLength,
|
|
Prefix,
|
|
LocalRequest->CookedUrl.pFullUrl,
|
|
urlBuffer,
|
|
Prefix,
|
|
LocalRequest->Headers.UnknownHeaderCount,
|
|
Prefix,
|
|
LocalRequest->Headers.pUnknownHeaders,
|
|
Prefix,
|
|
LocalRequest->pEntityChunks->FromMemory.BufferLength,
|
|
Prefix,
|
|
LocalRequest->pEntityChunks->FromMemory.pBuffer
|
|
);
|
|
|
|
} // DumpUlRequest
|
|
|
|
|
|
VOID
|
|
DumpHttpHeader(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_HTTP_HEADER LocalHeader,
|
|
IN ULONG HeaderOrdinal,
|
|
IN PSTR *pHeaderIdMap
|
|
)
|
|
{
|
|
UCHAR headerBuffer[MAX_HEADER_BUFFER];
|
|
|
|
READ_REMOTE_STRING(
|
|
headerBuffer,
|
|
sizeof(headerBuffer),
|
|
LocalHeader->pHeader,
|
|
LocalHeader->HeaderLength
|
|
);
|
|
|
|
dprintf(
|
|
"%s%s UL_HTTP_HEADER[%lu] @ %p (%s):\n"
|
|
"%s HeaderLength = %lu\n"
|
|
"%s pHeader = %p (%s)\n"
|
|
"%s OurBuffer = %lu\n"
|
|
"%s Valid = %lu\n",
|
|
Prefix,
|
|
CommandName,
|
|
HeaderOrdinal,
|
|
RemoteAddress,
|
|
pHeaderIdMap[HeaderOrdinal],
|
|
Prefix,
|
|
LocalHeader->HeaderLength,
|
|
Prefix,
|
|
LocalHeader->pHeader,
|
|
headerBuffer,
|
|
Prefix,
|
|
LocalHeader->OurBuffer,
|
|
Prefix,
|
|
1
|
|
);
|
|
|
|
} // DumpHttpHeader
|
|
|
|
|
|
VOID
|
|
DumpUnknownHeader(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_HTTP_UNKNOWN_HEADER LocalHeader
|
|
)
|
|
{
|
|
UCHAR headerName[MAX_HEADER_BUFFER];
|
|
UCHAR headerValue[MAX_HEADER_BUFFER];
|
|
|
|
READ_REMOTE_STRING(
|
|
headerName,
|
|
sizeof(headerName),
|
|
LocalHeader->pHeaderName,
|
|
LocalHeader->HeaderNameLength
|
|
);
|
|
|
|
READ_REMOTE_STRING(
|
|
headerValue,
|
|
sizeof(headerValue),
|
|
LocalHeader->HeaderValue.pHeader,
|
|
LocalHeader->HeaderValue.HeaderLength
|
|
);
|
|
|
|
dprintf(
|
|
"%s%s HTTP_UNKNOWN_HEADER @ %p:\n"
|
|
"%s List @ %p\n"
|
|
"%s HeaderNameLength = %lu\n"
|
|
"%s pHeaderName = %p (%s)\n"
|
|
"%s HeaderValue @ %p\n"
|
|
"%s HeaderLength = %lu\n"
|
|
"%s pHeader = %p (%s)\n"
|
|
"%s OurBuffer = %lu\n"
|
|
"%s Valid = %lu\n",
|
|
"%s ExternalAllocated = %lu\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_UNKNOWN_HEADER, List ),
|
|
Prefix,
|
|
LocalHeader->HeaderNameLength,
|
|
Prefix,
|
|
LocalHeader->pHeaderName,
|
|
headerName,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_HTTP_UNKNOWN_HEADER, HeaderValue ),
|
|
Prefix,
|
|
LocalHeader->HeaderValue.HeaderLength,
|
|
Prefix,
|
|
LocalHeader->HeaderValue.pHeader,
|
|
headerValue,
|
|
Prefix,
|
|
LocalHeader->HeaderValue.OurBuffer,
|
|
Prefix,
|
|
1,
|
|
Prefix,
|
|
LocalHeader->HeaderValue.ExternalAllocated
|
|
);
|
|
|
|
} // DumpUnknownHeader
|
|
|
|
|
|
VOID
|
|
DumpFileCacheEntry(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_FILE_CACHE_ENTRY LocalFile
|
|
)
|
|
{
|
|
ULONG result;
|
|
ULONG_PTR offset;
|
|
ULONG nameLength;
|
|
WCHAR fileNameBuffer[MAX_PATH+1];
|
|
CHAR mdlReadSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR mdlReadCompleteSymbol[MAX_SYMBOL_LENGTH];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
nameLength = min( sizeof(fileNameBuffer), (ULONG)LocalFile->FileName.Length );
|
|
|
|
if (!ReadMemory(
|
|
(ULONG_PTR)LocalFile->FileName.Buffer,
|
|
fileNameBuffer,
|
|
nameLength,
|
|
&result
|
|
))
|
|
{
|
|
nameLength = 0;
|
|
}
|
|
|
|
fileNameBuffer[nameLength / sizeof(WCHAR)] = L'\0';
|
|
|
|
GetSymbol(
|
|
LocalFile->pMdlRead,
|
|
mdlReadSymbol,
|
|
&offset
|
|
);
|
|
|
|
GetSymbol(
|
|
LocalFile->pMdlReadComplete,
|
|
mdlReadCompleteSymbol,
|
|
&offset
|
|
);
|
|
|
|
dprintf(
|
|
"%s%sUL_FILE_CACHE_ENTRY @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s ReferenceCount = %lu\n"
|
|
"%s pFileObject = %p\n"
|
|
"%s pDeviceObject = %p\n"
|
|
"%s pMdlRead = %p %s\n"
|
|
"%s pMdlReadComplete = %p %s\n"
|
|
"%s FileName @ %p (%ws)\n"
|
|
"%s FileHandle = %p\n"
|
|
"%s WorkItem @ %p\n"
|
|
"%s FileInfo @ %p\n"
|
|
"%s AllocationSize = %I64u\n"
|
|
"%s EndOfFile = %I64u\n"
|
|
"%s NumberOfLinks = %lu\n"
|
|
"%s DeletePending = %lu\n"
|
|
"%s Directory = %lu\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalFile->Signature,
|
|
SignatureToString(
|
|
LocalFile->Signature,
|
|
UL_FILE_CACHE_ENTRY_SIGNATURE,
|
|
UL_FILE_CACHE_ENTRY_SIGNATURE_X,
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
LocalFile->ReferenceCount,
|
|
Prefix,
|
|
LocalFile->pFileObject,
|
|
Prefix,
|
|
LocalFile->pDeviceObject,
|
|
Prefix,
|
|
LocalFile->pMdlRead,
|
|
mdlReadSymbol,
|
|
Prefix,
|
|
LocalFile->pMdlReadComplete,
|
|
mdlReadCompleteSymbol,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILE_CACHE_ENTRY, FileName ),
|
|
fileNameBuffer,
|
|
Prefix,
|
|
LocalFile->FileHandle,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILE_CACHE_ENTRY, WorkItem ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILE_CACHE_ENTRY, FileInfo ),
|
|
Prefix,
|
|
LocalFile->FileInfo.AllocationSize.QuadPart,
|
|
Prefix,
|
|
LocalFile->FileInfo.EndOfFile.QuadPart,
|
|
Prefix,
|
|
LocalFile->FileInfo.NumberOfLinks,
|
|
Prefix,
|
|
(ULONG)LocalFile->FileInfo.DeletePending,
|
|
Prefix,
|
|
(ULONG)LocalFile->FileInfo.Directory
|
|
);
|
|
|
|
} // DumpFileCacheEntry
|
|
|
|
|
|
#if 0
|
|
// BUGBUG: GeorgeRe must fix
|
|
|
|
VOID
|
|
DumpUriEntry(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_URI_CACHE_ENTRY UriEntry
|
|
)
|
|
{
|
|
UCHAR urlBuffer[MAX_URL_BUFFER];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
READ_REMOTE_STRING(
|
|
urlBuffer,
|
|
sizeof(urlBuffer),
|
|
UriEntry->Uri.pUri,
|
|
UriEntry->Uri.Length
|
|
);
|
|
|
|
dprintf(
|
|
"%s%sUL_URI_CACHE_ENTRY @ %p\n"
|
|
"%s%S\n"
|
|
"%s\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s BucketEntry @ %p\n"
|
|
"%s Flink = %p ( !ulkd.uri %p )\n"
|
|
"%s Blink = %p ( !ulkd.uri %p )\n"
|
|
"%s Uri @ %p\n"
|
|
"%s Hash = %08lx\n"
|
|
"%s Length = %lu\n"
|
|
"%s pUri = %p\n"
|
|
"%s ReferenceCount = %lu\n"
|
|
"%s HitCount = %lu\n"
|
|
"%s Zombie = %lu\n"
|
|
"%s Cached = %lu\n"
|
|
"%s ContentLengthSpecified = %lu\n"
|
|
"%s StatusCode = %u\n"
|
|
"%s Verb = %s\n"
|
|
"%s ScavengerTicks = %lu\n"
|
|
"%s CachePolicy @ %p\n"
|
|
"%s Policy = %s\n"
|
|
"%s SecondsToLive = %lu\n"
|
|
"%s ExpirationTime = %08x%08x\n"
|
|
"%s pConfigInfo = %p\n"
|
|
"%s pProcess = %p\n"
|
|
"%s HeaderLength = %lu\n"
|
|
"%s pHeaders = %p\n"
|
|
"%s ContentLength = %lu\n"
|
|
"%s pContent = %p\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
urlBuffer,
|
|
Prefix,
|
|
Prefix,
|
|
UriEntry->Signature,
|
|
SignatureToString(
|
|
UriEntry->Signature,
|
|
UL_URI_CACHE_ENTRY_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_URI_CACHE_ENTRY_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_URI_CACHE_ENTRY, BucketEntry ),
|
|
Prefix,
|
|
UriEntry->BucketEntry.Flink,
|
|
CONTAINING_RECORD(
|
|
UriEntry->BucketEntry.Flink,
|
|
UL_URI_CACHE_ENTRY,
|
|
BucketEntry
|
|
),
|
|
Prefix,
|
|
UriEntry->BucketEntry.Blink,
|
|
CONTAINING_RECORD(
|
|
UriEntry->BucketEntry.Blink,
|
|
UL_URI_CACHE_ENTRY,
|
|
BucketEntry
|
|
),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_URI_CACHE_ENTRY, Uri ),
|
|
Prefix,
|
|
UriEntry->Uri.Hash,
|
|
Prefix,
|
|
UriEntry->Uri.Length,
|
|
Prefix,
|
|
UriEntry->Uri.pUri,
|
|
Prefix,
|
|
UriEntry->ReferenceCount,
|
|
Prefix,
|
|
UriEntry->HitCount,
|
|
Prefix,
|
|
UriEntry->Zombie,
|
|
Prefix,
|
|
UriEntry->Cached,
|
|
Prefix,
|
|
UriEntry->ContentLengthSpecified,
|
|
Prefix,
|
|
(ULONG)UriEntry->StatusCode,
|
|
Prefix,
|
|
VerbToString( UriEntry->Verb ),
|
|
Prefix,
|
|
UriEntry->ScavengerTicks,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_URI_CACHE_ENTRY, CachePolicy ),
|
|
Prefix,
|
|
CachePolicyToString( UriEntry->CachePolicy.Policy ),
|
|
Prefix,
|
|
UriEntry->CachePolicy.SecondsToLive,
|
|
Prefix,
|
|
UriEntry->ExpirationTime.HighPart,
|
|
UriEntry->ExpirationTime.LowPart,
|
|
Prefix,
|
|
UriEntry->pConfigInfo,
|
|
Prefix,
|
|
UriEntry->pProcess,
|
|
Prefix,
|
|
UriEntry->HeaderLength,
|
|
Prefix,
|
|
UriEntry->pHeaders,
|
|
Prefix,
|
|
UriEntry->ContentLength,
|
|
Prefix,
|
|
UriEntry->pContent
|
|
);
|
|
|
|
} // DumpUriEntry
|
|
|
|
#endif
|
|
|
|
VOID
|
|
DumpAllUriEntries(
|
|
VOID
|
|
)
|
|
{
|
|
ULONG_PTR address = 0;
|
|
// UL_URI_CACHE_TABLE table;
|
|
ULONG_PTR dataAddress;
|
|
ULONG i;
|
|
|
|
dprintf("BUGBUG: GeorgeRe needs to fix DumpAllUriEntries!\n");
|
|
|
|
#if 0
|
|
//
|
|
// find table
|
|
//
|
|
|
|
address = GetExpression("&http!g_pUriCacheTable");
|
|
if (address) {
|
|
if (ReadMemory(
|
|
address,
|
|
&dataAddress,
|
|
sizeof(dataAddress),
|
|
NULL
|
|
))
|
|
{
|
|
if (ReadMemory(
|
|
dataAddress,
|
|
&table,
|
|
sizeof(table),
|
|
NULL
|
|
))
|
|
{
|
|
//
|
|
// dump live entries
|
|
//
|
|
dprintf("Live UL_URI_CACHE_ENTRIES\n\n");
|
|
|
|
for (i = 0; i < table.BucketCount; i++) {
|
|
|
|
EnumLinkedList(
|
|
((PLIST_ENTRY)
|
|
REMOTE_OFFSET(
|
|
dataAddress,
|
|
UL_URI_CACHE_TABLE,
|
|
Buckets
|
|
)) + i,
|
|
&DumpUriEntryCallback,
|
|
"L "
|
|
);
|
|
}
|
|
|
|
} else {
|
|
dprintf(
|
|
"uri*: cannot read memory for http!g_pUriCacheTable = %p\n",
|
|
dataAddress
|
|
);
|
|
}
|
|
} else {
|
|
dprintf(
|
|
"uri*: cannot read memory for http!g_pUriCacheTable @ %p\n",
|
|
address
|
|
);
|
|
}
|
|
} else {
|
|
dprintf(
|
|
"uri*: cannot find symbol for http!g_pUriCacheTable\n"
|
|
);
|
|
}
|
|
|
|
//
|
|
// dump the zombie list
|
|
//
|
|
address = GetExpression("&http!g_ZombieListHead");
|
|
|
|
if (!address) {
|
|
dprintf(
|
|
"uri*: cannot find symbol for http!g_ZombieListHead\n"
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
dprintf("Zombie UL_URI_CACHE_ENTRIES\n\n");
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY) address,
|
|
&DumpUriEntryCallback,
|
|
"Z "
|
|
);
|
|
|
|
#endif
|
|
|
|
} // DumpAllUriEntries
|
|
|
|
|
|
VOID
|
|
DumpMdl(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PMDL LocalMdl,
|
|
IN ULONG MaxBytesToDump
|
|
)
|
|
{
|
|
dprintf(
|
|
"%s%sMDL @ %p\n"
|
|
"%s Next = %p\n"
|
|
"%s Size = %04x\n"
|
|
"%s MdlFlags = %04x\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalMdl->Next,
|
|
Prefix,
|
|
LocalMdl->Size,
|
|
Prefix,
|
|
LocalMdl->MdlFlags
|
|
);
|
|
|
|
DumpBitVector(
|
|
Prefix,
|
|
" ",
|
|
LocalMdl->MdlFlags,
|
|
g_MdlFlagVector
|
|
);
|
|
|
|
dprintf(
|
|
"%s Process = %p\n"
|
|
"%s MappedSystemVa = %p\n"
|
|
"%s StartVa = %p\n"
|
|
"%s ByteCount = %08lx\n"
|
|
"%s ByteOffset = %08lx\n",
|
|
Prefix,
|
|
LocalMdl->Process,
|
|
Prefix,
|
|
LocalMdl->MappedSystemVa,
|
|
Prefix,
|
|
LocalMdl->StartVa,
|
|
Prefix,
|
|
LocalMdl->ByteCount,
|
|
Prefix,
|
|
LocalMdl->ByteOffset
|
|
);
|
|
|
|
if (MaxBytesToDump > LocalMdl->ByteCount)
|
|
{
|
|
MaxBytesToDump = LocalMdl->ByteCount;
|
|
}
|
|
|
|
if (MaxBytesToDump > 0)
|
|
{
|
|
DumpRawData(
|
|
Prefix,
|
|
(ULONG_PTR)LocalMdl->MappedSystemVa,
|
|
MaxBytesToDump
|
|
);
|
|
}
|
|
|
|
} // DumpMdl
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|
|
BOOLEAN
|
|
DumpUnknownHeadersCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
UL_HTTP_UNKNOWN_HEADER header;
|
|
UCHAR headerName[MAX_HEADER_BUFFER];
|
|
UCHAR headerValue[MAX_HEADER_BUFFER];
|
|
ULONG result;
|
|
ULONG_PTR address;
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_HTTP_UNKNOWN_HEADER,
|
|
List
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&header,
|
|
sizeof(header),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
DumpUnknownHeader(
|
|
(PSTR) Context,
|
|
"",
|
|
address,
|
|
&header
|
|
);
|
|
|
|
return TRUE;
|
|
|
|
} // DumpUnknownHeadersCallback
|
|
|
|
|
|
|
|
VOID
|
|
DumpApoolObj(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_APP_POOL_OBJECT ApoolObj
|
|
)
|
|
{
|
|
UCHAR name[MAX_URL_BUFFER];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
READ_REMOTE_STRING(
|
|
name,
|
|
sizeof(name),
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_OBJECT, pName ),
|
|
ApoolObj->NameLength
|
|
);
|
|
|
|
dprintf(
|
|
"%s%sUL_APP_POOL_OBJECT @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s RefCount = %d\n"
|
|
"%s ListEntry @ %p\n"
|
|
"%s Flink = %p ( !ulkd.apool %p )\n"
|
|
"%s Blink = %p ( !ulkd.apool %p )\n"
|
|
"%s pResource = %p\n"
|
|
"%s NewRequestQueue\n"
|
|
"%s RequestCount = %d\n"
|
|
"%s MaxRequests = %d\n"
|
|
"%s RequestHead @ %p\n"
|
|
"%s pDemandStartIrp = %p\n"
|
|
"%s pDemandStartProcess = %p\n"
|
|
"%s ProcessListHead @ %p\n"
|
|
"%s pSecurityDescriptor = %p\n"
|
|
"%s NameLength = %d\n"
|
|
"%s pName = %p ( %S )\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
ApoolObj->Signature,
|
|
SignatureToString(
|
|
ApoolObj->Signature,
|
|
UL_APP_POOL_OBJECT_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_APP_POOL_OBJECT_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
ApoolObj->RefCount,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_OBJECT, ListEntry ),
|
|
Prefix,
|
|
ApoolObj->ListEntry.Flink,
|
|
CONTAINING_RECORD(
|
|
ApoolObj->ListEntry.Flink,
|
|
UL_APP_POOL_OBJECT,
|
|
ListEntry
|
|
),
|
|
Prefix,
|
|
ApoolObj->ListEntry.Blink,
|
|
CONTAINING_RECORD(
|
|
ApoolObj->ListEntry.Blink,
|
|
UL_APP_POOL_OBJECT,
|
|
ListEntry
|
|
),
|
|
Prefix,
|
|
ApoolObj->pResource,
|
|
Prefix,
|
|
Prefix,
|
|
ApoolObj->NewRequestQueue.RequestCount,
|
|
Prefix,
|
|
ApoolObj->NewRequestQueue.MaxRequests,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_OBJECT, NewRequestQueue.RequestHead ),
|
|
Prefix,
|
|
ApoolObj->pDemandStartIrp,
|
|
Prefix,
|
|
ApoolObj->pDemandStartProcess,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_OBJECT, ProcessListHead ),
|
|
Prefix,
|
|
ApoolObj->pSecurityDescriptor,
|
|
Prefix,
|
|
ApoolObj->NameLength,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_OBJECT, pName ),
|
|
name
|
|
);
|
|
|
|
if (ApoolObj->ProcessListHead.Flink != (PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_OBJECT,
|
|
ProcessListHead
|
|
))
|
|
{
|
|
dprintf("%s AP Process List:\n", Prefix);
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_OBJECT,
|
|
ProcessListHead
|
|
),
|
|
&ProcListCallback,
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
if (ApoolObj->NewRequestQueue.RequestHead.Flink != (PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_OBJECT,
|
|
NewRequestQueue.RequestHead
|
|
))
|
|
{
|
|
dprintf("%s New Request List:\n", Prefix);
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_OBJECT,
|
|
NewRequestQueue.RequestHead
|
|
),
|
|
&RequestListCallback,
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
dprintf("\n");
|
|
|
|
} // DumpApoolObj
|
|
|
|
|
|
VOID
|
|
DumpAllApoolObjs(
|
|
VOID
|
|
)
|
|
{
|
|
ULONG_PTR address = 0;
|
|
|
|
address = GetExpression("&http!g_AppPoolListHead");
|
|
if (!address) {
|
|
dprintf(
|
|
"apool*: cannot find symbol for http!g_AppPoolListHead\n"
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY) address,
|
|
&DumpApoolCallback,
|
|
""
|
|
);
|
|
}
|
|
|
|
VOID
|
|
DumpApoolProc(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_APP_POOL_PROCESS ApoolProc
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_APP_POOL_PROCESS @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s InCleanup = %d\n"
|
|
"%s ListEntry @ %p\n"
|
|
"%s Flink = %p ( !ulkd.proc %p )\n"
|
|
"%s Blink = %p ( !ulkd.proc %p )\n"
|
|
"%s pAppPool = %p\n"
|
|
"%s NewIrpHead @ %p\n"
|
|
"%s PendingRequestQueue\n"
|
|
"%s RequestCount = %d\n"
|
|
"%s MaxRequests = %d\n"
|
|
"%s RequestHead @ %p\n"
|
|
"%s pProcess = %p\n"
|
|
"%s WaitForDisconnectHead @ %p\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
ApoolProc->Signature,
|
|
SignatureToString(
|
|
ApoolProc->Signature,
|
|
UL_APP_POOL_PROCESS_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_APP_POOL_PROCESS_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
ApoolProc->InCleanup,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_PROCESS, ListEntry ),
|
|
Prefix,
|
|
ApoolProc->ListEntry.Flink,
|
|
CONTAINING_RECORD(
|
|
ApoolProc->ListEntry.Flink,
|
|
UL_APP_POOL_PROCESS,
|
|
ListEntry
|
|
),
|
|
Prefix,
|
|
ApoolProc->ListEntry.Blink,
|
|
CONTAINING_RECORD(
|
|
ApoolProc->ListEntry.Blink,
|
|
UL_APP_POOL_PROCESS,
|
|
ListEntry
|
|
),
|
|
Prefix,
|
|
ApoolProc->pAppPool,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_PROCESS, NewIrpHead ),
|
|
Prefix,
|
|
Prefix,
|
|
ApoolProc->PendingRequestQueue.RequestCount,
|
|
Prefix,
|
|
ApoolProc->PendingRequestQueue.MaxRequests,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_PROCESS, PendingRequestQueue.RequestHead ),
|
|
Prefix,
|
|
ApoolProc->pProcess,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_APP_POOL_PROCESS, WaitForDisconnectHead )
|
|
);
|
|
|
|
//
|
|
// dump the IRP list
|
|
//
|
|
if (ApoolProc->NewIrpHead.Flink != (PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_PROCESS,
|
|
NewIrpHead
|
|
))
|
|
{
|
|
dprintf("%s Irp List:\n", Prefix);
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY) REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_PROCESS,
|
|
NewIrpHead
|
|
),
|
|
&IrpListCallback,
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
//
|
|
// dump pending request list
|
|
//
|
|
if (ApoolProc->PendingRequestQueue.RequestHead.Flink != (PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_PROCESS,
|
|
PendingRequestQueue.RequestHead
|
|
))
|
|
{
|
|
dprintf("%s Request List:\n", Prefix);
|
|
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY) REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_APP_POOL_PROCESS,
|
|
PendingRequestQueue.RequestHead
|
|
),
|
|
&RequestListCallback,
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
dprintf("\n");
|
|
} // DumpApoolProc
|
|
|
|
VOID
|
|
DumpConfigGroup(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_CONFIG_GROUP_OBJECT Obj
|
|
)
|
|
{
|
|
CHAR temp[sizeof("1234567812345678")];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_CONFIG_GROUP_OBJECT @ %p\n"
|
|
"%s Signature = %x (%s)\n"
|
|
"%s RefCount = %d\n"
|
|
"%s ConfigGroupId = %I64x\n"
|
|
"%s ControlChannelEntry @ %p\n"
|
|
"%s pControlChannel = %p\n"
|
|
"%s UrlListHead @ %p\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
Obj->Signature,
|
|
SignatureToString(
|
|
Obj->Signature,
|
|
UL_CG_OBJECT_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_CG_OBJECT_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
Obj->RefCount,
|
|
Prefix,
|
|
Obj->ConfigGroupId,
|
|
Prefix,
|
|
REMOTE_OFFSET(RemoteAddress, UL_CONFIG_GROUP_OBJECT, ControlChannelEntry),
|
|
Prefix,
|
|
Obj->pControlChannel,
|
|
Prefix,
|
|
REMOTE_OFFSET(RemoteAddress, UL_CONFIG_GROUP_OBJECT, UrlListHead)
|
|
);
|
|
|
|
if (Obj->AppPoolFlags.Present) {
|
|
dprintf(
|
|
"%s pAppPool = %p\n",
|
|
Prefix,
|
|
Obj->pAppPool
|
|
);
|
|
} else {
|
|
dprintf(
|
|
"%s pAppPool (none)\n",
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
dprintf(
|
|
"%s pAutoResponse = %p\n",
|
|
Prefix,
|
|
Obj->pAutoResponse
|
|
);
|
|
|
|
if (Obj->MaxBandwidth.Flags.Present) {
|
|
dprintf(
|
|
"%s MaxBandwidth = %d\n",
|
|
Prefix,
|
|
Obj->MaxBandwidth.MaxBandwidth
|
|
);
|
|
} else {
|
|
dprintf(
|
|
"%s MaxBandwidth (none)\n",
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
if (Obj->MaxConnections.Flags.Present) {
|
|
dprintf(
|
|
"%s MaxConnections = %d\n",
|
|
Prefix,
|
|
Obj->MaxConnections.MaxConnections
|
|
);
|
|
} else {
|
|
dprintf(
|
|
"%s MaxConnections (none)\n",
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
if (Obj->State.Flags.Present) {
|
|
dprintf(
|
|
"%s State = %s\n",
|
|
Prefix,
|
|
UlEnabledStateToString(Obj->State.State)
|
|
);
|
|
} else {
|
|
dprintf(
|
|
"%s State (none)\n",
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
if (Obj->Security.Flags.Present) {
|
|
dprintf(
|
|
"%s Security.pSecurityDescriptor = %p\n",
|
|
Prefix,
|
|
Obj->Security.pSecurityDescriptor
|
|
);
|
|
|
|
if (Obj->Security.pSecurityDescriptor) {
|
|
sprintf(temp, "%p", Obj->Security.pSecurityDescriptor);
|
|
CallExtensionRoutine("sd", temp);
|
|
}
|
|
} else {
|
|
dprintf(
|
|
"%s Security (none)\n",
|
|
Prefix
|
|
);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
DumpConfigTree(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_CG_URL_TREE_HEADER Tree
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_CG_URL_TREE_HEADER @ %p\n"
|
|
"%s Signature = %x (%s)\n"
|
|
"%s AllocCount = %u\n"
|
|
"%s UsedCount = %u\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
Tree->Signature,
|
|
SignatureToString(
|
|
Tree->Signature,
|
|
UL_CG_TREE_HEADER_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_CG_TREE_HEADER_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
Tree->AllocCount,
|
|
Prefix,
|
|
Tree->UsedCount
|
|
);
|
|
}
|
|
|
|
|
|
VOID
|
|
DumpCgroupEntry(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_CG_URL_TREE_ENTRY Entry
|
|
)
|
|
{
|
|
UCHAR tokenBuffer[MAX_URL_BUFFER];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_CG_URL_TREE_ENTRY @ %p\n"
|
|
"%s Signature = %08lx (%s)\n"
|
|
"%s pParent = %p (cgentry)\n"
|
|
"%s pChildren = %p (cgtree)\n"
|
|
"%s TokenHash = 0x%08x\n"
|
|
"%s TokenLength = %d\n"
|
|
"%s FullUrl = %d\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
Entry->Signature,
|
|
SignatureToString(
|
|
Entry->Signature,
|
|
UL_CG_TREE_ENTRY_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_CG_TREE_ENTRY_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
Entry->pParent,
|
|
Prefix,
|
|
Entry->pChildren,
|
|
Prefix,
|
|
Entry->TokenHash,
|
|
Prefix,
|
|
Entry->TokenLength,
|
|
Prefix,
|
|
Entry->FullUrl
|
|
);
|
|
|
|
if (Entry->FullUrl) {
|
|
|
|
dprintf(
|
|
"%s UrlContext = %I64x\n"
|
|
"%s pConfigGroup = %p\n"
|
|
"%s ConfigGroupListEntry @ %p\n",
|
|
Prefix,
|
|
Entry->UrlContext,
|
|
Prefix,
|
|
Entry->pConfigGroup,
|
|
Prefix,
|
|
REMOTE_OFFSET(RemoteAddress, UL_CG_URL_TREE_ENTRY, ConfigGroupListEntry)
|
|
);
|
|
|
|
}
|
|
|
|
READ_REMOTE_STRING(
|
|
tokenBuffer,
|
|
sizeof(tokenBuffer),
|
|
REMOTE_OFFSET(RemoteAddress, UL_CG_URL_TREE_ENTRY, pToken),
|
|
Entry->TokenLength
|
|
);
|
|
|
|
dprintf(
|
|
"%s pToken = %ws\n"
|
|
"\n",
|
|
Prefix,
|
|
tokenBuffer
|
|
);
|
|
}
|
|
|
|
VOID
|
|
DumpCgroupHeader(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_CG_HEADER_ENTRY Entry
|
|
)
|
|
{
|
|
UL_CG_URL_TREE_ENTRY tentry;
|
|
ULONG result;
|
|
|
|
dprintf(
|
|
"%s%sUL_CG_HEADER_ENTRY @ %p\n"
|
|
"%s TokenHash = 0x%08x\n"
|
|
"%s pEntry = %p\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
Entry->TokenHash,
|
|
Prefix,
|
|
Entry->pEntry
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
(ULONG_PTR)Entry->pEntry,
|
|
&tentry,
|
|
sizeof(tentry),
|
|
&result
|
|
))
|
|
{
|
|
dprintf(
|
|
"%scouldn't read UL_CG_TREE_ENTRY @ %p\n",
|
|
CommandName,
|
|
Entry->pEntry
|
|
);
|
|
return;
|
|
}
|
|
|
|
DumpCgroupEntry(
|
|
Prefix,
|
|
CommandName,
|
|
(ULONG_PTR)Entry->pEntry,
|
|
&tentry
|
|
);
|
|
}
|
|
|
|
#if 0
|
|
|
|
BOOLEAN
|
|
DumpUriEntryCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
UL_URI_CACHE_ENTRY entry;
|
|
ULONG_PTR address;
|
|
ULONG result;
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_URI_CACHE_ENTRY,
|
|
BucketEntry
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&entry,
|
|
sizeof(entry),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
DumpUriEntry(
|
|
(PSTR) Context,
|
|
"uri*: ",
|
|
address,
|
|
&entry
|
|
);
|
|
|
|
return TRUE;
|
|
|
|
} // DumpUriEntryCallback
|
|
|
|
#endif
|
|
|
|
BOOLEAN
|
|
DumpApoolCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
UL_APP_POOL_OBJECT obj;
|
|
ULONG_PTR address;
|
|
ULONG result;
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_APP_POOL_OBJECT,
|
|
ListEntry
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&obj,
|
|
sizeof(obj),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
DumpApoolObj(
|
|
(PSTR) Context,
|
|
"apool*: ",
|
|
address,
|
|
&obj
|
|
);
|
|
|
|
return TRUE;
|
|
|
|
} // DumpApoolCallback
|
|
|
|
|
|
BOOLEAN
|
|
DumpEndpointCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
UL_ENDPOINT endp;
|
|
ULONG_PTR address;
|
|
ULONG result;
|
|
|
|
PENDPOINT_GLOBAL_CALLBACK_CONTEXT pCtxt
|
|
= (PENDPOINT_GLOBAL_CALLBACK_CONTEXT) Context;
|
|
|
|
ASSERT(pCtxt->Signature == ENDPOINT_GLOBAL_CALLBACK_CONTEXT_SIGNATURE);
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_ENDPOINT,
|
|
GlobalEndpointListEntry
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&endp,
|
|
sizeof(endp),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
DumpUlEndpoint(
|
|
pCtxt->Prefix,
|
|
"endp *: ",
|
|
address,
|
|
&endp,
|
|
pCtxt->Verbosity
|
|
);
|
|
|
|
return TRUE;
|
|
|
|
} // DumpEndpointCallback
|
|
|
|
|
|
BOOLEAN
|
|
ProcListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
ULONG_PTR address;
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_APP_POOL_PROCESS,
|
|
ListEntry
|
|
);
|
|
|
|
dprintf("%s %p\n", (PSTR) Context, address);
|
|
|
|
return TRUE;
|
|
|
|
} // ProcListCallback
|
|
|
|
|
|
BOOLEAN
|
|
IrpListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
ULONG_PTR address;
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
IRP,
|
|
Tail.Overlay.ListEntry
|
|
);
|
|
|
|
dprintf("%s %p\n", (PSTR) Context, address);
|
|
|
|
return TRUE;
|
|
|
|
} // IrpListCallback
|
|
|
|
BOOLEAN
|
|
RequestListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
UL_INTERNAL_REQUEST request;
|
|
ULONG_PTR address;
|
|
ULONG result;
|
|
UCHAR urlBuffer[MAX_URL_BUFFER];
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_INTERNAL_REQUEST,
|
|
AppPool.AppPoolEntry
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&request,
|
|
sizeof(request),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
READ_REMOTE_STRING(
|
|
urlBuffer,
|
|
sizeof(urlBuffer),
|
|
request.CookedUrl.pUrl,
|
|
request.CookedUrl.Length
|
|
);
|
|
|
|
dprintf(
|
|
"%s %p - %s %ws\n",
|
|
(PSTR) Context,
|
|
address,
|
|
VerbToString(request.Verb),
|
|
urlBuffer
|
|
);
|
|
|
|
return TRUE;
|
|
|
|
} // RequestListCallback
|
|
|
|
|
|
VOID
|
|
DumpKernelQueue(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PKQUEUE LocalQueue,
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
dprintf(
|
|
"%s%sKQUEUE @ %p\n"
|
|
"%s Type = %02x\n"
|
|
"%s Absolute = %02x\n"
|
|
"%s Size = %02x\n"
|
|
"%s Inserted = %02x\n"
|
|
"%s SignalState = %ld\n"
|
|
"%s WaitListHead @ %p%s\n"
|
|
"%s EntryListHead @ %p%s\n"
|
|
"%s CurrentCount = %lu\n"
|
|
"%s MaximumCount = %lu\n"
|
|
"%s ThreadListHead @ %p%s\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
LocalQueue->Header.Type,
|
|
Prefix,
|
|
LocalQueue->Header.Absolute,
|
|
Prefix,
|
|
LocalQueue->Header.Size,
|
|
Prefix,
|
|
LocalQueue->Header.Inserted,
|
|
Prefix,
|
|
LocalQueue->Header.SignalState,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, KQUEUE, Header.WaitListHead ),
|
|
IS_LIST_EMPTY(
|
|
LocalQueue,
|
|
RemoteAddress,
|
|
KQUEUE,
|
|
Header.WaitListHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, KQUEUE, EntryListHead ),
|
|
IS_LIST_EMPTY(
|
|
LocalQueue,
|
|
RemoteAddress,
|
|
KQUEUE,
|
|
EntryListHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
LocalQueue->CurrentCount,
|
|
Prefix,
|
|
LocalQueue->MaximumCount,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, KQUEUE, ThreadListHead ),
|
|
IS_LIST_EMPTY(
|
|
LocalQueue,
|
|
RemoteAddress,
|
|
KQUEUE,
|
|
ThreadListHead
|
|
) ? " (EMPTY)" : ""
|
|
);
|
|
|
|
if (Flags & 1)
|
|
{
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY)REMOTE_OFFSET( RemoteAddress, KQUEUE, EntryListHead ),
|
|
&DumpKQueueEntriesCallback,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
} // DumpKernelQueue
|
|
|
|
BOOLEAN
|
|
DumpKQueueEntriesCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
ULONG_PTR address;
|
|
CHAR temp[sizeof("1234567812345678 f")];
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
IRP,
|
|
Tail.Overlay.ListEntry
|
|
);
|
|
|
|
sprintf( temp, "%p f", address );
|
|
|
|
CallExtensionRoutine( "irp", temp );
|
|
|
|
return TRUE;
|
|
|
|
} // DumpKQueueEntriesCallback
|
|
|
|
VOID
|
|
DumpFilterChannel(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_FILTER_CHANNEL Filter,
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
UCHAR name[MAX_URL_BUFFER];
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
READ_REMOTE_STRING(
|
|
name,
|
|
sizeof(name),
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_CHANNEL, pName ),
|
|
Filter->NameLength
|
|
);
|
|
|
|
dprintf(
|
|
"%s%sUL_FILTER_CHANNEL @ %p\n"
|
|
"%s Signature = %x (%s)\n"
|
|
"%s RefCount = %d\n"
|
|
"%s ListEntry @ %p\n"
|
|
"%s pDemandStartIrp = %p\n"
|
|
"%s pDemandStartProcess = %p\n"
|
|
"%s SpinLock @ %p (%s)\n"
|
|
"%s ProcessListHead @ %p%s\n"
|
|
"%s ConnectionListHead @ %p%s\n"
|
|
"%s pSecurityDescriptor = %p\n"
|
|
"%s NameLength = %d\n"
|
|
"%s pName = %p (%S)\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
Filter->Signature,
|
|
SignatureToString(
|
|
Filter->Signature,
|
|
UL_FILTER_CHANNEL_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_FILTER_CHANNEL_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
Filter->RefCount,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_CHANNEL, ListEntry ),
|
|
Prefix,
|
|
Filter->pDemandStartIrp,
|
|
Prefix,
|
|
Filter->pDemandStartProcess,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_CHANNEL, SpinLock ),
|
|
GetSpinlockState( &Filter->SpinLock ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_CHANNEL, ProcessListHead ),
|
|
IS_LIST_EMPTY(
|
|
Filter,
|
|
RemoteAddress,
|
|
UL_FILTER_CHANNEL,
|
|
ProcessListHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_CHANNEL, ConnectionListHead ),
|
|
IS_LIST_EMPTY(
|
|
Filter,
|
|
RemoteAddress,
|
|
UL_FILTER_CHANNEL,
|
|
ConnectionListHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
Filter->pSecurityDescriptor,
|
|
Prefix,
|
|
Filter->NameLength,
|
|
Prefix,
|
|
Filter->pName,
|
|
name
|
|
);
|
|
|
|
|
|
if (Filter->ProcessListHead.Flink != (PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_FILTER_CHANNEL,
|
|
ProcessListHead
|
|
))
|
|
{
|
|
dprintf("%s Filter Process List:\n", Prefix);
|
|
EnumLinkedList(
|
|
(PLIST_ENTRY)REMOTE_OFFSET(
|
|
RemoteAddress,
|
|
UL_FILTER_CHANNEL,
|
|
ProcessListHead
|
|
),
|
|
&FiltProcListCallback,
|
|
Prefix
|
|
);
|
|
}
|
|
|
|
dprintf("\n");
|
|
}
|
|
|
|
BOOLEAN
|
|
FiltProcListCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
ULONG_PTR address;
|
|
|
|
address = (ULONG_PTR)CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_FILTER_PROCESS,
|
|
ListEntry
|
|
);
|
|
|
|
dprintf("%s %p\n", (PSTR) Context, address);
|
|
|
|
return TRUE;
|
|
|
|
} // FiltProcListCallback
|
|
|
|
|
|
VOID
|
|
DumpFilterProc(
|
|
IN PSTR Prefix,
|
|
IN PSTR CommandName,
|
|
IN ULONG_PTR RemoteAddress,
|
|
IN PUL_FILTER_PROCESS Proc,
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
CHAR strSignature[MAX_SIGNATURE_LENGTH];
|
|
|
|
dprintf(
|
|
"%s%sUL_FILTER_PROCESS @ %p\n"
|
|
"%s Signature = %x (%s)\n"
|
|
"%s InCleanup = %ld\n"
|
|
"%s pFilterChannel = %p\n"
|
|
"%s ListEntry @ %p\n"
|
|
"%s ConnectionHead @ %p%s\n"
|
|
"%s IrpHead @ %p%s\n"
|
|
"%s pProcess = %p\n"
|
|
"\n",
|
|
Prefix,
|
|
CommandName,
|
|
RemoteAddress,
|
|
Prefix,
|
|
Proc->Signature,
|
|
SignatureToString(
|
|
Proc->Signature,
|
|
UL_FILTER_PROCESS_POOL_TAG,
|
|
MAKE_FREE_TAG(UL_FILTER_PROCESS_POOL_TAG),
|
|
strSignature
|
|
),
|
|
Prefix,
|
|
Proc->InCleanup,
|
|
Prefix,
|
|
Proc->pFilterChannel,
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_PROCESS, ListEntry ),
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_PROCESS, ConnectionHead ),
|
|
IS_LIST_EMPTY(
|
|
Proc,
|
|
RemoteAddress,
|
|
UL_FILTER_PROCESS,
|
|
ConnectionHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
REMOTE_OFFSET( RemoteAddress, UL_FILTER_PROCESS, IrpHead ),
|
|
IS_LIST_EMPTY(
|
|
Proc,
|
|
RemoteAddress,
|
|
UL_FILTER_PROCESS,
|
|
IrpHead
|
|
) ? " (EMPTY)" : "",
|
|
Prefix,
|
|
Proc->pProcess
|
|
);
|
|
|
|
} // DumpFilterProc
|
|
|
|
|
|
BOOLEAN
|
|
DumpUlActiveConnectionCallback(
|
|
IN PLIST_ENTRY RemoteListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
ULONG_PTR address;
|
|
UL_CONNECTION connection;
|
|
ULONG result;
|
|
PCONN_CALLBACK_CONTEXT pConnContext = (PCONN_CALLBACK_CONTEXT) Context;
|
|
|
|
ASSERT(pConnContext->Signature == CONN_CALLBACK_CONTEXT_SIGNATURE);
|
|
|
|
address = (ULONG_PTR) CONTAINING_RECORD(
|
|
RemoteListEntry,
|
|
UL_CONNECTION,
|
|
ActiveListEntry // <--
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&connection,
|
|
sizeof(connection),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dprintf("active conn[%2d][%2d]: ",
|
|
pConnContext->Index, pConnContext->SubIndex++);
|
|
|
|
switch (pConnContext->Verbosity)
|
|
{
|
|
case ENDPOINT_BRIEF_CONNS:
|
|
DumpUlConnectionLite(
|
|
pConnContext->Prefix,
|
|
"",
|
|
address,
|
|
&connection
|
|
);
|
|
break;
|
|
|
|
case ENDPOINT_VERBOSE_CONNS:
|
|
DumpUlConnection(
|
|
pConnContext->Prefix,
|
|
"",
|
|
address,
|
|
&connection
|
|
);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(! "Invalid ENDPOINT_CONNS");
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // DumpUlActiveConnectionCallback
|
|
|
|
|
|
BOOLEAN
|
|
DumpUlIdleConnectionCallback(
|
|
IN PSINGLE_LIST_ENTRY RemoteSListEntry,
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
ULONG_PTR address;
|
|
UL_CONNECTION connection;
|
|
ULONG result;
|
|
PCONN_CALLBACK_CONTEXT pConnContext = (PCONN_CALLBACK_CONTEXT) Context;
|
|
|
|
ASSERT(pConnContext->Signature == CONN_CALLBACK_CONTEXT_SIGNATURE);
|
|
|
|
address = (ULONG_PTR) CONTAINING_RECORD(
|
|
RemoteSListEntry,
|
|
UL_CONNECTION,
|
|
IdleSListEntry // <--
|
|
);
|
|
|
|
if (!ReadMemory(
|
|
address,
|
|
&connection,
|
|
sizeof(connection),
|
|
&result
|
|
))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
dprintf("idle conn[%2d]: ", pConnContext->SubIndex++);
|
|
|
|
switch (pConnContext->Verbosity)
|
|
{
|
|
case ENDPOINT_BRIEF_CONNS:
|
|
DumpUlConnectionLite(
|
|
pConnContext->Prefix,
|
|
"",
|
|
address,
|
|
&connection
|
|
);
|
|
break;
|
|
|
|
case ENDPOINT_VERBOSE_CONNS:
|
|
DumpUlConnection(
|
|
pConnContext->Prefix,
|
|
"",
|
|
address,
|
|
&connection
|
|
);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(! "Invalid ENDPOINT_CONNS");
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // DumpUlIdleConnectionCallback
|
|
|