指定盘符获取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:获取硬盘中容量最大的分区盘符 我们在安装一些在线视频软件比如迅雷看看时,会发现他们的安装程序会自动判断当前系统中容量最大的分区,以便在其中创建数据缓冲下载的文件夹,这种功能如果实现呢, ...
随机推荐
- 尝试实现一个简单的C语言string类型
用过`C++/Java/python/matlab/JS`等语言后,发现都能很轻松的使用string类型,而C只能这样: char str[] = "hello world"; o ...
- linux搭建mysql时ifconfig命令无法使用问题
刚搭建好的Centos 最小安装模式是没有ifconfig命令的.改变步骤:一:使用语句:cd /etc/sysconfig/network-scripts/二:使用语句vi ifcfg-eno167 ...
- Day1-C-CF-1144A
简述:给你一串字符,判断是否由连续字母构成且每个字符只出现一次 思路:用set直接储存,判断size和初末位置字母与size的关系即可 代码: #include<iostream> #in ...
- C++11并发编程1------并发介绍
也许有人会觉得多线程和并发难用,复杂,还会让代码出现各种各样的问题,不过,其实它是一个强有力的工具,能让程序充分利用硬件资源,让程序运行得更快. 何谓并发: 两个或更多独立得活动同时发生.计算机中就是 ...
- eclipse中使用maven创建项目JDK版本默认是1.5
1. 修改maven的settings.xml文件. 添加以下行,jdk版本改为自己需要的版本: <profile> <id>jdk-1.7</id> <ac ...
- 首款中文渗透测试专用Linux系统—MagicBox
1. MagicBox的介绍 首款中文渗透测试专用Linux系统——MagicBox即将问世,中文名称:“魔方系统”,开发代号:Genesis.第一版本发布时间计划为2012年12月5日 这是 ...
- Android 隐藏手机号中间四位和隐藏邮箱地址中间四位
/** * 手机号用****号隐藏中间数字 * * @param phone * @return */public static String settingphone(String phone) { ...
- android 桌面透明
目录(?)[-] public void setWallpaperOffsetSteps float xStep float yStep Parameters public void setWal ...
- 《N诺机试指南》(一)数组妙用
题目A: 大家思路有可能是这样: 将输入数据全部存储到一个数组里,然后可以冒泡排序一波,从小到大排序 那么怎么找到重复次数呢:我是这样想的,新定义数组b,原数组a,首先b[0] = a[0],定义指针 ...
- [Verilog] indexed part-select +:
That syntax is called an indexed part-select. The first term is the bit offset and the second term ...