From bb5e1b94a7cc08d9a1c09dbff757d94fcacc8a99 Mon Sep 17 00:00:00 2001 From: "mconnor%myrealbox.com" Date: Tue, 18 May 2004 21:31:12 +0000 Subject: [PATCH] land fix for bug 239722 on aviary branch git-svn-id: svn://10.0.0.236/branches/AVIARY_1_0_20040515_BRANCH@156551 18797224-902f-48f8-a5cc-f745e15eee43 --- .../installer/windows/wizard/setup/extra.c | 196 +++++++++++------- .../installer/windows/wizard/setup/extra.h | 1 + 2 files changed, 125 insertions(+), 72 deletions(-) diff --git a/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.c b/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.c index ae84a83634a..6f44ab405f5 100644 --- a/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.c +++ b/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.c @@ -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 { diff --git a/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.h b/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.h index c4ac76a291c..896bdb437b0 100644 --- a/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.h +++ b/mozilla/toolkit/mozapps/installer/windows/wizard/setup/extra.h @@ -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,