mtpt.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 36k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "shellprv.h"
  2. #pragma  hdrstop
  3. #include "mtpt.h"
  4. #include "ids.h"
  5. #include "shitemid.h"
  6. #include "apithk.h"
  7. #ifdef WINNT
  8. #include <ntddcdrm.h>
  9. #else
  10. #define Not_VxD
  11. #include <vwin32.h>     // DeviceIOCtl calls
  12. #endif
  13. #define REGSTR_MTPT_ROOTKEY TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints")
  14. #define FILE_ATTRIBUTE_INVALID 0xFFFFFFFF
  15. CRegSupportCached* CMountPoint::_prsStatic = NULL;
  16. #ifdef DEBUG
  17. int CMountPoint::_cMtPtDL = 0;
  18. int CMountPoint::_cMtPtMOF = 0;
  19. #endif
  20. ///////////////////////////////////////////////////////////////////////////////
  21. // Public methods
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // get the friendly name for a given drive thing
  24. // for example:
  25. //      Floppy (A:)
  26. //      Volume Name (D:)
  27. //      User on 'Pyrex' (V:)
  28. //      Dist on Strikesyspublic (Netware case)
  29. HRESULT CMountPoint::GetDisplayName(LPTSTR pszName, DWORD cchName)
  30. {
  31.     HRESULT hres = E_FAIL;
  32.     TCHAR szDriveLabel[MAX_DISPLAYNAME];
  33.     static BOOL s_fAllDriveLetterFirst = -1;
  34.     static BOOL s_fRemoteDriveLetterFirst = -1;
  35.     static BOOL s_fNoDriveLetter = -1;
  36.     ASSERT(cchName > 0);
  37.     *pszName = 0; // handle failure case
  38.     // for s_fDriveLetterFirst, see bug 250899, that's a long story.
  39.     if (-1 == s_fRemoteDriveLetterFirst)
  40.     {
  41.         DWORD dw;
  42.         DWORD cb = sizeof(dw);
  43.         s_fRemoteDriveLetterFirst = FALSE;
  44.         s_fAllDriveLetterFirst = FALSE;
  45.         s_fNoDriveLetter = FALSE;
  46.         if (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE, TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer"), 
  47.             TEXT("ShowDriveLettersFirst"), NULL, &dw, &cb))
  48.         {
  49.             if (1 == dw)
  50.             {
  51.                 s_fRemoteDriveLetterFirst = TRUE;
  52.             }
  53.             else
  54.             {
  55.                 if (2 == dw)
  56.                 {
  57.                     s_fNoDriveLetter = TRUE;
  58.                 }
  59.                 else
  60.                 {
  61.                     if (4 == dw)
  62.                     {
  63.                         s_fAllDriveLetterFirst = TRUE;
  64.                     }
  65.                 }
  66.             }
  67.         }
  68.     }
  69.     hres = GetLabel(szDriveLabel, ARRAYSIZE(szDriveLabel));
  70.     if (SUCCEEDED(hres))
  71.     {
  72.         if (s_fNoDriveLetter)
  73.         {
  74.             StrCpyN(pszName, szDriveLabel, cchName);
  75.         }
  76.         else
  77.         {
  78.             BOOL fDriveLetterFirst = ((DRIVE_REMOTE == _uDriveType) && s_fRemoteDriveLetterFirst) ||
  79.                                         s_fAllDriveLetterFirst;
  80.             // To return something like: "My Drive (c:)", we need a drive letter.
  81.             // Fortunately for us this fct is only called for a drive mounted on a
  82.             // letter (from drive implementation of IShellFolder), for volumes mounted
  83.             // on folders, the folder impl  is called rather than the drive one.
  84.             LPTSTR psz = ShellConstructMessageString(HINST_THISDLL, 
  85.                         MAKEINTRESOURCE(fDriveLetterFirst ? IDS_VOL_FORMAT_LETTER_1ST : IDS_VOL_FORMAT),
  86.                         szDriveLabel, _GetNameFirstChar());
  87.             if (psz)
  88.             {
  89.                 StrCpyN(pszName, psz, cchName);
  90.                 LocalFree(psz);
  91.             }
  92.             else
  93.             {
  94.                 hres = E_OUTOFMEMORY;
  95.             }
  96.         }
  97.     }
  98.     return hres;
  99. }
  100. int CMountPoint::GetDRIVEType(BOOL fOKToHitNet)
  101. {
  102.     TraceMsg(TF_MOUNTPOINT, "CMountPoint::GetDRIVEType: for '%s'", _GetName());
  103.     return _uDriveType;
  104. }
  105. int CMountPoint::GetDriveFlags()
  106. {
  107.     int i = 0;
  108.     if (_sdDriveFlags.Update())
  109.     {
  110.         i = __uDriveFlags;
  111.     }
  112.     return i;
  113. }
  114. // { DRIVE_ISCOMPRESSIBLE | DRIVE_COMPRESSED | DRIVE_LFN | DRIVE_SECURITY }
  115. int CMountPoint::GetVolumeFlags()
  116. {
  117.     int iFlags = _GetGVIDriveFlags();
  118.     // Try to avoid getting the attributes
  119.     if (iFlags & DRIVE_ISCOMPRESSIBLE)
  120.     {
  121.         DWORD dwAttrib = FILE_ATTRIBUTE_INVALID;
  122.         if (_GetAttributes(&dwAttrib))
  123.         {
  124.             if (dwAttrib & FILE_ATTRIBUTE_COMPRESSED)
  125.             {
  126.                 iFlags |= DRIVE_COMPRESSED;
  127.             }
  128.         }
  129.     }
  130.     return iFlags;
  131. }
  132. const ICONMAP c_aicmpDrive[] = {
  133.     { SHID_COMPUTER_DRIVE525 , II_DRIVE525      },
  134.     { SHID_COMPUTER_DRIVE35  , II_DRIVE35       },
  135.     { SHID_COMPUTER_FIXED    , II_DRIVEFIXED    },
  136.     { SHID_COMPUTER_REMOTE   , II_DRIVEFIXED    },
  137.     { SHID_COMPUTER_CDROM    , II_DRIVECD       },
  138.     { SHID_COMPUTER_NETDRIVE , II_DRIVENET      },
  139.     { SHID_COMPUTER_REMOVABLE, II_DRIVEREMOVE   },
  140.     { SHID_COMPUTER_RAMDISK  , II_DRIVERAM      },    
  141. };
  142. const int c_nicmpDrives = ARRAYSIZE(c_aicmpDrive);
  143. UINT CMountPoint::GetIcon(LPTSTR pszModule, DWORD cchModule)
  144. {
  145.     int bFlags = GetSHIDType(FALSE);
  146.     UINT uType = (bFlags & SHID_TYPEMASK);
  147.     UINT iIcon = -IDI_DRIVEUNKNOWN;
  148.     *pszModule = 0;
  149.     for (UINT i = 0; i < ARRAYSIZE(c_aicmpDrive); i++)
  150.     {
  151.         if (c_aicmpDrive[i].uType == uType)
  152.         {
  153.             iIcon = c_aicmpDrive[i].indexResource;
  154.             if (IsAudioDisc())
  155.                 iIcon = II_CDAUDIO;
  156.             break;
  157.         }
  158.     }
  159.     if (_IsAutoRun() || _HasDefaultIcon())
  160.     {
  161.         if (RSGetTextValue(TEXT("DefaultIcon"), NULL, pszModule, &cchModule))
  162.         {
  163.             iIcon = PathParseIconLocation(pszModule);
  164.         }
  165.         else
  166.         {
  167.             *pszModule = 0;
  168.         }
  169.     }
  170.     
  171.     if (*pszModule)
  172.         TraceMsg(TF_MOUNTPOINT, "CMountPoint::GetIcon: for '%s', chose '%s', '%d'", _GetName(), pszModule, iIcon);
  173.     else
  174.         TraceMsg(TF_MOUNTPOINT, "CMountPoint::GetIcon: for '%s', chose '%d'", _GetName(), iIcon);
  175.     return iIcon;
  176. }
  177. DWORD CMountPoint::GetClusterSize()
  178. {
  179.     DWORD dwSecPerClus, dwBytesPerSec, dwClusters, dwTemp;
  180.     // assume this, avoid div by zero
  181.     DWORD dwRet = 512;
  182. #ifndef WINNT
  183.     BOOL bFound = FALSE;
  184.     // Win95 FAT32 lies to GetDiskFreeSpace() because buggy apps can't
  185.     // deal with large return results here. so we try this IOCTL instead
  186.     // for drive based volumes
  187.     DevPB devpb;
  188.     devpb.SplFunctions = 0;     // get default (don't hit the drive!)
  189.     if (_DriveIOCTL(0x860, NULL, 0, &devpb, SIZEOF(devpb)))
  190.     {
  191.         dwRet = devpb.cbSec * devpb.secPerClus;
  192.         bFound = TRUE;
  193.     }
  194.     if (!bFound)
  195. #endif // !WINNT
  196.     {
  197.         if (GetDiskFreeSpace(_GetNameForFctCall(), &dwSecPerClus, &dwBytesPerSec, &dwTemp, &dwClusters))
  198.             dwRet = dwSecPerClus * dwBytesPerSec;
  199.     }
  200.     
  201.     return dwRet;   
  202. }
  203. HRESULT CMountPoint::SetLabel(LPCTSTR pszLabel)
  204. {
  205.     HRESULT hres = E_FAIL;
  206.     HDPA hdpaInvalidPath = DPA_Create(2);
  207.     StrCpyN(__szLabelFromReg, pszLabel, ARRAYSIZE(__szLabelFromReg));
  208.     hres = (_sdLabelFromReg.Propagate() ? S_OK : E_FAIL);
  209.     CMountPoint::InvalidateMountPoint(_szName, hdpaInvalidPath, MTPT_INV_LABEL);
  210.     if (hdpaInvalidPath && DPA_GetPtrCount(hdpaInvalidPath))
  211.     {
  212.         if (SUCCEEDED(hres))
  213.         {
  214.             int n = DPA_GetPtrCount(hdpaInvalidPath);
  215.             for (int i = 0; i < n; ++i)
  216.             {
  217.                 LPTSTR pszPath = (LPTSTR)DPA_GetPtr(hdpaInvalidPath, i);
  218.     
  219.                 if (pszPath)
  220.                 {
  221.                     SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_PATH, pszPath, pszPath);
  222.                     LocalFree((HLOCAL)pszPath);
  223.                 }
  224.             }
  225.         }
  226.     }
  227.     else
  228.     {
  229.         if (SUCCEEDED(hres))
  230.         {
  231.             SHChangeNotify(SHCNE_RENAMEFOLDER, SHCNF_PATH, _GetName(), _GetName());
  232.         }
  233.     }
  234.     if (hdpaInvalidPath)
  235.         DPA_Destroy(hdpaInvalidPath);
  236.     return hres;
  237. }
  238. const struct { BYTE bFlags; UINT uID; UINT uIDUgly; } c_drives_type[] = 
  239. {
  240.     { SHID_COMPUTER_REMOVABLE,  IDS_DRIVES_REMOVABLE , IDS_DRIVES_REMOVABLE },
  241.     { SHID_COMPUTER_DRIVE525,   IDS_DRIVES_DRIVE525  , IDS_DRIVES_DRIVE525_UGLY },
  242.     { SHID_COMPUTER_DRIVE35,    IDS_DRIVES_DRIVE35   , IDS_DRIVES_DRIVE35_UGLY  },
  243.     { SHID_COMPUTER_FIXED,      IDS_DRIVES_FIXED     , IDS_DRIVES_FIXED     },
  244.     { SHID_COMPUTER_REMOTE,     IDS_DRIVES_NETDRIVE  , IDS_DRIVES_NETDRIVE  },
  245.     { SHID_COMPUTER_CDROM,      IDS_DRIVES_CDROM     , IDS_DRIVES_CDROM     },
  246.     { SHID_COMPUTER_RAMDISK,    IDS_DRIVES_RAMDISK   , IDS_DRIVES_RAMDISK   },
  247.     { SHID_COMPUTER_NETDRIVE,   IDS_DRIVES_NETDRIVE  , IDS_DRIVES_NETDRIVE  },
  248.     { SHID_COMPUTER_NETUNAVAIL, IDS_DRIVES_NETUNAVAIL, IDS_DRIVES_NETUNAVAIL},
  249.     { SHID_COMPUTER_REGITEM,    IDS_DRIVES_REGITEM   , IDS_DRIVES_REGITEM   },
  250. };
  251. //static
  252. void CMountPoint::GetTypeString(BYTE bFlags, LPTSTR pszType, DWORD cchType)
  253. {
  254.     *pszType = 0;
  255.     for (int i = 0; i < ARRAYSIZE(c_drives_type); ++i)
  256.     {
  257.         if (c_drives_type[i].bFlags == (bFlags & SHID_TYPEMASK))
  258.         {
  259.             LoadString(HINST_THISDLL, _ShowUglyDriveNames() ? 
  260.                 c_drives_type[i].uIDUgly : c_drives_type[i].uID, pszType, cchType);
  261.             break;
  262.         }
  263.     }
  264. }
  265. void CMountPoint::GetTypeString(LPTSTR pszType, DWORD cchType)
  266. {
  267.     int iFlags = GetSHIDType(TRUE);
  268.     GetTypeString((BYTE)iFlags, pszType, cchType);
  269. }
  270. //static
  271. BOOL CMountPoint::GetDriveIDList(int iDrive, DRIVE_IDLIST *piddl)
  272. {
  273.     BOOL fRet = FALSE;
  274.     CMountPoint* pMtPt = CMountPoint::GetMountPoint(iDrive);
  275.     if (pMtPt)
  276.     {
  277.         fRet = pMtPt->_fDriveIDList;
  278.         if (fRet)
  279.             memcpy(piddl, &pMtPt->_DriveIDList, sizeof(DRIVE_IDLIST));
  280.         pMtPt->Release();
  281.     }
  282.     TraceMsg(TF_MOUNTPOINT, "static CMountPoint::GetDriveIDList: for '%d' -> %hs",
  283.         iDrive, fRet ? "HIT" : "MISS");
  284.     return fRet;
  285. }
  286. //static
  287. void CMountPoint::SetDriveIDList(int iDrive, DRIVE_IDLIST *piddl)
  288. {
  289.     CMountPoint* pMtPt = CMountPoint::GetMountPoint(iDrive);
  290.     if (pMtPt)
  291.     {
  292.         memcpy(&pMtPt->_DriveIDList, piddl, sizeof(DRIVE_IDLIST));
  293.         pMtPt->_fDriveIDList = TRUE;
  294.         pMtPt->Release();
  295.     }
  296.     TraceMsg(TF_MOUNTPOINT, "static CMountPoint::SetDriveIDList: for '%d'", iDrive);
  297. }
  298. HKEY CMountPoint::GetRegKey()
  299. {
  300.     TraceMsg(TF_MOUNTPOINT, "CMountPoint::GetRegKey: for '%s'", _GetName());
  301.     return RSDuplicateRootKey();
  302. }
  303. #ifndef WINNT
  304. BOOL CMountPoint::WantToHide()
  305. {
  306.     return _DriveIOCTL(0x872, NULL, 0, NULL, 0);
  307. }
  308. #endif
  309. BOOL CMountPoint::GetFileSystemName(LPTSTR pszFileSysName, DWORD cchFileSysName)
  310. {
  311.     BOOL fRet = _sdGVI.Update();
  312.     if (fRet)
  313.     {
  314.         StrCpyN(pszFileSysName, __gvi.szFileSysName, cchFileSysName);
  315.     }
  316.     else
  317.     {
  318.         *pszFileSysName = 0;
  319.     }
  320.     return fRet;
  321. }
  322. BOOL CMountPoint::GetFileSystemFlags(DWORD* pdwFlags)
  323. {
  324.     return _GetFileSystemFlags(pdwFlags);
  325. }
  326. HRESULT CMountPoint::GetComment(LPTSTR pszComment, DWORD cchComment)
  327. {
  328.     HRESULT hres = E_FAIL;
  329.     TCHAR szCommentFromDesktopINI[MAX_MTPTCOMMENT];
  330.     _sdCommentFromDesktopINI.SetBuffer(szCommentFromDesktopINI,
  331.         ARRAYSIZE(szCommentFromDesktopINI) * sizeof(TCHAR));
  332.     if ((DRIVE_REMOVABLE != _uDriveType) && 
  333.         (DRIVE_CDROM != _uDriveType) && 
  334.         _sdCommentFromDesktopINI.Update())
  335.     {
  336.         StrCpyN(pszComment, szCommentFromDesktopINI, cchComment);
  337.         hres = S_OK;
  338.     }
  339.     else
  340.     {
  341.         *pszComment = 0;
  342.     }
  343.     _sdCommentFromDesktopINI.ResetBuffer();
  344.     TraceMsg(TF_MOUNTPOINT, "CMountPoint::GetComment: for '%s' returned '%s'",
  345.         _GetName(), pszComment);
  346.     return hres;
  347. }
  348. HRESULT CMountPoint::GetHTMLInfoTipFile(LPTSTR pszHTMLInfoTipFile, DWORD cchHTMLInfoTipFile)
  349. {
  350.     HRESULT hres = E_FAIL;
  351.     TCHAR szHTMLInfoTipFileFromDesktopINI[MAX_PATH];
  352.     _sdHTMLInfoTipFileFromDesktopINI.SetBuffer(szHTMLInfoTipFileFromDesktopINI,
  353.         ARRAYSIZE(szHTMLInfoTipFileFromDesktopINI) * sizeof(TCHAR));
  354.     if ((DRIVE_REMOVABLE != _uDriveType) && 
  355.         (DRIVE_CDROM != _uDriveType) && 
  356.         _sdHTMLInfoTipFileFromDesktopINI.Update())
  357.     {
  358.         StrCpyN(pszHTMLInfoTipFile, szHTMLInfoTipFileFromDesktopINI, cchHTMLInfoTipFile);
  359.         hres = S_OK;
  360.     }
  361.     else
  362.     {
  363.         *pszHTMLInfoTipFile = 0;
  364.     }
  365.     _sdHTMLInfoTipFileFromDesktopINI.ResetBuffer();
  366.     TraceMsg(TF_MOUNTPOINT, "CMountPoint::GetHTMLInfoTipFile: for '%s' returned '%s'",
  367.         _GetName(), pszHTMLInfoTipFile);
  368.     return hres;
  369. }
  370. ///////////////////////////////////////////////////////////////////////////////
  371. // Misc
  372. CMountPoint::CMountPoint() : _cRef(1), __dwGFA(FILE_ATTRIBUTE_INVALID)
  373. {
  374. }
  375. ULONG CMountPoint::AddRef()
  376. {
  377.     return InterlockedIncrement(&_cRef);
  378. }
  379. ULONG CMountPoint::Release()
  380. {
  381.     if (InterlockedDecrement(&_cRef) > 0)
  382.         return _cRef;
  383. #ifdef DEBUG
  384.     _fMountedOnDriveLetter ? --_cMtPtDL : --_cMtPtMOF;
  385. #endif
  386.     
  387.     delete this;
  388.     return 0;
  389. }
  390. //static
  391. CRegSupport* CMountPoint::GetRSStatic()
  392. {
  393.     if (!_prsStatic)
  394.     {
  395.         _prsStatic = new CRegSupportCached();
  396.     }
  397.     return _prsStatic;
  398. }
  399. ///////////////////////////////////////////////////////////////////////////////
  400. // Call Backs
  401. ///////////////////////////////////////////////////////////////////////////////
  402. BOOL CMountPoint::_GetFileAttributesCB(PVOID pvData)
  403. {
  404.     DWORD* pdw = (DWORD*)pvData;
  405.     *pdw = GetFileAttributes(_GetNameForFctCall());
  406.     return (*pdw != FILE_ATTRIBUTE_INVALID);
  407. }
  408. BOOL CMountPoint::_GetVolumeInformationCB(PVOID pvData)
  409. {
  410.     GVI* pGVI = (GVI*)pvData;
  411.     ZeroMemory(pGVI, sizeof(*pGVI));
  412.     return GetVolumeInformation(_GetNameForFctCall(), pGVI->szLabel, ARRAYSIZE(pGVI->szLabel),
  413.             &pGVI->dwSerialNumber, &pGVI->dwMaxlen, &pGVI->dwFileSysFlags,
  414.             pGVI->szFileSysName, ARRAYSIZE(pGVI->szFileSysName));
  415. }
  416. BOOL CMountPoint::_AutorunCB(PVOID pvData)
  417. {
  418.     BOOL* pf = (BOOL*)pvData;
  419.     *pf = (_IsAutoRunDrive() && _ProcessAutoRunFile());
  420.     // Are we autorun?
  421.     if (!*pf)
  422.     {
  423.         // No, make sure to delete the shell key
  424.         RSDeleteSubKey(TEXT("Shell"));
  425.     }
  426.     return TRUE;
  427. }
  428. BOOL CMountPoint::_DefaultIconLabelCB(PVOID pvData)
  429. {
  430.     DEFICONLABEL* pdil = (DEFICONLABEL*)pvData;
  431.     return _ProcessDefaultIconLabel(&(pdil->fDefaultIcon), &(pdil->fDefaultLabel));
  432. }
  433. BOOL CMountPoint::_CommentFromDesktopINICB(PVOID pvData)
  434. {
  435.     BOOL fRet = TRUE;
  436.     LPTSTR pszCommentFromDesktopINI = (LPTSTR)pvData;
  437.     if (!GetShellClassInfoInfoTip(_GetName(), pszCommentFromDesktopINI, MAX_MTPTCOMMENT))
  438.     {
  439.          *pszCommentFromDesktopINI = 0;
  440.          fRet = FALSE;
  441.     }
  442.     return fRet;
  443. }
  444. BOOL CMountPoint::_HTMLInfoTipFileFromDesktopINICB(PVOID pvData)
  445. {
  446.     BOOL fRet = TRUE;
  447.     LPTSTR pszHTMLInfoTipFileFromDesktopINI = (LPTSTR)pvData;
  448.     if (!GetShellClassInfoHTMLInfoTipFile(_GetName(), pszHTMLInfoTipFileFromDesktopINI, MAX_PATH))
  449.     {
  450.          *pszHTMLInfoTipFileFromDesktopINI = 0;
  451.          fRet = FALSE;
  452.     }
  453.     return fRet;
  454. }
  455. ///////////////////////////////////////////////////////////////////////////////
  456. // 
  457. ///////////////////////////////////////////////////////////////////////////////
  458. BOOL CMountPoint::_GetAttributes(DWORD* pdwAttrib)
  459. {
  460.     if (_sdGFA.Update())
  461.     {
  462.         if (FILE_ATTRIBUTE_INVALID == __dwGFA)
  463.         {
  464.             *pdwAttrib = 0;
  465.         }
  466.         else
  467.         {
  468.             *pdwAttrib = __dwGFA;
  469.         }
  470.     }
  471.     return (FILE_ATTRIBUTE_INVALID != __dwGFA);
  472. }
  473. // { DRIVE_ISCOMPRESSIBLE | DRIVE_LFN | DRIVE_SECURITY }
  474. int CMountPoint::_GetGVIDriveFlags()
  475. {
  476.     int iFlags = 0;
  477.     if (_sdGVI.Update())
  478.     {
  479.         if (__gvi.dwFileSysFlags & FS_FILE_COMPRESSION)
  480.         {
  481.             iFlags |= DRIVE_ISCOMPRESSIBLE;
  482.         }
  483.         // Volume supports long filename (greater than 8.3)?
  484.         if (__gvi.dwMaxlen > 12)
  485.             iFlags |= DRIVE_LFN;
  486.         // Volume supports security?
  487.         if (__gvi.dwFileSysFlags & FS_PERSISTENT_ACLS)
  488.             iFlags |= DRIVE_SECURITY;
  489.     }
  490.     return iFlags;
  491. }
  492. BOOL CMountPoint::_GetGVILabelOrMixedCaseFromReg(LPTSTR pszLabel, DWORD cchLabel)
  493. {
  494.     BOOL fRet = FALSE;
  495.     // Do we have a label from the GetVolumeInformation
  496.     if (_sdGVI.Update() && *__gvi.szLabel)
  497.     {
  498.         LPTSTR pszFinalLabel = __gvi.szLabel;
  499.         fRet = TRUE;
  500.         // Do we already have a label from the registry for this volume?
  501.         // (the user may have renamed this drive)
  502.         if (_sdLabelFromReg.Update() && *__szLabelFromReg) 
  503.         {
  504.             // Yes
  505.             // Do they match (only diff in case)
  506.             if (lstrcmpi(__szLabelFromReg, __gvi.szLabel) == 0)
  507.             {
  508.                 // Yes
  509.                 pszFinalLabel = __szLabelFromReg;
  510.             }
  511.         }
  512.         lstrcpyn(pszLabel, pszFinalLabel, cchLabel);
  513.     }
  514.     else
  515.     {
  516.         *pszLabel = 0;
  517.     }
  518.     return fRet;
  519. }
  520. BOOL CMountPoint::_GetFileSystemFlags(DWORD* pdwFlags)
  521. {
  522.     BOOL fRet = _sdGVI.Update();
  523.     if (fRet)
  524.     {
  525.         *pdwFlags = __gvi.dwFileSysFlags;
  526.     }
  527.     return fRet;
  528. }
  529. BOOL CMountPoint::_IsAutoRun()
  530. {
  531.     return _sdAutorun.Update() && __fAutorun;
  532. }
  533. ///////////////////////////////////////////////////////////////////////////////
  534. // Default Icon/Label
  535. ///////////////////////////////////////////////////////////////////////////////
  536. BOOL CMountPoint::_ProcessDefaultIconLabel(BOOL* pfDefaultIcon, BOOL* pfDefaultLabel)
  537. {
  538.     BOOL fUseAutorunIcon = FALSE;
  539.     BOOL fUseAutorunLabel = FALSE;
  540.     TCHAR szIconLocation[MAX_PATH + 12];
  541.     DWORD cchIconLocation = ARRAYSIZE(szIconLocation);
  542.     TCHAR szLabel[MAX_LABEL];
  543.     DWORD cchLabel = ARRAYSIZE(szLabel);
  544.     RSDeleteSubKey(TEXT("DefaultIcon"));
  545.     RSDeleteSubKey(TEXT("DefaultLabel"));
  546.     
  547.     // First let's update the autorun info, it might provide us with a default icon and/or label
  548.     _sdAutorun.Update();
  549.     szIconLocation[0] = 0;
  550.     szLabel[0] = 0;
  551.     // Is it an autorun drive?
  552.     if (__fAutorun)
  553.     {
  554.         // Yes, does it provide a DefaultIcon?
  555.         if (RSGetTextValue(TEXT("_Autorun\DefaultIcon"), NULL, szIconLocation, &cchIconLocation))
  556.         {
  557.             // The Autorun provided icon has precedence
  558.             fUseAutorunIcon = TRUE;
  559.         }
  560.         else
  561.         {
  562.             szIconLocation[0] = 0;
  563.         }
  564.         // Same for Label
  565.         if (RSGetTextValue(TEXT("_Autorun\DefaultLabel"), NULL, szLabel, &cchLabel))
  566.         {
  567.             // The Autorun provided icon has precedence
  568.             fUseAutorunLabel = TRUE;
  569.         }
  570.         else
  571.         {
  572.             szLabel[0] = 0;
  573.         }
  574.     }
  575.     if (!fUseAutorunIcon && _fMountedOnDriveLetter)
  576.     {
  577.         // Let's check if there is one at the following locations
  578.         TCHAR szSubKey[MAX_PATH];
  579.         wnsprintf(szSubKey, ARRAYSIZE(szSubKey),
  580.             TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer\DriveIcons\%c\DefaultIcon"),
  581.             _GetNameFirstChar());
  582.         if (!RegGetValueString(HKEY_LOCAL_MACHINE, szSubKey, NULL, szIconLocation,
  583.             ARRAYSIZE(szIconLocation) * sizeof(TCHAR)))
  584.         {
  585.             szIconLocation[0] = 0;
  586.             // Let's try second location
  587.             wnsprintf(szSubKey, ARRAYSIZE(szSubKey),
  588.                 TEXT("Applications\Explorer.exe\Drives\%c\DefaultIcon"),
  589.                 _GetNameFirstChar());
  590.             if (!RegGetValueString(HKEY_CLASSES_ROOT, szSubKey, NULL, szIconLocation,
  591.                 ARRAYSIZE(szIconLocation) * sizeof(TCHAR)))
  592.             {
  593.                 szIconLocation[0] = 0;
  594.             }
  595.         }
  596.     }
  597.     if (szIconLocation[0])
  598.     {
  599.         // Let's copy the value under our drive key
  600.         RSSetTextValue(TEXT("DefaultIcon"), NULL, szIconLocation, REG_OPTION_NON_VOLATILE);
  601.         *pfDefaultIcon = TRUE;
  602.     }
  603.     if (!fUseAutorunLabel && _fMountedOnDriveLetter)
  604.     {
  605.         // Let's check if there is one at the following locations
  606.         TCHAR szSubKey[MAX_PATH];
  607.         wnsprintf(szSubKey, ARRAYSIZE(szSubKey),
  608.             TEXT("Software\Microsoft\Windows\CurrentVersion\Explorer\DriveIcons\%c\DefaultLabel"),
  609.             _GetNameFirstChar());
  610.         if (!RegGetValueString(HKEY_LOCAL_MACHINE, szSubKey, NULL, szLabel,
  611.             ARRAYSIZE(szLabel) * sizeof(TCHAR)))
  612.         {
  613.             szLabel[0] = 0;
  614.             // Let's try second location.
  615.             wnsprintf(szSubKey, ARRAYSIZE(szSubKey),
  616.                 TEXT("Applications\Explorer.exe\Drives\%c\DefaultLabel"),
  617.                 _GetNameFirstChar());
  618.             if (!RegGetValueString(HKEY_CLASSES_ROOT, szSubKey, NULL, szLabel,
  619.                 ARRAYSIZE(szLabel) * sizeof(TCHAR)))
  620.             {
  621.                 szLabel[0] = 0;
  622.             }
  623.         }
  624.     }
  625.     if (szLabel[0])
  626.     {
  627.         // Let's copy the value under our drive key
  628.         RSSetTextValue(TEXT("DefaultLabel"), NULL, szLabel, REG_OPTION_NON_VOLATILE);
  629.         *pfDefaultLabel = TRUE;
  630.     }
  631.     return TRUE;
  632. }
  633. BOOL CMountPoint::_HasDefaultIcon()
  634. {
  635.     return _sdDefaultIconLabel.Update() && __dil.fDefaultIcon;
  636. }
  637. BOOL CMountPoint::_HasDefaultLabel()
  638. {
  639.     return _sdDefaultIconLabel.Update() && __dil.fDefaultLabel;
  640. }
  641. BOOL CMountPoint::_GetDefaultLabel(LPTSTR pszLabel, DWORD cchLabel)
  642. {
  643.     DWORD cchLabelLocal = cchLabel;
  644.     return _sdDefaultIconLabel.Update() && 
  645.         RSGetTextValue(TEXT("DefaultLabel"), NULL, pszLabel,
  646.         &cchLabelLocal);
  647. }
  648. ///////////////////////////////////////////////////////////////////////////////
  649. // Drive cache
  650. ///////////////////////////////////////////////////////////////////////////////
  651. BOOL CMountPoint::_IsValidDriveCache()
  652. {
  653.     BOOL fRet = FALSE;
  654.     DWORD cbSize;
  655.     PBYTE pbUniqueBlob = _MakeUniqueBlob(&cbSize);
  656.     PBYTE pbRegUniqueBlob = _GetRegUniqueBlob(cbSize);
  657.     if (pbUniqueBlob && pbRegUniqueBlob)
  658.     {
  659.         fRet = !memcmp(pbUniqueBlob, pbRegUniqueBlob, cbSize);
  660.     }
  661.     if (pbRegUniqueBlob)
  662.     {
  663.         _ReleaseUniqueBlob(pbRegUniqueBlob);
  664.     }
  665.     if (pbUniqueBlob)
  666.     {
  667.         _ReleaseUniqueBlob(pbUniqueBlob);
  668.     }
  669.     return fRet;
  670. }
  671. void CMountPoint::_ResetDriveCache()
  672. {
  673.     DWORD cbSize;
  674.     RSDeleteValue(NULL, TEXT("_UB"));
  675.     PBYTE pb = _MakeUniqueBlob(&cbSize);
  676.     if (pb)
  677.     {
  678.         RSSetBinaryValue(NULL, TEXT("_UB"), pb, cbSize);
  679.         _ReleaseUniqueBlob(pb);
  680.     }
  681.     _sdDriveFlags.WipeReg();
  682.     _sdGFA.WipeReg();
  683.     _sdGVI.WipeReg();
  684.     _sdDefaultIconLabel.WipeReg();
  685.     _sdAutorun.WipeReg();
  686.     _sdCommentFromDesktopINI.WipeReg();
  687.     _sdHTMLInfoTipFileFromDesktopINI.WipeReg();
  688. }
  689. ///////////////////////////////////////////////////////////////////////////////
  690. // Name fcts
  691. ///////////////////////////////////////////////////////////////////////////////
  692. LPCTSTR CMountPoint::_GetNameForFctCall()
  693. {
  694.     return _szName;
  695. }
  696. TCHAR CMountPoint::_GetNameFirstChar()
  697. {
  698.     return _szName[0];
  699. }
  700. LPTSTR CMountPoint::_GetNameFirstXChar(LPTSTR pszBuffer, int c)
  701. {
  702.     StrCpyN(pszBuffer, _szName, c);
  703.     return pszBuffer;
  704. }
  705. LPCTSTR CMountPoint::_GetName()
  706. {
  707.     return _szName;
  708. }
  709. ///////////////////////////////////////////////////////////////////////////////
  710. // Unique blob
  711. ///////////////////////////////////////////////////////////////////////////////
  712. PBYTE CMountPoint::_GetRegUniqueBlob(DWORD cbSize)
  713. {
  714.     PBYTE pb = (PBYTE)LocalAlloc(LPTR, cbSize);
  715.     if (!RSGetBinaryValue(NULL, TEXT("_UB"), pb, &cbSize))
  716.     {
  717.         // Either the value is not there, or the buffer is too small,
  718.         // one way or the other the Blobs will not be the same
  719.         LocalFree(pb);
  720.         pb = NULL;
  721.     }
  722.     return pb;
  723. }
  724. void CMountPoint::_ReleaseUniqueBlob(PBYTE pbUniqueBlob)
  725. {
  726.     LocalFree(pbUniqueBlob);
  727. }
  728. ///////////////////////////////////////////////////////////////////////////////
  729. // 
  730. ///////////////////////////////////////////////////////////////////////////////
  731. HRESULT CMountPoint::_InitializeBase(LPCTSTR pszName, BOOL fMountedOnDriveLetter)
  732. {
  733.     lstrcpyn(_szName, pszName, ARRAYSIZE(_szName));
  734.     PathAddBackslash(_szName);
  735.     _fMountedOnDriveLetter = fMountedOnDriveLetter;
  736.     _SetKeyName();
  737.     RSInitRoot(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _szKeyName, REG_OPTION_NON_VOLATILE);
  738.     if (!_fMountedOnDriveLetter)
  739.     {
  740.         RSSetTextValue(NULL, NULL, _GetName());
  741.     }
  742.     _sdDriveFlags.Init(this, (SUBDATACB)_GetDriveFlagsCB, &__uDriveFlags);
  743.     _sdDriveFlags.InitExpiration(_GetExpirationInMilliSec());
  744.     _sdDriveFlags.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(), TEXT("_DriveFlags"),
  745.         sizeof(__uDriveFlags), TRUE);
  746.     _sdGFA.Init(this, (SUBDATACB)_GetFileAttributesCB, &__dwGFA);
  747.     _sdGFA.InitExpiration(_GetExpirationInMilliSec());
  748.     _sdGFA.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(), TEXT("_GFA"),
  749.         sizeof(__dwGFA), TRUE);
  750.     _sdGVI.Init(this, (SUBDATACB)_GetVolumeInformationCB, &__gvi);
  751.     _sdGVI.InitExpiration(_GetExpirationInMilliSec());
  752.     _sdGVI.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(), TEXT("_GVI"),
  753.         sizeof(__gvi), TRUE);
  754.     _sdLabelFromReg.Init(this, (SUBDATACB)NULL, &__szLabelFromReg);
  755.     _sdLabelFromReg.InitExpiration(EXPIRATION_NEVER);
  756.     _sdLabelFromReg.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(), TEXT("_LabelFromReg"),
  757.         ARRAYSIZE(__szLabelFromReg) * sizeof(TCHAR));
  758.     _sdAutorun.Init(this, (SUBDATACB)_AutorunCB, &__fAutorun);
  759.     _sdAutorun.InitExpiration(EXPIRATION_NEVER);
  760.     _sdAutorun.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(), TEXT("_Autorun"),
  761.         sizeof(__fAutorun));
  762.     _sdDefaultIconLabel.Init(this, (SUBDATACB)_DefaultIconLabelCB, &__dil);
  763.     _sdDefaultIconLabel.InitExpiration(EXPIRATION_NEVER);
  764.     _sdDefaultIconLabel.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(), TEXT("_DIL"),
  765.         sizeof(__dil));
  766.     _sdCommentFromDesktopINI.Init(this, (SUBDATACB)_CommentFromDesktopINICB, NULL);
  767.     // InitExpiration called below (after GetDriveType())
  768.     _sdCommentFromDesktopINI.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(),
  769.         TEXT("_CommentFromDesktopINI"), 0);
  770.     _sdHTMLInfoTipFileFromDesktopINI.Init(this, (SUBDATACB)_HTMLInfoTipFileFromDesktopINICB, NULL);
  771.     // InitExpiration called below (after GetDriveType())
  772.     _sdHTMLInfoTipFileFromDesktopINI.InitRegSupport(HKEY_CURRENT_USER, REGSTR_MTPT_ROOTKEY, _GetKeyName(),
  773.         TEXT("_HTMLInfoTipFileFromDesktopINI"), 0);
  774. #ifdef DEBUG
  775.     fMountedOnDriveLetter ? ++_cMtPtDL : ++_cMtPtMOF;
  776. #endif
  777.     _SetUniqueID();
  778.     _uDriveType = GetDriveType(_GetNameForFctCall());
  779.     if (DRIVE_NO_ROOT_DIR == _uDriveType)
  780.     {
  781.         // See comment in GetMountPoint(int iDrive, ...)
  782.         // It should be the only way of getting here for a DRIVE_NO_ROOT_DIR
  783.         _uDriveType = DRIVE_REMOTE;
  784.     }
  785.     if (!_IsValidDriveCache())
  786.     {
  787.         _ResetDriveCache();
  788.     }
  789.     RSSetTextValue(NULL, TEXT("BaseClass"), TEXT("Drive"));
  790.     if (DRIVE_CDROM == _uDriveType)
  791.     {
  792.         RSSetTextValue(NULL, TEXT("_HasNotif"), TEXT(""));
  793.     }
  794.     if (DRIVE_FIXED == _uDriveType)
  795.     {
  796.         _sdCommentFromDesktopINI.InitExpiration(3000);
  797.         _sdHTMLInfoTipFileFromDesktopINI.InitExpiration(3000);
  798.     }
  799.     else
  800.     {
  801.         _sdCommentFromDesktopINI.InitExpiration(EXPIRATION_NEVER);
  802.         _sdHTMLInfoTipFileFromDesktopINI.InitExpiration(EXPIRATION_NEVER);
  803.     }
  804.     if ((DRIVE_FIXED != _uDriveType) &&
  805.         (DRIVE_REMOVABLE != _uDriveType) && 
  806.         (DRIVE_CDROM != _uDriveType))
  807.     {
  808.         if (!_sdCommentFromDesktopINI.ExistInReg())
  809.         {
  810.             TCHAR szCommentFromDesktopINI[MAX_MTPTCOMMENT];
  811.             _sdCommentFromDesktopINI.SetBuffer(szCommentFromDesktopINI,
  812.                 ARRAYSIZE(szCommentFromDesktopINI) * sizeof(TCHAR));
  813.             _sdCommentFromDesktopINI.Update();
  814.     
  815.             _sdCommentFromDesktopINI.ResetBuffer();
  816.         }
  817.         if (!_sdHTMLInfoTipFileFromDesktopINI.ExistInReg())
  818.         {
  819.             TCHAR szHTMLInfoTipFileFromDesktopINI[MAX_PATH];
  820.             _sdHTMLInfoTipFileFromDesktopINI.SetBuffer(szHTMLInfoTipFileFromDesktopINI,
  821.                     ARRAYSIZE(szHTMLInfoTipFileFromDesktopINI) * sizeof(TCHAR));
  822.             _sdHTMLInfoTipFileFromDesktopINI.Update();
  823.             _sdHTMLInfoTipFileFromDesktopINI.ResetBuffer();
  824.         }
  825.     }
  826.     _sdDefaultIconLabel.Update();
  827.     RSCVInitSubKey(NULL);
  828.     _RSCVUpdateVersionOnCacheRead();
  829.     return S_OK;
  830. }
  831. ULONG CMountPoint::_ReleaseInternal()
  832. {
  833.     // we don't want to write to the registry from now on
  834.     //  this object is going to leave us soon
  835.     _sdLabelFromReg.HoldUpdates();
  836.     _sdCommentFromDesktopINI.HoldUpdates();
  837.     _sdHTMLInfoTipFileFromDesktopINI.HoldUpdates();
  838.     _sdDefaultIconLabel.HoldUpdates();
  839.     _sdDriveFlags.HoldUpdates();
  840.     _sdGFA.HoldUpdates();
  841.     _sdGVI.HoldUpdates();
  842.     _sdDefaultIconLabel.HoldUpdates();
  843.     _sdAutorun.HoldUpdates();
  844. #ifndef WINNT
  845.     if (_fWipeVolatileOnWin9X)
  846.     {
  847.         _sdLabelFromReg.FakeVolatileOnWin9X();
  848.         _sdCommentFromDesktopINI.FakeVolatileOnWin9X();
  849.         _sdHTMLInfoTipFileFromDesktopINI.FakeVolatileOnWin9X();
  850.         _sdDefaultIconLabel.FakeVolatileOnWin9X();
  851.         _sdDriveFlags.FakeVolatileOnWin9X();
  852.         _sdGFA.FakeVolatileOnWin9X();
  853.         _sdGVI.FakeVolatileOnWin9X();
  854.         _sdDefaultIconLabel.FakeVolatileOnWin9X();
  855.         _sdAutorun.FakeVolatileOnWin9X();
  856.     }
  857. #endif
  858.     return Release();
  859. }
  860. ///////////////////////////////////////////////////////////////////////////////
  861. // DeviceIOControl stuff
  862. ///////////////////////////////////////////////////////////////////////////////
  863. BOOL CMountPoint::_DriveIOCTL(int cmd, void *pvIn, DWORD dwIn, void *pvOut, DWORD dwOut, BOOL fFileSystem,
  864.                           HANDLE handle)
  865. {
  866.     BOOL fHandlePassedIn = TRUE;
  867.     BOOL fSuccess = FALSE;
  868.     DWORD dwRead;
  869.     TraceMsg(TF_MOUNTPOINT, 
  870.         "    CMountPoint::_DriveIOCTL: >>>EXT<<< (DeviceIOControl) '%s'", _GetName());
  871.     if (INVALID_HANDLE_VALUE == handle)
  872.     {
  873.         handle = _GetIOCTLHandle(fFileSystem);
  874.         fHandlePassedIn = FALSE;
  875.     }
  876.     if (INVALID_HANDLE_VALUE != handle)
  877.     {
  878. #ifdef WINNT
  879.         //
  880.         // On NT, we issue DEVIOCTLs by cmd id.
  881.         //
  882.         fSuccess = DeviceIoControl(handle, cmd, pvIn, dwIn, pvOut, dwOut, &dwRead, NULL);
  883. #else
  884.         DIOC_REGISTERS reg;
  885.         //
  886.         // On non-NT, we talk to VWIN32, issuing reads (which are converted
  887.         // internally to DEVIOCTLs)
  888.         //
  889.         //  BUGBUG: this is a real hack (talking to VWIN32) on NT we can just
  890.         //  open the device, we dont have to go through VWIN32
  891.         //
  892.         reg.reg_EBX = LOWORD(_GetNameFirstChar()) + 1;   // make 1 based drive number
  893.         reg.reg_EDX = (DWORD)pvOut; // out buffer
  894.         reg.reg_ECX = cmd;              // device specific command code
  895.         reg.reg_EAX = 0x440D;           // generic read ioctl
  896.         reg.reg_Flags = 0x0001;     // flags, assume error (carry)
  897.         DeviceIoControl(handle, VWIN32_DIOC_DOS_IOCTL, &reg, SIZEOF(reg), &reg, SIZEOF(reg), &dwRead, NULL);
  898.         fSuccess = !(reg.reg_Flags & 0x0001);
  899. #endif
  900.         if (!fHandlePassedIn)
  901.             CloseHandle(handle);
  902.     }
  903.     return fSuccess;
  904. }
  905. // returns INVALID_HANDLE_VALUE when failing
  906. HANDLE CMountPoint::_GetIOCTLHandle(BOOL fFileSystem)
  907. {
  908.     HANDLE handle = INVALID_HANDLE_VALUE;
  909.     DWORD dwDesiredAccess = 0;
  910.     DWORD dwShareMode = 0;
  911. #ifdef WINNT
  912.     if (fFileSystem)
  913.     {
  914.         // Used by XXXAudioDisc on NT.
  915.         // On NT, when use GENERIC_READ (as opposed to 0) in the CreateFile call, we
  916.         // get a handle to the filesystem (CDFS), not the device itself.  But we can't
  917.         // change DriveIOCTL to do this, since that causes the floppy disks to spin
  918.         // up, and we don't want to do that.
  919.         dwDesiredAccess = GENERIC_READ;
  920.         dwShareMode = FILE_SHARE_READ;
  921.     }
  922. #else
  923.     // Always use these hardcoded values
  924.     dwDesiredAccess = GENERIC_READ;
  925.     dwShareMode = FILE_SHARE_READ;
  926. #endif
  927.     handle = _GetIOCTLHandle(dwDesiredAccess, dwShareMode);
  928.     return handle;
  929. }
  930. // returns INVALID_HANDLE_VALUE when failing
  931. HANDLE CMountPoint::_GetIOCTLHandle(DWORD dwDesiredAccess, DWORD dwShareMode)
  932. {
  933.     HANDLE handle = INVALID_HANDLE_VALUE;
  934.     TCHAR szTmpName[MAX_PATH];
  935.     DWORD dwFileAttributes = 0;
  936. #ifdef WINNT
  937.     // Go for VolumeGUID first
  938.     if (GetVolumeNameForVolumeMountPoint(_GetName(), szTmpName, ARRAYSIZE(szTmpName)))
  939.     {
  940.         PathRemoveBackslash(szTmpName);
  941.     }
  942.     else
  943.     {
  944.         // Probably a floppy, which cannot be mounted on a folder
  945.         lstrcpy(szTmpName, TEXT("\\.\A:"));
  946.         szTmpName[4] = _GetNameFirstChar();;
  947.     }
  948. #else
  949.     // Always use these hardcoded values
  950.     lstrcpyn(szTmpName, TEXT("\\.\vwin32"), ARRAYSIZE(szTmpName));
  951.     dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
  952. #endif
  953.     handle = CreateFile(szTmpName, dwDesiredAccess, dwShareMode, NULL, OPEN_EXISTING, dwFileAttributes, NULL);
  954.     return handle;
  955. }
  956. ///////////////////////////////////////////////////////////////////////////////
  957. // Misc
  958. ///////////////////////////////////////////////////////////////////////////////
  959. //static
  960. BOOL CMountPoint::_ShowUglyDriveNames()
  961. {
  962.     static BOOL s_fShowUglyDriveNames = (BOOL)42;   // Preload some value to say lets calculate...
  963.     if (s_fShowUglyDriveNames == (BOOL)42)
  964.     {
  965.         int iACP;
  966. #ifdef WINNT
  967.         TCHAR szTemp[MAX_PATH];     // Nice large buffer
  968.         if (GetLocaleInfo(GetUserDefaultLCID(), LOCALE_IDEFAULTANSICODEPAGE, szTemp, ARRAYSIZE(szTemp)))
  969.         {
  970.             iACP = StrToInt(szTemp);
  971.             // per Samer Arafeh, show ugly name for 1256 (Arabic ACP)
  972.             if (iACP == 1252 || iACP == 1254 || iACP == 1255 || iACP == 1257 || iACP == 1258)
  973.                 goto TryLoadString;
  974.             else
  975.                 s_fShowUglyDriveNames = TRUE;
  976.         } else {
  977.         TryLoadString:
  978.             // All indications are that we can use pretty drive names.
  979.             // Double-check that the localizers didn't corrupt the chars.
  980.             LoadString(HINST_THISDLL, IDS_DRIVES_UGLY_TEST, szTemp, ARRAYSIZE(szTemp));
  981.             // If the characters did not come through properly set ugly mode...
  982.             s_fShowUglyDriveNames = (szTemp[0] != 0x00BC || szTemp[1] != 0x00BD);
  983.         }
  984. #else
  985.         // on win98 the shell font can't change with user locale. Because ACP
  986.         // is always same as system default, and all Ansi APIs are still just 
  987.         // following ACP.
  988.         // 
  989.         iACP = GetACP();
  990.         if (iACP == 1252 || iACP == 1254 || iACP == 1255 || iACP == 1257 || iACP == 1258)
  991.             s_fShowUglyDriveNames = FALSE;
  992.         else
  993.             s_fShowUglyDriveNames = TRUE;
  994. #endif
  995.     }
  996.     return s_fShowUglyDriveNames;
  997. }
  998. // Will return and icon index from the shell icon cache (-1 for failure)
  999. // This should be called only from within HandleWMDeviceChange
  1000. //static
  1001. int CMountPoint::_GetCachedIcon(int iDrive)
  1002. {
  1003.     int iIcon = -1;
  1004.     CMountPoint* pMtPt = _GetCachedMtPt(iDrive);
  1005.     if (pMtPt)
  1006.     {
  1007.         TCHAR szModule[MAX_PATH];
  1008.         int iIconTmp = pMtPt->GetIcon(szModule, ARRAYSIZE(szModule));
  1009.         if (!szModule[0])
  1010.         {
  1011.             lstrcpyn(szModule, c_szShell32Dll, ARRAYSIZE(szModule));
  1012.         }
  1013.         iIcon = Shell_GetCachedImageIndex(szModule, iIconTmp, 0);
  1014.         pMtPt->Release();
  1015.     }
  1016.     return iIcon;
  1017. }
  1018. //
  1019. // External API for use by non-CPP modules.
  1020. //
  1021. HRESULT MountPoint_RegisterChangeNotifyAlias(int iDrive)
  1022. {    
  1023.     HRESULT hr = E_FAIL;
  1024.     CMountPoint* pMtPt = CMountPoint::GetMountPoint(iDrive);
  1025.     if (pMtPt)
  1026.     {
  1027.         pMtPt->ChangeNotifyRegisterAlias();
  1028.         pMtPt->Release();
  1029.         hr = NOERROR;
  1030.     }
  1031.     return hr;
  1032. }