Bug 239722 Firefox install deletes windows system files, port of suite fix for bug 236312 by scottmacvicar@ntlworld.com, r=ben, original patch by dveditz

This commit is contained in:
mconnor%myrealbox.com 2004-05-16 14:58:08 +00:00
parent 774204ecef
commit 5c0b652bfd
2 changed files with 125 additions and 72 deletions

View File

@ -505,6 +505,129 @@ BOOL UpdateFile(char *szInFilename, char *szOutFilename, char *szIgnoreStr)
return(bFoundIgnoreStr);
}
/* Function: RemoveDelayedDeleteFileEntries()
*
* in: const char *aPathToMatch - path to match against
*
* purpose: To remove windows registry entries (normally set by the uninstaller)
* that dictates what files to remove at system remove.
* The windows registry key that will be parsed is:
*
* key : HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager
* name: PendingFileRenameOperations
*
* This will not remove any entries that are set to be 'renamed'
* at system remove, only to be 'deleted'.
*
* This function is multibyte safe.
*
* To see what format the value of the var is in, look up the win32 API:
* MoveFileEx()
*/
void RemoveDelayedDeleteFileEntries(const char *aPathToMatch)
{
HKEY hkResult;
DWORD dwErr;
DWORD dwType = REG_NONE;
DWORD oldMaxValueLen = 0;
DWORD newMaxValueLen = 0;
DWORD lenToEnd = 0;
char *multiStr = NULL;
const char key[] = "SYSTEM\\CurrentControlSet\\Control\\Session Manager";
const char name[] = "PendingFileRenameOperations";
char *pathToMatch;
char *lcName;
char *pName;
char *pRename;
int nameLen, renameLen;
assert(aPathToMatch);
/* if not NT systems (win2k, winXP) return */
if (!(gSystemInfo.dwOSType & OS_NT))
return;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_READ|KEY_WRITE, &hkResult) != ERROR_SUCCESS)
return;
dwErr = RegQueryValueEx(hkResult, name, 0, &dwType, NULL, &oldMaxValueLen);
if (dwErr != ERROR_SUCCESS || oldMaxValueLen == 0 || dwType != REG_MULTI_SZ)
{
/* no value, no data, or wrong type */
return;
}
multiStr = calloc(oldMaxValueLen, sizeof(BYTE));
if (!multiStr)
return;
pathToMatch = strdup(aPathToMatch);
if (!pathToMatch)
{
free(multiStr);
return;
}
if (RegQueryValueEx(hkResult, name, 0, NULL, multiStr, &oldMaxValueLen) == ERROR_SUCCESS)
{
// The registry value consists of name/newname pairs of null-terminated
// strings, with a final extra null termination. We're only interested
// in files to be deleted, which are indicated by a null newname.
CharLower(pathToMatch);
lenToEnd = newMaxValueLen = oldMaxValueLen;
pName = multiStr;
while(*pName && lenToEnd > 0)
{
// find the locations and lengths of the current pair. Count the
// nulls, we need to know how much data to skip or move
nameLen = strlen(pName) + 1;
pRename = pName + nameLen;
renameLen = strlen(pRename) + 1;
// How much remains beyond the current pair
lenToEnd -= (nameLen + renameLen);
if (*pRename == '\0')
{
// No new name, it's a delete. Is it the one we want?
lcName = strdup(pName);
if (lcName)
{
CharLower(lcName);
if (strstr(lcName, pathToMatch))
{
// It's a match--
// delete this pair by moving the remainder on top
memmove(pName, pRename + renameLen, lenToEnd);
// update the total length to reflect the missing pair
newMaxValueLen -= (nameLen + renameLen);
// next pair is in place, continue w/out moving pName
free(lcName);
continue;
}
free(lcName);
}
}
// on to the next pair
pName = pRename + renameLen;
}
if (newMaxValueLen != oldMaxValueLen)
{
// We've deleted something, save the changed data
RegSetValueEx(hkResult, name, 0, REG_MULTI_SZ, multiStr, newMaxValueLen);
RegFlushKey(hkResult);
}
}
RegCloseKey(hkResult);
free(multiStr);
free(pathToMatch);
}
/* Looks for and removes the uninstaller from the Windows Registry
* that is set to delete the uninstaller at the next restart of
* Windows. This key is set/created when the user does the following:
@ -518,92 +641,21 @@ BOOL UpdateFile(char *szInFilename, char *szOutFilename, char *szIgnoreStr)
*/
void ClearWinRegUninstallFileDeletion(void)
{
char *szPtrIn = NULL;
char *szPtrOut = NULL;
char szInMultiStr[MAX_BUF];
char szOutMultiStr[MAX_BUF];
char szLCKeyBuf[MAX_BUF];
char szLCUninstallFilenameLongBuf[MAX_BUF];
char szLCUninstallFilenameShortBuf[MAX_BUF];
char szWinInitFile[MAX_BUF];
char szTempInitFile[MAX_BUF];
char szWinDir[MAX_BUF];
DWORD dwOutMultiStrLen;
DWORD dwType;
BOOL bFoundUninstaller = FALSE;
if(!GetWindowsDirectory(szWinDir, sizeof(szWinDir)))
return;
wsprintf(szLCUninstallFilenameLongBuf, "%s\\%s", szWinDir, sgProduct.szUninstallFilename);
GetShortPathName(szLCUninstallFilenameLongBuf, szLCUninstallFilenameShortBuf, sizeof(szLCUninstallFilenameShortBuf));
CharLower(szLCUninstallFilenameLongBuf);
CharLower(szLCUninstallFilenameShortBuf);
if(gSystemInfo.dwOSType & OS_NT)
{
ZeroMemory(szInMultiStr, sizeof(szInMultiStr));
ZeroMemory(szOutMultiStr, sizeof(szOutMultiStr));
dwType = GetWinReg(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Control\\Session Manager",
"PendingFileRenameOperations",
szInMultiStr,
sizeof(szInMultiStr));
if((dwType == REG_MULTI_SZ) && (szInMultiStr != '\0'))
{
szPtrIn = szInMultiStr;
szPtrOut = szOutMultiStr;
dwOutMultiStrLen = 0;
do
{
lstrcpy(szLCKeyBuf, szPtrIn);
CharLower(szLCKeyBuf);
if(!strstr(szLCKeyBuf, szLCUninstallFilenameLongBuf) && !strstr(szLCKeyBuf, szLCUninstallFilenameShortBuf))
{
if((dwOutMultiStrLen + lstrlen(szPtrIn) + 3) <= sizeof(szOutMultiStr))
{
/* uninstaller not found, so copy the szPtrIn string to szPtrOut buffer */
lstrcpy(szPtrOut, szPtrIn);
dwOutMultiStrLen += lstrlen(szPtrIn) + 2; /* there are actually 2 NULL bytes between the strings */
szPtrOut = &szPtrOut[lstrlen(szPtrIn) + 2]; /* there are actually 2 NULL bytes between the strings */
}
else
{
bFoundUninstaller = FALSE;
/* not enough memory; break out of while loop. */
break;
}
}
else
bFoundUninstaller = TRUE;
szPtrIn = &szPtrIn[lstrlen(szPtrIn) + 2]; /* there are actually 2 NULL bytes between the strings */
}while(*szPtrIn != '\0');
}
if(bFoundUninstaller)
{
if(dwOutMultiStrLen > 0)
{
/* take into account the 3rd NULL byte that signifies the end of the MULTI string */
++dwOutMultiStrLen;
SetWinReg(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Control\\Session Manager",
TRUE,
"PendingFileRenameOperations",
TRUE,
REG_MULTI_SZ,
szOutMultiStr,
dwOutMultiStrLen,
FALSE,
FALSE);
}
else
DeleteWinRegValue(HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Control\\Session Manager",
"PendingFilerenameOperations");
}
RemoveDelayedDeleteFileEntries(szLCUninstallFilenameShortBuf);
}
else
{

View File

@ -210,6 +210,7 @@ void RestoreAdditionalFlag(siC *siCNode);
void RestoreEnabledFlag(siC *siCNode);
void SwapFTPAndHTTP(char *szInUrl, DWORD dwInUrlSize);
void ClearWinRegUninstallFileDeletion(void);
void RemoveDelayedDeleteFileEntries(const char *aPathToMatch);
int AppendToGlobalMessageStream(char *szInfo);
char *GetOSTypeString(char *szOSType, DWORD dwOSTypeBufSize);
int UpdateIdiFile(char *szPartialUrl,