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.
1089 lines
30 KiB
1089 lines
30 KiB
/*++
|
|
|
|
Copyright (c) 1999-2002 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Init.c
|
|
|
|
Abstract:
|
|
|
|
User-mode interface to HTTP.SYS: DLL initialization/termination routines.
|
|
|
|
Author:
|
|
|
|
Eric Stenson (ericsten) 31-May-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.h"
|
|
|
|
|
|
//
|
|
// Private macros.
|
|
//
|
|
|
|
|
|
//
|
|
// Private data.
|
|
//
|
|
|
|
//
|
|
// Initialize/Terminate control
|
|
//
|
|
static DWORD g_InitServerRefCount;
|
|
static DWORD g_InitClientRefCount;
|
|
static DWORD g_InitConfigRefCount;
|
|
static DWORD g_InitResourcesRefCount;
|
|
|
|
//
|
|
// Critical section for accessing the init counts. Also used by client
|
|
// api for synchronization during initialization.
|
|
//
|
|
|
|
CRITICAL_SECTION g_InitCritSec;
|
|
|
|
#if DBG
|
|
|
|
extern DWORD g_HttpTraceId = 0;
|
|
|
|
#endif
|
|
|
|
//
|
|
// DLL ref count (for tracking one-time DLL init)
|
|
//
|
|
static DWORD g_DllRefCount = 0;
|
|
|
|
//
|
|
// global, singleton control channel
|
|
//
|
|
extern HANDLE g_ControlChannel = NULL;
|
|
|
|
//
|
|
// Thread load storage index for synchronous I/O event
|
|
//
|
|
extern DWORD g_TlsIndex = 0;
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs DLL initialization/termination.
|
|
|
|
Arguments:
|
|
|
|
DllHandle - Supplies a handle to the current DLL.
|
|
|
|
Reason - Supplies the notification code.
|
|
|
|
pContext - Optionally supplies a context.
|
|
|
|
Return Value:
|
|
|
|
BOOLEAN - TRUE if initialization completed successfully, FALSE
|
|
otherwise. Ignored for notifications other than process
|
|
attach.
|
|
|
|
--***************************************************************************/
|
|
BOOL
|
|
WINAPI
|
|
DllMain(
|
|
IN HMODULE DllHandle,
|
|
IN DWORD Reason,
|
|
IN LPVOID pContext OPTIONAL
|
|
)
|
|
{
|
|
BOOL result = TRUE;
|
|
HANDLE hEvent = NULL;
|
|
|
|
UNREFERENCED_PARAMETER(pContext);
|
|
UNREFERENCED_PARAMETER(DllHandle);
|
|
|
|
//
|
|
// Interpret the reason code.
|
|
//
|
|
|
|
switch (Reason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
//
|
|
// One time init
|
|
//
|
|
if ( 1 == InterlockedIncrement( (PLONG)&g_DllRefCount ) )
|
|
{
|
|
//
|
|
// Allocate space in TLS for cached event for synchronous
|
|
// IOCTL calls
|
|
//
|
|
|
|
g_TlsIndex = TlsAlloc();
|
|
if(g_TlsIndex == TLS_OUT_OF_INDEXES)
|
|
{
|
|
result = FALSE;
|
|
}
|
|
|
|
if(TRUE == result)
|
|
{
|
|
HttpCmnInitializeHttpCharsTable(FALSE);
|
|
|
|
result = InitializeCriticalSectionAndSpinCount( &g_InitCritSec, 0 );
|
|
|
|
g_InitServerRefCount = 0L;
|
|
g_InitClientRefCount = 0L;
|
|
g_InitConfigRefCount = 0L;
|
|
g_InitResourcesRefCount = 0L;
|
|
}
|
|
|
|
#if DBG
|
|
if(TRUE == result)
|
|
{
|
|
g_HttpTraceId = TraceRegisterEx( HTTP_TRACE_NAME, 0 );
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
//
|
|
// Ref counting & cleanup assertion(s).
|
|
//
|
|
if ( 0 == InterlockedDecrement( (PLONG)&g_DllRefCount ) )
|
|
{
|
|
// Check to see if we've been cleaned up.
|
|
if ( NULL != g_ControlChannel )
|
|
{
|
|
HttpTrace( "DLL_PROCESS_DETACH called with Control Channel still OPEN!\n" );
|
|
}
|
|
|
|
if ( ( 0L != g_InitServerRefCount ) ||
|
|
( 0L != g_InitClientRefCount ) ||
|
|
( 0L != g_InitConfigRefCount ) ||
|
|
( 0L != g_InitResourcesRefCount ) )
|
|
{
|
|
HttpTrace( "DLL_PROCESS_DETACH called with nonzero Reference Count(s)!\n" );
|
|
}
|
|
|
|
#if DBG
|
|
if(0 != g_HttpTraceId)
|
|
{
|
|
TraceDeregisterEx(g_HttpTraceId, 0);
|
|
|
|
g_HttpTraceId = 0;
|
|
}
|
|
#endif
|
|
|
|
// If DeleteCriticalSection raises an exception should we catch it?
|
|
|
|
DeleteCriticalSection( &g_InitCritSec );
|
|
|
|
TlsFree( g_TlsIndex );
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
|
|
hEvent = (HANDLE) TlsGetValue( g_TlsIndex );
|
|
if ( hEvent != NULL )
|
|
{
|
|
NtClose( hEvent );
|
|
TlsSetValue( g_TlsIndex, NULL );
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
} // DllMain
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs global initialization.
|
|
|
|
Arguments:
|
|
|
|
Reserved - Must be zero. May be used in future for interface version
|
|
negotiation.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
WINAPI
|
|
HttpInitialize(
|
|
IN HTTPAPI_VERSION Version,
|
|
IN ULONG Flags,
|
|
IN OUT VOID* Reserved
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_FUNCTION;
|
|
HTTPAPI_VERSION HttpVersion = HTTPAPI_VERSION_1;
|
|
|
|
HttpTrace4("=> HttpInitialize Major=%d Minor%d Flags=%ld Reserved=%p",
|
|
Version.HttpApiMajorVersion, Version.HttpApiMinorVersion, Flags, Reserved);
|
|
|
|
if ( Version.HttpApiMajorVersion != HttpVersion.HttpApiMajorVersion ||
|
|
Version.HttpApiMinorVersion != HttpVersion.HttpApiMinorVersion )
|
|
{
|
|
result = ERROR_INVALID_DLL;
|
|
}
|
|
else if( (NULL != Reserved) || (HTTP_ILLEGAL_INIT_FLAGS & Flags) )
|
|
{
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
EnterCriticalSection( &g_InitCritSec );
|
|
|
|
// Initialize event cache even if no flags are set
|
|
|
|
result = HttpApiInitializeResources( Flags );
|
|
|
|
// Perform specified initialization
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
if ( HTTP_INITIALIZE_CONFIG & Flags )
|
|
{
|
|
result = HttpApiInitializeConfiguration( Flags );
|
|
}
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
// Perform specified initialization
|
|
|
|
if ( HTTP_INITIALIZE_SERVER & Flags )
|
|
{
|
|
result = HttpApiInitializeListener( Flags );
|
|
}
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
if ( HTTP_INITIALIZE_CLIENT & Flags )
|
|
{
|
|
result = HttpApiInitializeClient( Flags );
|
|
}
|
|
|
|
if ( ( NO_ERROR != result ) && ( HTTP_INITIALIZE_SERVER & Flags ) )
|
|
{
|
|
// If we try to initialize both the server and client features then we must succeed with both
|
|
// initializations or fail both. We have no error code that distinguishes between total and
|
|
// partial failure.
|
|
|
|
HttpApiTerminateListener( Flags );
|
|
}
|
|
}
|
|
|
|
// If we fail to initialize the specified server or client features then we terminate the associated configuration
|
|
// as well even if HTTP_INITIALIZE_CONFIGURATION was set in the Flags. We have no error code that
|
|
// distinguishes between total and partial failure.
|
|
|
|
if ( ( NO_ERROR != result ) && ( HTTP_INITIALIZE_CONFIG & Flags ) )
|
|
{
|
|
// Terminate config
|
|
HttpApiTerminateConfiguration( Flags );
|
|
}
|
|
}
|
|
|
|
// If we fail any initialization step then we terminate the associated cache initialization. We have no error code
|
|
// that distinguishes between total and partial failure.
|
|
|
|
if ( NO_ERROR != result )
|
|
{
|
|
HttpApiTerminateResources( Flags );
|
|
}
|
|
|
|
}
|
|
|
|
LeaveCriticalSection( &g_InitCritSec );
|
|
|
|
}
|
|
|
|
HttpTrace1( "<= HttpInitialize = 0x%0x", result );
|
|
ASSERT( ERROR_INVALID_FUNCTION != result );
|
|
|
|
return result;
|
|
|
|
} // HttpInitialize
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs global termination.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
WINAPI
|
|
HttpTerminate(
|
|
IN ULONG Flags,
|
|
IN OUT VOID* Reserved
|
|
)
|
|
{
|
|
ULONG result;
|
|
|
|
HttpTrace2("=> HttpTerminate Flags=%ld Reserved=%p", Flags, Reserved);
|
|
|
|
if( (NULL != Reserved) || (HTTP_ILLEGAL_TERM_FLAGS & Flags) )
|
|
{
|
|
result = ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
ULONG tempResult;
|
|
|
|
result = NO_ERROR;
|
|
|
|
EnterCriticalSection( &g_InitCritSec );
|
|
|
|
if ( (HTTP_INITIALIZE_SERVER) & Flags )
|
|
{
|
|
result = HttpApiTerminateListener( Flags );
|
|
}
|
|
|
|
if ( (HTTP_INITIALIZE_CLIENT) & Flags )
|
|
{
|
|
tempResult = HttpApiTerminateClient( Flags );
|
|
|
|
result = ( NO_ERROR == result ) ? tempResult : NO_ERROR;
|
|
}
|
|
|
|
if ( (HTTP_INITIALIZE_CONFIG) & Flags )
|
|
{
|
|
tempResult = HttpApiTerminateConfiguration( Flags );
|
|
|
|
result = ( NO_ERROR == result ) ? tempResult : NO_ERROR;
|
|
}
|
|
|
|
HttpApiTerminateResources( Flags );
|
|
|
|
LeaveCriticalSection( &g_InitCritSec );
|
|
|
|
}
|
|
|
|
HttpTrace1( "<= HttpApiTerminate = 0x%0x", result );
|
|
|
|
return result;
|
|
|
|
} // HttpTerminate
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Predicate to test if DLL has been initalized.
|
|
|
|
--***************************************************************************/
|
|
BOOL
|
|
HttpIsInitialized(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
|
|
//
|
|
// Grab crit sec
|
|
//
|
|
EnterCriticalSection( &g_InitCritSec );
|
|
|
|
if ( 0 == Flags )
|
|
{
|
|
fRet = (BOOL) (0 != g_InitResourcesRefCount );
|
|
}
|
|
else if ( HTTP_LEGAL_INIT_FLAGS & Flags )
|
|
{
|
|
fRet = (BOOL) (0 != g_InitResourcesRefCount );
|
|
|
|
if ( HTTP_INITIALIZE_SERVER & Flags )
|
|
{
|
|
fRet &= (BOOL) (0 != g_InitServerRefCount);
|
|
}
|
|
|
|
if ( HTTP_INITIALIZE_CLIENT & Flags )
|
|
{
|
|
fRet &= (BOOL) (0 != g_InitClientRefCount);
|
|
}
|
|
|
|
if ( HTTP_INITIALIZE_CONFIG & Flags )
|
|
{
|
|
fRet &= (BOOL) (0 != g_InitConfigRefCount);
|
|
}
|
|
}
|
|
|
|
LeaveCriticalSection( &g_InitCritSec );
|
|
|
|
return fRet;
|
|
|
|
} // HttpIsInitalized
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs configuration initialization. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. With any Flags bit set we check the reference count
|
|
and initialize the configuration if needed. On success we increment the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiInitializeConfiguration(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiInitializeConfiguration Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( HTTP_LEGAL_INIT_FLAGS & Flags )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0 == g_InitConfigRefCount )
|
|
{
|
|
// component not configured
|
|
|
|
result = InitializeConfigurationGlobals();
|
|
}
|
|
else if ( MAXULONG == g_InitConfigRefCount )
|
|
{
|
|
// don't want to overflow the reference count
|
|
|
|
result = ERROR_TOO_MANY_SEM_REQUESTS;
|
|
}
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
g_InitConfigRefCount++;
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiInitializeConfiguration = 0x%0x RefCount = 0x%0x", result, g_InitConfigRefCount );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs Resources initialization. This internal function must be called
|
|
from with the critical section g_ApiCriticalSection held. On success we
|
|
increment the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for
|
|
server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for
|
|
client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for
|
|
applications that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiInitializeResources(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
ULONG count;
|
|
|
|
HttpTrace1( "=> HttpApiInitializeResources Flags=%ld Reserved=%p",
|
|
Flags);
|
|
|
|
if ( ( HTTP_LEGAL_INIT_FLAGS & Flags ) || ( 0L == Flags ) )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
// We increment the resources ref count twice
|
|
// for every legal bit set. We increment the ref count
|
|
// once when the flags are ZERO.
|
|
// HttpInitialize may be called with no flags indicating
|
|
// that only the resources are to be initialized. This
|
|
// convention allows support for existing code.
|
|
|
|
if ( 0 == Flags )
|
|
{
|
|
count = 1;
|
|
}
|
|
else
|
|
{
|
|
count = 0;
|
|
if ( HTTP_INITIALIZE_CLIENT & Flags ) count += 2;
|
|
if ( HTTP_INITIALIZE_SERVER & Flags ) count += 2;
|
|
if ( HTTP_INITIALIZE_CONFIG & Flags ) count += 2;
|
|
}
|
|
|
|
if ( MAXULONG-count < g_InitResourcesRefCount )
|
|
{
|
|
// don't want to overflow the reference count
|
|
|
|
result = ERROR_TOO_MANY_SEM_REQUESTS;
|
|
}
|
|
else
|
|
{
|
|
g_InitResourcesRefCount += count;
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiInitializeResources = 0x%0x RefCount = 0x%0x",
|
|
result,
|
|
g_InitResourcesRefCount );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Private function to open a HTTP.sys control channel and enable it.
|
|
|
|
Arguments:
|
|
|
|
ControlChannelHandle - Supplies a ptr to hold the control channel handle.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
DWORD
|
|
OpenAndEnableControlChannel(
|
|
OUT PHANDLE pHandle
|
|
)
|
|
{
|
|
DWORD result;
|
|
|
|
result = HttpOpenControlChannel(
|
|
pHandle,
|
|
0
|
|
);
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
//
|
|
// Turn on Control Channel
|
|
//
|
|
|
|
HTTP_ENABLED_STATE controlState = HttpEnabledStateActive;
|
|
|
|
result = HttpSetControlChannelInformation(
|
|
*pHandle,
|
|
HttpControlChannelStateInformation,
|
|
&controlState,
|
|
sizeof(controlState)
|
|
);
|
|
|
|
if ( NO_ERROR != result )
|
|
{
|
|
CloseHandle(*pHandle);
|
|
|
|
*pHandle = NULL;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs server initialization. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. With the HTTP_INITIALIZE_SERVER Flags bit set we
|
|
check the reference count and initialize the configuration if needed. On success we
|
|
increment the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiInitializeListener(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiInitializeListener Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( HTTP_INITIALIZE_SERVER & Flags )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0 == g_InitServerRefCount )
|
|
{
|
|
//
|
|
// Start HTTPFilter service
|
|
//
|
|
HttpApiTryToStartDriver(HTTP_FILTER_SERVICE_NAME);
|
|
|
|
//
|
|
// Open Control channel
|
|
//
|
|
|
|
ASSERT( NULL == g_ControlChannel );
|
|
|
|
result = OpenAndEnableControlChannel(
|
|
&g_ControlChannel
|
|
);
|
|
|
|
if(NO_ERROR == result)
|
|
{
|
|
//
|
|
// Init Config Group Hash Table
|
|
//
|
|
result = InitializeConfigGroupTable();
|
|
|
|
if(NO_ERROR != result)
|
|
{
|
|
CloseHandle(g_ControlChannel);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
else if ( MAXULONG == g_InitServerRefCount )
|
|
{
|
|
// don't want to overflow the reference count
|
|
|
|
result = ERROR_TOO_MANY_SEM_REQUESTS;
|
|
}
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
g_InitServerRefCount++;
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiInitializeListener = 0x%0x RefCount = 0x%0x", result, g_InitServerRefCount );
|
|
|
|
return result;
|
|
|
|
} // HttpApiInitializeListener
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs server initialization. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. With the HTTP_INITIALIZE_CLIENT Flags bit set we
|
|
check the reference count and initialize the configuration if needed. On success we
|
|
increment the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiInitializeClient(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiInitializeClient Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( HTTP_INITIALIZE_CLIENT & Flags )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0 == g_InitClientRefCount )
|
|
{
|
|
WORD wVersionRequested;
|
|
WSADATA wsaData;
|
|
|
|
result = NO_ERROR;
|
|
wVersionRequested = MAKEWORD( 2, 2 );
|
|
|
|
if(WSAStartup( wVersionRequested, &wsaData ) != 0)
|
|
{
|
|
result = GetLastError();
|
|
}
|
|
}
|
|
else if ( MAXULONG == g_InitClientRefCount )
|
|
{
|
|
// don't want to overflow the reference count
|
|
|
|
result = ERROR_TOO_MANY_SEM_REQUESTS;
|
|
}
|
|
|
|
if ( NO_ERROR == result )
|
|
{
|
|
g_InitClientRefCount++;
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiInitializeClient = 0x%0x RefCount = 0x%0x", result, g_InitClientRefCount );
|
|
|
|
return result;
|
|
|
|
} // HttpApiInitializeClient
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs configuration termination. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. With any Flags bit set we check the reference count
|
|
and terminate the configuration if needed. On success we decrement the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiTerminateConfiguration(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiTerminateConfiguration Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( (HTTP_INITIALIZE_CONFIG) & Flags )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0L == g_InitConfigRefCount )
|
|
{
|
|
//
|
|
// Configuration not initalized, or init previously failed, or terminated
|
|
//
|
|
result = ERROR_DLL_INIT_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if ( 1L == g_InitConfigRefCount )
|
|
{
|
|
TerminateConfigurationGlobals();
|
|
|
|
g_InitConfigRefCount = 0L;
|
|
}
|
|
else
|
|
{
|
|
g_InitConfigRefCount--;
|
|
}
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiTerminateConfiguration = 0x%0x RefCount = 0x%0x", result, g_InitConfigRefCount );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs resource termination. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. On success we decrement the reference count.
|
|
|
|
We need to hold onto the cache configuration if any of the other ref counts for server, client,
|
|
or config are nonzero. This is true because we need event objects available in the cache
|
|
for 'synchronous' IO calls to http.sys.
|
|
|
|
As a result of our dependency on the other ref counts, HttpApiTerminateResources MUST be
|
|
called last in HttpTerminate or any similar termination routine.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiTerminateResources(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiTerminateResources Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( ( HTTP_LEGAL_TERM_FLAGS & Flags ) || ( 0L == Flags ) )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0L == g_InitResourcesRefCount )
|
|
{
|
|
//
|
|
// Configuration not initalized, or init previously failed, or terminated
|
|
//
|
|
result = ERROR_DLL_INIT_FAILED;
|
|
}
|
|
else
|
|
{
|
|
ULONG count = 1;
|
|
BOOL bTerminate = FALSE;
|
|
|
|
// We decrement the resources ref count twice
|
|
// for every legal initialization bit in the Flags.
|
|
// We decrement the ref count once if the flags are ZERO.
|
|
// HttpTerminate may be called with no flags indicating
|
|
// that only the resources are to be released. This
|
|
// convention allows support for existing code.
|
|
|
|
if ( 0 == Flags )
|
|
{
|
|
count = 1;
|
|
}
|
|
else
|
|
{
|
|
count = 0;
|
|
if ( HTTP_INITIALIZE_CLIENT & Flags ) count += 2;
|
|
if ( HTTP_INITIALIZE_SERVER & Flags ) count += 2;
|
|
if ( HTTP_INITIALIZE_CONFIG & Flags ) count += 2;
|
|
}
|
|
|
|
bTerminate = (BOOL) ( count >= g_InitResourcesRefCount );
|
|
|
|
g_InitResourcesRefCount -= count;
|
|
|
|
if ( bTerminate )
|
|
{
|
|
g_InitResourcesRefCount = 0L;
|
|
}
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiTerminateResources = 0x%0x RefCount = 0x%0x", result, g_InitResourcesRefCount );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs server termination. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. With any Flags bit set we check the reference count
|
|
and terminate the server context if needed. On success we decrement the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiTerminateListener(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiTerminateListener Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( (HTTP_INITIALIZE_SERVER) & Flags )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0L == g_InitServerRefCount )
|
|
{
|
|
//
|
|
// DLL not initalized, or init previously failed, or terminated
|
|
//
|
|
result = ERROR_DLL_INIT_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if ( 1L == g_InitServerRefCount )
|
|
{
|
|
// Clean up Config Group table
|
|
TerminateConfigGroupTable();
|
|
|
|
// Clean up Control Channel
|
|
if ( g_ControlChannel )
|
|
{
|
|
__try
|
|
{
|
|
CloseHandle( g_ControlChannel );
|
|
}
|
|
__finally
|
|
{
|
|
HttpTrace1(
|
|
"HttpTerminateListener: exception closing control channel handle %p\n",
|
|
g_ControlChannel
|
|
);
|
|
}
|
|
|
|
g_ControlChannel = NULL;
|
|
}
|
|
|
|
g_InitServerRefCount = 0L;
|
|
|
|
}
|
|
else
|
|
{
|
|
g_InitServerRefCount--;
|
|
}
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiTerminateListener = 0x%0x RefCount = 0x%0x", result, g_InitServerRefCount );
|
|
|
|
return result;
|
|
|
|
} // HttpTerminateListener
|
|
|
|
|
|
/***************************************************************************++
|
|
|
|
Routine Description:
|
|
|
|
Performs client termination. This internal function must be called from with the critical
|
|
section g_ApiCriticalSection held. With any Flags bit set we check the reference count
|
|
and terminate the client context if needed. On success we decrement the reference count.
|
|
|
|
Arguments:
|
|
|
|
Flags -
|
|
HTTP_INITIALIZE_SERVER - Initializes the HTTP API layer and driver for server applications
|
|
HTTP_INITIALIZE_CLIENT - Initializes the HTTP API layer and driver for client applications
|
|
HTTP_INITIALIZE_CONFIG - Initializes the HTTP API layer and driver for applications
|
|
that will modify the HTTP configuration.
|
|
|
|
Return Value:
|
|
|
|
ULONG - Completion status.
|
|
|
|
--***************************************************************************/
|
|
ULONG
|
|
HttpApiTerminateClient(
|
|
IN ULONG Flags
|
|
)
|
|
{
|
|
ULONG result = ERROR_INVALID_PARAMETER;
|
|
|
|
HttpTrace1("=> HttpApiTerminateClient Flags=%ld Reserved=%p", Flags);
|
|
|
|
if ( HTTP_INITIALIZE_CLIENT & Flags )
|
|
{
|
|
result = NO_ERROR;
|
|
|
|
if ( 0L == g_InitClientRefCount )
|
|
{
|
|
//
|
|
// Configuration not initalized, or init previously failed, or terminated
|
|
//
|
|
result = ERROR_DLL_INIT_FAILED;
|
|
}
|
|
else
|
|
{
|
|
if ( 1L == g_InitClientRefCount )
|
|
{
|
|
g_InitClientRefCount = 0L;
|
|
|
|
// Unload Ssl filter, if it was loaded.
|
|
UnloadStrmFilt();
|
|
|
|
WSACleanup();
|
|
}
|
|
else
|
|
{
|
|
g_InitClientRefCount--;
|
|
}
|
|
}
|
|
}
|
|
|
|
HttpTrace2( "<= HttpApiTerminateClient = 0x%0x RefCount = 0x%0x", result, g_InitClientRefCount );
|
|
|
|
return result;
|
|
|
|
}
|
|
|