VC6 하드 드라이브 일련 번호, 모델, 개정 번호 가져오기
1. 필요한 헤더 파일이 명시되지 않음
2. 일부 정의는 제시되지 않았다
3. 코드의 개발 환경이 명확하지 않아 컴파일할 때'XXX'가 정의되지 않았습니다.
3. 추가된 코드가 어디에 쓰여 있는지 명확하지 않다
위와 같은 상황은 초보자에게는 쉽게 만날 수 있기 때문에 정리해 봤습니다.
다음은'하드디스크 일련 번호, 모델, 수정 버전 번호 읽기'의 전체 코드(win32 C++ 콘솔 프로그램), 개발 환경: win XP SP2 + VC6.0
헤더 파일:StructDef.h
// VC( VS2010) :C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinIoCtl.h
typedef struct _DRIVERSTATUS {
BYTE bDriverError; // Error code from driver,
// or 0 if no error.
BYTE bIDEError; // 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;
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;
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;
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;
typedef struct _GETVERSIONINPARAMS {
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.
} GETVERSIONINPARAMS, *PGETVERSIONINPARAMS, *LPGETVERSIONINPARAMS;
#define SMART_GET_VERSION CTL_CODE(IOCTL_DISK_BASE, 0x0020, METHOD_BUFFERED, FILE_READ_ACCESS)
#define SMART_RCV_DRIVE_DATA CTL_CODE(IOCTL_DISK_BASE, 0x0022, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define DFP_SEND_DRIVE_COMMAND SMART_SEND_DRIVE_COMMAND
#define GETVERSIONOUTPARAMS GETVERSIONINPARAMS
#define DFP_RCV_DRIVE_DATA SMART_RCV_DRIVE_DATA
#define DFP_GET_VERSION SMART_GET_VERSION
#define IDENTIFY_BUFFER_SIZE 512
마스터: m.cpp
/*
:VC6 、 、
*/
#include <iostream>
#include <windows.h>
#include <winioctl.h>
#include "Struct_Def.h"
using namespace std;
const WORD IDE_ATAPI_IDENTIFY = 0xA1; // ATAPI
const WORD IDE_ATA_IDENTIFY = 0xEC; // ATA
const int MAX_IDE_DRIVES = 1; // IDE
string Trim(string str) // cut off leading and tailing blanks
{
string::size_type pos = str.find_last_not_of(' ');
if(pos != string::npos)
{
str.erase(pos + 1);
pos = str.find_first_not_of(' ');
if(pos != string::npos)
str.erase(0, pos);
}
else
str.erase(str.begin(), str.end());
return str;
}
// fetch characters what we need from DiskData[FirstIndex ... LastIndex]
string __fastcall ConvertToString(DWORD DiskData[256], int FirstIndex, int LastIndex)
{
int i = 0;
char ResBuf[1024] = {0};
for(char *p = (char*)(DiskData + FirstIndex); p <= (char*)(DiskData + LastIndex); p += sizeof(DiskData))
{
ResBuf[i++] = *(p+1);
ResBuf[i++] = *p;
}
return Trim(ResBuf); // cut off leading and tailing blanks
}
BOOL __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, byte bIDCmd, byte bDriveNum, PDWORD lpcbBytesReturned)
{
// Set up data structures for IDENTIFY command.
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
pSCIP->irDriveRegs.bFeaturesReg = 0;
pSCIP->irDriveRegs.bSectorCountReg = 1;
pSCIP->irDriveRegs.bSectorNumberReg = 1;
pSCIP->irDriveRegs.bCylLowReg = 0;
pSCIP->irDriveRegs.bCylHighReg = 0;
//Compute the drive number.( )
pSCIP->irDriveRegs.bDriveHeadReg = (bDriveNum & 1) ? 0xB0 : 0xA0;
// The command can either be IDE identify or ATAPI identify.
pSCIP->irDriveRegs.bCommandReg = bIDCmd;
pSCIP->bDriveNumber = bDriveNum;
pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA, (LPVOID)pSCIP, sizeof(SENDCMDINPARAMS) - 1,
(LPVOID)pSCOP, sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, lpcbBytesReturned, NULL);
}
// 、 、
void __fastcall ReadPhysicalDriveOnNT()
{
//IDENTIFY_BUFFER_SIZE = 512
byte IdOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
char serialNo[21], modelNo[21], revisionNo[21];
for(int Drive=0; Drive < 4; Drive++)
{
HANDLE hPhysicalDriveIOCTL;
char DriveName[32];
sprintf(DriveName, "\\\\.\\PhysicalDrive%d", Drive);
hPhysicalDriveIOCTL = CreateFile(DriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
DWORD cbBytesReturned = 0;
GETVERSIONOUTPARAMS VersionParams;
// Get the version, etc of PhysicalDrive IOCTL
ZeroMemory(&VersionParams, sizeof(GETVERSIONOUTPARAMS));
if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof(VersionParams), &cbBytesReturned, NULL))
{
continue;
}
if(VersionParams.bIDEDeviceMap > 0)
{
// IDE or ATAPI IDENTIFY cmd
byte bIDCmd = 0;
SENDCMDINPARAMS InParams;
// Now, get the ID sector for all IDE devices in the system.
// If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
// otherwise use the IDE_ATA_IDENTIFY command
//
bIDCmd = (VersionParams.bIDEDeviceMap >> Drive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS));
ZeroMemory(IdOutCmd, sizeof(IdOutCmd));
if(DoIdentify(hPhysicalDriveIOCTL, &InParams, (PSENDCMDOUTPARAMS)IdOutCmd, (BYTE)bIDCmd,(BYTE)Drive, &cbBytesReturned))
{
DWORD DiskData[256];
USHORT *pIDSector; // IDSECTOR,
pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)IdOutCmd)->bBuffer;
for(int i=0; i < 256; i++)
DiskData[i] = pIDSector[i];
FILE *fp = NULL;
if(NULL != (fp = fopen("a.log", "w")))
{
fwrite(DiskData, sizeof(DiskData), 1, fp);
fclose(fp);
cout<<"Write file successful"<<endl;
}
strcpy(serialNo, ConvertToString(DiskData, 10, 19).c_str()); // get serial number
strcpy(modelNo, ConvertToString(DiskData, 27, 46).c_str()); // get model type
strcpy(revisionNo, ConvertToString (DiskData, 23, 26).c_str()); //
printf("SerialNo=%s
ModelNo=%s
RevisionNo=%s
", serialNo, modelNo, revisionNo);
}
}
CloseHandle(hPhysicalDriveIOCTL);
}
}
}
int main()
{
ReadPhysicalDriveOnNT();
return 0;
}
실행 결과:
Write file successful
SerialNo=6VMSHFW9
ModelNo=ST3500418AS
RevisionNo=CC68
Press any key to continue
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Ruby의 구조체 클래스은 접근자 메서드가 있는 속성 모음입니다. 클래스를 명시적으로 작성할 필요 없이. Struct 클래스는 구성원 및 해당 값 집합을 포함하는 새 하위 클래스를 생성합니다. 각 멤버에 대해 #attr_accessor 와...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.