193 lines
5.9 KiB
C++
193 lines
5.9 KiB
C++
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// File: allcmdir.cpp
|
||
|
//
|
||
|
// Module: CMCFG32.DLL and CMSTP.EXE
|
||
|
//
|
||
|
// Synopsis: Implementation of GetAllUsersCmDir
|
||
|
//
|
||
|
// Copyright (c) 1999 Microsoft Corporation
|
||
|
//
|
||
|
// Author: quintinb Created Header 08/19/99
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: GetAllUsersCmDir
|
||
|
//
|
||
|
// Synopsis: This function fills in the string passed in with the path to the
|
||
|
// path where CM should be installed. For instance, it should return
|
||
|
// c:\Documents and Settings\All Users\Application Data\Microsoft\Network\Connections\Cm
|
||
|
//
|
||
|
// Arguments: LPTSTR pszDir - String to the Users Connection Manager Directory
|
||
|
//
|
||
|
// Returns: LPTSTR - String to the Users Connection Manager Directory
|
||
|
//
|
||
|
// History: quintinb Created Header 2/19/98
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
BOOL GetAllUsersCmDir(LPTSTR pszDir, HINSTANCE hInstance)
|
||
|
{
|
||
|
MYDBGASSERT(pszDir);
|
||
|
pszDir[0] = TEXT('\0');
|
||
|
|
||
|
LPMALLOC pMalloc;
|
||
|
HRESULT hr = SHGetMalloc(&pMalloc);
|
||
|
if (FAILED (hr))
|
||
|
{
|
||
|
CMASSERTMSG(FALSE, TEXT("Failed to get a Shell Malloc Pointer."));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
TCHAR szCmSubFolder[MAX_PATH+1];
|
||
|
TCHAR szAppData[MAX_PATH+1];
|
||
|
TCHAR szDesktop[MAX_PATH+1];
|
||
|
LPITEMIDLIST pidl;
|
||
|
BOOL bReturn = FALSE;
|
||
|
|
||
|
//
|
||
|
// We really want the Common App Data dir, but this CSIDL value is only supported on
|
||
|
// NT5 so far. If this succeeds, we only need to append the path to it.
|
||
|
//
|
||
|
hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_APPDATA, &pidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (!SHGetPathFromIDList(pidl, pszDir))
|
||
|
{
|
||
|
CMASSERTMSG(FALSE, TEXT("GetAllUsersCmDir -- SHGetPathFromIDList Failed to retrieve CSIDL_COMMON_APPDATA"));
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
pMalloc->Free(pidl);
|
||
|
pidl = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Of course, things aren't always that easy, lets try getting the regular
|
||
|
// Application Data dir. We can hopefully combine the returns from two
|
||
|
// CSIDL's like CSIDL_APPDATA and CSIDL_COMMON_DESKTOPDIRECTORY to acheive the
|
||
|
// same affect on older machines.
|
||
|
//
|
||
|
|
||
|
hr = SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (!SHGetPathFromIDList(pidl, szAppData))
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
pMalloc->Free(pidl);
|
||
|
pidl = NULL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// CSIDL_APPDATA isn't even supported on win95 gold
|
||
|
//
|
||
|
MYVERIFY(0 != LoadString(hInstance, IDS_APPDATA, szAppData, MAX_PATH));
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Now lets try to get the Common Desktop Directory to combine the two
|
||
|
//
|
||
|
BOOL bCommonFound = FALSE;
|
||
|
|
||
|
hr = SHGetSpecialFolderLocation(NULL, CSIDL_COMMON_DESKTOPDIRECTORY, &pidl);
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
if (SHGetPathFromIDList(pidl, szDesktop))
|
||
|
{
|
||
|
bCommonFound = TRUE;
|
||
|
}
|
||
|
|
||
|
pMalloc->Free(pidl);
|
||
|
pidl = NULL;
|
||
|
}
|
||
|
|
||
|
if (!bCommonFound)
|
||
|
{
|
||
|
//
|
||
|
// Okay, next lets try the Reg Key for the common desktop directory.
|
||
|
// (Win98 gold with profiling contains the reg key but the CSIDL fails)
|
||
|
//
|
||
|
const TCHAR* const c_pszRegShellFolders = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
|
||
|
const TCHAR* const c_pszRegCommonDesktop = TEXT("Common Desktop");
|
||
|
HKEY hKey;
|
||
|
|
||
|
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, c_pszRegShellFolders,
|
||
|
0, KEY_READ, &hKey))
|
||
|
{
|
||
|
DWORD dwSize = MAX_PATH;
|
||
|
DWORD dwType = REG_SZ;
|
||
|
|
||
|
if (ERROR_SUCCESS == RegQueryValueEx(hKey, c_pszRegCommonDesktop,
|
||
|
NULL, &dwType, (LPBYTE)szDesktop,
|
||
|
&dwSize))
|
||
|
{
|
||
|
bCommonFound = TRUE;
|
||
|
}
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!bCommonFound)
|
||
|
{
|
||
|
//
|
||
|
// As a fall back lets try the windows directory, NTRAID 374912
|
||
|
//
|
||
|
if (GetWindowsDirectory(szDesktop, MAX_PATH))
|
||
|
{
|
||
|
//
|
||
|
// Then we have the windows directory, but we need to append
|
||
|
// \\Desktop so that the parsing logic which follows parses
|
||
|
// this correctly. It is expecting the path to the desktop dir
|
||
|
// not a path to the windows dir (if we didn't we would end up with
|
||
|
// c:\Application Data instead of c:\windows\Application data as we
|
||
|
// want and expect). Note that there is no need to worry about
|
||
|
// localization of Desktop because we are going to remove it anyway.
|
||
|
//
|
||
|
lstrcat(szDesktop, TEXT("\\Desktop"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CFileNameParts AppData(szAppData);
|
||
|
CFileNameParts CommonDesktop(szDesktop);
|
||
|
|
||
|
wsprintf(pszDir, TEXT("%s%s%s"), CommonDesktop.m_Drive, CommonDesktop.m_Dir,
|
||
|
AppData.m_FileName, AppData.m_Extension);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Now append the CM sub directory structure
|
||
|
//
|
||
|
if (!LoadString(hInstance, IDS_CMSUBFOLDER, szCmSubFolder, MAX_PATH))
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
MYVERIFY(NULL != lstrcat(pszDir, szCmSubFolder));
|
||
|
|
||
|
bReturn = TRUE;
|
||
|
|
||
|
exit:
|
||
|
//
|
||
|
// Free the allocated pidl if necessary
|
||
|
//
|
||
|
if (pidl)
|
||
|
{
|
||
|
pMalloc->Free(pidl);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// release the shell's IMalloc ptr
|
||
|
//
|
||
|
pMalloc->Release();
|
||
|
|
||
|
return bReturn;
|
||
|
}
|