📄 block.cpp
字号:
pbData[1] = 6; // lsb
// medium type, 9.3.3
pbData[2] = 0x00; // default medium type
// device-specific parameter, 9.3.3
pbData[3] = 0x00; // bit 7 = WP (write protected); read from registry
dwResult = EXECUTE_PASS;
EXIT:;
return dwResult;
}
// ----------------------------------------------------------------------------
// Function: ProcessScsiRequestSense
// Process a SCSI-2 REQUEST SENSE command
//
// Parameters:
// ptcCommand - command block wrapper
// ptdData - data block wrapper
// ----------------------------------------------------------------------------
static
DWORD
ProcessScsiRequestSense(
PTRANSPORT_COMMAND ptcCommand,
PTRANSPORT_DATA ptdData
)
{
SETFNAME(_T("ProcessScsiRequestSense"));
const BYTE bErrorCode = 0x70;
const BYTE bAdditionalSenseLength = 10;
PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
PBYTE pbData = (PBYTE) ptdData->DataBlock;
DWORD dwResult = EXECUTE_FAIL;
// don't test if LUN is valid; LUNs are deprecated
// test if data block is large enough
if (ptdData->RequestLength < sizeof(SENSE_DATA)) {
DEBUGMSG(ZONE_ERROR, (_T(
"%s host requesting less than required; ptdData->RequestLength < %u\r\n"
), pszFname, sizeof(SENSE_DATA)));
goto EXIT;
}
ZeroMemory(pbData, ptdData->RequestLength);
ptdData->TransferLength = ptdData->RequestLength;
PSENSE_DATA pSenseData;
pSenseData = (PSENSE_DATA) pbData;
pSenseData->ErrorCode = bErrorCode;
pSenseData->SenseKey = g_bSenseKey;
pSenseData->AdditionalSenseLength = bAdditionalSenseLength;
pSenseData->AdditionalSenseCode = g_bASC;
pSenseData->AdditionalSenseCodeQualifier = g_bASCQ;
dwResult = EXECUTE_PASS;
EXIT:;
return dwResult;
}
// ----------------------------------------------------------------------------
// Function: ProcessScsiSendDiagnostic
// Process a SCSI-2 SEND DIAGNOSTIC command
//
// Parameters:
// ptcCommand - command block wrapper
// ----------------------------------------------------------------------------
static
DWORD
ProcessScsiSendDiagnostic(
PTRANSPORT_COMMAND ptcCommand
)
{
SETFNAME(_T("ProcessScsiSendDiagnostic"));
const BYTE bSelfTest = 0x04;
PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
DWORD dwResult = EXECUTE_FAIL;
// don't test if LUN is valid; LUNs are deprecated
// test if self-test bit is high
if (!(pbCommand[1] & bSelfTest)) {
DEBUGMSG(ZONE_ERROR, (_T("%s only self-test is supported\r\n"), pszFname));
goto EXIT;
}
// nothing to check
dwResult = EXECUTE_PASS;
EXIT:;
return dwResult;
}
// ----------------------------------------------------------------------------
// Function: ProcessScsiTestUnitReady
// Process a SCSI-2 TEST UNIT READY command
//
// Parameters:
// ptcCommand - command block wrapper
// ----------------------------------------------------------------------------
static
DWORD
ProcessScsiTestUnitReady(
PTRANSPORT_COMMAND ptcCommand
)
{
SETFNAME(_T("ProcessScsiTestUnitReady"));
PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
DWORD dwResult = EXECUTE_FAIL;
// don't test if LUN is valid; LUNs are deprecated
// nothing to check
dwResult = EXECUTE_PASS;
return dwResult;
}
void
usbmsfn_dump_MBR(
unsigned char * data,
unsigned short num_bytes,
unsigned short offset
)
{
int i;
RETAILMSG(TRUE, (L"Dump Partition tables in MBR---------------"));
for (i=0;i<4;i++) {
PPARTENTRY p=(PPARTENTRY)(data+PARTTABLE_OFFSET+i*SIZE_PARTTABLE_ENTRIES);
RETAILMSG(TRUE, (L"Partition %i\r\n", i));
RETAILMSG(TRUE, (L"\tPart_BootInd=%x\r\n", p->Part_BootInd));
RETAILMSG(TRUE, (L"\tPart_FirstHead=%x\r\n", p->Part_FirstHead));
RETAILMSG(TRUE, (L"\tPart_FirstSector=%x\r\n", p->Part_FirstSector));
RETAILMSG(TRUE, (L"\tPart_FirstTrack=%x\r\n", p->Part_FirstTrack));
RETAILMSG(TRUE, (L"\tPart_FileSystem=%x\r\n", p->Part_FileSystem));
RETAILMSG(TRUE, (L"\tPart_LastHead=%x\r\n", p->Part_LastHead));
RETAILMSG(TRUE, (L"\tPart_LastSector=%x\r\n", p->Part_LastSector));
RETAILMSG(TRUE, (L"\tPart_LastTrack=%x\r\n", p->Part_LastTrack));
RETAILMSG(TRUE, (L"\tPart_StartSector=%x\r\n", p->Part_StartSector));
RETAILMSG(TRUE, (L"\tPart_TotalSectors=%x\r\n", p->Part_TotalSectors));
}
*(data+0x1b8)=5;
*(data+0x1b9)=0xAe;
*(data+0x1bA)=0x65;
*(data+0x1bB)=0xB2;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Description:
Dumps data to the debug display formated in hex and ascii for easy viewing.
Used for debug output only. It is not compiled into the retail version.
Arguments:
data Buffer of data to be displayed
num_bytes Number of bytes to display
offset Beginning offset to be displayed before each line
Return Value:
None
---------------------------------------------------------------------------*/
void
usbmsfn_dump(
unsigned char * data,
unsigned short num_bytes,
unsigned short offset
)
{
unsigned short i,j,l;
unsigned char tmp_str[100];
unsigned char tmp_str1[10];
for (i = 0; i < num_bytes; i += 16)
{
unsigned short n ;
tmp_str[0]='\0';
n = i+offset ;
for (j=0; j<4; j++) {
l=n%16;
if (l>=10)
tmp_str[3-j]=(unsigned char)('A'+l-10);
else
tmp_str[3-j]=(unsigned char)(l+'0');
n >>= 4 ;
}
tmp_str[4]='\0';
strcat ( (char *)tmp_str, ": ");
/*
Output the hex bytes
*/
for (j = i; j < (i+16); j++)
{
int m ;
if (j < num_bytes)
{
m=((unsigned int)((unsigned char)*(data+j)))/16 ;
if (m>=10)
tmp_str1[0]='A'+(unsigned char)m-10;
else
tmp_str1[0]=(unsigned char)m+'0';
m=((unsigned int)((unsigned char)*(data+j)))%16 ;
if (m>=10)
tmp_str1[1]='A'+(unsigned char)m-10;
else
tmp_str1[1]=(unsigned char)m+'0';
tmp_str1[2]='\0';
strcat ((char *)tmp_str, (char *)tmp_str1);
strcat ((char *)tmp_str, " ");
}
else
{
strcat((char *)tmp_str," ");
}
}
strcat((char *)tmp_str, " ");
l=(unsigned short)strlen((char *)tmp_str);
/*
* Output the ASCII bytes
*/
for (j = i; j < (i+16); j++)
{
if (j < num_bytes)
{
char c = *(data+j);
if (c < ' ' || c > 'z')
{
c = '.';
}
tmp_str[l++]=c;
}
else
{
tmp_str[l++]=' ';
}
}
tmp_str[l++]='\r';
tmp_str[l++]='\n';
tmp_str[l++]='\0';
RETAILMSG(TRUE, (L"%S", (tmp_str)));
}
}
// ----------------------------------------------------------------------------
// Function: ProcessScsiRead10
// Process a SCSI-2 READ (10) command
//
// Parameters:
// ptcCommand - command block wrapper
// ptdData - data block wrapper
// ----------------------------------------------------------------------------
static
DWORD
ProcessScsiRead10(
PTRANSPORT_COMMAND ptcCommand,
PTRANSPORT_DATA ptdData
)
{
SETFNAME(_T("ProcessScsiRead10"));
PBYTE pbCommand = (PBYTE) ptcCommand->CommandBlock;
PBYTE pbData = (PBYTE) ptdData->DataBlock;
DWORD dwLogicalBlockAddress;
DWORD dwTransferLength;
DWORD dwResult = EXECUTE_FAIL;
SG_REQ sgSgReq;
SG_BUF sgSgBuf;
DWORD dwBytesReturned;
BOOL fResult = FALSE;
PUFI_CB pUfiCb = (PUFI_CB) pbCommand;
DEBUGCHK(pUfiCb->bReserved1 == 0);
// don't test if LUN is valid; LUNs are deprecated
if (g_hStore==NULL||g_hStore==INVALID_HANDLE_VALUE)
g_hStore=OpenStore(g_szDeviceName2);
// test if logical block address is valid
dwLogicalBlockAddress = ByteSwapUlong(pUfiCb->dwLogicalBlockAddress);
// test if transfer length is valid
dwTransferLength = ByteSwapUshort(pUfiCb->wTransferLength);
DEBUGMSG(ZONE_COMMENT, (_T(
"%s starting LBA/sector = %u, transfer length = %u (sectors)\r\n"
), pszFname, dwLogicalBlockAddress, dwTransferLength));
ZeroMemory(pbData, (dwTransferLength * BytesPerSector()));
ptdData->TransferLength = dwTransferLength * BytesPerSector();
// is the host reading the virtual disk's MBR?
if ((dwLogicalBlockAddress == 0) && (g_lpbMBR != NULL)) {
// we can't handle a request to access {virtual sector 0, physical
// sector 1, physical sector2, ...)
DEBUGCHK(dwTransferLength == 1);
DEBUGMSG(ZONE_COMMENT, (_T(
"%s read request targeting virtual disk's MBR\r\n"
), pszFname));
// return virtual disk's MBR
ptdData->DataBlock = g_lpbMBR;
dwResult = EXECUTE_PASS;
goto EXIT;
}
// prepare scatter/gather buffer
sgSgBuf.sb_buf = pbData;
sgSgBuf.sb_len = ptdData->TransferLength;
memset(pbData, 512,0);
// prepare scatter/gather request
sgSgReq.sr_start = dwLogicalBlockAddress;
sgSgReq.sr_num_sec = dwTransferLength;
sgSgReq.sr_status = 0;
sgSgReq.sr_callback = NULL;
sgSgReq.sr_num_sg = 1;
sgSgReq.sr_sglist[0] = sgSgBuf;
// read from device
DWORD dwIoControlCode = (g_fLegacyBlockDriver) ? DISK_IOCTL_READ : IOCTL_DISK_READ;
fResult = DeviceIoControl(
g_hStore,
dwIoControlCode,
&sgSgReq,
sizeof(sgSgReq),
NULL,
0,
&dwBytesReturned,
NULL);
if (fResult) {
DEBUGMSG(ZONE_COMMENT, (_T(
"%s IOCTL_DISK_READ passed; %u bytes read\r\n"
), pszFname, dwBytesReturned));
}
else {
DWORD dwError = GetLastError();
DEBUGMSG(ZONE_ERROR, (_T(
"%s IOCTL_DISK_READ failed; error = %u\r\n"
), pszFname, dwError));
goto EXIT;
}
if (dwLogicalBlockAddress==0) {
// Signature of MBR????
*(pbData+0x1b8)=5;
*(pbData+0x1b9)=0xAe;
*(pbData+0x1bA)=0x65;
*(pbData+0x1bB)=0xB2;
}
dwResult = EXECUTE_PASS;
EXIT:;
return dwResult;
}
// ----------------------------------------------------------------------------
// Function: ProcessScsiReadCapacity
// Process a SCSI-2 READ CAPACITY command
//
// Parameters:
// ptcCommand - command block wrapper
// ptdData - data block wrapper
// ----------------------------------------------------------------------------
static
DWORD
ProcessScsiReadCapacity(
PTRANSPORT_COMMAND ptcCommand,
PTRANSPORT_DATA ptdData
)
{
SETFNAME(_T("ProcessScsiReadCapacity"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -