mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
dll: FspFileSystemRegister, FspFileSystemUnregister: rename and place in fsctl.c
This commit is contained in:
parent
4a4fba4670
commit
de973fa5ab
252
src/dll/fs.c
252
src/dll/fs.c
@ -16,7 +16,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
#include <aclapi.h>
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -373,254 +372,3 @@ FSP_API VOID FspFileSystemSendResponse(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FspFsctlStop(FileSystem->VolumeHandle);
|
FspFsctlStop(FileSystem->VolumeHandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemFixServiceSecurity(HANDLE SvcHandle)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* This function adds an ACE that allows Everyone to start a service.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PSID WorldSid = 0;
|
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
|
||||||
EXPLICIT_ACCESSW AccessEntry;
|
|
||||||
ACCESS_MASK AccessRights;
|
|
||||||
PACL Dacl;
|
|
||||||
BOOL DaclPresent, DaclDefaulted;
|
|
||||||
DWORD Size;
|
|
||||||
DWORD LastError;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
/* get the Everyone (World) SID */
|
|
||||||
Size = SECURITY_MAX_SID_SIZE;
|
|
||||||
WorldSid = MemAlloc(Size);
|
|
||||||
if (0 == WorldSid)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (!CreateWellKnownSid(WinWorldSid, 0, WorldSid, &Size))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the service security descriptor DACL */
|
|
||||||
Size = 0;
|
|
||||||
if (!QueryServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
|
||||||
{
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (ERROR_INSUFFICIENT_BUFFER != LastError)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(LastError);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SecurityDescriptor = MemAlloc(Size);
|
|
||||||
if (0 == SecurityDescriptor)
|
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
if (!QueryServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extract the DACL */
|
|
||||||
if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare an EXPLICIT_ACCESS for the SERVICE_START right for Everyone */
|
|
||||||
AccessEntry.grfAccessPermissions = SERVICE_START;
|
|
||||||
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
|
||||||
AccessEntry.grfInheritance = NO_INHERITANCE;
|
|
||||||
AccessEntry.Trustee.pMultipleTrustee = 0;
|
|
||||||
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
|
||||||
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
|
||||||
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
|
||||||
AccessEntry.Trustee.ptstrName = WorldSid;
|
|
||||||
|
|
||||||
/* get the effective rights for Everyone */
|
|
||||||
AccessRights = 0;
|
|
||||||
if (DaclPresent && 0 != Dacl)
|
|
||||||
{
|
|
||||||
LastError = GetEffectiveRightsFromAclW(Dacl, &AccessEntry.Trustee, &AccessRights);
|
|
||||||
if (0 != LastError)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(LastError);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do we have the required access rights? */
|
|
||||||
if (AccessEntry.grfAccessPermissions != (AccessRights & AccessEntry.grfAccessPermissions))
|
|
||||||
{
|
|
||||||
/* create a new security descriptor with the new access */
|
|
||||||
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
|
||||||
&Size, &NewSecurityDescriptor);
|
|
||||||
if (0 != LastError)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(LastError);
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the new service security descriptor DACL */
|
|
||||||
if (!SetServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
LocalFree(NewSecurityDescriptor);
|
|
||||||
MemFree(SecurityDescriptor);
|
|
||||||
MemFree(WorldSid);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
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 = OpenServiceW(ScmHandle, DriverName, SERVICE_CHANGE_CONFIG | READ_CONTROL | WRITE_DAC);
|
|
||||||
if (0 != SvcHandle)
|
|
||||||
{
|
|
||||||
if (!ChangeServiceConfigW(SvcHandle,
|
|
||||||
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath,
|
|
||||||
0, 0, 0, 0, 0, DriverName))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SvcHandle = CreateServiceW(ScmHandle, DriverName, DriverName,
|
|
||||||
SERVICE_CHANGE_CONFIG | READ_CONTROL | WRITE_DAC,
|
|
||||||
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath,
|
|
||||||
0, 0, 0, 0, 0);
|
|
||||||
if (0 == SvcHandle)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
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 = FspFileSystemFixServiceSecurity(SvcHandle);
|
|
||||||
if (!NT_SUCCESS(Result))
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
MemFree(VersionInfo);
|
|
||||||
if (0 != SvcHandle)
|
|
||||||
CloseServiceHandle(SvcHandle);
|
|
||||||
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(SvcHandle);
|
|
||||||
if (0 != ScmHandle)
|
|
||||||
CloseServiceHandle(ScmHandle);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
376
src/dll/fsctl.c
376
src/dll/fsctl.c
@ -16,72 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
#include <aclapi.h>
|
||||||
|
|
||||||
#define GLOBALROOT L"\\\\?\\GLOBALROOT"
|
#define GLOBALROOT L"\\\\?\\GLOBALROOT"
|
||||||
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
|
#define PREFIXW L"" FSP_FSCTL_VOLUME_PARAMS_PREFIX
|
||||||
#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR))
|
#define PREFIXW_SIZE (sizeof PREFIXW - sizeof(WCHAR))
|
||||||
|
|
||||||
NTSTATUS FspFsctlStartService(VOID)
|
static NTSTATUS FspFsctlStartService(VOID);
|
||||||
{
|
|
||||||
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
|
||||||
SC_HANDLE ScmHandle = 0;
|
|
||||||
SC_HANDLE SvcHandle = 0;
|
|
||||||
SERVICE_STATUS ServiceStatus;
|
|
||||||
DWORD LastError;
|
|
||||||
NTSTATUS Result;
|
|
||||||
|
|
||||||
ScmHandle = OpenSCManagerW(0, 0, 0);
|
|
||||||
if (0 == ScmHandle)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
SvcHandle = OpenServiceW(ScmHandle, DriverName, SERVICE_QUERY_STATUS | SERVICE_START);
|
|
||||||
if (0 == SvcHandle)
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StartServiceW(SvcHandle, 0, 0))
|
|
||||||
{
|
|
||||||
LastError = GetLastError();
|
|
||||||
if (ERROR_SERVICE_ALREADY_RUNNING != LastError)
|
|
||||||
Result = FspNtStatusFromWin32(LastError);
|
|
||||||
else
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Poll until the service is running! Yes, that's the best we can do! */
|
|
||||||
Result = STATUS_DRIVER_UNABLE_TO_LOAD;
|
|
||||||
for (DWORD Timeout = 500, N = 20, I = 0; N > I; I++)
|
|
||||||
/* wait up to 500ms * 20 = 10000ms = 10s */
|
|
||||||
{
|
|
||||||
if (!QueryServiceStatus(SvcHandle, &ServiceStatus))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SERVICE_RUNNING == ServiceStatus.dwCurrentState)
|
|
||||||
{
|
|
||||||
Result = STATUS_SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sleep(Timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
|
||||||
if (0 != SvcHandle)
|
|
||||||
CloseServiceHandle(SvcHandle);
|
|
||||||
if (0 != ScmHandle)
|
|
||||||
CloseServiceHandle(ScmHandle);
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
FSP_API NTSTATUS FspFsctlCreateVolume(PWSTR DevicePath,
|
||||||
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
const FSP_FSCTL_VOLUME_PARAMS *VolumeParams,
|
||||||
@ -251,3 +192,316 @@ exit:
|
|||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsctlStartService(VOID)
|
||||||
|
{
|
||||||
|
PWSTR DriverName = L"" FSP_FSCTL_DRIVER_NAME;
|
||||||
|
SC_HANDLE ScmHandle = 0;
|
||||||
|
SC_HANDLE SvcHandle = 0;
|
||||||
|
SERVICE_STATUS ServiceStatus;
|
||||||
|
DWORD LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
ScmHandle = OpenSCManagerW(0, 0, 0);
|
||||||
|
if (0 == ScmHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
SvcHandle = OpenServiceW(ScmHandle, DriverName, SERVICE_QUERY_STATUS | SERVICE_START);
|
||||||
|
if (0 == SvcHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StartServiceW(SvcHandle, 0, 0))
|
||||||
|
{
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (ERROR_SERVICE_ALREADY_RUNNING != LastError)
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
else
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Poll until the service is running! Yes, that's the best we can do! */
|
||||||
|
Result = STATUS_DRIVER_UNABLE_TO_LOAD;
|
||||||
|
for (DWORD Timeout = 500, N = 20, I = 0; N > I; I++)
|
||||||
|
/* wait up to 500ms * 20 = 10000ms = 10s */
|
||||||
|
{
|
||||||
|
if (!QueryServiceStatus(SvcHandle, &ServiceStatus))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SERVICE_RUNNING == ServiceStatus.dwCurrentState)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sleep(Timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != SvcHandle)
|
||||||
|
CloseServiceHandle(SvcHandle);
|
||||||
|
if (0 != ScmHandle)
|
||||||
|
CloseServiceHandle(ScmHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This function adds an ACE that allows Everyone to start a service.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PSID WorldSid = 0;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
|
ACCESS_MASK AccessRights;
|
||||||
|
PACL Dacl;
|
||||||
|
BOOL DaclPresent, DaclDefaulted;
|
||||||
|
DWORD Size;
|
||||||
|
DWORD LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
/* get the Everyone (World) SID */
|
||||||
|
Size = SECURITY_MAX_SID_SIZE;
|
||||||
|
WorldSid = MemAlloc(Size);
|
||||||
|
if (0 == WorldSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!CreateWellKnownSid(WinWorldSid, 0, WorldSid, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the service security descriptor DACL */
|
||||||
|
Size = 0;
|
||||||
|
if (!QueryServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
||||||
|
{
|
||||||
|
LastError = GetLastError();
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SecurityDescriptor = MemAlloc(Size);
|
||||||
|
if (0 == SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!QueryServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extract the DACL */
|
||||||
|
if (!GetSecurityDescriptorDacl(SecurityDescriptor, &DaclPresent, &Dacl, &DaclDefaulted))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* prepare an EXPLICIT_ACCESS for the SERVICE_QUERY_STATUS | SERVICE_START right for Everyone */
|
||||||
|
AccessEntry.grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_START;
|
||||||
|
AccessEntry.grfAccessMode = GRANT_ACCESS;
|
||||||
|
AccessEntry.grfInheritance = NO_INHERITANCE;
|
||||||
|
AccessEntry.Trustee.pMultipleTrustee = 0;
|
||||||
|
AccessEntry.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
|
||||||
|
AccessEntry.Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
||||||
|
AccessEntry.Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
|
||||||
|
AccessEntry.Trustee.ptstrName = WorldSid;
|
||||||
|
|
||||||
|
/* get the effective rights for Everyone */
|
||||||
|
AccessRights = 0;
|
||||||
|
if (DaclPresent && 0 != Dacl)
|
||||||
|
{
|
||||||
|
LastError = GetEffectiveRightsFromAclW(Dacl, &AccessEntry.Trustee, &AccessRights);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do we have the required access rights? */
|
||||||
|
if (AccessEntry.grfAccessPermissions != (AccessRights & AccessEntry.grfAccessPermissions))
|
||||||
|
{
|
||||||
|
/* create a new security descriptor with the new access */
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the new service security descriptor DACL */
|
||||||
|
if (!SetServiceObjectSecurity(SvcHandle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
LocalFree(NewSecurityDescriptor);
|
||||||
|
MemFree(SecurityDescriptor);
|
||||||
|
MemFree(WorldSid);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspFsctlRegister(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;
|
||||||
|
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 = OpenServiceW(ScmHandle, DriverName, SERVICE_CHANGE_CONFIG | READ_CONTROL | WRITE_DAC);
|
||||||
|
if (0 != SvcHandle)
|
||||||
|
{
|
||||||
|
if (!ChangeServiceConfigW(SvcHandle,
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath,
|
||||||
|
0, 0, 0, 0, 0, DriverName))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SvcHandle = CreateServiceW(ScmHandle, DriverName, DriverName,
|
||||||
|
SERVICE_CHANGE_CONFIG | READ_CONTROL | WRITE_DAC,
|
||||||
|
SERVICE_FILE_SYSTEM_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath,
|
||||||
|
0, 0, 0, 0, 0);
|
||||||
|
if (0 == SvcHandle)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
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 = FspFsctlFixServiceSecurity(SvcHandle);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(VersionInfo);
|
||||||
|
if (0 != SvcHandle)
|
||||||
|
CloseServiceHandle(SvcHandle);
|
||||||
|
if (0 != ScmHandle)
|
||||||
|
CloseServiceHandle(ScmHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS FspFsctlUnregister(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(SvcHandle);
|
||||||
|
if (0 != ScmHandle)
|
||||||
|
CloseServiceHandle(ScmHandle);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
@ -51,18 +51,15 @@ HRESULT WINAPI DllRegisterServer(VOID)
|
|||||||
{
|
{
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
Result = FspFileSystemRegister();
|
Result = FspFsctlRegister();
|
||||||
FspDebugLog("FspFileSystemRegister = %lx\n", Result);
|
FspDebugLog("FspFsctlRegister = %lx\n", Result);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = FspNpRegister();
|
Result = FspNpRegister();
|
||||||
FspDebugLog("FspNpRegister = %lx\n", Result);
|
FspDebugLog("FspNpRegister = %lx\n", Result);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
|
||||||
FspFileSystemUnregister();
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
return NT_SUCCESS(Result) ? S_OK : 0x80040201/*SELFREG_E_CLASS*/;
|
return NT_SUCCESS(Result) ? S_OK : 0x80040201/*SELFREG_E_CLASS*/;
|
||||||
@ -77,10 +74,11 @@ HRESULT WINAPI DllUnregisterServer(VOID)
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = FspFileSystemUnregister();
|
Result = FspFsctlUnregister();
|
||||||
FspDebugLog("FspFileSystemUnregister = %lx\n", Result);
|
FspDebugLog("FspFsctlUnregister = %lx\n", Result);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
|
/* roll back network provider unregistration if possible */
|
||||||
FspNpRegister();
|
FspNpRegister();
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
@ -105,8 +105,9 @@ BOOLEAN RemoveEntryList(PLIST_ENTRY Entry)
|
|||||||
|
|
||||||
VOID FspFileSystemInitialize(VOID);
|
VOID FspFileSystemInitialize(VOID);
|
||||||
VOID FspFileSystemFinalize(VOID);
|
VOID FspFileSystemFinalize(VOID);
|
||||||
NTSTATUS FspFileSystemRegister(VOID);
|
|
||||||
NTSTATUS FspFileSystemUnregister(VOID);
|
NTSTATUS FspFsctlRegister(VOID);
|
||||||
|
NTSTATUS FspFsctlUnregister(VOID);
|
||||||
|
|
||||||
NTSTATUS FspNpRegister(VOID);
|
NTSTATUS FspNpRegister(VOID);
|
||||||
NTSTATUS FspNpUnregister(VOID);
|
NTSTATUS FspNpUnregister(VOID);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user