//////////////////////////////////////////////////////////////////// // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine // All rights reserved // This file was released under the GPLv2 on June 2015. //////////////////////////////////////////////////////////////////// #ifndef __CDRW_WCACHE_LIB_H__ #define __CDRW_WCACHE_LIB_H__ extern "C" { #include "platform.h" #ifdef _CONSOLE #include "env_spec_w32.h" #else //#include "env_spec.h" #endif #define WCACHE_BOUND_CHECKS typedef OSSTATUS (*PWRITE_BLOCK) (IN PVOID Context, IN PVOID Buffer, // Target buffer IN SIZE_T Length, IN lba_t Lba, OUT PSIZE_T WrittenBytes, IN uint32 Flags); typedef OSSTATUS (*PREAD_BLOCK) (IN PVOID Context, IN PVOID Buffer, // Target buffer IN SIZE_T Length, IN lba_t Lba, OUT PSIZE_T ReadBytes, IN uint32 Flags); typedef OSSTATUS (*PWRITE_BLOCK_ASYNC) (IN PVOID Context, IN PVOID WContext, IN PVOID Buffer, // Target buffer IN SIZE_T Length, IN lba_t Lba, OUT PSIZE_T WrittenBytes, IN BOOLEAN FreeBuffer); typedef OSSTATUS (*PREAD_BLOCK_ASYNC) (IN PVOID Context, IN PVOID WContext, IN PVOID Buffer, // Source buffer IN SIZE_T Length, IN lba_t Lba, OUT PSIZE_T ReadBytes); /*typedef BOOLEAN (*PCHECK_BLOCK) (IN PVOID Context, IN lba_t Lba);*/ #define WCACHE_BLOCK_USED 0x01 #define WCACHE_BLOCK_ZERO 0x02 #define WCACHE_BLOCK_BAD 0x04 typedef ULONG (*PCHECK_BLOCK) (IN PVOID Context, IN lba_t Lba); typedef OSSTATUS (*PUPDATE_RELOC) (IN PVOID Context, IN lba_t Lba, IN PULONG RelocTab, IN ULONG BCount); #define WCACHE_ERROR_READ 0x0001 #define WCACHE_ERROR_WRITE 0x0002 #define WCACHE_ERROR_INTERNAL 0x0003 #define WCACHE_W_OP FALSE #define WCACHE_R_OP TRUE typedef struct _WCACHE_ERROR_CONTEXT { ULONG WCErrorCode; OSSTATUS Status; BOOLEAN Retry; UCHAR Padding[3]; union { struct { ULONG Lba; ULONG BCount; PVOID Buffer; } ReadWrite; struct { ULONG p1; ULONG p2; ULONG p3; ULONG p4; } Internal; }; } WCACHE_ERROR_CONTEXT, *PWCACHE_ERROR_CONTEXT; typedef OSSTATUS (*PWC_ERROR_HANDLER) (IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo); // array of pointers to cached data // each entry corresponds to logical block on disk typedef struct _W_CACHE_ENTRY { union { PCHAR Sector; UCHAR Flags:3; }; } W_CACHE_ENTRY, *PW_CACHE_ENTRY; // array of pointers to cache frames // each frame corresponds to extent of logical blocks typedef struct _W_CACHE_FRAME { PW_CACHE_ENTRY Frame; ULONG BlockCount; //ULONG WriteCount; // number of modified packets in cache frame, is always 0, shall be removed ULONG UpdateCount; // number of updates in cache frame ULONG AccessCount; // number of accesses to cache frame } W_CACHE_FRAME, *PW_CACHE_FRAME; // memory type for cached blocks #define CACHED_BLOCK_MEMORY_TYPE PagedPool #define MAX_TRIES_FOR_NA 3 #define WCACHE_ADDR_MASK 0xfffffff8 #define WCACHE_FLAG_MASK 0x00000007 #define WCACHE_FLAG_MODIFIED 0x00000001 #define WCACHE_FLAG_ZERO 0x00000002 #define WCACHE_FLAG_BAD 0x00000004 #define WCACHE_MODE_ROM 0x00000000 // read only (CD-ROM) #define WCACHE_MODE_RW 0x00000001 // rewritable (CD-RW) #define WCACHE_MODE_R 0x00000002 // WORM (CD-R) #define WCACHE_MODE_RAM 0x00000003 // random writable device (HDD) #define WCACHE_MODE_EWR 0x00000004 // ERASE-cycle required (MO) #define WCACHE_MODE_MAX WCACHE_MODE_RAM #define PH_TMP_BUFFER 1 struct _W_CACHE_ASYNC; typedef struct _W_CACHE { // cache tables ULONG Tag; PW_CACHE_FRAME FrameList; // pointer to list of Frames lba_t* CachedBlocksList; // sorted list of cached blocks lba_t* CachedFramesList; // sorted list of cached frames lba_t* CachedModifiedBlocksList; // sorted list of cached modified blocks // settings & current state ULONG BlocksPerFrame; ULONG BlocksPerFrameSh; ULONG BlockCount; ULONG MaxBlocks; ULONG MaxBytesToRead; ULONG FrameCount; ULONG MaxFrames; ULONG PacketSize; // number of blocks in packet ULONG PacketSizeSh; ULONG BlockSize; ULONG BlockSizeSh; ULONG WriteCount; // number of modified packets in cache lba_t FirstLba; lba_t LastLba; ULONG Mode; // RO/WOR/RW/EWR ULONG Flags; BOOLEAN CacheWholePacket; BOOLEAN DoNotCompare; BOOLEAN Chained; BOOLEAN RememberBB; BOOLEAN NoWriteBB; BOOLEAN NoWriteThrough; UCHAR Padding[2]; ULONG RBalance; ULONG WBalance; ULONG FramesToKeepFree; // callbacks PWRITE_BLOCK WriteProc; PREAD_BLOCK ReadProc; PWRITE_BLOCK_ASYNC WriteProcAsync; PREAD_BLOCK_ASYNC ReadProcAsync; PCHECK_BLOCK CheckUsedProc; PUPDATE_RELOC UpdateRelocProc; PWC_ERROR_HANDLER ErrorHandlerProc; // sync resource ERESOURCE WCacheLock; // BOOLEAN WCResInit; // preallocated tmp buffers PCHAR tmp_buff; PCHAR tmp_buff_r; PULONG reloc_tab; } W_CACHE, *PW_CACHE; #define WCACHE_INVALID_LBA ((lba_t)(-1)) #define WCACHE_CACHE_WHOLE_PACKET 0x01 #define WCACHE_DO_NOT_COMPARE 0x02 #define WCACHE_CHAINED_IO 0x04 #define WCACHE_MARK_BAD_BLOCKS 0x08 #define WCACHE_RO_BAD_BLOCKS 0x10 #define WCACHE_NO_WRITE_THROUGH 0x20 #define WCACHE_VALID_FLAGS (WCACHE_CACHE_WHOLE_PACKET | \ WCACHE_DO_NOT_COMPARE | \ WCACHE_CHAINED_IO | \ WCACHE_MARK_BAD_BLOCKS | \ WCACHE_RO_BAD_BLOCKS | \ WCACHE_NO_WRITE_THROUGH) #define WCACHE_INVALID_FLAGS (0xffffffff) // init cache OSSTATUS WCacheInit__(IN PW_CACHE Cache, IN ULONG MaxFrames, IN ULONG MaxBlocks, IN SIZE_T MaxBytesToRead, IN ULONG PacketSizeSh, // number of blocks in packet (bit shift) IN ULONG BlockSizeSh, // bit shift IN ULONG BlocksPerFrameSh,// bit shift 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); // write cached 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); // read cached 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); // flush blocks OSSTATUS WCacheFlushBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN ULONG BCount); // discard blocks VOID WCacheDiscardBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN ULONG BCount); // flush whole cache VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context); // purge whole cache VOID WCachePurgeAll__(IN PW_CACHE Cache, IN PVOID Context); // free structures VOID WCacheRelease__(IN PW_CACHE Cache); // check if initialized BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache); // direct access to cached data OSSTATUS WCacheDirect__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN BOOLEAN Modified, OUT PCHAR* CachedBlock, IN BOOLEAN CachedOnly); // release resources after direct access OSSTATUS WCacheEODirect__(IN PW_CACHE Cache, IN PVOID Context); // release resources before direct access OSSTATUS WCacheStartDirect__(IN PW_CACHE Cache, IN PVOID Context, IN BOOLEAN Exclusive); // check if requested extent completly cached BOOLEAN WCacheIsCached__(IN PW_CACHE Cache, IN lba_t Lba, IN ULONG BCount); // change cache media mode 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); ULONG WCacheChFlags__(IN PW_CACHE Cache, IN ULONG SetFlags, IN ULONG ClrFlags); }; // complete async request (callback) OSSTATUS WCacheCompleteAsync__(IN PVOID WContext, IN OSSTATUS Status); #endif // __CDRW_WCACHE_LIB_H__