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