diff --git a/build/VStudio/testing/winfsp-tests.vcxproj b/build/VStudio/testing/winfsp-tests.vcxproj index 9bbe80cb..5ddf40fd 100644 --- a/build/VStudio/testing/winfsp-tests.vcxproj +++ b/build/VStudio/testing/winfsp-tests.vcxproj @@ -202,6 +202,7 @@ + diff --git a/build/VStudio/testing/winfsp-tests.vcxproj.filters b/build/VStudio/testing/winfsp-tests.vcxproj.filters index 9295b644..9afe1684 100644 --- a/build/VStudio/testing/winfsp-tests.vcxproj.filters +++ b/build/VStudio/testing/winfsp-tests.vcxproj.filters @@ -82,6 +82,9 @@ Source + + Source + diff --git a/inc/winfsp/winfsp.h b/inc/winfsp/winfsp.h index 324c3e1d..25dee19d 100644 --- a/inc/winfsp/winfsp.h +++ b/inc/winfsp/winfsp.h @@ -1627,6 +1627,7 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName, PVOID InBuffer, ULONG InBufferSize, PVOID OutBuffer, ULONG OutBufferSize, PULONG PBytesTransferred, ULONG Timeout, PSID Sid); +FSP_API NTSTATUS FspVersion(PUINT32 PVersion); /* * Delay load diff --git a/src/dll/util.c b/src/dll/util.c index ec6bc4d2..0f2f8a8d 100644 --- a/src/dll/util.c +++ b/src/dll/util.c @@ -163,3 +163,47 @@ exit: return Result; } + +FSP_API NTSTATUS FspVersion(PUINT32 PVersion) +{ + static UINT32 Version; + + if (0 == Version) + { + /* + * This check is not thread-safe, but that should be ok. + * Two threads competing to read the version will read + * the same value from the Version resource. + */ + extern HINSTANCE DllInstance; + WCHAR ModuleFileName[MAX_PATH]; + PVOID VersionInfo; + DWORD Size; + VS_FIXEDFILEINFO *FixedFileInfo = 0; + + if (0 != GetModuleFileNameW(DllInstance, ModuleFileName, MAX_PATH)) + { + Size = GetFileVersionInfoSizeW(ModuleFileName, &Size/*dummy*/); + if (0 < Size) + { + VersionInfo = MemAlloc(Size); + if (0 != VersionInfo && + GetFileVersionInfoW(ModuleFileName, 0, Size, VersionInfo) && + VerQueryValueW(VersionInfo, L"\\", &FixedFileInfo, &Size)) + { + /* 32-bit store should be atomic! */ + Version = FixedFileInfo->dwFileVersionMS; + } + + MemFree(VersionInfo); + } + } + + if (0 == FixedFileInfo) + return STATUS_UNSUCCESSFUL; + } + + *PVersion = Version; + + return STATUS_SUCCESS; +} diff --git a/tst/winfsp-tests/version-test.c b/tst/winfsp-tests/version-test.c new file mode 100644 index 00000000..8d1a030a --- /dev/null +++ b/tst/winfsp-tests/version-test.c @@ -0,0 +1,44 @@ +/** + * @file version-test.c + * + * @copyright 2015-2017 Bill Zissimopoulos + */ +/* + * This file is part of WinFsp. + * + * You can redistribute it and/or modify it under the terms of the GNU + * General Public License version 3 as published by the Free Software + * Foundation. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * software. + */ + +#include +#include + +#include "winfsp-tests.h" + +static void version_test(void) +{ + /* this is not a real test! */ + + UINT32 Version1, Version2; + NTSTATUS Result; + + Result = FspVersion(&Version1); + ASSERT(NT_SUCCESS(Result)); + + Result = FspVersion(&Version2); + ASSERT(NT_SUCCESS(Result)); + + ASSERT(Version1 == Version2); + + FspDebugLog(__FUNCTION__ ": FspVersion=%d.%d\n", HIWORD(Version1), LOWORD(Version1)); +} + +void version_tests(void) +{ + TEST(version_test); +} diff --git a/tst/winfsp-tests/winfsp-tests.c b/tst/winfsp-tests/winfsp-tests.c index b5053caa..e82999a0 100644 --- a/tst/winfsp-tests/winfsp-tests.c +++ b/tst/winfsp-tests/winfsp-tests.c @@ -184,6 +184,7 @@ int main(int argc, char *argv[]) TESTSUITE(eventlog_tests); TESTSUITE(path_tests); TESTSUITE(dirbuf_tests); + TESTSUITE(version_tests); TESTSUITE(mount_tests); TESTSUITE(timeout_tests); TESTSUITE(memfs_tests);