Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name :
  4. WpConfig.cxx
  5. Abstract:
  6. Module implementing the Worker Process Configuration Data structure.
  7. WP_CONFIG object encapsulates configuration supplied from the commandline
  8. as well as remotely supplied from the admin process.
  9. Author:
  10. Murali R. Krishnan ( MuraliK ) 21-Oct-1998
  11. Environment:
  12. Win32 - User Mode
  13. Project:
  14. IIS Worker Process
  15. --*/
  16. /************************************************************
  17. * Include Headers
  18. ************************************************************/
  19. #include "precomp.hxx"
  20. /*
  21. Usage: \bin\iisrearc\inetsrv\iiswp [options] APN
  22. APN -- AppPool Name
  23. -d <URL List> -- Indicates that the process should register the given
  24. namespace itself. This mode is for running worker process in
  25. stand alone mode (for debugging)
  26. -l -- Log errors that stop the worker process into the eventlog
  27. -ld -- Disables logging the errors of worker process to eventlog
  28. (default is not write to eventlog)
  29. -a -- Look for web admin service and register with the same
  30. (default is look for web admin service)
  31. -ad -- Do not look for web admin service and do registration
  32. -r <n> -- Restart the worker process after n requests.
  33. -t <n> -- Shutdown the worker process if idle for n milliseconds.
  34. <URL List> uses the syntax: {http[s]://IP:port/URL | http[s]://hostname:port/URL }+
  35. with space as separator
  36. eg: -d http://localhost:80/ => listen for all HTTP requests on port 80
  37. eg: -d http://localhost:80/ http://localhost:81/ => listen on port 80 & 81
  38. */
  39. const CHAR g_rgchUsage[] =
  40. "Usage: %ws [options] APN\n"
  41. "\tAPN -- AppPool Name\n"
  42. "\t-d <URL List> -- Indicates that the process should register the given \n"
  43. "\t\tnamespace itself. This mode is for running worker process in\n"
  44. "\t\tstand alone mode (for debugging)\n"
  45. "\t-l -- Log errors that stop the worker process into the eventlog\n"
  46. "\t-ld -- Disables logging the errors of worker process to eventlog\n"
  47. "\t\t(default is not write to eventlog)\n"
  48. "\t-a -- Look for web admin service and register with the same\n"
  49. "\t\t(default is look for web admin service)\n"
  50. "\t-ad -- Do not look for web admin service and do registration\n"
  51. "\t-r <n> -- Restart the worker process after n requests\n"
  52. "\t-t <n> -- Shutdown the worker process if idle for n milliseconds\n"
  53. "\t-p -- Tell COR to add IceCAP instrumentation\n"
  54. "\t<URL List> uses the syntax: {http[s]://IP:port/URL | http[s]://hostname:port/URL }+\n"
  55. "\t\twith space as separator\n"
  56. "\t\t eg: -d http://*:80/ => listen for all HTTP requests on port 80\n"
  57. "\t\t eg: -d http://localhost:80/ http://localhost:81/ => listen on port 80 & 81\n"
  58. ;
  59. /************************************************************
  60. * Member functions of WP_CONFIG
  61. ************************************************************/
  62. WP_CONFIG::WP_CONFIG(void)
  63. : _pwszAppPoolName (AP_NAME),
  64. _fSetupControlChannel(false),
  65. _fLogErrorsToEventLog(false),
  66. _fRegisterWithWAS (true),
  67. _RestartCount (0),
  68. _NamedPipeId (0),
  69. _IdleTime (0)
  70. {
  71. lstrcpy( _pwszProgram, L"WP");
  72. }
  73. WP_CONFIG::~WP_CONFIG()
  74. {
  75. _ulcc.Cleanup();
  76. }
  77. void
  78. WP_CONFIG::PrintUsage() const
  79. {
  80. DBGPRINTF((DBG_CONTEXT, g_rgchUsage, _pwszProgram));
  81. }
  82. /********************************************************************++
  83. Routine Description:
  84. Parses the command line to read in all configuration supplied.
  85. This function updates the state variables inside WP_CONFIG for use
  86. in starting up the Worker process.
  87. See g_rgchUsage[] for details on the arguments that can be supplied
  88. Arguments:
  89. argc - count of arguments supplied
  90. argv - pointer to strings containing the arguments.
  91. Returns:
  92. Boolean
  93. --********************************************************************/
  94. BOOL
  95. WP_CONFIG::ParseCommandLine(int argc, PWSTR argv[])
  96. {
  97. BOOL fRet = true;
  98. int iArg;
  99. lstrcpyn( _pwszProgram, argv[0], sizeof _pwszProgram / sizeof _pwszProgram[0]);
  100. if ( argc < 2)
  101. {
  102. DBGPRINTF((DBG_CONTEXT, "Invalid number of parameters (%d)\n", argc));
  103. PrintUsage();
  104. return (false);
  105. }
  106. for( iArg = 1; iArg < argc; iArg++)
  107. {
  108. if ( (argv[iArg][0] == L'-') || (argv[iArg][0] == L'/'))
  109. {
  110. switch (argv[iArg][1])
  111. {
  112. case L'c': case L'C':
  113. DBGPRINTF((DBG_CONTEXT, "-C: obsolete\n"));
  114. break;
  115. case L'd': case L'D':
  116. _fSetupControlChannel = true;
  117. iArg++;
  118. while ( (iArg < argc-1) &&
  119. (argv[iArg][0] != L'-') && (argv[iArg][0] != L'/'))
  120. {
  121. if ( !InsertURLIntoList(argv[iArg]) )
  122. {
  123. DBGPRINTF((DBG_CONTEXT, "Invalid URL: %ws\n", argv[iArg]));
  124. }
  125. iArg++;
  126. }
  127. iArg--;
  128. break;
  129. case L'a': case L'A':
  130. if ( (L'd' == argv[iArg][2]) || (L'D' == argv[iArg][2]))
  131. {
  132. _fRegisterWithWAS = false;
  133. }
  134. else
  135. {
  136. // -a NamedPipeId
  137. if (L'\0' == argv[iArg][2])
  138. {
  139. iArg++;
  140. }
  141. _NamedPipeId = wcstoul(argv[iArg], NULL, 0);
  142. DBGPRINTF((DBG_CONTEXT, "NamedPipe Id, %lu\n", _NamedPipeId));
  143. if (0 == _NamedPipeId)
  144. {
  145. DBGPRINTF((DBG_CONTEXT, "Invalid NamedPipe Id, %ws\n",
  146. argv[iArg]));
  147. fRet = false;
  148. }
  149. }
  150. break;
  151. case L'l': case L'L':
  152. DBGPRINTF((DBG_CONTEXT, "Warning: This option is not supported presently\n"));
  153. if (L' ' == argv[iArg][0])
  154. {
  155. _fLogErrorsToEventLog = true;
  156. }
  157. break;
  158. case L'r': case L'R':
  159. _RestartCount = wcstoul(argv[++iArg], NULL, 0);
  160. if (_RestartCount == 0)
  161. {
  162. DBGPRINTF((DBG_CONTEXT, "Invalid maximum requests %ws\n", argv[iArg]));
  163. return false;
  164. }
  165. else
  166. {
  167. DBGPRINTF((DBG_CONTEXT, "Maximum requests is %lu\n", _RestartCount));
  168. }
  169. break;
  170. case L't': case L'T':
  171. _IdleTime = wcstoul(argv[++iArg], NULL, 0);
  172. if (_IdleTime == 0)
  173. {
  174. DBGPRINTF((DBG_CONTEXT, "Invalid idle time %ws\n", argv[iArg]));
  175. return false;
  176. }
  177. else
  178. {
  179. DBGPRINTF((DBG_CONTEXT, "The idle time value is %lu\n", _IdleTime));
  180. }
  181. break;
  182. case L'p': case L'P':
  183. SetEnvironmentVariable(L"CORDBG_ENABLE", L"0x20");
  184. SetEnvironmentVariable(L"COR_PROFILER", L"\"ComPlusIcecapProfile.CorIcecapProfiler\"");
  185. SetEnvironmentVariable(L"PROF_CONFIG", L"/callcap");
  186. break;
  187. default:
  188. case L'?':
  189. fRet = false;
  190. break;
  191. } // switch
  192. }
  193. else
  194. {
  195. //
  196. // Take the next item as the NSG name and bail out here
  197. //
  198. _pwszAppPoolName = argv[iArg];
  199. if ( iArg != (argc - 1))
  200. {
  201. //
  202. // this is not the last argument => unwanted parameters exist
  203. // give warning and ignore
  204. //
  205. DBGPRINTF((DBG_CONTEXT, "Warning: Too many arguments supplied\n"));
  206. }
  207. break; // get out of here.
  208. }
  209. }
  210. if (!_fRegisterWithWAS)
  211. {
  212. _RestartCount = 0;
  213. _IdleTime = 0;
  214. }
  215. if (!fRet)
  216. {
  217. PrintUsage();
  218. }
  219. return ( fRet);
  220. } // WP_CONFIG::ParseCommandLine()
  221. /********************************************************************++
  222. Routine Description:
  223. Sets up the control channel for processing requests. It uses
  224. the configuration parameters supplied for initializing the
  225. UL_CONTROL_CHANNEL.
  226. See g_rgchUsage[] for details on the arguments that can be supplied
  227. Arguments:
  228. Returns:
  229. Win32 error
  230. --********************************************************************/
  231. ULONG
  232. WP_CONFIG::SetupControlChannel(void)
  233. {
  234. //
  235. // Setup a control channel for our local use now. Used mainly for
  236. // the purpose of debugging.
  237. // In general control channel work is done by the AdminProces.
  238. //
  239. return _ulcc.Initialize( _mszURLList, _pwszAppPoolName);
  240. } // WP_CONFIG::SetupControlChannel()
  241. /********************************************************************++
  242. --********************************************************************/
  243. WP_CONFIG::InsertURLIntoList( LPCWSTR pwszURL )
  244. {
  245. LPCWSTR pwszOriginalURL = pwszURL;
  246. //
  247. // Minimum length: 11 (http://*:1/). Begins with http
  248. //
  249. if ( ( wcslen(pwszURL) < 11 ) || ( 0 != _wcsnicmp(pwszURL, L"http", 4)) )
  250. {
  251. return false;
  252. }
  253. pwszURL += 4;
  254. //
  255. // https
  256. //
  257. if ((L's' == *pwszURL) || (L'S' == *pwszURL))
  258. {
  259. pwszURL++;
  260. }
  261. //
  262. // ://
  263. //
  264. if ( (L':' != *pwszURL) || (L'/' != *(pwszURL+1)) || (L'/' != *(pwszURL+2)) )
  265. {
  266. return false;
  267. }
  268. pwszURL += 3;
  269. //
  270. // Skip host name or Ip Address
  271. //
  272. while ( (0 != *pwszURL) && ( L':' != *pwszURL))
  273. {
  274. pwszURL++;
  275. }
  276. //
  277. // Check port # exists
  278. //
  279. if (0 == *pwszURL)
  280. {
  281. return false;
  282. }
  283. //
  284. // Check port number is numeric
  285. //
  286. pwszURL++;
  287. while ( (0 != *pwszURL) && ( L'/' != *pwszURL) )
  288. {
  289. if (( L'0' > *pwszURL) || ( L'9' < *pwszURL))
  290. {
  291. return false;
  292. }
  293. pwszURL++;
  294. }
  295. //
  296. // Check / after port number exists
  297. //
  298. if (0 == *pwszURL)
  299. {
  300. return false;
  301. }
  302. //
  303. // URL is good.
  304. //
  305. IF_DEBUG( TRACE)
  306. {
  307. DBGPRINTF(( DBG_CONTEXT,
  308. "Inserting URL '%ws' into Config Group List\n",
  309. pwszOriginalURL
  310. ));
  311. }
  312. return ( TRUE == _mszURLList.Append( pwszOriginalURL));
  313. } // WP_CONFIG::InsertURLIntoList()