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.

627 lines
21 KiB

  1. // Msie.cpp : Implementation of CMsieApp and DLL registration.
  2. #include "stdafx.h"
  3. #include "Msie.h"
  4. #include "regkeys.h"
  5. #include "resdefs.h"
  6. #include <wbemprov.h>
  7. #include <AFXPRIV.H>
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. CMsieApp theApp;
  14. const GUID CDECL BASED_CODE _tlid =
  15. { 0x25959bec, 0xe700, 0x11d2, { 0xa7, 0xaf, 0, 0xc0, 0x4f, 0x80, 0x62, 0 } };
  16. const WORD _wVerMajor = 1;
  17. const WORD _wVerMinor = 0;
  18. const LPCSTR CLSID_MSIE = "{25959BEF-E700-11D2-A7AF-00C04F806200}";
  19. const LPCSTR IE_REPAIR_CMD = "rundll32 setupwbv.dll,IE6Maintenance \"%s\\Setup\\SETUP.EXE\" /g \"%s\\%s\"";
  20. const LPCSTR OCX_FILE_IN_COMMON = "Microsoft Shared\\MSInfo\\ieinfo5.ocx";
  21. const LPCSTR MOF_FILE_PATH = "%SystemRoot%\\System32\\WBEM\\MOF";
  22. const LPCSTR MOF_FILE = "ieinfo5.mof";
  23. const MAX_KEY_LENGTH = 256;
  24. ////////////////////////////////////////////////////////////////////////////
  25. // CMsieApp::InitInstance - DLL initialization
  26. BOOL CMsieApp::InitInstance()
  27. {
  28. BOOL bInit = COleControlModule::InitInstance();
  29. if (bInit)
  30. {
  31. m_fTemplateLoaded = FALSE;
  32. m_pTemplateInfo = NULL;
  33. m_dwTemplateInfoLen = 0;
  34. }
  35. return bInit;
  36. }
  37. ////////////////////////////////////////////////////////////////////////////
  38. // CMsieApp::ExitInstance - DLL termination
  39. int CMsieApp::ExitInstance()
  40. {
  41. if (m_pTemplateInfo != NULL)
  42. {
  43. delete m_pTemplateInfo;
  44. m_pTemplateInfo = NULL;
  45. }
  46. return COleControlModule::ExitInstance();
  47. }
  48. //-----------------------------------------------------------------------------
  49. // AppGetTemplate is the entry point for the app object from outside the DLL.
  50. // It's called by the exported function GetTemplate. The reconstructed template
  51. // file should be returned to the caller as a pointer in the pBuffer parameter.
  52. //
  53. // If a NULL pointer is passed for pBuffer, we are free to delete the internal
  54. // buffer storing the template file.
  55. //-----------------------------------------------------------------------------
  56. DWORD CMsieApp::AppGetTemplate(void ** ppBuffer)
  57. {
  58. if (!m_fTemplateLoaded)
  59. {
  60. LoadTemplate();
  61. m_fTemplateLoaded = TRUE;
  62. }
  63. if (ppBuffer == NULL)
  64. {
  65. if (m_pTemplateInfo)
  66. delete m_pTemplateInfo;
  67. m_pTemplateInfo = NULL;
  68. m_dwTemplateInfoLen = 0;
  69. m_fTemplateLoaded = FALSE;
  70. return 0;
  71. }
  72. *ppBuffer = (void *)m_pTemplateInfo;
  73. return m_dwTemplateInfoLen;
  74. }
  75. //-----------------------------------------------------------------------------
  76. // This table of keywords is used during the reconstruction process. It matches
  77. // exactly the table used during the conversion from NFT to resources, and it
  78. // MUST NOT be modified, or the reconstructed information will be bogus.
  79. //-----------------------------------------------------------------------------
  80. #define KEYWORD_COUNT 19
  81. char * KEYWORD_STRING[KEYWORD_COUNT] =
  82. {
  83. "node", "columns", "line", "field", "enumlines", "(", ")", "{", "}", ",",
  84. "\"basic\"", "\"advanced\"", "\"BASIC\"", "\"ADVANCED\"", "\"static\"",
  85. "\"LEXICAL\"", "\"VALUE\"", "\"NONE\"", "\"\""
  86. };
  87. //-----------------------------------------------------------------------------
  88. // The LoadTemplate function needs to load the template information out of
  89. // our resources, and create a buffer which contains the restored template
  90. // file to return to our caller (through AppGetTemplate).
  91. //-----------------------------------------------------------------------------
  92. void CMsieApp::LoadTemplate()
  93. {
  94. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  95. CMapWordToPtr mapNonLocalized;
  96. HRSRC hrsrcNFN;
  97. HGLOBAL hglbNFN;
  98. unsigned char *pData;
  99. WORD wID;
  100. CString strToken, *pstrToken;
  101. // In debug mode, we'll reconstruct the original template file for comparison.
  102. /*#ifdef DBG
  103. CFile fileRestore(_T("ie-restore.nft"), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite);
  104. #endif*/
  105. // Load the non-localized strings from the custom resource type and create
  106. // a map of ID to strings. Because these are non-localized strings, they
  107. // will not be stored as Unicode. Each item in the stream is a 2 byte word
  108. // ID followed by a null-terminated string. A zero ID indicates the end of
  109. // the stream.
  110. hrsrcNFN = FindResource(AfxGetResourceHandle(), _T("#1"), _T("MSINonLocalizedTokens"));
  111. hglbNFN = LoadResource(AfxGetResourceHandle(), hrsrcNFN);
  112. pData = (unsigned char *)LockResource(hglbNFN);
  113. while (pData && *((WORD UNALIGNED *)pData))
  114. {
  115. wID = (WORD)(((WORD)*pData++) << 8); // deal with the byte order explicitly to avoid
  116. wID |= (WORD)*pData++; // endian problems.
  117. pstrToken = new CString((char *)pData);
  118. pData += strlen((char *)pData) + 1;
  119. if (pstrToken)
  120. mapNonLocalized.SetAt(wID, (void *)pstrToken);
  121. }
  122. // Load the binary stream of token identifiers into memory.
  123. HRSRC hrsrcNFB = FindResource(AfxGetResourceHandle(), _T("#1"), _T("MSITemplateStream"));
  124. HGLOBAL hglbNFB = LoadResource(AfxGetResourceHandle(), hrsrcNFB);
  125. unsigned char *pStream = (unsigned char *) LockResource(hglbNFB);
  126. if (pStream)
  127. {
  128. // The first DWORD in the stream is the size of the original text file. We'll
  129. // use this to allocate our buffer to store the reconstituted file.
  130. DWORD dwSize;
  131. dwSize = ((DWORD)*pStream++) << 24;
  132. dwSize |= ((DWORD)*pStream++) << 16;
  133. dwSize |= ((DWORD)*pStream++) << 8;
  134. dwSize |= ((DWORD)*pStream++);
  135. // The size stored is for an Ansi text file. We need to adjust for the
  136. // fact that our reconstituted file will be Unicode. We also want to add
  137. // a word to the front of the stream to hold the Unicode file marker (so
  138. // MSInfo can use the same functions to read a file or this stream).
  139. dwSize *= sizeof(WCHAR); // adjust for Unicode
  140. dwSize += sizeof(WORD); // add room for Unicode file marker
  141. m_pTemplateInfo = new unsigned char[dwSize];
  142. m_dwTemplateInfoLen = 0;
  143. if (m_pTemplateInfo == NULL)
  144. return;
  145. // Write the Unicode file marker.
  146. wID = 0xFEFF;
  147. memcpy(&m_pTemplateInfo[m_dwTemplateInfoLen], (void *)&wID, sizeof(WORD));
  148. m_dwTemplateInfoLen += sizeof(WORD);
  149. // Process the stream a token at a time. For each new item in the stream, we
  150. // process it as follows:
  151. //
  152. // 1. If ((byte & 0x80) == 0x00), use the byte to lookup a KEYWORD_STRING.
  153. // 2. If ((byte & 0xC0) == 0x80), use the byte and the next byte as a word
  154. // ID to lookup a non-localized token from mapNonLocalized.
  155. // 3. Else ((byte & 0xC0) == 0xC0), use the byte and the next byte as a word
  156. // ID to lookup a localized token from the resources of this DLL.
  157. while (pStream && *pStream)
  158. {
  159. if ((*pStream & 0x80) == 0x00)
  160. {
  161. // A byte with the high bit clear refers to a keyword. Look up the keyword
  162. // from the table, and add it to the restored file.
  163. wID = (WORD)(((WORD)*pStream++) - 1); ASSERT(wID <= KEYWORD_COUNT);
  164. if (wID <= KEYWORD_COUNT)
  165. strToken = KEYWORD_STRING[wID];
  166. }
  167. else
  168. {
  169. wID = (WORD)(((WORD)*pStream++) << 8); // deal with the byte order explicitly to avoid
  170. wID |= (WORD)*pStream++; // endian problems.
  171. if ((wID & 0xC000) == 0x8000)
  172. {
  173. // A byte with the high bit set, but the next to high bit clear indicates
  174. // the ID is actually a word, and should be used to get a non-localized
  175. // string. Get the string out of the map we created and add it to the file.
  176. if (mapNonLocalized.Lookup(((WORD)(wID & 0x7FFF)), (void *&)pstrToken))
  177. strToken = *pstrToken;
  178. else
  179. ASSERT(FALSE);
  180. }
  181. else
  182. {
  183. // A byte with the two MSB set indicates that the ID is a word, and should
  184. // be used to reference a localized string out of the string table in this
  185. // module's resources. This string will be UNICODE.
  186. VERIFY(strToken.LoadString((wID & 0x3FFF) + IDS_MSITEMPLATEBASE));
  187. strToken = _T("\"") + strToken + _T("\"");
  188. }
  189. }
  190. // Store the token on the end of our buffer. The data in this buffer must
  191. // be Unicode, so we'll need to convert the string if necessary.
  192. //v-stlowe if (m_dwTemplateInfoLen + strToken.GetLength() * sizeof(WCHAR) < dwSize)
  193. if (m_dwTemplateInfoLen + strToken.GetLength() < dwSize)
  194. {
  195. // Converting to strToken to Unicode
  196. WCHAR *pwchToken;
  197. pwchToken = new WCHAR[strToken.GetLength() + 1];
  198. //v-stlowe ::MultiByteToWideChar(CP_ACP, 0, strToken, -1, pwchToken, (strToken.GetLength() + 1) * sizeof(WCHAR));
  199. USES_CONVERSION;
  200. wcscpy(pwchToken,T2W((LPTSTR)(LPCTSTR)strToken));
  201. // Copying Unicode string to buffer
  202. memcpy(&m_pTemplateInfo[m_dwTemplateInfoLen], (void *)pwchToken, wcslen(pwchToken) * sizeof(WCHAR));
  203. m_dwTemplateInfoLen += wcslen(pwchToken) * sizeof(WCHAR);
  204. delete pwchToken;
  205. /*memcpy(&m_pTemplateInfo[m_dwTemplateInfoLen],(void *) strToken.GetBuffer(strToken.GetLength()),strToken.GetLength());
  206. strToken.ReleaseBuffer();*/
  207. }
  208. else
  209. ASSERT(FALSE);
  210. /*#ifdef DBG
  211. if (strToken == CString(_T("}")) || strToken == CString(_T("{")) || strToken == CString(_T(")")))
  212. strToken += CString(_T("\r\n"));
  213. fileRestore.Write((void *)(LPCTSTR)strToken, strToken.GetLength() * sizeof(TCHAR));
  214. #endif*/
  215. }
  216. }
  217. // Delete the contents of the lookup table.
  218. #ifdef DBG
  219. CFile fileRestore(_T("test.nft"), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite);
  220. fileRestore.Write(m_pTemplateInfo,m_dwTemplateInfoLen);
  221. #endif
  222. for (POSITION pos = mapNonLocalized.GetStartPosition(); pos != NULL;)
  223. {
  224. mapNonLocalized.GetNextAssoc(pos, wID, (void *&)pstrToken);
  225. if (pstrToken)
  226. delete pstrToken;
  227. }
  228. }
  229. ////////////////////////////////////////////////////////////////////////////
  230. // WriteNode - Helper function for writing an MSInfo node to the registry
  231. void WriteNode(HKEY hKey, LPCTSTR pszSubKey, int idsDefault, DWORD dwView, DWORD dwRank)
  232. {
  233. HKEY hNewKey;
  234. DWORD dwDisposition;
  235. CString strDefault;
  236. if (ERROR_SUCCESS == RegCreateKeyEx(hKey, pszSubKey, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNewKey, &dwDisposition))
  237. {
  238. strDefault.LoadString(idsDefault);
  239. RegSetValueEx(hNewKey, NULL, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strDefault, strDefault.GetLength() + sizeof(TCHAR));
  240. RegSetValueEx(hNewKey, REG_CLSID, 0, REG_SZ, (const LPBYTE)CLSID_MSIE, strlen(CLSID_MSIE) + 1);
  241. RegSetValueEx(hNewKey, REG_MSINFO_VIEW, 0, REG_BINARY, (const LPBYTE)&dwView, sizeof(DWORD));
  242. RegSetValueEx(hNewKey, REG_RANK, 0, REG_BINARY, (const LPBYTE)&dwRank, sizeof(DWORD));
  243. RegCloseKey(hNewKey);
  244. }
  245. }
  246. ////////////////////////////////////////////////////////////////////////////
  247. // RegDeleteKeyRecusive - Helper function for deleting reg keys
  248. DWORD RegDeleteKeyRecusive(HKEY hStartKey, LPCTSTR pKeyName)
  249. {
  250. DWORD dwRtn, dwSubKeyLength;
  251. LPTSTR pSubKey = NULL;
  252. TCHAR szSubKey[MAX_KEY_LENGTH]; // (256) this should be dynamic.
  253. HKEY hKey;
  254. // Do not allow NULL or empty key name
  255. if ( pKeyName && lstrlen(pKeyName))
  256. {
  257. if( (dwRtn = RegOpenKeyEx(hStartKey, pKeyName, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey )) == ERROR_SUCCESS)
  258. {
  259. while (dwRtn == ERROR_SUCCESS)
  260. {
  261. dwSubKeyLength = MAX_KEY_LENGTH;
  262. dwRtn=RegEnumKeyEx(
  263. hKey,
  264. 0, // always index zero
  265. szSubKey,
  266. &dwSubKeyLength,
  267. NULL,
  268. NULL,
  269. NULL,
  270. NULL
  271. );
  272. if(dwRtn == ERROR_NO_MORE_ITEMS)
  273. {
  274. dwRtn = RegDeleteKey(hStartKey, pKeyName);
  275. break;
  276. }
  277. else if(dwRtn == ERROR_SUCCESS)
  278. dwRtn = RegDeleteKeyRecusive(hKey, szSubKey);
  279. }
  280. RegCloseKey(hKey);
  281. // Do not save return code because error
  282. // has already occurred
  283. }
  284. }
  285. else
  286. dwRtn = ERROR_BADKEY;
  287. return dwRtn;
  288. }
  289. ////////////////////////////////////////////////////////////////////////////
  290. // GetIERepairToolCmdLine - Helper function for creating command line for
  291. // launching IE Repair Tool.
  292. CString GetIERepairToolCmdLine()
  293. {
  294. CString strRet, strIEPath, strIEPathExpanded, strWindowsPath, strRepairLog;
  295. HKEY hKey;
  296. DWORD cbData;
  297. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_IE_SETUP_KEY, 0, KEY_QUERY_VALUE, &hKey))
  298. {
  299. cbData = MAX_PATH;
  300. RegQueryValueEx(hKey, REG_PATH, NULL, NULL, (LPBYTE)strIEPath.GetBuffer(MAX_PATH), &cbData);
  301. strIEPath.ReleaseBuffer();
  302. ExpandEnvironmentStrings(strIEPath, strIEPathExpanded.GetBuffer(MAX_PATH), MAX_PATH);
  303. strIEPathExpanded.ReleaseBuffer();
  304. RegCloseKey(hKey);
  305. }
  306. GetWindowsDirectory(strWindowsPath.GetBuffer(MAX_PATH), MAX_PATH);
  307. strWindowsPath.ReleaseBuffer();
  308. strRepairLog.LoadString(IDS_REPAIR_LOG);
  309. strRet.Format((LPCTSTR) IE_REPAIR_CMD, strIEPathExpanded, strWindowsPath, strRepairLog);
  310. return strRet;
  311. }
  312. /////////////////////////////////////////////////////////////////////////////
  313. // DllRegisterServer - Adds entries to the system registry
  314. STDAPI DllRegisterServer(void)
  315. {
  316. AFX_MANAGE_STATE(_afxModuleAddrThis);
  317. OSVERSIONINFO osver;
  318. HKEY hCatKey, hIE6Key, hCacheKey, hContentKey, hRepairKey, hMsinfoKey, hTemplatesKey, hIeinfo5Key;
  319. HKEY hMicrosoftKey, hSharedToolsKey, hCurrentVersionKey;
  320. CString strCatKey, strKey, strValue, strFullPath, strMofPathSrc, strMofPathDest;
  321. BYTE szBuffer[MAX_PATH];
  322. DWORD dwDisposition, dwType, dwSize;
  323. int nIndex;
  324. HRESULT hr = S_OK;
  325. if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
  326. return ResultFromScode(SELFREG_E_TYPELIB);
  327. if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
  328. return ResultFromScode(SELFREG_E_CLASS);
  329. // check OS ver
  330. osver.dwOSVersionInfoSize = sizeof(osver);
  331. VERIFY(GetVersionEx(&osver));
  332. if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion >= 5))
  333. {
  334. //***** Windows 2000 *****
  335. // add template reg entry
  336. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_MICROSOFT_KEY, 0, KEY_CREATE_SUB_KEY, &hMicrosoftKey))
  337. {
  338. if (ERROR_SUCCESS == RegCreateKeyEx(hMicrosoftKey, REG_SHARED_TOOLS, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hSharedToolsKey, &dwDisposition))
  339. {
  340. if (ERROR_SUCCESS == RegCreateKeyEx(hSharedToolsKey, REG_MSINFO, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hMsinfoKey, &dwDisposition))
  341. {
  342. if (ERROR_SUCCESS == RegCreateKeyEx(hMsinfoKey, REG_TEMPLATES, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hTemplatesKey, &dwDisposition))
  343. {
  344. if (ERROR_SUCCESS == RegCreateKeyEx(hTemplatesKey, REG_IEINFO5, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hIeinfo5Key, &dwDisposition))
  345. {
  346. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION_KEY, 0, KEY_QUERY_VALUE, &hCurrentVersionKey))
  347. {
  348. dwType = REG_SZ;
  349. dwSize = MAX_PATH;
  350. if (ERROR_SUCCESS == RegQueryValueEx(hCurrentVersionKey, REG_COMMON_FILES_DIR, NULL, &dwType, (LPBYTE)strFullPath.GetBuffer(MAX_PATH), &dwSize))
  351. {
  352. strFullPath.ReleaseBuffer();
  353. strFullPath += _T('\\');
  354. strFullPath += OCX_FILE_IN_COMMON;
  355. if (strFullPath[0] == _T('"'))
  356. strFullPath = strFullPath.Right(strFullPath.GetLength() - 1);
  357. RegSetValueEx(hIeinfo5Key, NULL, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strFullPath, strFullPath.GetLength() * sizeof(TCHAR));
  358. }
  359. RegCloseKey(hCurrentVersionKey);
  360. }
  361. RegCloseKey(hIeinfo5Key);
  362. }
  363. RegCloseKey(hTemplatesKey);
  364. }
  365. RegCloseKey(hMsinfoKey);
  366. }
  367. RegCloseKey(hSharedToolsKey);
  368. }
  369. RegCloseKey(hMicrosoftKey);
  370. }
  371. // copy ieinfo5.mof to mof dir
  372. if (!strFullPath.IsEmpty() && false) //12/13/2000. a-sanka. do not compile mof.
  373. {
  374. WCHAR strPathMof[MAX_PATH];
  375. strMofPathSrc = strFullPath;
  376. nIndex = strMofPathSrc.ReverseFind(_T('\\'));
  377. strMofPathSrc = strMofPathSrc.Left(nIndex + 1);
  378. strMofPathSrc += MOF_FILE;
  379. if (strMofPathSrc[0] == _T('"'))
  380. strMofPathSrc = strMofPathSrc.Right(strMofPathSrc.GetLength() - 1);
  381. #ifdef UNICODE
  382. wsprintfW(strPathMof, L"%ls", strMofPathSrc);
  383. #else
  384. wsprintfW(strPathMof, L"%hs", strMofPathSrc);
  385. #endif
  386. HRESULT hrInit = CoInitialize(NULL);
  387. IMofCompiler * pMofComp;
  388. hr = CoCreateInstance(CLSID_MofCompiler, NULL, CLSCTX_INPROC_SERVER, IID_IMofCompiler, (void**)&pMofComp);
  389. if (SUCCEEDED(hr))
  390. {
  391. WBEM_COMPILE_STATUS_INFO Info;
  392. hr = pMofComp->CompileFile(strPathMof,NULL,NULL,NULL,NULL,WBEM_FLAG_AUTORECOVER,0,0,&Info);
  393. pMofComp->Release();
  394. }
  395. if (SUCCEEDED(hrInit))
  396. CoUninitialize();
  397. }
  398. }
  399. else
  400. {
  401. //***** NT4, Win 9x *****
  402. // Set all MSInfo category reg values for this extension
  403. strCatKey = REG_MSINFO_KEY;
  404. strCatKey += '\\';
  405. strCatKey += REG_CATEGORIES;
  406. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, strCatKey, 0, KEY_WRITE, &hCatKey))
  407. {
  408. WriteNode(hCatKey, REG_INTERNET_EXPLORER_6, IDS_INTERNET_EXPLORER_6, 1, 0x35);
  409. if (ERROR_SUCCESS == RegOpenKeyEx(hCatKey, REG_INTERNET_EXPLORER_6, 0, KEY_WRITE, &hIE6Key))
  410. {
  411. WriteNode(hIE6Key, REG_FILE_VERSIONS, IDS_FILE_VERSIONS, 2, 0x10);
  412. WriteNode(hIE6Key, REG_CONNECTIVITY, IDS_CONNECTIVITY, 3, 0x20);
  413. WriteNode(hIE6Key, REG_CACHE, IDS_CACHE, 4, 0x30);
  414. if (ERROR_SUCCESS == RegOpenKeyEx(hIE6Key, REG_CACHE, 0, KEY_WRITE, &hCacheKey))
  415. {
  416. WriteNode(hCacheKey, REG_OBJECT_LIST, IDS_OBJECT_LIST, 5, 0x10);
  417. RegCloseKey(hCacheKey);
  418. }
  419. WriteNode(hIE6Key, REG_CONTENT, IDS_CONTENT, 6, 0x40);
  420. if (ERROR_SUCCESS == RegOpenKeyEx(hIE6Key, REG_CONTENT, 0, KEY_WRITE, &hContentKey))
  421. {
  422. WriteNode(hContentKey, REG_PERSONAL_CERTIFICATES, IDS_PERSONAL_CERTIFICATES, 7, 0x10);
  423. WriteNode(hContentKey, REG_OTHER_PEOPLE_CERTIFICATES, IDS_OTHER_PEOPLE_CERTIFICATES, 8, 0x20);
  424. WriteNode(hContentKey, REG_PUBLISHERS, IDS_PUBLISHERS, 9, 0x30);
  425. RegCloseKey(hContentKey);
  426. }
  427. WriteNode(hIE6Key, REG_SECURITY, IDS_SECURITY, 10, 0x50);
  428. RegCloseKey(hIE6Key);
  429. }
  430. RegCloseKey(hCatKey);
  431. }
  432. // Add MSInfo tool reg values for IE Repair Tool
  433. strKey = REG_MSINFO_KEY;
  434. strKey += '\\';
  435. strKey += REG_TOOLS;
  436. strKey += '\\';
  437. strKey += REG_IE_REPAIR;
  438. if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, strKey, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRepairKey, &dwDisposition))
  439. {
  440. strValue.LoadString(IDS_IE_REPAIR_TOOL);
  441. RegSetValueEx(hRepairKey, NULL, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strValue, strValue.GetLength() + sizeof(TCHAR));
  442. strValue = GetIERepairToolCmdLine();
  443. RegSetValueEx(hRepairKey, REG_COMMAND, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strValue, strValue.GetLength() + sizeof(TCHAR));
  444. strValue.LoadString(IDS_RUNS_IE_REPAIR_TOOL);
  445. RegSetValueEx(hRepairKey, REG_DESCRIPTION, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strValue, strValue.GetLength() + sizeof(TCHAR));
  446. RegCloseKey(hRepairKey);
  447. }
  448. }
  449. return hr;
  450. }
  451. /////////////////////////////////////////////////////////////////////////////
  452. // DllUnregisterServer - Removes entries from the system registry
  453. STDAPI DllUnregisterServer(void)
  454. {
  455. AFX_MANAGE_STATE(_afxModuleAddrThis);
  456. OSVERSIONINFO osver;
  457. CString strKey;
  458. if (!AfxOleUnregisterTypeLib(_tlid /*, _wVerMajor, _wVerMinor*/))
  459. return ResultFromScode(SELFREG_E_TYPELIB);
  460. if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
  461. return ResultFromScode(SELFREG_E_CLASS);
  462. osver.dwOSVersionInfoSize = sizeof(osver);
  463. VERIFY(GetVersionEx(&osver));
  464. if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion >= 5))
  465. {
  466. // Windows 2000
  467. }
  468. else
  469. {
  470. // NT4, Win 9x
  471. // Remove all MSInfo category reg values for this extension
  472. strKey = REG_MSINFO_KEY;
  473. strKey += '\\';
  474. strKey += REG_CATEGORIES;
  475. strKey += '\\';
  476. strKey += REG_INTERNET_EXPLORER_6;
  477. RegDeleteKeyRecusive(HKEY_LOCAL_MACHINE, strKey);
  478. // Remove MSInfo tool reg values for IE Repair Tool
  479. strKey = REG_MSINFO_KEY;
  480. strKey += '\\';
  481. strKey += REG_TOOLS;
  482. strKey += '\\';
  483. strKey += REG_IE_REPAIR;
  484. RegDeleteKey(HKEY_LOCAL_MACHINE, strKey);
  485. }
  486. return NOERROR;
  487. }
  488. /////////////////////////////////////////////////////////////////////////////
  489. // GetTemplate - exported function for NT5 template dll
  490. DWORD __cdecl GetTemplate(void ** ppBuffer)
  491. {
  492. DWORD dwReturn = 0;
  493. TRY
  494. {
  495. dwReturn = theApp.AppGetTemplate(ppBuffer);
  496. }
  497. CATCH_ALL(e)
  498. {
  499. #ifdef DBG
  500. e->ReportError();
  501. #endif
  502. dwReturn = 0;
  503. }
  504. END_CATCH_ALL
  505. return dwReturn;
  506. }