最近学习scsi和DeviceIoControl,下载了微软WDK一些例子,以下代码精简自Windows-driver-samples-masterstorage oolssptisrcspti.c ,略有修改。
#include <windows.h> #include <stdio.h> #include <strsafe.h> #include <winioctl.h> void QueryPropertyForDevice(HANDLE); void PrintDeviceDescriptor(PSTORAGE_DEVICE_DESCRIPTOR); int main(int argc, char *argv[]) { if (argc != 2) { printf("Usage: %s ", argv[0] ); printf("Examples: "); printf(" %s g: (PrintDeviceDescriptor) ", 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 ", 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(" ***** STORAGE DEVICE DESCRIPTOR DATA *****"); printf(" Version: %08x " " TotalSize: %08x " " DeviceType: %08x " " DeviceTypeModifier: %08x " " RemovableMedia: %s " " CommandQueueing: %s " " Vendor Id: %s " " Product Id: %s " " Product Revision: %s " " Serial Number: %s " " Bus Type: %s ", DeviceDescriptor->Version, DeviceDescriptor->Size, DeviceDescriptor->DeviceType, DeviceDescriptor->DeviceTypeModifier, BOOLEAN_TO_STRING(DeviceDescriptor->RemovableMedia), BOOLEAN_TO_STRING(DeviceDescriptor->CommandQueueing), vendorId, productId, productRevision, serialNumber, busType); printf(" "); }
参考链接:
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