ReactOS  0.4.14-dev-1276-g8aa58c1
easup.c File Reference
#include "fatprocs.h"
Include dependency graph for easup.c:

Go to the source code of this file.

Macros

#define Dbg   (DEBUG_TRACE_EA)
 
#define EA_SECTION_SIZE   (0x00040000)
 

Functions

 _Requires_lock_held_ (_Global_critical_region_)
 
VOID FatReadEaSet (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT EaHandle, IN POEM_STRING FileName, IN BOOLEAN ReturnEntireSet, OUT PEA_RANGE EaSetRange)
 
VOID FatAppendPackedEa (IN PIRP_CONTEXT IrpContext, IN OUT PEA_SET_HEADER *EaSetHeader, IN OUT PULONG PackedEasLength, IN OUT PULONG AllocationLength, IN PFILE_FULL_EA_INFORMATION FullEa, IN ULONG BytesPerCluster)
 
VOID FatDeletePackedEa (IN PIRP_CONTEXT IrpContext, IN OUT PEA_SET_HEADER EaSetHeader, IN OUT PULONG PackedEasLength, IN ULONG Offset)
 
ULONG FatLocateNextEa (IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN ULONG PreviousOffset)
 
BOOLEAN FatLocateEaByName (IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN POEM_STRING EaName, OUT PULONG Offset)
 
BOOLEAN FatIsEaNameValid (IN PIRP_CONTEXT IrpContext, IN OEM_STRING Name)
 
VOID FatPinEaRange (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT VirtualEaFile, IN PFCB EaFcb, IN OUT PEA_RANGE EaRange, IN ULONG StartingVbo, IN ULONG Length, IN NTSTATUS ErrorStatus)
 
VOID FatMarkEaRangeDirty (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT EaFileObject, IN OUT PEA_RANGE EaRange)
 
VOID FatUnpinEaRange (IN PIRP_CONTEXT IrpContext, IN OUT PEA_RANGE EaRange)
 

Macro Definition Documentation

◆ Dbg

#define Dbg   (DEBUG_TRACE_EA)

Definition at line 22 of file easup.c.

◆ EA_SECTION_SIZE

#define EA_SECTION_SIZE   (0x00040000)

Definition at line 49 of file easup.c.

Function Documentation

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 52 of file easup.c.

86 {
87  PBCB EaBcb = NULL;
88  BOOLEAN LockedEaFcb = FALSE;
90 
91  PAGED_CODE();
92 
93  DebugTrace(+1, Dbg, "FatGetEaLength ...\n", 0);
94 
95  //
96  // If this is Fat32 volume, or if the handle is 0 then the Ea length is 0.
97  //
98 
99  if (FatIsFat32( Vcb ) ||
100  Dirent->ExtendedAttributes == 0) {
101 
102  *EaLength = 0;
103  DebugTrace(-1, Dbg, "FatGetEaLength -> %08lx\n", TRUE);
104  return;
105  }
106 
107  RtlZeroMemory( &EaSetRange, sizeof( EA_RANGE ));
108 
109  //
110  // Use a try to facilitate cleanup.
111  //
112 
113  _SEH2_TRY {
114 
116  OEM_STRING ThisFilename;
117  UCHAR Buffer[12];
118  PEA_SET_HEADER EaSetHeader;
119 
120  //
121  // Initial the local values.
122  //
123 
124  EaBcb = NULL;
125  LockedEaFcb = FALSE;
126 
127  //
128  // Try to get the Ea file object. Return FALSE on failure.
129  //
130 
131  FatGetEaFile( IrpContext,
132  Vcb,
133  &EaDirent,
134  &EaBcb,
135  FALSE,
136  FALSE );
137 
138  LockedEaFcb = TRUE;
139 
140  //
141  // If we didn't get the file because it doesn't exist, then the
142  // disk is corrupted.
143  //
144 
145  if (Vcb->VirtualEaFile == NULL) {
146 
147  DebugTrace(0, Dbg, "FatGetEaLength: Ea file doesn't exist\n", 0);
148  FatRaiseStatus( IrpContext, STATUS_NO_EAS_ON_FILE );
149  }
150 
151  //
152  // Try to pin down the Ea set header for the index in the
153  // dirent. If the operation doesn't complete, return FALSE
154  // from this routine.
155  //
156 
157  ThisFilename.Buffer = (PCHAR)Buffer;
158  Fat8dot3ToString( IrpContext, Dirent, FALSE, &ThisFilename );
159 
160  FatReadEaSet( IrpContext,
161  Vcb,
162  Dirent->ExtendedAttributes,
163  &ThisFilename,
164  FALSE,
165  &EaSetRange );
166 
167  EaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;
168 
169  //
170  // We now have the Ea set header for this file. We simply copy
171  // the Ea length field.
172  //
173 
174  CopyUchar4( EaLength, EaSetHeader->cbList );
175  DebugTrace(0, Dbg, "FatGetEaLength: Length of Ea is -> %08lx\n",
176  *EaLength);
177 
178  } _SEH2_FINALLY {
179 
180  DebugUnwind( FatGetEaLength );
181 
182  //
183  // Unpin the EaDirent and the EaSetHeader if pinned.
184  //
185 
186  FatUnpinBcb( IrpContext, EaBcb );
187 
188  FatUnpinEaRange( IrpContext, &EaSetRange );
189 
190  //
191  // Release the Fcb for the Ea file if locked.
192  //
193 
194  if (LockedEaFcb) {
195 
196  FatReleaseFcb( IrpContext, Vcb->EaFcb );
197  }
198 
199  DebugTrace(-1, Dbg, "FatGetEaLength: Ea length -> %08lx\n", *EaLength);
200  } _SEH2_END;
201 
202  return;
203 }
#define TRUE
Definition: types.h:120
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:304
VOID FatUnpinEaRange(IN PIRP_CONTEXT IrpContext, IN OUT PEA_RANGE EaRange)
Definition: easup.c:3782
STRING OEM_STRING
Definition: umtypes.h:203
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
IN OUT PVCB OUT PDIRENT * EaDirent
Definition: fatprocs.h:904
VOID FatReadEaSet(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT EaHandle, IN POEM_STRING FileName, IN BOOLEAN ReturnEntireSet, OUT PEA_RANGE EaSetRange)
Definition: easup.c:1306
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:537
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define PCHAR
Definition: match.c:90
#define DebugUnwind(X)
Definition: fatdata.h:315
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1635
#define CopyUchar4(Dst, Src)
Definition: cdprocs.h:1711
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:866
IN PVCB IN ULONG IN PBCB OUT PDIRENT OUT PUSHORT OUT PEA_RANGE EaSetRange
Definition: fatprocs.h:936
#define Vcb
Definition: cdprocs.h:1425
unsigned char UCHAR
Definition: xmlstorage.h:181
EA_SET_HEADER * PEA_SET_HEADER
Definition: fat.h:672
#define FatIsFat32(VCB)
Definition: fatprocs.h:1437
_SEH2_END
Definition: create.c:4424
_SEH2_FINALLY
Definition: create.c:4395
UCHAR cbList[4]
Definition: fat.h:669
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:429
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
IN OUT PVCB OUT PDIRENT OUT PBCB * EaBcb
Definition: fatprocs.h:904
#define Dbg
Definition: easup.c:22

◆ FatAppendPackedEa()

VOID FatAppendPackedEa ( IN PIRP_CONTEXT  IrpContext,
IN OUT PEA_SET_HEADER EaSetHeader,
IN OUT PULONG  PackedEasLength,
IN OUT PULONG  AllocationLength,
IN PFILE_FULL_EA_INFORMATION  FullEa,
IN ULONG  BytesPerCluster 
)

Definition at line 2967 of file easup.c.

3010 {
3011  ULONG PackedEaSize;
3012  PPACKED_EA ThisPackedEa;
3013  OEM_STRING EaName;
3014 
3015  PAGED_CODE();
3016 
3017  DebugTrace(+1, Dbg, "FatAppendPackedEa...\n", 0);
3018 
3019  //
3020  // As a quick check see if the computed packed ea size plus the
3021  // current packed ea list size will overflow the buffer. Full Ea and
3022  // packed Ea only differ by 4 in their size
3023  //
3024 
3025  PackedEaSize = SizeOfFullEa( FullEa ) - 4;
3026 
3027  if ( PackedEaSize + *PackedEasLength > *AllocationLength ) {
3028 
3029  //
3030  // We will overflow our current work buffer so allocate a larger
3031  // one and copy over the current buffer
3032  //
3033 
3034  PVOID Temp;
3035  ULONG NewAllocationSize;
3036  ULONG OldAllocationSize;
3037 
3038  DebugTrace(0, Dbg, "Allocate a new ea list buffer\n", 0);
3039 
3040  //
3041  // Compute a new size and allocate space. Always increase the
3042  // allocation in cluster increments.
3043  //
3044 
3045  NewAllocationSize = (SIZE_OF_EA_SET_HEADER
3046  + PackedEaSize
3047  + *PackedEasLength
3048  + BytesPerCluster - 1)
3049  & ~(BytesPerCluster - 1);
3050 
3052  NewAllocationSize,
3054 
3055  //
3056  // Move over the existing ea list, and deallocate the old one
3057  //
3058 
3059  RtlCopyMemory( Temp,
3060  *EaSetHeader,
3061  OldAllocationSize = *AllocationLength
3063 
3064  ExFreePool( *EaSetHeader );
3065 
3066  //
3067  // Set up so we will use the new packed ea list
3068  //
3069 
3070  *EaSetHeader = Temp;
3071 
3072  //
3073  // Zero out the added memory.
3074  //
3075 
3076  RtlZeroMemory( &(*EaSetHeader)->PackedEas[*AllocationLength],
3077  NewAllocationSize - OldAllocationSize );
3078 
3079  *AllocationLength = NewAllocationSize - SIZE_OF_EA_SET_HEADER;
3080  }
3081 
3082  //
3083  // Determine if we need to increment our need ea changes count
3084  //
3085 
3086  if ( FlagOn(FullEa->Flags, FILE_NEED_EA )) {
3087 
3088  //
3089  // The NeedEaCount field is long aligned so we will write
3090  // directly to it.
3091  //
3092 
3093  (*EaSetHeader)->NeedEaCount++;
3094  }
3095 
3096  //
3097  // Now copy over the ea, full ea's and packed ea are identical except
3098  // that full ea also have a next ea offset that we skip over
3099  //
3100  // Before:
3101  // UsedSize Allocated
3102  // | |
3103  // V V
3104  // +xxxxxxxx+-----------------------------+
3105  //
3106  // After:
3107  // UsedSize Allocated
3108  // | |
3109  // V V
3110  // +xxxxxxxx+yyyyyyyyyyyyyyyy+------------+
3111  //
3112 
3113  ThisPackedEa = (PPACKED_EA) (RtlOffsetToPointer( (*EaSetHeader)->PackedEas,
3114  *PackedEasLength ));
3115 
3116  RtlCopyMemory( ThisPackedEa,
3117  (PUCHAR) FullEa + 4,
3118  PackedEaSize );
3119 
3120  //
3121  // Now convert the name to uppercase.
3122  //
3123 
3124  EaName.MaximumLength = EaName.Length = FullEa->EaNameLength;
3125  EaName.Buffer = ThisPackedEa->EaName;
3126 
3127  FatUpcaseEaName( IrpContext, &EaName, &EaName );
3128 
3129  //
3130  // Increment the used size in the packed ea list structure
3131  //
3132 
3133  *PackedEasLength += PackedEaSize;
3134 
3135  //
3136  // And return to our caller
3137  //
3138 
3139  DebugTrace(-1, Dbg, "FatAppendPackedEa -> VOID\n", 0);
3140 
3141  UNREFERENCED_PARAMETER( IrpContext );
3142 
3143  return;
3144 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
CHAR EaName[1]
Definition: fat.h:698
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
unsigned char * PUCHAR
Definition: retypes.h:3
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
STRING OEM_STRING
Definition: umtypes.h:203
#define PAGED_CODE()
Definition: video.h:57
#define SizeOfFullEa(EA)
Definition: fatprocs.h:1021
#define RtlOffsetToPointer(B, O)
#define FILE_NEED_EA
#define FatUpcaseEaName(IRPCONTEXT, NAME, UPCASEDNAME)
Definition: fatprocs.h:859
PACKED_EA * PPACKED_EA
Definition: fat.h:700
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define TAG_EA_SET_HEADER
Definition: nodetype.h:161
#define SIZE_OF_EA_SET_HEADER
Definition: fat.h:674
#define Dbg
Definition: easup.c:22
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by FatCommonSetEa().

◆ FatDeletePackedEa()

VOID FatDeletePackedEa ( IN PIRP_CONTEXT  IrpContext,
IN OUT PEA_SET_HEADER  EaSetHeader,
IN OUT PULONG  PackedEasLength,
IN ULONG  Offset 
)

Definition at line 3148 of file easup.c.

3183 {
3184  PPACKED_EA PackedEa;
3185  ULONG PackedEaSize;
3186 
3187  PAGED_CODE();
3188 
3189  DebugTrace(+1, Dbg, "FatDeletePackedEa, Offset = %08lx\n", Offset);
3190 
3191  //
3192  // Get a reference to the packed ea and figure out its size
3193  //
3194 
3195  PackedEa = (PPACKED_EA) (&EaSetHeader->PackedEas[Offset]);
3196 
3197  SizeOfPackedEa( PackedEa, &PackedEaSize );
3198 
3199  //
3200  // Determine if we need to decrement our need ea changes count
3201  //
3202 
3203  if (FlagOn(PackedEa->Flags, EA_NEED_EA_FLAG)) {
3204 
3205  EaSetHeader->NeedEaCount--;
3206  }
3207 
3208  //
3209  // Shrink the ea list over the deleted ea. The amount to copy is the
3210  // total size of the ea list minus the offset to the end of the ea
3211  // we're deleting.
3212  //
3213  // Before:
3214  // Offset Offset+PackedEaSize UsedSize Allocated
3215  // | | | |
3216  // V V V V
3217  // +xxxxxxxx+yyyyyyyyyyyyyyyy+zzzzzzzzzzzzzzzzzz+------------+
3218  //
3219  // After
3220  // Offset UsedSize Allocated
3221  // | | |
3222  // V V V
3223  // +xxxxxxxx+zzzzzzzzzzzzzzzzzz+-----------------------------+
3224  //
3225 
3226  RtlCopyMemory( PackedEa,
3227  (PUCHAR) PackedEa + PackedEaSize,
3228  *PackedEasLength - (Offset + PackedEaSize) );
3229 
3230  //
3231  // And zero out the remaing part of the ea list, to make things
3232  // nice and more robust
3233  //
3234 
3235  RtlZeroMemory( &EaSetHeader->PackedEas[*PackedEasLength - PackedEaSize],
3236  PackedEaSize );
3237 
3238  //
3239  // Decrement the used size by the amount we just removed
3240  //
3241 
3242  *PackedEasLength -= PackedEaSize;
3243 
3244  //
3245  // And return to our caller
3246  //
3247 
3248  DebugTrace(-1, Dbg, "FatDeletePackedEa -> VOID\n", 0);
3249 
3250  UNREFERENCED_PARAMETER( IrpContext );
3251 
3252  return;
3253 }
UCHAR Flags
Definition: fat.h:695
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
unsigned char * PUCHAR
Definition: retypes.h:3
#define SizeOfPackedEa(EA, SIZE)
Definition: fat.h:738
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define PAGED_CODE()
Definition: video.h:57
#define EA_NEED_EA_FLAG
Definition: fat.h:745
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PACKED_EA * PPACKED_EA
Definition: fat.h:700
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define Dbg
Definition: easup.c:22

Referenced by FatCommonSetEa().

◆ FatIsEaNameValid()

BOOLEAN FatIsEaNameValid ( IN PIRP_CONTEXT  IrpContext,
IN OEM_STRING  Name 
)

Definition at line 3429 of file easup.c.

3457 {
3458  ULONG Index;
3459 
3460  UCHAR Char;
3461 
3462  PAGED_CODE();
3463 
3464  UNREFERENCED_PARAMETER( IrpContext );
3465 
3466  //
3467  // Empty names are not valid.
3468  //
3469 
3470  if ( Name.Length == 0 ) { return FALSE; }
3471 
3472  //
3473  // At this point we should only have a single name, which can't have
3474  // more than 254 characters
3475  //
3476 
3477  if ( Name.Length > 254 ) { return FALSE; }
3478 
3479  for ( Index = 0; Index < (ULONG)Name.Length; Index += 1 ) {
3480 
3481  Char = Name.Buffer[ Index ];
3482 
3483  //
3484  // Skip over and Dbcs chacters
3485  //
3486 
3487  if ( FsRtlIsLeadDbcsCharacter( Char ) ) {
3488 
3489  NT_ASSERT( Index != (ULONG)(Name.Length - 1) );
3490 
3491  Index += 1;
3492 
3493  continue;
3494  }
3495 
3496  //
3497  // Make sure this character is legal, and if a wild card, that
3498  // wild cards are permissible.
3499  //
3500 
3501  if ( !FsRtlIsAnsiCharacterLegalFat(Char, FALSE) ) {
3502 
3503  return FALSE;
3504  }
3505  }
3506 
3507  return TRUE;
3508 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define PAGED_CODE()
Definition: video.h:57
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FsRtlIsAnsiCharacterLegalFat(C, WILD)
Definition: fsrtlfuncs.h:1611
unsigned int ULONG
Definition: retypes.h:1
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:417
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by FatCommonSetEa().

◆ FatLocateEaByName()

BOOLEAN FatLocateEaByName ( IN PIRP_CONTEXT  IrpContext,
IN PPACKED_EA  FirstPackedEa,
IN ULONG  PackedEasLength,
IN POEM_STRING  EaName,
OUT PULONG  Offset 
)

Definition at line 3344 of file easup.c.

3377 {
3378  PPACKED_EA PackedEa;
3379  OEM_STRING Name;
3380 
3381  PAGED_CODE();
3382 
3383  DebugTrace(+1, Dbg, "FatLocateEaByName, EaName = %Z\n", EaName);
3384 
3385  //
3386  // For each packed ea in the list check its name against the
3387  // ea name we're searching for
3388  //
3389 
3390  for ( *Offset = 0;
3391  *Offset < PackedEasLength;
3392  *Offset = FatLocateNextEa( IrpContext,
3393  FirstPackedEa,
3394  PackedEasLength,
3395  *Offset )) {
3396 
3397  //
3398  // Reference the packed ea and get a string to its name
3399  //
3400 
3401  PackedEa = (PPACKED_EA) ((PUCHAR) FirstPackedEa + *Offset);
3402 
3403  Name.Buffer = &PackedEa->EaName[0];
3404  Name.Length = PackedEa->EaNameLength;
3405  Name.MaximumLength = PackedEa->EaNameLength;
3406 
3407  //
3408  // Compare the two strings, if they are equal then we've
3409  // found the caller's ea
3410  //
3411 
3412  if ( RtlCompareString( EaName, &Name, TRUE ) == 0 ) {
3413 
3414  DebugTrace(-1, Dbg, "FatLocateEaByName -> TRUE, *Offset = %08lx\n", *Offset);
3415  return TRUE;
3416  }
3417  }
3418 
3419  //
3420  // We've exhausted the ea list without finding a match so return false
3421  //
3422 
3423  DebugTrace(-1, Dbg, "FatLocateEaByName -> FALSE\n", 0);
3424  return FALSE;
3425 }
UCHAR EaNameLength
Definition: fat.h:696
#define TRUE
Definition: types.h:120
CHAR EaName[1]
Definition: fat.h:698
NTSYSAPI LONG NTAPI RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
unsigned char * PUCHAR
Definition: retypes.h:3
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
STRING OEM_STRING
Definition: umtypes.h:203
#define PAGED_CODE()
Definition: video.h:57
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
struct NameRec_ * Name
Definition: cdprocs.h:464
PACKED_EA * PPACKED_EA
Definition: fat.h:700
ULONG FatLocateNextEa(IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN ULONG PreviousOffset)
Definition: easup.c:3257
#define Dbg
Definition: easup.c:22

Referenced by FatCommonSetEa().

◆ FatLocateNextEa()

ULONG FatLocateNextEa ( IN PIRP_CONTEXT  IrpContext,
IN PPACKED_EA  FirstPackedEa,
IN ULONG  PackedEasLength,
IN ULONG  PreviousOffset 
)

Definition at line 3257 of file easup.c.

3291 {
3292  PPACKED_EA PackedEa;
3293  ULONG PackedEaSize;
3294  ULONG Offset;
3295 
3296  PAGED_CODE();
3297 
3298  DebugTrace(+1, Dbg, "FatLocateNextEa, PreviousOffset = %08lx\n",
3299  PreviousOffset);
3300 
3301  //
3302  // Make sure the previous offset is within the used size range
3303  //
3304 
3305  if ( PreviousOffset >= PackedEasLength ) {
3306 
3307  DebugTrace(-1, Dbg, "FatLocateNextEa -> 0xffffffff\n", 0);
3308  return 0xffffffff;
3309  }
3310 
3311  //
3312  // Get a reference to the previous packed ea, and compute its size
3313  //
3314 
3315  PackedEa = (PPACKED_EA) ((PUCHAR) FirstPackedEa + PreviousOffset );
3316  SizeOfPackedEa( PackedEa, &PackedEaSize );
3317 
3318  //
3319  // Compute to the next ea
3320  //
3321 
3322  Offset = PreviousOffset + PackedEaSize;
3323 
3324  //
3325  // Now, if the new offset is beyond the ea size then we know
3326  // that there isn't one so, we return an offset of 0xffffffff.
3327  // otherwise we'll leave the new offset alone.
3328  //
3329 
3330  if ( Offset >= PackedEasLength ) {
3331 
3332  Offset = 0xffffffff;
3333  }
3334 
3335  DebugTrace(-1, Dbg, "FatLocateNextEa -> %08lx\n", Offset);
3336 
3337  UNREFERENCED_PARAMETER( IrpContext );
3338 
3339  return Offset;
3340 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
unsigned char * PUCHAR
Definition: retypes.h:3
#define SizeOfPackedEa(EA, SIZE)
Definition: fat.h:738
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define PAGED_CODE()
Definition: video.h:57
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PACKED_EA * PPACKED_EA
Definition: fat.h:700
unsigned int ULONG
Definition: retypes.h:1
#define Dbg
Definition: easup.c:22

Referenced by FatLocateEaByName().

◆ FatMarkEaRangeDirty()

VOID FatMarkEaRangeDirty ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  EaFileObject,
IN OUT PEA_RANGE  EaRange 
)

Definition at line 3709 of file easup.c.

3735 {
3736  PBCB *NextBcb;
3737  ULONG BcbCount;
3738 
3739  PAGED_CODE();
3740 
3741  UNREFERENCED_PARAMETER( IrpContext );
3742 
3743  //
3744  // If there is an auxilary buffer we need to copy the data back into the cache.
3745  //
3746 
3747  if (EaRange->AuxilaryBuffer == TRUE) {
3748 
3749  LARGE_INTEGER LargeVbo;
3750 
3751  LargeVbo.QuadPart = EaRange->StartingVbo;
3752 
3753  CcCopyWrite( EaFileObject,
3754  &LargeVbo,
3755  EaRange->Length,
3756  TRUE,
3757  EaRange->Data );
3758  }
3759 
3760  //
3761  // Now walk through the Bcb chain and mark everything dirty.
3762  //
3763 
3764  BcbCount = EaRange->BcbChainLength;
3765  NextBcb = EaRange->BcbChain;
3766 
3767  while (BcbCount--) {
3768 
3769  if (*NextBcb != NULL) {
3770 
3771  CcSetDirtyPinnedData( *NextBcb, NULL );
3772  }
3773 
3774  NextBcb += 1;
3775  }
3776 
3777  return;
3778 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
unsigned int ULONG
Definition: retypes.h:1
LONGLONG QuadPart
Definition: typedefs.h:113

Referenced by FatCommonSetEa().

◆ FatPinEaRange()

VOID FatPinEaRange ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  VirtualEaFile,
IN PFCB  EaFcb,
IN OUT PEA_RANGE  EaRange,
IN ULONG  StartingVbo,
IN ULONG  Length,
IN NTSTATUS  ErrorStatus 
)

Definition at line 3512 of file easup.c.

3553 {
3554  LARGE_INTEGER LargeVbo;
3555  ULONG ByteCount;
3556  PBCB *NextBcb;
3557  PVOID Buffer;
3558  PCHAR DestinationBuffer = NULL;
3559  BOOLEAN FirstPage = TRUE;
3560 
3561  PAGED_CODE();
3562 
3563  //
3564  // Verify that the entire read is contained within the Ea file.
3565  //
3566 
3567  if (Length == 0
3568  || StartingVbo >= EaFcb->Header.AllocationSize.LowPart
3569  || (EaFcb->Header.AllocationSize.LowPart - StartingVbo) < Length) {
3570 
3571  FatRaiseStatus( IrpContext, ErrorStatus );
3572  }
3573 
3574  //
3575  // If the read will span a section, the system addresses may not be contiguous.
3576  // Allocate a separate buffer in this case.
3577  //
3578 
3579  if (((StartingVbo & (EA_SECTION_SIZE - 1)) + Length) > EA_SECTION_SIZE) {
3580 
3581  EaRange->Data = FsRtlAllocatePoolWithTag( PagedPool,
3582  Length,
3583  TAG_EA_DATA );
3584  EaRange->AuxilaryBuffer = TRUE;
3585 
3586  DestinationBuffer = EaRange->Data;
3587 
3588  } else {
3589 
3590  //
3591  // PREfix correctly notes that if we don't decide here to have an aux buffer
3592  // and the flag is up in the EaRange, we'll party on random memory since
3593  // DestinationBuffer won't be set; however, this will never happen due to
3594  // initialization of ea ranges and the cleanup in UnpinEaRange.
3595  //
3596 
3597  NT_ASSERT( EaRange->AuxilaryBuffer == FALSE );
3598  }
3599 
3600 
3601  //
3602  // If the read will require more pages than our structure will hold then
3603  // allocate an auxilary buffer. We have to figure the number of pages
3604  // being requested so we have to include the page offset of the first page of
3605  // the request.
3606  //
3607 
3608  EaRange->BcbChainLength = (USHORT) (((StartingVbo & (PAGE_SIZE - 1)) + Length + PAGE_SIZE - 1) / PAGE_SIZE);
3609 
3610  if (EaRange->BcbChainLength > EA_BCB_ARRAY_SIZE) {
3611 
3612  EaRange->BcbChain = FsRtlAllocatePoolWithTag( PagedPool,
3613  sizeof( PBCB ) * EaRange->BcbChainLength,
3614  TAG_BCB );
3615 
3616  RtlZeroMemory( EaRange->BcbChain, sizeof( PBCB ) * EaRange->BcbChainLength );
3617 
3618  } else {
3619 
3620  EaRange->BcbChain = (PBCB *) &EaRange->BcbArray;
3621  }
3622 
3623  //
3624  // Store the byte range data in the Ea Range structure.
3625  //
3626 
3627  EaRange->StartingVbo = StartingVbo;
3628  EaRange->Length = Length;
3629 
3630  //
3631  // Compute the initial pin length.
3632  //
3633 
3634  ByteCount = PAGE_SIZE - (StartingVbo & (PAGE_SIZE - 1));
3635 
3636  //
3637  // For each page in the range; pin the page and update the Bcb count, copy to
3638  // the auxiliary buffer.
3639  //
3640 
3641  NextBcb = EaRange->BcbChain;
3642 
3643  while (Length != 0) {
3644 
3645  //
3646  // Pin the page and remember the data start.
3647  //
3648 
3649  LargeVbo.QuadPart = StartingVbo;
3650 
3651  if (ByteCount > Length) {
3652 
3653  ByteCount = Length;
3654  }
3655 
3656  if (!CcPinRead( VirtualEaFile,
3657  &LargeVbo,
3658  ByteCount,
3659  BooleanFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
3660  NextBcb,
3661  &Buffer )) {
3662 
3663  //
3664  // Could not read the data without waiting (cache miss).
3665  //
3666 
3667  FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
3668  }
3669 
3670  //
3671  // Increment the Bcb pointer and copy to the auxilary buffer if necessary.
3672  //
3673 
3674  NextBcb += 1;
3675 
3676  if (EaRange->AuxilaryBuffer == TRUE) {
3677 
3678  RtlCopyMemory( DestinationBuffer,
3679  Buffer,
3680  ByteCount );
3681 
3682  DestinationBuffer = (PCHAR) Add2Ptr( DestinationBuffer, ByteCount );
3683  }
3684 
3686  Length -= ByteCount;
3687 
3688  //
3689  // If this is the first page then update the Ea Range structure.
3690  //
3691 
3692  if (FirstPage) {
3693 
3694  FirstPage = FALSE;
3695  ByteCount = PAGE_SIZE;
3696 
3697  if (EaRange->AuxilaryBuffer == FALSE) {
3698 
3699  EaRange->Data = Buffer;
3700  }
3701  }
3702  }
3703 
3704  return;
3705 }
signed char * PCHAR
Definition: retypes.h:7
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define Add2Ptr(PTR, INC)
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
#define EA_SECTION_SIZE
Definition: easup.c:49
#define TAG_BCB
Definition: nodetype.h:157
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define PAGED_CODE()
Definition: video.h:57
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define PCHAR
Definition: match.c:90
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
BOOLEAN NTAPI CcPinRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG Flags, OUT PVOID *Bcb, OUT PVOID *Buffer)
Definition: pinsup.c:802
#define TAG_EA_DATA
Definition: nodetype.h:160
#define PAGE_SIZE
Definition: env_spec_w32.h:49
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:402
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1061
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define EA_BCB_ARRAY_SIZE
Definition: fatstruc.h:1712
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LONGLONG QuadPart
Definition: typedefs.h:113
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by FatReadEaSet().

◆ FatReadEaSet()

VOID FatReadEaSet ( IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN USHORT  EaHandle,
IN POEM_STRING  FileName,
IN BOOLEAN  ReturnEntireSet,
OUT PEA_RANGE  EaSetRange 
)

Definition at line 1306 of file easup.c.

1350 {
1351  ULONG BytesPerCluster = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;
1352 
1353  ULONG EaOffsetVbo;
1354  EA_RANGE EaOffsetRange;
1355  USHORT EaOffsetCluster;
1356 
1357  EA_RANGE EaHeaderRange;
1358  PEA_FILE_HEADER EaHeader;
1359 
1360  ULONG EaSetVbo;
1361  PEA_SET_HEADER EaSet;
1362 
1363  ULONG CbList;
1364 
1365  PAGED_CODE();
1366 
1368 
1369  DebugTrace(+1, Dbg, "FatReadEaSet\n", 0);
1370  DebugTrace( 0, Dbg, " Vcb = %p\n", Vcb);
1371 
1372  //
1373  // Verify that the Ea index has a legal value. Raise status
1374  // STATUS_NONEXISTENT_EA_ENTRY if illegal.
1375  //
1376 
1377  if (EaHandle < MIN_EA_HANDLE
1378  || EaHandle > MAX_EA_HANDLE) {
1379 
1380  DebugTrace(-1, Dbg, "FatReadEaSet: Illegal handle value\n", 0);
1382  }
1383 
1384  //
1385  // Verify that the virtual Ea file is large enough for us to read
1386  // the EaOffet table for this index.
1387  //
1388 
1389  EaOffsetVbo = sizeof( EA_FILE_HEADER ) + (((ULONGLONG)EaHandle >> 7) << 8);
1390 
1391  //
1392  // Zero the Ea range structures.
1393  //
1394 
1395  RtlZeroMemory( &EaHeaderRange, sizeof( EA_RANGE ));
1396  RtlZeroMemory( &EaOffsetRange, sizeof( EA_RANGE ));
1397 
1398  //
1399  // Use a try statement to clean up on exit.
1400  //
1401 
1402  _SEH2_TRY {
1403 
1404  //
1405  // Pin down the EA file header.
1406  //
1407 
1408  FatPinEaRange( IrpContext,
1409  Vcb->VirtualEaFile,
1410  Vcb->EaFcb,
1411  &EaHeaderRange,
1412  0,
1413  sizeof( EA_FILE_HEADER ),
1415 
1416  EaHeader = (PEA_FILE_HEADER) EaHeaderRange.Data;
1417 
1418  //
1419  // Pin down the Ea offset table for the particular index.
1420  //
1421 
1422  FatPinEaRange( IrpContext,
1423  Vcb->VirtualEaFile,
1424  Vcb->EaFcb,
1425  &EaOffsetRange,
1426  EaOffsetVbo,
1427  sizeof( EA_OFF_TABLE ),
1429 
1430  //
1431  // Check if the specifific handle is currently being used.
1432  //
1433 
1434  EaOffsetCluster = *((PUSHORT) EaOffsetRange.Data
1435  + (EaHandle & (MAX_EA_OFFSET_INDEX - 1)));
1436 
1437  if (EaOffsetCluster == UNUSED_EA_HANDLE) {
1438 
1439  DebugTrace(0, Dbg, "FatReadEaSet: Ea handle is unused\n", 0);
1441  }
1442 
1443  //
1444  // Compute the file offset for the Ea data.
1445  //
1446 
1447  EaSetVbo = (EaHeader->EaBaseTable[EaHandle >> 7] + EaOffsetCluster)
1448  << Vcb->AllocationSupport.LogOfBytesPerCluster;
1449 
1450  //
1451  // Unpin the file header and offset table.
1452  //
1453 
1454  FatUnpinEaRange( IrpContext, &EaHeaderRange );
1455  FatUnpinEaRange( IrpContext, &EaOffsetRange );
1456 
1457  //
1458  // Pin the ea set.
1459  //
1460 
1461  FatPinEaRange( IrpContext,
1462  Vcb->VirtualEaFile,
1463  Vcb->EaFcb,
1464  EaSetRange,
1465  EaSetVbo,
1466  BytesPerCluster,
1468 
1469  //
1470  // Verify that the Ea set is valid and belongs to this index.
1471  // Raise STATUS_DATA_ERROR if there is a data conflict.
1472  //
1473 
1474  EaSet = (PEA_SET_HEADER) EaSetRange->Data;
1475 
1476  if (EaSet->Signature != EA_SET_SIGNATURE
1477  || EaSet->OwnEaHandle != EaHandle ) {
1478 
1479  DebugTrace(0, Dbg, "FatReadEaSet: Ea set header is corrupt\n", 0);
1480  FatRaiseStatus( IrpContext, STATUS_DATA_ERROR );
1481  }
1482 
1483  //
1484  // At this point we have pinned a single cluster of Ea data. If
1485  // this represents the entire Ea data for the Ea index, we are
1486  // done. Otherwise we need to check on the entire size of
1487  // of the Ea set header and whether it is contained in the allocated
1488  // size of the Ea virtual file. At that point we can unpin
1489  // the partial Ea set header and repin the entire header.
1490  //
1491 
1492  CbList = GetcbList( EaSet );
1493 
1494  if (ReturnEntireSet
1495  && CbList > BytesPerCluster ) {
1496 
1497  //
1498  // Round up to the cluster size.
1499  //
1500 
1501  CbList = (CbList + EA_CBLIST_OFFSET + BytesPerCluster - 1)
1502  & ~(BytesPerCluster - 1);
1503 
1504  FatUnpinEaRange( IrpContext, EaSetRange );
1505 
1506  RtlZeroMemory( EaSetRange, sizeof( EA_RANGE ));
1507 
1508  FatPinEaRange( IrpContext,
1509  Vcb->VirtualEaFile,
1510  Vcb->EaFcb,
1511  EaSetRange,
1512  EaSetVbo,
1513  CbList,
1515  }
1516 
1517  } _SEH2_FINALLY {
1518 
1520 
1521  //
1522  // Unpin the Ea base and offset tables if locked down.
1523  //
1524 
1525  FatUnpinEaRange( IrpContext, &EaHeaderRange );
1526  FatUnpinEaRange( IrpContext, &EaOffsetRange );
1527 
1528  DebugTrace(-1, Dbg, "FatReadEaSet: Exit\n", 0);
1529  } _SEH2_END;
1530 
1531  return;
1532 }
#define MAX_EA_OFFSET_INDEX
Definition: fat.h:751
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
USHORT Signature
Definition: fat.h:664
USHORT EaBaseTable[240]
Definition: fat.h:647
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
USHORT EA_OFF_TABLE[128]
Definition: fat.h:652
#define MAX_EA_HANDLE
Definition: fat.h:747
VOID FatUnpinEaRange(IN PIRP_CONTEXT IrpContext, IN OUT PEA_RANGE EaRange)
Definition: easup.c:3782
EA_FILE_HEADER * PEA_FILE_HEADER
Definition: fat.h:650
IN PVCB IN PUCHAR IN ULONG IN POEM_STRING OUT PUSHORT EaHandle
Definition: fatprocs.h:884
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2965
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
VOID FatReadEaSet(IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT EaHandle, IN POEM_STRING FileName, IN BOOLEAN ReturnEntireSet, OUT PEA_RANGE EaSetRange)
Definition: easup.c:1306
USHORT OwnEaHandle
Definition: fat.h:665
struct _EA_FILE_HEADER EA_FILE_HEADER
#define EA_CBLIST_OFFSET
Definition: fat.h:749
#define EA_SET_SIGNATURE
Definition: fat.h:626
#define MIN_EA_HANDLE
Definition: fat.h:746
#define DebugUnwind(X)
Definition: fatdata.h:315
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define STATUS_NONEXISTENT_EA_ENTRY
Definition: ntstatus.h:303
uint64_t ULONGLONG
Definition: typedefs.h:66
IN PVCB IN ULONG IN PBCB OUT PDIRENT OUT PUSHORT OUT PEA_RANGE EaSetRange
Definition: fatprocs.h:936
#define Vcb
Definition: cdprocs.h:1425
#define UNUSED_EA_HANDLE
Definition: fat.h:748
VOID FatPinEaRange(IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT VirtualEaFile, IN PFCB EaFcb, IN OUT PEA_RANGE EaRange, IN ULONG StartingVbo, IN ULONG Length, IN NTSTATUS ErrorStatus)
Definition: easup.c:3512
EA_SET_HEADER * PEA_SET_HEADER
Definition: fat.h:672
PCHAR Data
Definition: fatstruc.h:1716
_SEH2_END
Definition: create.c:4424
unsigned short USHORT
Definition: pedump.c:61
_SEH2_FINALLY
Definition: create.c:4395
#define STATUS_DATA_ERROR
Definition: ntstatus.h:284
#define GetcbList(EASET)
Definition: fat.h:678
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
unsigned short * PUSHORT
Definition: retypes.h:2
#define Dbg
Definition: easup.c:22

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), FatCommonSetEa(), and FatReadEaSet().

◆ FatUnpinEaRange()

VOID FatUnpinEaRange ( IN PIRP_CONTEXT  IrpContext,
IN OUT PEA_RANGE  EaRange 
)

Definition at line 3782 of file easup.c.

3804 {
3805  PBCB *NextBcb;
3806  ULONG BcbCount;
3807 
3808  PAGED_CODE();
3809 
3810  UNREFERENCED_PARAMETER( IrpContext );
3811 
3812  //
3813  // If we allocated a auxilary buffer, deallocate it here.
3814  //
3815 
3816  if (EaRange->AuxilaryBuffer == TRUE) {
3817 
3818  ExFreePool( EaRange->Data );
3819  EaRange->AuxilaryBuffer = FALSE;
3820  }
3821 
3822  //
3823  // Walk through the Bcb chain and unpin the data.
3824  //
3825 
3826  if (EaRange->BcbChain != NULL) {
3827 
3828  BcbCount = EaRange->BcbChainLength;
3829  NextBcb = EaRange->BcbChain;
3830 
3831  while (BcbCount--) {
3832 
3833  if (*NextBcb != NULL) {
3834 
3835  CcUnpinData( *NextBcb );
3836  *NextBcb = NULL;
3837  }
3838 
3839  NextBcb += 1;
3840  }
3841 
3842  //
3843  // If we allocated a Bcb chain, deallocate it here.
3844  //
3845 
3846  if (EaRange->BcbChain != &EaRange->BcbArray[0]) {
3847 
3848  ExFreePool( EaRange->BcbChain );
3849  }
3850 
3851  EaRange->BcbChain = NULL;
3852  }
3853 
3854  return;
3855 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
unsigned int ULONG
Definition: retypes.h:1
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by _Requires_lock_held_(), FatCommonQueryEa(), FatCommonSetEa(), and FatReadEaSet().