diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.c b/reactos/boot/environ/app/bootmgr/bootmgr.c index ab84d034124..abaa92bae5d 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.c +++ b/reactos/boot/environ/app/bootmgr/bootmgr.c @@ -180,8 +180,7 @@ BmFwInitializeBootDirectoryPath ( /* 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 @@ BmFwInitializeBootDirectoryPath ( } BootDirectory = L"\\EFI\\Microsoft\\Boot"; -#endif Quickie: /* Free all the allocations we made */ @@ -205,7 +203,7 @@ Quickie: /* Close the BCD file */ if (FileHandle != -1) { - //Status = BlFileClose(FileHandle); + Status = BlFileClose(FileHandle); } /* Close the boot device */ diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 2bf8a181cb2..5c94c3a64a0 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -265,6 +265,52 @@ typedef enum _BL_MEMORY_ATTR /* 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 @@ NTSTATUS typedef NTSTATUS (*PBL_FS_MOUNT_CALLBACK) ( - VOID + _In_ ULONG DeviceId, + _In_ ULONG Unknown, + _Out_ struct _BL_FILE_ENTRY** FileEntry ); typedef @@ -398,6 +446,73 @@ ULONG _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 ***********************************************************/ typedef struct _BL_LIBRARY_PARAMETERS @@ -626,9 +741,28 @@ typedef struct _BL_ADDRESS_RANGE 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 @@ typedef struct _BL_HASH_NODE 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 @@ typedef struct _BL_BLOCK_DEVICE } 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; @@ -785,6 +933,31 @@ typedef struct _BL_PROTOCOL_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 ***********************************************************/ FORCEINLINE @@ -893,11 +1066,6 @@ BlpFileInitialize ( VOID ); -NTSTATUS -FatInitialize ( - VOID - ); - NTSTATUS BlpDisplayInitialize ( _In_ ULONG Flags @@ -1036,6 +1204,20 @@ BlpTimeCalibratePerformanceCounter ( VOID ); +/* FILESYSTEM ROUTINES *******************************************************/ + +NTSTATUS +FatInitialize ( + VOID + ); + +NTSTATUS +FatMount ( + _In_ ULONG DeviceId, + _In_ ULONG Unknown, + _Out_ PBL_FILE_ENTRY* FileEntry + ); + /* UTILITY ROUTINES **********************************************************/ EFI_STATUS @@ -1295,6 +1477,27 @@ BlpDeviceOpen ( _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 *****************************************************/ NTSTATUS diff --git a/reactos/boot/environ/lib/io/device.c b/reactos/boot/environ/lib/io/device.c index a5aac41a147..c2c768ad0b1 100644 --- a/reactos/boot/environ/lib/io/device.c +++ b/reactos/boot/environ/lib/io/device.c @@ -12,111 +12,23 @@ /* 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 { LIST_ENTRY ListEntry; @@ -151,13 +63,72 @@ BlockIoOpen ( _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 ( _In_ PBL_DEVICE_DESCRIPTOR Device1, @@ -879,8 +850,6 @@ BL_DEVICE_CALLBACKS VirtualDiskDeviceFunctionTable = NULL, }; - - BL_DEVICE_CALLBACKS UdpFunctionTable = { NULL, @@ -895,9 +864,6 @@ BL_DEVICE_CALLBACKS SerialPortFunctionTable = NULL, }; - - - BOOLEAN DeviceTableCompare ( _In_ PVOID Entry, diff --git a/reactos/boot/environ/lib/io/fat.c b/reactos/boot/environ/lib/io/fat.c index a8c092525b7..46f05959b7a 100644 --- a/reactos/boot/environ/lib/io/fat.c +++ b/reactos/boot/environ/lib/io/fat.c @@ -18,6 +18,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 ( VOID diff --git a/reactos/boot/environ/lib/io/file.c b/reactos/boot/environ/lib/io/file.c index 5a4982c9d4c..fcf2564dc97 100644 --- a/reactos/boot/environ/lib/io/file.c +++ b/reactos/boot/environ/lib/io/file.c @@ -19,15 +19,460 @@ LIST_ENTRY RegisteredFileSystems; 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 ( _In_ PBL_FS_INIT_CALLBACK InitCallback, @@ -40,14 +485,16 @@ BlpFileRegisterFileSystem ( 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;