inc: winfsp: add Service class

This commit is contained in:
Bill Zissimopoulos 2017-03-28 17:32:19 -07:00
parent 0189adac8f
commit fac270e596
2 changed files with 193 additions and 70 deletions

View File

@ -25,9 +25,26 @@
#include <winfsp/winfsp.h> #include <winfsp/winfsp.h>
/*
* Convert C++ exceptions to STATUS_CPP_EH_EXCEPTION. This is known in the CRT sources
* as EH_EXCEPTION_NUMBER and its value is 0xE06D7363 (== 'msc' | 0xE0000000).
*
* See https://msdn.microsoft.com/en-us/library/windows/hardware/ff558784(v=vs.85).aspx
* See Visual Studio CRT sources.
*/
#define FSP_CPP_CALLBACK_PROLOG try {
#define FSP_CPP_CALLBACK_EPILOG } catch (...) { return 0xE06D7363; }
#define FSP_CPP_CALLBACK_EPILOG_VOID } catch (...) { return; }
namespace Fsp namespace Fsp
{ {
inline NTSTATUS Initialize()
{
static NTSTATUS LoadResult = FspLoad(0);
return LoadResult;
}
class FileSystem class FileSystem
{ {
public: public:
@ -56,6 +73,7 @@ public:
/* ctor/dtor */ /* ctor/dtor */
FileSystem() : _VolumeParams(), _FileSystem(0) FileSystem() : _VolumeParams(), _FileSystem(0)
{ {
Initialize();
_VolumeParams.SectorSize = 4096; _VolumeParams.SectorSize = 4096;
_VolumeParams.SectorsPerAllocationUnit = 1; _VolumeParams.SectorsPerAllocationUnit = 1;
_VolumeParams.MaxComponentLength = 255; _VolumeParams.MaxComponentLength = 255;
@ -407,42 +425,39 @@ protected:
private: private:
/* FSP_FILE_SYSTEM_INTERFACE */ /* FSP_FILE_SYSTEM_INTERFACE */
#define FSP_FSOP_PROLOG try {
#define FSP_FSOP_EPILOG } catch (...) { return STATUS_UNEXPECTED_IO_ERROR; }
#define FSP_FSOP_EPILOG_VOID } catch (...) { return; }
static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem0,
VOLUME_INFO *VolumeInfo) VOLUME_INFO *VolumeInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
return self->GetVolumeInfo(VolumeInfo); return self->GetVolumeInfo(VolumeInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS SetVolumeLabel_(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS SetVolumeLabel_(FSP_FILE_SYSTEM *FileSystem0,
PWSTR VolumeLabel, PWSTR VolumeLabel,
VOLUME_INFO *VolumeInfo) VOLUME_INFO *VolumeInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
return self->SetVolumeLabel_(VolumeLabel, VolumeInfo); return self->SetVolumeLabel_(VolumeLabel, VolumeInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem0,
PWSTR FileName, PUINT32 PFileAttributes/* or ReparsePointIndex */, PWSTR FileName, PUINT32 PFileAttributes/* or ReparsePointIndex */,
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
return self->GetSecurityByName( return self->GetSecurityByName(
FileName, PFileAttributes, SecurityDescriptor, PSecurityDescriptorSize); FileName, PFileAttributes, SecurityDescriptor, PSecurityDescriptorSize);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem0,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize,
PVOID *FullContext, FILE_INFO *FileInfo) PVOID *FullContext, FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext = { 0 }; FILE_CONTEXT FileContext = { 0 };
NTSTATUS Result = self->Create( NTSTATUS Result = self->Create(
@ -451,13 +466,13 @@ private:
((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = (UINT64)(UINT_PTR)FileContext.FileNode; ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = (UINT64)(UINT_PTR)FileContext.FileNode;
((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = (UINT64)(UINT_PTR)FileContext.FileDesc; ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = (UINT64)(UINT_PTR)FileContext.FileDesc;
return Result; return Result;
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem0,
PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess,
PVOID *FullContext, FILE_INFO *FileInfo) PVOID *FullContext, FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext = { 0 }; FILE_CONTEXT FileContext = { 0 };
NTSTATUS Result = self->Open( NTSTATUS Result = self->Open(
@ -466,99 +481,99 @@ private:
((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = (UINT64)(UINT_PTR)FileContext.FileNode; ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext = (UINT64)(UINT_PTR)FileContext.FileNode;
((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = (UINT64)(UINT_PTR)FileContext.FileDesc; ((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2 = (UINT64)(UINT_PTR)FileContext.FileDesc;
return Result; return Result;
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, PVOID FullContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize,
FILE_INFO *FileInfo) FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Overwrite(&FileContext, FileAttributes, ReplaceFileAttributes, AllocationSize, return self->Overwrite(&FileContext, FileAttributes, ReplaceFileAttributes, AllocationSize,
FileInfo); FileInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem0, static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PWSTR FileName, ULONG Flags) PVOID FullContext, PWSTR FileName, ULONG Flags)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Cleanup(&FileContext, FileName, (CLEANUP_FLAGS)Flags); return self->Cleanup(&FileContext, FileName, (CLEANUP_FLAGS)Flags);
FSP_FSOP_EPILOG_VOID FSP_CPP_CALLBACK_EPILOG_VOID
} }
static VOID Close(FSP_FILE_SYSTEM *FileSystem0, static VOID Close(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext) PVOID FullContext)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Close(&FileContext); return self->Close(&FileContext);
FSP_FSOP_EPILOG_VOID FSP_CPP_CALLBACK_EPILOG_VOID
} }
static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID Buffer, UINT64 Offset, ULONG Length, PVOID FullContext, PVOID Buffer, UINT64 Offset, ULONG Length,
PULONG PBytesTransferred) PULONG PBytesTransferred)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Read(&FileContext, Buffer, Offset, Length, PBytesTransferred); return self->Read(&FileContext, Buffer, Offset, Length, PBytesTransferred);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID Buffer, UINT64 Offset, ULONG Length, PVOID FullContext, PVOID Buffer, UINT64 Offset, ULONG Length,
BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo,
PULONG PBytesTransferred, FILE_INFO *FileInfo) PULONG PBytesTransferred, FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Write(&FileContext, Buffer, Offset, Length, WriteToEndOfFile, ConstrainedIo, return self->Write(&FileContext, Buffer, Offset, Length, WriteToEndOfFile, ConstrainedIo,
PBytesTransferred, FileInfo); PBytesTransferred, FileInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
FILE_INFO *FileInfo) FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Flush(&FileContext, FileInfo); return self->Flush(&FileContext, FileInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
FILE_INFO *FileInfo) FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->GetFileInfo(&FileContext, FileInfo); return self->GetFileInfo(&FileContext, FileInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, UINT32 FileAttributes, PVOID FullContext, UINT32 FileAttributes,
UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime, UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime,
FILE_INFO *FileInfo) FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
@ -566,149 +581,146 @@ private:
return self->SetBasicInfo(&FileContext, FileAttributes, return self->SetBasicInfo(&FileContext, FileAttributes,
CreationTime, LastAccessTime, LastWriteTime, ChangeTime, CreationTime, LastAccessTime, LastWriteTime, ChangeTime,
FileInfo); FileInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, UINT64 NewSize, BOOLEAN SetAllocationSize, PVOID FullContext, UINT64 NewSize, BOOLEAN SetAllocationSize,
FILE_INFO *FileInfo) FILE_INFO *FileInfo)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->SetFileSize(&FileContext, NewSize, SetAllocationSize, FileInfo); return self->SetFileSize(&FileContext, NewSize, SetAllocationSize, FileInfo);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS CanDelete(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS CanDelete(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PWSTR FileName) PVOID FullContext, PWSTR FileName)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->CanDelete(&FileContext, FileName); return self->CanDelete(&FileContext, FileName);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->Rename(&FileContext, FileName, NewFileName, ReplaceIfExists); return self->Rename(&FileContext, FileName, NewFileName, ReplaceIfExists);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->GetSecurity(&FileContext, SecurityDescriptor, PSecurityDescriptorSize); return self->GetSecurity(&FileContext, SecurityDescriptor, PSecurityDescriptorSize);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor) SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->SetSecurity(&FileContext, SecurityInformation, ModificationDescriptor); return self->SetSecurity(&FileContext, SecurityInformation, ModificationDescriptor);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PWSTR Pattern, PWSTR Marker, PVOID FullContext, PWSTR Pattern, PWSTR Marker,
PVOID Buffer, ULONG Length, PULONG PBytesTransferred) PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->ReadDirectory(&FileContext, Pattern, Marker, Buffer, Length, PBytesTransferred); return self->ReadDirectory(&FileContext, Pattern, Marker, Buffer, Length, PBytesTransferred);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem0,
PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent,
PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
return self->ResolveReparsePoints(FileName, ReparsePointIndex, ResolveLastPathComponent, return self->ResolveReparsePoints(FileName, ReparsePointIndex, ResolveLastPathComponent,
PIoStatus, Buffer, PSize); PIoStatus, Buffer, PSize);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS GetReparsePointByName( static NTSTATUS GetReparsePointByName(
FSP_FILE_SYSTEM *FileSystem0, PVOID Context, FSP_FILE_SYSTEM *FileSystem0, PVOID Context,
PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize) PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
return self->GetReparsePointByName(FileName, IsDirectory, Buffer, PSize); return self->GetReparsePointByName(FileName, IsDirectory, Buffer, PSize);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS GetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS GetReparsePoint(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
PWSTR FileName, PVOID Buffer, PSIZE_T PSize) PWSTR FileName, PVOID Buffer, PSIZE_T PSize)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->GetReparsePoint(&FileContext, FileName, Buffer, PSize); return self->GetReparsePoint(&FileContext, FileName, Buffer, PSize);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS SetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS SetReparsePoint(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
PWSTR FileName, PVOID Buffer, SIZE_T Size) PWSTR FileName, PVOID Buffer, SIZE_T Size)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->SetReparsePoint(&FileContext, FileName, Buffer, Size); return self->SetReparsePoint(&FileContext, FileName, Buffer, Size);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID FullContext,
PWSTR FileName, PVOID Buffer, SIZE_T Size) PWSTR FileName, PVOID Buffer, SIZE_T Size)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->DeleteReparsePoint(&FileContext, FileName, Buffer, Size); return self->DeleteReparsePoint(&FileContext, FileName, Buffer, Size);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem0, static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem0,
PVOID FullContext, PVOID Buffer, ULONG Length, PVOID FullContext, PVOID Buffer, ULONG Length,
PULONG PBytesTransferred) PULONG PBytesTransferred)
{ {
FSP_FSOP_PROLOG FSP_CPP_CALLBACK_PROLOG
FileSystem *self = (FileSystem *)FileSystem0->UserContext; FileSystem *self = (FileSystem *)FileSystem0->UserContext;
FILE_CONTEXT FileContext; FILE_CONTEXT FileContext;
FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext;
FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2;
return self->GetStreamInfo(&FileContext, Buffer, Length, PBytesTransferred); return self->GetStreamInfo(&FileContext, Buffer, Length, PBytesTransferred);
FSP_FSOP_EPILOG FSP_CPP_CALLBACK_EPILOG
} }
#undef FSP_FSOP_PROLOG
#undef FSP_FSOP_EPILOG
#undef FSP_FSOP_EPILOG_VOID
static FSP_FILE_SYSTEM_INTERFACE *Interface() static FSP_FILE_SYSTEM_INTERFACE *Interface()
{ {
static FSP_FILE_SYSTEM_INTERFACE _Interface = static FSP_FILE_SYSTEM_INTERFACE _Interface =
@ -751,6 +763,104 @@ private:
FSP_FILE_SYSTEM *_FileSystem; FSP_FILE_SYSTEM *_FileSystem;
}; };
class Service
{
public:
/* ctor/dtor */
Service(PWSTR ServiceName) : _Service(0), _CreateResult()
{
Initialize();
_CreateResult = FspServiceCreate(ServiceName, OnStart, OnStop, 0, &_Service);
if (!NT_SUCCESS(_CreateResult))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"The service %s cannot be created (Status=%lx).", ServiceName, _CreateResult);
return;
}
_Service->UserContext = this;
}
virtual ~Service()
{
if (0 != _Service)
FspServiceDelete(_Service);
}
/* control */
ULONG Run()
{
if (!NT_SUCCESS(_CreateResult))
return FspWin32FromNtStatus(_CreateResult);
FspServiceAllowConsoleMode(_Service);
NTSTATUS Result = FspServiceLoop(_Service);
ULONG ExitCode = FspServiceGetExitCode(_Service);
if (!NT_SUCCESS(Result))
{
FspServiceLog(EVENTLOG_ERROR_TYPE,
L"The service %s has failed to run (Status=%lx).", _Service->ServiceName, Result);
return FspWin32FromNtStatus(Result);
}
return ExitCode;
}
VOID Stop()
{
if (!NT_SUCCESS(_CreateResult))
return;
FspServiceStop(_Service);
}
static VOID Log(ULONG Type, PWSTR Format, ...)
{
va_list ap;
va_start(ap, Format);
FspServiceLogV(Type, Format, ap);
va_end(ap);
}
static VOID LogV(ULONG Type, PWSTR Format, va_list ap)
{
FspServiceLogV(Type, Format, ap);
}
protected:
/* virtuals */
virtual NTSTATUS OnStart(ULONG Argc, PWSTR *Argv)
{
return STATUS_SUCCESS;
}
virtual NTSTATUS OnStop()
{
return STATUS_SUCCESS;
}
private:
/* callbacks */
static NTSTATUS OnStart(FSP_SERVICE *Service0, ULONG Argc, PWSTR *Argv)
{
FSP_CPP_CALLBACK_PROLOG
Service *self = (Service *)Service0->UserContext;
return self->OnStart(Argc, Argv);
FSP_CPP_CALLBACK_EPILOG
}
static NTSTATUS OnStop(FSP_SERVICE *Service0)
{
FSP_CPP_CALLBACK_PROLOG
Service *self = (Service *)Service0->UserContext;
return self->OnStop();
FSP_CPP_CALLBACK_EPILOG
}
private:
/* disallow copy and assignment */
Service(const Service &);
Service &operator=(const Service &);
private:
FSP_SERVICE *_Service;
NTSTATUS _CreateResult;
};
} }
#undef FSP_CPP_CALLBACK_PROLOG
#undef FSP_CPP_CALLBACK_EPILOG
#undef FSP_CPP_CALLBACK_EPILOG_VOID
#endif #endif

View File

@ -23,9 +23,9 @@
#define ALLOCATION_UNIT 4096 #define ALLOCATION_UNIT 4096
#define FULLPATH_SIZE (MAX_PATH + FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)) #define FULLPATH_SIZE (MAX_PATH + FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR))
#define info(format, ...) FspServiceLog(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__) #define info(format, ...) Fsp::Service::Log(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__)
#define warn(format, ...) FspServiceLog(EVENTLOG_WARNING_TYPE, format, __VA_ARGS__) #define warn(format, ...) Fsp::Service::Log(EVENTLOG_WARNING_TYPE, format, __VA_ARGS__)
#define fail(format, ...) FspServiceLog(EVENTLOG_ERROR_TYPE, format, __VA_ARGS__) #define fail(format, ...) Fsp::Service::Log(EVENTLOG_ERROR_TYPE, format, __VA_ARGS__)
#define ConcatPath(FN, FP) (0 == StringCbPrintfW(FP, sizeof FP, L"%s%s", _Path, FN)) #define ConcatPath(FN, FP) (0 == StringCbPrintfW(FP, sizeof FP, L"%s%s", _Path, FN))
#define HandleFromContext(FC) ((PTFS_FILE_DESC *)FileContext->FileDesc)->Handle #define HandleFromContext(FC) ((PTFS_FILE_DESC *)FileContext->FileDesc)->Handle
@ -698,6 +698,19 @@ NTSTATUS PTFS::ReadDirectory(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
class PTFS_SERVICE : public Fsp::Service
{
public:
PTFS_SERVICE();
protected:
NTSTATUS OnStart(ULONG Argc, PWSTR *Argv);
NTSTATUS OnStop();
private:
PTFS *_Ptfs;
};
static NTSTATUS EnableBackupRestorePrivileges(VOID) static NTSTATUS EnableBackupRestorePrivileges(VOID)
{ {
union union
@ -737,7 +750,11 @@ static ULONG wcstol_deflt(wchar_t *w, ULONG deflt)
return L'\0' != w[0] && L'\0' == *endp ? ul : deflt; return L'\0' != w[0] && L'\0' == *endp ? ul : deflt;
} }
static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) PTFS_SERVICE::PTFS_SERVICE() : Fsp::Service(L"" PROGNAME)
{
}
NTSTATUS PTFS_SERVICE::OnStart(ULONG argc, PWSTR *argv)
{ {
#define argtos(v) if (arge > ++argp) v = *argp; else goto usage #define argtos(v) if (arge > ++argp) v = *argp; else goto usage
#define argtol(v) if (arge > ++argp) v = wcstol_deflt(*argp, v); else goto usage #define argtol(v) if (arge > ++argp) v = wcstol_deflt(*argp, v); else goto usage
@ -859,7 +876,7 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
PassThrough, PassThrough,
MountPoint); MountPoint);
Service->UserContext = Ptfs; _Ptfs = Ptfs;
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
exit: exit:
@ -887,20 +904,16 @@ usage:
#undef argtol #undef argtol
} }
static NTSTATUS SvcStop(FSP_SERVICE *Service) NTSTATUS PTFS_SERVICE::OnStop()
{ {
PTFS *Ptfs = (PTFS *)Service->UserContext; _Ptfs->Unmount();
delete _Ptfs;
Ptfs->Unmount(); _Ptfs = 0;
delete Ptfs;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
int wmain(int argc, wchar_t **argv) int wmain(int argc, wchar_t **argv)
{ {
if (!NT_SUCCESS(FspLoad(0))) return PTFS_SERVICE().Run();
return ERROR_DELAY_LOAD_FAILED;
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
} }