diff --git a/inc/winfsp/winfsp.hpp b/inc/winfsp/winfsp.hpp index af5d5c0e..346f40d3 100644 --- a/inc/winfsp/winfsp.hpp +++ b/inc/winfsp/winfsp.hpp @@ -25,9 +25,26 @@ #include +/* + * 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 { +inline NTSTATUS Initialize() +{ + static NTSTATUS LoadResult = FspLoad(0); + return LoadResult; +} + class FileSystem { public: @@ -56,6 +73,7 @@ public: /* ctor/dtor */ FileSystem() : _VolumeParams(), _FileSystem(0) { + Initialize(); _VolumeParams.SectorSize = 4096; _VolumeParams.SectorsPerAllocationUnit = 1; _VolumeParams.MaxComponentLength = 255; @@ -407,42 +425,39 @@ protected: private: /* 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, VOLUME_INFO *VolumeInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; return self->GetVolumeInfo(VolumeInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS SetVolumeLabel_(FSP_FILE_SYSTEM *FileSystem0, PWSTR VolumeLabel, VOLUME_INFO *VolumeInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; return self->SetVolumeLabel_(VolumeLabel, VolumeInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS GetSecurityByName(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, PUINT32 PFileAttributes/* or ReparsePointIndex */, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; return self->GetSecurityByName( FileName, PFileAttributes, SecurityDescriptor, PSecurityDescriptorSize); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, UINT32 FileAttributes, PSECURITY_DESCRIPTOR SecurityDescriptor, UINT64 AllocationSize, PVOID *FullContext, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext = { 0 }; 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)->UserContext2 = (UINT64)(UINT_PTR)FileContext.FileDesc; return Result; - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS Open(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, UINT32 CreateOptions, UINT32 GrantedAccess, PVOID *FullContext, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext = { 0 }; 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)->UserContext2 = (UINT64)(UINT_PTR)FileContext.FileDesc; return Result; - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, UINT32 FileAttributes, BOOLEAN ReplaceFileAttributes, UINT64 AllocationSize, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Overwrite(&FileContext, FileAttributes, ReplaceFileAttributes, AllocationSize, FileInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static VOID Cleanup(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR FileName, ULONG Flags) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Cleanup(&FileContext, FileName, (CLEANUP_FLAGS)Flags); - FSP_FSOP_EPILOG_VOID + FSP_CPP_CALLBACK_EPILOG_VOID } static VOID Close(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Close(&FileContext); - FSP_FSOP_EPILOG_VOID + FSP_CPP_CALLBACK_EPILOG_VOID } static NTSTATUS Read(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PVOID Buffer, UINT64 Offset, ULONG Length, PULONG PBytesTransferred) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Read(&FileContext, Buffer, Offset, Length, PBytesTransferred); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS Write(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PVOID Buffer, UINT64 Offset, ULONG Length, BOOLEAN WriteToEndOfFile, BOOLEAN ConstrainedIo, PULONG PBytesTransferred, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Write(&FileContext, Buffer, Offset, Length, WriteToEndOfFile, ConstrainedIo, PBytesTransferred, FileInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS Flush(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Flush(&FileContext, FileInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->GetFileInfo(&FileContext, FileInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, UINT32 FileAttributes, UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, UINT64 ChangeTime, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; @@ -566,149 +581,146 @@ private: return self->SetBasicInfo(&FileContext, FileAttributes, CreationTime, LastAccessTime, LastWriteTime, ChangeTime, FileInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, UINT64 NewSize, BOOLEAN SetAllocationSize, FILE_INFO *FileInfo) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->SetFileSize(&FileContext, NewSize, SetAllocationSize, FileInfo); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS CanDelete(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR FileName) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->CanDelete(&FileContext, FileName); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR FileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->Rename(&FileContext, FileName, NewFileName, ReplaceIfExists); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS GetSecurity(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->GetSecurity(&FileContext, SecurityDescriptor, PSecurityDescriptorSize); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS SetSecurity(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, SECURITY_INFORMATION SecurityInformation, PSECURITY_DESCRIPTOR ModificationDescriptor) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->SetSecurity(&FileContext, SecurityInformation, ModificationDescriptor); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS ReadDirectory(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR Pattern, PWSTR Marker, PVOID Buffer, ULONG Length, PULONG PBytesTransferred) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->ReadDirectory(&FileContext, Pattern, Marker, Buffer, Length, PBytesTransferred); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS ResolveReparsePoints(FSP_FILE_SYSTEM *FileSystem0, PWSTR FileName, UINT32 ReparsePointIndex, BOOLEAN ResolveLastPathComponent, PIO_STATUS_BLOCK PIoStatus, PVOID Buffer, PSIZE_T PSize) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; return self->ResolveReparsePoints(FileName, ReparsePointIndex, ResolveLastPathComponent, PIoStatus, Buffer, PSize); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS GetReparsePointByName( FSP_FILE_SYSTEM *FileSystem0, PVOID Context, PWSTR FileName, BOOLEAN IsDirectory, PVOID Buffer, PSIZE_T PSize) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; return self->GetReparsePointByName(FileName, IsDirectory, Buffer, PSize); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS GetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR FileName, PVOID Buffer, PSIZE_T PSize) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->GetReparsePoint(&FileContext, FileName, Buffer, PSize); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS SetReparsePoint(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR FileName, PVOID Buffer, SIZE_T Size) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->SetReparsePoint(&FileContext, FileName, Buffer, Size); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS DeleteReparsePoint(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PWSTR FileName, PVOID Buffer, SIZE_T Size) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; return self->DeleteReparsePoint(&FileContext, FileName, Buffer, Size); - FSP_FSOP_EPILOG + FSP_CPP_CALLBACK_EPILOG } static NTSTATUS GetStreamInfo(FSP_FILE_SYSTEM *FileSystem0, PVOID FullContext, PVOID Buffer, ULONG Length, PULONG PBytesTransferred) { - FSP_FSOP_PROLOG + FSP_CPP_CALLBACK_PROLOG FileSystem *self = (FileSystem *)FileSystem0->UserContext; FILE_CONTEXT FileContext; FileContext.FileNode = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext; FileContext.FileDesc = (PVOID)(UINT_PTR)((FSP_FSCTL_TRANSACT_FULL_CONTEXT *)FullContext)->UserContext2; 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 = @@ -751,6 +763,104 @@ private: 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 diff --git a/tst/passthrough-cpp/passthrough-cpp.cpp b/tst/passthrough-cpp/passthrough-cpp.cpp index fbbec469..fc6c58e1 100644 --- a/tst/passthrough-cpp/passthrough-cpp.cpp +++ b/tst/passthrough-cpp/passthrough-cpp.cpp @@ -23,9 +23,9 @@ #define ALLOCATION_UNIT 4096 #define FULLPATH_SIZE (MAX_PATH + FSP_FSCTL_TRANSACT_PATH_SIZEMAX / sizeof(WCHAR)) -#define info(format, ...) FspServiceLog(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__) -#define warn(format, ...) FspServiceLog(EVENTLOG_WARNING_TYPE, format, __VA_ARGS__) -#define fail(format, ...) FspServiceLog(EVENTLOG_ERROR_TYPE, format, __VA_ARGS__) +#define info(format, ...) Fsp::Service::Log(EVENTLOG_INFORMATION_TYPE, format, __VA_ARGS__) +#define warn(format, ...) Fsp::Service::Log(EVENTLOG_WARNING_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 HandleFromContext(FC) ((PTFS_FILE_DESC *)FileContext->FileDesc)->Handle @@ -698,6 +698,19 @@ NTSTATUS PTFS::ReadDirectory( 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) { union @@ -737,7 +750,11 @@ static ULONG wcstol_deflt(wchar_t *w, ULONG 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 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, MountPoint); - Service->UserContext = Ptfs; + _Ptfs = Ptfs; Result = STATUS_SUCCESS; exit: @@ -887,20 +904,16 @@ usage: #undef argtol } -static NTSTATUS SvcStop(FSP_SERVICE *Service) +NTSTATUS PTFS_SERVICE::OnStop() { - PTFS *Ptfs = (PTFS *)Service->UserContext; - - Ptfs->Unmount(); - delete Ptfs; + _Ptfs->Unmount(); + delete _Ptfs; + _Ptfs = 0; return STATUS_SUCCESS; } int wmain(int argc, wchar_t **argv) { - if (!NT_SUCCESS(FspLoad(0))) - return ERROR_DELAY_LOAD_FAILED; - - return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0); + return PTFS_SERVICE().Run(); }