📄 udfsudfs.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//+-------------------------------------------------------------------------
//
//
// File:
// udfsudfs.cpp
//
// Contents:
// UDFS specific methods
//
// Classes:
// CUDFSFileSystem
//
// Functions:
//
//--------------------------------------------------------------------------
#include "udfs.h"
//+-------------------------------------------------------------------------
//
// Member: CUDFSFileSystem::DetectCreateAndInit
//
// Synopsis: Detects a udf volume
//
// Arguments: [pCache] --
// [pRootDirectoryPointer] --
// [ppNewFS] --
//
// Returns: BOOL
//
// Notes:
//
//--------------------------------------------------------------------------
BYTE CUDFSFileSystem::DetectCreateAndInit( PUDFSDRIVER pDrv, PDIRECTORY_ENTRY pRootDirectoryPointer, CFileSystem** ppNewFS)
{
NSR_ANCHOR Anchor;
VSD_GENERIC GenericVSD;
BOOL fRet;
DWORD dwSector;
DWORD dwPartitionStart = (DWORD)-1;
DWORD dwVolumeStart = (DWORD)-1;
DWORD dwDiskSize;
DWORD dwBytesRead;
DWORD dwSectorOffset;
PNSR_FSD pFSD;
BOOL fUnicodeFileSystem = FALSE; // TODO:
CUDFSFileSystem* pUDFS;
//
// TODO: Add more checks to this code later
//
memset( &Anchor, 0, sizeof(1)); // Prefix
memset( &GenericVSD, 0, sizeof(1)); // Prefix
fRet = pDrv->Read( ANCHOR_SECTOR, 0, sizeof(NSR_ANCHOR), (PBYTE)&Anchor, &dwBytesRead, NULL);
if ((fRet == FALSE) || (Anchor.Destag.Ident != DESTAG_ID_NSR_ANCHOR)) {
return FALSE;
}
dwSector = Anchor.Main.Lsn;
//
// Track down the important structures:
// logical volume identifier
// partition descriptor
//
dwSectorOffset = 0;
do
{
fRet = pDrv->Read( dwSector + dwSectorOffset, 0, sizeof(VSD_GENERIC), (PBYTE)&GenericVSD, &dwBytesRead, NULL);
if (fRet == FALSE) {
return FALSE;
}
if (GenericVSD.Type == DESTAG_ID_NSR_PART) {
dwPartitionStart = ((PNSR_PART)&GenericVSD)->Start;
}
if (GenericVSD.Type == DESTAG_ID_NSR_LVOL) {
dwVolumeStart = ((PNSR_LVOL)&GenericVSD)->FSD.Start.Lbn;
}
//
// If we've found both items we where looking for then
// terminate the loop
//
if ((dwVolumeStart != (DWORD)-1) && (dwPartitionStart != (DWORD)-1)) {
break;
}
dwSectorOffset ++;
} while ((GenericVSD.Type != DESTAG_ID_NSR_TERM) || (dwSectorOffset < 20));
//
// If we didn't find the logical volume descriptor then bail.
//
if ((dwVolumeStart == (DWORD)-1) || (dwPartitionStart == (DWORD)-1)) {
return FALSE;
}
//
// Find the pointer to the fsd in the logical volume desc.
//
dwSector = dwVolumeStart + dwPartitionStart;
fRet = pDrv->Read( dwSector, 0, sizeof(VSD_GENERIC), (PBYTE)&GenericVSD, &dwBytesRead, NULL);
if (fRet == FALSE) {
return FALSE;
}
pFSD = (PNSR_FSD)&GenericVSD ;
pUDFS = new CUDFSFileSystem(pDrv);
if (pUDFS == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
//
// Make the partition start in the class. All sector values have to
// be offset by this value.
//
pUDFS->m_dwPartitionStart = dwPartitionStart;
fRet = pUDFS->ResolveFilePosition( pFSD->IcbRoot.Start.Lbn + dwPartitionStart, pRootDirectoryPointer, &dwDiskSize);
if (fRet == FALSE) {
delete pUDFS;
return FALSE;
}
// Save Volume Id used for Volume Registration
// pFSD->VolID[1] is probably wrong ?????
// Check structure definition in include fike!!!!!!
//
// Also fUnicodeFileSystem should be properly set according
// DiskInfo!!!!
pDrv->SaveRootName((PCHAR)&pFSD->VolID[1],fUnicodeFileSystem);
//
// The location of the root directory is specified in the IcbRoot
// member of the FSD
//
pRootDirectoryPointer->cbSize = sizeof(DIRECTORY_ENTRY);
pRootDirectoryPointer->pCacheLocation = NULL;
(*ppNewFS) = pUDFS;
return fRet;
}
//+-------------------------------------------------------------------------
//
// Member: CUDFSFileSystem::ReadDirectory
//
// Synopsis: Reads in a udf directory structure and parses the
// information into a the standard directory structures
//
// Arguments: [pszFullPath] --
// [pParentDirectoryEntry] --
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL CUDFSFileSystem::ReadDirectory( LPWSTR pszFullPath, PDIRECTORY_ENTRY pParentDirectoryEntry)
{
PNSR_FID pCurrentDiskDirectory;
PDIRECTORY_ENTRY pCurrentCacheEntry;
PDIRECTORY_HEADER pCacheHeader;
PBYTE pDiskBuffer;
PBYTE pDirectoryStart;
PBYTE pCacheBuffer;
BOOL fRet;
int count;
PUCHAR pStr;
DWORD dwDiskSize;
DWORD dwSector;
DWORD dwFileSize;
DWORD dwBytesRead;
//
// We only get to this point if this node has not been cached.
//
DEBUGCHK(pParentDirectoryEntry->pCacheLocation == NULL);
dwDiskSize = pParentDirectoryEntry->dwDiskSize;
dwSector = pParentDirectoryEntry->dwDiskLocation;
//
// Allocate enough memory to read the entire directory
//
if (dwDiskSize < CD_SECTOR_SIZE) {
dwDiskSize = CD_SECTOR_SIZE;
}
ASSERT(m_pDriver);
pDiskBuffer = (PBYTE)UDFSAlloc(m_pDriver->m_hHeap, dwDiskSize);
if (pDiskBuffer == NULL) {
//
// shrink our cache
//
CompactAllHeaps();
pDiskBuffer = (PBYTE)UDFSAlloc(m_pDriver->m_hHeap, dwDiskSize);
if (pDiskBuffer == NULL) {
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
}
//
// Allocate more than enough memory
//
pCacheBuffer = (PBYTE)UDFSAlloc(m_pDriver->m_hHeap, dwDiskSize * 5);
if (pCacheBuffer == NULL) {
CompactAllHeaps();
pCacheBuffer = (PBYTE)UDFSAlloc(m_pDriver->m_hHeap, dwDiskSize * 5);
if (pCacheBuffer == NULL) {
UDFSFree(m_pDriver->m_hHeap, pDiskBuffer);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
}
//
// Create the header
//
pCacheHeader = (PDIRECTORY_HEADER)pCacheBuffer;
pCacheHeader->cbSize = ALIGN(sizeof(DIRECTORY_HEADER) + (lstrlen(pszFullPath) * sizeof(WCHAR)));
pCacheHeader->dwLockCount = 1;
pCacheHeader->pParent = pParentDirectoryEntry;
memcpy(&(pCacheHeader->Signature), DIR_HEADER_SIGNATURE, sizeof(pCacheHeader->Signature));
lstrcpy(pCacheHeader->szFullPath, pszFullPath);
pCurrentCacheEntry = (PDIRECTORY_ENTRY)(pCacheBuffer + pCacheHeader->cbSize);
if (pCacheBuffer == NULL) {
//
// TODO: shrink our cache
//
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
fRet = FALSE;
goto Error;
}
fRet = m_pDriver->Read( dwSector, 0, dwDiskSize, pDiskBuffer, &dwBytesRead, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -