mirror of
https://github.com/winfsp/winfsp.git
synced 2025-06-09 13:32:14 -05:00
Merge branch 'pvt-launcher2'
This commit is contained in:
commit
299f371dee
@ -112,7 +112,7 @@
|
|||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -134,7 +134,7 @@
|
|||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -159,7 +159,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -184,7 +184,7 @@
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||||
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib</AdditionalDependencies>
|
<AdditionalDependencies>%(AdditionalDependencies);rpcrt4.lib;userenv.lib</AdditionalDependencies>
|
||||||
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
<StripPrivateSymbols>$(OutDir)$(TargetName).public.pdb</StripPrivateSymbols>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
<ClCompile Include="..\..\src\dll\path.c" />
|
<ClCompile Include="..\..\src\dll\path.c" />
|
||||||
<ClCompile Include="..\..\src\dll\service.c" />
|
<ClCompile Include="..\..\src\dll\service.c" />
|
||||||
<ClCompile Include="..\..\src\dll\util.c" />
|
<ClCompile Include="..\..\src\dll\util.c" />
|
||||||
|
<ClCompile Include="..\..\src\dll\wksid.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
|
<CustomBuild Include="..\..\src\dll\fuse\fuse.pc.in">
|
||||||
|
@ -112,6 +112,9 @@
|
|||||||
<ClCompile Include="..\..\src\dll\fuse\fuse_compat.c">
|
<ClCompile Include="..\..\src\dll\fuse\fuse_compat.c">
|
||||||
<Filter>Source\fuse</Filter>
|
<Filter>Source\fuse</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\src\dll\wksid.c">
|
||||||
|
<Filter>Source</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\src\dll\library.def">
|
<None Include="..\..\src\dll\library.def">
|
||||||
|
@ -1675,6 +1675,19 @@ FSP_API VOID FspServiceStop(FSP_SERVICE *Service);
|
|||||||
* TRUE if the process is running in running user interactive mode.
|
* TRUE if the process is running in running user interactive mode.
|
||||||
*/
|
*/
|
||||||
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
FSP_API BOOLEAN FspServiceIsInteractive(VOID);
|
||||||
|
/**
|
||||||
|
* Check if the supplied token is from the service context.
|
||||||
|
*
|
||||||
|
* @param Token
|
||||||
|
* Token to check. Pass NULL to check the current process token.
|
||||||
|
* @param PIsLocalSystem
|
||||||
|
* Pointer to a boolean that will receive a TRUE value if the token belongs to LocalSystem
|
||||||
|
* and FALSE otherwise. May be NULL.
|
||||||
|
* @return
|
||||||
|
* STATUS_SUCCESS if the token is from the service context. STATUS_ACCESS_DENIED if it is not.
|
||||||
|
* Other error codes are possible.
|
||||||
|
*/
|
||||||
|
FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem);
|
||||||
/**
|
/**
|
||||||
* Log a service message.
|
* Log a service message.
|
||||||
*
|
*
|
||||||
@ -1700,6 +1713,7 @@ FSP_API VOID FspEventLogV(ULONG Type, PWSTR Format, va_list ap);
|
|||||||
FSP_API VOID FspDebugLogSetHandle(HANDLE Handle);
|
FSP_API VOID FspDebugLogSetHandle(HANDLE Handle);
|
||||||
FSP_API VOID FspDebugLog(const char *Format, ...);
|
FSP_API VOID FspDebugLog(const char *Format, ...);
|
||||||
FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
FSP_API VOID FspDebugLogSD(const char *Format, PSECURITY_DESCRIPTOR SecurityDescriptor);
|
||||||
|
FSP_API VOID FspDebugLogSid(const char *format, PSID Sid);
|
||||||
FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime);
|
FSP_API VOID FspDebugLogFT(const char *Format, PFILETIME FileTime);
|
||||||
FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request);
|
FSP_API VOID FspDebugLogRequest(FSP_FSCTL_TRANSACT_REQ *Request);
|
||||||
FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_API VOID FspDebugLogResponse(FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
@ -63,6 +63,21 @@ FSP_API VOID FspDebugLogSD(const char *format, PSECURITY_DESCRIPTOR SecurityDesc
|
|||||||
FspDebugLog(format, "invalid security descriptor");
|
FspDebugLog(format, "invalid security descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API VOID FspDebugLogSid(const char *format, PSID Sid)
|
||||||
|
{
|
||||||
|
char *S;
|
||||||
|
|
||||||
|
if (0 == Sid)
|
||||||
|
FspDebugLog(format, "null SID");
|
||||||
|
else if (ConvertSidToStringSidA(Sid, &S))
|
||||||
|
{
|
||||||
|
FspDebugLog(format, S);
|
||||||
|
LocalFree(S);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FspDebugLog(format, "invalid SID");
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspDebugLogFT(const char *format, PFILETIME FileTime)
|
FSP_API VOID FspDebugLogFT(const char *format, PFILETIME FileTime)
|
||||||
{
|
{
|
||||||
SYSTEMTIME SystemTime;
|
SYSTEMTIME SystemTime;
|
||||||
|
104
src/dll/fs.c
104
src/dll/fs.c
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
#include <launcher/launcher.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -187,17 +188,101 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *FileSystem)
|
|||||||
MemFree(FileSystem);
|
MemFree(FileSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFileSystemLauncherDefineDosDevice(
|
||||||
|
WCHAR Sign, PWSTR MountPoint, PWSTR VolumeName)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
ULONG MountPointLen, VolumeNameLen;
|
||||||
|
PWSTR PipeBuf = 0, P;
|
||||||
|
DWORD BytesTransferred;
|
||||||
|
|
||||||
|
MountPointLen = lstrlenW(MountPoint);
|
||||||
|
VolumeNameLen = lstrlenW(VolumeName);
|
||||||
|
|
||||||
|
if (2 != MountPointLen ||
|
||||||
|
FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR) <= VolumeNameLen)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
if (0 == PipeBuf)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
P = PipeBuf;
|
||||||
|
*P++ = LauncherDefineDosDevice;
|
||||||
|
*P++ = Sign;
|
||||||
|
memcpy(P, MountPoint, MountPointLen * sizeof(WCHAR)); P += MountPointLen; *P++ = L'\0';
|
||||||
|
memcpy(P, VolumeName, VolumeNameLen * sizeof(WCHAR)); P += VolumeNameLen; *P++ = L'\0';
|
||||||
|
|
||||||
|
Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME,
|
||||||
|
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE,
|
||||||
|
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (sizeof(WCHAR) > BytesTransferred)
|
||||||
|
Result = RPC_NT_PROTOCOL_ERROR;
|
||||||
|
else if (LauncherSuccess == PipeBuf[0])
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
else if (LauncherFailure == PipeBuf[0])
|
||||||
|
{
|
||||||
|
DWORD ErrorCode = 0;
|
||||||
|
|
||||||
|
for (PWSTR P = PipeBuf + 1, EndP = PipeBuf + BytesTransferred / sizeof(WCHAR); EndP > P; P++)
|
||||||
|
{
|
||||||
|
if (L'0' > *P || *P > L'9')
|
||||||
|
break;
|
||||||
|
|
||||||
|
ErrorCode = 10 * ErrorCode + (*P - L'0');
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = FspNtStatusFromWin32(ErrorCode);
|
||||||
|
if (0 == Result)
|
||||||
|
Result = RPC_NT_PROTOCOL_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result = RPC_NT_PROTOCOL_ERROR;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(PipeBuf);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName,
|
||||||
PHANDLE PMountHandle)
|
PHANDLE PMountHandle)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
BOOLEAN IsLocalSystem, IsServiceContext;
|
||||||
|
|
||||||
*PMountHandle = 0;
|
*PMountHandle = 0;
|
||||||
|
|
||||||
|
Result = FspServiceContextCheck(0, &IsLocalSystem);
|
||||||
|
IsServiceContext = NT_SUCCESS(Result) && !IsLocalSystem;
|
||||||
|
if (IsServiceContext)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the current process is in the service context but not LocalSystem,
|
||||||
|
* ask the launcher to DefineDosDevice for us. This is because the launcher
|
||||||
|
* runs in the LocalSystem context and can create global drives.
|
||||||
|
*
|
||||||
|
* In this case the launcher will also add DELETE access to the drive symlink
|
||||||
|
* for us, so that we can make it temporary below.
|
||||||
|
*/
|
||||||
|
Result = FspFileSystemLauncherDefineDosDevice(L'+', MountPoint, VolumeName);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
if (!DefineDosDeviceW(DDD_RAW_TARGET_PATH, MountPoint, VolumeName))
|
||||||
return FspNtStatusFromWin32(GetLastError());
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
if (0 != FspNtOpenSymbolicLinkObject)
|
if (0 != FspNtOpenSymbolicLinkObject)
|
||||||
{
|
{
|
||||||
NTSTATUS Result;
|
|
||||||
WCHAR SymlinkBuf[6];
|
WCHAR SymlinkBuf[6];
|
||||||
UNICODE_STRING Symlink;
|
UNICODE_STRING Symlink;
|
||||||
OBJECT_ATTRIBUTES Obja;
|
OBJECT_ATTRIBUTES Obja;
|
||||||
@ -224,6 +309,13 @@ static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* HACK:
|
||||||
|
*
|
||||||
|
* Handles do not use the low 2 bits (unless they are console handles).
|
||||||
|
* Abuse this fact to remember that we are running in the service context.
|
||||||
|
*/
|
||||||
|
*PMountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)*PMountHandle | IsServiceContext);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,6 +503,16 @@ exit:
|
|||||||
|
|
||||||
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
static VOID FspFileSystemRemoveMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, HANDLE MountHandle)
|
||||||
{
|
{
|
||||||
|
BOOLEAN IsServiceContext = 0 != ((DWORD)(UINT_PTR)MountHandle & 1);
|
||||||
|
MountHandle = (HANDLE)(UINT_PTR)((DWORD)(UINT_PTR)MountHandle & ~1);
|
||||||
|
if (IsServiceContext)
|
||||||
|
/*
|
||||||
|
* If the current process is in the service context but not LocalSystem,
|
||||||
|
* ask the launcher to DefineDosDevice for us. This is because the launcher
|
||||||
|
* runs in the LocalSystem context and can remove global drives.
|
||||||
|
*/
|
||||||
|
FspFileSystemLauncherDefineDosDevice(L'-', MountPoint, VolumeName);
|
||||||
|
else
|
||||||
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
DefineDosDeviceW(DDD_RAW_TARGET_PATH | DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE,
|
||||||
MountPoint, VolumeName);
|
MountPoint, VolumeName);
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
* This function adds an ACE that allows Everyone to start a service.
|
* This function adds an ACE that allows Everyone to start a service.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
PSID WorldSid = 0;
|
PSID WorldSid;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
EXPLICIT_ACCESSW AccessEntry;
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
@ -296,18 +296,12 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
|
|
||||||
/* get the Everyone (World) SID */
|
/* get the Everyone (World) SID */
|
||||||
Size = SECURITY_MAX_SID_SIZE;
|
WorldSid = FspWksidGet(WinWorldSid);
|
||||||
WorldSid = MemAlloc(Size);
|
|
||||||
if (0 == WorldSid)
|
if (0 == WorldSid)
|
||||||
{
|
{
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (!CreateWellKnownSid(WinWorldSid, 0, WorldSid, &Size))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the service security descriptor DACL */
|
/* get the service security descriptor DACL */
|
||||||
Size = 0;
|
Size = 0;
|
||||||
@ -394,7 +388,6 @@ static NTSTATUS FspFsctlFixServiceSecurity(HANDLE SvcHandle)
|
|||||||
exit:
|
exit:
|
||||||
LocalFree(NewSecurityDescriptor);
|
LocalFree(NewSecurityDescriptor);
|
||||||
MemFree(SecurityDescriptor);
|
MemFree(SecurityDescriptor);
|
||||||
MemFree(WorldSid);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE Instance, DWORD Reason, PVOID Reserved)
|
|||||||
FspServiceFinalize(Dynamic);
|
FspServiceFinalize(Dynamic);
|
||||||
FspEventLogFinalize(Dynamic);
|
FspEventLogFinalize(Dynamic);
|
||||||
FspPosixFinalize(Dynamic);
|
FspPosixFinalize(Dynamic);
|
||||||
|
FspWksidFinalize(Dynamic);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
|
@ -31,11 +31,15 @@
|
|||||||
FspDebugLog("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", __VA_ARGS__)
|
FspDebugLog("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", __VA_ARGS__)
|
||||||
#define DEBUGLOGSD(fmt, SD) \
|
#define DEBUGLOGSD(fmt, SD) \
|
||||||
FspDebugLogSD("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", SD)
|
FspDebugLogSD("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", SD)
|
||||||
|
#define DEBUGLOGSID(fmt, Sid) \
|
||||||
|
FspDebugLogSid("[U] " LIBRARY_NAME "!" __FUNCTION__ ": " fmt "\n", Sid)
|
||||||
#else
|
#else
|
||||||
#define DEBUGLOG(fmt, ...) ((void)0)
|
#define DEBUGLOG(fmt, ...) ((void)0)
|
||||||
#define DEBUGLOGSD(fmt, SD) ((void)0)
|
#define DEBUGLOGSD(fmt, SD) ((void)0)
|
||||||
|
#define DEBUGLOGSID(fmt, Sid) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VOID FspWksidFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspPosixFinalize(BOOLEAN Dynamic);
|
VOID FspPosixFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspEventLogFinalize(BOOLEAN Dynamic);
|
VOID FspEventLogFinalize(BOOLEAN Dynamic);
|
||||||
VOID FspServiceFinalize(BOOLEAN Dynamic);
|
VOID FspServiceFinalize(BOOLEAN Dynamic);
|
||||||
@ -49,6 +53,9 @@ NTSTATUS FspNpUnregister(VOID);
|
|||||||
NTSTATUS FspEventLogRegister(VOID);
|
NTSTATUS FspEventLogRegister(VOID);
|
||||||
NTSTATUS FspEventLogUnregister(VOID);
|
NTSTATUS FspEventLogUnregister(VOID);
|
||||||
|
|
||||||
|
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult);
|
||||||
|
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType);
|
||||||
|
|
||||||
PWSTR FspDiagIdent(VOID);
|
PWSTR FspDiagIdent(VOID);
|
||||||
|
|
||||||
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
|
||||||
|
@ -453,9 +453,12 @@ FSP_API NTSTATUS FspPosixMapPermissionsToSecurityDescriptor(
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = FspPosixMapUidToSid(0x10100, &WorldSid);
|
WorldSid = FspWksidGet(WinWorldSid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (0 == WorldSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
OwnerPerm = (Mode & 0700) >> 6;
|
OwnerPerm = (Mode & 0700) >> 6;
|
||||||
GroupPerm = (Mode & 0070) >> 3;
|
GroupPerm = (Mode & 0070) >> 3;
|
||||||
@ -579,9 +582,6 @@ exit:
|
|||||||
|
|
||||||
MemFree(Acl);
|
MemFree(Acl);
|
||||||
|
|
||||||
if (0 != WorldSid)
|
|
||||||
FspDeleteSid(WorldSid, FspPosixMapUidToSid);
|
|
||||||
|
|
||||||
if (0 != GroupSid)
|
if (0 != GroupSid)
|
||||||
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
|
FspDeleteSid(GroupSid, FspPosixMapUidToSid);
|
||||||
|
|
||||||
@ -649,13 +649,19 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
|
|||||||
|
|
||||||
if (0 != Acl)
|
if (0 != Acl)
|
||||||
{
|
{
|
||||||
Result = FspPosixMapUidToSid(0x10100, &WorldSid);
|
WorldSid = FspWksidGet(WinWorldSid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (0 == WorldSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
Result = FspPosixMapUidToSid(11, &AuthUsersSid);
|
AuthUsersSid = FspWksidGet(WinAuthenticatedUserSid);
|
||||||
if (!NT_SUCCESS(Result))
|
if (0 == AuthUsersSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
goto exit;
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
|
OwnerAllow = OwnerDeny = GroupAllow = GroupDeny = WorldAllow = WorldDeny = 0;
|
||||||
|
|
||||||
@ -771,12 +777,6 @@ FSP_API NTSTATUS FspPosixMapSecurityDescriptorToPermissions(
|
|||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (0 != AuthUsersSid)
|
|
||||||
FspDeleteSid(AuthUsersSid, FspPosixMapUidToSid);
|
|
||||||
|
|
||||||
if (0 != WorldSid)
|
|
||||||
FspDeleteSid(WorldSid, FspPosixMapUidToSid);
|
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
|
|
||||||
lasterror:
|
lasterror:
|
||||||
|
@ -566,6 +566,106 @@ FSP_API BOOLEAN FspServiceIsInteractive(VOID)
|
|||||||
return IsInteractive;
|
return IsInteractive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspServiceContextCheck(HANDLE Token, PBOOLEAN PIsLocalSystem)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PSID LocalSystemSid, ServiceSid;
|
||||||
|
BOOLEAN IsLocalSystem = FALSE;
|
||||||
|
BOOL HasServiceSid = FALSE;
|
||||||
|
HANDLE ProcessToken = 0, ImpersonationToken = 0;
|
||||||
|
DWORD SessionId, Size;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
TOKEN_USER V;
|
||||||
|
UINT8 B[128];
|
||||||
|
} UserInfoBuf;
|
||||||
|
PTOKEN_USER UserInfo = &UserInfoBuf.V;
|
||||||
|
|
||||||
|
LocalSystemSid = FspWksidGet(WinLocalSystemSid);
|
||||||
|
ServiceSid = FspWksidGet(WinServiceSid);
|
||||||
|
if (0 == LocalSystemSid || 0 == ServiceSid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == Token)
|
||||||
|
{
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &ProcessToken) ||
|
||||||
|
!DuplicateToken(ProcessToken, SecurityImpersonation, &ImpersonationToken))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Token = ImpersonationToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenSessionId, &SessionId, sizeof SessionId, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != SessionId)
|
||||||
|
{
|
||||||
|
Result = STATUS_ACCESS_DENIED;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, sizeof UserInfoBuf, &Size))
|
||||||
|
{
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserInfo = MemAlloc(Size);
|
||||||
|
if (0 == UserInfo)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, UserInfo, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IsLocalSystem = EqualSid(LocalSystemSid, UserInfo->User.Sid);
|
||||||
|
if (IsLocalSystem)
|
||||||
|
{
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CheckTokenMembership(Token, ServiceSid, &HasServiceSid))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = HasServiceSid ? STATUS_SUCCESS : STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != PIsLocalSystem)
|
||||||
|
*PIsLocalSystem = NT_SUCCESS(Result) ? IsLocalSystem : FALSE;
|
||||||
|
|
||||||
|
if (UserInfo != &UserInfoBuf.V)
|
||||||
|
MemFree(UserInfo);
|
||||||
|
|
||||||
|
if (0 != ImpersonationToken)
|
||||||
|
CloseHandle(ImpersonationToken);
|
||||||
|
|
||||||
|
if (0 != ProcessToken)
|
||||||
|
CloseHandle(ProcessToken);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...)
|
FSP_API VOID FspServiceLog(ULONG Type, PWSTR Format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -97,26 +97,16 @@ FSP_API NTSTATUS FspCallNamedPipeSecurely(PWSTR PipeName,
|
|||||||
{
|
{
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
PSID OwnerSid, WellKnownSid = 0;
|
PSID OwnerSid, WellKnownSid = 0;
|
||||||
DWORD SidSize, LastError;
|
DWORD LastError;
|
||||||
|
|
||||||
/* if it is a small number treat it like a well known SID */
|
/* if it is a small number treat it like a well known SID */
|
||||||
if (1024 > (INT_PTR)Sid)
|
if (1024 > (INT_PTR)Sid)
|
||||||
{
|
{
|
||||||
SidSize = SECURITY_MAX_SID_SIZE;
|
WellKnownSid = FspWksidNew((INT_PTR)Sid, &Result);
|
||||||
WellKnownSid = MemAlloc(SidSize);
|
|
||||||
if (0 == WellKnownSid)
|
if (0 == WellKnownSid)
|
||||||
{
|
|
||||||
Result = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto sid_exit;
|
goto sid_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateWellKnownSid((INT_PTR)Sid, 0, WellKnownSid, &SidSize))
|
|
||||||
{
|
|
||||||
Result = FspNtStatusFromWin32(GetLastError());
|
|
||||||
goto sid_exit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LastError = GetSecurityInfo(Pipe, SE_FILE_OBJECT,
|
LastError = GetSecurityInfo(Pipe, SE_FILE_OBJECT,
|
||||||
OWNER_SECURITY_INFORMATION, &OwnerSid, 0, 0, 0, &SecurityDescriptor);
|
OWNER_SECURITY_INFORMATION, &OwnerSid, 0, 0, 0, &SecurityDescriptor);
|
||||||
if (0 != LastError)
|
if (0 != LastError)
|
||||||
|
108
src/dll/wksid.c
Normal file
108
src/dll/wksid.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
* @file dll/wksid.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 <dll/library.h>
|
||||||
|
|
||||||
|
static INIT_ONCE FspWksidInitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
|
static PSID FspWksidWorld;
|
||||||
|
static PSID FspWksidAuthenticatedUser;
|
||||||
|
static PSID FspWksidLocalSystem;
|
||||||
|
static PSID FspWksidService;
|
||||||
|
|
||||||
|
static BOOL WINAPI FspWksidInitialize(
|
||||||
|
PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context)
|
||||||
|
{
|
||||||
|
FspWksidWorld = FspWksidNew(WinWorldSid, 0);
|
||||||
|
FspWksidAuthenticatedUser = FspWksidNew(WinAuthenticatedUserSid, 0);
|
||||||
|
FspWksidLocalSystem = FspWksidNew(WinLocalSystemSid, 0);
|
||||||
|
FspWksidService = FspWksidNew(WinServiceSid, 0);
|
||||||
|
|
||||||
|
//DEBUGLOGSID("FspWksidWorld=%s", FspWksidWorld);
|
||||||
|
//DEBUGLOGSID("FspWksidAuthenticatedUser=%s", FspWksidAuthenticatedUser);
|
||||||
|
//DEBUGLOGSID("FspWksidLocalSystem=%s", FspWksidLocalSystem);
|
||||||
|
//DEBUGLOGSID("FspWksidService=%s", FspWksidService);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FspWksidFinalize(BOOLEAN Dynamic)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This function is called during DLL_PROCESS_DETACH. We must therefore keep
|
||||||
|
* finalization tasks to a minimum.
|
||||||
|
*
|
||||||
|
* We must deregister our event source (if any). We only do so if the library
|
||||||
|
* is being explicitly unloaded (rather than the process exiting).
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Dynamic)
|
||||||
|
{
|
||||||
|
MemFree(FspWksidWorld); FspWksidWorld = 0;
|
||||||
|
MemFree(FspWksidAuthenticatedUser); FspWksidAuthenticatedUser = 0;
|
||||||
|
MemFree(FspWksidLocalSystem); FspWksidLocalSystem = 0;
|
||||||
|
MemFree(FspWksidService); FspWksidService = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PSID FspWksidNew(WELL_KNOWN_SID_TYPE WellKnownSidType, PNTSTATUS PResult)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
PSID Sid;
|
||||||
|
DWORD Size;
|
||||||
|
|
||||||
|
Size = SECURITY_MAX_SID_SIZE;
|
||||||
|
Sid = MemAlloc(Size);
|
||||||
|
if (0 == Sid)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CreateWellKnownSid(WellKnownSidType, 0, Sid, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
MemFree(Sid); Sid = 0;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (0 != PResult)
|
||||||
|
*PResult = Result;
|
||||||
|
|
||||||
|
return Sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSID FspWksidGet(WELL_KNOWN_SID_TYPE WellKnownSidType)
|
||||||
|
{
|
||||||
|
InitOnceExecuteOnce(&FspWksidInitOnce, FspWksidInitialize, 0, 0);
|
||||||
|
|
||||||
|
switch (WellKnownSidType)
|
||||||
|
{
|
||||||
|
case WinWorldSid:
|
||||||
|
return FspWksidWorld;
|
||||||
|
case WinAuthenticatedUserSid:
|
||||||
|
return FspWksidAuthenticatedUser;
|
||||||
|
case WinLocalSystemSid:
|
||||||
|
return FspWksidLocalSystem;
|
||||||
|
case WinServiceSid:
|
||||||
|
return FspWksidService;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -16,10 +16,19 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <launcher/launcher.h>
|
#include <launcher/launcher.h>
|
||||||
|
#include <aclapi.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
#include <userenv.h>
|
||||||
|
|
||||||
#define PROGNAME "WinFsp.Launcher"
|
#define PROGNAME "WinFsp.Launcher"
|
||||||
|
|
||||||
|
static NTSTATUS (NTAPI *SvcNtOpenSymbolicLinkObject)(
|
||||||
|
PHANDLE LinkHandle,
|
||||||
|
ACCESS_MASK DesiredAccess,
|
||||||
|
POBJECT_ATTRIBUTES ObjectAttributes);
|
||||||
|
static NTSTATUS (NTAPI *SvcNtClose)(
|
||||||
|
HANDLE Handle);
|
||||||
|
|
||||||
BOOL CreateOverlappedPipe(
|
BOOL CreateOverlappedPipe(
|
||||||
PHANDLE PReadPipe, PHANDLE PWritePipe,
|
PHANDLE PReadPipe, PHANDLE PWritePipe,
|
||||||
DWORD Size,
|
DWORD Size,
|
||||||
@ -141,6 +150,201 @@ exit:
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS AddAccessForTokenUser(HANDLE Handle, DWORD Access, HANDLE Token)
|
||||||
|
{
|
||||||
|
TOKEN_USER *User = 0;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
||||||
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor = 0;
|
||||||
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
|
DWORD Size, LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (GetTokenInformation(Token, TokenUser, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
User = MemAlloc(Size);
|
||||||
|
if (0 == User)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, User, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityDescriptor = MemAlloc(Size);
|
||||||
|
if (0 == SecurityDescriptor)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, SecurityDescriptor, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessEntry.grfAccessPermissions = Access;
|
||||||
|
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 = User->User.Sid;
|
||||||
|
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetKernelObjectSecurity(Handle, DACL_SECURITY_INFORMATION, NewSecurityDescriptor))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
LocalFree(NewSecurityDescriptor);
|
||||||
|
MemFree(SecurityDescriptor);
|
||||||
|
MemFree(User);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL LogonCreateProcess(
|
||||||
|
PWSTR UserName,
|
||||||
|
LPCWSTR ApplicationName,
|
||||||
|
LPWSTR CommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES ProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES ThreadAttributes,
|
||||||
|
BOOL InheritHandles,
|
||||||
|
DWORD CreationFlags,
|
||||||
|
LPVOID Environment,
|
||||||
|
LPCWSTR CurrentDirectory,
|
||||||
|
LPSTARTUPINFOW StartupInfo,
|
||||||
|
LPPROCESS_INFORMATION ProcessInformation)
|
||||||
|
{
|
||||||
|
PWSTR DomainName = 0;
|
||||||
|
|
||||||
|
if (0 != UserName)
|
||||||
|
{
|
||||||
|
if (0 == invariant_wcsicmp(UserName, L"LocalSystem"))
|
||||||
|
UserName = 0;
|
||||||
|
else
|
||||||
|
if (0 == invariant_wcsicmp(UserName, L"LocalService") ||
|
||||||
|
0 == invariant_wcsicmp(UserName, L"NetworkService"))
|
||||||
|
DomainName = L"NT AUTHORITY";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_ACCESS_DENIED);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == UserName)
|
||||||
|
/* without a user name go ahead and call CreateProcessW */
|
||||||
|
return CreateProcessW(
|
||||||
|
ApplicationName,
|
||||||
|
CommandLine,
|
||||||
|
ProcessAttributes,
|
||||||
|
ThreadAttributes,
|
||||||
|
InheritHandles,
|
||||||
|
CreationFlags,
|
||||||
|
Environment,
|
||||||
|
CurrentDirectory,
|
||||||
|
StartupInfo,
|
||||||
|
ProcessInformation);
|
||||||
|
|
||||||
|
HANDLE LogonToken = 0;
|
||||||
|
PVOID EnvironmentBlock = 0;
|
||||||
|
DWORD LastError;
|
||||||
|
BOOL Success;
|
||||||
|
|
||||||
|
Success = LogonUserW(
|
||||||
|
UserName,
|
||||||
|
DomainName,
|
||||||
|
0,
|
||||||
|
LOGON32_LOGON_SERVICE,
|
||||||
|
LOGON32_PROVIDER_DEFAULT,
|
||||||
|
&LogonToken);
|
||||||
|
if (!Success)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
if (0 == Environment)
|
||||||
|
{
|
||||||
|
Success = CreateEnvironmentBlock(&EnvironmentBlock, LogonToken, FALSE);
|
||||||
|
if (!Success)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
CreationFlags |= CREATE_UNICODE_ENVIRONMENT;
|
||||||
|
Environment = EnvironmentBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = ImpersonateLoggedOnUser(LogonToken);
|
||||||
|
if (!Success)
|
||||||
|
goto exit;
|
||||||
|
|
||||||
|
Success = CreateProcessAsUserW(
|
||||||
|
LogonToken,
|
||||||
|
ApplicationName,
|
||||||
|
CommandLine,
|
||||||
|
ProcessAttributes,
|
||||||
|
ThreadAttributes,
|
||||||
|
InheritHandles,
|
||||||
|
CreationFlags,
|
||||||
|
Environment,
|
||||||
|
CurrentDirectory,
|
||||||
|
StartupInfo,
|
||||||
|
ProcessInformation);
|
||||||
|
|
||||||
|
if (!RevertToSelf())
|
||||||
|
/* should not happen! */
|
||||||
|
ExitProcess(GetLastError());
|
||||||
|
|
||||||
|
exit:
|
||||||
|
if (!Success)
|
||||||
|
LastError = GetLastError();
|
||||||
|
|
||||||
|
if (0 != EnvironmentBlock)
|
||||||
|
DestroyEnvironmentBlock(EnvironmentBlock);
|
||||||
|
if (0 != LogonToken)
|
||||||
|
CloseHandle(LogonToken);
|
||||||
|
|
||||||
|
if (!Success)
|
||||||
|
SetLastError(LastError);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Process;
|
HANDLE Process;
|
||||||
@ -352,6 +556,67 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS SvcInstanceAddUserRights(HANDLE Token,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR *PNewSecurityDescriptor)
|
||||||
|
{
|
||||||
|
PSECURITY_DESCRIPTOR NewSecurityDescriptor;
|
||||||
|
TOKEN_USER *User = 0;
|
||||||
|
EXPLICIT_ACCESSW AccessEntry;
|
||||||
|
DWORD Size, LastError;
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
*PNewSecurityDescriptor = 0;
|
||||||
|
|
||||||
|
if (GetTokenInformation(Token, TokenUser, 0, 0, &Size))
|
||||||
|
{
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
User = MemAlloc(Size);
|
||||||
|
if (0 == User)
|
||||||
|
{
|
||||||
|
Result = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetTokenInformation(Token, TokenUser, User, Size, &Size))
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(GetLastError());
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessEntry.grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_STOP;
|
||||||
|
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 = User->User.Sid;
|
||||||
|
|
||||||
|
LastError = BuildSecurityDescriptorW(0, 0, 1, &AccessEntry, 0, 0, SecurityDescriptor,
|
||||||
|
&Size, &NewSecurityDescriptor);
|
||||||
|
if (0 != LastError)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(LastError);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
*PNewSecurityDescriptor = NewSecurityDescriptor;
|
||||||
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
MemFree(User);
|
||||||
|
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
|
static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor)
|
PSECURITY_DESCRIPTOR SecurityDescriptor)
|
||||||
{
|
{
|
||||||
@ -380,7 +645,8 @@ static NTSTATUS SvcInstanceAccessCheck(HANDLE ClientToken, ULONG DesiredAccess,
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
NTSTATUS SvcInstanceCreateProcess(PWSTR UserName,
|
||||||
|
PWSTR Executable, PWSTR CommandLine,
|
||||||
HANDLE StdioHandles[2],
|
HANDLE StdioHandles[2],
|
||||||
PPROCESS_INFORMATION ProcessInfo)
|
PPROCESS_INFORMATION ProcessInfo)
|
||||||
{
|
{
|
||||||
@ -457,7 +723,8 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
|||||||
StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1];
|
StartupInfoEx.StartupInfo.hStdOutput = ChildHandles[1];
|
||||||
StartupInfoEx.StartupInfo.hStdError = ChildHandles[2];
|
StartupInfoEx.StartupInfo.hStdError = ChildHandles[2];
|
||||||
|
|
||||||
if (!CreateProcessW(Executable, CommandLine, 0, 0, TRUE,
|
if (!LogonCreateProcess(UserName,
|
||||||
|
Executable, CommandLine, 0, 0, TRUE,
|
||||||
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, 0, 0,
|
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP | EXTENDED_STARTUPINFO_PRESENT, 0, 0,
|
||||||
&StartupInfoEx.StartupInfo, ProcessInfo))
|
&StartupInfoEx.StartupInfo, ProcessInfo))
|
||||||
{
|
{
|
||||||
@ -476,7 +743,8 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
|||||||
* Not ideal, but...
|
* Not ideal, but...
|
||||||
*/
|
*/
|
||||||
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
|
StartupInfoEx.StartupInfo.cb = sizeof StartupInfoEx.StartupInfo;
|
||||||
if (!CreateProcessW(Executable, CommandLine, 0, 0, TRUE,
|
if (!LogonCreateProcess(UserName,
|
||||||
|
Executable, CommandLine, 0, 0, TRUE,
|
||||||
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0,
|
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0,
|
||||||
&StartupInfoEx.StartupInfo, ProcessInfo))
|
&StartupInfoEx.StartupInfo, ProcessInfo))
|
||||||
{
|
{
|
||||||
@ -487,7 +755,8 @@ NTSTATUS SvcInstanceCreateProcess(PWSTR Executable, PWSTR CommandLine,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!CreateProcessW(Executable, CommandLine, 0, 0, FALSE,
|
if (!LogonCreateProcess(UserName,
|
||||||
|
Executable, CommandLine, 0, 0, FALSE,
|
||||||
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0,
|
CREATE_SUSPENDED | CREATE_NEW_PROCESS_GROUP, 0, 0,
|
||||||
&StartupInfoEx.StartupInfo, ProcessInfo))
|
&StartupInfoEx.StartupInfo, ProcessInfo))
|
||||||
{
|
{
|
||||||
@ -531,10 +800,10 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
HKEY RegKey = 0;
|
HKEY RegKey = 0;
|
||||||
DWORD RegResult, RegSize;
|
DWORD RegResult, RegSize;
|
||||||
DWORD ClassNameSize, InstanceNameSize;
|
DWORD ClassNameSize, InstanceNameSize;
|
||||||
WCHAR Executable[MAX_PATH], CommandLineBuf[512], SecurityBuf[512];
|
WCHAR Executable[MAX_PATH], CommandLineBuf[512], SecurityBuf[512], RunAsBuf[256];
|
||||||
PWSTR CommandLine, Security;
|
PWSTR CommandLine, Security;
|
||||||
DWORD JobControl, Credentials;
|
DWORD JobControl, Credentials;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor = 0;
|
PSECURITY_DESCRIPTOR SecurityDescriptor = 0, NewSecurityDescriptor;
|
||||||
PWSTR Argv[10];
|
PWSTR Argv[10];
|
||||||
PROCESS_INFORMATION ProcessInfo;
|
PROCESS_INFORMATION ProcessInfo;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -618,6 +887,16 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RegSize = sizeof RunAsBuf;
|
||||||
|
RunAsBuf[0] = L'\0';
|
||||||
|
RegResult = RegGetValueW(RegKey, ClassName, L"RunAs", RRF_RT_REG_SZ, 0,
|
||||||
|
RunAsBuf, &RegSize);
|
||||||
|
if (ERROR_SUCCESS != RegResult && ERROR_FILE_NOT_FOUND != RegResult)
|
||||||
|
{
|
||||||
|
Result = FspNtStatusFromWin32(RegResult);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
RegSize = sizeof JobControl;
|
RegSize = sizeof JobControl;
|
||||||
JobControl = 1; /* default is YES! */
|
JobControl = 1; /* default is YES! */
|
||||||
RegResult = RegGetValueW(RegKey, ClassName, L"JobControl", RRF_RT_REG_DWORD, 0,
|
RegResult = RegGetValueW(RegKey, ClassName, L"JobControl", RRF_RT_REG_DWORD, 0,
|
||||||
@ -649,6 +928,14 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
|
Result = SvcInstanceAddUserRights(ClientToken, SecurityDescriptor, &NewSecurityDescriptor);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
goto exit;
|
||||||
|
LocalFree(SecurityDescriptor);
|
||||||
|
SecurityDescriptor = NewSecurityDescriptor;
|
||||||
|
|
||||||
|
//FspDebugLogSD(__FUNCTION__ ": SDDL = %s\n", SecurityDescriptor);
|
||||||
|
|
||||||
ClassNameSize = (lstrlenW(ClassName) + 1) * sizeof(WCHAR);
|
ClassNameSize = (lstrlenW(ClassName) + 1) * sizeof(WCHAR);
|
||||||
InstanceNameSize = (lstrlenW(InstanceName) + 1) * sizeof(WCHAR);
|
InstanceNameSize = (lstrlenW(InstanceName) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
@ -673,7 +960,8 @@ NTSTATUS SvcInstanceCreate(HANDLE ClientToken,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
Result = SvcInstanceCreateProcess(Executable, SvcInstance->CommandLine,
|
Result = SvcInstanceCreateProcess(L'\0' != RunAsBuf[0] ? RunAsBuf : 0,
|
||||||
|
Executable, SvcInstance->CommandLine,
|
||||||
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo);
|
RedirectStdio ? SvcInstance->StdioHandles : 0, &ProcessInfo);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -744,6 +1032,9 @@ exit:
|
|||||||
|
|
||||||
LeaveCriticalSection(&SvcInstanceLock);
|
LeaveCriticalSection(&SvcInstanceLock);
|
||||||
|
|
||||||
|
FspServiceLog(EVENTLOG_INFORMATION_TYPE,
|
||||||
|
L"create %s\\%s = %lx", ClassName, InstanceName, Result);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,6 +1068,9 @@ static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout)
|
|||||||
{
|
{
|
||||||
SVC_INSTANCE *SvcInstance = Context;
|
SVC_INSTANCE *SvcInstance = Context;
|
||||||
|
|
||||||
|
FspServiceLog(EVENTLOG_INFORMATION_TYPE,
|
||||||
|
L"terminated %s\\%s", SvcInstance->ClassName, SvcInstance->InstanceName);
|
||||||
|
|
||||||
SvcInstanceRelease(SvcInstance);
|
SvcInstanceRelease(SvcInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,6 +1303,53 @@ NTSTATUS SvcInstanceStopAndWaitAll(VOID)
|
|||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS SvcDefineDosDevice(HANDLE ClientToken,
|
||||||
|
PWSTR DeviceName, PWSTR TargetPath)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
|
||||||
|
if (L'+' != DeviceName[0] && L'-' != DeviceName[0])
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
Result = FspServiceContextCheck(ClientToken, 0);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
if (!DefineDosDeviceW(
|
||||||
|
DDD_RAW_TARGET_PATH |
|
||||||
|
(L'+' == DeviceName[0] ? 0 : DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE),
|
||||||
|
DeviceName + 1, TargetPath))
|
||||||
|
return FspNtStatusFromWin32(GetLastError());
|
||||||
|
|
||||||
|
if (L'+' == DeviceName[0] && 0 != SvcNtOpenSymbolicLinkObject)
|
||||||
|
{
|
||||||
|
/* The drive symlink now exists; add DELETE access to it for the ClientToken. */
|
||||||
|
WCHAR SymlinkBuf[6];
|
||||||
|
UNICODE_STRING Symlink;
|
||||||
|
OBJECT_ATTRIBUTES Obja;
|
||||||
|
HANDLE MountHandle;
|
||||||
|
|
||||||
|
memcpy(SymlinkBuf, L"\\??\\X:", sizeof SymlinkBuf);
|
||||||
|
SymlinkBuf[4] = DeviceName[1];
|
||||||
|
Symlink.Length = Symlink.MaximumLength = sizeof SymlinkBuf;
|
||||||
|
Symlink.Buffer = SymlinkBuf;
|
||||||
|
|
||||||
|
memset(&Obja, 0, sizeof Obja);
|
||||||
|
Obja.Length = sizeof Obja;
|
||||||
|
Obja.ObjectName = &Symlink;
|
||||||
|
Obja.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
|
||||||
|
Result = SvcNtOpenSymbolicLinkObject(&MountHandle, READ_CONTROL | WRITE_DAC, &Obja);
|
||||||
|
if (NT_SUCCESS(Result))
|
||||||
|
{
|
||||||
|
AddAccessForTokenUser(MountHandle, DELETE, ClientToken);
|
||||||
|
SvcNtClose(MountHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static HANDLE SvcJob, SvcThread, SvcEvent;
|
static HANDLE SvcJob, SvcThread, SvcEvent;
|
||||||
static DWORD SvcThreadId;
|
static DWORD SvcThreadId;
|
||||||
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
static HANDLE SvcPipe = INVALID_HANDLE_VALUE;
|
||||||
@ -1329,6 +1670,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
|
|
||||||
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR);
|
||||||
PWSTR ClassName, InstanceName, UserName;
|
PWSTR ClassName, InstanceName, UserName;
|
||||||
|
PWSTR DeviceName, TargetPath;
|
||||||
ULONG Argc; PWSTR Argv[9];
|
ULONG Argc; PWSTR Argv[9];
|
||||||
BOOLEAN HasSecret = FALSE;
|
BOOLEAN HasSecret = FALSE;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -1390,6 +1732,17 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LauncherDefineDosDevice:
|
||||||
|
DeviceName = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
TargetPath = SvcPipeTransactGetPart(&P, PipeBufEnd);
|
||||||
|
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
if (0 != DeviceName && 0 != TargetPath)
|
||||||
|
Result = SvcDefineDosDevice(ClientToken, DeviceName, TargetPath);
|
||||||
|
|
||||||
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
|
break;
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
case LauncherQuit:
|
case LauncherQuit:
|
||||||
SetEvent(SvcEvent);
|
SetEvent(SvcEvent);
|
||||||
@ -1408,6 +1761,19 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
|
|
||||||
int wmain(int argc, wchar_t **argv)
|
int wmain(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
|
HANDLE Handle = GetModuleHandleW(L"ntdll.dll");
|
||||||
|
if (0 != Handle)
|
||||||
|
{
|
||||||
|
SvcNtOpenSymbolicLinkObject = (PVOID)GetProcAddress(Handle, "NtOpenSymbolicLinkObject");
|
||||||
|
SvcNtClose = (PVOID)GetProcAddress(Handle, "NtClose");
|
||||||
|
|
||||||
|
if (0 == SvcNtOpenSymbolicLinkObject || 0 == SvcNtClose)
|
||||||
|
{
|
||||||
|
SvcNtOpenSymbolicLinkObject = 0;
|
||||||
|
SvcNtClose = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
|
return FspServiceRun(L"" PROGNAME, SvcStart, SvcStop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
||||||
#define LAUNCHER_PIPE_BUFFER_SIZE 4096
|
#define LAUNCHER_PIPE_BUFFER_SIZE 4096
|
||||||
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT 3000
|
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT (2 * 15000 + 1000)
|
||||||
|
|
||||||
#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000
|
#define LAUNCHER_START_WITH_SECRET_TIMEOUT 15000
|
||||||
|
|
||||||
@ -62,6 +62,7 @@ enum
|
|||||||
LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */
|
LauncherSvcInstanceStop = 'T', /* requires: SERVICE_STOP */
|
||||||
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
||||||
LauncherSvcInstanceList = 'L', /* requires: none*/
|
LauncherSvcInstanceList = 'L', /* requires: none*/
|
||||||
|
LauncherDefineDosDevice = 'D',
|
||||||
LauncherQuit = 'Q', /* DEBUG version only */
|
LauncherQuit = 'Q', /* DEBUG version only */
|
||||||
|
|
||||||
LauncherSuccess = '$',
|
LauncherSuccess = '$',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user