mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-14 18:51:28 +00:00
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:
parent
774204ecef
commit
5c0b652bfd
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user