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

// Msie.cpp : Implementation of CMsieApp and DLL registration.
#include "stdafx.h"
#include "Msie.h"
#include "regkeys.h"
#include "resdefs.h"
#include <wbemprov.h>
#include <AFXPRIV.H>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CMsieApp theApp;
const GUID CDECL BASED_CODE _tlid =
{ 0x25959bec, 0xe700, 0x11d2, { 0xa7, 0xaf, 0, 0xc0, 0x4f, 0x80, 0x62, 0 } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;
const LPCSTR CLSID_MSIE = "{25959BEF-E700-11D2-A7AF-00C04F806200}";
const LPCSTR IE_REPAIR_CMD = "rundll32 setupwbv.dll,IE6Maintenance \"%s\\Setup\\SETUP.EXE\" /g \"%s\\%s\"";
const LPCSTR OCX_FILE_IN_COMMON = "Microsoft Shared\\MSInfo\\ieinfo5.ocx";
const LPCSTR MOF_FILE_PATH = "%SystemRoot%\\System32\\WBEM\\MOF";
const LPCSTR MOF_FILE = "ieinfo5.mof";
const MAX_KEY_LENGTH = 256;
////////////////////////////////////////////////////////////////////////////
// CMsieApp::InitInstance - DLL initialization
BOOL CMsieApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
m_fTemplateLoaded = FALSE;
m_pTemplateInfo = NULL;
m_dwTemplateInfoLen = 0;
}
return bInit;
}
////////////////////////////////////////////////////////////////////////////
// CMsieApp::ExitInstance - DLL termination
int CMsieApp::ExitInstance()
{
if (m_pTemplateInfo != NULL)
{
delete m_pTemplateInfo;
m_pTemplateInfo = NULL;
}
return COleControlModule::ExitInstance();
}
//-----------------------------------------------------------------------------
// AppGetTemplate is the entry point for the app object from outside the DLL.
// It's called by the exported function GetTemplate. The reconstructed template
// file should be returned to the caller as a pointer in the pBuffer parameter.
//
// If a NULL pointer is passed for pBuffer, we are free to delete the internal
// buffer storing the template file.
//-----------------------------------------------------------------------------
DWORD CMsieApp::AppGetTemplate(void ** ppBuffer)
{
if (!m_fTemplateLoaded)
{
LoadTemplate();
m_fTemplateLoaded = TRUE;
}
if (ppBuffer == NULL)
{
if (m_pTemplateInfo)
delete m_pTemplateInfo;
m_pTemplateInfo = NULL;
m_dwTemplateInfoLen = 0;
m_fTemplateLoaded = FALSE;
return 0;
}
*ppBuffer = (void *)m_pTemplateInfo;
return m_dwTemplateInfoLen;
}
//-----------------------------------------------------------------------------
// This table of keywords is used during the reconstruction process. It matches
// exactly the table used during the conversion from NFT to resources, and it
// MUST NOT be modified, or the reconstructed information will be bogus.
//-----------------------------------------------------------------------------
#define KEYWORD_COUNT 19
char * KEYWORD_STRING[KEYWORD_COUNT] =
{
"node", "columns", "line", "field", "enumlines", "(", ")", "{", "}", ",",
"\"basic\"", "\"advanced\"", "\"BASIC\"", "\"ADVANCED\"", "\"static\"",
"\"LEXICAL\"", "\"VALUE\"", "\"NONE\"", "\"\""
};
//-----------------------------------------------------------------------------
// The LoadTemplate function needs to load the template information out of
// our resources, and create a buffer which contains the restored template
// file to return to our caller (through AppGetTemplate).
//-----------------------------------------------------------------------------
void CMsieApp::LoadTemplate()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMapWordToPtr mapNonLocalized;
HRSRC hrsrcNFN;
HGLOBAL hglbNFN;
unsigned char *pData;
WORD wID;
CString strToken, *pstrToken;
// In debug mode, we'll reconstruct the original template file for comparison.
/*#ifdef DBG
CFile fileRestore(_T("ie-restore.nft"), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite);
#endif*/
// Load the non-localized strings from the custom resource type and create
// a map of ID to strings. Because these are non-localized strings, they
// will not be stored as Unicode. Each item in the stream is a 2 byte word
// ID followed by a null-terminated string. A zero ID indicates the end of
// the stream.
hrsrcNFN = FindResource(AfxGetResourceHandle(), _T("#1"), _T("MSINonLocalizedTokens"));
hglbNFN = LoadResource(AfxGetResourceHandle(), hrsrcNFN);
pData = (unsigned char *)LockResource(hglbNFN);
while (pData && *((WORD UNALIGNED *)pData))
{
wID = (WORD)(((WORD)*pData++) << 8); // deal with the byte order explicitly to avoid
wID |= (WORD)*pData++; // endian problems.
pstrToken = new CString((char *)pData);
pData += strlen((char *)pData) + 1;
if (pstrToken)
mapNonLocalized.SetAt(wID, (void *)pstrToken);
}
// Load the binary stream of token identifiers into memory.
HRSRC hrsrcNFB = FindResource(AfxGetResourceHandle(), _T("#1"), _T("MSITemplateStream"));
HGLOBAL hglbNFB = LoadResource(AfxGetResourceHandle(), hrsrcNFB);
unsigned char *pStream = (unsigned char *) LockResource(hglbNFB);
if (pStream)
{
// The first DWORD in the stream is the size of the original text file. We'll
// use this to allocate our buffer to store the reconstituted file.
DWORD dwSize;
dwSize = ((DWORD)*pStream++) << 24;
dwSize |= ((DWORD)*pStream++) << 16;
dwSize |= ((DWORD)*pStream++) << 8;
dwSize |= ((DWORD)*pStream++);
// The size stored is for an Ansi text file. We need to adjust for the
// fact that our reconstituted file will be Unicode. We also want to add
// a word to the front of the stream to hold the Unicode file marker (so
// MSInfo can use the same functions to read a file or this stream).
dwSize *= sizeof(WCHAR); // adjust for Unicode
dwSize += sizeof(WORD); // add room for Unicode file marker
m_pTemplateInfo = new unsigned char[dwSize];
m_dwTemplateInfoLen = 0;
if (m_pTemplateInfo == NULL)
return;
// Write the Unicode file marker.
wID = 0xFEFF;
memcpy(&m_pTemplateInfo[m_dwTemplateInfoLen], (void *)&wID, sizeof(WORD));
m_dwTemplateInfoLen += sizeof(WORD);
// Process the stream a token at a time. For each new item in the stream, we
// process it as follows:
//
// 1. If ((byte & 0x80) == 0x00), use the byte to lookup a KEYWORD_STRING.
// 2. If ((byte & 0xC0) == 0x80), use the byte and the next byte as a word
// ID to lookup a non-localized token from mapNonLocalized.
// 3. Else ((byte & 0xC0) == 0xC0), use the byte and the next byte as a word
// ID to lookup a localized token from the resources of this DLL.
while (pStream && *pStream)
{
if ((*pStream & 0x80) == 0x00)
{
// A byte with the high bit clear refers to a keyword. Look up the keyword
// from the table, and add it to the restored file.
wID = (WORD)(((WORD)*pStream++) - 1); ASSERT(wID <= KEYWORD_COUNT);
if (wID <= KEYWORD_COUNT)
strToken = KEYWORD_STRING[wID];
}
else
{
wID = (WORD)(((WORD)*pStream++) << 8); // deal with the byte order explicitly to avoid
wID |= (WORD)*pStream++; // endian problems.
if ((wID & 0xC000) == 0x8000)
{
// A byte with the high bit set, but the next to high bit clear indicates
// the ID is actually a word, and should be used to get a non-localized
// string. Get the string out of the map we created and add it to the file.
if (mapNonLocalized.Lookup(((WORD)(wID & 0x7FFF)), (void *&)pstrToken))
strToken = *pstrToken;
else
ASSERT(FALSE);
}
else
{
// A byte with the two MSB set indicates that the ID is a word, and should
// be used to reference a localized string out of the string table in this
// module's resources. This string will be UNICODE.
VERIFY(strToken.LoadString((wID & 0x3FFF) + IDS_MSITEMPLATEBASE));
strToken = _T("\"") + strToken + _T("\"");
}
}
// Store the token on the end of our buffer. The data in this buffer must
// be Unicode, so we'll need to convert the string if necessary.
//v-stlowe if (m_dwTemplateInfoLen + strToken.GetLength() * sizeof(WCHAR) < dwSize)
if (m_dwTemplateInfoLen + strToken.GetLength() < dwSize)
{
// Converting to strToken to Unicode
WCHAR *pwchToken;
pwchToken = new WCHAR[strToken.GetLength() + 1];
//v-stlowe ::MultiByteToWideChar(CP_ACP, 0, strToken, -1, pwchToken, (strToken.GetLength() + 1) * sizeof(WCHAR));
USES_CONVERSION;
wcscpy(pwchToken,T2W((LPTSTR)(LPCTSTR)strToken));
// Copying Unicode string to buffer
memcpy(&m_pTemplateInfo[m_dwTemplateInfoLen], (void *)pwchToken, wcslen(pwchToken) * sizeof(WCHAR));
m_dwTemplateInfoLen += wcslen(pwchToken) * sizeof(WCHAR);
delete pwchToken;
/*memcpy(&m_pTemplateInfo[m_dwTemplateInfoLen],(void *) strToken.GetBuffer(strToken.GetLength()),strToken.GetLength());
strToken.ReleaseBuffer();*/
}
else
ASSERT(FALSE);
/*#ifdef DBG
if (strToken == CString(_T("}")) || strToken == CString(_T("{")) || strToken == CString(_T(")")))
strToken += CString(_T("\r\n"));
fileRestore.Write((void *)(LPCTSTR)strToken, strToken.GetLength() * sizeof(TCHAR));
#endif*/
}
}
// Delete the contents of the lookup table.
#ifdef DBG
CFile fileRestore(_T("test.nft"), CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite);
fileRestore.Write(m_pTemplateInfo,m_dwTemplateInfoLen);
#endif
for (POSITION pos = mapNonLocalized.GetStartPosition(); pos != NULL;)
{
mapNonLocalized.GetNextAssoc(pos, wID, (void *&)pstrToken);
if (pstrToken)
delete pstrToken;
}
}
////////////////////////////////////////////////////////////////////////////
// WriteNode - Helper function for writing an MSInfo node to the registry
void WriteNode(HKEY hKey, LPCTSTR pszSubKey, int idsDefault, DWORD dwView, DWORD dwRank)
{
HKEY hNewKey;
DWORD dwDisposition;
CString strDefault;
if (ERROR_SUCCESS == RegCreateKeyEx(hKey, pszSubKey, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hNewKey, &dwDisposition))
{
strDefault.LoadString(idsDefault);
RegSetValueEx(hNewKey, NULL, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strDefault, strDefault.GetLength() + sizeof(TCHAR));
RegSetValueEx(hNewKey, REG_CLSID, 0, REG_SZ, (const LPBYTE)CLSID_MSIE, strlen(CLSID_MSIE) + 1);
RegSetValueEx(hNewKey, REG_MSINFO_VIEW, 0, REG_BINARY, (const LPBYTE)&dwView, sizeof(DWORD));
RegSetValueEx(hNewKey, REG_RANK, 0, REG_BINARY, (const LPBYTE)&dwRank, sizeof(DWORD));
RegCloseKey(hNewKey);
}
}
////////////////////////////////////////////////////////////////////////////
// RegDeleteKeyRecusive - Helper function for deleting reg keys
DWORD RegDeleteKeyRecusive(HKEY hStartKey, LPCTSTR pKeyName)
{
DWORD dwRtn, dwSubKeyLength;
LPTSTR pSubKey = NULL;
TCHAR szSubKey[MAX_KEY_LENGTH]; // (256) this should be dynamic.
HKEY hKey;
// Do not allow NULL or empty key name
if ( pKeyName && lstrlen(pKeyName))
{
if( (dwRtn = RegOpenKeyEx(hStartKey, pKeyName, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey )) == ERROR_SUCCESS)
{
while (dwRtn == ERROR_SUCCESS)
{
dwSubKeyLength = MAX_KEY_LENGTH;
dwRtn=RegEnumKeyEx(
hKey,
0, // always index zero
szSubKey,
&dwSubKeyLength,
NULL,
NULL,
NULL,
NULL
);
if(dwRtn == ERROR_NO_MORE_ITEMS)
{
dwRtn = RegDeleteKey(hStartKey, pKeyName);
break;
}
else if(dwRtn == ERROR_SUCCESS)
dwRtn = RegDeleteKeyRecusive(hKey, szSubKey);
}
RegCloseKey(hKey);
// Do not save return code because error
// has already occurred
}
}
else
dwRtn = ERROR_BADKEY;
return dwRtn;
}
////////////////////////////////////////////////////////////////////////////
// GetIERepairToolCmdLine - Helper function for creating command line for
// launching IE Repair Tool.
CString GetIERepairToolCmdLine()
{
CString strRet, strIEPath, strIEPathExpanded, strWindowsPath, strRepairLog;
HKEY hKey;
DWORD cbData;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_IE_SETUP_KEY, 0, KEY_QUERY_VALUE, &hKey))
{
cbData = MAX_PATH;
RegQueryValueEx(hKey, REG_PATH, NULL, NULL, (LPBYTE)strIEPath.GetBuffer(MAX_PATH), &cbData);
strIEPath.ReleaseBuffer();
ExpandEnvironmentStrings(strIEPath, strIEPathExpanded.GetBuffer(MAX_PATH), MAX_PATH);
strIEPathExpanded.ReleaseBuffer();
RegCloseKey(hKey);
}
GetWindowsDirectory(strWindowsPath.GetBuffer(MAX_PATH), MAX_PATH);
strWindowsPath.ReleaseBuffer();
strRepairLog.LoadString(IDS_REPAIR_LOG);
strRet.Format((LPCTSTR) IE_REPAIR_CMD, strIEPathExpanded, strWindowsPath, strRepairLog);
return strRet;
}
/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
OSVERSIONINFO osver;
HKEY hCatKey, hIE6Key, hCacheKey, hContentKey, hRepairKey, hMsinfoKey, hTemplatesKey, hIeinfo5Key;
HKEY hMicrosoftKey, hSharedToolsKey, hCurrentVersionKey;
CString strCatKey, strKey, strValue, strFullPath, strMofPathSrc, strMofPathDest;
BYTE szBuffer[MAX_PATH];
DWORD dwDisposition, dwType, dwSize;
int nIndex;
HRESULT hr = S_OK;
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))
return ResultFromScode(SELFREG_E_CLASS);
// check OS ver
osver.dwOSVersionInfoSize = sizeof(osver);
VERIFY(GetVersionEx(&osver));
if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion >= 5))
{
//***** Windows 2000 *****
// add template reg entry
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_MICROSOFT_KEY, 0, KEY_CREATE_SUB_KEY, &hMicrosoftKey))
{
if (ERROR_SUCCESS == RegCreateKeyEx(hMicrosoftKey, REG_SHARED_TOOLS, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hSharedToolsKey, &dwDisposition))
{
if (ERROR_SUCCESS == RegCreateKeyEx(hSharedToolsKey, REG_MSINFO, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hMsinfoKey, &dwDisposition))
{
if (ERROR_SUCCESS == RegCreateKeyEx(hMsinfoKey, REG_TEMPLATES, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hTemplatesKey, &dwDisposition))
{
if (ERROR_SUCCESS == RegCreateKeyEx(hTemplatesKey, REG_IEINFO5, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hIeinfo5Key, &dwDisposition))
{
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION_KEY, 0, KEY_QUERY_VALUE, &hCurrentVersionKey))
{
dwType = REG_SZ;
dwSize = MAX_PATH;
if (ERROR_SUCCESS == RegQueryValueEx(hCurrentVersionKey, REG_COMMON_FILES_DIR, NULL, &dwType, (LPBYTE)strFullPath.GetBuffer(MAX_PATH), &dwSize))
{
strFullPath.ReleaseBuffer();
strFullPath += _T('\\');
strFullPath += OCX_FILE_IN_COMMON;
if (strFullPath[0] == _T('"'))
strFullPath = strFullPath.Right(strFullPath.GetLength() - 1);
RegSetValueEx(hIeinfo5Key, NULL, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strFullPath, strFullPath.GetLength() * sizeof(TCHAR));
}
RegCloseKey(hCurrentVersionKey);
}
RegCloseKey(hIeinfo5Key);
}
RegCloseKey(hTemplatesKey);
}
RegCloseKey(hMsinfoKey);
}
RegCloseKey(hSharedToolsKey);
}
RegCloseKey(hMicrosoftKey);
}
// copy ieinfo5.mof to mof dir
if (!strFullPath.IsEmpty() && false) //12/13/2000. a-sanka. do not compile mof.
{
WCHAR strPathMof[MAX_PATH];
strMofPathSrc = strFullPath;
nIndex = strMofPathSrc.ReverseFind(_T('\\'));
strMofPathSrc = strMofPathSrc.Left(nIndex + 1);
strMofPathSrc += MOF_FILE;
if (strMofPathSrc[0] == _T('"'))
strMofPathSrc = strMofPathSrc.Right(strMofPathSrc.GetLength() - 1);
#ifdef UNICODE
wsprintfW(strPathMof, L"%ls", strMofPathSrc);
#else
wsprintfW(strPathMof, L"%hs", strMofPathSrc);
#endif
HRESULT hrInit = CoInitialize(NULL);
IMofCompiler * pMofComp;
hr = CoCreateInstance(CLSID_MofCompiler, NULL, CLSCTX_INPROC_SERVER, IID_IMofCompiler, (void**)&pMofComp);
if (SUCCEEDED(hr))
{
WBEM_COMPILE_STATUS_INFO Info;
hr = pMofComp->CompileFile(strPathMof,NULL,NULL,NULL,NULL,WBEM_FLAG_AUTORECOVER,0,0,&Info);
pMofComp->Release();
}
if (SUCCEEDED(hrInit))
CoUninitialize();
}
}
else
{
//***** NT4, Win 9x *****
// Set all MSInfo category reg values for this extension
strCatKey = REG_MSINFO_KEY;
strCatKey += '\\';
strCatKey += REG_CATEGORIES;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, strCatKey, 0, KEY_WRITE, &hCatKey))
{
WriteNode(hCatKey, REG_INTERNET_EXPLORER_6, IDS_INTERNET_EXPLORER_6, 1, 0x35);
if (ERROR_SUCCESS == RegOpenKeyEx(hCatKey, REG_INTERNET_EXPLORER_6, 0, KEY_WRITE, &hIE6Key))
{
WriteNode(hIE6Key, REG_FILE_VERSIONS, IDS_FILE_VERSIONS, 2, 0x10);
WriteNode(hIE6Key, REG_CONNECTIVITY, IDS_CONNECTIVITY, 3, 0x20);
WriteNode(hIE6Key, REG_CACHE, IDS_CACHE, 4, 0x30);
if (ERROR_SUCCESS == RegOpenKeyEx(hIE6Key, REG_CACHE, 0, KEY_WRITE, &hCacheKey))
{
WriteNode(hCacheKey, REG_OBJECT_LIST, IDS_OBJECT_LIST, 5, 0x10);
RegCloseKey(hCacheKey);
}
WriteNode(hIE6Key, REG_CONTENT, IDS_CONTENT, 6, 0x40);
if (ERROR_SUCCESS == RegOpenKeyEx(hIE6Key, REG_CONTENT, 0, KEY_WRITE, &hContentKey))
{
WriteNode(hContentKey, REG_PERSONAL_CERTIFICATES, IDS_PERSONAL_CERTIFICATES, 7, 0x10);
WriteNode(hContentKey, REG_OTHER_PEOPLE_CERTIFICATES, IDS_OTHER_PEOPLE_CERTIFICATES, 8, 0x20);
WriteNode(hContentKey, REG_PUBLISHERS, IDS_PUBLISHERS, 9, 0x30);
RegCloseKey(hContentKey);
}
WriteNode(hIE6Key, REG_SECURITY, IDS_SECURITY, 10, 0x50);
RegCloseKey(hIE6Key);
}
RegCloseKey(hCatKey);
}
// Add MSInfo tool reg values for IE Repair Tool
strKey = REG_MSINFO_KEY;
strKey += '\\';
strKey += REG_TOOLS;
strKey += '\\';
strKey += REG_IE_REPAIR;
if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, strKey, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRepairKey, &dwDisposition))
{
strValue.LoadString(IDS_IE_REPAIR_TOOL);
RegSetValueEx(hRepairKey, NULL, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strValue, strValue.GetLength() + sizeof(TCHAR));
strValue = GetIERepairToolCmdLine();
RegSetValueEx(hRepairKey, REG_COMMAND, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strValue, strValue.GetLength() + sizeof(TCHAR));
strValue.LoadString(IDS_RUNS_IE_REPAIR_TOOL);
RegSetValueEx(hRepairKey, REG_DESCRIPTION, 0, REG_SZ, (const LPBYTE)(LPCTSTR)strValue, strValue.GetLength() + sizeof(TCHAR));
RegCloseKey(hRepairKey);
}
}
return hr;
}
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
AFX_MANAGE_STATE(_afxModuleAddrThis);
OSVERSIONINFO osver;
CString strKey;
if (!AfxOleUnregisterTypeLib(_tlid /*, _wVerMajor, _wVerMinor*/))
return ResultFromScode(SELFREG_E_TYPELIB);
if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))
return ResultFromScode(SELFREG_E_CLASS);
osver.dwOSVersionInfoSize = sizeof(osver);
VERIFY(GetVersionEx(&osver));
if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT) && (osver.dwMajorVersion >= 5))
{
// Windows 2000
}
else
{
// NT4, Win 9x
// Remove all MSInfo category reg values for this extension
strKey = REG_MSINFO_KEY;
strKey += '\\';
strKey += REG_CATEGORIES;
strKey += '\\';
strKey += REG_INTERNET_EXPLORER_6;
RegDeleteKeyRecusive(HKEY_LOCAL_MACHINE, strKey);
// Remove MSInfo tool reg values for IE Repair Tool
strKey = REG_MSINFO_KEY;
strKey += '\\';
strKey += REG_TOOLS;
strKey += '\\';
strKey += REG_IE_REPAIR;
RegDeleteKey(HKEY_LOCAL_MACHINE, strKey);
}
return NOERROR;
}
/////////////////////////////////////////////////////////////////////////////
// GetTemplate - exported function for NT5 template dll
DWORD __cdecl GetTemplate(void ** ppBuffer)
{
DWORD dwReturn = 0;
TRY
{
dwReturn = theApp.AppGetTemplate(ppBuffer);
}
CATCH_ALL(e)
{
#ifdef DBG
e->ReportError();
#endif
dwReturn = 0;
}
END_CATCH_ALL
return dwReturn;
}