指定盘符获取u盘PID、VID、序列号等信息
最近学习scsi和DeviceIoControl,下载了微软WDK一些例子,以下代码精简自Windows-driver-samples-master\storage\tools\spti\src\spti.c ,略有修改。
#include <windows.h>
#include <stdio.h>
#include <strsafe.h> void QueryPropertyForDevice(HANDLE);
void PrintDeviceDescriptor(PSTORAGE_DEVICE_DESCRIPTOR); int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: %s \n", argv[0] );
printf("Examples:\n");
printf(" %s g: (PrintDeviceDescriptor)\n", argv[0]);
} char filepath[7];
StringCbPrintf(filepath, sizeof(filepath), "\\\\.\\%s", argv[1]); HANDLE hDevice = CreateFile(filepath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL); if (hDevice == INVALID_HANDLE_VALUE) {
unsigned long errorCode = GetLastError();
printf("Error opening %s. Error: %d\n",
filepath, errorCode);
return errorCode;
} QueryPropertyForDevice(hDevice);
CloseHandle(hDevice); return 0;
} #define BOOLEAN_TO_STRING(_b_) \
( (_b_) ? "True" : "False" ) LPCSTR BusTypeStrings[] = {
"Unknown",
"Scsi",
"Atapi",
"Ata",
"1394",
"Ssa",
"Fibre",
"Usb",
"RAID",
"Not Defined",
};
#define NUMBER_OF_BUS_TYPE_STRINGS (sizeof(BusTypeStrings)/sizeof(BusTypeStrings[0])) void QueryPropertyForDevice(HANDLE hDevice)
{
bool result;
DWORD readed; STORAGE_DESCRIPTOR_HEADER *DeviceDescriptorHeader;
STORAGE_DEVICE_DESCRIPTOR *DeviceDescriptor;
DWORD devDescLength;
STORAGE_PROPERTY_QUERY query; query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery; DeviceDescriptorHeader = (STORAGE_DESCRIPTOR_HEADER *) malloc( sizeof(STORAGE_DESCRIPTOR_HEADER) ); result = DeviceIoControl( hDevice, // device to be queried
IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform
&query, sizeof query, // no input buffer
DeviceDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), // output buffer
&readed, // # bytes returned
NULL ); // synchronous I/O devDescLength = DeviceDescriptorHeader->Size;
DeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR *) malloc( devDescLength ); result = DeviceIoControl( hDevice, // device to be queried
IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform
&query, sizeof query, // no input buffer
DeviceDescriptor, devDescLength, // output buffer
&readed, // # bytes returned
NULL ); // synchronous I/O PrintDeviceDescriptor(DeviceDescriptor); free( DeviceDescriptorHeader );
free( DeviceDescriptor );
} void PrintDeviceDescriptor(PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor)
{
LPCSTR vendorId = "";
LPCSTR productId = "";
LPCSTR productRevision = "";
LPCSTR serialNumber = "";
LPCSTR busType; if ((ULONG)DeviceDescriptor->BusType < NUMBER_OF_BUS_TYPE_STRINGS) {
busType = BusTypeStrings[DeviceDescriptor->BusType];
} else {
busType = BusTypeStrings[NUMBER_OF_BUS_TYPE_STRINGS-1];
} if ((DeviceDescriptor->ProductIdOffset != 0) &&
(DeviceDescriptor->ProductIdOffset != -1)) {
productId = (LPCSTR)(DeviceDescriptor);
productId += (ULONG_PTR)DeviceDescriptor->ProductIdOffset;
}
if ((DeviceDescriptor->VendorIdOffset != 0) &&
(DeviceDescriptor->VendorIdOffset != -1)) {
vendorId = (LPCSTR)(DeviceDescriptor);
vendorId += (ULONG_PTR)DeviceDescriptor->VendorIdOffset;
}
if ((DeviceDescriptor->ProductRevisionOffset != 0) &&
(DeviceDescriptor->ProductRevisionOffset != -1)) {
productRevision = (LPCSTR)(DeviceDescriptor);
productRevision += (ULONG_PTR)DeviceDescriptor->ProductRevisionOffset;
}
if ((DeviceDescriptor->SerialNumberOffset != 0) &&
(DeviceDescriptor->SerialNumberOffset != -1)) {
serialNumber = (LPCSTR)(DeviceDescriptor);
serialNumber += (ULONG_PTR)DeviceDescriptor->SerialNumberOffset;
} puts("\n ***** STORAGE DEVICE DESCRIPTOR DATA *****");
printf(" Version: %08x\n"
" TotalSize: %08x\n"
" DeviceType: %08x\n"
" DeviceTypeModifier: %08x\n"
" RemovableMedia: %s\n"
" CommandQueueing: %s\n"
" Vendor Id: %s\n"
" Product Id: %s\n"
" Product Revision: %s\n"
" Serial Number: %s\n"
" Bus Type: %s\n",
DeviceDescriptor->Version,
DeviceDescriptor->Size,
DeviceDescriptor->DeviceType,
DeviceDescriptor->DeviceTypeModifier,
BOOLEAN_TO_STRING(DeviceDescriptor->RemovableMedia),
BOOLEAN_TO_STRING(DeviceDescriptor->CommandQueueing),
vendorId,
productId,
productRevision,
serialNumber,
busType); printf("\n");
}
参考链接:
https://www.cnblogs.com/shangdawei/p/3164005.html
c#参考
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles; namespace ConsoleApplication2
{
class Program
{
const uint GENERIC_READ = 0x80000000;
const uint GENERIC_WRITE = 0x40000000;
const uint FILE_SHARE_READ = 1;
const uint FILE_SHARE_WRITE = 2;
const uint OPEN_EXISTING = 3;
const int IOCTL_STORAGE_QUERY_PROPERTY = 2954240; public enum STORAGE_PROPERTY_ID
{
StorageDeviceProperty = 0,
StorageAdapterProperty = 1,
StorageDeviceIdProperty = 2,
StorageDeviceUniqueIdProperty = 3,
StorageDeviceWriteCacheProperty = 4,
StorageMiniportProperty = 5,
StorageAccessAlignmentProperty = 6,
StorageDeviceSeekPenaltyProperty = 7,
StorageDeviceTrimProperty = 8,
StorageDeviceWriteAggregationProperty = 9,
StorageDeviceDeviceTelemetryProperty = 10, // 0xA
StorageDeviceLBProvisioningProperty = 11, // 0xB
StorageDevicePowerProperty = 12, // 0xC
StorageDeviceCopyOffloadProperty = 13, // 0xD
StorageDeviceResiliencyProperty = 14 // 0xE
} public enum STORAGE_QUERY_TYPE
{
PropertyStandardQuery = 0,
PropertyExistsQuery = 1,
PropertyMaskQuery = 2,
PropertyQueryMaxDefined = 3
} [StructLayout(LayoutKind.Sequential)]
public struct STORAGE_PROPERTY_QUERY
{
public STORAGE_PROPERTY_ID PropertyId;
public STORAGE_QUERY_TYPE QueryType;
public byte[] AdditionalParameters;
} public enum STORAGE_BUS_TYPE
{
BusTypeUnknown = 0x00,
BusTypeScsi = 0x1,
BusTypeAtapi = 0x2,
BusTypeAta = 0x3,
BusType1394 = 0x4,
BusTypeSsa = 0x5,
BusTypeFibre = 0x6,
BusTypeUsb = 0x7,
BusTypeRAID = 0x8,
BusTypeiScsi = 0x9,
BusTypeSas = 0xA,
BusTypeSata = 0xB,
BusTypeSd = 0xC,
BusTypeMmc = 0xD,
BusTypeVirtual = 0xE,
BusTypeFileBackedVirtual = 0xF,
BusTypeMax = 0x10,
BusTypeMaxReserved = 0x7F
} public struct STORAGE_DESCRIPTOR_HEADER
{
public int Version;
public int Size;
} public struct STORAGE_DEVICE_DESCRIPTOR
{
public uint Version;
public uint Size;
public byte DeviceType;
public byte DeviceTypeModifier;
[MarshalAs(UnmanagedType.U1)]
public bool RemovableMedia;
[MarshalAs(UnmanagedType.U1)]
public bool CommandQueueing;
public uint VendorIdOffset;
public uint ProductIdOffset;
public uint ProductRevisionOffset;
public uint SerialNumberOffset;
public STORAGE_BUS_TYPE BusType;
public uint RawPropertiesLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
public byte[] RawDeviceProperties;
} [DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool DeviceIoControl(
SafeFileHandle hDevice,
int IoControlCode,
byte[] InBuffer,
int nInBufferSize,
byte[] OutBuffer,
int nOutBufferSize,
out int pBytesReturned,
IntPtr Overlapped
); [DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool DeviceIoControl(
int hDevice,
int IoControlCode,
ref STORAGE_PROPERTY_QUERY InBuffer,
int nInBufferSize,
out STORAGE_DESCRIPTOR_HEADER OutBuffer,
int nOutBufferSize,
out int pBytesReturned,
IntPtr Overlapped
); [DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool DeviceIoControl(
int hDevice,
int IoControlCode,
ref STORAGE_PROPERTY_QUERY InBuffer,
int nInBufferSize,
out STORAGE_DEVICE_DESCRIPTOR OutBuffer,
int nOutBufferSize,
out int pBytesReturned,
IntPtr Overlapped
); [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
static extern unsafe int CreateFile
(
string FileName, // file name
uint DesiredAccess, // access mode
uint ShareMode, // share mode
uint SecurityAttributes, // Security Attributes
uint CreationDisposition, // how to create
uint FlagsAndAttributes, // file attributes
int hTemplateFile // handle to template file
); static void Main(string[] args)
{
var query = new STORAGE_PROPERTY_QUERY {};
var qsize = Marshal.SizeOf(query);
var header = new STORAGE_DESCRIPTOR_HEADER { };
var hsize = Marshal.SizeOf(header);
var descriptor = new STORAGE_DEVICE_DESCRIPTOR { };
var rsize = Marshal.SizeOf(descriptor);
int written; var hDev = CreateFile("\\\\.\\H:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, ref query, qsize, out header, hsize, out written, IntPtr.Zero);
DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, ref query, qsize, out descriptor, header.Size, out written, IntPtr.Zero); IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(descriptor));
Marshal.StructureToPtr(descriptor, intptr, true);
var productId = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.ProductIdOffset));
var vendorId = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.VendorIdOffset));
var productRevision = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.ProductRevisionOffset));
var serialnumver = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.SerialNumberOffset)); //Console.WriteLine(Convert.ToUInt32(EIOControlCode.StorageQueryProperty)); Console.WriteLine();
Console.WriteLine(" Version: " + descriptor.Version);
Console.WriteLine(" Size: " + descriptor.Size);
Console.WriteLine(" DeviceType: " + descriptor.DeviceType);
Console.WriteLine(" DeviceTypeModifier: " + descriptor.DeviceTypeModifier);
Console.WriteLine(" RemovableMedia: " + descriptor.RemovableMedia);
Console.WriteLine(" CommandQueueing: " + descriptor.CommandQueueing);
Console.WriteLine(" Vendor Id: " + vendorId);
Console.WriteLine(" productId: " + productId);
Console.WriteLine(" productRevision: " + productRevision);
Console.WriteLine(" SerialNumber: " + serialnumver);
Console.WriteLine(" BusType: " + descriptor.BusType); Console.ReadLine();
} }
}
参考链接
http://www.pinvoke.net/default.aspx/Structures/STORAGE_DEVICE_DESCRIPTOR.html
https://stackoverflow.com/questions/17268889/pinvoke-deviceiocontrol-parameters
指定盘符获取u盘PID、VID、序列号等信息的更多相关文章
- C#通过盘符获取剩余空间
public static long GetHardDiskSpace(string str_HardDiskName) { ; str_HardDiskName = str_HardDiskName ...
- 学习1__STM32--FatFS之逻辑盘符与物理盘符
FatFS源代码中的函数逻辑关系 第一 调用函数 f_mount() result = f_mount(&fs, FS_VOLUME_NAND, ); /* Mount a logical d ...
- 外网远程顶级域名连接群晖的WebDAV文件服务映射盘符
外网远程顶级域名连接群晖的WebDAV文件服务映射盘符 https://www.cnblogs.com/delphixx/p/11846546.html 电子文件管理规范 1.手机拍照截屏 ...
- Win10 隐藏盘符
1.隐藏盘符 打开磁盘管理 -> 对要隐藏的盘符单击右键 -> 更改驱动器号和路径 -> 删除. 打开资源管理,已经看不到该盘符,该盘符已被隐藏.只是隐藏,该盘符上的数据仍然还在. ...
- REM 根据卷标搜索随身固态U盘的盘符.BAT
REM 根据卷标搜索随身固态U盘的盘符.BAT@echo offfor /f "tokens=2 delims==" %%a in ('wmic logicaldisk where ...
- 打开随身U盘_办公专用盘 2019年11月29日
;;; ; 打开随身U盘_办公专用盘 2019年11月29日 ; https://www.autoahk.com/?p=16553; https://www.cnblogs.com/delphixx/ ...
- 批处理bat命令--获取当前盘符和当前目录和上级目录
批处理bat命令--获取当前盘符和当前目录和上级目录 批处理命令获取当前盘符和当前目录%~d0 是当前盘符%cd% 是当前目录可以用echo %cd%进行打印测试 以下例子是命令行编译Visual S ...
- java web实现读取指定盘符下的图像(二)
之前写了一篇文章是关于如何读取指定盘符下的图片,虽然功能可以实现,但是使用的是I/O流的方式,效率不高.现在发现还有一个更好的办法,使用也更加的方便. 我们知道,当我们的图片是放在tomcat下web ...
- NSIS:获取硬盘中容量最大的分区盘符
原文 NSIS:获取硬盘中容量最大的分区盘符 我们在安装一些在线视频软件比如迅雷看看时,会发现他们的安装程序会自动判断当前系统中容量最大的分区,以便在其中创建数据缓冲下载的文件夹,这种功能如果实现呢, ...
随机推荐
- Codeforces1303C. Perfect Keyboard
本题可以转换成图论来做,每两个相邻点连一条边,然后统计每一个点的degree,如果>=2说明有一个点要相邻三个点,不满足题意,然后找出每个degree<2的点,这些点可以作为一段的起点,然 ...
- redis介绍及搭建
redis介绍 Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed(以写入磁盘的方式进行同步,实现持久化)的功能,跟传统意义上的 ...
- 5.Nginx
1.Nginx 安装 (1) 安装gcc (yum install gcc) 备注:可以输入gcc -v 查询版本信息,看系统是否自带安装 (2) 安装pcre (yum install pcre-d ...
- Intend之Date的几个功能
封装为一个方法 1.跳转到拨号页面 //跳转到拨号页面的方法 protected void takeCall(String info){ Intent intent=new Intent(); int ...
- 【Linux shell】 while read line
循环中的重定向或许你应该在其他脚本中见过下面的这种写法:while read linedo …done < file刚开始看到这种结构时,很难理解< file是如何与循环配合在一起工作的. ...
- java学习-初级入门-面向对象⑤-类与对象-类与对象的定义和使用3
这次我们要做一个日期类Date类 主要目的是 1. 熟悉-->构造不同参数的函数 2.善于利用已有的函数!! 题目要求: Date类要求 可设定年月日 可转换为字符串,并可指定分隔符, ...
- Django3.0中向后不兼容的更改
3.0中向后不兼容的更改 数据库后端API 本节描述了第三方数据库后端中可能需要的更改. 现在的第二个参数DatabaseIntrospection.get_geometry_type()是行描述,而 ...
- SSM-文件上传
因为开发环境和线上环境系统不一样,所以需要区别环境 config.java 可以判断系统进行自动化的区别,我是手动去切换注释的 public class config { //public stati ...
- luogu P3358 最长k可重区间集问题
网络流建图好难,这题居然是网络流(雾,一般分析来说,有限制的情况最大流情况可以拆点通过capacity来限制,比如只使用一次,把一个点拆成入点出点,capacity为1即可,这题是限制最大k重复,可以 ...
- Linux之文件传输
本文借鉴<Linux命令大全> 1. bye命令 功能:终端FTP连线并结束程序 语法:bye 补充:在ftp模式下,输入bye即可中断目前的连线作业,并结束ftp的执行. 2. ftp命 ...