Changed project names
This commit is contained in:
parent
b4c4aa4010
commit
a29e57e66d
130 changed files with 501 additions and 504 deletions
239
Common/AmagnoVirtualPrinter.Utils/Win32Sys.cs
Normal file
239
Common/AmagnoVirtualPrinter.Utils/Win32Sys.cs
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.ConstrainedExecution;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
using JetBrains.Annotations;
|
||||
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
|
||||
namespace AmagnoVirtualPrinter.Utils
|
||||
{
|
||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||
[SuppressMessage("ReSharper", "FieldCanBeMadeReadOnly.Global")]
|
||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
||||
[SuppressMessage("ReSharper", "ClassNeverInstantiated.Global")]
|
||||
internal static class Win32Sys
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates process with given command line via Win32 API.
|
||||
/// Use this method to start a process as a service.
|
||||
/// </summary>
|
||||
/// <param name="sessId"></param>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="commandLine"></param>
|
||||
internal static void CreateProcessAsUser(int sessId, string user, string commandLine)
|
||||
{
|
||||
WTSQueryUserToken((uint) sessId, out var userToken);
|
||||
if (userToken.IsInvalid)
|
||||
{
|
||||
throw new InvalidOperationException($"Could not query user token for session {sessId}! (" + GetLastError() + ")",
|
||||
Windows.LastError);
|
||||
}
|
||||
|
||||
CreateProcessAsUser(userToken, user, commandLine);
|
||||
}
|
||||
|
||||
private static void CreateProcessAsUser([NotNull]SafeTokenHandle token, string user, string commandLine)
|
||||
{
|
||||
var processInformation = new PROCESS_INFORMATION();
|
||||
try
|
||||
{
|
||||
var securityAttributes = new SECURITY_ATTRIBUTES();
|
||||
securityAttributes.Length = Marshal.SizeOf(securityAttributes);
|
||||
|
||||
var startupInfo = new STARTUPINFO();
|
||||
startupInfo.cb = Marshal.SizeOf(startupInfo);
|
||||
startupInfo.lpDesktop = "winsta0\\default";
|
||||
|
||||
var info = new ProfileInfo();
|
||||
info.dwSize = Marshal.SizeOf(info);
|
||||
info.lpUserName = user;
|
||||
info.dwFlags = 1;
|
||||
|
||||
var result = LoadUserProfile(token, ref info);
|
||||
if (!result)
|
||||
{
|
||||
throw Windows.LastError;
|
||||
}
|
||||
|
||||
result = CreateEnvironmentBlock(out var lpEnvironment, token, false);
|
||||
if (!result)
|
||||
{
|
||||
throw Windows.LastError;
|
||||
}
|
||||
|
||||
result = CreateProcessAsUser
|
||||
(
|
||||
token,
|
||||
null,
|
||||
commandLine,
|
||||
ref securityAttributes,
|
||||
ref securityAttributes,
|
||||
false,
|
||||
0x00000400,
|
||||
lpEnvironment,
|
||||
null,
|
||||
ref startupInfo,
|
||||
ref processInformation
|
||||
);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
throw Windows.LastError;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (processInformation.hProcess != IntPtr.Zero)
|
||||
{
|
||||
CloseMyHandle(processInformation.hProcess);
|
||||
}
|
||||
|
||||
if (processInformation.hThread != IntPtr.Zero)
|
||||
{
|
||||
CloseMyHandle(processInformation.hThread);
|
||||
}
|
||||
|
||||
if (!token.IsInvalid)
|
||||
{
|
||||
token.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Classes
|
||||
|
||||
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
|
||||
{
|
||||
private SafeTokenHandle() : base(true)
|
||||
{
|
||||
}
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool CloseHandle(IntPtr handle);
|
||||
|
||||
protected override bool ReleaseHandle()
|
||||
{
|
||||
return CloseHandle(handle);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{handle}";
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Structures
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct PROCESS_INFORMATION
|
||||
{
|
||||
public IntPtr hProcess;
|
||||
public IntPtr hThread;
|
||||
public int dwProcessID;
|
||||
public int dwThreadID;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct STARTUPINFO
|
||||
{
|
||||
public int cb;
|
||||
public string lpReserved;
|
||||
public string lpDesktop;
|
||||
public string lpTitle;
|
||||
public int dwX;
|
||||
public int dwY;
|
||||
public int dwXSize;
|
||||
public int dwXCountChars;
|
||||
public int dwYCountChars;
|
||||
public int dwFillAttribute;
|
||||
public int dwFlags;
|
||||
public short wShowWindow;
|
||||
public short cbReserved2;
|
||||
public IntPtr lpReserved2;
|
||||
public IntPtr hStdInput;
|
||||
public IntPtr hStdOutput;
|
||||
public IntPtr hStdError;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ProfileInfo
|
||||
{
|
||||
public int dwSize;
|
||||
public int dwFlags;
|
||||
public string lpUserName;
|
||||
public string lpProfilePath;
|
||||
public string lpDefaultPath;
|
||||
public string lpServerName;
|
||||
public string lpPolicyPath;
|
||||
public IntPtr hProfile;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
public int Length;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
public bool bInheritHandle;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Windows interop
|
||||
|
||||
[DllImport("userenv.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern bool LoadUserProfile(SafeTokenHandle hToken, ref ProfileInfo lpProfileInfo);
|
||||
|
||||
[DllImport("userenv.dll", SetLastError = true)]
|
||||
private static extern bool CreateEnvironmentBlock(out IntPtr lpEnvironment,
|
||||
SafeTokenHandle hToken, bool bInherit);
|
||||
|
||||
[DllImport("kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true,
|
||||
CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern bool CloseMyHandle(IntPtr handle);
|
||||
|
||||
[DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true,
|
||||
CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
|
||||
private static extern bool CreateProcessAsUser(SafeTokenHandle hToken,
|
||||
string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
|
||||
ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle,
|
||||
int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
|
||||
ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation);
|
||||
|
||||
[DllImport("wtsapi32.dll", SetLastError = true)]
|
||||
private static extern bool WTSQueryUserToken(uint sessionId, out SafeTokenHandle Token);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint GetLastError();
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public static extern int GetPrivateProfileString
|
||||
(
|
||||
string section,
|
||||
string key,
|
||||
string def,
|
||||
StringBuilder retVal,
|
||||
int size,
|
||||
string filePath
|
||||
);
|
||||
|
||||
[DllImport("kernel32")]
|
||||
public static extern long WritePrivateProfileString
|
||||
(
|
||||
string section,
|
||||
string key,
|
||||
string val,
|
||||
string filePath
|
||||
);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue