www.pudn.com > disk_primary.rar > disk.h


 
 
//&/#define PRINTING_TO_CONSOLE_ALLOWED 
 
 
//#include  
#include  
 
 
//  Required to ensure correct PhysicalDrive IOCTL structure setup 
//&/#pragma pack(1) 
 
 
//  Max number of drives assuming primary/secondary, master/slave topology 
#define  MAX_IDE_DRIVES  4 
#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 
 
//  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 
 
 
//  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; 
 
// Define global buffers. 
BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; 
 
 
// DoIDENTIFY 
// FUNCTION: Send an IDENTIFY command to the drive 
// bDriveNum = 0-3 
// bIDCmd = IDE_ATA_IDENTIFY or IDE_ATAPI_IDENTIFY 
BOOL 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 = 0xA0 | ((bDriveNum & 1) << 4); 
 
	// 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_RECEIVE_DRIVE_DATA, 
		(LPVOID) pSCIP, 
		sizeof(SENDCMDINPARAMS) - 1, 
		(LPVOID) pSCOP, 
		sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, 
		lpcbBytesReturned, NULL) ); 
} 
 
int ReadPhysicalDriveInNT(int drive,DWORD diskdata[256])	//drive从0开始; 
{ 
	int done = FALSE; 
 
	char driveName [256]; 
	memset(driveName,0,256); 
	driveName[ 0] = '\\'; 
	driveName[ 1] = '\\'; 
	driveName[ 2] = '.'; 
	driveName[ 3] = '\\'; 
	driveName[ 4] = 'P'; 
	driveName[ 5] = 'h'; 
	driveName[ 6] = 'y'; 
	driveName[ 7] = 's'; 
	driveName[ 8] = 'i'; 
	driveName[ 9] = 'c'; 
	driveName[10] = 'a'; 
	driveName[11] = 'l'; 
	driveName[12] = 'D'; 
	driveName[13] = 'r'; 
	driveName[14] = 'i'; 
	driveName[15] = 'v'; 
	driveName[16] = 'e'; 
	driveName[17] = 0x30+drive; 
 
	//&for (drive = 0; drive < MAX_IDE_DRIVES; drive++) 
	//&{	//处理driveName; 
	HANDLE hPhysicalDriveIOCTL = 0; 
 
	//  Try to get a handle to PhysicalDrive IOCTL, report failure 
	//  and exit if can't. 
 
//&controller for循环两次起点: 
	//sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive); 
 
	//  Windows NT, Windows 2000, must have admin rights 
	hPhysicalDriveIOCTL = CreateFile (driveName, 
						   GENERIC_READ | GENERIC_WRITE,  
						   FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
						   OPEN_EXISTING, 0, NULL); 
	// if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE) 
	//    printf ("Unable to open physical drive %d, error code: 0x%lX\n", 
	//            drive, GetLastError ()); 
 
	if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE) 
	{ 
		GETVERSIONOUTPARAMS VersionParams; 
		DWORD               cbBytesReturned = 0; 
 
		// Get the version, etc of PhysicalDrive IOCTL 
		memset ((void*) &VersionParams, 0, sizeof(VersionParams)); 
 
		if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION, 
			   NULL,  
			   0, 
			   &VersionParams, 
			   sizeof(VersionParams), 
			   &cbBytesReturned, NULL) ) 
		{          
			// printf ("DFP_GET_VERSION failed for drive %d\n", i); 
			// continue; 
		} 
 
		// If there is a IDE device at number "i" issue commands 
		// to the device 
		if (VersionParams.bIDEDeviceMap > 0) 
		{ 
			BYTE             bIDCmd = 0;   // IDE or ATAPI IDENTIFY cmd 
			SENDCMDINPARAMS  scip; 
			//SENDCMDOUTPARAMS OutCmd; 
 
			// 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; 
 
			memset (&scip, 0, sizeof(scip)); 
			memset (IdOutCmd, 0, sizeof(IdOutCmd)); 
 
			if ( DoIDENTIFY (hPhysicalDriveIOCTL,  
					   &scip,  
					   (PSENDCMDOUTPARAMS)&IdOutCmd,  
					   (BYTE) bIDCmd, 
					   (BYTE) drive, 
					   &cbBytesReturned)) 
			{ 
 
				int ijk = 0; 
				USHORT *pIdSector = (USHORT *)((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer; 
 
				for (ijk = 0; ijk < 256; ijk++) 
					diskdata[ijk] = pIdSector [ijk]; 
 
				//PrintIdeInfo (drive, diskdata); 
 
				done = TRUE; 
			} 
		} 
 
		 CloseHandle (hPhysicalDriveIOCTL); 
	} 
 
	return done; 
} 
 
char* ConvertToString(DWORD diskdata[256], int firstIndex, int len) 
{ 
	static char sc[512+1]; 
	 
	int index = 0; 
	int nScore = 0; 
	int end = firstIndex + len; 
	//  each integer has two characters stored in it backwards 
	for (index = firstIndex; index < end; index++) 
	{ 
		//  get high byte for 1st character 
		sc[nScore] = (char) (diskdata[index] / 256); 
		nScore++; 
 
		//  get low byte for 2nd character 
		sc[nScore] = (char) (diskdata[index] % 256); 
		nScore++; 
	} 
	//  end the sc  
	sc [nScore] = '\0'; 
	//  cut off the trailing blanks---从右边开始截去空格,遇到非空格返回! 
	for (index=nScore-1; index>0 && sc[index]==0x20; index--) 
		sc[index] = '\0';	//&/sc[index]==0x20 --- 不能放到for循环的{}内,否则逻辑错误! 
 
	return sc; 
} 
 
/////////////////////////////////////////////////////////////////////////////// 
//将一个无符号型数转换成16进制字符串: 
static char* UINTtosHex(unsigned int uN,bool bLmt8=true) 
{ 
	static char s[16+1]; 
	int bit = 4; 
	unsigned int nA[16]; 
    int i; 
    unsigned int Ib = uN; int len=0; while(Ib>0) { Ib = Ib>>bit; len++; } 
    for(i=0;i>((len-1-i)*bit)); 
		uN -= (((unsigned int)nA[i])<<((len-1-i)*bit));         
    } 
 
	for(int k=0;k<17;k++) 
		s[k] = 0; 
 
	int odd=0; 
	i = 0; 
	if(bLmt8) 
	{ 
		for(i=0;i<8-len;i++)	s[i] = 48; 
		odd = 8-len; 
		i = (len>8)? (len-8):0;	//长度超过8取后8位;//长度小于8前面补0;否则用实际的16进制字串! 
	} 
 
	for(   ;i9)	//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; 
			s[odd+i] = 55+nA[i]; 
		else 
			s[odd+i] = 48+nA[i]; 
	}	 
	return s; 
} 
 
//将一个16进制字符串转换成无符号型数: 
static void  sHextoUINT(unsigned int& uN,bool bLmt8=true,char* sH=0,int len=8) 
{ 
	int bit = 4; 
	unsigned int nA[16]; 
	int i; 
	for(i=0;i64)? (sH[i]-55):(sH[i]-48); 
	} 
 
	//如果需要限长:对于长度小于等于8,取前n位;长度>8,取后8位;或者补限制的也直接转换;不限长的也从0开始累加; 
	i = 0; 
	if(bLmt8) 
	{ 
		i = (len>8) ? (len-8) : 0; 
	} 
	 
	uN = 0; 
    for(   ;i 268435455) id %= 268435456; 
 
   return (long) id; 
} 
/////////////////////////////////////////////////////////////////////////////// 
*/ 
 
 
/* 
/////////////////////////////////////////////////////////////////////////////// 
typedef struct _SRB_IO_CONTROL 
{ 
	ULONG HeaderLength; 
	UCHAR Signature[8]; 
	ULONG Timeout; 
	ULONG ControlCode; 
	ULONG ReturnCode; 
	ULONG Length; 
}	SRB_IO_CONTROL, *PSRB_IO_CONTROL; 
 
 
// 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; 
 
 
//#define  SENDIDLENGTH  sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE 
int ReadIdeDriveAsScsiDriveInNT (int controller,int driver,DWORD diskdata[256]) 
{ 
	const int SENDIDLENGTH = sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE; 
	int done = FALSE; 
 
	char driveName [256]; 
	memset(driveName,0,256); 
	driveName[ 0] = '\\'; 
	driveName[ 1] = '\\'; 
	driveName[ 2] = '.'; 
	driveName[ 3] = '\\'; 
	driveName[ 4] = 'S'; 
	driveName[ 5] = 'c'; 
	driveName[ 6] = 's'; 
	driveName[ 7] = 'i'; 
	driveName[ 8] = 0x30 + controller; 
 
	HANDLE hScsiDriveIOCTL = 0; 
 
	//  Try to get a handle to PhysicalDrive IOCTL, report failure 
	//  and exit if can't. 
	//sprintf (driveName, "\\\\.\\Scsi%d:", controller); 
	//  Windows NT, Windows 2000, any rights should do 
//&controller for循环两次起点: 
	//for (controller = 0; controller < 2; controller++) 
	//{	//处理driveName; 
	hScsiDriveIOCTL = CreateFile (driveName, 
		GENERIC_READ | GENERIC_WRITE,  
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
		OPEN_EXISTING, 0, NULL); 
		// if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE) 
		//    printf ("Unable to open SCSI controller %d, error code: 0x%lX\n", 
		//            controller, GetLastError ()); 
 
	if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE) 
	{ 
		int drive = 0; 
 
//&driver for循环两次起点: 
		//for (drive = 0; drive < 2; drive++) 
		//{	//处理drive循环; 
		char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH]; 
		SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer; 
		SENDCMDINPARAMS *pin = 
		(SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL)); 
		DWORD dummy; 
 
		memset (buffer, 0, sizeof (buffer)); 
		p -> HeaderLength = sizeof (SRB_IO_CONTROL); 
		p -> Timeout = 10000; 
		p -> Length = SENDIDLENGTH; 
		p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY; 
		strncpy ((char *) p -> Signature, "SCSIDISK", 8); 
 
		pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY; 
		pin -> bDriveNumber = drive; 
 
		if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,  
		buffer, 
		sizeof (SRB_IO_CONTROL) + 
			 sizeof (SENDCMDINPARAMS) - 1, 
		buffer, 
		sizeof (SRB_IO_CONTROL) + SENDIDLENGTH, 
		&dummy, NULL)) 
		{ 
			SENDCMDOUTPARAMS *pOut = 
			(SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL)); 
			IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer); 
			if (pId -> sModelNumber [0]) 
			{ 
				//DWORD diskdata [256]; 
				int ijk = 0; 
				USHORT *pIdSector = (USHORT *) pId; 
 
				for (ijk = 0; ijk < 256; ijk++) 
				diskdata [ijk] = pIdSector [ijk]; 
 
				//PrintIdeInfo (controller * 2 + drive, diskdata); 
 
				done = TRUE; 
			} 
		} 
		//} 
		CloseHandle (hScsiDriveIOCTL); 
	} 
	//} 
 
	return done; 
} 
/////////////////////////////////////////////////////////////////////////////// 
*/