mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: FspFsctlServiceVersion
During file system volume creation FspFsctlCreateVolume calls FspFsctlServiceVersion which examines the version of the driver in use and initializes the variables FspFsctlTransactCode and FspFsctlTransactBatchCode with either the new FSP_IOCTL_TRANSACT* codes or the old FSP_FSCTL_TRANSACT* codes.
This commit is contained in:
parent
c343253718
commit
47aa53c70a
@ -26,6 +26,12 @@
|
||||
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
|
||||
#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR))
|
||||
|
||||
static INIT_ONCE FspFsctlServiceVersionInitOnce = INIT_ONCE_STATIC_INIT;
|
||||
static ULONG FspFsctlServiceVersionValue;
|
||||
static DWORD FspFsctlTransactCode = FSP_FSCTL_TRANSACT;
|
||||
static DWORD FspFsctlTransactBatchCode = FSP_FSCTL_TRANSACT_BATCH;
|
||||
|
||||
static VOID FspFsctlServiceVersion(PUINT32 PVersion);
|
||||
static NTSTATUS FspFsctlStartService(VOID);
|
||||
|
||||
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
||||
@ -76,6 +82,9 @@ FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
||||
if (!NT_SUCCESS(Result))
|
||||
return Result;
|
||||
|
||||
/* initialize FspFsctlTransactCode */
|
||||
FspFsctlServiceVersion(0);
|
||||
|
||||
VolumeHandle = CreateFileW(DevicePathBuf,
|
||||
0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
||||
if (INVALID_HANDLE_VALUE == VolumeHandle)
|
||||
@ -136,9 +145,15 @@ FSP_API NTSTATUS FspFsctlTransact(HANDLE VolumeHandle,
|
||||
*PRequestBufSize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* During file system volume creation FspFsctlCreateVolume called FspFsctlServiceVersion
|
||||
* which examined the version of the driver in use and initialized the variables
|
||||
* FspFsctlTransactCode and FspFsctlTransactBatchCode with either the new
|
||||
* FSP_IOCTL_TRANSACT* codes or the old FSP_FSCTL_TRANSACT* codes.
|
||||
*/
|
||||
ControlCode = Batch ?
|
||||
(DEBUGTEST(50) ? FSP_IOCTL_TRANSACT_BATCH : FSP_FSCTL_TRANSACT_BATCH) :
|
||||
(DEBUGTEST(50) ? FSP_IOCTL_TRANSACT : FSP_FSCTL_TRANSACT);
|
||||
(DEBUGTEST(50) ? FspFsctlTransactBatchCode : FSP_FSCTL_TRANSACT_BATCH) :
|
||||
(DEBUGTEST(50) ? FspFsctlTransactCode : FSP_FSCTL_TRANSACT);
|
||||
|
||||
if (!DeviceIoControl(VolumeHandle,
|
||||
ControlCode,
|
||||
@ -267,6 +282,79 @@ FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath)
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOL WINAPI FspFsctlServiceVersionInitialize(
|
||||
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||
{
|
||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
||||
PWSTR ModuleFileName;
|
||||
SC_HANDLE ScmHandle = 0;
|
||||
SC_HANDLE SvcHandle = 0;
|
||||
QUERY_SERVICE_CONFIGW *ServiceConfig = 0;
|
||||
DWORD Size;
|
||||
|
||||
ScmHandle = OpenSCManagerW(0, 0, 0);
|
||||
if (0 == ScmHandle)
|
||||
goto exit;
|
||||
|
||||
SvcHandle = OpenServiceW(ScmHandle, DriverName, SERVICE_QUERY_CONFIG);
|
||||
if (0 == SvcHandle)
|
||||
goto exit;
|
||||
|
||||
if (QueryServiceConfig(SvcHandle, 0, 0, &Size) ||
|
||||
ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||
goto exit;
|
||||
|
||||
ServiceConfig = MemAlloc(Size);
|
||||
if (0 == ServiceConfig)
|
||||
goto exit;
|
||||
|
||||
if (!QueryServiceConfig(SvcHandle, ServiceConfig, Size, &Size))
|
||||
goto exit;
|
||||
|
||||
ModuleFileName = ServiceConfig->lpBinaryPathName;
|
||||
if (L'\\' == ModuleFileName[0] &&
|
||||
L'?' == ModuleFileName[1] &&
|
||||
L'?' == ModuleFileName[2] &&
|
||||
L'\\' == ModuleFileName[3])
|
||||
{
|
||||
if (L'U' == ModuleFileName[4] &&
|
||||
L'N' == ModuleFileName[5] &&
|
||||
L'C' == ModuleFileName[6] &&
|
||||
L'\\' == ModuleFileName[7])
|
||||
{
|
||||
ModuleFileName[6] = L'\\';
|
||||
ModuleFileName = ModuleFileName + 6;
|
||||
}
|
||||
else
|
||||
ModuleFileName = ModuleFileName + 4;
|
||||
}
|
||||
|
||||
FspGetModuleVersion(ModuleFileName, &FspFsctlServiceVersionValue);
|
||||
|
||||
if (0x0001000b /*v1.11*/ <= FspFsctlServiceVersionValue)
|
||||
{
|
||||
FspFsctlTransactCode = FSP_IOCTL_TRANSACT;
|
||||
FspFsctlTransactBatchCode = FSP_IOCTL_TRANSACT_BATCH;
|
||||
}
|
||||
|
||||
exit:
|
||||
MemFree(ServiceConfig);
|
||||
if (0 != SvcHandle)
|
||||
CloseServiceHandle(SvcHandle);
|
||||
if (0 != ScmHandle)
|
||||
CloseServiceHandle(ScmHandle);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID FspFsctlServiceVersion(PUINT32 PVersion)
|
||||
{
|
||||
InitOnceExecuteOnce(&FspFsctlServiceVersionInitOnce, FspFsctlServiceVersionInitialize, 0, 0);
|
||||
|
||||
if (0 != PVersion)
|
||||
*PVersion = FspFsctlServiceVersionValue;
|
||||
}
|
||||
|
||||
static NTSTATUS FspFsctlStartService(VOID)
|
||||
{
|
||||
static SRWLOCK Lock = SRWLOCK_INIT;
|
||||
|
@ -81,6 +81,7 @@ ULONG FspLdapGetDefaultNamingContext(PVOID Ldap, PWSTR *PValue);
|
||||
ULONG FspLdapGetTrustPosixOffset(PVOID Ldap, PWSTR Context, PWSTR Domain, PWSTR *PValue);
|
||||
|
||||
PWSTR FspDiagIdent(VOID);
|
||||
NTSTATUS FspGetModuleVersion(PWSTR ModuleFileName, PUINT32 PVersion);
|
||||
|
||||
#define FspFileSystemDirectoryBufferEntryInvalid ((ULONG)-1)
|
||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||
|
@ -215,3 +215,36 @@ FSP_API NTSTATUS FspVersion(PUINT32 PVersion)
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FspGetModuleVersion(PWSTR ModuleFileName, PUINT32 PVersion)
|
||||
{
|
||||
/* internal only: get version of any module */
|
||||
|
||||
PVOID VersionInfo;
|
||||
DWORD Size;
|
||||
VS_FIXEDFILEINFO *FixedFileInfo = 0;
|
||||
UINT32 Version;
|
||||
|
||||
*PVersion = 0;
|
||||
|
||||
Size = GetFileVersionInfoSizeW(ModuleFileName, &Size/*dummy*/);
|
||||
if (0 < Size)
|
||||
{
|
||||
VersionInfo = MemAlloc(Size);
|
||||
if (0 != VersionInfo &&
|
||||
GetFileVersionInfoW(ModuleFileName, 0, Size, VersionInfo) &&
|
||||
VerQueryValueW(VersionInfo, L"\\", &FixedFileInfo, &Size))
|
||||
{
|
||||
Version = FixedFileInfo->dwFileVersionMS;
|
||||
}
|
||||
|
||||
MemFree(VersionInfo);
|
||||
}
|
||||
|
||||
if (0 == FixedFileInfo)
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
|
||||
*PVersion = Version;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user