[BOOTMGFW]

- Implement initial File I/O routines.
- We now die on attempting to mount the FAT volume.

svn path=/trunk/; revision=69165
This commit is contained in:
Alex Ionescu 2015-09-10 04:01:41 +00:00
parent bda290bc5e
commit 58407edd6b
5 changed files with 738 additions and 112 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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;