上一篇研究了利用 DefineDosDevice 和 QueryDosDevice 这两个函数来映射一个文件夹到一个本地盘符,以及查询所有 DOS 映射设备的方法,附带发现了一个获取硬盘序列号的方法。
卷挂接在 Unix/Linux/Netware 系统上应用比较常见,Windows 可能由于多用于个人平台,所以知道卷挂接技术的人就比例上来说少了很多。你可以将它理解为:把一个物理设备挂接到一个逻辑盘符或文件夹中来使用,例如:如果需要扩展 C 盘的容量,而 C 盘所在的分区/磁盘已没有空闲空间来扩展它时,可以加装一个 200GB 的新硬盘,然后在 C: 中新增一个目录 ExtDisk,并将这个新磁盘挂接到这个目录中即可,现在 C: 盘的容量就增加了 200GB。有一点要注意,就是卷挂接只能用于 NTFS 系统。
现在继续研究第二部分,卷挂接函数的使用。这一部分可以分为下面几组函数:
1. FindFirstVolume / FindNextVolume / FindVolumeClose / GetVolumePathNamesForVolumeName
用于枚举所有卷名,示例:(列出本机上的所有卷名及对应盘符)
示例一
- DECLARE Long FindFirstVolume IN WIN32API ;
- String @ lpszVolumeName, Long cchBufferLength
- DECLARE Long FindNextVolume IN WIN32API ;
- Long hFindVolume, String @ lpszVolumeName, Long cchBufferLength
- DECLARE Long FindVolumeClose IN WIN32API Long hFindVolume
- DECLARE Long GetVolumePathNamesForVolumeName IN WIN32API ;
- String lpszVolumeName, String @ lpszVolumePathNames, ;
- Long cchBufferLength, Long @ lpcchReturnLength
- CLEAR
- m.iSize = 0x200
- m.cBuff = REPLICATE( CHR(0), m.iSize )
- m.hVol = FindFirstVolume( @ m.cBuff, m.iSize )
- IF ( -1 == m.hVol )
- ? 'Error:', GetLastError()
- ELSE
- DO WHILE .T.
- m.cVolName = RTRIM( m.cBuff, CHR(0))
- m.cBuff = REPLICATE( CHR(0), m.iSize+2 )
- GetVolumePathNamesForVolumeName( m.cVolName, @ m.cBuff, m.iSize+2, m.iSize )
- ALINES( laPaths, m.cBuff, 1+4, CHR(0))
- ? m.laPaths[1], '', m.cVolName
- m.cBuff = REPLICATE( CHR(0), m.iSize )
- IF ( 0 == FindNextVolume( m.hVol, @ m.cBuff, m.iSize ))
- EXIT
- ENDIF
- ENDDO
- FindVolumeClose( m.hVol )
- ENDIF
2. GetVolumeNameForVolumeMountPoint / SetVolumeMountPoint / DeleteVolumeMountPoint
这是这部分中最重要的三个函数,卷的挂接和取消就全靠它们了
示例:首先在 C: 盘下创建一个名为 mnt 的目录,再在其下创建一个 cdrom 的目录,然后运行下面的代码:
示例二
- DECLARE Long GetVolumeNameForVolumeMountPoint IN WIN32API ;
- String lpszVolumeMountPoint, String @ lpszVolumeName, Long cchBufferLength
- DECLARE Long SetVolumeMountPoint IN WIN32API ;
- String lpszVolumeMountPoint, String lpszVolumeName
- DECLARE Long DeleteVolumeMountPoint IN WIN32API ;
- String lpszVolumeMountPoint
- #define MOUNTPOINTS 'c:/mnt/test/'
- #define VOLPATH 'E:/'
- m.iSize = 0x100
- m.cBuff = REPLICATE( CHR(0), m.iSize )
- GetVolumeNameForVolumeMountPoint( VOLPATH, @ m.cBuff, m.iSize )
- m.cBuff = RTRIM( m.cBuff, CHR(0))
- SetVolumeMountPoint( MOUNTPOINTS, m.cBuff )
- MessageBox( '现在切换到 ' + MOUNTPOINTS + ' 下去看看都有些什么?' )
- IF ( 6 == Messagebox( ;
- '取消挂接在 ' + MOUNTPOINTS + ' 下的卷吗? ', 4+32, '请确认' ))
- DeleteVolumeMountPoint( MOUNTPOINTS ) && 移除 E: 盘挂接
- ENDIF
在没有取消挂接之前,也可以到“控制面板”->“管理工具”->“计算机管理”->“磁盘管理”中找到 E: 盘,右击它并选“更改驱动器名和路径”,应该可以看到多个一个挂接项目。
你也可以先不取消挂接的卷,然后再运行一下“示例一”中代码,应该可以看到与第一次的运行结果有所不同。
3. FindFirstVolumeMountPoint / FindNextVolumeMountPoint / FindVolumeMountPointClose
这单个函数用于枚举指定盘符上存在的所有挂接卷,由于简单就不写示例代码了
=====================================================
总结:
1. DefineDosDevice 可以将一个文件夹虚拟成一个盘符
2. SetVolumeMountPoint 可以将一个物理盘虚拟到一个文件夹中
3. DefineDosDevice 中文件夹可以任何文件系统类型(FAT,FAT32,NTFS,...),而 SetVolumeMountPoint 中的目标文件夹必须存在于 NTFS 文件系统中,且必须为空。
5217

被折叠的 条评论
为什么被折叠?



