Bug 353089 - Fix / remove ddeexec hack. r=bsmedberg

This commit is contained in:
rob_strong%exchangecode.com 2006-09-19 18:09:58 +00:00
parent 99ed68e076
commit 78bc894bd6
3 changed files with 108 additions and 133 deletions

View File

@ -145,11 +145,12 @@ OpenKeyForWriting(const char* aKeyName, HKEY* aKey, PRBool aForAllUsers, PRBool
// are mapped like so:
//
// HKCU\SOFTWARE\Classes\<protocol>\
// DefaultIcon (default) REG_SZ <appname>,1
// DefaultIcon (default) REG_SZ <appname>,0
// shell\open\command (default) REG_SZ <appname> -url "%1"
// shell\open\ddeexec (default) REG_SZ "%1",,-1,0,,,,
// shell\open\ddeexec (default) REG_SZ "%1",,0,0,,,,
// shell\open\ddeexec NoActivateHandler REG_SZ
// \application (default) REG_SZ Firefox
// \ifexec (default) REG_SZ ,,0,0,,,,
// \topic (default) REG_SZ WWW_OpenURL
//
//
@ -193,10 +194,12 @@ typedef struct {
#define DDE "\\shell\\open\\ddeexec\\"
#define DDE_NAME "Firefox" // This must be kept in sync with ID_DDE_APPLICATION_NAME as defined in splash.rc
#define DDE_COMMAND "\"%1\",,0,0,,,,"
#define DDE_IFEXEC ",,0,0,,,,"
#define EXE "firefox.exe"
#define CLS_HTML "FirefoxHTML"
#define VAL_ICON "%APPPATH%,1"
#define VAL_URL_ICON "%APPPATH%,0"
#define VAL_FILE_ICON "%APPPATH%,1"
#define VAL_OPEN "%APPPATH% -url \"%1\""
#define MAKE_KEY_NAME1(PREFIX, MID) \
@ -223,21 +226,43 @@ static SETTING gSettings[] = {
{ MAKE_KEY_NAME1(CLS, ".xhtml"), "", CLS_HTML, NO_SUBSTITUTION | NON_ESSENTIAL },
// File Extension Class
{ MAKE_KEY_NAME2(CLS, CLS_HTML, DI), "", VAL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, CLS_HTML, DI), "", VAL_FILE_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, CLS_HTML, SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
// Protocol Handlers
{ MAKE_KEY_NAME2(CLS, "HTTP", DI), "", VAL_ICON, PATH_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTP", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTP", SOP), "", VAL_OPEN, PATH_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTPS", DI), "", VAL_ICON, PATH_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTPS", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTPS", SOP), "", VAL_OPEN, PATH_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "FTP", DI), "", VAL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "FTP", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "FTP", SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "GOPHER", DI), "", VAL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "GOPHER", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "GOPHER", SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "CHROME", DI), "", VAL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "CHROME", DI), "", VAL_URL_ICON, PATH_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME2(CLS, "CHROME", SOP), "", VAL_OPEN, PATH_SUBSTITUTION | NON_ESSENTIAL },
// DDE settings
{ MAKE_KEY_NAME2(CLS, "HTTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTPS", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "FTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "GOPHER", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "CHROME", DDE), "", DDE_COMMAND, NO_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION | NON_ESSENTIAL },
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "ifexec"), "", DDE_IFEXEC, NO_SUBSTITUTION },
// Windows XP Start Menu
{ MAKE_KEY_NAME2(SMI, "%APPEXE%", DI),
"",
@ -261,29 +286,6 @@ static SETTING gSettings[] = {
// firefox.exe\shell\safemode (default) REG_SZ Firefox &Safe Mode
};
static SETTING gDDESettings[] = {
{ MAKE_KEY_NAME2(CLS, "HTTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTP", DDE), "NoActivateHandler", "", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTPS", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "HTTPS", DDE), "NoActivateHandler", "", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "HTTPS", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "FTP", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "FTP", DDE), "NoActivateHandler", "", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "FTP", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "GOPHER", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "GOPHER", DDE), "NoActivateHandler", "", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "GOPHER", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "CHROME", DDE), "", DDE_COMMAND, NO_SUBSTITUTION },
{ MAKE_KEY_NAME2(CLS, "CHROME", DDE), "NoActivateHandler", "", NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "Application"), "", DDE_NAME, NO_SUBSTITUTION },
{ MAKE_KEY_NAME3(CLS, "CHROME", DDE, "Topic"), "", "WWW_OpenURL", NO_SUBSTITUTION }
};
NS_IMETHODIMP
nsWindowsShellService::Register(nsIComponentManager *aCompMgr, nsIFile *aPath, const char *registryLocation,
const char *componentType, const nsModuleComponentInfo *info)
@ -302,31 +304,6 @@ nsWindowsShellService::nsWindowsShellService()
obsServ->AddObserver(this, "quit-application", PR_FALSE);
}
nsresult
nsWindowsShellService::RegisterDDESupport()
{
SETTING* end = gDDESettings + sizeof(gDDESettings)/sizeof(SETTING);
for (SETTING* settings = gDDESettings; settings < end; ++settings) {
nsCAutoString key(settings->keyName);
nsCAutoString data(settings->valueData);
SetRegKey(key.get(), settings->valueName, data.get(),
PR_FALSE, 0, PR_TRUE, PR_TRUE);
}
return NS_OK;
}
nsresult
nsWindowsShellService::UnregisterDDESupport()
{
DeleteRegKey(HKEY_CLASSES_ROOT, "HTTP\\shell\\open\\ddeexec");
DeleteRegKey(HKEY_CLASSES_ROOT, "HTTPS\\shell\\open\\ddeexec");
DeleteRegKey(HKEY_CLASSES_ROOT, "FTP\\shell\\open\\ddeexec");
DeleteRegKey(HKEY_CLASSES_ROOT, "CHROME\\shell\\open\\ddeexec");
DeleteRegKey(HKEY_CLASSES_ROOT, "GOPHER\\shell\\open\\ddeexec");
return NS_OK;
}
NS_IMETHODIMP
nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck, PRBool* aIsDefaultBrowser)
{
@ -501,9 +478,6 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
// Close the key we opened.
::RegCloseKey(backupKey);
// We need to reregister DDE support
RegisterDDESupport();
// Refresh the Shell
::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL,
(LPARAM)"SOFTWARE\\Clients\\StartMenuInternet",
@ -556,43 +530,6 @@ nsWindowsShellService::RestoreFileSettings(PRBool aForAllUsers)
return NS_OK;
}
// Utility function to delete a registry subkey.
DWORD
nsWindowsShellService::DeleteRegKey(HKEY baseKey, const char *keyName)
{
// Make sure input subkey isn't null.
if (!keyName || !::strlen(keyName))
return ERROR_BADKEY;
DWORD rc;
// Open subkey.
HKEY key;
rc = ::RegOpenKeyEx(baseKey, keyName, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &key);
// Continue till we get an error or are done.
while (rc == ERROR_SUCCESS) {
char subkeyName[_MAX_PATH];
DWORD len = sizeof subkeyName;
// Get first subkey name. Note that we always get the
// first one, then delete it. So we need to get
// the first one next time, also.
rc = ::RegEnumKeyEx(key, 0, subkeyName, &len, 0, 0, 0, 0);
if (rc == ERROR_NO_MORE_ITEMS) {
// No more subkeys. Delete the main one.
rc = ::RegDeleteKey(baseKey, keyName);
break;
}
if (rc == ERROR_SUCCESS) {
// Another subkey, delete it, recursively.
rc = DeleteRegKey(key, subkeyName);
}
}
// Close the key we opened.
::RegCloseKey(key);
return rc;
}
void
nsWindowsShellService::SetRegKey(const char* aKeyName, const char* aValueName,
const char* aValue, PRBool aBackup,
@ -1062,8 +999,6 @@ nsWindowsShellService::Observe(nsISupports* aObject, const char* aTopic, const P
IsDefaultBrowser(PR_FALSE, &isDefault);
if (!isDefault)
return NS_OK;
return RegisterDDESupport();
}
else if (!nsCRT::strcmp("quit-application", aTopic)) {
PRBool isDefault;
@ -1073,8 +1008,6 @@ nsWindowsShellService::Observe(nsISupports* aObject, const char* aTopic, const P
nsCOMPtr<nsIObserverService> os(do_GetService("@mozilla.org/observer-service;1"));
os->RemoveObserver(this, "quit-application");
return UnregisterDDESupport();
}
return NS_OK;

View File

@ -66,10 +66,6 @@ protected:
void SetRegKey(const char* aKeyName, const char* aValueName,
const char* aValue, PRBool aBackup, HKEY aBackupKey,
PRBool aReplaceExisting, PRBool aForAllUsers);
DWORD DeleteRegKey(HKEY baseKey, const char *keyName);
nsresult RegisterDDESupport();
nsresult UnregisterDDESupport();
private:
PRBool mCheckedThisSession;

View File

@ -256,6 +256,47 @@ private:
* whether Mozilla is already running.
*/
/* Update 2006 September
*
* A change in behavior was implemented in July 2004 which made the
* application add on launch and remove on quit the ddexec registry key.
* See bug 246078.
* Windows Vista has changed the methods used to set an application as default
* and the new methods are incompatible with removing the ddeexec registry key.
* See bug 353089.
*
* OS DDE Sequence:
* 1. OS checks if the dde name is registered.
* 2. If it is registered the OS sends a DDE request with the WWW_OpenURL topic
* and the params as specified in the default value of the ddeexec registry
* key for the verb (e.g. open).
* 3. If it isn't registered the OS launches the executable defined in the
* verb's (e.g. open) command registry key.
* 4. If the ifexec registry key is not present the OS sends a DDE request with
* the WWW_OpenURL topic and the params as specified in the default value of
* the ddeexec registry key for the verb (e.g. open).
* 5. If the ifexec registry key is present the OS sends a DDE request with the
* WWW_OpenURL topic and the params as specified in the ifexec registry key
* for the verb (e.g. open).
*
* Application DDE Sequence:
* 1. If the application is running a DDE request is received DDE with the
* WWW_OpenURL topic and the params as specified in the default value of the
* ddeexec registry key (e.g. "%1",,0,0,,,, where '%1' is the url to open)
* for the verb (e.g. open).
* 2. If the application is not running it is launched with the -url argument.
*
* Note: Typically the application should use the DDE request to open the page
* instead of using a command line argument. The command line argument is
* used to work around when the DDE queue is hung by a different
* application. See bug 53952.
*
* 3. The application receives a DDE request with the WWW_OpenURL topic and the
* params from the ifexec key without the url (e.g. ,,0,0,,,,). The
* application treats this request as a noop internally and returns the
* correct values for the DDE request to the OS.
*/
class nsNativeAppSupportWin : public nsNativeAppSupportBase,
public nsIObserver
{
@ -976,23 +1017,26 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t
nsCAutoString url;
ParseDDEArg(hsz2, 0, url);
// Read the 3rd argument in the command to determine if a
// new window is to be used.
nsCAutoString windowID;
ParseDDEArg(hsz2, 2, windowID);
// "" means to open the URL in a new window.
if ( windowID.Equals( "" ) ) {
url.Insert("mozilla -new-window ", 0);
}
else {
url.Insert("mozilla -url ", 0);
}
if ( !url.Equals( "" ) ) {
// Read the 3rd argument in the command to determine if a
// new window is to be used.
nsCAutoString windowID;
ParseDDEArg(hsz2, 2, windowID);
// "" means to open the URL in a new window.
if ( windowID.Equals( "" ) ) {
url.Insert("mozilla -new-window ", 0);
}
else {
url.Insert("mozilla -url ", 0);
}
#if MOZ_DEBUG_DDE
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
#endif
// Now handle it.
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
// Now handle it.
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
}
// Return pseudo window ID.
result = CreateDDEData( 1 );
break;
@ -1146,23 +1190,25 @@ nsNativeAppSupportWin::HandleDDENotification( UINT uType, // transaction t
nsCAutoString url;
ParseDDEArg((const char*) request, 0, url);
// Read the 3rd argument in the command to determine if a
// new window is to be used.
nsCAutoString windowID;
ParseDDEArg((const char*) request, 2, windowID);
if ( !url.Equals( "" ) ) {
// Read the 3rd argument in the command to determine if a
// new window is to be used.
nsCAutoString windowID;
ParseDDEArg((const char*) request, 2, windowID);
// "" means to open the URL in a new window.
if ( windowID.Equals( "" ) ) {
url.Insert("mozilla -new-window ", 0);
}
else {
url.Insert("mozilla -url ", 0);
}
// "" means to open the URL in a new window.
if ( windowID.Equals( "" ) ) {
url.Insert("mozilla -new-window ", 0);
}
else {
url.Insert("mozilla -url ", 0);
}
#if MOZ_DEBUG_DDE
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
printf( "Handling dde XTYP_REQUEST request: [%s]...\n", url.get() );
#endif
// Now handle it.
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
// Now handle it.
HandleCommandLine(url.get(), nsnull, nsICommandLine::STATE_REMOTE_EXPLICIT);
}
// Release the data.
DdeUnaccessData( hdata );