|
|
#include "stock.h"
#pragma hdrstop
//
// Return root hkey and default client name. The caller is expected to
// retrieve the command from hkey\default\shell\open\command.
//
STDAPI_(HKEY) _GetClientKeyAndDefaultW(LPCWSTR pwszClientType, LPWSTR pwszDefault, DWORD cchDefault) { HKEY hkClient = NULL;
ASSERT(cchDefault); // This had better be a nonempty buffer
// Borrow pwszDefault as a scratch buffer
wnsprintfW(pwszDefault, cchDefault, L"SOFTWARE\\Clients\\%s", pwszClientType);
if (ERROR_SUCCESS == RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszDefault, 0, KEY_READ, &hkClient)) { DWORD dwSize = cchDefault * sizeof(*pwszDefault); pwszDefault[0] = 0; // in case of failure
RegQueryValueExW(hkClient, NULL, NULL, NULL, (LPBYTE)pwszDefault, &dwSize);
// If no default client, then fail
if (!pwszDefault[0]) { RegCloseKey(hkClient); hkClient = NULL; }
} else if (StrCmpIW(pwszClientType, L"webbrowser") == 0) { // In theory, we could use
// RegOpenKeyExW(HKEY_CLASSES_ROOT, NULL, 0, KEY_READ, &hkClient)
// but that just returns HKEY_CLASSES_ROOT back anyway.
hkClient = HKEY_CLASSES_ROOT; StrCpyNW(pwszDefault, L"http", cchDefault); } return hkClient; }
// Gets the path to open the default Mail, News, etc Client.
STDAPI SHGetDefaultClientOpenCommandW(LPCWSTR pwszClientType, LPWSTR pwszClientCommand, DWORD dwCch, OPTIONAL LPWSTR pwszClientParams, DWORD dwCchParams) { HRESULT hr = E_INVALIDARG; HKEY hkClient; WCHAR wszDefault[MAX_PATH];
ASSERT(pwszClientCommand && dwCch); ASSERT(pwszClientParams == NULL || dwCchParams);
hkClient = _GetClientKeyAndDefaultW(pwszClientType, wszDefault, ARRAYSIZE(wszDefault)); if (hkClient) { // For the webbrowser client, do not pass any command line arguments
// at all. This suppresses the "-nohome" flag that IE likes to throw
// in there. Also, if we end up being forced to use the Protocol key,
// then strip the args there, too.
BOOL fStripArgs = hkClient == HKEY_CLASSES_ROOT;
BOOL iRetry = 0; int cchDefault = lstrlenW(wszDefault); again: StrCatBuffW(wszDefault, L"\\shell\\open\\command", ARRAYSIZE(wszDefault));
// convert characters to bytes
DWORD cb = dwCch * (sizeof(WCHAR)/sizeof(BYTE)); // the default value of this key is the actual command to run the app
DWORD dwError; dwError = SHGetValueW(hkClient, wszDefault, NULL, NULL, (LPBYTE) pwszClientCommand, &cb);
if (dwError == ERROR_FILE_NOT_FOUND && iRetry == 0 && StrCmpICW(pwszClientType, L"mail") == 0) { // Sigh, Netscape doesn't register a shell\open\command; we have to
// look in Protocols\mailto\shell\open\command instead.
wszDefault[cchDefault] = L'\0'; StrCatBuffW(wszDefault, L"\\Protocols\\mailto", ARRAYSIZE(wszDefault)); fStripArgs = TRUE; iRetry++; goto again; }
if (dwError == ERROR_SUCCESS) { // Sigh. Netscape forgets to quote its EXE name.
PathProcessCommand(pwszClientCommand, pwszClientCommand, dwCch, PPCF_ADDQUOTES | PPCF_NODIRECTORIES | PPCF_LONGESTPOSSIBLE);
if (pwszClientParams) { if (fStripArgs) { pwszClientParams[0] = 0; } else { StrCpyNW(pwszClientParams, PathGetArgsW(pwszClientCommand), dwCchParams); } } PathRemoveArgsW(pwszClientCommand); PathUnquoteSpaces(pwszClientCommand);
// Bonus hack for Netscape! To read email you have to pass the
// "-mail" command line option even though there is no indication
// anywhere that this is the case.
if (iRetry > 0 && pwszClientParams && StrCmpIW(PathFindFileName(pwszClientCommand), L"netscape.exe") == 0) { StrCpyNW(pwszClientParams, L"-mail", dwCchParams); }
hr = S_OK; } else { hr = HRESULT_FROM_WIN32(dwError); }
// Do not RegCloseKey(HKEY_CLASSES_ROOT) or the world will end!
if (hkClient != HKEY_CLASSES_ROOT) RegCloseKey(hkClient); } return hr; }
// Gets the friendly name for the default Mail, News, etc Client.
// Note that this doesn't work for Webbrowser.
STDAPI SHGetDefaultClientNameW(LPCWSTR pwszClientType, LPWSTR pwszBuf, DWORD dwCch) { HRESULT hr = E_INVALIDARG; HKEY hkClient; WCHAR wszDefault[MAX_PATH];
ASSERT(pwszBuf && dwCch);
hkClient = _GetClientKeyAndDefaultW(pwszClientType, wszDefault, ARRAYSIZE(wszDefault)); if (hkClient && hkClient != HKEY_CLASSES_ROOT) { LONG cbValue = dwCch * sizeof(TCHAR); if (RegQueryValueW(hkClient, wszDefault, pwszBuf, &cbValue) == ERROR_SUCCESS && pwszBuf[0]) { hr = S_OK; } RegCloseKey(hkClient); } return hr; }
|