2 * COPYRIGHT: See COPYING.ARM in the top level directory
3 * PROJECT: ReactOS UEFI Boot Library
4 * FILE: boot/environ/lib/io/etfs.c
5 * PURPOSE: Boot Library El Torito File System Management Routines
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
12 #include <cdfs_new/cd.h>
13 typedef struct _RAW_ET_VD
20 ULONG BootCatalogOffset
;
22 } RAW_ET_VD
, *PRAW_ET_VD
;
24 /* DATA VARIABLES ************************************************************/
26 typedef struct _BL_ETFS_DEVICE
35 } BL_ETFS_DEVICE
, *PBL_ETFS_DEVICE
;
37 typedef struct _BL_ETFS_FILE
46 } BL_ETFS_FILE
, *PBL_ETFS_FILE
;
48 ULONG EtfsDeviceTableEntries
;
49 PVOID
* EtfsDeviceTable
;
53 _In_ PBL_FILE_ENTRY Directory
,
56 _Out_ PBL_FILE_ENTRY
*FileEntry
61 _In_ PBL_FILE_ENTRY FileEntry
,
62 _Out_ PBL_FILE_INFORMATION FileInfo
67 _In_ PBL_FILE_ENTRY FileEntry
,
68 _In_ PBL_FILE_INFORMATION FileInfo
73 _In_ PBL_FILE_ENTRY FileEntry
,
76 _Out_opt_ PULONG BytesReturned
79 BL_FILE_CALLBACKS EtfsFunctionTable
=
90 /* FUNCTIONS *****************************************************************/
93 EtfspGetDirectoryInfo (
94 _In_ PBL_ETFS_DEVICE EtfsDevice
,
95 _In_ PRAW_DIR_REC DirEntry
,
96 _Out_ PULONG FileOffset
,
97 _Out_ PULONG FileSize
,
98 _Out_opt_ PBOOLEAN IsDirectory
104 *FileOffset
= *(PULONG
)DirEntry
->FileLoc
* EtfsDevice
->BlockSize
;
105 *FileOffset
+= (DirEntry
->XarLen
* EtfsDevice
->BlockSize
);
107 SectorOffset
= ALIGN_DOWN_BY(*FileOffset
, CD_SECTOR_SIZE
);
109 *FileSize
= *(PULONG
)DirEntry
->DataLen
;
111 IsDir
= DE_FILE_FLAGS(EtfsDevice
->IsIso
, DirEntry
) & ISO_ATTR_DIRECTORY
;
114 *FileSize
+= ALIGN_UP_BY(SectorOffset
, CD_SECTOR_SIZE
) - SectorOffset
;
119 *IsDirectory
= IsDir
;
124 EtfspGetDirentNameLength (
125 _In_ PRAW_DIR_REC DirEntry
128 USHORT Length
, RealLength
;
131 RealLength
= Length
= DirEntry
->FileIdLen
;
132 for (Pos
= DirEntry
->FileId
+ Length
- 1; Length
; --Pos
)
144 for (Pos
= DirEntry
->FileId
+ Length
- 1; Length
; --Pos
)
162 __in PUNICODE_STRING Name2
168 l2
= Name2
->Length
/ sizeof(WCHAR
);
171 for (i
= 0; i
< l
; i
++)
173 if (toupper(Name1
->Buffer
[i
]) != toupper(Name2
->Buffer
[i
]))
175 return toupper(Name1
->Buffer
[i
]) - toupper(Name2
->Buffer
[i
]);
191 _In_ PRAW_DIR_REC DirEntry
,
192 _In_ PUNICODE_STRING FileName
199 if ((DirEntry
->FileIdLen
!= 1) ||
200 ((DirEntry
->FileId
[0] != 0) && (DirEntry
->FileId
[0] != 1)))
202 Length
= EtfspGetDirentNameLength(DirEntry
);
203 DirName
.Length
= Length
;
204 DirName
.MaximumLength
= Length
;
205 DirName
.Buffer
= (PCHAR
)DirEntry
->FileId
;
207 Match
= EtfspCompareNames(&DirName
, FileName
);
218 _In_ PBL_FILE_ENTRY DirectoryEntry
,
219 _Out_ PRAW_DIR_REC
*DirEntry
,
220 _Inout_ PULONG DirentOffset
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
;
232 EtfsFile
= DirectoryEntry
->FsSpecificData
;
233 DeviceId
= EtfsFile
->DeviceId
;
234 FileOffset
= EtfsFile
->DiskOffset
;
235 EtfsDevice
= EtfsDeviceTable
[DeviceId
];
237 DirectoryOffset
= *DirentOffset
;
238 MemoryBlock
= EtfsDevice
->MemoryBlock
;
242 AlignedOffset
= (FileOffset
+ *DirentOffset
) & ~CD_SECTOR_SIZE
;
243 RemainderOffset
= *DirentOffset
+ FileOffset
- AlignedOffset
;
245 ReadSize
= 2048 - RemainderOffset
;
246 NeedRead
= AlignedOffset
== EtfsDevice
->Offset
? 0 : 1;
249 if (DirectoryOffset
>= EtfsFile
->Size
)
251 return STATUS_NO_SUCH_FILE
;
254 while (ReadSize
< MIN_DIR_REC_SIZE
)
256 DirectoryOffset
+= ReadSize
;
257 AlignedOffset
+= 2048;
261 if (DirectoryOffset
>= EtfsFile
->Size
)
263 return STATUS_NO_SUCH_FILE
;
269 result
= BlDeviceReadAtOffset(DirectoryEntry
->DeviceId
,
274 if (!NT_SUCCESS(result
))
276 EfiPrintf(L
"Device read failed %lx\r\n", result
);
281 EtfsDevice
->Offset
= AlignedOffset
;
284 if (!*(MemoryBlock
+ RemainderOffset
))
286 AlignedOffset
+= 2048;
290 DirectoryOffset
+= ReadSize
;
295 DirEnt
= (PRAW_DIR_REC
)(MemoryBlock
+ RemainderOffset
);
296 DirLen
= DirEnt
->DirLen
;
297 if (DirLen
> ReadSize
)
299 EfiPrintf(L
"Dir won't fit %lx %lx\r\n", DirLen
, ReadSize
);
300 return STATUS_NO_SUCH_FILE
;
305 if (!(DE_FILE_FLAGS(EtfsDevice
->IsIso
, DirEnt
) & ISO_ATTR_MULTI
))
310 else if (DE_FILE_FLAGS(EtfsDevice
->IsIso
, DirEnt
) & ISO_ATTR_MULTI
)
316 if ((DirEnt
->FileIdLen
!= 1) ||
317 ((DirEnt
->FileId
[0] != 0) && (DirEnt
->FileId
[0] != 1)))
323 RemainderOffset
+= DirLen
;
324 DirectoryOffset
+= DirLen
;
330 *DirentOffset
= DirectoryOffset
;
331 return STATUS_SUCCESS
;
335 EtfspSearchForDirent (
336 _In_ PBL_FILE_ENTRY DirectoryEntry
,
337 _In_ PWCHAR FileName
,
338 _Out_ PRAW_DIR_REC
*DirEntry
,
339 _Out_ PULONG DirentOffset
347 RtlInitUnicodeString(&Name
, FileName
);
348 for (NextOffset
= *DirentOffset
;
350 NextOffset
= NextOffset
+ DirEnt
->DirLen
)
352 Status
= EtfspGetDirent(DirectoryEntry
, &DirEnt
, &NextOffset
);
353 if (!NT_SUCCESS(Status
))
355 return STATUS_NO_SUCH_FILE
;
358 if (!EtfspFileMatch(DirEnt
, &Name
))
365 *DirentOffset
= NextOffset
;
370 EtfspCachedSearchForDirent (
371 _In_ PBL_FILE_ENTRY DirectoryEntry
,
372 _In_ PWCHAR FileName
,
373 _Out_ PRAW_DIR_REC
*DirEntry
,
374 _Out_ PULONG DirOffset
,
375 _In_ BOOLEAN KeepOffset
378 PBL_ETFS_FILE EtfsFile
;
379 PBL_ETFS_DEVICE EtfsDevice
;
385 EtfsFile
= DirectoryEntry
->FsSpecificData
;
386 EtfsDevice
= EtfsDeviceTable
[EtfsFile
->DeviceId
];
387 RtlInitUnicodeString(&Name
, FileName
);
388 DirentOffset
= EtfsFile
->DirEntOffset
;
391 (ALIGN_DOWN_BY((DirentOffset
+ EtfsFile
->DiskOffset
), CD_SECTOR_SIZE
) ==
394 Status
= EtfspGetDirent(DirectoryEntry
, &Dirent
, &DirentOffset
);
395 if (NT_SUCCESS(Status
))
397 if (!EtfspFileMatch(Dirent
, &Name
))
400 *DirOffset
= DirentOffset
;
401 return STATUS_SUCCESS
;
414 Status
= EtfspSearchForDirent(DirectoryEntry
,
418 if (!(NT_SUCCESS(Status
)) && (DirentOffset
))
421 Status
= EtfspSearchForDirent(DirectoryEntry
,
427 if (NT_SUCCESS(Status
))
429 *DirOffset
= DirentOffset
;
437 _In_ PBL_FILE_ENTRY FileEntry
,
440 _Out_opt_ PULONG BytesReturned
444 PBL_ETFS_FILE EtfsFile
;
447 /* Assume failure for now */
450 /* Make sure that the read is within the file's boundaries */
451 EtfsFile
= FileEntry
->FsSpecificData
;
452 if ((Size
+ EtfsFile
->Offset
) > EtfsFile
->Size
)
454 /* Bail out otherwise */
455 Status
= STATUS_INVALID_PARAMETER
;
459 /* Read the offset that matches this file's offset, on the disk */
460 Status
= BlDeviceReadAtOffset(FileEntry
->DeviceId
,
462 EtfsFile
->Offset
+ EtfsFile
->DiskOffset
,
465 if (NT_SUCCESS(Status
))
467 /* Update the file offset and return the size as having been read */
468 EtfsFile
->Offset
+= Size
;
473 /* Check if caller wanted to know how many bytes were read */
476 /* Return the value */
477 *BytesReturned
= BytesRead
;
486 _In_ PBL_FILE_ENTRY FileEntry
,
487 _In_ PBL_FILE_INFORMATION FileInfo
490 PBL_ETFS_FILE EtfsFile
;
491 BL_FILE_INFORMATION LocalFileInfo
;
493 /* Get the underlying ETFS file data structure */
494 EtfsFile
= (PBL_ETFS_FILE
)FileEntry
->FsSpecificData
;
496 /* Make a copy of the incoming attributes, but ignore the new offset */
497 LocalFileInfo
= *FileInfo
;
498 LocalFileInfo
.Offset
= EtfsFile
->Offset
;
500 /* Check if these match exactly the current file */
501 if (!RtlEqualMemory(&LocalFileInfo
, &EtfsFile
->Size
, sizeof(*FileInfo
)))
503 /* Nope -- which means caller is trying to change an immutable */
504 EfiPrintf(L
"Incorrect information change\r\n");
505 return STATUS_INVALID_PARAMETER
;
508 /* Is the offset past the end of the file? */
509 if (FileInfo
->Offset
>= EtfsFile
->Size
)
511 /* Don't allow EOF */
512 EfiPrintf(L
"Offset too large: %lx vs %lx\r\n", FileInfo
->Offset
, EtfsFile
->Size
);
513 return STATUS_INVALID_PARAMETER
;
516 /* Update the offset */
517 EtfsFile
->Offset
= FileInfo
->Offset
;
518 return STATUS_SUCCESS
;
523 _In_ PBL_FILE_ENTRY FileEntry
,
524 _Out_ PBL_FILE_INFORMATION FileInfo
527 PBL_ETFS_FILE EtfsFile
;
529 /* Get the underlying ETFS file data structure */
530 EtfsFile
= (PBL_ETFS_FILE
)FileEntry
->FsSpecificData
;
532 /* Copy the cached information structure within it */
533 RtlCopyMemory(FileInfo
, &EtfsFile
->Size
, sizeof(*FileInfo
));
534 return STATUS_SUCCESS
;
539 _In_ PBL_FILE_ENTRY Directory
,
540 _In_ PWCHAR FileName
,
542 _Out_ PBL_FILE_ENTRY
*FileEntry
545 PBL_ETFS_DEVICE EtfsDevice
;
547 PBL_FILE_ENTRY NewFile
;
548 PWCHAR FilePath
, FormatString
;
549 PBL_ETFS_FILE EtfsFile
;
550 ULONG DeviceId
, FileSize
, DirOffset
, FileOffset
;
552 PRAW_DIR_REC DirEntry
;
555 EtfsFile
= Directory
->FsSpecificData
;
556 DeviceId
= EtfsFile
->DeviceId
;
557 EtfsDevice
= EtfsDeviceTable
[DeviceId
];
559 /* Find the given file (or directory) in the given directory */
560 Status
= EtfspCachedSearchForDirent(Directory
,
565 if (!NT_SUCCESS(Status
))
570 /* Find out information about the file (or directory) we found */
571 EtfspGetDirectoryInfo(EtfsDevice
,
577 /* Allocate a file entry */
578 NewFile
= BlMmAllocateHeap(sizeof(*NewFile
));
581 return STATUS_NO_MEMORY
;
585 RtlZeroMemory(NewFile
, sizeof(*NewFile
));
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
));
592 Status
= STATUS_NO_MEMORY
;
596 /* Allocate an ETFS file entry */
597 EtfsFile
= (PBL_ETFS_FILE
)BlMmAllocateHeap(sizeof(*EtfsFile
));
600 Status
= STATUS_NO_MEMORY
;
605 RtlZeroMemory(EtfsFile
, sizeof(*EtfsFile
));
607 /* Capture the device ID of the directory */
608 NewFile
->DeviceId
= Directory
->DeviceId
;
610 /* Check if this is the root or a filename\directory under */
611 FormatString
= L
"%ls%ls";
612 if (Directory
->FilePath
[1])
614 FormatString
= L
"%ls\\%ls";
617 /* Combine the paths, and save the final path in the file entry */
618 _snwprintf(FilePath
, Size
, FormatString
, Directory
->FilePath
, FileName
);
619 NewFile
->FilePath
= FilePath
;
621 /* Copy the ETFS function callbacks into the file netry */
622 RtlCopyMemory(&NewFile
->Callbacks
,
624 sizeof(NewFile
->Callbacks
));
626 /* Fill out the rest of the details */
627 EtfsFile
->DiskOffset
= FileOffset
;
628 EtfsFile
->DirOffset
= DirOffset
;
629 EtfsFile
->Size
= FileSize
;
630 EtfsFile
->DeviceId
= DeviceId
;
632 /* Check if this is a directory */
635 EtfsFile
->Flags
|= BL_ETFS_FILE_ENTRY_DIRECTORY
;
636 NewFile
->Flags
|= BL_FILE_ENTRY_DIRECTORY
;
639 /* Write down the name of the filesystem */
640 EtfsFile
->FsName
= L
"cdfs";
642 /* All done, return the file entry, and save the ETFS side */
643 NewFile
->FsSpecificData
= EtfsFile
;
644 *FileEntry
= NewFile
;
648 /* Failure path -- free the file path if we had one */
649 if (NewFile
->FilePath
)
651 BlMmFreeHeap(NewFile
->FilePath
);
654 /* Free the ETFS file entry if we had one */
655 if (NewFile
->FsSpecificData
)
657 BlMmFreeHeap(NewFile
->FsSpecificData
);
660 /* Free the file entry itself, and return the error code */
661 BlMmFreeHeap(NewFile
);
667 _In_ PBL_ETFS_DEVICE EtfsDevice
,
669 _Out_ PRAW_ISO_VD
*VolumeDescriptor
,
670 _Out_ PBOOLEAN VolumeIsIso
673 EfiPrintf(L
"Raw Cdfs not implemented\r\n");
674 return STATUS_NOT_IMPLEMENTED
;
679 _In_ PBL_ETFS_DEVICE EtfsDevice
,
681 _Out_ PRAW_ISO_VD
*VolumeDescriptor
,
682 _Out_ PBOOLEAN VolumeIsIso
689 BL_DEVICE_INFORMATION DeviceInformation
;
690 ULONG Unknown
, BytesRead
;
691 ANSI_STRING CompareString
, String
;
693 /* Save our static buffer pointer */
694 IsoVd
= (PRAW_ISO_VD
)EtfsDevice
->MemoryBlock
;
695 EtVd
= (PRAW_ET_VD
)IsoVd
;
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
,
704 (FIRST_VD_SECTOR
+ 1) * CD_SECTOR_SIZE
,
705 EtfsDevice
->MemoryBlock
,
707 DeviceInformation
.BlockDeviceInfo
.Unknown
= Unknown
;
708 BlDeviceSetInformation(DeviceId
, &DeviceInformation
);
709 if (!NT_SUCCESS(Status
))
711 EfiPrintf(L
" read failed\r\n");
715 /* Remember that's where we last read */
716 EtfsDevice
->Offset
= (FIRST_VD_SECTOR
+ 1) * CD_SECTOR_SIZE
;
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;
723 if (!RtlEqualString(&CompareString
, &String
, TRUE
))
725 return STATUS_UNSUCCESSFUL
;
728 /* Check the version and boot indicator */
729 if ((EtVd
->Version
!= 1) || (EtVd
->BootIndicator
))
731 return STATUS_UNSUCCESSFUL
;
734 /* Check if it has the CD0001 identifier */
735 RtlInitString(&String
, ISO_VOL_ID
);
736 CompareString
.Buffer
= (PCHAR
)EtVd
->StandardId
;
737 CompareString
.Length
= 5;
738 CompareString
.MaximumLength
= 5;
739 if (!RtlEqualString(&CompareString
, &String
, TRUE
))
741 return STATUS_UNSUCCESSFUL
;
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
,
749 FIRST_VD_SECTOR
* CD_SECTOR_SIZE
,
750 EtfsDevice
->MemoryBlock
,
752 DeviceInformation
.BlockDeviceInfo
.Unknown
= Unknown
;
753 BlDeviceSetInformation(DeviceId
, &DeviceInformation
);
754 if (!NT_SUCCESS(Status
))
759 /* Remember where we left off */
760 EtfsDevice
->Offset
= FIRST_VD_SECTOR
* CD_SECTOR_SIZE
;
762 /* This should also say CD0001 */
763 CompareString
.Buffer
= (PCHAR
)IsoVd
->StandardId
;
764 CompareString
.Length
= 5;
765 CompareString
.MaximumLength
= 5;
766 IsIso
= RtlEqualString(&CompareString
, &String
, TRUE
);
769 return STATUS_UNSUCCESSFUL
;
772 /* And should be a version we support */
773 if ((IsoVd
->Version
!= VERSION_1
) || (IsoVd
->DescType
!= VD_PRIMARY
))
775 return STATUS_UNSUCCESSFUL
;
778 /* Return back to the caller */
779 *VolumeDescriptor
= IsoVd
;
780 *VolumeIsIso
= IsIso
;
781 return STATUS_SUCCESS
;
785 EtfspDeviceContextDestroy (
786 _In_ PBL_ETFS_DEVICE EtfsDevice
789 if (EtfsDevice
->MemoryBlock
)
791 BlMmFreeHeap(EtfsDevice
->MemoryBlock
);
794 BlMmFreeHeap(EtfsDevice
);
796 return STATUS_SUCCESS
;
802 _Out_ PBL_ETFS_DEVICE
*EtfsDevice
805 PBL_ETFS_DEVICE NewContext
;
811 NewContext
= (PBL_ETFS_DEVICE
)BlMmAllocateHeap(sizeof(*NewContext
));
814 return STATUS_NO_MEMORY
;
816 RtlZeroMemory(NewContext
, sizeof(*NewContext
));
818 MemoryBlock
= BlMmAllocateHeap(CD_SECTOR_SIZE
);
819 NewContext
->MemoryBlock
= MemoryBlock
;
822 Status
= STATUS_NO_MEMORY
;
826 Status
= EtfspCheckEtfs(NewContext
, DeviceId
, &RawVd
, &IsIso
);
827 if (!NT_SUCCESS(Status
))
829 EfiPrintf(L
"Drive not EDFS. Checking for CDFS: %lx\r\n");
830 Status
= EtfspCheckCdfs(NewContext
, DeviceId
, &RawVd
, &IsIso
);
833 if (!NT_SUCCESS(Status
))
835 EfiPrintf(L
"Drive not CDFS. Failing: %lx\r\n");
839 NewContext
->IsIso
= IsIso
;
840 NewContext
->BlockSize
= RVD_LB_SIZE(RawVd
, IsIso
);
841 NewContext
->VolumeSize
= RVD_VOL_SIZE(RawVd
, IsIso
);
843 EtfspGetDirectoryInfo(NewContext
,
844 (PRAW_DIR_REC
)RVD_ROOT_DE(RawVd
, IsIso
),
845 &NewContext
->RootDirOffset
,
846 &NewContext
->RootDirSize
,
848 Status
= STATUS_SUCCESS
;
851 if (!NT_SUCCESS(Status
))
853 EtfspDeviceContextDestroy(NewContext
);
857 *EtfsDevice
= NewContext
;
862 EtfspDeviceTableDestroyEntry (
863 _In_ PBL_ETFS_DEVICE EtfsDevice
,
867 EtfspDeviceContextDestroy(EtfsDevice
);
868 EtfsDeviceTable
[Index
] = NULL
;
870 return STATUS_SUCCESS
;
877 _Out_ PBL_FILE_ENTRY
* FileEntry
880 PBL_ETFS_DEVICE EtfsDevice
= NULL
;
881 PBL_FILE_ENTRY RootEntry
;
883 PBL_ETFS_FILE EtfsFile
;
885 EfiPrintf(L
"Trying to mount as ETFS...\r\n");
887 Status
= EtfspCreateContext(DeviceId
, &EtfsDevice
);
888 if (!NT_SUCCESS(Status
))
890 EfiPrintf(L
"ETFS context failed: %lx\r\n");
894 Status
= BlTblSetEntry(&EtfsDeviceTable
,
895 &EtfsDeviceTableEntries
,
899 if (!NT_SUCCESS(Status
))
901 EtfspDeviceContextDestroy(EtfsDevice
);
905 RootEntry
= BlMmAllocateHeap(sizeof(*RootEntry
));
908 Status
= STATUS_NO_MEMORY
;
912 RtlZeroMemory(RootEntry
, sizeof(*RootEntry
));
914 RootEntry
->FilePath
= BlMmAllocateHeap(4);
915 if (!RootEntry
->FilePath
)
917 Status
= STATUS_NO_MEMORY
;
921 wcsncpy(RootEntry
->FilePath
, L
"\\", 1);
923 RootEntry
->DeviceId
= DeviceId
;
924 RtlCopyMemory(&RootEntry
->Callbacks
,
926 sizeof(RootEntry
->Callbacks
));
928 EtfsFile
= (PBL_ETFS_FILE
)BlMmAllocateHeap(sizeof(*EtfsFile
));
931 Status
= STATUS_NO_MEMORY
;
935 RootEntry
->Flags
|= 0x10000;
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
;
947 return STATUS_SUCCESS
;
950 if (RootEntry
->FilePath
)
952 BlMmFreeHeap(RootEntry
->FilePath
);
954 if (RootEntry
->FsSpecificData
)
956 BlMmFreeHeap(RootEntry
->FsSpecificData
);
960 BlMmFreeHeap(RootEntry
);
963 EtfspDeviceTableDestroyEntry(EtfsDevice
, DeviceId
);
975 /* Allocate the device table with 2 entries*/
976 EtfsDeviceTableEntries
= 2;
977 EtfsDeviceTable
= BlMmAllocateHeap(sizeof(PBL_FILE_ENTRY
) *
978 EtfsDeviceTableEntries
);
982 RtlZeroMemory(EtfsDeviceTable
,
983 sizeof(PBL_FILE_ENTRY
) * EtfsDeviceTableEntries
);
984 Status
= STATUS_SUCCESS
;
988 /* No memory, fail */
989 Status
= STATUS_NO_MEMORY
;
992 /* Return back to caller */