Author: ion Date: Thu Sep 10 04:01:41 2015 New Revision: 69165
URL: http://svn.reactos.org/svn/reactos?rev=69165&view=rev Log: [BOOTMGFW] - Implement initial File I/O routines. - We now die on attempting to mount the FAT volume.
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c trunk/reactos/boot/environ/include/bl.h trunk/reactos/boot/environ/lib/io/device.c trunk/reactos/boot/environ/lib/io/fat.c trunk/reactos/boot/environ/lib/io/file.c
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/bo... ============================================================================== --- trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] Thu Sep 10 04:01:41 2015 @@ -180,8 +180,7 @@
/* Try to open the file */ EfiPrintf(L"Opening: %s\r\n", FinalPath); -#if 0 - Status = BlFileOpen(DeviceHandle, FinalPath, 1u, &FileHandle); + Status = BlFileOpen(DeviceHandle, FinalPath, 1, &FileHandle); if (!NT_SUCCESS(Status)) { BootDirectory = BcdDirectory; @@ -189,7 +188,6 @@ }
BootDirectory = L"\EFI\Microsoft\Boot"; -#endif
Quickie: /* Free all the allocations we made */ @@ -205,7 +203,7 @@ /* Close the BCD file */ if (FileHandle != -1) { - //Status = BlFileClose(FileHandle); + Status = BlFileClose(FileHandle); }
/* Close the boot device */
Modified: trunk/reactos/boot/environ/include/bl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?r... ============================================================================== --- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original) +++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Thu Sep 10 04:01:41 2015 @@ -265,6 +265,52 @@
/* CALLBACKS *****************************************************************/
+struct _BL_FILE_ENTRY; +typedef +NTSTATUS +(*PBL_FILE_OPEN) ( + _In_ struct _BL_FILE_ENTRY* ParentFileEntry, + _In_ PWCHAR FileName, + _In_ ULONG OpenFlags, + _Out_ struct _BL_FILE_ENTRY** FileEntry + ); + +typedef +NTSTATUS +(*PBL_FILE_CLOSE) ( + _In_ struct _BL_FILE_ENTRY* FileEntry + ); + +typedef +NTSTATUS +(*PBL_FILE_READ) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_FILE_WRITE) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_FILE_GET_NEXT) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_FILE_GET_INFO) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_FILE_SET_INFO) ( + VOID + ); + typedef NTSTATUS (*PBL_FS_INIT_CALLBACK) ( @@ -280,7 +326,9 @@ typedef NTSTATUS (*PBL_FS_MOUNT_CALLBACK) ( - VOID + _In_ ULONG DeviceId, + _In_ ULONG Unknown, + _Out_ struct _BL_FILE_ENTRY** FileEntry );
typedef @@ -397,6 +445,73 @@ _In_ struct _BL_HASH_ENTRY* Entry, _In_ ULONG TableSize ); + +struct _BL_DEVICE_ENTRY; +struct _BL_DEVICE_DESCRIPTOR; +struct _BL_DEVICE_INFORMATION; + +typedef +NTSTATUS +(*PBL_DEVICE_ENUMERATE_DEVICE_CLASS) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_DEVICE_OPEN) ( + _In_ struct _BL_DEVICE_DESCRIPTOR* Device, + _In_ struct _BL_DEVICE_ENTRY* DeviceEntry + ); + +typedef +NTSTATUS +(*PBL_DEVICE_CLOSE) ( + _In_ struct _BL_DEVICE_ENTRY* DeviceEntry + ); + +typedef +NTSTATUS +(*PBL_DEVICE_READ) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_DEVICE_WRITE) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_DEVICE_GET_INFORMATION) ( + _In_ struct _BL_DEVICE_ENTRY* DeviceEntry, + _Out_ struct _BL_DEVICE_INFORMATION* DeviceInformation + ); + +typedef +NTSTATUS +(*PBL_DEVICE_SET_INFORMATION) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_DEVICE_RESET) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_DEVICE_FLUSH) ( + VOID + ); + +typedef +NTSTATUS +(*PBL_DEVICE_CREATE) ( + VOID + ); +
/* DATA STRUCTURES ***********************************************************/
@@ -626,9 +741,28 @@ ULONGLONG Maximum; } BL_ADDRESS_RANGE, *PBL_ADDRESS_RANGE;
+typedef struct _BL_FILE_CALLBACKS +{ + PBL_FILE_OPEN Open; + PBL_FILE_CLOSE Close; + PBL_FILE_READ Read; + PBL_FILE_WRITE Write; + PBL_FILE_GET_NEXT GetNext; + PBL_FILE_GET_INFO GetInfo; + PBL_FILE_SET_INFO SetInfo; +} BL_FILE_CALLBACKS, *PBL_FILE_CALLBACKS; + typedef struct _BL_FILE_ENTRY { - ULONG DeviceIndex; + ULONG ReferenceCount; + ULONG FileId; + ULONG DeviceId; + ULONG Flags; + PWCHAR FilePath; + ULONG Unknown; + ULONG Unknown1; + ULONG Unknown2; + BL_FILE_CALLBACKS Callbacks; PBL_FILE_DESTROY_CALLBACK DestroyCallback; } BL_FILE_ENTRY, *PBL_FILE_ENTRY;
@@ -752,7 +886,7 @@ BL_HASH_VALUE Value; } BL_HASH_NODE, *PBL_HASH_NODE;
-typedef struct _BL_BLOCK_DEVICE +typedef struct _BL_BLOCK_DEVICE_INFORMATION { BL_LOCAL_DEVICE_TYPE Type; ULONG DeviceFlags; @@ -774,6 +908,20 @@ } Gpt; }; } Disk; +} BL_BLOCK_DEVICE_INFORMATION, *PBL_BLOCK_DEVICE_INFORMATION; + +typedef struct _BL_DEVICE_INFORMATION +{ + BL_DEVICE_TYPE DeviceType; + union + { + BL_BLOCK_DEVICE_INFORMATION BlockDeviceInfo; + }; +} BL_DEVICE_INFORMATION, *PBL_DEVICE_INFORMATION; + +typedef struct _BL_BLOCK_DEVICE +{ + BL_BLOCK_DEVICE_INFORMATION; ULONGLONG LastBlock; EFI_BLOCK_IO* Protocol; EFI_HANDLE Handle; @@ -784,6 +932,31 @@ EFI_HANDLE Handle; PVOID Interface; } BL_PROTOCOL_HANDLE, *PBL_PROTOCOL_HANDLE; + +typedef struct _BL_DEVICE_CALLBACKS +{ + PBL_DEVICE_ENUMERATE_DEVICE_CLASS EnumerateDeviceClass; + PBL_DEVICE_OPEN Open; + PBL_DEVICE_CLOSE Close; + PBL_DEVICE_READ Read; + PBL_DEVICE_WRITE Write; + PBL_DEVICE_GET_INFORMATION GetInformation; + PBL_DEVICE_SET_INFORMATION SetInformation; + PBL_DEVICE_RESET Reset; + PBL_DEVICE_FLUSH Flush; + PBL_DEVICE_CREATE Create; +} BL_DEVICE_CALLBACKS, *PBL_DEVICE_CALLBACKS; + +typedef struct _BL_DEVICE_ENTRY +{ + ULONG DeviceId; + ULONG Flags; + ULONG Unknown; + ULONG ReferenceCount; + BL_DEVICE_CALLBACKS Callbacks; + PVOID DeviceSpecificData; + PBL_DEVICE_DESCRIPTOR DeviceDescriptor; +} BL_DEVICE_ENTRY, *PBL_DEVICE_ENTRY;
/* INLINE ROUTINES ***********************************************************/
@@ -894,11 +1067,6 @@ );
NTSTATUS -FatInitialize ( - VOID - ); - -NTSTATUS BlpDisplayInitialize ( _In_ ULONG Flags ); @@ -1034,6 +1202,20 @@ NTSTATUS BlpTimeCalibratePerformanceCounter ( VOID + ); + +/* FILESYSTEM ROUTINES *******************************************************/ + +NTSTATUS +FatInitialize ( + VOID + ); + +NTSTATUS +FatMount ( + _In_ ULONG DeviceId, + _In_ ULONG Unknown, + _Out_ PBL_FILE_ENTRY* FileEntry );
/* UTILITY ROUTINES **********************************************************/ @@ -1293,6 +1475,27 @@ _In_ ULONG Flags, _In_ ULONG Unknown, _Out_ PULONG DeviceId + ); + +NTSTATUS +BlDeviceGetInformation ( + _In_ ULONG DeviceId, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ); + +/* FILE I/O ROUTINES *********************************************************/ + +NTSTATUS +BlFileClose ( + _In_ ULONG FileId + ); + +NTSTATUS +BlFileOpen ( + _In_ ULONG DeviceId, + _In_ PWCHAR FileName, + _In_ ULONG OpenFlags, + _Out_ PULONG FileId );
/* TEXT CONSOLE ROUTINES *****************************************************/
Modified: trunk/reactos/boot/environ/lib/io/device.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/io/device.... ============================================================================== --- trunk/reactos/boot/environ/lib/io/device.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/io/device.c [iso-8859-1] Thu Sep 10 04:01:41 2015 @@ -12,110 +12,22 @@
/* DATA VARIABLES ************************************************************/
-typedef struct _BL_DEVICE_INFORMATION +typedef struct _BL_DEVICE_IO_INFORMATION { ULONG Unknown0; ULONG Unknown1; ULONG Unknown2; ULONG Unknown3; -} BL_DEVICE_INFORMATION, *PBL_DEVICE_INFORMATION; +} BL_DEVICE_IO_INFORMATION, *PBL_DEVICE_IO_INFORMATION;
LIST_ENTRY DmRegisteredDevices; ULONG DmTableEntries; LIST_ENTRY DmRegisteredDevices; PVOID* DmDeviceTable;
-BL_DEVICE_INFORMATION DmDeviceIoInformation; +BL_DEVICE_IO_INFORMATION DmDeviceIoInformation;
/* FUNCTIONS *****************************************************************/ - -struct _BL_DEVICE_ENTRY; - -typedef -NTSTATUS -(*PBL_DEVICE_ENUMERATE_DEVICE_CLASS) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_OPEN) ( - _In_ PBL_DEVICE_DESCRIPTOR Device, - _In_ struct _BL_DEVICE_ENTRY* DeviceEntry - ); - -typedef -NTSTATUS -(*PBL_DEVICE_CLOSE) ( - _In_ struct _BL_DEVICE_ENTRY* DeviceEntry - ); - -typedef -NTSTATUS -(*PBL_DEVICE_READ) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_WRITE) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_GET_INFORMATION) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_SET_INFORMATION) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_RESET) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_FLUSH) ( - VOID - ); - -typedef -NTSTATUS -(*PBL_DEVICE_CREATE) ( - VOID - ); - -typedef struct _BL_DEVICE_CALLBACKS -{ - PBL_DEVICE_ENUMERATE_DEVICE_CLASS EnumerateDeviceClass; - PBL_DEVICE_OPEN Open; - PBL_DEVICE_CLOSE Close; - PBL_DEVICE_READ Read; - PBL_DEVICE_WRITE Write; - PBL_DEVICE_GET_INFORMATION GetInformation; - PBL_DEVICE_SET_INFORMATION SetInformation; - PBL_DEVICE_RESET Reset; - PBL_DEVICE_FLUSH Flush; - PBL_DEVICE_CREATE Create; -} BL_DEVICE_CALLBACKS, *PBL_DEVICE_CALLBACKS; - -typedef struct _BL_DEVICE_ENTRY -{ - ULONG DeviceId; - ULONG Flags; - ULONG Unknown; - ULONG ReferenceCount; - BL_DEVICE_CALLBACKS Callbacks; - PVOID DeviceSpecificData; - PBL_DEVICE_DESCRIPTOR DeviceDescriptor; -} BL_DEVICE_ENTRY, *PBL_DEVICE_ENTRY;
typedef struct _BL_REGISTERED_DEVICE { @@ -151,12 +63,71 @@ _In_ PBL_DEVICE_ENTRY DeviceEntry );
+NTSTATUS +BlockIoGetInformation ( + _In_ PBL_DEVICE_ENTRY DeviceEntry, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ); + BL_DEVICE_CALLBACKS BlockIoDeviceFunctionTable = { NULL, BlockIoOpen, NULL, + NULL, + NULL, + BlockIoGetInformation }; + +NTSTATUS +BlockIoGetInformation ( + _In_ PBL_DEVICE_ENTRY DeviceEntry, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ) +{ + PBL_BLOCK_DEVICE BlockDevice; + + BlockDevice = DeviceEntry->DeviceSpecificData; + + RtlCopyMemory(&DeviceInformation->BlockDeviceInfo, + BlockDevice, + sizeof(DeviceInformation->BlockDeviceInfo)); + DeviceInformation->DeviceType = DiskDevice; + return STATUS_SUCCESS; +} + +NTSTATUS +BlDeviceGetInformation ( + _In_ ULONG DeviceId, + _Out_ PBL_DEVICE_INFORMATION DeviceInformation + ) +{ + PBL_DEVICE_ENTRY DeviceEntry; + + if (!(DeviceInformation)) + { + return STATUS_INVALID_PARAMETER; + } + + if (DmTableEntries <= DeviceId) + { + return STATUS_INVALID_PARAMETER; + } + + DeviceEntry = DmDeviceTable[DeviceId]; + if (!DeviceEntry) + { + return STATUS_INVALID_PARAMETER; + } + + if (!(DeviceEntry->Flags & 1)) + { + return STATUS_INVALID_PARAMETER; + } + + DeviceInformation->DeviceType = DeviceEntry->DeviceDescriptor->DeviceType; + return DeviceEntry->Callbacks.GetInformation(DeviceEntry, DeviceInformation); +}
BOOLEAN BlpDeviceCompare ( @@ -879,8 +850,6 @@ NULL, };
- - BL_DEVICE_CALLBACKS UdpFunctionTable = { NULL, @@ -894,9 +863,6 @@ SpOpen, NULL, }; - - -
BOOLEAN DeviceTableCompare (
Modified: trunk/reactos/boot/environ/lib/io/fat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/io/fat.c?r... ============================================================================== --- trunk/reactos/boot/environ/lib/io/fat.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/io/fat.c [iso-8859-1] Thu Sep 10 04:01:41 2015 @@ -17,6 +17,18 @@ PWCHAR FatpLongFileName;
/* FUNCTIONS *****************************************************************/ + +NTSTATUS +FatMount ( + _In_ ULONG DeviceId, + _In_ ULONG Unknown, + _Out_ PBL_FILE_ENTRY* FileEntry + ) +{ + EfiPrintf(L"FAT Mount on Device %d TODO\r\n", DeviceId); + EfiStall(3000000); + return STATUS_NOT_IMPLEMENTED; +}
NTSTATUS FatInitialize (
Modified: trunk/reactos/boot/environ/lib/io/file.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/io/file.c?... ============================================================================== --- trunk/reactos/boot/environ/lib/io/file.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/io/file.c [iso-8859-1] Thu Sep 10 04:01:41 2015 @@ -19,14 +19,459 @@ BL_FILE_SYSTEM_REGISTRATION_TABLE FatRegisterFunctionTable = { FatInitialize, -#if 0 - FatDestroy, + NULL, FatMount, NULL -#endif };
+extern ULONG DmTableEntries; +extern PVOID* DmDeviceTable; + /* FUNCTIONS *****************************************************************/ + +PWCHAR +FileIoCopyParentDirectoryPath ( + _In_ PWCHAR FilePath + ) +{ + ULONG PathSize, PathSizeWithNull; + PWCHAR Backslash, ParentCopy; + + PathSize = wcslen(FilePath) * sizeof(WCHAR); + + PathSizeWithNull = PathSize + sizeof(UNICODE_NULL); + if (PathSizeWithNull < PathSize) + { + return NULL; + } + + ParentCopy = BlMmAllocateHeap(PathSizeWithNull); + if (!ParentCopy) + { + return NULL; + } + wcsncpy(ParentCopy, FilePath, PathSizeWithNull / sizeof(WCHAR)); + + Backslash = wcsrchr(ParentCopy, '\'); + if (!Backslash) + { + BlMmFreeHeap(ParentCopy); + return NULL; + } + + if (Backslash == ParentCopy) + { + ++Backslash; + } + + *Backslash = UNICODE_NULL; + return ParentCopy; +} + +PWCHAR +FileIoCopyFileName ( + _In_ PWCHAR FilePath + ) +{ + PWCHAR Separator, FileCopy; + ULONG PathSize; + + Separator = wcsrchr(FilePath, '\'); + if (!Separator) + { + return NULL; + } + + PathSize = wcslen(Separator) * sizeof(WCHAR); + + FileCopy = BlMmAllocateHeap(PathSize); + if (!FileCopy) + { + return NULL; + } + + wcsncpy(FileCopy, Separator + 1, PathSize / sizeof(WCHAR)); + return FileCopy; +} + +BOOLEAN +FileTableCompareWithSubsetAttributes ( + _In_ PVOID Entry, + _In_ PVOID Argument1, + _In_ PVOID Argument2, + _In_ PVOID Argument3, + _In_ PVOID Argument4 + ) +{ + PBL_FILE_ENTRY FileEntry = (PBL_FILE_ENTRY)Entry; + ULONG DeviceId = *(PULONG)Argument1; + PWCHAR FilePath = (PWCHAR)Argument2; + ULONG OpenFlags = *(PULONG)Argument3; + ULONG Unknown = *(PULONG)Argument4; + BOOLEAN Found; + + Found = FALSE; + + if ((FileEntry->DeviceId == DeviceId) && !(_wcsicmp(FileEntry->FilePath, FilePath)) && (FileEntry->Unknown == Unknown)) + { + if ((!(OpenFlags & 1) || (FileEntry->Flags & 2)) && (!(OpenFlags & 2) || (FileEntry->Flags & 4))) + { + if ((!(OpenFlags & 4) || (FileEntry->Flags & 0x10000)) && ((OpenFlags & 4) || !(FileEntry->Flags & 0x10000))) + { + Found = TRUE; + } + } + } + return Found; +} + +BOOLEAN +FileTableCompareWithSameAttributes ( + _In_ PVOID Entry, + _In_ PVOID Argument1, + _In_ PVOID Argument2, + _In_ PVOID Argument3, + _In_ PVOID Argument4 + ) +{ + PBL_FILE_ENTRY FileEntry = (PBL_FILE_ENTRY)Entry; + ULONG DeviceId = *(PULONG)Argument1; + PWCHAR FilePath = (PWCHAR)Argument2; + ULONG OpenFlags = *(PULONG)Argument3; + ULONG Unknown = *(PULONG)Argument4; + BOOLEAN Found; + + Found = FALSE; + + if ((FileEntry->DeviceId == DeviceId) && !(_wcsicmp(FileEntry->FilePath, FilePath)) && (FileEntry->Unknown == Unknown)) + { + if ((!(OpenFlags & 1) || (FileEntry->Flags & 2)) && ((OpenFlags & 1) || !(FileEntry->Flags & 2)) && (!(OpenFlags & 2) || (FileEntry->Flags & 4)) && ((OpenFlags & 2) || !(FileEntry->Flags & 4))) + { + if ((!(OpenFlags & 4) || (FileEntry->Flags & 0x10000)) && ((OpenFlags & 4) || !(FileEntry->Flags & 0x10000))) + { + Found = TRUE; + } + } + } + return Found; +} + +NTSTATUS +FileTableDestroyEntry ( + _In_ PBL_FILE_ENTRY FileEntry, + _In_ ULONG Index + ) +{ + ULONG DeviceId; + PBL_DEVICE_ENTRY DeviceEntry; + NTSTATUS Status; + + DeviceId = FileEntry->DeviceId; + if (DmTableEntries > DeviceId) + { + DeviceEntry = DmDeviceTable[DeviceId]; + if (DeviceEntry) + { + --DeviceEntry->ReferenceCount; + } + } + + Status = FileEntry->Callbacks.Close(FileEntry); + + BlMmFreeHeap(FileEntry); + + FileTable[Index] = NULL; + return Status; +} + +NTSTATUS +FileTablePurgeEntry ( + _In_ PVOID Entry + ) +{ + PBL_FILE_ENTRY FileEntry = (PBL_FILE_ENTRY)Entry; + NTSTATUS Status; + + if (((FileEntry->Flags & 1) || (FileEntry->Flags & 0x10000)) && (FileEntries < 0x200)) + { + Status = STATUS_UNSUCCESSFUL; + } + else + { + Status = FileTableDestroyEntry(FileEntry, FileEntry->FileId); + } + + return Status; +} + +NTSTATUS +BlFileClose ( + _In_ ULONG FileId + ) +{ + PBL_FILE_ENTRY FileEntry; + + if (FileEntries <= FileId) + { + return STATUS_INVALID_PARAMETER; + } + + FileEntry = FileTable[FileId]; + if (!FileEntry) + { + return STATUS_INVALID_PARAMETER; + } + + if (!(FileEntry->Flags & 1)) + { + return STATUS_INVALID_PARAMETER; + } + + --FileEntry->ReferenceCount; + if (!FileEntry->ReferenceCount) + { + FileEntry->Flags &= ~1; + } + + return STATUS_SUCCESS; +} + +NTSTATUS +FileIoOpen ( + _In_ ULONG DeviceId, + _In_ PWCHAR FileName, + _In_ ULONG OpenFlags, + _In_ ULONG Unknown, + _In_ PBL_TBL_LOOKUP_ROUTINE CompareRoutine, + _Out_ PBL_FILE_ENTRY *ReturnFileEntry + ) +{ + PWCHAR FileNameCopy, ParentFileName; + NTSTATUS Status; + PBL_DEVICE_ENTRY DeviceEntry; + PBL_FILE_SYSTEM_ENTRY FileSystem; + ULONG FileId; + PBL_FILE_ENTRY ParentDirectoryEntry, FileEntry; + PLIST_ENTRY NextEntry, ListHead; + + ParentDirectoryEntry = NULL; + FileNameCopy = NULL; + OpenFlags |= 1; + ParentFileName = NULL; + Status = STATUS_SUCCESS; + + if (DmTableEntries <= DeviceId) + { + return STATUS_ACCESS_DENIED; + } + + DeviceEntry = DmDeviceTable[DeviceId]; + if (!DeviceEntry) + { + return STATUS_ACCESS_DENIED; + } + + if ((OpenFlags & 1) && (!(DeviceEntry->Flags & 1) || !(DeviceEntry->Flags & 2))) + { + EfiPrintf(L"Access denied\r\n"); + return STATUS_ACCESS_DENIED; + } + + if ((OpenFlags & 2) && (!(DeviceEntry->Flags & 1) || !(DeviceEntry->Flags & 4))) + { + EfiPrintf(L"Access denied2\r\n"); + return STATUS_ACCESS_DENIED; + } + + FileEntry = (PBL_FILE_ENTRY )BlTblFindEntry(FileTable, + FileEntries, + &FileId, + CompareRoutine, + &DeviceId, + FileName, + &OpenFlags, + &Unknown); + if (FileEntry) + { + EfiPrintf(L"Entry exists: %p\n", FileEntry); + goto FileOpened; + } + + if ((*FileName != OBJ_NAME_PATH_SEPARATOR) || (FileName[1])) + { + ParentFileName = FileIoCopyParentDirectoryPath(FileName); + if (!ParentFileName) + { + Status = STATUS_NO_MEMORY; + goto FileOpenEnd; + } + + Status = FileIoOpen(DeviceId, + ParentFileName, + 5, + Unknown, + FileTableCompareWithSubsetAttributes, + &ParentDirectoryEntry); + if (Status < 0) + { + goto FileOpenEnd; + } + + FileNameCopy = FileIoCopyFileName(FileName); + if (!FileNameCopy) + { + Status = STATUS_NO_MEMORY; + goto FileOpenEnd; + } + + Status = ParentDirectoryEntry->Callbacks.Open(ParentDirectoryEntry, + FileNameCopy, + OpenFlags, + &FileEntry); + } + else + { + EfiPrintf(L"Opening root drive\r\n"); + Status = STATUS_UNSUCCESSFUL; + + ListHead = &RegisteredFileSystems; + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) + { + FileSystem = CONTAINING_RECORD(NextEntry, BL_FILE_SYSTEM_ENTRY, ListEntry); + + EfiPrintf(L"Calling filesystem %p mount routine: %p\r\n", FileSystem, FileSystem->MountCallback); + Status = FileSystem->MountCallback(DeviceId, Unknown, &FileEntry); + if (NT_SUCCESS(Status)) + { + break; + } + + NextEntry = NextEntry->Flink; + } + + FileNameCopy = 0; + } + + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"Could not open file!: %lx\r\n", Status); + goto FileOpenEnd; + } + + FileEntry->Unknown = Unknown; + + if (OpenFlags & 1) + { + FileEntry->Flags |= 2u; + } + + if (OpenFlags & 2) + { + FileEntry->Flags |= 4u; + } + + Status = BlTblSetEntry(&FileTable, + &FileEntries, + (PVOID)FileEntry, + &FileId, + FileTablePurgeEntry); + if (!NT_SUCCESS(Status)) + { + FileEntry->Callbacks.Close(FileEntry); + goto FileOpenEnd; + } + + ++DeviceEntry->ReferenceCount; + Status = STATUS_SUCCESS; + + FileEntry->FileId = FileId; + +FileOpened: + if (++FileEntry->ReferenceCount == 1) + { + FileEntry->Unknown1 = 0; + FileEntry->Unknown2 = 0; + } + + FileEntry->Flags |= 1; + + if (OpenFlags & 0x10) + { + FileEntry->Flags |= 0x10; + } + + if (ReturnFileEntry) + { + *ReturnFileEntry = FileEntry; + } + +FileOpenEnd: + if (ParentDirectoryEntry) + { + BlFileClose(ParentDirectoryEntry->FileId); + } + if (ParentFileName) + { + BlMmFreeHeap(ParentFileName); + } + if (FileNameCopy) + { + BlMmFreeHeap(FileNameCopy); + } + return Status; +} + +NTSTATUS +BlFileOpen ( + _In_ ULONG DeviceId, + _In_ PWCHAR FileName, + _In_ ULONG OpenFlags, + _Out_ PULONG FileId + ) +{ + NTSTATUS Status; + PBL_FILE_ENTRY FileEntry; + BL_DEVICE_INFORMATION DeviceInformation; + + if (!(FileName) || + (*FileName != OBJ_NAME_PATH_SEPARATOR) || + !(FileId) || + !(OpenFlags & 3)) + { + EfiPrintf(L"Invalid file options\r\n"); + return STATUS_INVALID_PARAMETER; + } + + Status = BlDeviceGetInformation(DeviceId, &DeviceInformation); + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"Get device info failed: %lx\r\n", Status); + return Status; + } + + if ((DeviceInformation.DeviceType != DiskDevice) && + (DeviceInformation.DeviceType != LegacyPartitionDevice) && + (DeviceInformation.DeviceType != UdpDevice)) + { + EfiPrintf(L"Invalid device type\r\n"); + return STATUS_INVALID_PARAMETER; + } + + Status = FileIoOpen(DeviceId, + FileName, + OpenFlags, + 0, + FileTableCompareWithSameAttributes, + &FileEntry); + if (NT_SUCCESS(Status)) + { + EfiPrintf(L"File opened: %lx\r\n", FileEntry->FileId); + *FileId = FileEntry->FileId; + } + + return Status; +}
NTSTATUS BlpFileRegisterFileSystem ( @@ -40,14 +485,16 @@ PBL_FILE_SYSTEM_ENTRY FsEntry; NTSTATUS Status;
+ /* Allocate an entry */ FsEntry = BlMmAllocateHeap(sizeof(*FsEntry)); if (!FsEntry) { return STATUS_NO_MEMORY; }
+ /* Initialize the file system */ Status = InitCallback(); - if (NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status)) { BlMmFreeHeap(FsEntry); return Status;