Blame iis/moduleconfig.cpp

Packit 284210
/*
Packit 284210
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
Packit 284210
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
Packit 284210
*
Packit 284210
* You may not use this file except in compliance with
Packit 284210
* the License.  You may obtain a copy of the License at
Packit 284210
*
Packit 284210
*     http://www.apache.org/licenses/LICENSE-2.0
Packit 284210
*
Packit 284210
* If any of the files related to licensing are missing or if you have any
Packit 284210
* other questions related to licensing please contact Trustwave Holdings, Inc.
Packit 284210
* directly using the email address security@modsecurity.org.
Packit 284210
*/
Packit 284210

Packit 284210
#define WIN32_LEAN_AND_MEAN
Packit 284210

Packit 284210
#undef inline
Packit 284210
#define inline inline
Packit 284210

Packit 284210
//  IIS7 Server API header file
Packit 284210
#include "httpserv.h"
Packit 284210

Packit 284210
//  Project header files
Packit 284210
#include "mymodule.h"
Packit 284210
#include "mymodulefactory.h"
Packit 284210
#include "moduleconfig.h"
Packit 284210

Packit 284210
HRESULT
Packit 284210
MODSECURITY_STORED_CONTEXT::Initialize(
Packit 284210
    IHttpContext *              pW3Context,
Packit 284210
    IAppHostConfigException **  ppException
Packit 284210
)
Packit 284210
{
Packit 284210
    HRESULT                    hr                       = S_OK;
Packit 284210
    IAppHostAdminManager       *pAdminManager           = NULL;
Packit 284210
    IAppHostElement            *pSessionTrackingElement = NULL;
Packit 284210
    IAppHostPropertyException  *pPropertyException      = NULL;
Packit 284210

Packit 284210
    PCWSTR pszConfigPath = pW3Context->GetMetadata()->GetMetaPath();
Packit 284210
    BSTR bstrUrlPath     = SysAllocString( pszConfigPath );
Packit 284210

Packit 284210
    pAdminManager = g_pHttpServer->GetAdminManager();
Packit 284210

Packit 284210
    if ( ( FAILED( hr ) ) || ( pAdminManager == NULL ) )
Packit 284210
    {
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        goto Failure;   
Packit 284210
    }
Packit 284210

Packit 284210
    // Get a handle to the section:
Packit 284210
    hr = pAdminManager->GetAdminSection(
Packit 284210
                                MODSECURITY_SECTION,
Packit 284210
                                bstrUrlPath,
Packit 284210
                                &pSessionTrackingElement );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    if ( pSessionTrackingElement == NULL )
Packit 284210
    {
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the property object for the 'enabled' attribute:
Packit 284210
    hr = GetBooleanPropertyValue( 
Packit 284210
                pSessionTrackingElement,
Packit 284210
                MODSECURITY_SECTION_ENABLED,
Packit 284210
                &pPropertyException,
Packit 284210
                &m_bIsEnabled);
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // If there is a config failure, we cannot continue execution:
Packit 284210
    if ( pPropertyException != NULL )
Packit 284210
    {
Packit 284210

Packit 284210
        ppException = ( IAppHostConfigException** ) &pPropertyException;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    if ( m_bIsEnabled == FALSE )
Packit 284210
    {
Packit 284210
        // There is no point in reading any more of the config associated with the session
Packit 284210
        // tracking section, since this feature is not enabled for the current URL 
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the property object for the 'configfile' attribute:
Packit 284210
    hr = GetStringPropertyValue( 
Packit 284210
                pSessionTrackingElement,
Packit 284210
                MODSECURITY_SECTION_CONFIGFILE,
Packit 284210
                &pPropertyException,
Packit 284210
                &m_pszPath);
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // If there is a config failure, we cannot continue execution:
Packit 284210
    if ( pPropertyException != NULL )
Packit 284210
    {
Packit 284210

Packit 284210
        ppException = ( IAppHostConfigException** ) &pPropertyException;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
Failure:
Packit 284210
    SysFreeString( bstrUrlPath );
Packit 284210
    return hr;
Packit 284210
}
Packit 284210

Packit 284210
HRESULT 
Packit 284210
MODSECURITY_STORED_CONTEXT::GetBooleanPropertyValue( 
Packit 284210
        IAppHostElement*            pElement,
Packit 284210
        WCHAR*                      pszPropertyName,
Packit 284210
        IAppHostPropertyException** pException,
Packit 284210
        BOOL*                       pBoolValue )
Packit 284210
{
Packit 284210
    HRESULT                 hr              = S_OK;
Packit 284210
    IAppHostProperty        *pProperty      = NULL;    
Packit 284210
    VARIANT                 vPropertyValue;
Packit 284210

Packit 284210
    if ( 
Packit 284210
           ( pElement        == NULL ) || 
Packit 284210
           ( pszPropertyName == NULL ) ||
Packit 284210
           ( pException      == NULL ) ||
Packit 284210
           ( pBoolValue      == NULL )
Packit 284210
       )
Packit 284210
    {
Packit 284210
        hr = E_INVALIDARG;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the property object for the BOOLEAN attribute:
Packit 284210
    hr = pElement->GetPropertyByName( 
Packit 284210
                        pszPropertyName,
Packit 284210
                        &pProperty );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    if ( pProperty == NULL )
Packit 284210
    {
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the attribute value:
Packit 284210
    VariantInit( &vPropertyValue );
Packit 284210

Packit 284210
    hr = pProperty->get_Value( &vPropertyValue );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // See it there is an exception that might be due to the actual value in the 
Packit 284210
    // config not meeting validation criteria
Packit 284210
    *pException = NULL;
Packit 284210

Packit 284210
    hr = pProperty->get_Exception( pException );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // No need to continue if we got an exception...
Packit 284210
    if ( ( *pException ) != NULL )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Finally, get the value:
Packit 284210
    *pBoolValue = ( vPropertyValue.boolVal == VARIANT_TRUE ) ? TRUE : FALSE;
Packit 284210
    
Packit 284210

Packit 284210
Failure:
Packit 284210
    VariantClear( &vPropertyValue );
Packit 284210

Packit 284210
    if ( pProperty != NULL )
Packit 284210
    {
Packit 284210
        pProperty->Release();
Packit 284210
        pProperty = NULL;
Packit 284210
    }
Packit 284210

Packit 284210
    return hr;
Packit 284210
}
Packit 284210

Packit 284210
HRESULT 
Packit 284210
MODSECURITY_STORED_CONTEXT::GetDWORDPropertyValue( 
Packit 284210
        IAppHostElement*            pElement,
Packit 284210
        WCHAR*                      pszPropertyName,
Packit 284210
        IAppHostPropertyException** pException,
Packit 284210
        DWORD*                      pnValue )
Packit 284210
{
Packit 284210
    HRESULT                 hr              = S_OK;
Packit 284210
    IAppHostProperty        *pProperty      = NULL;    
Packit 284210
    VARIANT                 vPropertyValue;
Packit 284210

Packit 284210
    if ( 
Packit 284210
           ( pElement        == NULL ) || 
Packit 284210
           ( pszPropertyName == NULL ) ||
Packit 284210
           ( pException      == NULL ) ||
Packit 284210
           ( pnValue         == NULL )
Packit 284210
       )
Packit 284210
    {
Packit 284210
        hr = E_INVALIDARG;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the property object for the INT attribute:
Packit 284210
    hr = pElement->GetPropertyByName( 
Packit 284210
                        pszPropertyName,
Packit 284210
                        &pProperty );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    if ( pProperty == NULL )
Packit 284210
    {
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the attribute value:
Packit 284210
    VariantInit( &vPropertyValue );
Packit 284210

Packit 284210
    hr = pProperty->get_Value( &vPropertyValue );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // See it there is an exception that might be due to the actual value in the 
Packit 284210
    // config not meeting validation criteria
Packit 284210
    *pException = NULL;
Packit 284210

Packit 284210
    hr = pProperty->get_Exception( pException );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // No need to continue if we got an exception...
Packit 284210
    if ( ( *pException ) != NULL )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Finally, get the value:
Packit 284210
    *pnValue =  vPropertyValue.ulVal;  
Packit 284210

Packit 284210
Failure:
Packit 284210
    VariantClear( &vPropertyValue );
Packit 284210

Packit 284210
    if ( pProperty != NULL )
Packit 284210
    {
Packit 284210
        pProperty->Release();
Packit 284210
        pProperty = NULL;
Packit 284210
    }
Packit 284210

Packit 284210
    return hr;
Packit 284210
}
Packit 284210

Packit 284210
HRESULT 
Packit 284210
MODSECURITY_STORED_CONTEXT::GetTimeSpanPropertyValue( 
Packit 284210
        IAppHostElement*            pElement,
Packit 284210
        WCHAR*                      pszPropertyName,
Packit 284210
        IAppHostPropertyException** pException,
Packit 284210
        ULONGLONG*                 pnValue )
Packit 284210
{
Packit 284210
    HRESULT                 hr              = S_OK;
Packit 284210
    IAppHostProperty        *pProperty      = NULL;    
Packit 284210
    VARIANT                 vPropertyValue;
Packit 284210

Packit 284210
    if ( 
Packit 284210
           ( pElement        == NULL ) || 
Packit 284210
           ( pszPropertyName == NULL ) ||
Packit 284210
           ( pException      == NULL ) ||
Packit 284210
           ( pnValue         == NULL )
Packit 284210
       )
Packit 284210
    {
Packit 284210
        hr = E_INVALIDARG;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the property object for the INT attribute:
Packit 284210
    hr = pElement->GetPropertyByName( 
Packit 284210
                        pszPropertyName,
Packit 284210
                        &pProperty );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    if ( pProperty == NULL )
Packit 284210
    {
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the attribute value:
Packit 284210
    VariantInit( &vPropertyValue );
Packit 284210

Packit 284210
    hr = pProperty->get_Value( &vPropertyValue );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // See it there is an exception that might be due to the actual value in the 
Packit 284210
    // config not meeting validation criteria
Packit 284210
    *pException = NULL;
Packit 284210

Packit 284210
    hr = pProperty->get_Exception( pException );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // No need to continue if we got an exception...
Packit 284210
    if ( ( *pException ) != NULL )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Finally, get the value:
Packit 284210
    *pnValue =  vPropertyValue.ullVal;  
Packit 284210

Packit 284210
Failure:
Packit 284210
    VariantClear( &vPropertyValue );
Packit 284210

Packit 284210
    if ( pProperty != NULL )
Packit 284210
    {
Packit 284210
        pProperty->Release();
Packit 284210
        pProperty = NULL;
Packit 284210
    }
Packit 284210

Packit 284210
    return hr;
Packit 284210
}
Packit 284210

Packit 284210
HRESULT 
Packit 284210
MODSECURITY_STORED_CONTEXT::GetStringPropertyValue( 
Packit 284210
        IAppHostElement*            pElement,
Packit 284210
        WCHAR*                      pszPropertyName,
Packit 284210
        IAppHostPropertyException** pException,
Packit 284210
        WCHAR**                     ppszValue )
Packit 284210
{
Packit 284210
    HRESULT                 hr              = S_OK;
Packit 284210
    IAppHostProperty        *pProperty      = NULL;    
Packit 284210
    DWORD                   dwLength;
Packit 284210
    VARIANT                 vPropertyValue;
Packit 284210

Packit 284210
    if ( 
Packit 284210
           ( pElement        == NULL ) || 
Packit 284210
           ( pszPropertyName == NULL ) ||
Packit 284210
           ( pException      == NULL ) ||
Packit 284210
           ( ppszValue       == NULL )
Packit 284210
       )
Packit 284210
    {
Packit 284210
        hr = E_INVALIDARG;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    *ppszValue = NULL;
Packit 284210

Packit 284210
    // Get the property object for the string attribute:
Packit 284210
    hr = pElement->GetPropertyByName( 
Packit 284210
                        pszPropertyName,
Packit 284210
                        &pProperty );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    if ( pProperty == NULL )
Packit 284210
    {
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Get the attribute value:
Packit 284210
    VariantInit( &vPropertyValue );
Packit 284210

Packit 284210
    hr = pProperty->get_Value( &vPropertyValue );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // See it there is an exception that might be due to the actual value in the 
Packit 284210
    // config not meeting validation criteria
Packit 284210
    *pException = NULL;
Packit 284210

Packit 284210
    hr = pProperty->get_Exception( pException );
Packit 284210

Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // No need to continue if we got an exception...
Packit 284210
    if ( ( *pException ) != NULL )
Packit 284210
    {
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    // Finally, get the value:
Packit 284210
    dwLength = SysStringLen( vPropertyValue.bstrVal );
Packit 284210
    *ppszValue = new WCHAR[ dwLength + 1 ];
Packit 284210

Packit 284210
    if ( (*ppszValue) == NULL )
Packit 284210
    {
Packit 284210
        hr = E_OUTOFMEMORY;
Packit 284210
        goto Failure;
Packit 284210
    }
Packit 284210

Packit 284210
    wcsncpy(
Packit 284210
        *ppszValue,
Packit 284210
        vPropertyValue.bstrVal,
Packit 284210
        dwLength );
Packit 284210

Packit 284210
    (*ppszValue)[ dwLength ] = L'\0';
Packit 284210
    
Packit 284210
Failure:
Packit 284210
    VariantClear( &vPropertyValue );
Packit 284210

Packit 284210
    if ( pProperty != NULL )
Packit 284210
    {
Packit 284210
        pProperty->Release();
Packit 284210
        pProperty = NULL;
Packit 284210
    }
Packit 284210

Packit 284210
    return hr;
Packit 284210
}
Packit 284210

Packit 284210
MODSECURITY_STORED_CONTEXT::~MODSECURITY_STORED_CONTEXT()
Packit 284210
{
Packit 284210
    if ( m_pszPath != NULL )
Packit 284210
    {
Packit 284210
        delete [] m_pszPath;
Packit 284210
        m_pszPath = NULL;
Packit 284210
    }
Packit 284210
}
Packit 284210

Packit 284210
MODSECURITY_STORED_CONTEXT::MODSECURITY_STORED_CONTEXT():
Packit 284210
    m_bIsEnabled ( FALSE ),
Packit 284210
    m_pszPath( NULL ),
Packit 284210
	m_Config( NULL ),
Packit 284210
	m_dwLastCheck( 0 )
Packit 284210
{
Packit 284210
	m_LastChange.dwLowDateTime = 0;
Packit 284210
	m_LastChange.dwHighDateTime = 0;
Packit 284210
}
Packit 284210

Packit 284210
DWORD 
Packit 284210
MODSECURITY_STORED_CONTEXT::GlobalWideCharToMultiByte(
Packit 284210
        WCHAR*  pSource,
Packit 284210
        DWORD   dwLengthSource,
Packit 284210
        CHAR**  ppszDestination,
Packit 284210
        USHORT*  pdwLengthDestination )
Packit 284210
{
Packit 284210
    DWORD       dwResult    = NULL;
Packit 284210
    DWORD       dwCount     = 0;
Packit 284210

Packit 284210
    if (  
Packit 284210
          ( pSource == NULL ) ||
Packit 284210
          ( ppszDestination == NULL ) ||
Packit 284210
          ( pdwLengthDestination == NULL ) 
Packit 284210
       )
Packit 284210
    {
Packit 284210
        dwResult = ERROR_INVALID_PARAMETER;
Packit 284210
        goto Exit;
Packit 284210
    }
Packit 284210

Packit 284210
    // Initialize result length
Packit 284210
    *pdwLengthDestination = 0;
Packit 284210
    *ppszDestination     = NULL;
Packit 284210

Packit 284210
    dwCount =   WideCharToMultiByte( 
Packit 284210
                    CP_ACP, 
Packit 284210
                    0, 
Packit 284210
                    pSource, 
Packit 284210
                    dwLengthSource + 1, 
Packit 284210
                    *ppszDestination, 
Packit 284210
                    0,
Packit 284210
                    NULL,
Packit 284210
                    NULL );
Packit 284210

Packit 284210
    if ( 0 == dwCount )
Packit 284210
    {
Packit 284210
        dwResult = GetLastError ();
Packit 284210

Packit 284210
        if ( dwResult == 0 )
Packit 284210
        {
Packit 284210
            dwResult = ERROR_INVALID_DATA;
Packit 284210
        }
Packit 284210

Packit 284210
        goto Exit;
Packit 284210
    }
Packit 284210

Packit 284210
    *ppszDestination = new CHAR[ dwCount + 1 ];
Packit 284210

Packit 284210
    if ( NULL == ( *ppszDestination ) )
Packit 284210
    {
Packit 284210
        dwResult = ERROR_OUTOFMEMORY;
Packit 284210
        goto Exit;
Packit 284210
    }
Packit 284210

Packit 284210
    // Make sure the memory is 'clean':
Packit 284210
    SecureZeroMemory(
Packit 284210
        ( *ppszDestination ),
Packit 284210
        ( dwCount + 1 ) * sizeof ( CHAR ) );
Packit 284210

Packit 284210
    if ( 
Packit 284210
        0 == WideCharToMultiByte( 
Packit 284210
                CP_ACP, 
Packit 284210
                0, 
Packit 284210
                pSource, 
Packit 284210
                dwLengthSource + 1, 
Packit 284210
                *ppszDestination, 
Packit 284210
                dwCount,
Packit 284210
                NULL,
Packit 284210
                NULL )
Packit 284210
       )
Packit 284210
    {
Packit 284210
        dwResult = GetLastError();
Packit 284210

Packit 284210
        goto Exit;
Packit 284210
    }
Packit 284210

Packit 284210
    *pdwLengthDestination = ( USHORT )dwCount;
Packit 284210

Packit 284210
Exit:
Packit 284210
    if ( dwResult != 0 )
Packit 284210
    {
Packit 284210
        // Make sure we do the proper cleanup in the error case:
Packit 284210
        if ( pdwLengthDestination != NULL )
Packit 284210
        {
Packit 284210
            *pdwLengthDestination = 0;
Packit 284210
        }
Packit 284210

Packit 284210
        if ( ppszDestination != NULL )
Packit 284210
        {
Packit 284210
            if ( ( *ppszDestination ) != NULL )
Packit 284210
            {
Packit 284210
                delete [] ( *ppszDestination );
Packit 284210
                ( *ppszDestination ) = NULL;
Packit 284210
            }
Packit 284210
        }
Packit 284210
    }
Packit 284210

Packit 284210
    return dwResult;
Packit 284210
}
Packit 284210

Packit 284210
HRESULT
Packit 284210
MODSECURITY_STORED_CONTEXT::GetConfig(
Packit 284210
    IHttpContext *   pContext,
Packit 284210
    MODSECURITY_STORED_CONTEXT ** ppModuleConfig
Packit 284210
)
Packit 284210
{
Packit 284210
    HRESULT                          hr                 = S_OK;
Packit 284210
    MODSECURITY_STORED_CONTEXT * pModuleConfig      = NULL;
Packit 284210
    IHttpModuleContextContainer *    pMetadataContainer = NULL;
Packit 284210
	IAppHostConfigException *        pException         = NULL;
Packit 284210

Packit 284210
    pMetadataContainer = pContext->GetMetadata()->GetModuleContextContainer();
Packit 284210

Packit 284210
	if ( pMetadataContainer == NULL )
Packit 284210
	{
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210
        return hr;
Packit 284210
	}
Packit 284210

Packit 284210
    pModuleConfig = (MODSECURITY_STORED_CONTEXT *)pMetadataContainer->GetModuleContext( g_pModuleContext );	
Packit 284210
    if ( pModuleConfig != NULL )
Packit 284210
    {
Packit 284210
        //
Packit 284210
        // We found stored data for this module for the metadata
Packit 284210
        // object which is different for unique configuration path
Packit 284210
        //
Packit 284210
        *ppModuleConfig = pModuleConfig;
Packit 284210
        return S_OK;
Packit 284210
    }
Packit 284210

Packit 284210
    //
Packit 284210
    // If we reach here, that means this is first request or first
Packit 284210
    // request after a configuration change IIS core will throw stored context away
Packit 284210
    // if a change notification arrives for this metadata path
Packit 284210
    //
Packit 284210
    pModuleConfig = new MODSECURITY_STORED_CONTEXT();
Packit 284210
    if ( pModuleConfig == NULL )
Packit 284210
    {
Packit 284210
        return E_OUTOFMEMORY;
Packit 284210
    }
Packit 284210

Packit 284210
    //
Packit 284210
    // Read module configuration data and store in MODSECURITY_STORED_CONTEXT
Packit 284210
    //
Packit 284210
    hr = pModuleConfig->Initialize( pContext, &pException );
Packit 284210
    if ( FAILED( hr )  || pException != NULL )
Packit 284210
    {
Packit 284210
        pModuleConfig->CleanupStoredContext();
Packit 284210

Packit 284210
        pModuleConfig = NULL;
Packit 284210
        hr = E_UNEXPECTED;
Packit 284210

Packit 284210
        return hr;
Packit 284210
    }
Packit 284210

Packit 284210
    //
Packit 284210
    // Store MODSECURITY_STORED_CONTEXT data as metadata stored context
Packit 284210
    //
Packit 284210
    hr = pMetadataContainer->SetModuleContext( pModuleConfig,
Packit 284210
                                               g_pModuleContext );
Packit 284210
    if ( FAILED( hr ) )
Packit 284210
    {
Packit 284210
        pModuleConfig->CleanupStoredContext();
Packit 284210
        pModuleConfig = NULL;
Packit 284210

Packit 284210
        //
Packit 284210
        // It is possible that some other thread stored context before this thread
Packit 284210
        // could do. Check returned hr and return context stored by other thread
Packit 284210
        //
Packit 284210
        if ( hr == HRESULT_FROM_WIN32( ERROR_ALREADY_ASSIGNED ) )
Packit 284210
        {
Packit 284210
            *ppModuleConfig = (MODSECURITY_STORED_CONTEXT *)pMetadataContainer->GetModuleContext( g_pModuleContext );
Packit 284210
            return S_OK;
Packit 284210
        }
Packit 284210
    }
Packit 284210

Packit 284210
    *ppModuleConfig = pModuleConfig;
Packit 284210
    return hr;
Packit 284210
}