windows-nt/Source/XPSP1/NT/inetsrv/iis/iisrearc/iisplus/ulatq/wpconfig.cxx
2020-09-26 16:20:57 +08:00

398 lines
11 KiB
C++

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name :
WpConfig.cxx
Abstract:
Module implementing the Worker Process Configuration Data structure.
WP_CONFIG object encapsulates configuration supplied from the commandline
as well as remotely supplied from the admin process.
Author:
Murali R. Krishnan ( MuraliK ) 21-Oct-1998
Environment:
Win32 - User Mode
Project:
IIS Worker Process
--*/
/************************************************************
* Include Headers
************************************************************/
#include "precomp.hxx"
/*
Usage: \bin\iisrearc\inetsrv\iiswp [options] APN
APN -- AppPool Name
-d <URL List> -- Indicates that the process should register the given
namespace itself. This mode is for running worker process in
stand alone mode (for debugging)
-l -- Log errors that stop the worker process into the eventlog
-ld -- Disables logging the errors of worker process to eventlog
(default is not write to eventlog)
-a -- Look for web admin service and register with the same
(default is look for web admin service)
-ad -- Do not look for web admin service and do registration
-r <n> -- Restart the worker process after n requests.
-t <n> -- Shutdown the worker process if idle for n milliseconds.
<URL List> uses the syntax: {http[s]://IP:port/URL | http[s]://hostname:port/URL }+
with space as separator
eg: -d http://localhost:80/ => listen for all HTTP requests on port 80
eg: -d http://localhost:80/ http://localhost:81/ => listen on port 80 & 81
*/
const CHAR g_rgchUsage[] =
"Usage: %ws [options] APN\n"
"\tAPN -- AppPool Name\n"
"\t-d <URL List> -- Indicates that the process should register the given \n"
"\t\tnamespace itself. This mode is for running worker process in\n"
"\t\tstand alone mode (for debugging)\n"
"\t-l -- Log errors that stop the worker process into the eventlog\n"
"\t-ld -- Disables logging the errors of worker process to eventlog\n"
"\t\t(default is not write to eventlog)\n"
"\t-a -- Look for web admin service and register with the same\n"
"\t\t(default is look for web admin service)\n"
"\t-ad -- Do not look for web admin service and do registration\n"
"\t-r <n> -- Restart the worker process after n requests\n"
"\t-t <n> -- Shutdown the worker process if idle for n milliseconds\n"
"\t-p -- Tell COR to add IceCAP instrumentation\n"
"\t<URL List> uses the syntax: {http[s]://IP:port/URL | http[s]://hostname:port/URL }+\n"
"\t\twith space as separator\n"
"\t\t eg: -d http://*:80/ => listen for all HTTP requests on port 80\n"
"\t\t eg: -d http://localhost:80/ http://localhost:81/ => listen on port 80 & 81\n"
;
/************************************************************
* Member functions of WP_CONFIG
************************************************************/
WP_CONFIG::WP_CONFIG(void)
: _pwszAppPoolName (AP_NAME),
_fSetupControlChannel(false),
_fLogErrorsToEventLog(false),
_fRegisterWithWAS (true),
_RestartCount (0),
_NamedPipeId (0),
_IdleTime (0)
{
lstrcpy( _pwszProgram, L"WP");
}
WP_CONFIG::~WP_CONFIG()
{
_ulcc.Cleanup();
}
void
WP_CONFIG::PrintUsage() const
{
DBGPRINTF((DBG_CONTEXT, g_rgchUsage, _pwszProgram));
}
/********************************************************************++
Routine Description:
Parses the command line to read in all configuration supplied.
This function updates the state variables inside WP_CONFIG for use
in starting up the Worker process.
See g_rgchUsage[] for details on the arguments that can be supplied
Arguments:
argc - count of arguments supplied
argv - pointer to strings containing the arguments.
Returns:
Boolean
--********************************************************************/
BOOL
WP_CONFIG::ParseCommandLine(int argc, PWSTR argv[])
{
BOOL fRet = true;
int iArg;
lstrcpyn( _pwszProgram, argv[0], sizeof _pwszProgram / sizeof _pwszProgram[0]);
if ( argc < 2)
{
DBGPRINTF((DBG_CONTEXT, "Invalid number of parameters (%d)\n", argc));
PrintUsage();
return (false);
}
for( iArg = 1; iArg < argc; iArg++)
{
if ( (argv[iArg][0] == L'-') || (argv[iArg][0] == L'/'))
{
switch (argv[iArg][1])
{
case L'c': case L'C':
DBGPRINTF((DBG_CONTEXT, "-C: obsolete\n"));
break;
case L'd': case L'D':
_fSetupControlChannel = true;
iArg++;
while ( (iArg < argc-1) &&
(argv[iArg][0] != L'-') && (argv[iArg][0] != L'/'))
{
if ( !InsertURLIntoList(argv[iArg]) )
{
DBGPRINTF((DBG_CONTEXT, "Invalid URL: %ws\n", argv[iArg]));
}
iArg++;
}
iArg--;
break;
case L'a': case L'A':
if ( (L'd' == argv[iArg][2]) || (L'D' == argv[iArg][2]))
{
_fRegisterWithWAS = false;
}
else
{
// -a NamedPipeId
if (L'\0' == argv[iArg][2])
{
iArg++;
}
_NamedPipeId = wcstoul(argv[iArg], NULL, 0);
DBGPRINTF((DBG_CONTEXT, "NamedPipe Id, %lu\n", _NamedPipeId));
if (0 == _NamedPipeId)
{
DBGPRINTF((DBG_CONTEXT, "Invalid NamedPipe Id, %ws\n",
argv[iArg]));
fRet = false;
}
}
break;
case L'l': case L'L':
DBGPRINTF((DBG_CONTEXT, "Warning: This option is not supported presently\n"));
if (L' ' == argv[iArg][0])
{
_fLogErrorsToEventLog = true;
}
break;
case L'r': case L'R':
_RestartCount = wcstoul(argv[++iArg], NULL, 0);
if (_RestartCount == 0)
{
DBGPRINTF((DBG_CONTEXT, "Invalid maximum requests %ws\n", argv[iArg]));
return false;
}
else
{
DBGPRINTF((DBG_CONTEXT, "Maximum requests is %lu\n", _RestartCount));
}
break;
case L't': case L'T':
_IdleTime = wcstoul(argv[++iArg], NULL, 0);
if (_IdleTime == 0)
{
DBGPRINTF((DBG_CONTEXT, "Invalid idle time %ws\n", argv[iArg]));
return false;
}
else
{
DBGPRINTF((DBG_CONTEXT, "The idle time value is %lu\n", _IdleTime));
}
break;
case L'p': case L'P':
SetEnvironmentVariable(L"CORDBG_ENABLE", L"0x20");
SetEnvironmentVariable(L"COR_PROFILER", L"\"ComPlusIcecapProfile.CorIcecapProfiler\"");
SetEnvironmentVariable(L"PROF_CONFIG", L"/callcap");
break;
default:
case L'?':
fRet = false;
break;
} // switch
}
else
{
//
// Take the next item as the NSG name and bail out here
//
_pwszAppPoolName = argv[iArg];
if ( iArg != (argc - 1))
{
//
// this is not the last argument => unwanted parameters exist
// give warning and ignore
//
DBGPRINTF((DBG_CONTEXT, "Warning: Too many arguments supplied\n"));
}
break; // get out of here.
}
}
if (!_fRegisterWithWAS)
{
_RestartCount = 0;
_IdleTime = 0;
}
if (!fRet)
{
PrintUsage();
}
return ( fRet);
} // WP_CONFIG::ParseCommandLine()
/********************************************************************++
Routine Description:
Sets up the control channel for processing requests. It uses
the configuration parameters supplied for initializing the
UL_CONTROL_CHANNEL.
See g_rgchUsage[] for details on the arguments that can be supplied
Arguments:
Returns:
Win32 error
--********************************************************************/
ULONG
WP_CONFIG::SetupControlChannel(void)
{
//
// Setup a control channel for our local use now. Used mainly for
// the purpose of debugging.
// In general control channel work is done by the AdminProces.
//
return _ulcc.Initialize( _mszURLList, _pwszAppPoolName);
} // WP_CONFIG::SetupControlChannel()
/********************************************************************++
--********************************************************************/
WP_CONFIG::InsertURLIntoList( LPCWSTR pwszURL )
{
LPCWSTR pwszOriginalURL = pwszURL;
//
// Minimum length: 11 (http://*:1/). Begins with http
//
if ( ( wcslen(pwszURL) < 11 ) || ( 0 != _wcsnicmp(pwszURL, L"http", 4)) )
{
return false;
}
pwszURL += 4;
//
// https
//
if ((L's' == *pwszURL) || (L'S' == *pwszURL))
{
pwszURL++;
}
//
// ://
//
if ( (L':' != *pwszURL) || (L'/' != *(pwszURL+1)) || (L'/' != *(pwszURL+2)) )
{
return false;
}
pwszURL += 3;
//
// Skip host name or Ip Address
//
while ( (0 != *pwszURL) && ( L':' != *pwszURL))
{
pwszURL++;
}
//
// Check port # exists
//
if (0 == *pwszURL)
{
return false;
}
//
// Check port number is numeric
//
pwszURL++;
while ( (0 != *pwszURL) && ( L'/' != *pwszURL) )
{
if (( L'0' > *pwszURL) || ( L'9' < *pwszURL))
{
return false;
}
pwszURL++;
}
//
// Check / after port number exists
//
if (0 == *pwszURL)
{
return false;
}
//
// URL is good.
//
IF_DEBUG( TRACE)
{
DBGPRINTF(( DBG_CONTEXT,
"Inserting URL '%ws' into Config Group List\n",
pwszOriginalURL
));
}
return ( TRUE == _mszURLList.Append( pwszOriginalURL));
} // WP_CONFIG::InsertURLIntoList()