今天研究 Volume Management Functions 部分的 api 函数:
这个部分函数包含两大块,第一块是卷管理,第二块是卷挂接
第一块中的函数包括:
DefineDosDevice, GetDriveType, GetLogicalDrives, GetLogicalDriveStrings, GetVolumeInformation, GetVolumeInformationByHandleW, SetVolumeLabel , QueryDosDevice
大部分函数都很常用,唯独没有研究过 DefineDosDevice 和 QueryDosDevice 这两个,需要看看有什么用。
第二块中的函数包括:
DeleteVolumeMountPoint, FindFirstVolume, FindFirstVolumeMountPoint, FindNextVolume, FindNextVolumeMountPoint, FindVolumeClose, FindVolumeMountPointClose, GetVolumeNameForVolumeMountPoint, GetVolumePathName, GetVolumePathNamesForVolumeName, SetVolumeMountPoint
基本上都没用过,更需要研究一下
---------------------------------------------------------------------------------------------------------
首先看看 QueryDosDevice 函数,MSDN 中解释是:
Retrieves information about MS-DOS device names. The function can obtain the current mapping for a particular MS-DOS device name. The function can also obtain a list of all existing MS-DOS device names.
好,我们来检索一下我们的系统中都存在那些 DOS 映射设备名
- LOCAL iSize, cBuff
- LOCAL ARRAY laDevs[1]
- DECLARE Long QueryDosDevice IN WIN32API ;
- String lpDeviceName, String @ lpTargetPath, Long ucchMax
- CLOSE TABLES
- CREATE CURSOR temp ( name C(250))
- m.iSize = 0x5000
- m.cBuff = REPLICATE( CHR(0), m.iSize )
- QueryDosDevice( NULL, @ m.cBuff, m.iSize )
- ALINES( m.laDevs, m.cBuff, 1+4, CHR(0))
- m.cBuff = ''
- FOR m.ii = 1 TO ALEN( m.laDevs )
- INSERT INTO temp ( name ) VALUES ( m.laDevs[m.ii] )
- ENDFOR
- DIMENSION laDevs[1]
- m.laDevs[1] = NULL
- SELECT LEN(RTRIM(name)) AS nlen, name ;
- FROM temp INTO CURSOR dosdevs ORDER BY 1,2 READWRITE
- USE IN temp
- ALTER TABLE dosdevs DROP COLUMN nlen
- LOCATE
- BROWSE NOWAIT NAME oBrowser
- oBrowser.SetAll( 'DynamicBackColor', ;
- 'iif([IDE#]==left(name,4),rgb(255,0,0),rgb(255,255,255))' )
前面显示的都是些我们常见的 DOS 设备名,往后翻到有背景为红色行,这些是 IDE 设备,仔细看看那些硬盘设备,例如我的其中一个 120g 的盘是这样:
IDE#DiskMaxtor_6Y120L0__________________________YAR41BW0#33594b5059394557202020202020202020202020#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
可以看到:Maxtor_6Y120L0(硬盘厂商/型号),YAR41BW0(硬盘 Module 号),这个 33594b5059394557202020202020202020202020 是什么呢?这个就是我的意外发现,运行下面代码出结果:
- m.cWhatNo = '33594b5059394557202020202020202020202020'
- m.cResult = ''
- FOR m.ii = 1 TO INT(LEN( m.cWhatNo )/4)
- m.cLow = '0x' + SUBSTR( m.cWhatNo, (m.ii-1)*4+1, 2 )
- m.cHigh = '0x' + SUBSTR( m.cWhatNo, (m.ii-1)*4+3, 2 )
- m.cResult = m.cResult + CHR( EVALUATE( m.cHigh )) + CHR( EVALUATE( m.cLow ))
- ENDFOR
- ? RTRIM( m.cResult )
显示结果为:Y3PK9YWE,原来它就是我这块硬盘的出厂序列号!又一种获取序列号的方法诞生,只是不知适用性如何?QueryDosDevice 函数只能运行在 Win2000 以上的版本,所以至少 9x/Me 被排除了,好在现在应该没人用这些了。到现在为止,已经掌握的获取序列号的方法增加到了5 种,它们是: SCSI 后门 / Smart 参数 / IOCTL_STORAGE_QUERY_PROPERTY / WMI 以及这个方法。因为调用这个函数 MSDN 上没有特别指出需要什么权限,所以应该任何权限的用户都可以。
--------------------------------------------------------------------------------------------------------
继续研究 DefineDosDevice 函数
这个函数很简单,主要用于将一个盘符映射到一个已存在的文件夹,要注意到这个被映射的盘符是一个本地磁盘,而不是网络盘(例如使用 WNetAddConnection2 映射的网络驱动器)。这个函数返回 0 表示操作失败,返回 1 表示操作成功。一旦映射完成,“我的电脑”中就会出现一个新的盘符,你可以用它来快速访问一个包含在多层文件夹下的文件。如果你用过 DOS,它会使你想起一个 DOS 命令 SUBST !
- DECLARE Long DefineDosDevice IN WIN32API ;
- Long dwFlags, String lpDeviceName, String lpTargetPath
- * 将 Windows 文件保护缓存文件夹映射到 K 盘
- DefineDosDevice( 0, 'K:', 'C:/WINDOWS/system32/dllcache' )
- * 移除这个映射盘
- * DefineDosDevice( 2, 'K:', 'C:/WINDOWS/system32/dllcache' )