This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Runtime.InteropServices; | |
namespace StandardActivator | |
{ | |
enum RUNLEVEL : uint | |
{ | |
RUNLEVEL_LUA = 0x0, | |
RUNLEVEL_HIGHEST = 0x1, | |
RUNLEVEL_ADMIN = 0x2, | |
RUNLEVEL_MAX_NON_UIA = 0x3, | |
RUNLEVEL_LUA_UIA = 0x10, | |
RUNLEVEL_HIGHEST_UIA = 0x11, | |
RUNLEVEL_ADMIN_UIA = 0x12, | |
RUNLEVEL_MAX = 0x13, | |
INVALID_LUA_RUNLEVEL = 0xFFFFFFFF, | |
}; | |
enum PRT | |
{ | |
PRT_IGNORE = 0x0, | |
PRT_CREATE_NEW = 0x1, | |
PRT_USE_THIS = 0x2, | |
PRT_USE_THIS_ONLY = 0x3, | |
}; | |
[Guid("000001B9-0000-0000-c000-000000000046")] | |
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
interface ISpecialSystemPropertiesActivator | |
{ | |
void SetSessionId(int dwSessionId, int bUseConsole, int fRemoteThisSessionId); | |
void GetSessionId(out int pdwSessionId, out int pbUseConsole); | |
void GetSessionId2(out int pdwSessionId, out int pbUseConsole, out int pfRemoteThisSessionId); | |
void SetClientImpersonating(int fClientImpersonating); | |
void GetClientImpersonating(out int pfClientImpersonating); | |
void SetPartitionId(ref Guid guidPartition); | |
void GetPartitionId(out Guid pguidPartition); | |
void SetProcessRequestType(PRT dwPRT); | |
void GetProcessRequestType(out PRT pdwPRT); | |
void SetOrigClsctx(int dwOrigClsctx); | |
void GetOrigClsctx(out int pdwOrigClsctx); | |
void GetDefaultAuthenticationLevel(out int pdwDefaultAuthnLvl); | |
void SetDefaultAuthenticationLevel(int dwDefaultAuthnLvl); | |
void GetLUARunLevel(out RUNLEVEL pdwLUARunLevel, out IntPtr phwnd); | |
void SetLUARunLevel(RUNLEVEL dwLUARunLevel, IntPtr hwnd); | |
} | |
[Flags] | |
public enum CLSCTX : uint | |
{ | |
INPROC_SERVER = 0x1, | |
INPROC_HANDLER = 0x2, | |
LOCAL_SERVER = 0x4, | |
INPROC_SERVER16 = 0x8, | |
REMOTE_SERVER = 0x10, | |
INPROC_HANDLER16 = 0x20, | |
RESERVED1 = 0x40, | |
RESERVED2 = 0x80, | |
RESERVED3 = 0x100, | |
RESERVED4 = 0x200, | |
NO_CODE_DOWNLOAD = 0x400, | |
RESERVED5 = 0x800, | |
NO_CUSTOM_MARSHAL = 0x1000, | |
ENABLE_CODE_DOWNLOAD = 0x2000, | |
NO_FAILURE_LOG = 0x4000, | |
DISABLE_AAA = 0x8000, | |
ENABLE_AAA = 0x10000, | |
FROM_DEFAULT_CONTEXT = 0x20000, | |
ACTIVATE_32_BIT_SERVER = 0x40000, | |
ACTIVATE_64_BIT_SERVER = 0x80000, | |
ENABLE_CLOAKING = 0x100000, | |
APPCONTAINER = 0x400000, | |
ACTIVATE_AAA_AS_IU = 0x800000, | |
ACTIVATE_NATIVE_SERVER = 0x1000000, | |
ACTIVATE_ARM32_SERVER = 0x2000000, | |
PS_DLL = 0x80000000, | |
SERVER = INPROC_SERVER | LOCAL_SERVER | REMOTE_SERVER, | |
ALL = INPROC_SERVER | INPROC_HANDLER | LOCAL_SERVER | REMOTE_SERVER | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct OptionalGuid : IDisposable | |
{ | |
IntPtr pGuid; | |
void IDisposable.Dispose() | |
{ | |
if (pGuid != IntPtr.Zero) | |
{ | |
Marshal.FreeCoTaskMem(pGuid); | |
pGuid = IntPtr.Zero; | |
} | |
} | |
public OptionalGuid(Guid guid) | |
{ | |
pGuid = Marshal.AllocCoTaskMem(16); | |
Marshal.Copy(guid.ToByteArray(), 0, pGuid, 16); | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct MULTI_QI : IDisposable | |
{ | |
OptionalGuid pIID; | |
IntPtr pItf; | |
int hr; | |
public object GetObject() | |
{ | |
if (pItf == IntPtr.Zero) | |
{ | |
return null; | |
} | |
else | |
{ | |
return Marshal.GetObjectForIUnknown(pItf); | |
} | |
} | |
public IntPtr GetObjectPointer() | |
{ | |
if (pItf != IntPtr.Zero) | |
{ | |
Marshal.AddRef(pItf); | |
} | |
return pItf; | |
} | |
public int HResult() | |
{ | |
return hr; | |
} | |
void IDisposable.Dispose() | |
{ | |
((IDisposable)pIID).Dispose(); | |
if (pItf != IntPtr.Zero) | |
{ | |
Marshal.Release(pItf); | |
pItf = IntPtr.Zero; | |
} | |
} | |
public MULTI_QI(Guid iid) | |
{ | |
pIID = new OptionalGuid(iid); | |
pItf = IntPtr.Zero; | |
hr = 0; | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public sealed class COSERVERINFO : IDisposable | |
{ | |
int dwReserved1; | |
[MarshalAs(UnmanagedType.LPWStr)] | |
string pwszName; | |
IntPtr pAuthInfo; | |
int dwReserved2; | |
void IDisposable.Dispose() | |
{ | |
if (pAuthInfo != IntPtr.Zero) | |
{ | |
Marshal.FreeCoTaskMem(pAuthInfo); | |
} | |
} | |
public COSERVERINFO(string name) | |
{ | |
pwszName = name; | |
} | |
} | |
[Guid("000001B8-0000-0000-c000-000000000046")] | |
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
interface IStandardActivator | |
{ | |
void StandardGetClassObject(in Guid rclsid, CLSCTX dwContext, [In] COSERVERINFO pServerInfo, in Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppvClassObj); | |
void StandardCreateInstance(in Guid Clsid, IntPtr punkOuter, CLSCTX dwClsCtx, [In] COSERVERINFO pServerInfo, int dwCount, [In, Out][MarshalAs(UnmanagedType.LPArray)] MULTI_QI[] pResults); | |
void StandardGetInstanceFromFile([In] COSERVERINFO pServerInfo, in Guid pclsidOverride, | |
IntPtr punkOuter, CLSCTX dwClsCtx, int grfMode, [MarshalAs(UnmanagedType.LPWStr)] string pwszName, int dwCount, [In, Out] [MarshalAs(UnmanagedType.LPArray)] MULTI_QI[] pResults); | |
void StandardGetInstanceFromIStorage([In] COSERVERINFO pServerInfo, in Guid pclsidOverride, | |
IntPtr punkOuter, CLSCTX dwClsCtx, IntPtr /*IStorage* */ pstg, int dwCount, [In, Out][MarshalAs(UnmanagedType.LPArray)] MULTI_QI[] pResults); | |
void Reset(); | |
} | |
[Flags] | |
enum STGM | |
{ | |
READ = 0x00000000, | |
WRITE = 0x00000001, | |
READWRITE = 0x00000002, | |
SHARE_DENY_NONE = 0x00000040, | |
SHARE_DENY_READ = 0x00000030, | |
SHARE_DENY_WRITE = 0x00000020, | |
SHARE_EXCLUSIVE = 0x00000010, | |
PRIORITY = 0x00040000, | |
CREATE = 0x00001000, | |
CONVERT = 0x00020000, | |
FAILIFTHERE = READ, | |
DIRECT = READ, | |
TRANSACTED = 0x00010000, | |
NOSCRATCH = 0x00100000, | |
NOSNAPSHOT = 0x00200000, | |
SIMPLE = 0x08000000, | |
DIRECT_SWMR = 0x00400000, | |
DELETEONRELEASE = 0x04000000 | |
} | |
enum STGFMT | |
{ | |
Storage = 0, | |
File = 3, | |
Any = 4, | |
Docfile = 5 | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
class STGOPTIONS | |
{ | |
public short usVersion; | |
public short reserved; | |
public int ulSectorSize; | |
[MarshalAs(UnmanagedType.LPWStr)] | |
public string pwcsTemplateFile; | |
} | |
class Program | |
{ | |
[DllImport("ole32.dll", CharSet = CharSet.Unicode, PreserveSig = false)] | |
public static extern IntPtr StgCreateStorageEx( | |
string pwcsName, | |
STGM grfMode, | |
STGFMT stgfmt, | |
int grfAttrs, | |
[In] STGOPTIONS pStgOptions, | |
IntPtr pSecurityDescriptor, | |
ref Guid riid | |
); | |
[Guid("0000033C-0000-0000-c000-000000000046")] | |
[ComImport] | |
class StandardActivator | |
{ | |
} | |
enum EOLE_AUTHENTICATION_CAPABILITIES | |
{ | |
EOAC_NONE = 0, | |
EOAC_MUTUAL_AUTH = 0x1, | |
EOAC_STATIC_CLOAKING = 0x20, | |
EOAC_DYNAMIC_CLOAKING = 0x40, | |
EOAC_ANY_AUTHORITY = 0x80, | |
EOAC_MAKE_FULLSIC = 0x100, | |
EOAC_DEFAULT = 0x800, | |
EOAC_SECURE_REFS = 0x2, | |
EOAC_ACCESS_CONTROL = 0x4, | |
EOAC_APPID = 0x8, | |
EOAC_DYNAMIC = 0x10, | |
EOAC_REQUIRE_FULLSIC = 0x200, | |
EOAC_AUTO_IMPERSONATE = 0x400, | |
EOAC_NO_CUSTOM_MARSHAL = 0x2000, | |
EOAC_DISABLE_AAA = 0x1000 | |
} | |
enum AuthnLevel | |
{ | |
RPC_C_AUTHN_LEVEL_DEFAULT = 0, | |
RPC_C_AUTHN_LEVEL_NONE = 1, | |
RPC_C_AUTHN_LEVEL_CONNECT = 2, | |
RPC_C_AUTHN_LEVEL_CALL = 3, | |
RPC_C_AUTHN_LEVEL_PKT = 4, | |
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5, | |
RPC_C_AUTHN_LEVEL_PKT_PRIVACY = 6 | |
} | |
enum ImpLevel | |
{ | |
RPC_C_IMP_LEVEL_DEFAULT = 0, | |
RPC_C_IMP_LEVEL_ANONYMOUS = 1, | |
RPC_C_IMP_LEVEL_IDENTIFY = 2, | |
RPC_C_IMP_LEVEL_IMPERSONATE = 3, | |
RPC_C_IMP_LEVEL_DELEGATE = 4, | |
} | |
[DllImport("ole32.dll")] | |
static extern int CoInitializeSecurity( | |
IntPtr pSecDesc, | |
int cAuthSvc, | |
IntPtr asAuthSvc, | |
IntPtr pReserved1, | |
AuthnLevel dwAuthnLevel, | |
ImpLevel dwImpLevel, | |
IntPtr pAuthList, | |
EOLE_AUTHENTICATION_CAPABILITIES dwCapabilities, | |
IntPtr pReserved3 | |
); | |
// Run here to ensure it's called before the main thread. | |
static readonly int _security_init = CoInitializeSecurity(IntPtr.Zero, -1, IntPtr.Zero, IntPtr.Zero, | |
AuthnLevel.RPC_C_AUTHN_LEVEL_DEFAULT, ImpLevel.RPC_C_IMP_LEVEL_IMPERSONATE, IntPtr.Zero, | |
EOLE_AUTHENTICATION_CAPABILITIES.EOAC_DYNAMIC_CLOAKING, IntPtr.Zero); | |
static IntPtr CreateStorage(string name, STGM mode, STGFMT format) | |
{ | |
Guid iid = new Guid("0000000B-0000-0000-C000-000000000046"); | |
return StgCreateStorageEx(name, mode, format, 0, null, IntPtr.Zero, ref iid); | |
} | |
[STAThread] | |
static void Main(string[] args) | |
{ | |
try | |
{ | |
string path = Path.GetDirectoryName(typeof(Program).Assembly.Location); | |
IntPtr stg = CreateStorage(Path.Combine(path, "test.stg"), STGM.CREATE | STGM.READWRITE | STGM.SHARE_EXCLUSIVE, STGFMT.Docfile); | |
Console.WriteLine(stg); | |
var act = (IStandardActivator)new StandardActivator(); | |
ISpecialSystemPropertiesActivator props = (ISpecialSystemPropertiesActivator)act; | |
if (args.Length > 0) | |
{ | |
int session_id = int.Parse(args[0]); | |
Console.WriteLine("Spawning in session {0}", session_id); | |
props.SetSessionId(session_id, 0, 1); | |
} | |
Guid test_clsid = new Guid("8cec58ae-07a1-11d9-b15e-000d56bfe6ee"); | |
Guid iid = new Guid("00000000-0000-0000-c000-000000000046"); | |
MULTI_QI[] qis = new MULTI_QI[1]; | |
qis[0] = new MULTI_QI(iid); | |
act.StandardGetInstanceFromIStorage(null, test_clsid, IntPtr.Zero, CLSCTX.LOCAL_SERVER, stg, 1, qis); | |
Console.WriteLine(qis[0].GetObject()); | |
} | |
catch (Exception ex) | |
{ | |
Console.WriteLine(ex); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment