ReactOS 0.4.15-dev-7842-g558ab78
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);
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 PAGED_CODE()
unsigned char BOOLEAN
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:427
#define CopyUchar4(Dst, Src)
Definition: cdprocs.h:1701
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
EA_SET_HEADER * PEA_SET_HEADER
Definition: fat.h:672
VOID FatUnpinEaRange(IN PIRP_CONTEXT IrpContext, IN OUT PEA_RANGE EaRange)
Definition: easup.c:3782
#define Dbg
Definition: easup.c:22
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 DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define DebugUnwind(X)
Definition: fatdata.h:315
IN PVCB IN ULONG IN PBCB OUT PDIRENT OUT PUSHORT OUT PEA_RANGE EaSetRange
Definition: fatprocs.h:951
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
#define FatRaiseStatus(IRPCONTEXT, STATUS)
Definition: fatprocs.h:2977
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:878
VOID Fat8dot3ToString(_In_ PIRP_CONTEXT IrpContext, _In_ PDIRENT Dirent, _In_ BOOLEAN RestoreCase, _Out_ POEM_STRING OutputString)
Definition: namesup.c:179
IN OUT PVCB OUT PDIRENT OUT PBCB * EaBcb
Definition: fatprocs.h:915
IN OUT PVCB OUT PDIRENT * EaDirent
Definition: fatprocs.h:914
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define PCHAR
Definition: match.c:90
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:318
#define Vcb
Definition: cdprocs.h:1415
UCHAR cbList[4]
Definition: fat.h:669
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
STRING OEM_STRING
Definition: umtypes.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ 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}
PACKED_EA * PPACKED_EA
Definition: fat.h:700
#define SIZE_OF_EA_SET_HEADER
Definition: fat.h:674
#define TAG_EA_SET_HEADER
Definition: nodetype.h:161
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define PagedPool
Definition: env_spec_w32.h:308
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define FatUpcaseEaName(IRPCONTEXT, NAME, UPCASEDNAME)
Definition: fatprocs.h:868
#define SizeOfFullEa(EA)
Definition: fatprocs.h:1030
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#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
CHAR EaName[1]
Definition: fat.h:698
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define FILE_NEED_EA

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}
#define EA_NEED_EA_FLAG
Definition: fat.h:745
#define SizeOfPackedEa(EA, SIZE)
Definition: fat.h:738
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
UCHAR Flags
Definition: fat.h:695

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 FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
Definition: init.c:428
#define FsRtlIsAnsiCharacterLegalFat(C, WILD)
Definition: fsrtlfuncs.h:1611
_In_ WDFCOLLECTION _In_ ULONG Index
#define NT_ASSERT
Definition: rtlfuncs.h:3310

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;
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}
struct NameRec_ * Name
Definition: cdprocs.h:460
ULONG FatLocateNextEa(IN PIRP_CONTEXT IrpContext, IN PPACKED_EA FirstPackedEa, IN ULONG PackedEasLength, IN ULONG PreviousOffset)
Definition: easup.c:3257
NTSYSAPI LONG NTAPI RtlCompareString(PSTRING String1, PSTRING String2, BOOLEAN CaseInSensitive)
UCHAR EaNameLength
Definition: fat.h:696

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}

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}
VOID NTAPI CcSetDirtyPinnedData(IN PVOID BcbVoid, IN OPTIONAL PLARGE_INTEGER Lsn)
Definition: cachesub.c:121
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
LONGLONG QuadPart
Definition: typedefs.h:114

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;
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
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;
3696
3697 if (EaRange->AuxilaryBuffer == FALSE) {
3698
3699 EaRange->Data = Buffer;
3700 }
3701 }
3702 }
3703
3704 return;
3705}
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1215
#define TAG_BCB
Definition: nodetype.h:157
#define TAG_EA_DATA
Definition: nodetype.h:160
#define EA_SECTION_SIZE
Definition: easup.c:49
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PVCB IN VBO StartingVbo
Definition: fatprocs.h:412
#define EA_BCB_ARRAY_SIZE
Definition: fatstruc.h:1717
#define Add2Ptr(PTR, INC)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
unsigned short USHORT
Definition: pedump.c:61
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
char * PCHAR
Definition: typedefs.h:51
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _In_ LARGE_INTEGER ByteCount
Definition: iotypes.h:1099

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
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 GetcbList(EASET)
Definition: fat.h:678
#define EA_CBLIST_OFFSET
Definition: fat.h:749
#define UNUSED_EA_HANDLE
Definition: fat.h:748
#define MAX_EA_HANDLE
Definition: fat.h:747
#define MAX_EA_OFFSET_INDEX
Definition: fat.h:751
struct _EA_FILE_HEADER EA_FILE_HEADER
#define EA_SET_SIGNATURE
Definition: fat.h:626
USHORT EA_OFF_TABLE[128]
Definition: fat.h:652
EA_FILE_HEADER * PEA_FILE_HEADER
Definition: fat.h:650
#define MIN_EA_HANDLE
Definition: fat.h:746
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
IN PVCB IN PUCHAR IN ULONG IN POEM_STRING OUT PUSHORT EaHandle
Definition: fatprocs.h:898
if(dx< 0)
Definition: linetemp.h:194
#define STATUS_NONEXISTENT_EA_ENTRY
Definition: ntstatus.h:317
#define STATUS_DATA_ERROR
Definition: ntstatus.h:298
USHORT EaBaseTable[240]
Definition: fat.h:647
PCHAR Data
Definition: fatstruc.h:1721
USHORT OwnEaHandle
Definition: fat.h:665
USHORT Signature
Definition: fat.h:664
uint16_t * PUSHORT
Definition: typedefs.h:56
uint64_t ULONGLONG
Definition: typedefs.h:67

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}
VOID NTAPI CcUnpinData(IN PVOID Bcb)
Definition: pinsup.c:955

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