最近学习scsi和DeviceIoControl,下载了微软WDK一些例子,以下代码精简自Windows-driver-samples-master\storage\tools\spti\src\spti.c ,略有修改。

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <strsafe.h>
  4.  
  5. void QueryPropertyForDevice(HANDLE);
  6. void PrintDeviceDescriptor(PSTORAGE_DEVICE_DESCRIPTOR);
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10. if (argc != 2) {
  11. printf("Usage: %s \n", argv[0] );
  12. printf("Examples:\n");
  13. printf(" %s g: (PrintDeviceDescriptor)\n", argv[0]);
  14. }
  15.  
  16. char filepath[7];
  17. StringCbPrintf(filepath, sizeof(filepath), "\\\\.\\%s", argv[1]);
  18.  
  19. HANDLE hDevice = CreateFile(filepath,
  20. GENERIC_READ,
  21. FILE_SHARE_READ,
  22. NULL,
  23. OPEN_EXISTING,
  24. 0,
  25. NULL);
  26.  
  27. if (hDevice == INVALID_HANDLE_VALUE) {
  28. unsigned long errorCode = GetLastError();
  29. printf("Error opening %s. Error: %d\n",
  30. filepath, errorCode);
  31. return errorCode;
  32. }
  33.  
  34. QueryPropertyForDevice(hDevice);
  35. CloseHandle(hDevice);
  36.  
  37. return 0;
  38. }
  39.  
  40. #define BOOLEAN_TO_STRING(_b_) \
  41. ( (_b_) ? "True" : "False" )
  42.  
  43. LPCSTR BusTypeStrings[] = {
  44. "Unknown",
  45. "Scsi",
  46. "Atapi",
  47. "Ata",
  48. "1394",
  49. "Ssa",
  50. "Fibre",
  51. "Usb",
  52. "RAID",
  53. "Not Defined",
  54. };
  55. #define NUMBER_OF_BUS_TYPE_STRINGS (sizeof(BusTypeStrings)/sizeof(BusTypeStrings[0]))
  56.  
  57. void QueryPropertyForDevice(HANDLE hDevice)
  58. {
  59. bool result;
  60. DWORD readed;
  61.  
  62. STORAGE_DESCRIPTOR_HEADER *DeviceDescriptorHeader;
  63. STORAGE_DEVICE_DESCRIPTOR *DeviceDescriptor;
  64. DWORD devDescLength;
  65. STORAGE_PROPERTY_QUERY query;
  66.  
  67. query.PropertyId = StorageDeviceProperty;
  68. query.QueryType = PropertyStandardQuery;
  69.  
  70. DeviceDescriptorHeader = (STORAGE_DESCRIPTOR_HEADER *) malloc( sizeof(STORAGE_DESCRIPTOR_HEADER) );
  71.  
  72. result = DeviceIoControl( hDevice, // device to be queried
  73. IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform
  74. &query, sizeof query, // no input buffer
  75. DeviceDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), // output buffer
  76. &readed, // # bytes returned
  77. NULL ); // synchronous I/O
  78.  
  79. devDescLength = DeviceDescriptorHeader->Size;
  80. DeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR *) malloc( devDescLength );
  81.  
  82. result = DeviceIoControl( hDevice, // device to be queried
  83. IOCTL_STORAGE_QUERY_PROPERTY, // operation to perform
  84. &query, sizeof query, // no input buffer
  85. DeviceDescriptor, devDescLength, // output buffer
  86. &readed, // # bytes returned
  87. NULL ); // synchronous I/O
  88.  
  89. PrintDeviceDescriptor(DeviceDescriptor);
  90.  
  91. free( DeviceDescriptorHeader );
  92. free( DeviceDescriptor );
  93. }
  94.  
  95. void PrintDeviceDescriptor(PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor)
  96. {
  97. LPCSTR vendorId = "";
  98. LPCSTR productId = "";
  99. LPCSTR productRevision = "";
  100. LPCSTR serialNumber = "";
  101. LPCSTR busType;
  102.  
  103. if ((ULONG)DeviceDescriptor->BusType < NUMBER_OF_BUS_TYPE_STRINGS) {
  104. busType = BusTypeStrings[DeviceDescriptor->BusType];
  105. } else {
  106. busType = BusTypeStrings[NUMBER_OF_BUS_TYPE_STRINGS-1];
  107. }
  108.  
  109. if ((DeviceDescriptor->ProductIdOffset != 0) &&
  110. (DeviceDescriptor->ProductIdOffset != -1)) {
  111. productId = (LPCSTR)(DeviceDescriptor);
  112. productId += (ULONG_PTR)DeviceDescriptor->ProductIdOffset;
  113. }
  114. if ((DeviceDescriptor->VendorIdOffset != 0) &&
  115. (DeviceDescriptor->VendorIdOffset != -1)) {
  116. vendorId = (LPCSTR)(DeviceDescriptor);
  117. vendorId += (ULONG_PTR)DeviceDescriptor->VendorIdOffset;
  118. }
  119. if ((DeviceDescriptor->ProductRevisionOffset != 0) &&
  120. (DeviceDescriptor->ProductRevisionOffset != -1)) {
  121. productRevision = (LPCSTR)(DeviceDescriptor);
  122. productRevision += (ULONG_PTR)DeviceDescriptor->ProductRevisionOffset;
  123. }
  124. if ((DeviceDescriptor->SerialNumberOffset != 0) &&
  125. (DeviceDescriptor->SerialNumberOffset != -1)) {
  126. serialNumber = (LPCSTR)(DeviceDescriptor);
  127. serialNumber += (ULONG_PTR)DeviceDescriptor->SerialNumberOffset;
  128. }
  129.  
  130. puts("\n ***** STORAGE DEVICE DESCRIPTOR DATA *****");
  131. printf(" Version: %08x\n"
  132. " TotalSize: %08x\n"
  133. " DeviceType: %08x\n"
  134. " DeviceTypeModifier: %08x\n"
  135. " RemovableMedia: %s\n"
  136. " CommandQueueing: %s\n"
  137. " Vendor Id: %s\n"
  138. " Product Id: %s\n"
  139. " Product Revision: %s\n"
  140. " Serial Number: %s\n"
  141. " Bus Type: %s\n",
  142. DeviceDescriptor->Version,
  143. DeviceDescriptor->Size,
  144. DeviceDescriptor->DeviceType,
  145. DeviceDescriptor->DeviceTypeModifier,
  146. BOOLEAN_TO_STRING(DeviceDescriptor->RemovableMedia),
  147. BOOLEAN_TO_STRING(DeviceDescriptor->CommandQueueing),
  148. vendorId,
  149. productId,
  150. productRevision,
  151. serialNumber,
  152. busType);
  153.  
  154. printf("\n");
  155. }

参考链接:

https://www.cnblogs.com/shangdawei/p/3164005.html

c#参考

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Runtime.InteropServices;
  6. using Microsoft.Win32.SafeHandles;
  7.  
  8. namespace ConsoleApplication2
  9. {
  10. class Program
  11. {
  12. const uint GENERIC_READ = 0x80000000;
  13. const uint GENERIC_WRITE = 0x40000000;
  14. const uint FILE_SHARE_READ = 1;
  15. const uint FILE_SHARE_WRITE = 2;
  16. const uint OPEN_EXISTING = 3;
  17. const int IOCTL_STORAGE_QUERY_PROPERTY = 2954240;
  18.  
  19. public enum STORAGE_PROPERTY_ID
  20. {
  21. StorageDeviceProperty = 0,
  22. StorageAdapterProperty = 1,
  23. StorageDeviceIdProperty = 2,
  24. StorageDeviceUniqueIdProperty = 3,
  25. StorageDeviceWriteCacheProperty = 4,
  26. StorageMiniportProperty = 5,
  27. StorageAccessAlignmentProperty = 6,
  28. StorageDeviceSeekPenaltyProperty = 7,
  29. StorageDeviceTrimProperty = 8,
  30. StorageDeviceWriteAggregationProperty = 9,
  31. StorageDeviceDeviceTelemetryProperty = 10, // 0xA
  32. StorageDeviceLBProvisioningProperty = 11, // 0xB
  33. StorageDevicePowerProperty = 12, // 0xC
  34. StorageDeviceCopyOffloadProperty = 13, // 0xD
  35. StorageDeviceResiliencyProperty = 14 // 0xE
  36. }
  37.  
  38. public enum STORAGE_QUERY_TYPE
  39. {
  40. PropertyStandardQuery = 0,
  41. PropertyExistsQuery = 1,
  42. PropertyMaskQuery = 2,
  43. PropertyQueryMaxDefined = 3
  44. }
  45.  
  46. [StructLayout(LayoutKind.Sequential)]
  47. public struct STORAGE_PROPERTY_QUERY
  48. {
  49. public STORAGE_PROPERTY_ID PropertyId;
  50. public STORAGE_QUERY_TYPE QueryType;
  51. public byte[] AdditionalParameters;
  52. }
  53.  
  54. public enum STORAGE_BUS_TYPE
  55. {
  56. BusTypeUnknown = 0x00,
  57. BusTypeScsi = 0x1,
  58. BusTypeAtapi = 0x2,
  59. BusTypeAta = 0x3,
  60. BusType1394 = 0x4,
  61. BusTypeSsa = 0x5,
  62. BusTypeFibre = 0x6,
  63. BusTypeUsb = 0x7,
  64. BusTypeRAID = 0x8,
  65. BusTypeiScsi = 0x9,
  66. BusTypeSas = 0xA,
  67. BusTypeSata = 0xB,
  68. BusTypeSd = 0xC,
  69. BusTypeMmc = 0xD,
  70. BusTypeVirtual = 0xE,
  71. BusTypeFileBackedVirtual = 0xF,
  72. BusTypeMax = 0x10,
  73. BusTypeMaxReserved = 0x7F
  74. }
  75.  
  76. public struct STORAGE_DESCRIPTOR_HEADER
  77. {
  78. public int Version;
  79. public int Size;
  80. }
  81.  
  82. public struct STORAGE_DEVICE_DESCRIPTOR
  83. {
  84. public uint Version;
  85. public uint Size;
  86. public byte DeviceType;
  87. public byte DeviceTypeModifier;
  88. [MarshalAs(UnmanagedType.U1)]
  89. public bool RemovableMedia;
  90. [MarshalAs(UnmanagedType.U1)]
  91. public bool CommandQueueing;
  92. public uint VendorIdOffset;
  93. public uint ProductIdOffset;
  94. public uint ProductRevisionOffset;
  95. public uint SerialNumberOffset;
  96. public STORAGE_BUS_TYPE BusType;
  97. public uint RawPropertiesLength;
  98. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
  99. public byte[] RawDeviceProperties;
  100. }
  101.  
  102. [DllImport("Kernel32.dll", SetLastError = true)]
  103. public static extern bool DeviceIoControl(
  104. SafeFileHandle hDevice,
  105. int IoControlCode,
  106. byte[] InBuffer,
  107. int nInBufferSize,
  108. byte[] OutBuffer,
  109. int nOutBufferSize,
  110. out int pBytesReturned,
  111. IntPtr Overlapped
  112. );
  113.  
  114. [DllImport("Kernel32.dll", SetLastError = true)]
  115. public static extern bool DeviceIoControl(
  116. int hDevice,
  117. int IoControlCode,
  118. ref STORAGE_PROPERTY_QUERY InBuffer,
  119. int nInBufferSize,
  120. out STORAGE_DESCRIPTOR_HEADER OutBuffer,
  121. int nOutBufferSize,
  122. out int pBytesReturned,
  123. IntPtr Overlapped
  124. );
  125.  
  126. [DllImport("Kernel32.dll", SetLastError = true)]
  127. public static extern bool DeviceIoControl(
  128. int hDevice,
  129. int IoControlCode,
  130. ref STORAGE_PROPERTY_QUERY InBuffer,
  131. int nInBufferSize,
  132. out STORAGE_DEVICE_DESCRIPTOR OutBuffer,
  133. int nOutBufferSize,
  134. out int pBytesReturned,
  135. IntPtr Overlapped
  136. );
  137.  
  138. [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
  139. static extern unsafe int CreateFile
  140. (
  141. string FileName, // file name
  142. uint DesiredAccess, // access mode
  143. uint ShareMode, // share mode
  144. uint SecurityAttributes, // Security Attributes
  145. uint CreationDisposition, // how to create
  146. uint FlagsAndAttributes, // file attributes
  147. int hTemplateFile // handle to template file
  148. );
  149.  
  150. static void Main(string[] args)
  151. {
  152. var query = new STORAGE_PROPERTY_QUERY {};
  153. var qsize = Marshal.SizeOf(query);
  154. var header = new STORAGE_DESCRIPTOR_HEADER { };
  155. var hsize = Marshal.SizeOf(header);
  156. var descriptor = new STORAGE_DEVICE_DESCRIPTOR { };
  157. var rsize = Marshal.SizeOf(descriptor);
  158. int written;
  159.  
  160. var hDev = CreateFile("\\\\.\\H:", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
  161.  
  162. DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, ref query, qsize, out header, hsize, out written, IntPtr.Zero);
  163. DeviceIoControl(hDev, IOCTL_STORAGE_QUERY_PROPERTY, ref query, qsize, out descriptor, header.Size, out written, IntPtr.Zero);
  164.  
  165. IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(descriptor));
  166. Marshal.StructureToPtr(descriptor, intptr, true);
  167. var productId = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.ProductIdOffset));
  168. var vendorId = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.VendorIdOffset));
  169. var productRevision = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.ProductRevisionOffset));
  170. var serialnumver = Marshal.PtrToStringAnsi(new IntPtr((long)intptr + descriptor.SerialNumberOffset));
  171.  
  172. //Console.WriteLine(Convert.ToUInt32(EIOControlCode.StorageQueryProperty));
  173.  
  174. Console.WriteLine();
  175. Console.WriteLine(" Version: " + descriptor.Version);
  176. Console.WriteLine(" Size: " + descriptor.Size);
  177. Console.WriteLine(" DeviceType: " + descriptor.DeviceType);
  178. Console.WriteLine(" DeviceTypeModifier: " + descriptor.DeviceTypeModifier);
  179. Console.WriteLine(" RemovableMedia: " + descriptor.RemovableMedia);
  180. Console.WriteLine(" CommandQueueing: " + descriptor.CommandQueueing);
  181. Console.WriteLine(" Vendor Id: " + vendorId);
  182. Console.WriteLine(" productId: " + productId);
  183. Console.WriteLine(" productRevision: " + productRevision);
  184. Console.WriteLine(" SerialNumber: " + serialnumver);
  185. Console.WriteLine(" BusType: " + descriptor.BusType);
  186.  
  187. Console.ReadLine();
  188. }
  189.  
  190. }
  191. }

参考链接
http://www.pinvoke.net/default.aspx/Structures/STORAGE_DEVICE_DESCRIPTOR.html

https://stackoverflow.com/questions/17268889/pinvoke-deviceiocontrol-parameters

指定盘符获取u盘PID、VID、序列号等信息的更多相关文章

  1. C#通过盘符获取剩余空间

    public static long GetHardDiskSpace(string str_HardDiskName) { ; str_HardDiskName = str_HardDiskName ...

  2. 学习1__STM32--FatFS之逻辑盘符与物理盘符

    FatFS源代码中的函数逻辑关系 第一 调用函数 f_mount() result = f_mount(&fs, FS_VOLUME_NAND, ); /* Mount a logical d ...

  3. 外网远程顶级域名连接群晖的WebDAV文件服务映射盘符

       外网远程顶级域名连接群晖的WebDAV文件服务映射盘符 https://www.cnblogs.com/delphixx/p/11846546.html 电子文件管理规范   1.手机拍照截屏 ...

  4. Win10 隐藏盘符

    1.隐藏盘符 打开磁盘管理 -> 对要隐藏的盘符单击右键 -> 更改驱动器号和路径 -> 删除. 打开资源管理,已经看不到该盘符,该盘符已被隐藏.只是隐藏,该盘符上的数据仍然还在. ...

  5. REM 根据卷标搜索随身固态U盘的盘符.BAT

    REM 根据卷标搜索随身固态U盘的盘符.BAT@echo offfor /f "tokens=2 delims==" %%a in ('wmic logicaldisk where ...

  6. 打开随身U盘_办公专用盘 2019年11月29日

    ;;; ; 打开随身U盘_办公专用盘 2019年11月29日 ; https://www.autoahk.com/?p=16553; https://www.cnblogs.com/delphixx/ ...

  7. 批处理bat命令--获取当前盘符和当前目录和上级目录

    批处理bat命令--获取当前盘符和当前目录和上级目录 批处理命令获取当前盘符和当前目录%~d0 是当前盘符%cd% 是当前目录可以用echo %cd%进行打印测试 以下例子是命令行编译Visual S ...

  8. java web实现读取指定盘符下的图像(二)

    之前写了一篇文章是关于如何读取指定盘符下的图片,虽然功能可以实现,但是使用的是I/O流的方式,效率不高.现在发现还有一个更好的办法,使用也更加的方便. 我们知道,当我们的图片是放在tomcat下web ...

  9. NSIS:获取硬盘中容量最大的分区盘符

    原文 NSIS:获取硬盘中容量最大的分区盘符 我们在安装一些在线视频软件比如迅雷看看时,会发现他们的安装程序会自动判断当前系统中容量最大的分区,以便在其中创建数据缓冲下载的文件夹,这种功能如果实现呢, ...

随机推荐

  1. JavaScript一个简单的图片切换布局

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. java打包成可执行的jar或者exe的详细步骤

    Java程序完成以后,对于Windows操作系统,习惯总是想双击某个exe文件就可以直接运行程序,现我将一步一步的实现该过程.最终结果是:不用安装JRE环境,不用安装数据库,直接双击一个exe文件,就 ...

  3. 网站seo优化教你如何引蜘蛛爬行网站

    1. 网站和页面的权重 这个是咱们都知道的,网站和页面的权重越高的话,蜘蛛一般会匍匐的越深,被蜘蛛录入的页面也更多一些.可是一个新的网站,权重到达1的话是相对简单的,可是假如想要把权重再网上添加则会越 ...

  4. Linux-使用之vim出现的问题

    参考来源: https://stackoverflow.com/questions/47667119/ycm-error-the-ycmd-server-shut-down-restart-wit-t ...

  5. java并发AtomicReference

    java并发AtomicReference AtomicReference的作用 已经介绍过AtomicInteger,AtomicIntegerArray,AtomicReference是针对对象的 ...

  6. L1和L2范数理解

    参考:https://www.jianshu.com/p/4bad38fe07e6

  7. Day3-G - Task HDU4864

    Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this ...

  8. php 实现店铺装修4

    /** * @title 发布装修的店铺 * @example FlagShipShopDecorate.fabu? 调试参数:{"username":"17721355 ...

  9. USACO[19-20]Dec银组题解

    1,MooBuzz 这题其实是道数学题. 我们先找找符合要求的数:1,2,4,7,8,11,13,14…… 我们发现再往后找都是这8个数中的一个加15k如:16……19……29…… 找规律发现k=n/ ...

  10. call 和 apply 用法

    ECMAScript规范中,所有函数都包含这两个方法,并且两个方法的使用基本一致,都是用于改变函数的作用域,即改变函数体内 this 指向.不同的是 call 方法的第二个参数可以接收任意个参数,以逗 ...