Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1637498
  • 博文数量: 584
  • 博客积分: 13857
  • 博客等级: 上将
  • 技术积分: 11883
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-16 09:34

分类: WINDOWS

2011-03-29 14:47:05

      昨天,在CSDN中看见寻求解决挂载盘符的问题,今天把它搞定了。
      本文只要用最新的SDK(或者2k以上)然后定义Windows版本_WIN32_WINNT为0x0500以上就能编译通过了。
      改变盘符主要是用SetVolumeMountPointDeleteVolumeMountPoint 两个函数。DeleteVolumeMountPoint 很简单就不多说了。SetVolumeMountPoint 的使用主要是要找到被挂载设备的VolumeName。但是设备被卸载以后用GetVolumeNameForVolumeMountPoint根本取不到VolumeName,怎么办呢?
      微软XP的系统文件夹里面有一个叫diskpart.exe的命令行工具,用它可以改变盘符。那么它是怎么做到的呢?
简单的分析(用VC6自带的工具DEPENDS.EXE)就可以看见这个程序使用了很多Setup API函数,我判断使用SetupDiEnumDeviceInfo来取得VolumeName的ClassGUID,但是结果发现取到的ClassGUID和用GetVolumeNameForVolumeMountPoint获取的没有卸载前的VolumeName中的ClassGUID不一样。怎么办呢?
      没关系,让我们祭出屠龙刀:IDA Pro。如何反汇编分析不在本文的介绍了(挺麻烦,而我这人又比较懒嘿嘿)。我一阵海扁它,发现关键是要通过DefineDosDevice 函数将设备Attach到盘符上,然后用GetVolumeNameForVolumeMountPoint取到VolumeName,之后就可以用SetVolumeMountPoint将设备挂载到盘符上了。我把它写成了函数如果要加载盘符就可以使用(前提是盘符未被占用):
ChangeMountPoint( _T("H:\\"), _T("\\Device\\HarddiskVolume2"),true);
卸载的话用:
ChangeMountPoint( _T("H:\\"),NULL, false);
下面是ChangeMountPoint函数的实现:

bool ChangeMountPoint(LPCTSTR lpDriveLetter,LPCTSTR lpDevice,bool bAddMountPoint)
{
    bool bRet 
= false;
    TCHAR szDriveLetterAndSlash[
4= {0};
    TCHAR szDriveLetter[
3= {0};
    TCHAR szUniqueVolumeName[MAX_PATH] 
= {0};
    
if(lpDriveLetter && lpDevice)
    {
        szDriveLetter[
0= lpDriveLetter[0];
        szDriveLetter[
1= TEXT(':');
        szDriveLetter[
2= TEXT('\0');
        
        szDriveLetterAndSlash[
0= lpDriveLetter[0];
        szDriveLetterAndSlash[
1= TEXT(':');
        szDriveLetterAndSlash[
2= TEXT('\\');
        szDriveLetterAndSlash[
3= TEXT('\0');
        
if ( bAddMountPoint )
        {
            
//Try to Attach lpDevice to lpDriveLetter
            bRet = DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter,
                lpDevice);
            
            
if (bRet)
            {
                
if (!GetVolumeNameForVolumeMountPoint (szDriveLetterAndSlash,
                    szUniqueVolumeName,
                    MAX_PATH))
                {
                    
//Can't Find Attached lpDevice 's VolumeName
                    szUniqueVolumeName[0= '\0';
                }
                
                bRet 
= DefineDosDevice ( 
                    DDD_RAW_TARGET_PATH
|DDD_REMOVE_DEFINITION|
                    DDD_EXACT_MATCH_ON_REMOVE, szDriveLetter,
                    lpDevice);
                
                
if (!bRet)
                    
return bRet;
                
                bRet 
= SetVolumeMountPoint(szDriveLetterAndSlash, 
                    szUniqueVolumeName);
            }
        }
        
else
        {
            bRet 
= DeleteVolumeMountPoint (szDriveLetterAndSlash);
        }
    }
    
    
return bRet;
}
阅读(726) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~