ReactOS 0.4.15-dev-8419-g7f0e8a3
etfs.c
Go to the documentation of this file.
1/*
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)
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <bl.h>
12#include <cdfs/cd.h>
13typedef struct _RAW_ET_VD
14{
23
24/* DATA VARIABLES ************************************************************/
25
26typedef struct _BL_ETFS_DEVICE
27{
36
37typedef struct _BL_ETFS_FILE
38{
42
44
47
50
56 _Out_ PBL_FILE_ENTRY *FileEntry
57 );
58
61 _In_ PBL_FILE_ENTRY FileEntry,
63 );
64
67 _In_ PBL_FILE_ENTRY FileEntry,
69 );
70
73 _In_ PBL_FILE_ENTRY FileEntry,
77 );
78
80{
82 NULL,
84 NULL,
85 NULL,
88};
89
90/* FUNCTIONS *****************************************************************/
91
92VOID
94 _In_ PBL_ETFS_DEVICE EtfsDevice,
99 )
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}
122
123USHORT
126 )
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}
158
159LONG
161 __in PSTRING Name1,
163 )
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}
188
193 )
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}
215
218 _In_ PBL_FILE_ENTRY DirectoryEntry,
221 )
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}
333
336 _In_ PBL_FILE_ENTRY DirectoryEntry,
340 )
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}
368
371 _In_ PBL_FILE_ENTRY DirectoryEntry,
374 _Out_ PULONG DirOffset,
375 _In_ BOOLEAN KeepOffset
376 )
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}
434
437 _In_ PBL_FILE_ENTRY FileEntry,
441 )
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}
483
486 _In_ PBL_FILE_ENTRY FileEntry,
488 )
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}
520
523 _In_ PBL_FILE_ENTRY FileEntry,
525 )
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}
536
542 _Out_ PBL_FILE_ENTRY *FileEntry
543 )
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}
664
667 _In_ PBL_ETFS_DEVICE EtfsDevice,
668 _In_ ULONG DeviceId,
669 _Out_ PRAW_ISO_VD *VolumeDescriptor,
670 _Out_ PBOOLEAN VolumeIsIso
671 )
672{
673 EfiPrintf(L"Raw Cdfs not implemented\r\n");
675}
676
679 _In_ PBL_ETFS_DEVICE EtfsDevice,
680 _In_ ULONG DeviceId,
681 _Out_ PRAW_ISO_VD *VolumeDescriptor,
682 _Out_ PBOOLEAN VolumeIsIso
683 )
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}
783
786 _In_ PBL_ETFS_DEVICE EtfsDevice
787 )
788{
789 if (EtfsDevice->MemoryBlock)
790 {
791 BlMmFreeHeap(EtfsDevice->MemoryBlock);
792 }
793
794 BlMmFreeHeap(EtfsDevice);
795
796 return STATUS_SUCCESS;
797}
798
801 _In_ ULONG DeviceId,
802 _Out_ PBL_ETFS_DEVICE *EtfsDevice
803 )
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}
860
863 _In_ PBL_ETFS_DEVICE EtfsDevice,
865 )
866{
867 EtfspDeviceContextDestroy(EtfsDevice);
869
870 return STATUS_SUCCESS;
871}
872
875 _In_ ULONG DeviceId,
877 _Out_ PBL_FILE_ENTRY* FileEntry
878 )
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}
967
970 VOID
971 )
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}
995
#define ALIGN_DOWN_BY(size, align)
#define ALIGN_UP_BY(size, align)
PCWSTR FilePath
unsigned char BOOLEAN
int toupper(int c)
Definition: utclib.c:881
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
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
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
#define BL_FILE_ENTRY_DIRECTORY
Definition: bl.h:163
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 BlDeviceSetInformation(_In_ ULONG DeviceId, _In_ PBL_DEVICE_INFORMATION DeviceInformation)
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define BL_ETFS_FILE_ENTRY_DIRECTORY
Definition: bl.h:165
r l[0]
Definition: byte_order.h:168
#define ISO_ATTR_DIRECTORY
Definition: cd.h:71
#define CD_SECTOR_SIZE
Definition: cd.h:65
#define ISO_VOL_ID
Definition: cd.h:67
#define RVD_ROOT_DE(r, i)
Definition: cd.h:90
RAW_DIRENT * PRAW_DIR_REC
Definition: cd.h:350
#define RVD_LB_SIZE(r, i)
Definition: cd.h:84
#define DE_FILE_FLAGS(iso, de)
Definition: cd.h:93
#define ISO_ATTR_MULTI
Definition: cd.h:70
#define RVD_VOL_SIZE(r, i)
Definition: cd.h:87
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 MIN_DIR_REC_SIZE
Definition: cd.h:73
#define VD_PRIMARY
Definition: cd.h:56
Dirent DirentOffset
Definition: dirsup.c:444
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
#define SectorOffset(L)
Definition: cdprocs.h:1622
Definition: bufpool.h:45
#define __in
Definition: dbghelp.h:35
ush Pos
Definition: deflate.h:92
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS EtfsGetInformation(_In_ PBL_FILE_ENTRY FileEntry, _Out_ PBL_FILE_INFORMATION FileInfo)
Definition: etfs.c:522
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
NTSTATUS EtfspCreateContext(_In_ ULONG DeviceId, _Out_ PBL_ETFS_DEVICE *EtfsDevice)
Definition: etfs.c:800
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
struct _BL_ETFS_FILE BL_ETFS_FILE
NTSTATUS EtfspCheckEtfs(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
Definition: etfs.c:678
USHORT EtfspGetDirentNameLength(_In_ PRAW_DIR_REC DirEntry)
Definition: etfs.c:124
struct _RAW_ET_VD * PRAW_ET_VD
PVOID * EtfsDeviceTable
Definition: etfs.c:49
BOOLEAN EtfspFileMatch(_In_ PRAW_DIR_REC DirEntry, _In_ PUNICODE_STRING FileName)
Definition: etfs.c:190
NTSTATUS EtfsRead(_In_ PBL_FILE_ENTRY FileEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_opt_ PULONG BytesReturned)
Definition: etfs.c:436
struct _BL_ETFS_DEVICE BL_ETFS_DEVICE
struct _BL_ETFS_FILE * PBL_ETFS_FILE
NTSTATUS EtfsSetInformation(_In_ PBL_FILE_ENTRY FileEntry, _In_ PBL_FILE_INFORMATION FileInfo)
Definition: etfs.c:485
struct _BL_ETFS_DEVICE * PBL_ETFS_DEVICE
NTSTATUS EtfspDeviceTableDestroyEntry(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG Index)
Definition: etfs.c:862
LONG EtfspCompareNames(__in PSTRING Name1, __in PUNICODE_STRING Name2)
Definition: etfs.c:160
ULONG EtfsDeviceTableEntries
Definition: etfs.c:48
NTSTATUS EtfspCheckCdfs(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
Definition: etfs.c:666
NTSTATUS EtfspDeviceContextDestroy(_In_ PBL_ETFS_DEVICE EtfsDevice)
Definition: etfs.c:785
NTSTATUS EtfsInitialize(VOID)
Definition: etfs.c:969
NTSTATUS EtfsMount(_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
Definition: etfs.c:874
BL_FILE_CALLBACKS EtfsFunctionTable
Definition: etfs.c:79
NTSTATUS EtfsOpen(_In_ PBL_FILE_ENTRY Directory, _In_ PWCHAR FileName, _In_ ULONG Flags, _Out_ PBL_FILE_ENTRY *FileEntry)
Definition: etfs.c:538
struct _RAW_ET_VD RAW_ET_VD
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
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT NewContext
Definition: fltkernel.h:1468
DWORD FormatString(DWORD dwFlags, HINSTANCE hInstance, DWORD dwStringId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
Definition: fontview.c:34
_Must_inspect_result_ _In_ PCUNICODE_STRING Name2
Definition: fsrtlfuncs.h:796
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
Status
Definition: gdiplustypes.h:25
GLuint64EXT * result
Definition: glext.h:11304
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
@ Unknown
Definition: i8042prt.h:114
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RtlEqualMemory(dst, src, len)
Definition: kdvm.h:18
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_opt_
Definition: ms_sal.h:346
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
#define STATUS_SUCCESS
Definition: shellext.h:65
base for all directory entries
Definition: entries.h:138
BL_BLOCK_DEVICE_INFORMATION BlockDeviceInfo
Definition: bl.h:1228
BOOLEAN IsIso
Definition: etfs.c:32
ULONG RootDirSize
Definition: etfs.c:29
ULONG RootDirOffset
Definition: etfs.c:28
ULONG BlockSize
Definition: etfs.c:30
PUCHAR MemoryBlock
Definition: etfs.c:33
ULONG VolumeSize
Definition: etfs.c:31
ULONG Offset
Definition: etfs.c:34
ULONG DirEntOffset
Definition: etfs.c:41
ULONG DiskOffset
Definition: etfs.c:39
ULONG DeviceId
Definition: etfs.c:45
BL_FILE_INFORMATION
Definition: etfs.c:43
ULONG DirOffset
Definition: etfs.c:40
Definition: bl.h:1038
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
ULONGLONG Offset
Definition: bl.h:1021
UCHAR FileIdLen
Definition: cd.h:345
UCHAR FileId[MAX_FILE_ID_LENGTH]
Definition: cd.h:346
UCHAR DirLen
Definition: cd.h:332
UCHAR BootIndicator
Definition: etfs.c:15
UCHAR SystemId[32]
Definition: etfs.c:18
ULONG BootCatalogOffset
Definition: etfs.c:20
UCHAR Padding[1973]
Definition: etfs.c:21
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
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint16_t * PWCHAR
Definition: typedefs.h:56
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
_In_ WDFCOLLECTION _In_ ULONG Index
_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_ WDFSTRING String
Definition: wdfdevice.h:2433
_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
_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
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define CompareString
Definition: winnls.h:1174
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180