ReactOS  0.4.14-dev-114-gc8cbd56
pathsup.c File Reference
#include "cdprocs.h"
Include dependency graph for pathsup.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (CDFS_BUG_CHECK_PATHSUP)
 
#define CdRawPathEntry(IC, PC)   Add2Ptr( (PC)->Data, (PC)->DataOffset, PRAW_PATH_ENTRY )
 

Functions

VOID CdMapPathTableBlock (_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ LONGLONG BaseOffset, _Inout_ PPATH_ENUM_CONTEXT PathContext)
 
 _Success_ (return !=FALSE)
 
BOOLEAN CdLookupNextPathEntry (_In_ PIRP_CONTEXT IrpContext, _Inout_ PPATH_ENUM_CONTEXT PathContext, _Inout_ PPATH_ENTRY PathEntry)
 
VOID CdUpdatePathEntryName (_In_ PIRP_CONTEXT IrpContext, _Inout_ PPATH_ENTRY PathEntry, _In_ BOOLEAN IgnoreCase)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (CDFS_BUG_CHECK_PATHSUP)

Definition at line 82 of file pathsup.c.

◆ CdRawPathEntry

#define CdRawPathEntry (   IC,
  PC 
)    Add2Ptr( (PC)->Data, (PC)->DataOffset, PRAW_PATH_ENTRY )

Definition at line 96 of file pathsup.c.

Function Documentation

◆ _Success_()

_Success_ ( return = FALSE)

Definition at line 111 of file pathsup.c.

167 {
168  PPATH_ENUM_CONTEXT PathContext = &CompoundPathEntry->PathContext;
169  LONGLONG CurrentBaseOffset;
170 
171  PAGED_CODE();
172 
173  //
174  // Compute the starting base and starting path table offset.
175  //
176 
177  CurrentBaseOffset = SectorTruncate( PathEntryOffset );
178 
179  //
180  // Map the next block in the Path Table.
181  //
182 
183  CdMapPathTableBlock( IrpContext,
184  IrpContext->Vcb->PathTableFcb,
185  CurrentBaseOffset,
186  PathContext );
187 
188  //
189  // Set up our current offset into the Path Context.
190  //
191 
192  PathContext->DataOffset = PathEntryOffset - PathContext->BaseOffset;
193 
194  //
195  // Update the in-memory structure for this path entry.
196  //
197 
198  (VOID) CdUpdatePathEntryFromRawPathEntry( IrpContext,
199  Ordinal,
200  VerifyBounds,
201  &CompoundPathEntry->PathContext,
202  &CompoundPathEntry->PathEntry );
203 }
VOID CdMapPathTableBlock(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ LONGLONG BaseOffset, _Inout_ PPATH_ENUM_CONTEXT PathContext)
Definition: pathsup.c:484
#define PAGED_CODE()
Definition: video.h:57
int64_t LONGLONG
Definition: typedefs.h:66
#define SectorTruncate(L)
Definition: cdprocs.h:1598
#define VOID
Definition: acefi.h:82
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
Definition: cdprocs.h:741

◆ CdLookupNextPathEntry()

BOOLEAN CdLookupNextPathEntry ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PPATH_ENUM_CONTEXT  PathContext,
_Inout_ PPATH_ENTRY  PathEntry 
)

Definition at line 207 of file pathsup.c.

242 {
243  LONGLONG CurrentBaseOffset;
244 
245  PAGED_CODE();
246 
247  //
248  // Get the offset of the next path entry within the current
249  // data block.
250  //
251 
252  PathContext->DataOffset += PathEntry->PathEntryLength;
253 
254  //
255  // If we are in the last data block then check if we are beyond the
256  // end of the file.
257  //
258 
259  if (PathContext->LastDataBlock) {
260 
261  if (PathContext->DataOffset >= PathContext->DataLength) {
262 
263  return FALSE;
264  }
265 
266  //
267  // If we are not in the last data block of the path table and
268  // this offset is in the second sector then move to the next
269  // data block.
270  //
271 
272  } else if (PathContext->DataOffset >= SECTOR_SIZE) {
273 
274  CurrentBaseOffset = PathContext->BaseOffset + SECTOR_SIZE;
275 
276  CdMapPathTableBlock( IrpContext,
277  IrpContext->Vcb->PathTableFcb,
278  CurrentBaseOffset,
279  PathContext );
280 
281  //
282  // Set up our current offset into the Path Context.
283  //
284 
285  PathContext->DataOffset -= SECTOR_SIZE;
286  }
287 
288  //
289  // Now update the path entry with the values from the on-disk
290  // structure.
291  //
292 
293  return CdUpdatePathEntryFromRawPathEntry( IrpContext,
294  PathEntry->Ordinal + 1,
295  TRUE,
296  PathContext,
297  PathEntry );
298 }
#define TRUE
Definition: types.h:120
VOID CdMapPathTableBlock(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ LONGLONG BaseOffset, _Inout_ PPATH_ENUM_CONTEXT PathContext)
Definition: pathsup.c:484
#define PAGED_CODE()
Definition: video.h:57
int64_t LONGLONG
Definition: typedefs.h:66
#define SECTOR_SIZE
Definition: fs.h:22

Referenced by _Requires_lock_held_().

◆ CdMapPathTableBlock()

VOID CdMapPathTableBlock ( _In_ PIRP_CONTEXT  IrpContext,
_In_ PFCB  Fcb,
_In_ LONGLONG  BaseOffset,
_Inout_ PPATH_ENUM_CONTEXT  PathContext 
)

Definition at line 484 of file pathsup.c.

514 {
515  ULONG CurrentLength;
517  ULONG DataOffset;
518  ULONG PassCount;
519  PVOID Sector;
520 
521  PAGED_CODE();
522 
523  UNREFERENCED_PARAMETER( IrpContext );
524 
525  //
526  // Map the new block and set the enumeration context to this
527  // point. Allocate an auxilary buffer if necessary.
528  //
529 
530  CurrentLength = 2 * SECTOR_SIZE;
531 
532  if (CurrentLength >= (ULONG) (Fcb->FileSize.QuadPart - BaseOffset)) {
533 
534  CurrentLength = (ULONG) (Fcb->FileSize.QuadPart - BaseOffset);
535 
536  //
537  // We know this is the last data block for this
538  // path table.
539  //
540 
541  PathContext->LastDataBlock = TRUE;
542  }
543 
544  //
545  // Set context values.
546  //
547 
548  PathContext->BaseOffset = (ULONG) BaseOffset;
549  PathContext->DataLength = CurrentLength;
550 
551  //
552  // Drop the previous sector's mapping
553  //
554 
555  CdUnpinData( IrpContext, &PathContext->Bcb );
556 
557  //
558  // Check if spanning a view section. The following must
559  // be true before we take this step.
560  //
561  // Data length is more than one sector.
562  // Starting offset must be one sector before the
563  // cache manager VACB boundary.
564  //
565 
566  if ((CurrentLength > SECTOR_SIZE) &&
567  (FlagOn( ((ULONG) BaseOffset), VACB_MAPPING_MASK ) == LAST_VACB_SECTOR_OFFSET )) {
568 
569  //
570  // Map each sector individually and store into an auxilary
571  // buffer.
572  //
573 
575  DataOffset = 0;
576  PassCount = 2;
577 
578  PathContext->Data = FsRtlAllocatePoolWithTag( CdPagedPool,
579  CurrentLength,
581  PathContext->AllocatedData = TRUE;
582 
583  while (PassCount--) {
584 
586  (PLARGE_INTEGER) &BaseOffset,
587  SectorSize,
588  TRUE,
589  &PathContext->Bcb,
590  &Sector );
591 
592  RtlCopyMemory( Add2Ptr( PathContext->Data, DataOffset, PVOID ),
593  Sector,
594  SectorSize );
595 
596  CdUnpinData( IrpContext, &PathContext->Bcb );
597 
598  BaseOffset += SECTOR_SIZE;
599  SectorSize = CurrentLength - SECTOR_SIZE;
600  DataOffset = SECTOR_SIZE;
601  }
602 
603  //
604  // Otherwise we can just map the data into the cache.
605  //
606 
607  } else {
608 
609  //
610  // There is a slight chance that we have allocated an
611  // auxilary buffer on the previous sector.
612  //
613 
614  if (PathContext->AllocatedData) {
615 
616  CdFreePool( &PathContext->Data );
617  PathContext->AllocatedData = FALSE;
618  }
619 
621  (PLARGE_INTEGER) &BaseOffset,
622  CurrentLength,
623  TRUE,
624  &PathContext->Bcb,
625  &PathContext->Data );
626  }
627 
628  return;
629 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define Add2Ptr(PTR, INC)
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
PFILE_OBJECT FileObject
Definition: ntfs.h:516
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define LAST_VACB_SECTOR_OFFSET
Definition: cdstruc.h:1459
#define PAGED_CODE()
Definition: video.h:57
#define TAG_SPANNING_PATH_TABLE
Definition: cdprocs.h:95
#define VACB_MAPPING_MASK
Definition: cdstruc.h:1458
BOOLEAN NTAPI CcMapData(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *BcbResult, OUT PVOID *Buffer)
Definition: pinsup.c:694
#define CdPagedPool
Definition: cdprocs.h:1385
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define CdFreePool(x)
Definition: cdprocs.h:2200
unsigned int ULONG
Definition: retypes.h:1
#define SECTOR_SIZE
Definition: fs.h:22
_In_ ULONG SectorSize
Definition: halfuncs.h:291
_In_ PFCB Fcb
Definition: cdprocs.h:151
#define CdUnpinData(IC, B)
Definition: cdprocs.h:261

Referenced by CdLookupNextPathEntry().

◆ CdUpdatePathEntryName()

VOID CdUpdatePathEntryName ( _In_ PIRP_CONTEXT  IrpContext,
_Inout_ PPATH_ENTRY  PathEntry,
_In_ BOOLEAN  IgnoreCase 
)

Definition at line 781 of file pathsup.c.

815 {
816  ULONG Length;
818 
819  PAGED_CODE();
820 
821  //
822  // Check if this is a self entry. We use a fixed string for this.
823  //
824  // Self-Entry - Length is 1, value is 0.
825  //
826 
827  if ((*PathEntry->DirName == 0) &&
828  (PathEntry->DirNameLen == 1)) {
829 
830  //
831  // There should be no allocated buffers.
832  //
833 
834  NT_ASSERT( !FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ));
835 
836  //
837  // Now use one of the hard coded directory names.
838  //
839 
840  PathEntry->CdDirName.FileName = CdUnicodeDirectoryNames[0];
841 
842  //
843  // Show that there is no version number.
844  //
845 
846  PathEntry->CdDirName.VersionString.Length = 0;
847 
848  //
849  // The case name is identical.
850  //
851 
852  PathEntry->CdCaseDirName = PathEntry->CdDirName;
853 
854  //
855  // Return now.
856  //
857 
858  return;
859  }
860 
861  //
862  // Compute how large a buffer we will need. If this is an ignore
863  // case operation then we will want a double size buffer. If the disk is not
864  // a Joliet disk then we might need two bytes for each byte in the name.
865  //
866 
867  Length = PathEntry->DirNameLen;
868 
869  if (IgnoreCase) {
870 
871  Length *= 2;
872  }
873 
874  if (!FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
875 
876  Length *= sizeof( WCHAR );
877  }
878 
879  //
880  // Now decide if we need to allocate a new buffer. We will if
881  // this name won't fit in the embedded name buffer and it is
882  // larger than the current allocated buffer. We always use the
883  // allocated buffer if present.
884  //
885  // If we haven't allocated a buffer then use the embedded buffer if the data
886  // will fit. This is the typical case.
887  //
888 
889  if (!FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER ) &&
890  (Length <= sizeof( PathEntry->NameBuffer ))) {
891 
892  PathEntry->CdDirName.FileName.MaximumLength = sizeof( PathEntry->NameBuffer );
893  PathEntry->CdDirName.FileName.Buffer = PathEntry->NameBuffer;
894 
895  } else {
896 
897  //
898  // We need to use an allocated buffer. Check if the current buffer
899  // is large enough.
900  //
901 
902  if (Length > PathEntry->CdDirName.FileName.MaximumLength) {
903 
904  //
905  // Free any allocated buffer.
906  //
907 
908  if (FlagOn( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER )) {
909 
910  CdFreePool( &PathEntry->CdDirName.FileName.Buffer );
911  ClearFlag( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER );
912  }
913 
914  PathEntry->CdDirName.FileName.Buffer = FsRtlAllocatePoolWithTag( CdPagedPool,
915  Length,
917 
918  SetFlag( PathEntry->Flags, PATH_ENTRY_FLAG_ALLOC_BUFFER );
919 
920  PathEntry->CdDirName.FileName.MaximumLength = (USHORT) Length;
921  }
922  }
923 
924  //
925  // We now have a buffer for the name. We need to either convert the on-disk bigendian
926  // to little endian or covert the name to Unicode.
927  //
928 
929  if (!FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_JOLIET )) {
930 
931  Status = RtlOemToUnicodeN( PathEntry->CdDirName.FileName.Buffer,
932  PathEntry->CdDirName.FileName.MaximumLength,
933  &Length,
934  PathEntry->DirName,
935  PathEntry->DirNameLen );
936 
938  __analysis_assert( Status == STATUS_SUCCESS );
939  PathEntry->CdDirName.FileName.Length = (USHORT) Length;
940 
941  } else {
942 
943  //
944  // Convert this string to little endian.
945  //
946 
947  CdConvertBigToLittleEndian( IrpContext,
948  PathEntry->DirName,
949  PathEntry->DirNameLen,
950  (PCHAR) PathEntry->CdDirName.FileName.Buffer );
951 
952  PathEntry->CdDirName.FileName.Length = (USHORT) PathEntry->DirNameLen;
953  }
954 
955  //
956  // There is no version string.
957  //
958 
959  PathEntry->CdDirName.VersionString.Length =
960  PathEntry->CdCaseDirName.VersionString.Length = 0;
961 
962  //
963  // If the name string ends with a period then knock off the last
964  // character.
965  //
966 
967  if (PathEntry->CdDirName.FileName.Buffer[(PathEntry->CdDirName.FileName.Length - sizeof( WCHAR )) / 2] == L'.') {
968 
969  //
970  // Shrink the filename length.
971  //
972 
973  PathEntry->CdDirName.FileName.Length -= sizeof( WCHAR );
974  }
975 
976  //
977  // Update the case name buffer if necessary. If this is an exact case
978  // operation then just copy the exact case string.
979  //
980 
981  if (IgnoreCase) {
982 
983  PathEntry->CdCaseDirName.FileName.Buffer = Add2Ptr( PathEntry->CdDirName.FileName.Buffer,
984  PathEntry->CdDirName.FileName.MaximumLength / 2,
985  PWCHAR);
986 
987  PathEntry->CdCaseDirName.FileName.MaximumLength = PathEntry->CdDirName.FileName.MaximumLength / 2;
988 
989  CdUpcaseName( IrpContext,
990  &PathEntry->CdDirName,
991  &PathEntry->CdCaseDirName );
992 
993  } else {
994 
995  PathEntry->CdCaseDirName = PathEntry->CdDirName;
996  }
997 
998  return;
999 }
signed char * PCHAR
Definition: retypes.h:7
#define VCB_STATE_JOLIET
Definition: cdstruc.h:714
#define Add2Ptr(PTR, INC)
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
VOID CdUpcaseName(_In_ PIRP_CONTEXT IrpContext, _In_ PCD_NAME Name, _Inout_ PCD_NAME UpcaseName)
Definition: namesup.c:194
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI NTSTATUS WINAPI RtlOemToUnicodeN(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD)
uint16_t * PWCHAR
Definition: typedefs.h:54
VOID CdConvertBigToLittleEndian(_In_ PIRP_CONTEXT IrpContext, _In_reads_bytes_(ByteCount) PCHAR BigEndian, _In_ ULONG ByteCount, _Out_writes_bytes_(ByteCount) PCHAR LittleEndian)
Definition: namesup.c:110
#define PAGED_CODE()
Definition: video.h:57
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define TAG_PATH_ENTRY_NAME
Definition: cdprocs.h:92
#define CdPagedPool
Definition: cdprocs.h:1385
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define PATH_ENTRY_FLAG_ALLOC_BUFFER
Definition: cdstruc.h:1523
static const WCHAR L[]
Definition: oid.c:1250
UNICODE_STRING CdUnicodeDirectoryNames[]
Definition: cddata.c:52
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define CdFreePool(x)
Definition: cdprocs.h:2200
#define IgnoreCase
Definition: cdprocs.h:464
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define NT_ASSERT
Definition: rtlfuncs.h:3312