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.
1954 lines
49 KiB
1954 lines
49 KiB
/*++
|
|
|
|
Copyright (c) 1998-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.cxx
|
|
|
|
Abstract:
|
|
|
|
This module performs initialization for the UL device driver.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 10-Jun-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
#define DEFAULT_THREAD_AFFINITY_MASK ((1ui64 << KeNumberProcessors) - 1)
|
|
|
|
|
|
|
|
//
|
|
// Private types.
|
|
//
|
|
|
|
|
|
typedef struct _SID_MASK_PAIR
|
|
{
|
|
PSID pSid;
|
|
ACCESS_MASK AccessMask;
|
|
|
|
} SID_MASK_PAIR, *PSID_MASK_PAIR;
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
#endif // __cplusplus
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
|
|
NTSTATUS
|
|
UlpApplySecurityToDeviceObjects(
|
|
VOID
|
|
);
|
|
|
|
NTSTATUS
|
|
UlpCreateSecurityDescriptor(
|
|
OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
|
IN PSID_MASK_PAIR pSidMaskPairs,
|
|
IN ULONG NumSidMaskPairs
|
|
);
|
|
|
|
VOID
|
|
UlpCleanupSecurityDescriptor(
|
|
IN PSECURITY_DESCRIPTOR pSecurityDescriptor
|
|
);
|
|
|
|
NTSTATUS
|
|
UlpSetDeviceObjectSecurity(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN SECURITY_INFORMATION SecurityInformation,
|
|
IN PSECURITY_DESCRIPTOR pSecurityDescriptor
|
|
);
|
|
|
|
VOID
|
|
UlpReadRegistry (
|
|
IN PUL_CONFIG pConfig
|
|
);
|
|
|
|
VOID
|
|
UlpTerminateModules(
|
|
VOID
|
|
);
|
|
|
|
#if ALLOW_UNLOAD
|
|
VOID
|
|
UlpUnload (
|
|
IN PDRIVER_OBJECT DriverObject
|
|
);
|
|
#endif // ALLOW_UNLOAD
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}; // extern "C"
|
|
#endif // __cplusplus
|
|
|
|
//
|
|
// Private globals.
|
|
//
|
|
|
|
#if DBG
|
|
ULONG g_UlpForceInitFailure = 0;
|
|
#endif // DBG
|
|
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
#pragma alloc_text( INIT, DriverEntry )
|
|
#pragma alloc_text( INIT, UlpApplySecurityToDeviceObjects )
|
|
#pragma alloc_text( INIT, UlpCreateSecurityDescriptor )
|
|
#pragma alloc_text( INIT, UlpCleanupSecurityDescriptor )
|
|
#pragma alloc_text( INIT, UlpSetDeviceObjectSecurity )
|
|
#pragma alloc_text( INIT, UlpReadRegistry )
|
|
#if ALLOW_UNLOAD
|
|
#pragma alloc_text( PAGE, UlpUnload )
|
|
#pragma alloc_text( PAGE, UlpTerminateModules )
|
|
#endif // ALLOW_UNLOAD
|
|
|
|
//
|
|
// Note that UlpTerminateModules() must be "page" if driver unloading
|
|
// is enabled (it's called from UlpUnload), but can be "init" otherwise
|
|
// (it's only called after initialization failure).
|
|
//
|
|
#if ALLOW_UNLOAD
|
|
#pragma alloc_text( PAGE, UlpTerminateModules )
|
|
#else
|
|
#pragma alloc_text( INIT, UlpTerminateModules )
|
|
#endif // ALLOW_UNLOAD
|
|
#endif // ALLOC_PRAGMA
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
This is the initialization routine for the UL device driver.
|
|
|
|
Arguments:
|
|
|
|
DriverObject - Supplies a pointer to driver object created by the
|
|
system.
|
|
|
|
RegistryPath - Supplies the name of the driver's configuration
|
|
registry tree.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
UNICODE_STRING deviceName;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
CLONG i;
|
|
UL_CONFIG config;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Grab the number of processors in the system.
|
|
//
|
|
|
|
g_UlNumberOfProcessors = KeNumberProcessors;
|
|
g_UlThreadAffinityMask = DEFAULT_THREAD_AFFINITY_MASK;
|
|
|
|
//
|
|
// Grab the largest cache line size in the system
|
|
//
|
|
|
|
g_UlCacheLineSize = KeGetRecommendedSharedDataAlignment();
|
|
|
|
for (g_UlCacheLineBits = 0;
|
|
(1U << g_UlCacheLineBits) < g_UlCacheLineSize;
|
|
++g_UlCacheLineBits)
|
|
{}
|
|
|
|
ASSERT(g_UlCacheLineSize <= (1U << g_UlCacheLineBits));
|
|
|
|
//
|
|
// Snag a pointer to the system process.
|
|
//
|
|
|
|
g_pUlSystemProcess = (PKPROCESS)IoGetCurrentProcess();
|
|
|
|
//
|
|
// Read registry information.
|
|
//
|
|
|
|
UlpReadRegistry( &config );
|
|
|
|
#if DBG
|
|
//
|
|
// Give anyone using the kernel debugger a chance to abort
|
|
// initialization.
|
|
//
|
|
|
|
if (g_UlpForceInitFailure != 0)
|
|
{
|
|
status = STATUS_UNSUCCESSFUL;
|
|
goto fatal;
|
|
}
|
|
#endif // DBG
|
|
|
|
//
|
|
// Initialize the global trace logs.
|
|
//
|
|
|
|
UlInitializeOwnerRefTraceLog();
|
|
|
|
CREATE_REF_TRACE_LOG( g_pMondoGlobalTraceLog, 16384 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pTdiTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pHttpRequestTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pHttpConnectionTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pHttpResponseTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pAppPoolTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pConfigGroupTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pThreadTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pMdlTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pFilterTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_IRP_TRACE_LOG( g_pIrpTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_TIME_TRACE_LOG( g_pTimeTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REPLENISH_TRACE_LOG( g_pReplenishTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_FILTQ_TRACE_LOG( g_pFilterQueueTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pSiteCounterTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pConnectionCountTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pConfigGroupInfoTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pChunkTrackerTraceLog, 2048 - REF_TRACE_OVERHEAD, 0 );
|
|
CREATE_REF_TRACE_LOG( g_pWorkItemTraceLog, 32768 - REF_TRACE_OVERHEAD, 0 );
|
|
|
|
//
|
|
// Create an object directory to contain our device objects.
|
|
//
|
|
|
|
RtlInitUnicodeString( &deviceName, HTTP_DIRECTORY_NAME );
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes, // ObjectAttributes
|
|
&deviceName, // ObjectName
|
|
OBJ_CASE_INSENSITIVE | // Attributes
|
|
UL_KERNEL_HANDLE,
|
|
NULL, // RootDirectory
|
|
NULL // SecurityDescriptor
|
|
);
|
|
|
|
UlAttachToSystemProcess();
|
|
|
|
status = ZwCreateDirectoryObject(
|
|
&g_UlDirectoryObject, // DirectoryHandle
|
|
DIRECTORY_ALL_ACCESS, // AccessMask
|
|
&objectAttributes // ObjectAttributes
|
|
);
|
|
|
|
UlDetachFromSystemProcess();
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Create the control channel device object.
|
|
//
|
|
|
|
RtlInitUnicodeString( &deviceName, HTTP_CONTROL_DEVICE_NAME );
|
|
|
|
status = IoCreateDevice(
|
|
DriverObject, // DriverObject
|
|
0, // DeviceExtension
|
|
&deviceName, // DeviceName
|
|
FILE_DEVICE_NETWORK, // DeviceType
|
|
0, // DeviceCharacteristics
|
|
TRUE, // Exclusive
|
|
&g_pUlControlDeviceObject // DeviceObject
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Create the filter device object.
|
|
//
|
|
|
|
RtlInitUnicodeString( &deviceName, HTTP_FILTER_DEVICE_NAME );
|
|
|
|
status = IoCreateDevice(
|
|
DriverObject, // DriverObject
|
|
0, // DeviceExtension
|
|
&deviceName, // DeviceName
|
|
FILE_DEVICE_NETWORK, // DeviceType
|
|
0, // DeviceCharacteristics
|
|
FALSE, // Exclusive
|
|
&g_pUlFilterDeviceObject // DeviceObject
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
g_pUlFilterDeviceObject->StackSize = g_UlIrpStackSize;
|
|
|
|
//
|
|
// Create the app pool device object.
|
|
//
|
|
|
|
RtlInitUnicodeString( &deviceName, HTTP_APP_POOL_DEVICE_NAME );
|
|
|
|
status = IoCreateDevice(
|
|
DriverObject, // DriverObject
|
|
0, // DeviceExtension
|
|
&deviceName, // DeviceName
|
|
FILE_DEVICE_NETWORK, // DeviceType
|
|
0, // DeviceCharacteristics
|
|
FALSE, // Exclusive
|
|
&g_pUlAppPoolDeviceObject // DeviceObject
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
g_pUlAppPoolDeviceObject->StackSize = g_UlIrpStackSize;
|
|
|
|
|
|
//
|
|
// If so requested, apply security to the device objects.
|
|
//
|
|
// CODEWORK: REMOVE THIS CONFIGURATION PARAMETER!
|
|
//
|
|
|
|
if (config.EnableSecurity)
|
|
{
|
|
status = UlpApplySecurityToDeviceObjects();
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
KdPrint(( "UL: security disabled\n" ));
|
|
}
|
|
|
|
//
|
|
// Initialize the driver object with this driver's entrypoints.
|
|
//
|
|
|
|
DriverObject->MajorFunction[IRP_MJ_CREATE] = &UlCreate;
|
|
DriverObject->MajorFunction[IRP_MJ_CLOSE] = &UlClose;
|
|
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = &UlCleanup;
|
|
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = &UlDeviceControl;
|
|
DriverObject->FastIoDispatch = &UlFastIoDispatch;
|
|
DriverObject->DriverUnload = NULL;
|
|
|
|
#if ALLOW_UNLOAD
|
|
if( config.EnableUnload )
|
|
{
|
|
KdPrint(( "UL: DriverUnload enabled\n" ));
|
|
DriverObject->DriverUnload = &UlpUnload;
|
|
}
|
|
#endif // ALLOW_UNLOAD
|
|
|
|
//
|
|
// Initialize global data.
|
|
//
|
|
|
|
status = UlInitializeData(&config);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Create the thread pool.
|
|
//
|
|
|
|
status = UlInitializeThreadPool(config.ThreadsPerCpu);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Initialize common TDI.
|
|
//
|
|
|
|
status = UxInitializeTdi();
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Initialize server connection code.
|
|
//
|
|
|
|
status = UlInitializeTdi();
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
//
|
|
// Initialize temporary test code.
|
|
//
|
|
// status = UlInitializeTdiTest();
|
|
// if (!NT_SUCCESS(status))
|
|
// {
|
|
// goto fatal;
|
|
// }
|
|
|
|
//
|
|
// Initialize George.
|
|
//
|
|
|
|
status = UlLargeMemInitialize(&config);
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Keith.
|
|
//
|
|
|
|
status = UlInitializeControlChannel();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Henry.
|
|
//
|
|
|
|
status = InitializeHttpUtil();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
status = InitializeParser();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
status = UlInitializeOpaqueIdTable();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
status = InitializeFileCache();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Michael.
|
|
//
|
|
status = UlInitializeFilterChannel();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Alex.
|
|
//
|
|
status = UlInitializeUriCache(&config);
|
|
if ( !NT_SUCCESS(status) )
|
|
{
|
|
goto fatal;
|
|
}
|
|
|
|
status = UlInitializeDateCache();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Paul.
|
|
//
|
|
|
|
status = UlInitializeCG();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
status = UlInitializeAP();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Ali
|
|
//
|
|
|
|
status = UlInitializeLogs();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
// TC Init may fail if PSched
|
|
// is not installed.
|
|
UlTcInitialize();
|
|
#if 0
|
|
status = UlTcInitialize();
|
|
ASSERT( NT_SUCCESS(status));
|
|
#endif
|
|
|
|
status = UlInitGlobalConnectionLimits();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
//
|
|
// Initialize Eric.
|
|
//
|
|
|
|
status = UlInitializeHttpRcv();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
status = UlInitializeCounters();
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
UlInitializeTimeoutMonitor();
|
|
|
|
#if DBG
|
|
//
|
|
// Give anyone using the kernel debugger one final chance to abort
|
|
// initialization.
|
|
//
|
|
|
|
if (g_UlpForceInitFailure != 0)
|
|
{
|
|
status = STATUS_UNSUCCESSFUL;
|
|
goto fatal;
|
|
}
|
|
#endif // DBG
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
//
|
|
// Fatal error handlers.
|
|
//
|
|
|
|
fatal:
|
|
|
|
UlpTerminateModules();
|
|
|
|
ASSERT( !NT_SUCCESS(status) );
|
|
return status;
|
|
|
|
} // DriverEntry
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Applies the appropriate security descriptors to the global device
|
|
objects created at initialization time.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlpApplySecurityToDeviceObjects(
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
SECURITY_DESCRIPTOR securityDescriptor;
|
|
PGENERIC_MAPPING pFileObjectGenericMapping;
|
|
ACCESS_MASK fileRead;
|
|
ACCESS_MASK fileAll;
|
|
HANDLE handle;
|
|
SID_MASK_PAIR sidMaskPairs[3];
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT( IS_VALID_DEVICE_OBJECT( g_pUlControlDeviceObject ) );
|
|
ASSERT( IS_VALID_DEVICE_OBJECT( g_pUlFilterDeviceObject ) );
|
|
ASSERT( IS_VALID_DEVICE_OBJECT( g_pUlAppPoolDeviceObject ) );
|
|
|
|
//
|
|
// Gain access to the predefined SIDs and other security-related
|
|
// goodies exported by the kernel.
|
|
//
|
|
|
|
//SeEnableAccessToExports();
|
|
|
|
//
|
|
// Map a couple of generic file access types to their corresponding
|
|
// object-specific rights.
|
|
//
|
|
|
|
pFileObjectGenericMapping = IoGetFileObjectGenericMapping();
|
|
ASSERT( pFileObjectGenericMapping != NULL );
|
|
|
|
fileRead = GENERIC_READ;
|
|
|
|
RtlMapGenericMask(
|
|
&fileRead,
|
|
pFileObjectGenericMapping
|
|
);
|
|
|
|
fileAll = GENERIC_ALL;
|
|
|
|
RtlMapGenericMask(
|
|
&fileAll,
|
|
pFileObjectGenericMapping
|
|
);
|
|
|
|
//
|
|
// Build a restrictive security descriptor for the control device
|
|
// object:
|
|
//
|
|
// Full access for NT AUTHORITY\SYSTEM
|
|
// Full access for BUILTIN\Administrators
|
|
//
|
|
|
|
sidMaskPairs[0].pSid = SeExports->SeLocalSystemSid;
|
|
sidMaskPairs[0].AccessMask = fileAll;
|
|
|
|
sidMaskPairs[1].pSid = SeExports->SeAliasAdminsSid;
|
|
sidMaskPairs[1].AccessMask = fileAll;
|
|
|
|
status = UlpCreateSecurityDescriptor(
|
|
&securityDescriptor, // pSecurityDescriptor
|
|
&sidMaskPairs[0], // pSidMaskPairs
|
|
2 // NumSidMaskPairs
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto complete;
|
|
}
|
|
|
|
status = UlpSetDeviceObjectSecurity(
|
|
g_pUlControlDeviceObject,
|
|
DACL_SECURITY_INFORMATION,
|
|
&securityDescriptor
|
|
);
|
|
|
|
UlpCleanupSecurityDescriptor( &securityDescriptor );
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Build a restrictive security descriptor for the filter device
|
|
// object:
|
|
//
|
|
// Full access for NT AUTHORITY\SYSTEM
|
|
// Full access for BUILTIN\Administrators
|
|
//
|
|
|
|
sidMaskPairs[0].pSid = SeExports->SeLocalSystemSid;
|
|
sidMaskPairs[0].AccessMask = fileAll;
|
|
|
|
sidMaskPairs[1].pSid = SeExports->SeAliasAdminsSid;
|
|
sidMaskPairs[1].AccessMask = fileAll;
|
|
|
|
status = UlpCreateSecurityDescriptor(
|
|
&securityDescriptor, // pSecurityDescriptor
|
|
&sidMaskPairs[0], // pSidMaskPairs
|
|
2 // NumSidMaskPairs
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto complete;
|
|
}
|
|
|
|
status = UlpSetDeviceObjectSecurity(
|
|
g_pUlFilterDeviceObject,
|
|
DACL_SECURITY_INFORMATION,
|
|
&securityDescriptor
|
|
);
|
|
|
|
UlpCleanupSecurityDescriptor( &securityDescriptor );
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto complete;
|
|
}
|
|
|
|
//
|
|
// Build a slightly less restrictive security descriptor for the
|
|
// app pool device object:
|
|
//
|
|
// Full access for NT AUTHORITY\SYSTEM
|
|
// Full access for BUILTIN\Administrators
|
|
// Read access for Everyone
|
|
//
|
|
|
|
sidMaskPairs[0].pSid = SeExports->SeLocalSystemSid;
|
|
sidMaskPairs[0].AccessMask = fileAll;
|
|
|
|
sidMaskPairs[1].pSid = SeExports->SeAliasAdminsSid;
|
|
sidMaskPairs[1].AccessMask = fileAll;
|
|
|
|
sidMaskPairs[2].pSid = SeExports->SeWorldSid;
|
|
sidMaskPairs[2].AccessMask = fileRead;
|
|
|
|
status = UlpCreateSecurityDescriptor(
|
|
&securityDescriptor, // pSecurityDescriptor
|
|
&sidMaskPairs[0], // pSidMaskPairs
|
|
3 // NumSidMaskPairs
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto complete;
|
|
}
|
|
|
|
status = UlpSetDeviceObjectSecurity(
|
|
g_pUlAppPoolDeviceObject,
|
|
DACL_SECURITY_INFORMATION,
|
|
&securityDescriptor
|
|
);
|
|
|
|
UlpCleanupSecurityDescriptor( &securityDescriptor );
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto complete;
|
|
}
|
|
|
|
complete:
|
|
|
|
return status;
|
|
|
|
} // UlpApplySecurityToDeviceObjects
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Allocates and initializes a security descriptor with the specified
|
|
attributes.
|
|
|
|
Arguments:
|
|
|
|
pSecurityDescriptor - Supplies a pointer to the security descriptor
|
|
to initialize.
|
|
|
|
pSidMaskPairs - Supplies an array of SID/ACCESS_MASK pairs.
|
|
|
|
NumSidMaskPairs - Supplies the number of SID/ACESS_MASK pairs.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlpCreateSecurityDescriptor(
|
|
OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
|
IN PSID_MASK_PAIR pSidMaskPairs,
|
|
IN ULONG NumSidMaskPairs
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PACL pDacl;
|
|
ULONG daclLength;
|
|
ULONG i;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT( pSecurityDescriptor != NULL );
|
|
ASSERT( pSidMaskPairs != NULL );
|
|
ASSERT( NumSidMaskPairs > 0 );
|
|
|
|
//
|
|
// Setup locals so we know how to cleanup on exit.
|
|
//
|
|
|
|
pDacl = NULL;
|
|
|
|
//
|
|
// Initialize the security descriptor.
|
|
//
|
|
|
|
status = RtlCreateSecurityDescriptor(
|
|
pSecurityDescriptor, // SecurityDescriptor
|
|
SECURITY_DESCRIPTOR_REVISION // Revision
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Calculate the DACL length.
|
|
//
|
|
|
|
daclLength = sizeof(ACL);
|
|
|
|
for (i = 0 ; i < NumSidMaskPairs ; i++)
|
|
{
|
|
daclLength += sizeof(ACCESS_ALLOWED_ACE);
|
|
daclLength += RtlLengthSid( pSidMaskPairs[i].pSid );
|
|
}
|
|
|
|
//
|
|
// Allocate & initialize the DACL.
|
|
//
|
|
|
|
pDacl = (PACL) UL_ALLOCATE_POOL(
|
|
PagedPool,
|
|
daclLength,
|
|
UL_SECURITY_DATA_POOL_TAG
|
|
);
|
|
|
|
if (pDacl == NULL)
|
|
{
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto cleanup;
|
|
}
|
|
|
|
status = RtlCreateAcl(
|
|
pDacl, // Acl
|
|
daclLength, // AclLength
|
|
ACL_REVISION // AclRevision
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Add the necessary access-allowed ACEs to the DACL.
|
|
//
|
|
|
|
for (i = 0 ; i < NumSidMaskPairs ; i++)
|
|
{
|
|
status = RtlAddAccessAllowedAce(
|
|
pDacl, // Acl
|
|
ACL_REVISION, // AceRevision
|
|
pSidMaskPairs[i].AccessMask, // AccessMask
|
|
pSidMaskPairs[i].pSid // Sid
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Attach the DACL to the security descriptor.
|
|
//
|
|
|
|
status = RtlSetDaclSecurityDescriptor(
|
|
pSecurityDescriptor, // SecurityDescriptor
|
|
TRUE, // DaclPresent
|
|
pDacl, // Dacl
|
|
FALSE // DaclDefaulted
|
|
);
|
|
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Success!
|
|
//
|
|
|
|
ASSERT( NT_SUCCESS(status) );
|
|
return STATUS_SUCCESS;
|
|
|
|
cleanup:
|
|
|
|
ASSERT( !NT_SUCCESS(status) );
|
|
|
|
if (pDacl != NULL)
|
|
{
|
|
UL_FREE_POOL(
|
|
pDacl,
|
|
UL_SECURITY_DATA_POOL_TAG
|
|
);
|
|
}
|
|
|
|
return status;
|
|
|
|
} // UlpCreateSecurityDescriptor
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Frees any resources associated with the security descriptor created
|
|
by UlpCreateSecurityDescriptor().
|
|
|
|
Arguments:
|
|
|
|
pSecurityDescriptor - Supplies the security descriptor to cleanup.
|
|
|
|
--***************************************************************************/
|
|
VOID
|
|
UlpCleanupSecurityDescriptor(
|
|
IN PSECURITY_DESCRIPTOR pSecurityDescriptor
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
PACL pDacl;
|
|
BOOLEAN daclPresent;
|
|
BOOLEAN daclDefaulted;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT( RtlValidSecurityDescriptor( pSecurityDescriptor ) );
|
|
|
|
//
|
|
// Try to retrieve the DACL from the security descriptor.
|
|
//
|
|
|
|
status = RtlGetDaclSecurityDescriptor(
|
|
pSecurityDescriptor, // SecurityDescriptor
|
|
&daclPresent, // DaclPresent
|
|
&pDacl, // Dacl
|
|
&daclDefaulted // DaclDefaulted
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
if (daclPresent && (pDacl != NULL))
|
|
{
|
|
UL_FREE_POOL(
|
|
pDacl,
|
|
UL_SECURITY_DATA_POOL_TAG
|
|
);
|
|
}
|
|
}
|
|
|
|
} // UlpCleanupSecurityDescriptor
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Applies the specified security descriptor to the specified device
|
|
object.
|
|
|
|
Arguments:
|
|
|
|
pDeviceObject - Supplies the device object to manipulate.
|
|
|
|
SecurityInformation - Supplies the level of information to change.
|
|
|
|
pSecurityDescriptor - Supplies the new security descriptor for the
|
|
device object.
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS - Completion status.
|
|
|
|
--***************************************************************************/
|
|
NTSTATUS
|
|
UlpSetDeviceObjectSecurity(
|
|
IN PDEVICE_OBJECT pDeviceObject,
|
|
IN SECURITY_INFORMATION SecurityInformation,
|
|
IN PSECURITY_DESCRIPTOR pSecurityDescriptor
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
HANDLE handle;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
ASSERT( IS_VALID_DEVICE_OBJECT( pDeviceObject ) );
|
|
ASSERT( RtlValidSecurityDescriptor( pSecurityDescriptor ) );
|
|
|
|
//
|
|
// Open a handle to the device object.
|
|
//
|
|
|
|
UlAttachToSystemProcess();
|
|
|
|
status = ObOpenObjectByPointer(
|
|
pDeviceObject, // Object
|
|
OBJ_CASE_INSENSITIVE | // HandleAttributes
|
|
UL_KERNEL_HANDLE,
|
|
NULL, // PassedAccessState
|
|
MAXIMUM_ALLOWED, // DesiredAccess
|
|
NULL, // ObjectType
|
|
KernelMode, // AccessMode
|
|
&handle // Handle
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
status = NtSetSecurityObject(
|
|
handle, // Handle
|
|
SecurityInformation, // SecurityInformation
|
|
pSecurityDescriptor // SecurityDescriptor
|
|
);
|
|
|
|
ZwClose( handle );
|
|
}
|
|
|
|
UlDetachFromSystemProcess();
|
|
|
|
return status;
|
|
|
|
} // UlpSetDeviceObjectSecurity
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Reads the UL section of the registry. Any values contained in the
|
|
registry override defaults.
|
|
|
|
Arguments:
|
|
|
|
pConfig - Supplies a pointer to a UL_CONFIG structure that receives
|
|
init-time configuration parameters. These are basically
|
|
parameters that do not need to persist in the driver once
|
|
initialization is complete.
|
|
|
|
--***************************************************************************/
|
|
VOID
|
|
UlpReadRegistry(
|
|
IN PUL_CONFIG pConfig
|
|
)
|
|
{
|
|
HANDLE parametersHandle;
|
|
NTSTATUS status;
|
|
LONG tmp;
|
|
LONGLONG tmp64;
|
|
UNICODE_STRING registryPath;
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Establish defaults.
|
|
//
|
|
|
|
pConfig->ThreadsPerCpu = DEFAULT_THREADS_PER_CPU;
|
|
pConfig->IrpContextLookasideDepth = DEFAULT_IRP_CONTEXT_LOOKASIDE_DEPTH;
|
|
pConfig->ReceiveBufferLookasideDepth = DEFAULT_RCV_BUFFER_LOOKASIDE_DEPTH;
|
|
pConfig->ResourceLookasideDepth = DEFAULT_RESOURCE_LOOKASIDE_DEPTH;
|
|
pConfig->RequestBufferLookasideDepth = DEFAULT_REQ_BUFFER_LOOKASIDE_DEPTH;
|
|
pConfig->InternalRequestLookasideDepth = DEFAULT_INT_REQUEST_LOOKASIDE_DEPTH;
|
|
pConfig->ResponseBufferLookasideDepth = DEFAULT_RESP_BUFFER_LOOKASIDE_DEPTH;
|
|
pConfig->SendTrackerLookasideDepth = DEFAULT_SEND_TRACKER_LOOKASIDE_DEPTH;
|
|
pConfig->LogBufferLookasideDepth = DEFAULT_LOG_BUFFER_LOOKASIDE_DEPTH;
|
|
pConfig->EnableUnload = DEFAULT_ENABLE_UNLOAD;
|
|
pConfig->EnableSecurity = DEFAULT_ENABLE_SECURITY;
|
|
|
|
pConfig->UriConfig.EnableCache = DEFAULT_CACHE_ENABLED;
|
|
pConfig->UriConfig.MaxCacheUriCount = DEFAULT_MAX_CACHE_URI_COUNT;
|
|
pConfig->UriConfig.MaxCacheMegabyteCount = DEFAULT_MAX_CACHE_MEGABYTE_COUNT;
|
|
pConfig->UriConfig.MaxUriBytes = DEFAULT_MAX_URI_BYTES;
|
|
pConfig->UriConfig.ScavengerPeriod = DEFAULT_CACHE_SCAVENGER_PERIOD;
|
|
pConfig->LargeMemMegabytes = DEFAULT_LARGE_MEM_MEGABYTES;
|
|
|
|
//
|
|
// Open the registry.
|
|
//
|
|
|
|
RtlInitUnicodeString( ®istryPath, REGISTRY_UL_INFORMATION );
|
|
|
|
status = UlOpenRegistry( ®istryPath, ¶metersHandle );
|
|
|
|
if (status != STATUS_SUCCESS)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if DBG
|
|
//
|
|
// Read the debug flags.
|
|
//
|
|
|
|
g_UlDebug = (ULONG)UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_DEBUG_FLAGS,
|
|
g_UlDebug
|
|
);
|
|
|
|
//
|
|
// Force a breakpoint if so requested.
|
|
//
|
|
|
|
if (UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_BREAK_ON_STARTUP,
|
|
DEFAULT_BREAK_ON_STARTUP) != 0 )
|
|
{
|
|
DbgBreakPoint();
|
|
}
|
|
|
|
//
|
|
// Read the break-on-error flags.
|
|
//
|
|
|
|
g_UlBreakOnError = (ULONG)UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_BREAK_ON_ERROR,
|
|
g_UlBreakOnError
|
|
);
|
|
|
|
g_UlVerboseErrors = (ULONG)UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_VERBOSE_ERRORS,
|
|
g_UlVerboseErrors
|
|
);
|
|
|
|
//
|
|
// Break-on-error implies verbose-errors.
|
|
//
|
|
|
|
if (g_UlBreakOnError)
|
|
{
|
|
g_UlVerboseErrors = TRUE;
|
|
}
|
|
#endif // DBG
|
|
|
|
#if ALLOW_UNLOAD
|
|
//
|
|
// Enable driver unload if requested.
|
|
//
|
|
|
|
pConfig->EnableUnload = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_UNLOAD,
|
|
(LONG)pConfig->EnableUnload
|
|
) != 0;
|
|
#endif // ALLOW_UNLOAD
|
|
|
|
//
|
|
// Enable driver security if requested.
|
|
//
|
|
|
|
pConfig->EnableSecurity = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_SECURITY,
|
|
(LONG)pConfig->EnableSecurity
|
|
) != 0;
|
|
|
|
//
|
|
// Read the stack size and priority boost values from the registry.
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_IRP_STACK_SIZE,
|
|
(LONG)g_UlIrpStackSize
|
|
);
|
|
|
|
//
|
|
// Enforce reasonable minimum/maximum values for the IRP stack size.
|
|
//
|
|
|
|
if (tmp < 2)
|
|
{
|
|
tmp = 2;
|
|
}
|
|
else if (tmp > 64)
|
|
{
|
|
tmp = 64;
|
|
}
|
|
|
|
g_UlIrpStackSize = (CCHAR)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_PRIORITY_BOOST,
|
|
(LONG)g_UlPriorityBoost
|
|
);
|
|
|
|
if (tmp > 16 || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_PRIORITY_BOOST;
|
|
}
|
|
|
|
g_UlPriorityBoost = (CCHAR)tmp;
|
|
|
|
//
|
|
// Read the thread pool parameters.
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_THREADS_PER_CPU,
|
|
(LONG)pConfig->ThreadsPerCpu
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_THREADS_PER_CPU;
|
|
}
|
|
|
|
pConfig->ThreadsPerCpu = (USHORT)tmp;
|
|
|
|
//
|
|
// Other configuration parameters.
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MIN_IDLE_CONNECTIONS,
|
|
(LONG)g_UlMinIdleConnections
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 1)
|
|
{
|
|
tmp = DEFAULT_MIN_IDLE_CONNECTIONS;
|
|
}
|
|
|
|
g_UlMinIdleConnections = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_IDLE_CONNECTIONS,
|
|
(LONG)g_UlMaxIdleConnections
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_MAX_IDLE_CONNECTIONS;
|
|
}
|
|
|
|
g_UlMaxIdleConnections = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_IRP_CONTEXT_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->IrpContextLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_IRP_CONTEXT_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->IrpContextLookasideDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_RCV_BUFFER_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->ReceiveBufferLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_RCV_BUFFER_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->ReceiveBufferLookasideDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_REQ_BUFFER_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->RequestBufferLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_REQ_BUFFER_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->RequestBufferLookasideDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_INT_REQUEST_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->InternalRequestLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_INT_REQUEST_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->InternalRequestLookasideDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_RESP_BUFFER_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->ResponseBufferLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_RESP_BUFFER_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->ResponseBufferLookasideDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_SEND_TRACKER_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->SendTrackerLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_SEND_TRACKER_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->SendTrackerLookasideDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_LOG_BUFFER_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->LogBufferLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_LOG_BUFFER_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->LogBufferLookasideDepth = (USHORT)tmp;
|
|
|
|
g_UlEnableConnectionReuse = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_CONNECTION_REUSE,
|
|
(LONG)g_UlEnableConnectionReuse
|
|
) != 0;
|
|
|
|
g_UlEnableNagling = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_NAGLING,
|
|
(LONG)g_UlEnableNagling
|
|
) != 0;
|
|
|
|
g_UlEnableThreadAffinity = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_THREAD_AFFINITY,
|
|
(LONG)g_UlEnableThreadAffinity
|
|
) != 0;
|
|
|
|
tmp64 = UlReadLongLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_THREAD_AFFINITY_MASK,
|
|
g_UlThreadAffinityMask
|
|
);
|
|
|
|
if ((ULONGLONG)tmp64 > DEFAULT_THREAD_AFFINITY_MASK
|
|
|| (ULONGLONG)tmp64 == 0)
|
|
{
|
|
tmp64 = DEFAULT_THREAD_AFFINITY_MASK;
|
|
}
|
|
|
|
g_UlThreadAffinityMask = (ULONGLONG)tmp64;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_WORK_QUEUE_DEPTH,
|
|
(LONG)g_UlMaxWorkQueueDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp < 0)
|
|
{
|
|
tmp = DEFAULT_MAX_WORK_QUEUE_DEPTH;
|
|
}
|
|
|
|
g_UlMaxWorkQueueDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MIN_WORK_DEQUEUE_DEPTH,
|
|
(LONG)g_UlMinWorkDequeueDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp < 0)
|
|
{
|
|
tmp = DEFAULT_MIN_WORK_DEQUEUE_DEPTH;
|
|
}
|
|
|
|
g_UlMinWorkDequeueDepth = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_OPAQUE_ID_TABLE_SIZE,
|
|
(LONG)g_UlOpaqueIdTableSize
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_OPAQUE_ID_TABLE_SIZE;
|
|
}
|
|
|
|
g_UlOpaqueIdTableSize = tmp;
|
|
|
|
//
|
|
// MAX url setting
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_URL_LENGTH,
|
|
(LONG)g_UlMaxUrlLength
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_MAX_URL_LENGTH;
|
|
}
|
|
|
|
g_UlMaxUrlLength = (USHORT)tmp;
|
|
|
|
//
|
|
// MAX allowed field length in HTTP requests
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_FIELD_LENGTH,
|
|
(LONG)g_UlMaxFieldLength
|
|
);
|
|
|
|
if (tmp > 0xFFFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_MAX_FIELD_LENGTH;
|
|
}
|
|
|
|
g_UlMaxFieldLength = tmp;
|
|
|
|
//
|
|
// If defined this will overwrite the default
|
|
// log timer cycle period of 1 hour and make
|
|
// the testing of the log recycling easier.
|
|
// The value is interpreted in seconds.
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_DEBUG_LOGTIMER_CYCLE,
|
|
(LONG)g_UlDebugLogTimerCycle
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_DEBUG_LOGTIMER_CYCLE;
|
|
}
|
|
|
|
g_UlDebugLogTimerCycle = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_DEBUG_LOG_BUFFER_PERIOD,
|
|
(LONG)g_UlDebugLogBufferPeriod
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_DEBUG_LOG_BUFFER_PERIOD;
|
|
}
|
|
|
|
g_UlDebugLogBufferPeriod = (USHORT)tmp;
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_LOG_BUFFER_SIZE,
|
|
(LONG)g_UlLogBufferSize
|
|
);
|
|
|
|
if (tmp > MAXIMUM_ALLOWED_LOG_BUFFER_SIZE
|
|
|| tmp < MINIMUM_ALLOWED_LOG_BUFFER_SIZE )
|
|
{
|
|
// Basically this value will be discarted by the logging code
|
|
// instead systems granularity size (64K) will be used.
|
|
tmp = DEFAULT_LOG_BUFFER_SIZE;
|
|
}
|
|
|
|
tmp -= tmp % 4096; // Align down to 4k
|
|
|
|
g_UlLogBufferSize = (ULONG) tmp;
|
|
|
|
//
|
|
// read the resource lookaside config
|
|
//
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_RESOURCE_LOOKASIDE_DEPTH,
|
|
(LONG)pConfig->ResourceLookasideDepth
|
|
);
|
|
|
|
if (tmp > 0xFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_RESOURCE_LOOKASIDE_DEPTH;
|
|
}
|
|
|
|
pConfig->ResourceLookasideDepth = (USHORT)tmp;
|
|
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_REQUEST_BYTES,
|
|
g_UlMaxRequestBytes
|
|
);
|
|
|
|
if (tmp > 0xFFFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_MAX_REQUEST_BYTES;
|
|
}
|
|
|
|
g_UlMaxRequestBytes = ALIGN_DOWN( tmp, PVOID );
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_RCV_BUFFER_SIZE,
|
|
g_UlReceiveBufferSize
|
|
);
|
|
|
|
if (tmp > 0xFFFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_RCV_BUFFER_SIZE;
|
|
}
|
|
|
|
g_UlReceiveBufferSize = ALIGN_DOWN( tmp, PVOID );
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_RESP_BUFFER_SIZE,
|
|
g_UlResponseBufferSize
|
|
);
|
|
|
|
if (tmp > 0xFFFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_RESP_BUFFER_SIZE;
|
|
}
|
|
|
|
g_UlResponseBufferSize = ALIGN_DOWN( tmp, PVOID );
|
|
|
|
//
|
|
// Read URL processing parameters.
|
|
// BUGBUG: read legacy IIS value?
|
|
//
|
|
|
|
g_UlEnableNonUTF8 = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_NON_UTF8_URL,
|
|
DEFAULT_ENABLE_NON_UTF8_URL
|
|
) != 0;
|
|
|
|
if (g_UlEnableNonUTF8)
|
|
{
|
|
g_UlEnableDBCS = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_ENABLE_DBCS_URL,
|
|
DEFAULT_ENABLE_DBCS_URL
|
|
) != 0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We can't do DBCS if we only accept UTF-8.
|
|
//
|
|
g_UlEnableDBCS = FALSE;
|
|
}
|
|
|
|
if (g_UlEnableDBCS)
|
|
{
|
|
g_UlFavorDBCS = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_FAVOR_DBCS_URL,
|
|
DEFAULT_FAVOR_DBCS_URL
|
|
) != 0;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We can't favor DBCS if we don't allow DBCS.
|
|
//
|
|
g_UlFavorDBCS = FALSE;
|
|
}
|
|
|
|
tmp = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_INTERNAL_URL_LENGTH,
|
|
g_UlMaxInternalUrlLength
|
|
);
|
|
|
|
if (tmp > 0xFFFFFF || tmp <= 0)
|
|
{
|
|
tmp = DEFAULT_MAX_INTERNAL_URL_LENGTH;
|
|
}
|
|
|
|
g_UlMaxInternalUrlLength = (USHORT)tmp;
|
|
|
|
//
|
|
// Read URI Cache parameters
|
|
//
|
|
|
|
pConfig->UriConfig.EnableCache = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_CACHE_ENABLED,
|
|
DEFAULT_CACHE_ENABLED
|
|
) != 0;
|
|
|
|
pConfig->UriConfig.MaxCacheUriCount = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_CACHE_URI_COUNT,
|
|
DEFAULT_MAX_CACHE_URI_COUNT
|
|
);
|
|
|
|
pConfig->UriConfig.MaxCacheMegabyteCount = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_CACHE_MEGABYTE_COUNT,
|
|
DEFAULT_MAX_CACHE_MEGABYTE_COUNT
|
|
);
|
|
|
|
pConfig->UriConfig.MaxUriBytes = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_MAX_URI_BYTES,
|
|
DEFAULT_MAX_URI_BYTES
|
|
);
|
|
|
|
pConfig->UriConfig.ScavengerPeriod = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_CACHE_SCAVENGER_PERIOD,
|
|
DEFAULT_CACHE_SCAVENGER_PERIOD
|
|
);
|
|
|
|
pConfig->UriConfig.HashTableBits = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_HASH_TABLE_BITS,
|
|
DEFAULT_HASH_TABLE_BITS
|
|
);
|
|
|
|
pConfig->LargeMemMegabytes = UlReadLongParameter(
|
|
parametersHandle,
|
|
REGISTRY_LARGE_MEM_MEGABYTES,
|
|
DEFAULT_LARGE_MEM_MEGABYTES
|
|
);
|
|
|
|
//
|
|
// Make sure we can always buffer enough bytes for an entire request
|
|
// header.
|
|
//
|
|
|
|
g_UlMaxBufferedBytes = MAX(g_UlMaxBufferedBytes, g_UlMaxRequestBytes);
|
|
|
|
//
|
|
// Dump configuration on checked builds.
|
|
//
|
|
|
|
#if DBG
|
|
DbgPrint( "UL Configuration:\n" );
|
|
#if DBG
|
|
DbgPrint( " g_UlDebug = %08lx\n", g_UlDebug );
|
|
DbgPrint( " g_UlBreakOnError = %lu\n", g_UlBreakOnError );
|
|
DbgPrint( " g_UlVerboseErrors = %lu\n", g_UlVerboseErrors );
|
|
#endif // DBG
|
|
DbgPrint( " g_UlIrpStackSize = %lu\n", g_UlIrpStackSize );
|
|
DbgPrint( " g_UlPriorityBoost = %lu\n", g_UlPriorityBoost );
|
|
DbgPrint( " g_UlMinIdleConnections = %lu\n", g_UlMinIdleConnections );
|
|
DbgPrint( " g_UlMaxIdleConnections = %lu\n", g_UlMaxIdleConnections );
|
|
DbgPrint( " g_UlEnableConnectionReuse = %lu\n", g_UlEnableConnectionReuse );
|
|
DbgPrint( " g_UlEnableNagling = %lu\n", g_UlEnableNagling );
|
|
DbgPrint( " g_UlEnableThreadAffinity = %lu\n", g_UlEnableThreadAffinity );
|
|
DbgPrint( " g_UlThreadAffinityMask = %I64x\n", g_UlThreadAffinityMask );
|
|
DbgPrint( " g_UlMaxWorkQueueDepth = %lu\n", g_UlMaxWorkQueueDepth );
|
|
DbgPrint( " g_UlMinWorkDequeueDepth = %lu\n", g_UlMinWorkDequeueDepth );
|
|
DbgPrint( " g_UlOpaqueIdTableSize = %lu\n", g_UlOpaqueIdTableSize );
|
|
DbgPrint( " g_UlMaxRequestBytes = %lu\n", g_UlMaxRequestBytes );
|
|
DbgPrint( " g_UlReceiveBufferSize = %lu\n", g_UlReceiveBufferSize );
|
|
DbgPrint( " g_UlResponseBufferSize = %lu\n", g_UlResponseBufferSize );
|
|
DbgPrint( " g_UlMaxUrlLength = %lu\n", g_UlMaxUrlLength );
|
|
DbgPrint( " g_UlMaxFieldLength = %lu\n", g_UlMaxFieldLength );
|
|
DbgPrint( " g_UlDebugLogTimerCycle = %lu\n", g_UlDebugLogTimerCycle );
|
|
DbgPrint( " g_UlDebugLogBufferPeriod = %lu\n", g_UlDebugLogBufferPeriod );
|
|
DbgPrint( " g_UlLogBufferSize = %lu\n", g_UlLogBufferSize );
|
|
|
|
DbgPrint( " g_UlEnableNonUTF8 = %lu\n", g_UlEnableNonUTF8 );
|
|
DbgPrint( " g_UlEnableDBCS = %lu\n", g_UlEnableDBCS );
|
|
DbgPrint( " g_UlFavorDBCS = %lu\n", g_UlFavorDBCS );
|
|
|
|
DbgPrint( " g_UlMaxInternalUrlLength = %lu\n", g_UlMaxInternalUrlLength );
|
|
|
|
#if ALLOW_UNLOAD
|
|
DbgPrint( " EnableUnload = %lu\n", pConfig->EnableUnload );
|
|
#endif // ALLOW_UNLOAD
|
|
DbgPrint( " EnableSecurity = %lu\n", pConfig->EnableSecurity );
|
|
DbgPrint( " ThreadsPerCpu = %lx\n", pConfig->ThreadsPerCpu );
|
|
DbgPrint( " IrpContextLookasideDepth = %lu\n", pConfig->IrpContextLookasideDepth );
|
|
DbgPrint( " ReceiveBufferLookasideDepth = %lu\n", pConfig->ReceiveBufferLookasideDepth );
|
|
DbgPrint( " ResourceLookasideDepth = %lu\n", pConfig->ResourceLookasideDepth );
|
|
DbgPrint( " RequestBufferLookasideDepth = %lu\n", pConfig->RequestBufferLookasideDepth );
|
|
DbgPrint( " IntlRequestLookasideDepth = %lu\n", pConfig->InternalRequestLookasideDepth );
|
|
DbgPrint( " ResponseBufferLookasideDepth = %lu\n", pConfig->ResponseBufferLookasideDepth );
|
|
DbgPrint( " SendTrackerLookasideDepth = %lu\n", pConfig->SendTrackerLookasideDepth );
|
|
DbgPrint( " LogBufferLookasideDepth = %lu\n", pConfig->LogBufferLookasideDepth );
|
|
DbgPrint( " EnableCache = %lu\n", pConfig->UriConfig.EnableCache );
|
|
DbgPrint( " MaxCacheUriCount = %lu\n", pConfig->UriConfig.MaxCacheUriCount );
|
|
DbgPrint( " MaxCacheMegabyteCount = %lu\n", pConfig->UriConfig.MaxCacheMegabyteCount );
|
|
DbgPrint( " ScavengerPeriod = %lu\n", pConfig->UriConfig.ScavengerPeriod );
|
|
DbgPrint( " HashTableBits = %ld\n", pConfig->UriConfig.HashTableBits);
|
|
DbgPrint( " MaxUriBytes = %lu\n", pConfig->UriConfig.MaxUriBytes );
|
|
DbgPrint( " LargeMemMegabytes = %ld\n", pConfig->LargeMemMegabytes );
|
|
#endif // DBG
|
|
|
|
//
|
|
// Cleanup.
|
|
//
|
|
|
|
UlCloseSystemHandle( parametersHandle );
|
|
|
|
} // UlpReadRegistry
|
|
|
|
|
|
#if ALLOW_UNLOAD
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Unload routine called by the IO subsystem when UL is getting
|
|
unloaded.
|
|
|
|
--***************************************************************************/
|
|
VOID
|
|
UlpUnload(
|
|
IN PDRIVER_OBJECT DriverObject
|
|
)
|
|
{
|
|
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
UL_ENTER_DRIVER("UlpUnload", NULL);
|
|
|
|
#if DBG
|
|
KdPrint(( "UlpUnload called.\n" ));
|
|
#endif // DBG
|
|
|
|
//
|
|
// Terminate the UL modules.
|
|
//
|
|
|
|
UlpTerminateModules();
|
|
|
|
UL_LEAVE_DRIVER("UlpUnload");
|
|
|
|
#if DBG
|
|
//
|
|
// Terminate any debug-specific data after UL_LEAVE_DRIVER
|
|
//
|
|
|
|
UlDbgTerminateDebugData( );
|
|
#endif // DBG
|
|
|
|
|
|
} // UlpUnload
|
|
|
|
#endif // ALLOW_UNLOAD
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Terminates the various UL modules in the correct order.
|
|
|
|
--***************************************************************************/
|
|
VOID
|
|
UlpTerminateModules(
|
|
VOID
|
|
)
|
|
{
|
|
//
|
|
// Sanity check.
|
|
//
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Wait for endpoints to go away, so we're sure all I/O is done.
|
|
//
|
|
UlWaitForEndpointDrain();
|
|
|
|
//
|
|
// Kill Michael.
|
|
//
|
|
|
|
UlTerminateDateCache();
|
|
UlTerminateUriCache();
|
|
UlTerminateFilterChannel();
|
|
|
|
//
|
|
// Kill Henry.
|
|
//
|
|
|
|
TerminateFileCache();
|
|
|
|
//
|
|
// Kill Paul.
|
|
//
|
|
|
|
UlTerminateCG();
|
|
UlTerminateAP();
|
|
|
|
//
|
|
// Kill Keith.
|
|
//
|
|
|
|
UlTerminateControlChannel();
|
|
|
|
//
|
|
// TerminateLogs Blocks until all Io To Be Complete
|
|
//
|
|
// Note:CG should be terminated before Logs.
|
|
// Otherwise we won't stop issuing the buffer writes.
|
|
// ThreadPool should be terminated after Logs.
|
|
// Otherwise our Completion APCs won't be completed back.
|
|
//
|
|
|
|
//
|
|
// Kill Ali
|
|
//
|
|
|
|
UlTerminateLogs();
|
|
UlTcTerminate();
|
|
|
|
//
|
|
// Kill Eric.
|
|
//
|
|
|
|
UlTerminateHttpRcv();
|
|
UlTerminateCounters();
|
|
UlTerminateTimeoutMonitor();
|
|
|
|
//
|
|
// Kill George.
|
|
//
|
|
|
|
UlLargeMemTerminate();
|
|
|
|
//
|
|
// Kill TDI.
|
|
//
|
|
|
|
UxTerminateTdi();
|
|
UlTerminateTdi();
|
|
|
|
//
|
|
// Kill the thread pool.
|
|
//
|
|
|
|
UlTerminateThreadPool();
|
|
|
|
|
|
//
|
|
// Kill the opaque Ids
|
|
//
|
|
|
|
UlTerminateOpaqueIdTable();
|
|
|
|
|
|
//
|
|
// Kill any global data.
|
|
//
|
|
|
|
UlTerminateData();
|
|
|
|
|
|
//
|
|
// Delete our device objects.
|
|
//
|
|
|
|
if (g_pUlAppPoolDeviceObject != NULL)
|
|
{
|
|
IoDeleteDevice( g_pUlAppPoolDeviceObject );
|
|
}
|
|
|
|
if (g_pUlFilterDeviceObject != NULL)
|
|
{
|
|
IoDeleteDevice( g_pUlFilterDeviceObject );
|
|
}
|
|
|
|
if (g_pUlControlDeviceObject != NULL)
|
|
{
|
|
IoDeleteDevice( g_pUlControlDeviceObject );
|
|
}
|
|
|
|
//
|
|
// Delete the directory container.
|
|
//
|
|
|
|
if (g_UlDirectoryObject != NULL)
|
|
{
|
|
UlCloseSystemHandle( g_UlDirectoryObject );
|
|
}
|
|
|
|
//
|
|
// Delete the global trace logs.
|
|
//
|
|
|
|
DESTROY_REF_TRACE_LOG( g_pTdiTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pHttpRequestTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pHttpConnectionTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pHttpResponseTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pAppPoolTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pConfigGroupTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pThreadTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pMdlTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pFilterTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pMondoGlobalTraceLog );
|
|
DESTROY_IRP_TRACE_LOG( g_pIrpTraceLog );
|
|
DESTROY_TIME_TRACE_LOG( g_pTimeTraceLog );
|
|
DESTROY_REPLENISH_TRACE_LOG( g_pReplenishTraceLog );
|
|
DESTROY_FILTQ_TRACE_LOG( g_pFilterQueueTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pSiteCounterTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pConnectionCountTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pConfigGroupInfoTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pChunkTrackerTraceLog );
|
|
DESTROY_REF_TRACE_LOG( g_pWorkItemTraceLog );
|
|
|
|
UlTerminateOwnerRefTraceLog();
|
|
} // UlpTerminateModules
|
|
|