RSS订阅信息安全技术跟踪与研究:技术、平台、会议、论文、产业
你现在的位置:首页 / 技术积累 / 正文

Windows编程:Volume设备名到盘符Dos名的转换

0 技术积累 | 2015年4月1日
转载申明:本站原创,欢迎转载。但转载时请保留原文地址。
原文地址:http://www.vonwei.com/post/VolumeToDosname.html

Windows系统或者驱动编程中可能经常碰到如下的问题。

问题:

         已知设备名“\Device\HarddiskVolume1\Windows\notepad.exe”,想要转换为带盘符的常见形式“C:\Windows\notepad.exe”。

 

解决方法:

         在内核ring0层,可以使用RtlVolumeDeviceToDosName(在NT/2000系统下)或者IoVolumeDeviceToDosName(在XP/2003等系统下)。

         ring3应用层,QueryDosDevice可以从C: 等盘符名获取对应的Volume设备名\Device\HarddiskVolume1,没有反过来的API可用;而且除了盘符,对于带文件路径的全路径进行转换,更没有相应的API可用。

         这里基于QueryDosDevice采用一个傻瓜的方法进行全路径的转换:Windows下盘符从A:Z:,枚举即可,找到盘符与Volume名的对应关系并存储在一个数组中。对于输入一个带Volume名的全路径,与数组中的Volume名进行匹配(只匹配Volume名对应长度的字节),找到相符的后用数组中对应的盘符名称代替即可。下面上源码:

 

//存储映射关系的数据结构DosMapToDeviceName

typedef struct _DosMapToDeviceName{

         WCHAR lpDeviceName[3];//DoS盘符名,如C:

         WCHAR lpTargetPath[250];//Volume中路径,/Device/HarddiskVolume1

         int PathLen;//volume路径实际长度

}DosMapToDeviceName,*PDosMapToDeviceName;

 

//定义一个数组,AZ26个字母

DosMapToDeviceName mapName[26] = {0};

 

//找到所有的盘符,枚举找到对应的路径,并存储到mapName数组

void SetMapping()

{

         WCHAR lpDeviceName[3] = L"C:";

         WCHAR lpTargetPath[250];

         DWORD ns;

         WCHAR c;

         int i =0;

        

         for(c=L'A';c<=L'Z';c++)

         {

                   lpDeviceName[0]=c;

                   ns = QueryDosDeviceW(lpDeviceName,lpTargetPath,250);

                   //printf("The Dos device name for %ws is: %ws (sizeof:%d)\n",lpDeviceName,lpTargetPath,wcslen(lpTargetPath));

                   mapName[i].PathLen = wcslen(lpTargetPath);

                   memmove(mapName[i].lpDeviceName,lpDeviceName,3);

                   memmove(mapName[i].lpTargetPath,lpTargetPath,250);

                  i++;

         }

}

 

//对于设备路径path,与mapName对比,将VolumeDevice名字换成对应的盘符名字

void doPathMapping(WCHAR* path)

{

         int i,j,len,k,l;

         int result;

         len = wcslen(path);

         for(i=0;i<26;i++)

         {

                   l = mapName[i].PathLen;

                   result=wmemcmp(mapName[i].lpTargetPath, path, l);

                   if(result==0)

                   {

                            for(j=2,k=l;k<len;j++,k++)

                                     path[j]=path[k];

                            for(;j<len;j++)

                                     path[j]=L'\0';

                            path[0]=mapName[i].lpDeviceName[0];

                            path[1]=mapName[i].lpDeviceName[1];

                            break;

                   }

         }

}

 

在需要执行转换的地方,先调用SetMapping()函数,然后执行void doPathMapping(WCHAR* path)函数,会将输入的“\Device\HarddiskVolume1\Windows\notepad.exe”这个形式的path,转换为“C:\Windows\notepad.exe”这种形式的path

注意,上面的函数都是处理Unicode形式的宽字符,如果是采用ANSI单字节编码形式,使用对应的ANSI API替换即可,如QueryDosDeviceAstrlenmemcmp等。内核中一般采用Unicode形式居多,应用层可以转化为相应的ANSI后处理。这里在应用层也直接对Unicode进行处理。


  • ------------------分隔线----------------

  • 如果感兴趣,欢迎关注本站微信号,跟踪最新博文信息,手机微信扫一扫下面的二维码,即可关注!
  • 微月信公众号
  • 推荐您阅读更多有关于“ Windows编程   ”的文章

    请填写你的在线分享代码
    上一篇:Windows内核中获取全路径:IoQueryFileDosDeviceName、ObQueryNameString下一篇:Windows8任务栏卡死

    猜你喜欢

    评论列表:

    发表评论

    必填

    选填

    选填

    必填,不填不让过哦,嘻嘻。

    记住我,下次回复时不用重新输入个人信息

    本站介绍
    最近发表
    本年最热文章
    本月最热文章
    网站分类
    文章归档