ReactOS 0.4.15-dev-7942-gd23573b
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}
#define PAGED_CODE()
#define VOID
Definition: acefi.h:82
_In_ PFCB _In_ PCD_NAME _In_ BOOLEAN _Inout_ PCOMPOUND_PATH_ENTRY CompoundPathEntry
Definition: cdprocs.h:740
#define SectorTruncate(L)
Definition: cdprocs.h:1588
VOID CdMapPathTableBlock(_In_ PIRP_CONTEXT IrpContext, _In_ PFCB Fcb, _In_ LONGLONG BaseOffset, _Inout_ PPATH_ENUM_CONTEXT PathContext)
Definition: pathsup.c:484
int64_t LONGLONG
Definition: typedefs.h:68

◆ 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 SECTOR_SIZE
Definition: fs.h:22
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117

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,
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 CdUnpinData(IC, B)
Definition: cdprocs.h:269
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define CdFreePool(x)
Definition: cdprocs.h:2190
#define TAG_SPANNING_PATH_TABLE
Definition: cdprocs.h:103
#define CdPagedPool
Definition: cdprocs.h:1380
#define VACB_MAPPING_MASK
Definition: cdstruc.h:1452
#define LAST_VACB_SECTOR_OFFSET
Definition: cdstruc.h:1453
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define Add2Ptr(PTR, INC)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
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
PFILE_OBJECT FileObject
Definition: ntfs.h:520
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG
Definition: typedefs.h:59
_In_ ULONG SectorSize
Definition: halfuncs.h:291

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{
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
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}
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING CdUnicodeDirectoryNames[]
Definition: cddata.c:52
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
VOID CdUpcaseName(_In_ PIRP_CONTEXT IrpContext, _In_ PCD_NAME Name, _Inout_ PCD_NAME UpcaseName)
Definition: namesup.c:194
#define TAG_PATH_ENTRY_NAME
Definition: cdprocs.h:100
#define PATH_ENTRY_FLAG_ALLOC_BUFFER
Definition: cdstruc.h:1517
#define VCB_STATE_JOLIET
Definition: cdstruc.h:708
#define IgnoreCase
Definition: cdprocs.h:461
#define ClearFlag(_F, _SF)
Definition: ext2fs.h:191
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
Status
Definition: gdiplustypes.h:25
_Use_decl_annotations_ NTSTATUS NTAPI RtlOemToUnicodeN(_Out_ PWCHAR UnicodeString, _In_ ULONG UnicodeSize, _Out_opt_ PULONG ResultSize, _In_ PCCH OemString, _In_ ULONG OemSize)
Definition: nlsboot.c:282
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define __analysis_assert(e)
Definition: specstrings.h:259
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
#define NT_ASSERT
Definition: rtlfuncs.h:3310
__wchar_t WCHAR
Definition: xmlstorage.h:180