#include "shellprv.h" #pragma hdrstop #include "mtpt.h" #include "ids.h" #include "shitemid.h" #include "filetbl.h" #include "shpriv.h" #include "hwcmmn.h" #include "apithk.h" #include /////////////////////////////////////////////////////////////////////////////// // Public methods /////////////////////////////////////////////////////////////////////////////// // get the friendly name for a given drive thing // for example: // Floppy (A:) // Volume Name (D:) // User on 'Pyrex' (V:) // Dist on Strike\sys\public (Netware case) HRESULT CMountPoint::GetDisplayName(LPTSTR pszName, DWORD cchName) { HRESULT hres = E_FAIL; TCHAR szDriveLabel[MAX_DISPLAYNAME]; static BOOL s_fAllDriveLetterFirst = -1; static BOOL s_fRemoteDriveLetterFirst = -1; static BOOL s_fNoDriveLetter = -1; ASSERT(cchName > 0); *pszName = 0; // handle failure case // for s_fDriveLetterFirst, see bug 250899, that's a long story. if (-1 == s_fRemoteDriveLetterFirst) { DWORD dw; DWORD cb = sizeof(dw); s_fRemoteDriveLetterFirst = FALSE; s_fAllDriveLetterFirst = FALSE; s_fNoDriveLetter = FALSE; if (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"), TEXT("ShowDriveLettersFirst"), NULL, &dw, &cb)) { if (1 == dw) { s_fRemoteDriveLetterFirst = TRUE; } else { if (2 == dw) { s_fNoDriveLetter = TRUE; } else { if (4 == dw) { s_fAllDriveLetterFirst = TRUE; } } } } } hres = GetLabel(szDriveLabel, ARRAYSIZE(szDriveLabel)); if (SUCCEEDED(hres)) { if (s_fNoDriveLetter) { StrCpyN(pszName, szDriveLabel, cchName); } else { BOOL fDriveLetterFirst = ((_IsRemote()) && s_fRemoteDriveLetterFirst) || s_fAllDriveLetterFirst; // To return something like: "My Drive (c:)", we need a drive letter. // Fortunately for us this fct is only called for a drive mounted on a // letter (from drive implementation of IShellFolder), for volumes mounted // on folders, the folder impl is called rather than the drive one. LPTSTR psz = ShellConstructMessageString(HINST_THISDLL, MAKEINTRESOURCE(fDriveLetterFirst ? IDS_VOL_FORMAT_LETTER_1ST : IDS_VOL_FORMAT), szDriveLabel, _GetNameFirstCharUCase()); if (psz) { StrCpyN(pszName, psz, cchName); LocalFree(psz); } else { hres = E_OUTOFMEMORY; } } } return hres; } // { DRIVE_ISCOMPRESSIBLE | DRIVE_COMPRESSED | DRIVE_LFN | DRIVE_SECURITY } int CMountPoint::GetVolumeFlags() { int iFlags = _GetGVIDriveFlags(); // Try to avoid getting the attributes if (iFlags & DRIVE_ISCOMPRESSIBLE) { DWORD dwAttrib = -1; if (_GetFileAttributes(&dwAttrib)) { if (dwAttrib & FILE_ATTRIBUTE_COMPRESSED) { iFlags |= DRIVE_COMPRESSED; } } } return iFlags; } DWORD CMountPoint::GetClusterSize() { DWORD dwSecPerClus, dwBytesPerSec, dwClusters, dwTemp; // assume this, avoid div by zero DWORD dwRet = 512; if (GetDiskFreeSpace(_GetNameForFctCall(), &dwSecPerClus, &dwBytesPerSec, &dwTemp, &dwClusters)) { dwRet = dwSecPerClus * dwBytesPerSec; } return dwRet; } //static void CMountPoint::GetTypeString(int iDrive, LPTSTR pszType, DWORD cchType) { *pszType = 0; CMountPoint* pmtpt = GetMountPoint(iDrive); if (pmtpt) { pmtpt->GetTypeString(pszType, cchType); pmtpt->Release(); } } // static UINT CMountPoint::GetSuperPlainDriveIcon(LPCWSTR pszDrive, UINT uDriveType) { int iIcon; switch (uDriveType) { case DRIVE_REMOVABLE: { iIcon = II_DRIVEREMOVE; if (pszDrive) { if ((TEXT('a') == *pszDrive) || (TEXT('A') == *pszDrive)) { iIcon = II_DRIVE35; } else { if ((TEXT('b') == *pszDrive) || (TEXT('B') == *pszDrive)) { iIcon = II_DRIVE35; } } } break; } case DRIVE_FIXED: { iIcon = II_DRIVEFIXED; break; } case DRIVE_REMOTE: { iIcon = II_DRIVENET; break; } case DRIVE_CDROM: { iIcon = II_DRIVECD; break; } case DRIVE_RAMDISK: { iIcon = II_DRIVERAM; break; } case DRIVE_UNKNOWN: case DRIVE_NO_ROOT_DIR: default: { iIcon = -IDI_DRIVEUNKNOWN; break; } } return iIcon; } /////////////////////////////////////////////////////////////////////////////// // Call Backs /////////////////////////////////////////////////////////////////////////////// void CMountPoint::_UpdateCommentFromDesktopINI() { WCHAR szCommentFromDesktopINI[MAX_MTPTCOMMENT]; GetShellClassInfoInfoTip(_GetName(), szCommentFromDesktopINI, ARRAYSIZE(szCommentFromDesktopINI)); RSSetTextValue(NULL, TEXT("_CommentFromDesktopINI"), szCommentFromDesktopINI, REG_OPTION_NON_VOLATILE); } /////////////////////////////////////////////////////////////////////////////// // Default Icon/Label /////////////////////////////////////////////////////////////////////////////// void CMountPoint::_InitLegacyRegIconAndLabel(BOOL fUseAutorunIcon, BOOL fUseAutorunLabel) { // No Autorun icon, load the legacy reg icon if any if (!fUseAutorunIcon && _IsMountedOnDriveLetter()) { WCHAR szSubKey[MAX_PATH]; WCHAR szIconLocation[MAX_PATH + 12]; wnsprintf(szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\%c\\DefaultIcon"), _GetNameFirstCharUCase()); szIconLocation[0] = 0; if (!RegGetValueString(HKEY_LOCAL_MACHINE, szSubKey, NULL, szIconLocation, ARRAYSIZE(szIconLocation) * sizeof(TCHAR))) { // Let's try second location wnsprintf(szSubKey, ARRAYSIZE(szSubKey), TEXT("Applications\\Explorer.exe\\Drives\\%c\\DefaultIcon"), _GetNameFirstCharUCase()); RegGetValueString(HKEY_CLASSES_ROOT, szSubKey, NULL, szIconLocation, ARRAYSIZE(szIconLocation) * sizeof(TCHAR)); } if (szIconLocation[0]) { AssertMsg(!_pszLegacyRegIcon, TEXT("_InitLegacyRegIconAndLabel: called twice")); _pszLegacyRegIcon = StrDup(szIconLocation); } } if (!fUseAutorunLabel && _IsMountedOnDriveLetter()) { WCHAR szSubKey[MAX_PATH]; WCHAR szLabel[MAX_LABEL]; wnsprintf(szSubKey, ARRAYSIZE(szSubKey), TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\DriveIcons\\%c\\DefaultLabel"), _GetNameFirstCharUCase()); szLabel[0] = 0; if (!RegGetValueString(HKEY_LOCAL_MACHINE, szSubKey, NULL, szLabel, ARRAYSIZE(szLabel) * sizeof(TCHAR))) { // Let's try second location wnsprintf(szSubKey, ARRAYSIZE(szSubKey), TEXT("Applications\\Explorer.exe\\Drives\\%c\\DefaultLabel"), _GetNameFirstCharUCase()); RegGetValueString(HKEY_CLASSES_ROOT, szSubKey, NULL, szLabel, ARRAYSIZE(szLabel) * sizeof(TCHAR)); } if (szLabel[0]) { AssertMsg(!_pszLegacyRegLabel, TEXT("_InitLegacyRegIconAndLabel: called twice")); _pszLegacyRegLabel = StrDup(szLabel); } } } BOOL CMountPoint::_GetLegacyRegLabel(LPTSTR pszLabel, DWORD cchLabel) { BOOL fRet; if (_pszLegacyRegLabel) { StrCpyN(pszLabel, _pszLegacyRegLabel, cchLabel); fRet = TRUE; } else { *pszLabel = 0; fRet = FALSE; } return fRet; } LPCTSTR CMountPoint::_GetNameForFctCall() { return _szName; } // the first character in the name, and convert it to upper case // the first character is generally the drive letter TCHAR CMountPoint::_GetNameFirstCharUCase() { return (TCHAR) CharUpper((LPTSTR) _szName[0]); } LPTSTR CMountPoint::_GetNameFirstXChar(LPTSTR pszBuffer, int c) { StrCpyN(pszBuffer, _szName, c); return pszBuffer; } LPCTSTR CMountPoint::_GetNameDebug() { return _szName; } LPCTSTR CMountPoint::_GetName() { return _szName; } /////////////////////////////////////////////////////////////////////////////// // Misc /////////////////////////////////////////////////////////////////////////////// // // External API for use by non-CPP modules. // HRESULT MountPoint_RegisterChangeNotifyAlias(int iDrive) { HRESULT hr = E_FAIL; CMountPoint* pMtPt = CMountPoint::GetMountPoint(iDrive); if (pMtPt) { pMtPt->ChangeNotifyRegisterAlias(); pMtPt->Release(); hr = NOERROR; } return hr; } HRESULT CMountPoint::GetComment(LPTSTR pszComment, DWORD cchComment) { RSGetTextValue(NULL, TEXT("_CommentFromDesktopINI"), pszComment, &cchComment); return *pszComment ? S_OK : E_FAIL; } BOOL CMountPoint::GetFileSystemName(LPTSTR pszFileSysName, DWORD cchFileSysName) { return _GetFileSystemName(pszFileSysName, cchFileSysName); } BOOL CMountPoint::_GetLabelFromReg(LPWSTR psz, DWORD cch) { *psz = 0; return (RSGetTextValue(NULL, TEXT("_LabelFromReg"), psz, &cch) && *psz); } BOOL CMountPoint::_GetLabelFromDesktopINI(LPWSTR psz, DWORD cch) { *psz = 0; return (RSGetTextValue(NULL, TEXT("_LabelFromDesktopINI"), psz, &cch) && *psz); } DWORD CMountPoint::GetAttributes() { DWORD dwAttrib; _GetFileAttributes(&dwAttrib); return dwAttrib; } CMountPoint::CMountPoint() : _cRef(1) { } ULONG CMountPoint::AddRef() { return InterlockedIncrement(&_cRef); } ULONG CMountPoint::Release() { if (InterlockedDecrement(&_cRef) > 0) return _cRef; delete this; return 0; }