📄 block.cpp
字号:
if (fResult) {
DEBUGMSG(ZONE_INIT, (_T("%s IOCTL_DISK_GETINFO passed\r\n"), pszFname));
DUMP_DISKINFO(g_diDiskInfo);
}
else {
dwError = GetLastError();
DEBUGMSG(ZONE_ERROR, (_T(
"%s IOCTL_DISK_GETINFO failed; error = %u\r\n"
), pszFname, dwError));
// is this a legacy block driver?
fResult = DeviceIoControl(
g_hStore,
DISK_IOCTL_GETINFO,
&g_diDiskInfo,
sizeof(g_diDiskInfo),
NULL,
0,
&dwBytesReturned,
NULL);
if (fResult) {
DEBUGMSG(ZONE_INIT, (_T("%s DISK_IOCTL_GETINFO passed\r\n"), pszFname));
DUMP_DISKINFO(g_diDiskInfo);
g_fLegacyBlockDriver = TRUE; // legacy block driver
}
else {
dwError = GetLastError();
DEBUGMSG(ZONE_ERROR, (_T(
"%s DISK_IOCTL_GETINFO failed; error = %u\r\n"
), pszFname, dwError));
goto EXIT;
}
}
// selective partition exposure is not supported; default is to expose all partitions
#if 0
// dismount entire store (all partitions)
if (!DismountStore(g_hStore)) {
dwError = GetLastError();
goto EXIT;
}
#endif
CLOSE_HANDLE(g_hStore);
g_hStore=NULL;
g_bmPartitions = 0x0F;
g_fInitialized = TRUE;
dwError = ERROR_SUCCESS;
EXIT:;
if (!g_fInitialized) {
STORE_Close();
}
CLOSE_KEY(hKey);
FUNCTION_LEAVE_MSG();
return dwError;
}
// ----------------------------------------------------------------------------
// Function: STORE_Close
// Close SCSI-2 direct-access device emulator; unitialize, close associated
// store, and remount exposed partitions
//
// Parameters:
// None
// ----------------------------------------------------------------------------
DWORD
STORE_Close(
)
{
SETFNAME(_T("STORE_Close"));
FUNCTION_ENTER_MSG();
DWORD dwRet = ERROR_SUCCESS;
TCHAR szFullDeviceName[32] = {
'\\', 'S', 't', 'o', 'r', 'e', 'M', 'g', 'r', '\\'
};
ULONG ulFullDeviceNameIndex = 10;
if ((g_hStore != NULL) && (g_hStore != INVALID_HANDLE_VALUE)) {
// a virtual MBR does not exist
// dismount store; this isn't strictly necessary, as the store should
// already be dismounted
//DismountStore(g_hStore);
CLOSE_HANDLE(g_hStore);
g_hStore = NULL;
#if 0
// append g_szDeviceName to "\\StoreMgr\\" to get full device name
ULONG ulDeviceNameChars = _tcslen(g_szDeviceName);
DEBUGCHK(ulDeviceNameChars <= PRX_STREAM_NAME_LEN);
for (ULONG ul = 0; ul < ulDeviceNameChars; ul += 1) {
szFullDeviceName[ulFullDeviceNameIndex + ul] = g_szDeviceName[ul];
}
// force re-examination of disk's organization
DEBUGMSG(ZONE_COMMENT, (_T(
"%s forcing storage manager to re-examine %s\r\n"
), pszFname, szFullDeviceName));
if (!MoveFile(szFullDeviceName, szFullDeviceName)) {
DEBUGMSG(ZONE_COMMENT, (_T(
"%s failed to force storage manager to re-examine %s\r\n"
), pszFname, szFullDeviceName));
}
#endif
}
// clean up emulator
// deallocate list of partition names
LOCAL_FREE(g_ptcPartitions);
g_ptcPartitions = NULL;
// deallocate virtual disk's MBR
LOCAL_FREE(g_lpbMBR);
g_lpbMBR = NULL;
// deallocate copy of actual disk's MBR
LOCAL_FREE(g_lpbPhysMBR);
g_lpbPhysMBR = NULL;
g_bmPartitions = 0;
g_fInitialized = FALSE;
g_fLegacyBlockDriver = FALSE;
FUNCTION_LEAVE_MSG();
return dwRet;
}
// ----------------------------------------------------------------------------
// Function: STORE_IsCommandSupported
// Determine whether a SCSI-2 command is supported by the SCSI-2
// direct-access device emulator
//
// Parameters:
// ptcCommand - command block wrapper
// pfDataStageRequired - return whether a data stage is required, if
// command is supported
// pdwDirection - return the direction of the command
// pdwDataSize - return the size of the data stage
// ----------------------------------------------------------------------------
// Determine whether a SCSI-2 command is supported
BOOL
STORE_IsCommandSupported(
PTRANSPORT_COMMAND ptcCommand,
PBOOL pfDataStageRequired,
PDWORD pdwDirection,
PDWORD pdwDataSize
)
{
SETFNAME(_T("STORE_IsCommandSupported"));
FUNCTION_ENTER_MSG();
BYTE bOpCode = 0;
BOOL fResult = TRUE;
PREFAST_DEBUGCHK(ptcCommand);
DEBUGCHK(ptcCommand->CommandBlock);
DEBUGCHK(pfDataStageRequired);
DEBUGCHK(pdwDirection);
DEBUGCHK(pdwDataSize);
#if 0
if ((g_hStore == NULL) || (!g_fInitialized)) {
DEBUGMSG(ZONE_ERROR, (_T(
"%s emulator not open; commands not accepted\r\n"
), pszFname));
fResult = FALSE;
goto EXIT;
}
#endif
*pfDataStageRequired = FALSE;
*pdwDirection = 0;
*pdwDataSize = 0;
// command/op code is byte 0
bOpCode = *((PBYTE) ptcCommand->CommandBlock);
PUFI_CB pUfiCb = (PUFI_CB) ptcCommand->CommandBlock;
DEBUGMSG(ZONE_COMMENT, (_T("%s command 0x%x\r\n"), pszFname, bOpCode));
switch (bOpCode) {
case SCSI_INQUIRY:
DEBUGMSG(ZONE_COMMENT, (_T("%s INQUIRY\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_IN;
*pdwDataSize = DATASIZE_INQUIRY;
break;
case SCSI_MODE_SENSE6:
DEBUGMSG(ZONE_COMMENT, (_T("%s MODE SENSE (6)\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_IN;
*pdwDataSize = DATASIZE_MODE_SENSE6;
break;
case SCSI_MODE_SENSE10:
DEBUGMSG(ZONE_COMMENT, (_T("%s MODE SENSE (10)\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_IN;
*pdwDataSize = DATASIZE_MODE_SENSE10;
break;
case SCSI_REQUEST_SENSE:
DEBUGMSG(ZONE_COMMENT, (_T("%s REQUEST SENSE\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_IN;
*pdwDataSize = DATASIZE_REQUEST_SENSE;
break;
case SCSI_SEND_DIAGNOSTIC:
DEBUGMSG(ZONE_COMMENT, (_T("%s SEND DIAGNOSTIC\r\n"), pszFname));
break;
case SCSI_TEST_UNIT_READY:
DEBUGMSG(ZONE_COMMENT, (_T("%s TEST UNIT READY\r\n"), pszFname));
break;
case SCSI_READ10:
DEBUGMSG(ZONE_COMMENT, (_T("%s READ (10)\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_IN;
// transfer length is byte 7 + 8
*pdwDataSize = ByteSwapUshort(pUfiCb->wTransferLength);
*pdwDataSize *= BytesPerSector();
break;
case SCSI_READ_CAPACITY:
DEBUGMSG(ZONE_COMMENT, (_T("%s READ CAPACITY\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_IN;
*pdwDataSize = sizeof(READ_CAPACITY_DATA);
break;
case SCSI_START_STOP:
DEBUGMSG(ZONE_COMMENT, (_T("%s START STOP\r\n"), pszFname));
break;
case SCSI_WRITE10:
DEBUGMSG(ZONE_COMMENT, (_T("%s WRITE (10)\r\n"), pszFname));
*pfDataStageRequired = TRUE;
*pdwDirection = DATA_OUT;
*pdwDataSize = ByteSwapUshort(pUfiCb->wTransferLength);
*pdwDataSize *= BytesPerSector();
break;
case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
DEBUGMSG(ZONE_COMMENT, (_T("%s PREVENT ALLOW MEDIUM REMOVAL\r\n"), pszFname));
break;
case SCSI_VERIFY:
DEBUGMSG(ZONE_COMMENT, (_T("%s VERIFY\r\n"), pszFname));
break;
default:
DEBUGMSG(ZONE_WARNING, (_T("%s unsupported command 0x%x\r\n"),
pszFname, bOpCode));
fResult = FALSE;
break;
}
//EXIT:;
FUNCTION_LEAVE_MSG();
return fResult;
}
// ----------------------------------------------------------------------------
// Function: STORE_ExecuteCommand
// Execute and/or emulate the specified command
//
// Parameters:
// ptcCommand - command block wrapper
// ptdData - data block wrapper
// ----------------------------------------------------------------------------
DWORD
STORE_ExecuteCommand(
PTRANSPORT_COMMAND ptcCommand,
PTRANSPORT_DATA ptdData
)
{
SETFNAME(_T("STORE_ExecuteCommand"));
FUNCTION_ENTER_MSG();
DWORD dwResult = EXECUTE_FAIL;
#if 0
if ((g_hStore == NULL) || (!g_fInitialized)) {
DEBUGMSG(ZONE_ERROR, (_T(
"%s emulator not open; commands not accepted\r\n"
), pszFname));
dwResult = EXECUTE_FAIL;
goto EXIT;
}
#endif
DEBUGCHK(ptcCommand);
DEBUGCHK(ptcCommand->CommandBlock);
#ifdef DEBUG
{
BOOL fDataStageRequired;
DWORD dwDirection;
DWORD dwDataSize;
BOOL fSupported = STORE_IsCommandSupported(ptcCommand, &fDataStageRequired, &dwDirection, &dwDataSize);
DEBUGCHK(fSupported);
DEBUGCHK(!fDataStageRequired || (ptdData && ptdData->DataBlock));
}
#endif
// command/op code is byte 0
BYTE bOpCode = ((PBYTE) ptcCommand->CommandBlock)[0];
DEBUGMSG(ZONE_COMMENT, (_T("%s command 0x%x\r\n"), pszFname, bOpCode));
switch (bOpCode) {
case SCSI_INQUIRY:
DEBUGMSG(ZONE_COMMENT, (_T("%s SCSI INQUIRY\r\n"), pszFname));
dwResult = ProcessScsiInquiry(ptcCommand, ptdData);
break;
case SCSI_MODE_SENSE6:
DEBUGMSG(ZONE_COMMENT, (_T("%s MODE SENSE (6)\r\n"), pszFname));
dwResult = ProcessScsiModeSense6(ptcCommand, ptdData);
break;
case SCSI_MODE_SENSE10:
DEBUGMSG(ZONE_COMMENT, (_T("%s MODE SENSE (10)\r\n"), pszFname));
dwResult = ProcessScsiModeSense10(ptcCommand, ptdData);
break;
case SCSI_REQUEST_SENSE:
DEBUGMSG(ZONE_COMMENT, (_T("%s REQUEST SENSE\r\n"), pszFname));
dwResult = ProcessScsiRequestSense(ptcCommand, ptdData);
break;
case SCSI_SEND_DIAGNOSTIC:
DEBUGMSG(ZONE_COMMENT, (_T("%s SEND DIAGNOSTIC\r\n"), pszFname));
dwResult = ProcessScsiSendDiagnostic(ptcCommand);
break;
case SCSI_TEST_UNIT_READY:
DEBUGMSG(ZONE_COMMENT, (_T("%s TEST UNIT READY\r\n"), pszFname));
dwResult = ProcessScsiTestUnitReady(ptcCommand);
break;
case SCSI_READ10:
DEBUGMSG(ZONE_COMMENT, (_T("%s READ (10)\r\n"), pszFname));
dwResult = ProcessScsiRead10(ptcCommand, ptdData);
break;
case SCSI_READ_CAPACITY:
DEBUGMSG(ZONE_COMMENT, (_T("%s READ CAPACITY\r\n"), pszFname));
dwResult = ProcessScsiReadCapacity(ptcCommand, ptdData);
break;
case SCSI_START_STOP:
DEBUGMSG(ZONE_COMMENT, (_T("%s START STOP\r\n"), pszFname));
dwResult = ProcessScsiStartStop(ptcCommand);
break;
case SCSI_WRITE10:
DEBUGMSG(ZONE_COMMENT, (_T("%s WRITE (10)\r\n"), pszFname));
dwResult = ProcessScsiWrite10(ptcCommand, ptdData);
break;
case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
DEBUGMSG(ZONE_COMMENT, (_T("%s PREVENT ALLOW MEDIUM REMOVAL\r\n"), pszFname));
dwResult = ProcessScsiPreventAllowMediumRemoval(ptcCommand);
break;
case SCSI_VERIFY:
DEBUGMSG(ZONE_COMMENT, (_T("%s VERIFY\r\n"), pszFname));
dwResult = ProcessScsiVerify(ptcCommand);
break;
default:
DEBUGCHK(FALSE);
break;
}
//EXIT:;
if (dwResult != EXECUTE_PASS) {
DEBUGMSG(ZONE_ERROR, (_T(
"%s failed to execute command 0x%02x\r\n"
), pszFname, bOpCode));
}
FUNCTION_LEAVE_MSG();
return dwResult;
}
#pragma optimize ( "", on )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -