ReactOS 0.4.15-dev-8339-g4028de8
file.c File Reference
#include "bl.h"
Include dependency graph for file.c:

Go to the source code of this file.

Macros

#define BL_FILE_PURGE_LIMIT   512
 

Functions

PWCHAR FileIoCopyParentDirectoryPath (_In_ PWCHAR FilePath)
 
PWCHAR FileIoCopyFileName (_In_ PWCHAR FilePath)
 
BOOLEAN FileTableCompareWithSubsetAttributes (_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
 
BOOLEAN FileTableCompareWithSameAttributes (_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
 
NTSTATUS FileTableDestroyEntry (_In_ PBL_FILE_ENTRY FileEntry, _In_ ULONG Index)
 
NTSTATUS FileTablePurgeEntry (_In_ PVOID Entry)
 
NTSTATUS BlFileClose (_In_ ULONG FileId)
 
NTSTATUS FileIoOpen (_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _In_ ULONG Unknown, _In_ PBL_TBL_LOOKUP_ROUTINE CompareRoutine, _Out_opt_ PBL_FILE_ENTRY *NewFileEntry)
 
NTSTATUS BlFileOpen (_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PULONG FileId)
 
NTSTATUS BlFileSetInformation (_In_ ULONG FileId, _Out_ PBL_FILE_INFORMATION FileInfo)
 
NTSTATUS BlFileGetInformation (_In_ ULONG FileId, _In_ PBL_FILE_INFORMATION FileInfo)
 
NTSTATUS FileInformationCheck (_In_ PBL_FILE_INFORMATION FileInformation, _In_ BOOLEAN Write, _In_opt_ PULONG InputSize, _In_opt_ PULONG BytesReturned, _Out_opt_ PULONG RequiredSize)
 
NTSTATUS BlFileReadEx (_In_ ULONG FileId, _Out_ PVOID Buffer, _In_ ULONG Size, _Out_ PULONG BytesReturned, _In_ ULONG Flags)
 
NTSTATUS BlFileReadAtOffsetEx (_In_ ULONG FileId, _In_ ULONG Size, _In_ ULONGLONG ByteOffset, _In_ PVOID Buffer, _Out_ PULONG BytesReturned, _In_ ULONG Flags)
 
NTSTATUS BlpFileRegisterFileSystem (_In_ PBL_FS_INIT_CALLBACK InitCallback, _In_ PBL_FS_DESTROY_CALLBACK DestroyCallback, _In_ PBL_FS_MOUNT_CALLBACK MountCallback, _In_ PBL_FS_PURGE_CALLBACK PurgeCallback, _In_ ULONG Flags)
 
NTSTATUS BlpFileInitialize (VOID)
 

Variables

PVOIDFileTable
 
ULONG FileEntries
 
LIST_ENTRY RegisteredFileSystems
 
BL_FILE_SYSTEM_REGISTRATION_TABLE FatRegisterFunctionTable
 
BL_FILE_SYSTEM_REGISTRATION_TABLE EtfsRegisterFunctionTable
 
ULONG DmTableEntries
 
PVOIDDmDeviceTable
 

Macro Definition Documentation

◆ BL_FILE_PURGE_LIMIT

#define BL_FILE_PURGE_LIMIT   512

Definition at line 198 of file file.c.

Function Documentation

◆ BlFileClose()

NTSTATUS BlFileClose ( _In_ ULONG  FileId)

Definition at line 220 of file file.c.

223{
224 PBL_FILE_ENTRY FileEntry;
225
226 /* Validate the file ID */
227 if (FileEntries <= FileId)
228 {
230 }
231
232 /* Make sure a file entry actually exists */
233 FileEntry = FileTable[FileId];
234 if (!FileEntry)
235 {
237 }
238
239 /* And that it's actually open */
240 if (!(FileEntry->Flags & BL_FILE_ENTRY_OPENED))
241 {
243 }
244
245 /* Drop a reference, check if this was the last one */
246 --FileEntry->ReferenceCount;
247 if (!FileEntry->ReferenceCount)
248 {
249 /* File is no longer open */
250 FileEntry->Flags &= ~BL_FILE_ENTRY_OPENED;
251 }
252
253 /* All good */
254 return STATUS_SUCCESS;
255}
#define BL_FILE_ENTRY_OPENED
Definition: bl.h:159
ULONG FileEntries
Definition: file.c:16
PVOID * FileTable
Definition: file.c:15
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: bl.h:1038
ULONG ReferenceCount
Definition: bl.h:1043
ULONG Flags
Definition: bl.h:1042
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by BlBsdInitializeLog(), BmFwInitializeBootDirectoryPath(), FileIoOpen(), and ImgpCloseFile().

◆ BlFileGetInformation()

NTSTATUS BlFileGetInformation ( _In_ ULONG  FileId,
_In_ PBL_FILE_INFORMATION  FileInfo 
)

Definition at line 564 of file file.c.

568{
569 PBL_FILE_ENTRY FileEntry;
570
571 /* Make sure caller passed this in */
572 if (!FileInfo)
573 {
575 }
576
577 /* Validate file ID */
578 if (FileId > FileEntries)
579 {
581 }
582
583 /* Make sure an opened file exits with this ID */
584 FileEntry = FileTable[FileId];
585 if (!(FileEntry) || !(FileEntry->Flags & BL_FILE_ENTRY_OPENED))
586 {
588 }
589
590 /* Do the I/O operation */
591 return FileEntry->Callbacks.GetInfo(FileEntry, FileInfo);
592}
PBL_FILE_GET_INFO GetInfo
Definition: bl.h:1033
BL_FILE_CALLBACKS Callbacks
Definition: bl.h:1047

Referenced by BlFileReadAtOffsetEx(), BlFileReadEx(), and ImgpGetFileSize().

◆ BlFileOpen()

NTSTATUS BlFileOpen ( _In_ ULONG  DeviceId,
_In_ PWCHAR  FileName,
_In_ ULONG  Flags,
_Out_ PULONG  FileId 
)

Definition at line 477 of file file.c.

483{
485 PBL_FILE_ENTRY FileEntry;
486 BL_DEVICE_INFORMATION DeviceInformation;
487
488 /* Make sure we have a valid file name, access flags and parameters */
489 if (!(FileName) ||
491 !(FileId) ||
493 {
494 EfiPrintf(L"Invalid file options\r\n");
496 }
497
498 /* Get information on the underlying device */
499 Status = BlDeviceGetInformation(DeviceId, &DeviceInformation);
500 if (!NT_SUCCESS(Status))
501 {
502 EfiPrintf(L"Get device info failed: %lx\r\n", Status);
503 return Status;
504 }
505
506 /* Make sure it's a device that can host files */
507 if ((DeviceInformation.DeviceType != DiskDevice) &&
508 (DeviceInformation.DeviceType != LegacyPartitionDevice) &&
509 (DeviceInformation.DeviceType != UdpDevice))
510 {
511 EfiPrintf(L"Invalid device type\r\n");
513 }
514
515 /* Open a file on this device, creating one if needed */
516 Status = FileIoOpen(DeviceId,
517 FileName,
518 Flags,
519 0,
521 &FileEntry);
522 if (NT_SUCCESS(Status))
523 {
524 /* Return the file ID back to the caller */
525 *FileId = FileEntry->FileId;
526 }
527
528 /* All good */
529 return Status;
530}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS BlDeviceGetInformation(_In_ ULONG DeviceId, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:682
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
#define BL_FILE_WRITE_ACCESS
Definition: bl.h:148
@ LegacyPartitionDevice
Definition: bl.h:248
@ DiskDevice
Definition: bl.h:247
@ UdpDevice
Definition: bl.h:250
#define BL_FILE_READ_ACCESS
Definition: bl.h:147
BOOLEAN FileTableCompareWithSameAttributes(_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
Definition: file.c:138
NTSTATUS FileIoOpen(_In_ ULONG DeviceId, _In_ PWCHAR FileName, _In_ ULONG Flags, _In_ ULONG Unknown, _In_ PBL_TBL_LOOKUP_ROUTINE CompareRoutine, _Out_opt_ PBL_FILE_ENTRY *NewFileEntry)
Definition: file.c:258
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
#define L(x)
Definition: ntvdm.h:50
BL_DEVICE_TYPE DeviceType
Definition: bl.h:1225
ULONG FileId
Definition: bl.h:1041
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by BlBsdInitializeLog(), BmFwInitializeBootDirectoryPath(), and ImgpOpenFile().

◆ BlFileReadAtOffsetEx()

NTSTATUS BlFileReadAtOffsetEx ( _In_ ULONG  FileId,
_In_ ULONG  Size,
_In_ ULONGLONG  ByteOffset,
_In_ PVOID  Buffer,
_Out_ PULONG  BytesReturned,
_In_ ULONG  Flags 
)

Definition at line 788 of file file.c.

796{
801
802 /* Get information on the specified file */
804 if (!NT_SUCCESS(Status))
805 {
806 return Status;
807 }
808
809 /* Save the current offset, and overwrite it with the one we want */
810 FileOffset = FileInfo.Offset;
811 FileInfo.Offset = ByteOffset;
812
813 /* Check the validity of the read and the actual size to read */
816 FALSE,
819 &RequiredSize);
820 if (!NT_SUCCESS(Status))
821 {
822 /* Bail out if the read is invalid */
823 EfiPrintf(L"File info check failure: %lx\r\n", Status);
824 return Status;
825 }
826
827 /* Check if the offset we're requesting is not the current offset */
828 if (FileInfo.Offset != FileOffset)
829 {
830 /* Set the new offset to use */
832 if (!NT_SUCCESS(Status))
833 {
834 /* Can't do much if that failed */
835 return Status;
836 }
837 }
838
839 /* Do the read at the required offset now */
840 Status = BlFileReadEx(FileId,
841 Buffer,
844 Flags);
845 if (!NT_SUCCESS(Status))
846 {
847 /* The read failed -- had we modified the offset? */
848 if (FileInfo.Offset != FileOffset)
849 {
850 /* Restore the offset back to its original value */
851 FileInfo.Offset = FileOffset;
853 }
854 }
855
856 /* Return the status of the read */
857 return Status;
858}
NTSTATUS BlFileSetInformation(_In_ ULONG FileId, _Out_ PBL_FILE_INFORMATION FileInfo)
Definition: file.c:533
NTSTATUS BlFileGetInformation(_In_ ULONG FileId, _In_ PBL_FILE_INFORMATION FileInfo)
Definition: file.c:564
NTSTATUS FileInformationCheck(_In_ PBL_FILE_INFORMATION FileInformation, _In_ BOOLEAN Write, _In_opt_ PULONG InputSize, _In_opt_ PULONG BytesReturned, _Out_opt_ PULONG RequiredSize)
Definition: file.c:595
NTSTATUS BlFileReadEx(_In_ ULONG FileId, _Out_ PVOID Buffer, _In_ ULONG Size, _Out_ PULONG BytesReturned, _In_ ULONG Flags)
Definition: file.c:655
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
Definition: bufpool.h:45
#define FALSE
Definition: types.h:117
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ ULONG _Out_ PVOID _Out_ PULONG RequiredSize
Definition: wdfdevice.h:4439
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052

Referenced by ImgpReadAtFileOffset().

◆ BlFileReadEx()

NTSTATUS BlFileReadEx ( _In_ ULONG  FileId,
_Out_ PVOID  Buffer,
_In_ ULONG  Size,
_Out_ PULONG  BytesReturned,
_In_ ULONG  Flags 
)

Definition at line 655 of file file.c.

662{
663 PBL_FILE_ENTRY FileEntry;
665 ULONG OldUnknown, RequiredSize;
666 BOOLEAN ChangedUnknown;
668 BL_FILE_INFORMATION fileInfo;
669
670 /* Initialize variables */
672 OldUnknown = 0;
673 ChangedUnknown = FALSE;
674
675 /* Bail out if there's no buffer */
676 if (!Buffer)
677 {
679 }
680
681 /* Bail out of the file ID is invalid */
682 if (FileId > FileEntries)
683 {
685 }
686
687 /* Bail out if there's no file opened for read access */
688 FileEntry = FileTable[FileId];
689 if (!(FileEntry) ||
691 {
693 }
694
695 /* Bail out if we can't read the file's information */
696 Status = BlFileGetInformation(FileId, &fileInfo);
697 if (!NT_SUCCESS(Status))
698 {
699 return Status;
700 }
701
702 /* Ensure the read attempt is valid, and fix up the size if needed */
704 Status = FileInformationCheck(&fileInfo,
705 FALSE,
708 &RequiredSize);
709 if (!NT_SUCCESS(Status))
710 {
711 /* Invalid or illegal read attempt */
712 return Status;
713 }
714
715 /* Is there anything left to read after all? */
716 if (RequiredSize)
717 {
718 /* Check if flags 2 or 4 are set */
719 if ((Flags & 2) || (Flags & 4))
720 {
721 /* Check if this is a disk or partition device */
723 if ((DeviceInfo.DeviceType == DiskDevice) ||
724 (DeviceInfo.DeviceType == LegacyPartitionDevice))
725 {
726 /* Check if request flags are incompatible with device flags */
727 if ((!(DeviceInfo.BlockDeviceInfo.Unknown & 1) && (Flags & 2)) ||
728 (!(DeviceInfo.BlockDeviceInfo.Unknown & 2) && (Flags & 4)))
729 {
730 /* We're going to change the device flags */
731 ChangedUnknown = TRUE;
732
733 /* Set unknown flag 1 for request flag 2 */
734 if (Flags & 2)
735 {
736 DeviceInfo.BlockDeviceInfo.Unknown |= 1;
737 }
738
739 /* Set unknown flag 2 for request flag 4 */
740 if (Flags & 4)
741 {
742 DeviceInfo.BlockDeviceInfo.Unknown |= 2;
743 }
744
745 /* Save the new device flags */
747 }
748 }
749 }
750
751 /* Issue the read to the underlying file system */
752 Status = FileEntry->Callbacks.Read(FileEntry,
753 Buffer,
756 if (!NT_SUCCESS(Status))
757 {
758 /* Don't update the bytes read on failure */
759 RequiredSize = 0;
760 }
761 }
762 else
763 {
764 /* There's nothing to do, return success and 0 bytes */
766 if (BytesReturned)
767 {
768 *BytesReturned = 0;
769 }
770 }
771
772 /* Increment the number of bytes read */
773 FileEntry->TotalBytesRead += RequiredSize;
774
775 /* Check if the unknown flag on the device was changed during this routine */
776 if (ChangedUnknown)
777 {
778 /* Reset it back to its original value */
779 DeviceInfo.BlockDeviceInfo.Unknown = OldUnknown;
781 }
782
783 /* Return the final status */
784 return Status;
785}
unsigned char BOOLEAN
#define BL_FILE_ENTRY_READ_ACCESS
Definition: bl.h:160
NTSTATUS BlDeviceSetInformation(_In_ ULONG DeviceId, _In_ PBL_DEVICE_INFORMATION DeviceInformation)
#define TRUE
Definition: types.h:120
PBL_FILE_READ Read
Definition: bl.h:1030
ULONGLONG TotalBytesRead
Definition: bl.h:1045
ULONG DeviceId
Definition: bl.h:1040
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by BlFileReadAtOffsetEx().

◆ BlFileSetInformation()

NTSTATUS BlFileSetInformation ( _In_ ULONG  FileId,
_Out_ PBL_FILE_INFORMATION  FileInfo 
)

Definition at line 533 of file file.c.

537{
538 PBL_FILE_ENTRY FileEntry;
539
540 /* Make sure caller passed this in */
541 if (!FileInfo)
542 {
544 }
545
546 /* Validate file ID */
547 if (FileId > FileEntries)
548 {
550 }
551
552 /* Make sure an opened file exits with this ID */
553 FileEntry = FileTable[FileId];
554 if (!(FileEntry) || !(FileEntry->Flags & BL_FILE_ENTRY_OPENED))
555 {
557 }
558
559 /* Do the I/O operation */
560 return FileEntry->Callbacks.SetInfo(FileEntry, FileInfo);
561}
PBL_FILE_SET_INFO SetInfo
Definition: bl.h:1034

Referenced by BlFileReadAtOffsetEx().

◆ BlpFileInitialize()

NTSTATUS BlpFileInitialize ( VOID  )

Definition at line 908 of file file.c.

911{
913
914 /* Allocate the file table */
915 FileEntries = 16;
917 if (!FileTable)
918 {
920 }
921
922 /* Initialize it */
925
926#if 0
927 /* Initialize the network file system */
928 Status = BlpFileRegisterFileSystem(NetRegisterFunctionTable.Init,
929 NetRegisterFunctionTable.Destroy,
930 NetRegisterFunctionTable.Mount,
931 NetRegisterFunctionTable.Purge,
932 1);
933 if (NT_SUCCESS(Status))
934 {
935 /* Initialize NTFS */
936 Status = BlpFileRegisterFileSystem(NtfsRegisterFunctionTable.Init,
937 NtfsRegisterFunctionTable.Destroy,
938 NtfsRegisterFunctionTable.Mount,
939 NtfsRegisterFunctionTable.Purge,
940 0);
941 }
942
943 if (NT_SUCCESS(Status))
944#endif
945 {
946 /* Initialize FAT */
951 0);
952 }
953
954#if 0
955 if (NT_SUCCESS(Status))
956 {
957 /* Initialize EXFAT (FatPlus) */
958 Status = BlpFileRegisterFileSystem(FppRegisterFunctionTable.Init,
959 FppRegisterFunctionTable.Destroy,
960 FppRegisterFunctionTable.Mount,
961 FppRegisterFunctionTable.Purge,
962 0);
963 }
964
965 if (NT_SUCCESS(Status))
966 {
967 /* Initialize WIM */
968 Status = BlpFileRegisterFileSystem(WimRegisterFunctionTable.Init,
969 WimRegisterFunctionTable.Destroy,
970 WimRegisterFunctionTable.Mount,
971 WimRegisterFunctionTable.Purge,
972 0);
973 }
974
975 if (NT_SUCCESS(Status))
976 {
977 /* Initialize UDFS */
978 Status = BlpFileRegisterFileSystem(UdfsRegisterFunctionTable.Init,
979 UdfsRegisterFunctionTable.Destroy,
980 UdfsRegisterFunctionTable.Mount,
981 UdfsRegisterFunctionTable.Purge,
982 0);
983 }
984#endif
985 if (NT_SUCCESS(Status))
986 {
987 /* Initialize El-Torito CDFS */
992 0);
993 }
994
995 /* Destroy the file manager if any of the file systems didn't initialize */
996 if (!NT_SUCCESS(Status))
997 {
998 if (FileTable)
999 {
1000 //BlpFileDestroy();
1001 }
1002 }
1003 return Status;
1004}
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
BL_FILE_SYSTEM_REGISTRATION_TABLE FatRegisterFunctionTable
Definition: file.c:19
BL_FILE_SYSTEM_REGISTRATION_TABLE EtfsRegisterFunctionTable
Definition: file.c:26
LIST_ENTRY RegisteredFileSystems
Definition: file.c:18
NTSTATUS BlpFileRegisterFileSystem(_In_ PBL_FS_INIT_CALLBACK InitCallback, _In_ PBL_FS_DESTROY_CALLBACK DestroyCallback, _In_ PBL_FS_MOUNT_CALLBACK MountCallback, _In_ PBL_FS_PURGE_CALLBACK PurgeCallback, _In_ ULONG Flags)
Definition: file.c:861
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PBL_FS_PURGE_CALLBACK Purge
Definition: bl.h:1065
PBL_FS_MOUNT_CALLBACK Mount
Definition: bl.h:1064
PBL_FS_DESTROY_CALLBACK Destroy
Definition: bl.h:1063
PBL_FS_INIT_CALLBACK Init
Definition: bl.h:1062

Referenced by BlpIoInitialize().

◆ BlpFileRegisterFileSystem()

NTSTATUS BlpFileRegisterFileSystem ( _In_ PBL_FS_INIT_CALLBACK  InitCallback,
_In_ PBL_FS_DESTROY_CALLBACK  DestroyCallback,
_In_ PBL_FS_MOUNT_CALLBACK  MountCallback,
_In_ PBL_FS_PURGE_CALLBACK  PurgeCallback,
_In_ ULONG  Flags 
)

Definition at line 861 of file file.c.

868{
869 PBL_FILE_SYSTEM_ENTRY FsEntry;
871
872 /* Allocate an entry */
873 FsEntry = BlMmAllocateHeap(sizeof(*FsEntry));
874 if (!FsEntry)
875 {
876 return STATUS_NO_MEMORY;
877 }
878
879 /* Initialize the file system */
881 if (!NT_SUCCESS(Status))
882 {
883 BlMmFreeHeap(FsEntry);
884 return Status;
885 }
886
887 /* Register the callbacks */
888 FsEntry->MountCallback = MountCallback;
889 FsEntry->DestroyCallback = DestroyCallback;
890 FsEntry->InitCallback = InitCallback;
891 FsEntry->PurgeCallback = PurgeCallback;
892
893 /* Insert in the right location in the list */
895 {
897 }
898 else
899 {
901 }
902
903 /* Return */
904 return STATUS_SUCCESS;
905}
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define BL_FS_REGISTER_AT_HEAD_FLAG
Definition: bl.h:139
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
VOID WINAPI InitCallback(_In_ RUNONCEEX_CALLBACK Callback, _In_ BOOL bSilence)
Definition: iernonce.cpp:56
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
Definition: bl.h:1052
PBL_FS_PURGE_CALLBACK PurgeCallback
Definition: bl.h:1057
PBL_FS_DESTROY_CALLBACK DestroyCallback
Definition: bl.h:1055
PBL_FS_INIT_CALLBACK InitCallback
Definition: bl.h:1054
PBL_FS_MOUNT_CALLBACK MountCallback
Definition: bl.h:1056
LIST_ENTRY ListEntry
Definition: bl.h:1053

Referenced by BlpFileInitialize().

◆ FileInformationCheck()

NTSTATUS FileInformationCheck ( _In_ PBL_FILE_INFORMATION  FileInformation,
_In_ BOOLEAN  Write,
_In_opt_ PULONG  InputSize,
_In_opt_ PULONG  BytesReturned,
_Out_opt_ PULONG  RequiredSize 
)

Definition at line 595 of file file.c.

602{
604 ULONG Size;
605
606 /* Initialize variables */
608 Size = 0;
609
610 /* Make sure we didn't overshoot */
611 if (FileInformation->Offset > FileInformation->Size)
612 {
613 /* Bail out */
615 goto Quickie;
616 }
617
618 /* Compute the appropriate 32-bit size of this read, based on file size */
619 Size = ULONG_MAX;
620 if ((FileInformation->Size - FileInformation->Offset) <= ULONG_MAX)
621 {
622 Size = (ULONG)(FileInformation->Size) - (ULONG)(FileInformation->Offset);
623 }
624
625 /* Check if the caller has an input buffer */
626 if (InputSize)
627 {
628 /* Is the size bigger than what the caller can handle? */
629 if (Size >= *InputSize)
630 {
631 /* Yes, so cap it at the size of the caller's buffer */
632 Size = *InputSize;
633 }
634 else if (!(BytesReturned) || (Write))
635 {
636 /* Caller's input buffer is too smaller is fatal for writes */
638 goto Quickie;
639 }
640 }
641
642Quickie:
643 /* Does the caller want to know how big to make their buffer? */
644 if (RequiredSize)
645 {
646 /* Let them know*/
648 }
649
650 /* Return final status */
651 return Status;
652}
#define ULONG_MAX
Definition: limits.h:44
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
static BOOL Write(PBYTE Address, PBYTE Data, SIZE_T Size)
Definition: vmhorizon.c:15

Referenced by BlFileReadAtOffsetEx(), and BlFileReadEx().

◆ FileIoCopyFileName()

PWCHAR FileIoCopyFileName ( _In_ PWCHAR  FilePath)

Definition at line 79 of file file.c.

82{
83 PWCHAR Separator, FileCopy;
84 SIZE_T PathSize;
85
86 Separator = wcsrchr(FilePath, '\\');
87 if (!Separator)
88 {
89 return NULL;
90 }
91
92 PathSize = wcslen(Separator) * sizeof(WCHAR);
93
94 FileCopy = BlMmAllocateHeap(PathSize);
95 if (!FileCopy)
96 {
97 return NULL;
98 }
99
100 wcsncpy(FileCopy, Separator + 1, PathSize / sizeof(WCHAR));
101 return FileCopy;
102}
PCWSTR FilePath
#define NULL
Definition: types.h:112
#define wcsrchr
Definition: compat.h:16
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PWCHAR
Definition: typedefs.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by FileIoOpen().

◆ FileIoCopyParentDirectoryPath()

PWCHAR FileIoCopyParentDirectoryPath ( _In_ PWCHAR  FilePath)

Definition at line 40 of file file.c.

43{
44 SIZE_T PathSize, PathSizeWithNull;
45 PWCHAR Backslash, ParentCopy;
46
47 PathSize = wcslen(FilePath) * sizeof(WCHAR);
48
49 PathSizeWithNull = PathSize + sizeof(UNICODE_NULL);
50 if (PathSizeWithNull < PathSize)
51 {
52 return NULL;
53 }
54
55 ParentCopy = BlMmAllocateHeap(PathSizeWithNull);
56 if (!ParentCopy)
57 {
58 return NULL;
59 }
60 wcsncpy(ParentCopy, FilePath, PathSizeWithNull / sizeof(WCHAR));
61
62 Backslash = wcsrchr(ParentCopy, '\\');
63 if (!Backslash)
64 {
65 BlMmFreeHeap(ParentCopy);
66 return NULL;
67 }
68
69 if (Backslash == ParentCopy)
70 {
71 ++Backslash;
72 }
73
74 *Backslash = UNICODE_NULL;
75 return ParentCopy;
76}
#define UNICODE_NULL

Referenced by FileIoOpen().

◆ FileIoOpen()

NTSTATUS FileIoOpen ( _In_ ULONG  DeviceId,
_In_ PWCHAR  FileName,
_In_ ULONG  Flags,
_In_ ULONG  Unknown,
_In_ PBL_TBL_LOOKUP_ROUTINE  CompareRoutine,
_Out_opt_ PBL_FILE_ENTRY NewFileEntry 
)

Definition at line 258 of file file.c.

266{
267 PWCHAR FileNameCopy, ParentFileName;
269 PBL_DEVICE_ENTRY DeviceEntry;
271 ULONG FileId, CheckFlags;
272 PBL_FILE_ENTRY DirectoryEntry, FileEntry;
273 PLIST_ENTRY NextEntry, ListHead;
274
275 /* Preinitialize variables for failure */
276 DirectoryEntry = NULL;
277 FileNameCopy = NULL;
280
281 /* Bail out if the device ID is invalid */
282 if (DmTableEntries <= DeviceId)
283 {
285 }
286
287 /* Bail out if there's no device entry */
288 DeviceEntry = DmDeviceTable[DeviceId];
289 if (!DeviceEntry)
290 {
292 }
293
294 /* Read access is always required for touching the device */
295 CheckFlags = Flags | BL_FILE_READ_ACCESS;
296
297 /* Check if the device is granting us read access */
298 if ((CheckFlags & BL_FILE_READ_ACCESS) &&
299 (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
300 !(DeviceEntry->Flags & BL_DEVICE_ENTRY_READ_ACCESS)))
301 {
302 EfiPrintf(L"Access denied\r\n");
304 }
305
306 /* Check if the device is granting us write access */
307 if ((CheckFlags & BL_FILE_WRITE_ACCESS) &&
308 (!(DeviceEntry->Flags & BL_DEVICE_ENTRY_OPENED) ||
309 !(DeviceEntry->Flags & BL_DEVICE_ENTRY_WRITE_ACCESS)))
310 {
311 EfiPrintf(L"Access denied2\r\n");
313 }
314
315 /* Check if we already have this file open */
318 &FileId,
320 &DeviceId,
321 FileName,
322 &Flags,
323 &Unknown);
324 if (FileEntry)
325 {
326 goto FileOpened;
327 }
328
329 /* Check if we are opening the root drive or an actual file/directory */
330 if ((*FileName != OBJ_NAME_PATH_SEPARATOR) || (FileName[1]))
331 {
332 /* Get the name of the directory */
334 if (!ParentFileName)
335 {
337 goto Quickie;
338 }
339
340 /* Open it */
341 Status = FileIoOpen(DeviceId,
344 Unknown,
346 &DirectoryEntry);
347 if (!NT_SUCCESS(Status))
348 {
349 goto Quickie;
350 }
351
352 /* Now get the the file name itself */
353 FileNameCopy = FileIoCopyFileName(FileName);
354 if (!FileNameCopy)
355 {
357 goto Quickie;
358 }
359
360 /* Open it */
361 Status = DirectoryEntry->Callbacks.Open(DirectoryEntry,
362 FileNameCopy,
363 Flags,
364 &FileEntry);
365 }
366 else
367 {
368 /* We're opening the root, scan through all the file systems */
370 ListHead = &RegisteredFileSystems;
371 NextEntry = ListHead->Flink;
372 while (NextEntry != ListHead)
373 {
374 /* Try to mount this one */
375 FileSystem = CONTAINING_RECORD(NextEntry, BL_FILE_SYSTEM_ENTRY, ListEntry);
376 Status = FileSystem->MountCallback(DeviceId, Unknown, &FileEntry);
377 if (NT_SUCCESS(Status))
378 {
379 /* Mount successful */
380 break;
381 }
382
383 /* Try the next file system */
384 NextEntry = NextEntry->Flink;
385 }
386
387 /* Nothing to free on this path */
388 FileNameCopy = NULL;
389 }
390
391 /* Handle failure */
392 if (!NT_SUCCESS(Status))
393 {
394 EfiPrintf(L"Could not open file!: %lx\r\n", Status);
395 goto Quickie;
396 }
397
398 /* Save the unknown */
399 FileEntry->Unknown = Unknown;
400
401 /* Convert open flags into entry flags */
403 {
404 FileEntry->Flags |= BL_FILE_ENTRY_READ_ACCESS;
405 }
407 {
408 FileEntry->Flags |= BL_FILE_ENTRY_WRITE_ACCESS;
409 }
410
411 /* Save the file into the file table */
414 (PVOID)FileEntry,
415 &FileId,
417 if (!NT_SUCCESS(Status))
418 {
419 /* Close it if that failed */
420 FileEntry->Callbacks.Close(FileEntry);
421 goto Quickie;
422 }
423
424 /* Add a reference on the device, and save our file ID */
425 ++DeviceEntry->ReferenceCount;
427 FileEntry->FileId = FileId;
428
429FileOpened:
430 /* Add a reference to the file entry, and see if this is the first one */
431 if (++FileEntry->ReferenceCount == 1)
432 {
433 /* Reset unknowns */
434 FileEntry->TotalBytesRead = 0;
435 FileEntry->Unknown2 = 0;
436 }
437
438 /* Set the file as opened */
439 FileEntry->Flags |= BL_FILE_ENTRY_OPENED;
440
441 /* Not sure what this flag does */
443 {
445 }
446
447 /* If the caller wanted the entry back, return it */
448 if (NewFileEntry)
449 {
450 *NewFileEntry = FileEntry;
451 }
452
453Quickie:
454 /* Close the parent */
455 if (DirectoryEntry)
456 {
457 BlFileClose(DirectoryEntry->FileId);
458 }
459
460 /* Free the parent name copy */
461 if (ParentFileName)
462 {
464 }
465
466 /* Free the file name copy */
467 if (FileNameCopy)
468 {
469 BlMmFreeHeap(FileNameCopy);
470 }
471
472 /* Return back to caller */
473 return Status;
474}
PWCHAR FileSystem
Definition: format.c:72
#define BL_DEVICE_ENTRY_WRITE_ACCESS
Definition: bl.h:157
PVOID BlTblFindEntry(_In_ PVOID *Table, _In_ ULONG Count, _Out_ PULONG EntryIndex, _In_ PBL_TBL_LOOKUP_ROUTINE Callback, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
Definition: util.c:273
#define BL_UNKNOWN_ACCESS
Definition: bl.h:150
#define BL_DIRECTORY_ACCESS
Definition: bl.h:149
#define BL_FILE_ENTRY_UNKNOWN_ACCESS
Definition: bl.h:162
#define BL_DEVICE_ENTRY_OPENED
Definition: bl.h:155
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
#define BL_FILE_ENTRY_WRITE_ACCESS
Definition: bl.h:161
#define BL_DEVICE_ENTRY_READ_ACCESS
Definition: bl.h:156
struct _BL_FILE_ENTRY * PBL_FILE_ENTRY
PVOID * DmDeviceTable
Definition: device.c:24
NTSTATUS FileTablePurgeEntry(_In_ PVOID Entry)
Definition: file.c:201
PWCHAR FileIoCopyParentDirectoryPath(_In_ PWCHAR FilePath)
Definition: file.c:40
ULONG DmTableEntries
Definition: device.c:22
NTSTATUS BlFileClose(_In_ ULONG FileId)
Definition: file.c:220
BOOLEAN FileTableCompareWithSubsetAttributes(_In_ PVOID Entry, _In_ PVOID Argument1, _In_ PVOID Argument2, _In_ PVOID Argument3, _In_ PVOID Argument4)
Definition: file.c:105
PWCHAR FileIoCopyFileName(_In_ PWCHAR FilePath)
Definition: file.c:79
PWCHAR ParentFileName
Definition: bootmgr.c:32
@ Unknown
Definition: i8042prt.h:114
Definition: bl.h:1261
ULONG Flags
Definition: bl.h:1263
ULONG ReferenceCount
Definition: bl.h:1265
PBL_FILE_CLOSE Close
Definition: bl.h:1029
PBL_FILE_OPEN Open
Definition: bl.h:1028
ULONG Unknown
Definition: bl.h:1044
ULONGLONG Unknown2
Definition: bl.h:1046
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_In_ PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine
Definition: rtlfuncs.h:1088

Referenced by BlFileOpen(), and FileIoOpen().

◆ FileTableCompareWithSameAttributes()

BOOLEAN FileTableCompareWithSameAttributes ( _In_ PVOID  Entry,
_In_ PVOID  Argument1,
_In_ PVOID  Argument2,
_In_ PVOID  Argument3,
_In_ PVOID  Argument4 
)

Definition at line 138 of file file.c.

145{
147 ULONG DeviceId = *(PULONG)Argument1;
149 ULONG Flags = *(PULONG)Argument3;
152
153 Found = FALSE;
154
155 if ((FileEntry->DeviceId == DeviceId) &&
156 !(_wcsicmp(FileEntry->FilePath, FilePath)) &&
157 (FileEntry->Unknown == Unknown))
158 {
159 if ((!(Flags & 1) || (FileEntry->Flags & 2)) && ((Flags & 1) || !(FileEntry->Flags & 2)) && (!(Flags & 2) || (FileEntry->Flags & 4)) && ((Flags & 2) || !(FileEntry->Flags & 4)))
160 {
161 if ((!(Flags & 4) || (FileEntry->Flags & 0x10000)) && ((Flags & 4) || !(FileEntry->Flags & 0x10000)))
162 {
163 Found = TRUE;
164 }
165 }
166 }
167 return Found;
168}
return Found
Definition: dirsup.c:1270
_In_ PVOID Argument2
Definition: classpnp.h:721
InternalIoctlParams Argument4
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
base of all file and directory entries
Definition: entries.h:83
PWCHAR FilePath
Definition: bl.h:1039
uint32_t * PULONG
Definition: typedefs.h:59
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696

Referenced by BlFileOpen().

◆ FileTableCompareWithSubsetAttributes()

BOOLEAN FileTableCompareWithSubsetAttributes ( _In_ PVOID  Entry,
_In_ PVOID  Argument1,
_In_ PVOID  Argument2,
_In_ PVOID  Argument3,
_In_ PVOID  Argument4 
)

Definition at line 105 of file file.c.

112{
114 ULONG DeviceId = *(PULONG)Argument1;
116 ULONG Flags = *(PULONG)Argument3;
119
120 Found = FALSE;
121
122 if ((FileEntry->DeviceId == DeviceId) &&
123 !(_wcsicmp(FileEntry->FilePath, FilePath)) &&
124 (FileEntry->Unknown == Unknown))
125 {
126 if ((!(Flags & 1) || (FileEntry->Flags & 2)) && (!(Flags & 2) || (FileEntry->Flags & 4)))
127 {
128 if ((!(Flags & 4) || (FileEntry->Flags & 0x10000)) && ((Flags & 4) || !(FileEntry->Flags & 0x10000)))
129 {
130 Found = TRUE;
131 }
132 }
133 }
134 return Found;
135}

Referenced by FileIoOpen().

◆ FileTableDestroyEntry()

NTSTATUS FileTableDestroyEntry ( _In_ PBL_FILE_ENTRY  FileEntry,
_In_ ULONG  Index 
)

Definition at line 171 of file file.c.

175{
176 ULONG DeviceId;
177 PBL_DEVICE_ENTRY DeviceEntry;
179
180 DeviceId = FileEntry->DeviceId;
181 if (DmTableEntries > DeviceId)
182 {
183 DeviceEntry = DmDeviceTable[DeviceId];
184 if (DeviceEntry)
185 {
186 --DeviceEntry->ReferenceCount;
187 }
188 }
189
190 Status = FileEntry->Callbacks.Close(FileEntry);
191
192 BlMmFreeHeap(FileEntry);
193
195 return Status;
196}
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by FileTablePurgeEntry().

◆ FileTablePurgeEntry()

NTSTATUS FileTablePurgeEntry ( _In_ PVOID  Entry)

Definition at line 201 of file file.c.

204{
206
207 /* Don't purge opened files, or if there's less than 512 files cached */
208 if (((FileEntry->Flags & BL_FILE_ENTRY_OPENED) ||
209 (FileEntry->Flags & 0x10000)) &&
211 {
212 return STATUS_UNSUCCESSFUL;
213 }
214
215 /* Purge the entry otherwise */
216 return FileTableDestroyEntry(FileEntry, FileEntry->FileId);
217}
#define BL_FILE_PURGE_LIMIT
Definition: file.c:198
NTSTATUS FileTableDestroyEntry(_In_ PBL_FILE_ENTRY FileEntry, _In_ ULONG Index)
Definition: file.c:171

Referenced by FileIoOpen().

Variable Documentation

◆ DmDeviceTable

◆ DmTableEntries

◆ EtfsRegisterFunctionTable

BL_FILE_SYSTEM_REGISTRATION_TABLE EtfsRegisterFunctionTable
Initial value:
=
{
}
NTSTATUS EtfsInitialize(VOID)
Definition: etfs.c:969
NTSTATUS EtfsMount(_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
Definition: etfs.c:874

Definition at line 26 of file file.c.

Referenced by BlpFileInitialize().

◆ FatRegisterFunctionTable

BL_FILE_SYSTEM_REGISTRATION_TABLE FatRegisterFunctionTable
Initial value:
=
{
}
NTSTATUS FatInitialize(VOID)
Definition: fat.c:81
NTSTATUS FatMount(_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
Definition: fat.c:23

Definition at line 19 of file file.c.

Referenced by BlpFileInitialize().

◆ FileEntries

◆ FileTable

◆ RegisteredFileSystems

LIST_ENTRY RegisteredFileSystems

Definition at line 18 of file file.c.

Referenced by BlpFileInitialize(), BlpFileRegisterFileSystem(), and FileIoOpen().