📄 cedriver.c
字号:
{
// IOCTL_DISK_WRITE operation
//
// Complete leftovers from previous iteration, if needed
if (dwIntermediatIndex < FL_SECTOR_SIZE)
{
copyBytes(&intermediateBuf[dwIntermediatIndex], realBuf, dwBytesToUse);
dwIntermediatIndex += dwBytesToUse;
if (dwIntermediatIndex < FL_SECTOR_SIZE)
{
// The buffer was smamller then sector, advance to next buffer
continue;
}
// Intermediate sector aggragation is complete, write it
status = WriteSectors(pDisk,
ptrSG,
intermediateBuf,
ptrSG->sr_start + dwSectorsUsed,
1,
pBytesReturned);
if (status!=flOK)
{
return ptrSG->sr_status;
}
dwSectorsUsed++;
}
// Write continuous sectors if possible
if (dwNumOfSect)
{
status = WriteSectors(pDisk,
ptrSG,
&realBuf[dwBytesToUse],
ptrSG->sr_start + dwSectorsUsed,
dwNumOfSect,
pBytesReturned);
if (status != flOK)
{
return ptrSG->sr_status;
}
}
// Write sector for a non-complete S/G buffer if needed
if (dwLeftOverBytes)
{
realBuf = &realBuf[dwBytesToUse + dwNumOfSect*FL_SECTOR_SIZE];
copyBytes(intermediateBuf, realBuf, dwLeftOverBytes);
dwIntermediatIndex = dwLeftOverBytes;
}
}
// remember first error
if((ptrSG->sr_status == ERROR_SUCCESS) && (status != flOK))
{
ptrSG->sr_status = statusTranslate(status);
}
dwSectorsUsed += dwNumOfSect;
}
DBGMSG(ZONE_RDWR, (TEXT("TrueFFS, doDiskIo(): Operation ended.\r\n"), ptrSG->sr_status));
return ptrSG->sr_status;
}
//----------------------------------------------------------------------------
// Function Name: mountDisk
// Purpose......: mount vloume and obtain BIOS Parameter Block (BPB)
// Returns......: status
//----------------------------------------------------------------------------
static FLStatus mountDisk(PDISK pDisk)
{
IOreq ioreq;
FLStatus status;
SectorNo capacity; // Volume size in sectors
DWORD cylinders,heads,sectors;
DBGMSG(ZONE_OPEN, (TEXT("TrueFFS, mountDisk(): [START] pDisk = 0x%x\r\n"), pDisk));
ioreq.irHandle = BSP_MDOC_USERSTORE_PARTITION_HANDLE;
status = flAbsMountVolume(&ioreq);
if (status != flOK)
{
DBGMSG(ZONE_OPEN | ZONE_ERROR, (TEXT("TrueFFS, mountDisk(): absMount failed with error %d.\r\n"), status));
return status;
}
pDisk->numberOfMounts++;
ioreq.irHandle = BSP_MDOC_USERSTORE_PARTITION_HANDLE;
status = flSectorsInVolume(&ioreq);
if (status != flOK)
{
DBGMSG(ZONE_OPEN | ZONE_ERROR, (TEXT("TrueFFS, mountDisk(): flSectorsInVolume failed with error %d.\r\n"), status));
return status;
}
capacity=ioreq.irLength;
flBuildGeometry(capacity, &cylinders, &heads, §ors, FALSE, (FLWord)ioreq.irHandle);
// copy data to pDisk->diskInfo:
pDisk->mountStatus = FL_MOUNTED;
pDisk->diskInfo.di_bytes_per_sect = FL_SECTOR_SIZE;
pDisk->diskInfo.di_heads = heads;
pDisk->diskInfo.di_sectors = sectors;
pDisk->diskInfo.di_cylinders = cylinders;
pDisk->diskInfo.di_flags = (DISK_INFO_FLAG_MBR | DISK_INFO_FLAG_PAGEABLE);
pDisk->diskInfo.di_total_sectors = heads * sectors * cylinders;
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, mountDisk(): [END], returning %d\r\n"), status));
return status;
}
//----------------------------------------------------------------------------
// Function Name: DllMain
// Purpose......: Main entry point for the DLL.
// Returns......: TRUE.
//----------------------------------------------------------------------------
BOOL WINAPI DllMain(HINSTANCE DLLinstance,
DWORD Reason,
LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
DEBUGREGISTER(DLLinstance);
DBGMSG(ZONE_DLLINIT, (TEXT("TrueFFS, TFFSdiskEntry(): TrueFFS DLL_PROCESS_ATTACH\r\n")));
// don't need thread attach/detach messages
DisableThreadLibraryCalls (DLLinstance);
return TRUE;
case DLL_PROCESS_DETACH:
flExit(); // Tell FLite to release OS recources
DBGMSG(ZONE_DLLINIT, (TEXT("TrueFFS, TFFSdiskEntry(): TrueFFS DLL_PROCESS_DETACH\r\n")));
return TRUE;
default:
return TRUE;
}
}
// ********************************************************
// *
// * Driver's interface routines exported by .DEF file
// *
// ********************************************************
//----------------------------------------------------------------------------
// Function Name: DSK_Init
// Purpose......: Initialize, create new DISK object, try to mount.
// Returns......: Pointer to DISK
//----------------------------------------------------------------------------
DWORD DSK_Init(DWORD dwContext)
{
PDISK pDisk = NULL;
DWORD keylength;
FLStatus flStatus = flOK;
IOreq ioreq;
LPWSTR pszRegPath = NULL;
LPBYTE pBuff = NULL;
DWORD retVal = 0;
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_Init\r\n")));
// Validate the caller.
//
// This driver allows only kernel mode access.
// So in order to reduce attack surface and the need to marshal embedded pointers,
// all user-mode access will be blocked here
if(GetDirectCallerProcessId() != GetCurrentProcessId())
{
SetLastError(ERROR_ACCESS_DENIED);
DBGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("TrueFFS, Init(): Received user mode request. Returning FALSE.")));
return 0;
}
pDisk = (PDISK)LocalAlloc(LPTR, sizeof(DISK));
if (NULL == pDisk)
{
goto Error;
}
memset(pDisk, 0, sizeof(DISK));
InitializeCriticalSection(&pDisk->cs);
pDisk->diskState = STATE_INITIALIZING;
pDisk->openCount = 0; // No threads have opened this disk yet
// set signature so that the structure can be validated at function entry points
pDisk->signature = TFFS_DISK_SIGNATURE;
flStatus = flInit();
if( flStatus != flOK)
{
DBGMSG(ZONE_ERROR | ZONE_INIT, (TEXT("TrueFFS, DSK_Init: flInit() failed with status %d. Exit with error.\r\n"),flStatus));
goto Error;
}
else
{
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_Init: DiskOnChip was detected (ChipID identified).\r\n")));
}
pszRegPath = (LPWSTR)LocalAlloc(LPTR, MAX_REGISTRY_PATH_SIZE * sizeof(TCHAR));
if(pszRegPath == NULL)
{
DBGMSG(ZONE_ERROR | ZONE_INIT, (TEXT("TrueFFS, DSK_Init:Failed to allocate memory for registry name.\r\n")));
goto Error;
}
if (getDeviceRegistryPath( (LPTSTR)dwContext, pszRegPath, MAX_REGISTRY_PATH_SIZE * sizeof(TCHAR)) == FALSE)
{
goto Error;
}
pDisk->registryPath = pszRegPath;
pszRegPath = NULL;
pBuff = (LPBYTE)LocalAlloc(LPTR, FL_SECTOR_SIZE+3); // ( +3 For alignment purposes)
if (pBuff == NULL)
{
DBGMSG(ZONE_ERROR | ZONE_INIT, (TEXT("TrueFFS, DSK_Init:Failed to allocate memory for internal buffer.\r\n")));
goto Error;
}
pDisk->intermediateBuf = pBuff;
pBuff = NULL;
if (getRegValue(pDisk->registryPath,(LPBYTE)&(pDisk->foldingResolution), sizeof (pDisk->foldingResolution), &keylength, FOLDING_RESOLUTION_REG_NAME)==FALSE)
{
pDisk->foldingResolution = DEFAULT_FOLDING_RESOLUTION;
DBGMSG(ZONE_ERROR | ZONE_INIT, (TEXT("TrueFFS, DSK_Init:Failed to read folding resolution from registry. Using default.\r\n")));
}
DBGMSG(ZONE_INIT, (TEXT("TrueFFS: Foldingresolution = %d\r\n"),pDisk->foldingResolution));
//Try to mount the partition in order to make sure it exists.
ioreq.irHandle = BSP_MDOC_USERSTORE_PARTITION_HANDLE;
ioreq.irFlags = 0;
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_Init: Trying to mount the partition.\r\n")));
flStatus = flAbsMountVolume(&ioreq);
if (flStatus == flOK)
{
// Make sure the media is dismounted since we don't want to mount too many times.
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_Init: Mount was done successfully. Dismounting partition and finish the initialization.\r\n")));
flStatus = flDismountVolume(&ioreq);
if(flStatus != flOK)
{
DBGMSG(ZONE_ERROR | ZONE_INIT, (TEXT("TrueFFS, DSK_INIT: Dismount failed. Exit with error.\r\n")));
goto Error;
}
}
else
{
DBGMSG(ZONE_ERROR | ZONE_INIT, (TEXT("TrueFFS, DSK_INIT: Mount of partition failed. return error for this pDisk.\r\n")));
goto Error;
}
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_INIT(): =========================\r\n")));
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_INIT(): [END] pDisk = 0x%x\r\n"), pDisk));
DBGMSG(ZONE_INIT, (TEXT("TrueFFS, DSK_INIT(): ========================\r\n")));
retVal = (DWORD)pDisk;
Error:
if (retVal == 0)
{
// Clean up everything in case for failure to init.
if (NULL != pDisk)
{
flExit();
DeleteCriticalSection(&pDisk->cs);
LocalFree(pDisk->registryPath);
LocalFree(pDisk->intermediateBuf);
LocalFree(pDisk);
LocalFree(pszRegPath);
LocalFree(pBuff);
}
}
return retVal;
}
//----------------------------------------------------------------------------
// Function Name: DSK_Open
// Purpose......: mount the volume
// Returns......: Pointer to DISK, 0 if mount failed
//----------------------------------------------------------------------------
DWORD DSK_Open(DWORD dwData, // Pointer to DISK
DWORD dwAccess, // Not used here
DWORD dwShareMode) // Not used here
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -