ReactOS 0.4.16-dev-297-gc569aee
etfs.c File Reference
#include <bl.h>
#include <cdfs/cd.h>
Include dependency graph for etfs.c:

Go to the source code of this file.

Classes

struct  _RAW_ET_VD
 
struct  _BL_ETFS_DEVICE
 
struct  _BL_ETFS_FILE
 

Typedefs

typedef struct _RAW_ET_VD RAW_ET_VD
 
typedef struct _RAW_ET_VDPRAW_ET_VD
 
typedef struct _BL_ETFS_DEVICE BL_ETFS_DEVICE
 
typedef struct _BL_ETFS_DEVICEPBL_ETFS_DEVICE
 
typedef struct _BL_ETFS_FILE BL_ETFS_FILE
 
typedef struct _BL_ETFS_FILEPBL_ETFS_FILE
 

Functions

NTSTATUS EtfsOpen (_In_ PBL_FILE_ENTRY Directory, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PBL_FILE_ENTRY *FileEntry)
 
NTSTATUS EtfsGetInformation (_In_ PBL_FILE_ENTRY FileEntry, _Out_ PBL_FILE_INFORMATION FileInfo)
 
NTSTATUS EtfsSetInformation (_In_ PBL_FILE_ENTRY FileEntry, _In_ PBL_FILE_INFORMATION FileInfo)
 
NTSTATUS EtfsRead (_In_ PBL_FILE_ENTRY FileEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_opt_ PULONG BytesReturned)
 
VOID EtfspGetDirectoryInfo (_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ PRAW_DIR_REC DirEntry, _Out_ PULONG FileOffset, _Out_ PULONG FileSize, _Out_opt_ PBOOLEAN IsDirectory)
 
USHORT EtfspGetDirentNameLength (_In_ PRAW_DIR_REC DirEntry)
 
LONG EtfspCompareNames (__in PSTRING Name1, __in PUNICODE_STRING Name2)
 
BOOLEAN EtfspFileMatch (_In_ PRAW_DIR_REC DirEntry, _In_ PUNICODE_STRING FileName)
 
NTSTATUS EtfspGetDirent (_In_ PBL_FILE_ENTRY DirectoryEntry, _Out_ PRAW_DIR_REC *DirEntry, _Inout_ PULONG DirentOffset)
 
NTSTATUS EtfspSearchForDirent (_In_ PBL_FILE_ENTRY DirectoryEntry, _In_ PWCHAR FileName, _Out_ PRAW_DIR_REC *DirEntry, _Out_ PULONG DirentOffset)
 
NTSTATUS EtfspCachedSearchForDirent (_In_ PBL_FILE_ENTRY DirectoryEntry, _In_ PWCHAR FileName, _Out_ PRAW_DIR_REC *DirEntry, _Out_ PULONG DirOffset, _In_ BOOLEAN KeepOffset)
 
NTSTATUS EtfspCheckCdfs (_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
 
NTSTATUS EtfspCheckEtfs (_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
 
NTSTATUS EtfspDeviceContextDestroy (_In_ PBL_ETFS_DEVICE EtfsDevice)
 
NTSTATUS EtfspCreateContext (_In_ ULONG DeviceId, _Out_ PBL_ETFS_DEVICE *EtfsDevice)
 
NTSTATUS EtfspDeviceTableDestroyEntry (_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG Index)
 
NTSTATUS EtfsMount (_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
 
NTSTATUS EtfsInitialize (VOID)
 

Variables

ULONG EtfsDeviceTableEntries
 
PVOIDEtfsDeviceTable
 
BL_FILE_CALLBACKS EtfsFunctionTable
 

Typedef Documentation

◆ BL_ETFS_DEVICE

◆ BL_ETFS_FILE

◆ PBL_ETFS_DEVICE

◆ PBL_ETFS_FILE

◆ PRAW_ET_VD

◆ RAW_ET_VD

Function Documentation

◆ EtfsGetInformation()

NTSTATUS EtfsGetInformation ( _In_ PBL_FILE_ENTRY  FileEntry,
_Out_ PBL_FILE_INFORMATION  FileInfo 
)

Definition at line 522 of file etfs.c.

526{
527 PBL_ETFS_FILE EtfsFile;
528
529 /* Get the underlying ETFS file data structure */
530 EtfsFile = (PBL_ETFS_FILE)FileEntry->FsSpecificData;
531
532 /* Copy the cached information structure within it */
533 RtlCopyMemory(FileInfo, &EtfsFile->Size, sizeof(*FileInfo));
534 return STATUS_SUCCESS;
535}
struct _BL_ETFS_FILE * PBL_ETFS_FILE
#define STATUS_SUCCESS
Definition: shellext.h:65
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

◆ EtfsInitialize()

NTSTATUS EtfsInitialize ( VOID  )

Definition at line 969 of file etfs.c.

972{
974
975 /* Allocate the device table with 2 entries*/
979 if (EtfsDeviceTable)
980 {
981 /* Zero it out */
985 }
986 else
987 {
988 /* No memory, fail */
990 }
991
992 /* Return back to caller */
993 return Status;
994}
LONG NTSTATUS
Definition: precomp.h:26
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
PVOID * EtfsDeviceTable
Definition: etfs.c:49
ULONG EtfsDeviceTableEntries
Definition: etfs.c:48
Status
Definition: gdiplustypes.h:25
Definition: bl.h:1038
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

◆ EtfsMount()

NTSTATUS EtfsMount ( _In_ ULONG  DeviceId,
_In_ ULONG  Unknown,
_Out_ PBL_FILE_ENTRY FileEntry 
)

Definition at line 874 of file etfs.c.

879{
880 PBL_ETFS_DEVICE EtfsDevice = NULL;
881 PBL_FILE_ENTRY RootEntry;
883 PBL_ETFS_FILE EtfsFile;
884
885 EfiPrintf(L"Trying to mount as ETFS...\r\n");
886
887 Status = EtfspCreateContext(DeviceId, &EtfsDevice);
888 if (!NT_SUCCESS(Status))
889 {
890 EfiPrintf(L"ETFS context failed: %lx\r\n");
891 return Status;
892 }
893
896 EtfsDevice,
897 &DeviceId,
899 if (!NT_SUCCESS(Status))
900 {
901 EtfspDeviceContextDestroy(EtfsDevice);
902 return Status;
903 }
904
905 RootEntry = BlMmAllocateHeap(sizeof(*RootEntry));
906 if (!RootEntry)
907 {
909 goto Quickie;
910 }
911
912 RtlZeroMemory(RootEntry, sizeof(*RootEntry));
913
914 RootEntry->FilePath = BlMmAllocateHeap(4);
915 if (!RootEntry->FilePath)
916 {
918 goto Quickie;
919 }
920
921 wcsncpy(RootEntry->FilePath, L"\\", 1);
922
923 RootEntry->DeviceId = DeviceId;
924 RtlCopyMemory(&RootEntry->Callbacks,
926 sizeof(RootEntry->Callbacks));
927
928 EtfsFile = (PBL_ETFS_FILE)BlMmAllocateHeap(sizeof(*EtfsFile));
929 if (!EtfsFile)
930 {
932 goto Quickie;
933 }
934
935 RootEntry->Flags |= 0x10000;
936
937 RtlZeroMemory(EtfsFile, sizeof(*EtfsFile));
938 RootEntry->FsSpecificData = EtfsFile;
939 EtfsFile->DeviceId = DeviceId;
940 EtfsFile->Flags |= 1;
941 EtfsFile->DiskOffset = EtfsDevice->RootDirOffset;
942 EtfsFile->DirOffset = 0;
943 EtfsFile->Size = EtfsDevice->RootDirSize;
944 EtfsFile->FsName = L"cdfs";
945 *FileEntry = RootEntry;
946
947 return STATUS_SUCCESS;
948
949Quickie:
950 if (RootEntry->FilePath)
951 {
952 BlMmFreeHeap(RootEntry->FilePath);
953 }
954 if (RootEntry->FsSpecificData)
955 {
956 BlMmFreeHeap(RootEntry->FsSpecificData);
957 }
958 if (RootEntry)
959 {
960 BlMmFreeHeap(RootEntry);
961 }
962
963 EtfspDeviceTableDestroyEntry(EtfsDevice, DeviceId);
964
965 return Status;
966}
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
NTSTATUS TblDoNotPurgeEntry(_In_ PVOID Entry)
Definition: util.c:495
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS EtfspCreateContext(_In_ ULONG DeviceId, _Out_ PBL_ETFS_DEVICE *EtfsDevice)
Definition: etfs.c:800
NTSTATUS EtfspDeviceTableDestroyEntry(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG Index)
Definition: etfs.c:862
NTSTATUS EtfspDeviceContextDestroy(_In_ PBL_ETFS_DEVICE EtfsDevice)
Definition: etfs.c:785
BL_FILE_CALLBACKS EtfsFunctionTable
Definition: etfs.c:79
#define L(x)
Definition: ntvdm.h:50
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
ULONG RootDirSize
Definition: etfs.c:29
ULONG RootDirOffset
Definition: etfs.c:28
ULONG DiskOffset
Definition: etfs.c:39
ULONG DeviceId
Definition: etfs.c:45
ULONG DirOffset
Definition: etfs.c:40
BL_FILE_CALLBACKS Callbacks
Definition: bl.h:1047
PVOID FsSpecificData
Definition: bl.h:1048
PWCHAR FilePath
Definition: bl.h:1039
ULONG DeviceId
Definition: bl.h:1040
ULONG Flags
Definition: bl.h:1042

◆ EtfsOpen()

NTSTATUS EtfsOpen ( _In_ PBL_FILE_ENTRY  Directory,
_In_ PWCHAR  FileName,
_In_ ULONG  Flags,
_Out_ PBL_FILE_ENTRY FileEntry 
)

Definition at line 538 of file etfs.c.

544{
545 PBL_ETFS_DEVICE EtfsDevice;
547 PBL_FILE_ENTRY NewFile;
549 PBL_ETFS_FILE EtfsFile;
550 ULONG DeviceId, FileSize, DirOffset, FileOffset;
551 SIZE_T Size;
554
555 EtfsFile = Directory->FsSpecificData;
556 DeviceId = EtfsFile->DeviceId;
557 EtfsDevice = EtfsDeviceTable[DeviceId];
558
559 /* Find the given file (or directory) in the given directory */
561 FileName,
562 &DirEntry,
563 &DirOffset,
564 FALSE);
565 if (!NT_SUCCESS(Status))
566 {
567 return Status;
568 }
569
570 /* Find out information about the file (or directory) we found */
571 EtfspGetDirectoryInfo(EtfsDevice,
572 DirEntry,
573 &FileOffset,
574 &FileSize,
575 &IsDirectory);
576
577 /* Allocate a file entry */
578 NewFile = BlMmAllocateHeap(sizeof(*NewFile));
579 if (!NewFile)
580 {
581 return STATUS_NO_MEMORY;
582 }
583
584 /* Zero it out */
585 RtlZeroMemory(NewFile, sizeof(*NewFile));
586
587 /* Figure out the size of the path and filename plus a slash and NUL */
588 Size = wcslen(Directory->FilePath) + wcslen(FileName) + 2;
589 FilePath = BlMmAllocateHeap(Size * sizeof(WCHAR));
590 if (!FilePath)
591 {
593 goto Quickie;
594 }
595
596 /* Allocate an ETFS file entry */
597 EtfsFile = (PBL_ETFS_FILE)BlMmAllocateHeap(sizeof(*EtfsFile));
598 if (!EtfsFile)
599 {
601 goto Quickie;
602 }
603
604 /* Zero it out */
605 RtlZeroMemory(EtfsFile, sizeof(*EtfsFile));
606
607 /* Capture the device ID of the directory */
608 NewFile->DeviceId = Directory->DeviceId;
609
610 /* Check if this is the root or a filename\directory under */
611 FormatString = L"%ls%ls";
612 if (Directory->FilePath[1])
613 {
614 FormatString = L"%ls\\%ls";
615 }
616
617 /* Combine the paths, and save the final path in the file entry */
619 NewFile->FilePath = FilePath;
620
621 /* Copy the ETFS function callbacks into the file netry */
622 RtlCopyMemory(&NewFile->Callbacks,
624 sizeof(NewFile->Callbacks));
625
626 /* Fill out the rest of the details */
627 EtfsFile->DiskOffset = FileOffset;
628 EtfsFile->DirOffset = DirOffset;
629 EtfsFile->Size = FileSize;
630 EtfsFile->DeviceId = DeviceId;
631
632 /* Check if this is a directory */
633 if (IsDirectory)
634 {
635 EtfsFile->Flags |= BL_ETFS_FILE_ENTRY_DIRECTORY;
636 NewFile->Flags |= BL_FILE_ENTRY_DIRECTORY;
637 }
638
639 /* Write down the name of the filesystem */
640 EtfsFile->FsName = L"cdfs";
641
642 /* All done, return the file entry, and save the ETFS side */
643 NewFile->FsSpecificData = EtfsFile;
644 *FileEntry = NewFile;
645 return Status;
646
647Quickie:
648 /* Failure path -- free the file path if we had one */
649 if (NewFile->FilePath)
650 {
651 BlMmFreeHeap(NewFile->FilePath);
652 }
653
654 /* Free the ETFS file entry if we had one */
655 if (NewFile->FsSpecificData)
656 {
658 }
659
660 /* Free the file entry itself, and return the error code */
661 BlMmFreeHeap(NewFile);
662 return Status;
663}
PCWSTR FilePath
unsigned char BOOLEAN
#define BL_FILE_ENTRY_DIRECTORY
Definition: bl.h:163
#define BL_ETFS_FILE_ENTRY_DIRECTORY
Definition: bl.h:165
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define FALSE
Definition: types.h:117
NTSTATUS EtfspCachedSearchForDirent(_In_ PBL_FILE_ENTRY DirectoryEntry, _In_ PWCHAR FileName, _Out_ PRAW_DIR_REC *DirEntry, _Out_ PULONG DirOffset, _In_ BOOLEAN KeepOffset)
Definition: etfs.c:370
VOID EtfspGetDirectoryInfo(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ PRAW_DIR_REC DirEntry, _Out_ PULONG FileOffset, _Out_ PULONG FileSize, _Out_opt_ PBOOLEAN IsDirectory)
Definition: etfs.c:93
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
DWORD FormatString(DWORD dwFlags, HINSTANCE hInstance, DWORD dwStringId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
Definition: fontview.c:34
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
base for all directory entries
Definition: entries.h:138
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ EtfspCachedSearchForDirent()

NTSTATUS EtfspCachedSearchForDirent ( _In_ PBL_FILE_ENTRY  DirectoryEntry,
_In_ PWCHAR  FileName,
_Out_ PRAW_DIR_REC DirEntry,
_Out_ PULONG  DirOffset,
_In_ BOOLEAN  KeepOffset 
)

Definition at line 370 of file etfs.c.

377{
378 PBL_ETFS_FILE EtfsFile;
379 PBL_ETFS_DEVICE EtfsDevice;
384
385 EtfsFile = DirectoryEntry->FsSpecificData;
386 EtfsDevice = EtfsDeviceTable[EtfsFile->DeviceId];
388 DirentOffset = EtfsFile->DirEntOffset;
389
390 if ((KeepOffset) ||
392 EtfsDevice->Offset))
393 {
394 Status = EtfspGetDirent(DirectoryEntry, &Dirent, &DirentOffset);
395 if (NT_SUCCESS(Status))
396 {
397 if (!EtfspFileMatch(Dirent, &Name))
398 {
399 *DirEntry = Dirent;
400 *DirOffset = DirentOffset;
401 return STATUS_SUCCESS;
402 }
403 }
404 else
405 {
406 DirentOffset = 0;
407 }
408 }
409 else
410 {
411 DirentOffset = 0;
412 }
413
414 Status = EtfspSearchForDirent(DirectoryEntry,
415 FileName,
416 DirEntry,
417 &DirentOffset);
418 if (!(NT_SUCCESS(Status)) && (DirentOffset))
419 {
420 DirentOffset = 0;
421 Status = EtfspSearchForDirent(DirectoryEntry,
422 FileName,
423 DirEntry,
424 &DirentOffset);
425 }
426
427 if (NT_SUCCESS(Status))
428 {
429 *DirOffset = DirentOffset;
430 }
431
432 return Status;
433}
#define ALIGN_DOWN_BY(size, align)
struct NameRec_ * Name
Definition: cdprocs.h:460
#define CD_SECTOR_SIZE
Definition: cd.h:65
Dirent DirentOffset
Definition: dirsup.c:444
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
NTSTATUS EtfspGetDirent(_In_ PBL_FILE_ENTRY DirectoryEntry, _Out_ PRAW_DIR_REC *DirEntry, _Inout_ PULONG DirentOffset)
Definition: etfs.c:217
NTSTATUS EtfspSearchForDirent(_In_ PBL_FILE_ENTRY DirectoryEntry, _In_ PWCHAR FileName, _Out_ PRAW_DIR_REC *DirEntry, _Out_ PULONG DirentOffset)
Definition: etfs.c:335
BOOLEAN EtfspFileMatch(_In_ PRAW_DIR_REC DirEntry, _In_ PUNICODE_STRING FileName)
Definition: etfs.c:190
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
ULONG Offset
Definition: etfs.c:34
ULONG DirEntOffset
Definition: etfs.c:41

Referenced by EtfsOpen().

◆ EtfspCheckCdfs()

NTSTATUS EtfspCheckCdfs ( _In_ PBL_ETFS_DEVICE  EtfsDevice,
_In_ ULONG  DeviceId,
_Out_ PRAW_ISO_VD VolumeDescriptor,
_Out_ PBOOLEAN  VolumeIsIso 
)

Definition at line 666 of file etfs.c.

672{
673 EfiPrintf(L"Raw Cdfs not implemented\r\n");
675}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42

Referenced by EtfspCreateContext().

◆ EtfspCheckEtfs()

NTSTATUS EtfspCheckEtfs ( _In_ PBL_ETFS_DEVICE  EtfsDevice,
_In_ ULONG  DeviceId,
_Out_ PRAW_ISO_VD VolumeDescriptor,
_Out_ PBOOLEAN  VolumeIsIso 
)

Definition at line 678 of file etfs.c.

684{
685 PRAW_ISO_VD IsoVd;
686 PRAW_ET_VD EtVd;
688 BOOLEAN IsIso;
689 BL_DEVICE_INFORMATION DeviceInformation;
692
693 /* Save our static buffer pointer */
694 IsoVd = (PRAW_ISO_VD)EtfsDevice->MemoryBlock;
695 EtVd = (PRAW_ET_VD)IsoVd;
696
697 /* First, read the El Torito Volume Descriptor */
698 BlDeviceGetInformation(DeviceId, &DeviceInformation);
699 Unknown = DeviceInformation.BlockDeviceInfo.Unknown;
700 DeviceInformation.BlockDeviceInfo.Unknown |= 1;
701 BlDeviceSetInformation(DeviceId, &DeviceInformation);
702 Status = BlDeviceReadAtOffset(DeviceId,
705 EtfsDevice->MemoryBlock,
706 &BytesRead);
707 DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
708 BlDeviceSetInformation(DeviceId, &DeviceInformation);
709 if (!NT_SUCCESS(Status))
710 {
711 EfiPrintf(L" read failed\r\n");
712 return Status;
713 }
714
715 /* Remember that's where we last read */
716 EtfsDevice->Offset = (FIRST_VD_SECTOR + 1) * CD_SECTOR_SIZE;
717
718 /* Check if it's EL TORITO! */
719 RtlInitString(&String, "EL TORITO SPECIFICATION");
720 CompareString.Buffer = (PCHAR)EtVd->SystemId;
721 CompareString.Length = 23;
722 CompareString.MaximumLength = 23;
724 {
725 return STATUS_UNSUCCESSFUL;
726 }
727
728 /* Check the version and boot indicator */
729 if ((EtVd->Version != 1) || (EtVd->BootIndicator))
730 {
731 return STATUS_UNSUCCESSFUL;
732 }
733
734 /* Check if it has the CD0001 identifier */
736 CompareString.Buffer = (PCHAR)EtVd->StandardId;
737 CompareString.Length = 5;
738 CompareString.MaximumLength = 5;
740 {
741 return STATUS_UNSUCCESSFUL;
742 }
743
744 /* Step two, we now want to read the ISO Volume Descriptor */
745 DeviceInformation.BlockDeviceInfo.Unknown |= 1u;
746 BlDeviceSetInformation(DeviceId, &DeviceInformation);
747 Status = BlDeviceReadAtOffset(DeviceId,
750 EtfsDevice->MemoryBlock,
751 &BytesRead);
752 DeviceInformation.BlockDeviceInfo.Unknown = Unknown;
753 BlDeviceSetInformation(DeviceId, &DeviceInformation);
754 if (!NT_SUCCESS(Status))
755 {
756 return Status;
757 }
758
759 /* Remember where we left off */
760 EtfsDevice->Offset = FIRST_VD_SECTOR * CD_SECTOR_SIZE;
761
762 /* This should also say CD0001 */
763 CompareString.Buffer = (PCHAR)IsoVd->StandardId;
764 CompareString.Length = 5;
765 CompareString.MaximumLength = 5;
767 if (!IsIso)
768 {
769 return STATUS_UNSUCCESSFUL;
770 }
771
772 /* And should be a version we support */
773 if ((IsoVd->Version != VERSION_1) || (IsoVd->DescType != VD_PRIMARY))
774 {
775 return STATUS_UNSUCCESSFUL;
776 }
777
778 /* Return back to the caller */
779 *VolumeDescriptor = IsoVd;
780 *VolumeIsIso = IsIso;
781 return STATUS_SUCCESS;
782}
NTSTATUS BlDeviceGetInformation(_In_ ULONG DeviceId, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:682
NTSTATUS BlDeviceReadAtOffset(_In_ ULONG DeviceId, _In_ ULONG Size, _In_ ULONGLONG Offset, _In_ PVOID Buffer, _Out_ PULONG BytesRead)
Definition: device.c:773
NTSTATUS BlDeviceSetInformation(_In_ ULONG DeviceId, _In_ PBL_DEVICE_INFORMATION DeviceInformation)
#define ISO_VOL_ID
Definition: cd.h:67
RAW_ISO_VD * PRAW_ISO_VD
Definition: cd.h:166
#define VERSION_1
Definition: cd.h:53
#define FIRST_VD_SECTOR
Definition: cd.h:48
#define VD_PRIMARY
Definition: cd.h:56
#define TRUE
Definition: types.h:120
@ Unknown
Definition: i8042prt.h:114
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
BL_BLOCK_DEVICE_INFORMATION BlockDeviceInfo
Definition: bl.h:1228
UCHAR BootIndicator
Definition: etfs.c:15
UCHAR SystemId[32]
Definition: etfs.c:18
UCHAR Version
Definition: etfs.c:17
UCHAR StandardId[5]
Definition: etfs.c:16
UCHAR DescType
Definition: cd.h:128
UCHAR StandardId[5]
Definition: cd.h:129
UCHAR Version
Definition: cd.h:130
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
#define CompareString
Definition: winnls.h:1230

Referenced by EtfspCreateContext().

◆ EtfspCompareNames()

LONG EtfspCompareNames ( __in PSTRING  Name1,
__in PUNICODE_STRING  Name2 
)

Definition at line 160 of file etfs.c.

164{
165 ULONG i, l1, l2, l;
166
167 l1 = Name1->Length;
168 l2 = Name2->Length / sizeof(WCHAR);
169 l = min(l1, l2);
170
171 for (i = 0; i < l; i++)
172 {
173 if (toupper(Name1->Buffer[i]) != toupper(Name2->Buffer[i]))
174 {
175 return toupper(Name1->Buffer[i]) - toupper(Name2->Buffer[i]);
176 }
177 }
178
179 if (l2 <= l1)
180 {
181 return l2 < l1;
182 }
183 else
184 {
185 return -1;
186 }
187}
int toupper(int c)
Definition: utclib.c:881
r l[0]
Definition: byte_order.h:168
_Must_inspect_result_ _In_ PCUNICODE_STRING Name2
Definition: fsrtlfuncs.h:796
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define min(a, b)
Definition: monoChain.cc:55

Referenced by EtfspFileMatch().

◆ EtfspCreateContext()

NTSTATUS EtfspCreateContext ( _In_ ULONG  DeviceId,
_Out_ PBL_ETFS_DEVICE EtfsDevice 
)

Definition at line 800 of file etfs.c.

804{
806 PVOID MemoryBlock;
808 BOOLEAN IsIso;
809 PRAW_ISO_VD RawVd;
810
812 if (!NewContext)
813 {
814 return STATUS_NO_MEMORY;
815 }
817
818 MemoryBlock = BlMmAllocateHeap(CD_SECTOR_SIZE);
819 NewContext->MemoryBlock = MemoryBlock;
820 if (!MemoryBlock)
821 {
823 goto Quickie;
824 }
825
826 Status = EtfspCheckEtfs(NewContext, DeviceId, &RawVd, &IsIso);
827 if (!NT_SUCCESS(Status))
828 {
829 EfiPrintf(L"Drive not EDFS. Checking for CDFS: %lx\r\n");
830 Status = EtfspCheckCdfs(NewContext, DeviceId, &RawVd, &IsIso);
831 }
832
833 if (!NT_SUCCESS(Status))
834 {
835 EfiPrintf(L"Drive not CDFS. Failing: %lx\r\n");
836 goto Quickie;
837 }
838
839 NewContext->IsIso = IsIso;
840 NewContext->BlockSize = RVD_LB_SIZE(RawVd, IsIso);
841 NewContext->VolumeSize = RVD_VOL_SIZE(RawVd, IsIso);
842
844 (PRAW_DIR_REC)RVD_ROOT_DE(RawVd, IsIso),
845 &NewContext->RootDirOffset,
846 &NewContext->RootDirSize,
847 0);
849
850Quickie:
851 if (!NT_SUCCESS(Status))
852 {
855 }
856
857 *EtfsDevice = NewContext;
858 return Status;
859}
#define RVD_ROOT_DE(r, i)
Definition: cd.h:90
#define RVD_LB_SIZE(r, i)
Definition: cd.h:84
#define RVD_VOL_SIZE(r, i)
Definition: cd.h:87
NTSTATUS EtfspCheckEtfs(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
Definition: etfs.c:678
struct _BL_ETFS_DEVICE * PBL_ETFS_DEVICE
NTSTATUS EtfspCheckCdfs(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
Definition: etfs.c:666
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT NewContext
Definition: fltkernel.h:1468

Referenced by EtfsMount().

◆ EtfspDeviceContextDestroy()

NTSTATUS EtfspDeviceContextDestroy ( _In_ PBL_ETFS_DEVICE  EtfsDevice)

Definition at line 785 of file etfs.c.

788{
789 if (EtfsDevice->MemoryBlock)
790 {
791 BlMmFreeHeap(EtfsDevice->MemoryBlock);
792 }
793
794 BlMmFreeHeap(EtfsDevice);
795
796 return STATUS_SUCCESS;
797}

Referenced by EtfsMount(), EtfspCreateContext(), and EtfspDeviceTableDestroyEntry().

◆ EtfspDeviceTableDestroyEntry()

NTSTATUS EtfspDeviceTableDestroyEntry ( _In_ PBL_ETFS_DEVICE  EtfsDevice,
_In_ ULONG  Index 
)

Definition at line 862 of file etfs.c.

866{
867 EtfspDeviceContextDestroy(EtfsDevice);
869
870 return STATUS_SUCCESS;
871}
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by EtfsMount().

◆ EtfspFileMatch()

BOOLEAN EtfspFileMatch ( _In_ PRAW_DIR_REC  DirEntry,
_In_ PUNICODE_STRING  FileName 
)

Definition at line 190 of file etfs.c.

194{
195 BOOLEAN Match;
198
199 if ((DirEntry->FileIdLen != 1) ||
200 ((DirEntry->FileId[0] != 0) && (DirEntry->FileId[0] != 1)))
201 {
203 DirName.Length = Length;
204 DirName.MaximumLength = Length;
205 DirName.Buffer = (PCHAR)DirEntry->FileId;
206
208 }
209 else
210 {
211 Match = -1;
212 }
213 return Match;
214}
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
USHORT EtfspGetDirentNameLength(_In_ PRAW_DIR_REC DirEntry)
Definition: etfs.c:124
LONG EtfspCompareNames(__in PSTRING Name1, __in PUNICODE_STRING Name2)
Definition: etfs.c:160
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61

Referenced by EtfspCachedSearchForDirent(), and EtfspSearchForDirent().

◆ EtfspGetDirectoryInfo()

VOID EtfspGetDirectoryInfo ( _In_ PBL_ETFS_DEVICE  EtfsDevice,
_In_ PRAW_DIR_REC  DirEntry,
_Out_ PULONG  FileOffset,
_Out_ PULONG  FileSize,
_Out_opt_ PBOOLEAN  IsDirectory 
)

Definition at line 93 of file etfs.c.

100{
102 BOOLEAN IsDir;
103
104 *FileOffset = *(PULONG)DirEntry->FileLoc * EtfsDevice->BlockSize;
105 *FileOffset += (DirEntry->XarLen * EtfsDevice->BlockSize);
106
108
109 *FileSize = *(PULONG)DirEntry->DataLen;
110
111 IsDir = DE_FILE_FLAGS(EtfsDevice->IsIso, DirEntry) & ISO_ATTR_DIRECTORY;
112 if (IsDir)
113 {
115 }
116
117 if (IsDirectory)
118 {
119 *IsDirectory = IsDir;
120 }
121}
#define ALIGN_UP_BY(size, align)
#define ISO_ATTR_DIRECTORY
Definition: cd.h:71
#define DE_FILE_FLAGS(iso, de)
Definition: cd.h:93
#define SectorOffset(L)
Definition: cdprocs.h:1622
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by EtfsOpen(), and EtfspCreateContext().

◆ EtfspGetDirent()

NTSTATUS EtfspGetDirent ( _In_ PBL_FILE_ENTRY  DirectoryEntry,
_Out_ PRAW_DIR_REC DirEntry,
_Inout_ PULONG  DirentOffset 
)

Definition at line 217 of file etfs.c.

222{
223 PBL_ETFS_FILE EtfsFile;
224 ULONG FileOffset, DirectoryOffset, AlignedOffset, RemainderOffset;
225 ULONG DeviceId, ReadSize, DirLen;
226 PBL_ETFS_DEVICE EtfsDevice;
227 BOOLEAN NeedRead, IsMulti;
229 PRAW_DIR_REC DirEnt;
230 PUCHAR MemoryBlock;
231
232 EtfsFile = DirectoryEntry->FsSpecificData;
233 DeviceId = EtfsFile->DeviceId;
234 FileOffset = EtfsFile->DiskOffset;
235 EtfsDevice = EtfsDeviceTable[DeviceId];
236
237 DirectoryOffset = *DirentOffset;
238 MemoryBlock = EtfsDevice->MemoryBlock;
239
240 IsMulti = 0;
241
242 AlignedOffset = (FileOffset + *DirentOffset) & ~CD_SECTOR_SIZE;
243 RemainderOffset = *DirentOffset + FileOffset - AlignedOffset;
244
245 ReadSize = 2048 - RemainderOffset;
246 NeedRead = AlignedOffset == EtfsDevice->Offset ? 0 : 1;
247
248ReadAgain:
249 if (DirectoryOffset >= EtfsFile->Size)
250 {
251 return STATUS_NO_SUCH_FILE;
252 }
253
254 while (ReadSize < MIN_DIR_REC_SIZE)
255 {
256 DirectoryOffset += ReadSize;
257 AlignedOffset += 2048;
258 ReadSize = 2048;
259 RemainderOffset = 0;
260 NeedRead = 1;
261 if (DirectoryOffset >= EtfsFile->Size)
262 {
263 return STATUS_NO_SUCH_FILE;
264 }
265 }
266
267 if (NeedRead)
268 {
269 result = BlDeviceReadAtOffset(DirectoryEntry->DeviceId,
271 AlignedOffset,
272 MemoryBlock,
273 NULL);
274 if (!NT_SUCCESS(result))
275 {
276 EfiPrintf(L"Device read failed %lx\r\n", result);
277 return result;
278 }
279
280 NeedRead = FALSE;
281 EtfsDevice->Offset = AlignedOffset;
282 }
283
284 if (!*(MemoryBlock + RemainderOffset))
285 {
286 AlignedOffset += 2048;
287 NeedRead = TRUE;
288
289 RemainderOffset = 0;
290 DirectoryOffset += ReadSize;
291 ReadSize = 2048;
292 goto ReadAgain;
293 }
294
295 DirEnt = (PRAW_DIR_REC)(MemoryBlock + RemainderOffset);
296 DirLen = DirEnt->DirLen;
297 if (DirLen > ReadSize)
298 {
299 EfiPrintf(L"Dir won't fit %lx %lx\r\n", DirLen, ReadSize);
300 return STATUS_NO_SUCH_FILE;
301 }
302
303 if (IsMulti)
304 {
305 if (!(DE_FILE_FLAGS(EtfsDevice->IsIso, DirEnt) & ISO_ATTR_MULTI))
306 {
307 IsMulti = TRUE;
308 }
309 }
310 else if (DE_FILE_FLAGS(EtfsDevice->IsIso, DirEnt) & ISO_ATTR_MULTI)
311 {
312 IsMulti = TRUE;
313 }
314 else
315 {
316 if ((DirEnt->FileIdLen != 1) ||
317 ((DirEnt->FileId[0] != 0) && (DirEnt->FileId[0] != 1)))
318 {
319 goto Quickie;
320 }
321 }
322
323 RemainderOffset += DirLen;
324 DirectoryOffset += DirLen;
325 ReadSize -= DirLen;
326 goto ReadAgain;
327
328Quickie:
329 *DirEntry = DirEnt;
330 *DirentOffset = DirectoryOffset;
331 return STATUS_SUCCESS;
332}
RAW_DIRENT * PRAW_DIR_REC
Definition: cd.h:350
#define ISO_ATTR_MULTI
Definition: cd.h:70
#define MIN_DIR_REC_SIZE
Definition: cd.h:73
GLuint64EXT * result
Definition: glext.h:11304
BOOLEAN IsIso
Definition: etfs.c:32
PUCHAR MemoryBlock
Definition: etfs.c:33
UCHAR FileIdLen
Definition: cd.h:345
UCHAR FileId[MAX_FILE_ID_LENGTH]
Definition: cd.h:346
UCHAR DirLen
Definition: cd.h:332
unsigned char * PUCHAR
Definition: typedefs.h:53
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137

Referenced by EtfspCachedSearchForDirent(), and EtfspSearchForDirent().

◆ EtfspGetDirentNameLength()

USHORT EtfspGetDirentNameLength ( _In_ PRAW_DIR_REC  DirEntry)

Definition at line 124 of file etfs.c.

127{
128 USHORT Length, RealLength;
129 PUCHAR Pos;
130
131 RealLength = Length = DirEntry->FileIdLen;
132 for (Pos = DirEntry->FileId + Length - 1; Length; --Pos)
133 {
134 --Length;
135
136 if (*Pos == ';')
137 {
138 RealLength = Length;
139 break;
140 }
141 }
142
143 Length = RealLength;
144 for (Pos = DirEntry->FileId + Length - 1; Length; --Pos)
145 {
146 --Length;
147
148 if (*Pos != '.')
149 {
150 break;
151 }
152
153 RealLength = Length;
154 }
155
156 return RealLength;
157}
ush Pos
Definition: deflate.h:92

Referenced by EtfspFileMatch().

◆ EtfspSearchForDirent()

NTSTATUS EtfspSearchForDirent ( _In_ PBL_FILE_ENTRY  DirectoryEntry,
_In_ PWCHAR  FileName,
_Out_ PRAW_DIR_REC DirEntry,
_Out_ PULONG  DirentOffset 
)

Definition at line 335 of file etfs.c.

341{
343 ULONG NextOffset;
344 PRAW_DIR_REC DirEnt;
346
348 for (NextOffset = *DirentOffset;
349 ;
350 NextOffset = NextOffset + DirEnt->DirLen)
351 {
352 Status = EtfspGetDirent(DirectoryEntry, &DirEnt, &NextOffset);
353 if (!NT_SUCCESS(Status))
354 {
355 return STATUS_NO_SUCH_FILE;
356 }
357
358 if (!EtfspFileMatch(DirEnt, &Name))
359 {
360 break;
361 }
362 }
363
364 *DirEntry = DirEnt;
365 *DirentOffset = NextOffset;
366 return 0;
367}

Referenced by EtfspCachedSearchForDirent().

◆ EtfsRead()

NTSTATUS EtfsRead ( _In_ PBL_FILE_ENTRY  FileEntry,
_In_ PVOID  Buffer,
_In_ ULONG  Size,
_Out_opt_ PULONG  BytesReturned 
)

Definition at line 436 of file etfs.c.

442{
444 PBL_ETFS_FILE EtfsFile;
446
447 /* Assume failure for now */
448 BytesRead = 0;
449
450 /* Make sure that the read is within the file's boundaries */
451 EtfsFile = FileEntry->FsSpecificData;
452 if ((Size + EtfsFile->Offset) > EtfsFile->Size)
453 {
454 /* Bail out otherwise */
456 }
457 else
458 {
459 /* Read the offset that matches this file's offset, on the disk */
460 Status = BlDeviceReadAtOffset(FileEntry->DeviceId,
461 Size,
462 EtfsFile->Offset + EtfsFile->DiskOffset,
463 Buffer,
464 &BytesRead);
465 if (NT_SUCCESS(Status))
466 {
467 /* Update the file offset and return the size as having been read */
468 EtfsFile->Offset += Size;
469 BytesRead = Size;
470 }
471 }
472
473 /* Check if caller wanted to know how many bytes were read */
474 if (BytesReturned)
475 {
476 /* Return the value */
478 }
479
480 /* All done */
481 return Status;
482}
Definition: bufpool.h:45
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_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

◆ EtfsSetInformation()

NTSTATUS EtfsSetInformation ( _In_ PBL_FILE_ENTRY  FileEntry,
_In_ PBL_FILE_INFORMATION  FileInfo 
)

Definition at line 485 of file etfs.c.

489{
490 PBL_ETFS_FILE EtfsFile;
491 BL_FILE_INFORMATION LocalFileInfo;
492
493 /* Get the underlying ETFS file data structure */
494 EtfsFile = (PBL_ETFS_FILE)FileEntry->FsSpecificData;
495
496 /* Make a copy of the incoming attributes, but ignore the new offset */
497 LocalFileInfo = *FileInfo;
498 LocalFileInfo.Offset = EtfsFile->Offset;
499
500 /* Check if these match exactly the current file */
501 if (!RtlEqualMemory(&LocalFileInfo, &EtfsFile->Size, sizeof(*FileInfo)))
502 {
503 /* Nope -- which means caller is trying to change an immutable */
504 EfiPrintf(L"Incorrect information change\r\n");
506 }
507
508 /* Is the offset past the end of the file? */
509 if (FileInfo->Offset >= EtfsFile->Size)
510 {
511 /* Don't allow EOF */
512 EfiPrintf(L"Offset too large: %lx vs %lx\r\n", FileInfo->Offset, EtfsFile->Size);
514 }
515
516 /* Update the offset */
517 EtfsFile->Offset = FileInfo->Offset;
518 return STATUS_SUCCESS;
519}
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
ULONGLONG Offset
Definition: bl.h:1021

Variable Documentation

◆ EtfsDeviceTable

◆ EtfsDeviceTableEntries

ULONG EtfsDeviceTableEntries

Definition at line 48 of file etfs.c.

Referenced by EtfsInitialize(), and EtfsMount().

◆ EtfsFunctionTable

BL_FILE_CALLBACKS EtfsFunctionTable
Initial value:
=
{
}
NTSTATUS EtfsGetInformation(_In_ PBL_FILE_ENTRY FileEntry, _Out_ PBL_FILE_INFORMATION FileInfo)
Definition: etfs.c:522
NTSTATUS EtfsRead(_In_ PBL_FILE_ENTRY FileEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_opt_ PULONG BytesReturned)
Definition: etfs.c:436
NTSTATUS EtfsSetInformation(_In_ PBL_FILE_ENTRY FileEntry, _In_ PBL_FILE_INFORMATION FileInfo)
Definition: etfs.c:485
NTSTATUS EtfsOpen(_In_ PBL_FILE_ENTRY Directory, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PBL_FILE_ENTRY *FileEntry)
Definition: etfs.c:538

Definition at line 79 of file etfs.c.

Referenced by EtfsMount(), and EtfsOpen().