📄 udfsudfs.cpp
字号:
// TODO: Verrify that Read() return accurate bytes read count in all cases and do (dwBytesRead != pParentDirectoryEntry->dwDiskSize)
if (fRet == FALSE) {
goto Error;
}
dwDiskSize = pParentDirectoryEntry->dwDiskSize;
pDirectoryStart = pDiskBuffer;
pCurrentDiskDirectory = (PNSR_FID)pDiskBuffer;
if (pCurrentDiskDirectory->Destag.Ident == DESTAG_ID_NSR_FILE) {
//
// We get this if we have immediate data the previous time
// around.
//
pDirectoryStart = (PBYTE)((&(((PICBFILE)pCurrentDiskDirectory)->EAs)) + ((PICBFILE)pCurrentDiskDirectory)->EALength);
pCurrentDiskDirectory = (PNSR_FID)pDirectoryStart;
}
if (pCurrentDiskDirectory->Destag.Ident != DESTAG_ID_NSR_FID) {
SetLastError(ERROR_DISK_CORRUPT);
fRet = FALSE;
goto Error;
}
//
// Parse the structures
//
while (TRUE)
{
if (pCurrentDiskDirectory->Destag.Ident == 0)
{
//
// This generally means we've arrived at a sector boundary
//
// TODO: Clean this up
pCurrentDiskDirectory = (PNSR_FID) ((PBYTE)pDiskBuffer + (((PBYTE)pCurrentDiskDirectory - pDiskBuffer + (CD_SECTOR_SIZE-1)) & ~(CD_SECTOR_SIZE-1)));
}
if (((DWORD)pCurrentDiskDirectory) >= (((DWORD)pDirectoryStart) + dwDiskSize)) {
pCurrentCacheEntry->cbSize = 0;
break;
}
//
// If this bit is set then this is a reference to itself, a . entry
// so we skip it
//
if ((pCurrentDiskDirectory->Flags & 8) == 0) {
//
// This is very inefficient but this is what we have to do ! We have to go out and read a whole
// sector for every directory entry. This is the only way to find the file size.
//
fRet = ResolveFilePosition( pCurrentDiskDirectory->Icb.Start.Lbn + m_dwPartitionStart, pCurrentCacheEntry, &dwFileSize);
if (fRet == FALSE) {
goto Error;
}
//
// Copy information
//
if (pCurrentDiskDirectory->Flags & NSR_FID_F_DIRECTORY) {
pCurrentCacheEntry->fFlags = FILE_ATTRIBUTE_DIRECTORY;
pCurrentCacheEntry->dwDiskSize = dwFileSize;
} else {
pCurrentCacheEntry->fFlags = 0;
}
if (pCurrentDiskDirectory->Flags & NSR_FID_F_HIDDEN) {
pCurrentCacheEntry->fFlags |= FILE_ATTRIBUTE_HIDDEN;
}
pCurrentCacheEntry->pCacheLocation = NULL;
pCurrentCacheEntry->pHeader = pCacheHeader;
pCurrentCacheEntry->cbSize = ALIGN(sizeof(DIRECTORY_ENTRY) + (pCurrentDiskDirectory->FileIDLen * sizeof(WCHAR)));
//
// Copy file name
//
pStr = pCurrentDiskDirectory->ImpUse + (pCurrentDiskDirectory->ImpUseLen);
if (pStr[0] == 8) {
pCurrentCacheEntry->fFlags |= IS_ANSI_FILENAME;
pStr++;
for (count = 0; count < (pCurrentDiskDirectory->FileIDLen - 1); count++) {
pCurrentCacheEntry->szNameA[count] = pStr[count];
}
} else
if (pStr[0] == 16) {
pStr++;
for (count = 0; count < (pCurrentDiskDirectory->FileIDLen - 1); count+=2)
{
//
// convert from big to little endian
//
pCurrentCacheEntry->szNameA[count] = pStr[count+1];
pCurrentCacheEntry->szNameA[count+1] = pStr[count];
}
pCurrentCacheEntry->szNameA[count] = 0;
count++;
} else {
SetLastError(ERROR_DISK_CORRUPT);
fRet = FALSE;
goto Error;
}
pCurrentCacheEntry->szNameA[count] = 0;
//
// Update the cache endFileIDLen
//
pCurrentCacheEntry = NextDirectoryEntry(pCurrentCacheEntry);
}
//
// Move the disk cache pointer forward
//
// TODO: Clean this up
pCurrentDiskDirectory = (PNSR_FID) (((PBYTE)pCurrentDiskDirectory)+
(((DWORD)(sizeof(NSR_FID) + pCurrentDiskDirectory->ImpUseLen + pCurrentDiskDirectory->FileIDLen)) & (DWORD)(~3)));
}
Error:
UDFSFree(m_pDriver->m_hHeap, pDiskBuffer);
if (fRet == FALSE) {
UDFSFree(m_pDriver->m_hHeap, pCacheBuffer);
} else {
//
// Shrink the size of the cache entry to the actual size
//
pParentDirectoryEntry->pCacheLocation = (PDIRECTORY_ENTRY)UDFSReAlloc( m_pDriver->m_hHeap, pCacheBuffer,
((DWORD)pCurrentCacheEntry - (DWORD)pCacheBuffer) +
sizeof(pCurrentCacheEntry->cbSize));
if (!pParentDirectoryEntry->pCacheLocation) {
UDFSFree( m_pDriver->m_hHeap, pCacheBuffer);
fRet = FALSE;
}
}
return fRet;
}
//+-------------------------------------------------------------------------
//
// Member: CUDFSFileSystem::ResolveFilePosition
//
// Synopsis: udf volumes never directly point to the file or directory
// they go through a file icb first. This resolves that
// indirection.
//
// The indirection is there to support for information on the
// file, including fragmentation information, which we don't
// support.
//
// Arguments: [dwDiskLocation] --
// [pdwSector] --
// [pdwDiskSize] --
// [pInfoLength] --
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL CUDFSFileSystem::ResolveFilePosition(
DWORD dwDiskLocation,
PDIRECTORY_ENTRY pCurrentCacheEntry,
PDWORD pInfoLength)
{
BOOL fRet;
VSD_GENERIC GenericVSD;
PICBFILE pICB = (PICBFILE)&GenericVSD;
SYSTEMTIME SystemTime;
memset( pICB, 0, sizeof(1)); // Prefix
fRet = m_pDriver->ReadDisk( dwDiskLocation, (PBYTE)&GenericVSD, sizeof(VSD_GENERIC));
if (fRet == FALSE) {
return FALSE;
}
//
// Make sure we have the correct tag identifier
//
if (pICB->Destag.Ident != DESTAG_ID_NSR_FILE) {
SetLastError(ERROR_DISK_CORRUPT);
return FALSE;
}
//
// Copy the file time
//
SystemTime.wYear = pICB->ModifyTime.Year;
SystemTime.wMonth = pICB->ModifyTime.Month;
SystemTime.wDay = pICB->ModifyTime.Day;
SystemTime.wHour = pICB->ModifyTime.Hour;
SystemTime.wMinute = pICB->ModifyTime.Minute;
SystemTime.wSecond = pICB->ModifyTime.Second;
SystemTime.wMilliseconds = (pICB->ModifyTime.Usec100 / 10) + (pICB->ModifyTime.CentiSecond * 10);
SystemTimeToFileTime(&SystemTime, &pCurrentCacheEntry->Time);
//
// Make sure the size isn't too big
// If it become important to have big files we need to change the
// entry directoryentry
//
*pInfoLength = (DWORD)pICB->InfoLength;
//
// The position of the file is at the end of the structure
//
pCurrentCacheEntry->dwByteOffset = 0;
switch (pICB->Icbtag.Flags & ICBTAG_F_ALLOC_MASK) {
case ICBTAG_F_ALLOC_SHORT:
PSHORTAD pAllocation;
pAllocation = (PSHORTAD)((&(pICB->EAs)) + pICB->EALength);
//
// Update the size based on allocation structure
//
pCurrentCacheEntry->dwDiskSize = (DWORD)*pInfoLength;
pCurrentCacheEntry->dwDiskLocation = pAllocation->Start + m_dwPartitionStart;
break;
case ICBTAG_F_ALLOC_LONG:
DebugBreak();
break;
case ICBTAG_F_ALLOC_EXTENDED:
//
// EXTAD
//
DebugBreak();
break;
case ICBTAG_F_ALLOC_IMMEDIATE:
pCurrentCacheEntry->dwDiskSize = pICB->AllocLength;
*pInfoLength = pICB->AllocLength;
pCurrentCacheEntry->dwDiskLocation = dwDiskLocation;
pCurrentCacheEntry->dwByteOffset = sizeof(ICBFILE)+pICB->EALength-1;
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -