1c2c66affSColin Finck //////////////////////////////////////////////////////////////////// 2c2c66affSColin Finck // Copyright (C) Alexander Telyatnikov, Ivan Keliukh, Yegor Anchishkin, SKIF Software, 1999-2013. Kiev, Ukraine 3c2c66affSColin Finck // All rights reserved 4c2c66affSColin Finck // This file was released under the GPLv2 on June 2015. 5c2c66affSColin Finck //////////////////////////////////////////////////////////////////// 6c2c66affSColin Finck 7c2c66affSColin Finck #ifndef __CDRW_WCACHE_LIB_H__ 8c2c66affSColin Finck #define __CDRW_WCACHE_LIB_H__ 9c2c66affSColin Finck 10c2c66affSColin Finck extern "C" { 11c2c66affSColin Finck 12c2c66affSColin Finck #include "platform.h" 13c2c66affSColin Finck 14c2c66affSColin Finck #ifdef _CONSOLE 15c2c66affSColin Finck #include "env_spec_w32.h" 16c2c66affSColin Finck #else 17c2c66affSColin Finck //#include "env_spec.h" 18c2c66affSColin Finck #endif 19c2c66affSColin Finck 20c2c66affSColin Finck #define WCACHE_BOUND_CHECKS 21c2c66affSColin Finck 22c2c66affSColin Finck typedef OSSTATUS (*PWRITE_BLOCK) (IN PVOID Context, 23c2c66affSColin Finck IN PVOID Buffer, // Target buffer 24*c334c17dSTimo Kreuzer IN SIZE_T Length, 25c2c66affSColin Finck IN lba_t Lba, 26*c334c17dSTimo Kreuzer OUT PSIZE_T WrittenBytes, 27c2c66affSColin Finck IN uint32 Flags); 28c2c66affSColin Finck 29c2c66affSColin Finck typedef OSSTATUS (*PREAD_BLOCK) (IN PVOID Context, 30c2c66affSColin Finck IN PVOID Buffer, // Target buffer 31*c334c17dSTimo Kreuzer IN SIZE_T Length, 32c2c66affSColin Finck IN lba_t Lba, 33*c334c17dSTimo Kreuzer OUT PSIZE_T ReadBytes, 34c2c66affSColin Finck IN uint32 Flags); 35c2c66affSColin Finck 36c2c66affSColin Finck typedef OSSTATUS (*PWRITE_BLOCK_ASYNC) (IN PVOID Context, 37c2c66affSColin Finck IN PVOID WContext, 38c2c66affSColin Finck IN PVOID Buffer, // Target buffer 39*c334c17dSTimo Kreuzer IN SIZE_T Length, 40c2c66affSColin Finck IN lba_t Lba, 41*c334c17dSTimo Kreuzer OUT PSIZE_T WrittenBytes, 42c2c66affSColin Finck IN BOOLEAN FreeBuffer); 43c2c66affSColin Finck 44c2c66affSColin Finck typedef OSSTATUS (*PREAD_BLOCK_ASYNC) (IN PVOID Context, 45c2c66affSColin Finck IN PVOID WContext, 46c2c66affSColin Finck IN PVOID Buffer, // Source buffer 47*c334c17dSTimo Kreuzer IN SIZE_T Length, 48c2c66affSColin Finck IN lba_t Lba, 49*c334c17dSTimo Kreuzer OUT PSIZE_T ReadBytes); 50c2c66affSColin Finck 51c2c66affSColin Finck /*typedef BOOLEAN (*PCHECK_BLOCK) (IN PVOID Context, 52c2c66affSColin Finck IN lba_t Lba);*/ 53c2c66affSColin Finck 54c2c66affSColin Finck #define WCACHE_BLOCK_USED 0x01 55c2c66affSColin Finck #define WCACHE_BLOCK_ZERO 0x02 56c2c66affSColin Finck #define WCACHE_BLOCK_BAD 0x04 57c2c66affSColin Finck 58c2c66affSColin Finck typedef ULONG (*PCHECK_BLOCK) (IN PVOID Context, 59c2c66affSColin Finck IN lba_t Lba); 60c2c66affSColin Finck 61c2c66affSColin Finck typedef OSSTATUS (*PUPDATE_RELOC) (IN PVOID Context, 62c2c66affSColin Finck IN lba_t Lba, 63c2c66affSColin Finck IN PULONG RelocTab, 64c2c66affSColin Finck IN ULONG BCount); 65c2c66affSColin Finck 66c2c66affSColin Finck #define WCACHE_ERROR_READ 0x0001 67c2c66affSColin Finck #define WCACHE_ERROR_WRITE 0x0002 68c2c66affSColin Finck #define WCACHE_ERROR_INTERNAL 0x0003 69c2c66affSColin Finck 70c2c66affSColin Finck #define WCACHE_W_OP FALSE 71c2c66affSColin Finck #define WCACHE_R_OP TRUE 72c2c66affSColin Finck 73c2c66affSColin Finck typedef struct _WCACHE_ERROR_CONTEXT { 74c2c66affSColin Finck ULONG WCErrorCode; 75c2c66affSColin Finck OSSTATUS Status; 76c2c66affSColin Finck BOOLEAN Retry; 77c2c66affSColin Finck UCHAR Padding[3]; 78c2c66affSColin Finck union { 79c2c66affSColin Finck struct { 80c2c66affSColin Finck ULONG Lba; 81c2c66affSColin Finck ULONG BCount; 82c2c66affSColin Finck PVOID Buffer; 83c2c66affSColin Finck } ReadWrite; 84c2c66affSColin Finck struct { 85c2c66affSColin Finck ULONG p1; 86c2c66affSColin Finck ULONG p2; 87c2c66affSColin Finck ULONG p3; 88c2c66affSColin Finck ULONG p4; 89c2c66affSColin Finck } Internal; 90c2c66affSColin Finck }; 91c2c66affSColin Finck } WCACHE_ERROR_CONTEXT, *PWCACHE_ERROR_CONTEXT; 92c2c66affSColin Finck 93c2c66affSColin Finck typedef OSSTATUS (*PWC_ERROR_HANDLER) (IN PVOID Context, 94c2c66affSColin Finck IN PWCACHE_ERROR_CONTEXT ErrorInfo); 95c2c66affSColin Finck // array of pointers to cached data 96c2c66affSColin Finck // each entry corresponds to logical block on disk 97c2c66affSColin Finck typedef struct _W_CACHE_ENTRY { 98c2c66affSColin Finck union { 99c2c66affSColin Finck PCHAR Sector; 100c2c66affSColin Finck UCHAR Flags:3; 101c2c66affSColin Finck }; 102c2c66affSColin Finck } W_CACHE_ENTRY, *PW_CACHE_ENTRY; 103c2c66affSColin Finck 104c2c66affSColin Finck // array of pointers to cache frames 105c2c66affSColin Finck // each frame corresponds to extent of logical blocks 106c2c66affSColin Finck typedef struct _W_CACHE_FRAME { 107c2c66affSColin Finck PW_CACHE_ENTRY Frame; 108c2c66affSColin Finck ULONG BlockCount; 109c2c66affSColin Finck //ULONG WriteCount; // number of modified packets in cache frame, is always 0, shall be removed 110c2c66affSColin Finck ULONG UpdateCount; // number of updates in cache frame 111c2c66affSColin Finck ULONG AccessCount; // number of accesses to cache frame 112c2c66affSColin Finck } W_CACHE_FRAME, *PW_CACHE_FRAME; 113c2c66affSColin Finck 114c2c66affSColin Finck // memory type for cached blocks 115c2c66affSColin Finck #define CACHED_BLOCK_MEMORY_TYPE PagedPool 116c2c66affSColin Finck #define MAX_TRIES_FOR_NA 3 117c2c66affSColin Finck 118c2c66affSColin Finck #define WCACHE_ADDR_MASK 0xfffffff8 119c2c66affSColin Finck #define WCACHE_FLAG_MASK 0x00000007 120c2c66affSColin Finck #define WCACHE_FLAG_MODIFIED 0x00000001 121c2c66affSColin Finck #define WCACHE_FLAG_ZERO 0x00000002 122c2c66affSColin Finck #define WCACHE_FLAG_BAD 0x00000004 123c2c66affSColin Finck 124c2c66affSColin Finck #define WCACHE_MODE_ROM 0x00000000 // read only (CD-ROM) 125c2c66affSColin Finck #define WCACHE_MODE_RW 0x00000001 // rewritable (CD-RW) 126c2c66affSColin Finck #define WCACHE_MODE_R 0x00000002 // WORM (CD-R) 127c2c66affSColin Finck #define WCACHE_MODE_RAM 0x00000003 // random writable device (HDD) 128c2c66affSColin Finck #define WCACHE_MODE_EWR 0x00000004 // ERASE-cycle required (MO) 129c2c66affSColin Finck #define WCACHE_MODE_MAX WCACHE_MODE_RAM 130c2c66affSColin Finck 131c2c66affSColin Finck #define PH_TMP_BUFFER 1 132c2c66affSColin Finck 133c2c66affSColin Finck struct _W_CACHE_ASYNC; 134c2c66affSColin Finck 135c2c66affSColin Finck typedef struct _W_CACHE { 136c2c66affSColin Finck // cache tables 137c2c66affSColin Finck ULONG Tag; 138c2c66affSColin Finck PW_CACHE_FRAME FrameList; // pointer to list of Frames 139c2c66affSColin Finck lba_t* CachedBlocksList; // sorted list of cached blocks 140c2c66affSColin Finck lba_t* CachedFramesList; // sorted list of cached frames 141c2c66affSColin Finck lba_t* CachedModifiedBlocksList; // sorted list of cached modified blocks 142c2c66affSColin Finck // settings & current state 143c2c66affSColin Finck ULONG BlocksPerFrame; 144c2c66affSColin Finck ULONG BlocksPerFrameSh; 145c2c66affSColin Finck ULONG BlockCount; 146c2c66affSColin Finck ULONG MaxBlocks; 147c2c66affSColin Finck ULONG MaxBytesToRead; 148c2c66affSColin Finck ULONG FrameCount; 149c2c66affSColin Finck ULONG MaxFrames; 150c2c66affSColin Finck ULONG PacketSize; // number of blocks in packet 151c2c66affSColin Finck ULONG PacketSizeSh; 152c2c66affSColin Finck ULONG BlockSize; 153c2c66affSColin Finck ULONG BlockSizeSh; 154c2c66affSColin Finck ULONG WriteCount; // number of modified packets in cache 155c2c66affSColin Finck lba_t FirstLba; 156c2c66affSColin Finck lba_t LastLba; 157c2c66affSColin Finck ULONG Mode; // RO/WOR/RW/EWR 158c2c66affSColin Finck 159c2c66affSColin Finck ULONG Flags; 160c2c66affSColin Finck BOOLEAN CacheWholePacket; 161c2c66affSColin Finck BOOLEAN DoNotCompare; 162c2c66affSColin Finck BOOLEAN Chained; 163c2c66affSColin Finck BOOLEAN RememberBB; 164c2c66affSColin Finck BOOLEAN NoWriteBB; 165c2c66affSColin Finck BOOLEAN NoWriteThrough; 166c2c66affSColin Finck UCHAR Padding[2]; 167c2c66affSColin Finck 168c2c66affSColin Finck ULONG RBalance; 169c2c66affSColin Finck ULONG WBalance; 170c2c66affSColin Finck ULONG FramesToKeepFree; 171c2c66affSColin Finck // callbacks 172c2c66affSColin Finck PWRITE_BLOCK WriteProc; 173c2c66affSColin Finck PREAD_BLOCK ReadProc; 174c2c66affSColin Finck PWRITE_BLOCK_ASYNC WriteProcAsync; 175c2c66affSColin Finck PREAD_BLOCK_ASYNC ReadProcAsync; 176c2c66affSColin Finck PCHECK_BLOCK CheckUsedProc; 177c2c66affSColin Finck PUPDATE_RELOC UpdateRelocProc; 178c2c66affSColin Finck PWC_ERROR_HANDLER ErrorHandlerProc; 179c2c66affSColin Finck // sync resource 180c2c66affSColin Finck ERESOURCE WCacheLock; 181c2c66affSColin Finck // BOOLEAN WCResInit; 182c2c66affSColin Finck // preallocated tmp buffers 183c2c66affSColin Finck PCHAR tmp_buff; 184c2c66affSColin Finck PCHAR tmp_buff_r; 185c2c66affSColin Finck PULONG reloc_tab; 186c2c66affSColin Finck 187c2c66affSColin Finck } W_CACHE, *PW_CACHE; 188c2c66affSColin Finck 189c2c66affSColin Finck #define WCACHE_INVALID_LBA ((lba_t)(-1)) 190c2c66affSColin Finck 191c2c66affSColin Finck #define WCACHE_CACHE_WHOLE_PACKET 0x01 192c2c66affSColin Finck #define WCACHE_DO_NOT_COMPARE 0x02 193c2c66affSColin Finck #define WCACHE_CHAINED_IO 0x04 194c2c66affSColin Finck #define WCACHE_MARK_BAD_BLOCKS 0x08 195c2c66affSColin Finck #define WCACHE_RO_BAD_BLOCKS 0x10 196c2c66affSColin Finck #define WCACHE_NO_WRITE_THROUGH 0x20 197c2c66affSColin Finck 198c2c66affSColin Finck #define WCACHE_VALID_FLAGS (WCACHE_CACHE_WHOLE_PACKET | \ 199c2c66affSColin Finck WCACHE_DO_NOT_COMPARE | \ 200c2c66affSColin Finck WCACHE_CHAINED_IO | \ 201c2c66affSColin Finck WCACHE_MARK_BAD_BLOCKS | \ 202c2c66affSColin Finck WCACHE_RO_BAD_BLOCKS | \ 203c2c66affSColin Finck WCACHE_NO_WRITE_THROUGH) 204c2c66affSColin Finck 205c2c66affSColin Finck #define WCACHE_INVALID_FLAGS (0xffffffff) 206c2c66affSColin Finck 207c2c66affSColin Finck // init cache 208c2c66affSColin Finck OSSTATUS WCacheInit__(IN PW_CACHE Cache, 209c2c66affSColin Finck IN ULONG MaxFrames, 210c2c66affSColin Finck IN ULONG MaxBlocks, 211*c334c17dSTimo Kreuzer IN SIZE_T MaxBytesToRead, 212c2c66affSColin Finck IN ULONG PacketSizeSh, // number of blocks in packet (bit shift) 213c2c66affSColin Finck IN ULONG BlockSizeSh, // bit shift 214c2c66affSColin Finck IN ULONG BlocksPerFrameSh,// bit shift 215c2c66affSColin Finck IN lba_t FirstLba, 216c2c66affSColin Finck IN lba_t LastLba, 217c2c66affSColin Finck IN ULONG Mode, 218c2c66affSColin Finck IN ULONG Flags, 219c2c66affSColin Finck IN ULONG FramesToKeepFree, 220c2c66affSColin Finck IN PWRITE_BLOCK WriteProc, 221c2c66affSColin Finck IN PREAD_BLOCK ReadProc, 222c2c66affSColin Finck IN PWRITE_BLOCK_ASYNC WriteProcAsync, 223c2c66affSColin Finck IN PREAD_BLOCK_ASYNC ReadProcAsync, 224c2c66affSColin Finck IN PCHECK_BLOCK CheckUsedProc, 225c2c66affSColin Finck IN PUPDATE_RELOC UpdateRelocProc, 226c2c66affSColin Finck IN PWC_ERROR_HANDLER ErrorHandlerProc); 227c2c66affSColin Finck // write cached 228c2c66affSColin Finck OSSTATUS WCacheWriteBlocks__(IN PW_CACHE Cache, 229c2c66affSColin Finck IN PVOID Context, 230c2c66affSColin Finck IN PCHAR Buffer, 231c2c66affSColin Finck IN lba_t Lba, 232c2c66affSColin Finck IN ULONG BCount, 233*c334c17dSTimo Kreuzer OUT PSIZE_T WrittenBytes, 234c2c66affSColin Finck IN BOOLEAN CachedOnly); 235c2c66affSColin Finck // read cached 236c2c66affSColin Finck OSSTATUS WCacheReadBlocks__(IN PW_CACHE Cache, 237c2c66affSColin Finck IN PVOID Context, 238c2c66affSColin Finck IN PCHAR Buffer, 239c2c66affSColin Finck IN lba_t Lba, 240c2c66affSColin Finck IN ULONG BCount, 241*c334c17dSTimo Kreuzer OUT PSIZE_T ReadBytes, 242c2c66affSColin Finck IN BOOLEAN CachedOnly); 243c2c66affSColin Finck // flush blocks 244c2c66affSColin Finck OSSTATUS WCacheFlushBlocks__(IN PW_CACHE Cache, 245c2c66affSColin Finck IN PVOID Context, 246c2c66affSColin Finck IN lba_t Lba, 247c2c66affSColin Finck IN ULONG BCount); 248c2c66affSColin Finck // discard blocks 249c2c66affSColin Finck VOID WCacheDiscardBlocks__(IN PW_CACHE Cache, 250c2c66affSColin Finck IN PVOID Context, 251c2c66affSColin Finck IN lba_t Lba, 252c2c66affSColin Finck IN ULONG BCount); 253c2c66affSColin Finck // flush whole cache 254c2c66affSColin Finck VOID WCacheFlushAll__(IN PW_CACHE Cache, 255c2c66affSColin Finck IN PVOID Context); 256c2c66affSColin Finck // purge whole cache 257c2c66affSColin Finck VOID WCachePurgeAll__(IN PW_CACHE Cache, 258c2c66affSColin Finck IN PVOID Context); 259c2c66affSColin Finck // free structures 260c2c66affSColin Finck VOID WCacheRelease__(IN PW_CACHE Cache); 261c2c66affSColin Finck 262c2c66affSColin Finck // check if initialized 263c2c66affSColin Finck BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache); 264c2c66affSColin Finck 265c2c66affSColin Finck // direct access to cached data 266c2c66affSColin Finck OSSTATUS WCacheDirect__(IN PW_CACHE Cache, 267c2c66affSColin Finck IN PVOID Context, 268c2c66affSColin Finck IN lba_t Lba, 269c2c66affSColin Finck IN BOOLEAN Modified, 270c2c66affSColin Finck OUT PCHAR* CachedBlock, 271c2c66affSColin Finck IN BOOLEAN CachedOnly); 272c2c66affSColin Finck // release resources after direct access 273c2c66affSColin Finck OSSTATUS WCacheEODirect__(IN PW_CACHE Cache, 274c2c66affSColin Finck IN PVOID Context); 275c2c66affSColin Finck // release resources before direct access 276c2c66affSColin Finck OSSTATUS WCacheStartDirect__(IN PW_CACHE Cache, 277c2c66affSColin Finck IN PVOID Context, 278c2c66affSColin Finck IN BOOLEAN Exclusive); 279c2c66affSColin Finck // check if requested extent completly cached 280c2c66affSColin Finck BOOLEAN WCacheIsCached__(IN PW_CACHE Cache, 281c2c66affSColin Finck IN lba_t Lba, 282c2c66affSColin Finck IN ULONG BCount); 283c2c66affSColin Finck 284c2c66affSColin Finck // change cache media mode 285c2c66affSColin Finck OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, 286c2c66affSColin Finck IN ULONG Mode); 287c2c66affSColin Finck // 288c2c66affSColin Finck ULONG WCacheGetMode__(IN PW_CACHE Cache); 289c2c66affSColin Finck // 290c2c66affSColin Finck ULONG WCacheGetWriteBlockCount__(IN PW_CACHE Cache); 291c2c66affSColin Finck // 292c2c66affSColin Finck VOID WCacheSyncReloc__(IN PW_CACHE Cache, 293c2c66affSColin Finck IN PVOID Context); 294c2c66affSColin Finck 295c2c66affSColin Finck VOID WCacheDiscardBlocks__(IN PW_CACHE Cache, 296c2c66affSColin Finck IN PVOID Context, 297c2c66affSColin Finck IN lba_t ReqLba, 298c2c66affSColin Finck IN ULONG BCount); 299c2c66affSColin Finck 300c2c66affSColin Finck ULONG WCacheChFlags__(IN PW_CACHE Cache, 301c2c66affSColin Finck IN ULONG SetFlags, 302c2c66affSColin Finck IN ULONG ClrFlags); 303c2c66affSColin Finck 304c2c66affSColin Finck }; 305c2c66affSColin Finck 306c2c66affSColin Finck // complete async request (callback) 307c2c66affSColin Finck OSSTATUS WCacheCompleteAsync__(IN PVOID WContext, 308c2c66affSColin Finck IN OSSTATUS Status); 309c2c66affSColin Finck 310c2c66affSColin Finck #endif // __CDRW_WCACHE_LIB_H__ 311