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.

562 lines
18 KiB

  1. /*===================================================================
  2. Microsoft IIS Active Server Pages
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: Registry stuff
  6. File: reg.cpp
  7. Owner: AndrewS/LeiJin
  8. ===================================================================*/
  9. #include "denpre.h"
  10. #pragma hdrstop
  11. #include <iadmw.h>
  12. #include "comadmin.h"
  13. #include "memchk.h"
  14. #include "Accctrl.h"
  15. #include "aclapi.h"
  16. #include "iiscnfg.h"
  17. //External functions, defined in glob.cpp
  18. extern HRESULT MDRegisterProperties(void);
  19. extern HRESULT MDUnRegisterProperties(void);
  20. // Globals
  21. const REGSAM samDesired = KEY_READ | KEY_WRITE;
  22. /*
  23. * Info about our intrinsics used by Register & UnRegister
  24. */
  25. const char *szClassDesc[] = { "ASP Response Object",
  26. "ASP Request Object",
  27. "ASP Request Dictionary",
  28. "ASP Server Object",
  29. "ASP Application Object",
  30. "ASP Session Object",
  31. "ASP String List Object",
  32. "ASP Read Cookie",
  33. "ASP Write Cookie",
  34. "ASP Scripting Context Object",
  35. "ASP Certificate Object",
  36. };
  37. const char *szCLSIDEntry[] = { "CLSID\\{D97A6DA0-A864-11cf-83BE-00A0C90C2BD8}", // IResponse
  38. "CLSID\\{D97A6DA0-A861-11cf-93AE-00A0C90C2BD8}", // IRequest
  39. "CLSID\\{D97A6DA0-A85F-11df-83AE-00A0C90C2BD8}", // IRequestDictionary
  40. "CLSID\\{D97A6DA0-A867-11cf-83AE-01A0C90C2BD8}", // IServer
  41. "CLSID\\{D97A6DA0-A866-11cf-83AE-10A0C90C2BD8}", // IApplicationObject
  42. "CLSID\\{D97A6DA0-A865-11cf-83AF-00A0C90C2BD8}", // ISessionObject
  43. "CLSID\\{D97A6DA0-A85D-11cf-83AE-00A0C90C2BD8}", // IStringList
  44. "CLSID\\{71EAF260-0CE0-11d0-A53E-00A0C90C2091}", // IReadCookie
  45. "CLSID\\{D97A6DA0-A862-11cf-84AE-00A0C90C2BD8}", // IWriteCookie
  46. "CLSID\\{D97A6DA0-A868-11cf-83AE-00B0C90C2BD8}", // IScriptingContext
  47. "CLSID\\{b3192190-1176-11d0-8ce8-00aa006c400c}", // ICertificate
  48. };
  49. const cClassesMax = sizeof(szCLSIDEntry) / sizeof(char *);
  50. /*===================================================================
  51. RegisterIntrinsics
  52. Register info about our intrinsics in the registry.
  53. Returns:
  54. HRESULT - S_OK on success
  55. Side effects:
  56. Registers denali objects in the registry
  57. ===================================================================*/
  58. HRESULT RegisterIntrinsics(void)
  59. {
  60. static const char szDenaliDLL[] = "asp.DLL";
  61. static const char szThreadingModel[] = "ThreadingModel";
  62. static const char szInprocServer32[] = "InprocServer32";
  63. static const char szFreeThreaded[] = "Both";
  64. static const char szProgIdKey[] = "ProgId";
  65. static const char szCLSIDKey[] = "CLSID";
  66. HRESULT hr = S_OK;
  67. char szPath[MAX_PATH];
  68. char *pch;
  69. HKEY hkeyCLSID = NULL;
  70. HKEY hkeyT = NULL;
  71. DWORD iClass;
  72. // Get the path and name of Denali
  73. if (!GetModuleFileNameA(g_hinstDLL, szPath, sizeof(szPath)/sizeof(char)))
  74. return E_FAIL;
  75. // bug fix 102010 DBCS fixes
  76. //
  77. //for (pch = szPath + lstrlen(szPath); pch > szPath && *pch != TEXT('\\'); pch--)
  78. // ;
  79. //if (pch == szPath)
  80. pch = (char*) _mbsrchr((const unsigned char*)szPath, '\\');
  81. if (pch == NULL)
  82. {
  83. Assert(FALSE);
  84. goto LErrExit;
  85. }
  86. strcpy(pch + 1, szDenaliDLL);
  87. for (iClass = 0; iClass < cClassesMax; iClass++)
  88. {
  89. // install the CLSID key
  90. // Setting the value of the description creates the key for the clsid
  91. if ((RegSetValueA(HKEY_CLASSES_ROOT, szCLSIDEntry[iClass], REG_SZ, szClassDesc[iClass],
  92. strlen(szClassDesc[iClass])) != ERROR_SUCCESS))
  93. goto LErrExit;
  94. // Open the CLSID key so we can set values on it
  95. if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szCLSIDEntry[iClass], 0, samDesired, &hkeyCLSID) != ERROR_SUCCESS)
  96. goto LErrExit;
  97. // install the InprocServer32 key and open the sub-key to set the named value
  98. if ((RegSetValueA(hkeyCLSID, szInprocServer32, REG_SZ, szPath, strlen(szPath)) != ERROR_SUCCESS))
  99. goto LErrExit;
  100. if ((RegOpenKeyExA(hkeyCLSID, szInprocServer32, 0, samDesired, &hkeyT) != ERROR_SUCCESS))
  101. goto LErrExit;
  102. // install the ThreadingModel named value
  103. if (RegSetValueExA(hkeyT, szThreadingModel, 0, REG_SZ, (const BYTE *)szFreeThreaded,
  104. (strlen(szFreeThreaded)+1) * sizeof(char)) != ERROR_SUCCESS)
  105. goto LErrExit;
  106. if (RegCloseKey(hkeyT) != ERROR_SUCCESS)
  107. goto LErrExit;
  108. hkeyT = NULL;
  109. RegCloseKey(hkeyCLSID);
  110. hkeyCLSID = NULL;
  111. }
  112. return hr;
  113. LErrExit:
  114. if (hkeyT)
  115. RegCloseKey(hkeyT);
  116. if (hkeyCLSID)
  117. RegCloseKey(hkeyCLSID);
  118. return E_FAIL;
  119. }
  120. /*===================================================================
  121. UnRegisterKey
  122. Given a string which is the name of a key under HKEY_CLASSES_ROOT,
  123. delete everything under that key and the key itself from the registry
  124. (why the heck isnt there an API that does this!?!?)
  125. Returns:
  126. HRESULT - S_OK on success
  127. Side effects:
  128. Removes a key & all subkeys from the registry
  129. ===================================================================*/
  130. HRESULT UnRegisterKey(CHAR *szKey)
  131. {
  132. HKEY hkey = NULL;
  133. CHAR szKeyName[255];
  134. DWORD cbKeyName;
  135. LONG errT;
  136. // Open the HKEY_CLASSES_ROOT\CLSID\{...} key so we can delete its subkeys
  137. if (RegOpenKeyExA(HKEY_CLASSES_ROOT, szKey, 0, samDesired, &hkey) != ERROR_SUCCESS)
  138. goto LErrExit;
  139. // Enumerate all its subkeys, and delete them
  140. while (TRUE)
  141. {
  142. cbKeyName = sizeof(szKeyName);
  143. if ((errT = RegEnumKeyExA(hkey, 0, szKeyName, &cbKeyName, 0, NULL, 0, NULL)) != ERROR_SUCCESS)
  144. break;
  145. if ((errT = RegDeleteKeyA(hkey, szKeyName)) != ERROR_SUCCESS)
  146. goto LErrExit;
  147. }
  148. // Close the key, and then delete it
  149. if ((errT = RegCloseKey(hkey)) != ERROR_SUCCESS)
  150. return(E_FAIL);
  151. if ((errT = RegDeleteKeyA(HKEY_CLASSES_ROOT, szKey)) != ERROR_SUCCESS)
  152. {
  153. DBGPRINTF((DBG_CONTEXT, "Deleting key %s returned %d\n",
  154. szKey, GetLastError()));
  155. return(E_FAIL);
  156. }
  157. return S_OK;
  158. LErrExit:
  159. if (hkey)
  160. RegCloseKey(hkey);
  161. return E_FAIL;
  162. }
  163. /*===================================================================
  164. UnRegisterIntrinsics
  165. UnRegister the info about our intrinsics from the registry.
  166. Returns:
  167. HRESULT - S_OK on success
  168. Side effects:
  169. Removes denali objects from the registry
  170. ===================================================================*/
  171. HRESULT UnRegisterIntrinsics(void)
  172. {
  173. HRESULT hr = S_OK, hrT;
  174. DWORD iClass;
  175. // Now delete the keys for the objects
  176. for (iClass = 0; iClass < cClassesMax; iClass++)
  177. {
  178. // Open the HKEY_CLASSES_ROOT\CLSID\{...} key so we can delete its subkeys
  179. if (FAILED(hrT = UnRegisterKey((CHAR *)szCLSIDEntry[iClass])))
  180. hr = hrT; // Hold onto the error, but keep going
  181. }
  182. return hr;
  183. }
  184. /*===================================================================
  185. RegisterTypeLib
  186. Register denali typelib in the registry.
  187. Returns:
  188. HRESULT - S_OK on success
  189. Side effects:
  190. register denali typelib in the registry
  191. ===================================================================*/
  192. HRESULT RegisterTypeLib(void)
  193. {
  194. HRESULT hr;
  195. ITypeLib *pITypeLib = NULL;
  196. char szFile[MAX_PATH+4];
  197. BSTR bstrFile;
  198. // Get the path and name of Denali
  199. if (!GetModuleFileNameA(g_hinstDLL, szFile, MAX_PATH))
  200. return E_FAIL;
  201. // There are two type libraries: First the standard ASP typelib
  202. // then the typelib for the Transacted Script Context object.
  203. // Load them both.
  204. // First type lib, from default (first ITypeLib entry) location
  205. hr = SysAllocStringFromSz(szFile, 0, &bstrFile);
  206. if (FAILED(hr))
  207. return hr;
  208. hr = LoadTypeLibEx(bstrFile, REGKIND_REGISTER, &pITypeLib);
  209. if (pITypeLib) {
  210. pITypeLib->Release();
  211. pITypeLib = NULL;
  212. }
  213. SysFreeString(bstrFile);
  214. if (FAILED(hr))
  215. return hr;
  216. // now register the Transacted Script Context Object
  217. strcat(szFile, "\\2");
  218. hr = SysAllocStringFromSz(szFile, 0, &bstrFile);
  219. if (FAILED(hr))
  220. return hr;
  221. hr = LoadTypeLibEx(bstrFile, REGKIND_REGISTER, &pITypeLib);
  222. if (pITypeLib) {
  223. pITypeLib->Release();
  224. pITypeLib = NULL;
  225. }
  226. SysFreeString(bstrFile);
  227. return hr;
  228. }
  229. /*===================================================================
  230. UnRegisterTypeLib
  231. UnRegister denali typelib in the registry. Note: Only the current version used by asp.dll is removed.
  232. Returns:
  233. HRESULT - S_OK on success
  234. Side effects:
  235. unregister denali typelib in the registry
  236. ===================================================================*/
  237. HRESULT UnRegisterTypeLib(void)
  238. {
  239. HRESULT hr;
  240. ITypeLib *pITypeLib = NULL;
  241. TLIBATTR *pTLibAttr = NULL;
  242. char szFile[MAX_PATH + 4];
  243. BSTR bstrFile;
  244. // Get the path and name of Denali
  245. if (!GetModuleFileNameA(g_hinstDLL, szFile, MAX_PATH))
  246. return E_FAIL;
  247. hr = SysAllocStringFromSz(szFile, 0, &bstrFile);
  248. if (FAILED(hr))
  249. return hr;
  250. hr = LoadTypeLibEx(bstrFile, REGKIND_REGISTER, &pITypeLib);
  251. if(SUCCEEDED(hr) && pITypeLib)
  252. {
  253. hr = pITypeLib->GetLibAttr(&pTLibAttr);
  254. if(SUCCEEDED(hr) && pTLibAttr)
  255. {
  256. hr = UnRegisterTypeLib( pTLibAttr->guid,
  257. pTLibAttr->wMajorVerNum,
  258. pTLibAttr->wMinorVerNum,
  259. pTLibAttr->lcid,
  260. pTLibAttr->syskind);
  261. pITypeLib->ReleaseTLibAttr(pTLibAttr);
  262. pTLibAttr = NULL;
  263. }
  264. pITypeLib->Release();
  265. pITypeLib = NULL;
  266. }
  267. SysFreeString(bstrFile);
  268. // unregister the Txn typelib
  269. strcat(szFile, "\\2");
  270. hr = SysAllocStringFromSz(szFile, 0, &bstrFile);
  271. if (FAILED(hr))
  272. return hr;
  273. hr = LoadTypeLibEx(bstrFile, REGKIND_REGISTER, &pITypeLib);
  274. if(SUCCEEDED(hr) && pITypeLib)
  275. {
  276. hr = pITypeLib->GetLibAttr(&pTLibAttr);
  277. if(SUCCEEDED(hr) && pTLibAttr)
  278. {
  279. hr = UnRegisterTypeLib( pTLibAttr->guid,
  280. pTLibAttr->wMajorVerNum,
  281. pTLibAttr->wMinorVerNum,
  282. pTLibAttr->lcid,
  283. pTLibAttr->syskind);
  284. pITypeLib->ReleaseTLibAttr(pTLibAttr);
  285. pTLibAttr = NULL;
  286. }
  287. pITypeLib->Release();
  288. pITypeLib = NULL;
  289. }
  290. SysFreeString(bstrFile);
  291. return hr;
  292. }
  293. HRESULT CreateCompiledTemplatesTempDir()
  294. {
  295. HRESULT hr = S_OK;
  296. BYTE szRegString[MAX_PATH];
  297. BYTE pszExpanded[MAX_PATH];
  298. int result = 0;
  299. EXPLICIT_ACCESSA ea[2];
  300. PACL pNewDACL = NULL;
  301. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  302. // read the temp dir name for the persistant templ
  303. // cache.
  304. CchLoadStringOfId(IDS_DEFAULTPERSISTDIR, (LPSTR)szRegString, MAX_PATH);
  305. result = ExpandEnvironmentStringsA((LPCSTR)szRegString,
  306. (LPSTR)pszExpanded,
  307. MAX_PATH);
  308. if ((result <= MAX_PATH) && (result > 0)) {
  309. CreateDirectoryA((LPCSTR)pszExpanded,NULL);
  310. }
  311. // this next section of code will place the SYSTEM and IWAM_<ComputerName>
  312. // ACEs on the directorie's ACL
  313. ZeroMemory(ea, sizeof(EXPLICIT_ACCESSA) * 2);
  314. ea[0].grfAccessPermissions = SYNCHRONIZE | GENERIC_ALL;
  315. ea[0].grfAccessMode = GRANT_ACCESS;
  316. ea[0].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  317. ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  318. ea[1].grfAccessPermissions = SYNCHRONIZE | GENERIC_ALL;
  319. ea[1].grfAccessMode = GRANT_ACCESS;
  320. ea[1].grfInheritance= SUB_CONTAINERS_AND_OBJECTS_INHERIT;
  321. ea[1].Trustee.TrusteeForm = TRUSTEE_IS_NAME;
  322. ea[1].Trustee.ptstrName = "IIS_WPG";
  323. // Admin privilages.
  324. if (!AllocateAndInitializeSid(&NtAuthority,
  325. 2, // 2 sub-authorities
  326. SECURITY_BUILTIN_DOMAIN_RID,
  327. DOMAIN_ALIAS_RID_ADMINS,
  328. 0,0,0,0,0,0,
  329. (PSID *)(&ea[0].Trustee.ptstrName)))
  330. hr = HRESULT_FROM_WIN32(GetLastError());
  331. else if ((hr = SetEntriesInAclA(2,
  332. ea,
  333. NULL,
  334. &pNewDACL)) != ERROR_SUCCESS);
  335. // set the ACL on the directory
  336. else hr = SetNamedSecurityInfoA((LPSTR)pszExpanded,
  337. SE_FILE_OBJECT,
  338. DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
  339. NULL,
  340. NULL,
  341. pNewDACL,
  342. NULL);
  343. if (pNewDACL)
  344. LocalFree(pNewDACL);
  345. if (ea[0].Trustee.ptstrName)
  346. FreeSid(ea[0].Trustee.ptstrName);
  347. return(hr);
  348. }
  349. /*===================================================================
  350. DllRegisterServer
  351. Entry point used by RegSvr32.exe to register the DLL.
  352. Returns:
  353. HRESULT - S_OK on success
  354. Side effects:
  355. Registers denali objects in the registry
  356. ===================================================================*/
  357. STDAPI DllRegisterServer(void)
  358. {
  359. HRESULT hr = E_FAIL;
  360. HRESULT hrCoInit;
  361. hrCoInit = CoInitialize(NULL);
  362. if (FAILED(InitializeResourceDll()))
  363. goto LErr;
  364. // First try to unregister some stuff
  365. // This is important when we are registering on top of
  366. // an old IIS 3.0 Denali registration
  367. // Don't care if fails
  368. UnRegisterEventLog();
  369. UnRegisterIntrinsics();
  370. UnRegisterTypeLib();
  371. // Now do the registration
  372. if (FAILED(hr = MDRegisterProperties()))
  373. goto LErr;
  374. // Register NT event log
  375. if(FAILED(hr = RegisterEventLog()))
  376. goto LErr;
  377. if (FAILED(hr = RegisterTypeLib()))
  378. goto LErr;
  379. // Register our intrinsics
  380. if (FAILED(hr = RegisterIntrinsics()))
  381. goto LErr;
  382. if (FAILED(hr = CreateCompiledTemplatesTempDir()))
  383. goto LErr;
  384. LErr:
  385. UninitializeResourceDll();
  386. if (SUCCEEDED(hrCoInit))
  387. CoUninitialize();
  388. return(hr);
  389. }
  390. /*===================================================================
  391. DllUnregisterServer
  392. Entry point used by RegSvr32.exe to unregister the DLL.
  393. Returns:
  394. HRESULT - S_OK on success
  395. Side effects:
  396. Removes denali registrations from the registry
  397. ===================================================================*/
  398. STDAPI DllUnregisterServer(void)
  399. {
  400. HRESULT hr = S_OK, hrT;
  401. HRESULT hrCoInit;
  402. hrCoInit = CoInitialize(NULL);
  403. hrT = InitializeResourceDll();
  404. if (FAILED(hrT))
  405. hr = hrT;
  406. hrT = UnRegisterEventLog();
  407. if (FAILED(hrT))
  408. hr = hrT;
  409. hrT = MDUnRegisterProperties();
  410. if (FAILED(hrT))
  411. hr = hrT;
  412. hrT = UnRegisterIntrinsics();
  413. if (FAILED(hrT))
  414. hr = hrT;
  415. hrT = UnRegisterTypeLib();
  416. if (FAILED(hrT))
  417. hr = hrT;
  418. // UNDONE BUG 80063: Ignore errors from this call
  419. #ifdef UNDONE
  420. if (FAILED(hrT))
  421. hr = hrT;
  422. #endif
  423. UninitializeResourceDll();
  424. if (SUCCEEDED(hrCoInit))
  425. CoUninitialize();
  426. return(hr);
  427. }