mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-31 12:08:41 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			299 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			299 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|  * @file launch-test.c
 | |
|  *
 | |
|  * @copyright 2015-2025 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 software
 | |
|  * in accordance with the commercial license agreement provided in
 | |
|  * conjunction with the software.  The terms and conditions of any such
 | |
|  * commercial license agreement shall govern, supersede, and render
 | |
|  * ineffective any application of the GPLv3 license to this software,
 | |
|  * notwithstanding of any reference thereto in the software or
 | |
|  * associated repository.
 | |
|  */
 | |
| 
 | |
| #include <winfsp/launch.h>
 | |
| #include <tlib/testsuite.h>
 | |
| 
 | |
| #include "winfsp-tests.h"
 | |
| 
 | |
| static void launch_reg_test(void)
 | |
| {
 | |
|     NTSTATUS Result;
 | |
|     PWSTR ClassName = L"winfsp-tests-launch-reg-test";
 | |
|     FSP_LAUNCH_REG_RECORD RecordBuf = { 0 }, *Record;
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(STATUS_OBJECT_NAME_NOT_FOUND == Result);
 | |
|     ASSERT(0 == Record);
 | |
| 
 | |
|     RecordBuf.Executable = 0;
 | |
|     Result = FspLaunchRegSetRecord(ClassName, &RecordBuf);
 | |
|     ASSERT(STATUS_INVALID_PARAMETER == Result);
 | |
| 
 | |
|     RecordBuf.Executable = L"Executable";
 | |
|     RecordBuf.CommandLine = L"CommandLine";
 | |
|     RecordBuf.WorkDirectory = L"WorkDirectory";
 | |
|     RecordBuf.RunAs = L"RunAs";
 | |
|     RecordBuf.Security = L"Security";
 | |
|     RecordBuf.JobControl = 1;
 | |
|     RecordBuf.Credentials = 42;
 | |
|     Result = FspLaunchRegSetRecord(ClassName, &RecordBuf);
 | |
|     if (STATUS_ACCESS_DENIED == Result)
 | |
|     {
 | |
|         FspDebugLog(__FUNCTION__ ": need Administrator\n");
 | |
|         return;
 | |
|     }
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 != Record);
 | |
|     ASSERT(0 == Record->Agent);
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Executable, Record->Executable));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.CommandLine, Record->CommandLine));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.WorkDirectory, Record->WorkDirectory));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.RunAs, Record->RunAs));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Security, Record->Security));
 | |
|     ASSERT(RecordBuf.JobControl == Record->JobControl);
 | |
|     ASSERT(RecordBuf.Credentials == Record->Credentials);
 | |
|     FspLaunchRegFreeRecord(Record);
 | |
| 
 | |
|     Result = FspLaunchRegSetRecord(ClassName, &RecordBuf);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 != Record);
 | |
|     ASSERT(0 == Record->Agent);
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Executable, Record->Executable));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.CommandLine, Record->CommandLine));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.WorkDirectory, Record->WorkDirectory));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.RunAs, Record->RunAs));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Security, Record->Security));
 | |
|     ASSERT(RecordBuf.JobControl == Record->JobControl);
 | |
|     ASSERT(RecordBuf.Credentials == Record->Credentials);
 | |
|     FspLaunchRegFreeRecord(Record);
 | |
| 
 | |
|     RecordBuf.Security = 0;
 | |
|     RecordBuf.Credentials = 0;
 | |
|     Result = FspLaunchRegSetRecord(ClassName, &RecordBuf);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 != Record);
 | |
|     ASSERT(0 == Record->Agent);
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Executable, Record->Executable));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.CommandLine, Record->CommandLine));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.WorkDirectory, Record->WorkDirectory));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.RunAs, Record->RunAs));
 | |
|     ASSERT(0 == Record->Security);
 | |
|     ASSERT(RecordBuf.JobControl == Record->JobControl);
 | |
|     ASSERT(RecordBuf.Credentials == Record->Credentials);
 | |
|     FspLaunchRegFreeRecord(Record);
 | |
| 
 | |
|     Result = FspLaunchRegSetRecord(ClassName, 0);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(STATUS_OBJECT_NAME_NOT_FOUND == Result);
 | |
|     ASSERT(0 == Record);
 | |
| 
 | |
|     Result = FspLaunchRegSetRecord(ClassName, 0);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(STATUS_OBJECT_NAME_NOT_FOUND == Result);
 | |
|     ASSERT(0 == Record);
 | |
| 
 | |
|     RecordBuf.Agent = L"Agent1,Agent2";
 | |
|     Result = FspLaunchRegSetRecord(ClassName, &RecordBuf);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, L"Agent", &Record);
 | |
|     ASSERT(STATUS_OBJECT_NAME_NOT_FOUND == Result);
 | |
|     ASSERT(0 == Record);
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, L"Agent1", &Record);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 != Record);
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Agent, Record->Agent));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Executable, Record->Executable));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.CommandLine, Record->CommandLine));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.WorkDirectory, Record->WorkDirectory));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.RunAs, Record->RunAs));
 | |
|     ASSERT(0 == Record->Security);
 | |
|     ASSERT(RecordBuf.JobControl == Record->JobControl);
 | |
|     ASSERT(RecordBuf.Credentials == Record->Credentials);
 | |
|     FspLaunchRegFreeRecord(Record);
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 != Record);
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Agent, Record->Agent));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.Executable, Record->Executable));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.CommandLine, Record->CommandLine));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.WorkDirectory, Record->WorkDirectory));
 | |
|     ASSERT(0 == wcscmp(RecordBuf.RunAs, Record->RunAs));
 | |
|     ASSERT(0 == Record->Security);
 | |
|     ASSERT(RecordBuf.JobControl == Record->JobControl);
 | |
|     ASSERT(RecordBuf.Credentials == Record->Credentials);
 | |
|     FspLaunchRegFreeRecord(Record);
 | |
| 
 | |
|     Result = FspLaunchRegSetRecord(ClassName, 0);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(ClassName, 0, &Record);
 | |
|     ASSERT(STATUS_OBJECT_NAME_NOT_FOUND == Result);
 | |
|     ASSERT(0 == Record);
 | |
| }
 | |
| 
 | |
| static void launch_test(void)
 | |
| {
 | |
|     /* this test assumes that memfs32 is registered */
 | |
| 
 | |
|     NTSTATUS Result;
 | |
|     ULONG LauncherError;
 | |
|     PWSTR Argv[2];
 | |
|     FSP_LAUNCH_REG_RECORD *Record;
 | |
|     WCHAR Buffer[1024];
 | |
|     ULONG Size;
 | |
|     ULONG FoundClass, FoundInst1, FoundInst2;
 | |
| 
 | |
|     Result = FspLaunchRegGetRecord(L"memfs32", 0, &Record);
 | |
|     if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
 | |
|     {
 | |
|         FspDebugLog(__FUNCTION__ ": need memfs32 registration\n");
 | |
|         return;
 | |
|     }
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
| 
 | |
|     Argv[0] = L"";
 | |
|     Argv[1] = L"*";
 | |
| 
 | |
|     Result = FspLaunchStart(L"memfs32", L"winfsp-tests-share1", 2, Argv, FALSE, &LauncherError);
 | |
|     if (STATUS_OBJECT_NAME_NOT_FOUND == Result)
 | |
|     {
 | |
|         FspDebugLog(__FUNCTION__ ": need WinFsp.Launcher\n");
 | |
|         return;
 | |
|     }
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
| 
 | |
|     Result = FspLaunchStart(L"memfs32", L"winfsp-tests-share2", 2, Argv, FALSE, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
| 
 | |
|     Result = FspLaunchStart(L"memfs32", L"winfsp-tests-share1", 2, Argv, FALSE, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(ERROR_ALREADY_EXISTS == LauncherError);
 | |
| 
 | |
|     Result = FspLaunchStart(L"memfs32", L"winfsp-tests-share2", 2, Argv, FALSE, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(ERROR_ALREADY_EXISTS == LauncherError);
 | |
| 
 | |
|     Size = sizeof Buffer;
 | |
|     Result = FspLaunchGetInfo(L"memfs32", L"winfsp-tests-share1", Buffer, &Size, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
|     ASSERT((wcslen(L"memfs32") + 1) * sizeof(WCHAR) < Size);
 | |
|     ASSERT((wcslen(L"winfsp-tests-share1") + 1) * sizeof(WCHAR) < Size);
 | |
|     ASSERT(0 == wcscmp(L"memfs32", Buffer));
 | |
|     ASSERT(0 == wcscmp(L"winfsp-tests-share1", Buffer + 8));
 | |
| 
 | |
|     Size = sizeof Buffer;
 | |
|     Result = FspLaunchGetInfo(L"memfs32", L"winfsp-tests-share2", Buffer, &Size, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
|     ASSERT((wcslen(L"memfs32") + 1) * sizeof(WCHAR) < Size);
 | |
|     ASSERT((wcslen(L"winfsp-tests-share2") + 1) * sizeof(WCHAR) < Size);
 | |
|     ASSERT(0 == wcscmp(L"memfs32", Buffer));
 | |
|     ASSERT(0 == wcscmp(L"winfsp-tests-share2", Buffer + 8));
 | |
| 
 | |
|     Size = sizeof Buffer;
 | |
|     Result = FspLaunchGetNameList(Buffer, &Size, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
|     FoundClass = FoundInst1 = FoundInst2 = 0;
 | |
|     for (PWSTR P = Buffer, EndP = (PVOID)((PUINT8)P + Size), Part = P; EndP > P; P++)
 | |
|         if (L'\0' == *P)
 | |
|         {
 | |
|             if (0 == wcscmp(L"memfs32", Part))
 | |
|                 FoundClass++;
 | |
|             else if (0 == wcscmp(L"winfsp-tests-share1", Part))
 | |
|                 FoundInst1++;
 | |
|             else if (0 == wcscmp(L"winfsp-tests-share2", Part))
 | |
|                 FoundInst2++;
 | |
|             Part = P + 1;
 | |
|         }
 | |
|     ASSERT(2 == FoundClass);
 | |
|     ASSERT(1 == FoundInst1);
 | |
|     ASSERT(1 == FoundInst2);
 | |
| 
 | |
|     Result = FspLaunchStop(L"memfs32", L"winfsp-tests-share1", &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
| 
 | |
|     Result = FspLaunchStop(L"memfs32", L"winfsp-tests-share2", &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
| 
 | |
|     /* give the launcher a chance to stop the file systems! */
 | |
|     Sleep(3000);
 | |
| 
 | |
|     Size = sizeof Buffer;
 | |
|     Result = FspLaunchGetInfo(L"memfs32", L"winfsp-tests-share1", Buffer, &Size, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(ERROR_FILE_NOT_FOUND == LauncherError);
 | |
| 
 | |
|     Size = sizeof Buffer;
 | |
|     Result = FspLaunchGetInfo(L"memfs32", L"winfsp-tests-share2", Buffer, &Size, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(ERROR_FILE_NOT_FOUND == LauncherError);
 | |
| 
 | |
|     Result = FspLaunchStop(L"memfs32", L"winfsp-tests-share1", &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(ERROR_FILE_NOT_FOUND == LauncherError);
 | |
| 
 | |
|     Result = FspLaunchStop(L"memfs32", L"winfsp-tests-share2", &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(ERROR_FILE_NOT_FOUND == LauncherError);
 | |
| 
 | |
|     Size = sizeof Buffer;
 | |
|     Result = FspLaunchGetNameList(Buffer, &Size, &LauncherError);
 | |
|     ASSERT(NT_SUCCESS(Result));
 | |
|     ASSERT(0 == LauncherError);
 | |
|     FoundClass = FoundInst1 = FoundInst2 = 0;
 | |
|     for (PWSTR P = Buffer, EndP = (PVOID)((PUINT8)P + Size), Part = P; EndP > P; P++)
 | |
|         if (L'\0' == *P)
 | |
|         {
 | |
|             if (0 == wcscmp(L"memfs32", Part))
 | |
|                 FoundClass++;
 | |
|             else if (0 == wcscmp(L"winfsp-tests-share1", Part))
 | |
|                 FoundInst1++;
 | |
|             else if (0 == wcscmp(L"winfsp-tests-share2", Part))
 | |
|                 FoundInst2++;
 | |
|             Part = P + 1;
 | |
|         }
 | |
|     ASSERT(0 == FoundClass);
 | |
|     ASSERT(0 == FoundInst1);
 | |
|     ASSERT(0 == FoundInst2);
 | |
| }
 | |
| 
 | |
| void launch_tests(void)
 | |
| {
 | |
|     if (OptExternal)
 | |
|         return;
 | |
| 
 | |
|     TEST(launch_reg_test);
 | |
|     //TEST(launch_test);
 | |
| }
 |