mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-22 16:33:02 -05:00
dll: np: NPAddConnection3, NPCancelConnection implementation
This commit is contained in:
parent
67c6cd453a
commit
1c3fc530f6
@ -3,3 +3,6 @@ EXPORTS
|
|||||||
DllUnregisterServer PRIVATE
|
DllUnregisterServer PRIVATE
|
||||||
NPGetCaps PRIVATE
|
NPGetCaps PRIVATE
|
||||||
NPGetConnection PRIVATE
|
NPGetConnection PRIVATE
|
||||||
|
NPAddConnection PRIVATE
|
||||||
|
NPAddConnection3 PRIVATE
|
||||||
|
NPCancelConnection PRIVATE
|
||||||
|
209
src/dll/np.c
209
src/dll/np.c
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <dll/library.h>
|
#include <dll/library.h>
|
||||||
|
#include <launcher/launcher.h>
|
||||||
#include <npapi.h>
|
#include <npapi.h>
|
||||||
|
|
||||||
#define FSP_NP_NAME LIBRARY_NAME ".Np"
|
#define FSP_NP_NAME LIBRARY_NAME ".Np"
|
||||||
@ -33,14 +34,17 @@ DWORD APIENTRY NPGetCaps(DWORD Index)
|
|||||||
return 0;
|
return 0;
|
||||||
case WNNC_CONNECTION:
|
case WNNC_CONNECTION:
|
||||||
/*
|
/*
|
||||||
* WNNC_CON_ADDCONECTION
|
* WNNC_CON_ADDCONNECTION
|
||||||
* WNNC_CON_CANCELCONNECTION
|
* WNNC_CON_CANCELCONNECTION
|
||||||
* WNNC_CON_GETCONNECTIONS
|
* WNNC_CON_GETCONNECTIONS
|
||||||
* WNNC_CON_ADDCONECTION3
|
* WNNC_CON_ADDCONNECTION3
|
||||||
* WNNC_CON_GETPERFORMANCE
|
* WNNC_CON_GETPERFORMANCE
|
||||||
* WNNC_CON_DEFER
|
* WNNC_CON_DEFER
|
||||||
*/
|
*/
|
||||||
return WNNC_CON_GETCONNECTIONS;
|
return
|
||||||
|
WNNC_CON_GETCONNECTIONS |
|
||||||
|
WNNC_CON_ADDCONNECTION | WNNC_CON_ADDCONNECTION3 |
|
||||||
|
WNNC_CON_CANCELCONNECTION;
|
||||||
case WNNC_DIALOG:
|
case WNNC_DIALOG:
|
||||||
/*
|
/*
|
||||||
* WNNC_DLG_DEVICEMODE
|
* WNNC_DLG_DEVICEMODE
|
||||||
@ -75,6 +79,88 @@ DWORD APIENTRY NPGetCaps(DWORD Index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline BOOLEAN FspNpCheckLocalName(PWSTR LocalName)
|
||||||
|
{
|
||||||
|
return 0 != LocalName &&
|
||||||
|
(
|
||||||
|
(L'A' <= LocalName[0] && LocalName[0] <= L'Z') ||
|
||||||
|
(L'a' <= LocalName[0] && LocalName[0] <= L'z')
|
||||||
|
) &&
|
||||||
|
L':' == LocalName[1] || L'\0' == LocalName[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOLEAN FspNpCheckRemoteName(PWSTR RemoteName)
|
||||||
|
{
|
||||||
|
return 0 != RemoteName && L'\\' == RemoteName[0] && L'\\' == RemoteName[1] &&
|
||||||
|
sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR) >= lstrlenW(RemoteName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline BOOLEAN FspNpParseRemoteName(PWSTR RemoteName,
|
||||||
|
PWSTR *PClassName, PULONG PClassNameLen,
|
||||||
|
PWSTR *PInstanceName, PULONG PInstanceNameLen)
|
||||||
|
{
|
||||||
|
PWSTR ClassName, InstanceName, P;
|
||||||
|
ULONG ClassNameLen, InstanceNameLen;
|
||||||
|
|
||||||
|
ClassName = RemoteName + 2; /* skip \\ */
|
||||||
|
for (P = ClassName; *P; P++)
|
||||||
|
if (L'\\' == *P)
|
||||||
|
break;
|
||||||
|
if (ClassName == P || L'\\' != *P)
|
||||||
|
return FALSE;
|
||||||
|
ClassNameLen = (ULONG)(P - ClassName);
|
||||||
|
|
||||||
|
InstanceName = P + 1;
|
||||||
|
for (P = InstanceName; *P; P++)
|
||||||
|
;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (InstanceName == P)
|
||||||
|
return FALSE;
|
||||||
|
if (L'\\' != P[-1])
|
||||||
|
break;
|
||||||
|
P--;
|
||||||
|
}
|
||||||
|
InstanceNameLen = (ULONG)(P - InstanceName);
|
||||||
|
|
||||||
|
*PClassName = ClassName; *PClassNameLen = ClassNameLen;
|
||||||
|
*PInstanceName = InstanceName; *PInstanceNameLen = InstanceNameLen;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
||||||
|
{
|
||||||
|
DWORD NpResult;
|
||||||
|
DWORD LastError, BytesTransferred;
|
||||||
|
|
||||||
|
LastError = CallNamedPipeW(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
||||||
|
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT) ? 0 : GetLastError();
|
||||||
|
|
||||||
|
if (0 != LastError)
|
||||||
|
NpResult = WN_NO_NETWORK;
|
||||||
|
else if (sizeof(WCHAR) > BytesTransferred)
|
||||||
|
NpResult = WN_NO_NETWORK;
|
||||||
|
else if (LauncherSuccess == PipeBuf[0])
|
||||||
|
NpResult = WN_SUCCESS;
|
||||||
|
else if (LauncherFailure == PipeBuf[0])
|
||||||
|
{
|
||||||
|
if (BytesTransferred < RecvSize)
|
||||||
|
PipeBuf[BytesTransferred / sizeof(WCHAR)] = L'\0';
|
||||||
|
else
|
||||||
|
PipeBuf[RecvSize / sizeof(WCHAR) - 1] = L'\0';
|
||||||
|
|
||||||
|
if (0 == lstrcmpW(L"183"/*ERROR_ALREADY_EXISTS*/, PipeBuf + 1))
|
||||||
|
NpResult = WN_ALREADY_CONNECTED;
|
||||||
|
else
|
||||||
|
NpResult = WN_NO_NETWORK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
NpResult = WN_NO_NETWORK;
|
||||||
|
|
||||||
|
return NpResult;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS FspNpGetVolumeList(
|
static NTSTATUS FspNpGetVolumeList(
|
||||||
PWCHAR *PVolumeListBuf, PSIZE_T PVolumeListSize)
|
PWCHAR *PVolumeListBuf, PSIZE_T PVolumeListSize)
|
||||||
{
|
{
|
||||||
@ -107,7 +193,8 @@ static NTSTATUS FspNpGetVolumeList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD APIENTRY NPGetConnection(LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnBufferLen)
|
DWORD APIENTRY NPGetConnection(
|
||||||
|
LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD lpnBufferLen)
|
||||||
{
|
{
|
||||||
DWORD NpResult;
|
DWORD NpResult;
|
||||||
NTSTATUS Result;
|
NTSTATUS Result;
|
||||||
@ -117,15 +204,10 @@ DWORD APIENTRY NPGetConnection(LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD
|
|||||||
SIZE_T VolumeListSize, VolumeNameSize;
|
SIZE_T VolumeListSize, VolumeNameSize;
|
||||||
ULONG Backslashes;
|
ULONG Backslashes;
|
||||||
|
|
||||||
if (0 == lpLocalName ||
|
if (!FspNpCheckLocalName(lpLocalName))
|
||||||
!(
|
|
||||||
(L'A' <= lpLocalName[0] && lpLocalName[0] <= L'Z') ||
|
|
||||||
(L'a' <= lpLocalName[0] && lpLocalName[0] <= L'z')
|
|
||||||
) ||
|
|
||||||
L':' != lpLocalName[1])
|
|
||||||
return WN_BAD_LOCALNAME;
|
return WN_BAD_LOCALNAME;
|
||||||
|
|
||||||
LocalNameBuf[0] = lpLocalName[0];
|
LocalNameBuf[0] = lpLocalName[0] & ~0x20; /* convert to uppercase */
|
||||||
LocalNameBuf[1] = L':';
|
LocalNameBuf[1] = L':';
|
||||||
LocalNameBuf[2] = L'\0';
|
LocalNameBuf[2] = L'\0';
|
||||||
|
|
||||||
@ -188,6 +270,111 @@ DWORD APIENTRY NPGetConnection(LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD
|
|||||||
return NpResult;
|
return NpResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, LPWSTR lpUserName)
|
||||||
|
{
|
||||||
|
return NPAddConnection3(0, lpNetResource, lpPassword, lpUserName, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY NPAddConnection3(HWND hwndOwner,
|
||||||
|
LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, LPWSTR lpUserName, DWORD dwFlags)
|
||||||
|
{
|
||||||
|
DWORD NpResult;
|
||||||
|
DWORD dwType = lpNetResource->dwType;
|
||||||
|
LPWSTR lpRemoteName = lpNetResource->lpRemoteName;
|
||||||
|
LPWSTR lpLocalName = lpNetResource->lpLocalName;
|
||||||
|
WCHAR LocalNameBuf[3];
|
||||||
|
PWSTR ClassName, InstanceName, RemoteName, P;
|
||||||
|
ULONG ClassNameLen, InstanceNameLen;
|
||||||
|
PWSTR PipeBuf = 0;
|
||||||
|
|
||||||
|
if (dwType & RESOURCETYPE_PRINT)
|
||||||
|
return WN_BAD_VALUE;
|
||||||
|
|
||||||
|
if (!FspNpCheckRemoteName(lpRemoteName))
|
||||||
|
return WN_BAD_NETNAME;
|
||||||
|
|
||||||
|
if (!FspNpParseRemoteName(lpRemoteName,
|
||||||
|
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
|
||||||
|
return WN_BAD_NETNAME;
|
||||||
|
RemoteName = lpRemoteName + 1;
|
||||||
|
|
||||||
|
LocalNameBuf[0] = L'\0';
|
||||||
|
if (0 != lpLocalName && L'\0' != lpLocalName[0])
|
||||||
|
{
|
||||||
|
if (!FspNpCheckLocalName(lpLocalName))
|
||||||
|
return WN_BAD_LOCALNAME;
|
||||||
|
|
||||||
|
LocalNameBuf[0] = lpLocalName[0] & ~0x20; /* convert to uppercase */
|
||||||
|
LocalNameBuf[1] = L':';
|
||||||
|
LocalNameBuf[2] = L'\0';
|
||||||
|
|
||||||
|
if (GetLogicalDrives() & (1 << (LocalNameBuf[0] - 'A')))
|
||||||
|
return WN_ALREADY_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
if (0 == PipeBuf)
|
||||||
|
return WN_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
P = PipeBuf;
|
||||||
|
*P++ = LauncherSvcInstanceStart;
|
||||||
|
memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0';
|
||||||
|
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
||||||
|
lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1;
|
||||||
|
lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1;
|
||||||
|
|
||||||
|
NpResult = FspNpCallLauncherPipe(
|
||||||
|
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
|
||||||
|
MemFree(PipeBuf);
|
||||||
|
|
||||||
|
return NpResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce)
|
||||||
|
{
|
||||||
|
DWORD NpResult;
|
||||||
|
WCHAR RemoteNameBuf[sizeof(((FSP_FSCTL_VOLUME_PARAMS *)0)->Prefix) / sizeof(WCHAR)];
|
||||||
|
DWORD RemoteNameSize;
|
||||||
|
PWSTR ClassName, InstanceName, RemoteName, P;
|
||||||
|
ULONG ClassNameLen, InstanceNameLen;
|
||||||
|
PWSTR PipeBuf = 0;
|
||||||
|
|
||||||
|
if (FspNpCheckLocalName(lpName))
|
||||||
|
{
|
||||||
|
RemoteNameSize = sizeof RemoteNameBuf / sizeof(WCHAR);
|
||||||
|
NpResult = NPGetConnection(lpName, RemoteNameBuf, &RemoteNameSize);
|
||||||
|
if (WN_SUCCESS != NpResult)
|
||||||
|
return NpResult;
|
||||||
|
|
||||||
|
RemoteName = RemoteNameBuf;
|
||||||
|
}
|
||||||
|
else if (FspNpCheckRemoteName(lpName))
|
||||||
|
RemoteName = lpName;
|
||||||
|
else
|
||||||
|
return WN_BAD_NETNAME;
|
||||||
|
|
||||||
|
if (!FspNpParseRemoteName(RemoteName,
|
||||||
|
&ClassName, &ClassNameLen, &InstanceName, &InstanceNameLen))
|
||||||
|
return WN_BAD_NETNAME;
|
||||||
|
|
||||||
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
if (0 == PipeBuf)
|
||||||
|
return WN_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
P = PipeBuf;
|
||||||
|
*P++ = LauncherSvcInstanceStop;
|
||||||
|
memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0';
|
||||||
|
memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0';
|
||||||
|
|
||||||
|
NpResult = FspNpCallLauncherPipe(
|
||||||
|
PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
|
|
||||||
|
MemFree(PipeBuf);
|
||||||
|
|
||||||
|
return NpResult;
|
||||||
|
}
|
||||||
|
|
||||||
NTSTATUS FspNpRegister(VOID)
|
NTSTATUS FspNpRegister(VOID)
|
||||||
{
|
{
|
||||||
extern HINSTANCE DllInstance;
|
extern HINSTANCE DllInstance;
|
||||||
|
@ -65,14 +65,14 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
|||||||
{
|
{
|
||||||
DWORD LastError, BytesTransferred;
|
DWORD LastError, BytesTransferred;
|
||||||
|
|
||||||
LastError = CallNamedPipeW(L"" PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
LastError = CallNamedPipeW(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize,
|
||||||
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT) ? 0 : GetLastError();
|
&BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT) ? 0 : GetLastError();
|
||||||
|
|
||||||
if (0 != LastError)
|
if (0 != LastError)
|
||||||
warn("KO CallNamedPipeW = %ld", LastError);
|
warn("KO CallNamedPipeW = %ld", LastError);
|
||||||
else if (0 == BytesTransferred)
|
else if (sizeof(WCHAR) > BytesTransferred)
|
||||||
warn("KO launcher: empty buffer");
|
warn("KO launcher: empty buffer");
|
||||||
else if (L'$' == PipeBuf[0])
|
else if (LauncherSuccess == PipeBuf[0])
|
||||||
{
|
{
|
||||||
if (sizeof(WCHAR) == BytesTransferred)
|
if (sizeof(WCHAR) == BytesTransferred)
|
||||||
info("OK");
|
info("OK");
|
||||||
@ -97,7 +97,7 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize)
|
|||||||
info("OK\n%S", PipeBuf + 1);
|
info("OK\n%S", PipeBuf + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (L'!' == PipeBuf[0])
|
else if (LauncherFailure == PipeBuf[0])
|
||||||
{
|
{
|
||||||
if (BytesTransferred < RecvSize)
|
if (BytesTransferred < RecvSize)
|
||||||
PipeBuf[BytesTransferred / sizeof(WCHAR)] = L'\0';
|
PipeBuf[BytesTransferred / sizeof(WCHAR)] = L'\0';
|
||||||
@ -213,7 +213,7 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
PWSTR PipeBuf = 0;
|
PWSTR PipeBuf = 0;
|
||||||
|
|
||||||
/* allocate our PipeBuf early on; freed on process exit by the system */
|
/* allocate our PipeBuf early on; freed on process exit by the system */
|
||||||
PipeBuf = MemAlloc(PIPE_BUFFER_SIZE);
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
if (0 == PipeBuf)
|
if (0 == PipeBuf)
|
||||||
return ERROR_NO_SYSTEM_RESOURCES;
|
return ERROR_NO_SYSTEM_RESOURCES;
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
if (3 > argc || argc > 12)
|
if (3 > argc || argc > 12)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
return start(PipeBuf, PIPE_BUFFER_SIZE, argv[1], argv[2], argc - 3, argv + 3);
|
return start(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2], argc - 3, argv + 3);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (0 == lstrcmpW(L"stop", argv[0]))
|
if (0 == lstrcmpW(L"stop", argv[0]))
|
||||||
@ -236,7 +236,7 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
if (3 != argc)
|
if (3 != argc)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
return stop(PipeBuf, PIPE_BUFFER_SIZE, argv[1], argv[2]);
|
return stop(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (0 == lstrcmpW(L"info", argv[0]))
|
if (0 == lstrcmpW(L"info", argv[0]))
|
||||||
@ -244,7 +244,7 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
if (3 != argc)
|
if (3 != argc)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
return getinfo(PipeBuf, PIPE_BUFFER_SIZE, argv[1], argv[2]);
|
return getinfo(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (0 == lstrcmpW(L"list", argv[0]))
|
if (0 == lstrcmpW(L"list", argv[0]))
|
||||||
@ -252,7 +252,7 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
if (1 != argc)
|
if (1 != argc)
|
||||||
usage();
|
usage();
|
||||||
|
|
||||||
return list(PipeBuf, PIPE_BUFFER_SIZE);
|
return list(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (0 == lstrcmpW(L"quit", argv[0]))
|
if (0 == lstrcmpW(L"quit", argv[0]))
|
||||||
@ -261,7 +261,7 @@ int wmain(int argc, wchar_t **argv)
|
|||||||
usage();
|
usage();
|
||||||
|
|
||||||
/* works only against DEBUG version of launcher */
|
/* works only against DEBUG version of launcher */
|
||||||
return quit(PipeBuf, PIPE_BUFFER_SIZE);
|
return quit(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
usage();
|
usage();
|
||||||
|
@ -487,7 +487,7 @@ NTSTATUS SvcInstanceStop(HANDLE ClientToken,
|
|||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
KillProcess(SvcInstance->ProcessId, SvcInstance->Process, KILL_TIMEOUT);
|
KillProcess(SvcInstance->ProcessId, SvcInstance->Process, LAUNCHER_KILL_TIMEOUT);
|
||||||
|
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
|
|
||||||
@ -588,12 +588,12 @@ NTSTATUS SvcInstanceStopAndWaitAll(VOID)
|
|||||||
{
|
{
|
||||||
SvcInstance = CONTAINING_RECORD(ListEntry, SVC_INSTANCE, ListEntry);
|
SvcInstance = CONTAINING_RECORD(ListEntry, SVC_INSTANCE, ListEntry);
|
||||||
|
|
||||||
KillProcess(SvcInstance->ProcessId, SvcInstance->Process, KILL_TIMEOUT);
|
KillProcess(SvcInstance->ProcessId, SvcInstance->Process, LAUNCHER_KILL_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&SvcInstanceLock);
|
LeaveCriticalSection(&SvcInstanceLock);
|
||||||
|
|
||||||
WaitForSingleObject(SvcInstanceEvent, STOP_TIMEOUT);
|
WaitForSingleObject(SvcInstanceEvent, LAUNCHER_STOP_TIMEOUT);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -621,7 +621,7 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
|
|
||||||
SecurityAttributes.nLength = sizeof SecurityAttributes;
|
SecurityAttributes.nLength = sizeof SecurityAttributes;
|
||||||
SecurityAttributes.bInheritHandle = FALSE;
|
SecurityAttributes.bInheritHandle = FALSE;
|
||||||
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"" PIPE_SDDL, SDDL_REVISION_1,
|
if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"" LAUNCHER_PIPE_SDDL, SDDL_REVISION_1,
|
||||||
&SecurityAttributes.lpSecurityDescriptor, 0))
|
&SecurityAttributes.lpSecurityDescriptor, 0))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -654,11 +654,12 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
if (0 == SvcOverlapped.hEvent)
|
if (0 == SvcOverlapped.hEvent)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
SvcPipe = CreateNamedPipeW(L"" PIPE_NAME,
|
SvcPipe = CreateNamedPipeW(L"" LAUNCHER_PIPE_NAME,
|
||||||
PIPE_ACCESS_DUPLEX |
|
PIPE_ACCESS_DUPLEX |
|
||||||
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED,
|
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED,
|
||||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS,
|
||||||
1, PIPE_BUFFER_SIZE, PIPE_BUFFER_SIZE, PIPE_DEFAULT_TIMEOUT, &SecurityAttributes);
|
1, LAUNCHER_PIPE_BUFFER_SIZE, LAUNCHER_PIPE_BUFFER_SIZE, LAUNCHER_PIPE_DEFAULT_TIMEOUT,
|
||||||
|
&SecurityAttributes);
|
||||||
if (INVALID_HANDLE_VALUE == SvcPipe)
|
if (INVALID_HANDLE_VALUE == SvcPipe)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
@ -708,8 +709,8 @@ static NTSTATUS SvcStop(FSP_SERVICE *Service)
|
|||||||
if (GetCurrentThreadId() != SvcThreadId)
|
if (GetCurrentThreadId() != SvcThreadId)
|
||||||
{
|
{
|
||||||
SetEvent(SvcEvent);
|
SetEvent(SvcEvent);
|
||||||
FspServiceRequestTime(Service, STOP_TIMEOUT);
|
FspServiceRequestTime(Service, LAUNCHER_STOP_TIMEOUT);
|
||||||
WaitForSingleObject(SvcThread, STOP_TIMEOUT);
|
WaitForSingleObject(SvcThread, LAUNCHER_STOP_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -779,7 +780,7 @@ static DWORD WINAPI SvcPipeServer(PVOID Context)
|
|||||||
HANDLE ClientToken;
|
HANDLE ClientToken;
|
||||||
DWORD LastError, BytesTransferred;
|
DWORD LastError, BytesTransferred;
|
||||||
|
|
||||||
PipeBuf = MemAlloc(PIPE_BUFFER_SIZE);
|
PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE);
|
||||||
if (0 == PipeBuf)
|
if (0 == PipeBuf)
|
||||||
{
|
{
|
||||||
FspServiceSetExitCode(Service, ERROR_NO_SYSTEM_RESOURCES);
|
FspServiceSetExitCode(Service, ERROR_NO_SYSTEM_RESOURCES);
|
||||||
@ -802,7 +803,7 @@ static DWORD WINAPI SvcPipeServer(PVOID Context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LastError = SvcPipeWaitResult(
|
LastError = SvcPipeWaitResult(
|
||||||
ReadFile(SvcPipe, PipeBuf, PIPE_BUFFER_SIZE, &BytesTransferred, &SvcOverlapped),
|
ReadFile(SvcPipe, PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, &BytesTransferred, &SvcOverlapped),
|
||||||
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred);
|
||||||
if (-1 == LastError)
|
if (-1 == LastError)
|
||||||
break;
|
break;
|
||||||
@ -892,11 +893,12 @@ static inline VOID SvcPipeTransactResult(NTSTATUS Result, PWSTR PipeBuf, PULONG
|
|||||||
{
|
{
|
||||||
if (NT_SUCCESS(Result))
|
if (NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
*PipeBuf = L'$';
|
*PipeBuf = LauncherSuccess;
|
||||||
*PSize += sizeof(WCHAR);
|
*PSize += sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*PSize = (wsprintfW(PipeBuf, L"!%ld", FspWin32FromNtStatus(Result)) + 1) * sizeof(WCHAR);
|
*PSize = (wsprintfW(PipeBuf, L"%c%ld", LauncherFailure, FspWin32FromNtStatus(Result)) + 1) *
|
||||||
|
sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
||||||
@ -945,7 +947,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
Result = STATUS_INVALID_PARAMETER;
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
if (0 != ClassName && 0 != InstanceName)
|
if (0 != ClassName && 0 != InstanceName)
|
||||||
{
|
{
|
||||||
*PSize = PIPE_BUFFER_SIZE - 1;
|
*PSize = LAUNCHER_PIPE_BUFFER_SIZE - 1;
|
||||||
Result = SvcInstanceGetInfo(ClientToken, ClassName, InstanceName, PipeBuf + 1, PSize);
|
Result = SvcInstanceGetInfo(ClientToken, ClassName, InstanceName, PipeBuf + 1, PSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +955,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case LauncherSvcInstanceList:
|
case LauncherSvcInstanceList:
|
||||||
*PSize = PIPE_BUFFER_SIZE - 1;
|
*PSize = LAUNCHER_PIPE_BUFFER_SIZE - 1;
|
||||||
Result = SvcInstanceGetNameList(ClientToken, PipeBuf + 1, PSize);
|
Result = SvcInstanceGetNameList(ClientToken, PipeBuf + 1, PSize);
|
||||||
|
|
||||||
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
SvcPipeTransactResult(Result, PipeBuf, PSize);
|
||||||
|
@ -21,12 +21,12 @@
|
|||||||
#include <winfsp/winfsp.h>
|
#include <winfsp/winfsp.h>
|
||||||
#include <shared/minimal.h>
|
#include <shared/minimal.h>
|
||||||
|
|
||||||
#define STOP_TIMEOUT 5500
|
#define LAUNCHER_STOP_TIMEOUT 5500
|
||||||
#define KILL_TIMEOUT 5000
|
#define LAUNCHER_KILL_TIMEOUT 5000
|
||||||
|
|
||||||
#define PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
#define LAUNCHER_PIPE_NAME "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}"
|
||||||
#define PIPE_BUFFER_SIZE 2048
|
#define LAUNCHER_PIPE_BUFFER_SIZE 2048
|
||||||
#define PIPE_DEFAULT_TIMEOUT 3000
|
#define LAUNCHER_PIPE_DEFAULT_TIMEOUT 3000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The launcher named pipe SDDL gives full access to LocalSystem and Administrators.
|
* The launcher named pipe SDDL gives full access to LocalSystem and Administrators.
|
||||||
@ -38,7 +38,7 @@
|
|||||||
* the FILE_CREATE_PIPE_INSTANCE right is that the server creates the named pipe with
|
* the FILE_CREATE_PIPE_INSTANCE right is that the server creates the named pipe with
|
||||||
* MaxInstances == 1 (and therefore no client can create additional instances).
|
* MaxInstances == 1 (and therefore no client can create additional instances).
|
||||||
*/
|
*/
|
||||||
#define PIPE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;WD)"
|
#define LAUNCHER_PIPE_SDDL "D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GRGW;;;WD)"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The default service instance SDDL gives full access to LocalSystem and Administrators.
|
* The default service instance SDDL gives full access to LocalSystem and Administrators.
|
||||||
@ -60,6 +60,9 @@ enum
|
|||||||
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
LauncherSvcInstanceInfo = 'I', /* requires: SERVICE_QUERY_STATUS */
|
||||||
LauncherSvcInstanceList = 'L', /* requires: none*/
|
LauncherSvcInstanceList = 'L', /* requires: none*/
|
||||||
LauncherQuit = 'Q', /* DEBUG version only */
|
LauncherQuit = 'Q', /* DEBUG version only */
|
||||||
|
|
||||||
|
LauncherSuccess = '$',
|
||||||
|
LauncherFailure = '!',
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -82,6 +82,9 @@ NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
if (arge > argp)
|
if (arge > argp)
|
||||||
goto usage;
|
goto usage;
|
||||||
|
|
||||||
|
if (MemfsDisk == Flags && 0 == MountPoint)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
Result = MemfsCreate(Flags, FileInfoTimeout, MaxFileNodes, MaxFileSize, VolumePrefix, RootSddl,
|
Result = MemfsCreate(Flags, FileInfoTimeout, MaxFileNodes, MaxFileSize, VolumePrefix, RootSddl,
|
||||||
&Memfs);
|
&Memfs);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -90,13 +93,16 @@ NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 != MountPoint && L'\0' != MountPoint[0])
|
||||||
|
{
|
||||||
Result = FspFileSystemSetMountPoint(MemfsFileSystem(Memfs),
|
Result = FspFileSystemSetMountPoint(MemfsFileSystem(Memfs),
|
||||||
MountPoint && MountPoint[0] ? MountPoint : 0);
|
L'*' == MountPoint[0] && L'\0' == MountPoint[1] ? 0 : MountPoint);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
{
|
{
|
||||||
fail(L"cannot mount MEMFS");
|
fail(L"cannot mount MEMFS");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Result = MemfsStart(Memfs);
|
Result = MemfsStart(Memfs);
|
||||||
if (!NT_SUCCESS(Result))
|
if (!NT_SUCCESS(Result))
|
||||||
@ -107,11 +113,11 @@ NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv)
|
|||||||
|
|
||||||
MountPoint = FspFileSystemMountPoint(MemfsFileSystem(Memfs));
|
MountPoint = FspFileSystemMountPoint(MemfsFileSystem(Memfs));
|
||||||
|
|
||||||
info(L"%s -t %ld -n %ld -s %ld%s%s%s%s -m %s",
|
info(L"%s -t %ld -n %ld -s %ld%s%s%s%s%s%s",
|
||||||
L"" PROGNAME, FileInfoTimeout, MaxFileNodes, MaxFileSize,
|
L"" PROGNAME, FileInfoTimeout, MaxFileNodes, MaxFileSize,
|
||||||
RootSddl ? L" -S " : L"", RootSddl ? RootSddl : L"",
|
RootSddl ? L" -S " : L"", RootSddl ? RootSddl : L"",
|
||||||
VolumePrefix ? L" -u " : L"", VolumePrefix ? VolumePrefix : L"",
|
VolumePrefix ? L" -u " : L"", VolumePrefix ? VolumePrefix : L"",
|
||||||
MountPoint);
|
MountPoint ? L" -m " : L"", MountPoint ? MountPoint : L"");
|
||||||
|
|
||||||
Service->UserContext = Memfs;
|
Service->UserContext = Memfs;
|
||||||
Result = STATUS_SUCCESS;
|
Result = STATUS_SUCCESS;
|
||||||
@ -132,7 +138,7 @@ usage:
|
|||||||
" -s MaxFileSize [bytes]\n"
|
" -s MaxFileSize [bytes]\n"
|
||||||
" -S RootSddl [file rights: FA, etc; NO generic rights: GA, etc.]\n"
|
" -S RootSddl [file rights: FA, etc; NO generic rights: GA, etc.]\n"
|
||||||
" -u \\Server\\Share [UNC prefix (single backslash)]\n"
|
" -u \\Server\\Share [UNC prefix (single backslash)]\n"
|
||||||
" -m MountPoint [X:]\n";
|
" -m MountPoint [X:|* (required if no UNC prefix)]\n";
|
||||||
|
|
||||||
fail(usage, L"" PROGNAME);
|
fail(usage, L"" PROGNAME);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user