磁盘设备类型获取函数

2023-11-18

//将该部分内容保存到.cpp文件中可直接编译运行,用于辨别驱动器的类型!

 

#define MEDIA_INFO_SIZE    sizeof(GET_MEDIA_TYPES)+15*sizeof(DEVICE_MEDIA_INFO)
#define IOCTL_STORAGE_QUERY_PROPERTY   CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef enum _STORAGE_BUS_TYPE { 
 BusTypeUnknown = 0x00, 
  BusTypeScsi, 
  BusTypeAtapi, 
  BusTypeAta, 
  BusType1394, 
  BusTypeSsa, 
  BusTypeFibre, 
  BusTypeUsb, 
  BusTypeRAID, 
  BusTypeiScsi, 
  BusTypeSas, 
  BusTypeSata, 
  BusTypeSd, 
  BusTypeMmc, 
  BusTypeMax, 
  BusTypeMaxReserved = 0x7F
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;


typedef enum _STORAGE_PROPERTY_ID {
 StorageDeviceProperty = 0,
  StorageAdapterProperty,
  StorageDeviceIdProperty
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;

typedef enum _STORAGE_QUERY_TYPE {
 PropertyStandardQuery = 0,
  PropertyExistsQuery,
  PropertyMaskQuery,
  PropertyQueryMaxDefined
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;


typedef struct _STORAGE_PROPERTY_QUERY {
 STORAGE_PROPERTY_ID  PropertyId;
 STORAGE_QUERY_TYPE  QueryType;
 unsigned char  AdditionalParameters[1];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;


typedef struct _STORAGE_DEVICE_DESCRIPTOR {
 unsigned long  Version;
 unsigned long  Size;
 unsigned char DeviceType;
 unsigned char DeviceTypeModifier;
 unsigned char  RemovableMedia;
 unsigned char  CommandQueueing;
 unsigned long  VendorIdOffset;
 unsigned long  ProductIdOffset;
 unsigned long  ProductRevisionOffset;
 unsigned long  SerialNumberOffset;
 STORAGE_BUS_TYPE  BusType;
 unsigned long  RawPropertiesLength;
 unsigned char RawDeviceProperties[1];
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;

#include <windows.h>
#include <winioctl.h>
#include <iostream.h>
#include <string.h>
#include <tchar.h>

 

BOOL GetDriveGeometry(const TCHAR * filename, DISK_GEOMETRY * pdg)
{
 HANDLE hDevice;         // 设备句柄
 BOOL bResult;           // DeviceIoControl的返回结果
 GET_MEDIA_TYPES *pmt;   // 内部用的输出缓冲区
 DWORD dwOutBytes;       // 输出数据长度
 
 // 打开设备
 hDevice = ::CreateFile(filename,           // 文件名
  GENERIC_READ,                          // 软驱需要读盘
  FILE_SHARE_READ | FILE_SHARE_WRITE,    // 共享方式
  NULL,                                  // 默认的安全描述符
  OPEN_EXISTING,                         // 创建方式
  0,                                     // 不需设置文件属性
  NULL);                                 // 不需参照模板文件
 
 if (hDevice == INVALID_HANDLE_VALUE)
 {
  // 设备无法打开...
  return FALSE;
 }
 
 // 用IOCTL_DISK_GET_DRIVE_GEOMETRY取磁盘参数
 bResult = ::DeviceIoControl(hDevice,       // 设备句柄
  IOCTL_DISK_GET_DRIVE_GEOMETRY,         // 取磁盘参数
  NULL, 0,                               // 不需要输入数据
  pdg, sizeof(DISK_GEOMETRY),            // 输出数据缓冲区
  &dwOutBytes,                           // 输出数据长度
  (LPOVERLAPPED)NULL);                   // 用同步I/O
 
 // 如果失败,再用IOCTL_STORAGE_GET_MEDIA_TYPES_EX取介质类型参数
 if (!bResult)
 {
  pmt = (GET_MEDIA_TYPES *)new BYTE[MEDIA_INFO_SIZE];
  
  bResult = ::DeviceIoControl(hDevice,    // 设备句柄
   IOCTL_STORAGE_GET_MEDIA_TYPES_EX,   // 取介质类型参数
   NULL, 0,                            // 不需要输入数据
   pmt, MEDIA_INFO_SIZE,               // 输出数据缓冲区
   &dwOutBytes,                        // 输出数据长度
   (LPOVERLAPPED)NULL);                // 用同步I/O
  
  if (bResult)
  {
   // 注意到结构DEVICE_MEDIA_INFO是在结构DISK_GEOMETRY的基础上扩充的
   // 为简化程序,用memcpy代替如下多条赋值语句:
   // pdg->MediaType = (MEDIA_TYPE)pmt->MediaInfo[0].DeviceSpecific.DiskInfo.MediaType;
   // pdg->Cylinders = pmt->MediaInfo[0].DeviceSpecific.DiskInfo.Cylinders;
   // pdg->TracksPerCylinder = pmt->MediaInfo[0].DeviceSpecific.DiskInfo.TracksPerCylinder;
   // ... ...
   ::memcpy(pdg, pmt->MediaInfo, sizeof(DISK_GEOMETRY));
  }
  
  delete pmt;
 }
 
 // 关闭设备句柄
 ::CloseHandle(hDevice);
 
 return (bResult);
 
}

 


int main()
{
 TCHAR szBuf[256];
 memset(szBuf,0,sizeof(szBuf));
 DISK_GEOMETRY dg;
 TCHAR sztmpPath[100] = _T(".//");
 TCHAR szPath[100] = _T(".//");
 HANDLE hDevice;         // 设备句柄
 BOOL bResult;           // DeviceIoControl的返回结果
 STORAGE_PROPERTY_QUERY Query; // input param for query
 DWORD dwOutBytes; // IOCTL output length
 STORAGE_DEVICE_DESCRIPTOR pDevDesc;

 

 DWORD len = GetLogicalDriveStrings(sizeof(szBuf)/sizeof(TCHAR),szBuf);
 
 for (TCHAR* s = szBuf; *s; s += strlen(s)+1)
 {
  LPCTSTR sDrivePath = s;
  memcpy(szPath,sztmpPath,sizeof(szPath));
  ::_tcscat(szPath,sDrivePath); 
  int nSize = ::_tcslen(szPath);
  szPath[nSize-1] = '/0';  
        BOOL bResult = GetDriveGeometry(szPath,&dg);
  
  // 打开设备
  hDevice = ::CreateFile(szPath,             // 文件名
   GENERIC_READ,                          // 软驱需要读盘
   FILE_SHARE_READ | FILE_SHARE_WRITE,    // 共享方式
   NULL,                                  // 默认的安全描述符
   OPEN_EXISTING,                         // 创建方式
   0,                                     // 不需设置文件属性
   NULL);   
  if (hDevice == INVALID_HANDLE_VALUE)
  {
   return FALSE;
  }
  
  
  Query.PropertyId = StorageDeviceProperty;
  Query.QueryType = PropertyStandardQuery;
    
  pDevDesc.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);

  
  // 用 IOCTL_STORAGE_QUERY_PROPERTY  
  bResult = ::DeviceIoControl(hDevice, // device handle
   IOCTL_STORAGE_QUERY_PROPERTY, // info of device property
   &Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer
   &pDevDesc, pDevDesc.Size, // output data buffer
   &dwOutBytes, // out's length
   (LPOVERLAPPED)NULL);

  if (bResult == FALSE)
  {
   CloseHandle(hDevice);
   return 0;
  }
  
  UINT Type = pDevDesc.BusType;
  switch(Type)
  {
  case    BusTypeUnknown:
   cout<<sDrivePath<<"  未知设备"<<'/n';
   break;

  case    BusTypeScsi:
   cout<<sDrivePath<<"  SCSI设备"<<'/n';
   break;
   
  case    BusTypeAtapi:
   cout<<sDrivePath<<"  API设备"<<'/n';
   break;
   
  case  BusTypeAta:
   cout<<sDrivePath<<"  ATA设备"<<'/n';
   break;
   
  case  BusType1394:
   cout<<sDrivePath<<"  1394设备"<<'/n';
   break;
   
  case BusTypeSsa:
   cout<<sDrivePath<<"  SSA设备"<<'/n';
   break;
   
  case  BusTypeFibre:
   cout<<sDrivePath<<"  光纤设备"<<'/n';
   break;
   
  case  BusTypeUsb:
   cout<<sDrivePath<<"  USB设备"<<'/n';
   break;
   
  case  BusTypeRAID:
   cout<<sDrivePath<<"  RAID设备"<<'/n';
   break;
   
  case BusTypeiScsi:
   cout<<sDrivePath<<"  iSCSI设备"<<'/n';
   break;
   
  case BusTypeSas:
   cout<<sDrivePath<<"  SAS设备"<<'/n';
   break;
   
  case BusTypeSata:
   cout<<sDrivePath<<"  SATA设备"<<'/n';
   break;
   
  case  BusTypeSd:
   cout<<sDrivePath<<"  SD设备"<<'/n';
   break;
   
  case BusTypeMmc:
   cout<<sDrivePath<<"  MMC设备"<<'/n';
   break;
   
  case BusTypeMax:
   cout<<sDrivePath<<"  MAX设备"<<'/n';
   break;
   
  case  BusTypeMaxReserved:
   cout<<sDrivePath<<"  ...设备"<<'/n';
   break;
  default:
   break;
  }
  CloseHandle(hDevice);
 }
};

 

欢迎大家加入"数据恢复技术"QQ群:30481379 

        本QQ群主要研究分析NTFS、EXT2/3、ResierFS等文件系统及数据恢复技术,同时对各种系统的磁盘阵列恢复的阵列参数智能分析算法进行技术交流,欢迎有志同道合者加入!

         由于本群主要面向数据恢复的技术研究,同时起点要高于一般的数据恢复技术,所以希望加入者在加入本群以前已经有关于这方面技术的积累会相关研究经验,希望大家能理解!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ddl007/archive/2008/02/28/2127981.aspx

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

磁盘设备类型获取函数 的相关文章

  • 如何检查 python pandas 中列内容的数据类型?

    这个问题与如何检查 python pandas 中列的 dtype https stackoverflow com questions 22697773 how to check the dtype of a column in pytho
  • C#:“Pretty”类型名称函数?

    对于泛型类型 System Type 类的名称属性会返回一个奇怪的结果 有没有办法以更接近我指定的方式获取类型名称 例子 typeof List
  • Coq案例分析和函数返回子集类型的重写

    我正在做一个关于使用子集类型编写经过认证的函数的简单练习 想法是先写一个前驱函数 pred forall n n nat n gt 0 m nat S m n 1 然后使用这个定义给定一个函数 pred2 forall n n nat n
  • 如何防止(卸载)TypeScript 安装并引用它自己的 @types 到 AppData\Local 中

    我遇到了一个有点令人困惑的问题 似乎TypeScript正在安装自己的副本React进入它自己的全局缓存 不确定它叫什么 假设那就是它是什么 并在我的项目中引用它 具体来说 我最终得到了两个对 React 的引用 其中一个位于我的项目的根目
  • 在联合上分配泛型类型

    TS 中有没有办法通过联合 分布 泛型类型 type Container a value A type Containers a
  • 任意类型说明符上的 Defmethod?

    我想做的是 defgeneric fn x defmethod fn x integer 1 Positive integer defmethod fn x integer 1 Negative integer 我想要一个可以与任意类型说明
  • Haskell——从具体类型实例获取 TypeRep

    我想编写一个具有这种类型签名的函数 getTypeRep Typeable a gt t a gt TypeRep 其中 TypeRep 将是类型表示a 不是为了t a 也就是说 编译器应该在任何调用站点自动返回正确的类型表示 to获取类型
  • MS Access SQL,更改数据类型

    当尝试在 Access 的设计模式下将数据类型从文本更改为数字 使用接近 2 GB 的数据库 时 我不断收到 磁盘空间或内存不足 错误 因此我找到了一种解决方法 基本上创建一个新列 将数据类型设置为数字 复制旧列内容 删除旧列并将新列重命名
  • 在 Scala 中模拟可变参数模板

    假设你想要类似的东西可变参数模板 http en wikipedia org wiki Variadic Templates 为泛型类定义 n 个类型参数的能力 在 Scala 中 例如你不想定义Tuple2 T1 T2 and Tuple
  • R 矩阵可以包含不同的数据类型吗?这个被修改的列表矩阵有用吗?

    我读了这些 https stackoverflow com a 5159049 1175496 https stackoverflow com a 5159049 1175496 Matrices are for data of the s
  • 整数最小值和最大值

    我是编程新手 我正在学习一本Java对象编程书籍 并在计算机上同时执行书中的教程和示例 书中说整数的最大值和最小值是 Integer MAX VALUE 2147483647 Integer MIN VALUE 2147483648 那么好
  • 转换为具体类并调用 Java 中的方法

    假设我们有一个名为A和一些子类 B C D ETC 大多数子类都有这个方法do 但基类没有 班级AA提供了一个方法叫做getObject 这将创建一个类型的对象B or C or D等 但将对象作为类型返回A 如何将返回的对象转换为具体类型
  • 在 JavaScript 中将浮点数转换为整数的最佳方法是什么?

    在 JavaScript 中 有多种不同的方法可以将浮点数转换为整数 我的问题是哪种方法可以提供最佳性能 最兼容或被认为是最佳实践 以下是我所知道的几种方法 var a 2 5 window parseInt a 2 Math floor
  • 有什么好的 JavaScript 货币或小数类吗?

    我正在尝试处理 JavaScript 值 例如23 45 但我希望能够对这些值进行数学运算 加法 减法 乘法 除法 而不会遇到浮点问题 是的 有时我可能需要对结果进行四舍五入 但我希望它给出合理的答案 在 JavaScript 中考虑一下
  • Haskell:使用 RankNTypes 折叠记录构造函数

    import Data ConfigFile data Test Test field1 Int field2 Bool field3 String deriving Show whatMyConfigLooksLike field1 5
  • Haskell 重叠/不连贯的实例

    我知道这段代码有点傻 但有人可以解释为什么吗isList 42 回报True然而isList2 42 prints False 以及如何防止这种情况发生 我想更好地理解一些更晦涩的 GHC 类型扩展 我认为这将是一个有趣的例子 LANGUA
  • 未确定的泛型类型在 ghci 的运行时中如何表示

    我很清楚通用函数和通用数据类型 在泛型类型中 data SB forall x show x gt SB x instance Show SB where show SB x show x 所以对于任何给定类型x 如果它有一个签名Show
  • 类型衰减——它是什么以及为什么会出现?

    我很惊讶类型衰减在 SO 或其他地方没有得到很好的解释 也许我没有使用正确的术语进行搜索 或者也许我没有正确理解整个事情 我的问题是 它是什么 它是如何 为什么 到达那里的 它的规则是什么 如果你想知道我为什么问 下面是我的哭泣型腐烂故事
  • TypeScript:使用调用签名和构造函数签名实现接口

    是否可以创建一个实现以下接口的对象 interface I string new any 我看到可以实现一个具有调用签名和这个问题的一些字段的接口 使用裸函数签名和其他字段实现 TypeScript 接口 https stackoverfl
  • mypy 如何忽略源文件中的一行?

    我在用着mypy http mypy lang org 在我的 python 项目中进行类型检查 我还使用 PyYAML 来读取和写入项目配置文件 不幸的是 当使用PyYAML 文档中推荐的导入机制 http pyyaml org wiki

随机推荐

  • awk内置函数

    http blog csdn net nuoline article details 8610679
  • 【爬虫进阶】猿人学任务七之字体反爬(难度2.0)

    目录 前言 特此说明 分析 代码过程 成果 完整源码 前言 往期有讲解过某团字体反爬 感觉效果不太好 所以本章重新找了个例子 希望能帮助大家理解透彻 再遇到直接手撕 特此说明 如果涉及到版权问题 请立刻联系博主删除 分析 首先 我们看题目
  • C++实现栈(链表模拟)【每一步详细深入讲解,代码清晰、简单、易懂】

    文章目录 一 利用链表实现栈 1 链表实现的思路 2 设计栈的结构 3 入栈操作 4 出栈操作 5 判断栈空 6 构造析构 7 完整代码 一 利用链表实现栈 1 链表实现的思路 由于栈是一种较为简单的数据结构 用链表实现栈 逻辑上和数组差不
  • 多输入通道和多输出通道

    目录 多输入通道和多输出通道 目录 1 什么是多输入通道和多输出通道 2 多输入通道和多输出通道的实现 2 1 多输入通道和多输出通道的卷积操作 2 2 多输入通道和多输出通道的全连接操作 3 多输入通道和多输出通道的实例 3 1 导入必要
  • 若依SpringBoot+Vue分离版打包部署(前端)

    遇到的问题为vue项目webpack dev server配置后本地连接服务器地址正常请求 但是打包之后请求服务器接口一直是404 Vue前端打包 1 npm run build prod 打包 2 npm run preview 打包正式
  • 【Vue2从入门到精通】深入浅出,带你彻底搞懂Vue2组件通信的9种方式

    文章目录 人工智能福利文章 Vue组件间通信分类 1 props emit 1 1 父组件向子组件传值 1 2 子组件向父组件传值 2 parent children 3 ref refs 3 1 ref作用于组件 3 2 ref作用于Ht
  • FLASH位宽为8、16、32时,CPU与外设之间地址线的连接方法

    原文地址 http www eefocus com E5 8D 83 E9 87 8C E7 9F A5 E9 B9 B0 blog 10 03 186914 04945 html FLASH连接CPU时 根据不同的数据宽度 比如16位的N
  • java BigDecimal保留两位小数

    对于一些精准的数字 如涉及到金额时我们一般会使用BigDecimal类型来保存和处理 在处理保留小数位数时 如果通过DecimalFormat表达式需要注意下 1 通过DecimalFormat保留两位小数 通过上图可以看到 在补位时 如果
  • 文件上传之IIS6.0解析漏洞

    文章目录 1 判断iis版本 2 使用目录解析漏洞 2 1 写asp一句话木马 2 2 bp抓包 2 3 修改上传路径 2 4 实用工具连接 2 5 get shell 3 使用文件解析漏洞 3 1 写一句话马 3 2 上传 3 3 抓包改
  • mmyolo框架实现在VOC数据集上复现Yolov6教程(详细)

    写在开头 最近学习mmyolo的框架 想着它能将所有配置都写在一个config文件里 只需要改配置文件就可以改动模型 感觉挺方便的 就想着Yolov6用mmyolo框架来实现 但mmyolo并没有提供v6的voc实现配置 v5是有的 看下图
  • RocketMQ的消息优先级

    有些场景 需要应用程序处理几种类型的消息 不同消息的优先级不同 RocketMQ是个先入先出的队列 不支持消息级别或者Topic级别的优先级 业务中简单的优先级需求 可以通过间接的方式解决 下面列举三种优先级相关需求的具体处理方法 第一种
  • Linux环境下的jdk安装(大数据环境)

    jdk安装 创建软件存放目录 上传文件 我使用的MobaXterm 创建解压目录 解压jdk压缩包 修改软件名 使他简洁易操作 配置环境变量 让配置文件生效 查看jdk版本信息 将HP01 的usr文件夹整体拷贝到HP02 HP03目录下
  • 如何使用 FreeRTOS中的xQueueCreate,xQueueSend,xQueueReceive

    信号量Semaphore和互斥量mutex 只能用于进程间的同步 并不能传递更多的数据 在freertos 提供了messageQ 用来在实现进程同步的同时 传递数据 进程间通信 或者ISR和TASK之间通信 如果没有messageQ 则只
  • Object&Objects

    Object 概念 Object 是类层次结构的根 每个类都可以将 Object 作为超类 所有类都直接或者间接的继承自该类 换句话说 该类所具备的方法 所有类都会有一份 toString 作用 以良好的格式 更方便的展示对象中的属性值 重
  • c++ Json库读取和写入json文件

    include json include writer h include json include reader h include
  • Fabric中的“账户”体系

    本文的联盟链是以Fabric为例 本文中transaction翻译成事务 而非交易 联盟链相对于公链 最大的不同在于 联盟链上的数据不是对所有人都公开的 只有联盟内的成员才可以访问 写入链上数据 第二个重要的区别 联盟链不发币 所以联盟链里
  • WSL安装与使用(Ubuntu22.04)

    文章目录 概要 WSL介绍 WSL安装 安装环境 安装方式一 命令行安装 不推荐 可能出现奇怪的问题 安装方式二 通过控制面板安装 WSL 安装Ubuntu22 04 通过Microsoft Store Ubuntu更换镜像源 进入Ubun
  • I2C接口与SPI和UART接口的区别

    一 SPI I2C UART通信速率比较 SPI gt I2C gt UART 1 同步通信 gt 异步通信 2 同步通信时必须有一根时钟线连接传输的两端 3 都是串行通信方式 并行通信用于内部存储间的通信 如flash 4 适合传输的距离
  • python爬虫(爬取唯品会)

    import json import requests from bs4 import BeautifulSoup from selenium import webdriver from time import sleep class Vi
  • 磁盘设备类型获取函数

    将该部分内容保存到 cpp文件中可直接编译运行 用于辨别驱动器的类型 define MEDIA INFO SIZE sizeof GET MEDIA TYPES 15 sizeof DEVICE MEDIA INFO define IOCT