Blame iis/mymodule.cpp

Packit Service 384592
/*
Packit Service 384592
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
Packit Service 384592
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
Packit Service 384592
*
Packit Service 384592
* You may not use this file except in compliance with
Packit Service 384592
* the License.  You may obtain a copy of the License at
Packit Service 384592
*
Packit Service 384592
*     http://www.apache.org/licenses/LICENSE-2.0
Packit Service 384592
*
Packit Service 384592
* If any of the files related to licensing are missing or if you have any
Packit Service 384592
* other questions related to licensing please contact Trustwave Holdings, Inc.
Packit Service 384592
* directly using the email address security@modsecurity.org.
Packit Service 384592
*/
Packit Service 384592
Packit Service 384592
#define WIN32_LEAN_AND_MEAN
Packit Service 384592
Packit Service 384592
#undef inline
Packit Service 384592
#define inline inline
Packit Service 384592
Packit Service 384592
//  IIS7 Server API header file
Packit Service 384592
#include <Windows.h>
Packit Service 384592
#include <sal.h>
Packit Service 384592
#include <strsafe.h>
Packit Service 384592
#include "httpserv.h"
Packit Service 384592
Packit Service 384592
//  Project header files
Packit Service 384592
#include "mymodule.h"
Packit Service 384592
#include "mymodulefactory.h"
Packit Service 384592
Packit Service 384592
#include "api.h"
Packit Service 384592
#include "moduleconfig.h"
Packit Service 384592
Packit Service 384592
#include "winsock2.h"
Packit Service 384592
Packit Service 384592
class REQUEST_STORED_CONTEXT : public IHttpStoredContext
Packit Service 384592
{
Packit Service 384592
 public:
Packit Service 384592
    REQUEST_STORED_CONTEXT()
Packit Service 384592
	{
Packit Service 384592
		m_pConnRec = NULL;
Packit Service 384592
		m_pRequestRec = NULL;
Packit Service 384592
		m_pHttpContext = NULL;
Packit Service 384592
		m_pProvider = NULL;
Packit Service 384592
		m_pResponseBuffer = NULL;
Packit Service 384592
		m_pResponseLength = 0;
Packit Service 384592
		m_pResponsePosition = 0;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
    ~REQUEST_STORED_CONTEXT()
Packit Service 384592
	{
Packit Service 384592
		FinishRequest();
Packit Service 384592
	}
Packit Service 384592
    
Packit Service 384592
    // virtual
Packit Service 384592
    VOID
Packit Service 384592
    CleanupStoredContext(
Packit Service 384592
        VOID
Packit Service 384592
    )
Packit Service 384592
    {
Packit Service 384592
		FinishRequest();
Packit Service 384592
        delete this;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	void FinishRequest()
Packit Service 384592
	{
Packit Service 384592
		if(m_pRequestRec != NULL)
Packit Service 384592
		{
Packit Service 384592
			modsecFinishRequest(m_pRequestRec);
Packit Service 384592
			m_pRequestRec = NULL;
Packit Service 384592
		}
Packit Service 384592
		if(m_pConnRec != NULL)
Packit Service 384592
		{
Packit Service 384592
			modsecFinishConnection(m_pConnRec);
Packit Service 384592
			m_pConnRec = NULL;
Packit Service 384592
		}
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	conn_rec			*m_pConnRec;
Packit Service 384592
	request_rec			*m_pRequestRec;
Packit Service 384592
	IHttpContext		*m_pHttpContext;
Packit Service 384592
	IHttpEventProvider	*m_pProvider;
Packit Service 384592
	char				*m_pResponseBuffer;
Packit Service 384592
	ULONGLONG			m_pResponseLength;
Packit Service 384592
	ULONGLONG			m_pResponsePosition;
Packit Service 384592
};
Packit Service 384592
Packit Service 384592
//----------------------------------------------------------------------------
Packit Service 384592
Packit Service 384592
char *GetIpAddr(apr_pool_t *pool, PSOCKADDR pAddr)
Packit Service 384592
{
Packit Service 384592
	const char *format = "%15[0-9.]:%5[0-9]";
Packit Service 384592
	char ip[16] = { 0 };  // ip4 addresses have max len 15
Packit Service 384592
	char port[6] = { 0 }; // port numbers are 16bit, ie 5 digits max
Packit Service 384592
Packit Service 384592
	DWORD len = 50;
Packit Service 384592
	char *buf = (char *)apr_palloc(pool, len);
Packit Service 384592
Packit Service 384592
	if(buf == NULL)
Packit Service 384592
		return "";
Packit Service 384592
Packit Service 384592
	buf[0] = 0;
Packit Service 384592
Packit Service 384592
	WSAAddressToString(pAddr, sizeof(SOCKADDR), NULL, buf, &len;;
Packit Service 384592
Packit Service 384592
	// test for IPV4 with port on the end
Packit Service 384592
	if (sscanf(buf, format, ip, port) == 2) {
Packit Service 384592
		// IPV4 but with port - remove the port
Packit Service 384592
		char* input = ":";
Packit Service 384592
		char* ipv4 = strtok(buf, input);
Packit Service 384592
		return ipv4;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	return buf;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
apr_sockaddr_t *CopySockAddr(apr_pool_t *pool, PSOCKADDR pAddr)
Packit Service 384592
{
Packit Service 384592
    apr_sockaddr_t *addr = (apr_sockaddr_t *)apr_palloc(pool, sizeof(apr_sockaddr_t));
Packit Service 384592
	int adrlen = 16, iplen = 4;
Packit Service 384592
Packit Service 384592
	if(pAddr->sa_family == AF_INET6)
Packit Service 384592
	{
Packit Service 384592
		adrlen = 46;
Packit Service 384592
		iplen = 16;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	addr->addr_str_len = adrlen;
Packit Service 384592
	addr->family = pAddr->sa_family;
Packit Service 384592
Packit Service 384592
	addr->hostname = "unknown";
Packit Service 384592
#ifdef WIN32
Packit Service 384592
    addr->ipaddr_len = sizeof(IN_ADDR);
Packit Service 384592
#else
Packit Service 384592
    addr->ipaddr_len = sizeof(struct in_addr);
Packit Service 384592
#endif
Packit Service 384592
    addr->ipaddr_ptr = &addr->sa.sin.sin_addr;
Packit Service 384592
    addr->pool = pool;
Packit Service 384592
    addr->port = 80;
Packit Service 384592
#ifdef WIN32
Packit Service 384592
	memcpy(&addr->sa.sin.sin_addr.S_un.S_addr, pAddr->sa_data, iplen);
Packit Service 384592
#else
Packit Service 384592
    memcpy(&addr->sa.sin.sin_addr.s_addr, pAddr->sa_data, iplen);
Packit Service 384592
#endif
Packit Service 384592
	addr->sa.sin.sin_family = pAddr->sa_family;
Packit Service 384592
    addr->sa.sin.sin_port = 80;
Packit Service 384592
    addr->salen = sizeof(addr->sa);
Packit Service 384592
	addr->servname = addr->hostname;
Packit Service 384592
Packit Service 384592
	return addr;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
//----------------------------------------------------------------------------
Packit Service 384592
Packit Service 384592
char *ZeroTerminate(const char *str, size_t len, apr_pool_t *pool)
Packit Service 384592
{
Packit Service 384592
	char *_n = (char *)apr_palloc(pool, len + 1);
Packit Service 384592
Packit Service 384592
	memcpy(_n, str, len);
Packit Service 384592
Packit Service 384592
	_n[len] = 0;
Packit Service 384592
Packit Service 384592
	return _n;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
//----------------------------------------------------------------------------
Packit Service 384592
// FUNCTION: ConvertUTF16ToUTF8
Packit Service 384592
// DESC: Converts Unicode UTF-16 (Windows default) text to Unicode UTF-8.
Packit Service 384592
//----------------------------------------------------------------------------
Packit Service 384592
Packit Service 384592
char *ConvertUTF16ToUTF8( __in const WCHAR * pszTextUTF16, size_t cchUTF16, apr_pool_t *pool )
Packit Service 384592
{
Packit Service 384592
    //
Packit Service 384592
    // Special case of NULL or empty input string
Packit Service 384592
    //
Packit Service 384592
    if ( (pszTextUTF16 == NULL) || (*pszTextUTF16 == L'\0') || cchUTF16 == 0 )
Packit Service 384592
    {
Packit Service 384592
        // Return empty string
Packit Service 384592
        return "";
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    //
Packit Service 384592
    // Get size of destination UTF-8 buffer, in CHAR's (= bytes)
Packit Service 384592
    //
Packit Service 384592
    int cbUTF8 = ::WideCharToMultiByte(
Packit Service 384592
        CP_UTF8,                // convert to UTF-8
Packit Service 384592
        0,      // specify conversion behavior
Packit Service 384592
        pszTextUTF16,           // source UTF-16 string
Packit Service 384592
        static_cast<int>( cchUTF16 ),   // total source string length, in WCHAR's, 
Packit Service 384592
        NULL,                   // unused - no conversion required in this step
Packit Service 384592
        0,                      // request buffer size
Packit Service 384592
        NULL, NULL              // unused
Packit Service 384592
        );
Packit Service 384592
Packit Service 384592
    if ( cbUTF8 == 0 )
Packit Service 384592
    {
Packit Service 384592
		return "";
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    //
Packit Service 384592
    // Allocate destination buffer for UTF-8 string
Packit Service 384592
    //
Packit Service 384592
Packit Service 384592
    int cchUTF8 = cbUTF8; // sizeof(CHAR) = 1 byte
Packit Service 384592
Packit Service 384592
    char *pszUTF8 = (char *)apr_palloc(pool, cchUTF8 + 1 );
Packit Service 384592
Packit Service 384592
    //
Packit Service 384592
    // Do the conversion from UTF-16 to UTF-8
Packit Service 384592
    //
Packit Service 384592
    int result = ::WideCharToMultiByte(
Packit Service 384592
        CP_UTF8,                // convert to UTF-8
Packit Service 384592
        0,      // specify conversion behavior
Packit Service 384592
        pszTextUTF16,           // source UTF-16 string
Packit Service 384592
        static_cast<int>( cchUTF16 ),   // total source string length, in WCHAR's, 
Packit Service 384592
                                        // including end-of-string \0
Packit Service 384592
        pszUTF8,                // destination buffer
Packit Service 384592
        cbUTF8,                 // destination buffer size, in bytes
Packit Service 384592
        NULL, NULL              // unused
Packit Service 384592
        );  
Packit Service 384592
Packit Service 384592
    if ( result == 0 )
Packit Service 384592
    {
Packit Service 384592
		return "";
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	pszUTF8[cchUTF8] =  0;
Packit Service 384592
Packit Service 384592
    return pszUTF8;
Packit Service 384592
}
Packit Service 384592
 
Packit Service 384592
void Log(void *obj, int level, char *str)
Packit Service 384592
{
Packit Service 384592
	CMyHttpModule *mod = (CMyHttpModule *)obj;
Packit Service 384592
	WORD logcat = EVENTLOG_INFORMATION_TYPE;
Packit Service 384592
Packit Service 384592
	level &= APLOG_LEVELMASK;
Packit Service 384592
Packit Service 384592
	if(level <= APLOG_ERR)
Packit Service 384592
		logcat = EVENTLOG_ERROR_TYPE;
Packit Service 384592
Packit Service 384592
	if(level == APLOG_WARNING || strstr(str, "Warning.") != NULL)
Packit Service 384592
		logcat = EVENTLOG_WARNING_TYPE;
Packit Service 384592
Packit Service 384592
	mod->WriteEventViewerLog(str, logcat);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
#define NOTE_IIS "iis-tx-context"
Packit Service 384592
Packit Service 384592
void StoreIISContext(request_rec *r, REQUEST_STORED_CONTEXT *rsc)
Packit Service 384592
{
Packit Service 384592
    apr_table_setn(r->notes, NOTE_IIS, (const char *)rsc);
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
REQUEST_STORED_CONTEXT *RetrieveIISContext(request_rec *r)
Packit Service 384592
{
Packit Service 384592
    REQUEST_STORED_CONTEXT *msr = NULL;
Packit Service 384592
    request_rec *rx = NULL;
Packit Service 384592
Packit Service 384592
    /* Look in the current request first. */
Packit Service 384592
    msr = (REQUEST_STORED_CONTEXT *)apr_table_get(r->notes, NOTE_IIS);
Packit Service 384592
    if (msr != NULL) {
Packit Service 384592
        //msr->r = r;
Packit Service 384592
        return msr;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* If this is a subrequest then look in the main request. */
Packit Service 384592
    if (r->main != NULL) {
Packit Service 384592
        msr = (REQUEST_STORED_CONTEXT *)apr_table_get(r->main->notes, NOTE_IIS);
Packit Service 384592
        if (msr != NULL) {
Packit Service 384592
            //msr->r = r;
Packit Service 384592
            return msr;
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    /* If the request was redirected then look in the previous requests. */
Packit Service 384592
    rx = r->prev;
Packit Service 384592
    while(rx != NULL) {
Packit Service 384592
        msr = (REQUEST_STORED_CONTEXT *)apr_table_get(rx->notes, NOTE_IIS);
Packit Service 384592
        if (msr != NULL) {
Packit Service 384592
            //msr->r = r;
Packit Service 384592
            return msr;
Packit Service 384592
        }
Packit Service 384592
        rx = rx->prev;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    return NULL;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
HRESULT CMyHttpModule::ReadFileChunk(HTTP_DATA_CHUNK *chunk, char *buf)
Packit Service 384592
{
Packit Service 384592
    OVERLAPPED ovl;
Packit Service 384592
    DWORD dwDataStartOffset;
Packit Service 384592
    ULONGLONG bytesTotal = 0;
Packit Service 384592
	BYTE *	pIoBuffer = NULL;
Packit Service 384592
	HANDLE	hIoEvent = INVALID_HANDLE_VALUE;
Packit Service 384592
	HRESULT hr = S_OK;
Packit Service 384592
Packit Service 384592
    pIoBuffer = (BYTE *)VirtualAlloc(NULL,
Packit Service 384592
                                        1,
Packit Service 384592
                                        MEM_COMMIT | MEM_RESERVE,
Packit Service 384592
                                        PAGE_READWRITE);
Packit Service 384592
    if (pIoBuffer == NULL)
Packit Service 384592
    {
Packit Service 384592
        hr = HRESULT_FROM_WIN32(GetLastError());
Packit Service 384592
		goto Done;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    hIoEvent = CreateEvent(NULL,  // security attr
Packit Service 384592
                                FALSE, // manual reset
Packit Service 384592
                                FALSE, // initial state
Packit Service 384592
                                NULL); // name
Packit Service 384592
    if (hIoEvent == NULL)
Packit Service 384592
    {
Packit Service 384592
        hr = HRESULT_FROM_WIN32(GetLastError());
Packit Service 384592
		goto Done;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	while(bytesTotal < chunk->FromFileHandle.ByteRange.Length.QuadPart)
Packit Service 384592
	{
Packit Service 384592
		DWORD bytesRead = 0;
Packit Service 384592
		int was_eof = 0;
Packit Service 384592
		ULONGLONG offset = chunk->FromFileHandle.ByteRange.StartingOffset.QuadPart + bytesTotal;
Packit Service 384592
Packit Service 384592
		ZeroMemory(&ovl, sizeof ovl);
Packit Service 384592
		ovl.hEvent     = hIoEvent;
Packit Service 384592
		ovl.Offset = (DWORD)offset;
Packit Service 384592
		dwDataStartOffset = ovl.Offset & (m_dwPageSize - 1);
Packit Service 384592
		ovl.Offset &= ~(m_dwPageSize - 1);
Packit Service 384592
		ovl.OffsetHigh = offset >> 32;
Packit Service 384592
Packit Service 384592
		if (!ReadFile(chunk->FromFileHandle.FileHandle,
Packit Service 384592
					  pIoBuffer,
Packit Service 384592
					  m_dwPageSize,
Packit Service 384592
					  &bytesRead,
Packit Service 384592
					  &ovl))
Packit Service 384592
		{
Packit Service 384592
			DWORD dwErr = GetLastError();
Packit Service 384592
Packit Service 384592
			switch (dwErr)
Packit Service 384592
			{
Packit Service 384592
			case ERROR_IO_PENDING:
Packit Service 384592
				//
Packit Service 384592
				// GetOverlappedResult can return without waiting for the
Packit Service 384592
				// event thus leaving it signalled and causing problems
Packit Service 384592
				// with future use of that event handle, so just wait ourselves
Packit Service 384592
				//
Packit Service 384592
				WaitForSingleObject(ovl.hEvent, INFINITE); // == WAIT_OBJECT_0);
Packit Service 384592
Packit Service 384592
				if (!GetOverlappedResult(
Packit Service 384592
						 chunk->FromFileHandle.FileHandle,
Packit Service 384592
						 &ovl,
Packit Service 384592
						 &bytesRead,
Packit Service 384592
						 TRUE))
Packit Service 384592
				{
Packit Service 384592
					dwErr = GetLastError();
Packit Service 384592
Packit Service 384592
					switch(dwErr)
Packit Service 384592
					{
Packit Service 384592
					case ERROR_HANDLE_EOF:
Packit Service 384592
						was_eof = 1;
Packit Service 384592
						break;
Packit Service 384592
Packit Service 384592
					default:
Packit Service 384592
						hr = HRESULT_FROM_WIN32(dwErr);
Packit Service 384592
						goto Done;
Packit Service 384592
					}
Packit Service 384592
				}
Packit Service 384592
				break;
Packit Service 384592
Packit Service 384592
			case ERROR_HANDLE_EOF:
Packit Service 384592
				was_eof = 1;
Packit Service 384592
				break;
Packit Service 384592
Packit Service 384592
			default:
Packit Service 384592
				hr = HRESULT_FROM_WIN32(dwErr);
Packit Service 384592
				goto Done;
Packit Service 384592
			}
Packit Service 384592
		}
Packit Service 384592
Packit Service 384592
		bytesRead -= dwDataStartOffset;
Packit Service 384592
Packit Service 384592
		if (bytesRead > chunk->FromFileHandle.ByteRange.Length.QuadPart)
Packit Service 384592
		{
Packit Service 384592
			bytesRead = (DWORD)chunk->FromFileHandle.ByteRange.Length.QuadPart;
Packit Service 384592
		}
Packit Service 384592
		if ((bytesTotal + bytesRead) > chunk->FromFileHandle.ByteRange.Length.QuadPart)
Packit Service 384592
		{ 
Packit Service 384592
			bytesRead = chunk->FromFileHandle.ByteRange.Length.QuadPart - bytesTotal; 
Packit Service 384592
		}
Packit Service 384592
Packit Service 384592
		memcpy(buf, pIoBuffer + dwDataStartOffset, bytesRead);
Packit Service 384592
Packit Service 384592
		buf += bytesRead;
Packit Service 384592
		bytesTotal += bytesRead;
Packit Service 384592
Packit Service 384592
		if(was_eof != 0)
Packit Service 384592
			chunk->FromFileHandle.ByteRange.Length.QuadPart = bytesTotal;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
Done:
Packit Service 384592
	if(NULL != pIoBuffer)
Packit Service 384592
	{
Packit Service 384592
		VirtualFree(pIoBuffer, 0, MEM_RELEASE);
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	if(INVALID_HANDLE_VALUE != hIoEvent)
Packit Service 384592
	{
Packit Service 384592
		CloseHandle(hIoEvent);
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	return hr;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
REQUEST_NOTIFICATION_STATUS
Packit Service 384592
CMyHttpModule::OnSendResponse(
Packit Service 384592
    IN IHttpContext * pHttpContext,
Packit Service 384592
    IN ISendResponseProvider * pResponseProvider
Packit Service 384592
)
Packit Service 384592
{
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = NULL;
Packit Service 384592
Packit Service 384592
	rsc = (REQUEST_STORED_CONTEXT *)pHttpContext->GetModuleContextContainer()->GetModuleContext(g_pModuleContext);
Packit Service 384592
Packit Service 384592
	EnterCriticalSection(&m_csLock);
Packit Service 384592
Packit Service 384592
	// here we must check if response body processing is enabled
Packit Service 384592
	//
Packit Service 384592
	if(rsc == NULL || rsc->m_pRequestRec == NULL || rsc->m_pResponseBuffer != NULL || !modsecIsResponseBodyAccessEnabled(rsc->m_pRequestRec))
Packit Service 384592
	{
Packit Service 384592
		goto Exit;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
    HRESULT hr = S_OK;
Packit Service 384592
	IHttpResponse *pHttpResponse = NULL;
Packit Service 384592
    HTTP_RESPONSE *pRawHttpResponse = NULL;
Packit Service 384592
    HTTP_BYTE_RANGE *pFileByteRange = NULL;
Packit Service 384592
    HTTP_DATA_CHUNK *pSourceDataChunk = NULL;
Packit Service 384592
    LARGE_INTEGER  lFileSize;
Packit Service 384592
    REQUEST_NOTIFICATION_STATUS ret = RQ_NOTIFICATION_CONTINUE;
Packit Service 384592
	ULONGLONG ulTotalLength = 0;
Packit Service 384592
	DWORD c;
Packit Service 384592
	request_rec *r = rsc->m_pRequestRec;
Packit Service 384592
Packit Service 384592
	pHttpResponse = pHttpContext->GetResponse();
Packit Service 384592
	pRawHttpResponse = pHttpResponse->GetRawHttpResponse();
Packit Service 384592
Packit Service 384592
	// here we must add handling of chunked response
Packit Service 384592
	// apparently IIS 7 calls this handler once per chunk
Packit Service 384592
	// see: http://stackoverflow.com/questions/4385249/how-to-buffer-and-process-chunked-data-before-sending-headers-in-iis7-native-mod
Packit Service 384592
Packit Service 384592
	if(pRawHttpResponse->EntityChunkCount == 0)
Packit Service 384592
		goto Exit;
Packit Service 384592
Packit Service 384592
	// here we must transfer response headers
Packit Service 384592
	//
Packit Service 384592
	USHORT ctcch = 0;
Packit Service 384592
	char *ct = (char *)pHttpResponse->GetHeader(HttpHeaderContentType, &ctcch);
Packit Service 384592
	char *ctz = ZeroTerminate(ct, ctcch, r->pool);
Packit Service 384592
Packit Service 384592
	// assume HTML if content type not set
Packit Service 384592
	// without this output filter would not buffer response and processing would hang
Packit Service 384592
	//
Packit Service 384592
	if(ctz[0] == 0)
Packit Service 384592
		ctz = "text/html";
Packit Service 384592
Packit Service 384592
	r->content_type = ctz;
Packit Service 384592
Packit Service 384592
#define _TRANSHEADER(id,str) if(pRawHttpResponse->Headers.KnownHeaders[id].pRawValue != NULL) \
Packit Service 384592
	{\
Packit Service 384592
		apr_table_setn(r->headers_out, str, \
Packit Service 384592
			ZeroTerminate(pRawHttpResponse->Headers.KnownHeaders[id].pRawValue, pRawHttpResponse->Headers.KnownHeaders[id].RawValueLength, r->pool)); \
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
    _TRANSHEADER(HttpHeaderCacheControl, "Cache-Control");
Packit Service 384592
    _TRANSHEADER(HttpHeaderConnection, "Connection");
Packit Service 384592
    _TRANSHEADER(HttpHeaderDate, "Date");
Packit Service 384592
    _TRANSHEADER(HttpHeaderKeepAlive, "Keep-Alive");             
Packit Service 384592
    _TRANSHEADER(HttpHeaderPragma, "Pragma");                
Packit Service 384592
    _TRANSHEADER(HttpHeaderTrailer, "Trailer");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderTransferEncoding, "Transfer-Encoding");      
Packit Service 384592
    _TRANSHEADER(HttpHeaderUpgrade, "Upgrade");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderVia, "Via");                   
Packit Service 384592
    _TRANSHEADER(HttpHeaderWarning, "Warning");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderAllow, "Allow");                 
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentLength, "Content-Length");         
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentType, "Content-Type");           
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentEncoding, "Content-Encoding");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentLanguage, "Content-Language");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentLocation, "Content-Location");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentMd5, "Content-Md5");            
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentRange, "Content-Range");          
Packit Service 384592
    _TRANSHEADER(HttpHeaderExpires, "Expires");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderLastModified, "Last-Modified");          
Packit Service 384592
	_TRANSHEADER(HttpHeaderAcceptRanges, "Accept-Ranges");
Packit Service 384592
    _TRANSHEADER(HttpHeaderAge, "Age");                   
Packit Service 384592
    _TRANSHEADER(HttpHeaderEtag, "Etag");                  
Packit Service 384592
    _TRANSHEADER(HttpHeaderLocation, "Location");              
Packit Service 384592
    _TRANSHEADER(HttpHeaderProxyAuthenticate, "Proxy-Authenticate");     
Packit Service 384592
    _TRANSHEADER(HttpHeaderRetryAfter, "Retry-After");            
Packit Service 384592
    _TRANSHEADER(HttpHeaderServer, "Server");                
Packit Service 384592
    _TRANSHEADER(HttpHeaderSetCookie, "Set-Cookie");             
Packit Service 384592
    _TRANSHEADER(HttpHeaderVary, "Vary");                  
Packit Service 384592
    _TRANSHEADER(HttpHeaderWwwAuthenticate, "Www-Authenticate");
Packit Service 384592
Packit Service 384592
#undef	_TRANSHEADER
Packit Service 384592
Packit Service 384592
	for(int i = 0; i < pRawHttpResponse->Headers.UnknownHeaderCount; i++)
Packit Service 384592
	{
Packit Service 384592
		apr_table_setn(r->headers_out, 
Packit Service 384592
			ZeroTerminate(pRawHttpResponse->Headers.pUnknownHeaders[i].pName, pRawHttpResponse->Headers.pUnknownHeaders[i].NameLength, r->pool), 
Packit Service 384592
			ZeroTerminate(pRawHttpResponse->Headers.pUnknownHeaders[i].pRawValue, pRawHttpResponse->Headers.pUnknownHeaders[i].RawValueLength, r->pool));
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	r->content_encoding = apr_table_get(r->headers_out, "Content-Encoding");
Packit Service 384592
	//r->content_type = apr_table_get(r->headers_out, "Content-Type");		-- already set above
Packit Service 384592
Packit Service 384592
	const char *lng = apr_table_get(r->headers_out, "Content-Languages");
Packit Service 384592
Packit Service 384592
	if(lng != NULL)
Packit Service 384592
	{
Packit Service 384592
		r->content_languages = apr_array_make(r->pool, 1, sizeof(const char *));
Packit Service 384592
Packit Service 384592
		*(const char **)apr_array_push(r->content_languages) = lng;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	// Disable kernel caching for this response
Packit Service 384592
	// Probably we don't have to do it for ModSecurity
Packit Service 384592
Packit Service 384592
    //pHttpContext->GetResponse()->DisableKernelCache(
Packit Service 384592
    //        IISCacheEvents::HTTPSYS_CACHEABLE::HANDLER_HTTPSYS_UNFRIENDLY);
Packit Service 384592
Packit Service 384592
    for(c = 0; c < pRawHttpResponse->EntityChunkCount; c++ )
Packit Service 384592
    {
Packit Service 384592
        pSourceDataChunk = &pRawHttpResponse->pEntityChunks[ c ];
Packit Service 384592
Packit Service 384592
        switch( pSourceDataChunk->DataChunkType )
Packit Service 384592
        {
Packit Service 384592
            case HttpDataChunkFromMemory:
Packit Service 384592
                ulTotalLength += pSourceDataChunk->FromMemory.BufferLength;
Packit Service 384592
                break;
Packit Service 384592
            case HttpDataChunkFromFileHandle:
Packit Service 384592
                pFileByteRange = &pSourceDataChunk->FromFileHandle.ByteRange;
Packit Service 384592
                //
Packit Service 384592
                // File chunks may contain by ranges with unspecified length 
Packit Service 384592
                // (HTTP_BYTE_RANGE_TO_EOF).  In order to send parts of such a chunk, 
Packit Service 384592
                // its necessary to know when the chunk is finished, and
Packit Service 384592
                // we need to move to the next chunk.
Packit Service 384592
                //              
Packit Service 384592
                if ( pFileByteRange->Length.QuadPart == HTTP_BYTE_RANGE_TO_EOF)
Packit Service 384592
                {
Packit Service 384592
                    if ( GetFileType( pSourceDataChunk->FromFileHandle.FileHandle ) == 
Packit Service 384592
                                    FILE_TYPE_DISK )
Packit Service 384592
                    {
Packit Service 384592
                        if ( !GetFileSizeEx( pSourceDataChunk->FromFileHandle.FileHandle,
Packit Service 384592
                                             &lFileSize ) )
Packit Service 384592
                        {
Packit Service 384592
                            DWORD dwError = GetLastError();
Packit Service 384592
                            hr = HRESULT_FROM_WIN32(dwError);
Packit Service 384592
                            goto Finished;
Packit Service 384592
                        }
Packit Service 384592
Packit Service 384592
                        // put the resolved file length in the chunk, replacing 
Packit Service 384592
                        // HTTP_BYTE_RANGE_TO_EOF
Packit Service 384592
                        pFileByteRange->Length.QuadPart = 
Packit Service 384592
                              lFileSize.QuadPart - pFileByteRange->StartingOffset.QuadPart;
Packit Service 384592
                    }
Packit Service 384592
                    else
Packit Service 384592
                    {
Packit Service 384592
                        hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
Packit Service 384592
                        goto Finished;                        
Packit Service 384592
                    }
Packit Service 384592
                }  
Packit Service 384592
Packit Service 384592
                ulTotalLength += pFileByteRange->Length.QuadPart;
Packit Service 384592
                break;
Packit Service 384592
            default:
Packit Service 384592
                // TBD: consider implementing HttpDataChunkFromFragmentCache, 
Packit Service 384592
                // and HttpDataChunkFromFragmentCacheEx
Packit Service 384592
                hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
Packit Service 384592
                goto Finished;                        
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	rsc->m_pResponseBuffer = (char *)apr_palloc(rsc->m_pRequestRec->pool, ulTotalLength);
Packit Service 384592
Packit Service 384592
	ulTotalLength = 0;
Packit Service 384592
Packit Service 384592
    for(c = 0; c < pRawHttpResponse->EntityChunkCount; c++ )
Packit Service 384592
    {
Packit Service 384592
        pSourceDataChunk = &pRawHttpResponse->pEntityChunks[ c ];
Packit Service 384592
Packit Service 384592
        switch( pSourceDataChunk->DataChunkType )
Packit Service 384592
        {
Packit Service 384592
            case HttpDataChunkFromMemory:
Packit Service 384592
				memcpy(rsc->m_pResponseBuffer + ulTotalLength, pSourceDataChunk->FromMemory.pBuffer, pSourceDataChunk->FromMemory.BufferLength);
Packit Service 384592
                ulTotalLength += pSourceDataChunk->FromMemory.BufferLength;
Packit Service 384592
                break;
Packit Service 384592
            case HttpDataChunkFromFileHandle:
Packit Service 384592
                pFileByteRange = &pSourceDataChunk->FromFileHandle.ByteRange;
Packit Service 384592
Packit Service 384592
				if(ReadFileChunk(pSourceDataChunk, rsc->m_pResponseBuffer + ulTotalLength) != S_OK)
Packit Service 384592
				{
Packit Service 384592
			        DWORD dwErr = GetLastError();
Packit Service 384592
Packit Service 384592
					hr = HRESULT_FROM_WIN32(dwErr);
Packit Service 384592
	                goto Finished;
Packit Service 384592
				}
Packit Service 384592
Packit Service 384592
                ulTotalLength += pFileByteRange->Length.QuadPart;
Packit Service 384592
                break;
Packit Service 384592
            default:
Packit Service 384592
                // TBD: consider implementing HttpDataChunkFromFragmentCache, 
Packit Service 384592
                // and HttpDataChunkFromFragmentCacheEx
Packit Service 384592
                hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
Packit Service 384592
                goto Finished;                        
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	rsc->m_pResponseLength = ulTotalLength;
Packit Service 384592
Packit Service 384592
	//
Packit Service 384592
    // If there's no content-length set, we need to set it to avoid chunked transfer mode
Packit Service 384592
    // We can only do it if there is it's the only response to be sent.
Packit Service 384592
    //
Packit Service 384592
Packit Service 384592
    DWORD dwFlags = pResponseProvider->GetFlags();
Packit Service 384592
Packit Service 384592
	if (pResponseProvider->GetHeadersBeingSent() && 
Packit Service 384592
         (dwFlags & HTTP_SEND_RESPONSE_FLAG_MORE_DATA) == 0 &&
Packit Service 384592
         pHttpContext->GetResponse()->GetHeader(HttpHeaderContentLength) == NULL)    
Packit Service 384592
    {
Packit Service 384592
        CHAR szLength[21]; //Max length for a 64 bit int is 20
Packit Service 384592
Packit Service 384592
         ZeroMemory(szLength, sizeof(szLength));
Packit Service 384592
Packit Service 384592
         hr = StringCchPrintfA(
Packit Service 384592
                    szLength, 
Packit Service 384592
                    sizeof(szLength) / sizeof(CHAR) - 1, "%d", 
Packit Service 384592
                    ulTotalLength);
Packit Service 384592
Packit Service 384592
        if(FAILED(hr))
Packit Service 384592
        {
Packit Service 384592
            goto Finished;      
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
         hr = pHttpContext->GetResponse()->SetHeader(
Packit Service 384592
                    HttpHeaderContentLength, 
Packit Service 384592
                    szLength, 
Packit Service 384592
                    (USHORT)strlen(szLength),
Packit Service 384592
                    TRUE);
Packit Service 384592
Packit Service 384592
        if(FAILED(hr))
Packit Service 384592
        {
Packit Service 384592
            goto Finished;      
Packit Service 384592
        }
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
Finished:
Packit Service 384592
Packit Service 384592
	int status = modsecProcessResponse(rsc->m_pRequestRec);
Packit Service 384592
Packit Service 384592
	// the logic here is temporary, needs clarification
Packit Service 384592
	//
Packit Service 384592
	if(status != 0 && status != -1)
Packit Service 384592
	{
Packit Service 384592
		pHttpContext->GetResponse()->Clear();
Packit Service 384592
		pHttpContext->GetResponse()->SetStatus(status, "ModSecurity Action");
Packit Service 384592
		pHttpContext->SetRequestHandled();
Packit Service 384592
Packit Service 384592
		rsc->FinishRequest();
Packit Service 384592
Packit Service 384592
		LeaveCriticalSection(&m_csLock);
Packit Service 384592
		
Packit Service 384592
		return RQ_NOTIFICATION_FINISH_REQUEST;
Packit Service 384592
	}
Packit Service 384592
Exit:
Packit Service 384592
	// temporary hack, in reality OnSendRequest theoretically could possibly come before OnEndRequest
Packit Service 384592
	//
Packit Service 384592
	if(rsc != NULL)
Packit Service 384592
		rsc->FinishRequest();
Packit Service 384592
Packit Service 384592
	LeaveCriticalSection(&m_csLock);
Packit Service 384592
		
Packit Service 384592
	return RQ_NOTIFICATION_CONTINUE;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
REQUEST_NOTIFICATION_STATUS
Packit Service 384592
CMyHttpModule::OnPostEndRequest(
Packit Service 384592
    IN IHttpContext * pHttpContext,
Packit Service 384592
    IN IHttpEventProvider * pProvider
Packit Service 384592
)
Packit Service 384592
{
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = NULL;
Packit Service 384592
Packit Service 384592
	rsc = (REQUEST_STORED_CONTEXT *)pHttpContext->GetModuleContextContainer()->GetModuleContext(g_pModuleContext);
Packit Service 384592
Packit Service 384592
	// only finish request if OnSendResponse have been called already
Packit Service 384592
	//
Packit Service 384592
	if(rsc != NULL && rsc->m_pResponseBuffer != NULL)
Packit Service 384592
	{
Packit Service 384592
		EnterCriticalSection(&m_csLock);
Packit Service 384592
Packit Service 384592
		rsc->FinishRequest();
Packit Service 384592
Packit Service 384592
		LeaveCriticalSection(&m_csLock);
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	return RQ_NOTIFICATION_CONTINUE;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
REQUEST_NOTIFICATION_STATUS
Packit Service 384592
CMyHttpModule::OnBeginRequest(
Packit Service 384592
    IN IHttpContext * pHttpContext,
Packit Service 384592
    IN IHttpEventProvider * pProvider
Packit Service 384592
)
Packit Service 384592
{
Packit Service 384592
    HRESULT                         hr                  = S_OK;
Packit Service 384592
    IHttpRequest*                   pRequest            = NULL;
Packit Service 384592
	MODSECURITY_STORED_CONTEXT*		pConfig = NULL;
Packit Service 384592
    
Packit Service 384592
    UNREFERENCED_PARAMETER ( pProvider );
Packit Service 384592
Packit Service 384592
	EnterCriticalSection(&m_csLock);
Packit Service 384592
Packit Service 384592
    if ( pHttpContext == NULL ) 
Packit Service 384592
    {
Packit Service 384592
        hr = E_UNEXPECTED;
Packit Service 384592
        goto Finished;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    pRequest = pHttpContext->GetRequest();
Packit Service 384592
Packit Service 384592
    if ( pRequest == NULL )
Packit Service 384592
    {
Packit Service 384592
        hr = E_UNEXPECTED;
Packit Service 384592
        goto Finished;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    hr = MODSECURITY_STORED_CONTEXT::GetConfig(pHttpContext, &pConfig );
Packit Service 384592
    
Packit Service 384592
    if ( FAILED( hr ) )
Packit Service 384592
    {
Packit Service 384592
        //hr = E_UNEXPECTED;
Packit Service 384592
		hr = S_OK;
Packit Service 384592
        goto Finished;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	// If module is disabled, dont go any further
Packit Service 384592
	//
Packit Service 384592
	if( pConfig->GetIsEnabled() == false )
Packit Service 384592
	{
Packit Service 384592
        goto Finished;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	// every 3 seconds we check for changes in config file
Packit Service 384592
	//
Packit Service 384592
	DWORD ctime = GetTickCount();
Packit Service 384592
Packit Service 384592
	if(pConfig->m_Config == NULL || (ctime - pConfig->m_dwLastCheck) > 3000)
Packit Service 384592
	{
Packit Service 384592
		char *path;
Packit Service 384592
		USHORT pathlen;
Packit Service 384592
Packit Service 384592
		hr = pConfig->GlobalWideCharToMultiByte(pConfig->GetPath(), wcslen(pConfig->GetPath()), &path, &pathlen);
Packit Service 384592
Packit Service 384592
		if ( FAILED( hr ) )
Packit Service 384592
		{
Packit Service 384592
			hr = E_UNEXPECTED;
Packit Service 384592
			goto Finished;
Packit Service 384592
		}
Packit Service 384592
Packit Service 384592
		WIN32_FILE_ATTRIBUTE_DATA fdata;
Packit Service 384592
		BOOL ret;
Packit Service 384592
Packit Service 384592
		ret = GetFileAttributesEx(path, GetFileExInfoStandard, &fdata);
Packit Service 384592
Packit Service 384592
		pConfig->m_dwLastCheck = ctime;
Packit Service 384592
Packit Service 384592
		if(pConfig->m_Config == NULL || (ret != 0 && (pConfig->m_LastChange.dwLowDateTime != fdata.ftLastWriteTime.dwLowDateTime ||
Packit Service 384592
			pConfig->m_LastChange.dwHighDateTime != fdata.ftLastWriteTime.dwHighDateTime)))
Packit Service 384592
		{
Packit Service 384592
			pConfig->m_LastChange.dwLowDateTime = fdata.ftLastWriteTime.dwLowDateTime;
Packit Service 384592
			pConfig->m_LastChange.dwHighDateTime = fdata.ftLastWriteTime.dwHighDateTime;
Packit Service 384592
Packit Service 384592
			pConfig->m_Config = modsecGetDefaultConfig();
Packit Service 384592
Packit Service 384592
			PCWSTR servpath = pHttpContext->GetApplication()->GetApplicationPhysicalPath();
Packit Service 384592
			char *apppath;
Packit Service 384592
			USHORT apppathlen;
Packit Service 384592
Packit Service 384592
			hr = pConfig->GlobalWideCharToMultiByte((WCHAR *)servpath, wcslen(servpath), &apppath, &apppathlen);
Packit Service 384592
Packit Service 384592
			if ( FAILED( hr ) )
Packit Service 384592
			{
Packit Service 384592
				delete path;
Packit Service 384592
				hr = E_UNEXPECTED;
Packit Service 384592
				goto Finished;
Packit Service 384592
			}
Packit Service 384592
Packit Service 384592
			if(path[0] != 0)
Packit Service 384592
			{
Packit Service 384592
				const char * err = modsecProcessConfig((directory_config *)pConfig->m_Config, path, apppath);
Packit Service 384592
Packit Service 384592
				if(err != NULL)
Packit Service 384592
				{
Packit Service 384592
					WriteEventViewerLog(err, EVENTLOG_ERROR_TYPE);
Packit Service 384592
					delete apppath;
Packit Service 384592
					delete path;
Packit Service 384592
					goto Finished;
Packit Service 384592
				}
Packit Service 384592
Packit Service 384592
				modsecReportRemoteLoadedRules();
Packit Service 384592
				if (this->status_call_already_sent == false)
Packit Service 384592
				{
Packit Service 384592
					this->status_call_already_sent = true;
Packit Service 384592
					modsecStatusEngineCall();
Packit Service 384592
				}
Packit Service 384592
			}
Packit Service 384592
			delete apppath;
Packit Service 384592
		}
Packit Service 384592
		delete path;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	conn_rec *c;
Packit Service 384592
	request_rec *r;
Packit Service 384592
Packit Service 384592
	c = modsecNewConnection();
Packit Service 384592
Packit Service 384592
	modsecProcessConnection(c);
Packit Service 384592
Packit Service 384592
	r = modsecNewRequest(c, (directory_config *)pConfig->m_Config);
Packit Service 384592
Packit Service 384592
	// on IIS we force input stream inspection flag, because its absence does not add any performance gain
Packit Service 384592
	// it's because on IIS request body must be restored each time it was read
Packit Service 384592
	//
Packit Service 384592
	modsecSetConfigForIISRequestBody(r);
Packit Service 384592
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = new REQUEST_STORED_CONTEXT();
Packit Service 384592
Packit Service 384592
	rsc->m_pConnRec = c;
Packit Service 384592
	rsc->m_pRequestRec = r;
Packit Service 384592
	rsc->m_pHttpContext = pHttpContext;
Packit Service 384592
	rsc->m_pProvider = pProvider;
Packit Service 384592
Packit Service 384592
	pHttpContext->GetModuleContextContainer()->SetModuleContext(rsc, g_pModuleContext);
Packit Service 384592
Packit Service 384592
	StoreIISContext(r, rsc);
Packit Service 384592
Packit Service 384592
	HTTP_REQUEST *req = pRequest->GetRawHttpRequest();
Packit Service 384592
Packit Service 384592
	r->hostname = ConvertUTF16ToUTF8(req->CookedUrl.pHost, req->CookedUrl.HostLength / sizeof(WCHAR), r->pool);
Packit Service 384592
	r->path_info = ConvertUTF16ToUTF8(req->CookedUrl.pAbsPath, req->CookedUrl.AbsPathLength / sizeof(WCHAR), r->pool);
Packit Service 384592
Packit Service 384592
	if(r->hostname == NULL)
Packit Service 384592
	{
Packit Service 384592
		if(req->Headers.KnownHeaders[HttpHeaderHost].pRawValue != NULL)
Packit Service 384592
			r->hostname = ZeroTerminate(req->Headers.KnownHeaders[HttpHeaderHost].pRawValue,
Packit Service 384592
										req->Headers.KnownHeaders[HttpHeaderHost].RawValueLength, r->pool);
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	int port = 0;
Packit Service 384592
	char *port_str = NULL;
Packit Service 384592
Packit Service 384592
	if(r->hostname != NULL)
Packit Service 384592
	{
Packit Service 384592
		int k = 0;
Packit Service 384592
		char *ptr = (char *)r->hostname;
Packit Service 384592
Packit Service 384592
		while(*ptr != 0 && *ptr != ':')
Packit Service 384592
			ptr++;
Packit Service 384592
Packit Service 384592
		if(*ptr == ':')
Packit Service 384592
		{
Packit Service 384592
			*ptr = 0;
Packit Service 384592
			port_str = ptr + 1;
Packit Service 384592
			port = atoi(port_str);
Packit Service 384592
		}
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	if(req->CookedUrl.pQueryString != NULL && req->CookedUrl.QueryStringLength > 0)
Packit Service 384592
		r->args = ConvertUTF16ToUTF8(req->CookedUrl.pQueryString + 1, (req->CookedUrl.QueryStringLength / sizeof(WCHAR)) - 1, r->pool);
Packit Service 384592
Packit Service 384592
#define _TRANSHEADER(id,str) if(req->Headers.KnownHeaders[id].pRawValue != NULL) \
Packit Service 384592
	{\
Packit Service 384592
		apr_table_setn(r->headers_in, str, \
Packit Service 384592
			ZeroTerminate(req->Headers.KnownHeaders[id].pRawValue, req->Headers.KnownHeaders[id].RawValueLength, r->pool)); \
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
    _TRANSHEADER(HttpHeaderCacheControl, "Cache-Control");
Packit Service 384592
    _TRANSHEADER(HttpHeaderConnection, "Connection");
Packit Service 384592
    _TRANSHEADER(HttpHeaderDate, "Date");
Packit Service 384592
    _TRANSHEADER(HttpHeaderKeepAlive, "Keep-Alive");             
Packit Service 384592
    _TRANSHEADER(HttpHeaderPragma, "Pragma");                
Packit Service 384592
    _TRANSHEADER(HttpHeaderTrailer, "Trailer");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderTransferEncoding, "Transfer-Encoding");      
Packit Service 384592
    _TRANSHEADER(HttpHeaderUpgrade, "Upgrade");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderVia, "Via");                   
Packit Service 384592
    _TRANSHEADER(HttpHeaderWarning, "Warning");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderAllow, "Allow");                 
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentLength, "Content-Length");         
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentType, "Content-Type");           
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentEncoding, "Content-Encoding");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentLanguage, "Content-Language");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentLocation, "Content-Location");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentMd5, "Content-Md5");            
Packit Service 384592
    _TRANSHEADER(HttpHeaderContentRange, "Content-Range");          
Packit Service 384592
    _TRANSHEADER(HttpHeaderExpires, "Expires");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderLastModified, "Last-Modified");          
Packit Service 384592
    _TRANSHEADER(HttpHeaderAccept, "Accept");                
Packit Service 384592
    _TRANSHEADER(HttpHeaderAcceptCharset, "Accept-Charset");        
Packit Service 384592
    _TRANSHEADER(HttpHeaderAcceptEncoding, "Accept-Encoding");        
Packit Service 384592
    _TRANSHEADER(HttpHeaderAcceptLanguage, "Accept-Language");        
Packit Service 384592
    _TRANSHEADER(HttpHeaderAuthorization, "Authorization");         
Packit Service 384592
    _TRANSHEADER(HttpHeaderCookie, "Cookie");                
Packit Service 384592
    _TRANSHEADER(HttpHeaderExpect, "Expect");                
Packit Service 384592
    _TRANSHEADER(HttpHeaderFrom, "From");                  
Packit Service 384592
    _TRANSHEADER(HttpHeaderHost, "Host");                  
Packit Service 384592
    _TRANSHEADER(HttpHeaderIfMatch, "If-Match");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderIfModifiedSince, "If-Modified-Since");       
Packit Service 384592
    _TRANSHEADER(HttpHeaderIfNoneMatch, "If-None-Match");           
Packit Service 384592
    _TRANSHEADER(HttpHeaderIfRange, "If-Range");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderIfUnmodifiedSince, "If-Unmodified-Since");     
Packit Service 384592
    _TRANSHEADER(HttpHeaderMaxForwards, "Max-Forwards");           
Packit Service 384592
    _TRANSHEADER(HttpHeaderProxyAuthorization, "Proxy-Authorization");    
Packit Service 384592
    _TRANSHEADER(HttpHeaderReferer, "Referer");               
Packit Service 384592
    _TRANSHEADER(HttpHeaderRange, "Range");                 
Packit Service 384592
    _TRANSHEADER(HttpHeaderTe, "TE");                    
Packit Service 384592
    _TRANSHEADER(HttpHeaderTranslate, "Translate");             
Packit Service 384592
    _TRANSHEADER(HttpHeaderUserAgent, "User-Agent");
Packit Service 384592
Packit Service 384592
#undef _TRANSHEADER
Packit Service 384592
Packit Service 384592
	for(int i = 0; i < req->Headers.UnknownHeaderCount; i++)
Packit Service 384592
	{
Packit Service 384592
		apr_table_setn(r->headers_in, 
Packit Service 384592
			ZeroTerminate(req->Headers.pUnknownHeaders[i].pName, req->Headers.pUnknownHeaders[i].NameLength, r->pool), 
Packit Service 384592
			ZeroTerminate(req->Headers.pUnknownHeaders[i].pRawValue, req->Headers.pUnknownHeaders[i].RawValueLength, r->pool));
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	r->content_encoding = apr_table_get(r->headers_in, "Content-Encoding");
Packit Service 384592
	r->content_type = apr_table_get(r->headers_in, "Content-Type");
Packit Service 384592
Packit Service 384592
	const char *lng = apr_table_get(r->headers_in, "Content-Languages");
Packit Service 384592
Packit Service 384592
	if(lng != NULL)
Packit Service 384592
	{
Packit Service 384592
		r->content_languages = apr_array_make(r->pool, 1, sizeof(const char *));
Packit Service 384592
Packit Service 384592
		*(const char **)apr_array_push(r->content_languages) = lng;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	switch(req->Verb)
Packit Service 384592
	{
Packit Service 384592
	case HttpVerbUnparsed:
Packit Service 384592
	case HttpVerbUnknown:
Packit Service 384592
	case HttpVerbInvalid:
Packit Service 384592
    case HttpVerbTRACK:  // used by Microsoft Cluster Server for a non-logged trace
Packit Service 384592
    case HttpVerbSEARCH:
Packit Service 384592
	default:
Packit Service 384592
		r->method = "INVALID";
Packit Service 384592
		r->method_number = M_INVALID;
Packit Service 384592
		break;
Packit Service 384592
	case HttpVerbOPTIONS:
Packit Service 384592
		r->method = "OPTIONS";
Packit Service 384592
		r->method_number = M_OPTIONS;
Packit Service 384592
		break;
Packit Service 384592
	case HttpVerbGET:
Packit Service 384592
	case HttpVerbHEAD:
Packit Service 384592
		r->method = "GET";
Packit Service 384592
		r->method_number = M_GET;
Packit Service 384592
		break;
Packit Service 384592
	case HttpVerbPOST:
Packit Service 384592
		r->method = "POST";
Packit Service 384592
		r->method_number = M_POST;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbPUT:
Packit Service 384592
		r->method = "PUT";
Packit Service 384592
		r->method_number = M_PUT;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbDELETE:
Packit Service 384592
		r->method = "DELETE";
Packit Service 384592
		r->method_number = M_DELETE;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbTRACE:
Packit Service 384592
		r->method = "TRACE";
Packit Service 384592
		r->method_number = M_TRACE;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbCONNECT:
Packit Service 384592
		r->method = "CONNECT";
Packit Service 384592
		r->method_number = M_CONNECT;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbMOVE:
Packit Service 384592
		r->method = "MOVE";
Packit Service 384592
		r->method_number = M_MOVE;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbCOPY:
Packit Service 384592
		r->method = "COPY";
Packit Service 384592
		r->method_number = M_COPY;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbPROPFIND:
Packit Service 384592
		r->method = "PROPFIND";
Packit Service 384592
		r->method_number = M_PROPFIND;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbPROPPATCH:
Packit Service 384592
		r->method = "PROPPATCH";
Packit Service 384592
		r->method_number = M_PROPPATCH;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbMKCOL:
Packit Service 384592
		r->method = "MKCOL";
Packit Service 384592
		r->method_number = M_MKCOL;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbLOCK:
Packit Service 384592
		r->method = "LOCK";
Packit Service 384592
		r->method_number = M_LOCK;
Packit Service 384592
		break;
Packit Service 384592
    case HttpVerbUNLOCK:
Packit Service 384592
		r->method = "UNLOCK";
Packit Service 384592
		r->method_number = M_UNLOCK;
Packit Service 384592
		break;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	if(HTTP_EQUAL_VERSION(req->Version, 0, 9))
Packit Service 384592
		r->protocol = "HTTP/0.9";
Packit Service 384592
	else if(HTTP_EQUAL_VERSION(req->Version, 1, 0))
Packit Service 384592
		r->protocol = "HTTP/1.0";
Packit Service 384592
	else
Packit Service 384592
		r->protocol = "HTTP/1.1";
Packit Service 384592
Packit Service 384592
	r->request_time = apr_time_now();
Packit Service 384592
Packit Service 384592
	r->parsed_uri.scheme = "http";
Packit Service 384592
	r->parsed_uri.path = r->path_info;
Packit Service 384592
	r->parsed_uri.hostname = (char *)r->hostname;
Packit Service 384592
	r->parsed_uri.is_initialized = 1;
Packit Service 384592
	r->parsed_uri.port = port;
Packit Service 384592
	r->parsed_uri.port_str = port_str;
Packit Service 384592
	r->parsed_uri.query = r->args;
Packit Service 384592
	r->parsed_uri.dns_looked_up = 0;
Packit Service 384592
	r->parsed_uri.dns_resolved = 0;
Packit Service 384592
	r->parsed_uri.password = NULL;
Packit Service 384592
	r->parsed_uri.user = NULL;
Packit Service 384592
	r->parsed_uri.fragment = NULL;
Packit Service 384592
Packit Service 384592
	r->unparsed_uri = ZeroTerminate(req->pRawUrl, req->RawUrlLength, r->pool);
Packit Service 384592
	r->uri = r->unparsed_uri;
Packit Service 384592
Packit Service 384592
	r->the_request = (char *)apr_palloc(r->pool, strlen(r->method) + 1 + req->RawUrlLength + 1 + strlen(r->protocol) + 1);
Packit Service 384592
Packit Service 384592
	strcpy(r->the_request, r->method);
Packit Service 384592
	strcat(r->the_request, " ");
Packit Service 384592
	strcat(r->the_request, r->uri);
Packit Service 384592
	strcat(r->the_request, " ");
Packit Service 384592
	strcat(r->the_request, r->protocol);
Packit Service 384592
Packit Service 384592
	HTTP_REQUEST_ID httpRequestID;
Packit Service 384592
	char *pszValue = (char *)apr_palloc(r->pool, 24);
Packit Service 384592
Packit Service 384592
	httpRequestID = pRequest->GetRawHttpRequest()->RequestId;
Packit Service 384592
Packit Service 384592
	_ui64toa(httpRequestID, pszValue, 10);
Packit Service 384592
Packit Service 384592
	apr_table_setn(r->subprocess_env, "UNIQUE_ID", pszValue);
Packit Service 384592
Packit Service 384592
	PSOCKADDR pAddr = pRequest->GetRemoteAddress();
Packit Service 384592
Packit Service 384592
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER < 3
Packit Service 384592
    c->remote_addr = CopySockAddr(r->pool, pAddr);
Packit Service 384592
    c->remote_ip = GetIpAddr(r->pool, pAddr);
Packit Service 384592
#else
Packit Service 384592
    c->client_addr = CopySockAddr(r->pool, pAddr);
Packit Service 384592
	c->client_ip = GetIpAddr(r->pool, pAddr);
Packit Service 384592
#endif
Packit Service 384592
	c->remote_host = NULL;
Packit Service 384592
Packit Service 384592
	int status = modsecProcessRequest(r);
Packit Service 384592
Packit Service 384592
	if(status != DECLINED)
Packit Service 384592
	{
Packit Service 384592
		pHttpContext->GetResponse()->SetStatus(status, "ModSecurity Action");
Packit Service 384592
		pHttpContext->SetRequestHandled();
Packit Service 384592
Packit Service 384592
		hr = E_FAIL;
Packit Service 384592
		goto Finished;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
Finished:
Packit Service 384592
	LeaveCriticalSection(&m_csLock);
Packit Service 384592
Packit Service 384592
    if ( FAILED( hr )  )
Packit Service 384592
    {
Packit Service 384592
        return RQ_NOTIFICATION_FINISH_REQUEST;
Packit Service 384592
    }
Packit Service 384592
	return RQ_NOTIFICATION_CONTINUE;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
Packit Service 384592
{
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = RetrieveIISContext(r);
Packit Service 384592
Packit Service 384592
	*readcnt = 0;
Packit Service 384592
Packit Service 384592
	if(rsc == NULL)
Packit Service 384592
	{
Packit Service 384592
		*is_eos = 1;
Packit Service 384592
		return APR_SUCCESS;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	IHttpContext *pHttpContext = rsc->m_pHttpContext;
Packit Service 384592
	IHttpRequest *pRequest = pHttpContext->GetRequest();
Packit Service 384592
Packit Service 384592
	if(pRequest->GetRemainingEntityBytes() == 0)
Packit Service 384592
	{
Packit Service 384592
		*is_eos = 1;
Packit Service 384592
		return APR_SUCCESS;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	HRESULT hr = pRequest->ReadEntityBody(buf, length, false, (DWORD *)readcnt, NULL);
Packit Service 384592
Packit Service 384592
	if (FAILED(hr))
Packit Service 384592
    {
Packit Service 384592
        // End of data is okay.
Packit Service 384592
        if (ERROR_HANDLE_EOF != (hr  & 0x0000FFFF))
Packit Service 384592
        {
Packit Service 384592
            // Set the error status.
Packit Service 384592
            rsc->m_pProvider->SetErrorStatus( hr );
Packit Service 384592
        }
Packit Service 384592
Packit Service 384592
		*is_eos = 1;
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
apr_status_t WriteBodyCallback(request_rec *r, char *buf, unsigned int length)
Packit Service 384592
{
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = RetrieveIISContext(r);
Packit Service 384592
Packit Service 384592
	if(rsc == NULL || rsc->m_pRequestRec == NULL)
Packit Service 384592
		return APR_SUCCESS;
Packit Service 384592
Packit Service 384592
	IHttpContext *pHttpContext = rsc->m_pHttpContext;
Packit Service 384592
	IHttpRequest *pHttpRequest = pHttpContext->GetRequest();
Packit Service 384592
Packit Service 384592
    CHAR szLength[21]; //Max length for a 64 bit int is 20
Packit Service 384592
Packit Service 384592
    ZeroMemory(szLength, sizeof(szLength));
Packit Service 384592
Packit Service 384592
    HRESULT hr = StringCchPrintfA(
Packit Service 384592
            szLength, 
Packit Service 384592
            sizeof(szLength) / sizeof(CHAR) - 1, "%d", 
Packit Service 384592
            length);
Packit Service 384592
Packit Service 384592
    if(FAILED(hr))
Packit Service 384592
    {
Packit Service 384592
		// not possible
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    hr = pHttpRequest->SetHeader(
Packit Service 384592
            HttpHeaderContentLength, 
Packit Service 384592
            szLength, 
Packit Service 384592
            (USHORT)strlen(szLength),
Packit Service 384592
            TRUE);
Packit Service 384592
Packit Service 384592
    if(FAILED(hr))
Packit Service 384592
    {
Packit Service 384592
		// possible, but there's nothing we can do
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	// since we clean the APR pool at the end of OnSendRequest, we must get IIS-managed memory chunk
Packit Service 384592
	//
Packit Service 384592
	void *reqbuf = pHttpContext->AllocateRequestMemory(length);
Packit Service 384592
Packit Service 384592
	memcpy(reqbuf, buf, length);
Packit Service 384592
Packit Service 384592
	pHttpRequest->InsertEntityBody(reqbuf, length);
Packit Service 384592
Packit Service 384592
	return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
apr_status_t ReadResponseCallback(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
Packit Service 384592
{
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = RetrieveIISContext(r);
Packit Service 384592
Packit Service 384592
	*readcnt = 0;
Packit Service 384592
Packit Service 384592
	if(rsc == NULL || rsc->m_pResponseBuffer == NULL)
Packit Service 384592
	{
Packit Service 384592
		*is_eos = 1;
Packit Service 384592
		return APR_SUCCESS;
Packit Service 384592
	}
Packit Service 384592
Packit Service 384592
	unsigned int size = length;
Packit Service 384592
Packit Service 384592
	if(size > rsc->m_pResponseLength - rsc->m_pResponsePosition)
Packit Service 384592
		size = rsc->m_pResponseLength - rsc->m_pResponsePosition;
Packit Service 384592
Packit Service 384592
	memcpy(buf, rsc->m_pResponseBuffer + rsc->m_pResponsePosition, size);
Packit Service 384592
Packit Service 384592
	*readcnt = size;
Packit Service 384592
	rsc->m_pResponsePosition += size;
Packit Service 384592
Packit Service 384592
	if(rsc->m_pResponsePosition >= rsc->m_pResponseLength)
Packit Service 384592
		*is_eos = 1;
Packit Service 384592
Packit Service 384592
	return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
apr_status_t WriteResponseCallback(request_rec *r, char *buf, unsigned int length)
Packit Service 384592
{
Packit Service 384592
	REQUEST_STORED_CONTEXT *rsc = RetrieveIISContext(r);
Packit Service 384592
Packit Service 384592
	if(rsc == NULL || rsc->m_pRequestRec == NULL || rsc->m_pResponseBuffer == NULL)
Packit Service 384592
		return APR_SUCCESS;
Packit Service 384592
Packit Service 384592
	IHttpContext *pHttpContext = rsc->m_pHttpContext;
Packit Service 384592
	IHttpResponse *pHttpResponse = pHttpContext->GetResponse();
Packit Service 384592
	HTTP_RESPONSE *pRawHttpResponse = pHttpResponse->GetRawHttpResponse();
Packit Service 384592
	HTTP_DATA_CHUNK *pDataChunk = (HTTP_DATA_CHUNK *)apr_palloc(rsc->m_pRequestRec->pool, sizeof(HTTP_DATA_CHUNK));
Packit Service 384592
Packit Service 384592
	pRawHttpResponse->EntityChunkCount = 0;
Packit Service 384592
Packit Service 384592
	// since we clean the APR pool at the end of OnSendRequest, we must get IIS-managed memory chunk
Packit Service 384592
	//
Packit Service 384592
	void *reqbuf = pHttpContext->AllocateRequestMemory(length);
Packit Service 384592
Packit Service 384592
	memcpy(reqbuf, buf, length);
Packit Service 384592
Packit Service 384592
	pDataChunk->DataChunkType = HttpDataChunkFromMemory;
Packit Service 384592
	pDataChunk->FromMemory.pBuffer = reqbuf;
Packit Service 384592
	pDataChunk->FromMemory.BufferLength = length;
Packit Service 384592
Packit Service 384592
    CHAR szLength[21]; //Max length for a 64 bit int is 20
Packit Service 384592
Packit Service 384592
    ZeroMemory(szLength, sizeof(szLength));
Packit Service 384592
Packit Service 384592
    HRESULT hr = StringCchPrintfA(
Packit Service 384592
            szLength, 
Packit Service 384592
            sizeof(szLength) / sizeof(CHAR) - 1, "%d", 
Packit Service 384592
            length);
Packit Service 384592
Packit Service 384592
    if(FAILED(hr))
Packit Service 384592
    {
Packit Service 384592
		// not possible
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
    hr = pHttpResponse->SetHeader(
Packit Service 384592
            HttpHeaderContentLength, 
Packit Service 384592
            szLength, 
Packit Service 384592
            (USHORT)strlen(szLength),
Packit Service 384592
            TRUE);
Packit Service 384592
Packit Service 384592
    if(FAILED(hr))
Packit Service 384592
    {
Packit Service 384592
		// possible, but there's nothing we can do
Packit Service 384592
    }
Packit Service 384592
Packit Service 384592
	pHttpResponse->WriteEntityChunkByReference(pDataChunk);
Packit Service 384592
Packit Service 384592
	return APR_SUCCESS;
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
Packit Service 384592
CMyHttpModule::CMyHttpModule()
Packit Service 384592
{
Packit Service 384592
    // Open a handle to the Event Viewer.
Packit Service 384592
    m_hEventLog = RegisterEventSource( NULL, "ModSecurity" );
Packit Service 384592
Packit Service 384592
    SYSTEM_INFO         sysInfo;
Packit Service 384592
Packit Service 384592
    GetSystemInfo(&sysInfo);
Packit Service 384592
    m_dwPageSize = sysInfo.dwPageSize;
Packit Service 384592
Packit Service 384592
    this->status_call_already_sent = false;
Packit Service 384592
Packit Service 384592
	InitializeCriticalSection(&m_csLock);
Packit Service 384592
Packit Service 384592
	modsecSetLogHook(this, Log);
Packit Service 384592
Packit Service 384592
	modsecSetReadBody(ReadBodyCallback);
Packit Service 384592
	modsecSetReadResponse(ReadResponseCallback);
Packit Service 384592
	modsecSetWriteBody(WriteBodyCallback);
Packit Service 384592
	modsecSetWriteResponse(WriteResponseCallback);
Packit Service 384592
Packit Service 384592
	server_rec *s = modsecInit();
Packit Service 384592
	char *compname = (char *)malloc(128);
Packit Service 384592
	DWORD size = 128;
Packit Service 384592
Packit Service 384592
	GetComputerName(compname, &size);
Packit Service 384592
Packit Service 384592
	s->server_hostname = compname;
Packit Service 384592
Packit Service 384592
	modsecStartConfig();
Packit Service 384592
Packit Service 384592
	modsecFinalizeConfig();
Packit Service 384592
Packit Service 384592
	modsecInitProcess();
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
CMyHttpModule::~CMyHttpModule()
Packit Service 384592
{
Packit Service 384592
	// ModSecurity registers APR pool cleanups, which interfere with APR pool tear down process
Packit Service 384592
	// this causes crashes and since we are exiting the process here, so this is a temporary solution
Packit Service 384592
	//
Packit Service 384592
	//modsecTerminate();
Packit Service 384592
Packit Service 384592
	//WriteEventViewerLog("Module deleted.");
Packit Service 384592
Packit Service 384592
	// Test whether the handle for the Event Viewer is open.
Packit Service 384592
    if (NULL != m_hEventLog)
Packit Service 384592
    {
Packit Service 384592
        // Close the handle to the Event Viewer.
Packit Service 384592
        DeregisterEventSource( m_hEventLog );
Packit Service 384592
        m_hEventLog = NULL;
Packit Service 384592
Packit Service 384592
		DeleteCriticalSection(&m_csLock);
Packit Service 384592
    }
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
void CMyHttpModule::Dispose()
Packit Service 384592
{
Packit Service 384592
}
Packit Service 384592
Packit Service 384592
BOOL CMyHttpModule::WriteEventViewerLog(LPCSTR szNotification, WORD category)
Packit Service 384592
{
Packit Service 384592
    // Test whether the handle for the Event Viewer is open.
Packit Service 384592
    if (NULL != m_hEventLog)
Packit Service 384592
    {
Packit Service 384592
        // Write any strings to the Event Viewer and return.
Packit Service 384592
        return ReportEvent(
Packit Service 384592
            m_hEventLog,
Packit Service 384592
            category, 0, 0x1,
Packit Service 384592
            NULL, 1, 0, &szNotification, NULL );
Packit Service 384592
    }
Packit Service 384592
    return FALSE;
Packit Service 384592
}