1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
| #pragma once
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <windows.h>
#include <winioctl.h>
#define NATIVE_CODE
#pragma warning(disable:4996)
// Required to ensure correct PhysicalDrive IOCTL structure setup
#pragma pack(1)
#define IDENTIFY_BUFFER_SIZE 512
// IOCTL commands
#define DFP_GET_VERSION 0x00074080
#define DFP_SEND_DRIVE_COMMAND 0x0007c084
#define DFP_RECEIVE_DRIVE_DATA 0x0007c088
#define FILE_DEVICE_SCSI 0x0000001b
#define IOCTL_SCSI_MINIPORT_IDENTIFY ((FILE_DEVICE_SCSI << 16) + 0x0501)
#define IOCTL_SCSI_MINIPORT 0x0004D008 // see NTDDSCSI.H for definition
#ifndef SMART_GET_VERSION
#define SMART_GET_VERSION CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
#define SMART_SEND_DRIVE_COMMAND CTL_CODE(IOCTL_DISK_BASE, 0x0021, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#endif
// GETVERSIONOUTPARAMS contains the data returned from the
// Get Driver Version function.
typedef struct _GETVERSIONOUTPARAMS
{
BYTE bVersion; // Binary driver version.
BYTE bRevision; // Binary driver revision.
BYTE bReserved; // Not used.
BYTE bIDEDeviceMap; // Bit map of IDE devices.
DWORD fCapabilities; // Bit mask of driver capabilities.
DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;
// Bits returned in the fCapabilities member of GETVERSIONOUTPARAMS
#define CAP_IDE_ID_FUNCTION 1 // ATA ID command supported
#define CAP_IDE_ATAPI_ID 2 // ATAPI ID command supported
#define CAP_IDE_EXECUTE_SMART_FUNCTION 4 // SMART commannds supported
//typedef struct _GETVERSIONINPARAMS {
// UCHAR bVersion; // Binary driver version.
// UCHAR bRevision; // Binary driver revision.
// UCHAR bReserved; // Not used.
// UCHAR bIDEDeviceMap; // Bit map of IDE devices.
// ULONG fCapabilities; // Bit mask of driver capabilities.
// ULONG dwReserved[4]; // For future use.
//} GETVERSIONINPARAMS, *PGETVERSIONINPARAMS, *LPGETVERSIONINPARAMS;
// IDE registers
//typedef struct _IDEREGS
//{
// BYTE bFeaturesReg; // Used for specifying SMART "commands".
// BYTE bSectorCountReg; // IDE sector count register
// BYTE bSectorNumberReg; // IDE sector number register
// BYTE bCylLowReg; // IDE low order cylinder value
// BYTE bCylHighReg; // IDE high order cylinder value
// BYTE bDriveHeadReg; // IDE drive/head register
// BYTE bCommandReg; // Actual IDE command.
// BYTE bReserved; // reserved for future use. Must be zero.
//} IDEREGS, *PIDEREGS, *LPIDEREGS;
// SENDCMDINPARAMS contains the input parameters for the
// Send Command to Drive function.
//typedef struct _SENDCMDINPARAMS
//{
// DWORD cBufferSize; // Buffer size in bytes
// IDEREGS irDriveRegs; // Structure with drive register values.
// BYTE bDriveNumber; // Physical drive number to send
// // command to (0,1,2,3).
// BYTE bReserved[3]; // Reserved for future expansion.
// DWORD dwReserved[4]; // For future use.
// BYTE bBuffer[1]; // Input buffer.
//} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;
// Valid values for the bCommandReg member of IDEREGS.
#define IDE_ATAPI_IDENTIFY 0xA1 // Returns ID sector for ATAPI.
#define IDE_ATA_IDENTIFY 0xEC // Returns ID sector for ATA.
// // Status returned from driver
//typedef struct _DRIVERSTATUS
//{
// BYTE bDriverError; // Error code from driver, or 0 if no error.
// BYTE bIDEStatus; // Contents of IDE Error register.
// // Only valid when bDriverError is SMART_IDE_ERROR.
// BYTE bReserved[2]; // Reserved for future expansion.
// DWORD dwReserved[2]; // Reserved for future expansion.
//} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;
//
// Structure returned by PhysicalDrive IOCTL for several commands
//typedef struct _SENDCMDOUTPARAMS
//{
// DWORD cBufferSize; // Size of bBuffer in bytes
// DRIVERSTATUS DriverStatus; // Driver status structure.
// BYTE bBuffer[1]; // Buffer of arbitrary length in which to store the data read from the // drive.
//} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;
// The following struct defines the interesting part of the IDENTIFY
// buffer:
typedef struct _IDSECTOR
{
USHORT wGenConfig;
USHORT wNumCyls;
USHORT wReserved;
USHORT wNumHeads;
USHORT wBytesPerTrack;
USHORT wBytesPerSector;
USHORT wSectorsPerTrack;
USHORT wVendorUnique[3];
CHAR sSerialNumber[20];
USHORT wBufferType;
USHORT wBufferSize;
USHORT wECCSize;
CHAR sFirmwareRev[8];
CHAR sModelNumber[40];
USHORT wMoreVendorUnique;
USHORT wDoubleWordIO;
USHORT wCapabilities;
USHORT wReserved1;
USHORT wPIOTiming;
USHORT wDMATiming;
USHORT wBS;
USHORT wNumCurrentCyls;
USHORT wNumCurrentHeads;
USHORT wNumCurrentSectorsPerTrack;
ULONG ulCurrentSectorCapacity;
USHORT wMultSectorStuff;
ULONG ulTotalAddressableSectors;
USHORT wSingleWordDMA;
USHORT wMultiWordDMA;
BYTE bReserved[128];
} IDSECTOR, *PIDSECTOR;
//
// IDENTIFY data (from ATAPI driver source)
//
#pragma pack(1)
typedef struct _IDENTIFY_DATA {
USHORT GeneralConfiguration; // 00 00
USHORT NumberOfCylinders; // 02 1
USHORT Reserved1; // 04 2
USHORT NumberOfHeads; // 06 3
USHORT UnformattedBytesPerTrack; // 08 4
USHORT UnformattedBytesPerSector; // 0A 5
USHORT SectorsPerTrack; // 0C 6
USHORT VendorUnique1[3]; // 0E 7-9
USHORT SerialNumber[10]; // 14 10-19
USHORT BufferType; // 28 20
USHORT BufferSectorSize; // 2A 21
USHORT NumberOfEccBytes; // 2C 22
USHORT FirmwareRevision[4]; // 2E 23-26
USHORT ModelNumber[20]; // 36 27-46
UCHAR MaximumBlockTransfer; // 5E 47
UCHAR VendorUnique2; // 5F
USHORT DoubleWordIo; // 60 48
USHORT Capabilities; // 62 49
USHORT Reserved2; // 64 50
UCHAR VendorUnique3; // 66 51
UCHAR PioCycleTimingMode; // 67
UCHAR VendorUnique4; // 68 52
UCHAR DmaCycleTimingMode; // 69
USHORT TranslationFieldsValid:1; // 6A 53
USHORT Reserved3:15;
USHORT NumberOfCurrentCylinders; // 6C 54
USHORT NumberOfCurrentHeads; // 6E 55
USHORT CurrentSectorsPerTrack; // 70 56
ULONG CurrentSectorCapacity; // 72 57-58
USHORT CurrentMultiSectorSetting; // 59
ULONG UserAddressableSectors; // 60-61
USHORT SingleWordDMASupport : 8; // 62
USHORT SingleWordDMAActive : 8;
USHORT MultiWordDMASupport : 8; // 63
USHORT MultiWordDMAActive : 8;
USHORT AdvancedPIOModes : 8; // 64
USHORT Reserved4 : 8;
USHORT MinimumMWXferCycleTime; // 65
USHORT RecommendedMWXferCycleTime; // 66
USHORT MinimumPIOCycleTime; // 67
USHORT MinimumPIOCycleTimeIORDY; // 68
USHORT Reserved5[2]; // 69-70
USHORT ReleaseTimeOverlapped; // 71
USHORT ReleaseTimeServiceCommand; // 72
USHORT MajorRevision; // 73
USHORT MinorRevision; // 74
USHORT Reserved6[50]; // 75-126
USHORT SpecialFunctionsEnabled; // 127
USHORT Reserved7[128]; // 128-255
} IDENTIFY_DATA, *PIDENTIFY_DATA;
#pragma pack()
typedef struct _SRB_IO_CONTROL
{
ULONG HeaderLength;
UCHAR Signature[8];
ULONG Timeout;
ULONG ControlCode;
ULONG ReturnCode;
ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#ifndef NATIVE_CODE
using namespace System;
#endif
#include <myvector.h>
typedef myvector<WORD*> LISTDATA;
/*
АОЕЪ ЕНєёёЮёрё®°Ў АЦґВ °жїм,(ґлЅГєёµе ѕИѕІґВ °жїм)
Г№№шВ° µе¶уАМєк·О АвИч№З·О ГЦјТ 2№шА» °Л»зЗПµµ·П ЗСґЩ.
ЕНєёёЮёрё®ґВ SMART_GET_VERSION µо DeviceIoControl їА·щ°Ў і*ґЩ.
2010.07.25 [url]http://krkim.net[/url]
*/
#define MAX_IDE_DRIVES 2
class DiskInfo
{
static DiskInfo* m_instance;
static char HardDriveSerialNumber [1024];
LISTDATA m_list;
public:
DiskInfo(void);
static DiskInfo& GetDiskInfo()
{
if(m_instance == NULL)
m_instance = new DiskInfo();
return *m_instance;
};
static void Destroy()
{
if(m_instance != NULL)
delete m_instance;
m_instance = NULL;
};
~DiskInfo(void);
int ReadIdeDriveAsScsiDriveInNT (void);
long LoadDiskInfo ();
int ReadPhysicalDriveInNTWithAdminRights (void);
int ReadPhysicalDriveInNTWithZeroRights (void);
int ReadDrivePortsInWin9X (void);
int ReadPhysicalDriveInNTUsingSmart (void);
unsigned __int64 DriveSize (UINT drive);
UINT GetCount (){return m_list.size();};
UINT BufferSize (UINT drive);
#ifndef NATIVE_CODE
String^ GetModelNumber (UINT drive);
String^ GetSerialNumber(UINT drive);
String^ GetRevisionNumber (UINT drive);
String^ GetDriveType (UINT drive);
#else
char* ModelNumber (UINT drive);
char* SerialNumber (UINT drive);
char* RevisionNumber (UINT drive);
char* DriveType (UINT drive);
char* VolumnSerial(UINT drive);
#endif
private:
static char * flipAndCodeBytes (char * str);
static char * ConvertToString (WORD diskdata [256], int firstIndex, int lastIndex);
static BOOL DoIDENTIFY (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
PDWORD lpcbBytesReturned);
BOOL AddIfNew(USHORT *pIdSector);
#ifndef NATIVE_CODE
String^ GetString (WORD* pdiskdata, int firstIndex, int lastIndex);
#endif
}; |