源代码如下
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"new.h"
using namespace std;
BOOL GetDriveString(TCHAR *j)
{
TCHAR cBuff[MAX_PATH]={0};
DWORD slen=GetLogicalDriveStrings(MAX_PATH,cBuff);
TCHAR *pc=cBuff;
int i=0;
int iLength=0;
while('\0'!=*pc)
{
j[i]=*pc;
iLength=_tcslen(pc);
pc+=iLength+1;
i++;
}
if(_tcslen(j)!=0)
return 1;
else
return 0;
}
BOOL GetDriveTypeStr(const TCHAR *strDrive,TCHAR *strType)
{
char RPathName[]="C:\";
RPathName[0]=*strDrive;
UINT uDrivetype=GetDriveType(RPathName);
switch(uDrivetype)
{
case DRIVE_UNKNOWN:
sprintf(strType, _T("%s: %s"), strDrive, _T("UnKnow"));
//_tcscpy(strType, _T("UnKnow"));
break;
case DRIVE_NO_ROOT_DIR:
sprintf(strType, _T("%s: %s"), strDrive, _T("DRIVE_NO_ROOT_DIR"));
break;
case DRIVE_REMOVABLE:
sprintf(strType, _T("%s: %s"), strDrive, _T("DRIVE_REMOVABLE"));
break;
case DRIVE_FIXED:
sprintf(strType, _T("%s: %s"), strDrive, _T("DRIVE_FIXED"));
break;
case DRIVE_REMOTE:
_stprintf(strType, _T("%s: %s"), strDrive, _T("DRIVE_REMOTE"));
break;
case DRIVE_CDROM:
sprintf(strType, _T("%s: %s"), strDrive, _T("DRIVE_CDROM"));
break;
case DRIVE_RAMDISK:
sprintf(strType, _T("%s: %s"), strDrive, _T("DRIVE_RAMDISK"));
break;
default:
sprintf(strType, _T("%s: %s"), strDrive, _T("Else"));
break;
}
return 1;
}
BOOL GetDriveHandle(const TCHAR *strDrive,HANDLE *hDevice)
{
TCHAR RPathName[]="\\.\C:";
RPathName[4]=*strDrive;
*hDevice = CreateFile((LPCSTR)RPathName, // drive to open
GENERIC_READ | GENERIC_WRITE, // no access to the drive
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
return TRUE;
}
BOOL GetDriveGeometry(HANDLE hDevice, const TCHAR *strDrive, char *Dgeometry)
{
BOOL bResult = FALSE; // results flag
DWORD junk = 0; // discard results
DISK_GEOMETRY pdg={0}; // disk drive geometry structure
ULONGLONG DiskSize = 0; // size of the drive, in bytes
bResult =DeviceIoControl(hDevice, // device to be queried
IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform
NULL, 0, // no input buffer
&pdg, sizeof(pdg), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
if (bResult)
{
sprintf(Dgeometry, "Drive path = %s;\n", strDrive);
DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder * (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
sprintf(Dgeometry, "%sDisk size = %I64d (Bytes);\n"
" = %.2f (Gb).\n",
Dgeometry,DiskSize, (double) DiskSize / (1024 * 1024 * 1024));
return 1;
}
else
{
sprintf (Dgeometry, "GetDriveGeometry failed.");
return 0;
}
}
BOOL ScsiPassthrough(HANDLE hDevice,BYTE *ucAddress,int wBlock)
{
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
ULONG length = 0;
DWORD bytesReturn;
BYTE bufDataRead[64 * 1024 + 10];
//数组清零
memset(bufDataRead,0,sizeof(bufDataRead));
int iRet;
//扇区数
int sectors=bufDataRead[0]*(1<<24)+bufDataRead[1]*(1<<16)+bufDataRead[2]*(1<<8)+bufDataRead[3]+1;
//每个扇区的字节数
int bytesPerSector=bufDataRead[4]*(1<<24)+bufDataRead[5]*(1<<16)+bufDataRead[6]*(1<<8)+bufDataRead[7];
printf("sectors=%d bytesPerSector=%d\n",sectors,bytesPerSector);
ZeroMemory(&sptdwb, sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER));
sptdwb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
sptdwb.sptd.PathId = 0;
sptdwb.sptd.TargetId = 1;
sptdwb.sptd.Lun = 0;
sptdwb.sptd.CdbLength = 12; //SCSI命令长度
sptdwb.sptd.DataIn = SCSI_IOCTL_DATA_IN;
sptdwb.sptd.SenseInfoLength = 24;
sptdwb.sptd.DataTransferLength =bytesPerSector*wBlock; //读数据量
sptdwb.sptd.TimeOutValue = 2;
sptdwb.sptd.DataBuffer =bufDataRead;
sptdwb.sptd.SenseInfoOffset =offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
sptdwb.sptd.Cdb[0] = 0x28; //读READ(10)数据命令
sptdwb.sptd.Cdb[1] = 0x00;
sptdwb.sptd.Cdb[2] = (*ucAddress>>24)&0xff;
sptdwb.sptd.Cdb[3] = (*ucAddress>>16)&0xff;
sptdwb.sptd.Cdb[4] = (*ucAddress>>8)&0xff;
sptdwb.sptd.Cdb[5] = *ucAddress&0xff;
sptdwb.sptd.Cdb[6] = 0x00;
sptdwb.sptd.Cdb[7] = (wBlock>>8)&0xff;
sptdwb.sptd.Cdb[8] = wBlock&0xff; //读readSectors个扇区 ,注意这个值一定要与DataTransferLength相对应
sptdwb.sptd.Cdb[9] = 0x00;
sptdwb.sptd.Cdb[10] = 0x00;
sptdwb.sptd.Cdb[11] = 0x00;
length = sizeof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER);
//向设备发送
iRet = DeviceIoControl(hDevice,
IOCTL_SCSI_PASS_THROUGH_DIRECT,
NULL,
0,
bufDataRead,
wBlock,
&bytesReturn,
NULL);
if (0 == iRet)
{
printf("读取光盘数据失败");
return 0;
}
//放置到公用数组
memcpy(&ucAddress[0],&bufDataRead[0],wBlock);
return true;
}
/*for(int i=0;i<iSize*bytesPerSector;i++)
{
if(i%16==0)
{
printf("\n");
}
printf("%02X",bufDataRead[i]);
}
printf("\n");
return 0;
}*/
BOOL SetCDSpeed(HANDLE hDevice, int speed)
{
DWORD dwOutBytes;
CDROM_SET_SPEED SetSpeed;
SetSpeed.RequestType =(CDROM_SPEED_REQUEST)0;
SetSpeed.ReadSpeed =speed;
if (DeviceIoControl(hDevice,
IOCTL_CDROM_SET_SPEED,
&SetSpeed, sizeof(SetSpeed),
0, NULL,
&dwOutBytes,
(LPOVERLAPPED)NULL))
return true;
return false;
}
BOOL CloseDriveHandle(HANDLE hDevice)
{
return (CloseHandle(hDevice));
}
void main()
{
TCHAR j[MAX_PATH]={0};
TCHAR strType[100] = {0};
TCHAR Dgeometry[1000] = {0};
int speed =100;
HANDLE hDevice;
BYTE bufDataRead[64 * 1024 + 10];
int ucAddress=65;
int wBlock=2;
GetDriveString(j);
j[0] ='H';
GetDriveTypeStr(j,strType);
GetDriveHandle(j,&hDevice);
GetDriveGeometry(hDevice, j, Dgeometry);
if(ScsiPassthrough(hDevice,ucAddress,wBlock))
printf("%d,%d",ucAddress,wBlock);
CloseDriveHandle(hDevice);
while(1);
}