指定盘符获取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:获取硬盘中容量最大的分区盘符 我们在安装一些在线视频软件比如迅雷看看时,会发现他们的安装程序会自动判断当前系统中容量最大的分区,以便在其中创建数据缓冲下载的文件夹,这种功能如果实现呢, ...
随机推荐
- Eclipse java SE版本解决无法新建web项目问题
最近工作要涉及web开发,之前下载的java SE (我的是indigo) 版本默认无法新建web项目,也就是找不到Dynamic Web ,在网上看了些解决办法,最终却是解决了问题,说到底就是安装一 ...
- h5 穿透滚动
引子 h5 页面有弹窗浮层时,浮层之下若产生了滚动,滑动浮层时会让其产生滚动.这是示例页面,移动端访问如下: Origin My GitHub 原因 找到的信息里面有两种说法: 使用了 -webkit ...
- Netty实现原理和使用
参考: https://www.jdon.com/concurrent/netty.html Java NIO原理和使用 参考:https://www.jdon.com/concurrent/nio% ...
- Prometheus组件
Prometheus组件 上一小节,通过部署Node Exporter我们成功的获取到了当前主机的资源使用情况.接下来我们将从Prometheus的架构角度详细介绍Prometheus生态中的各个组件 ...
- Ubuntu的妥协将支持精选的32位应用
据外媒Tom's hardware,Ubuntu开发人员Canonical在早先的时候宣布Ubuntu 19.10将不再更新32位软件包和应用程序,引来了诸多应用开发者的不满.现在,Ubuntu方面宣 ...
- Mac OS 下升级gcc遇到的坑
为了升级gcc,原来版本是4.8,想升级到4.9,因为在Mac上安装cocoNLP一直出错,想试试看是不是gcc版本太低的原因,因此在此想要升级到4.9 经历了三个问题: - brew update太 ...
- 分享Linux CentOS7 VMware 系统目录结构、 ls命令 、文件类型、alias命令——笔记
一. 系统目录结构 生成目录树结构: tree -a 显示所有 tree -d 仅显示目录 tree -L n n代表数字..表示要显示几层... tree -f 显示完整路径.. yum insta ...
- Maven:sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
还是记录使用 maven 时遇到的问题. 一.maven报错 maven package 进行打包时出现了以下报错: Non-resolvable parent POM for com.wpbxin: ...
- ios 获取当前系统时间
1. NSDate + NSDateFormatter NSDate *date = [NSDate date]; NSDateFormatter *format = [[NSDateFormatte ...
- HDU5943 Kingdom of Obsession 题解
题意 有 \(n\) 个数 \(s+1\ldots s+n\),求是否能将这 \(n\) 个数放到 \(1\ldots n\) 上,且当令原数为 \(x\),放到 \(y\) 位置时有 \(x \mo ...