diff --git a/build/VStudio/winfsp.sln b/build/VStudio/winfsp.sln index 8799e9dd..4a838aaf 100644 --- a/build/VStudio/winfsp.sln +++ b/build/VStudio/winfsp.sln @@ -74,10 +74,8 @@ Global {AA7190E8-877F-4827-8CDD-E0D85F83C8C1}.Release|x86.Build.0 = Release|Win32 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x64.ActiveCfg = Debug|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x86.ActiveCfg = Debug|x86 - {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Debug|x86.Build.0 = Debug|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x64.ActiveCfg = Release|x86 {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x86.ActiveCfg = Release|x86 - {D53AAC39-4C57-4CA5-A4F3-C2B24888C594}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build/VStudio/winfsp_dll.vcxproj b/build/VStudio/winfsp_dll.vcxproj index d84bbdca..82b3ef51 100644 --- a/build/VStudio/winfsp_dll.vcxproj +++ b/build/VStudio/winfsp_dll.vcxproj @@ -145,6 +145,7 @@ $(OutDir)$(TargetFileName).map true ..\..\src\dll\library.def + %(AdditionalDependencies);version.lib @@ -169,6 +170,7 @@ $(OutDir)$(TargetFileName).map true ..\..\src\dll\library.def + %(AdditionalDependencies);version.lib @@ -196,6 +198,7 @@ $(OutDir)$(TargetFileName).map true ..\..\src\dll\library.def + %(AdditionalDependencies);version.lib @@ -223,6 +226,7 @@ $(OutDir)$(TargetFileName).map true ..\..\src\dll\library.def + %(AdditionalDependencies);version.lib diff --git a/inc/winfsp/fsctl.h b/inc/winfsp/fsctl.h index 3fc26327..7e7cdb36 100644 --- a/inc/winfsp/fsctl.h +++ b/inc/winfsp/fsctl.h @@ -24,6 +24,7 @@ extern "C" { #endif +#define FSP_FSCTL_DRIVER_NAME "WinFsp" #define FSP_FSCTL_DISK_DEVICE_NAME "WinFsp.Disk" #define FSP_FSCTL_NET_DEVICE_NAME "WinFsp.Net" diff --git a/src/dll/fs.c b/src/dll/fs.c index 9b358936..543a04df 100644 --- a/src/dll/fs.c +++ b/src/dll/fs.c @@ -372,3 +372,128 @@ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem, FspFsctlStop(FileSystem->VolumeHandle); } } + +NTSTATUS FspFileSystemRegister(VOID) +{ + extern HINSTANCE DllInstance; + PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME; + WCHAR DriverPath[MAX_PATH]; + DWORD Size; + SC_HANDLE ScmHandle = 0; + SC_HANDLE SvcHandle = 0; + PVOID VersionInfo = 0; + SERVICE_DESCRIPTION ServiceDescription; + DWORD LastError; + NTSTATUS Result; + + if (0 == GetModuleFileNameW(DllInstance, DriverPath, MAX_PATH)) + return FspNtStatusFromWin32(GetLastError()); + + Size = lstrlenW(DriverPath); + if (4 < Size && + (L'.' == DriverPath[Size - 4]) && + (L'D' == DriverPath[Size - 3] || L'd' == DriverPath[Size - 3]) && + (L'L' == DriverPath[Size - 2] || L'l' == DriverPath[Size - 2]) && + (L'L' == DriverPath[Size - 1] || L'l' == DriverPath[Size - 1]) && + (L'\0' == DriverPath[Size])) + { + DriverPath[Size - 3] = L's'; + DriverPath[Size - 2] = L'y'; + DriverPath[Size - 1] = L's'; + } + else + /* should not happen! */ + return STATUS_NO_SUCH_DEVICE; + + ScmHandle = OpenSCManagerW(0, 0, SC_MANAGER_CREATE_SERVICE); + if (0 == ScmHandle) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + SvcHandle = CreateServiceW(ScmHandle, DriverName, DriverName, + SERVICE_CHANGE_CONFIG, + SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath, + 0, 0, 0, 0, 0); + if (0 == SvcHandle) + { + LastError = GetLastError(); + if (ERROR_SERVICE_EXISTS != LastError && ERROR_DUPLICATE_SERVICE_NAME != LastError) + Result = FspNtStatusFromWin32(LastError); + else + Result = STATUS_SUCCESS; + goto exit; + } + + Size = GetFileVersionInfoSizeW(DriverPath, &Size/*dummy*/); + if (0 < Size) + { + VersionInfo = MemAlloc(Size); + if (0 != VersionInfo && + GetFileVersionInfoW(DriverPath, 0, Size, VersionInfo) && + VerQueryValueW(VersionInfo, L"\\StringFileInfo\\040904b0\\FileDescription", + &ServiceDescription.lpDescription, &Size)) + { + ChangeServiceConfig2W(SvcHandle, SERVICE_CONFIG_DESCRIPTION, &ServiceDescription); + } + } + + Result = STATUS_SUCCESS; + +exit: + MemFree(VersionInfo); + if (0 != SvcHandle) + CloseServiceHandle(ScmHandle); + if (0 != ScmHandle) + CloseServiceHandle(ScmHandle); + + return Result; +} + +NTSTATUS FspFileSystemUnregister(VOID) +{ + PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME; + SC_HANDLE ScmHandle = 0; + SC_HANDLE SvcHandle = 0; + DWORD LastError; + NTSTATUS Result; + + ScmHandle = OpenSCManagerW(0, 0, 0); + if (0 == ScmHandle) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + SvcHandle = OpenServiceW(ScmHandle, DriverName, DELETE); + if (0 == SvcHandle) + { + LastError = GetLastError(); + if (ERROR_SERVICE_DOES_NOT_EXIST != LastError) + Result = FspNtStatusFromWin32(LastError); + else + Result = STATUS_SUCCESS; + goto exit; + } + + if (!DeleteService(SvcHandle)) + { + LastError = GetLastError(); + if (ERROR_SERVICE_MARKED_FOR_DELETE != LastError) + Result = FspNtStatusFromWin32(LastError); + else + Result = STATUS_SUCCESS; + goto exit; + } + + Result = STATUS_SUCCESS; + +exit: + if (0 != SvcHandle) + CloseServiceHandle(ScmHandle); + if (0 != ScmHandle) + CloseServiceHandle(ScmHandle); + + return Result; +} diff --git a/src/dll/library.c b/src/dll/library.c index 47fcab1e..5529e2fe 100644 --- a/src/dll/library.c +++ b/src/dll/library.c @@ -51,10 +51,20 @@ HRESULT WINAPI DllRegisterServer(VOID) { NTSTATUS Result; + Result = FspFileSystemRegister(); + FspDebugLog("FspFileSystemRegister = %lx\n", Result); + if (!NT_SUCCESS(Result)) + goto exit; + Result = FspNpRegister(); + FspDebugLog("FspNpRegister = %lx\n", Result); + if (!NT_SUCCESS(Result)) + { + FspFileSystemUnregister(); + goto exit; + } - FspDebugLog("FspNpRegister = %ld\n", Result); - +exit: return NT_SUCCESS(Result) ? S_OK : 0x80040201/*SELFREG_E_CLASS*/; } @@ -63,8 +73,18 @@ HRESULT WINAPI DllUnregisterServer(VOID) NTSTATUS Result; Result = FspNpUnregister(); + FspDebugLog("FspNpUnregister = %lx\n", Result); + if (!NT_SUCCESS(Result)) + goto exit; - FspDebugLog("FspNpUnregister = %ld\n", Result); + Result = FspFileSystemUnregister(); + FspDebugLog("FspFileSystemUnregister = %lx\n", Result); + if (!NT_SUCCESS(Result)) + { + FspNpRegister(); + goto exit; + } +exit: return NT_SUCCESS(Result) ? S_OK : 0x80040201/*SELFREG_E_CLASS*/; } diff --git a/src/dll/library.h b/src/dll/library.h index 82f32650..b655180f 100644 --- a/src/dll/library.h +++ b/src/dll/library.h @@ -105,6 +105,8 @@ BOOLEAN RemoveEntryList(PLIST_ENTRY Entry) VOID FspFileSystemInitialize(VOID); VOID FspFileSystemFinalize(VOID); +NTSTATUS FspFileSystemRegister(VOID); +NTSTATUS FspFileSystemUnregister(VOID); NTSTATUS FspNpRegister(VOID); NTSTATUS FspNpUnregister(VOID); diff --git a/src/sys/driver.h b/src/sys/driver.h index 1409b2b9..510f73e2 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -28,7 +28,7 @@ #pragma warning(disable:4100) /* unreferenced formal parameter */ #pragma warning(disable:4200) /* zero-sized array in struct/union */ -#define DRIVER_NAME "WinFsp" +#define DRIVER_NAME FSP_FSCTL_DRIVER_NAME /* IoCreateDeviceSecure default SDDL's */ #define FSP_FSCTL_DEVICE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GR;;;WD)"