📄 cedriver.c
字号:
ERROR_GEN_FAILURE, // flDirectoryNotEmpty = 58
ERROR_INVALID_PARAMETER, // flFileIsADirectory = 59
ERROR_SEEK, // flAdapterNotFound = 60
ERROR_GEN_FAILURE, // Skip This entry (61)
ERROR_GEN_FAILURE, // flFormattingError = 62
ERROR_OUTOFMEMORY, // flNotEnoughMemory = 63
ERROR_GEN_FAILURE, // flVolumeTooSmall = 64
ERROR_GEN_FAILURE, // flBufferingError = 65
ERROR_GEN_FAILURE, // Skip This entry (66)
ERROR_GEN_FAILURE, // Skip This entry (67)
ERROR_GEN_FAILURE, // Skip This entry (68)
ERROR_GEN_FAILURE, // Skip This entry (69)
ERROR_GEN_FAILURE, // Skip This entry (70)
ERROR_GEN_FAILURE, // Skip This entry (71)
ERROR_GEN_FAILURE, // Skip This entry (72)
ERROR_GEN_FAILURE, // Skip This entry (73)
ERROR_GEN_FAILURE, // Skip This entry (74)
ERROR_GEN_FAILURE, // Skip This entry (75)
ERROR_GEN_FAILURE, // Skip This entry (76)
ERROR_GEN_FAILURE, // Skip This entry (77)
ERROR_GEN_FAILURE, // Skip This entry (78)
ERROR_GEN_FAILURE, // Skip This entry (79)
ERROR_FILE_EXISTS, // flFileAlreadyExists = 80
ERROR_GEN_FAILURE, // Skip This entry (81)
ERROR_GEN_FAILURE, // Skip This entry (82)
ERROR_GEN_FAILURE, // Skip This entry (83)
ERROR_GEN_FAILURE, // Skip This entry (84)
ERROR_GEN_FAILURE, // Skip This entry (85)
ERROR_GEN_FAILURE, // Skip This entry (86)
ERROR_GEN_FAILURE, // Skip This entry (87)
ERROR_GEN_FAILURE, // Skip This entry (88)
ERROR_GEN_FAILURE, // Skip This entry (89)
ERROR_GEN_FAILURE, // Skip This entry (90)
ERROR_GEN_FAILURE, // Skip This entry (91)
ERROR_GEN_FAILURE, // Skip This entry (92)
ERROR_GEN_FAILURE, // Skip This entry (93)
ERROR_GEN_FAILURE, // Skip This entry (94)
ERROR_GEN_FAILURE, // Skip This entry (95)
ERROR_GEN_FAILURE, // Skip This entry (96)
ERROR_GEN_FAILURE, // Skip This entry (97)
ERROR_GEN_FAILURE, // Skip This entry (98)
ERROR_GEN_FAILURE, // Skip This entry (99)
ERROR_CAN_NOT_COMPLETE, // flIncomplete = 100
ERROR_BUSY_DRIVE, // flTimedOut = 101
ERROR_GEN_FAILURE // flTooManyComponents = 102
};
if(status > (sizeof(statusTranslateTable) / sizeof(DWORD)))
return ERROR_GEN_FAILURE;
return statusTranslateTable[status];
}
//----------------------------------------------------------------------------
// Function Name: copyBytes
// Purpose......: Copy a buffer from one memory to another.
// Remarks......: Recieved buffers might be unalligned.
// Returns......: Void
//----------------------------------------------------------------------------
void copyBytes(char * dest, char * src, DWORD length)
{
DWORD fastCopy, firstSlowIdx;
DWORD i;
if ((((DWORD)dest & 0x3) == 0) &&
(((DWORD)src & 0x3) == 0))
{
fastCopy = length >> 2;
firstSlowIdx = fastCopy << 2;
}
else
{
fastCopy = 0;
firstSlowIdx = 0;
}
for (i = 0; i < fastCopy; i++)
((DWORD*)dest)[i]=((DWORD*)src)[i];
for (i = firstSlowIdx ; i < length; i++)
dest[i]=src[i];
}
//----------------------------------------------------------------------------
// Function Name: ReadSectors
// Purpose......: Read sectors to a buffer using TrueFFS. This function
// handles a single SG section of the Read command.
// Remarks......: Recieved buffers might be unalligned.
// Returns......: flOK for success, other for failure.
//----------------------------------------------------------------------------
static FLStatus ReadSectors(PDISK pDisk,
PSG_REQ ptrSG,
char *cBuf,
DWORD dwStartSector,
DWORD dwNumOfSectors,
PDWORD pBytesReturned)
{
IOreq ioreq;
FLStatus status;
// Fill in FLite request packet
ioreq.irHandle = BSP_MDOC_USERSTORE_PARTITION_HANDLE;
ioreq.irData = cBuf; // Target buffer
ioreq.irSectorNo = dwStartSector; // First sector No.
ioreq.irSectorCount= dwNumOfSectors; // Sectors to read / write
DBGMSG(ZONE_RDWR, (TEXT("TrueFFS, doDiskIo(): Reading %d sectors starting at sector %d\r\n"), dwNumOfSectors, dwStartSector));
try
{
status = flAbsRead(&ioreq);
}
except (EXCEPTION_EXECUTE_HANDLER)
{
ptrSG->sr_status = statusTranslate(flBadParameter);
DBGMSG(ZONE_RDWR | ZONE_ERROR, (TEXT("TrueFFS, doDiskIo(): recieved bad pointer for read operation.\r\n")));
return flBadParameter;
}
if (pBytesReturned)
{
*pBytesReturned += (ioreq.irSectorCount << FL_SECTOR_SIZE_BITS);
}
return status;
}
//----------------------------------------------------------------------------
// Function Name: WriteSectors
// Purpose......: Write sectors from a buffer using TrueFFS. This function
// handles a single SG section of the Write command.
// Remarks......: Recieved buffers might be unalligned.
// Returns......: flOK for success, other for failure.
//----------------------------------------------------------------------------
static FLStatus WriteSectors(PDISK pDisk,
PSG_REQ ptrSG,
char *cBuf,
DWORD dwStartSector,
DWORD dwNumOfSectors,
PDWORD pBytesReturned)
{
IOreq ioreq;
FLStatus status;
// Fill in FLite request packet
ioreq.irHandle = BSP_MDOC_USERSTORE_PARTITION_HANDLE;
ioreq.irData = cBuf; // Target buffer
ioreq.irSectorNo = dwStartSector; // First sector No.
ioreq.irSectorCount= dwNumOfSectors; // Sectors to read / write
DBGMSG(ZONE_RDWR, (TEXT("TrueFFS, doDiskIo(): Writing %d sectors starting at sector %d\r\n"),dwNumOfSectors, dwStartSector));
try
{
status = flAbsWrite(&ioreq);
}
except (EXCEPTION_EXECUTE_HANDLER)
{
ptrSG->sr_status = statusTranslate(flBadParameter);
DBGMSG(ZONE_ERROR, (TEXT("TrueFFS, doDiskIo(): recieved bad pointer for write operation.\r\n")));
return flBadParameter;
}
return status;
}
//----------------------------------------------------------------------------
// Function Name: doDiskIo
// Purpose......: Perform the IO requests in the scatter/gather buffer.
// Remarks......: This function is called from DSK_IOControl.
// Returns......: Status of operation
//----------------------------------------------------------------------------
static DWORD doDiskIo(PDISK pDisk,
DWORD Opcode, // IOCTL_DISK_READ, IOCTL_DISK_WRITE
PSG_REQ ptrSG, // list of scatter/gather buffers
PDWORD pBytesReturned)
{
DWORD bufSize;
FLStatus status = flOK;
DWORD curSG, dwSectorsUsed, dwIntermediatIndex;
char *realBuf=NULL, *tempBuf, *intermediateBuf;
DWORD i;
// Check the sanity of SG parameters.
try
{
// check each sg buffer and calculate total buffer size
for (i = 0, bufSize = 0; i < ptrSG->sr_num_sg ; i++)
{
if (ptrSG->sr_sglist[i].sb_buf == NULL)
{
//If the buffer is NULL - it is an error
DBGMSG(ZONE_ERROR | ZONE_RDWR, (TEXT("TrueFFS, doDiskIo(): Recieved NULL user buffer. Return with error.\r\n")));
ptrSG->sr_status = ERROR_INVALID_PARAMETER;
return ptrSG->sr_status;
}
bufSize += ptrSG->sr_sglist[i].sb_len;
}
if (ptrSG->sr_num_sec == 0 || ptrSG->sr_num_sg == 0)
{
//If the read length is 0 - there is nothing to read.
DBGMSG(ZONE_RDWR, (TEXT("TrueFFS, doDiskIo(): asked to read/write 0 sectors - return with OK but don't do anything.\r\n")));
ptrSG->sr_status = ERROR_SUCCESS;
return ptrSG->sr_status;
}
if (bufSize < (ptrSG->sr_num_sec * FL_SECTOR_SIZE))
{
//If the givven buffer is less than the data in the required sectors - it is an error
DBGMSG(ZONE_RDWR | ZONE_ERROR, (TEXT("TrueFFS, doDiskIo(): user buffer too small for data. Return with error.\r\n")));
ptrSG->sr_status = ERROR_INVALID_PARAMETER;
return ptrSG->sr_status;
}
}
except (EXCEPTION_EXECUTE_HANDLER)
{
DBGMSG(ZONE_RDWR | ZONE_ERROR, (TEXT("TrueFFS, doDiskIo(): Recieved bad pointer for read operation.\r\n")));
return ERROR_INVALID_PARAMETER;
}
if (pBytesReturned)
{
*pBytesReturned = 0;
}
// Align the Intermediate buffer
tempBuf = (char *)pDisk->intermediateBuf;
intermediateBuf = (((DWORD)tempBuf & 3) == 0) ? tempBuf : &tempBuf[4-((DWORD)tempBuf & 3)];
ptrSG->sr_status = ERROR_SUCCESS;
dwSectorsUsed = 0;
dwIntermediatIndex = FL_SECTOR_SIZE;
for (curSG = 0; curSG < ptrSG->sr_num_sg; curSG++)
{
// And now - we start the actual read/write operation for each SG entry
DWORD dwNumOfSect, dwLeftOverBytes;
DWORD dwBytesToUse = (FL_SECTOR_SIZE-dwIntermediatIndex < ptrSG->sr_sglist[curSG].sb_len) ?
FL_SECTOR_SIZE - dwIntermediatIndex : ptrSG->sr_sglist[curSG].sb_len;
dwLeftOverBytes = (ptrSG->sr_sglist[curSG].sb_len - dwBytesToUse) & (FL_SECTOR_SIZE-1);
dwNumOfSect = (ptrSG->sr_sglist[curSG].sb_len - dwBytesToUse) >> FL_SECTOR_SIZE_BITS;
realBuf = ptrSG->sr_sglist[curSG].sb_buf;
if(Opcode == IOCTL_DISK_READ || Opcode == DISK_IOCTL_READ)
{
// IOCTL_DISK_READ operation
//
// Complete leftovers from previous iteration, if needed
if (dwIntermediatIndex < FL_SECTOR_SIZE)
{
copyBytes(realBuf, &intermediateBuf[dwIntermediatIndex], dwBytesToUse);
dwIntermediatIndex += dwBytesToUse;
if (dwIntermediatIndex < FL_SECTOR_SIZE)
{
// The buffer was smaller then sector, advance to next buffer
continue;
}
// Intermediate sector reading is complete
dwSectorsUsed++;
}
// Read continuous sectors if possible
if (dwNumOfSect)
{
status = ReadSectors(pDisk,
ptrSG,
&realBuf[dwBytesToUse],
ptrSG->sr_start+dwSectorsUsed,
dwNumOfSect,
pBytesReturned);
if (status==flReadFault)
{
return ptrSG->sr_status;
}
}
// Read from sector to a non-complete S/G buffer if needed
if (dwLeftOverBytes)
{
// Start using Intermediate buffer
status = ReadSectors(pDisk,
ptrSG,
intermediateBuf,
ptrSG->sr_start + dwNumOfSect + dwSectorsUsed,
1,
pBytesReturned);
if (status==flReadFault)
{
return ptrSG->sr_status;
}
realBuf = &realBuf[dwBytesToUse+dwNumOfSect*FL_SECTOR_SIZE];
copyBytes(realBuf, intermediateBuf, dwLeftOverBytes);
dwIntermediatIndex = dwLeftOverBytes;
}
}
else if (Opcode == DISK_IOCTL_WRITE || Opcode == IOCTL_DISK_WRITE)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -