mirror of https://github.com/tongzx/nt5src
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.
495 lines
11 KiB
495 lines
11 KiB
/*++
|
|
|
|
Copyright (c) 1998-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
apool.h
|
|
|
|
Abstract:
|
|
|
|
The public definition of app pool interfaces.
|
|
|
|
Author:
|
|
|
|
Paul McDaniel (paulmcd) 28-Jan-1999
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _APOOL_H_
|
|
#define _APOOL_H_
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
|
|
//
|
|
// Kernel mode mappings to the user mode set defined in ulapi.h
|
|
//
|
|
|
|
//
|
|
// Forwarders.
|
|
//
|
|
|
|
typedef struct _UL_INTERNAL_REQUEST *PUL_INTERNAL_REQUEST;
|
|
typedef struct _UL_HTTP_CONNECTION *PUL_HTTP_CONNECTION;
|
|
typedef struct _UL_CONFIG_GROUP_OBJECT *PUL_CONFIG_GROUP_OBJECT;
|
|
|
|
|
|
//
|
|
// this structure contains a queue of HTTP_REQUEST objects
|
|
// CODEWORK: investigate using an NBQUEUE instead
|
|
//
|
|
|
|
typedef struct _UL_REQUEST_QUEUE
|
|
{
|
|
LONG RequestCount;
|
|
LONG MaxRequests;
|
|
LIST_ENTRY RequestHead;
|
|
|
|
} UL_REQUEST_QUEUE, *PUL_REQUEST_QUEUE;
|
|
|
|
|
|
//
|
|
// This structure represents an internal app pool object
|
|
//
|
|
|
|
#define IS_VALID_AP_OBJECT(pObject) \
|
|
(((pObject) != NULL) && ((pObject)->Signature == UL_APP_POOL_OBJECT_POOL_TAG) && ((pObject)->RefCount > 0))
|
|
|
|
typedef struct _UL_APP_POOL_OBJECT
|
|
{
|
|
//
|
|
// NonPagedPool
|
|
//
|
|
|
|
//
|
|
// lock that protects NewRequestQueue, PendingRequestQueue
|
|
// for each attached process and queue state of the request
|
|
//
|
|
// ensure it on cache-line and use InStackQueuedSpinLock for
|
|
// better performance
|
|
//
|
|
UL_SPIN_LOCK QueueSpinLock;
|
|
|
|
//
|
|
// UL_APP_POOL_OBJECT_POOL_TAG
|
|
//
|
|
ULONG Signature;
|
|
|
|
//
|
|
// Ref count for this app pool
|
|
//
|
|
LONG RefCount;
|
|
|
|
//
|
|
// links all apool objects, anchored by g_AppPoolListHead
|
|
//
|
|
LIST_ENTRY ListEntry;
|
|
|
|
//
|
|
// Locks lists on the app pool & process objects, is refcounted and
|
|
// given to the HTTP_REQUEST object to synchronize access to process
|
|
// objects when connections drop and the request(s) need to be released
|
|
//
|
|
PUL_NONPAGED_RESOURCE pResource;
|
|
|
|
//
|
|
// A apool wide new request list (when no irps are available)
|
|
//
|
|
UL_REQUEST_QUEUE NewRequestQueue;
|
|
|
|
//
|
|
// the demand start irp (OPTIONAL)
|
|
//
|
|
PIRP pDemandStartIrp;
|
|
PEPROCESS pDemandStartProcess;
|
|
|
|
//
|
|
// the list of processes bound to this app pool
|
|
//
|
|
LIST_ENTRY ProcessListHead;
|
|
|
|
PSECURITY_DESCRIPTOR pSecurityDescriptor;
|
|
|
|
//
|
|
// List of transient config groups
|
|
//
|
|
UL_NOTIFY_HEAD TransientHead;
|
|
|
|
//
|
|
// the length of pName
|
|
//
|
|
ULONG NameLength;
|
|
|
|
//
|
|
// number of active processes in the AppPool, used to decide if binding
|
|
// is necessary
|
|
//
|
|
ULONG NumberActiveProcesses;
|
|
|
|
//
|
|
// Only route requests to this AppPool if it's marked active
|
|
//
|
|
HTTP_ENABLED_STATE Enabled;
|
|
|
|
//
|
|
// the apool's name
|
|
//
|
|
WCHAR pName[0];
|
|
|
|
} UL_APP_POOL_OBJECT, *PUL_APP_POOL_OBJECT;
|
|
|
|
|
|
//
|
|
// The structure representing a process bound to an app pool.
|
|
//
|
|
|
|
#define IS_VALID_AP_PROCESS(pObject) \
|
|
(((pObject) != NULL) && ((pObject)->Signature == UL_APP_POOL_PROCESS_POOL_TAG))
|
|
|
|
typedef struct _UL_APP_POOL_PROCESS
|
|
{
|
|
//
|
|
// NonPagedPool
|
|
//
|
|
|
|
//
|
|
// UL_APP_POOL_PROCESS_POOL_TAG
|
|
//
|
|
ULONG Signature;
|
|
|
|
//
|
|
// set if we are in cleanup. You must check this flag before attaching
|
|
// any IRPs to the process.
|
|
//
|
|
ULONG InCleanup : 1;
|
|
|
|
//
|
|
// set if process is attached with the HTTP_OPTION_CONTROLLER option
|
|
//
|
|
ULONG Controller : 1;
|
|
|
|
//
|
|
// used to link into the apool object
|
|
//
|
|
LIST_ENTRY ListEntry;
|
|
|
|
//
|
|
// points to the app pool this process belongs
|
|
//
|
|
PUL_APP_POOL_OBJECT pAppPool;
|
|
|
|
//
|
|
// a list of pending IRP(s) waiting to receive new requests
|
|
//
|
|
LIST_ENTRY NewIrpHead;
|
|
|
|
//
|
|
// lock that protects the above list
|
|
//
|
|
UL_SPIN_LOCK NewIrpSpinLock;
|
|
|
|
//
|
|
// links requests that would not fit in a irp buffer and need to wait for
|
|
// the larger buffer
|
|
//
|
|
// and
|
|
//
|
|
// requests that this process is working on and need
|
|
// i/o cancellation if the process detaches from the apool
|
|
//
|
|
UL_REQUEST_QUEUE PendingRequestQueue;
|
|
|
|
//
|
|
// Pointer to the actual process (for debugging)
|
|
//
|
|
PEPROCESS pProcess;
|
|
|
|
//
|
|
// List of pending "wait for disconnect" IRPs.
|
|
//
|
|
UL_NOTIFY_HEAD WaitForDisconnectHead;
|
|
|
|
} UL_APP_POOL_PROCESS, *PUL_APP_POOL_PROCESS;
|
|
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlAttachProcessToAppPool(
|
|
IN PWCHAR pName OPTIONAL,
|
|
IN ULONG NameLength,
|
|
IN BOOLEAN Create,
|
|
IN PACCESS_STATE pAccessState,
|
|
IN ACCESS_MASK DesiredAccess,
|
|
IN KPROCESSOR_MODE RequestorMode,
|
|
OUT PUL_APP_POOL_PROCESS * ppProcess
|
|
);
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlDetachProcessFromAppPool(
|
|
IN PUL_APP_POOL_PROCESS pProcess
|
|
);
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
#if REFERENCE_DEBUG
|
|
VOID
|
|
UlReferenceAppPool(
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
#else
|
|
__inline
|
|
VOID
|
|
FASTCALL
|
|
UlReferenceAppPool(
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
)
|
|
{
|
|
InterlockedIncrement(&pAppPool->RefCount);
|
|
}
|
|
#endif
|
|
|
|
#define REFERENCE_APP_POOL( papp ) \
|
|
UlReferenceAppPool( \
|
|
(papp) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
VOID
|
|
UlDeleteAppPool(
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
|
|
#define DELETE_APP_POOL( papp ) \
|
|
UlDeleteAppPool( \
|
|
(papp) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
#if REFERENCE_DEBUG
|
|
VOID
|
|
UlDereferenceAppPool(
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
REFERENCE_DEBUG_FORMAL_PARAMS
|
|
);
|
|
#else
|
|
__inline
|
|
VOID
|
|
FASTCALL
|
|
UlDereferenceAppPool(
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
)
|
|
{
|
|
if (InterlockedDecrement(&pAppPool->RefCount) == 0)
|
|
{
|
|
UlDeleteAppPool(pAppPool);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define DEREFERENCE_APP_POOL( papp ) \
|
|
UlDereferenceAppPool( \
|
|
(papp) \
|
|
REFERENCE_DEBUG_ACTUAL_PARAMS \
|
|
)
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlQueryAppPoolInformation(
|
|
IN PUL_APP_POOL_PROCESS pProcess,
|
|
IN HTTP_APP_POOL_INFORMATION_CLASS InformationClass,
|
|
OUT PVOID pAppPoolInformation,
|
|
IN ULONG Length,
|
|
OUT PULONG pReturnLength OPTIONAL
|
|
);
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlSetAppPoolInformation(
|
|
IN PUL_APP_POOL_PROCESS pProcess,
|
|
IN HTTP_APP_POOL_INFORMATION_CLASS InformationClass,
|
|
IN PVOID pAppPoolInformation,
|
|
IN ULONG Length
|
|
);
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlWaitForDemandStart(
|
|
IN PUL_APP_POOL_PROCESS pProcess,
|
|
IN PIRP pIrp
|
|
);
|
|
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlReceiveHttpRequest(
|
|
IN HTTP_REQUEST_ID RequestId,
|
|
IN ULONG Flags,
|
|
IN PUL_APP_POOL_PROCESS pProcess,
|
|
IN PIRP pIrp
|
|
);
|
|
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlDeliverRequestToProcess(
|
|
IN PUL_APP_POOL_OBJECT pAppPool,
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
);
|
|
|
|
VOID
|
|
UlUnlinkRequestFromProcess(
|
|
IN PUL_APP_POOL_OBJECT pAppPool,
|
|
IN PUL_INTERNAL_REQUEST pRequest
|
|
);
|
|
|
|
// IRQL == PASSIVE_LEVEL
|
|
//
|
|
NTSTATUS
|
|
UlGetPoolFromHandle(
|
|
IN HANDLE hAppPool,
|
|
OUT PUL_APP_POOL_OBJECT * ppAppPool
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
UlInitializeAP(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
UlTerminateAP(
|
|
VOID
|
|
);
|
|
|
|
PUL_APP_POOL_PROCESS
|
|
UlCreateAppPoolProcess(
|
|
PUL_APP_POOL_OBJECT pObject
|
|
);
|
|
|
|
VOID
|
|
UlFreeAppPoolProcess(
|
|
PUL_APP_POOL_PROCESS pProcess
|
|
);
|
|
|
|
PUL_APP_POOL_OBJECT
|
|
UlAppPoolObjectFromProcess(
|
|
PUL_APP_POOL_PROCESS pProcess
|
|
);
|
|
|
|
VOID
|
|
UlLinkConfigGroupToAppPool(
|
|
IN PUL_CONFIG_GROUP_OBJECT pConfigGroup,
|
|
IN PUL_APP_POOL_OBJECT pAppPool
|
|
);
|
|
|
|
NTSTATUS
|
|
UlWaitForDisconnect(
|
|
IN PUL_APP_POOL_PROCESS pProcess,
|
|
IN PUL_HTTP_CONNECTION pHttpConn,
|
|
IN PIRP pIrp
|
|
);
|
|
|
|
VOID
|
|
UlCompleteAllWaitForDisconnect(
|
|
IN PUL_HTTP_CONNECTION pHttpConnection
|
|
);
|
|
|
|
NTSTATUS
|
|
UlpCopyRequestToBuffer(
|
|
IN PUL_INTERNAL_REQUEST pRequest,
|
|
IN PUCHAR pKernelBuffer,
|
|
IN PVOID pUserBuffer,
|
|
IN ULONG BufferLength,
|
|
IN PUCHAR pEntityBody,
|
|
IN ULONG EntityBodyLength
|
|
);
|
|
|
|
PUL_INTERNAL_REQUEST
|
|
UlpDequeueNewRequest(
|
|
IN PUL_APP_POOL_PROCESS pProcess
|
|
);
|
|
|
|
__inline
|
|
NTSTATUS
|
|
FASTCALL
|
|
UlpComputeRequestBytesNeeded(
|
|
IN PUL_INTERNAL_REQUEST pRequest,
|
|
IN PULONG pBytesNeeded
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG SslInfoSize;
|
|
|
|
//
|
|
// Calculate the size needed for the request, we'll need it below.
|
|
//
|
|
|
|
*pBytesNeeded =
|
|
sizeof(HTTP_REQUEST) +
|
|
pRequest->TotalRequestSize +
|
|
(pRequest->UnknownHeaderCount * sizeof(HTTP_UNKNOWN_HEADER));
|
|
|
|
//
|
|
// Include additional space for the local and remote addresses.
|
|
//
|
|
// CODEWORK: Make this transport independent.
|
|
//
|
|
|
|
*pBytesNeeded += sizeof(HTTP_NETWORK_ADDRESS_IPV4) * 2;
|
|
|
|
//
|
|
// Include space for any SSL information.
|
|
//
|
|
|
|
if (pRequest->pHttpConn->SecureConnection)
|
|
{
|
|
Status = UlGetSslInfo(
|
|
&pRequest->pHttpConn->pConnection->FilterInfo,
|
|
0, // BufferSize
|
|
NULL, // pUserBuffer
|
|
NULL, // pBuffer
|
|
&SslInfoSize // pBytesNeeded
|
|
);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
//
|
|
// Struct must be aligned; add some slop space
|
|
//
|
|
|
|
*pBytesNeeded = ALIGN_UP(*pBytesNeeded, PVOID);
|
|
*pBytesNeeded += SslInfoSize;
|
|
}
|
|
else
|
|
{
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}; // extern "C"
|
|
#endif
|
|
|
|
#endif // _APOOL_H_
|