mirror of
https://github.com/reactos/reactos.git
synced 2025-07-29 13:42:33 +00:00
[BOOTMGFW]
- Additional El Torito support. We now parse the EFI, BOOT directories, and find/open the BCD file, and get a handle to it! svn path=/trunk/; revision=69189
This commit is contained in:
parent
b1114c9e93
commit
feab49d6ab
1 changed files with 487 additions and 68 deletions
|
@ -23,25 +23,26 @@ typedef struct _RAW_ET_VD
|
||||||
|
|
||||||
/* DATA VARIABLES ************************************************************/
|
/* DATA VARIABLES ************************************************************/
|
||||||
|
|
||||||
typedef struct _BL_ETFS_CONTEXT
|
typedef struct _BL_ETFS_DEVICE
|
||||||
{
|
{
|
||||||
ULONG RootDirOffset;
|
ULONG RootDirOffset;
|
||||||
ULONG RootDirSize;
|
ULONG RootDirSize;
|
||||||
ULONG BlockSize;
|
ULONG BlockSize;
|
||||||
ULONG VolumeSize;
|
ULONG VolumeSize;
|
||||||
BOOLEAN IsIso;
|
BOOLEAN IsIso;
|
||||||
PRAW_ISO_VD MemoryBlock;
|
PUCHAR MemoryBlock;
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
} BL_ETFS_CONTEXT, *PBL_ETFS_CONTEXT;
|
} BL_ETFS_DEVICE, *PBL_ETFS_DEVICE;
|
||||||
|
|
||||||
typedef struct _BL_ETFS_FILE
|
typedef struct _BL_ETFS_FILE
|
||||||
{
|
{
|
||||||
|
ULONG DirOffset;
|
||||||
|
ULONG DirEntOffset;
|
||||||
|
ULONGLONG Size;
|
||||||
|
ULONGLONG Offset;
|
||||||
|
PWCHAR FsName;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
ULONG DeviceId;
|
ULONG DeviceId;
|
||||||
ULONG Offset;
|
|
||||||
ULONG Unknown;
|
|
||||||
ULONGLONG Size;
|
|
||||||
PWCHAR FsName;
|
|
||||||
} BL_ETFS_FILE, *PBL_ETFS_FILE;
|
} BL_ETFS_FILE, *PBL_ETFS_FILE;
|
||||||
|
|
||||||
ULONG EtfsDeviceTableEntries;
|
ULONG EtfsDeviceTableEntries;
|
||||||
|
@ -62,6 +63,349 @@ BL_FILE_CALLBACKS EtfsFunctionTable =
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
EtfspGetDirectoryInfo (
|
||||||
|
_In_ PBL_ETFS_DEVICE EtfsDevice,
|
||||||
|
_In_ PRAW_DIR_REC DirEntry,
|
||||||
|
_Out_ PULONG FileOffset,
|
||||||
|
_Out_ PULONG FileSize,
|
||||||
|
_Out_opt_ PBOOLEAN IsDirectory
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG SectorOffset;
|
||||||
|
BOOLEAN IsDir;
|
||||||
|
|
||||||
|
*FileOffset = *(PULONG)DirEntry->FileLoc * EtfsDevice->BlockSize;
|
||||||
|
*FileOffset += (DirEntry->XarLen * EtfsDevice->BlockSize);
|
||||||
|
|
||||||
|
SectorOffset = ALIGN_DOWN_BY(*FileOffset, CD_SECTOR_SIZE);
|
||||||
|
|
||||||
|
*FileSize = *(PULONG)DirEntry->DataLen;
|
||||||
|
|
||||||
|
IsDir = DE_FILE_FLAGS(EtfsDevice->IsIso, DirEntry) & ISO_ATTR_DIRECTORY;
|
||||||
|
if (IsDir)
|
||||||
|
{
|
||||||
|
*FileSize += ALIGN_UP_BY(SectorOffset, CD_SECTOR_SIZE) - SectorOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsDirectory)
|
||||||
|
{
|
||||||
|
*IsDirectory = IsDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
USHORT
|
||||||
|
EtfspGetDirentNameLength (
|
||||||
|
_In_ PRAW_DIR_REC DirEntry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
USHORT Length, RealLength;
|
||||||
|
PUCHAR Pos;
|
||||||
|
|
||||||
|
RealLength = Length = DirEntry->FileIdLen;
|
||||||
|
for (Pos = &DirEntry->FileIdLen + Length; Length; --Pos)
|
||||||
|
{
|
||||||
|
--Length;
|
||||||
|
|
||||||
|
if (*Pos == ';')
|
||||||
|
{
|
||||||
|
RealLength = Length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Length = RealLength;
|
||||||
|
for (Pos = &DirEntry->FileIdLen + Length; Length; --Pos)
|
||||||
|
{
|
||||||
|
--Length;
|
||||||
|
|
||||||
|
if (*Pos != '.')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
RealLength = Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RealLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
EtfspCompareNames (
|
||||||
|
__in PSTRING Name1,
|
||||||
|
__in PUNICODE_STRING Name2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ULONG i, l1, l2, l;
|
||||||
|
|
||||||
|
l1 = Name1->Length;
|
||||||
|
l2 = Name2->Length / sizeof(WCHAR);
|
||||||
|
l = min(l1, l2);
|
||||||
|
|
||||||
|
for (i = 0; i < l; i++)
|
||||||
|
{
|
||||||
|
if (toupper(Name1->Buffer[i]) != toupper(Name2->Buffer[i]))
|
||||||
|
{
|
||||||
|
return toupper(Name1->Buffer[i]) - toupper(Name2->Buffer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l2 <= l1)
|
||||||
|
{
|
||||||
|
return l2 < l1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
EtfspFileMatch (
|
||||||
|
_In_ PRAW_DIR_REC DirEntry,
|
||||||
|
_In_ PUNICODE_STRING FileName
|
||||||
|
)
|
||||||
|
{
|
||||||
|
BOOLEAN Match;
|
||||||
|
USHORT Length;
|
||||||
|
ANSI_STRING DirName;
|
||||||
|
|
||||||
|
if ((DirEntry->FileIdLen != 1) ||
|
||||||
|
((DirEntry->FileId[0] != 0) && (DirEntry->FileId[0] != 1)))
|
||||||
|
{
|
||||||
|
Length = EtfspGetDirentNameLength(DirEntry);
|
||||||
|
DirName.Length = Length;
|
||||||
|
DirName.MaximumLength = Length;
|
||||||
|
DirName.Buffer = (PCHAR)DirEntry->FileId;
|
||||||
|
|
||||||
|
Match = EtfspCompareNames(&DirName, FileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Match = -1;
|
||||||
|
}
|
||||||
|
return Match;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
EtfspGetDirent (
|
||||||
|
_In_ PBL_FILE_ENTRY DirectoryEntry,
|
||||||
|
_Out_ PRAW_DIR_REC *DirEntry,
|
||||||
|
_Inout_ PULONG DirentOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PBL_ETFS_FILE EtfsFile;
|
||||||
|
ULONG FileOffset, DirectoryOffset, AlignedOffset, RemainderOffset;
|
||||||
|
ULONG DeviceId, ReadSize, DirLen;
|
||||||
|
PBL_ETFS_DEVICE EtfsDevice;
|
||||||
|
BOOLEAN NeedRead, IsMulti;
|
||||||
|
NTSTATUS result;
|
||||||
|
PRAW_DIR_REC DirEnt;
|
||||||
|
PUCHAR MemoryBlock;
|
||||||
|
|
||||||
|
EtfsFile = DirectoryEntry->FsSpecificData;
|
||||||
|
DeviceId = EtfsFile->DeviceId;
|
||||||
|
FileOffset = EtfsFile->Offset;
|
||||||
|
EtfsDevice = EtfsDeviceTable[DeviceId];
|
||||||
|
|
||||||
|
DirectoryOffset = *DirentOffset;
|
||||||
|
MemoryBlock = EtfsDevice->MemoryBlock;
|
||||||
|
|
||||||
|
IsMulti = 0;
|
||||||
|
|
||||||
|
AlignedOffset = (FileOffset + *DirentOffset) & ~CD_SECTOR_SIZE;
|
||||||
|
RemainderOffset = *DirentOffset + FileOffset - AlignedOffset;
|
||||||
|
|
||||||
|
ReadSize = 2048 - RemainderOffset;
|
||||||
|
NeedRead = AlignedOffset == EtfsDevice->Offset ? 0 : 1;
|
||||||
|
|
||||||
|
ReadAgain:
|
||||||
|
if (DirectoryOffset >= EtfsFile->Size)
|
||||||
|
{
|
||||||
|
return STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (ReadSize < MIN_DIR_REC_SIZE)
|
||||||
|
{
|
||||||
|
DirectoryOffset += ReadSize;
|
||||||
|
AlignedOffset += 2048;
|
||||||
|
ReadSize = 2048;
|
||||||
|
RemainderOffset = 0;
|
||||||
|
NeedRead = 1;
|
||||||
|
if (DirectoryOffset >= EtfsFile->Size)
|
||||||
|
{
|
||||||
|
return STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NeedRead)
|
||||||
|
{
|
||||||
|
result = BlDeviceReadAtOffset(DirectoryEntry->DeviceId,
|
||||||
|
CD_SECTOR_SIZE,
|
||||||
|
AlignedOffset,
|
||||||
|
MemoryBlock,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(result))
|
||||||
|
{
|
||||||
|
EfiPrintf(L"Device read failed %lx\r\n", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NeedRead = FALSE;
|
||||||
|
EtfsDevice->Offset = AlignedOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*(MemoryBlock + RemainderOffset))
|
||||||
|
{
|
||||||
|
AlignedOffset += 2048;
|
||||||
|
NeedRead = TRUE;
|
||||||
|
|
||||||
|
RemainderOffset = 0;
|
||||||
|
DirectoryOffset += ReadSize;
|
||||||
|
ReadSize = 2048;
|
||||||
|
goto ReadAgain;
|
||||||
|
}
|
||||||
|
|
||||||
|
DirEnt = (PRAW_DIR_REC)(MemoryBlock + RemainderOffset);
|
||||||
|
DirLen = DirEnt->DirLen;
|
||||||
|
if (DirLen > ReadSize)
|
||||||
|
{
|
||||||
|
EfiPrintf(L"Dir won't fit %lx %lx\r\n", DirLen, ReadSize);
|
||||||
|
return STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsMulti)
|
||||||
|
{
|
||||||
|
if (!(DE_FILE_FLAGS(EtfsDevice->IsIso, DirEnt) & ISO_ATTR_MULTI))
|
||||||
|
{
|
||||||
|
IsMulti = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DE_FILE_FLAGS(EtfsDevice->IsIso, DirEnt) & ISO_ATTR_MULTI)
|
||||||
|
{
|
||||||
|
IsMulti = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((DirEnt->FileIdLen != 1) ||
|
||||||
|
((DirEnt->FileId[0] != 0) && (DirEnt->FileId[0] != 1)))
|
||||||
|
{
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RemainderOffset += DirLen;
|
||||||
|
DirectoryOffset += DirLen;
|
||||||
|
ReadSize -= DirLen;
|
||||||
|
goto ReadAgain;
|
||||||
|
|
||||||
|
Quickie:
|
||||||
|
*DirEntry = DirEnt;
|
||||||
|
*DirentOffset = DirectoryOffset;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
EtfspSearchForDirent (
|
||||||
|
_In_ PBL_FILE_ENTRY DirectoryEntry,
|
||||||
|
_In_ PWCHAR FileName,
|
||||||
|
_Out_ PRAW_DIR_REC *DirEntry,
|
||||||
|
_Out_ PULONG DirentOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
ULONG NextOffset;
|
||||||
|
PRAW_DIR_REC DirEnt;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&Name, FileName);
|
||||||
|
for (NextOffset = *DirentOffset;
|
||||||
|
;
|
||||||
|
NextOffset = NextOffset + DirEnt->DirLen)
|
||||||
|
{
|
||||||
|
Status = EtfspGetDirent(DirectoryEntry, &DirEnt, &NextOffset);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return STATUS_NO_SUCH_FILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EtfspFileMatch(DirEnt, &Name))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*DirEntry = DirEnt;
|
||||||
|
*DirentOffset = NextOffset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
EtfspCachedSearchForDirent (
|
||||||
|
_In_ PBL_FILE_ENTRY DirectoryEntry,
|
||||||
|
_In_ PWCHAR FileName,
|
||||||
|
_Out_ PRAW_DIR_REC *DirEntry,
|
||||||
|
_Out_ PULONG DirOffset,
|
||||||
|
_In_ BOOLEAN KeepOffset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
PBL_ETFS_FILE EtfsFile;
|
||||||
|
PBL_ETFS_DEVICE EtfsDevice;
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG DirentOffset;
|
||||||
|
PRAW_DIR_REC Dirent;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
|
||||||
|
EtfsFile = DirectoryEntry->FsSpecificData;
|
||||||
|
EtfsDevice = EtfsDeviceTable[EtfsFile->DeviceId];
|
||||||
|
RtlInitUnicodeString(&Name, FileName);
|
||||||
|
DirentOffset = EtfsFile->DirEntOffset;
|
||||||
|
|
||||||
|
if ((KeepOffset) ||
|
||||||
|
(ALIGN_DOWN_BY((DirentOffset + EtfsFile->Offset), CD_SECTOR_SIZE) ==
|
||||||
|
EtfsDevice->Offset))
|
||||||
|
{
|
||||||
|
Status = EtfspGetDirent(DirectoryEntry, &Dirent, &DirentOffset);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (!EtfspFileMatch(Dirent, &Name))
|
||||||
|
{
|
||||||
|
*DirEntry = Dirent;
|
||||||
|
*DirOffset = DirentOffset;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DirentOffset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DirentOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = EtfspSearchForDirent(DirectoryEntry,
|
||||||
|
FileName,
|
||||||
|
DirEntry,
|
||||||
|
&DirentOffset);
|
||||||
|
if (!(NT_SUCCESS(Status)) && (DirentOffset))
|
||||||
|
{
|
||||||
|
DirentOffset = 0;
|
||||||
|
Status = EtfspSearchForDirent(DirectoryEntry,
|
||||||
|
FileName,
|
||||||
|
DirEntry,
|
||||||
|
&DirentOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
*DirOffset = DirentOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EtfsOpen (
|
EtfsOpen (
|
||||||
_In_ PBL_FILE_ENTRY Directory,
|
_In_ PBL_FILE_ENTRY Directory,
|
||||||
|
@ -70,13 +414,112 @@ EtfsOpen (
|
||||||
_Out_ PBL_FILE_ENTRY *FileEntry
|
_Out_ PBL_FILE_ENTRY *FileEntry
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EfiPrintf(L"Attempting to open file %s in directory %s. Not yet supported\r\n", FileName, Directory->FilePath);
|
PBL_ETFS_DEVICE EtfsDevice;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
NTSTATUS Status;
|
||||||
|
PBL_FILE_ENTRY NewFile;
|
||||||
|
PWCHAR FilePath, FormatString;
|
||||||
|
PBL_ETFS_FILE EtfsFile;
|
||||||
|
ULONG DeviceId, FileSize, DirOffset, FileOffset, Size;
|
||||||
|
PRAW_DIR_REC DirEntry;
|
||||||
|
BOOLEAN IsDirectory;
|
||||||
|
|
||||||
|
EfiPrintf(L"Attempting to open file %s in directory %s\r\n", FileName, Directory->FilePath);
|
||||||
|
|
||||||
|
EtfsFile = Directory->FsSpecificData;
|
||||||
|
DeviceId = EtfsFile->DeviceId;
|
||||||
|
EtfsDevice = EtfsDeviceTable[DeviceId];
|
||||||
|
|
||||||
|
/* Find the given file (or directory) in the given directory */
|
||||||
|
Status = EtfspCachedSearchForDirent(Directory,
|
||||||
|
FileName,
|
||||||
|
&DirEntry,
|
||||||
|
&DirOffset,
|
||||||
|
FALSE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
EfiPrintf(L"no dirent found: %lx\r\n", Status);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find out information about the file (or directory) we found */
|
||||||
|
EtfspGetDirectoryInfo(EtfsDevice,
|
||||||
|
DirEntry,
|
||||||
|
&FileOffset,
|
||||||
|
&FileSize,
|
||||||
|
&IsDirectory);
|
||||||
|
|
||||||
|
NewFile = BlMmAllocateHeap(sizeof(*NewFile));
|
||||||
|
if (!NewFile)
|
||||||
|
{
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
RtlZeroMemory(NewFile, sizeof(*NewFile));
|
||||||
|
|
||||||
|
Size = wcslen(Directory->FilePath) + wcslen(FileName) + 2;
|
||||||
|
|
||||||
|
FilePath = BlMmAllocateHeap(Size * sizeof(WCHAR));
|
||||||
|
if (!FilePath)
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
EtfsFile = (PBL_ETFS_FILE)BlMmAllocateHeap(sizeof(*EtfsFile));
|
||||||
|
if (!EtfsFile)
|
||||||
|
{
|
||||||
|
Status = STATUS_NO_MEMORY;
|
||||||
|
goto Quickie;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(NewFile, sizeof(*EtfsFile));
|
||||||
|
|
||||||
|
NewFile->DeviceId = Directory->DeviceId;
|
||||||
|
FormatString = L"%ls%ls";
|
||||||
|
if (Directory->FilePath[1])
|
||||||
|
{
|
||||||
|
FormatString = L"%ls\\%ls";
|
||||||
|
}
|
||||||
|
|
||||||
|
_snwprintf(FilePath, Size, FormatString, Directory->FilePath, FileName);
|
||||||
|
NewFile->FilePath = FilePath;
|
||||||
|
|
||||||
|
RtlCopyMemory(&NewFile->Callbacks,
|
||||||
|
&EtfsFunctionTable,
|
||||||
|
sizeof(NewFile->Callbacks));
|
||||||
|
EtfsFile->Offset = FileOffset;
|
||||||
|
EtfsFile->DirOffset = DirOffset;
|
||||||
|
EtfsFile->Size = FileSize;
|
||||||
|
EtfsFile->DeviceId = DeviceId;
|
||||||
|
if (IsDirectory)
|
||||||
|
{
|
||||||
|
EtfsFile->Flags |= 1;
|
||||||
|
NewFile->Flags |= 0x10000;
|
||||||
|
}
|
||||||
|
EtfsFile->FsName = L"cdfs";
|
||||||
|
|
||||||
|
NewFile->FsSpecificData = EtfsFile;
|
||||||
|
*FileEntry = NewFile;
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Quickie:
|
||||||
|
|
||||||
|
if (NewFile->FilePath)
|
||||||
|
{
|
||||||
|
BlMmFreeHeap(NewFile->FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NewFile->FsSpecificData)
|
||||||
|
{
|
||||||
|
BlMmFreeHeap(NewFile->FsSpecificData);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlMmFreeHeap(NewFile);
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EtfspCheckCdfs (
|
EtfspCheckCdfs (
|
||||||
_In_ PBL_ETFS_CONTEXT EtfsContext,
|
_In_ PBL_ETFS_DEVICE EtfsDevice,
|
||||||
_In_ ULONG DeviceId,
|
_In_ ULONG DeviceId,
|
||||||
_Out_ PRAW_ISO_VD *VolumeDescriptor,
|
_Out_ PRAW_ISO_VD *VolumeDescriptor,
|
||||||
_Out_ PBOOLEAN VolumeIsIso
|
_Out_ PBOOLEAN VolumeIsIso
|
||||||
|
@ -88,7 +531,7 @@ EtfspCheckCdfs (
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EtfspCheckEtfs (
|
EtfspCheckEtfs (
|
||||||
_In_ PBL_ETFS_CONTEXT EtfsContext,
|
_In_ PBL_ETFS_DEVICE EtfsDevice,
|
||||||
_In_ ULONG DeviceId,
|
_In_ ULONG DeviceId,
|
||||||
_Out_ PRAW_ISO_VD *VolumeDescriptor,
|
_Out_ PRAW_ISO_VD *VolumeDescriptor,
|
||||||
_Out_ PBOOLEAN VolumeIsIso
|
_Out_ PBOOLEAN VolumeIsIso
|
||||||
|
@ -103,7 +546,7 @@ EtfspCheckEtfs (
|
||||||
ANSI_STRING CompareString, String;
|
ANSI_STRING CompareString, String;
|
||||||
|
|
||||||
/* Save our static buffer pointer */
|
/* Save our static buffer pointer */
|
||||||
IsoVd = EtfsContext->MemoryBlock;
|
IsoVd = (PRAW_ISO_VD)EtfsDevice->MemoryBlock;
|
||||||
EtVd = (PRAW_ET_VD)IsoVd;
|
EtVd = (PRAW_ET_VD)IsoVd;
|
||||||
|
|
||||||
/* First, read the El Torito Volume Descriptor */
|
/* First, read the El Torito Volume Descriptor */
|
||||||
|
@ -114,7 +557,7 @@ EtfspCheckEtfs (
|
||||||
Status = BlDeviceReadAtOffset(DeviceId,
|
Status = BlDeviceReadAtOffset(DeviceId,
|
||||||
CD_SECTOR_SIZE,
|
CD_SECTOR_SIZE,
|
||||||
(FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE,
|
(FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE,
|
||||||
EtfsContext->MemoryBlock,
|
EtfsDevice->MemoryBlock,
|
||||||
&BytesRead);
|
&BytesRead);
|
||||||
DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
|
DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
|
||||||
BlDeviceSetInformation(DeviceId, &DeviceInformation);
|
BlDeviceSetInformation(DeviceId, &DeviceInformation);
|
||||||
|
@ -125,7 +568,7 @@ EtfspCheckEtfs (
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember that's where we last read */
|
/* Remember that's where we last read */
|
||||||
EtfsContext->Offset = (FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE;
|
EtfsDevice->Offset = (FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE;
|
||||||
|
|
||||||
/* Check if it's EL TORITO! */
|
/* Check if it's EL TORITO! */
|
||||||
RtlInitString(&String, "EL TORITO SPECIFICATION");
|
RtlInitString(&String, "EL TORITO SPECIFICATION");
|
||||||
|
@ -159,7 +602,7 @@ EtfspCheckEtfs (
|
||||||
Status = BlDeviceReadAtOffset(DeviceId,
|
Status = BlDeviceReadAtOffset(DeviceId,
|
||||||
CD_SECTOR_SIZE,
|
CD_SECTOR_SIZE,
|
||||||
FIRST_VD_SECTOR * CD_SECTOR_SIZE,
|
FIRST_VD_SECTOR * CD_SECTOR_SIZE,
|
||||||
EtfsContext->MemoryBlock,
|
EtfsDevice->MemoryBlock,
|
||||||
&BytesRead);
|
&BytesRead);
|
||||||
DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
|
DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
|
||||||
BlDeviceSetInformation(DeviceId, &DeviceInformation);
|
BlDeviceSetInformation(DeviceId, &DeviceInformation);
|
||||||
|
@ -169,7 +612,7 @@ EtfspCheckEtfs (
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remember where we left off */
|
/* Remember where we left off */
|
||||||
EtfsContext->Offset = FIRST_VD_SECTOR * CD_SECTOR_SIZE;
|
EtfsDevice->Offset = FIRST_VD_SECTOR * CD_SECTOR_SIZE;
|
||||||
|
|
||||||
/* This should also say CD0001 */
|
/* This should also say CD0001 */
|
||||||
CompareString.Buffer = (PCHAR)IsoVd->StandardId;
|
CompareString.Buffer = (PCHAR)IsoVd->StandardId;
|
||||||
|
@ -194,63 +637,34 @@ EtfspCheckEtfs (
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
EtfspGetDirectoryInfo (
|
|
||||||
_In_ PBL_ETFS_CONTEXT EtfsContext,
|
|
||||||
_In_ PRAW_DIR_REC DirEntry,
|
|
||||||
_Out_ PULONG FileOffset,
|
|
||||||
_Out_ PULONG FileSize,
|
|
||||||
_Out_opt_ PBOOLEAN IsDirectory
|
|
||||||
)
|
|
||||||
{
|
|
||||||
ULONG SectorOffset;
|
|
||||||
BOOLEAN IsDir;
|
|
||||||
|
|
||||||
*FileOffset = *(PULONG)DirEntry->FileLoc * EtfsContext->BlockSize;
|
|
||||||
*FileOffset += (DirEntry->XarLen * EtfsContext->BlockSize);
|
|
||||||
|
|
||||||
SectorOffset = ALIGN_DOWN_BY(*FileOffset, CD_SECTOR_SIZE);
|
|
||||||
|
|
||||||
*FileSize = *(PULONG)DirEntry->DataLen;
|
|
||||||
|
|
||||||
IsDir = DE_FILE_FLAGS(EtfsContext->IsIso, DirEntry) & ISO_ATTR_DIRECTORY;
|
|
||||||
if (IsDir)
|
|
||||||
{
|
|
||||||
*FileSize += ALIGN_UP_BY(SectorOffset, CD_SECTOR_SIZE) - SectorOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsDirectory)
|
|
||||||
{
|
|
||||||
*IsDirectory = IsDir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EtfspDeviceContextDestroy (
|
EtfspDeviceContextDestroy (
|
||||||
_In_ PBL_ETFS_CONTEXT EtfsContext
|
_In_ PBL_ETFS_DEVICE EtfsDevice
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (EtfsContext->MemoryBlock)
|
if (EtfsDevice->MemoryBlock)
|
||||||
{
|
{
|
||||||
BlMmFreeHeap(EtfsContext->MemoryBlock);
|
BlMmFreeHeap(EtfsDevice->MemoryBlock);
|
||||||
}
|
}
|
||||||
BlMmFreeHeap(EtfsContext);
|
|
||||||
return 0;
|
BlMmFreeHeap(EtfsDevice);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EtfspCreateContext (
|
EtfspCreateContext (
|
||||||
_In_ ULONG DeviceId,
|
_In_ ULONG DeviceId,
|
||||||
_Out_ PBL_ETFS_CONTEXT *EtfsContext
|
_Out_ PBL_ETFS_DEVICE *EtfsDevice
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PBL_ETFS_CONTEXT NewContext;
|
PBL_ETFS_DEVICE NewContext;
|
||||||
PVOID MemoryBlock;
|
PVOID MemoryBlock;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOLEAN IsIso;
|
BOOLEAN IsIso;
|
||||||
PRAW_ISO_VD RawVd;
|
PRAW_ISO_VD RawVd;
|
||||||
|
|
||||||
NewContext = (PBL_ETFS_CONTEXT)BlMmAllocateHeap(sizeof(*NewContext));
|
NewContext = (PBL_ETFS_DEVICE)BlMmAllocateHeap(sizeof(*NewContext));
|
||||||
if (!NewContext)
|
if (!NewContext)
|
||||||
{
|
{
|
||||||
return STATUS_NO_MEMORY;
|
return STATUS_NO_MEMORY;
|
||||||
|
@ -287,22 +701,26 @@ EtfspCreateContext (
|
||||||
&NewContext->RootDirOffset,
|
&NewContext->RootDirOffset,
|
||||||
&NewContext->RootDirSize,
|
&NewContext->RootDirSize,
|
||||||
0);
|
0);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
Quickie:
|
Quickie:
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
EtfspDeviceContextDestroy(NewContext);
|
EtfspDeviceContextDestroy(NewContext);
|
||||||
NewContext = NULL;
|
NewContext = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
*EtfsContext = NewContext;
|
*EtfsDevice = NewContext;
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
EtfspDeviceTableDestroyEntry (
|
EtfspDeviceTableDestroyEntry (
|
||||||
_In_ PBL_ETFS_CONTEXT EtfsContext,
|
_In_ PBL_ETFS_DEVICE EtfsDevice,
|
||||||
_In_ ULONG Index
|
_In_ ULONG Index
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EtfspDeviceContextDestroy(EtfsContext);
|
EtfspDeviceContextDestroy(EtfsDevice);
|
||||||
EtfsDeviceTable[Index] = NULL;
|
EtfsDeviceTable[Index] = NULL;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
@ -315,14 +733,14 @@ EtfsMount (
|
||||||
_Out_ PBL_FILE_ENTRY* FileEntry
|
_Out_ PBL_FILE_ENTRY* FileEntry
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PBL_ETFS_CONTEXT EtfsContext = NULL;
|
PBL_ETFS_DEVICE EtfsDevice = NULL;
|
||||||
PBL_FILE_ENTRY RootEntry;
|
PBL_FILE_ENTRY RootEntry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PBL_ETFS_FILE EtfsFile;
|
PBL_ETFS_FILE EtfsFile;
|
||||||
|
|
||||||
EfiPrintf(L"Trying to mount as ETFS...\r\n");
|
EfiPrintf(L"Trying to mount as ETFS...\r\n");
|
||||||
|
|
||||||
Status = EtfspCreateContext(DeviceId, &EtfsContext);
|
Status = EtfspCreateContext(DeviceId, &EtfsDevice);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
EfiPrintf(L"ETFS context failed: %lx\r\n");
|
EfiPrintf(L"ETFS context failed: %lx\r\n");
|
||||||
|
@ -331,12 +749,12 @@ EtfsMount (
|
||||||
|
|
||||||
Status = BlTblSetEntry(&EtfsDeviceTable,
|
Status = BlTblSetEntry(&EtfsDeviceTable,
|
||||||
&EtfsDeviceTableEntries,
|
&EtfsDeviceTableEntries,
|
||||||
EtfsContext,
|
EtfsDevice,
|
||||||
&DeviceId,
|
&DeviceId,
|
||||||
TblDoNotPurgeEntry);
|
TblDoNotPurgeEntry);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
EtfspDeviceContextDestroy(EtfsContext);
|
EtfspDeviceContextDestroy(EtfsDevice);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,9 +794,10 @@ EtfsMount (
|
||||||
RootEntry->FsSpecificData = EtfsFile;
|
RootEntry->FsSpecificData = EtfsFile;
|
||||||
EtfsFile->DeviceId = DeviceId;
|
EtfsFile->DeviceId = DeviceId;
|
||||||
EtfsFile->Flags |= 1;
|
EtfsFile->Flags |= 1;
|
||||||
EtfsFile->Offset = EtfsContext->RootDirOffset;
|
EtfsFile->Offset = EtfsDevice->RootDirOffset;
|
||||||
EtfsFile->Unknown = 0;
|
EtfsFile->DirOffset = 0;
|
||||||
EtfsFile->Size = EtfsContext->RootDirSize;
|
EtfsFile->Size = EtfsDevice->RootDirSize;
|
||||||
|
EfiPrintf(L"Root offset: %I64x Size: %I64x\r\n", EtfsFile->Offset, EtfsFile->Size);
|
||||||
EtfsFile->FsName = L"cdfs";
|
EtfsFile->FsName = L"cdfs";
|
||||||
*FileEntry = RootEntry;
|
*FileEntry = RootEntry;
|
||||||
|
|
||||||
|
@ -398,7 +817,7 @@ Quickie:
|
||||||
BlMmFreeHeap(RootEntry);
|
BlMmFreeHeap(RootEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
EtfspDeviceTableDestroyEntry(EtfsContext, DeviceId);
|
EtfspDeviceTableDestroyEntry(EtfsDevice, DeviceId);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue