Updated PATH setting code to be less reliant on registry settings. b=71363

This commit is contained in:
locka%iol.ie 2001-03-23 14:56:12 +00:00
Родитель 012887c32a
Коммит 25c4877957
1 изменённых файлов: 300 добавлений и 160 удалений

Просмотреть файл

@ -24,162 +24,298 @@
#include "stdafx.h"
#include <sys/types.h>
#include <sys/stat.h>
#include "shlobj.h"
static BOOL LoadMozLibraryFromCurrentDir();
static BOOL LoadMozLibraryFromRegistry(BOOL bAskUserToSetPath);
static BOOL LoadLibraryWithPATHFixup(const TCHAR *szBinDirPath);
static HMODULE ghMozCtlX = NULL;
static HMODULE ghMozCtl = NULL;
static const _TCHAR *c_szMozCtlDll = _T("mozctl.dll");
static const _TCHAR *c_szMozillaControlKey = _T("Software\\Mozilla\\");
static const _TCHAR *c_szMozillaBinDirPathValue = _T("BinDirectoryPath");
static const _TCHAR *c_szMozCtlInProcServerKey = _T("CLSID\\{1339B54C-3453-11D2-93B9-000000000000}\\InProcServer32");
static LPCTSTR c_szMozCtlDll = _T("mozctl.dll");
static LPCTSTR c_szMozillaControlKey = _T("Software\\Mozilla\\");
static LPCTSTR c_szMozillaBinDirPathValue = _T("BinDirectoryPath");
static LPCTSTR c_szMozCtlInProcServerKey =
_T("CLSID\\{1339B54C-3453-11D2-93B9-000000000000}\\InProcServer32");
// Message strings - should come from a resource file
static LPCTSTR c_szWarningTitle =
_T("Mozilla Control Warning");
static LPCTSTR c_szErrorTitle =
_T("Mozilla Control Error");
static LPCTSTR c_szPrePickFolderMsg =
_T("The Mozilla control was unable to detect where your Mozilla "
"layout libraries may be found. You will now be shown a directory "
"picker for you to locate them.");
static LPCTSTR c_szPickFolderDlgTitle =
_T("Pick where the Mozilla bin directory is located, "
"e.g. (c:\\mozilla\\bin)");
static LPCTSTR c_szRegistryErrorMsg =
_T("The Mozilla control was unable to store the location of the Mozilla"
"layout libraries in the registry. This may be due to the host "
"program running with insufficient permissions to write there.\n\n"
"You should consider running the control once as Administrator "
"to enable this entry to added or alternatively move the "
"control files mozctlx.dll and mozctl.dll into the same folder as "
"the other libraries.");
static LPCTSTR c_szLoadErrorMsg =
_T("The Mozilla control could not be loaded correctly. This is could "
"be due to an invalid location being specified for the Mozilla "
"layout libraries or missing files from your installation.\n\n"
"Visit http://www.iol.ie/~locka/mozilla/mozilla.htm for in-depth"
"troubleshooting advice.");
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
ghMozCtlX = (HMODULE) hModule;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
{
case DLL_PROCESS_ATTACH:
ghMozCtlX = (HMODULE) hModule;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
if (ghMozCtl)
{
FreeLibrary(ghMozCtl);
ghMozCtl = NULL;
}
break;
}
return TRUE;
}
static BOOL LoadMozLibrary(BOOL bAskUserToSetPath = TRUE)
{
if (ghMozCtl)
{
return TRUE;
}
if (ghMozCtl)
{
return TRUE;
}
ghMozCtl = LoadLibrary(c_szMozCtlDll);
if (ghMozCtl)
{
return TRUE;
}
ghMozCtl = LoadLibrary(c_szMozCtlDll);
if (ghMozCtl)
{
return TRUE;
}
// Try modifying the PATH environment variable
HKEY hkey = NULL;
DWORD dwDisposition = 0;
RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szMozillaControlKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL);
if (hkey)
{
_TCHAR szBinDirPath[MAX_PATH + 1];
DWORD dwBufSize = sizeof(szBinDirPath);
DWORD dwType = REG_SZ;
ZeroMemory(szBinDirPath, dwBufSize);
RegQueryValueEx(hkey, c_szMozillaBinDirPathValue, NULL, &dwType, (LPBYTE) szBinDirPath, &dwBufSize);
if (LoadMozLibraryFromCurrentDir())
{
return TRUE;
}
// Append the bin dir path to the PATH environment variable
int nPathLength = lstrlen(szBinDirPath);
if (bAskUserToSetPath && nPathLength == 0)
{
// TODO ask the user if they wish to set the bin dir path to something
// Show a folder picker for the user to choose the bin directory
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.hwndOwner = NULL;
bi.pidlRoot = NULL;
bi.pszDisplayName = szBinDirPath;
bi.lpszTitle = _T("Pick where the Mozilla bin directory is located, e.g. (c:\\mozilla\\bin)");
LPITEMIDLIST pItemList = SHBrowseForFolder(&bi);
if (pItemList)
{
// Get the path from the user selection
IMalloc *pShellAllocator = NULL;
SHGetMalloc(&pShellAllocator);
if (pShellAllocator)
{
char szPath[MAX_PATH + 1];
if (LoadMozLibraryFromRegistry(bAskUserToSetPath))
{
return TRUE;
}
if (SHGetPathFromIDList(pItemList, szPath))
{
// Chop off the end path seperator
int nPathSize = strlen(szPath);
if (nPathSize > 0)
{
if (szPath[nPathSize - 1] == '\\')
{
szPath[nPathSize - 1] = '\0';
}
}
::MessageBox(NULL, c_szLoadErrorMsg, c_szErrorTitle, MB_OK);
// Form the file pattern
return FALSE;
}
static BOOL LoadMozLibraryFromCurrentDir()
{
TCHAR szMozCtlXPath[MAX_PATH + 1];
// Get this module's path
ZeroMemory(szMozCtlXPath, sizeof(szMozCtlXPath));
GetModuleFileName(ghMozCtlX, szMozCtlXPath,
sizeof(szMozCtlXPath) / sizeof(szMozCtlXPath[0]));
// Make the control path
TCHAR szTmpDrive[_MAX_DRIVE];
TCHAR szTmpDir[_MAX_DIR];
TCHAR szTmpFname[_MAX_FNAME];
TCHAR szTmpExt[_MAX_EXT];
_tsplitpath(szMozCtlXPath, szTmpDrive, szTmpDir, szTmpFname, szTmpExt);
TCHAR szMozCtlPath[MAX_PATH + 1];
ZeroMemory(szMozCtlPath, sizeof(szMozCtlPath));
_tmakepath(szMozCtlPath, szTmpDrive, szTmpDir, c_szMozCtlDll, NULL);
// Stat to see if the control exists
struct _stat dirStat;
if (_tstat(szMozCtlPath, &dirStat) == 0)
{
TCHAR szBinDirPath[MAX_PATH + 1];
ZeroMemory(szBinDirPath, sizeof(szBinDirPath));
_tmakepath(szBinDirPath, szTmpDrive, szTmpDir, NULL, NULL);
if (LoadLibraryWithPATHFixup(szBinDirPath))
{
return TRUE;
}
}
return FALSE;
}
static BOOL LoadMozLibraryFromRegistry(BOOL bAskUserToSetPath)
{
//
HKEY hkey = NULL;
TCHAR szBinDirPath[MAX_PATH + 1];
DWORD dwBufSize = sizeof(szBinDirPath);
ZeroMemory(szBinDirPath, dwBufSize);
// First try and read the path from the registry
RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szMozillaControlKey, 0, KEY_READ, &hkey);
if (hkey)
{
DWORD dwType = REG_SZ;
RegQueryValueEx(hkey, c_szMozillaBinDirPathValue, NULL, &dwType,
(LPBYTE) szBinDirPath, &dwBufSize);
RegCloseKey(hkey);
hkey = NULL;
if (lstrlen(szBinDirPath) > 0 && LoadLibraryWithPATHFixup(szBinDirPath))
{
return TRUE;
}
// NOTE: We will drop through here if the registry key existed
// but didn't lead to the control being loaded.
}
// Ask the user to pick to pick the path?
if (bAskUserToSetPath)
{
// Tell the user that they have to pick the bin dir path
::MessageBox(NULL, c_szPrePickFolderMsg, c_szWarningTitle, MB_OK);
// Show a folder picker for the user to choose the bin directory
BROWSEINFO bi;
ZeroMemory(&bi, sizeof(bi));
bi.hwndOwner = NULL;
bi.pidlRoot = NULL;
bi.pszDisplayName = szBinDirPath;
bi.lpszTitle = c_szPickFolderDlgTitle;
LPITEMIDLIST pItemList = SHBrowseForFolder(&bi);
if (pItemList)
{
// Get the path from the user selection
IMalloc *pShellAllocator = NULL;
SHGetMalloc(&pShellAllocator);
if (pShellAllocator)
{
char szPath[MAX_PATH + 1];
if (SHGetPathFromIDList(pItemList, szPath))
{
// Chop off the end path seperator
int nPathSize = strlen(szPath);
if (nPathSize > 0)
{
if (szPath[nPathSize - 1] == '\\')
{
szPath[nPathSize - 1] = '\0';
}
}
// Form the file pattern
#ifdef UNICODE
MultiByteToWideChar(CP_ACP, 0, szPath, szBinDirPath, -1, sizeof(szBinDirPath) / sizeof(_TCHAR));
MultiByteToWideChar(CP_ACP, 0, szPath, szBinDirPath, -1,
sizeof(szBinDirPath) / sizeof(TCHAR));
#else
lstrcpy(szBinDirPath, szPath);
lstrcpy(szBinDirPath, szPath);
#endif
}
pShellAllocator->Free(pItemList);
pShellAllocator->Release();
}
}
// Store the new path if it was set
nPathLength = lstrlen(szBinDirPath);
if (nPathLength > 0)
{
RegSetValueEx(hkey, c_szMozillaBinDirPathValue, 0, REG_SZ,
(LPBYTE) szBinDirPath, _tcslen(szBinDirPath) * sizeof(_TCHAR));
}
}
}
pShellAllocator->Free(pItemList);
pShellAllocator->Release();
}
}
// Store the new path if we can
if (lstrlen(szBinDirPath) > 0)
{
RegCreateKeyEx(HKEY_LOCAL_MACHINE, c_szMozillaControlKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL);
if (hkey)
{
RegSetValueEx(hkey, c_szMozillaBinDirPathValue, 0, REG_SZ,
(LPBYTE) szBinDirPath, lstrlen(szBinDirPath) * sizeof(TCHAR));
RegCloseKey(hkey);
}
else
{
// Tell the user the key can't be stored but the path they
// chose will be used for this session
::MessageBox(NULL, c_szRegistryErrorMsg, c_szErrorTitle, MB_OK);
}
}
}
RegCloseKey(hkey);
if (lstrlen(szBinDirPath) > 0 && LoadLibraryWithPATHFixup(szBinDirPath))
{
return TRUE;
}
if (nPathLength > 0)
{
_TCHAR szPath[8192];
ZeroMemory(szPath, sizeof(szPath));
GetEnvironmentVariable("PATH", szPath, sizeof(szPath) / sizeof(_TCHAR));
lstrcat(szPath, _T(";"));
lstrcat(szPath, szBinDirPath);
SetEnvironmentVariable("PATH", szPath);
return FALSE;
}
ghMozCtl = LoadLibrary(c_szMozCtlDll);
if (ghMozCtl)
{
return TRUE;
}
}
}
static BOOL LoadLibraryWithPATHFixup(const TCHAR *szBinDirPath)
{
TCHAR szOldPath[8192];
TCHAR szNewPath[8192];
ZeroMemory(szOldPath, sizeof(szOldPath));
ZeroMemory(szNewPath, sizeof(szNewPath));
return FALSE;
// Append path to front of PATH
GetEnvironmentVariable("PATH", szOldPath, sizeof(szOldPath) / sizeof(TCHAR));
lstrcat(szNewPath, szBinDirPath);
lstrcat(szNewPath, _T(";"));
lstrcat(szNewPath, szOldPath);
SetEnvironmentVariable("PATH", szNewPath);
// Attempt load
ghMozCtl = LoadLibrary(c_szMozCtlDll);
if (ghMozCtl)
{
return TRUE;
}
// Restore old PATH
SetEnvironmentVariable("PATH", szOldPath);
return FALSE;
}
static BOOL FixupInProcRegistryEntry()
{
_TCHAR szMozCtlXLongPath[MAX_PATH+1];
ZeroMemory(szMozCtlXLongPath, sizeof(szMozCtlXLongPath));
GetModuleFileName(ghMozCtlX, szMozCtlXLongPath, sizeof(szMozCtlXLongPath) * sizeof(_TCHAR));
TCHAR szMozCtlXLongPath[MAX_PATH+1];
ZeroMemory(szMozCtlXLongPath, sizeof(szMozCtlXLongPath));
GetModuleFileName(ghMozCtlX, szMozCtlXLongPath,
sizeof(szMozCtlXLongPath) * sizeof(TCHAR));
_TCHAR szMozCtlXPath[MAX_PATH+1];
ZeroMemory(szMozCtlXPath, sizeof(szMozCtlXPath));
GetShortPathName(szMozCtlXLongPath, szMozCtlXPath, sizeof(szMozCtlXPath) * sizeof(_TCHAR));
TCHAR szMozCtlXPath[MAX_PATH+1];
ZeroMemory(szMozCtlXPath, sizeof(szMozCtlXPath));
GetShortPathName(szMozCtlXLongPath, szMozCtlXPath,
sizeof(szMozCtlXPath) * sizeof(TCHAR));
HKEY hkey = NULL;
RegOpenKeyEx(HKEY_CLASSES_ROOT, c_szMozCtlInProcServerKey, 0, KEY_ALL_ACCESS, &hkey);
if (hkey)
{
RegSetValueEx(hkey, NULL, 0, REG_SZ, (LPBYTE) szMozCtlXPath, lstrlen(szMozCtlXPath) * sizeof(_TCHAR));
RegCloseKey(hkey);
return TRUE;
}
HKEY hkey = NULL;
RegOpenKeyEx(HKEY_CLASSES_ROOT, c_szMozCtlInProcServerKey, 0, KEY_ALL_ACCESS, &hkey);
if (hkey)
{
RegSetValueEx(hkey, NULL, 0, REG_SZ, (LPBYTE) szMozCtlXPath,
lstrlen(szMozCtlXPath) * sizeof(TCHAR));
RegCloseKey(hkey);
return TRUE;
}
return FALSE;
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
@ -189,15 +325,16 @@ typedef HRESULT (STDAPICALLTYPE *DllCanUnloadNowFn)(void);
STDAPI DllCanUnloadNow(void)
{
if (LoadMozLibrary())
{
DllCanUnloadNowFn pfn = (DllCanUnloadNowFn) GetProcAddress(ghMozCtl, _T("DllCanUnloadNow"));
if (pfn)
{
return pfn();
}
}
return S_OK;
if (LoadMozLibrary())
{
DllCanUnloadNowFn pfn = (DllCanUnloadNowFn)
GetProcAddress(ghMozCtl, _T("DllCanUnloadNow"));
if (pfn)
{
return pfn();
}
}
return S_OK;
}
/////////////////////////////////////////////////////////////////////////////
@ -207,15 +344,16 @@ typedef HRESULT (STDAPICALLTYPE *DllGetClassObjectFn)(REFCLSID rclsid, REFIID ri
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
if (LoadMozLibrary())
{
DllGetClassObjectFn pfn = (DllGetClassObjectFn) GetProcAddress(ghMozCtl, _T("DllGetClassObject"));
if (pfn)
{
return pfn(rclsid, riid, ppv);
}
}
return E_FAIL;
if (LoadMozLibrary())
{
DllGetClassObjectFn pfn = (DllGetClassObjectFn)
GetProcAddress(ghMozCtl, _T("DllGetClassObject"));
if (pfn)
{
return pfn(rclsid, riid, ppv);
}
}
return E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
@ -225,20 +363,21 @@ typedef HRESULT (STDAPICALLTYPE *DllRegisterServerFn)(void);
STDAPI DllRegisterServer(void)
{
if (LoadMozLibrary())
{
DllRegisterServerFn pfn = (DllRegisterServerFn) GetProcAddress(ghMozCtl, _T("DllRegisterServer"));
if (pfn)
{
HRESULT hr = pfn();
if (SUCCEEDED(hr))
{
FixupInProcRegistryEntry();
}
return hr;
}
}
return E_FAIL;
if (LoadMozLibrary())
{
DllRegisterServerFn pfn = (DllRegisterServerFn)
GetProcAddress(ghMozCtl, _T("DllRegisterServer"));
if (pfn)
{
HRESULT hr = pfn();
if (SUCCEEDED(hr))
{
FixupInProcRegistryEntry();
}
return hr;
}
}
return E_FAIL;
}
/////////////////////////////////////////////////////////////////////////////
@ -248,13 +387,14 @@ typedef HRESULT (STDAPICALLTYPE *DllUnregisterServerFn)(void);
STDAPI DllUnregisterServer(void)
{
if (LoadMozLibrary())
{
DllUnregisterServerFn pfn = (DllUnregisterServerFn) GetProcAddress(ghMozCtl, _T("DllUnregisterServer"));
if (pfn)
{
return pfn();
}
}
return E_FAIL;
if (LoadMozLibrary())
{
DllUnregisterServerFn pfn = (DllUnregisterServerFn)
GetProcAddress(ghMozCtl, _T("DllUnregisterServer"));
if (pfn)
{
return pfn();
}
}
return E_FAIL;
}