1、函数简介
BOOL WINAPI DefineDosDevice(
__in DWORD dwFlags,
__in LPCTSTR lpDeviceName,
__in LPCTSTR lpTargetPath
);
参数:
DWORD dwFlags,该函数的控制标志,可取下列值:
DDD_EXACT_MATCH_ON_REMOVE ,确保不会删除未声明的对象
DDD_NO_BROADCAST_SYSTEM, 设置 WM_SETTINGCHANGE消息的状态为不发送。(默认情况下,该消息状态为发送)
DDD_RAW_TARGET_PATH, 使用lpTargetPath参数
DDD_REMOVE_DEFINITION, 删除指定设备声明;
如果lpTargetPath为NULL或指向空字符串,则删除第一个设备或堆栈中顶层的设备;
If this value is not specified, the string pointed to by the lpTargetPath parameter will become the new mapping for this device.
LPCTSTR lpDeviceName,设备名称字符串不是必须将冒号作为最后一个字符,除非一个驱动器号被定义,重新定义或删除。在任何情况下,一个反斜杆是不允许的。
LPCTSTR lpTargetPath,指向路径字符串,如果设置DDD_RAW_TARGET_PATH参数,则指向路径字符串
返回值:
如果成功,返回非0值
失败,则返回0,可通过GetLastError获得进一步信息。
备注:
使用SetVolumeMountPoint函数定义一个驱动器号。
使用DeleteVolumeMountPoint函数删除一个已存在的驱动器号。
在应用层调用DefinesDosDevice创建的符号链接,会放在内核对象空间\\Sessions\\X\\DosDevices\\xxxxxxxx\\ 下
2、范例
#include <windows.h>
int main(int argc, char* argv[])
{
printf("DefineDosDevice!\n");
BOOL rs1 =DefineDosDevice(DDD_REMOVE_DEFINITION,"N:",NULL);
printf(" rs= %d\R\N",rs1);
BOOL rs2 =DefineDosDevice(DDD_RAW_TARGET_PATH, "U:","\\GLOBAL??\\D:\\paper");
if (0)
{
rs2 =DefineDosDevice(DDD_REMOVE_DEFINITION,"U:",NULL);
}
printf(" rs= %d\r\n",rs2);
return 0;
}
使程序访问物理硬盘的N种方法
访问硬盘最常用的路径是://./PhysicalDrive+数字,如//./PhysicalDrive0表示第一个物理硬盘。取得该硬盘句柄的方法一般用CreateFile(),如
CString hd=.//PhysicalDrive0;
hDevice = CreateFile(
hd,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
打开成功后就可以用ReadFile等函数进行读写操作。
访问硬盘还可以有其它路径,如“/Device/Harddisk0”。
如果想访问分区,可以有以下几种方法:
//?/C:表示C盘的路径,用访问硬盘的方法可以对它进行访问。C盘还可以用"/Device/HarddiskVolume1","/Device/Harddisk0/Partition1",//?/Volume{385baaca-8b42-11dc-bb79-0013d324fc7d}/(用GetVolumeNameForVolumeMountPoint()获得)。
提示:如果想获得硬盘整体的物理信息,可以用这个硬盘上任意一个分区的句柄来代替硬盘句柄。
如果发现某些路径用CreateFile打不开,可以用DefineDosDevice()给它定义一个盘符,这个盘符可以是A:,B:,也可以是特殊符号(如[:,]:)甚至是数字(1:,2:)。对于非字母的的盘符,在我的电脑里是不可见的,只有程序可以访问, 这种方法常用于访问隐藏分区。
例:
DefineDosDevice (DDD_RAW_TARGET_PATH, "[:"
"//Device//Harddisk0//Partition1");//分配一个“[:”盘符,该盘符不可见。
…………………………//处理代码
bRet = DefineDosDevice (
DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|
DDD_EXACT_MATCH_ON_REMOVE, "[:",
"//Device//Harddisk0//Partition1");//用完后删除这个盘符。
快速隐藏分区---实现代码
#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct SaveContext
{
string strNtPath;
string strDosDevice;
};
typedef vector<SaveContext> svrVector;
void RestoreDevice(SaveContext &Context);
int main(void)
{
//读磁盘配置并排除C盘
DWORD dwDisks=GetLogicalDrives()&0xfffffffb;
svrVector NtDevices;
TCHAR chDosDevice[8]={0};
*(WORD*)chDosDevice=':A';
TCHAR chNtPath[MAX_PATH]={0};
for(int Mask=1;Mask;Mask<<=1,chDosDevice[0]++)
{
if(dwDisks&Mask)
{
QueryDosDevice(chDosDevice,chNtPath,MAX_PATH);
SaveContext Context;
Context.strDosDevice=chDosDevice;
Context.strNtPath=chNtPath;
//先保存符号名和设备之间的关系
NtDevices.push_back(Context);
cout<<Context.strDosDevice<<"<--->"<<Context.strNtPath<<endl;
//除了C:以外其它的盘符正一个一个的不见了
DefineDosDevice(DDD_REMOVE_DEFINITION,Context.strDosDevice.c_str(),NULL);
}
}
//现在打开"我的电脑"看看
system("pause");
//现在隐藏的盘符又出现了,呵呵
for_each(NtDevices.begin(),NtDevices.end(),RestoreDevice);
return 0;
}
void RestoreDevice(SaveContext &Context)
{
DefineDosDevice(DDD_RAW_TARGET_PATH,Context.strDosDevice.c_str(),Context.strNtPath.c_str());
}
在我的机器上输出下面的结果:
D:<--->/Device/HarddiskVolume2
E:<--->/Device/CdRom0
F:<--->/Device/CdRom1
G:<--->/Device/HarddiskVolume4
H:<--->/Device/HarddiskVolume5
I:<--->/Device/HarddiskVolume6
J:<--->/Device/HarddiskVolume7
Z:<--->/Device/PGPdisks/PGPdiskVolume1
请按任意键继续. . .