ReactOS  0.4.13-dev-257-gfabbd7c
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>
13 typedef struct _RAW_ET_VD
14 {
21  UCHAR Padding[1973];
23 
24 /* DATA VARIABLES ************************************************************/
25 
26 typedef struct _BL_ETFS_DEVICE
27 {
36 
37 typedef struct _BL_ETFS_FILE
38 {
42 
44 
47 
50 
52 EtfsOpen (
56  _Out_ PBL_FILE_ENTRY *FileEntry
57  );
58 
61  _In_ PBL_FILE_ENTRY FileEntry,
63  );
64 
67  _In_ PBL_FILE_ENTRY FileEntry,
69  );
70 
72 EtfsRead (
73  _In_ PBL_FILE_ENTRY FileEntry,
75  _In_ ULONG Size,
77  );
78 
80 {
81  EtfsOpen,
82  NULL,
83  EtfsRead,
84  NULL,
85  NULL,
88 };
89 
90 /* FUNCTIONS *****************************************************************/
91 
92 VOID
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 
123 USHORT
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 
159 LONG
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 
189 BOOLEAN
193  )
194 {
195  BOOLEAN Match;
196  USHORT Length;
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 
216 NTSTATUS
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 
248 ReadAgain:
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 
328 Quickie:
329  *DirEntry = DirEnt;
330  *DirentOffset = DirectoryOffset;
331  return STATUS_SUCCESS;
332 }
333 
334 NTSTATUS
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 
369 NTSTATUS
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 
435 NTSTATUS
437  _In_ PBL_FILE_ENTRY FileEntry,
438  _In_ PVOID Buffer,
439  _In_ ULONG Size,
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 
484 NTSTATUS
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 
521 NTSTATUS
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 
537 NTSTATUS
541  _In_ ULONG Flags,
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 
647 Quickie:
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  {
657  BlMmFreeHeap(NewFile->FsSpecificData);
658  }
659 
660  /* Free the file entry itself, and return the error code */
661  BlMmFreeHeap(NewFile);
662  return Status;
663 }
664 
665 NTSTATUS
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");
674  return STATUS_NOT_IMPLEMENTED;
675 }
676 
677 NTSTATUS
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 
784 NTSTATUS
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 
799 NTSTATUS
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 
850 Quickie:
851  if (!NT_SUCCESS(Status))
852  {
854  NewContext = NULL;
855  }
856 
857  *EtfsDevice = NewContext;
858  return Status;
859 }
860 
861 NTSTATUS
863  _In_ PBL_ETFS_DEVICE EtfsDevice,
865  )
866 {
867  EtfspDeviceContextDestroy(EtfsDevice);
869 
870  return STATUS_SUCCESS;
871 }
872 
873 NTSTATUS
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 
949 Quickie:
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 
968 NTSTATUS
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 
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 * u
Definition: glfuncs.h:240
NTSTATUS EtfsSetInformation(_In_ PBL_FILE_ENTRY FileEntry, _In_ PBL_FILE_INFORMATION FileInfo)
Definition: etfs.c:485
UCHAR Version
Definition: etfs.c:17
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
UCHAR DirLen
Definition: cd.h:332
NTSTATUS EtfsRead(_In_ PBL_FILE_ENTRY FileEntry, _In_ PVOID Buffer, _In_ ULONG Size, _Out_opt_ PULONG BytesReturned)
Definition: etfs.c:436
PUCHAR MemoryBlock
Definition: etfs.c:33
LONG EtfspCompareNames(__in PSTRING Name1, __in PUNICODE_STRING Name2)
Definition: etfs.c:160
ULONG DeviceId
Definition: etfs.c:45
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOLEAN EtfspFileMatch(_In_ PRAW_DIR_REC DirEntry, _In_ PUNICODE_STRING FileName)
Definition: etfs.c:190
ULONG DirEntOffset
Definition: etfs.c:41
UCHAR Version
Definition: cd.h:130
unsigned char * PUCHAR
Definition: retypes.h:3
Dirent DirentOffset
Definition: dirsup.c:444
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 TblDoNotPurgeEntry(_In_ PVOID Entry)
Definition: util.c:495
PWCHAR FilePath
Definition: bl.h:1040
LONG NTSTATUS
Definition: precomp.h:26
ush Pos
Definition: deflate.h:92
BL_FILE_CALLBACKS EtfsFunctionTable
Definition: etfs.c:79
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
ULONG Offset
Definition: etfs.c:34
NTSTATUS EtfsMount(_In_ ULONG DeviceId, _In_ ULONG Unknown, _Out_ PBL_FILE_ENTRY *FileEntry)
Definition: etfs.c:874
static WCHAR String[]
Definition: stringtable.c:55
uint16_t * PWCHAR
Definition: typedefs.h:54
DWORD FormatString(DWORD dwFlags, HINSTANCE hInstance, DWORD dwStringId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
Definition: fontview.c:48
NTSTATUS BlDeviceGetInformation(_In_ ULONG DeviceId, _Out_ PBL_DEVICE_INFORMATION DeviceInformation)
Definition: device.c:682
NTSYSAPI BOOLEAN NTAPI RtlEqualString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
NTSTATUS BlMmFreeHeap(_In_ PVOID Buffer)
Definition: heapalloc.c:663
#define RVD_VOL_SIZE(r, i)
Definition: cd.h:87
PCWSTR FilePath
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
BL_FILE_CALLBACKS Callbacks
Definition: bl.h:1048
#define BL_FILE_ENTRY_DIRECTORY
Definition: bl.h:164
UCHAR FileIdLen
Definition: cd.h:345
UCHAR SystemId[32]
Definition: etfs.c:18
long LONG
Definition: pedump.c:60
ULONG DirOffset
Definition: etfs.c:40
ULONG VolumeSize
Definition: etfs.c:31
PVOID * EtfsDeviceTable
Definition: etfs.c:49
#define DE_FILE_FLAGS(iso, de)
Definition: cd.h:93
struct NameRec_ * Name
Definition: cdprocs.h:464
UCHAR Padding[1973]
Definition: etfs.c:21
NTSTATUS EtfspDeviceTableDestroyEntry(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG Index)
Definition: etfs.c:862
struct _BL_ETFS_FILE BL_ETFS_FILE
#define SectorOffset(L)
Definition: cdprocs.h:1632
unsigned char BOOLEAN
UCHAR DescType
Definition: cd.h:128
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
PVOID BlMmAllocateHeap(_In_ SIZE_T Size)
Definition: heapalloc.c:569
BL_BLOCK_DEVICE_INFORMATION BlockDeviceInfo
Definition: bl.h:1229
#define _Out_
Definition: no_sal2.h:323
ULONG BlockSize
Definition: etfs.c:30
ULONG Flags
Definition: bl.h:1043
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
Definition: bufpool.h:45
ULONG EtfsDeviceTableEntries
Definition: etfs.c:48
struct _BL_ETFS_FILE * PBL_ETFS_FILE
#define PCHAR
Definition: match.c:90
r l[0]
Definition: byte_order.h:167
UCHAR FileId[MAX_FILE_ID_LENGTH]
Definition: cd.h:346
#define RVD_LB_SIZE(r, i)
Definition: cd.h:84
#define _Out_opt_
Definition: no_sal2.h:339
NTSTATUS BlDeviceReadAtOffset(_In_ ULONG DeviceId, _In_ ULONG Size, _In_ ULONGLONG Offset, _In_ PVOID Buffer, _Out_ PULONG BytesRead)
Definition: device.c:773
BL_FILE_INFORMATION
Definition: etfs.c:43
int toupper(int c)
Definition: utclib.c:881
#define CompareString
Definition: winnls.h:1171
ULONG BootCatalogOffset
Definition: etfs.c:20
NTSYSAPI ULONG NTAPI RtlEqualMemory(CONST VOID *Source1, CONST VOID *Source2, ULONG Length)
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS EtfspDeviceContextDestroy(_In_ PBL_ETFS_DEVICE EtfsDevice)
Definition: etfs.c:785
#define FIRST_VD_SECTOR
Definition: cd.h:48
#define ISO_ATTR_DIRECTORY
Definition: cd.h:71
static const UCHAR Index[8]
Definition: usbohci.c:18
#define BL_ETFS_FILE_ENTRY_DIRECTORY
Definition: bl.h:166
NTSTATUS EtfspSearchForDirent(_In_ PBL_FILE_ENTRY DirectoryEntry, _In_ PWCHAR FileName, _Out_ PRAW_DIR_REC *DirEntry, _Out_ PULONG DirentOffset)
Definition: etfs.c:335
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
UCHAR BootIndicator
Definition: etfs.c:15
ULONG RootDirOffset
Definition: etfs.c:28
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
char * PBOOLEAN
Definition: retypes.h:11
ULONG DeviceId
Definition: bl.h:1041
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
NTSTATUS EtfspCheckCdfs(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
Definition: etfs.c:666
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
struct DirEntry DirEntry
Definition: storage32.h:133
NTSTATUS EtfspGetDirent(_In_ PBL_FILE_ENTRY DirectoryEntry, _Out_ PRAW_DIR_REC *DirEntry, _Inout_ PULONG DirentOffset)
Definition: etfs.c:217
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
NTSYSAPI VOID NTAPI RtlInitString(PSTRING DestinationString, PCSZ SourceString)
Status
Definition: gdiplustypes.h:24
NTSTATUS EtfsGetInformation(_In_ PBL_FILE_ENTRY FileEntry, _Out_ PBL_FILE_INFORMATION FileInfo)
Definition: etfs.c:522
#define ALIGN_DOWN_BY(size, align)
#define _In_
Definition: no_sal2.h:204
#define ISO_VOL_ID
Definition: cd.h:67
ULONG_PTR SIZE_T
Definition: typedefs.h:78
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 * PRAW_ET_VD
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)
Definition: bl.h:1038
unsigned short USHORT
Definition: pedump.c:61
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
#define MIN_DIR_REC_SIZE
Definition: cd.h:73
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
USHORT EtfspGetDirentNameLength(_In_ PRAW_DIR_REC DirEntry)
Definition: etfs.c:124
ULONG RootDirSize
Definition: etfs.c:29
_In_ FILTER_INFORMATION_CLASS _In_ ULONG _Out_ PULONG BytesReturned
Definition: fltkernel.h:1716
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
struct _BL_ETFS_DEVICE * PBL_ETFS_DEVICE
VOID EfiPrintf(_In_ PWCHAR Format,...)
Definition: firmware.c:126
UCHAR StandardId[5]
Definition: etfs.c:16
RAW_ISO_VD * PRAW_ISO_VD
Definition: cd.h:166
#define CD_SECTOR_SIZE
Definition: cd.h:65
NTSTATUS EtfsInitialize(VOID)
Definition: etfs.c:969
struct _RAW_ET_VD RAW_ET_VD
NTSTATUS BlTblSetEntry(_Inout_ PVOID **Table, _Inout_ PULONG Count, _In_ PVOID Entry, _Out_ PULONG EntryIndex, _In_ PBL_TBL_SET_ROUTINE Callback)
Definition: util.c:321
_In_ FLT_SET_CONTEXT_OPERATION _In_ PFLT_CONTEXT NewContext
Definition: fltkernel.h:1468
struct _BL_ETFS_DEVICE BL_ETFS_DEVICE
#define RVD_ROOT_DE(r, i)
Definition: cd.h:90
NTSTATUS EtfspCheckEtfs(_In_ PBL_ETFS_DEVICE EtfsDevice, _In_ ULONG DeviceId, _Out_ PRAW_ISO_VD *VolumeDescriptor, _Out_ PBOOLEAN VolumeIsIso)
Definition: etfs.c:678
PVOID FsSpecificData
Definition: bl.h:1049
BOOLEAN IsIso
Definition: etfs.c:32
#define VD_PRIMARY
Definition: cd.h:56
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
base for all directory entries
Definition: entries.h:138
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:741
#define ALIGN_UP_BY(size, align)
NTSTATUS BlDeviceSetInformation(_In_ ULONG DeviceId, _In_ PBL_DEVICE_INFORMATION DeviceInformation)
ULONGLONG Offset
Definition: bl.h:1022
ULONG DiskOffset
Definition: etfs.c:39
#define ISO_ATTR_MULTI
Definition: cd.h:70
_Must_inspect_result_ _In_ PCUNICODE_STRING Name2
Definition: fsrtlfuncs.h:796
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define __in
Definition: dbghelp.h:35
GLuint64EXT * result
Definition: glext.h:11304
NTSTATUS EtfspCreateContext(_In_ ULONG DeviceId, _Out_ PBL_ETFS_DEVICE *EtfsDevice)
Definition: etfs.c:800
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
RAW_DIRENT * PRAW_DIR_REC
Definition: cd.h:350
#define VERSION_1
Definition: cd.h:53
UCHAR StandardId[5]
Definition: cd.h:129