removed exception structure in favor throw at the point of the exception.
- Removed pattern of throwing access violation in configuration lookup and catching the error. - Moved Electronfixup to statically link library calls - Tested by running automated testsuite - Tested electronfixup on electron helloWorld 5.0.6
This commit is contained in:
Родитель
c41cc4d161
Коммит
91c44291e5
|
@ -1,73 +0,0 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include "utilities.h"
|
||||
|
||||
class ErrorInformation
|
||||
{
|
||||
public:
|
||||
ErrorInformation()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ErrorInformation(std::wstring customMessage, DWORD errorNumber) :
|
||||
ErrorInformation(customMessage, errorNumber, L"")
|
||||
{
|
||||
}
|
||||
|
||||
ErrorInformation(std::wstring customMessage, DWORD errorNumber, std::wstring exeName)
|
||||
: customMessage(customMessage)
|
||||
, errorNumber(errorNumber)
|
||||
, errorMessage(widen(std::system_category().message(errorNumber)))
|
||||
, isThereAnError(true)
|
||||
, exeName(exeName)
|
||||
{
|
||||
}
|
||||
|
||||
std::wstring Print()
|
||||
{
|
||||
std::wstring errorToPrint;
|
||||
|
||||
if (!this->customMessage.empty())
|
||||
{
|
||||
errorToPrint.append(this->customMessage);
|
||||
errorToPrint.append(L"\r\n");
|
||||
}
|
||||
|
||||
errorToPrint.append(L"Message: " + this->errorMessage + L"\r\n");
|
||||
errorToPrint.append(L"Error number: " + std::to_wstring(this->errorNumber));
|
||||
errorToPrint.append(L"\r\n");
|
||||
|
||||
if(!this->exeName.empty())
|
||||
{
|
||||
errorToPrint.append(L"ExeName: " + this->exeName + L"\r\n");
|
||||
}
|
||||
|
||||
return errorToPrint;
|
||||
}
|
||||
|
||||
bool IsThereAnError()
|
||||
{
|
||||
return this->isThereAnError;
|
||||
}
|
||||
|
||||
DWORD GetErrorNumber()
|
||||
{
|
||||
return this->errorNumber;
|
||||
}
|
||||
|
||||
void AddExeName(std::wstring exeNameToAdd)
|
||||
{
|
||||
this->exeName = exeNameToAdd;
|
||||
}
|
||||
|
||||
private:
|
||||
std::wstring customMessage;
|
||||
DWORD errorNumber;
|
||||
std::wstring exeName;
|
||||
std::wstring errorMessage;
|
||||
bool isThereAnError = false;
|
||||
};
|
||||
|
|
@ -3,6 +3,6 @@
|
|||
SchemaLocation="https://github.com/Microsoft/MSIX-PackageSupportFramework/blob/master/MetadataSchema.xml ..\MetadataSchema.xsd">
|
||||
<Version>1.1.0</Version>
|
||||
<MinimumWindowsPlatform>1607</MinimumWindowsPlatform>
|
||||
<Description></Description>
|
||||
<WhenToUse></WhenToUse>
|
||||
<Description></Description>
|
||||
<WhenToUse></WhenToUse>
|
||||
</PSFData>
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
<ItemGroup>
|
||||
<Xml Include="PSFLauncherMetadata.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ErrorInformation.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{29EE27EF-A3A3-4B8F-8DA2-532A5C04BD9E}</ProjectGuid>
|
||||
|
|
|
@ -18,9 +18,4 @@
|
|||
<Filter>src</Filter>
|
||||
</Xml>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ErrorInformation.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -15,7 +15,6 @@
|
|||
#include <combaseapi.h>
|
||||
#include <ppltasks.h>
|
||||
#include <ShObjIdl.h>
|
||||
#include "ErrorInformation.h"
|
||||
#include <wil\resource.h>
|
||||
#include <wil\result.h>
|
||||
#include <TraceLoggingProvider.h>
|
||||
|
@ -28,8 +27,8 @@ TRACELOGGING_DEFINE_PROVIDER(
|
|||
(0xf7f4e8c4, 0x9981, 0x5221, 0xe6, 0xfb, 0xff, 0x9d, 0xd1, 0xcd, 0xa4, 0xe1),
|
||||
TraceLoggingOptionMicrosoftTelemetry());
|
||||
|
||||
//These two macros don't exist in RS1. Define them here to prevent build
|
||||
//failures when building for RS1.
|
||||
// These two macros don't exist in RS1. Define them here to prevent build
|
||||
// failures when building for RS1.
|
||||
#ifndef PROCESS_CREATION_DESKTOP_APP_BREAKAWAY_DISABLE_PROCESS_TREE
|
||||
# define PROCESS_CREATION_DESKTOP_APP_BREAKAWAY_DISABLE_PROCESS_TREE PROCESS_CREATION_DESKTOP_APPX_OVERRIDE
|
||||
#endif
|
||||
|
@ -40,31 +39,23 @@ TRACELOGGING_DEFINE_PROVIDER(
|
|||
|
||||
using namespace std::literals;
|
||||
|
||||
// Forward declarations
|
||||
void LogApplicationAndProcessesCollection();
|
||||
|
||||
struct ExecutionInformation
|
||||
{
|
||||
LPCWSTR ApplicationName;
|
||||
std::wstring CommandLine;
|
||||
LPCWSTR CurrentDirectory;
|
||||
};
|
||||
|
||||
//Forward declarations
|
||||
ErrorInformation StartProcess(ExecutionInformation execInfo, int cmdShow, bool runInVirtualEnvironment) noexcept;
|
||||
int launcher_main(PCWSTR args, int cmdShow) noexcept;
|
||||
ErrorInformation RunScript(const psf::json_object &scriptInformation, std::filesystem::path packageRoot, LPCWSTR dirStr, int cmdShow) noexcept;
|
||||
ErrorInformation GetAndLaunchMonitor(const psf::json_object &monitor, std::filesystem::path packageRoot, int cmdShow, LPCWSTR dirStr) noexcept;
|
||||
ErrorInformation LaunchMonitorInBackground(std::filesystem::path packageRoot, const wchar_t executable[], const wchar_t arguments[], bool wait, bool asAdmin, int cmdShow, LPCWSTR dirStr) noexcept;
|
||||
void GetAndLaunchMonitor(const psf::json_object &monitor, std::filesystem::path packageRoot, int cmdShow, LPCWSTR dirStr);
|
||||
void LaunchMonitorInBackground(std::filesystem::path packageRoot, const wchar_t executable[], const wchar_t arguments[], bool wait, bool asAdmin, int cmdShow, LPCWSTR dirStr);
|
||||
|
||||
static inline bool check_suffix_if(iwstring_view str, iwstring_view suffix) noexcept;
|
||||
void LogString(const char name[], const wchar_t value[]) noexcept;
|
||||
void LogString(const char name[], const char value[]) noexcept;
|
||||
void Log(const char fmt[], ...) noexcept;
|
||||
ErrorInformation StartWithShellExecute(std::filesystem::path packageRoot, std::filesystem::path exeName, std::wstring exeArgString, LPCWSTR dirStr, int cmdShow) noexcept;
|
||||
ErrorInformation CheckIfPowershellIsInstalled(bool& isPowershellInstalled) noexcept;
|
||||
std::wstring GetApplicationNameFromExecInfo(ExecutionInformation execInfo);
|
||||
ErrorInformation GetExitCodeForProcess(ExecutionInformation execInfo, HANDLE hProcess);
|
||||
|
||||
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR args, int cmdShow)
|
||||
void RunScript(const psf::json_object& scriptInformation, std::filesystem::path packageRoot, LPCWSTR dirStr, int cmdShow);
|
||||
void StartProcess(LPCWSTR applicationName, LPWSTR commandLine, LPCWSTR currentDirectory, int cmdShow, bool runInVirtualEnvironment);
|
||||
void StartWithShellExecute(std::filesystem::path packageRoot, std::filesystem::path exeName, std::wstring exeArgString, LPCWSTR dirStr, int cmdShow);
|
||||
void CheckIfPowershellIsInstalled(bool& isPowershellInstalled);
|
||||
|
||||
int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR args, _In_ int cmdShow)
|
||||
{
|
||||
return launcher_main(args, cmdShow);
|
||||
}
|
||||
|
@ -73,10 +64,7 @@ int launcher_main(PCWSTR args, int cmdShow) noexcept try
|
|||
{
|
||||
Log("\tIn Launcher_main()");
|
||||
auto appConfig = PSFQueryCurrentAppLaunchConfig(true);
|
||||
if (!appConfig)
|
||||
{
|
||||
throw_win32(ERROR_NOT_FOUND, "Error: could not find matching appid in config.json and appx manifest");
|
||||
}
|
||||
THROW_HR_IF_MSG(ERROR_NOT_FOUND, !appConfig, "Error: could not find matching appid in config.json and appx manifest");
|
||||
|
||||
LogApplicationAndProcessesCollection();
|
||||
|
||||
|
@ -87,89 +75,45 @@ int launcher_main(PCWSTR args, int cmdShow) noexcept try
|
|||
// At least for now, configured launch paths are relative to the package root
|
||||
std::filesystem::path packageRoot = PSFQueryPackageRootPath();
|
||||
|
||||
ErrorInformation error;
|
||||
|
||||
//Launch the starting PowerShell script if we are using one.
|
||||
// Launch the starting PowerShell script if we are using one.
|
||||
auto startScriptInformation = PSFQueryStartScriptInfo();
|
||||
if (startScriptInformation)
|
||||
{
|
||||
auto isPowershellInstalled = false;
|
||||
error = CheckIfPowershellIsInstalled(isPowershellInstalled);
|
||||
|
||||
if (error.IsThereAnError())
|
||||
{
|
||||
::PSFReportError(error.Print().c_str());
|
||||
return error.GetErrorNumber();
|
||||
}
|
||||
|
||||
if (!isPowershellInstalled)
|
||||
{
|
||||
::PSFReportError(L"PowerShell is not installed. Please install PowerShell to run scripts in PSF");
|
||||
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
error = RunScript(*startScriptInformation, packageRoot, dirStr, cmdShow);
|
||||
|
||||
if (error.IsThereAnError())
|
||||
{
|
||||
::PSFReportError(error.Print().c_str());
|
||||
return error.GetErrorNumber();
|
||||
}
|
||||
CheckIfPowershellIsInstalled(isPowershellInstalled);
|
||||
THROW_HR_IF_MSG(ERROR_NOT_SUPPORTED, !isPowershellInstalled, "PowerShell is not installed. Please install PowerShell to run scripts in PSF");
|
||||
RunScript(*startScriptInformation, packageRoot, dirStr, cmdShow);
|
||||
}
|
||||
|
||||
//If we get here we know that starting script did NOT encounter an error
|
||||
//Launch monitor if we are using one.
|
||||
// If we get here we know that starting script did NOT encounter an error
|
||||
// Launch monitor if we are using one.
|
||||
auto monitor = PSFQueryAppMonitorConfig();
|
||||
if (monitor != nullptr)
|
||||
{
|
||||
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
||||
error = GetAndLaunchMonitor(*monitor, packageRoot, cmdShow, dirStr);
|
||||
THROW_IF_FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE));
|
||||
GetAndLaunchMonitor(*monitor, packageRoot, cmdShow, dirStr);
|
||||
}
|
||||
|
||||
if (!error.IsThereAnError())
|
||||
// Launch underlying application.
|
||||
auto exeName = appConfig->get("executable").as_string().wide();
|
||||
auto exePath = packageRoot / exeName;
|
||||
auto exeArgString = exeArgs ? exeArgs->as_string().wide() : (wchar_t*)L"";
|
||||
|
||||
// Keep these quotes here. StartProcess assumes there are quotes around the exe file name
|
||||
if (check_suffix_if(exeName, L".exe"_isv))
|
||||
{
|
||||
//Launch underlying application.
|
||||
auto exeName = appConfig->get("executable").as_string().wide();
|
||||
auto exePath = packageRoot / exeName;
|
||||
auto exeArgString = exeArgs ? exeArgs->as_string().wide() : (wchar_t*)L"";
|
||||
|
||||
//Keep these quotes here. StartProcess assums there are quptes around the exe file name
|
||||
std::wstring cmdLine = L"\"" + exePath.filename().native() + L"\" " + exeArgString + L" " + args;
|
||||
if (check_suffix_if(exeName, L".exe"_isv))
|
||||
{
|
||||
std::wstring workingDirectory = (packageRoot / dirStr).native();
|
||||
|
||||
ExecutionInformation execInfo = { exePath.c_str(), cmdLine };
|
||||
|
||||
auto currentDirectory = (packageRoot / dirStr);
|
||||
execInfo.CurrentDirectory = currentDirectory.c_str();
|
||||
error = StartProcess(execInfo, cmdShow, false);
|
||||
error.AddExeName(exeName);
|
||||
}
|
||||
else
|
||||
{
|
||||
error = StartWithShellExecute(packageRoot, exeName, exeArgString, dirStr, cmdShow);
|
||||
}
|
||||
StartProcess(exePath.c_str(), (L"\"" + exePath.filename().native() + L"\" " + exeArgString + L" " + args).data(), (packageRoot / dirStr).c_str(), cmdShow, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
StartWithShellExecute(packageRoot, exeName, exeArgString, dirStr, cmdShow);
|
||||
}
|
||||
|
||||
//Launch the end PowerShell script if we are using one.
|
||||
// Launch the end PowerShell script if we are using one.
|
||||
auto endScriptInformation = PSFQueryEndScriptInfo();
|
||||
if (endScriptInformation)
|
||||
{
|
||||
ErrorInformation endingScriptError = RunScript(*endScriptInformation, packageRoot, dirStr, cmdShow);
|
||||
error.AddExeName(L"PowerShell.exe -file ");
|
||||
|
||||
//If there is an existing error from Monitor or the packaged exe
|
||||
if (error.IsThereAnError())
|
||||
{
|
||||
::PSFReportError(error.Print().c_str());
|
||||
return error.GetErrorNumber();
|
||||
}
|
||||
else if (endingScriptError.IsThereAnError())
|
||||
{
|
||||
::PSFReportError(endingScriptError.Print().c_str());
|
||||
return endingScriptError.GetErrorNumber();
|
||||
}
|
||||
RunScript(*endScriptInformation, packageRoot, dirStr, cmdShow);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -180,16 +124,16 @@ catch (...)
|
|||
return win32_from_caught_exception();
|
||||
}
|
||||
|
||||
ErrorInformation RunScript(const psf::json_object &scriptInformation, std::filesystem::path packageRoot, LPCWSTR dirStr, int cmdShow) noexcept
|
||||
void RunScript(const psf::json_object &scriptInformation, std::filesystem::path packageRoot, LPCWSTR dirStr, int cmdShow)
|
||||
{
|
||||
//Generate the command string that we will use to call powershell
|
||||
// Generate the command string that we will use to call powershell
|
||||
std::wstring powershellCommandString(L"Powershell.exe -file ");
|
||||
|
||||
std::wstring scriptPath = scriptInformation.get("scriptPath").as_string().wide();
|
||||
powershellCommandString.append(scriptPath);
|
||||
powershellCommandString.append(L" ");
|
||||
|
||||
//Script arguments are optional.
|
||||
// Script arguments are optional.
|
||||
auto scriptArgumentsJObject = scriptInformation.try_get("scriptArguments");
|
||||
if (scriptArgumentsJObject)
|
||||
{
|
||||
|
@ -199,41 +143,30 @@ ErrorInformation RunScript(const psf::json_object &scriptInformation, std::files
|
|||
auto currentDirectory = (packageRoot / dirStr);
|
||||
std::filesystem::path powershellScriptPath(scriptPath);
|
||||
|
||||
//The file might be on a network drive.
|
||||
// The file might be on a network drive.
|
||||
auto doesFileExist = std::filesystem::exists(powershellScriptPath);
|
||||
|
||||
//Check on local computer.
|
||||
// Check on local computer.
|
||||
if (!doesFileExist)
|
||||
{
|
||||
doesFileExist = std::filesystem::exists(currentDirectory / powershellScriptPath);
|
||||
}
|
||||
|
||||
if (doesFileExist)
|
||||
THROW_HR_IF_MSG(ERROR_FILE_NOT_FOUND, !doesFileExist, "The PowerShell file %ws cannot be found", (currentDirectory / powershellScriptPath).c_str());
|
||||
|
||||
// runInVirtualEnvironment is optional.
|
||||
auto runInVirtualEnvironmentJObject = scriptInformation.try_get("runInVirtualEnvironment");
|
||||
auto runInVirtualEnvironment = false;
|
||||
|
||||
if (runInVirtualEnvironmentJObject)
|
||||
{
|
||||
//runInVirtualEnvironment is optional.
|
||||
auto runInVirtualEnvironmentJObject = scriptInformation.try_get("runInVirtualEnvironment");
|
||||
auto runInVirtualEnvironment = false;
|
||||
|
||||
if (runInVirtualEnvironmentJObject)
|
||||
{
|
||||
runInVirtualEnvironment = runInVirtualEnvironmentJObject->as_boolean().get();
|
||||
}
|
||||
|
||||
ExecutionInformation execInfo = { nullptr, powershellCommandString , currentDirectory.c_str() };
|
||||
return StartProcess(execInfo, cmdShow, runInVirtualEnvironment);
|
||||
runInVirtualEnvironment = runInVirtualEnvironmentJObject->as_boolean().get();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring errorMessage = L"The PowerShell file ";
|
||||
errorMessage.append(currentDirectory / powershellScriptPath);
|
||||
errorMessage.append(L" can't be found");
|
||||
ErrorInformation error = { errorMessage, ERROR_FILE_NOT_FOUND };
|
||||
|
||||
return error;
|
||||
}
|
||||
StartProcess(nullptr, powershellCommandString.data(), currentDirectory.c_str(), cmdShow, runInVirtualEnvironment);
|
||||
}
|
||||
|
||||
ErrorInformation GetAndLaunchMonitor(const psf::json_object &monitor, std::filesystem::path packageRoot, int cmdShow, LPCWSTR dirStr) noexcept
|
||||
void GetAndLaunchMonitor(const psf::json_object &monitor, std::filesystem::path packageRoot, int cmdShow, LPCWSTR dirStr)
|
||||
{
|
||||
bool asAdmin = false;
|
||||
bool wait = false;
|
||||
|
@ -252,12 +185,10 @@ ErrorInformation GetAndLaunchMonitor(const psf::json_object &monitor, std::files
|
|||
}
|
||||
|
||||
Log("\tCreating the monitor: %ls", monitorExecutable->as_string().wide());
|
||||
ErrorInformation error = LaunchMonitorInBackground(packageRoot, monitorExecutable->as_string().wide(), monitorArguments->as_string().wide(), wait, asAdmin, cmdShow, dirStr);
|
||||
|
||||
return error;
|
||||
LaunchMonitorInBackground(packageRoot, monitorExecutable->as_string().wide(), monitorArguments->as_string().wide(), wait, asAdmin, cmdShow, dirStr);
|
||||
}
|
||||
|
||||
ErrorInformation LaunchMonitorInBackground(std::filesystem::path packageRoot, const wchar_t executable[], const wchar_t arguments[], bool wait, bool asAdmin, int cmdShow, LPCWSTR dirStr) noexcept
|
||||
void LaunchMonitorInBackground(std::filesystem::path packageRoot, const wchar_t executable[], const wchar_t arguments[], bool wait, bool asAdmin, int cmdShow, LPCWSTR dirStr)
|
||||
{
|
||||
std::wstring cmd = L"\"" + (packageRoot / executable).native() + L"\"";
|
||||
|
||||
|
@ -266,81 +197,67 @@ ErrorInformation LaunchMonitorInBackground(std::filesystem::path packageRoot, co
|
|||
// This happens when the program is requested for elevation.
|
||||
SHELLEXECUTEINFOW shExInfo =
|
||||
{
|
||||
sizeof(shExInfo) //cbSize
|
||||
sizeof(shExInfo) // bSize
|
||||
, wait ? (ULONG)SEE_MASK_NOCLOSEPROCESS : (ULONG)(SEE_MASK_NOCLOSEPROCESS | SEE_MASK_WAITFORINPUTIDLE) // fmask
|
||||
, 0 //hwnd
|
||||
, L"runas" //lpVerb
|
||||
, 0 // hwnd
|
||||
, L"runas" // lpVerb
|
||||
, cmd.c_str() // lpFile
|
||||
, arguments //lpParameters
|
||||
, nullptr //lpDirectory
|
||||
, 1 //nShow
|
||||
, 0 //hInstApp
|
||||
, arguments // lpParameters
|
||||
, nullptr // lpDirectory
|
||||
, 1 // nShow
|
||||
, 0 // hInstApp
|
||||
};
|
||||
|
||||
THROW_LAST_ERROR_IF_MSG(!ShellExecuteEx(&shExInfo), "Error starting monitor using ShellExecuteEx");
|
||||
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE), shExInfo.hProcess == INVALID_HANDLE_VALUE);
|
||||
|
||||
if (ShellExecuteEx(&shExInfo))
|
||||
if (wait)
|
||||
{
|
||||
if (wait)
|
||||
{
|
||||
WaitForSingleObject(shExInfo.hProcess, INFINITE);
|
||||
CloseHandle(shExInfo.hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
WaitForInputIdle(shExInfo.hProcess, 1000);
|
||||
// Due to elevation, the process starts, relaunches, and the main process ends in under 1ms.
|
||||
// So we'll just toss in an ugly sleep here for now.
|
||||
Sleep(5000);
|
||||
}
|
||||
|
||||
return GetExitCodeForProcess({ executable }, shExInfo.hProcess);
|
||||
WaitForSingleObject(shExInfo.hProcess, INFINITE);
|
||||
CloseHandle(shExInfo.hProcess);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto err = ::GetLastError();
|
||||
ErrorInformation error = { L"Error starting monitor using ShellExecuteEx", err, executable };
|
||||
WaitForInputIdle(shExInfo.hProcess, 1000);
|
||||
// Due to elevation, the process starts, relaunches, and the main process ends in under 1ms.
|
||||
// So we'll just toss in an ugly sleep here for now.
|
||||
Sleep(5000);
|
||||
}
|
||||
|
||||
DWORD exitCode{};
|
||||
THROW_LAST_ERROR_IF_MSG(!GetExitCodeProcess(shExInfo.hProcess, &exitCode), "Could not get error for process");
|
||||
THROW_IF_WIN32_ERROR(exitCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecutionInformation execInfo = { executable, (cmd + L" " + arguments) };
|
||||
|
||||
auto currentDirectory = (packageRoot / dirStr);
|
||||
execInfo.CurrentDirectory = currentDirectory.c_str();
|
||||
|
||||
ErrorInformation error = StartProcess(execInfo, cmdShow, false);
|
||||
error.AddExeName(executable);
|
||||
|
||||
return error;
|
||||
StartProcess(executable, (cmd + L" " + arguments).data(), (packageRoot / dirStr).c_str(), cmdShow, false);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorInformation StartProcess(ExecutionInformation execInfo, int cmdShow, bool runInVirtualEnvironment) noexcept
|
||||
void StartProcess(LPCWSTR applicationName, LPWSTR commandLine, LPCWSTR currentDirectory, int cmdShow, bool runInVirtualEnvironment)
|
||||
{
|
||||
STARTUPINFOEXW startupInfoEx =
|
||||
{
|
||||
{
|
||||
sizeof(startupInfoEx)
|
||||
, nullptr //lpReserved
|
||||
, nullptr // lpReserved
|
||||
, nullptr // lpDesktop
|
||||
, nullptr // lpTitle
|
||||
, 0 //dwX
|
||||
, 0 //dwY
|
||||
, 0 //dwXSize
|
||||
, 0 //swYSize
|
||||
, 0 //dwXCountChar
|
||||
, 0 //dwYCountChar
|
||||
, 0 // dwX
|
||||
, 0 // dwY
|
||||
, 0 // dwXSize
|
||||
, 0 // swYSize
|
||||
, 0 // dwXCountChar
|
||||
, 0 // dwYCountChar
|
||||
, 0 // dwFillAttribute
|
||||
, STARTF_USESHOWWINDOW //dwFlags
|
||||
, STARTF_USESHOWWINDOW // dwFlags
|
||||
, static_cast<WORD>(cmdShow) // wShowWindow
|
||||
}
|
||||
};
|
||||
|
||||
if (runInVirtualEnvironment)
|
||||
{
|
||||
SIZE_T AttributeListSize;
|
||||
SIZE_T AttributeListSize{};
|
||||
InitializeProcThreadAttributeList(nullptr, 1, 0, &AttributeListSize);
|
||||
startupInfoEx.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(
|
||||
GetProcessHeap(),
|
||||
|
@ -348,105 +265,50 @@ ErrorInformation StartProcess(ExecutionInformation execInfo, int cmdShow, bool r
|
|||
AttributeListSize
|
||||
);
|
||||
|
||||
if (InitializeProcThreadAttributeList(startupInfoEx.lpAttributeList,
|
||||
1,
|
||||
0,
|
||||
&AttributeListSize) == FALSE)
|
||||
{
|
||||
auto err{ ::GetLastError() };
|
||||
ErrorInformation error = { L"Could not initialize the proc thread attribute list.", err };
|
||||
}
|
||||
THROW_LAST_ERROR_IF_MSG(
|
||||
!InitializeProcThreadAttributeList(
|
||||
startupInfoEx.lpAttributeList,
|
||||
1,
|
||||
0,
|
||||
&AttributeListSize),
|
||||
"Could not initialize the proc thread attribute list.");
|
||||
|
||||
DWORD attribute = PROCESS_CREATION_DESKTOP_APP_BREAKAWAY_DISABLE_PROCESS_TREE;
|
||||
if (UpdateProcThreadAttribute(startupInfoEx.lpAttributeList,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY,
|
||||
&attribute,
|
||||
sizeof(attribute),
|
||||
nullptr,
|
||||
nullptr) == FALSE)
|
||||
{
|
||||
auto err{ ::GetLastError() };
|
||||
ErrorInformation error{ L"Could not update Proc thread attribute.", err };
|
||||
}
|
||||
THROW_LAST_ERROR_IF_MSG(
|
||||
!UpdateProcThreadAttribute(
|
||||
startupInfoEx.lpAttributeList,
|
||||
0,
|
||||
PROC_THREAD_ATTRIBUTE_DESKTOP_APP_POLICY,
|
||||
&attribute,
|
||||
sizeof(attribute),
|
||||
nullptr,
|
||||
nullptr),
|
||||
"Could not update Proc thread attribute.");
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION processInfo = { 0 };
|
||||
if (::CreateProcessW(
|
||||
execInfo.ApplicationName,
|
||||
execInfo.CommandLine.data(),
|
||||
nullptr, nullptr, // Process/ThreadAttributes
|
||||
true, // InheritHandles
|
||||
EXTENDED_STARTUPINFO_PRESENT, // CreationFlags
|
||||
nullptr, // Environment
|
||||
execInfo.CurrentDirectory,
|
||||
(LPSTARTUPINFO)&startupInfoEx,
|
||||
&processInfo))
|
||||
{
|
||||
DWORD waitResult = ::WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
PROCESS_INFORMATION processInfo{};
|
||||
THROW_LAST_ERROR_IF_MSG(
|
||||
!::CreateProcessW(
|
||||
applicationName,
|
||||
commandLine,
|
||||
nullptr, nullptr, // Process/ThreadAttributes
|
||||
true, // InheritHandles
|
||||
EXTENDED_STARTUPINFO_PRESENT, // CreationFlags
|
||||
nullptr, // Environment
|
||||
currentDirectory,
|
||||
(LPSTARTUPINFO)& startupInfoEx,
|
||||
&processInfo),
|
||||
"ERROR: Failed to create a process for %ws",
|
||||
applicationName);
|
||||
|
||||
if (waitResult != WAIT_OBJECT_0)
|
||||
{
|
||||
auto err{ ::GetLastError() };
|
||||
return { L"Waiting operation failed unexpectedly.", err };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wostringstream ss;
|
||||
auto err{ ::GetLastError() };
|
||||
ss << L"ERROR: Failed to create a process for " << GetApplicationNameFromExecInfo(execInfo);
|
||||
|
||||
return { ss.str(), err };
|
||||
}
|
||||
|
||||
return {};
|
||||
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE), processInfo.hProcess == INVALID_HANDLE_VALUE);
|
||||
DWORD waitResult = ::WaitForSingleObject(processInfo.hProcess, INFINITE);
|
||||
THROW_LAST_ERROR_IF_MSG(waitResult != WAIT_OBJECT_0, "Waiting operation failed unexpectedly.");
|
||||
CloseHandle(processInfo.hProcess);
|
||||
CloseHandle(processInfo.hThread);
|
||||
}
|
||||
|
||||
std::wstring GetApplicationNameFromExecInfo(ExecutionInformation execInfo)
|
||||
{
|
||||
if (execInfo.ApplicationName)
|
||||
{
|
||||
return execInfo.ApplicationName;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring applicationName;
|
||||
//If the application name contains spaces, the application needs to be surrounded in quotes.
|
||||
if (execInfo.CommandLine[0] == '"')
|
||||
{
|
||||
//Skip the first quote and don't include the last quote.
|
||||
applicationName = execInfo.CommandLine.substr(1, execInfo.CommandLine.find('"', 1) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
applicationName = execInfo.CommandLine.substr(0, execInfo.CommandLine.find(' '));
|
||||
|
||||
}
|
||||
|
||||
return applicationName;
|
||||
}
|
||||
}
|
||||
|
||||
ErrorInformation GetExitCodeForProcess(ExecutionInformation execInfo, HANDLE hProcess)
|
||||
{
|
||||
DWORD exitCode = ERROR_SUCCESS;
|
||||
if (GetExitCodeProcess(hProcess, &exitCode))
|
||||
{
|
||||
if (exitCode != ERROR_SUCCESS)
|
||||
{
|
||||
return { L"Exit code for " + GetApplicationNameFromExecInfo(execInfo), exitCode };
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return { L"Could not get the exit code for " + GetApplicationNameFromExecInfo(execInfo), ::GetLastError() };
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorInformation StartWithShellExecute(std::filesystem::path packageRoot, std::filesystem::path exeName, std::wstring exeArgString, LPCWSTR dirStr, int cmdShow) noexcept
|
||||
void StartWithShellExecute(std::filesystem::path packageRoot, std::filesystem::path exeName, std::wstring exeArgString, LPCWSTR dirStr, int cmdShow)
|
||||
{
|
||||
// Non Exe case, use shell launching to pick up local FTA
|
||||
auto nonExePath = packageRoot / exeName;
|
||||
|
@ -462,15 +324,16 @@ ErrorInformation StartWithShellExecute(std::filesystem::path packageRoot, std::f
|
|||
, static_cast<WORD>(cmdShow)
|
||||
};
|
||||
|
||||
|
||||
Log("\tUsing Shell launch: %ls %ls", shex.lpFile, shex.lpParameters);
|
||||
if (!ShellExecuteEx(&shex))
|
||||
{
|
||||
auto err{ ::GetLastError() };
|
||||
return { L"ERROR: Failed to create detoured shell process", err };
|
||||
}
|
||||
THROW_LAST_ERROR_IF_MSG (
|
||||
!ShellExecuteEx(&shex),
|
||||
"ERROR: Failed to create detoured shell process");
|
||||
|
||||
return GetExitCodeForProcess({ exeName.native().c_str() }, shex.hProcess);
|
||||
THROW_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE), shex.hProcess == INVALID_HANDLE_VALUE);
|
||||
DWORD exitCode{};
|
||||
THROW_IF_WIN32_ERROR(GetExitCodeProcess(shex.hProcess, &exitCode));
|
||||
THROW_IF_WIN32_ERROR(exitCode);
|
||||
CloseHandle(shex.hProcess);
|
||||
}
|
||||
|
||||
static inline bool check_suffix_if(iwstring_view str, iwstring_view suffix) noexcept
|
||||
|
@ -512,7 +375,7 @@ void LogString(const char name[], const wchar_t value[]) noexcept
|
|||
Log("\t%s=%ls\n", name, value);
|
||||
}
|
||||
|
||||
ErrorInformation CheckIfPowershellIsInstalled(bool& isPowershellInstalled) noexcept
|
||||
void CheckIfPowershellIsInstalled(bool& isPowershellInstalled)
|
||||
{
|
||||
wil::unique_hkey registryHandle;
|
||||
LSTATUS createResult = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\PowerShell\\1", 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_READ, nullptr, ®istryHandle, nullptr);
|
||||
|
@ -521,23 +384,17 @@ ErrorInformation CheckIfPowershellIsInstalled(bool& isPowershellInstalled) noexc
|
|||
{
|
||||
// If the key cannot be found, powershell is not installed
|
||||
isPowershellInstalled = false;
|
||||
return {};
|
||||
}
|
||||
else if (createResult != ERROR_SUCCESS)
|
||||
{
|
||||
return { L"Error with getting the key to see if PowerShell is installed. ", (DWORD)createResult };
|
||||
THROW_HR_MSG(createResult, "Error with getting the key to see if PowerShell is installed.");
|
||||
}
|
||||
|
||||
DWORD valueFromRegistry = 0;
|
||||
DWORD bufferSize = sizeof(DWORD);
|
||||
DWORD type = REG_DWORD;
|
||||
auto getResult = RegQueryValueExW(registryHandle.get(), L"Install", nullptr, &type, reinterpret_cast<BYTE*>(&valueFromRegistry), &bufferSize);
|
||||
|
||||
if (getResult != ERROR_SUCCESS)
|
||||
{
|
||||
//Don't set isPowershellInstalled since we can't figure it out.
|
||||
return { L"Error with querying the key to see if PowerShell is installed. ", (DWORD)getResult };
|
||||
}
|
||||
THROW_IF_WIN32_ERROR_MSG(RegQueryValueExW(registryHandle.get(), L"Install", nullptr, &type, reinterpret_cast<BYTE*>(&valueFromRegistry), &bufferSize),
|
||||
"Error with querying the key to see if PowerShell is installed.");
|
||||
|
||||
if (valueFromRegistry == 1)
|
||||
{
|
||||
|
@ -547,20 +404,18 @@ ErrorInformation CheckIfPowershellIsInstalled(bool& isPowershellInstalled) noexc
|
|||
{
|
||||
isPowershellInstalled = false;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void LogApplicationAndProcessesCollection()
|
||||
{
|
||||
auto configRoot = PSFQueryConfigRoot();
|
||||
|
||||
if (auto applications = configRoot->as_object().try_get("applications"))
|
||||
{
|
||||
for (auto& applicationsConfig : applications->as_array())
|
||||
{
|
||||
auto exeStr = applicationsConfig.as_object().try_get("executable")->as_string().wide();
|
||||
auto idStr = applicationsConfig.as_object().try_get("id")->as_string().wide();
|
||||
auto configRoot = PSFQueryConfigRoot();
|
||||
|
||||
if (auto applications = configRoot->as_object().try_get("applications"))
|
||||
{
|
||||
for (auto& applicationsConfig : applications->as_array())
|
||||
{
|
||||
auto exeStr = applicationsConfig.as_object().try_get("executable")->as_string().wide();
|
||||
auto idStr = applicationsConfig.as_object().try_get("id")->as_string().wide();
|
||||
TraceLoggingWrite(
|
||||
g_Log_ETW_ComponentProvider,
|
||||
"ApplicationsConfigdata",
|
||||
|
@ -568,37 +423,37 @@ void LogApplicationAndProcessesCollection()
|
|||
TraceLoggingWideString(idStr, "applications_id"),
|
||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto processes = configRoot->as_object().try_get("processes"))
|
||||
{
|
||||
for (auto& processConfig : processes->as_array())
|
||||
{
|
||||
auto exeStr = processConfig.as_object().get("executable").as_string().wide();
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto processes = configRoot->as_object().try_get("processes"))
|
||||
{
|
||||
for (auto& processConfig : processes->as_array())
|
||||
{
|
||||
auto exeStr = processConfig.as_object().get("executable").as_string().wide();
|
||||
TraceLoggingWrite(
|
||||
g_Log_ETW_ComponentProvider,
|
||||
"ProcessesExecutableConfigdata",
|
||||
TraceLoggingWideString(exeStr, "processes_executable"),
|
||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));
|
||||
|
||||
if (auto fixups = processConfig.as_object().try_get("fixups"))
|
||||
{
|
||||
for (auto& fixupConfig : fixups->as_array())
|
||||
{
|
||||
auto dllStr = fixupConfig.as_object().try_get("dll")->as_string().wide();
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));
|
||||
|
||||
if (auto fixups = processConfig.as_object().try_get("fixups"))
|
||||
{
|
||||
for (auto& fixupConfig : fixups->as_array())
|
||||
{
|
||||
auto dllStr = fixupConfig.as_object().try_get("dll")->as_string().wide();
|
||||
TraceLoggingWrite(
|
||||
g_Log_ETW_ComponentProvider,
|
||||
"ProcessesFixUpConfigdata",
|
||||
TraceLoggingWideString(dllStr, "processes_fixups"),
|
||||
TraceLoggingBoolean(TRUE, "UTCReplace_AppSessionGuid"),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));
|
||||
}
|
||||
}
|
||||
}
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_CRITICAL_DATA));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
using EntryPointProc = void (CALLBACK *)(HWND, HINSTANCE, LPSTR, int);
|
||||
|
||||
int __stdcall WinMain(HINSTANCE, HINSTANCE, PSTR cmdLine, int cmdShow)
|
||||
int __stdcall WinMain(_In_ HINSTANCE, _In_ HINSTANCE, _In_opt_ PSTR cmdLine, _In_ int cmdShow)
|
||||
{
|
||||
// RUNDLL.EXE <dllname>,<entrypoint> <optional arguments>
|
||||
auto dllPath = cmdLine;
|
||||
|
|
|
@ -216,41 +216,41 @@ static struct
|
|||
|
||||
void Log(const char* fmt, ...)
|
||||
{
|
||||
std::string str;
|
||||
str.resize(256);
|
||||
std::string str;
|
||||
str.resize(256);
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::size_t count = std::vsnprintf(str.data(), str.size() + 1, fmt, args);
|
||||
assert(count >= 0);
|
||||
va_end(args);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
std::size_t count = std::vsnprintf(str.data(), str.size() + 1, fmt, args);
|
||||
assert(count >= 0);
|
||||
va_end(args);
|
||||
|
||||
if (count > str.size())
|
||||
{
|
||||
str.resize(count);
|
||||
if (count > str.size())
|
||||
{
|
||||
str.resize(count);
|
||||
|
||||
va_list args2;
|
||||
va_start(args2, fmt);
|
||||
count = std::vsnprintf(str.data(), str.size() + 1, fmt, args2);
|
||||
assert(count >= 0);
|
||||
va_end(args2);
|
||||
}
|
||||
va_list args2;
|
||||
va_start(args2, fmt);
|
||||
count = std::vsnprintf(str.data(), str.size() + 1, fmt, args2);
|
||||
assert(count >= 0);
|
||||
va_end(args2);
|
||||
}
|
||||
|
||||
str.resize(count);
|
||||
::OutputDebugStringA(str.c_str());
|
||||
str.resize(count);
|
||||
::OutputDebugStringA(str.c_str());
|
||||
}
|
||||
void LogString(const char* name, const char* value)
|
||||
{
|
||||
Log("\t%s=%s\n", name, value);
|
||||
Log("\t%s=%s\n", name, value);
|
||||
}
|
||||
void LogString(const char* name, const wchar_t* value)
|
||||
{
|
||||
Log("\t%s=%ls\n", name, value);
|
||||
Log("\t%s=%ls\n", name, value);
|
||||
}
|
||||
|
||||
void LogCountedStringW(const char* name, const wchar_t* value, std::size_t length)
|
||||
{
|
||||
Log("\t%s=%.*ls\n", name, length, value);
|
||||
Log("\t%s=%.*ls\n", name, length, value);
|
||||
}
|
||||
|
||||
static const psf::json_object* g_CurrentExeConfig = nullptr;
|
||||
|
@ -332,7 +332,7 @@ void LoadConfig()
|
|||
g_ApplicationUserModelId = psf::current_application_user_model_id();
|
||||
g_ApplicationId = psf::application_id_from_application_user_model_id(g_ApplicationUserModelId);
|
||||
g_PackageRootPath = psf::current_package_path();
|
||||
g_FinalPackageRootPath = psf::get_final_path_name(g_PackageRootPath);
|
||||
g_FinalPackageRootPath = psf::get_final_path_name(g_PackageRootPath);
|
||||
g_CurrentExecutable = psf::current_executable_path();
|
||||
|
||||
LogCountedStringW("g_PackageFullName", g_PackageFullName.data(), g_PackageFullName.length());
|
||||
|
@ -359,7 +359,7 @@ const std::wstring& PackageFullName() noexcept
|
|||
|
||||
const std::wstring& PackageFamilyName() noexcept
|
||||
{
|
||||
return g_PackageFamilyName;
|
||||
return g_PackageFamilyName;
|
||||
}
|
||||
|
||||
const std::wstring& ApplicationUserModelId() noexcept
|
||||
|
@ -400,7 +400,7 @@ PSFAPI const wchar_t* __stdcall PSFQueryPackageFullName() noexcept
|
|||
|
||||
PSFAPI const wchar_t* __stdcall PSFQueryPackageFamilyName() noexcept
|
||||
{
|
||||
return g_PackageFamilyName.c_str();
|
||||
return g_PackageFamilyName.c_str();
|
||||
}
|
||||
|
||||
PSFAPI const wchar_t* __stdcall PSFQueryApplicationUserModelId() noexcept
|
||||
|
@ -434,11 +434,13 @@ PSFAPI const psf::json_object* __stdcall PSFQueryAppLaunchConfig(_In_ const wcha
|
|||
{
|
||||
auto& appObj = app.as_object();
|
||||
auto appId = appObj.get("id").as_string().wstring();
|
||||
if (verbose)
|
||||
{
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
LogCountedStringW("Compare against json id", appId.data(), appId.length());
|
||||
}
|
||||
if (iwstring_view(appId.data(), appId.length()) == applicationId)
|
||||
|
||||
if (iwstring_view(appId.data(), appId.length()) == applicationId)
|
||||
{
|
||||
return &appObj;
|
||||
}
|
||||
|
@ -459,46 +461,45 @@ PSFAPI const psf::json_object* __stdcall PSFQueryCurrentAppLaunchConfig(bool ver
|
|||
return PSFQueryAppLaunchConfig(g_ApplicationId.c_str(), verbose);
|
||||
}
|
||||
|
||||
PSFAPI const psf::json_object* __stdcall PSFQueryAppMonitorConfig_try() noexcept try
|
||||
{
|
||||
const psf::json_object* application = PSFQueryAppLaunchConfig(g_ApplicationId.c_str(),false);
|
||||
auto& mon = application->get("monitor").as_object();
|
||||
auto& monObj = mon.as_object();
|
||||
|
||||
return &monObj;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
PSFAPI const psf::json_object* __stdcall PSFQueryAppMonitorConfig() noexcept
|
||||
{
|
||||
return PSFQueryAppMonitorConfig_try();
|
||||
}
|
||||
|
||||
PSFAPI const psf::json_object* __stdcall PSFQueryStartScriptInfo() noexcept try
|
||||
{
|
||||
const psf::json_object* application = PSFQueryAppLaunchConfig(g_ApplicationId.c_str(), false);
|
||||
auto& mon = application->get("startScript").as_object();
|
||||
auto& monObj = mon.as_object();
|
||||
auto mon = application->try_get("monitor");
|
||||
|
||||
if (mon)
|
||||
{
|
||||
auto& monObj = mon->as_object();
|
||||
return &monObj;
|
||||
}
|
||||
|
||||
return &monObj;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PSFAPI const psf::json_object* __stdcall PSFQueryEndScriptInfo() noexcept try
|
||||
PSFAPI const psf::json_object* __stdcall PSFQueryStartScriptInfo() noexcept
|
||||
{
|
||||
const psf::json_object* application = PSFQueryAppLaunchConfig(g_ApplicationId.c_str(), false);
|
||||
auto& mon = application->get("endScript").as_object();
|
||||
auto& monObj = mon.as_object();
|
||||
auto application = PSFQueryAppLaunchConfig(g_ApplicationId.c_str(), false);
|
||||
auto mon = application->try_get("startScript");
|
||||
|
||||
return &monObj;
|
||||
if (mon)
|
||||
{
|
||||
auto& monObj = mon->as_object();
|
||||
return &monObj;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
catch (...)
|
||||
|
||||
PSFAPI const psf::json_object* __stdcall PSFQueryEndScriptInfo() noexcept
|
||||
{
|
||||
auto application = PSFQueryAppLaunchConfig(g_ApplicationId.c_str(), false);
|
||||
auto mon = application->try_get("endScript");
|
||||
|
||||
if (mon)
|
||||
{
|
||||
auto& monObj = mon->as_object();
|
||||
return &monObj;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ BOOL WINAPI CreateProcessFixup(
|
|||
}
|
||||
}
|
||||
}
|
||||
Log("\tInject %ls into PID=%d\n", psf::runtime_dll_name, processInformation->dwProcessId);
|
||||
Log("\tInject %ls into PID=%d\n", psf::runtime_dll_name, processInformation->dwProcessId);
|
||||
|
||||
if ((creationFlags & CREATE_SUSPENDED) != CREATE_SUSPENDED)
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@ struct loaded_fixup
|
|||
swap(other);
|
||||
}
|
||||
|
||||
loaded_fixup& operator=(loaded_fixup&& other)
|
||||
loaded_fixup& operator=(loaded_fixup&& other) noexcept
|
||||
{
|
||||
swap(other);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ void load_fixups()
|
|||
throw_last_error(message.c_str());
|
||||
}
|
||||
}
|
||||
Log("\tInject into current process: %ls\n", path.c_str());
|
||||
Log("\tInject into current process: %ls\n", path.c_str());
|
||||
|
||||
auto initialize = reinterpret_cast<PSFInitializeProc>(::GetProcAddress(fixup.module_handle, "PSFInitialize"));
|
||||
if (!initialize)
|
||||
|
|
|
@ -48,6 +48,10 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CLRSupport>
|
||||
</CLRSupport>
|
||||
<UseOfMfc>
|
||||
</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
|
@ -67,39 +71,94 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>windowsapp.lib;wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>windowsapp.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<LinkTimeCodeGeneration Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</LinkTimeCodeGeneration>
|
||||
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Windows</SubSystem>
|
||||
<SubSystem Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Windows</SubSystem>
|
||||
<ImageHasSafeExceptionHandlers Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<OptimizeReferences Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</OptimizeReferences>
|
||||
<EnableCOMDATFolding Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<GenerateDebugInformation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_CRT_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_DEBUG;DEBUG;_CRT_SECURE_NO_WARNINGS;_WINDOWS;NOGDICAPMASKS;NOVIRTUALKEYCODES;NOWINSTYLES;NOSYSMETRICS;NOMENUS;NOICONS;NOKEYSTATES;NOSYSCOMMANDS;NORASTEROPS;NOSHOWWINDOW;OEMRESOURCE;NOATOM;NOCLIPBOARD;NOCOLOR;NODRAWTEXT;NOGDI;NOKERNEL;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOWH;NOWINOFFSETS;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\include</AdditionalIncludeDirectories>
|
||||
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">stdcpp17</LanguageStandard>
|
||||
<RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Level4</WarningLevel>
|
||||
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError>
|
||||
<DebugInformationFormat Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EditAndContinue</DebugInformationFormat>
|
||||
<SupportJustMyCode Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</SupportJustMyCode>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
|
||||
</ClCompile>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_CRT_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">_CRT_SECURE_NO_WARNINGS;_WINDOWS;NOGDICAPMASKS;NOVIRTUALKEYCODES;NOWINSTYLES;NOSYSMETRICS;NOMENUS;NOICONS;NOKEYSTATES;NOSYSCOMMANDS;NORASTEROPS;NOSHOWWINDOW;OEMRESOURCE;NOATOM;NOCLIPBOARD;NOCOLOR;NODRAWTEXT;NOGDI;NOKERNEL;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOWH;NOWINOFFSETS;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\include</AdditionalIncludeDirectories>
|
||||
<LanguageStandard Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">stdcpp17</LanguageStandard>
|
||||
<IntrinsicFunctions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</IntrinsicFunctions>
|
||||
<WholeProgramOptimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</WholeProgramOptimization>
|
||||
<FunctionLevelLinking Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</FunctionLevelLinking>
|
||||
<RuntimeLibrary Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Level4</WarningLevel>
|
||||
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</TreatWarningAsError>
|
||||
<MultiProcessorCompilation Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile />
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_DEBUG;DEBUG;_CRT_SECURE_NO_WARNINGS;_WINDOWS;NOGDICAPMASKS;NOVIRTUALKEYCODES;NOWINSTYLES;NOSYSMETRICS;NOMENUS;NOICONS;NOKEYSTATES;NOSYSCOMMANDS;NORASTEROPS;NOSHOWWINDOW;OEMRESOURCE;NOATOM;NOCLIPBOARD;NOCOLOR;NODRAWTEXT;NOGDI;NOKERNEL;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOWH;NOWINOFFSETS;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<SupportJustMyCode>true</SupportJustMyCode>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<OmitFramePointers>
|
||||
</OmitFramePointers>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile />
|
||||
<ClCompile />
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_WINDOWS;NOGDICAPMASKS;NOVIRTUALKEYCODES;NOWINSTYLES;NOSYSMETRICS;NOMENUS;NOICONS;NOKEYSTATES;NOSYSCOMMANDS;NORASTEROPS;NOSHOWWINDOW;OEMRESOURCE;NOATOM;NOCLIPBOARD;NOCOLOR;NODRAWTEXT;NOGDI;NOKERNEL;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOWH;NOWINOFFSETS;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;WIN32_LEAN_AND_MEAN;_SCL_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<OmitFramePointers>
|
||||
</OmitFramePointers>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<LinkTimeCodeGeneration>UseFastLinkTimeCodeGeneration</LinkTimeCodeGeneration>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
#include <Windows.h>
|
||||
#include <fileapifromapp.h>
|
||||
#include <sstream>
|
||||
|
||||
///
|
||||
// detectPipe
|
||||
|
@ -341,10 +340,10 @@ static wide_argument_string_with_buffer getLocalPipeName(LPCWSTR pipeName)
|
|||
if (detectPipe(pipeName))
|
||||
{
|
||||
std::wstring_view name(pipeName);
|
||||
std::wostringstream formattedPipe;
|
||||
std::wstring formattedPipe{ LR"(\\.\pipe\LOCAL\)" };
|
||||
// Stomp on the server name. In an app container, pipe name must be as follows
|
||||
formattedPipe << R"(\\.\pipe\LOCAL\)" << name.substr(uwpPipePrefixLen);
|
||||
return wide_argument_string_with_buffer{ formattedPipe.str() };
|
||||
formattedPipe.append(name.substr(uwpPipePrefixLen));
|
||||
return wide_argument_string_with_buffer{ formattedPipe };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -383,13 +383,13 @@ std::wstring GenerateRedirectedPath(std::wstring_view relativePath, bool ensureD
|
|||
/// <returns>The new absolute path.</returns>
|
||||
std::wstring RedirectedPath(const normalized_path& deVirtualizedPath, bool ensureDirectoryStructure)
|
||||
{
|
||||
//To prevent apps breaking on an upgrade we redirect writes to the package root path to
|
||||
//a path that contains the package family name and not the package full name.
|
||||
// To prevent apps breaking on an upgrade we redirect writes to the package root path to
|
||||
// a path that contains the package family name and not the package full name.
|
||||
std::wstring result;
|
||||
bool shouldredirectToPackageRoot = false;
|
||||
auto deVirtualizedFullPath = deVirtualizedPath.full_path;
|
||||
|
||||
//Lowercase the devirtualized full path because .find is case-sensitive.
|
||||
// Lowercase the devirtualized full path because .find is case-sensitive.
|
||||
transform(deVirtualizedFullPath.begin(), deVirtualizedFullPath.end(), deVirtualizedFullPath.begin(), towlower);
|
||||
|
||||
if (deVirtualizedFullPath.find(g_packageRootPath) != std::wstring::npos)
|
||||
|
|
|
@ -73,7 +73,7 @@ To make things simpler to understand, an example configuration object might look
|
|||
]
|
||||
},
|
||||
{
|
||||
"id": " {FDD39AD0-238F-46AF-ADB4-6C85480369C7}",
|
||||
"id": " {FDD39AD0-238F-46AF-ADB4-6C85480369C7}",
|
||||
"relativePaths": [
|
||||
{
|
||||
"base": "MyApplication",
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace psf
|
|||
|
||||
inline std::filesystem::path current_package_path()
|
||||
{
|
||||
//Use GetCurrentPackagePath2 if avalible
|
||||
// Use GetCurrentPackagePath2 if avalible
|
||||
std::wstring kernelDll = L"kernel.appcore.dll";
|
||||
HMODULE appModelDll = LoadLibraryEx(kernelDll.c_str(), nullptr, 0);
|
||||
|
||||
|
@ -140,7 +140,7 @@ namespace psf
|
|||
std::wstring result;
|
||||
if (getCurrentPackagePath2)
|
||||
{
|
||||
//If GetCurrentPackagePath 2 does exists
|
||||
// If GetCurrentPackagePath 2 does exists
|
||||
result = details::appmodel_string(getCurrentPackagePath2);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -12,7 +12,7 @@ enum class trace_method
|
|||
{
|
||||
printf,
|
||||
output_debug_string,
|
||||
eventlog,
|
||||
eventlog,
|
||||
};
|
||||
|
||||
enum class function_result
|
||||
|
@ -66,33 +66,33 @@ inline function_result from_win32(DWORD code)
|
|||
}
|
||||
inline std::string InterpretFrom_win32(DWORD code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
return "Success";
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
return "File not found";
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
return "Path not found";
|
||||
case ERROR_INVALID_NAME:
|
||||
return "Invalid Name";
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
return "Already exists";
|
||||
case ERROR_FILE_EXISTS:
|
||||
return "File exists";
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
return "Buffer overflow";
|
||||
case ERROR_MORE_DATA:
|
||||
return "More data";
|
||||
case ERROR_NO_MORE_ITEMS:
|
||||
return "No more items";
|
||||
case ERROR_NO_MORE_FILES:
|
||||
return "No more files";
|
||||
case ERROR_MOD_NOT_FOUND:
|
||||
return "Module not found";
|
||||
default:
|
||||
return "Unknown failure";
|
||||
}
|
||||
switch (code)
|
||||
{
|
||||
case ERROR_SUCCESS:
|
||||
return "Success";
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
return "File not found";
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
return "Path not found";
|
||||
case ERROR_INVALID_NAME:
|
||||
return "Invalid Name";
|
||||
case ERROR_ALREADY_EXISTS:
|
||||
return "Already exists";
|
||||
case ERROR_FILE_EXISTS:
|
||||
return "File exists";
|
||||
case ERROR_INSUFFICIENT_BUFFER:
|
||||
return "Buffer overflow";
|
||||
case ERROR_MORE_DATA:
|
||||
return "More data";
|
||||
case ERROR_NO_MORE_ITEMS:
|
||||
return "No more items";
|
||||
case ERROR_NO_MORE_FILES:
|
||||
return "No more files";
|
||||
case ERROR_MOD_NOT_FOUND:
|
||||
return "Module not found";
|
||||
default:
|
||||
return "Unknown failure";
|
||||
}
|
||||
}
|
||||
|
||||
inline function_result from_win32_bool(BOOL value)
|
||||
|
|
|
@ -121,7 +121,7 @@ BOOL __stdcall CreateProcessAsUserFixup(
|
|||
_Out_ LPPROCESS_INFORMATION processInformation)
|
||||
{
|
||||
LARGE_INTEGER TickStart, TickEnd;
|
||||
QueryPerformanceCounter(&TickStart);
|
||||
QueryPerformanceCounter(&TickStart);
|
||||
auto entry = LogFunctionEntry();
|
||||
auto result = CreateProcessAsUserImpl(token, applicationName, commandLine, processAttributes, threadAttributes, inheritHandles, creationFlags, environment, currentDirectory, startupInfo, processInformation);
|
||||
QueryPerformanceCounter(&TickEnd);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -31,67 +31,67 @@ inline void LogObjectAttributes(ULONG attributes)
|
|||
}
|
||||
inline std::string InterpretObjectAttributes(ULONG attributes)
|
||||
{
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex("Object Attributes", attributes);
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex("Object Attributes", attributes);
|
||||
|
||||
if (attributes)
|
||||
{
|
||||
sout << " (";
|
||||
const char* prefix = "";
|
||||
|
||||
if (IsFlagSet(attributes, OBJ_INHERIT))
|
||||
{
|
||||
sout << prefix << "OBJ_INHERIT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_PERMANENT))
|
||||
{
|
||||
sout << prefix << "OBJ_PERMANENT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_EXCLUSIVE))
|
||||
{
|
||||
sout << prefix << "OBJ_EXCLUSIVE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_CASE_INSENSITIVE))
|
||||
{
|
||||
sout << prefix << "OBJ_CASE_INSENSITIVE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_OPENIF))
|
||||
{
|
||||
sout << prefix << "OBJ_OPENIF";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_OPENLINK))
|
||||
{
|
||||
sout << prefix << "OBJ_OPENLINK";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_KERNEL_HANDLE))
|
||||
{
|
||||
sout << prefix << "OBJ_KERNEL_HANDLE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_FORCE_ACCESS_CHECK))
|
||||
{
|
||||
sout << prefix << "OBJ_FORCE_ACCESS_CHECK";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_IGNORE_IMPERSONATED_DEVICEMAP))
|
||||
{
|
||||
sout << prefix << "OBJ_IGNORE_IMPERSONATED_DEVICEMAP";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_DONT_REPARSE))
|
||||
{
|
||||
sout << prefix << "OBJ_DONT_REPARSE";
|
||||
prefix = " | ";
|
||||
}
|
||||
sout << ")";
|
||||
}
|
||||
return sout.str();
|
||||
if (attributes)
|
||||
{
|
||||
sout << " (";
|
||||
const char* prefix = "";
|
||||
|
||||
if (IsFlagSet(attributes, OBJ_INHERIT))
|
||||
{
|
||||
sout << prefix << "OBJ_INHERIT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_PERMANENT))
|
||||
{
|
||||
sout << prefix << "OBJ_PERMANENT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_EXCLUSIVE))
|
||||
{
|
||||
sout << prefix << "OBJ_EXCLUSIVE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_CASE_INSENSITIVE))
|
||||
{
|
||||
sout << prefix << "OBJ_CASE_INSENSITIVE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_OPENIF))
|
||||
{
|
||||
sout << prefix << "OBJ_OPENIF";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_OPENLINK))
|
||||
{
|
||||
sout << prefix << "OBJ_OPENLINK";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_KERNEL_HANDLE))
|
||||
{
|
||||
sout << prefix << "OBJ_KERNEL_HANDLE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_FORCE_ACCESS_CHECK))
|
||||
{
|
||||
sout << prefix << "OBJ_FORCE_ACCESS_CHECK";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_IGNORE_IMPERSONATED_DEVICEMAP))
|
||||
{
|
||||
sout << prefix << "OBJ_IGNORE_IMPERSONATED_DEVICEMAP";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(attributes, OBJ_DONT_REPARSE))
|
||||
{
|
||||
sout << prefix << "OBJ_DONT_REPARSE";
|
||||
prefix = " | ";
|
||||
}
|
||||
sout << ")";
|
||||
}
|
||||
return sout.str();
|
||||
}
|
||||
|
||||
inline void LogCreationDispositionInternal(ULONG creationDisposition)
|
||||
|
@ -108,26 +108,26 @@ inline void LogCreationDispositionInternal(ULONG creationDisposition)
|
|||
}
|
||||
inline std::string InterpretCreationDispositionInternal(ULONG creationDisposition)
|
||||
{
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex("Creation Disposition",creationDisposition);
|
||||
sout << " (";
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex("Creation Disposition",creationDisposition);
|
||||
sout << " (";
|
||||
|
||||
if (IsFlagEqual(creationDisposition, FILE_SUPERSEDE))
|
||||
sout << "FILE_SUPERSEDE";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_CREATE))
|
||||
sout << "FILE_CREATE";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OPEN))
|
||||
sout << "FILE_OPEN";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OPEN_IF))
|
||||
sout << "FILE_OPEN_IF";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OVERWRITE))
|
||||
sout << "FILE_OVERWRITE";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OVERWRITE_IF))
|
||||
sout << "FILE_OVERWRITE_IF";
|
||||
else
|
||||
sout << "Unknown";
|
||||
sout << ")";
|
||||
return sout.str();
|
||||
if (IsFlagEqual(creationDisposition, FILE_SUPERSEDE))
|
||||
sout << "FILE_SUPERSEDE";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_CREATE))
|
||||
sout << "FILE_CREATE";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OPEN))
|
||||
sout << "FILE_OPEN";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OPEN_IF))
|
||||
sout << "FILE_OPEN_IF";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OVERWRITE))
|
||||
sout << "FILE_OVERWRITE";
|
||||
else if (IsFlagEqual(creationDisposition, FILE_OVERWRITE_IF))
|
||||
sout << "FILE_OVERWRITE_IF";
|
||||
else
|
||||
sout << "Unknown";
|
||||
sout << ")";
|
||||
return sout.str();
|
||||
}
|
||||
|
||||
inline void LogFileCreateOptions(ULONG options)
|
||||
|
@ -165,138 +165,138 @@ inline void LogFileCreateOptions(ULONG options)
|
|||
}
|
||||
inline std::string InterpretFileCreateOptions(ULONG options)
|
||||
{
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex("Options", options);
|
||||
if (options)
|
||||
{
|
||||
sout << " (";
|
||||
const char* prefix = "";
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex("Options", options);
|
||||
if (options)
|
||||
{
|
||||
sout << " (";
|
||||
const char* prefix = "";
|
||||
|
||||
if (IsFlagSet(options, FILE_DIRECTORY_FILE))
|
||||
{
|
||||
sout << prefix << "FILE_DIRECTORY_FILE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NON_DIRECTORY_FILE))
|
||||
{
|
||||
sout << prefix << "FILE_NON_DIRECTORY_FILE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_WRITE_THROUGH))
|
||||
{
|
||||
sout << prefix << "FILE_WRITE_THROUGH";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SEQUENTIAL_ONLY))
|
||||
{
|
||||
sout << prefix << "FILE_SEQUENTIAL_ONLY";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NO_INTERMEDIATE_BUFFERING))
|
||||
{
|
||||
sout << prefix << "FILE_NO_INTERMEDIATE_BUFFERING";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SYNCHRONOUS_IO_ALERT))
|
||||
{
|
||||
sout << prefix << "FILE_SYNCHRONOUS_IO_ALERT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SYNCHRONOUS_IO_NONALERT))
|
||||
{
|
||||
sout << prefix << "FILE_SYNCHRONOUS_IO_NONALERT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_CREATE_TREE_CONNECTION))
|
||||
{
|
||||
sout << prefix << "FILE_CREATE_TREE_CONNECTION";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_COMPLETE_IF_OPLOCKED))
|
||||
{
|
||||
sout << prefix << "FILE_COMPLETE_IF_OPLOCKED";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NO_EA_KNOWLEDGE))
|
||||
{
|
||||
sout << prefix << "FILE_NO_EA_KNOWLEDGE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_REMOTE_INSTANCE))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_REMOTE_INSTANCE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_RANDOM_ACCESS))
|
||||
{
|
||||
sout << prefix << "FILE_RANDOM_ACCESS";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_DELETE_ON_CLOSE))
|
||||
{
|
||||
sout << prefix << "FILE_DELETE_ON_CLOSE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_BY_FILE_ID))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_BY_FILE_ID";
|
||||
prefix = " | ";
|
||||
};
|
||||
if (IsFlagSet(options, FILE_OPEN_FOR_BACKUP_INTENT))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_FOR_BACKUP_INTENT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NO_COMPRESSION))
|
||||
{
|
||||
sout << prefix << "FILE_NO_COMPRESSION";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_REQUIRING_OPLOCK))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_REQUIRING_OPLOCK";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SUPPORTS_ENCRYPTION))
|
||||
{
|
||||
sout << prefix << "FILE_SUPPORTS_ENCRYPTION";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NAMED_STREAMS))
|
||||
{
|
||||
sout << prefix << "FILE_NAMED_STREAMS";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_READ_ONLY_VOLUME))
|
||||
{
|
||||
sout << prefix << "FILE_READ_ONLY_VOLUME";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_DIRECTORY_FILE))
|
||||
{
|
||||
sout << prefix << "FILE_DIRECTORY_FILE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NON_DIRECTORY_FILE))
|
||||
{
|
||||
sout << prefix << "FILE_NON_DIRECTORY_FILE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_WRITE_THROUGH))
|
||||
{
|
||||
sout << prefix << "FILE_WRITE_THROUGH";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SEQUENTIAL_ONLY))
|
||||
{
|
||||
sout << prefix << "FILE_SEQUENTIAL_ONLY";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NO_INTERMEDIATE_BUFFERING))
|
||||
{
|
||||
sout << prefix << "FILE_NO_INTERMEDIATE_BUFFERING";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SYNCHRONOUS_IO_ALERT))
|
||||
{
|
||||
sout << prefix << "FILE_SYNCHRONOUS_IO_ALERT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SYNCHRONOUS_IO_NONALERT))
|
||||
{
|
||||
sout << prefix << "FILE_SYNCHRONOUS_IO_NONALERT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_CREATE_TREE_CONNECTION))
|
||||
{
|
||||
sout << prefix << "FILE_CREATE_TREE_CONNECTION";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_COMPLETE_IF_OPLOCKED))
|
||||
{
|
||||
sout << prefix << "FILE_COMPLETE_IF_OPLOCKED";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NO_EA_KNOWLEDGE))
|
||||
{
|
||||
sout << prefix << "FILE_NO_EA_KNOWLEDGE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_REMOTE_INSTANCE))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_REMOTE_INSTANCE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_RANDOM_ACCESS))
|
||||
{
|
||||
sout << prefix << "FILE_RANDOM_ACCESS";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_DELETE_ON_CLOSE))
|
||||
{
|
||||
sout << prefix << "FILE_DELETE_ON_CLOSE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_BY_FILE_ID))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_BY_FILE_ID";
|
||||
prefix = " | ";
|
||||
};
|
||||
if (IsFlagSet(options, FILE_OPEN_FOR_BACKUP_INTENT))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_FOR_BACKUP_INTENT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NO_COMPRESSION))
|
||||
{
|
||||
sout << prefix << "FILE_NO_COMPRESSION";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_REQUIRING_OPLOCK))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_REQUIRING_OPLOCK";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_SUPPORTS_ENCRYPTION))
|
||||
{
|
||||
sout << prefix << "FILE_SUPPORTS_ENCRYPTION";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_NAMED_STREAMS))
|
||||
{
|
||||
sout << prefix << "FILE_NAMED_STREAMS";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_READ_ONLY_VOLUME))
|
||||
{
|
||||
sout << prefix << "FILE_READ_ONLY_VOLUME";
|
||||
prefix = " | ";
|
||||
}
|
||||
|
||||
if (IsFlagSet(options, FILE_RESERVE_OPFILTER))
|
||||
{
|
||||
sout << prefix << "FILE_RESERVE_OPFILTER";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_REPARSE_POINT))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_REPARSE_POINT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_NO_RECALL))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_NO_RECALL";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_FOR_FREE_SPACE_QUERY))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_FOR_FREE_SPACE_QUERY";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_RESERVE_OPFILTER))
|
||||
{
|
||||
sout << prefix << "FILE_RESERVE_OPFILTER";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_REPARSE_POINT))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_REPARSE_POINT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_NO_RECALL))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_NO_RECALL";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(options, FILE_OPEN_FOR_FREE_SPACE_QUERY))
|
||||
{
|
||||
sout << prefix << "FILE_OPEN_FOR_FREE_SPACE_QUERY";
|
||||
prefix = " | ";
|
||||
}
|
||||
|
||||
sout << ")";
|
||||
}
|
||||
return sout.str();
|
||||
sout << ")";
|
||||
}
|
||||
return sout.str();
|
||||
}
|
||||
|
||||
inline void LogDirectoryAccessInternal(ACCESS_MASK access, const char* msg = "Access")
|
||||
|
@ -328,47 +328,47 @@ inline void LogDirectoryAccessInternal(ACCESS_MASK access, const char* msg = "Ac
|
|||
}
|
||||
inline std::string InterpretDirectoryAccessInternal(ACCESS_MASK access, const char* msg = "Access")
|
||||
{
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex(msg, access);
|
||||
if (access)
|
||||
{
|
||||
// NOTE: Only documented; definitions don't exist anywhere
|
||||
constexpr ACCESS_MASK DIRECTORY_QUERY = 0x0001;
|
||||
constexpr ACCESS_MASK DIRECTORY_TRAVERSE = 0x0002;
|
||||
constexpr ACCESS_MASK DIRECTORY_CREATE_OBJECT = 0x0004;
|
||||
constexpr ACCESS_MASK DIRECTORY_CREATE_SUBDIRECTORY = 0x0008;
|
||||
std::ostringstream sout;
|
||||
sout << InterpretAsHex(msg, access);
|
||||
if (access)
|
||||
{
|
||||
// NOTE: Only documented; definitions don't exist anywhere
|
||||
constexpr ACCESS_MASK DIRECTORY_QUERY = 0x0001;
|
||||
constexpr ACCESS_MASK DIRECTORY_TRAVERSE = 0x0002;
|
||||
constexpr ACCESS_MASK DIRECTORY_CREATE_OBJECT = 0x0004;
|
||||
constexpr ACCESS_MASK DIRECTORY_CREATE_SUBDIRECTORY = 0x0008;
|
||||
|
||||
const char* prefix = "";
|
||||
sout << " (";
|
||||
const char* prefix = "";
|
||||
sout << " (";
|
||||
|
||||
// Specific rights
|
||||
if (IsFlagSet(access, DIRECTORY_QUERY))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_QUERY";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(access, DIRECTORY_TRAVERSE))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_TRAVERSE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(access, DIRECTORY_CREATE_OBJECT))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_CREATE_OBJECT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(access, DIRECTORY_CREATE_SUBDIRECTORY))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_CREATE_SUBDIRECTORY";
|
||||
prefix = " | ";
|
||||
}
|
||||
// Specific rights
|
||||
if (IsFlagSet(access, DIRECTORY_QUERY))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_QUERY";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(access, DIRECTORY_TRAVERSE))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_TRAVERSE";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(access, DIRECTORY_CREATE_OBJECT))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_CREATE_OBJECT";
|
||||
prefix = " | ";
|
||||
}
|
||||
if (IsFlagSet(access, DIRECTORY_CREATE_SUBDIRECTORY))
|
||||
{
|
||||
sout << prefix << "DIRECTORY_CREATE_SUBDIRECTORY";
|
||||
prefix = " | ";
|
||||
}
|
||||
|
||||
sout << InterpretCommonAccess(access, prefix);
|
||||
sout << InterpretCommonAccess(access, prefix);
|
||||
|
||||
sout << ")";
|
||||
}
|
||||
sout << ")";
|
||||
}
|
||||
|
||||
return sout.str();
|
||||
return sout.str();
|
||||
}
|
||||
|
||||
inline void LogUnicodeString(const char* msg, const PUNICODE_STRING string)
|
||||
|
@ -383,14 +383,13 @@ inline void LogUnicodeString(const char* msg, const PUNICODE_STRING string)
|
|||
}
|
||||
inline std::string InterpretUnicodeString(const char* msg, const PUNICODE_STRING string)
|
||||
{
|
||||
std::ostringstream olog;
|
||||
|
||||
if (string->Buffer)
|
||||
//olog << msg << "=" << string->Buffer;
|
||||
olog << InterpretCountedString(msg, string->Buffer, string->Length / 2);
|
||||
else
|
||||
olog << msg << "=";
|
||||
return olog.str();
|
||||
std::ostringstream olog;
|
||||
|
||||
if (string->Buffer)
|
||||
olog << InterpretCountedString(msg, string->Buffer, string->Length / 2);
|
||||
else
|
||||
olog << msg << "=";
|
||||
return olog.str();
|
||||
}
|
||||
|
||||
inline bool TryGetDirectoryPath(HANDLE dir, std::wstring& result)
|
||||
|
@ -442,38 +441,38 @@ inline void LogObjectAttributes(POBJECT_ATTRIBUTES objectAttributes)
|
|||
}
|
||||
inline std::string InterpretObjectAttributes(POBJECT_ATTRIBUTES objectAttributes)
|
||||
{
|
||||
std::ostringstream olog;
|
||||
std::ostringstream olog;
|
||||
|
||||
// Get the root directory/registry/etc. path that the ObjectName is relative to
|
||||
std::wstring rootDir;
|
||||
if (objectAttributes->RootDirectory && (objectAttributes->RootDirectory != INVALID_HANDLE_VALUE))
|
||||
{
|
||||
TryGetDirectoryPath(objectAttributes->RootDirectory, rootDir) ||
|
||||
TryGetKeyPath(objectAttributes->RootDirectory, rootDir);
|
||||
}
|
||||
// Get the root directory/registry/etc. path that the ObjectName is relative to
|
||||
std::wstring rootDir;
|
||||
if (objectAttributes->RootDirectory && (objectAttributes->RootDirectory != INVALID_HANDLE_VALUE))
|
||||
{
|
||||
TryGetDirectoryPath(objectAttributes->RootDirectory, rootDir) ||
|
||||
TryGetKeyPath(objectAttributes->RootDirectory, rootDir);
|
||||
}
|
||||
|
||||
olog << InterpretUnicodeString("Path", objectAttributes->ObjectName);
|
||||
if (!rootDir.empty())
|
||||
olog << "\nRoot=" << InterpretStringA(rootDir.c_str());
|
||||
olog << "\n" << InterpretObjectAttributes(objectAttributes->Attributes);
|
||||
return olog.str();
|
||||
olog << InterpretUnicodeString("Path", objectAttributes->ObjectName);
|
||||
if (!rootDir.empty())
|
||||
olog << "\nRoot=" << InterpretStringA(rootDir.c_str());
|
||||
olog << "\n" << InterpretObjectAttributes(objectAttributes->Attributes);
|
||||
return olog.str();
|
||||
}
|
||||
|
||||
inline std::string InterpretKeyValueInformationClass(winternl::KEY_VALUE_INFORMATION_CLASS infoclass)
|
||||
{
|
||||
switch (infoclass)
|
||||
{
|
||||
case winternl::KeyValueBasicInformation:
|
||||
return "KeyValueBasicInformation";
|
||||
case winternl::KeyValueFullInformation:
|
||||
return "KeyValueFullInformation";
|
||||
case winternl::KeyValueFullInformationAlign64:
|
||||
return "KeyValueFullInformationAlign64";
|
||||
case winternl::KeyValuePartialInformation:
|
||||
return "KeyValuePartialInformation";
|
||||
case winternl::KeyValuePartialInformationAlign64:
|
||||
return "KeyValuePartialInformationAlign64";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
switch (infoclass)
|
||||
{
|
||||
case winternl::KeyValueBasicInformation:
|
||||
return "KeyValueBasicInformation";
|
||||
case winternl::KeyValueFullInformation:
|
||||
return "KeyValueFullInformation";
|
||||
case winternl::KeyValueFullInformationAlign64:
|
||||
return "KeyValueFullInformationAlign64";
|
||||
case winternl::KeyValuePartialInformation:
|
||||
return "KeyValuePartialInformation";
|
||||
case winternl::KeyValuePartialInformationAlign64:
|
||||
return "KeyValuePartialInformationAlign64";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче