ReactOS 0.4.15-dev-8002-gbbb3b00
wcache_lib.cpp File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _W_CACHE_ASYNC
 

Macros

#define ASYNC_STATE_NONE   0
 
#define ASYNC_STATE_READ_PRE   1
 
#define ASYNC_STATE_READ   2
 
#define ASYNC_STATE_WRITE_PRE   3
 
#define ASYNC_STATE_WRITE   4
 
#define ASYNC_STATE_DONE   5
 
#define ASYNC_CMD_NONE   0
 
#define ASYNC_CMD_READ   1
 
#define ASYNC_CMD_UPDATE   2
 
#define WCACHE_MAX_CHAIN   (0x10)
 
#define MEM_WCCTX_TAG   'xtCW'
 
#define MEM_WCFRM_TAG   'rfCW'
 
#define MEM_WCBUF_TAG   'fbCW'
 
#define USE_WC_PRINT
 
#define WcPrint   UDFPrint
 
#define WCLOCK_RES   1
 
#define WCacheSetModFlag(block_array, i)    *((PULONG)&(block_array[i].Sector)) |= WCACHE_FLAG_MODIFIED
 
#define WCacheClrModFlag(block_array, i)    *((PULONG)&(block_array[i].Sector)) &= ~WCACHE_FLAG_MODIFIED
 
#define WCacheGetModFlag(block_array, i)    (*((PULONG)&(block_array[i].Sector)) & WCACHE_FLAG_MODIFIED)
 
#define WCacheSectorAddr(block_array, i)    ((ULONG_PTR)(block_array[i].Sector) & WCACHE_ADDR_MASK)
 
#define WCacheFreeSector(frame, offs)
 

Typedefs

typedef struct _W_CACHE_ASYNC W_CACHE_ASYNC
 
typedef struct _W_CACHE_ASYNCPW_CACHE_ASYNC
 

Functions

OSSTATUS __fastcall WCacheCheckLimits (IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
 
OSSTATUS __fastcall WCacheCheckLimitsRAM (IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
 
OSSTATUS __fastcall WCacheCheckLimitsRW (IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
 
OSSTATUS __fastcall WCacheCheckLimitsR (IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
 
VOID __fastcall WCachePurgeAllRW (IN PW_CACHE Cache, IN PVOID Context)
 
VOID __fastcall WCacheFlushAllRW (IN PW_CACHE Cache, IN PVOID Context)
 
VOID __fastcall WCachePurgeAllR (IN PW_CACHE Cache, IN PVOID Context)
 
OSSTATUS __fastcall WCacheDecodeFlags (IN PW_CACHE Cache, IN ULONG Flags)
 
VOID WCacheUpdatePacketComplete (IN PW_CACHE Cache, IN PVOID Context, IN OUT PW_CACHE_ASYNC *FirstWContext, IN OUT PW_CACHE_ASYNC *PrevWContext, IN BOOLEAN FreePacket=TRUE)
 
OSSTATUS WCacheInit__ (IN PW_CACHE Cache, IN ULONG MaxFrames, IN ULONG MaxBlocks, IN SIZE_T MaxBytesToRead, IN ULONG PacketSizeSh, IN ULONG BlockSizeSh, IN ULONG BlocksPerFrameSh, IN lba_t FirstLba, IN lba_t LastLba, IN ULONG Mode, IN ULONG Flags, IN ULONG FramesToKeepFree, IN PWRITE_BLOCK WriteProc, IN PREAD_BLOCK ReadProc, IN PWRITE_BLOCK_ASYNC WriteProcAsync, IN PREAD_BLOCK_ASYNC ReadProcAsync, IN PCHECK_BLOCK CheckUsedProc, IN PUPDATE_RELOC UpdateRelocProc, IN PWC_ERROR_HANDLER ErrorHandlerProc)
 
LONGLONG WCacheRandom (VOID)
 
lba_t __fastcall WCacheFindLbaToRelease (IN PW_CACHE Cache)
 
lba_t __fastcall WCacheFindModifiedLbaToRelease (IN PW_CACHE Cache)
 
lba_t __fastcall WCacheFindFrameToRelease (IN PW_CACHE Cache)
 
ULONG WCacheGetSortedListIndex (IN ULONG BlockCount, IN lba_t *List, IN lba_t Lba)
 
VOID __fastcall WCacheInsertRangeToList (IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba, IN ULONG BCount)
 
VOID __fastcall WCacheInsertItemToList (IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba)
 
VOID __fastcall WCacheRemoveRangeFromList (IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba, IN ULONG BCount)
 
VOID __fastcall WCacheRemoveItemFromList (IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba)
 
PW_CACHE_ENTRY __fastcall WCacheInitFrame (IN PW_CACHE Cache, IN PVOID Context, IN ULONG frame)
 
VOID __fastcall WCacheRemoveFrame (IN PW_CACHE Cache, IN PVOID Context, IN ULONG frame)
 
PW_CACHE_ASYNC WCacheAllocAsyncEntry (IN PW_CACHE Cache, IN OUT PW_CACHE_ASYNC *FirstWContext, IN OUT PW_CACHE_ASYNC *PrevWContext, IN ULONG BufferSize)
 
VOID WCacheFreeAsyncEntry (IN PW_CACHE Cache, PW_CACHE_ASYNC WContext)
 
OSSTATUS WCacheRaiseIoError (IN PW_CACHE Cache, IN PVOID Context, IN OSSTATUS Status, IN ULONG Lba, IN ULONG BCount, IN PVOID Buffer, IN BOOLEAN ReadOp, IN PBOOLEAN Retry)
 
OSSTATUS WCacheUpdatePacket (IN PW_CACHE Cache, IN PVOID Context, IN OUT PW_CACHE_ASYNC *FirstWContext, IN OUT PW_CACHE_ASYNC *PrevWContext, IN PW_CACHE_ENTRY block_array, IN lba_t firstLba, IN lba_t Lba, IN ULONG BSh, IN ULONG BS, IN ULONG PS, IN ULONG PSs, IN PSIZE_T ReadBytes, IN BOOLEAN PrefereWrite, IN ULONG State)
 
VOID WCacheFreePacket (IN PW_CACHE Cache, IN ULONG frame, IN PW_CACHE_ENTRY block_array, IN ULONG offs, IN ULONG PSs)
 
OSSTATUS __fastcall WCacheFlushBlocksRAM (IN PW_CACHE Cache, IN PVOID Context, PW_CACHE_ENTRY block_array, lba_t *List, ULONG firstPos, ULONG lastPos, BOOLEAN Purge)
 
OSSTATUS __fastcall WCachePurgeAllRAM (IN PW_CACHE Cache, IN PVOID Context)
 
OSSTATUS __fastcall WCacheFlushAllRAM (IN PW_CACHE Cache, IN PVOID Context)
 
OSSTATUS WCachePreReadPacket__ (IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba)
 
OSSTATUS WCacheReadBlocks__ (IN PW_CACHE Cache, IN PVOID Context, IN PCHAR Buffer, IN lba_t Lba, IN ULONG BCount, OUT PSIZE_T ReadBytes, IN BOOLEAN CachedOnly)
 
OSSTATUS WCacheWriteBlocks__ (IN PW_CACHE Cache, IN PVOID Context, IN PCHAR Buffer, IN lba_t Lba, IN ULONG BCount, OUT PSIZE_T WrittenBytes, IN BOOLEAN CachedOnly)
 
VOID WCacheFlushAll__ (IN PW_CACHE Cache, IN PVOID Context)
 
VOID WCachePurgeAll__ (IN PW_CACHE Cache, IN PVOID Context)
 
VOID WCacheRelease__ (IN PW_CACHE Cache)
 
BOOLEAN WCacheIsInitialized__ (IN PW_CACHE Cache)
 
OSSTATUS WCacheFlushBlocksRW (IN PW_CACHE Cache, IN PVOID Context, IN lba_t _Lba, IN ULONG BCount)
 
OSSTATUS WCacheFlushBlocks__ (IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN ULONG BCount)
 
OSSTATUS WCacheDirect__ (IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN BOOLEAN Modified, OUT PCHAR *CachedBlock, IN BOOLEAN CachedOnly)
 
OSSTATUS WCacheEODirect__ (IN PW_CACHE Cache, IN PVOID Context)
 
OSSTATUS WCacheStartDirect__ (IN PW_CACHE Cache, IN PVOID Context, IN BOOLEAN Exclusive)
 
BOOLEAN WCacheIsCached__ (IN PW_CACHE Cache, IN lba_t Lba, IN ULONG BCount)
 
OSSTATUS WCacheSetMode__ (IN PW_CACHE Cache, IN ULONG Mode)
 
ULONG WCacheGetMode__ (IN PW_CACHE Cache)
 
ULONG WCacheGetWriteBlockCount__ (IN PW_CACHE Cache)
 
VOID WCacheSyncReloc__ (IN PW_CACHE Cache, IN PVOID Context)
 
VOID WCacheDiscardBlocks__ (IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
 
OSSTATUS WCacheCompleteAsync__ (IN PVOID WContext, IN OSSTATUS Status)
 
ULONG WCacheChFlags__ (IN PW_CACHE Cache, IN ULONG SetFlags, IN ULONG ClrFlags)
 

Variables

ULONG WCache_random
 

Macro Definition Documentation

◆ ASYNC_CMD_NONE

#define ASYNC_CMD_NONE   0

Definition at line 48 of file wcache_lib.cpp.

◆ ASYNC_CMD_READ

#define ASYNC_CMD_READ   1

Definition at line 49 of file wcache_lib.cpp.

◆ ASYNC_CMD_UPDATE

#define ASYNC_CMD_UPDATE   2

Definition at line 50 of file wcache_lib.cpp.

◆ ASYNC_STATE_DONE

#define ASYNC_STATE_DONE   5

Definition at line 46 of file wcache_lib.cpp.

◆ ASYNC_STATE_NONE

#define ASYNC_STATE_NONE   0

Definition at line 41 of file wcache_lib.cpp.

◆ ASYNC_STATE_READ

#define ASYNC_STATE_READ   2

Definition at line 43 of file wcache_lib.cpp.

◆ ASYNC_STATE_READ_PRE

#define ASYNC_STATE_READ_PRE   1

Definition at line 42 of file wcache_lib.cpp.

◆ ASYNC_STATE_WRITE

#define ASYNC_STATE_WRITE   4

Definition at line 45 of file wcache_lib.cpp.

◆ ASYNC_STATE_WRITE_PRE

#define ASYNC_STATE_WRITE_PRE   3

Definition at line 44 of file wcache_lib.cpp.

◆ MEM_WCBUF_TAG

#define MEM_WCBUF_TAG   'fbCW'

Definition at line 56 of file wcache_lib.cpp.

◆ MEM_WCCTX_TAG

#define MEM_WCCTX_TAG   'xtCW'

Definition at line 54 of file wcache_lib.cpp.

◆ MEM_WCFRM_TAG

#define MEM_WCFRM_TAG   'rfCW'

Definition at line 55 of file wcache_lib.cpp.

◆ USE_WC_PRINT

#define USE_WC_PRINT

Definition at line 58 of file wcache_lib.cpp.

◆ WCACHE_MAX_CHAIN

#define WCACHE_MAX_CHAIN   (0x10)

Definition at line 52 of file wcache_lib.cpp.

◆ WCacheClrModFlag

#define WCacheClrModFlag (   block_array,
  i 
)     *((PULONG)&(block_array[i].Sector)) &= ~WCACHE_FLAG_MODIFIED

Definition at line 819 of file wcache_lib.cpp.

◆ WCacheFreeSector

#define WCacheFreeSector (   frame,
  offs 
)
Value:
{ \
DbgFreePool((PVOID)WCacheSectorAddr(block_array, offs)); \
block_array[offs].Sector = NULL; \
Cache->FrameList[frame].BlockCount--; \
}
#define NULL
Definition: types.h:112
Definition: fatfs.h:173
#define WCacheSectorAddr(block_array, i)
Definition: wcache_lib.cpp:864

Definition at line 873 of file wcache_lib.cpp.

◆ WCacheGetModFlag

#define WCacheGetModFlag (   block_array,
  i 
)     (*((PULONG)&(block_array[i].Sector)) & WCACHE_FLAG_MODIFIED)

Definition at line 828 of file wcache_lib.cpp.

◆ WCacheSectorAddr

#define WCacheSectorAddr (   block_array,
  i 
)     ((ULONG_PTR)(block_array[i].Sector) & WCACHE_ADDR_MASK)

Definition at line 864 of file wcache_lib.cpp.

◆ WCacheSetModFlag

#define WCacheSetModFlag (   block_array,
  i 
)     *((PULONG)&(block_array[i].Sector)) |= WCACHE_FLAG_MODIFIED

Definition at line 811 of file wcache_lib.cpp.

◆ WCLOCK_RES

#define WCLOCK_RES   1

◆ WcPrint

#define WcPrint   UDFPrint

Definition at line 61 of file wcache_lib.cpp.

Typedef Documentation

◆ PW_CACHE_ASYNC

◆ W_CACHE_ASYNC

Function Documentation

◆ WCacheAllocAsyncEntry()

PW_CACHE_ASYNC WCacheAllocAsyncEntry ( IN PW_CACHE  Cache,
IN OUT PW_CACHE_ASYNC FirstWContext,
IN OUT PW_CACHE_ASYNC PrevWContext,
IN ULONG  BufferSize 
)

Definition at line 890 of file wcache_lib.cpp.

898{
899 PW_CACHE_ASYNC WContext;
901
903 if(!WContext)
904 return NULL;
906 if(!Buffer) {
907 MyFreePool__(WContext);
908 return NULL;
909 }
910
911 if(!Cache->Chained)
913 WContext->Cache = Cache;
914 if(*PrevWContext)
915 (*PrevWContext)->NextWContext = WContext;
916// WContext->NextWContext = (*PrevWContext);
917 WContext->NextWContext = NULL;
918 WContext->Buffer = Buffer;
919 WContext->Buffer2 = Buffer+(Cache->Chained ? 0 : BufferSize);
920
921 if(!(*FirstWContext))
922 (*FirstWContext) = WContext;
923 (*PrevWContext) = WContext;
924
925 return WContext;
926} // end WCacheAllocAsyncEntry()
Definition: bufpool.h:45
#define BufferSize
Definition: mmc.h:75
#define FALSE
Definition: types.h:117
#define DbgAllocatePoolWithTag(a, b, c)
Definition: env_spec_w32.h:333
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
#define MyFreePool__(addr)
Definition: mem_tools.h:152
#define MyAllocatePoolTag__(type, size, tag)
Definition: mem_tools.h:150
#define PCHAR
Definition: match.c:90
@ SynchronizationEvent
struct _W_CACHE_ASYNC * NextWContext
Definition: wcache_lib.cpp:76
PW_CACHE Cache
Definition: wcache_lib.cpp:70
UDF_PH_CALL_CONTEXT PhContext
Definition: wcache_lib.cpp:67
char * PCHAR
Definition: typedefs.h:51
struct _W_CACHE_ASYNC * PW_CACHE_ASYNC
#define MEM_WCBUF_TAG
Definition: wcache_lib.cpp:56
#define MEM_WCCTX_TAG
Definition: wcache_lib.cpp:54
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by WCacheUpdatePacket().

◆ WCacheCheckLimits()

OSSTATUS __fastcall WCacheCheckLimits ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  ReqLba,
IN ULONG  BCount 
)

Definition at line 1300 of file wcache_lib.cpp.

1306{
1307/* if(!Cache->FrameCount || !Cache->BlockCount) {
1308 ASSERT(!Cache->FrameCount);
1309 ASSERT(!Cache->BlockCount);
1310 if(!Cache->FrameCount)
1311 return STATUS_SUCCESS;
1312 }*/
1313
1314 // check if we have reached Frame or Block limit
1315 if(!Cache->FrameCount && !Cache->BlockCount) {
1316 return STATUS_SUCCESS;
1317 }
1318
1319 // check for empty frames
1320 if(Cache->FrameCount > (Cache->MaxFrames*3)/4) {
1321 ULONG frame;
1322 ULONG i;
1323 for(i=Cache->FrameCount; i>0; i--) {
1324 frame = Cache->CachedFramesList[i-1];
1325 // check if frame is empty
1326 if(!(Cache->FrameList[frame].BlockCount)) {
1328 } else {
1329 ASSERT(Cache->FrameList[frame].Frame);
1330 }
1331 }
1332 }
1333
1334 if(!Cache->BlockCount) {
1335 return STATUS_SUCCESS;
1336 }
1337
1338 // invoke media-specific limit-checker
1339 switch(Cache->Mode) {
1340 case WCACHE_MODE_RAM:
1341 return WCacheCheckLimitsRAM(Cache, Context, ReqLba, BCount);
1342 case WCACHE_MODE_ROM:
1343 case WCACHE_MODE_RW:
1344 return WCacheCheckLimitsRW(Cache, Context, ReqLba, BCount);
1345 case WCACHE_MODE_R:
1346 return WCacheCheckLimitsR(Cache, Context, ReqLba, BCount);
1347 }
1349} // end WCacheCheckLimits()
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
OSSTATUS __fastcall WCacheCheckLimitsR(IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
OSSTATUS __fastcall WCacheCheckLimitsRAM(IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
OSSTATUS __fastcall WCacheCheckLimitsRW(IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
VOID __fastcall WCacheRemoveFrame(IN PW_CACHE Cache, IN PVOID Context, IN ULONG frame)
Definition: wcache_lib.cpp:780
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
#define WCACHE_MODE_RW
Definition: wcache_lib.h:125
#define WCACHE_MODE_ROM
Definition: wcache_lib.h:124
#define WCACHE_MODE_RAM
Definition: wcache_lib.h:127

Referenced by WCacheDirect__(), WCacheInitFrame(), WCacheReadBlocks__(), and WCacheWriteBlocks__().

◆ WCacheCheckLimitsR()

OSSTATUS __fastcall WCacheCheckLimitsR ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  ReqLba,
IN ULONG  BCount 
)

Definition at line 3189 of file wcache_lib.cpp.

3195{
3196 ULONG frame;
3197 lba_t firstLba;
3198 lba_t* List = Cache->CachedBlocksList;
3199 lba_t Lba;
3200 PCHAR tmp_buff = Cache->tmp_buff;
3201 ULONG firstPos;
3202 ULONG BSh = Cache->BlockSizeSh;
3203 ULONG BS = Cache->BlockSize;
3204 ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
3205 ULONG PSs = Cache->PacketSize;
3206 ULONG i;
3207 PW_CACHE_ENTRY block_array;
3208 BOOLEAN mod;
3211 ULONG MaxReloc = Cache->PacketSize;
3212 PULONG reloc_tab = Cache->reloc_tab;
3213
3214 // check if we try to read too much data
3215 if(BCount > Cache->MaxBlocks) {
3217 }
3218
3219 // remove(flush) packets from entire frame(s)
3220 while( ((Cache->BlockCount + WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba) +
3221 BCount - WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba+BCount)) > Cache->MaxBlocks) ||
3222 (Cache->FrameCount >= Cache->MaxFrames) ) {
3223
3224WCCL_retry_1:
3225
3227 if(Lba == WCACHE_INVALID_LBA) {
3228 ASSERT(!Cache->FrameCount);
3229 ASSERT(!Cache->BlockCount);
3230 break;
3231 }
3232 frame = Lba >> Cache->BlocksPerFrameSh;
3233 firstLba = frame << Cache->BlocksPerFrameSh;
3234 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba);
3235 block_array = Cache->FrameList[frame].Frame;
3236 if(!block_array) {
3238 }
3239 // check if modified
3240 mod = WCacheGetModFlag(block_array, Lba - firstLba);
3241 // read/modify/write
3242 if(mod && (Cache->CheckUsedProc(Context, Lba) & WCACHE_BLOCK_USED)) {
3243 if(Cache->WriteCount < MaxReloc) goto WCCL_retry_1;
3244 firstPos = WCacheGetSortedListIndex(Cache->WriteCount, Cache->CachedModifiedBlocksList, Lba);
3245 if(!block_array) {
3247 }
3248 // prepare packet & reloc table
3249 for(i=0; i<MaxReloc; i++) {
3250 Lba = Cache->CachedModifiedBlocksList[firstPos];
3251 frame = Lba >> Cache->BlocksPerFrameSh;
3252 firstLba = frame << Cache->BlocksPerFrameSh;
3253 block_array = Cache->FrameList[frame].Frame;
3254 DbgCopyMemory(tmp_buff + (i << BSh),
3255 (PVOID)WCacheSectorAddr(block_array, Lba-firstLba),
3256 BS);
3257 reloc_tab[i] = Lba;
3258 WCacheRemoveItemFromList(List, &(Cache->BlockCount), Lba);
3259 WCacheRemoveItemFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3260 // mark as non-cached & free pool
3261 WCacheFreeSector(frame, Lba-firstLba);
3262 // check if frame is empty
3263 if(!Cache->FrameList[frame].BlockCount) {
3265 }
3266 if(firstPos >= Cache->WriteCount) firstPos=0;
3267 }
3268 // write packet
3269// status = Cache->WriteProcAsync(Context, tmp_buff, PS, Lba, &ReadBytes, FALSE);
3270 Cache->UpdateRelocProc(Context, NULL, reloc_tab, MaxReloc);
3271 status = Cache->WriteProc(Context, tmp_buff, PS, NULL, &ReadBytes, 0);
3272 if(!OS_SUCCESS(status)) {
3274 }
3275 } else {
3276
3277 if((i = Cache->BlockCount - Cache->WriteCount) > MaxReloc) i = MaxReloc;
3278 // discard blocks
3279 for(; i; i--) {
3280 Lba = List[firstPos];
3281 frame = Lba >> Cache->BlocksPerFrameSh;
3282 firstLba = frame << Cache->BlocksPerFrameSh;
3283 block_array = Cache->FrameList[frame].Frame;
3284
3285 if( (mod = WCacheGetModFlag(block_array, Lba - firstLba)) &&
3286 (Cache->CheckUsedProc(Context, Lba) & WCACHE_BLOCK_USED) )
3287 continue;
3288 WCacheRemoveItemFromList(List, &(Cache->BlockCount), Lba);
3289 if(mod)
3290 WCacheRemoveItemFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3291 // mark as non-cached & free pool
3292 WCacheFreeSector(frame, Lba-firstLba);
3293 // check if frame is empty
3294 if(!Cache->FrameList[frame].BlockCount) {
3296 }
3297 if(firstPos >= Cache->WriteCount) firstPos=0;
3298 }
3299 }
3300 }
3301 return STATUS_SUCCESS;
3302} // end WCacheCheckLimitsR()
unsigned char BOOLEAN
uint32 lba_t
Definition: platform.h:20
static NTSTATUS ReadBytes(IN PDEVICE_OBJECT LowerDevice, OUT PUCHAR Buffer, IN ULONG BufferSize, OUT PULONG_PTR FilledBytes)
Definition: detect.c:67
#define OS_SUCCESS(a)
Definition: env_spec_w32.h:56
#define DbgCopyMemory
Definition: env_spec_w32.h:331
#define OSSTATUS
Definition: env_spec_w32.h:57
static int mod
Definition: i386-dis.c:1288
@ PS
Definition: wcache_lib.h:97
Definition: ps.c:97
#define BS
Definition: telnetd.h:22
uint32_t * PULONG
Definition: typedefs.h:59
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
VOID __fastcall WCacheRemoveItemFromList(IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba)
Definition: wcache_lib.cpp:704
lba_t __fastcall WCacheFindLbaToRelease(IN PW_CACHE Cache)
Definition: wcache_lib.cpp:352
#define WCacheFreeSector(frame, offs)
Definition: wcache_lib.cpp:873
ULONG WCacheGetSortedListIndex(IN ULONG BlockCount, IN lba_t *List, IN lba_t Lba)
Definition: wcache_lib.cpp:449
#define WCacheGetModFlag(block_array, i)
Definition: wcache_lib.cpp:828
OSSTATUS WCacheRaiseIoError(IN PW_CACHE Cache, IN PVOID Context, IN OSSTATUS Status, IN ULONG Lba, IN ULONG BCount, IN PVOID Buffer, IN BOOLEAN ReadOp, IN PBOOLEAN Retry)
Definition: wcache_lib.cpp:946
#define WCACHE_BLOCK_USED
Definition: wcache_lib.h:54
#define WCACHE_W_OP
Definition: wcache_lib.h:70
#define WCACHE_INVALID_LBA
Definition: wcache_lib.h:189
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by WCacheCheckLimits().

◆ WCacheCheckLimitsRAM()

OSSTATUS __fastcall WCacheCheckLimitsRAM ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  ReqLba,
IN ULONG  BCount 
)

Definition at line 1631 of file wcache_lib.cpp.

1637{
1638 ULONG frame;
1639 lba_t firstLba;
1640 lba_t* List = Cache->CachedBlocksList;
1641 lba_t lastLba;
1642 lba_t Lba;
1643// PCHAR tmp_buff = Cache->tmp_buff;
1644 ULONG firstPos;
1645 ULONG lastPos;
1646// ULONG BSh = Cache->BlockSizeSh;
1647// ULONG BS = Cache->BlockSize;
1648// ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
1649 ULONG PSs = Cache->PacketSize;
1650// ULONG try_count = 0;
1651 PW_CACHE_ENTRY block_array;
1652// OSSTATUS status;
1653 ULONG FreeFrameCount = 0;
1654// PVOID addr;
1655
1656 if(Cache->FrameCount >= Cache->MaxFrames) {
1657 FreeFrameCount = Cache->FramesToKeepFree;
1658 } else
1659 if((Cache->BlockCount + WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba) +
1660 BCount - WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba+BCount)) > Cache->MaxBlocks) {
1661 // we need free space to grow WCache without flushing data
1662 // for some period of time
1663 FreeFrameCount = Cache->FramesToKeepFree;
1664 goto Try_Another_Frame;
1665 }
1666 // remove(flush) some frames
1667 while((Cache->FrameCount >= Cache->MaxFrames) || FreeFrameCount) {
1668 ASSERT(Cache->FrameCount <= Cache->MaxFrames);
1669Try_Another_Frame:
1670 if(!Cache->FrameCount || !Cache->BlockCount) {
1671 ASSERT(!Cache->FrameCount);
1672 ASSERT(!Cache->BlockCount);
1673 if(!Cache->FrameCount)
1674 break;
1675 }
1676
1678#if 0
1679 if(Cache->FrameList[frame].WriteCount) {
1680 try_count++;
1681 if(try_count < MAX_TRIES_FOR_NA) goto Try_Another_Frame;
1682 } else {
1683 try_count = 0;
1684 }
1685#else
1686/*
1687 if(Cache->FrameList[frame].UpdateCount) {
1688 try_count = MAX_TRIES_FOR_NA;
1689 } else {
1690 try_count = 0;
1691 }
1692*/
1693#endif
1694
1695 if(FreeFrameCount)
1696 FreeFrameCount--;
1697
1698 firstLba = frame << Cache->BlocksPerFrameSh;
1699 lastLba = firstLba + Cache->BlocksPerFrame;
1700 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, firstLba);
1701 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, lastLba);
1702 block_array = Cache->FrameList[frame].Frame;
1703
1704 if(!block_array) {
1705 UDFPrint(("Hmm...\n"));
1706 BrutePoint();
1708 }
1709 WCacheFlushBlocksRAM(Cache, Context, block_array, List, firstPos, lastPos, TRUE);
1710
1711 WCacheRemoveRangeFromList(List, &(Cache->BlockCount), firstLba, Cache->BlocksPerFrame);
1712 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), firstLba, Cache->BlocksPerFrame);
1714 }
1715
1716 // check if we try to read too much data
1717 if(BCount > Cache->MaxBlocks) {
1719 }
1720
1721 // remove(flush) packet
1722 while((Cache->BlockCount + WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba) +
1723 BCount - WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba+BCount)) > Cache->MaxBlocks) {
1724// try_count = 0;
1725//Try_Another_Block:
1726
1727 ASSERT(Cache->FrameCount <= Cache->MaxFrames);
1728 Lba = WCacheFindLbaToRelease(Cache) & ~(PSs-1);
1729 if(Lba == WCACHE_INVALID_LBA) {
1730 ASSERT(!Cache->FrameCount);
1731 ASSERT(!Cache->BlockCount);
1732 break;
1733 }
1734 frame = Lba >> Cache->BlocksPerFrameSh;
1735 firstLba = frame << Cache->BlocksPerFrameSh;
1736 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba);
1737 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba+PSs);
1738 block_array = Cache->FrameList[frame].Frame;
1739 if(!block_array) {
1740 ASSERT(FALSE);
1742 }
1743 WCacheFlushBlocksRAM(Cache, Context, block_array, List, firstPos, lastPos, TRUE);
1744 WCacheRemoveRangeFromList(List, &(Cache->BlockCount), Lba, PSs);
1745 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba, PSs);
1746 // check if frame is empty
1747 if(!(Cache->FrameList[frame].BlockCount)) {
1749 } else {
1750 ASSERT(Cache->FrameList[frame].Frame);
1751 }
1752 }
1753 return STATUS_SUCCESS;
1754} // end WCacheCheckLimitsRAM()
#define TRUE
Definition: types.h:120
#define BrutePoint()
Definition: env_spec_w32.h:504
#define UDFPrint(Args)
Definition: udffs.h:223
OSSTATUS __fastcall WCacheFlushBlocksRAM(IN PW_CACHE Cache, IN PVOID Context, PW_CACHE_ENTRY block_array, lba_t *List, ULONG firstPos, ULONG lastPos, BOOLEAN Purge)
VOID __fastcall WCacheRemoveRangeFromList(IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba, IN ULONG BCount)
Definition: wcache_lib.cpp:675
lba_t __fastcall WCacheFindFrameToRelease(IN PW_CACHE Cache)
Definition: wcache_lib.cpp:386
#define MAX_TRIES_FOR_NA
Definition: wcache_lib.h:116

Referenced by WCacheCheckLimits().

◆ WCacheCheckLimitsRW()

OSSTATUS __fastcall WCacheCheckLimitsRW ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  ReqLba,
IN ULONG  BCount 
)

Definition at line 1361 of file wcache_lib.cpp.

1367{
1368 ULONG frame;
1369 lba_t firstLba;
1370 lba_t* List = Cache->CachedBlocksList;
1371 lba_t lastLba;
1372 lba_t Lba;
1373// PCHAR tmp_buff = Cache->tmp_buff;
1374 ULONG firstPos;
1375 ULONG lastPos;
1376 ULONG BSh = Cache->BlockSizeSh;
1377 ULONG BS = Cache->BlockSize;
1378 ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
1379 ULONG PSs = Cache->PacketSize;
1380 ULONG try_count = 0;
1381 PW_CACHE_ENTRY block_array;
1384 ULONG FreeFrameCount = 0;
1385// PVOID addr;
1386 PW_CACHE_ASYNC FirstWContext = NULL;
1387 PW_CACHE_ASYNC PrevWContext = NULL;
1388 ULONG chain_count = 0;
1389
1390 if(Cache->FrameCount >= Cache->MaxFrames) {
1391 FreeFrameCount = Cache->FramesToKeepFree;
1392 } else
1393 if((Cache->BlockCount + WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba) +
1394 BCount - WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba+BCount)) > Cache->MaxBlocks) {
1395 // we need free space to grow WCache without flushing data
1396 // for some period of time
1397 FreeFrameCount = Cache->FramesToKeepFree;
1398 goto Try_Another_Frame;
1399 }
1400 // remove(flush) some frames
1401 while((Cache->FrameCount >= Cache->MaxFrames) || FreeFrameCount) {
1402Try_Another_Frame:
1403 if(!Cache->FrameCount || !Cache->BlockCount) {
1404 //ASSERT(!Cache->FrameCount);
1405 if(Cache->FrameCount) {
1406 UDFPrint(("ASSERT: Cache->FrameCount = %d, when 0 is expected\n", Cache->FrameCount));
1407 }
1408 ASSERT(!Cache->BlockCount);
1409 if(!Cache->FrameCount)
1410 break;
1411 }
1412
1414#if 0
1415 if(Cache->FrameList[frame].WriteCount) {
1416 try_count++;
1417 if(try_count < MAX_TRIES_FOR_NA) goto Try_Another_Frame;
1418 } else {
1419 try_count = 0;
1420 }
1421#else
1422 if(Cache->FrameList[frame].UpdateCount) {
1423 try_count = MAX_TRIES_FOR_NA;
1424 } else {
1425 try_count = 0;
1426 }
1427#endif
1428
1429 if(FreeFrameCount)
1430 FreeFrameCount--;
1431
1432 firstLba = frame << Cache->BlocksPerFrameSh;
1433 lastLba = firstLba + Cache->BlocksPerFrame;
1434 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, firstLba);
1435 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, lastLba);
1436 block_array = Cache->FrameList[frame].Frame;
1437
1438 if(!block_array) {
1439 UDFPrint(("Hmm...\n"));
1440 BrutePoint();
1442 }
1443
1444 while(firstPos < lastPos) {
1445 // flush packet
1446 Lba = List[firstPos] & ~(PSs-1);
1447
1448 // write packet out or prepare and add to chain (if chained mode enabled)
1449 status = WCacheUpdatePacket(Cache, Context, &FirstWContext, &PrevWContext, block_array, firstLba,
1450 Lba, BSh, BS, PS, PSs, &ReadBytes, TRUE, ASYNC_STATE_NONE);
1451
1452 if(status != STATUS_PENDING) {
1453 // free memory
1454 WCacheFreePacket(Cache, frame, block_array, Lba-firstLba, PSs);
1455 }
1456
1457 Lba += PSs;
1458 while((firstPos < lastPos) && (Lba > List[firstPos])) {
1459 firstPos++;
1460 }
1461 chain_count++;
1462 // write chained packets
1463 if(chain_count >= WCACHE_MAX_CHAIN) {
1464 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
1465 chain_count = 0;
1466 }
1467 }
1468 // remove flushed blocks from all lists
1469 WCacheRemoveRangeFromList(List, &(Cache->BlockCount), firstLba, Cache->BlocksPerFrame);
1470 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), firstLba, Cache->BlocksPerFrame);
1471
1473 }
1474
1475 // check if we try to read too much data
1476 if(BCount > Cache->MaxBlocks) {
1477 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext);
1479 }
1480
1481 // remove(flush) packet
1482 while((Cache->BlockCount + WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba) +
1483 BCount - WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba+BCount)) > Cache->MaxBlocks) {
1484 try_count = 0;
1485Try_Another_Block:
1486
1487 Lba = WCacheFindLbaToRelease(Cache) & ~(PSs-1);
1488 if(Lba == WCACHE_INVALID_LBA) {
1489 ASSERT(!Cache->FrameCount);
1490 ASSERT(!Cache->BlockCount);
1491 break;
1492 }
1493 frame = Lba >> Cache->BlocksPerFrameSh;
1494 firstLba = frame << Cache->BlocksPerFrameSh;
1495 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba);
1496 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba+PSs);
1497 block_array = Cache->FrameList[frame].Frame;
1498 if(!block_array) {
1499 // write already prepared blocks to disk and return error
1500 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext);
1501 ASSERT(FALSE);
1503 }
1504
1505 // write packet out or prepare and add to chain (if chained mode enabled)
1506 status = WCacheUpdatePacket(Cache, Context, &FirstWContext, &PrevWContext, block_array, firstLba,
1507 Lba, BSh, BS, PS, PSs, &ReadBytes, (try_count >= MAX_TRIES_FOR_NA), ASYNC_STATE_NONE);
1508
1509 if(status == STATUS_RETRY) {
1510 try_count++;
1511 goto Try_Another_Block;
1512 }
1513
1514 // free memory
1515 WCacheFreePacket(Cache, frame, block_array, Lba-firstLba, PSs);
1516
1517 WCacheRemoveRangeFromList(List, &(Cache->BlockCount), Lba, PSs);
1518 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba, PSs);
1519 // check if frame is empty
1520 if(!(Cache->FrameList[frame].BlockCount)) {
1522 } else {
1523 ASSERT(Cache->FrameList[frame].Frame);
1524 }
1525 chain_count++;
1526 if(chain_count >= WCACHE_MAX_CHAIN) {
1527 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
1528 chain_count = 0;
1529 }
1530 }
1531 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext);
1532 return STATUS_SUCCESS;
1533} // end WCacheCheckLimitsRW()
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_RETRY
Definition: udferr_usr.h:182
VOID WCacheFreePacket(IN PW_CACHE Cache, IN ULONG frame, IN PW_CACHE_ENTRY block_array, IN ULONG offs, IN ULONG PSs)
#define ASYNC_STATE_NONE
Definition: wcache_lib.cpp:41
VOID WCacheUpdatePacketComplete(IN PW_CACHE Cache, IN PVOID Context, IN OUT PW_CACHE_ASYNC *FirstWContext, IN OUT PW_CACHE_ASYNC *PrevWContext, IN BOOLEAN FreePacket=TRUE)
OSSTATUS WCacheUpdatePacket(IN PW_CACHE Cache, IN PVOID Context, IN OUT PW_CACHE_ASYNC *FirstWContext, IN OUT PW_CACHE_ASYNC *PrevWContext, IN PW_CACHE_ENTRY block_array, IN lba_t firstLba, IN lba_t Lba, IN ULONG BSh, IN ULONG BS, IN ULONG PS, IN ULONG PSs, IN PSIZE_T ReadBytes, IN BOOLEAN PrefereWrite, IN ULONG State)
Definition: wcache_lib.cpp:986
#define WCACHE_MAX_CHAIN
Definition: wcache_lib.cpp:52

Referenced by WCacheCheckLimits().

◆ WCacheChFlags__()

ULONG WCacheChFlags__ ( IN PW_CACHE  Cache,
IN ULONG  SetFlags,
IN ULONG  ClrFlags 
)

Definition at line 3635 of file wcache_lib.cpp.

3640{
3641 ULONG Flags;
3642
3643 if(SetFlags || ClrFlags) {
3644 Flags = (Cache->Flags & ~ClrFlags) | SetFlags;
3645
3647 return -1;
3648 }
3649 } else {
3650 return Cache->Flags;
3651 }
3652 return Flags;
3653} // end WCacheSetMode__()
OSSTATUS __fastcall WCacheDecodeFlags(IN PW_CACHE Cache, IN ULONG Flags)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by UDFMountVolume(), and UDFVerifyVolume().

◆ WCacheCompleteAsync__()

OSSTATUS WCacheCompleteAsync__ ( IN PVOID  WContext,
IN OSSTATUS  Status 
)

Definition at line 3586 of file wcache_lib.cpp.

3590{
3591 PW_CACHE_ASYNC AsyncCtx = (PW_CACHE_ASYNC)WContext;
3592// PW_CACHE Cache = AsyncCtx->Cache;
3593
3594 AsyncCtx->PhContext.IosbToUse.Status = Status;
3595 KeSetEvent(&(AsyncCtx->PhContext.event), 0, FALSE);
3596
3597 return STATUS_SUCCESS;
3598} // end WCacheSetMode__()
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
Status
Definition: gdiplustypes.h:25
IO_STATUS_BLOCK IosbToUse
Definition: Sys_spec_lib.h:24

Referenced by WCacheUpdatePacket().

◆ WCacheDecodeFlags()

OSSTATUS __fastcall WCacheDecodeFlags ( IN PW_CACHE  Cache,
IN ULONG  Flags 
)

Definition at line 3606 of file wcache_lib.cpp.

3610{
3611 //ULONG OldFlags;
3612 if(Flags & ~WCACHE_VALID_FLAGS) {
3613 UDFPrint(("Invalid flags: %x\n", Flags & ~WCACHE_VALID_FLAGS));
3615 }
3616 Cache->CacheWholePacket = (Flags & WCACHE_CACHE_WHOLE_PACKET) ? TRUE : FALSE;
3617 Cache->DoNotCompare = (Flags & WCACHE_DO_NOT_COMPARE) ? TRUE : FALSE;
3618 Cache->Chained = (Flags & WCACHE_CHAINED_IO) ? TRUE : FALSE;
3619 Cache->RememberBB = (Flags & WCACHE_MARK_BAD_BLOCKS) ? TRUE : FALSE;
3620 if(Cache->RememberBB) {
3621 Cache->NoWriteBB = (Flags & WCACHE_RO_BAD_BLOCKS) ? TRUE : FALSE;
3622 }
3623 Cache->NoWriteThrough = (Flags & WCACHE_NO_WRITE_THROUGH) ? TRUE : FALSE;
3624
3625 Cache->Flags = Flags;
3626
3627 return STATUS_SUCCESS;
3628}
#define WCACHE_VALID_FLAGS
Definition: wcache_lib.h:198
#define WCACHE_RO_BAD_BLOCKS
Definition: wcache_lib.h:195
#define WCACHE_NO_WRITE_THROUGH
Definition: wcache_lib.h:196
#define WCACHE_CACHE_WHOLE_PACKET
Definition: wcache_lib.h:191
#define WCACHE_MARK_BAD_BLOCKS
Definition: wcache_lib.h:194
#define WCACHE_DO_NOT_COMPARE
Definition: wcache_lib.h:192
#define WCACHE_CHAINED_IO
Definition: wcache_lib.h:193

Referenced by WCacheChFlags__(), and WCacheInit__().

◆ WCacheDirect__()

OSSTATUS WCacheDirect__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  Lba,
IN BOOLEAN  Modified,
OUT PCHAR CachedBlock,
IN BOOLEAN  CachedOnly 
)

Definition at line 2949 of file wcache_lib.cpp.

2957{
2958 ULONG frame;
2959 ULONG i;
2961 PW_CACHE_ENTRY block_array;
2962 ULONG BS = Cache->BlockSize;
2963 PCHAR addr;
2964 SIZE_T _ReadBytes;
2965 ULONG block_type;
2966
2967 WcPrint(("WC:%sD %x (1)\n", Modified ? "W" : "R", Lba));
2968
2969 // lock cache if nececcary
2970 if(!CachedOnly) {
2971 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2972 }
2973 // check if we try to access beyond cached area
2974 if((Lba < Cache->FirstLba) ||
2975 (Lba > Cache->LastLba)) {
2976 UDFPrint(("LBA %#x is beyond cacheable area\n", Lba));
2977 BrutePoint();
2979 goto EO_WCache_D;
2980 }
2981
2982 frame = Lba >> Cache->BlocksPerFrameSh;
2983 i = Lba - (frame << Cache->BlocksPerFrameSh);
2984 // check if we have enough space to store requested block
2985 if(!CachedOnly &&
2987 BrutePoint();
2988 goto EO_WCache_D;
2989 }
2990
2991 // small updates are more important
2992 block_array = Cache->FrameList[frame].Frame;
2993 if(Modified) {
2994 Cache->FrameList[frame].UpdateCount+=8;
2995 } else {
2996 Cache->FrameList[frame].AccessCount+=8;
2997 }
2998 if(!block_array) {
2999 ASSERT(Cache->FrameCount < Cache->MaxFrames);
3000 block_array = WCacheInitFrame(Cache, Context, frame);
3001 if(!block_array) {
3003 goto EO_WCache_D;
3004 }
3005 }
3006 // check if requested block is already cached
3007 if( !(addr = (PCHAR)WCacheSectorAddr(block_array, i)) ) {
3008 // block is not cached
3009 // allocate memory and read block from media
3010 // do not set block_array[i].Sector here, because if media access fails and recursive access to cache
3011 // comes, this block should not be marked as 'cached'
3013 if(!addr) {
3015 goto EO_WCache_D;
3016 }
3017 block_type = Cache->CheckUsedProc(Context, Lba);
3018 if(block_type == WCACHE_BLOCK_USED) {
3019 status = Cache->ReadProc(Context, addr, BS, Lba, &_ReadBytes, PH_TMP_BUFFER);
3020 if(Cache->RememberBB) {
3021 if(!OS_SUCCESS(status)) {
3023 //WCacheSetBadFlag(block_array,i);
3024 }
3025 }
3026 } else {
3027 if(block_type & WCACHE_BLOCK_BAD) {
3029 addr = NULL;
3031 goto EO_WCache_D;
3032 }
3033 if(!(block_type & WCACHE_BLOCK_ZERO)) {
3034 BrutePoint();
3035 }
3038 }
3039 // now add pointer to buffer to common storage
3040 block_array[i].Sector = addr;
3041 WCacheInsertItemToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba);
3042 if(Modified) {
3043 WCacheInsertItemToList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3044 WCacheSetModFlag(block_array, i);
3045 }
3046 Cache->FrameList[frame].BlockCount ++;
3047 } else {
3048 // block is not cached
3049 // just return pointer
3050 block_type = Cache->CheckUsedProc(Context, Lba);
3051 if(block_type & WCACHE_BLOCK_BAD) {
3052 //if(WCacheGetBadFlag(block_array,i)) {
3053 // bad packet. no pre-read
3055 goto EO_WCache_D;
3056 }
3057#ifndef UDF_CHECK_UTIL
3058 ASSERT(block_type & WCACHE_BLOCK_USED);
3059#else
3060 if(!(block_type & WCACHE_BLOCK_USED)) {
3061 UDFPrint(("LBA %#x is not marked as used\n", Lba));
3062 }
3063#endif
3064 if(Modified &&
3065 !WCacheGetModFlag(block_array, i)) {
3066 WCacheInsertItemToList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3067 WCacheSetModFlag(block_array, i);
3068 }
3069 }
3070 (*CachedBlock) = addr;
3071
3072EO_WCache_D:
3073
3074 return status;
3075} // end WCacheDirect__()
#define DbgFreePool
Definition: env_spec_w32.h:334
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
GLenum const GLvoid * addr
Definition: glext.h:9621
#define PH_TMP_BUFFER
Definition: phys_lib.h:65
PCHAR Sector
Definition: wcache_lib.h:99
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PW_CACHE_ENTRY __fastcall WCacheInitFrame(IN PW_CACHE Cache, IN PVOID Context, IN ULONG frame)
Definition: wcache_lib.cpp:731
OSSTATUS __fastcall WCacheCheckLimits(IN PW_CACHE Cache, IN PVOID Context, IN lba_t ReqLba, IN ULONG BCount)
#define WCacheSetModFlag(block_array, i)
Definition: wcache_lib.cpp:811
VOID __fastcall WCacheInsertItemToList(IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba)
Definition: wcache_lib.cpp:637
#define WcPrint
Definition: wcache_lib.cpp:61
#define CACHED_BLOCK_MEMORY_TYPE
Definition: wcache_lib.h:115
#define WCACHE_BLOCK_ZERO
Definition: wcache_lib.h:55
#define WCACHE_BLOCK_BAD
Definition: wcache_lib.h:56

Referenced by UDFWriteInSector().

◆ WCacheDiscardBlocks__()

VOID WCacheDiscardBlocks__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  ReqLba,
IN ULONG  BCount 
)

Definition at line 3520 of file wcache_lib.cpp.

3526{
3527 ULONG frame;
3528 lba_t firstLba;
3529 lba_t* List;
3530 lba_t Lba;
3531 PW_CACHE_ENTRY block_array;
3532 BOOLEAN mod;
3533 ULONG i;
3534
3535 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
3536
3537 UDFPrint((" Discard req: %x@%x\n",BCount, ReqLba));
3538
3539 List = Cache->CachedBlocksList;
3540 if(!List) {
3542 return;
3543 }
3544 i = WCacheGetSortedListIndex(Cache->BlockCount, List, ReqLba);
3545
3546 // enumerate requested blocks
3547 while((List[i] < (ReqLba+BCount)) && (i < Cache->BlockCount)) {
3548
3549 Lba = List[i];
3550 frame = Lba >> Cache->BlocksPerFrameSh;
3551 firstLba = frame << Cache->BlocksPerFrameSh;
3552 block_array = Cache->FrameList[frame].Frame;
3553 if(!block_array) {
3555 BrutePoint();
3556 return;
3557 }
3558 // check if modified
3559 mod = WCacheGetModFlag(block_array, Lba - firstLba);
3560 // just discard
3561
3562 // mark as non-cached & free pool
3563 if(WCacheSectorAddr(block_array,Lba-firstLba)) {
3564 WCacheRemoveItemFromList(List, &(Cache->BlockCount), Lba);
3565 if(mod)
3566 WCacheRemoveItemFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3567 // mark as non-cached & free pool
3568 WCacheFreeSector(frame, Lba-firstLba);
3569 // check if frame is empty
3570 if(!Cache->FrameList[frame].BlockCount) {
3572 } else {
3573 ASSERT(Cache->FrameList[frame].Frame);
3574 }
3575 } else {
3576 // we should never get here !!!
3577 // getting this part of code means that we have
3578 // placed non-cached block in CachedBlocksList
3579 BrutePoint();
3580 }
3581 }
3583} // end WCacheDiscardBlocks__()
#define ExReleaseResourceForThreadLite(res, thrdID)
Definition: env_spec_w32.h:635
#define ExGetCurrentResourceThread()
Definition: env_spec_w32.h:633

Referenced by UDFMarkSpaceAsXXXNoProtect_().

◆ WCacheEODirect__()

OSSTATUS WCacheEODirect__ ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 3083 of file wcache_lib.cpp.

3087{
3089 return STATUS_SUCCESS;
3090} // end WCacheEODirect__()

Referenced by UDFCommonRead(), UDFCommonWrite(), UDFIsExtentCached(), UDFVWorkItem(), and UDFWriteInSector().

◆ WCacheFindFrameToRelease()

lba_t __fastcall WCacheFindFrameToRelease ( IN PW_CACHE  Cache)

Definition at line 386 of file wcache_lib.cpp.

389{
390 ULONG i, j;
391 ULONG frame = 0;
392 ULONG prev_uc = -1;
393 ULONG uc = -1;
394 lba_t lba;
395 BOOLEAN mod = FALSE;
396
397 if(!(Cache->FrameCount))
398 return 0;
399 /*
400 return(Cache->CachedFramesList[((ULONG)WCacheRandom() % Cache->FrameCount)]);
401 */
402
403 for(i=0; i<Cache->FrameCount; i++) {
404
405 j = Cache->CachedFramesList[i];
406
407 mod |= (Cache->FrameList[j].UpdateCount != 0);
408 uc = Cache->FrameList[j].UpdateCount*32 + Cache->FrameList[j].AccessCount;
409
410 if(prev_uc > uc) {
411 prev_uc = uc;
412 frame = j;
413 }
414 }
415 if(!mod) {
416 frame = Cache->CachedFramesList[((ULONG)WCacheRandom() % Cache->FrameCount)];
417 lba = frame << Cache->BlocksPerFrameSh;
418 WcPrint(("WC:-frm %x\n", lba));
419 } else {
420 lba = frame << Cache->BlocksPerFrameSh;
421 WcPrint(("WC:-frm(mod) %x\n", lba));
422 for(i=0; i<Cache->FrameCount; i++) {
423
424 j = Cache->CachedFramesList[i];
425 Cache->FrameList[j].UpdateCount = (Cache->FrameList[j].UpdateCount*2)/3;
426 Cache->FrameList[j].AccessCount = (Cache->FrameList[j].AccessCount*3)/4;
427 }
428 }
429 return frame;
430} // end WCacheFindFrameToRelease()
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define lba
LONGLONG WCacheRandom(VOID)
Definition: wcache_lib.cpp:339

Referenced by WCacheCheckLimitsRAM(), and WCacheCheckLimitsRW().

◆ WCacheFindLbaToRelease()

lba_t __fastcall WCacheFindLbaToRelease ( IN PW_CACHE  Cache)

Definition at line 352 of file wcache_lib.cpp.

355{
356 if(!(Cache->BlockCount))
357 return WCACHE_INVALID_LBA;
358 return(Cache->CachedBlocksList[((ULONG)WCacheRandom() % Cache->BlockCount)]);
359} // end WCacheFindLbaToRelease()

Referenced by WCacheCheckLimitsR(), WCacheCheckLimitsRAM(), and WCacheCheckLimitsRW().

◆ WCacheFindModifiedLbaToRelease()

lba_t __fastcall WCacheFindModifiedLbaToRelease ( IN PW_CACHE  Cache)

Definition at line 369 of file wcache_lib.cpp.

372{
373 if(!(Cache->WriteCount))
374 return WCACHE_INVALID_LBA;
375 return(Cache->CachedModifiedBlocksList[((ULONG)WCacheRandom() % Cache->WriteCount)]);
376} // end WCacheFindModifiedLbaToRelease()

◆ WCacheFlushAll__()

VOID WCacheFlushAll__ ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 2560 of file wcache_lib.cpp.

2563{
2564 if(!(Cache->ReadProc)) return;
2565 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2566
2567 switch(Cache->Mode) {
2568 case WCACHE_MODE_RAM:
2570 break;
2571 case WCACHE_MODE_ROM:
2572 case WCACHE_MODE_RW:
2574 break;
2575 case WCACHE_MODE_R:
2577 break;
2578 }
2579
2581 return;
2582} // end WCacheFlushAll__()
OSSTATUS __fastcall WCacheFlushAllRAM(IN PW_CACHE Cache, IN PVOID Context)
VOID __fastcall WCachePurgeAllR(IN PW_CACHE Cache, IN PVOID Context)
VOID __fastcall WCacheFlushAllRW(IN PW_CACHE Cache, IN PVOID Context)

Referenced by UDFEjectReqWaiter(), UDFFlushLogicalVolume(), UDFLoadPartDesc(), UDFRecordVAT(), UDFReleaseVCB(), UDFUmount__(), and UDFVerifyVolume().

◆ WCacheFlushAllRAM()

OSSTATUS __fastcall WCacheFlushAllRAM ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 1810 of file wcache_lib.cpp.

1814{
1815 ULONG frame;
1816 lba_t firstLba;
1817 lba_t* List = Cache->CachedBlocksList;
1818 lba_t lastLba;
1819 ULONG firstPos;
1820 ULONG lastPos;
1821 PW_CACHE_ENTRY block_array;
1822// OSSTATUS status;
1823
1824 // flush frames
1825 while(Cache->WriteCount) {
1826
1827 frame = Cache->CachedModifiedBlocksList[0] >> Cache->BlocksPerFrameSh;
1828
1829 firstLba = frame << Cache->BlocksPerFrameSh;
1830 lastLba = firstLba + Cache->BlocksPerFrame;
1831 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, firstLba);
1832 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, lastLba);
1833 block_array = Cache->FrameList[frame].Frame;
1834
1835 if(!block_array) {
1836 UDFPrint(("Hmm...\n"));
1837 BrutePoint();
1839 }
1840 WCacheFlushBlocksRAM(Cache, Context, block_array, List, firstPos, lastPos, FALSE);
1841
1842 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), firstLba, Cache->BlocksPerFrame);
1843 }
1844
1845 return STATUS_SUCCESS;
1846} // end WCacheFlushAllRAM()

Referenced by WCacheFlushAll__().

◆ WCacheFlushAllRW()

VOID __fastcall WCacheFlushAllRW ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 2689 of file wcache_lib.cpp.

2692{
2693 ULONG frame;
2694 lba_t firstLba;
2695 lba_t* List = Cache->CachedModifiedBlocksList;
2696 lba_t Lba;
2697// ULONG firstPos;
2698// ULONG lastPos;
2699 ULONG BSh = Cache->BlockSizeSh;
2700 ULONG BS = Cache->BlockSize;
2701 ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
2702 ULONG PSs = Cache->PacketSize;
2703 ULONG BFs = Cache->BlocksPerFrameSh;
2704 PW_CACHE_ENTRY block_array;
2705// OSSTATUS status;
2707 PW_CACHE_ASYNC FirstWContext = NULL;
2708 PW_CACHE_ASYNC PrevWContext = NULL;
2709 ULONG i;
2710 ULONG chain_count = 0;
2711
2712 if(!(Cache->ReadProc)) return;
2713
2714 // walk through modified blocks
2715 while(Cache->WriteCount) {
2716 Lba = List[0] & ~(PSs-1);
2717 frame = Lba >> BFs;
2718 firstLba = frame << BFs;
2719// firstPos = WCacheGetSortedListIndex(Cache->WriteCount, List, Lba);
2720// lastPos = WCacheGetSortedListIndex(Cache->WriteCount, List, Lba+PSs);
2721 block_array = Cache->FrameList[frame].Frame;
2722 if(!block_array) {
2723 BrutePoint();
2724 continue;;
2725 }
2726 // queue modify request
2727 WCacheUpdatePacket(Cache, Context, &FirstWContext, &PrevWContext, block_array, firstLba,
2728 Lba, BSh, BS, PS, PSs, &ReadBytes, TRUE, ASYNC_STATE_NONE);
2729 // clear MODIFIED flag for queued blocks
2730 WCacheRemoveRangeFromList(List, &(Cache->WriteCount), Lba, PSs);
2731 Lba -= firstLba;
2732 for(i=0; i<PSs; i++) {
2733 WCacheClrModFlag(block_array, Lba+i);
2734 }
2735 chain_count++;
2736 // check queue size
2737 if(chain_count >= WCACHE_MAX_CHAIN) {
2738 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
2739 chain_count = 0;
2740 }
2741 }
2742 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
2743#ifdef DBG
2744#if 1
2745 // check consistency
2746 List = Cache->CachedBlocksList;
2747 for(i=0; i<Cache->BlockCount; i++) {
2748 Lba = List[i] /*& ~(PSs-1)*/;
2749 frame = Lba >> Cache->BlocksPerFrameSh;
2750 firstLba = frame << Cache->BlocksPerFrameSh;
2751 block_array = Cache->FrameList[frame].Frame;
2752 if(!block_array) {
2753 BrutePoint();
2754 }
2755 ASSERT(!WCacheGetModFlag(block_array, Lba-firstLba));
2756 }
2757#endif // 1
2758#endif // DBG
2759 return;
2760} // end WCacheFlushAllRW()
#define WCacheClrModFlag(block_array, i)
Definition: wcache_lib.cpp:819

Referenced by WCacheFlushAll__().

◆ WCacheFlushBlocks__()

OSSTATUS WCacheFlushBlocks__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  Lba,
IN ULONG  BCount 
)

Definition at line 2899 of file wcache_lib.cpp.

2905{
2907
2908 if(!(Cache->ReadProc)) return STATUS_INVALID_PARAMETER;
2909 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2910
2911 // check if we try to access beyond cached area
2912 if((Lba < Cache->FirstLba) ||
2913 (Lba+BCount-1 > Cache->LastLba)) {
2914 UDFPrint(("LBA %#x (%x) is beyond cacheable area\n", Lba, BCount));
2915 BrutePoint();
2917 goto EO_WCache_F;
2918 }
2919
2920 switch(Cache->Mode) {
2921 case WCACHE_MODE_RAM:
2922// WCacheFlushBlocksRW(Cache, Context);
2923// break;
2924 case WCACHE_MODE_ROM:
2925 case WCACHE_MODE_RW:
2926 status = WCacheFlushBlocksRW(Cache, Context, Lba, BCount);
2927 break;
2928 case WCACHE_MODE_R:
2930 break;
2931 }
2932EO_WCache_F:
2934 return status;
2935} // end WCacheFlushBlocks__()
OSSTATUS WCacheFlushBlocksRW(IN PW_CACHE Cache, IN PVOID Context, IN lba_t _Lba, IN ULONG BCount)

Referenced by UDFCommonDeviceControl(), UDFEjectReqWaiter(), UDFFlushLogicalVolume(), UDFUmount__(), and UDFUpdateLogicalVolInt().

◆ WCacheFlushBlocksRAM()

OSSTATUS __fastcall WCacheFlushBlocksRAM ( IN PW_CACHE  Cache,
IN PVOID  Context,
PW_CACHE_ENTRY  block_array,
lba_t List,
ULONG  firstPos,
ULONG  lastPos,
BOOLEAN  Purge 
)

Definition at line 1537 of file wcache_lib.cpp.

1546{
1547 ULONG frame;
1548 lba_t Lba;
1549 lba_t PrevLba;
1550 lba_t firstLba;
1551 PCHAR tmp_buff = NULL;
1552 ULONG n;
1553 ULONG BSh = Cache->BlockSizeSh;
1554 ULONG BS = Cache->BlockSize;
1555// ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
1556 ULONG PSs = Cache->PacketSize;
1557 SIZE_T _WrittenBytes;
1559
1560 frame = List[firstPos] >> Cache->BlocksPerFrameSh;
1561 firstLba = frame << Cache->BlocksPerFrameSh;
1562
1563 while(firstPos < lastPos) {
1564 // flush blocks
1565 ASSERT(Cache->FrameCount <= Cache->MaxFrames);
1566 Lba = List[firstPos];
1567 if(!WCacheGetModFlag(block_array, Lba - firstLba)) {
1568 // free memory
1569 if(Purge) {
1570 WCacheFreePacket(Cache, frame, block_array, Lba-firstLba, 1);
1571 }
1572 firstPos++;
1573 continue;
1574 }
1575 tmp_buff = Cache->tmp_buff;
1576 PrevLba = Lba;
1577 n=1;
1578 while((firstPos+n < lastPos) &&
1579 (List[firstPos+n] == PrevLba+1)) {
1580 PrevLba++;
1581 if(!WCacheGetModFlag(block_array, PrevLba - firstLba))
1582 break;
1583 DbgCopyMemory(tmp_buff + (n << BSh),
1584 (PVOID)WCacheSectorAddr(block_array, PrevLba - firstLba),
1585 BS);
1586 n++;
1587 if(n >= PSs)
1588 break;
1589 }
1590 if(n > 1) {
1591 DbgCopyMemory(tmp_buff,
1592 (PVOID)WCacheSectorAddr(block_array, Lba - firstLba),
1593 BS);
1594 } else {
1595 tmp_buff = (PCHAR)WCacheSectorAddr(block_array, Lba - firstLba);
1596 }
1597 // write sectors out
1598 status = Cache->WriteProc(Context, tmp_buff, n<<BSh, Lba, &_WrittenBytes, 0);
1599 if(!OS_SUCCESS(status)) {
1601 if(!OS_SUCCESS(status)) {
1602 BrutePoint();
1603 }
1604 }
1605 firstPos += n;
1606 if(Purge) {
1607 // free memory
1608 WCacheFreePacket(Cache, frame, block_array, Lba-firstLba, n);
1609 } else {
1610 // clear Modified flag
1611 ULONG i;
1612 Lba -= firstLba;
1613 for(i=0; i<n; i++) {
1614 WCacheClrModFlag(block_array, Lba+i);
1615 }
1616 }
1617 }
1618
1619 return status;
1620} // end WCacheFlushBlocksRAM()
GLdouble n
Definition: glext.h:7729

Referenced by WCacheCheckLimitsRAM(), WCacheFlushAllRAM(), WCachePurgeAllRAM(), and WCacheWriteBlocks__().

◆ WCacheFlushBlocksRW()

OSSTATUS WCacheFlushBlocksRW ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  _Lba,
IN ULONG  BCount 
)

Definition at line 2825 of file wcache_lib.cpp.

2831{
2832 ULONG frame;
2833 lba_t firstLba;
2834 lba_t* List = Cache->CachedModifiedBlocksList;
2835 lba_t Lba;
2836// ULONG firstPos;
2837// ULONG lastPos;
2838 ULONG BSh = Cache->BlockSizeSh;
2839 ULONG BS = Cache->BlockSize;
2840 ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
2841 ULONG PSs = Cache->PacketSize;
2842 ULONG BFs = Cache->BlocksPerFrameSh;
2843 PW_CACHE_ENTRY block_array;
2844// OSSTATUS status;
2846 PW_CACHE_ASYNC FirstWContext = NULL;
2847 PW_CACHE_ASYNC PrevWContext = NULL;
2848 ULONG i;
2849 ULONG chain_count = 0;
2850 lba_t lim;
2851
2852 if(!(Cache->ReadProc)) return STATUS_INVALID_PARAMETER;
2853
2854 // walk through modified blocks
2855 lim = (_Lba+BCount+PSs-1) & ~(PSs-1);
2856 for(Lba = _Lba & ~(PSs-1);Lba < lim ; Lba += PSs) {
2857 frame = Lba >> BFs;
2858 firstLba = frame << BFs;
2859// firstPos = WCacheGetSortedListIndex(Cache->WriteCount, List, Lba);
2860// lastPos = WCacheGetSortedListIndex(Cache->WriteCount, List, Lba+PSs);
2861 block_array = Cache->FrameList[frame].Frame;
2862 if(!block_array) {
2863 // not cached block may be requested for flush
2864 Lba += (1 << BFs) - PSs;
2865 continue;
2866 }
2867 // queue modify request
2868 WCacheUpdatePacket(Cache, Context, &FirstWContext, &PrevWContext, block_array, firstLba,
2869 Lba, BSh, BS, PS, PSs, &ReadBytes, TRUE, ASYNC_STATE_NONE);
2870 // clear MODIFIED flag for queued blocks
2871 WCacheRemoveRangeFromList(List, &(Cache->WriteCount), Lba, PSs);
2872 Lba -= firstLba;
2873 for(i=0; i<PSs; i++) {
2874 WCacheClrModFlag(block_array, Lba+i);
2875 }
2876 Lba += firstLba;
2877 chain_count++;
2878 // check queue size
2879 if(chain_count >= WCACHE_MAX_CHAIN) {
2880 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
2881 chain_count = 0;
2882 }
2883 }
2884 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
2885/*
2886 if(Cache->Mode != WCACHE_MODE_RAM)
2887 return STATUS_SUCCESS;
2888*/
2889
2890 return STATUS_SUCCESS;
2891} // end WCacheFlushBlocksRW()

Referenced by WCacheFlushBlocks__().

◆ WCacheFreeAsyncEntry()

VOID WCacheFreeAsyncEntry ( IN PW_CACHE  Cache,
PW_CACHE_ASYNC  WContext 
)

Definition at line 934 of file wcache_lib.cpp.

938{
939 DbgFreePool(WContext->Buffer);
940 MyFreePool__(WContext);
941} // end WCacheFreeAsyncEntry()

Referenced by WCacheUpdatePacketComplete().

◆ WCacheFreePacket()

VOID WCacheFreePacket ( IN PW_CACHE  Cache,
IN ULONG  frame,
IN PW_CACHE_ENTRY  block_array,
IN ULONG  offs,
IN ULONG  PSs 
)

Definition at line 1186 of file wcache_lib.cpp.

1194{
1195 ULONG i;
1196 // mark as non-cached & free pool
1197 for(i=0; i<PSs; i++, offs++) {
1198 if(WCacheSectorAddr(block_array,offs)) {
1199 WCacheFreeSector(frame, offs);
1200 }
1201 }
1202} // end WCacheFreePacket()

Referenced by WCacheCheckLimitsRW(), WCacheFlushBlocksRAM(), WCachePurgeAllRW(), and WCacheUpdatePacketComplete().

◆ WCacheGetMode__()

ULONG WCacheGetMode__ ( IN PW_CACHE  Cache)

Definition at line 3441 of file wcache_lib.cpp.

3444{
3445 return Cache->Mode;
3446} // end WCacheGetMode__()

◆ WCacheGetSortedListIndex()

ULONG WCacheGetSortedListIndex ( IN ULONG  BlockCount,
IN lba_t List,
IN lba_t  Lba 
)

Definition at line 449 of file wcache_lib.cpp.

454{
455 if(!BlockCount)
456 return 0;
457
458#if defined(_X86_) && defined(_MSC_VER) && !defined(__clang__)
459
460 __asm push ecx
461 __asm push ebx
462 __asm push edx
463 __asm push esi
464 __asm push edi
465// left = 0;
466// right = BlockCount - 1;
467// pos = 0;
468 __asm xor edx,edx // left
469 __asm mov ebx,BlockCount
470 __asm dec ebx // right
471 __asm xor esi,esi // pos
472 __asm mov edi,List // List
473 __asm mov ecx,Lba // Lba
474
475While_1:
476// while(left != right) {
477 __asm cmp edx,ebx
478 __asm jz EO_while_1
479
480// pos = (left + right) >> 1;
481 __asm lea esi,[ebx+edx]
482 __asm shr esi,1
483// if(List[pos] == Lba)
484// return pos;
485 __asm mov eax,[edi+esi*4]
486 __asm cmp eax,ecx
487 __asm jz EO_while_2
488
489// if(right - left == 1) {
490 __asm sub ebx,edx
491 __asm cmp ebx,1
492 __asm jne NO_r_sub_l_eq_1
493// if(List[pos+1] < Lba) <=> if(List[pos+1] >= Lba)
494// return (pos+2); <=> break;
495// break; <=> return (pos+2);
496 __asm cmp [edi+esi*4+4],ecx
497 __asm jae EO_while_1
498 __asm add esi,2
499 __asm jmp EO_while_2
500// }
501NO_r_sub_l_eq_1:
502// if(List[pos] < Lba) {
503 __asm cmp eax,ecx
504 __asm jae Update_r
505// left = pos;
506 __asm add ebx,edx
507 __asm mov edx,esi
508 __asm jmp While_1
509// } else {
510Update_r:
511// right = pos;
512 __asm mov ebx,esi
513 __asm jmp While_1
514// }
515// }
516EO_while_1:
517// if((List[pos] < Lba) && ((pos+1) <= BlockCount)) pos++;
518 __asm mov eax,[edi+esi*4]
519 __asm cmp eax,ecx
520 __asm jae EO_while_2
521 __asm inc esi
522 __asm cmp esi,BlockCount
523 __asm jbe EO_while_2
524 __asm dec esi
525EO_while_2:
526// return pos;
527 __asm mov eax,esi
528
529 __asm pop edi
530 __asm pop esi
531 __asm pop edx
532 __asm pop ebx
533 __asm pop ecx
534
535#else // NO X86 optimization , use generic C/C++
536
537 ULONG pos;
538 ULONG left;
539 ULONG right;
540
541 if(!BlockCount)
542 return 0;
543
544 left = 0;
545 right = BlockCount - 1;
546 pos = 0;
547 while(left != right) {
548 pos = (left + right) >> 1;
549 if(List[pos] == Lba)
550 return pos;
551 if(right - left == 1) {
552 if(List[pos+1] < Lba)
553 return (pos+2);
554 break;
555 }
556 if(List[pos] < Lba) {
557 left = pos;
558 } else {
559 right = pos;
560 }
561 }
562 if((List[pos] < Lba) && ((pos+1) <= BlockCount)) pos++;
563
564 return pos;
565
566#endif // _X86_
567
568}
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
static void xor(unsigned char *dst, const unsigned char *a, const unsigned char *b, const int count)
Definition: crypt_des.c:251
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
#define cmp(status, error)
Definition: error.c:114
static calc_node_t * pop(void)
Definition: rpn_ieee.c:90
static void push(calc_node_t *op)
Definition: rpn_ieee.c:113
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl ebx
Definition: synth_sse3d.h:83
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw edi esi edx edi
Definition: synth_sse3d.h:185
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esi
Definition: synth_sse3d.h:103
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx
Definition: synth_sse3d.h:87

Referenced by WCacheCheckLimitsR(), WCacheCheckLimitsRAM(), WCacheCheckLimitsRW(), WCacheDiscardBlocks__(), WCacheFlushAllRAM(), WCacheInsertItemToList(), WCacheInsertRangeToList(), WCachePurgeAllRAM(), WCacheRemoveItemFromList(), WCacheRemoveRangeFromList(), and WCacheWriteBlocks__().

◆ WCacheGetWriteBlockCount__()

ULONG WCacheGetWriteBlockCount__ ( IN PW_CACHE  Cache)

Definition at line 3455 of file wcache_lib.cpp.

3458{
3459 return Cache->WriteCount;
3460} // end WCacheGetWriteBlockCount__()

Referenced by UDFRecordVAT(), and UDFUmount__().

◆ WCacheInit__()

OSSTATUS WCacheInit__ ( IN PW_CACHE  Cache,
IN ULONG  MaxFrames,
IN ULONG  MaxBlocks,
IN SIZE_T  MaxBytesToRead,
IN ULONG  PacketSizeSh,
IN ULONG  BlockSizeSh,
IN ULONG  BlocksPerFrameSh,
IN lba_t  FirstLba,
IN lba_t  LastLba,
IN ULONG  Mode,
IN ULONG  Flags,
IN ULONG  FramesToKeepFree,
IN PWRITE_BLOCK  WriteProc,
IN PREAD_BLOCK  ReadProc,
IN PWRITE_BLOCK_ASYNC  WriteProcAsync,
IN PREAD_BLOCK_ASYNC  ReadProcAsync,
IN PCHECK_BLOCK  CheckUsedProc,
IN PUPDATE_RELOC  UpdateRelocProc,
IN PWC_ERROR_HANDLER  ErrorHandlerProc 
)

Definition at line 116 of file wcache_lib.cpp.

171{
172 ULONG l1, l2, l3;
173 ULONG PacketSize = (1) << PacketSizeSh;
174 ULONG BlockSize = (1) << BlockSizeSh;
175 ULONG BlocksPerFrame = (1) << BlocksPerFrameSh;
177 LARGE_INTEGER rseed;
178 ULONG res_init_flags = 0;
179
180#define WCLOCK_RES 1
181
182 _SEH2_TRY {
183 // check input parameters
184 if(Mode == WCACHE_MODE_R) {
185 UDFPrint(("Disable Async-Write for WORM media\n"));
186 WriteProcAsync = NULL;
187 }
188 if((MaxBlocks % PacketSize) || !MaxBlocks) {
189 UDFPrint(("Total number of sectors must be packet-size-aligned\n"));
191 }
192 if(BlocksPerFrame % PacketSize) {
193 UDFPrint(("Number of sectors per Frame must be packet-size-aligned\n"));
195 }
196 if(!ReadProc) {
197 UDFPrint(("Read routine pointer must be valid\n"));
199 }
200 if(FirstLba >= LastLba) {
201 UDFPrint(("Invalid cached area parameters: (%x - %x)\n",FirstLba, LastLba));
203 }
204 if(!MaxFrames) {
205 UDFPrint(("Total frame number must be non-zero\n",FirstLba, LastLba));
207 }
208 if(Mode > WCACHE_MODE_MAX) {
209 UDFPrint(("Invalid media mode. Should be 0-%x\n",WCACHE_MODE_MAX));
211 }
212 if(FramesToKeepFree >= MaxFrames/2) {
213 UDFPrint(("Invalid FramesToKeepFree (%x). Should be Less or equal to MaxFrames/2 (%x)\n", FramesToKeepFree, MaxFrames/2));
215 }
216 // check 'features'
217 if(!WriteProc) {
218 UDFPrint(("Write routine not specified\n"));
219 UDFPrint(("Read-only mode enabled\n"));
220 }
221 MaxBlocks = max(MaxBlocks, BlocksPerFrame*3);
222 // initialize required structures
223 // we'll align structure size on system page size to
224 // avoid system crashes caused by pool fragmentation
225 if(!(Cache->FrameList =
226 (PW_CACHE_FRAME)MyAllocatePoolTag__(NonPagedPool, l1 = (((LastLba >> BlocksPerFrameSh)+1)*sizeof(W_CACHE_FRAME)), MEM_WCFRM_TAG) )) {
227 UDFPrint(("Cache init err 1\n"));
229 }
230 if(!(Cache->CachedBlocksList =
231 (PULONG)MyAllocatePoolTag__(NonPagedPool, l2 = ((MaxBlocks+2)*sizeof(lba_t)), MEM_WCFRM_TAG) )) {
232 UDFPrint(("Cache init err 2\n"));
234 }
235 if(!(Cache->CachedModifiedBlocksList =
237 UDFPrint(("Cache init err 3\n"));
239 }
240 if(!(Cache->CachedFramesList =
241 (PULONG)MyAllocatePoolTag__(NonPagedPool, l3 = ((MaxFrames+2)*sizeof(lba_t)), MEM_WCFRM_TAG) )) {
242 UDFPrint(("Cache init err 4\n"));
244 }
245 RtlZeroMemory(Cache->FrameList, l1);
246 RtlZeroMemory(Cache->CachedBlocksList, l2);
247 RtlZeroMemory(Cache->CachedModifiedBlocksList, l2);
248 RtlZeroMemory(Cache->CachedFramesList, l3);
249 // remember all useful parameters
250 Cache->BlocksPerFrame = BlocksPerFrame;
251 Cache->BlocksPerFrameSh = BlocksPerFrameSh;
252 Cache->BlockCount = 0;
253 Cache->MaxBlocks = MaxBlocks;
254 Cache->MaxBytesToRead = MaxBytesToRead;
255 Cache->FrameCount = 0;
256 Cache->MaxFrames = MaxFrames;
257 Cache->PacketSize = PacketSize;
258 Cache->PacketSizeSh = PacketSizeSh;
259 Cache->BlockSize = BlockSize;
260 Cache->BlockSizeSh = BlockSizeSh;
261 Cache->WriteCount = 0;
262 Cache->FirstLba = FirstLba;
263 Cache->LastLba = LastLba;
264 Cache->Mode = Mode;
265
267 return RC;
268 }
269
270 Cache->FramesToKeepFree = FramesToKeepFree;
271 Cache->WriteProc = WriteProc;
272 Cache->ReadProc = ReadProc;
273 Cache->WriteProcAsync = WriteProcAsync;
274 Cache->ReadProcAsync = ReadProcAsync;
275 Cache->CheckUsedProc = CheckUsedProc;
276 Cache->UpdateRelocProc = UpdateRelocProc;
277 Cache->ErrorHandlerProc = ErrorHandlerProc;
278 // init permanent tmp buffers
279 if(!(Cache->tmp_buff =
281 UDFPrint(("Cache init err 5.W\n"));
283 }
284 if(!(Cache->tmp_buff_r =
286 UDFPrint(("Cache init err 5.R\n"));
288 }
289 if(!(Cache->reloc_tab =
291 UDFPrint(("Cache init err 6\n"));
293 }
294 if(!OS_SUCCESS(RC = ExInitializeResourceLite(&(Cache->WCacheLock)))) {
295 UDFPrint(("Cache init err (res)\n"));
296 try_return(RC);
297 }
298 res_init_flags |= WCLOCK_RES;
300 WCache_random = rseed.LowPart;
301
302try_exit: NOTHING;
303
304 } _SEH2_FINALLY {
305
306 if(!OS_SUCCESS(RC)) {
307 if(res_init_flags & WCLOCK_RES)
308 ExDeleteResourceLite(&(Cache->WCacheLock));
309 if(Cache->FrameList)
310 MyFreePool__(Cache->FrameList);
311 if(Cache->CachedBlocksList)
312 MyFreePool__(Cache->CachedBlocksList);
313 if(Cache->CachedModifiedBlocksList)
314 MyFreePool__(Cache->CachedModifiedBlocksList);
315 if(Cache->CachedFramesList)
316 MyFreePool__(Cache->CachedFramesList);
317 if(Cache->tmp_buff_r)
318 MyFreePool__(Cache->tmp_buff_r);
319 if(Cache->tmp_buff)
320 MyFreePool__(Cache->tmp_buff);
321 if(Cache->reloc_tab)
322 MyFreePool__(Cache->reloc_tab);
323 RtlZeroMemory(Cache, sizeof(W_CACHE));
324 } else {
325 Cache->Tag = 0xCAC11E00;
326 }
327
328 } _SEH2_END;
329
330 return RC;
331} // end WCacheInit__()
#define try_return(S)
Definition: cdprocs.h:2179
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
#define _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_ ULONG Mode
Definition: hubbusif.h:303
#define NOTHING
Definition: input_list.c:10
#define max(a, b)
Definition: svc.c:63
ULONG LowPart
Definition: typedefs.h:106
ULONG WCache_random
Definition: wcache_lib.cpp:90
#define MEM_WCFRM_TAG
Definition: wcache_lib.cpp:55
#define WCLOCK_RES
#define WCACHE_MODE_MAX
Definition: wcache_lib.h:129
_In_ USHORT PacketSize
Definition: iofuncs.h:1058

Referenced by UDFMountVolume(), and UDFVerifyVolume().

◆ WCacheInitFrame()

PW_CACHE_ENTRY __fastcall WCacheInitFrame ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN ULONG  frame 
)

Definition at line 731 of file wcache_lib.cpp.

736{
737 PW_CACHE_ENTRY block_array;
738 ULONG l;
739#ifdef DBG
740 ULONG old_count = Cache->FrameCount;
741#endif //DBG
742
743 // We are about to add new cache frame.
744 // Thus check if we have enough free entries and
745 // flush unused ones if it is neccessary.
746 if(Cache->FrameCount >= Cache->MaxFrames) {
747 BrutePoint();
748 WCacheCheckLimits(Cache, Context, frame << Cache->BlocksPerFrameSh, Cache->PacketSize*2);
749 }
750 ASSERT(Cache->FrameCount < Cache->MaxFrames);
751 block_array = (PW_CACHE_ENTRY)MyAllocatePoolTag__(NonPagedPool, l = sizeof(W_CACHE_ENTRY) << Cache->BlocksPerFrameSh, MEM_WCFRM_TAG);
752 Cache->FrameList[frame].Frame = block_array;
753
754 // Keep history !!!
755 //Cache->FrameList[frame].UpdateCount = 0;
756 //Cache->FrameList[frame].AccessCount = 0;
757
758 if(block_array) {
759 ASSERT((ULONG_PTR)block_array > 0x1000);
760 WCacheInsertItemToList(Cache->CachedFramesList, &(Cache->FrameCount), frame);
761 RtlZeroMemory(block_array, l);
762 } else {
763 BrutePoint();
764 }
765 ASSERT(Cache->FrameCount <= Cache->MaxFrames);
766#ifdef DBG
767 ASSERT(old_count < Cache->FrameCount);
768#endif //DBG
769 return block_array;
770} // end WCacheInitFrame()
r l[0]
Definition: byte_order.h:168
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _W_CACHE_ENTRY * PW_CACHE_ENTRY

Referenced by WCacheDirect__(), WCachePreReadPacket__(), WCacheReadBlocks__(), and WCacheWriteBlocks__().

◆ WCacheInsertItemToList()

VOID __fastcall WCacheInsertItemToList ( IN lba_t List,
IN PULONG  BlockCount,
IN lba_t  Lba 
)

Definition at line 637 of file wcache_lib.cpp.

642{
643 ULONG firstPos = WCacheGetSortedListIndex(*BlockCount, List, Lba+1);
644 if(firstPos && (List[firstPos-1] == Lba))
645 return;
646
647 // move list tail
648 if(*BlockCount) {
649#ifdef WCACHE_BOUND_CHECKS
650 MyCheckArray(List, firstPos+1+(*BlockCount)-firstPos-1);
651#endif //WCACHE_BOUND_CHECKS
652// DbgMoveMemory(&(List[firstPos+1]), &(List[firstPos]), ((*BlockCount) - firstPos)*sizeof(ULONG));
653 DbgMoveMemory(&(List[firstPos+1]), &(List[firstPos]), ((*BlockCount) - firstPos) * sizeof(ULONG));
654 }
655#ifdef WCACHE_BOUND_CHECKS
656 MyCheckArray(List, firstPos);
657#endif //WCACHE_BOUND_CHECKS
658 List[firstPos] = Lba;
659 (*BlockCount) ++;
660} // end WCacheInsertItemToList()
#define DbgMoveMemory
Definition: env_spec_w32.h:329
#define MyCheckArray(base, index)
Definition: mem_tools.h:310

Referenced by WCacheDirect__(), and WCacheInitFrame().

◆ WCacheInsertRangeToList()

VOID __fastcall WCacheInsertRangeToList ( IN lba_t List,
IN PULONG  BlockCount,
IN lba_t  Lba,
IN ULONG  BCount 
)

Definition at line 588 of file wcache_lib.cpp.

594{
595 if(!BCount)
596 return;
597
598 ASSERT(!(BCount & 0x80000000));
599
600 ULONG firstPos = WCacheGetSortedListIndex(*BlockCount, List, Lba);
601 ULONG lastPos = WCacheGetSortedListIndex(*BlockCount, List, Lba+BCount);
602 ULONG offs = firstPos + BCount - lastPos;
603
604 if(offs) {
605 // move list tail
606// ASSERT(lastPos+offs + ((*BlockCount) - lastPos) <= qq);
607 if(*BlockCount) {
608#ifdef WCACHE_BOUND_CHECKS
609 MyCheckArray(List, lastPos+offs+(*BlockCount)-lastPos-1);
610#endif //WCACHE_BOUND_CHECKS
611 DbgMoveMemory(&(List[lastPos+offs]), &(List[lastPos]), ((*BlockCount) - lastPos) * sizeof(ULONG));
612 }
613 lastPos += offs;
614 for(; firstPos<lastPos; firstPos++) {
615#ifdef WCACHE_BOUND_CHECKS
616 MyCheckArray(List, firstPos);
617#endif //WCACHE_BOUND_CHECKS
618 List[firstPos] = Lba;
619 Lba++;
620 }
621 (*BlockCount) += offs;
622 }
623} // end WCacheInsertRangeToList()

Referenced by WCachePreReadPacket__(), WCacheReadBlocks__(), and WCacheWriteBlocks__().

◆ WCacheIsCached__()

BOOLEAN WCacheIsCached__ ( IN PW_CACHE  Cache,
IN lba_t  Lba,
IN ULONG  BCount 
)

WCacheGetBadFlag(block_array, i)

(Cache->CheckUsedProc(Context, Lba) & WCACHE_BLOCK_BAD)

Definition at line 3127 of file wcache_lib.cpp.

3132{
3133 ULONG frame;
3134 ULONG i;
3135 PW_CACHE_ENTRY block_array;
3136
3137 // check if we try to access beyond cached area
3138 if((Lba < Cache->FirstLba) ||
3139 (Lba + BCount - 1 > Cache->LastLba)) {
3140 return FALSE;
3141 }
3142
3143 frame = Lba >> Cache->BlocksPerFrameSh;
3144 i = Lba - (frame << Cache->BlocksPerFrameSh);
3145
3146 block_array = Cache->FrameList[frame].Frame;
3147 if(!block_array) {
3148 return FALSE;
3149 }
3150
3151 while(BCount) {
3152 if(i >= Cache->BlocksPerFrame) {
3153 frame++;
3154 block_array = Cache->FrameList[frame].Frame;
3155 i -= Cache->BlocksPerFrame;
3156 }
3157 if(!block_array) {
3158 return FALSE;
3159 }
3160 // 'read' cached extent (if any)
3161 while(BCount &&
3162 (i < Cache->BlocksPerFrame) &&
3163 WCacheSectorAddr(block_array, i) &&
3166 TRUE ) {
3167 i++;
3168 BCount--;
3169 Lba++;
3170 }
3171 if(BCount &&
3172 (i < Cache->BlocksPerFrame) /*&&
3173 (!WCacheSectorAddr(block_array, i))*/ ) {
3174 return FALSE;
3175 }
3176 }
3177 return TRUE;
3178} // end WCacheIsCached__()

◆ WCacheIsInitialized__()

BOOLEAN WCacheIsInitialized__ ( IN PW_CACHE  Cache)

Definition at line 2817 of file wcache_lib.cpp.

2820{
2821 return (Cache->ReadProc != NULL);
2822} // end WCacheIsInitialized__()

Referenced by UDFVerifyVolume(), and UDFWriteInSector().

◆ WCachePreReadPacket__()

OSSTATUS WCachePreReadPacket__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN lba_t  Lba 
)

Definition at line 1856 of file wcache_lib.cpp.

1861{
1862 ULONG frame;
1864 PW_CACHE_ENTRY block_array;
1865 ULONG BSh = Cache->BlockSizeSh;
1866 ULONG BS = Cache->BlockSize;
1867 PCHAR addr;
1868 SIZE_T _ReadBytes;
1869 ULONG PS = Cache->PacketSize; // (in blocks)
1870 ULONG BCount = PS;
1871 ULONG i, n, err_count;
1872 BOOLEAN sector_added = FALSE;
1873 ULONG block_type;
1874 BOOLEAN zero = FALSE;//TRUE;
1875/*
1876 ULONG first_zero=0, last_zero=0;
1877 BOOLEAN count_first_zero = TRUE;
1878*/
1879
1880 Lba &= ~(PS-1);
1881 frame = Lba >> Cache->BlocksPerFrameSh;
1882 i = Lba - (frame << Cache->BlocksPerFrameSh);
1883
1884 // assume successful operation
1885 block_array = Cache->FrameList[frame].Frame;
1886 if(!block_array) {
1887 ASSERT(Cache->FrameCount < Cache->MaxFrames);
1888 block_array = WCacheInitFrame(Cache, Context, frame);
1889 if(!block_array)
1891 }
1892
1893 // skip cached extent (if any)
1894 n=0;
1895 while((n < BCount) &&
1896 (n < Cache->BlocksPerFrame)) {
1897
1898 addr = (PCHAR)WCacheSectorAddr(block_array, i+n);
1899 block_type = Cache->CheckUsedProc(Context, Lba+n);
1900 if(/*WCacheGetBadFlag(block_array,i+n)*/
1901 block_type & WCACHE_BLOCK_BAD) {
1902 // bad packet. no pre-read
1904 }
1905 if(!(block_type & WCACHE_BLOCK_ZERO)) {
1906 zero = FALSE;
1907 //count_first_zero = FALSE;
1908 //last_zero = 0;
1909 if(!addr) {
1910 // sector is not cached, stop search
1911 break;
1912 }
1913 } else {
1914/*
1915 if(count_first_zero) {
1916 first_zero++;
1917 }
1918 last_zero++;
1919*/
1920 }
1921 n++;
1922 }
1923 // do nothing if all sectors are already cached
1924 if(n < BCount) {
1925
1926 // read whole packet
1927 if(!zero) {
1928 status = Cache->ReadProc(Context, Cache->tmp_buff_r, PS<<BSh, Lba, &_ReadBytes, PH_TMP_BUFFER);
1929 if(!OS_SUCCESS(status)) {
1931 }
1932 } else {
1934 //RtlZeroMemory(Cache->tmp_buff_r, PS<<BSh);
1935 _ReadBytes = PS<<BSh;
1936 }
1937 if(OS_SUCCESS(status)) {
1938 // and now we'll copy them to cache
1939 for(n=0; n<BCount; n++, i++) {
1940 if(WCacheSectorAddr(block_array,i)) {
1941 continue;
1942 }
1944 if(!addr) {
1945 BrutePoint();
1946 break;
1947 }
1948 sector_added = TRUE;
1949 if(!zero) {
1950 DbgCopyMemory(addr, Cache->tmp_buff_r+(n<<BSh), BS);
1951 } else {
1953 }
1954 Cache->FrameList[frame].BlockCount++;
1955 }
1956 } else {
1957 // read sectors one by one and copy them to cache
1958 // unreadable sectors will be treated as zero-filled
1959 err_count = 0;
1960 for(n=0; n<BCount; n++, i++) {
1961 if(WCacheSectorAddr(block_array,i)) {
1962 continue;
1963 }
1965 if(!addr) {
1966 BrutePoint();
1967 break;
1968 }
1969 sector_added = TRUE;
1970 status = Cache->ReadProc(Context, Cache->tmp_buff_r, BS, Lba+n, &_ReadBytes, PH_TMP_BUFFER);
1971 if(!OS_SUCCESS(status)) {
1972 status = WCacheRaiseIoError(Cache, Context, status, Lba+n, 1, Cache->tmp_buff_r, WCACHE_R_OP, NULL);
1973 if(!OS_SUCCESS(status)) {
1974 err_count++;
1975 }
1976 }
1977 if(!zero && OS_SUCCESS(status)) {
1978 DbgCopyMemory(addr, Cache->tmp_buff_r, BS);
1979 } else
1980 if(Cache->RememberBB) {
1982 /*
1983 if(!OS_SUCCESS(status)) {
1984 WCacheSetBadFlag(block_array,i);
1985 }
1986 */
1987 }
1988 Cache->FrameList[frame].BlockCount++;
1989 if(err_count >= 2) {
1990 break;
1991 }
1992 }
1993// _ReadBytes = n<<BSh;
1994 }
1995 }
1996
1997 // we know the number of unread sectors if an error occured
1998 // so we can need to update BlockCount
1999 // return number of read bytes
2000 if(sector_added)
2001 WCacheInsertRangeToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba, n);
2002
2003 return status;
2004} // end WCachePreReadPacket__()
int zero
Definition: sehframes.cpp:29
VOID __fastcall WCacheInsertRangeToList(IN lba_t *List, IN PULONG BlockCount, IN lba_t Lba, IN ULONG BCount)
Definition: wcache_lib.cpp:588
#define WCACHE_R_OP
Definition: wcache_lib.h:71

Referenced by WCacheReadBlocks__().

◆ WCachePurgeAll__()

VOID WCachePurgeAll__ ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 2590 of file wcache_lib.cpp.

2593{
2594 if(!(Cache->ReadProc)) return;
2595 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2596
2597 switch(Cache->Mode) {
2598 case WCACHE_MODE_RAM:
2600 break;
2601 case WCACHE_MODE_ROM:
2602 case WCACHE_MODE_RW:
2604 break;
2605 case WCACHE_MODE_R:
2607 break;
2608 }
2609
2611 return;
2612} // end WCachePurgeAll__()
OSSTATUS __fastcall WCachePurgeAllRAM(IN PW_CACHE Cache, IN PVOID Context)
VOID __fastcall WCachePurgeAllRW(IN PW_CACHE Cache, IN PVOID Context)

Referenced by UDFFindAnchor().

◆ WCachePurgeAllR()

VOID __fastcall WCachePurgeAllR ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 3312 of file wcache_lib.cpp.

3315{
3316 ULONG frame;
3317 lba_t firstLba;
3318 lba_t* List = Cache->CachedBlocksList;
3319 lba_t Lba;
3320 PCHAR tmp_buff = Cache->tmp_buff;
3321 ULONG BSh = Cache->BlockSizeSh;
3322 ULONG BS = Cache->BlockSize;
3323// ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
3324// ULONG PSs = Cache->PacketSize;
3325 PW_CACHE_ENTRY block_array;
3326 BOOLEAN mod;
3329 ULONG MaxReloc = Cache->PacketSize;
3330 PULONG reloc_tab = Cache->reloc_tab;
3331 ULONG RelocCount = 0;
3332 BOOLEAN IncompletePacket;
3333 ULONG i=0;
3334 ULONG PacketTail;
3335
3336 while(Cache->WriteCount < Cache->BlockCount) {
3337
3338 Lba = List[i];
3339 frame = Lba >> Cache->BlocksPerFrameSh;
3340 firstLba = frame << Cache->BlocksPerFrameSh;
3341 block_array = Cache->FrameList[frame].Frame;
3342 if(!block_array) {
3343 BrutePoint();
3344 return;
3345 }
3346 // check if modified
3347 mod = WCacheGetModFlag(block_array, Lba - firstLba);
3348 // just discard
3349 if(!mod || !(Cache->CheckUsedProc(Context, Lba) & WCACHE_BLOCK_USED)) {
3350 // mark as non-cached & free pool
3351 if(WCacheSectorAddr(block_array,Lba-firstLba)) {
3352 WCacheRemoveItemFromList(List, &(Cache->BlockCount), Lba);
3353 if(mod)
3354 WCacheRemoveItemFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3355 // mark as non-cached & free pool
3356 WCacheFreeSector(frame, Lba-firstLba);
3357 // check if frame is empty
3358 if(!Cache->FrameList[frame].BlockCount) {
3360 }
3361 } else {
3362 BrutePoint();
3363 }
3364 } else {
3365 i++;
3366 }
3367 }
3368
3369 PacketTail = Cache->WriteCount & (MaxReloc-1);
3370 IncompletePacket = (Cache->WriteCount >= MaxReloc) ? FALSE : TRUE;
3371
3372 // remove(flush) packet
3373 while((Cache->WriteCount > PacketTail) || (Cache->WriteCount && IncompletePacket)) {
3374
3375 Lba = List[0];
3376 frame = Lba >> Cache->BlocksPerFrameSh;
3377 firstLba = frame << Cache->BlocksPerFrameSh;
3378 block_array = Cache->FrameList[frame].Frame;
3379 if(!block_array) {
3380 BrutePoint();
3381 return;
3382 }
3383 // check if modified
3384 mod = WCacheGetModFlag(block_array, Lba - firstLba);
3385 // pack/reloc/write
3386 if(mod) {
3387 DbgCopyMemory(tmp_buff + (RelocCount << BSh),
3388 (PVOID)WCacheSectorAddr(block_array, Lba-firstLba),
3389 BS);
3390 reloc_tab[RelocCount] = Lba;
3391 RelocCount++;
3392 // write packet
3393 if((RelocCount >= MaxReloc) || (Cache->BlockCount == 1)) {
3394// status = Cache->WriteProcAsync(Context, tmp_buff, PS, Lba, &ReadBytes, FALSE);
3395 Cache->UpdateRelocProc(Context, NULL, reloc_tab, RelocCount);
3396 status = Cache->WriteProc(Context, tmp_buff, RelocCount<<BSh, NULL, &ReadBytes, 0);
3397 if(!OS_SUCCESS(status)) {
3398 status = WCacheRaiseIoError(Cache, Context, status, NULL, RelocCount, tmp_buff, WCACHE_W_OP, NULL);
3399 }
3400 RelocCount = 0;
3401 }
3402 WCacheRemoveItemFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba);
3403 } else {
3404 BrutePoint();
3405 }
3406 // mark as non-cached & free pool
3407 if(WCacheSectorAddr(block_array,Lba-firstLba)) {
3408 WCacheRemoveItemFromList(List, &(Cache->BlockCount), Lba);
3409 // mark as non-cached & free pool
3410 WCacheFreeSector(frame, Lba-firstLba);
3411 // check if frame is empty
3412 if(!Cache->FrameList[frame].BlockCount) {
3414 }
3415 } else {
3416 BrutePoint();
3417 }
3418 }
3419} // end WCachePurgeAllR()

Referenced by WCacheFlushAll__(), and WCachePurgeAll__().

◆ WCachePurgeAllRAM()

OSSTATUS __fastcall WCachePurgeAllRAM ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 1762 of file wcache_lib.cpp.

1766{
1767 ULONG frame;
1768 lba_t firstLba;
1769 lba_t* List = Cache->CachedBlocksList;
1770 lba_t lastLba;
1771 ULONG firstPos;
1772 ULONG lastPos;
1773 PW_CACHE_ENTRY block_array;
1774// OSSTATUS status;
1775
1776 // remove(flush) some frames
1777 while(Cache->FrameCount) {
1778
1779 frame = Cache->CachedFramesList[0];
1780
1781 firstLba = frame << Cache->BlocksPerFrameSh;
1782 lastLba = firstLba + Cache->BlocksPerFrame;
1783 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, firstLba);
1784 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, lastLba);
1785 block_array = Cache->FrameList[frame].Frame;
1786
1787 if(!block_array) {
1788 UDFPrint(("Hmm...\n"));
1789 BrutePoint();
1791 }
1792 WCacheFlushBlocksRAM(Cache, Context, block_array, List, firstPos, lastPos, TRUE);
1793
1794 WCacheRemoveRangeFromList(List, &(Cache->BlockCount), firstLba, Cache->BlocksPerFrame);
1795 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), firstLba, Cache->BlocksPerFrame);
1797 }
1798
1799 ASSERT(!Cache->FrameCount);
1800 ASSERT(!Cache->BlockCount);
1801 return STATUS_SUCCESS;
1802} // end WCachePurgeAllRAM()

Referenced by WCachePurgeAll__().

◆ WCachePurgeAllRW()

VOID __fastcall WCachePurgeAllRW ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 2622 of file wcache_lib.cpp.

2625{
2626 ULONG frame;
2627 lba_t firstLba;
2628 lba_t* List = Cache->CachedBlocksList;
2629 lba_t Lba;
2630// ULONG firstPos;
2631// ULONG lastPos;
2632 ULONG BSh = Cache->BlockSizeSh;
2633 ULONG BS = Cache->BlockSize;
2634 ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
2635 ULONG PSs = Cache->PacketSize;
2636 PW_CACHE_ENTRY block_array;
2637// OSSTATUS status;
2639 PW_CACHE_ASYNC FirstWContext = NULL;
2640 PW_CACHE_ASYNC PrevWContext = NULL;
2641 ULONG chain_count = 0;
2642
2643 if(!(Cache->ReadProc)) return;
2644
2645 while(Cache->BlockCount) {
2646 Lba = List[0] & ~(PSs-1);
2647 frame = Lba >> Cache->BlocksPerFrameSh;
2648 firstLba = frame << Cache->BlocksPerFrameSh;
2649// firstPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba);
2650// lastPos = WCacheGetSortedListIndex(Cache->BlockCount, List, Lba+PSs);
2651 block_array = Cache->FrameList[frame].Frame;
2652 if(!block_array) {
2653 BrutePoint();
2654 return;
2655 }
2656
2657 WCacheUpdatePacket(Cache, Context, &FirstWContext, &PrevWContext, block_array, firstLba,
2658 Lba, BSh, BS, PS, PSs, &ReadBytes, TRUE, ASYNC_STATE_NONE);
2659
2660 // free memory
2661 WCacheFreePacket(Cache, frame, block_array, Lba-firstLba, PSs);
2662
2663 WCacheRemoveRangeFromList(List, &(Cache->BlockCount), Lba, PSs);
2664 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba, PSs);
2665 // check if frame is empty
2666 if(!(Cache->FrameList[frame].BlockCount)) {
2668 } else {
2669 ASSERT(Cache->FrameList[frame].Frame);
2670 }
2671 chain_count++;
2672 if(chain_count >= WCACHE_MAX_CHAIN) {
2673 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext, FALSE);
2674 chain_count = 0;
2675 }
2676 }
2677 WCacheUpdatePacketComplete(Cache, Context, &FirstWContext, &PrevWContext);
2678 return;
2679} // end WCachePurgeAllRW()

Referenced by WCachePurgeAll__().

◆ WCacheRaiseIoError()

OSSTATUS WCacheRaiseIoError ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN OSSTATUS  Status,
IN ULONG  Lba,
IN ULONG  BCount,
IN PVOID  Buffer,
IN BOOLEAN  ReadOp,
IN PBOOLEAN  Retry 
)

Definition at line 946 of file wcache_lib.cpp.

956{
957 if(!Cache->ErrorHandlerProc)
958 return Status;
959
961
963 ec.Status = Status;
964 ec.ReadWrite.Lba = Lba;
965 ec.ReadWrite.BCount = BCount;
966 ec.ReadWrite.Buffer = Buffer;
967 Status = Cache->ErrorHandlerProc(Context, &ec);
968 if(Retry)
969 (*Retry) = ec.Retry;
970
971 return Status;
972
973} // end WCacheRaiseIoError()
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
struct _WCACHE_ERROR_CONTEXT::@955::@957 ReadWrite
#define WCACHE_ERROR_WRITE
Definition: wcache_lib.h:67
#define WCACHE_ERROR_READ
Definition: wcache_lib.h:66

Referenced by WCacheCheckLimitsR(), WCacheFlushBlocksRAM(), WCachePreReadPacket__(), WCachePurgeAllR(), WCacheReadBlocks__(), WCacheUpdatePacket(), and WCacheWriteBlocks__().

◆ WCacheRandom()

LONGLONG WCacheRandom ( VOID  )

Definition at line 339 of file wcache_lib.cpp.

340{
341 WCache_random = (WCache_random * 0x8088405 + 1);
342 return WCache_random;
343} // end WCacheRandom()

Referenced by WCacheFindFrameToRelease(), WCacheFindLbaToRelease(), and WCacheFindModifiedLbaToRelease().

◆ WCacheReadBlocks__()

OSSTATUS WCacheReadBlocks__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN PCHAR  Buffer,
IN lba_t  Lba,
IN ULONG  BCount,
OUT PSIZE_T  ReadBytes,
IN BOOLEAN  CachedOnly 
)

Definition at line 2012 of file wcache_lib.cpp.

2022{
2023 ULONG frame;
2024 ULONG i, saved_i, saved_BC = BCount, n;
2026 PW_CACHE_ENTRY block_array;
2027 ULONG BSh = Cache->BlockSizeSh;
2028 SIZE_T BS = Cache->BlockSize;
2029 PCHAR addr;
2030 ULONG to_read, saved_to_read;
2031// PCHAR saved_buff = Buffer;
2032 SIZE_T _ReadBytes;
2033 ULONG PS = Cache->PacketSize;
2034 ULONG MaxR = Cache->MaxBytesToRead;
2035 ULONG PacketMask = PS-1; // here we assume that Packet Size value is 2^n
2036 ULONG d;
2037 ULONG block_type;
2038
2039 WcPrint(("WC:R %x (%x)\n", Lba, BCount));
2040
2041 (*ReadBytes) = 0;
2042 // check if we try to read too much data
2043 if(BCount >= Cache->MaxBlocks) {
2044 i = 0;
2045 if(CachedOnly) {
2047 goto EO_WCache_R2;
2048 }
2049 while(TRUE) {
2050 status = WCacheReadBlocks__(Cache, Context, Buffer + (i<<BSh), Lba, PS, &_ReadBytes, FALSE);
2051 (*ReadBytes) += _ReadBytes;
2052 if(!OS_SUCCESS(status) || (BCount <= PS)) break;
2053 BCount -= PS;
2054 Lba += PS;
2055 i += PS;
2056 }
2057 return status;
2058 }
2059 // check if we try to access beyond cached area
2060 if((Lba < Cache->FirstLba) ||
2061 (Lba + BCount - 1 > Cache->LastLba)) {
2062 status = Cache->ReadProc(Context, Buffer, BCount, Lba, ReadBytes, 0);
2063 if(!OS_SUCCESS(status)) {
2065 }
2066 return status;
2067 }
2068 if(!CachedOnly) {
2069 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2070 }
2071
2072 frame = Lba >> Cache->BlocksPerFrameSh;
2073 i = Lba - (frame << Cache->BlocksPerFrameSh);
2074
2075 if(Cache->CacheWholePacket && (BCount < PS)) {
2076 if(!CachedOnly &&
2077 !OS_SUCCESS(status = WCacheCheckLimits(Cache, Context, Lba & ~(PS-1), PS*2)) ) {
2079 return status;
2080 }
2081 } else {
2082 if(!CachedOnly &&
2083 !OS_SUCCESS(status = WCacheCheckLimits(Cache, Context, Lba, BCount))) {
2085 return status;
2086 }
2087 }
2088 if(!CachedOnly) {
2089 // convert to shared
2090// ExConvertExclusiveToSharedLite(&(Cache->WCacheLock));
2091 }
2092
2093 // pre-read packet. It is very useful for
2094 // highly fragmented files
2095 if(Cache->CacheWholePacket && (BCount < PS)) {
2096// status = WCacheReadBlocks__(Cache, Context, Cache->tmp_buff_r, Lba & (~PacketMask), PS, &_ReadBytes, TRUE);
2097 // we should not perform IO if user requested CachedOnly data
2098 if(!CachedOnly) {
2100 }
2102 }
2103
2104 // assume successful operation
2105 block_array = Cache->FrameList[frame].Frame;
2106 if(!block_array) {
2107 ASSERT(!CachedOnly);
2108 ASSERT(Cache->FrameCount < Cache->MaxFrames);
2109 block_array = WCacheInitFrame(Cache, Context, frame);
2110 if(!block_array) {
2112 goto EO_WCache_R;
2113 }
2114 }
2115
2116 Cache->FrameList[frame].AccessCount++;
2117 while(BCount) {
2118 if(i >= Cache->BlocksPerFrame) {
2119 frame++;
2120 block_array = Cache->FrameList[frame].Frame;
2121 i -= Cache->BlocksPerFrame;
2122 }
2123 if(!block_array) {
2124 ASSERT(Cache->FrameCount < Cache->MaxFrames);
2125 block_array = WCacheInitFrame(Cache, Context, frame);
2126 if(!block_array) {
2128 goto EO_WCache_R;
2129 }
2130 }
2131 // 'read' cached extent (if any)
2132 // it is just copying
2133 while(BCount &&
2134 (i < Cache->BlocksPerFrame) &&
2135 (addr = (PCHAR)WCacheSectorAddr(block_array, i)) ) {
2136 block_type = Cache->CheckUsedProc(Context, Lba+saved_BC-BCount);
2137 if(block_type & WCACHE_BLOCK_BAD) {
2138 //if(WCacheGetBadFlag(block_array,i)) {
2140 goto EO_WCache_R;
2141 }
2143 Buffer += BS;
2144 *ReadBytes += BS;
2145 i++;
2146 BCount--;
2147 }
2148 // read non-cached packet-size-aligned extent (if any)
2149 // now we'll calculate total length & decide if it has enough size
2150 if(!((d = Lba+saved_BC-BCount) & PacketMask) && d ) {
2151 n = 0;
2152 while(BCount &&
2153 (i < Cache->BlocksPerFrame) &&
2154 (!WCacheSectorAddr(block_array, i)) ) {
2155 n++;
2156 BCount--;
2157 }
2158 BCount += n;
2159 n &= ~PacketMask;
2160 if(n>PS) {
2161 if(!OS_SUCCESS(status = Cache->ReadProc(Context, Buffer, BS*n, Lba+saved_BC-BCount, &_ReadBytes, 0))) {
2162 status = WCacheRaiseIoError(Cache, Context, status, Lba+saved_BC-BCount, n, Buffer, WCACHE_R_OP, NULL);
2163 if(!OS_SUCCESS(status)) {
2164 goto EO_WCache_R;
2165 }
2166 }
2167// WCacheInsertRangeToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba, saved_BC - BCount);
2168 BCount -= n;
2169 Lba += saved_BC - BCount;
2170 saved_BC = BCount;
2171 i += n;
2172 Buffer += BS*n;
2173 *ReadBytes += BS*n;
2174 }
2175// } else {
2176// UDFPrint(("Unaligned\n"));
2177 }
2178 // read non-cached extent (if any)
2179 // firstable, we'll get total number of sectors to read
2180 to_read = 0;
2181 saved_i = i;
2182 d = BCount;
2183 while(d &&
2184 (i < Cache->BlocksPerFrame) &&
2185 (!WCacheSectorAddr(block_array, i)) ) {
2186 i++;
2187 to_read += BS;
2188 d--;
2189 }
2190 // read some not cached sectors
2191 if(to_read) {
2192 i = saved_i;
2193 saved_to_read = to_read;
2194 d = BCount - d;
2195 // split request if necessary
2196 if(saved_to_read > MaxR) {
2197 WCacheInsertRangeToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba, saved_BC - BCount);
2198 n = MaxR >> BSh;
2199 do {
2200 status = Cache->ReadProc(Context, Buffer, MaxR, i + (frame << Cache->BlocksPerFrameSh), &_ReadBytes, 0);
2201 *ReadBytes += _ReadBytes;
2202 if(!OS_SUCCESS(status)) {
2203 _ReadBytes &= ~(BS-1);
2204 BCount -= _ReadBytes >> BSh;
2205 saved_to_read -= _ReadBytes;
2206 Buffer += _ReadBytes;
2207 saved_BC = BCount;
2208 goto store_read_data_1;
2209 }
2210 Buffer += MaxR;
2211 saved_to_read -= MaxR;
2212 i += n;
2213 BCount -= n;
2214 d -= n;
2215 } while(saved_to_read > MaxR);
2216 saved_BC = BCount;
2217 }
2218 if(saved_to_read) {
2219 status = Cache->ReadProc(Context, Buffer, saved_to_read, i + (frame << Cache->BlocksPerFrameSh), &_ReadBytes, 0);
2220 *ReadBytes += _ReadBytes;
2221 if(!OS_SUCCESS(status)) {
2222 _ReadBytes &= ~(BS-1);
2223 BCount -= _ReadBytes >> BSh;
2224 saved_to_read -= _ReadBytes;
2225 Buffer += _ReadBytes;
2226 goto store_read_data_1;
2227 }
2228 Buffer += saved_to_read;
2229 saved_to_read = 0;
2230 BCount -= d;
2231 }
2232
2233store_read_data_1:
2234 // and now we'll copy them to cache
2235
2236 //
2237 Buffer -= (to_read - saved_to_read);
2238 i = saved_i;
2239 while(to_read - saved_to_read) {
2241 if(!block_array[i].Sector) {
2242 BCount += to_read >> BSh;
2244 goto EO_WCache_R;
2245 }
2246 DbgCopyMemory(block_array[i].Sector, Buffer, BS);
2247 Cache->FrameList[frame].BlockCount++;
2248 i++;
2249 Buffer += BS;
2250 to_read -= BS;
2251 }
2252 if(!OS_SUCCESS(status))
2253 goto EO_WCache_R;
2254 to_read = 0;
2255 }
2256 }
2257
2258EO_WCache_R:
2259
2260 // we know the number of unread sectors if an error occured
2261 // so we can need to update BlockCount
2262 // return number of read bytes
2263 WCacheInsertRangeToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba, saved_BC - BCount);
2264// Cache->FrameList[frame].BlockCount -= BCount;
2265EO_WCache_R2:
2266 if(!CachedOnly) {
2268 }
2269
2270 return status;
2271} // end WCacheReadBlocks__()
ULONG to_read
Definition: btrfs.c:4260
#define d
Definition: ke_i.h:81
OSSTATUS WCacheReadBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN PCHAR Buffer, IN lba_t Lba, IN ULONG BCount, OUT PSIZE_T ReadBytes, IN BOOLEAN CachedOnly)
OSSTATUS WCachePreReadPacket__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba)

Referenced by WCacheReadBlocks__().

◆ WCacheRelease__()

VOID WCacheRelease__ ( IN PW_CACHE  Cache)

Definition at line 2768 of file wcache_lib.cpp.

2771{
2772 ULONG i, j, k;
2773 PW_CACHE_ENTRY block_array;
2774
2775 Cache->Tag = 0xDEADCACE;
2776 if(!(Cache->ReadProc)) return;
2777// ASSERT(Cache->Tag == 0xCAC11E00);
2778 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2779 for(i=0; i<Cache->FrameCount; i++) {
2780 j = Cache->CachedFramesList[i];
2781 block_array = Cache->FrameList[j].Frame;
2782 if(block_array) {
2783 for(k=0; k<Cache->BlocksPerFrame; k++) {
2784 if(WCacheSectorAddr(block_array, k)) {
2786 }
2787 }
2788 MyFreePool__(block_array);
2789 }
2790 }
2791 if(Cache->FrameList)
2792 MyFreePool__(Cache->FrameList);
2793 if(Cache->CachedBlocksList)
2794 MyFreePool__(Cache->CachedBlocksList);
2795 if(Cache->CachedModifiedBlocksList)
2796 MyFreePool__(Cache->CachedModifiedBlocksList);
2797 if(Cache->CachedFramesList)
2798 MyFreePool__(Cache->CachedFramesList);
2799 if(Cache->tmp_buff_r)
2800 MyFreePool__(Cache->tmp_buff_r);
2801 if(Cache->CachedFramesList)
2802 MyFreePool__(Cache->tmp_buff);
2803 if(Cache->CachedFramesList)
2804 MyFreePool__(Cache->reloc_tab);
2806 ExDeleteResourceLite(&(Cache->WCacheLock));
2807 RtlZeroMemory(Cache, sizeof(W_CACHE));
2808 return;
2809} // end WCacheRelease__()
int k
Definition: mpi.c:3369

Referenced by UDFDoDismountSequence(), UDFReleaseVCB(), and UDFVerifyVolume().

◆ WCacheRemoveFrame()

VOID __fastcall WCacheRemoveFrame ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN ULONG  frame 
)

Definition at line 780 of file wcache_lib.cpp.

785{
786 PW_CACHE_ENTRY block_array;
787#ifdef DBG
788 ULONG old_count = Cache->FrameCount;
789#endif //DBG
790
791 ASSERT(Cache->FrameCount <= Cache->MaxFrames);
792 block_array = Cache->FrameList[frame].Frame;
793
794 WCacheRemoveItemFromList(Cache->CachedFramesList, &(Cache->FrameCount), frame);
795 MyFreePool__(block_array);
796// ASSERT(!(Cache->FrameList[frame].WriteCount));
797// ASSERT(!(Cache->FrameList[frame].WriteCount));
798 Cache->FrameList[frame].Frame = NULL;
799 ASSERT(Cache->FrameCount < Cache->MaxFrames);
800#ifdef DBG
801 ASSERT(old_count > Cache->FrameCount);
802#endif //DBG
803
804} // end WCacheRemoveFrame()

Referenced by WCacheCheckLimits(), WCacheCheckLimitsR(), WCacheCheckLimitsRAM(), WCacheCheckLimitsRW(), WCacheDiscardBlocks__(), WCachePurgeAllR(), WCachePurgeAllRAM(), and WCachePurgeAllRW().

◆ WCacheRemoveItemFromList()

VOID __fastcall WCacheRemoveItemFromList ( IN lba_t List,
IN PULONG  BlockCount,
IN lba_t  Lba 
)

Definition at line 704 of file wcache_lib.cpp.

709{
710 if(!(*BlockCount)) return;
711 ULONG lastPos = WCacheGetSortedListIndex(*BlockCount, List, Lba+1);
712 if(!lastPos || (lastPos && (List[lastPos-1] != Lba)))
713 return;
714
715 // move list tail
716 DbgMoveMemory(&(List[lastPos-1]), &(List[lastPos]), ((*BlockCount) - lastPos) * sizeof(ULONG));
717 (*BlockCount) --;
718} // end WCacheRemoveItemFromList()

Referenced by WCacheCheckLimitsR(), WCacheDiscardBlocks__(), WCachePurgeAllR(), and WCacheRemoveFrame().

◆ WCacheRemoveRangeFromList()

VOID __fastcall WCacheRemoveRangeFromList ( IN lba_t List,
IN PULONG  BlockCount,
IN lba_t  Lba,
IN ULONG  BCount 
)

Definition at line 675 of file wcache_lib.cpp.

681{
682 ULONG firstPos = WCacheGetSortedListIndex(*BlockCount, List, Lba);
683 ULONG lastPos = WCacheGetSortedListIndex(*BlockCount, List, Lba+BCount);
684 ULONG offs = lastPos - firstPos;
685
686 if(offs) {
687 // move list tail
688 DbgMoveMemory(&(List[lastPos-offs]), &(List[lastPos]), ((*BlockCount) - lastPos) * sizeof(ULONG));
689 (*BlockCount) -= offs;
690 }
691} // end WCacheRemoveRangeFromList()

Referenced by WCacheCheckLimitsRAM(), WCacheCheckLimitsRW(), WCacheFlushAllRAM(), WCacheFlushAllRW(), WCacheFlushBlocksRW(), WCachePurgeAllRAM(), WCachePurgeAllRW(), and WCacheWriteBlocks__().

◆ WCacheSetMode__()

OSSTATUS WCacheSetMode__ ( IN PW_CACHE  Cache,
IN ULONG  Mode 
)

Definition at line 3426 of file wcache_lib.cpp.

3430{
3432 Cache->Mode = Mode;
3433 return STATUS_SUCCESS;
3434} // end WCacheSetMode__()

Referenced by UDFLoadPartDesc(), UDFMountVolume(), and UDFVerifyVolume().

◆ WCacheStartDirect__()

OSSTATUS WCacheStartDirect__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN BOOLEAN  Exclusive 
)

Definition at line 3101 of file wcache_lib.cpp.

3107{
3108 if(Exclusive) {
3109 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
3110 } else {
3111 BrutePoint();
3112 ExAcquireResourceSharedLite(&(Cache->WCacheLock), TRUE);
3113 }
3114 return STATUS_SUCCESS;
3115} // end WCacheStartDirect__()
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
__in PWDFDEVICE_INIT __in BOOLEAN Exclusive

Referenced by UDFIsExtentCached(), and UDFVWorkItem().

◆ WCacheSyncReloc__()

VOID WCacheSyncReloc__ ( IN PW_CACHE  Cache,
IN PVOID  Context 
)

Definition at line 3470 of file wcache_lib.cpp.

3473{
3474 ULONG frame;
3475 lba_t firstLba;
3476 lba_t* List = Cache->CachedBlocksList;
3477 lba_t Lba;
3478// ULONG BSh = Cache->BlockSizeSh;
3479// ULONG BS = Cache->BlockSize;
3480// ULONG PS = BS << Cache->PacketSizeSh; // packet size (bytes)
3481// ULONG PSs = Cache->PacketSize;
3482 PW_CACHE_ENTRY block_array;
3483 BOOLEAN mod;
3484 ULONG MaxReloc = Cache->PacketSize;
3485 PULONG reloc_tab = Cache->reloc_tab;
3486 ULONG RelocCount = 0;
3487 BOOLEAN IncompletePacket;
3488
3489 IncompletePacket = (Cache->WriteCount >= MaxReloc) ? FALSE : TRUE;
3490 // enumerate modified blocks
3491 for(ULONG i=0; IncompletePacket && (i<Cache->BlockCount); i++) {
3492
3493 Lba = List[i];
3494 frame = Lba >> Cache->BlocksPerFrameSh;
3495 firstLba = frame << Cache->BlocksPerFrameSh;
3496 block_array = Cache->FrameList[frame].Frame;
3497 if(!block_array) {
3498 return;
3499 }
3500 // check if modified
3501 mod = WCacheGetModFlag(block_array, Lba - firstLba);
3502 // update relocation table for modified sectors
3503 if(mod && (Cache->CheckUsedProc(Context, Lba) & WCACHE_BLOCK_USED)) {
3504 reloc_tab[RelocCount] = Lba;
3505 RelocCount++;
3506 if(RelocCount >= Cache->WriteCount) {
3507 Cache->UpdateRelocProc(Context, NULL, reloc_tab, RelocCount);
3508 break;
3509 }
3510 }
3511 }
3512} // end WCacheSyncReloc__()

Referenced by UDFRecordVAT().

◆ WCacheUpdatePacket()

OSSTATUS WCacheUpdatePacket ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN OUT PW_CACHE_ASYNC FirstWContext,
IN OUT PW_CACHE_ASYNC PrevWContext,
IN PW_CACHE_ENTRY  block_array,
IN lba_t  firstLba,
IN lba_t  Lba,
IN ULONG  BSh,
IN ULONG  BS,
IN ULONG  PS,
IN ULONG  PSs,
IN PSIZE_T  ReadBytes,
IN BOOLEAN  PrefereWrite,
IN ULONG  State 
)

Definition at line 986 of file wcache_lib.cpp.

1003{
1005 PCHAR tmp_buff = Cache->tmp_buff;
1006 PCHAR tmp_buff2 = Cache->tmp_buff;
1007 BOOLEAN mod;
1008 BOOLEAN read;
1009 BOOLEAN zero;
1010 ULONG i;
1011 lba_t Lba0;
1012 PW_CACHE_ASYNC WContext;
1013 BOOLEAN Async = (Cache->ReadProcAsync && Cache->WriteProcAsync);
1014 ULONG block_type;
1015 BOOLEAN Chained = Cache->Chained;
1016
1017 // Check if we are going to write down to disk
1018 // all prewiously prepared (chained) data
1019 if(State == ASYNC_STATE_WRITE) {
1020 WContext = (*PrevWContext);
1021 tmp_buff = (PCHAR)(WContext->Buffer);
1022 tmp_buff2 = (PCHAR)(WContext->Buffer2);
1023 if(!Chained)
1024 mod = (DbgCompareMemory(tmp_buff2, tmp_buff, PS) != PS);
1025 goto try_write;
1026 }
1027
1028 // Check if packet contains modified blocks
1029 // If packet contains non-cached and unchanged, but used
1030 // blocks, it must be read from media before modification
1031 mod = read = zero = FALSE;
1032 Lba0 = Lba - firstLba;
1033 for(i=0; i<PSs; i++, Lba0++) {
1034 if(WCacheGetModFlag(block_array, Lba0)) {
1035 mod = TRUE;
1036 } else if(!WCacheSectorAddr(block_array,Lba0) &&
1037 ((block_type = Cache->CheckUsedProc(Context, Lba+i)) & WCACHE_BLOCK_USED) ) {
1038 //
1039 if(block_type & WCACHE_BLOCK_ZERO) {
1040 zero = TRUE;
1041 } else {
1042 read = TRUE;
1043 }
1044 }
1045 }
1046 // check if we are allowed to write to media
1047 if(mod && !PrefereWrite) {
1048 return STATUS_RETRY;
1049 }
1050 // return STATUS_SUCCESS if requested packet contains no modified blocks
1051 if(!mod) {
1052 (*ReadBytes) = PS;
1053 return STATUS_SUCCESS;
1054 }
1055
1056 // pefrorm full update cycle: prepare(optional)/read/modify/write
1057
1058 // do some preparations
1059 if(Chained || Async) {
1060 // For chained and async I/O we allocates context entry
1061 // and add it to list (chain)
1062 // We shall only read data to temporary buffer and
1063 // modify it. Write operations will be invoked later.
1064 // This is introduced in order to avoid frequent
1065 // read.write mode switching, because it significantly degrades
1066 // performance
1067 WContext = WCacheAllocAsyncEntry(Cache, FirstWContext, PrevWContext, PS);
1068 if(!WContext) {
1069 //return STATUS_INSUFFICIENT_RESOURCES;
1070 // try to recover
1071 Chained = FALSE;
1072 Async = FALSE;
1073 } else {
1074 tmp_buff = tmp_buff2 = (PCHAR)(WContext->Buffer);
1075 WContext->Lba = Lba;
1076 WContext->Cmd = ASYNC_CMD_UPDATE;
1077 WContext->State = ASYNC_STATE_NONE;
1078 }
1079 }
1080
1081 // read packet (if it necessary)
1082 if(read) {
1083 if(Async) {
1084 WContext->State = ASYNC_STATE_READ;
1085 status = Cache->ReadProcAsync(Context, WContext, tmp_buff, PS, Lba,
1086 &(WContext->TransferredBytes));
1087// tmp_buff2 = (PCHAR)(WContext->Buffer2);
1088 (*ReadBytes) = PS;
1089 return status;
1090 } else {
1091 status = Cache->ReadProc(Context, tmp_buff, PS, Lba, ReadBytes, PH_TMP_BUFFER);
1092 }
1093 if(!OS_SUCCESS(status)) {
1094 status = WCacheRaiseIoError(Cache, Context, status, Lba, PSs, tmp_buff, WCACHE_R_OP, NULL);
1095 if(!OS_SUCCESS(status)) {
1096 return status;
1097 }
1098 }
1099 } else
1100 if(zero) {
1101 RtlZeroMemory(tmp_buff, PS);
1102 }
1103
1104 if(Chained) {
1105 // indicate that we prepared for writing block to disk
1106 WContext->State = ASYNC_STATE_WRITE_PRE;
1107 tmp_buff2 = tmp_buff;
1109 }
1110
1111 // modify packet
1112
1113 // If we didn't read packet from media, we can't
1114 // perform comparison to assure that packet was really modified.
1115 // Thus, assume that it is modified in this case.
1116 mod = !read || Cache->DoNotCompare;
1117 Lba0 = Lba - firstLba;
1118 for(i=0; i<PSs; i++, Lba0++) {
1119 if( WCacheGetModFlag(block_array, Lba0) ||
1120 (!read && WCacheSectorAddr(block_array,Lba0)) ) {
1121
1122#ifdef _NTDEF_
1123 ASSERT((ULONG)WCacheSectorAddr(block_array,Lba0) & 0x80000000);
1124#endif //_NTDEF_
1125 if(!mod) {
1126 ASSERT(read);
1127 mod = (DbgCompareMemory(tmp_buff2 + (i << BSh),
1128 (PVOID)WCacheSectorAddr(block_array, Lba0),
1129 BS) != BS);
1130 }
1131 if(mod) {
1132 DbgCopyMemory(tmp_buff2 + (i << BSh),
1133 (PVOID)WCacheSectorAddr(block_array, Lba0),
1134 BS);
1135 }
1136 }
1137 }
1138
1139 if(Chained &&
1140 WContext->State == ASYNC_STATE_WRITE_PRE) {
1141 // Return if block is prepared for write and we are in chained mode.
1142 if(!mod) {
1143 // Mark block as written if we have found that data in it
1144 // is not actually modified.
1145 WContext->State = ASYNC_STATE_DONE;
1146 (*ReadBytes) = PS;
1147 }
1148 return STATUS_SUCCESS;
1149 }
1150
1151 // write packet
1152
1153 // If the check above reported some changes in packet
1154 // we should write packet out to media.
1155 // Otherwise, just complete request.
1156 if(mod) {
1157try_write:
1158 if(Async) {
1159 WContext->State = ASYNC_STATE_WRITE;
1160 status = Cache->WriteProcAsync(Context, WContext, tmp_buff2, PS, Lba,
1161 &(WContext->TransferredBytes), FALSE);
1162 (*ReadBytes) = PS;
1163 } else {
1164 status = Cache->WriteProc(Context, tmp_buff2, PS, Lba, ReadBytes, 0);
1165 if(!OS_SUCCESS(status)) {
1166 status = WCacheRaiseIoError(Cache, Context, status, Lba, PSs, tmp_buff2, WCACHE_W_OP, NULL);
1167 }
1168 }
1169 } else {
1170 if(Async)
1172 (*ReadBytes) = PS;
1173 return STATUS_SUCCESS;
1174 }
1175
1176 return status;
1177} // end WCacheUpdatePacket()
#define read
Definition: acwin.h:96
#define DbgCompareMemory
Definition: env_spec_w32.h:330
SIZE_T TransferredBytes
Definition: wcache_lib.cpp:73
#define ASYNC_STATE_DONE
Definition: wcache_lib.cpp:46
#define ASYNC_STATE_WRITE_PRE
Definition: wcache_lib.cpp:44
#define ASYNC_STATE_READ
Definition: wcache_lib.cpp:43
#define ASYNC_STATE_WRITE
Definition: wcache_lib.cpp:45
PW_CACHE_ASYNC WCacheAllocAsyncEntry(IN PW_CACHE Cache, IN OUT PW_CACHE_ASYNC *FirstWContext, IN OUT PW_CACHE_ASYNC *PrevWContext, IN ULONG BufferSize)
Definition: wcache_lib.cpp:890
OSSTATUS WCacheCompleteAsync__(IN PVOID WContext, IN OSSTATUS Status)
#define ASYNC_CMD_UPDATE
Definition: wcache_lib.cpp:50

Referenced by WCacheCheckLimitsRW(), WCacheFlushAllRW(), WCacheFlushBlocksRW(), WCachePurgeAllRW(), and WCacheUpdatePacketComplete().

◆ WCacheUpdatePacketComplete()

VOID WCacheUpdatePacketComplete ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN OUT PW_CACHE_ASYNC FirstWContext,
IN OUT PW_CACHE_ASYNC PrevWContext,
IN BOOLEAN  FreePacket = TRUE 
)

Definition at line 1213 of file wcache_lib.cpp.

1220{
1221 PW_CACHE_ASYNC WContext = (*FirstWContext);
1222 if(!WContext)
1223 return;
1224 PW_CACHE_ASYNC NextWContext;
1225 ULONG PS = Cache->BlockSize << Cache->PacketSizeSh; // packet size (bytes)
1226 ULONG PSs = Cache->PacketSize;
1227 ULONG frame;
1228 lba_t firstLba;
1229
1230 // Walk through all chained blocks and wait
1231 // for completion of read operations.
1232 // Also invoke writes of already prepared packets.
1233 while(WContext) {
1234 if(WContext->Cmd == ASYNC_CMD_UPDATE &&
1235 WContext->State == ASYNC_STATE_READ) {
1236 // wait for async read for update
1238
1239 WContext->State = ASYNC_STATE_WRITE;
1240 WCacheUpdatePacket(Cache, Context, NULL, &WContext, NULL, -1, WContext->Lba, -1, -1,
1241 PS, -1, &(WContext->TransferredBytes), TRUE, ASYNC_STATE_WRITE);
1242 } else
1243 if(WContext->Cmd == ASYNC_CMD_UPDATE &&
1244 WContext->State == ASYNC_STATE_WRITE_PRE) {
1245 // invoke physical write it the packet is prepared for writing
1246 // by previuous call to WCacheUpdatePacket()
1247 WContext->State = ASYNC_STATE_WRITE;
1248 WCacheUpdatePacket(Cache, Context, NULL, &WContext, NULL, -1, WContext->Lba, -1, -1,
1249 PS, -1, &(WContext->TransferredBytes), TRUE, ASYNC_STATE_WRITE);
1250 WContext->State = ASYNC_STATE_DONE;
1251 } else
1252 if(WContext->Cmd == ASYNC_CMD_READ &&
1253 WContext->State == ASYNC_STATE_READ) {
1254 // wait for async read
1256 }
1257 WContext = WContext->NextWContext;
1258 }
1259 // Walk through all chained blocks and wait
1260 // and wait for completion of async writes (if any).
1261 // Also free temporary buffers containing already written blocks.
1262 WContext = (*FirstWContext);
1263 while(WContext) {
1264 NextWContext = WContext->NextWContext;
1265 if(WContext->Cmd == ASYNC_CMD_UPDATE &&
1266 WContext->State == ASYNC_STATE_WRITE) {
1267
1268 if(!Cache->Chained)
1270
1271 frame = WContext->Lba >> Cache->BlocksPerFrameSh;
1272 firstLba = frame << Cache->BlocksPerFrameSh;
1273
1274 if(FreePacket) {
1275 WCacheFreePacket(Cache, frame,
1276 Cache->FrameList[frame].Frame,
1277 WContext->Lba - firstLba, PSs);
1278 }
1279 }
1280 WCacheFreeAsyncEntry(Cache, WContext);
1281 WContext = NextWContext;
1282 }
1283 (*FirstWContext) = NULL;
1284 (*PrevWContext) = NULL;
1285} // end WCacheUpdatePacketComplete()
#define DbgWaitForSingleObject(o, to)
Definition: env_spec_w32.h:479
#define ASYNC_CMD_READ
Definition: wcache_lib.cpp:49
VOID WCacheFreeAsyncEntry(IN PW_CACHE Cache, PW_CACHE_ASYNC WContext)
Definition: wcache_lib.cpp:934

Referenced by WCacheCheckLimitsRW(), WCacheFlushAllRW(), WCacheFlushBlocksRW(), and WCachePurgeAllRW().

◆ WCacheWriteBlocks__()

OSSTATUS WCacheWriteBlocks__ ( IN PW_CACHE  Cache,
IN PVOID  Context,
IN PCHAR  Buffer,
IN lba_t  Lba,
IN ULONG  BCount,
OUT PSIZE_T  WrittenBytes,
IN BOOLEAN  CachedOnly 
)

Definition at line 2281 of file wcache_lib.cpp.

2291{
2292 ULONG frame;
2293 ULONG i, saved_BC = BCount, n, d;
2295 PW_CACHE_ENTRY block_array;
2296 ULONG BSh = Cache->BlockSizeSh;
2297 ULONG BS = Cache->BlockSize;
2298 PCHAR addr;
2299// PCHAR saved_buff = Buffer;
2300 SIZE_T _WrittenBytes;
2301 ULONG PS = Cache->PacketSize;
2302 ULONG PacketMask = PS-1; // here we assume that Packet Size value is 2^n
2303 ULONG block_type;
2304// BOOLEAN Aligned = FALSE;
2305
2306 BOOLEAN WriteThrough = FALSE;
2307 lba_t WTh_Lba;
2308 ULONG WTh_BCount;
2309
2310 WcPrint(("WC:W %x (%x)\n", Lba, BCount));
2311
2312 *WrittenBytes = 0;
2313// UDFPrint(("BCount:%x\n",BCount));
2314 // check if we try to read too much data
2315 if(BCount >= Cache->MaxBlocks) {
2316 i = 0;
2317 if(CachedOnly) {
2319 goto EO_WCache_W2;
2320 }
2321 while(TRUE) {
2322// UDFPrint((" BCount:%x\n",BCount));
2323 status = WCacheWriteBlocks__(Cache, Context, Buffer + (i<<BSh), Lba, min(PS,BCount), &_WrittenBytes, FALSE);
2324 (*WrittenBytes) += _WrittenBytes;
2325 BCount -= PS;
2326 Lba += PS;
2327 i += PS;
2328 if(!OS_SUCCESS(status) || (BCount < PS))
2329 return status;
2330 }
2331 }
2332 // check if we try to access beyond cached area
2333 if((Lba < Cache->FirstLba) ||
2334 (Lba + BCount - 1 > Cache->LastLba)) {
2336 }
2337 if(!CachedOnly) {
2338 ExAcquireResourceExclusiveLite(&(Cache->WCacheLock), TRUE);
2339 }
2340
2341 frame = Lba >> Cache->BlocksPerFrameSh;
2342 i = Lba - (frame << Cache->BlocksPerFrameSh);
2343
2344 if(!CachedOnly &&
2345 !OS_SUCCESS(status = WCacheCheckLimits(Cache, Context, Lba, BCount))) {
2347 return status;
2348 }
2349
2350 // assume successful operation
2351 block_array = Cache->FrameList[frame].Frame;
2352 if(!block_array) {
2353
2354 if(BCount && !(BCount & (PS-1)) && !(Lba & (PS-1)) &&
2355 (Cache->Mode != WCACHE_MODE_R) &&
2356 (i+BCount <= Cache->BlocksPerFrame) &&
2357 !Cache->NoWriteThrough) {
2358 status = Cache->WriteProc(Context, Buffer, BCount<<BSh, Lba, WrittenBytes, 0);
2359 if(!OS_SUCCESS(status)) {
2361 }
2362 goto EO_WCache_W2;
2363 }
2364
2365 ASSERT(!CachedOnly);
2366 ASSERT(Cache->FrameCount < Cache->MaxFrames);
2367 block_array = WCacheInitFrame(Cache, Context, frame);
2368 if(!block_array) {
2370 goto EO_WCache_W;
2371 }
2372 }
2373
2374 if(Cache->Mode == WCACHE_MODE_RAM &&
2375 BCount &&
2376// !(Lba & (PS-1)) &&
2377 (!(BCount & (PS-1)) || (BCount > PS)) ) {
2378 WriteThrough = TRUE;
2379 WTh_Lba = Lba;
2380 WTh_BCount = BCount;
2381 } else
2382 if(Cache->Mode == WCACHE_MODE_RAM &&
2383 ((Lba & ~PacketMask) != ((Lba+BCount-1) & ~PacketMask))
2384 ) {
2385 WriteThrough = TRUE;
2386 WTh_Lba = Lba & ~PacketMask;
2387 WTh_BCount = PS;
2388 }
2389
2390 Cache->FrameList[frame].UpdateCount++;
2391// UDFPrint((" BCount:%x\n",BCount));
2392 while(BCount) {
2393 if(i >= Cache->BlocksPerFrame) {
2394 frame++;
2395 block_array = Cache->FrameList[frame].Frame;
2396 i -= Cache->BlocksPerFrame;
2397 }
2398 if(!block_array) {
2399 ASSERT(Cache->FrameCount < Cache->MaxFrames);
2400 block_array = WCacheInitFrame(Cache, Context, frame);
2401 if(!block_array) {
2403 goto EO_WCache_W;
2404 }
2405 }
2406 // 'write' cached extent (if any)
2407 // it is just copying
2408 while(BCount &&
2409 (i < Cache->BlocksPerFrame) &&
2410 (addr = (PCHAR)WCacheSectorAddr(block_array, i)) ) {
2411// UDFPrint(("addr:%x:Buffer:%x:BS:%x:BCount:%x\n",addr, Buffer, BS, BCount));
2412 block_type = Cache->CheckUsedProc(Context, Lba+saved_BC-BCount);
2413 if(Cache->NoWriteBB &&
2414 /*WCacheGetBadFlag(block_array,i)*/
2415 (block_type & WCACHE_BLOCK_BAD)) {
2416 // bad packet. no cached write
2418 goto EO_WCache_W;
2419 }
2421 WCacheSetModFlag(block_array, i);
2422 Buffer += BS;
2423 *WrittenBytes += BS;
2424 i++;
2425 BCount--;
2426 }
2427 // write non-cached not-aligned extent (if any) till aligned one
2428 while(BCount &&
2429 (i & PacketMask) &&
2430 (Cache->Mode != WCACHE_MODE_R) &&
2431 (i < Cache->BlocksPerFrame) &&
2432 (!WCacheSectorAddr(block_array, i)) ) {
2434 if(!block_array[i].Sector) {
2436 goto EO_WCache_W;
2437 }
2438// UDFPrint(("addr:%x:Buffer:%x:BS:%x:BCount:%x\n",block_array[i].Sector, Buffer, BS, BCount));
2439 DbgCopyMemory(block_array[i].Sector, Buffer, BS);
2440 WCacheSetModFlag(block_array, i);
2441 i++;
2442 Buffer += BS;
2443 *WrittenBytes += BS;
2444 BCount--;
2445 Cache->FrameList[frame].BlockCount ++;
2446 }
2447 // write non-cached packet-size-aligned extent (if any)
2448 // now we'll calculate total length & decide if has enough size
2449 if(!Cache->NoWriteThrough
2450 &&
2451 ( !(i & PacketMask) ||
2452 ((Cache->Mode == WCACHE_MODE_R) && (BCount >= PS)) )) {
2453 n = 0;
2454 while(BCount &&
2455 (i < Cache->BlocksPerFrame) &&
2456 (!WCacheSectorAddr(block_array, i)) ) {
2457 n++;
2458 BCount--;
2459 }
2460 BCount += n;
2461 n &= ~PacketMask;
2462// if(!OS_SUCCESS(status = Cache->WriteProcAsync(Context, Buffer, BS*n, Lba+saved_BC-BCount, &_WrittenBytes, FALSE)))
2463 if(n) {
2464 // add previously written data to list
2465 d = saved_BC - BCount;
2466 WCacheInsertRangeToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba, d);
2467 WCacheInsertRangeToList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba, d);
2468 Lba += d;
2469 saved_BC = BCount;
2470
2471 while(n) {
2472 if(Cache->Mode == WCACHE_MODE_R)
2473 Cache->UpdateRelocProc(Context, Lba, NULL, PS);
2474 if(!OS_SUCCESS(status = Cache->WriteProc(Context, Buffer, PS<<BSh, Lba, &_WrittenBytes, 0))) {
2476 if(!OS_SUCCESS(status)) {
2477 goto EO_WCache_W;
2478 }
2479 }
2480 BCount -= PS;
2481 Lba += PS;
2482 saved_BC = BCount;
2483 i += PS;
2484 Buffer += PS<<BSh;
2485 *WrittenBytes += PS<<BSh;
2486 n-=PS;
2487 }
2488 }
2489 }
2490 // write non-cached not-aligned extent (if any)
2491 while(BCount &&
2492 (i < Cache->BlocksPerFrame) &&
2493 (!WCacheSectorAddr(block_array, i)) ) {
2495 if(!block_array[i].Sector) {
2497 goto EO_WCache_W;
2498 }
2499// UDFPrint(("addr:%x:Buffer:%x:BS:%x:BCount:%x\n",block_array[i].Sector, Buffer, BS, BCount));
2500 DbgCopyMemory(block_array[i].Sector, Buffer, BS);
2501 WCacheSetModFlag(block_array, i);
2502 i++;
2503 Buffer += BS;
2504 *WrittenBytes += BS;
2505 BCount--;
2506 Cache->FrameList[frame].BlockCount ++;
2507 }
2508 }
2509
2510EO_WCache_W:
2511
2512 // we know the number of unread sectors if an error occured
2513 // so we can need to update BlockCount
2514 // return number of read bytes
2515 WCacheInsertRangeToList(Cache->CachedBlocksList, &(Cache->BlockCount), Lba, saved_BC - BCount);
2516 WCacheInsertRangeToList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba, saved_BC - BCount);
2517
2518 if(WriteThrough && !BCount) {
2519 ULONG d;
2520// lba_t lastLba;
2521 ULONG firstPos;
2522 ULONG lastPos;
2523
2524 BCount = WTh_BCount;
2525 Lba = WTh_Lba;
2526 while(BCount) {
2527 frame = Lba >> Cache->BlocksPerFrameSh;
2528// firstLba = frame << Cache->BlocksPerFrameSh;
2529 firstPos = WCacheGetSortedListIndex(Cache->BlockCount, Cache->CachedBlocksList, Lba);
2530 d = min(Lba+BCount, (frame+1) << Cache->BlocksPerFrameSh) - Lba;
2531 lastPos = WCacheGetSortedListIndex(Cache->BlockCount, Cache->CachedBlocksList, Lba+d);
2532 block_array = Cache->FrameList[frame].Frame;
2533 if(!block_array) {
2534 ASSERT(FALSE);
2535 BCount -= d;
2536 Lba += d;
2537 continue;
2538 }
2539 status = WCacheFlushBlocksRAM(Cache, Context, block_array, Cache->CachedBlocksList, firstPos, lastPos, FALSE);
2540 WCacheRemoveRangeFromList(Cache->CachedModifiedBlocksList, &(Cache->WriteCount), Lba, d);
2541 BCount -= d;
2542 Lba += d;
2543 }
2544 }
2545
2546EO_WCache_W2:
2547
2548 if(!CachedOnly) {
2550 }
2551 return status;
2552} // end WCacheWriteBlocks__()
#define min(a, b)
Definition: monoChain.cc:55
OSSTATUS WCacheWriteBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN PCHAR Buffer, IN lba_t Lba, IN ULONG BCount, OUT PSIZE_T WrittenBytes, IN BOOLEAN CachedOnly)

Referenced by UDFWriteSectors(), and WCacheWriteBlocks__().

Variable Documentation

◆ WCache_random

ULONG WCache_random

Definition at line 90 of file wcache_lib.cpp.

Referenced by WCacheInit__(), and WCacheRandom().