2629 lines
88 KiB
C++
2629 lines
88 KiB
C++
#include "stdafx.h"
|
|
#include "guid.h"
|
|
#include "iadm.h"
|
|
#include "mdkey.h"
|
|
|
|
extern HANDLE g_MyModuleHandle;
|
|
extern int g_iPWS40OrBetterInstalled;
|
|
extern int g_iPWS10Installed;
|
|
extern int g_iVermeerPWS10Installed;
|
|
|
|
extern CHAR g_FullFileNamePathToSettingsFile[_MAX_PATH];
|
|
extern CHAR g_PWS10_Migration_Section_Name_AddReg[];
|
|
extern CHAR g_PWS40_Migration_Section_Name_AddReg[];
|
|
extern CHAR g_Migration_Section_Name_AddReg[];
|
|
|
|
extern CHAR g_PWS10_Migration_Section_Name_CopyFiles[];
|
|
extern CHAR g_PWS40_Migration_Section_Name_CopyFiles[];
|
|
extern char g_Migration_Section_Name_CopyFiles[];
|
|
|
|
extern MyLogFile g_MyLogFile;
|
|
|
|
int g_SectionCount = 0;
|
|
|
|
#define METABASE_BIN_FILENAME "Metabase.bin"
|
|
#define METABASE_BIN_BEFORE_CHANGE "kjhgfdsa.001"
|
|
#define METABASE_BIN_AFTER_CHANGE "kjhgfdsa.002"
|
|
|
|
#define REG_NETWORK_MSWEBSVR "Enum\\Network\\MSWEBSVR"
|
|
#define REG_HKLM_NETWORK_MSWEBSVR "HKLM\\Enum\\Network\\MSWEBSVR"
|
|
|
|
#define REG_PWS_40_UNINSTALL_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSIIS"
|
|
#define REG_HKLM_PWS_40_UNINSTALL_KEY "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\MSIIS"
|
|
|
|
// used to check if pws 4.0 is installed
|
|
#define REG_INETSTP "Software\\Microsoft\\INetStp"
|
|
#define REG_INETSTP_MAJORVERSION_STRINGVALUE "MajorVersion"
|
|
#define REG_INETSTP_INSTALLPATH_STRINGVALUE "InstallPath"
|
|
// used to check if pws 1.0 is installed
|
|
#define REG_WWWPARAMETERS "System\\CurrentControlSet\\Services\\W3Svc\\Parameters"
|
|
#define REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE "MajorVersion"
|
|
|
|
// used to check if vermeer pws 1.0 is installed
|
|
#define FILENAME_FRONTPG_INI "frontpg.ini"
|
|
#define FILENAME_FRONTPG_INI_SECTION "FrontPage 1.1"
|
|
#define FILENAME_FRONTPG_INI_KEY "PWSRoot"
|
|
|
|
// used for parsing the values in the .rc file
|
|
#define g_LoadString_token_delimiters ",;\t\n\r"
|
|
|
|
// regkey value for the metabase flag for doing unsecuredread
|
|
#define METABASEUNSECUREDREAD_VALUENAME "MetabaseUnSecuredRead"
|
|
|
|
// unattend answer file stuff for UNATTEND_TXT_PWS_SECTION section
|
|
#define UNATTEND_TXT_PWS_SECTION "InternetServer"
|
|
#define UNATTEND_TXT_PWS_METABASE_NEW "Win95MigrateDllMetabaseNew"
|
|
#define UNATTEND_TXT_PWS_METABASE_ORGINAL "Win95MigrateDllMetabaseOrg"
|
|
|
|
#define UNATTEND_TXT_FILES_TO_DELETE_SECTION "Win95MigrateDll_DeleteFilesOrDirs_IIS"
|
|
|
|
// Special key to say "hey, we need to do some special metabase stuff
|
|
// like: doing an AppDeleteRecoverable() on the metabase.
|
|
// we don't have to do AppDeleteRecoverable if MTS is migrated automagically.
|
|
//#define SPECIAL_METABASE_STUFF
|
|
|
|
int MyMessageBox(char [], char []);
|
|
int MySettingsFile_Write_PWS10(HANDLE);
|
|
int MySettingsFile_Write_PWS40(HANDLE);
|
|
int InstallInfSection(char szINFFilename[],char szSectionName[]);
|
|
|
|
void RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile);
|
|
int RecursivelyMoveRegFormatToInfFormat(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile);
|
|
int SetMetabaseToDoUnEncryptedRead(int iOnFlag);
|
|
|
|
|
|
typedef struct _QUEUECONTEXT {
|
|
HWND OwnerWindow;
|
|
DWORD MainThreadId;
|
|
HWND ProgressDialog;
|
|
HWND ProgressBar;
|
|
BOOL Cancelled;
|
|
PTSTR CurrentSourceName;
|
|
BOOL ScreenReader;
|
|
BOOL MessageBoxUp;
|
|
WPARAM PendingUiType;
|
|
PVOID PendingUiParameters;
|
|
UINT CancelReturnCode;
|
|
BOOL DialogKilled;
|
|
//
|
|
// If the SetupInitDefaultQueueCallbackEx is used, the caller can
|
|
// specify an alternate handler for progress. This is useful to
|
|
// get the default behavior for disk prompting, error handling, etc,
|
|
// but to provide a gas gauge embedded, say, in a wizard page.
|
|
//
|
|
// The alternate window is sent ProgressMsg once when the copy queue
|
|
// is started (wParam = 0. lParam = number of files to copy).
|
|
// It is then also sent once per file copied (wParam = 1. lParam = 0).
|
|
//
|
|
// NOTE: a silent installation (i.e., no progress UI) can be accomplished
|
|
// by specifying an AlternateProgressWindow handle of INVALID_HANDLE_VALUE.
|
|
//
|
|
HWND AlternateProgressWindow;
|
|
UINT ProgressMsg;
|
|
UINT NoToAllMask;
|
|
|
|
HANDLE UiThreadHandle;
|
|
|
|
#ifdef NOCANCEL_SUPPORT
|
|
BOOL AllowCancel;
|
|
#endif
|
|
|
|
} QUEUECONTEXT, *PQUEUECONTEXT;
|
|
|
|
|
|
|
|
int ReturnTrueIfPWS40_Installed(void)
|
|
{
|
|
iisDebugOut(_T("ReturnTrueIfPWS40_Installed. Start."));
|
|
int iReturn = FALSE;
|
|
|
|
// Check if pws 4.0 or better is installed.
|
|
DWORD rc = 0;
|
|
HKEY hKey = NULL;
|
|
|
|
DWORD dwType, cbData;
|
|
BYTE bData[1000];
|
|
cbData = 1000;
|
|
|
|
rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_INETSTP, &hKey);
|
|
if (rc == ERROR_SUCCESS)
|
|
{
|
|
// try open a particular value...
|
|
|
|
// Check if we can read the Major Version Value.
|
|
// try to query the value
|
|
rc = RegQueryValueEx(hKey,REG_INETSTP_MAJORVERSION_STRINGVALUE,NULL,&dwType,bData,&cbData);
|
|
if ( ERROR_SUCCESS == rc)
|
|
{iReturn = TRUE;}
|
|
}
|
|
else
|
|
{
|
|
SetLastError(rc);
|
|
}
|
|
|
|
if (hKey){RegCloseKey(hKey);}
|
|
iisDebugOut(_T("ReturnTrueIfPWS40_Installed. Return=%d. End."), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
int ReturnTrueIfVermeerPWS10_Installed(void)
|
|
{
|
|
iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Start."));
|
|
int iReturn = FALSE;
|
|
|
|
char szFrontpgIniFile[_MAX_PATH];
|
|
strcpy(szFrontpgIniFile, "");
|
|
if (0 == GetSystemDirectory(szFrontpgIniFile, sizeof(szFrontpgIniFile)))
|
|
{
|
|
// Error so write it out
|
|
SetupLogError_Wrap(LogSevError, "Call to GetSystemDirectory() Failed. GetLastError=%x.", GetLastError());
|
|
goto ReturnTrueIfVermeerPWS10_Installed_Exit;
|
|
}
|
|
else
|
|
{
|
|
AddPath(szFrontpgIniFile, FILENAME_FRONTPG_INI);
|
|
}
|
|
|
|
if (CheckIfFileExists(szFrontpgIniFile) == TRUE)
|
|
{
|
|
iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Found %s file. Check FrontPage 1.1/PWSRoot Section."), szFrontpgIniFile);
|
|
char buf[_MAX_PATH];
|
|
GetPrivateProfileString(FILENAME_FRONTPG_INI_SECTION, FILENAME_FRONTPG_INI_KEY, _T(""), buf, _MAX_PATH, szFrontpgIniFile);
|
|
if (*buf && CheckIfFileExists(buf))
|
|
{
|
|
// yes, vermeer frontpage's personal web server is installed
|
|
iReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Check FrontPage 1.1/PWSRoot Section references file %s. but it's not found so, Vermeer pws1.0 not installed."), buf);
|
|
}
|
|
}
|
|
|
|
ReturnTrueIfVermeerPWS10_Installed_Exit:
|
|
iisDebugOut(_T("ReturnTrueIfVermeerPWS10_Installed. Return=%d. End."), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
|
|
int ReturnTrueIfPWS10_Installed(void)
|
|
{
|
|
iisDebugOut(_T("ReturnTrueIfPWS10_Installed. Start."));
|
|
int iReturn = FALSE;
|
|
|
|
// For old win95 pws 1.0 check
|
|
// Check if we can get the w3svc\parameters key.
|
|
HKEY hKey = NULL;
|
|
DWORD rc = 0;
|
|
|
|
DWORD dwType, cbData;
|
|
BYTE bData[1000];
|
|
cbData = 1000;
|
|
|
|
rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_WWWPARAMETERS, &hKey);
|
|
if ( ERROR_SUCCESS != rc)
|
|
{
|
|
SetLastError (rc);
|
|
// if the key Does not exists pws 1.0a is not installed
|
|
goto ReturnTrueIfPWS10_Installed_Exit;
|
|
}
|
|
|
|
// Check if we can read the Major Version Value. Should be set to '\0' if pws 1.0
|
|
// try to query the value
|
|
rc = RegQueryValueEx(hKey,REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE,NULL,&dwType,bData,&cbData);
|
|
if ( ERROR_SUCCESS != rc)
|
|
{
|
|
// SetLastError (rc);
|
|
// if the key Does not exists pws 1.0a is not installed
|
|
//SetupLogError_Wrap(LogSevError, "Failed to Read Registry Value '%s' in Key '%s'. GetLastError()=%x",REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE, REG_WWWPARAMETERS, GetLastError());
|
|
//iisDebugOut(_T("Failed to Read Registry Value '%s' in Key '%s'. pws1.0a is not installed."),REG_WWWPARAMETERS_MAJORVERSION_STRINGVALUE,REG_WWWPARAMETERS);
|
|
goto ReturnTrueIfPWS10_Installed_Exit;
|
|
}
|
|
|
|
// Check if we can read the MajorVersion value should be set to '\0' if pws 1.0
|
|
if (bData[0] == '\0') {iReturn = TRUE;}
|
|
|
|
ReturnTrueIfPWS10_Installed_Exit:
|
|
if (hKey){RegCloseKey(hKey);}
|
|
iisDebugOut(_T("ReturnTrueIfPWS10_Installed. Return=%d. End."), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
int CheckIfPWS95Exists(void)
|
|
{
|
|
iisDebugOut(_T("CheckIfPWS95Exists. Start."));
|
|
int iReturn = FALSE;
|
|
|
|
// Check if this is pws 4.0 or better
|
|
if (ReturnTrueIfPWS40_Installed() == TRUE)
|
|
{
|
|
g_iPWS40OrBetterInstalled = TRUE;
|
|
iReturn = TRUE;
|
|
goto CheckIfPWS95Exists_Exit;
|
|
}
|
|
|
|
// Check if this is pws 1.0a
|
|
if (ReturnTrueIfPWS10_Installed() == TRUE)
|
|
{
|
|
iReturn = TRUE;
|
|
g_iPWS10Installed = TRUE;
|
|
goto CheckIfPWS95Exists_Exit;
|
|
}
|
|
|
|
// Check if this is Vermeer pws 1.0
|
|
if (ReturnTrueIfVermeerPWS10_Installed() == TRUE)
|
|
{
|
|
iReturn = TRUE;
|
|
g_iVermeerPWS10Installed = TRUE;
|
|
goto CheckIfPWS95Exists_Exit;
|
|
}
|
|
|
|
CheckIfPWS95Exists_Exit:
|
|
iisDebugOut(_T("CheckIfPWS95Exists. Return=%d. End."), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
void iisDebugOut( TCHAR *pszfmt, ...)
|
|
{
|
|
TCHAR acsString[1000];
|
|
TCHAR acsString2[1000];
|
|
|
|
va_list va;
|
|
va_start(va, pszfmt);
|
|
_vstprintf(acsString, pszfmt, va);
|
|
va_end(va);
|
|
|
|
#if DBG == 1 || DEBUG == 1 || _DEBUG == 1
|
|
_stprintf(acsString2, _T("%s"), acsString);
|
|
OutputDebugString(acsString2);
|
|
g_MyLogFile.LogFileWrite(acsString2);
|
|
#else // DBG == 0
|
|
_stprintf(acsString2, _T("%s"), acsString);
|
|
// no outputdebug string for fre builds
|
|
g_MyLogFile.LogFileWrite(acsString2);
|
|
#endif // DBG
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//*
|
|
//* purpose: TRUE if the file is opened, FALSE if the file does not exists.
|
|
//*
|
|
//***************************************************************************
|
|
int CheckIfFileExists(LPCTSTR szFile)
|
|
{
|
|
return (GetFileAttributes(szFile) != 0xFFFFFFFF);
|
|
}
|
|
|
|
BOOL isDirEmpty(LPCTSTR szDirName)
|
|
{
|
|
TCHAR szSearchString[MAX_PATH+1];
|
|
HANDLE hFileSearch;
|
|
WIN32_FIND_DATA wfdFindData;
|
|
BOOL bMoreFiles = TRUE;
|
|
|
|
//
|
|
// Now search for files
|
|
//
|
|
sprintf(szSearchString, _T("%s\\*.*"), szDirName);
|
|
|
|
hFileSearch = FindFirstFile(szSearchString, &wfdFindData);
|
|
while ((INVALID_HANDLE_VALUE != hFileSearch) && bMoreFiles)
|
|
{
|
|
if ((0 != lstrcmpi(wfdFindData.cFileName, _T("."))) &&
|
|
(0 != lstrcmpi(wfdFindData.cFileName, _T(".."))))
|
|
{
|
|
FindClose(hFileSearch);
|
|
return FALSE;
|
|
}
|
|
|
|
bMoreFiles = FindNextFile(hFileSearch, &wfdFindData);
|
|
}
|
|
|
|
if (INVALID_HANDLE_VALUE != hFileSearch)
|
|
{
|
|
FindClose(hFileSearch);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL RemoveAllDirsIfEmpty(LPCTSTR szTheDir)
|
|
{
|
|
TCHAR szDirCopy[_MAX_PATH];
|
|
DWORD retCode = GetFileAttributes(szTheDir);
|
|
_tcscpy(szDirCopy,szTheDir);
|
|
if (retCode == 0xFFFFFFFF)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if ((retCode & FILE_ATTRIBUTE_DIRECTORY))
|
|
{
|
|
if (TRUE == isDirEmpty(szDirCopy))
|
|
{
|
|
iisDebugOut(_T("RemoveDirectory:%s"),szDirCopy);
|
|
RemoveDirectory(szDirCopy);
|
|
// Get the next dir in...
|
|
// and see if it's empty
|
|
|
|
// strip off the filename
|
|
TCHAR * pTemp = strrchr(szDirCopy, '\\');
|
|
if (pTemp){*pTemp = '\0';}
|
|
RemoveAllDirsIfEmpty(szDirCopy);
|
|
|
|
// strip off the filename
|
|
pTemp = strrchr(szDirCopy, '\\');
|
|
if (pTemp){*pTemp = '\0';}
|
|
RemoveAllDirsIfEmpty(szDirCopy);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL InetDeleteFile(LPCTSTR szFileName)
|
|
{
|
|
// if file exists but DeleteFile() fails
|
|
if ( CheckIfFileExists(szFileName) && !(DeleteFile(szFileName)) )
|
|
{
|
|
// failed to delete it
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("InetDeleteFile:%s"),szFileName);
|
|
|
|
TCHAR szDrive_only[_MAX_DRIVE];
|
|
TCHAR szPath_only[_MAX_PATH];
|
|
TCHAR szTheDir[_MAX_PATH];
|
|
_tsplitpath(szFileName,szDrive_only,szPath_only,NULL,NULL);
|
|
|
|
_tcscpy(szTheDir, szDrive_only);
|
|
_tcscat(szTheDir, szPath_only);
|
|
|
|
// see if the directory is empty...
|
|
// if it is.. then remove it...
|
|
RemoveAllDirsIfEmpty(szTheDir);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL RecRemoveDir(LPCTSTR szName)
|
|
{
|
|
BOOL iRet = FALSE;
|
|
DWORD retCode;
|
|
WIN32_FIND_DATA FindFileData;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
TCHAR szSubDir[_MAX_PATH] = _T("");
|
|
TCHAR szDirName[_MAX_PATH] = _T("");
|
|
|
|
retCode = GetFileAttributes(szName);
|
|
|
|
if (retCode == 0xFFFFFFFF)
|
|
return FALSE;
|
|
|
|
if (!(retCode & FILE_ATTRIBUTE_DIRECTORY)) {
|
|
InetDeleteFile(szName);
|
|
return TRUE;
|
|
}
|
|
|
|
_stprintf(szDirName, _T("%s\\*"), szName);
|
|
hFile = FindFirstFile(szDirName, &FindFileData);
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
do {
|
|
if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 &&
|
|
_tcsicmp(FindFileData.cFileName, _T("..")) != 0 ) {
|
|
_stprintf(szSubDir, _T("%s\\%s"), szName, FindFileData.cFileName);
|
|
RecRemoveDir(szSubDir);
|
|
}
|
|
|
|
if ( !FindNextFile(hFile, &FindFileData) ) {
|
|
FindClose(hFile);
|
|
break;
|
|
}
|
|
} while (TRUE);
|
|
}
|
|
|
|
iRet = RemoveAllDirsIfEmpty(szName);
|
|
return iRet;
|
|
}
|
|
|
|
void MyDeleteLinkWildcard(TCHAR *szDir, TCHAR *szFileName)
|
|
{
|
|
WIN32_FIND_DATA FindFileData;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
TCHAR szFileToBeDeleted[_MAX_PATH];
|
|
|
|
_stprintf(szFileToBeDeleted, _T("%s\\%s"), szDir, szFileName);
|
|
|
|
hFile = FindFirstFile(szFileToBeDeleted, &FindFileData);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
do {
|
|
if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 && _tcsicmp(FindFileData.cFileName, _T("..")) != 0 )
|
|
{
|
|
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
// this is a directory, so let's skip it
|
|
}
|
|
else
|
|
{
|
|
// this is a file, so let's Delete it.
|
|
TCHAR szTempFileName[_MAX_PATH];
|
|
_stprintf(szTempFileName, _T("%s\\%s"), szDir, FindFileData.cFileName);
|
|
// set to normal attributes, so we can delete it
|
|
SetFileAttributes(szTempFileName, FILE_ATTRIBUTE_NORMAL);
|
|
// delete it, hopefully
|
|
InetDeleteFile(szTempFileName);
|
|
}
|
|
}
|
|
|
|
// get the next file
|
|
if ( !FindNextFile(hFile, &FindFileData) )
|
|
{
|
|
FindClose(hFile);
|
|
break;
|
|
}
|
|
} while (TRUE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//*
|
|
//* purpose: Write out our "settings" file which is just a setupapi .inf file
|
|
//* which will get installed on the WinNT side
|
|
//*
|
|
//***************************************************************************
|
|
int MySettingsFile_Write(void)
|
|
{
|
|
int iReturn = FALSE;
|
|
HANDLE hFile;
|
|
iisDebugOut(_T("MySettingsFile_Write. Start."));
|
|
|
|
// Get From the registry
|
|
// if pws 4.0 installed then get all that information
|
|
// and save it in the Settings file.
|
|
if (g_iPWS40OrBetterInstalled == TRUE)
|
|
{
|
|
strcpy(g_Migration_Section_Name_AddReg, g_PWS40_Migration_Section_Name_AddReg);
|
|
strcpy(g_Migration_Section_Name_CopyFiles, g_PWS40_Migration_Section_Name_CopyFiles);
|
|
}
|
|
else if (g_iPWS10Installed == TRUE)
|
|
{
|
|
strcpy(g_Migration_Section_Name_AddReg, g_PWS10_Migration_Section_Name_AddReg);
|
|
strcpy(g_Migration_Section_Name_CopyFiles, g_PWS10_Migration_Section_Name_CopyFiles);
|
|
}
|
|
|
|
if (g_iPWS40OrBetterInstalled || g_iPWS10Installed)
|
|
{
|
|
// Open existing file or create a new one.
|
|
if (g_FullFileNamePathToSettingsFile)
|
|
{
|
|
iisDebugOut(_T("MySettingsFile_Write. CreatingFile '%s'."), g_FullFileNamePathToSettingsFile);
|
|
hFile = CreateFile(g_FullFileNamePathToSettingsFile,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
if (g_iPWS40OrBetterInstalled == TRUE)
|
|
{
|
|
// Get all the pws4.0 registry stuff and save it in the settings file.
|
|
iReturn = MySettingsFile_Write_PWS40(hFile);
|
|
if (iReturn != TRUE) {SetupLogError_Wrap(LogSevError, "Failed to Write PWS40 Registry values to file '%s'.",g_FullFileNamePathToSettingsFile);}
|
|
|
|
// On PWS 4.0, We need to make sure to
|
|
// 1. Not copy over files/dirs in the inetsrv directory from pws 4.0
|
|
// 2. copy over all other files in the inetsrv directory for the user
|
|
// might have some controls and such that they created and want to keep.
|
|
|
|
// add deleted files
|
|
}
|
|
else if (g_iPWS10Installed == TRUE)
|
|
{
|
|
// if pws 1.0 installed then get all that information and save it in the Settings file.
|
|
iReturn = MySettingsFile_Write_PWS10(hFile);
|
|
if (iReturn != TRUE) {SetupLogError_Wrap(LogSevError, "Failed to Write PWS10 Registry values to file '%s'.",g_FullFileNamePathToSettingsFile);}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Failed to Create to file '%s'.",g_FullFileNamePathToSettingsFile);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "File handle Does not exist '%s'.",g_FullFileNamePathToSettingsFile);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("MySettingsFile_Write. Neither PWS 1.0 or 4.0 is currently installed, no upgraded required."));
|
|
}
|
|
|
|
if (hFile && hFile != INVALID_HANDLE_VALUE) {CloseHandle(hFile);hFile=NULL;}
|
|
iisDebugOut(_T("MySettingsFile_Write. End. Return = %d"), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
int AnswerFile_AppendDeletion(TCHAR * szFileNameOrPathToDelete,LPCSTR AnswerFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
CHAR szTempString[30];
|
|
CHAR szQuotedPath[_MAX_PATH];
|
|
|
|
if (!szFileNameOrPathToDelete)
|
|
{
|
|
goto AnswerFile_AppendDeletion_Exit;
|
|
}
|
|
// Open existing file or create a new one.
|
|
if (!AnswerFile)
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "File handle Does not exist '%s'.",AnswerFile);
|
|
goto AnswerFile_AppendDeletion_Exit;
|
|
}
|
|
|
|
if (CheckIfFileExists(AnswerFile) != TRUE)
|
|
{
|
|
iisDebugOut(_T("AnswerFile_AppendDeletion:file not exist...\n"));
|
|
goto AnswerFile_AppendDeletion_Exit;
|
|
}
|
|
|
|
sprintf(szTempString,"%d",g_SectionCount);
|
|
iisDebugOut(_T("AnswerFile_AppendDeletion:%s=%s\n"), szTempString,szFileNameOrPathToDelete);
|
|
sprintf(szQuotedPath, "\"%s\"",szFileNameOrPathToDelete);
|
|
if (0 == WritePrivateProfileString(UNATTEND_TXT_FILES_TO_DELETE_SECTION, szTempString, szQuotedPath, AnswerFile))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_FILES_TO_DELETE_SECTION, AnswerFile, GetLastError());
|
|
iisDebugOut(_T("Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x."), UNATTEND_TXT_FILES_TO_DELETE_SECTION, AnswerFile, GetLastError());
|
|
goto AnswerFile_AppendDeletion_Exit;
|
|
}
|
|
g_SectionCount++;
|
|
|
|
iReturn = TRUE;
|
|
|
|
AnswerFile_AppendDeletion_Exit:
|
|
iisDebugOut(_T("AnswerFile_AppendDeletion:end.ret=%d,%s\n"),iReturn,szFileNameOrPathToDelete);
|
|
return iReturn;
|
|
}
|
|
|
|
int AnswerFile_ReadSectionAndDoDelete(IN HINF AnswerFileHandle)
|
|
{
|
|
int iReturn = FALSE;
|
|
BOOL bFlag = FALSE;
|
|
INFCONTEXT Context;
|
|
DWORD dwRequiredSize = 0;
|
|
LPTSTR szLine = NULL;
|
|
DWORD retCode = 0;
|
|
|
|
iisDebugOut(_T("MySettingsFile_ReadSectionAndDoDelete:start\n"));
|
|
|
|
// go to the beginning of the section in the INF file
|
|
bFlag = SetupFindFirstLine(AnswerFileHandle,UNATTEND_TXT_FILES_TO_DELETE_SECTION, NULL, &Context);
|
|
if (!bFlag)
|
|
{
|
|
goto MySettingsFile_ReadSectionAndDoDelete_Exit;
|
|
}
|
|
|
|
// loop through the items in the section.
|
|
while (bFlag)
|
|
{
|
|
// get the size of the memory we need for this
|
|
bFlag = SetupGetLineText(&Context, NULL, NULL, NULL, NULL, 0, &dwRequiredSize);
|
|
|
|
// prepare the buffer to receive the line
|
|
szLine = (LPTSTR)GlobalAlloc( GPTR, dwRequiredSize * sizeof(TCHAR) );
|
|
if ( !szLine )
|
|
{
|
|
iisDebugOut(_T("err:Out of Memory"));
|
|
goto MySettingsFile_ReadSectionAndDoDelete_Exit;
|
|
}
|
|
|
|
// get the line from the inf file1
|
|
if (SetupGetLineText(&Context, NULL, NULL, NULL, szLine, dwRequiredSize, NULL) == FALSE)
|
|
{
|
|
iisDebugOut(_T("SetupGetLineText failed"));
|
|
goto MySettingsFile_ReadSectionAndDoDelete_Exit;
|
|
}
|
|
|
|
// For each of these entries do something
|
|
// Delete the file...
|
|
|
|
retCode = GetFileAttributes(szLine);
|
|
if (retCode != 0xFFFFFFFF)
|
|
{
|
|
iReturn = TRUE;
|
|
if (retCode & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
// it's a directory...recusively delete it
|
|
iisDebugOut(_T("RecRemoveDir:%s\n"),szLine);
|
|
RecRemoveDir(szLine);
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("InetDeleteFile:%s\n"),szLine);
|
|
InetDeleteFile(szLine);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("not found:%s, skipping delete\n"),szLine);
|
|
}
|
|
|
|
// find the next line in the section. If there is no next line it should return false
|
|
bFlag = SetupFindNextLine(&Context, &Context);
|
|
|
|
// free the temporary buffer
|
|
if (szLine) {GlobalFree(szLine);szLine=NULL;}
|
|
iReturn = TRUE;
|
|
}
|
|
|
|
MySettingsFile_ReadSectionAndDoDelete_Exit:
|
|
if (szLine) {GlobalFree(szLine);szLine=NULL;}
|
|
iisDebugOut(_T("MySettingsFile_ReadSectionAndDoDelete:end\n"));
|
|
return iReturn;
|
|
}
|
|
|
|
int MySettingsFile_Install(void)
|
|
{
|
|
int iReturn = 0;
|
|
iReturn = InstallInfSection(g_FullFileNamePathToSettingsFile, "DefaultInstall");
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//*
|
|
//* purpose:
|
|
//*
|
|
//***************************************************************************
|
|
LPWSTR MakeWideStrFromAnsi(LPSTR psz)
|
|
{
|
|
LPWSTR pwsz;
|
|
int i;
|
|
|
|
// arg checking.
|
|
if (!psz)
|
|
return NULL;
|
|
|
|
// compute the length
|
|
i = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
|
|
if (i <= 0) return NULL;
|
|
|
|
pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
|
|
|
|
if (!pwsz) return NULL;
|
|
MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
|
|
pwsz[i - 1] = 0;
|
|
return pwsz;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//*
|
|
//* purpose:
|
|
//*
|
|
//***************************************************************************
|
|
void MakePath(LPTSTR lpPath)
|
|
{
|
|
LPTSTR lpTmp;
|
|
lpTmp = CharPrev( lpPath, lpPath + _tcslen(lpPath));
|
|
|
|
// chop filename off
|
|
while ( (lpTmp > lpPath) && *lpTmp && (*lpTmp != '\\') )
|
|
lpTmp = CharPrev( lpPath, lpTmp );
|
|
|
|
if ( *CharPrev( lpPath, lpTmp ) != ':' )
|
|
*lpTmp = '\0';
|
|
else
|
|
*CharNext(lpTmp) = '\0';
|
|
return;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//*
|
|
//* purpose: add's filename onto path
|
|
//*
|
|
//***************************************************************************
|
|
void AddPath(LPTSTR szPath, LPCTSTR szName )
|
|
{
|
|
LPTSTR p = szPath;
|
|
|
|
// Find end of the string
|
|
while (*p){p = _tcsinc(p);}
|
|
|
|
// If no trailing backslash then add one
|
|
if (*(_tcsdec(szPath, p)) != _T('\\'))
|
|
{_tcscat(szPath, _T("\\"));}
|
|
|
|
// if there are spaces precluding szName, then skip
|
|
while ( *szName == ' ' ) szName = _tcsinc(szName);;
|
|
|
|
// Add new name to existing path string
|
|
_tcscat(szPath, szName);
|
|
}
|
|
|
|
|
|
|
|
// Prepare to read a value by finding the value's size.
|
|
LONG RegPrepareValue(HKEY hKey, LPCTSTR pchValueName, DWORD * pdwType,DWORD * pcbSize,BYTE ** ppbData )
|
|
{
|
|
LONG err = 0 ;
|
|
BYTE chDummy[2] ;
|
|
DWORD cbData = 0 ;
|
|
|
|
do
|
|
{
|
|
// Set the resulting buffer size to 0.
|
|
*pcbSize = 0 ;
|
|
*ppbData = NULL ;
|
|
|
|
err = ::RegQueryValueEx( hKey, (TCHAR *) pchValueName, 0, pdwType, chDummy, & cbData ) ;
|
|
|
|
// The only error we should get here is ERROR_MORE_DATA, but
|
|
// we may get no error if the value has no data.
|
|
if ( err == 0 )
|
|
{
|
|
cbData = sizeof (LONG) ; // Just a fudgy number
|
|
}
|
|
else
|
|
if ( err != ERROR_MORE_DATA )
|
|
break ;
|
|
|
|
// Allocate a buffer large enough for the data.
|
|
|
|
*ppbData = new BYTE [ (*pcbSize = cbData) + sizeof (LONG) ] ;
|
|
|
|
if ( *ppbData == NULL )
|
|
{
|
|
err = ERROR_NOT_ENOUGH_MEMORY ;
|
|
break ;
|
|
}
|
|
|
|
// Now that have a buffer, re-fetch the value.
|
|
|
|
err = ::RegQueryValueEx( hKey, (TCHAR *) pchValueName, 0, pdwType, *ppbData, pcbSize ) ;
|
|
|
|
} while ( FALSE ) ;
|
|
|
|
if ( err ) {delete [] *ppbData ;}
|
|
|
|
return err ;
|
|
}
|
|
|
|
|
|
|
|
int AddRegToInfIfExist_Dword(HKEY hRootKeyType,CHAR szRootKey[],CHAR szRootName[],HANDLE fAppendToFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
HKEY hOpen = NULL;
|
|
DWORD dwType;
|
|
DWORD cbData = 500;
|
|
BYTE bData[500];
|
|
|
|
CHAR szTheStringToWrite[2000];
|
|
DWORD dwBytesWritten = 0;
|
|
|
|
// Create the HKLM string for the output string
|
|
CHAR szThisKeyType[5];
|
|
strcpy(szThisKeyType, "HKLM");
|
|
if (hRootKeyType == HKEY_LOCAL_MACHINE) {strcpy(szThisKeyType, "HKLM");}
|
|
if (hRootKeyType == HKEY_CLASSES_ROOT) {strcpy(szThisKeyType, "HKCR");}
|
|
if (hRootKeyType == HKEY_CURRENT_USER) {strcpy(szThisKeyType, "HKCU");}
|
|
if (hRootKeyType == HKEY_USERS) {strcpy(szThisKeyType, "HKU");}
|
|
|
|
// try to open the key
|
|
if (ERROR_SUCCESS == RegOpenKey(hRootKeyType, szRootKey, &hOpen))
|
|
{
|
|
// try to query the value
|
|
DWORD dwData = 0;
|
|
DWORD dwDataSize = 0;
|
|
dwDataSize = sizeof (DWORD);
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hOpen,szRootName,NULL,&dwType,(LPBYTE) &dwData,&dwDataSize))
|
|
{
|
|
DWORD dwTheValue = 0;
|
|
dwTheValue = dwData;
|
|
|
|
// We got the value. so now let's write the darn thing out to the file.
|
|
//HKLM,"System\CurrentControlSet\Services\W3Svc\Parameters","MajorVersion",0x00010001,4
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00010001,%ld\r\n",szThisKeyType,szRootKey,szRootName,dwTheValue);
|
|
|
|
iisDebugOut(_T("AddRegToInfIfExist_Dword:%s."),szTheStringToWrite);
|
|
|
|
// write it to the file
|
|
if (fAppendToFile) {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
|
|
else {printf(szTheStringToWrite);}
|
|
|
|
iReturn = TRUE;
|
|
}
|
|
}
|
|
|
|
if (hOpen) {RegCloseKey(hOpen);}
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
This function can be used to recursively grab a whole key out
|
|
of the registry and write it to a setupapi style .inf file.
|
|
|
|
[version]
|
|
signature="$CHICAGO$"
|
|
advancedinf=2.0
|
|
|
|
[PWS10_Migrate_install]
|
|
AddReg=PWS10_Migrate_Reg
|
|
|
|
[PWS10_Migrate_Reg] (Creates this section)
|
|
HKLM,"System\CurrentControlSet\Services\InetInfo",,,""
|
|
HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters",,,""
|
|
HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","MaxPoolThreads",0x00000001,05
|
|
HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","MaxConcurrency",0x00000001,01
|
|
HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","ThreadTimeout",0x00000001,00,2
|
|
...
|
|
...
|
|
|
|
Here are the flags as defined in the setupapi.h file:
|
|
#define FLG_ADDREG_BINVALUETYPE ( 0x00000001 )
|
|
#define FLG_ADDREG_NOCLOBBER ( 0x00000002 )
|
|
#define FLG_ADDREG_DELVAL ( 0x00000004 )
|
|
#define FLG_ADDREG_APPEND ( 0x00000008 ) // Currently supported only for REG_MULTI_SZ values.
|
|
#define FLG_ADDREG_KEYONLY ( 0x00000010 ) // Just create the key, ignore value
|
|
#define FLG_ADDREG_OVERWRITEONLY ( 0x00000020 ) // Set only if value already exists
|
|
#define FLG_ADDREG_TYPE_SZ ( 0x00000000 )
|
|
#define FLG_ADDREG_TYPE_MULTI_SZ ( 0x00010000 )
|
|
#define FLG_ADDREG_TYPE_EXPAND_SZ ( 0x00020000 )
|
|
#define FLG_ADDREG_TYPE_BINARY ( 0x00000000 | FLG_ADDREG_BINVALUETYPE )
|
|
#define FLG_ADDREG_TYPE_DWORD ( 0x00010000 | FLG_ADDREG_BINVALUETYPE )
|
|
#define FLG_ADDREG_TYPE_NONE ( 0x00020000 | FLG_ADDREG_BINVALUETYPE )
|
|
#define FLG_ADDREG_TYPE_MASK ( 0xFFFF0000 | FLG_ADDREG_BINVALUETYPE )
|
|
*/
|
|
int RecursivelyMoveRegFormatToInfFormat(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
int iGotDefaultValue = FALSE;
|
|
|
|
// Stuff for getting values in our node
|
|
HKEY hKey = NULL;
|
|
DWORD rc = 0;
|
|
DWORD dwIndex =0, dwType, cbValueName, cbValue, nStrSize;
|
|
CHAR lpTemp[20], lpValueName[32], msg[512];
|
|
CHAR *strResult = NULL;
|
|
unsigned int i = 0;
|
|
union vEntry
|
|
{
|
|
DWORD dw; // REG_DWORD, REG_DWORD_LITTLE_ENDIAN
|
|
CHAR sz[256]; // REG_SZ
|
|
CHAR esz[256]; // REG_EXPAND_SZ
|
|
CHAR bin[1024]; // REG_BINARY
|
|
CHAR dwbig[4]; // REG_DWORD_BIG_ENDIAN
|
|
CHAR msz[2048]; // REG_MULTI_SZ
|
|
} vEntry1;
|
|
|
|
// Stuff for looping thru keys that we can see
|
|
HANDLE hHeap = NULL;
|
|
DWORD dwBufSize, nSubkeys, nSubkeyNameLen;
|
|
LPTSTR lpBuffer = NULL;
|
|
|
|
CHAR szThisKeyType[5];
|
|
CHAR szCompoundFromRootKey[1000];
|
|
CHAR szTheStringToWrite[2000];
|
|
DWORD dwBytesWritten = 0;
|
|
|
|
// Create the HKLM string for the output string
|
|
strcpy(szThisKeyType, "HKLM");
|
|
if (hRootKeyType == HKEY_LOCAL_MACHINE) {strcpy(szThisKeyType, "HKLM");}
|
|
if (hRootKeyType == HKEY_CLASSES_ROOT) {strcpy(szThisKeyType, "HKCR");}
|
|
if (hRootKeyType == HKEY_CURRENT_USER) {strcpy(szThisKeyType, "HKCU");}
|
|
if (hRootKeyType == HKEY_USERS) {strcpy(szThisKeyType, "HKU");}
|
|
|
|
// Get the szRootKey and work from there
|
|
rc = RegOpenKey(hRootKeyType, szRootKey, &hKey);
|
|
if (rc != ERROR_SUCCESS)
|
|
{
|
|
goto RecursivelyMoveRegFormatToInfFormat_Exit;
|
|
}
|
|
|
|
// Grab the "Default" Entry if there is one.
|
|
cbValue = sizeof(vEntry1);
|
|
rc = RegQueryValueEx(hKey, NULL, 0, &dwType, (LPBYTE) &vEntry1, &cbValue) ;
|
|
if ( ERROR_SUCCESS == rc)
|
|
{
|
|
if (vEntry1.sz)
|
|
{
|
|
iGotDefaultValue = TRUE;
|
|
strResult = (TCHAR *) vEntry1.sz;
|
|
// This can only be a string!
|
|
// from: System\\CurrentControlSet\\Services\\InetInfo
|
|
// Value = Something
|
|
// to: HKLM,"Software\Microsoft\InetSrv",,,"Something"
|
|
// ---------------------------------------------------
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",,,\"%s\"\r\n",szThisKeyType, szRootKey, strResult);
|
|
if (fAppendToFile)
|
|
{WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
|
|
else
|
|
{printf(szTheStringToWrite);}
|
|
}
|
|
}
|
|
// if there was no default entry, then just write the key without a default entry.
|
|
if (!iGotDefaultValue)
|
|
{
|
|
// to: HKLM,"Software\Microsoft\InetSrv",,0x00000010,"Something"
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",,0x00000010,\"%s\"\r\n",szThisKeyType, szRootKey, strResult);
|
|
if (fAppendToFile) {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
|
|
else {printf(szTheStringToWrite);}
|
|
}
|
|
|
|
// Now Enum all ValueNames under this
|
|
dwIndex = 0;
|
|
while (rc == ERROR_SUCCESS)
|
|
{
|
|
memset(msg, 0, sizeof(msg));
|
|
cbValueName = 32;
|
|
cbValue = sizeof(vEntry1);
|
|
rc = RegEnumValue( hKey, dwIndex++, lpValueName, &cbValueName, NULL, &dwType, (LPBYTE) &vEntry1, &cbValue );
|
|
if ( ERROR_SUCCESS == rc)
|
|
{
|
|
strcpy(szTheStringToWrite, "");
|
|
switch (dwType)
|
|
{
|
|
case REG_SZ:
|
|
// to: HKLM,"Software\Microsoft\InetSrv","SomethingName",0x00000000,"SomethingData"
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00000000,\"%s\"\r\n",szThisKeyType,szRootKey, lpValueName, vEntry1.sz);
|
|
break;
|
|
case REG_EXPAND_SZ:
|
|
// to: HKLM,"Software\Microsoft\InetSrv","SomethingName",0x00020000,"%windir%\SomethingData"
|
|
nStrSize = ExpandEnvironmentStrings(vEntry1.esz, msg, 512);
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00020000,\"%s\"\r\n",szThisKeyType,szRootKey, lpValueName, vEntry1.sz);
|
|
break;
|
|
case REG_MULTI_SZ:
|
|
// to: HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","ThreadTimeout",0x00000001,00,20
|
|
strcpy(msg, "");
|
|
for (i=0;i < cbValue; i++)
|
|
{
|
|
if (i==0){sprintf(lpTemp, "%02X", (BYTE) vEntry1.bin[i]);}
|
|
else{sprintf(lpTemp, ",%02X", (BYTE) vEntry1.bin[i]);}
|
|
strcat(msg, lpTemp);
|
|
}
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00000001,%s\r\n",szThisKeyType,szRootKey, lpValueName, msg);
|
|
break;
|
|
case REG_DWORD:
|
|
// to: HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","StartupServices",0x00010001,1
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00010001,%ld\r\n",szThisKeyType,szRootKey, lpValueName, vEntry1.dw);
|
|
break;
|
|
case REG_DWORD_BIG_ENDIAN:
|
|
case REG_BINARY:
|
|
// to: HKLM,"System\CurrentControlSet\Services\InetInfo\Parameters","MaxPoolThreads",0x00000001,05
|
|
strcpy(msg, "");
|
|
for (i=0;i < cbValue; i++)
|
|
{
|
|
if (i==0){sprintf(lpTemp, "%02X", (BYTE) vEntry1.bin[i]);}
|
|
else{sprintf(lpTemp, ",%02X", (BYTE) vEntry1.bin[i]);}
|
|
strcat(msg, lpTemp);
|
|
}
|
|
sprintf(szTheStringToWrite, "%s,\"%s\",\"%s\",0x00000001,%s\r\n",szThisKeyType,szRootKey, lpValueName, msg);
|
|
break;
|
|
default:
|
|
sprintf(szTheStringToWrite, "; Unknown data value for Key '%s', Value '%s'", szRootKey, lpValueName);
|
|
SetupLogError_Wrap(LogSevError, "Error Reading Registry Key '%s', Unknown data value for key '%s'.",szRootKey, lpValueName);
|
|
}
|
|
if (fAppendToFile) {WriteFile(fAppendToFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);}
|
|
else {printf(szTheStringToWrite);}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Now Recursively go thru the Sub keys
|
|
//
|
|
RegQueryInfoKey(hKey, NULL, NULL, NULL, &nSubkeys, &nSubkeyNameLen, NULL, NULL, NULL, NULL, NULL, NULL);
|
|
// Allocate memory
|
|
hHeap = GetProcessHeap();
|
|
lpBuffer = (CHAR *) HeapAlloc(hHeap, 0, ++nSubkeyNameLen);
|
|
if (lpBuffer)
|
|
{
|
|
// Enum thru the keys
|
|
for (dwIndex = 0; dwIndex < nSubkeys; dwIndex++)
|
|
{
|
|
dwBufSize = nSubkeyNameLen;
|
|
rc = RegEnumKeyEx(hKey, dwIndex, lpBuffer, &dwBufSize, NULL, NULL, NULL, NULL);
|
|
if ( ERROR_SUCCESS == rc)
|
|
{
|
|
strcpy(szCompoundFromRootKey, szRootKey);
|
|
strcat(szCompoundFromRootKey, "\\");
|
|
strcat(szCompoundFromRootKey, lpBuffer);
|
|
// Call this function again, but with the newly created key.
|
|
// and they'll tell they're friends, who will tell they're friends... it's amway!
|
|
RecursivelyMoveRegFormatToInfFormat(hRootKeyType, szCompoundFromRootKey, fAppendToFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set the flag to say, yes we did some work
|
|
iReturn = TRUE;
|
|
|
|
RecursivelyMoveRegFormatToInfFormat_Exit:
|
|
if (hKey){RegCloseKey(hKey);}
|
|
if (hHeap && lpBuffer){HeapFree(hHeap, 0, lpBuffer);}
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
// purpose: install an section in an .inf file
|
|
//-------------------------------------------------------------------
|
|
int InstallInfSection(char szINFFilename_Full[],char szSectionName[])
|
|
{
|
|
|
|
HWND Window = NULL;
|
|
PTSTR SourcePath = NULL;
|
|
HINF InfHandle = INVALID_HANDLE_VALUE;
|
|
HSPFILEQ FileQueue = INVALID_HANDLE_VALUE;
|
|
PQUEUECONTEXT QueueContext = NULL;
|
|
BOOL bReturn = FALSE;
|
|
BOOL bError = TRUE; // assume failure.
|
|
TCHAR ActualSection[1000];
|
|
DWORD ActualSectionLength;
|
|
TCHAR * pTemp = NULL;
|
|
iisDebugOut(_T("InstallInfSection(%s, [%s]). Start."),szINFFilename_Full,szSectionName);
|
|
|
|
//__try {
|
|
|
|
// Get the path to setup.exe and strip off filename so we only have the path
|
|
char szPath[_MAX_PATH];
|
|
|
|
// get the path only
|
|
strcpy(szPath,g_FullFileNamePathToSettingsFile);
|
|
|
|
// strip off the filename
|
|
pTemp = strrchr(szPath, '\\');
|
|
if (pTemp){*pTemp = '\0';}
|
|
|
|
// set it to the pointer
|
|
SourcePath = szPath;
|
|
pTemp = NULL;
|
|
pTemp = strrchr(SourcePath, '\\');
|
|
if (pTemp) {*pTemp = '\0';}
|
|
|
|
// Check if the file exists
|
|
if (CheckIfFileExists(szINFFilename_Full) == FALSE)
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "InstallInfSection() Error: Cannot Find the file '%s'. FAILURE.", szINFFilename_Full);
|
|
goto c0;
|
|
}
|
|
|
|
//
|
|
// Load the inf file and get the handle
|
|
//
|
|
InfHandle = SetupOpenInfFile(szINFFilename_Full, NULL, INF_STYLE_WIN4, NULL);
|
|
if(InfHandle == INVALID_HANDLE_VALUE)
|
|
{
|
|
if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupOpenInfFile(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
|
|
goto c1;
|
|
}
|
|
|
|
//
|
|
// See if there is an nt-specific section
|
|
//
|
|
SetupDiGetActualSectionToInstall(InfHandle,szSectionName,ActualSection,sizeof(ActualSection),&ActualSectionLength,NULL);
|
|
|
|
//
|
|
// Create a setup file queue and initialize the default queue callback.
|
|
//
|
|
FileQueue = SetupOpenFileQueue();
|
|
if(FileQueue == INVALID_HANDLE_VALUE)
|
|
{
|
|
if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupOpenFileQueue(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
|
|
goto c1;
|
|
}
|
|
|
|
//QueueContext = SetupInitDefaultQueueCallback(Window);
|
|
//if(!QueueContext) {goto c1;}
|
|
QueueContext = (PQUEUECONTEXT) SetupInitDefaultQueueCallbackEx(Window,NULL,0,0,0);
|
|
if(!QueueContext)
|
|
{
|
|
if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupInitDefaultQueueCallbackEx(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
|
|
goto c1;
|
|
}
|
|
QueueContext->PendingUiType = IDF_CHECKFIRST;
|
|
|
|
//
|
|
// Enqueue file operations for the section passed on the cmd line.
|
|
//
|
|
//SourcePath = NULL;
|
|
bReturn = SetupInstallFilesFromInfSection(InfHandle,NULL,FileQueue,ActualSection,SourcePath,SP_COPY_NEWER);
|
|
if(!bReturn)
|
|
{
|
|
if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupInstallFilesFromInfSection(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
|
|
goto c1;
|
|
}
|
|
|
|
//
|
|
// Commit file queue.
|
|
//
|
|
if(!SetupCommitFileQueue(Window, FileQueue, SetupDefaultQueueCallback, QueueContext))
|
|
{
|
|
if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupCommitFileQueue(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
|
|
goto c1;
|
|
}
|
|
|
|
//
|
|
// Perform non-file operations for the section passed on the cmd line.
|
|
//
|
|
bReturn = SetupInstallFromInfSection(Window,InfHandle,ActualSection,SPINST_ALL ^ SPINST_FILES,NULL,NULL,0,NULL,NULL,NULL,NULL);
|
|
if(!bReturn)
|
|
{
|
|
if (GetLastError() != ERROR_CANCELLED) {SetupLogError_Wrap(LogSevError, "SetupInstallFromInfSection(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);}
|
|
goto c1;
|
|
}
|
|
|
|
//
|
|
// Refresh the desktop.
|
|
//
|
|
SHChangeNotify(SHCNE_ASSOCCHANGED,SHCNF_FLUSHNOWAIT,0,0);
|
|
|
|
//
|
|
// If we get to here, then this routine has been successful.
|
|
//
|
|
bError = FALSE;
|
|
|
|
c1:
|
|
//
|
|
// If the bError was because the user cancelled, then we don't want to consider
|
|
// that as an bError (i.e., we don't want to give an bError popup later).
|
|
//
|
|
if(bError && (GetLastError() == ERROR_CANCELLED)) {bError = FALSE;}
|
|
if(QueueContext) {SetupTermDefaultQueueCallback(QueueContext);QueueContext = NULL;}
|
|
if(FileQueue != INVALID_HANDLE_VALUE) {SetupCloseFileQueue(FileQueue);FileQueue = INVALID_HANDLE_VALUE;}
|
|
if(InfHandle != INVALID_HANDLE_VALUE) {SetupCloseInfFile(InfHandle);InfHandle = INVALID_HANDLE_VALUE;}
|
|
|
|
c0: ;
|
|
|
|
// } __except(EXCEPTION_EXECUTE_HANDLER)
|
|
// {
|
|
// if(QueueContext) {SetupTermDefaultQueueCallback(QueueContext);}
|
|
// if(FileQueue != INVALID_HANDLE_VALUE) {SetupCloseFileQueue(FileQueue);}
|
|
// if(InfHandle != INVALID_HANDLE_VALUE) {SetupCloseInfFile(InfHandle);}
|
|
// }
|
|
|
|
//
|
|
// If the bError was because the user cancelled, then we don't want to consider
|
|
// that as an bError (i.e., we don't want to give an bError popup later).
|
|
//
|
|
if(bError && (GetLastError() == ERROR_CANCELLED)) {bError = FALSE;}
|
|
|
|
// Display installation failed message
|
|
if(bError)
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "InstallInfSection(), Filename='%s',Section='%s' FAILED.", szINFFilename_Full, szSectionName);
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("InstallInfSection(%s, [%s]). End."),szINFFilename_Full,szSectionName);
|
|
}
|
|
|
|
return bError;
|
|
}
|
|
|
|
int MySettingsFile_Write_PWS40(HANDLE hFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
int iEverythingIsKool = TRUE;
|
|
CHAR szTheStringToWrite[2000];
|
|
DWORD dwBytesWritten = 0;
|
|
TCHAR szMetabaseFullPath[_MAX_PATH];
|
|
|
|
// Registry variables
|
|
HKEY hKey = NULL;
|
|
DWORD dwType, cbData=1000,rc=0;
|
|
BYTE bData[1000];
|
|
|
|
char *token = NULL;
|
|
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. Start."));
|
|
|
|
if (hFile)
|
|
{
|
|
// ----------------------------
|
|
// Write the header information
|
|
// ----------------------------
|
|
strcpy(szTheStringToWrite, "[version]\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
strcpy(szTheStringToWrite, "signature=\"$CHICAGO$\"\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
strcpy(szTheStringToWrite, "advancedinf=2.0\r\n\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
// Create a [DefaultInstall] section which will get run
|
|
// ----------------------------
|
|
strcpy(szTheStringToWrite, "[DefaultInstall]\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "AddReg=%s\r\n", g_Migration_Section_Name_AddReg);
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
// sprintf(szTheStringToWrite, "CopyFiles=%s\r\n\r\n", g_Migration_Section_Name_CopyFiles);
|
|
// iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
// if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
// inetstp setup information
|
|
// AddReg information
|
|
// ----------------------------
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. Adding AddReg Section."));
|
|
sprintf(szTheStringToWrite, "[%s]\r\n", g_Migration_Section_Name_AddReg);
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
// Now, Get the ";" delimited list of HKLM registry values to read and write to our file.
|
|
char szSemiColonDelimitedList[1024];
|
|
strcpy(szSemiColonDelimitedList,"");
|
|
if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_PWS40_HKLM_REG_TO_MIGRATE, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
|
|
{
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. Err or LoadString retieval of IDS_PWS40_HKLM_REG_TO_MIGRATE, Defaulting with english registry values to copy over."));
|
|
strcpy(szSemiColonDelimitedList,"Software\\Microsoft\\InetStp;System\\CurrentControlSet\\Services\\InetInfo;System\\CurrentControlSet\\Services\\W3Svc;System\\CurrentControlSet\\Services\\ASP");
|
|
}
|
|
|
|
//LOOP THRU THE LIST
|
|
token = NULL;
|
|
token = strtok( szSemiColonDelimitedList, g_LoadString_token_delimiters);
|
|
while( token != NULL )
|
|
{
|
|
// we really should remove pre/post trailing spaces
|
|
|
|
// Grab this certain value("Software\\Microsoft\\INetStp")
|
|
// and recursively write it to our "settings" file
|
|
RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY_LOCAL_MACHINE,token,hFile);
|
|
|
|
// Get next token
|
|
token = strtok( NULL, g_LoadString_token_delimiters);
|
|
}
|
|
|
|
// Lookup these key,string value pairs and
|
|
// if they exist, add them to the inf file.
|
|
AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_common",hFile);
|
|
AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_www",hFile);
|
|
AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_pwmgr",hFile);
|
|
AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_doc_common",hFile);
|
|
AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_doc_pwmcore",hFile);
|
|
AddRegToInfIfExist_Dword(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Setup\\OC Manager\\Subcomponents","iis_doc_asp",hFile);
|
|
|
|
/*
|
|
// CopyFiles information
|
|
// ----------------------------
|
|
// Lookup the inetstp key to get the location of inetsrv directory.
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. CopyFiles Section. lookup registry inetstp."));
|
|
rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_INETSTP, &hKey);
|
|
if ( ERROR_SUCCESS != rc)
|
|
{
|
|
SetLastError (rc);
|
|
SetupLogError_Wrap(LogSevError, "Failed to open registry key %s GetLastError()=%x", REG_INETSTP, GetLastError());
|
|
// if the key does not exist, then hey, we won't be able to find
|
|
// the metabase, much less upgrade it!
|
|
// so let's bag out of here!
|
|
iEverythingIsKool = FALSE;
|
|
goto MySettingsFile_Write_PWS40_Exit;
|
|
}
|
|
|
|
// try to query the value
|
|
rc = RegQueryValueEx(hKey,REG_INETSTP_INSTALLPATH_STRINGVALUE,NULL,&dwType,bData,&cbData);
|
|
if ( ERROR_SUCCESS != rc)
|
|
{
|
|
SetLastError (rc);
|
|
SetupLogError_Wrap(LogSevError, "Failed to Read Registry key %s Value in Key '%s'. GetLastError()=%x", REG_INETSTP_INSTALLPATH_STRINGVALUE, REG_INETSTP, GetLastError());
|
|
iEverythingIsKool = FALSE;
|
|
goto MySettingsFile_Write_PWS40_Exit;
|
|
}
|
|
// We have the value, copy it to our string
|
|
// Should look something like this "c:\\windows\system\inetsrv"
|
|
_tcscpy(szMetabaseFullPath, (const char *) bData);
|
|
// Now add on the metadata.dll part
|
|
AddPath(szMetabaseFullPath, METADATA_DLL_FILENAME);
|
|
|
|
// Check if it exists.
|
|
if (CheckIfFileExists(szMetabaseFullPath) != TRUE)
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "File not found FAILURE. '%s'.", szMetabaseFullPath);
|
|
iEverythingIsKool = FALSE;
|
|
goto MySettingsFile_Write_PWS40_Exit;
|
|
}
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. CopyFiles Section. Check if file exist %s = TRUE", szMetabaseFullPath));
|
|
|
|
// Now we need to copy this file from
|
|
// the system dir to the system32 directory.
|
|
// So... let's create an entry in our "settings" file
|
|
// to do it upon installation.
|
|
//[Section1]
|
|
//Metabase.Dll
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. Adding CopyFiles supporting Sections."));
|
|
sprintf(szTheStringToWrite, "\r\n[%s]\r\n", g_Migration_Section_Name_CopyFiles);
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "%s\r\n\r\n", METADATA_DLL_FILENAME);
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
//[DestinationDirs]
|
|
//Section1=11
|
|
sprintf(szTheStringToWrite, "[DestinationDirs]\r\n");
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "%s=11 ;System on win95, System32 on WinNT\r\n\r\n", g_Migration_Section_Name_CopyFiles);
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
//[SourceDisksNames]
|
|
//1="Setup Files",,,system
|
|
sprintf(szTheStringToWrite, "[SourceDisksNames]\r\n");
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "1= \"Files copied from win95\\system dir\",,,System\r\n\r\n");
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
//[SourceDisksFiles]
|
|
//Metabase.Dll=1
|
|
sprintf(szTheStringToWrite, "[SourceDisksFiles]\r\n");
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "%s=1\r\n\r\n", METADATA_DLL_FILENAME);
|
|
iReturn = WriteFile( hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
*/
|
|
|
|
iReturn = iEverythingIsKool;
|
|
}
|
|
|
|
|
|
//MySettingsFile_Write_PWS40_Exit:
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS40. End. Return=%d"), iReturn);
|
|
if (hKey){RegCloseKey(hKey);}
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
int MySettingsFile_Write_PWS10(HANDLE hFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
int iEverythingIsKool = TRUE;
|
|
CHAR szTheStringToWrite[2000];
|
|
DWORD dwBytesWritten;
|
|
char *token = NULL;
|
|
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS10. Start."));
|
|
if (hFile)
|
|
{
|
|
strcpy(szTheStringToWrite, "[version]\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
strcpy(szTheStringToWrite, "signature=\"$CHICAGO$\"\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
strcpy(szTheStringToWrite, "advancedinf=2.0\r\n\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
// Create a [DefaultInstall] section which will get run
|
|
strcpy(szTheStringToWrite, "[DefaultInstall]\r\n");
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "AddReg=%s\r\n\r\n", g_Migration_Section_Name_AddReg);
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
sprintf(szTheStringToWrite, "[%s]\r\n", g_Migration_Section_Name_AddReg);
|
|
iReturn = WriteFile(hFile,szTheStringToWrite,strlen(szTheStringToWrite),&dwBytesWritten,NULL);
|
|
if (!iReturn) {iEverythingIsKool = FALSE;}
|
|
|
|
// Now, Get the ";" delimited list of HKLM registry values to read and write to our file.
|
|
char szSemiColonDelimitedList[1024];
|
|
strcpy(szSemiColonDelimitedList,"");
|
|
if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_PWS10_HKLM_REG_TO_MIGRATE, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
|
|
{
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS10. Err or LoadString retieval of IDS_PWS10_HKLM_REG_TO_MIGRATE, Defaulting with english registry values to copy over."));
|
|
strcpy(szSemiColonDelimitedList, "Software\\Microsoft\\INetStp;System\\CurrentControlSet\\Services\\InetInfo;System\\CurrentControlSet\\Services\\MsFtpSvc;System\\CurrentControlSet\\Services\\W3Svc");
|
|
}
|
|
|
|
//LOOP THRU THE LIST
|
|
token = NULL;
|
|
token = strtok( szSemiColonDelimitedList, g_LoadString_token_delimiters);
|
|
while( token != NULL )
|
|
{
|
|
// we really should remove pre/post trailing spaces
|
|
|
|
// Grab this certain value("Software\\Microsoft\\INetStp")
|
|
// and recursively write it to our "settings" file
|
|
RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY_LOCAL_MACHINE,token,hFile);
|
|
|
|
// Get next token
|
|
token = strtok( NULL, g_LoadString_token_delimiters);
|
|
}
|
|
|
|
// set the return value to
|
|
iReturn = iEverythingIsKool;
|
|
}
|
|
iisDebugOut(_T("MySettingsFile_Write_PWS10. End. Return=%d"), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
int MyMessageBox(char szMsg[], char szFileName[])
|
|
{
|
|
char szTempErrString[200];
|
|
sprintf(szTempErrString, szMsg, szFileName);
|
|
return MessageBox(NULL, szTempErrString, "PWS Migration Dll Failure", MB_OK);
|
|
}
|
|
|
|
// handle the [HKEY_LOCAL_MACHINE\Enum\Network\MSWEBSVR] reg key
|
|
void HandleSpecialRegKey(void)
|
|
{
|
|
int iReturn = FALSE;
|
|
|
|
HKEY hKey = NULL;
|
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REG_NETWORK_MSWEBSVR, &hKey))
|
|
{iReturn = TRUE;}
|
|
if (hKey){RegCloseKey(hKey);}
|
|
|
|
if (iReturn == TRUE)
|
|
{
|
|
// Write to the Migrate.inf file that we are "Handling" this registry settings.
|
|
iisDebugOut(_T("HandleSpecialRegKey. Write Entry to Migrate.inf file."));
|
|
iReturn = MigInf_AddHandledRegistry(REG_HKLM_NETWORK_MSWEBSVR, NULL);
|
|
if (iReturn != TRUE) {SetupLogError_Wrap(LogSevWarning, "Warning: MigInf_AddHandledRegistry() FAILED.");}
|
|
|
|
//
|
|
// Important: Write memory version of migrate.inf to disk
|
|
//
|
|
if (!MigInf_WriteInfToDisk())
|
|
{
|
|
iReturn = GetLastError();
|
|
SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.err=0x%x",iReturn);
|
|
}
|
|
}
|
|
|
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REG_PWS_40_UNINSTALL_KEY, &hKey))
|
|
{iReturn = TRUE;}
|
|
if (hKey){RegCloseKey(hKey);}
|
|
|
|
if (iReturn == TRUE)
|
|
{
|
|
// Write to the Migrate.inf file that we are "Handling" this registry settings.
|
|
iisDebugOut(_T("HandleSpecialRegKey. Write Entry2 to Migrate.inf file."));
|
|
iReturn = MigInf_AddHandledRegistry(REG_HKLM_PWS_40_UNINSTALL_KEY, NULL);
|
|
if (iReturn != TRUE) {SetupLogError_Wrap(LogSevWarning, "Warning: MigInf_AddHandledRegistry2() FAILED.");}
|
|
|
|
//
|
|
// Important: Write memory version of migrate.inf to disk
|
|
//
|
|
if (!MigInf_WriteInfToDisk())
|
|
{
|
|
iReturn = GetLastError();
|
|
SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk2() FAILED.err=0x%x",iReturn);
|
|
}
|
|
}
|
|
}
|
|
|
|
void RecursivelyMoveRegFormatToInfFormat_Wrap1(HKEY hRootKeyType, CHAR szRootKey[], HANDLE fAppendToFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
char szTheFullKey[512];
|
|
char szTheMask[50];
|
|
|
|
// use this stuff for the migrate.inf file
|
|
strcpy(szTheMask, "HKLM\\%s");
|
|
if (hRootKeyType == HKEY_LOCAL_MACHINE) {strcpy(szTheMask, "HKLM\\%s");}
|
|
if (hRootKeyType == HKEY_CLASSES_ROOT) {strcpy(szTheMask, "HKCR\\%s");}
|
|
if (hRootKeyType == HKEY_CURRENT_USER) {strcpy(szTheMask, "HKCU\\%s");}
|
|
if (hRootKeyType == HKEY_USERS) {strcpy(szTheMask, "HKU\\%s");}
|
|
sprintf(szTheFullKey, szTheMask, szRootKey);
|
|
iisDebugOut(_T("RecursivelyMoveRegFormatToInfFormat_Wrap1. %s"), szTheFullKey);
|
|
|
|
// Call the real recursive function
|
|
iReturn = RecursivelyMoveRegFormatToInfFormat(hRootKeyType, szRootKey, fAppendToFile);
|
|
|
|
//
|
|
// Write handled for every setting we are processing. Because this
|
|
// DLL supports only some of the values in the Desktop key, we must
|
|
// be very specific as to which values are actually handled. If
|
|
// your DLL handles all registry values AND subkeys of a registry
|
|
// key, you can specify NULL in the second parameter of
|
|
// MigInf_AddHandledRegistry.
|
|
//
|
|
if (iReturn == TRUE)
|
|
{
|
|
// Write to the Migrate.inf file that we are "Handling" this registry settings.
|
|
iisDebugOut(_T("RecursivelyMoveRegFormatToInfFormat_Wrap1. Write Entry to Migrate.inf file."));
|
|
iReturn = MigInf_AddHandledRegistry(szTheFullKey, NULL);
|
|
if (iReturn != TRUE) {SetupLogError_Wrap(LogSevWarning, "Warning: MigInf_AddHandledRegistry() FAILED.");}
|
|
|
|
//
|
|
// Important: Write memory version of migrate.inf to disk
|
|
//
|
|
if (!MigInf_WriteInfToDisk())
|
|
{
|
|
iReturn = GetLastError();
|
|
SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.err=0x%x",iReturn);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int ReturnImportantDirs(void)
|
|
{
|
|
int iReturn = FALSE;
|
|
if (g_iPWS40OrBetterInstalled == TRUE)
|
|
{
|
|
// do something
|
|
}
|
|
else if (g_iPWS10Installed == TRUE)
|
|
{
|
|
// do something else
|
|
}
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
void SetupLogError_Wrap(IN LogSeverity TheSeverityErr, TCHAR *MessageString, ...)
|
|
{
|
|
TCHAR acsString[1000];
|
|
TCHAR acsString2[1000];
|
|
|
|
va_list va;
|
|
va_start(va, MessageString);
|
|
_vstprintf(acsString, MessageString, va);
|
|
va_end(va);
|
|
|
|
// Append on Our modules information.
|
|
_stprintf(acsString2, _T("SetupLogError: %s"), acsString);
|
|
iisDebugOut(acsString2);
|
|
|
|
_stprintf(acsString2, _T("[PWS Migration DLL]:%s%s"), g_MyLogFile.m_szLogPreLineInfo, acsString);
|
|
SetupLogError(acsString2, TheSeverityErr);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
int SetMetabaseToDoUnEncryptedRead(int iOnFlag)
|
|
{
|
|
int iReturn = FALSE;
|
|
|
|
DWORD rc = 0;
|
|
HKEY hKey = NULL;
|
|
DWORD dwResult = 0;
|
|
DWORD DontCare;
|
|
rc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, REG_INETSTP, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, &DontCare);
|
|
if (rc != ERROR_SUCCESS)
|
|
{
|
|
SetLastError(rc);
|
|
goto SetMetabaseToDoUnEncryptedRead_Exit;
|
|
}
|
|
|
|
dwResult = 1;
|
|
rc = RegSetValueEx(hKey, METABASEUNSECUREDREAD_VALUENAME, 0, REG_DWORD, (const BYTE *) &dwResult, sizeof dwResult);
|
|
if (rc != ERROR_SUCCESS)
|
|
{
|
|
SetLastError(rc);
|
|
goto SetMetabaseToDoUnEncryptedRead_Exit;
|
|
}
|
|
|
|
iReturn = TRUE;
|
|
|
|
SetMetabaseToDoUnEncryptedRead_Exit:
|
|
if (hKey){RegCloseKey(hKey);}
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
void DeleteMetabaseSchemaNode(void)
|
|
{
|
|
CMDKey cmdKey;
|
|
cmdKey.OpenNode(_T("/"));
|
|
if ( (METADATA_HANDLE) cmdKey )
|
|
{
|
|
iisDebugOut(_T("MyUpgradeTasks.DeleteNode /Schema.Start."));
|
|
cmdKey.DeleteNode(_T("Schema"));
|
|
cmdKey.Close();
|
|
iisDebugOut(_T("MyUpgradeTasks.DeleteNode /Schema.End."));
|
|
}
|
|
return;
|
|
}
|
|
|
|
BOOL MyDeleteLink(LPTSTR lpszShortcut)
|
|
{
|
|
TCHAR szFile[_MAX_PATH];
|
|
SHFILEOPSTRUCT fos;
|
|
|
|
ZeroMemory(szFile, sizeof(szFile));
|
|
_tcscpy(szFile, lpszShortcut);
|
|
|
|
iisDebugOut(_T("MyDeleteLink(): %s.\n"), szFile);
|
|
|
|
if (CheckIfFileExists(szFile))
|
|
{
|
|
ZeroMemory(&fos, sizeof(fos));
|
|
fos.hwnd = NULL;
|
|
fos.wFunc = FO_DELETE;
|
|
fos.pFrom = szFile;
|
|
fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
|
|
if (SHFileOperation(&fos) != 0)
|
|
{
|
|
iisDebugOut(_T("MyDeleteLink(): SHFileOperation FAILED\n"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//iisDebugOutSafeParams((_T("MyDeleteLink(): CheckIfFileExists(%1!s!) = FALSE FAILURE\n"), szFile));
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void MyDeleteItem(LPCTSTR szGroupName, LPCTSTR szAppName)
|
|
{
|
|
TCHAR szPath[_MAX_PATH];
|
|
|
|
MyGetGroupPath(szGroupName, szPath);
|
|
_tcscat(szPath, _T("\\"));
|
|
_tcscat(szPath, szAppName);
|
|
_tcscat(szPath, _T(".lnk"));
|
|
|
|
MyDeleteLink(szPath);
|
|
|
|
// try to remove items added by AddURLShortcutItem()
|
|
MyGetGroupPath(szGroupName, szPath);
|
|
_tcscat(szPath, _T("\\"));
|
|
_tcscat(szPath, szAppName);
|
|
_tcscat(szPath, _T(".url"));
|
|
|
|
MyDeleteLink(szPath);
|
|
|
|
if (MyIsGroupEmpty(szGroupName)) {MyDeleteGroup(szGroupName);}
|
|
}
|
|
|
|
void MyGetGroupPath(LPCTSTR szGroupName, LPTSTR szPath)
|
|
{
|
|
int nLen = 0;
|
|
LPITEMIDLIST pidlPrograms;
|
|
|
|
if (SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_PROGRAMS, &pidlPrograms) != NOERROR)
|
|
{
|
|
if (SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAMS, &pidlPrograms) != NOERROR)
|
|
{iisDebugOut(_T("MyGetGroupPath() SHGetSpecialFolderLocation FAILED\n"));}
|
|
}
|
|
|
|
if (SHGetPathFromIDList(pidlPrograms, szPath) != TRUE)
|
|
{iisDebugOut(_T("MyGetGroupPath() SHGetPathFromIDList FAILED\n"));}
|
|
|
|
nLen = _tcslen(szPath);
|
|
if (szGroupName)
|
|
{
|
|
if (szPath[nLen-1] != _T('\\')){_tcscat(szPath, _T("\\"));}
|
|
_tcscat(szPath, szGroupName);
|
|
}
|
|
|
|
//iisDebugOut(_T("MyGetGroupPath(%s). Returns %s.\n"), szGroupName, szPath);
|
|
return;
|
|
}
|
|
|
|
|
|
BOOL MyIsGroupEmpty(LPCTSTR szGroupName)
|
|
{
|
|
TCHAR szPath[MAX_PATH];
|
|
TCHAR szFile[MAX_PATH];
|
|
WIN32_FIND_DATA FindData;
|
|
HANDLE hFind;
|
|
BOOL bFindFile = TRUE;
|
|
BOOL fReturn = TRUE;
|
|
|
|
MyGetGroupPath(szGroupName, szPath);
|
|
|
|
_tcscpy(szFile, szPath);
|
|
_tcscat(szFile, _T("\\*.*"));
|
|
|
|
hFind = FindFirstFile(szFile, &FindData);
|
|
while((INVALID_HANDLE_VALUE != hFind) && bFindFile)
|
|
{
|
|
if(*(FindData.cFileName) != _T('.'))
|
|
{
|
|
fReturn = FALSE;
|
|
break;
|
|
}
|
|
|
|
//find the next file
|
|
bFindFile = FindNextFile(hFind, &FindData);
|
|
}
|
|
FindClose(hFind);
|
|
|
|
return fReturn;
|
|
}
|
|
|
|
|
|
BOOL MyDeleteGroup(LPCTSTR szGroupName)
|
|
{
|
|
BOOL fResult;
|
|
TCHAR szPath[MAX_PATH];
|
|
TCHAR szFile[MAX_PATH];
|
|
SHFILEOPSTRUCT fos;
|
|
WIN32_FIND_DATA FindData;
|
|
HANDLE hFind;
|
|
BOOL bFindFile = TRUE;
|
|
|
|
MyGetGroupPath(szGroupName, szPath);
|
|
|
|
//we can't remove a directory that is not empty, so we need to empty this one
|
|
|
|
_tcscpy(szFile, szPath);
|
|
_tcscat(szFile, _T("\\*.*"));
|
|
|
|
ZeroMemory(&fos, sizeof(fos));
|
|
fos.hwnd = NULL;
|
|
fos.wFunc = FO_DELETE;
|
|
fos.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
|
|
|
|
hFind = FindFirstFile(szFile, &FindData);
|
|
while((INVALID_HANDLE_VALUE != hFind) && bFindFile)
|
|
{
|
|
if(*(FindData.cFileName) != _T('.'))
|
|
{
|
|
//copy the path and file name to our temp buffer
|
|
memset( (PVOID)szFile, 0, sizeof(szFile));
|
|
_tcscpy(szFile, szPath);
|
|
_tcscat(szFile, _T("\\"));
|
|
_tcscat(szFile, FindData.cFileName);
|
|
//add a second NULL because SHFileOperation is looking for this
|
|
_tcscat(szFile, _T("\0"));
|
|
|
|
//delete the file
|
|
fos.pFrom = szFile;
|
|
if (SHFileOperation(&fos) != 0)
|
|
{iisDebugOut(_T("MyDeleteGroup(): SHFileOperation FAILED\n"));}
|
|
}
|
|
|
|
//find the next file
|
|
bFindFile = FindNextFile(hFind, &FindData);
|
|
}
|
|
FindClose(hFind);
|
|
|
|
fResult = RemoveDirectory(szPath);
|
|
if (fResult) {SHChangeNotify(SHCNE_RMDIR, SHCNF_PATH, szPath, 0);}
|
|
return(fResult);
|
|
}
|
|
|
|
|
|
#define PWS_SHUTDOWN_EVENT "Inet_shutdown"
|
|
BOOL W95ShutdownW3SVC(void)
|
|
{
|
|
HANDLE hEvent;
|
|
|
|
hEvent = CreateEvent(NULL, TRUE, FALSE, _T(PWS_SHUTDOWN_EVENT));
|
|
if ( hEvent == NULL )
|
|
{return(TRUE);}
|
|
|
|
if ( GetLastError() == ERROR_ALREADY_EXISTS )
|
|
{SetEvent( hEvent );}
|
|
|
|
CloseHandle(hEvent);
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
typedef void (*pFunctionIISDLL)(CHAR *szSectionName);
|
|
|
|
int Call_IIS_DLL_INF_Section(CHAR *szSectionName)
|
|
{
|
|
int iReturn = FALSE;
|
|
HINSTANCE hDll = NULL;
|
|
pFunctionIISDLL pMyFunctionPointer = NULL;
|
|
|
|
TCHAR szSystemDir[_MAX_PATH];
|
|
TCHAR szFullPath[_MAX_PATH];
|
|
|
|
// get the c:\winnt\system32 dir
|
|
if (0 == GetSystemDirectory(szSystemDir, _MAX_PATH))
|
|
{
|
|
iisDebugOut(_T("Call_IIS_DLL_INF_Section(%s).GetSystemDirectory FAILED."),szSectionName);
|
|
goto Call_IIS_DLL_INF_Section_Exit;
|
|
}
|
|
|
|
// Tack on the setup\iis.dll subdir and filename
|
|
sprintf(szFullPath, "%s\\setup\\iis.dll",szSystemDir);
|
|
|
|
// Check if the file exists
|
|
if (TRUE != CheckIfFileExists(szFullPath))
|
|
{
|
|
iisDebugOut(_T("Call_IIS_DLL_INF_Section.CheckIfFileExists(%s) FAILED."),szFullPath);
|
|
goto Call_IIS_DLL_INF_Section_Exit;
|
|
}
|
|
|
|
// Try to load the module,dll,ocx.
|
|
hDll = LoadLibraryEx(szFullPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
|
|
if (!hDll)
|
|
{
|
|
iisDebugOut(_T("Call_IIS_DLL_INF_Section.LoadLibraryEx(%s) FAILED."),szFullPath);
|
|
goto Call_IIS_DLL_INF_Section_Exit;
|
|
}
|
|
|
|
// get the function
|
|
pMyFunctionPointer = (pFunctionIISDLL) GetProcAddress( hDll, "ProcessInfSection");
|
|
if (pMyFunctionPointer)
|
|
{
|
|
// we have the function.. let's call it.
|
|
iisDebugOut(_T("Call_IIS_DLL_INF_Section.Calling function [ProcessInfSection] Now...start"));
|
|
(*pMyFunctionPointer)(szSectionName);
|
|
iisDebugOut(_T("Call_IIS_DLL_INF_Section.Calling function [ProcessInfSection] Now...end"));
|
|
iReturn = TRUE;
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("Call_IIS_DLL_INF_Section.GetProcAddress(ProcessInfSection) FAILED."));
|
|
}
|
|
|
|
Call_IIS_DLL_INF_Section_Exit:
|
|
if (hDll){FreeLibrary(hDll);}
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
int GetInetSrvDir(CHAR *szOutputThisFullPath)
|
|
{
|
|
int iEverythingIsKool = TRUE;
|
|
TCHAR szMetabaseFullPath[_MAX_PATH];
|
|
|
|
// Registry variables
|
|
HKEY hKey = NULL;
|
|
DWORD dwType, cbData=1000,rc=0;
|
|
BYTE bData[1000];
|
|
|
|
// CopyFiles information
|
|
// ----------------------------
|
|
// Lookup the inetstp key to get the location of inetsrv directory.
|
|
iisDebugOut(_T("GetInetSrvDir. lookup registry inetstp."));
|
|
rc = RegOpenKey(HKEY_LOCAL_MACHINE, REG_INETSTP, &hKey);
|
|
if ( ERROR_SUCCESS != rc)
|
|
{
|
|
SetLastError (rc);
|
|
SetupLogError_Wrap(LogSevError, "Failed to open registry key %s GetLastError()=%x", REG_INETSTP, GetLastError());
|
|
// if the key does not exist, then hey, we won't be able to find
|
|
// the metabase, much less upgrade it!
|
|
// so let's bag out of here!
|
|
iEverythingIsKool = FALSE;
|
|
goto GetInetSrvDir_Exit;
|
|
}
|
|
|
|
// try to query the value
|
|
rc = RegQueryValueEx(hKey,REG_INETSTP_INSTALLPATH_STRINGVALUE,NULL,&dwType,bData,&cbData);
|
|
if ( ERROR_SUCCESS != rc)
|
|
{
|
|
SetLastError (rc);
|
|
SetupLogError_Wrap(LogSevError, "Failed to Read Registry key %s Value in Key '%s'. GetLastError()=%x", REG_INETSTP_INSTALLPATH_STRINGVALUE, REG_INETSTP, GetLastError());
|
|
iEverythingIsKool = FALSE;
|
|
goto GetInetSrvDir_Exit;
|
|
}
|
|
// We have the value, copy it to our string
|
|
// Should look something like this "c:\\windows\system\inetsrv"
|
|
_tcscpy(szMetabaseFullPath, (const char *) bData);
|
|
// we only want the path part, so copy that to the output string
|
|
_tcscpy(szOutputThisFullPath, szMetabaseFullPath);
|
|
|
|
iEverythingIsKool = TRUE;
|
|
iisDebugOut(_T("GetInetSrvDir. Check if file exist %s = TRUE"), szMetabaseFullPath);
|
|
|
|
GetInetSrvDir_Exit:
|
|
if (hKey){RegCloseKey(hKey);}
|
|
return iEverythingIsKool;
|
|
}
|
|
|
|
|
|
int MyUpgradeTasks(LPCSTR AnswerFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
HANDLE hFile;
|
|
TCHAR szQuotedPath[_MAX_PATH];
|
|
TCHAR szMyInetsrvDir[_MAX_PATH];
|
|
TCHAR szFullMetadataPath[_MAX_PATH];
|
|
TCHAR szNewFileName[_MAX_PATH];
|
|
int iDoTheSwap = FALSE;
|
|
iisDebugOut(_T("MyUpgradeTasks. Start."));
|
|
|
|
// if this is pws 1.0, then hey, we don't need to do anything
|
|
// other than copy over the registry, so just get out of here.
|
|
if (g_iPWS10Installed == TRUE) {goto MyUpgradeTasks_Exit;}
|
|
|
|
// if this is pws 4.0 then we
|
|
// need to take the iis 4.0 metabase and do certain things to it:
|
|
// 1. Call DeleteApp
|
|
if (g_iPWS40OrBetterInstalled == TRUE)
|
|
{
|
|
// Facts:
|
|
// 1. win95 doesn't have security, so the encrypted stuff in metabase on win95
|
|
// is not encrypted.
|
|
// 2. NT does have security, so the encrypted stuff in the metabase is read/write
|
|
// as encrypted automatically, within the metabase code.
|
|
//
|
|
// problem:
|
|
// 1. If we are migrating the metabase from pws 4.0 on win95, then there is
|
|
// a bunch of encrypted keys in the metabase which aren't encrypted and
|
|
// we need a way to tell the metabase that it needs to read the data
|
|
// as "not encrypted" data. it's okay to write it out as encrypted, but
|
|
// it's not cool to read the "not encrypted" data as encrypted.
|
|
//
|
|
// Solution:
|
|
// 1. Set the registry stuff:
|
|
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\INetStp
|
|
// MetabaseUnSecuredRead= (DWORD) 1 or 0
|
|
// 1= Yes, metabase, please read your stuff our of the metabase as unsecured.
|
|
// 2= No, Metabase, read your stuff out of the metabase like you normally do.
|
|
// The noexistance of the key is equal to MetabaseUnSecuredRead=0
|
|
|
|
// Create a special key in the registry.
|
|
if (SetMetabaseToDoUnEncryptedRead(TRUE) != TRUE)
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Unable to set Metabase (MetabaseUnSecuredRead flag) on. PWS 4.0 metabase will not be Migrated. FAILER.");
|
|
goto MyUpgradeTasks_Exit;
|
|
}
|
|
|
|
// try to call the AppDeleteRecoverable() function in the metabase.
|
|
// Which will tell the metabase to prepare to disconnect itself from
|
|
// Transaction Server and save all it's data to it's dat file.
|
|
/*
|
|
#ifdef SPECIAL_METABASE_STUFF
|
|
if (TRUE != AppDeleteRecoverable_Wrap("LM/W3SVC"))
|
|
{
|
|
// Set to true anyway, because the user could be re-running this.
|
|
iReturn = TRUE;
|
|
SetupLogError_Wrap(LogSevError, "Call to AppDeleteRecoverable_Wrap() FAILED.");
|
|
goto MyUpgradeTasks_Exit;
|
|
}
|
|
#endif
|
|
*/
|
|
|
|
// Before changing the metabase.bin file
|
|
// let's save it somewhere.
|
|
|
|
// 1. Get the %windir%\system\inetsrv directory where metabase.bin lives.
|
|
// 2. copy that metabase.bin file to "anothername".
|
|
_tcscpy(szMyInetsrvDir, _T(""));
|
|
if (TRUE == GetInetSrvDir(szMyInetsrvDir))
|
|
{
|
|
_tcscpy(szFullMetadataPath, szMyInetsrvDir);
|
|
AddPath(szFullMetadataPath, METABASE_BIN_FILENAME);
|
|
// Check if it exists.
|
|
if (CheckIfFileExists(szFullMetadataPath) == TRUE)
|
|
{iDoTheSwap = TRUE;}
|
|
if (TRUE == iDoTheSwap)
|
|
{
|
|
_tcscpy(szNewFileName, szMyInetsrvDir);
|
|
AddPath(szNewFileName, METABASE_BIN_BEFORE_CHANGE);
|
|
|
|
// Delete any that already exists.
|
|
if (CheckIfFileExists(szNewFileName) == TRUE){DeleteFile(szNewFileName);}
|
|
|
|
iisDebugOut(_T("Calling WritePrivateProfileString.%s."), AnswerFile);
|
|
sprintf(szQuotedPath, "\"%s\"",szFullMetadataPath);
|
|
if (0 == WritePrivateProfileString(UNATTEND_TXT_PWS_SECTION, UNATTEND_TXT_PWS_METABASE_ORGINAL, szQuotedPath, AnswerFile))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_PWS_METABASE_ORGINAL, AnswerFile, GetLastError());
|
|
}
|
|
|
|
// Copy Metadata.bin to anothername
|
|
if (0 == CopyFile(szFullMetadataPath, szNewFileName, FALSE))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. from=s%,to=%s. GetLastError=%x.", szFullMetadataPath, szNewFileName, GetLastError());
|
|
iDoTheSwap = FALSE;
|
|
}
|
|
}
|
|
}
|
|
// 3. change the metabase.bin
|
|
// Delete the "Schema" node
|
|
DeleteMetabaseSchemaNode();
|
|
|
|
// 4. stop the web server
|
|
// 5. rename metabase.bin to "asdfghjk.002"
|
|
// 6. rename "asdfghjk.001" to metabase.bin
|
|
// 7. this way if setup is cancelled, then they will still have a win95/98 web server that works!
|
|
if (TRUE == iDoTheSwap)
|
|
{
|
|
// Stop the web server...
|
|
W95ShutdownW3SVC();
|
|
W95ShutdownIISADMIN();
|
|
|
|
_tcscpy(szFullMetadataPath, szMyInetsrvDir);
|
|
AddPath(szFullMetadataPath, METABASE_BIN_FILENAME);
|
|
// Check if it exists.
|
|
if (CheckIfFileExists(szFullMetadataPath) == TRUE)
|
|
{
|
|
// rename metadata.bin to somethingelsenew
|
|
_tcscpy(szNewFileName, szMyInetsrvDir);
|
|
AddPath(szNewFileName, METABASE_BIN_AFTER_CHANGE);
|
|
// Delete any that already exists.
|
|
if (CheckIfFileExists(szNewFileName) == TRUE){DeleteFile(szNewFileName);}
|
|
// Copy Metadata.bin to anothername
|
|
if (0 == CopyFile(szFullMetadataPath, szNewFileName, FALSE))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. from=s%,to=%s. GetLastError=%x.", szFullMetadataPath, szNewFileName, GetLastError());
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("Calling WritePrivateProfileString.%s."), AnswerFile);
|
|
sprintf(szQuotedPath, "\"%s\"",szNewFileName);
|
|
if (0 == WritePrivateProfileString(UNATTEND_TXT_PWS_SECTION, UNATTEND_TXT_PWS_METABASE_NEW, szQuotedPath, AnswerFile))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Failed to WritePrivateProfileString Section=%s, in File %s. GetLastError=%x.", UNATTEND_TXT_PWS_METABASE_NEW, AnswerFile, GetLastError());
|
|
}
|
|
|
|
// rename old backedupname to metadata.bin
|
|
_tcscpy(szNewFileName, szMyInetsrvDir);
|
|
AddPath(szNewFileName, METABASE_BIN_BEFORE_CHANGE);
|
|
|
|
// Delete any that already exists.
|
|
if (CheckIfFileExists(szFullMetadataPath) == TRUE){DeleteFile(szFullMetadataPath);}
|
|
|
|
// Copy anothername to Metadata.bin
|
|
if (0 == CopyFile(szNewFileName, szFullMetadataPath, FALSE))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. from=s%,to=%s. GetLastError=%x.", szNewFileName, szFullMetadataPath, GetLastError());
|
|
}
|
|
else
|
|
{
|
|
// Delete the anothername old file
|
|
DeleteFile(szNewFileName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// we've gotten this far, things must be good.
|
|
iReturn = TRUE;
|
|
}
|
|
|
|
MyUpgradeTasks_Exit:
|
|
iisDebugOut(_T("MyUpgradeTasks. End. Return = %d"), iReturn);
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
#define IISADMIN_SHUTDOWN_EVENT "Internet_infosvc_as_exe"
|
|
BOOL W95ShutdownIISADMIN(void)
|
|
{
|
|
DWORD i;
|
|
HANDLE hEvent;
|
|
|
|
hEvent = CreateEvent(NULL, TRUE, FALSE, _T(IISADMIN_SHUTDOWN_EVENT));
|
|
if ( hEvent == NULL ) {
|
|
return(TRUE);
|
|
}
|
|
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
|
|
SetEvent( hEvent );
|
|
}
|
|
CloseHandle(hEvent);
|
|
for (i=0; i < 20; i++)
|
|
{
|
|
hEvent = CreateEvent(NULL, TRUE, FALSE, _T(IISADMIN_SHUTDOWN_EVENT));
|
|
if ( hEvent != NULL ) {
|
|
DWORD err = GetLastError();
|
|
CloseHandle(hEvent);
|
|
|
|
if ( err == ERROR_ALREADY_EXISTS ) {
|
|
Sleep(500);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
int CheckFrontPageINI(void)
|
|
{
|
|
int iReturn = FALSE;
|
|
char szWindowsDir[_MAX_PATH];
|
|
char szFullPathedFilename[_MAX_PATH];
|
|
char szFrontPageINIFilename[] = "frontpg.ini\0";
|
|
|
|
strcpy(szWindowsDir, "");
|
|
if (0 == GetWindowsDirectory(szWindowsDir, sizeof(szWindowsDir)))
|
|
{
|
|
// Error so write it out
|
|
SetupLogError_Wrap(LogSevError, "Call to GetWindowsDirectory() Failed. GetLastError=%x.", GetLastError());
|
|
goto CheckFrontPageINI_Exit;
|
|
}
|
|
|
|
// copy our settings file to this directory.
|
|
strcpy(szFullPathedFilename, szWindowsDir);
|
|
AddPath(szFullPathedFilename, szFrontPageINIFilename);
|
|
iReturn = CheckIfFileExists(szFullPathedFilename);
|
|
|
|
CheckFrontPageINI_Exit:
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
void MoveFrontPageINI(void)
|
|
{
|
|
// since the frontpage guys didn't write a migrate.dll
|
|
// we'll have to handle one file for them during the win95/98 upgrade.
|
|
//
|
|
// if we find the c:\windows\frontpg.ini file
|
|
// then we'll have to rename it to frontpage.txt
|
|
// then during they're install they will rename it back to frontpg.ini
|
|
int iSomethingToDo = FALSE;
|
|
int iFileExists = FALSE;
|
|
int iFileExists_new = FALSE;
|
|
char szWindowsDir[_MAX_PATH];
|
|
char szFullPathedFilename[_MAX_PATH];
|
|
char szFullPathedFilename_new[_MAX_PATH];
|
|
char szFrontPageINIFilename[] = "frontpg.ini\0";
|
|
char szFrontPageINIFilename_new[] = "frontpg.txt\0";
|
|
|
|
strcpy(szWindowsDir, "");
|
|
if (0 == GetWindowsDirectory(szWindowsDir, sizeof(szWindowsDir)))
|
|
{
|
|
// Error so write it out
|
|
SetupLogError_Wrap(LogSevError, "Call to GetWindowsDirectory() Failed. GetLastError=%x.", GetLastError());
|
|
goto MoveFrontPageINI_Exit;
|
|
}
|
|
|
|
// copy our settings file to this directory.
|
|
strcpy(szFullPathedFilename, szWindowsDir);
|
|
AddPath(szFullPathedFilename, szFrontPageINIFilename);
|
|
iFileExists = CheckIfFileExists(szFullPathedFilename);
|
|
|
|
strcpy(szFullPathedFilename_new, szWindowsDir);
|
|
AddPath(szFullPathedFilename_new, szFrontPageINIFilename_new);
|
|
iFileExists_new = CheckIfFileExists(szFullPathedFilename_new);
|
|
|
|
if (FALSE == iFileExists && FALSE == iFileExists_new)
|
|
{
|
|
// Neither files exists, we don't have to do jack
|
|
goto MoveFrontPageINI_Exit;
|
|
}
|
|
|
|
if (TRUE == iFileExists)
|
|
{
|
|
if (TRUE == iFileExists_new)
|
|
{DeleteFile(szFullPathedFilename_new);}
|
|
|
|
if (0 == CopyFile(szFullPathedFilename, szFullPathedFilename_new, FALSE))
|
|
{
|
|
SetupLogError_Wrap(LogSevError, "Call to CopyFile() Failed. GetLastError=%x.", GetLastError());
|
|
goto MoveFrontPageINI_Exit;
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("MoveFrontPageINI. %s renamed to %s"),szFullPathedFilename,szFrontPageINIFilename_new);
|
|
// don't delete the old .ini file since the user could actually cancel the upgrade.
|
|
//DeleteFile(szFullPathedFilename);
|
|
iSomethingToDo = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if we're here then that means that
|
|
// file1 doesn't exists and file2 does exist.
|
|
// that means that we probably already copied file1 to file2 and deleted file1.
|
|
iSomethingToDo = TRUE;
|
|
}
|
|
|
|
if (iSomethingToDo)
|
|
{
|
|
// Tell the upgrade module that we are going to 'handle' this newly created file.
|
|
// We really don't care if this get's added to the file or not,
|
|
// so let's not check the return code.
|
|
MigInf_AddHandledFile(szFullPathedFilename_new);
|
|
// Important: Write memory version of migrate.inf to disk
|
|
if (!MigInf_WriteInfToDisk()) {SetupLogError_Wrap(LogSevError, "Error: MigInf_WriteInfToDisk() FAILED.");}
|
|
}
|
|
else
|
|
{
|
|
iisDebugOut(_T("MoveFrontPageINI. %s not exist. no action."),szFullPathedFilename);
|
|
}
|
|
|
|
MoveFrontPageINI_Exit:
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT GetLNKProgramRunInfo(LPCTSTR lpszLink, LPTSTR lpszProgram)
|
|
{
|
|
HRESULT hres;
|
|
int iDoUninit = FALSE;
|
|
IShellLink* pShellLink = NULL;
|
|
WIN32_FIND_DATA wfd;
|
|
|
|
if (SUCCEEDED(CoInitialize(NULL)))
|
|
{iDoUninit = TRUE;}
|
|
|
|
hres = CoCreateInstance( CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(LPVOID*)&pShellLink);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
IPersistFile* pPersistFile = NULL;
|
|
hres = pShellLink->QueryInterface(IID_IPersistFile, (LPVOID*)&pPersistFile);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
WCHAR wsz[_MAX_PATH];
|
|
|
|
// Ensure that the string is WCHAR.
|
|
#if defined(UNICODE) || defined(_UNICODE)
|
|
_tcscpy(wsz, lpszLink);
|
|
#else
|
|
MultiByteToWideChar( CP_ACP, 0, lpszLink, -1, wsz, _MAX_PATH);
|
|
#endif
|
|
hres = pPersistFile->Load(wsz, STGM_READ);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
hres = pShellLink->Resolve(NULL, SLR_ANY_MATCH | SLR_NO_UI);
|
|
if (SUCCEEDED(hres))
|
|
{
|
|
pShellLink->GetPath(lpszProgram, _MAX_PATH, (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH);
|
|
}
|
|
}
|
|
if (pPersistFile)
|
|
{pPersistFile->Release();pPersistFile = NULL;}
|
|
}
|
|
if (pShellLink)
|
|
{pShellLink->Release();pShellLink = NULL;}
|
|
}
|
|
|
|
if (TRUE == iDoUninit)
|
|
{CoUninitialize();}
|
|
return hres;
|
|
}
|
|
|
|
|
|
int LNKSearchAndReturn(LPTSTR szDirToLookThru, LPTSTR szExeNameWithoutPath, LPTSTR szFileNameReturned)
|
|
{
|
|
int iReturn = FALSE;
|
|
WIN32_FIND_DATA FindFileData;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
TCHAR szFilePath[_MAX_PATH];
|
|
TCHAR szFilename_ext_only[_MAX_EXT];
|
|
|
|
_tcscpy(szFileNameReturned, _T(""));
|
|
_tcscpy(szFilePath, szDirToLookThru);
|
|
AddPath(szFilePath, _T("*.lnk"));
|
|
|
|
hFile = FindFirstFile(szFilePath, &FindFileData);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
do {
|
|
if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 && _tcsicmp(FindFileData.cFileName, _T("..")) != 0 )
|
|
{
|
|
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
// this is a directory, so let's skip it
|
|
}
|
|
else
|
|
{
|
|
// check if this file is a .lnk file
|
|
// if it is then let's open it and
|
|
// see if it points to our .exe we're looking for...
|
|
|
|
// get only the filename's extention
|
|
_tsplitpath( FindFileData.cFileName, NULL, NULL, NULL, szFilename_ext_only);
|
|
|
|
// check for .lnk
|
|
if (0 == _tcsicmp(szFilename_ext_only, _T(".lnk")))
|
|
{
|
|
TCHAR szFilename_only[_MAX_FNAME];
|
|
TCHAR szFullPathAndFilename[_MAX_PATH];
|
|
TCHAR szTemporaryString[_MAX_PATH];
|
|
|
|
// this is a .lnk,
|
|
// open it and check the .exe..
|
|
_tcscpy(szFullPathAndFilename,szDirToLookThru);
|
|
AddPath(szFullPathAndFilename,FindFileData.cFileName);
|
|
_tcscpy(szTemporaryString,_T(""));
|
|
|
|
if (SUCCEEDED(GetLNKProgramRunInfo(szFullPathAndFilename, szTemporaryString)))
|
|
{
|
|
_tsplitpath( szTemporaryString, NULL, NULL, szFilename_only, szFilename_ext_only);
|
|
_tcscpy(szTemporaryString, szFilename_only);
|
|
_tcscat(szTemporaryString, szFilename_ext_only);
|
|
|
|
// check if it matches our .exe name.
|
|
if (0 == _tcsicmp(szTemporaryString,szExeNameWithoutPath))
|
|
{
|
|
_tcscpy(szFileNameReturned,FindFileData.cFileName);
|
|
iReturn = TRUE;
|
|
FindClose(hFile);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// get the next file
|
|
if ( !FindNextFile(hFile, &FindFileData) )
|
|
{
|
|
FindClose(hFile);
|
|
break;
|
|
}
|
|
} while (TRUE);
|
|
}
|
|
|
|
return iReturn;
|
|
}
|
|
|
|
int MyGetSendToPath(LPTSTR szPath)
|
|
{
|
|
LPITEMIDLIST pidlSendTo;
|
|
HRESULT hRes = NOERROR;
|
|
int iTemp;
|
|
int iReturn = FALSE;
|
|
|
|
hRes = SHGetSpecialFolderLocation(NULL, CSIDL_SENDTO, &pidlSendTo);
|
|
if (hRes != NOERROR)
|
|
{
|
|
iReturn = FALSE;
|
|
}
|
|
|
|
iTemp = SHGetPathFromIDList(pidlSendTo, szPath);
|
|
if (iTemp != TRUE)
|
|
{
|
|
iReturn = FALSE;
|
|
goto MyGetSendToPath_Exit;
|
|
}
|
|
|
|
iReturn = TRUE;
|
|
|
|
MyGetSendToPath_Exit:
|
|
return iReturn;
|
|
}
|
|
|
|
|
|
int MyGetDesktopPath(LPTSTR szPath)
|
|
{
|
|
LPITEMIDLIST pidlSendTo;
|
|
HRESULT hRes = NOERROR;
|
|
int iTemp;
|
|
int iReturn = FALSE;
|
|
|
|
hRes = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &pidlSendTo);
|
|
if (hRes != NOERROR)
|
|
{
|
|
iReturn = FALSE;
|
|
}
|
|
|
|
iTemp = SHGetPathFromIDList(pidlSendTo, szPath);
|
|
if (iTemp != TRUE)
|
|
{
|
|
iReturn = FALSE;
|
|
goto MyGetDesktopPath_Exit;
|
|
}
|
|
|
|
iReturn = TRUE;
|
|
|
|
MyGetDesktopPath_Exit:
|
|
return iReturn;
|
|
}
|
|
|
|
void MyDeleteSendToItem(LPCTSTR szAppName)
|
|
{
|
|
TCHAR szPath[_MAX_PATH];
|
|
TCHAR szPath2[_MAX_PATH];
|
|
|
|
MyGetSendToPath(szPath);
|
|
_tcscpy(szPath2, szAppName);
|
|
//_tcscat(szPath2, _T(".lnk")); // already in the resource, so let's not tack it on again.
|
|
|
|
MyDeleteLinkWildcard(szPath, szPath2);
|
|
}
|
|
|
|
BOOL IsFileNameInDelimitedList(LPTSTR szCommaDelimList,LPTSTR szExeNameWithoutPath)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
char *token = NULL;
|
|
TCHAR szCopyOfDataBecauseStrTokIsLame[_MAX_PATH];
|
|
_tcscpy(szCopyOfDataBecauseStrTokIsLame,szCommaDelimList);
|
|
|
|
// breakup the szCommaDelimList into strings and see if it contains the szExeNameWithoutPath string
|
|
token = strtok(szCopyOfDataBecauseStrTokIsLame, g_LoadString_token_delimiters);
|
|
while(token != NULL)
|
|
{
|
|
// check if it matches our .exe name.
|
|
if (0 == _tcsicmp(token,szExeNameWithoutPath))
|
|
{
|
|
return TRUE;
|
|
}
|
|
// Get next token
|
|
token = strtok(NULL, g_LoadString_token_delimiters);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
int LNKSearchAndDestroyRecursive(LPTSTR szDirToLookThru, LPTSTR szSemiColonDelmitedListOfExeNames, BOOL bDeleteItsDirToo, LPCSTR AnswerFile)
|
|
{
|
|
int iReturn = FALSE;
|
|
WIN32_FIND_DATA FindFileData;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
TCHAR szFilePath[_MAX_PATH];
|
|
TCHAR szFilename_ext_only[_MAX_EXT];
|
|
|
|
DWORD retCode = GetFileAttributes(szDirToLookThru);
|
|
|
|
if (retCode == 0xFFFFFFFF || !(retCode & FILE_ATTRIBUTE_DIRECTORY))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
_tcscpy(szFilePath, szDirToLookThru);
|
|
AddPath(szFilePath, _T("*.*"));
|
|
|
|
hFile = FindFirstFile(szFilePath, &FindFileData);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
do {
|
|
if ( _tcsicmp(FindFileData.cFileName, _T(".")) != 0 && _tcsicmp(FindFileData.cFileName, _T("..")) != 0 )
|
|
{
|
|
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
TCHAR szFullNewDirToLookInto[_MAX_EXT];
|
|
_tcscpy(szFullNewDirToLookInto, szDirToLookThru);
|
|
AddPath(szFullNewDirToLookInto,FindFileData.cFileName);
|
|
|
|
// this is a directory, so let's go into this
|
|
// directory recursively
|
|
LNKSearchAndDestroyRecursive(szFullNewDirToLookInto,szSemiColonDelmitedListOfExeNames,bDeleteItsDirToo,AnswerFile);
|
|
}
|
|
else
|
|
{
|
|
// check if this file is a .lnk file
|
|
// if it is then let's open it and
|
|
// see if it points to our .exe we're looking for...
|
|
|
|
// get only the filename's extention
|
|
_tsplitpath( FindFileData.cFileName, NULL, NULL, NULL, szFilename_ext_only);
|
|
|
|
// check for .lnk
|
|
if (0 == _tcsicmp(szFilename_ext_only, _T(".lnk")))
|
|
{
|
|
TCHAR szFilename_only[_MAX_FNAME];
|
|
TCHAR szFullPathAndFilename[_MAX_PATH];
|
|
TCHAR szTemporaryString[_MAX_PATH];
|
|
|
|
// this is a .lnk,
|
|
// open it and check the .exe..
|
|
_tcscpy(szFullPathAndFilename,szDirToLookThru);
|
|
AddPath(szFullPathAndFilename,FindFileData.cFileName);
|
|
_tcscpy(szTemporaryString,_T(""));
|
|
|
|
if (SUCCEEDED(GetLNKProgramRunInfo(szFullPathAndFilename, szTemporaryString)))
|
|
{
|
|
_tsplitpath( szTemporaryString, NULL, NULL, szFilename_only, szFilename_ext_only);
|
|
_tcscpy(szTemporaryString, szFilename_only);
|
|
_tcscat(szTemporaryString, szFilename_ext_only);
|
|
|
|
//_tprintf(TEXT("open:%s,%s\n"),szFullPathAndFilename,szTemporaryString);
|
|
|
|
// see if it is on our list of comma delimited names...
|
|
if (TRUE == IsFileNameInDelimitedList(szSemiColonDelmitedListOfExeNames,szTemporaryString))
|
|
{
|
|
// DELETE the file that references this .exe
|
|
MigInf_AddMovedFile(szFullPathAndFilename, "");
|
|
AnswerFile_AppendDeletion(szFullPathAndFilename,AnswerFile);
|
|
|
|
if (bDeleteItsDirToo)
|
|
{
|
|
// Get it's dirname and delete that too...
|
|
MigInf_AddMovedDirectory(szDirToLookThru, "");
|
|
AnswerFile_AppendDeletion(szDirToLookThru,AnswerFile);
|
|
}
|
|
|
|
iReturn = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// get the next file
|
|
if ( !FindNextFile(hFile, &FindFileData) )
|
|
{
|
|
FindClose(hFile);
|
|
break;
|
|
}
|
|
} while (TRUE);
|
|
}
|
|
|
|
return iReturn;
|
|
}
|
|
|
|
// We need to tell migration setup that we are going to handle certain files...
|
|
// particularly the c:\windows\SendTo\Personal Web Server.lnk file
|
|
// since it doesn't seem to be accessible during win2000/20001 guimode setup
|
|
void HandleSendToItems(LPCSTR AnswerFile)
|
|
{
|
|
char szPath[_MAX_PATH];
|
|
char szSemiColonDelimitedList[255];
|
|
|
|
// Now, Get the ";" delimited list of things to act upon
|
|
strcpy(szSemiColonDelimitedList,"");
|
|
if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_DEL_LNK_TO_THESE_EXE_FILENAMES, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
|
|
{
|
|
iisDebugOut(_T("LoopThruStartMenuDeletions.Err LoadString IDS_DEL_LNK_TO_THESE_EXE_FILENAMES\n"));
|
|
return;
|
|
}
|
|
|
|
if (TRUE == MyGetSendToPath(szPath))
|
|
{
|
|
LNKSearchAndDestroyRecursive(szPath,szSemiColonDelimitedList,FALSE,AnswerFile);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void HandleDesktopItems(LPCSTR AnswerFile)
|
|
{
|
|
char szPath[_MAX_PATH];
|
|
char szSemiColonDelimitedList[255];
|
|
|
|
// Now, Get the ";" delimited list of things to act upon
|
|
strcpy(szSemiColonDelimitedList,"");
|
|
if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_DEL_LNK_TO_THESE_EXE_FILENAMES, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
|
|
{
|
|
iisDebugOut(_T("LoopThruStartMenuDeletions.Err LoadString IDS_DEL_LNK_TO_THESE_EXE_FILENAMES\n"));
|
|
return;
|
|
}
|
|
|
|
if (TRUE == MyGetDesktopPath(szPath))
|
|
{
|
|
LNKSearchAndDestroyRecursive(szPath,szSemiColonDelimitedList,FALSE,AnswerFile);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void HandleStartMenuItems(LPCSTR AnswerFile)
|
|
{
|
|
TCHAR szPath[_MAX_PATH];
|
|
char szSemiColonDelimitedList[255];
|
|
|
|
// Now, Get the ";" delimited list of things to act upon
|
|
strcpy(szSemiColonDelimitedList,"");
|
|
if (!LoadString((HINSTANCE) g_MyModuleHandle, IDS_DEL_LNK_TO_THESE_EXE_FILENAMES, szSemiColonDelimitedList, sizeof(szSemiColonDelimitedList)))
|
|
{
|
|
iisDebugOut(_T("LoopThruStartMenuDeletions.Err LoadString IDS_DEL_LNK_TO_THESE_EXE_FILENAMES\n"));
|
|
return;
|
|
}
|
|
|
|
MyGetGroupPath(_T(""), szPath);
|
|
|
|
// search thru all the start menu items looking for
|
|
// anything that links to our know programs...
|
|
LNKSearchAndDestroyRecursive(szPath,szSemiColonDelimitedList,TRUE,AnswerFile);
|
|
return;
|
|
}
|
|
|