第一种方法:
通过WMI来读取硬盘的ID.代码如下:
1 public string DiskDrive
2 {//硬盘厂商
3 get
4 {
5 string strDiskDrive;
6 ManagementObjectSearcher opSearch;
7 ManagementObjectCollection mocSystem;
8 strDiskDrive="";
9 try
10 {
11 opSearch = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
12 mocSystem=opSearch.Get();
13 foreach( ManagementObject opInfo in mocSystem)
14 {
15 strDiskDrive+= opInfo["PNPDeviceID"].ToString().Trim() ;
16 }
17 }
18 catch
19 {
20 //TO DO:添加异常处理
21 }
22 return strDiskDrive;
23 }
24 }
2 {//硬盘厂商
3 get
4 {
5 string strDiskDrive;
6 ManagementObjectSearcher opSearch;
7 ManagementObjectCollection mocSystem;
8 strDiskDrive="";
9 try
10 {
11 opSearch = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
12 mocSystem=opSearch.Get();
13 foreach( ManagementObject opInfo in mocSystem)
14 {
15 strDiskDrive+= opInfo["PNPDeviceID"].ToString().Trim() ;
16 }
17 }
18 catch
19 {
20 //TO DO:添加异常处理
21 }
22 return strDiskDrive;
23 }
24 }
第二种方法:
通过windowsAPI方法调用硬盘的ID.代码如下:
1 public class IDE
2 {
3 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
4 internal struct IDSECTOR
5 {
6 public ushort wGenConfig;
7 public ushort wNumCyls;
8 public ushort wReserved;
9 public ushort wNumHeads;
10 public ushort wBytesPerTrack;
11 public ushort wBytesPerSector;
12 public ushort wSectorsPerTrack;
13 [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
14 public ushort [] wVendorUnique;
15 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)]
16 public string sSerialNumber;
17 public ushort wBufferType;
18 public ushort wBufferSize;
19 public ushort wECCSize;
20 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
21 public string sFirmwareRev;
22 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)]
23 public string sModelNumber;
24 public ushort wMoreVendorUnique;
25 public ushort wDoubleWordIO;
26 public ushort wCapabilities;
27 public ushort wReserved1;
28 public ushort wPIOTiming;
29 public ushort wDMATiming;
30 public ushort wBS;
31 public ushort wNumCurrentCyls;
32 public ushort wNumCurrentHeads;
33 public ushort wNumCurrentSectorsPerTrack;
34 public uint ulCurrentSectorCapacity;
35 public ushort wMultSectorStuff;
36 public uint ulTotalAddressableSectors;
37 public ushort wSingleWordDMA;
38 public ushort wMultiWordDMA;
39 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=128 )]
40 public byte [] bReserved;
41 }
42
43 [StructLayout(LayoutKind.Sequential)]
44 internal struct DRIVERSTATUS
45 {
46 public byte bDriverError;
47 public byte bIDEStatus;
48 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 )]
49 public byte [] bReserved;
50 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 )]
51 public uint [] dwReserved;
52 }
53
54 [StructLayout(LayoutKind.Sequential)]
55 internal struct SENDCMDOUTPARAMS
56 {
57 public uint cBufferSize;
58 public DRIVERSTATUS DriverStatus;
59 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=513 )]
60 public byte [] bBuffer;
61 }
62
63 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
64 internal struct SRB_IO_CONTROL
65 {
66 public uint HeaderLength;
67 [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=8 )]
68 public string Signature;
69 public uint Timeout;
70 public uint ControlCode;
71 public uint ReturnCode;
72 public uint Length;
73 }
74
75 [StructLayout(LayoutKind.Sequential)]
76 internal struct IDEREGS
77 {
78 public byte bFeaturesReg;
79 public byte bSectorCountReg;
80 public byte bSectorNumberReg;
81 public byte bCylLowReg;
82 public byte bCylHighReg;
83 public byte bDriveHeadReg;
84 public byte bCommandReg;
85 public byte bReserved;
86 }
87
88 [StructLayout(LayoutKind.Sequential)]
89 internal struct SENDCMDINPARAMS
90 {
91 public uint cBufferSize;
92 public IDEREGS irDriveRegs;
93 public byte bDriveNumber;
94 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]
95 public byte [] bReserved;
96 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )]
97 public uint [] dwReserved;
98 public byte bBuffer;
99 }
100
101 [StructLayout(LayoutKind.Sequential)]
102 internal struct GETVERSIONOUTPARAMS
103 {
104 public byte bVersion;
105 public byte bRevision;
106 public byte bReserved;
107 public byte bIDEDeviceMap;
108 public uint fCapabilities;
109 [MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )]
110 public uint [] dwReserved; // For future use.
111 }
112
113 [DllImport("kernel32.dll")]
114 private static extern int CloseHandle(uint hObject);
115
116 [DllImport("kernel32.dll")]
117 private static extern int DeviceIoControl(uint hDevice,
118 uint dwIoControlCode,
119 ref SENDCMDINPARAMS lpInBuffer,
120 int nInBufferSize,
121 ref SENDCMDOUTPARAMS lpOutBuffer,
122 int nOutBufferSize,
123 ref uint lpbytesReturned,
124 int lpOverlapped);
125
126 [DllImport("kernel32.dll")]
127 private static extern int DeviceIoControl(uint hDevice,
128 uint dwIoControlCode,
129 int lpInBuffer,
130 int nInBufferSize,
131 ref GETVERSIONOUTPARAMS lpOutBuffer,
132 int nOutBufferSize,
133 ref uint lpbytesReturned,
134 int lpOverlapped);
135
136 [DllImport("kernel32.dll")]
137 private static extern uint CreateFile(string lpFileName,
138 uint dwDesiredAccess,
139 uint dwShareMode,
140 int lpSecurityAttributes,
141 uint dwCreationDisposition,
142 uint dwFlagsAndAttributes,
143 int hTemplateFile);
144
145 private const uint GENERIC_READ = 0x80000000;
146 private const uint GENERIC_WRITE = 0x40000000;
147 private const uint FILE_SHARE_READ = 0x00000001;
148 private const uint FILE_SHARE_WRITE = 0x00000002;
149 private const uint OPEN_EXISTING = 3;
150 private const uint INVALID_HANDLE_VALUE = 0xffffffff;
151 private const uint DFP_GET_VERSION = 0x00074080;
152 private const int IDE_ATAPI_IDENTIFY = 0xA1; // Returns ID sector for ATAPI.
153 private const int IDE_ATA_IDENTIFY = 0xEC; // Returns ID sector for ATA.
154 private const int IDENTIFY_BUFFER_SIZE = 512;
155 private const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088;
156
157 public static string Read(byte drive)
158 {
159 OperatingSystem os = Environment.OSVersion;
160 if (os.Platform != PlatformID.Win32NT) throw new NotSupportedException("仅支持WindowsNT/2000/XP");
161 //我没有NT4,请哪位大大测试一下NT4下能不能用
162 //if (os.Version.Major < 5) throw new NotSupportedException("仅支持WindowsNT/2000/XP");
163
164 string driveName = "\\\\.\\PhysicalDrive" + drive.ToString();
165 uint device = CreateFile(driveName,
166 GENERIC_READ | GENERIC_WRITE,
167 FILE_SHARE_READ | FILE_SHARE_WRITE,
168 0, OPEN_EXISTING, 0, 0);
169 if (device == INVALID_HANDLE_VALUE) return "";
170 GETVERSIONOUTPARAMS verPara = new GETVERSIONOUTPARAMS();
171 uint bytRv = 0;
172
173 if (0 != DeviceIoControl(device, DFP_GET_VERSION,
174 0, 0, ref verPara, Marshal.SizeOf(verPara),
175 ref bytRv, 0))
176 {
177 if (verPara.bIDEDeviceMap > 0)
178 {
179 byte bIDCmd = (byte)(((verPara.bIDEDeviceMap >> drive & 0x10) != 0) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY);
180 SENDCMDINPARAMS scip = new SENDCMDINPARAMS();
181 SENDCMDOUTPARAMS scop = new SENDCMDOUTPARAMS();
182
183 scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
184 scip.irDriveRegs.bFeaturesReg = 0;
185 scip.irDriveRegs.bSectorCountReg = 1;
186 scip.irDriveRegs.bCylLowReg = 0;
187 scip.irDriveRegs.bCylHighReg = 0;
188 scip.irDriveRegs.bDriveHeadReg = (byte)(0xA0 | ((drive & 1) << 4));
189 scip.irDriveRegs.bCommandReg = bIDCmd;
190 scip.bDriveNumber = drive;
191
192 if (0 != DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA,
193 ref scip, Marshal.SizeOf(scip), ref scop,
194 Marshal.SizeOf(scop), ref bytRv, 0))
195 {
196 StringBuilder s = new StringBuilder();
197 for (int i = 20; i < 40; i += 2)
198 {
199 s.Append((char)(scop.bBuffer[i+1]));
200 s.Append((char)scop.bBuffer[i]);
201 }
202 CloseHandle(device);
203 return s.ToString().Trim();
204 }
205 }
206 }
207 CloseHandle(device);
208 return "";
209 }
210 }
211
2 {
3 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
4 internal struct IDSECTOR
5 {
6 public ushort wGenConfig;
7 public ushort wNumCyls;
8 public ushort wReserved;
9 public ushort wNumHeads;
10 public ushort wBytesPerTrack;
11 public ushort wBytesPerSector;
12 public ushort wSectorsPerTrack;
13 [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
14 public ushort [] wVendorUnique;
15 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)]
16 public string sSerialNumber;
17 public ushort wBufferType;
18 public ushort wBufferSize;
19 public ushort wECCSize;
20 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
21 public string sFirmwareRev;
22 [MarshalAs(UnmanagedType.ByValTStr, SizeConst=40)]
23 public string sModelNumber;
24 public ushort wMoreVendorUnique;
25 public ushort wDoubleWordIO;
26 public ushort wCapabilities;
27 public ushort wReserved1;
28 public ushort wPIOTiming;
29 public ushort wDMATiming;
30 public ushort wBS;
31 public ushort wNumCurrentCyls;
32 public ushort wNumCurrentHeads;
33 public ushort wNumCurrentSectorsPerTrack;
34 public uint ulCurrentSectorCapacity;
35 public ushort wMultSectorStuff;
36 public uint ulTotalAddressableSectors;
37 public ushort wSingleWordDMA;
38 public ushort wMultiWordDMA;
39 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=128 )]
40 public byte [] bReserved;
41 }
42
43 [StructLayout(LayoutKind.Sequential)]
44 internal struct DRIVERSTATUS
45 {
46 public byte bDriverError;
47 public byte bIDEStatus;
48 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 )]
49 public byte [] bReserved;
50 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=2 )]
51 public uint [] dwReserved;
52 }
53
54 [StructLayout(LayoutKind.Sequential)]
55 internal struct SENDCMDOUTPARAMS
56 {
57 public uint cBufferSize;
58 public DRIVERSTATUS DriverStatus;
59 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=513 )]
60 public byte [] bBuffer;
61 }
62
63 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
64 internal struct SRB_IO_CONTROL
65 {
66 public uint HeaderLength;
67 [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=8 )]
68 public string Signature;
69 public uint Timeout;
70 public uint ControlCode;
71 public uint ReturnCode;
72 public uint Length;
73 }
74
75 [StructLayout(LayoutKind.Sequential)]
76 internal struct IDEREGS
77 {
78 public byte bFeaturesReg;
79 public byte bSectorCountReg;
80 public byte bSectorNumberReg;
81 public byte bCylLowReg;
82 public byte bCylHighReg;
83 public byte bDriveHeadReg;
84 public byte bCommandReg;
85 public byte bReserved;
86 }
87
88 [StructLayout(LayoutKind.Sequential)]
89 internal struct SENDCMDINPARAMS
90 {
91 public uint cBufferSize;
92 public IDEREGS irDriveRegs;
93 public byte bDriveNumber;
94 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]
95 public byte [] bReserved;
96 [ MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )]
97 public uint [] dwReserved;
98 public byte bBuffer;
99 }
100
101 [StructLayout(LayoutKind.Sequential)]
102 internal struct GETVERSIONOUTPARAMS
103 {
104 public byte bVersion;
105 public byte bRevision;
106 public byte bReserved;
107 public byte bIDEDeviceMap;
108 public uint fCapabilities;
109 [MarshalAs( UnmanagedType.ByValArray, SizeConst=4 )]
110 public uint [] dwReserved; // For future use.
111 }
112
113 [DllImport("kernel32.dll")]
114 private static extern int CloseHandle(uint hObject);
115
116 [DllImport("kernel32.dll")]
117 private static extern int DeviceIoControl(uint hDevice,
118 uint dwIoControlCode,
119 ref SENDCMDINPARAMS lpInBuffer,
120 int nInBufferSize,
121 ref SENDCMDOUTPARAMS lpOutBuffer,
122 int nOutBufferSize,
123 ref uint lpbytesReturned,
124 int lpOverlapped);
125
126 [DllImport("kernel32.dll")]
127 private static extern int DeviceIoControl(uint hDevice,
128 uint dwIoControlCode,
129 int lpInBuffer,
130 int nInBufferSize,
131 ref GETVERSIONOUTPARAMS lpOutBuffer,
132 int nOutBufferSize,
133 ref uint lpbytesReturned,
134 int lpOverlapped);
135
136 [DllImport("kernel32.dll")]
137 private static extern uint CreateFile(string lpFileName,
138 uint dwDesiredAccess,
139 uint dwShareMode,
140 int lpSecurityAttributes,
141 uint dwCreationDisposition,
142 uint dwFlagsAndAttributes,
143 int hTemplateFile);
144
145 private const uint GENERIC_READ = 0x80000000;
146 private const uint GENERIC_WRITE = 0x40000000;
147 private const uint FILE_SHARE_READ = 0x00000001;
148 private const uint FILE_SHARE_WRITE = 0x00000002;
149 private const uint OPEN_EXISTING = 3;
150 private const uint INVALID_HANDLE_VALUE = 0xffffffff;
151 private const uint DFP_GET_VERSION = 0x00074080;
152 private const int IDE_ATAPI_IDENTIFY = 0xA1; // Returns ID sector for ATAPI.
153 private const int IDE_ATA_IDENTIFY = 0xEC; // Returns ID sector for ATA.
154 private const int IDENTIFY_BUFFER_SIZE = 512;
155 private const uint DFP_RECEIVE_DRIVE_DATA = 0x0007c088;
156
157 public static string Read(byte drive)
158 {
159 OperatingSystem os = Environment.OSVersion;
160 if (os.Platform != PlatformID.Win32NT) throw new NotSupportedException("仅支持WindowsNT/2000/XP");
161 //我没有NT4,请哪位大大测试一下NT4下能不能用
162 //if (os.Version.Major < 5) throw new NotSupportedException("仅支持WindowsNT/2000/XP");
163
164 string driveName = "\\\\.\\PhysicalDrive" + drive.ToString();
165 uint device = CreateFile(driveName,
166 GENERIC_READ | GENERIC_WRITE,
167 FILE_SHARE_READ | FILE_SHARE_WRITE,
168 0, OPEN_EXISTING, 0, 0);
169 if (device == INVALID_HANDLE_VALUE) return "";
170 GETVERSIONOUTPARAMS verPara = new GETVERSIONOUTPARAMS();
171 uint bytRv = 0;
172
173 if (0 != DeviceIoControl(device, DFP_GET_VERSION,
174 0, 0, ref verPara, Marshal.SizeOf(verPara),
175 ref bytRv, 0))
176 {
177 if (verPara.bIDEDeviceMap > 0)
178 {
179 byte bIDCmd = (byte)(((verPara.bIDEDeviceMap >> drive & 0x10) != 0) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY);
180 SENDCMDINPARAMS scip = new SENDCMDINPARAMS();
181 SENDCMDOUTPARAMS scop = new SENDCMDOUTPARAMS();
182
183 scip.cBufferSize = IDENTIFY_BUFFER_SIZE;
184 scip.irDriveRegs.bFeaturesReg = 0;
185 scip.irDriveRegs.bSectorCountReg = 1;
186 scip.irDriveRegs.bCylLowReg = 0;
187 scip.irDriveRegs.bCylHighReg = 0;
188 scip.irDriveRegs.bDriveHeadReg = (byte)(0xA0 | ((drive & 1) << 4));
189 scip.irDriveRegs.bCommandReg = bIDCmd;
190 scip.bDriveNumber = drive;
191
192 if (0 != DeviceIoControl(device, DFP_RECEIVE_DRIVE_DATA,
193 ref scip, Marshal.SizeOf(scip), ref scop,
194 Marshal.SizeOf(scop), ref bytRv, 0))
195 {
196 StringBuilder s = new StringBuilder();
197 for (int i = 20; i < 40; i += 2)
198 {
199 s.Append((char)(scop.bBuffer[i+1]));
200 s.Append((char)scop.bBuffer[i]);
201 }
202 CloseHandle(device);
203 return s.ToString().Trim();
204 }
205 }
206 }
207 CloseHandle(device);
208 return "";
209 }
210 }
211
我自己本人认为第二种方法比较好,效率高.因此也推荐第二种方法.(个人整理使用)
转载自:http://fjwuyongzhi.cnblogs.com/archive/2005/12/20/300665.html
http://blog.csdn.net/metababy/