Leaked source code of windows server 2003
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.

428 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name :
  4. w3wp.cxx
  5. Abstract:
  6. Main module for IIS compatible worker process
  7. Author:
  8. Murali R. Krishnan ( MuraliK ) 23-Sept-1998
  9. Environment:
  10. Win32 - User Mode
  11. Project:
  12. IIS compatible worker process
  13. --*/
  14. /************************************************************
  15. * Include Headers
  16. ************************************************************/
  17. #include "precomp.hxx"
  18. #include "wpif.h"
  19. #include "ulw3.h"
  20. #include "../../../svcs/mdadmin/ntsec.h"
  21. DECLARE_DEBUG_PRINTS_OBJECT();
  22. DECLARE_DEBUG_VARIABLE();
  23. //
  24. // Configuration parameters registry key.
  25. //
  26. // BUGBUG
  27. #undef INET_INFO_KEY
  28. #undef INET_INFO_PARAMETERS_KEY
  29. #define INET_INFO_KEY \
  30. "System\\CurrentControlSet\\Services\\iisw3adm"
  31. #define INET_INFO_PARAMETERS_KEY \
  32. INET_INFO_KEY "\\Parameters"
  33. const CHAR g_pszWpRegLocation[] =
  34. INET_INFO_PARAMETERS_KEY "\\WP";
  35. class DEBUG_WRAPPER {
  36. public:
  37. DEBUG_WRAPPER( IN LPCSTR pszModule)
  38. {
  39. #if DBG
  40. CREATE_DEBUG_PRINT_OBJECT( pszModule);
  41. #else
  42. UNREFERENCED_PARAMETER(pszModule);
  43. #endif
  44. LOAD_DEBUG_FLAGS_FROM_REG_STR( g_pszWpRegLocation, DEBUG_ERROR );
  45. }
  46. ~DEBUG_WRAPPER(void)
  47. { DELETE_DEBUG_PRINT_OBJECT(); }
  48. };
  49. HRESULT
  50. InitializeComSecurity( VOID );
  51. //
  52. // W3 DLL which does all the work
  53. //
  54. extern "C" INT
  55. __cdecl
  56. wmain(
  57. INT argc,
  58. PWSTR argv[]
  59. )
  60. {
  61. DEBUG_WRAPPER dbgWrapper( "w3wp" );
  62. HRESULT hr;
  63. HMODULE hModule = NULL;
  64. PFN_ULW3_ENTRY pEntry = NULL;
  65. ULONG rcRet = CLEAN_WORKER_PROCESS_EXIT_CODE;
  66. BOOL fCoInit = FALSE;
  67. HDESK hIISDesktop = NULL;
  68. //
  69. // We don't want the worker process to get stuck in a dialog box
  70. // if it goes awry.
  71. //
  72. SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX );
  73. IF_DEBUG( TRACE)
  74. {
  75. //
  76. // Print out our process affinity mask on debug builds.
  77. //
  78. BOOL fRet = TRUE;
  79. DWORD_PTR ProcessAffinityMask = 0;
  80. DWORD_PTR SystemAffinityMask = 0;
  81. fRet = GetProcessAffinityMask(
  82. GetCurrentProcess(),
  83. &ProcessAffinityMask,
  84. &SystemAffinityMask
  85. );
  86. DBGPRINTF(( DBG_CONTEXT, "Process affinity mask: %p\n", ProcessAffinityMask ));
  87. }
  88. //
  89. // Move this process to the WindowStation (with full access to all) in
  90. // which we would have been if running in inetinfo.exe (look at
  91. // iis\svcs\mdadmin\ntsec.cxx)
  92. //
  93. HWINSTA hWinSta = OpenWindowStationA(SZ_IIS_WINSTA, FALSE, WINSTA_DESIRED);
  94. if (hWinSta == NULL)
  95. {
  96. hr = HRESULT_FROM_WIN32(GetLastError());
  97. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  98. goto Finished;
  99. }
  100. //
  101. // Set this as this process's window station
  102. //
  103. if (!SetProcessWindowStation(hWinSta))
  104. {
  105. hr = HRESULT_FROM_WIN32(GetLastError());
  106. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  107. goto Finished;
  108. }
  109. //
  110. // Save the previous desktop and then load the IIS one and set it to
  111. // active for this thread. This causes COM to cache the desktop
  112. // and makes launching local COM servers work.
  113. //
  114. HDESK hPrevDesk = GetThreadDesktop(GetCurrentThreadId());
  115. if (hPrevDesk == NULL)
  116. {
  117. hr = HRESULT_FROM_WIN32(GetLastError());
  118. goto Finished;
  119. }
  120. hIISDesktop = OpenDesktopA(SZ_IIS_DESKTOP, 0, FALSE, DESKTOP_DESIRED);
  121. if (hIISDesktop == NULL)
  122. {
  123. hr = HRESULT_FROM_WIN32(GetLastError());
  124. goto Finished;
  125. }
  126. if (!SetThreadDesktop(hIISDesktop))
  127. {
  128. hr = HRESULT_FROM_WIN32(GetLastError());
  129. goto Finished;
  130. }
  131. //
  132. // Do some COM junk
  133. //
  134. // BUGBUG: CoInitialize twice to protect against applications which
  135. // over CoUnInitialize()
  136. //
  137. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  138. if (FAILED(hr))
  139. {
  140. DBGPRINTF(( DBG_CONTEXT,
  141. "Error in CoInitializeEx(). hr = %x\n",
  142. hr ));
  143. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  144. goto Finished;
  145. }
  146. else
  147. {
  148. hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  149. if (FAILED(hr))
  150. {
  151. CoUninitialize();
  152. DBGPRINTF(( DBG_CONTEXT,
  153. "Error in second CoInitializeEx(). hr = %x\n",
  154. hr ));
  155. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  156. goto Finished;
  157. }
  158. }
  159. fCoInit = TRUE;
  160. hr = InitializeComSecurity();
  161. if (FAILED(hr))
  162. {
  163. DBGPRINTF(( DBG_CONTEXT,
  164. "Error in InitializeComSecurity(). hr = %x\n",
  165. hr ));
  166. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  167. goto Finished;
  168. }
  169. //
  170. // Reset back to the default desktop
  171. //
  172. if (!SetThreadDesktop(hPrevDesk))
  173. {
  174. hr = HRESULT_FROM_WIN32(GetLastError());
  175. goto Finished;
  176. }
  177. //
  178. // Load the ULW3 DLL which does all the work
  179. //
  180. hModule = LoadLibrary( ULW3_DLL_NAME );
  181. if ( hModule == NULL )
  182. {
  183. DBGPRINTF(( DBG_CONTEXT,
  184. "Error loading W3 service dll '%ws'. Error = %d\n",
  185. ULW3_DLL_NAME,
  186. GetLastError() ));
  187. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  188. goto Finished;
  189. }
  190. pEntry = (PFN_ULW3_ENTRY) GetProcAddress( hModule,
  191. ULW3_DLL_ENTRY );
  192. if ( pEntry == NULL )
  193. {
  194. DBGPRINTF(( DBG_CONTEXT,
  195. "Could not find entry point '%s'. Error = %d\n",
  196. ULW3_DLL_ENTRY,
  197. GetLastError() ));
  198. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  199. goto Finished;
  200. }
  201. hr = pEntry( argc,
  202. argv,
  203. FALSE ); // Compatibility Mode = FALSE
  204. if ( FAILED( hr ) )
  205. {
  206. DBGPRINTF(( DBG_CONTEXT,
  207. "Error executing W3WP. hr = %x\n",
  208. hr ));
  209. rcRet = ERROR_WORKER_PROCESS_EXIT_CODE;
  210. goto Finished;
  211. }
  212. Finished:
  213. if ( IsDebuggerPresent() )
  214. {
  215. DBG_ASSERT( SUCCEEDED( hr ) );
  216. }
  217. //
  218. // Cleanup any lingering COM objects before unloading
  219. //
  220. if ( fCoInit )
  221. {
  222. CoUninitialize();
  223. CoUninitialize();
  224. }
  225. if ( hModule != NULL )
  226. {
  227. FreeLibrary( hModule );
  228. }
  229. if (hIISDesktop)
  230. {
  231. CloseDesktop(hIISDesktop);
  232. }
  233. return rcRet;
  234. }
  235. HRESULT
  236. InitializeComSecurity( VOID )
  237. /*++
  238. Routine Description:
  239. Call CoInitializeSecurity. Seems simple, but it has significant
  240. security and compatibility implications. Defaults can be overriden
  241. with registry setting that are based on those used by svchost.exe.
  242. There are three controllable parameters:
  243. AuthenticationLevel
  244. IIS5 inetinfo RPC_C_AUTHN_LEVEL_DEFAULT = 0
  245. iisadmin RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6
  246. svchost RPC_C_AUTHN_LEVEL_PKT = 4
  247. default IIS5
  248. ImpersonationLevel
  249. IIS5 inetinfo RPC_C_IMP_LEVEL_IMPERSONATE = 3
  250. iisadmin RPC_C_IMP_LEVEL_IDENTIFY = 2
  251. svchost RPC_C_IMP_LEVEL_IDENTIFY = 2
  252. default IIS5
  253. AuthenticationCapabilities
  254. IIS5 inetinfo EOAC_DYNAMIC_CLOAKING = 0x40
  255. iisadmin EOAC_DYNAMIC_CLOAKING |
  256. EOAC_DISABLE_AAA |
  257. EOAC_NO_CUSTOM_MARSHAL = 0x3040
  258. svchost EOAC_NO_CUSTOM_MARSHAL |
  259. EOAC_DISABLE_AAA = 0x1040
  260. default IIS5
  261. A fourth parameter CoInitializeSecurityParam controls whether
  262. we read the other three parameters at all.
  263. Arguments:
  264. None
  265. Return Value:
  266. HRESULT
  267. --*/
  268. {
  269. HRESULT hr;
  270. HKEY hKey;
  271. DWORD CoInitializeSecurityParam = 0;
  272. DWORD AuthenticationLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
  273. DWORD ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  274. DWORD AuthenticationCapabilities = EOAC_DYNAMIC_CLOAKING;
  275. if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  276. L"System\\CurrentControlSet\\Services\\w3svc\\Parameters",
  277. 0,
  278. KEY_READ,
  279. &hKey ) == ERROR_SUCCESS )
  280. {
  281. DWORD dwValue;
  282. DWORD dwType;
  283. DWORD cbValue = sizeof(DWORD);
  284. if( RegQueryValueEx( hKey,
  285. L"CoInitializeSecurityParam",
  286. NULL,
  287. &dwType,
  288. (LPBYTE)&dwValue,
  289. &cbValue ) == ERROR_SUCCESS &&
  290. dwType == REG_DWORD )
  291. {
  292. CoInitializeSecurityParam = dwValue;
  293. }
  294. if( CoInitializeSecurityParam )
  295. {
  296. if( RegQueryValueEx( hKey,
  297. L"AuthenticationLevel",
  298. NULL,
  299. &dwType,
  300. (LPBYTE)&dwValue,
  301. &cbValue ) == ERROR_SUCCESS &&
  302. dwType == REG_DWORD )
  303. {
  304. AuthenticationLevel = dwValue;
  305. }
  306. if( RegQueryValueEx( hKey,
  307. L"ImpersonationLevel",
  308. NULL,
  309. &dwType,
  310. (LPBYTE)&dwValue,
  311. &cbValue ) == ERROR_SUCCESS &&
  312. dwType == REG_DWORD )
  313. {
  314. ImpersonationLevel = dwValue;
  315. }
  316. if( RegQueryValueEx( hKey,
  317. L"AuthenticationCapabilities",
  318. NULL,
  319. &dwType,
  320. (LPBYTE)&dwValue,
  321. &cbValue ) == ERROR_SUCCESS &&
  322. dwType == REG_DWORD )
  323. {
  324. AuthenticationCapabilities = dwValue;
  325. }
  326. }
  327. RegCloseKey( hKey );
  328. }
  329. hr = CoInitializeSecurity( NULL,
  330. -1,
  331. NULL,
  332. NULL,
  333. AuthenticationLevel,
  334. ImpersonationLevel,
  335. NULL,
  336. AuthenticationCapabilities,
  337. NULL );
  338. return hr;
  339. }