mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 03:28:38 -05:00 
			
		
		
		
	dll: FspLaunch API
This commit is contained in:
		
							
								
								
									
										68
									
								
								src/dll/fs.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								src/dll/fs.c
									
									
									
									
									
								
							| @@ -16,7 +16,6 @@ | ||||
|  */ | ||||
|  | ||||
| #include <dll/library.h> | ||||
| #include <launcher/launcher.h> | ||||
|  | ||||
| enum | ||||
| { | ||||
| @@ -191,64 +190,25 @@ FSP_API VOID FspFileSystemDelete(FSP_FILE_SYSTEM *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) | ||||
|     if (2 != lstrlenW(MountPoint) || | ||||
|         FSP_FSCTL_VOLUME_NAME_SIZEMAX / sizeof(WCHAR) <= lstrlenW(VolumeName)) | ||||
|         return STATUS_INVALID_PARAMETER; | ||||
|  | ||||
|     PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|     if (0 == PipeBuf) | ||||
|     { | ||||
|         Result = STATUS_INSUFFICIENT_RESOURCES; | ||||
|         goto exit; | ||||
|     } | ||||
|     WCHAR Argv0[4]; | ||||
|     PWSTR Argv[2]; | ||||
|     NTSTATUS Result; | ||||
|     ULONG ErrorCode; | ||||
|  | ||||
|     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'; | ||||
|     Argv0[0] = Sign; | ||||
|     Argv0[1] = MountPoint[0]; | ||||
|     Argv0[2] = MountPoint[1]; | ||||
|     Argv0[3] = 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; | ||||
|     Argv[0] = Argv0; | ||||
|     Argv[1] = VolumeName; | ||||
|  | ||||
|     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; | ||||
|     Result = FspLaunchCallLauncherPipe('D', 2, Argv, 0, 0, 0, &ErrorCode); | ||||
|     return !NT_SUCCESS(Result) ? Result : FspNtStatusFromWin32(ErrorCode); | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspFileSystemSetMountPoint_Drive(PWSTR MountPoint, PWSTR VolumeName, | ||||
|   | ||||
							
								
								
									
										152
									
								
								src/dll/launch.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								src/dll/launch.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,152 @@ | ||||
| /** | ||||
|  * @file dll/launch.c | ||||
|  * | ||||
|  * @copyright 2015-2018 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> | ||||
| #include <launcher/launcher.h> | ||||
|  | ||||
| FSP_API NTSTATUS FspLaunchCallLauncherPipe( | ||||
|     WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, | ||||
|     PWSTR Buffer, PULONG PSize, PULONG PLauncherError) | ||||
| { | ||||
|     PWSTR PipeBuf = 0, P; | ||||
|     ULONG Length, BytesTransferred; | ||||
|     NTSTATUS Result; | ||||
|     ULONG ErrorCode; | ||||
|  | ||||
|     if (0 != PSize) | ||||
|         *PSize = 0; | ||||
|     *PLauncherError = 0; | ||||
|  | ||||
|     PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|     if (0 == PipeBuf) | ||||
|     { | ||||
|         Result = STATUS_INSUFFICIENT_RESOURCES; | ||||
|         goto exit; | ||||
|     } | ||||
|  | ||||
|     P = PipeBuf; | ||||
|     *P++ = Command; | ||||
|     for (ULONG I = 0; Argc > I; I++) | ||||
|         if (0 != Argv[I]) | ||||
|         { | ||||
|             Length = 0 == Argl || -1 == Argl[I] ? lstrlenW(Argv[I]) : Argl[I]; | ||||
|             if (LAUNCHER_PIPE_BUFFER_SIZE < ((ULONG)(P - PipeBuf) + Length + 1) * sizeof(WCHAR)) | ||||
|             { | ||||
|                 Result = STATUS_INVALID_PARAMETER; | ||||
|                 goto exit; | ||||
|             } | ||||
|             memcpy(P, Argv[I], Length * sizeof(WCHAR)); P += Length; *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; | ||||
|  | ||||
|     Result = STATUS_SUCCESS; | ||||
|     ErrorCode = ERROR_BROKEN_PIPE; /* protocol error! */ | ||||
|     if (sizeof(WCHAR) <= BytesTransferred) | ||||
|     { | ||||
|         if (LauncherSuccess == PipeBuf[0]) | ||||
|         { | ||||
|             ErrorCode = 0; | ||||
|  | ||||
|             if (0 != PSize) | ||||
|             { | ||||
|                 BytesTransferred -= sizeof(WCHAR); | ||||
|                 memcpy(Buffer, PipeBuf, *PSize < BytesTransferred ? *PSize : BytesTransferred); | ||||
|                 *PSize = BytesTransferred; | ||||
|             } | ||||
|         } | ||||
|         else if (LauncherFailure == PipeBuf[0]) | ||||
|         { | ||||
|             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'); | ||||
|             } | ||||
|  | ||||
|             if (0 == ErrorCode) | ||||
|                 ErrorCode = ERROR_BROKEN_PIPE; /* protocol error! */ | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     *PLauncherError = ErrorCode; | ||||
|  | ||||
| exit: | ||||
|     MemFree(PipeBuf); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| FSP_API NTSTATUS FspLaunchStart( | ||||
|     PWSTR ClassName, PWSTR InstanceName, ULONG Argc, PWSTR *Argv0, | ||||
|     BOOLEAN HasSecret, | ||||
|     PULONG PLauncherError) | ||||
| { | ||||
|     PWSTR Argv[9 + 2]; | ||||
|  | ||||
|     if (9 < Argc) | ||||
|         return STATUS_INVALID_PARAMETER; | ||||
|  | ||||
|     Argv[0] = ClassName; | ||||
|     Argv[1] = InstanceName; | ||||
|     memcpy(Argv + 2, Argv, Argc * sizeof(PWSTR)); | ||||
|  | ||||
|     return FspLaunchCallLauncherPipe( | ||||
|         HasSecret ? LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart, | ||||
|         Argc + 2, Argv, 0, 0, 0, PLauncherError); | ||||
| } | ||||
|  | ||||
| FSP_API NTSTATUS FspLaunchStop( | ||||
|     PWSTR ClassName, PWSTR InstanceName, | ||||
|     PULONG PLauncherError) | ||||
| { | ||||
|     PWSTR Argv[2]; | ||||
|  | ||||
|     Argv[0] = ClassName; | ||||
|     Argv[1] = InstanceName; | ||||
|  | ||||
|     return FspLaunchCallLauncherPipe(LauncherSvcInstanceStop, | ||||
|         2, Argv, 0, 0, 0, PLauncherError); | ||||
| } | ||||
|  | ||||
| FSP_API NTSTATUS FspLaunchGetInfo( | ||||
|     PWSTR ClassName, PWSTR InstanceName, | ||||
|     PWSTR Buffer, PULONG PSize, | ||||
|     PULONG PLauncherError) | ||||
| { | ||||
|     PWSTR Argv[2]; | ||||
|  | ||||
|     Argv[0] = ClassName; | ||||
|     Argv[1] = InstanceName; | ||||
|  | ||||
|     return FspLaunchCallLauncherPipe(LauncherSvcInstanceInfo, | ||||
|         2, Argv, 0, Buffer, PSize, PLauncherError); | ||||
| } | ||||
|  | ||||
| FSP_API NTSTATUS FspLaunchGetNameList( | ||||
|     PWSTR Buffer, PULONG PSize, | ||||
|     PULONG PLauncherError) | ||||
| { | ||||
|     return FspLaunchCallLauncherPipe(LauncherSvcInstanceList, | ||||
|         0, 0, 0, Buffer, PSize, PLauncherError); | ||||
| } | ||||
							
								
								
									
										104
									
								
								src/dll/np.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								src/dll/np.c
									
									
									
									
									
								
							| @@ -168,39 +168,17 @@ static inline BOOLEAN FspNpParseRemoteUserName(PWSTR RemoteName, | ||||
|     return FALSE; | ||||
| } | ||||
|  | ||||
| static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize) | ||||
| static inline DWORD FspNpCallLauncherPipe( | ||||
|     WCHAR Command, ULONG Argc, PWSTR *Argv, ULONG *Argl, | ||||
|     PWSTR Buffer, PULONG PSize) | ||||
| { | ||||
|     DWORD NpResult; | ||||
|     NTSTATUS Result; | ||||
|     DWORD BytesTransferred; | ||||
|     ULONG ErrorCode; | ||||
|  | ||||
|     Result = FspCallNamedPipeSecurely(L"" LAUNCHER_PIPE_NAME, PipeBuf, SendSize, PipeBuf, RecvSize, | ||||
|         &BytesTransferred, NMPWAIT_USE_DEFAULT_WAIT, LAUNCHER_PIPE_OWNER); | ||||
|  | ||||
|     if (!NT_SUCCESS(Result)) | ||||
|         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]) | ||||
|     { | ||||
|         NpResult = 0; | ||||
|         for (PWSTR P = PipeBuf + 1, EndP = PipeBuf + BytesTransferred / sizeof(WCHAR); EndP > P; P++) | ||||
|         { | ||||
|             if (L'0' > *P || *P > L'9') | ||||
|                 break; | ||||
|  | ||||
|             NpResult = 10 * NpResult + (*P - L'0'); | ||||
|         } | ||||
|  | ||||
|         if (0 == NpResult) | ||||
|             NpResult = WN_NO_NETWORK; | ||||
|     } | ||||
|     else  | ||||
|         NpResult = WN_NO_NETWORK; | ||||
|  | ||||
|     return NpResult; | ||||
|     Result = FspLaunchCallLauncherPipe(Command, Argc, Argv, Argl, Buffer, PSize, &ErrorCode); | ||||
|     return !NT_SUCCESS(Result) ? | ||||
|         WN_NO_NETWORK : | ||||
|         (ERROR_BROKEN_PIPE == ErrorCode ? WN_NO_NETWORK : ErrorCode); | ||||
| } | ||||
|  | ||||
| static NTSTATUS FspNpGetVolumeList( | ||||
| @@ -490,7 +468,9 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, | ||||
|     PWSTR ClassName, InstanceName, RemoteName, P; | ||||
|     ULONG ClassNameLen, InstanceNameLen; | ||||
|     DWORD CredentialsKind; | ||||
|     PWSTR PipeBuf = 0; | ||||
|     ULONG Argc; | ||||
|     PWSTR Argv[6]; | ||||
|     ULONG Argl[6]; | ||||
| #if defined(FSP_NP_CREDENTIAL_MANAGER) | ||||
|     PCREDENTIALW Credential = 0; | ||||
| #endif | ||||
| @@ -556,32 +536,24 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     PipeBuf = MemAlloc(LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|     if (0 == PipeBuf) | ||||
|     { | ||||
|         NpResult = WN_OUT_OF_MEMORY; | ||||
|         goto exit; | ||||
|     } | ||||
|  | ||||
|     /* we do not explicitly check, but assumption is it all fits in LAUNCHER_PIPE_BUFFER_SIZE */ | ||||
|     P = PipeBuf; | ||||
|     *P++ = FSP_NP_CREDENTIALS_NONE != CredentialsKind ? | ||||
|         LauncherSvcInstanceStartWithSecret : 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; | ||||
|     Argc = 0; | ||||
|     Argv[Argc] = ClassName; Argl[Argc] = ClassNameLen; Argc++; | ||||
|     Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++; | ||||
|     Argv[Argc] = RemoteName; Argl[Argc] = -1; Argc++; | ||||
|     Argv[Argc] = LocalNameBuf; Argl[Argc] = -1; Argc++; | ||||
|     if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind) | ||||
|     { | ||||
|         lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1; | ||||
|         Argv[Argc] = lpUserName; Argl[Argc] = -1; Argc++; | ||||
|     } | ||||
|     if (FSP_NP_CREDENTIALS_NONE != CredentialsKind) | ||||
|     { | ||||
|         lstrcpyW(P, lpPassword); P += lstrlenW(lpPassword) + 1; | ||||
|         Argv[Argc] = lpPassword; Argl[Argc] = -1; Argc++; | ||||
|     } | ||||
|  | ||||
|     NpResult = FspNpCallLauncherPipe( | ||||
|         PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|         FSP_NP_CREDENTIALS_NONE != CredentialsKind ? | ||||
|             LauncherSvcInstanceStartWithSecret : LauncherSvcInstanceStart, | ||||
|         Argc, Argv, Argl, 0, 0); | ||||
|     switch (NpResult) | ||||
|     { | ||||
|     case WN_SUCCESS: | ||||
| @@ -627,13 +599,13 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, | ||||
|                     break; | ||||
|                 } | ||||
|  | ||||
|                 P = PipeBuf; | ||||
|                 *P++ = LauncherSvcInstanceInfo; | ||||
|                 memcpy(P, ClassName, ClassNameLen * sizeof(WCHAR)); P += ClassNameLen; *P++ = L'\0'; | ||||
|                 memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0'; | ||||
|                 Argc = 0; | ||||
|                 Argv[Argc] = ClassName; Argl[Argc] = ClassNameLen; Argc++; | ||||
|                 Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++; | ||||
|  | ||||
|                 if (WN_SUCCESS != FspNpCallLauncherPipe( | ||||
|                     PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE)) | ||||
|                     LauncherSvcInstanceInfo, | ||||
|                     Argc, Argv, Argl, 0, 0)) | ||||
|                 { | ||||
|                     /* looks like the file system is gone! */ | ||||
|                     NpResult = WN_NO_NETWORK; | ||||
| @@ -677,8 +649,6 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, | ||||
|     } | ||||
|  | ||||
| exit: | ||||
|     MemFree(PipeBuf); | ||||
|  | ||||
| #if defined(FSP_NP_CREDENTIAL_MANAGER) | ||||
|     if (0 != Credential) | ||||
|         CredFree(Credential); | ||||
| @@ -767,9 +737,11 @@ 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; | ||||
|     PWSTR ClassName, InstanceName, RemoteName; | ||||
|     ULONG ClassNameLen, InstanceNameLen; | ||||
|     PWSTR PipeBuf = 0; | ||||
|     ULONG Argc; | ||||
|     PWSTR Argv[2]; | ||||
|     ULONG Argl[2]; | ||||
|  | ||||
|     if (FspNpCheckLocalName(lpName)) | ||||
|     { | ||||
| @@ -789,17 +761,13 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce) | ||||
|         &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'; | ||||
|     Argc = 0; | ||||
|     Argv[Argc] = ClassName; Argl[Argc] = ClassNameLen; Argc++; | ||||
|     Argv[Argc] = InstanceName; Argl[Argc] = InstanceNameLen; Argc++; | ||||
|  | ||||
|     NpResult = FspNpCallLauncherPipe( | ||||
|         PipeBuf, (ULONG)(P - PipeBuf) * sizeof(WCHAR), LAUNCHER_PIPE_BUFFER_SIZE); | ||||
|         LauncherSvcInstanceStop, | ||||
|         Argc, Argv, Argl, 0, 0); | ||||
|     switch (NpResult) | ||||
|     { | ||||
|     case WN_SUCCESS: | ||||
| @@ -812,8 +780,6 @@ DWORD APIENTRY NPCancelConnection(LPWSTR lpName, BOOL fForce) | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     MemFree(PipeBuf); | ||||
|  | ||||
|     return NpResult; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user