mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-29 11:08:37 -05:00 
			
		
		
		
	dll: np: NPAddConnection3, NPCancelConnection implementation
This commit is contained in:
		| @@ -3,3 +3,6 @@ EXPORTS | ||||
|     DllUnregisterServer PRIVATE | ||||
|     NPGetCaps           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 <launcher/launcher.h> | ||||
| #include <npapi.h> | ||||
|  | ||||
| #define FSP_NP_NAME                     LIBRARY_NAME ".Np" | ||||
| @@ -33,14 +34,17 @@ DWORD APIENTRY NPGetCaps(DWORD Index) | ||||
|         return 0; | ||||
|     case WNNC_CONNECTION: | ||||
|         /* | ||||
|          * WNNC_CON_ADDCONECTION | ||||
|          * WNNC_CON_ADDCONNECTION | ||||
|          * WNNC_CON_CANCELCONNECTION | ||||
|          * WNNC_CON_GETCONNECTIONS | ||||
|          * WNNC_CON_ADDCONECTION3 | ||||
|          * WNNC_CON_ADDCONNECTION3 | ||||
|          * WNNC_CON_GETPERFORMANCE | ||||
|          * WNNC_CON_DEFER | ||||
|          */ | ||||
|         return WNNC_CON_GETCONNECTIONS; | ||||
|         return | ||||
|             WNNC_CON_GETCONNECTIONS | | ||||
|             WNNC_CON_ADDCONNECTION | WNNC_CON_ADDCONNECTION3 | | ||||
|             WNNC_CON_CANCELCONNECTION; | ||||
|     case WNNC_DIALOG: | ||||
|         /* | ||||
|          * 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( | ||||
|     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; | ||||
|     NTSTATUS Result; | ||||
| @@ -117,15 +204,10 @@ DWORD APIENTRY NPGetConnection(LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD | ||||
|     SIZE_T VolumeListSize, VolumeNameSize; | ||||
|     ULONG Backslashes; | ||||
|  | ||||
|     if (0 == lpLocalName || | ||||
|         !( | ||||
|             (L'A' <= lpLocalName[0] && lpLocalName[0] <= L'Z') || | ||||
|             (L'a' <= lpLocalName[0] && lpLocalName[0] <= L'z') | ||||
|         ) || | ||||
|         L':' != lpLocalName[1]) | ||||
|     if (!FspNpCheckLocalName(lpLocalName)) | ||||
|         return WN_BAD_LOCALNAME; | ||||
|  | ||||
|     LocalNameBuf[0] = lpLocalName[0]; | ||||
|     LocalNameBuf[0] = lpLocalName[0] & ~0x20; /* convert to uppercase */ | ||||
|     LocalNameBuf[1] = L':'; | ||||
|     LocalNameBuf[2] = L'\0'; | ||||
|  | ||||
| @@ -188,6 +270,111 @@ DWORD APIENTRY NPGetConnection(LPWSTR lpLocalName, LPWSTR lpRemoteName, LPDWORD | ||||
|     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) | ||||
| { | ||||
|     extern HINSTANCE DllInstance; | ||||
|   | ||||
| @@ -65,14 +65,14 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize) | ||||
| { | ||||
|     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(); | ||||
|  | ||||
|     if (0 != LastError) | ||||
|         warn("KO CallNamedPipeW = %ld", LastError); | ||||
|     else if (0 == BytesTransferred) | ||||
|     else if (sizeof(WCHAR) > BytesTransferred) | ||||
|         warn("KO launcher: empty buffer"); | ||||
|     else if (L'$' == PipeBuf[0]) | ||||
|     else if (LauncherSuccess == PipeBuf[0]) | ||||
|     { | ||||
|         if (sizeof(WCHAR) == BytesTransferred) | ||||
|             info("OK"); | ||||
| @@ -97,7 +97,7 @@ static int call_pipe_and_report(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize) | ||||
|             info("OK\n%S", PipeBuf + 1); | ||||
|         } | ||||
|     } | ||||
|     else if (L'!' == PipeBuf[0]) | ||||
|     else if (LauncherFailure == PipeBuf[0]) | ||||
|     { | ||||
|         if (BytesTransferred < RecvSize) | ||||
|             PipeBuf[BytesTransferred / sizeof(WCHAR)] = L'\0'; | ||||
| @@ -213,7 +213,7 @@ int wmain(int argc, wchar_t **argv) | ||||
|     PWSTR PipeBuf = 0; | ||||
|  | ||||
|     /* 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) | ||||
|         return ERROR_NO_SYSTEM_RESOURCES; | ||||
|  | ||||
| @@ -228,7 +228,7 @@ int wmain(int argc, wchar_t **argv) | ||||
|         if (3 > argc || argc > 12) | ||||
|             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 | ||||
|     if (0 == lstrcmpW(L"stop", argv[0])) | ||||
| @@ -236,7 +236,7 @@ int wmain(int argc, wchar_t **argv) | ||||
|         if (3 != argc) | ||||
|             usage(); | ||||
|  | ||||
|         return stop(PipeBuf, PIPE_BUFFER_SIZE, argv[1], argv[2]); | ||||
|         return stop(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2]); | ||||
|     } | ||||
|     else | ||||
|     if (0 == lstrcmpW(L"info", argv[0])) | ||||
| @@ -244,7 +244,7 @@ int wmain(int argc, wchar_t **argv) | ||||
|         if (3 != argc) | ||||
|             usage(); | ||||
|  | ||||
|         return getinfo(PipeBuf, PIPE_BUFFER_SIZE, argv[1], argv[2]); | ||||
|         return getinfo(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, argv[1], argv[2]); | ||||
|     } | ||||
|     else | ||||
|     if (0 == lstrcmpW(L"list", argv[0])) | ||||
| @@ -252,7 +252,7 @@ int wmain(int argc, wchar_t **argv) | ||||
|         if (1 != argc) | ||||
|             usage(); | ||||
|  | ||||
|         return list(PipeBuf, PIPE_BUFFER_SIZE); | ||||
|         return list(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|     } | ||||
|     else | ||||
|     if (0 == lstrcmpW(L"quit", argv[0])) | ||||
| @@ -261,7 +261,7 @@ int wmain(int argc, wchar_t **argv) | ||||
|             usage(); | ||||
|  | ||||
|         /* works only against DEBUG version of launcher */ | ||||
|         return quit(PipeBuf, PIPE_BUFFER_SIZE); | ||||
|         return quit(PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|     } | ||||
|     else | ||||
|         usage(); | ||||
|   | ||||
| @@ -487,7 +487,7 @@ NTSTATUS SvcInstanceStop(HANDLE ClientToken, | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         goto exit; | ||||
|  | ||||
|     KillProcess(SvcInstance->ProcessId, SvcInstance->Process, KILL_TIMEOUT); | ||||
|     KillProcess(SvcInstance->ProcessId, SvcInstance->Process, LAUNCHER_KILL_TIMEOUT); | ||||
|  | ||||
|     Result = STATUS_SUCCESS; | ||||
|  | ||||
| @@ -588,12 +588,12 @@ NTSTATUS SvcInstanceStopAndWaitAll(VOID) | ||||
|     { | ||||
|         SvcInstance = CONTAINING_RECORD(ListEntry, SVC_INSTANCE, ListEntry); | ||||
|  | ||||
|         KillProcess(SvcInstance->ProcessId, SvcInstance->Process, KILL_TIMEOUT); | ||||
|         KillProcess(SvcInstance->ProcessId, SvcInstance->Process, LAUNCHER_KILL_TIMEOUT); | ||||
|     } | ||||
|  | ||||
|     LeaveCriticalSection(&SvcInstanceLock); | ||||
|  | ||||
|     WaitForSingleObject(SvcInstanceEvent, STOP_TIMEOUT); | ||||
|     WaitForSingleObject(SvcInstanceEvent, LAUNCHER_STOP_TIMEOUT); | ||||
|  | ||||
|     return STATUS_SUCCESS; | ||||
| } | ||||
| @@ -621,7 +621,7 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) | ||||
|  | ||||
|     SecurityAttributes.nLength = sizeof SecurityAttributes; | ||||
|     SecurityAttributes.bInheritHandle = FALSE; | ||||
|     if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"" PIPE_SDDL, SDDL_REVISION_1, | ||||
|     if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(L"" LAUNCHER_PIPE_SDDL, SDDL_REVISION_1, | ||||
|         &SecurityAttributes.lpSecurityDescriptor, 0)) | ||||
|         goto fail; | ||||
|  | ||||
| @@ -654,11 +654,12 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) | ||||
|     if (0 == SvcOverlapped.hEvent) | ||||
|         goto fail; | ||||
|  | ||||
|     SvcPipe = CreateNamedPipeW(L"" PIPE_NAME, | ||||
|     SvcPipe = CreateNamedPipeW(L"" LAUNCHER_PIPE_NAME, | ||||
|         PIPE_ACCESS_DUPLEX | | ||||
|             FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED, | ||||
|         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) | ||||
|         goto fail; | ||||
|  | ||||
| @@ -708,8 +709,8 @@ static NTSTATUS SvcStop(FSP_SERVICE *Service) | ||||
|     if (GetCurrentThreadId() != SvcThreadId) | ||||
|     { | ||||
|         SetEvent(SvcEvent); | ||||
|         FspServiceRequestTime(Service, STOP_TIMEOUT); | ||||
|         WaitForSingleObject(SvcThread, STOP_TIMEOUT); | ||||
|         FspServiceRequestTime(Service, LAUNCHER_STOP_TIMEOUT); | ||||
|         WaitForSingleObject(SvcThread, LAUNCHER_STOP_TIMEOUT); | ||||
|     } | ||||
|  | ||||
|     /* | ||||
| @@ -779,7 +780,7 @@ static DWORD WINAPI SvcPipeServer(PVOID Context) | ||||
|     HANDLE ClientToken; | ||||
|     DWORD LastError, BytesTransferred; | ||||
|  | ||||
|     PipeBuf = MemAlloc(PIPE_BUFFER_SIZE); | ||||
|     PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|     if (0 == PipeBuf) | ||||
|     { | ||||
|         FspServiceSetExitCode(Service, ERROR_NO_SYSTEM_RESOURCES); | ||||
| @@ -802,7 +803,7 @@ static DWORD WINAPI SvcPipeServer(PVOID Context) | ||||
|         } | ||||
|  | ||||
|         LastError = SvcPipeWaitResult( | ||||
|             ReadFile(SvcPipe, PipeBuf, PIPE_BUFFER_SIZE, &BytesTransferred, &SvcOverlapped), | ||||
|             ReadFile(SvcPipe, PipeBuf, LAUNCHER_PIPE_BUFFER_SIZE, &BytesTransferred, &SvcOverlapped), | ||||
|             SvcEvent, SvcPipe, &SvcOverlapped, &BytesTransferred); | ||||
|         if (-1 == LastError) | ||||
|             break; | ||||
| @@ -892,11 +893,12 @@ static inline VOID SvcPipeTransactResult(NTSTATUS Result, PWSTR PipeBuf, PULONG | ||||
| { | ||||
|     if (NT_SUCCESS(Result)) | ||||
|     { | ||||
|         *PipeBuf = L'$'; | ||||
|         *PipeBuf = LauncherSuccess; | ||||
|         *PSize += sizeof(WCHAR); | ||||
|     } | ||||
|     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) | ||||
| @@ -945,7 +947,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) | ||||
|         Result = STATUS_INVALID_PARAMETER; | ||||
|         if (0 != ClassName && 0 != InstanceName) | ||||
|         { | ||||
|             *PSize = PIPE_BUFFER_SIZE - 1; | ||||
|             *PSize = LAUNCHER_PIPE_BUFFER_SIZE - 1; | ||||
|             Result = SvcInstanceGetInfo(ClientToken, ClassName, InstanceName, PipeBuf + 1, PSize); | ||||
|         } | ||||
|  | ||||
| @@ -953,7 +955,7 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) | ||||
|         break; | ||||
|  | ||||
|     case LauncherSvcInstanceList: | ||||
|         *PSize = PIPE_BUFFER_SIZE - 1; | ||||
|         *PSize = LAUNCHER_PIPE_BUFFER_SIZE - 1; | ||||
|         Result = SvcInstanceGetNameList(ClientToken, PipeBuf + 1, PSize); | ||||
|  | ||||
|         SvcPipeTransactResult(Result, PipeBuf, PSize); | ||||
|   | ||||
| @@ -21,12 +21,12 @@ | ||||
| #include <winfsp/winfsp.h> | ||||
| #include <shared/minimal.h> | ||||
|  | ||||
| #define STOP_TIMEOUT                    5500 | ||||
| #define KILL_TIMEOUT                    5000 | ||||
| #define LAUNCHER_STOP_TIMEOUT           5500 | ||||
| #define LAUNCHER_KILL_TIMEOUT           5000 | ||||
|  | ||||
| #define PIPE_NAME                       "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" | ||||
| #define PIPE_BUFFER_SIZE                2048 | ||||
| #define PIPE_DEFAULT_TIMEOUT            3000 | ||||
| #define LAUNCHER_PIPE_NAME              "\\\\.\\pipe\\WinFsp.{14E7137D-22B4-437A-B0C1-D21D1BDF3767}" | ||||
| #define LAUNCHER_PIPE_BUFFER_SIZE       2048 | ||||
| #define LAUNCHER_PIPE_DEFAULT_TIMEOUT   3000 | ||||
|  | ||||
| /* | ||||
|  * 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 | ||||
|  * 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. | ||||
| @@ -60,6 +60,9 @@ enum | ||||
|     LauncherSvcInstanceInfo             = 'I',  /* requires: SERVICE_QUERY_STATUS */ | ||||
|     LauncherSvcInstanceList             = 'L',  /* requires: none*/ | ||||
|     LauncherQuit                        = 'Q',  /* DEBUG version only */ | ||||
|  | ||||
|     LauncherSuccess                     = '$', | ||||
|     LauncherFailure                     = '!', | ||||
| }; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -82,6 +82,9 @@ NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) | ||||
|     if (arge > argp) | ||||
|         goto usage; | ||||
|  | ||||
|     if (MemfsDisk == Flags && 0 == MountPoint) | ||||
|         goto usage; | ||||
|  | ||||
|     Result = MemfsCreate(Flags, FileInfoTimeout, MaxFileNodes, MaxFileSize, VolumePrefix, RootSddl, | ||||
|         &Memfs); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
| @@ -90,13 +93,16 @@ NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) | ||||
|         goto exit; | ||||
|     } | ||||
|  | ||||
|     if (0 != MountPoint && L'\0' != MountPoint[0]) | ||||
|     { | ||||
|         Result = FspFileSystemSetMountPoint(MemfsFileSystem(Memfs), | ||||
|         MountPoint && MountPoint[0] ? MountPoint : 0); | ||||
|             L'*' == MountPoint[0] && L'\0' == MountPoint[1] ? 0 : MountPoint); | ||||
|         if (!NT_SUCCESS(Result)) | ||||
|         { | ||||
|             fail(L"cannot mount MEMFS"); | ||||
|             goto exit; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     Result = MemfsStart(Memfs); | ||||
|     if (!NT_SUCCESS(Result)) | ||||
| @@ -107,11 +113,11 @@ NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) | ||||
|  | ||||
|     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, | ||||
|         RootSddl ? L" -S " : L"", RootSddl ? RootSddl : L"", | ||||
|         VolumePrefix ? L" -u " : L"", VolumePrefix ? VolumePrefix : L"", | ||||
|         MountPoint); | ||||
|         MountPoint ? L" -m " : L"", MountPoint ? MountPoint : L""); | ||||
|  | ||||
|     Service->UserContext = Memfs; | ||||
|     Result = STATUS_SUCCESS; | ||||
| @@ -132,7 +138,7 @@ usage: | ||||
|         "    -s MaxFileSize      [bytes]\n" | ||||
|         "    -S RootSddl         [file rights: FA, etc; NO generic rights: GA, etc.]\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); | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user