163 lines
7.6 KiB
C
163 lines
7.6 KiB
C
// Public nt-lite DDK filesystem and mounted-volume declarations.
|
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <stdbool.h>
|
|
#include <ntlite/status.h>
|
|
#include <ntlite/string_view.h>
|
|
#include <ntlite/dirent.h>
|
|
#include <ntlite/file_stat.h>
|
|
#include <ntlite/ddk/async.h>
|
|
#include <ntlite/ddk/object.h>
|
|
#include <ntlite/ddk/sync.h>
|
|
|
|
typedef SYS_DIR_ENTRY KDIR_ENTRY;
|
|
#define KDIR_NAME_MAX SYS_DIR_NAME_MAX
|
|
|
|
typedef void (*IO_FS_ASYNC_COMPLETE)(void* completeContext,
|
|
KSTATUS status,
|
|
size_t information);
|
|
|
|
typedef struct IO_FILESYSTEM_STATS {
|
|
uint64_t PathLookups;
|
|
uint64_t PathCacheHits;
|
|
uint64_t PathCacheMisses;
|
|
uint64_t PathCacheStores;
|
|
uint64_t PathCacheInvalidations;
|
|
uint64_t PathCacheGeneration;
|
|
uint64_t DirectorySearches;
|
|
uint64_t DirectoryBlocksRead;
|
|
uint64_t DirectoryEntriesScanned;
|
|
uint64_t DataReadRuns;
|
|
uint64_t DataReadSectors;
|
|
uint64_t DataReadRunMerges;
|
|
uint64_t MaxDataReadSpanSectors;
|
|
} IO_FILESYSTEM_STATS;
|
|
|
|
typedef struct IO_FILE_IDENTITY {
|
|
uint64_t VolumeId;
|
|
uint64_t FileId;
|
|
uint64_t Generation;
|
|
uint64_t Size;
|
|
} IO_FILE_IDENTITY;
|
|
|
|
typedef enum IO_VOLUME_REMOVAL_REASON {
|
|
IoVolumeUnmounted = 1,
|
|
IoVolumeBackingRemoved,
|
|
IoVolumeProviderDead,
|
|
} IO_VOLUME_REMOVAL_REASON;
|
|
|
|
// Kernel filesystem providers implement this backend. IO_VOLUME owns a copy of
|
|
// the dispatch and keeps Context alive until all file and directory references drain.
|
|
typedef struct IO_VOLUME_PROVIDER {
|
|
KSTATUS (*Open)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW path, void** fileCtx);
|
|
KSTATUS (*Read)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, uint64_t offset, void* buf, size_t size, size_t* bytesRead);
|
|
KSTATUS (*Write)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten);
|
|
KSTATUS (*ReadAsync)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, uint64_t offset, void* buf, size_t size, IO_FS_ASYNC_COMPLETE complete, void* completeContext);
|
|
KSTATUS (*WriteAsync)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, uint64_t offset, const void* buf, size_t size, IO_FS_ASYNC_COMPLETE complete, void* completeContext);
|
|
KSTATUS (*Create)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW path, void** fileCtx);
|
|
KSTATUS (*Delete)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW path);
|
|
KSTATUS (*Rename)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW oldPath, SYS_STRING_VIEW newPath);
|
|
KSTATUS (*CreateDir)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW path);
|
|
KSTATUS (*RemoveDir)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW path);
|
|
KSTATUS (*Truncate)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, uint64_t newSize, uint32_t fileFlags);
|
|
uint64_t (*GetSize)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx);
|
|
KSTATUS (*QueryInfo)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, SYS_FILE_STAT* out);
|
|
KSTATUS (*Stat)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW path, SYS_FILE_STAT* out);
|
|
KSTATUS (*QueryIdentity)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx, IO_FILE_IDENTITY* out);
|
|
KSTATUS (*Flush)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx);
|
|
void (*Close)(struct IO_VOLUME_PROVIDER* provider, void* fileCtx);
|
|
void (*QueryStats)(struct IO_VOLUME_PROVIDER* provider, IO_FILESYSTEM_STATS* out);
|
|
KSTATUS (*OpenDir)(struct IO_VOLUME_PROVIDER* provider, SYS_STRING_VIEW dirPath, void** dirCtx);
|
|
KSTATUS (*ReadDir)(struct IO_VOLUME_PROVIDER* provider, void* dirCtx, KDIR_ENTRY* out);
|
|
void (*CloseDir)(struct IO_VOLUME_PROVIDER* provider, void* dirCtx);
|
|
|
|
// Called once when the mounted volume becomes unusable. It must not free Context.
|
|
void (*VolumeDead)(struct IO_VOLUME_PROVIDER* provider, IO_VOLUME_REMOVAL_REASON reason);
|
|
|
|
// Called once after the final IO_VOLUME/file/directory reference drains.
|
|
void (*Destroy)(struct IO_VOLUME_PROVIDER* provider);
|
|
void* Context;
|
|
} IO_VOLUME_PROVIDER;
|
|
|
|
typedef struct IO_VOLUME IO_VOLUME;
|
|
|
|
struct EVENT;
|
|
struct KAPC;
|
|
typedef struct MM_LOCKED_USER_BUFFER MM_LOCKED_USER_BUFFER;
|
|
typedef struct IO_ASYNC_FILE_REQUEST_OBJECT IO_ASYNC_FILE_REQUEST_OBJECT;
|
|
|
|
#define IO_FILE_FLAG_NO_CACHE 0x00000001u
|
|
#define IO_FILE_FLAG_SKIP_ZERO_EXTEND 0x00000002u
|
|
#define IO_FILE_FLAG_APPEND 0x00000004u
|
|
|
|
typedef struct FILE_OBJECT {
|
|
OBJECT Header;
|
|
IO_VOLUME* Volume;
|
|
void* FileCtx;
|
|
SPINLOCK Lock;
|
|
uint64_t Size;
|
|
uint64_t Offset;
|
|
uint32_t Flags;
|
|
} FILE_OBJECT;
|
|
|
|
typedef struct DIR_OBJECT {
|
|
OBJECT Header;
|
|
IO_VOLUME* Volume;
|
|
void* DirCtx;
|
|
char* Path;
|
|
size_t PathLength;
|
|
} DIR_OBJECT;
|
|
|
|
typedef enum IO_VOLUME_SOURCE_TYPE {
|
|
IoVolumeSourcePartition = 1,
|
|
IoVolumeSourceBlockDevice,
|
|
} IO_VOLUME_SOURCE_TYPE;
|
|
|
|
typedef struct IO_VOLUME_SOURCE {
|
|
uint32_t Type;
|
|
uint8_t DiskIndex;
|
|
uint8_t Reserved[3];
|
|
uint64_t StartLba;
|
|
uint64_t SectorCount;
|
|
} IO_VOLUME_SOURCE;
|
|
|
|
// Creates a mounted, refcounted volume and returns one caller reference.
|
|
__declspec(dllexport) KSTATUS IoCreateVolume(const IO_VOLUME_PROVIDER* provider,
|
|
const IO_VOLUME_SOURCE* source,
|
|
IO_VOLUME** volumeOut);
|
|
|
|
// Marks a volume dead, removes it from the mounted-volume registry, and rejects future provider I/O.
|
|
__declspec(dllexport) KSTATUS IoRemoveVolume(IO_VOLUME* volume, IO_VOLUME_REMOVAL_REASON reason);
|
|
|
|
// Releases a caller-owned volume reference returned by IoCreateVolume.
|
|
__declspec(dllexport) void IoReleaseVolume(IO_VOLUME* volume);
|
|
|
|
// Returns the monotonic runtime instance identifier assigned to a mounted volume.
|
|
__declspec(dllexport) uint32_t IoGetVolumeInstanceId(const IO_VOLUME* volume);
|
|
|
|
// Returns the immutable block source associated with a mounted volume.
|
|
__declspec(dllexport) KSTATUS IoGetVolumeSource(const IO_VOLUME* volume, IO_VOLUME_SOURCE* sourceOut);
|
|
|
|
__declspec(dllexport) void IoQueryFilesystemStats(IO_FILESYSTEM_STATS* out);
|
|
// Capability-relative native opens. Paths are canonical relative paths: '/' separators only,
|
|
// no leading/trailing separator, empty components, '.', '..', backslash, or embedded NUL.
|
|
__declspec(dllexport) KSTATUS IoOpenFileAtVolume(IO_VOLUME* volume, SYS_STRING_VIEW path, FILE_OBJECT** out);
|
|
__declspec(dllexport) KSTATUS IoCreateFileAtVolume(IO_VOLUME* volume, SYS_STRING_VIEW path, FILE_OBJECT** out);
|
|
__declspec(dllexport) KSTATUS IoOpenDirAtVolume(IO_VOLUME* volume, SYS_STRING_VIEW path, DIR_OBJECT** out);
|
|
__declspec(dllexport) KSTATUS IoReadFile(FILE_OBJECT* file, void* buf, size_t size, size_t* bytesRead);
|
|
__declspec(dllexport) KSTATUS IoReadFileAt(FILE_OBJECT* file, uint64_t offset, void* buf, size_t size, size_t* bytesRead);
|
|
__declspec(dllexport) KSTATUS IoWriteFile(FILE_OBJECT* file, const void* buf, size_t size, size_t* bytesWritten);
|
|
__declspec(dllexport) KSTATUS IoWriteFileAt(FILE_OBJECT* file, uint64_t offset, const void* buf, size_t size, size_t* bytesWritten);
|
|
__declspec(dllexport) KSTATUS IoFlushFile(FILE_OBJECT* file);
|
|
__declspec(dllexport) KSTATUS IoTruncateFile(FILE_OBJECT* file, uint64_t newSize);
|
|
__declspec(dllexport) KSTATUS IoSeekFile(FILE_OBJECT* file, uint64_t offset);
|
|
__declspec(dllexport) uint64_t IoGetFileSize(FILE_OBJECT* file);
|
|
__declspec(dllexport) KSTATUS IoGetFileStat(FILE_OBJECT* file, SYS_FILE_STAT* out);
|
|
__declspec(dllexport) KSTATUS IoQueryFileIdentity(FILE_OBJECT* file, IO_FILE_IDENTITY* out);
|
|
__declspec(dllexport) void IoCloseFile(FILE_OBJECT* file);
|
|
__declspec(dllexport) KSTATUS IoReadDir(DIR_OBJECT* dir, KDIR_ENTRY* entryOut);
|
|
__declspec(dllexport) void IoCloseDir(DIR_OBJECT* dir);
|