mirror of
https://github.com/reactos/reactos.git
synced 2024-09-10 04:42:00 +00:00
311 lines
11 KiB
C
311 lines
11 KiB
C
////////////////////////////////////////////////////////////////////
|
|
// 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__
|