mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 08:23:05 -05:00
dll: FspFsctlEnumServices
This commit is contained in:
parent
b99fb9a5cb
commit
2fc2c237d3
@ -698,6 +698,9 @@ FSP_API NTSTATUS FspFsctlGetVolumeList(PWSTR DevicePath,
|
|||||||
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath);
|
FSP_API NTSTATUS FspFsctlPreflight(PWSTR DevicePath);
|
||||||
FSP_API NTSTATUS FspFsctlStartService(VOID);
|
FSP_API NTSTATUS FspFsctlStartService(VOID);
|
||||||
FSP_API NTSTATUS FspFsctlStopService(VOID);
|
FSP_API NTSTATUS FspFsctlStopService(VOID);
|
||||||
|
FSP_API NTSTATUS FspFsctlEnumServices(
|
||||||
|
VOID (*EnumFn)(PVOID Context, PWSTR ServiceName, BOOLEAN Running),
|
||||||
|
PVOID Context);
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
126
src/dll/fsctl.c
126
src/dll/fsctl.c
@ -447,17 +447,14 @@ static BOOLEAN FspFsctlRunningInContainer(VOID)
|
|||||||
0, 0);
|
0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlStartService(VOID)
|
static NTSTATUS FspFsctlStartServiceByName(PWSTR DriverName)
|
||||||
{
|
{
|
||||||
WCHAR DriverName[256];
|
|
||||||
SC_HANDLE ScmHandle = 0;
|
SC_HANDLE ScmHandle = 0;
|
||||||
SC_HANDLE SvcHandle = 0;
|
SC_HANDLE SvcHandle = 0;
|
||||||
SERVICE_STATUS ServiceStatus;
|
SERVICE_STATUS ServiceStatus;
|
||||||
DWORD LastError;
|
DWORD LastError;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
|
||||||
|
|
||||||
AcquireSRWLockExclusive(&FspFsctlStartStopServiceLock);
|
AcquireSRWLockExclusive(&FspFsctlStartStopServiceLock);
|
||||||
|
|
||||||
if (FspFsctlRunningInContainer())
|
if (FspFsctlRunningInContainer())
|
||||||
@ -525,6 +522,58 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID FspFsctlStartService_EnumFn(PVOID Context, PWSTR ServiceName, BOOLEAN Running)
|
||||||
|
{
|
||||||
|
PWSTR *PDriverName = Context;
|
||||||
|
if (0 == *PDriverName ||
|
||||||
|
0 > invariant_wcscmp(*PDriverName, ServiceName))
|
||||||
|
*PDriverName = ServiceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlStartService(VOID)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* With the introduction of side-by-side (SxS) FSD installations,
|
||||||
|
* we revisit how the FSD is started:
|
||||||
|
*
|
||||||
|
* - If the DLL is started in non-SxS mode, we first try to start
|
||||||
|
* the non-SxS FSD. If that fails we then enumerate all SxS FSD's
|
||||||
|
* and make a best guess on which one to start.
|
||||||
|
*
|
||||||
|
* - If the DLL is started in SxS mode, we only attempt to start
|
||||||
|
* the associated SxS FSD.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (L'\0' == FspSxsIdent()[0])
|
||||||
|
{
|
||||||
|
/* non-SxS mode */
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
PWSTR DriverName = 0;
|
||||||
|
|
||||||
|
Result = FspFsctlStartServiceByName(L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
/* DO NOT CLOBBER Result. We will return it if our best effort below fails. */
|
||||||
|
|
||||||
|
FspFsctlEnumServices(FspFsctlStartService_EnumFn, &DriverName);
|
||||||
|
|
||||||
|
if (0 == DriverName || !NT_SUCCESS(FspFsctlStartServiceByName(DriverName)))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* SxS mode */
|
||||||
|
|
||||||
|
WCHAR DriverName[256];
|
||||||
|
FspSxsAppendSuffix(DriverName, sizeof DriverName, L"" FSP_FSCTL_DRIVER_NAME);
|
||||||
|
return FspFsctlStartServiceByName(DriverName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlStopService(VOID)
|
FSP_API NTSTATUS FspFsctlStopService(VOID)
|
||||||
{
|
{
|
||||||
WCHAR DriverName[256];
|
WCHAR DriverName[256];
|
||||||
@ -615,6 +664,75 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFsctlEnumServices(
|
||||||
|
VOID (*EnumFn)(PVOID Context, PWSTR ServiceName, BOOLEAN Running),
|
||||||
|
PVOID Context)
|
||||||
|
{
|
||||||
|
SC_HANDLE ScmHandle = 0;
|
||||||
|
LPENUM_SERVICE_STATUSW Services = 0;
|
||||||
|
DWORD Size, ServiceCount;
|
||||||
|
DWORD LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
ScmHandle = OpenSCManagerW(0, 0, SC_MANAGER_ENUMERATE_SERVICE);
|
||||||
|
if (0 == ScmHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnumServicesStatusW(ScmHandle,
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_STATE_ALL, 0, 0, &Size, &ServiceCount, 0))
|
||||||
|
{
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (ERROR_MORE_DATA != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 == Size)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Services = MemAlloc(Size);
|
||||||
|
if (0 == Services)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EnumServicesStatusW(ScmHandle,
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_STATE_ALL, Services, Size, &Size, &ServiceCount, 0))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DWORD I = 0; ServiceCount > I; I++)
|
||||||
|
{
|
||||||
|
if (0 != invariant_wcsicmp(Services[I].lpServiceName, L"" FSP_FSCTL_DRIVER_NAME) &&
|
||||||
|
0 != invariant_wcsnicmp(Services[I].lpServiceName,
|
||||||
|
L"" FSP_FSCTL_DRIVER_NAME FSP_SXS_SEPARATOR_STRING,
|
||||||
|
sizeof(FSP_FSCTL_DRIVER_NAME FSP_SXS_SEPARATOR_STRING) - 1))
|
||||||
|
continue;
|
||||||
|
EnumFn(Context,
|
||||||
|
Services[I].lpServiceName,
|
||||||
|
SERVICE_STOPPED != Services[I].ServiceStatus.dwCurrentState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(Services);
|
||||||
|
if (0 != ScmHandle)
|
||||||
|
CloseServiceHandle(ScmHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -93,7 +93,7 @@ static BOOLEAN FspSxsIdentInitializeFromFile(VOID)
|
|||||||
if (0 == Size)
|
if (0 == Size)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
FspSxsIdentBuf[0] = L'+';
|
FspSxsIdentBuf[0] = FSP_SXS_SEPARATOR_CHAR;
|
||||||
memcpy(FspSxsIdentBuf + 1, WBuffer, Size * sizeof(WCHAR));
|
memcpy(FspSxsIdentBuf + 1, WBuffer, Size * sizeof(WCHAR));
|
||||||
FspSxsIdentBuf[1 + Size] = L'\0';
|
FspSxsIdentBuf[1 + Size] = L'\0';
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ static BOOLEAN FspSxsIdentInitializeFromDirectory(VOID)
|
|||||||
if (0 == Ident)
|
if (0 == Ident)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
FspSxsIdentBuf[0] = L'+';
|
FspSxsIdentBuf[0] = FSP_SXS_SEPARATOR_CHAR;
|
||||||
EndQ = FspSxsIdentBuf + (ARRAYSIZE(FspSxsIdentBuf) - 1);
|
EndQ = FspSxsIdentBuf + (ARRAYSIZE(FspSxsIdentBuf) - 1);
|
||||||
for (P = Ident, Q = FspSxsIdentBuf + 1; EndP > P && EndQ > Q && L'\\' != *P; P++, Q++)
|
for (P = Ident, Q = FspSxsIdentBuf + 1; EndP > P && EndQ > Q && L'\\' != *P; P++, Q++)
|
||||||
*Q = *P;
|
*Q = *P;
|
||||||
|
@ -65,6 +65,7 @@ static void usage(void)
|
|||||||
" lsvol list file system devices (volumes)\n"
|
" lsvol list file system devices (volumes)\n"
|
||||||
" id [NAME|SID|UID] print user id\n"
|
" id [NAME|SID|UID] print user id\n"
|
||||||
" perm [PATH|SDDL|UID:GID:MODE] print permissions\n"
|
" perm [PATH|SDDL|UID:GID:MODE] print permissions\n"
|
||||||
|
" lsdrv list drivers\n"
|
||||||
" unload unload driver (requires load driver priv)\n",
|
" unload unload driver (requires load driver priv)\n",
|
||||||
PROGNAME);
|
PROGNAME);
|
||||||
}
|
}
|
||||||
@ -564,6 +565,25 @@ static int perm(int argc, wchar_t **argv)
|
|||||||
return FspWin32FromNtStatus(Result);
|
return FspWin32FromNtStatus(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID lsdrv_enumfn(PVOID Context, PWSTR ServiceName, BOOLEAN Running)
|
||||||
|
{
|
||||||
|
info("%-4s%S", Running ? "R" : "-", ServiceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lsdrv(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
if (1 != argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
Result = FspFsctlEnumServices(lsdrv_enumfn, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return FspWin32FromNtStatus(Result);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int unload(int argc, wchar_t **argv)
|
static int unload(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
if (1 != argc)
|
if (1 != argc)
|
||||||
@ -598,6 +618,9 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
if (0 == invariant_wcscmp(L"perm", argv[0]))
|
if (0 == invariant_wcscmp(L"perm", argv[0]))
|
||||||
return perm(argc, argv);
|
return perm(argc, argv);
|
||||||
else
|
else
|
||||||
|
if (0 == invariant_wcscmp(L"lsdrv", argv[0]))
|
||||||
|
return lsdrv(argc, argv);
|
||||||
|
else
|
||||||
if (0 == invariant_wcscmp(L"unload", argv[0]))
|
if (0 == invariant_wcscmp(L"unload", argv[0]))
|
||||||
return unload(argc, argv);
|
return unload(argc, argv);
|
||||||
else
|
else
|
||||||
|
@ -30,4 +30,10 @@
|
|||||||
*/
|
*/
|
||||||
#define FSP_CFG_REJECT_EARLY_IRP
|
#define FSP_CFG_REJECT_EARLY_IRP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SxS separator. The '+' in "WinFsp+20220906T173701Z".
|
||||||
|
*/
|
||||||
|
#define FSP_SXS_SEPARATOR_CHAR '+'
|
||||||
|
#define FSP_SXS_SEPARATOR_STRING "+"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -42,7 +42,7 @@ VOID FspSxsIdentInitialize(PUNICODE_STRING DriverName)
|
|||||||
{
|
{
|
||||||
if (L'\\' == *P)
|
if (L'\\' == *P)
|
||||||
break;
|
break;
|
||||||
if (L'+' == *P)
|
if (FSP_SXS_SEPARATOR_CHAR == *P)
|
||||||
{
|
{
|
||||||
Ident = P;
|
Ident = P;
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user