2025-04-27 07:49:33 -04:00

388 lines
8.7 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
tfilt.c
Abstract:
Stupid filter test server for UL.SYS.
This program configures a global filter called TestFilter
and then servs requests like tfile. See tupfilt and tsslfilt
for actual filter processes.
Author:
Michael Courage (mcourage) 16-Mar-2000
Revision History:
--*/
#include "precomp.h"
DEFINE_COMMON_GLOBALS();
ULONG
InitFilterStuff(
IN HANDLE ControlChannel,
OUT PHANDLE pFitlerHandle
);
INT
__cdecl
wmain(
INT argc,
PWSTR argv[]
)
{
ULONG result;
HANDLE controlChannel;
HANDLE appPool;
HANDLE filterChannel;
HTTP_CONFIG_GROUP_ID configId;
HTTP_CONFIG_GROUP_APP_POOL configAppPool;
HTTP_CONFIG_GROUP_STATE configState;
HTTP_ENABLED_STATE controlState;
HTTP_REQUEST_ID requestId;
DWORD bytesRead;
DWORD bytesSent;
PHTTP_REQUEST request;
HTTP_RESPONSE response;
HTTP_DATA_CHUNK dataChunk;
PWSTR fileNamePart;
ULONG i;
ULONG urlLength;
PWSTR url;
PWSTR tmp;
BOOL initDone;
HTTP_REQUEST_ALIGNMENT UCHAR requestBuffer[REQUEST_LENGTH];
WCHAR fileName[MAX_PATH + 10];
//
// Initialize.
//
result = CommonInit();
if (result != NO_ERROR)
{
wprintf( L"CommonInit() failed, error %lu\n", result );
return 1;
}
if (!ParseCommandLine( argc, argv ))
{
return 1;
}
//
// Setup locals so we know how to cleanup on exit.
//
initDone = FALSE;
controlChannel = NULL;
appPool = NULL;
filterChannel = NULL;
HTTP_SET_NULL_ID( &configId );
//
// Get UL started.
//
result = InitUlStuff(
&controlChannel,
&appPool,
&filterChannel, // FilterChannel
&configId,
TRUE, // AllowSystem
TRUE, // AllowAdmin
FALSE, // AllowCurrentUser
FALSE, // AllowWorld
0,
TRUE, // EnableSsl
TRUE // EnableRawFilters
);
if (result != NO_ERROR)
{
wprintf( L"InitUlStuff() failed, error %lu\n", result );
goto cleanup;
}
/*
result = InitFilterStuff(
controlChannel,
&filterChannel
);
if (result != NO_ERROR)
{
wprintf( L"InitFilterStuff() failed, error %lu\n", result );
goto cleanup;
}
*/
initDone = TRUE;
//
// Get the local directory and build part of the fully canonicalized
// NT path. This makes it a bit faster to build the physical file name
// down in the request/response loop.
//
GetCurrentDirectoryW( MAX_PATH, fileName );
if (fileName[wcslen(fileName) - 1] == L'\\' )
{
fileName[wcslen(fileName) - 1] = L'\0';
}
fileNamePart = fileName + wcslen(fileName);
//
// Build the fixed part of our response.
//
INIT_RESPONSE( &response, 200, "OK" );
//
// Loop forever...
//
request = (PHTTP_REQUEST)requestBuffer;
HTTP_SET_NULL_ID( &requestId );
for( ; ; )
{
//
// Wait for a request.
//
//DEBUG_BREAK();
result = HttpReceiveHttpRequest(
appPool,
requestId,
0,
(PHTTP_REQUEST)requestBuffer,
sizeof(requestBuffer),
&bytesRead,
NULL
);
if (result != NO_ERROR)
{
wprintf( L"HttpReceiveHttpRequest() failed, error %lu\n", result );
break;
}
//
// Dump it.
//
if (TEST_OPTION(Verbose))
{
DumpHttpRequest( request );
}
//
// Build the response.
//
url = request->CookedUrl.pFullUrl;
urlLength = request->CookedUrl.FullUrlLength;
//
// Hack: Find the port number, then skip to the following slash.
//
tmp = wcschr( url, L':' );
if (tmp != NULL)
{
tmp = wcschr( tmp, L'/' );
}
if (tmp != NULL)
{
tmp = wcschr( tmp, L':' );
}
if (tmp != NULL)
{
tmp = wcschr( tmp, L'/' );
}
if (tmp != NULL)
{
urlLength -= (ULONG)( (tmp - url) * sizeof(WCHAR) );
url = tmp;
}
//
// Map it into the filename.
//
for (i = 0 ; i < (urlLength/sizeof(WCHAR)) ; url++, i++)
{
if (*url == L'/')
{
fileNamePart[i] = L'\\';
}
else
{
fileNamePart[i] = *url;
}
}
fileNamePart[i] = L'\0';
if (wcscmp( fileNamePart, L"\\" ) == 0 )
{
wcscat( fileNamePart, L"default.htm" );
}
if (TEST_OPTION(Verbose))
{
wprintf(
L"mapped URL %s to physical file %s\n",
request->CookedUrl.pFullUrl,
fileName
);
}
dataChunk.DataChunkType = HttpDataChunkFromFileName;
dataChunk.FromFileName.FileNameLength = wcslen(fileName) * sizeof(WCHAR);
dataChunk.FromFileName.pFileName = fileName;
dataChunk.FromFileName.ByteRange.StartingOffset.QuadPart = 0;
dataChunk.FromFileName.ByteRange.Length.QuadPart = HTTP_BYTE_RANGE_TO_EOF;
//
// Send the canned response.
//
DEBUG_BREAK();
response.EntityChunkCount = 1;
response.pEntityChunks = &dataChunk;
result = HttpSendHttpResponse(
appPool,
request->RequestId,
0,
&response,
NULL,
&bytesSent,
NULL,
NULL
);
if ((result != NO_ERROR) && (result != ERROR_NETNAME_DELETED))
{
wprintf( L"HttpSendHttpResponse() failed, error %lu\n", result );
break;
}
}
cleanup:
if (!HTTP_IS_NULL_ID( &configId ))
{
result = HttpDeleteConfigGroup(
controlChannel,
configId
);
if (result != NO_ERROR)
{
wprintf( L"HttpDeleteConfigGroup() failed, error %lu\n", result );
}
}
if (filterChannel != NULL)
{
CloseHandle( filterChannel );
}
if (appPool != NULL)
{
CloseHandle( appPool );
}
if (controlChannel != NULL)
{
CloseHandle( controlChannel );
}
if (initDone)
{
HttpTerminate();
}
return 0;
} // wmain
ULONG
InitFilterStuff(
IN HANDLE ControlChannel,
OUT PHANDLE pFilterHandle
)
{
HANDLE filterHandle;
ULONG result;
HTTP_CONTROL_CHANNEL_FILTER controlFilter;
//
// Create the filter.
//
result = HttpCreateFilter(
&filterHandle, // filter handle
L"TestFilter", // filter name
NULL, // security attributes
HTTP_OPTION_OVERLAPPED // options
);
if (result == NO_ERROR)
{
//
// Attach the filter to the control channel.
//
RtlZeroMemory(&controlFilter, sizeof(controlFilter));
controlFilter.Flags.Present = 1;
controlFilter.FilterHandle = filterHandle;
controlFilter.FilterOnlySsl = FALSE;
result = HttpSetControlChannelInformation(
ControlChannel,
HttpControlChannelFilterInformation,
&controlFilter,
sizeof(controlFilter)
);
if (result == NO_ERROR)
{
//
// Return the filter handle.
//
*pFilterHandle = filterHandle;
}
else
{
CloseHandle(filterHandle);
}
}
return result;
}