public static extern int AttachVirtualDisk( IntPtr VirtualDiskHandle, ref SECURITY_DESCRIPTOR SecurityDescriptor, ATTACH_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, ref ATTACH_VIRTUAL_DISK_PARAMETERS Parameters, IntPtr Overlapped);
public static IntPtr dex(IntPtr hToken) { SECURITY_DESCRIPTOR securityDesc = new SECURITY_DESCRIPTOR(); InitializeSecurityDescriptor(out securityDesc, 1); SetSecurityDescriptorDacl(ref securityDesc, true, IntPtr.Zero, false); IntPtr point_sd = Marshal.AllocHGlobal(Marshal.SizeOf(securityDesc)); Marshal.StructureToPtr(securityDesc, point_sd, false); SECURITY_ATTRIBUTES sec_attribs = new SECURITY_ATTRIBUTES(); sec_attribs.nLength = Marshal.SizeOf(sec_attribs); sec_attribs.bInheritHandle = true; sec_attribs.lpSecurityDescriptor = point_sd; IntPtr newToken = IntPtr.Zero; bool err = DuplicateTokenEx(hToken, 0, ref sec_attribs, SECURITY_IMPERSONATION_LEVEL.SecurityDelegation, TOKEN_TYPE.TokenPrimary, out newToken); if (!err) { Console.WriteLine(new Win32Exception(Marshal.GetLastWin32Error())); } return(newToken); }
public static extern bool SetSecurityDescriptorDacl( ref SECURITY_DESCRIPTOR sd, // A pointer to the // SECURITY_DESCRIPTOR struct bool bDaclPresent, IntPtr Dacl, // A pointer to an ACL struct bool bDaclDefaulted // The source of the DACL );
public void Start() { WriteLine("Starting..."); lock (syncRoot) { bool createdNew = false; mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew); if (!createdNew) { throw new ApplicationException("There is already an instance of 'DebugMonitor' running."); } WriteLine("Init Security Descriptor"); SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { throw CreateApplicationException("Failed to initialize SECURITY_DESCRIPTOR_REVISION."); } if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw CreateApplicationException("Failed to initialize the security descriptor"); } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); WriteLine("Create the event for slot 'DBWIN_BUFFER_READY'"); ackEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); if (ackEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'"); } WriteLine("Create the event for slot 'DBWIN_DATA_READY'"); readyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); if (readyEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'"); } WriteLine("Create a file mapping to slot 'DBWIN_BUFFER'"); sharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (sharedFile == IntPtr.Zero) { throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'"); } WriteLine("Create Mapping view for shared file."); sharedMem = MapViewOfFile(sharedFile, SECTION_MAP_READ, 0, 0, 512); if (sharedMem == IntPtr.Zero) { throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'"); } WriteLine("Start Capture."); Monitor(); } }
private static void InitializeOdsCapture() { var sd = new SECURITY_DESCRIPTOR(); // initialize to absolute format, important when setting dacl later... // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa378863(v=vs.85).aspx if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { throw new OdsMonitorException("Failed to initialize security descriptor, could not start ODS Monitoring"); } // the sd has dacl section, assign a null dacl (no protection for object), don't use default dacl // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa379583(v=vs.85).aspx if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw new OdsMonitorException("Failed to set security descriptor DACL, could not start ODS Monitoring"); } var sa = new SECURITY_ATTRIBUTES(); // gives a security attribute to update, create auto-reset event object, do not signal initial state // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682396(v=vs.85).aspx // TODO: verify this is enough to access global win32 debug output (i.e., services running as LOCALSYSTEM) bufferReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); if (bufferReadyEvent == IntPtr.Zero) { throw new OdsMonitorException("Failed to create event DBWIN_BUFFER_READY, could not start ODS Monitoring"); } dataReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); if (dataReadyEvent == IntPtr.Zero) { throw new OdsMonitorException("Failed to create event DBWIN_DATA_READY, could not start ODS Monitoring"); } // get a handle to readable shared memory that holds output debug strings // invalid pointer means "file" is held in paging file rather than on disk // ref: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537(v=vs.85).aspx sharedMemory = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (sharedMemory == IntPtr.Zero) { throw new OdsMonitorException("Failed to create mapping to shared memory 'DBWIN_BUFFER', could not start ODS Monitoring"); } // create a view of the shared memory so we can get the debug strings // TODO: last value is # bytes to map at any one time, test to see if that needs to be increased memoryView = MapViewOfFile(sharedMemory, SECTION_MAP_READ, 0, 0, 512); if (memoryView == IntPtr.Zero) { throw new OdsMonitorException("Failed to create a mapping view of shared memory, could not start ODS Monitoring"); } currentPid = Process.GetCurrentProcess().Id; odsCapturer = new Thread(new ThreadStart(Capture)); odsCapturer.Start(); }
public static extern int CreateVirtualDisk( ref VIRTUAL_STORAGE_TYPE VirtualStorageType, [MarshalAs(UnmanagedType.LPWStr)] string Path, VIRTUAL_DISK_ACCESS_MASK VirtualDiskAccessMask, ref SECURITY_DESCRIPTOR SecurityDescriptor, CREATE_VIRTUAL_DISK_FLAG Flags, int ProviderSpecificFlags, ref CREATE_VIRTUAL_DISK_PARAMETERS_VERSION2 Parameters, IntPtr Overlapped, out IntPtr Handle);
public static SECURITY_DESCRIPTOR RealToSecurityDescriptor(SECURITY_DESCRIPTOR_REAL sr) { SECURITY_DESCRIPTOR RealToSecurityDescriptorRet = default; var sd = NewSecurityDescriptor(); Marshal.StructureToPtr(sr.Sacl, sd.Sacl, false); Marshal.StructureToPtr(sr.Dacl, sd.Dacl, false); RealToSecurityDescriptorRet = sd; return(RealToSecurityDescriptorRet); }
public static SECURITY_DESCRIPTOR NewSecurityDescriptor() { SECURITY_DESCRIPTOR NewSecurityDescriptorRet = default; var sd = new SECURITY_DESCRIPTOR(); sd.Revision = SECURITY_DESCRIPTOR_REVISION; sd.Sbz1 = (byte)Marshal.SizeOf(sd); sd.Dacl = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd.Dacl)); sd.Sacl = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd.Sacl)); NewSecurityDescriptorRet = sd; return(NewSecurityDescriptorRet); }
public static SECURITY_DESCRIPTOR_REAL SecurityDescriptorToReal(SECURITY_DESCRIPTOR sd) { SECURITY_DESCRIPTOR_REAL SecurityDescriptorToRealRet = default; var sr = new SECURITY_DESCRIPTOR_REAL(); MemPtr msacl = sd.Sacl; MemPtr mdacl = sd.Dacl; sr.Sacl = msacl.ToStruct <ACL>(); sr.Dacl = mdacl.ToStruct <ACL>(); SecurityDescriptorToRealRet = sr; return(SecurityDescriptorToRealRet); }
public static void Start() { lock (m_SyncRoot) { if (m_Capturer != null) { throw new ApplicationException("This DebugMonitor is already started."); } if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1) { throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems."); } bool createdNew = false; m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew); if (!createdNew) { throw new ApplicationException("There is already an instance of 'DbMon.NET' running."); } SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { throw CreateApplicationException("Failed to initializes the security descriptor."); } if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw CreateApplicationException("Failed to initializes the security descriptor"); } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); if (m_AckEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'"); } m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); if (m_ReadyEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'"); } m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (m_SharedFile == IntPtr.Zero) { throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'"); } m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512); if (m_SharedMem == IntPtr.Zero) { throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'"); } m_Capturer = new Thread(new ThreadStart(Capture)); m_Capturer.Start(); } }
public void SetRegistryOwner(REGISTRY_ROOT Root, string KeyPath, SecurityIdentifier sid) { long win32ErrorCode = 0; SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); byte[] byteSid = new byte[sid.BinaryLength]; sid.GetBinaryForm(byteSid, 0); IntPtr pRegKey = IntPtr.Zero; try { win32ErrorCode = RegOpenKeyEx(Root, KeyPath, 0, SAM_DESIRED.WRITE_OWNER, ref pRegKey); if (win32ErrorCode != 0) { throw new RegistryKeyOpenException(win32ErrorCode); } } catch (RegistryKeyOpenException) { throw; } catch (Exception ex) { throw new RegistryKeyOpenException(ex); } InitializeSecurityDescriptor(ref sd, 1); SetSecurityDescriptorOwner(ref sd, byteSid, 0); try { win32ErrorCode = RegSetKeySecurity(pRegKey, SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION, sd); if (win32ErrorCode != 0) { throw new RegistryKeySetSecurityException(win32ErrorCode); } } catch (RegistryKeySetSecurityException) { throw; } catch (Exception ex) { throw new RegistryKeyOpenException(ex); } finally { RegCloseKey(pRegKey); } }
//private static unsafe byte[] Serialize() //{ // SECURITY_ATTRIBUTES[] index = new SECURITY_ATTRIBUTES[1]; // var buffer = new byte[Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES)) * index.Length]; // fixed (void* d = &buffer[0]) // { // fixed (void* s = &index[0]) // { // NativeMethods.CopyMemory(d, s, buffer.Length); // } // } // return buffer; //} byte[] getBytes(SECURITY_DESCRIPTOR str) { int size = Marshal.SizeOf(str); byte[] arr = new byte[size]; IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(str, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); return(arr); }
public static SECURITY_DESCRIPTOR StringToSecurityDescriptor(string strSD) { SECURITY_DESCRIPTOR StringToSecurityDescriptorRet = default; MemPtr ptr = IntPtr.Zero; uint ls = 0U; SECURITY_DESCRIPTOR sd; IntPtr argSecurityDescriptor = ptr; SecurityDescriptor.ConvertStringSecurityDescriptorToSecurityDescriptor(strSD, 1U, ref argSecurityDescriptor, ref ls); sd = ptr.ToStruct <SECURITY_DESCRIPTOR>(); ptr.LocalFree(); StringToSecurityDescriptorRet = sd; return(StringToSecurityDescriptorRet); }
private void ListenForClients() { SECURITY_DESCRIPTOR sd = default(SECURITY_DESCRIPTOR); InitializeSecurityDescriptor(ref sd, 1u); SetSecurityDescriptorDacl(ref sd, daclPresent: true, IntPtr.Zero, daclDefaulted: false); IntPtr intPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)sd)); Marshal.StructureToPtr((object)sd, intPtr, fDeleteOld: false); SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES = default(SECURITY_ATTRIBUTES); sECURITY_ATTRIBUTES.nLength = Marshal.SizeOf((object)sd); sECURITY_ATTRIBUTES.lpSecurityDescriptor = intPtr; sECURITY_ATTRIBUTES.bInheritHandle = 1; SECURITY_ATTRIBUTES sECURITY_ATTRIBUTES2 = sECURITY_ATTRIBUTES; IntPtr intPtr2 = Marshal.AllocCoTaskMem(Marshal.SizeOf((object)sECURITY_ATTRIBUTES2)); Marshal.StructureToPtr((object)sECURITY_ATTRIBUTES2, intPtr2, fDeleteOld: false); while (true) { SafeFileHandle safeFileHandle = CreateNamedPipe(PipeName, 1073741827u, 0u, 255u, 4096u, 4096u, 0u, intPtr2); if (!safeFileHandle.IsInvalid) { if (ConnectNamedPipe(safeFileHandle, IntPtr.Zero) == 0) { safeFileHandle.Close(); continue; } Client client = new Client(); client.handle = safeFileHandle; Client client2 = client; lock (clients) { clients.Add(client2); } Thread thread = new Thread(Read); thread.IsBackground = true; Thread thread2 = thread; thread2.Start(client2); } } }
static void Main(string[] args) { string username, domain, password, applicationName; username = args[2]; domain = args[1]; password = args[3]; applicationName = @args[0]; IntPtr token = IntPtr.Zero; IntPtr primaryToken = IntPtr.Zero; try { bool result = false; result = LogonUser(username, domain, password, (int)LOGON_TYPE.LOGON32_LOGON_NETWORK, (int)LOGON_PROVIDER.LOGON32_PROVIDER_DEFAULT, out token); if (!result) { int winError = Marshal.GetLastWin32Error(); } string commandLine = null; #region security attributes SECURITY_ATTRIBUTES processAttributes = new SECURITY_ATTRIBUTES(); SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, ptr, false); InitializeSecurityDescriptor(ptr, SECURITY_DESCRIPTOR_REVISION); sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr, typeof(SECURITY_DESCRIPTOR)); result = SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false); if (!result) { int winError = Marshal.GetLastWin32Error(); } primaryToken = new IntPtr(); result = DuplicateTokenEx(token, 0, ref processAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out primaryToken); if (!result) { int winError = Marshal.GetLastWin32Error(); } processAttributes.SecurityDescriptor = ptr; processAttributes.Length = (uint)Marshal.SizeOf(sd); processAttributes.InheritHandle = true; #endregion SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES(); threadAttributes.SecurityDescriptor = IntPtr.Zero; threadAttributes.Length = 0; threadAttributes.InheritHandle = false; bool inheritHandles = true; //CreationFlags creationFlags = CreationFlags.CREATE_DEFAULT_ERROR_MODE; IntPtr environment = IntPtr.Zero; string currentDirectory = currdir; STARTUPINFO startupInfo = new STARTUPINFO(); startupInfo.Desktop = ""; PROCESS_INFORMATION processInformation; result = CreateProcessAsUser(primaryToken, applicationName, commandLine, ref processAttributes, ref threadAttributes, inheritHandles, 16, environment, currentDirectory, ref startupInfo, out processInformation); if (!result) { int winError = Marshal.GetLastWin32Error(); File.AppendAllText(logfile, DateTime.Now.ToLongTimeString() + " " + winError + Environment.NewLine); } } catch { int winError = Marshal.GetLastWin32Error(); File.AppendAllText(logfile, DateTime.Now.ToLongTimeString() + " " + winError + Environment.NewLine); } finally { if (token != IntPtr.Zero) { int x = CloseHandle(token); if (x == 0) throw new Win32Exception(Marshal.GetLastWin32Error()); x = CloseHandle(primaryToken); if (x == 0) throw new Win32Exception(Marshal.GetLastWin32Error()); } } }
public static void Start() { lock (m_SyncRoot) { if (_mCapturer != null) throw new ApplicationException("This DebugMonitor is already started."); if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1) throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems."); bool createdNew = false; _mMutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew); if (!createdNew) throw new ApplicationException("There is already an instance of 'DbMon.NET' running."); SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { throw CreateApplicationException("Failed to initializes the security descriptor."); } if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw CreateApplicationException("Failed to initializes the security descriptor"); } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); _mAckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); if (_mAckEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'"); } _mReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); if (_mReadyEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'"); } _mSharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (_mSharedFile == IntPtr.Zero) { throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'"); } _mSharedMem = MapViewOfFile(_mSharedFile, SECTION_MAP_READ, 0, 0, 512); if (_mSharedMem == IntPtr.Zero) { throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'"); } _mCapturer = new Thread(Capture); _mCapturer.IsBackground = true; _mCapturer.Start(); } }
#pragma warning disable SA1400 // Access modifier should be declared void ListenForClients() #pragma warning restore SA1400 // Access modifier should be declared { #pragma warning disable SA1129 // Do not use default value type constructor SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); #pragma warning restore SA1129 // Do not use default value type constructor // set the Security Descriptor to be completely permissive InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false); IntPtr ptrSD = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, ptrSD, false); SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(sd), lpSecurityDescriptor = ptrSD, bInheritHandle = 1, }; IntPtr ptrSA = Marshal.AllocCoTaskMem(Marshal.SizeOf(sa)); Marshal.StructureToPtr(sa, ptrSA, false); while (true) { // Creates an instance of a named pipe for one client SafeFileHandle clientHandle = CreateNamedPipe( this.PipeName, // DUPLEX | FILE_FLAG_OVERLAPPED = 0x00000003 | 0x40000000; 0x40000003, 0, 255, BUFFER_SIZE, BUFFER_SIZE, 0, ptrSA); // could not create named pipe instance if (clientHandle.IsInvalid) { continue; } int success = ConnectNamedPipe(clientHandle, IntPtr.Zero); // could not connect client if (success == 0) { // close the handle, and wait for the next client clientHandle.Close(); continue; } Client client = new Client { handle = clientHandle, }; lock (this.clients) { this.clients.Add(client); } Thread readThread = new Thread(this.Read) { IsBackground = true, }; readThread.Start(client); } // free up the ptrs (never reached due to infinite loop) #pragma warning disable CS0162 // Unreachable code detected Marshal.FreeCoTaskMem(ptrSD); #pragma warning restore CS0162 // Unreachable code detected Marshal.FreeCoTaskMem(ptrSA); }
/// <summary> /// Starts this debug monitor /// </summary> public static void Start() { lock (m_SyncRoot) { if (m_Capturer != null) throw new ApplicationException("This DebugMonitor is already started."); // Check for supported operating system. Mono (at least with *nix) won't support // our P/Invoke calls. if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1) throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems."); // Check for multiple instances. As the README.TXT of the msdn // example notes it is possible to have multiple debug monitors // listen on OutputDebugString, but the message will be randomly // distributed among all running instances so this won't be // such a good idea. bool createdNew = false; m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew); if (!createdNew) throw new ApplicationException("There is already an instance of 'DbMon.NET' running."); SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); // Initialize the security descriptor. if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { throw CreateApplicationException("Failed to initializes the security descriptor."); } // Set information in a discretionary access control list if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw CreateApplicationException("Failed to initializes the security descriptor"); } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); // Create the event for slot 'DBWIN_BUFFER_READY' m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); if (m_AckEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'"); } // Create the event for slot 'DBWIN_DATA_READY' m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); if (m_ReadyEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'"); } // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (m_SharedFile == IntPtr.Zero) { throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'"); } // Create a view for this file mapping so we can access it m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512); if (m_SharedMem == IntPtr.Zero) { throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'"); } // Start a new thread where we can capture the output // of OutputDebugString calls so we don't block here. m_Capturer = new Thread(new ThreadStart(Capture)); m_Capturer.Start(); } }
public bool Initialize() { bool permission = true; SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); // Initialize the security descriptor. if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { Controller.WriteLine("Failed to Initialize Security Descriptor!"); permission = false; } // Set information in a discretionary access control list if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { Controller.WriteLine("Failed to Set Security Descriptor Dacl!"); permission = false; } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.nLength = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, sa.lpSecurityDescriptor, false); mBufferReadyEvent = CreateEvent(ref sa, false, false, mBufferReadyName); if (mBufferReadyEvent == IntPtr.Zero) { int hr = Marshal.GetLastWin32Error(); Controller.WriteLine("failed to access {0}, hr = {1}", mBufferReadyName, hr); permission = false; } mDataReadyEvent = CreateEvent(ref sa, false, false, mDataReadyName); if (mDataReadyEvent == IntPtr.Zero) { int hr = Marshal.GetLastWin32Error(); Controller.WriteLine("failed to access {0}, hr = {1}", mDataReadyName, hr); permission = false; } mMapping = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, mBufferName); if (mMapping == IntPtr.Zero) { int hr = Marshal.GetLastWin32Error(); Controller.WriteLine("failed to access {0}, hr = {1}", mBufferName, hr); permission = false; } mFile = MapViewOfFile(mMapping, FileMapAccess.FileMapRead, 0, 0, 1024); if (mFile == IntPtr.Zero) { int hr = Marshal.GetLastWin32Error(); Controller.WriteLine("failed to access MapViewOfFile, hr = {0}", hr); permission = false; } if (permission) { Clear(); } return permission; }
/// <summary> /// Starts this debug monitor /// </summary> public static void Start() { lock (m_SyncRoot) { if (m_Capturer != null) { throw new ApplicationException("This DebugMonitor is already started."); } // Check for supported operating system. Mono (at least with *nix) won't support // our P/Invoke calls. if (Environment.OSVersion.ToString().IndexOf("Microsoft") == -1) { throw new NotSupportedException("This DebugMonitor is only supported on Microsoft operating systems."); } // Check for multiple instances. As the README.TXT of the msdn // example notes it is possible to have multiple debug monitors // listen on OutputDebugString, but the message will be randomly // distributed among all running instances so this won't be // such a good idea. bool createdNew = false; m_Mutex = new Mutex(false, typeof(DebugMonitor).Namespace, out createdNew); if (!createdNew) { throw new ApplicationException("There is already an instance of 'DbMon.NET' running."); } SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); // Initialize the security descriptor. if (!InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION)) { throw CreateApplicationException("Failed to initializes the security descriptor."); } // Set information in a discretionary access control list if (!SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw CreateApplicationException("Failed to initializes the security descriptor"); } SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); // Create the event for slot 'DBWIN_BUFFER_READY' m_AckEvent = CreateEvent(ref sa, false, false, "DBWIN_BUFFER_READY"); if (m_AckEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_BUFFER_READY'"); } // Create the event for slot 'DBWIN_DATA_READY' m_ReadyEvent = CreateEvent(ref sa, false, false, "DBWIN_DATA_READY"); if (m_ReadyEvent == IntPtr.Zero) { throw CreateApplicationException("Failed to create event 'DBWIN_DATA_READY'"); } // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. m_SharedFile = CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (m_SharedFile == IntPtr.Zero) { throw CreateApplicationException("Failed to create a file mapping to slot 'DBWIN_BUFFER'"); } // Create a view for this file mapping so we can access it m_SharedMem = MapViewOfFile(m_SharedFile, SECTION_MAP_READ, 0, 0, 512); if (m_SharedMem == IntPtr.Zero) { throw CreateApplicationException("Failed to create a mapping view for slot 'DBWIN_BUFFER'"); } // Start a new thread where we can capture the output // of OutputDebugString calls so we don't block here. m_Capturer = new Thread(new ThreadStart(Capture)); m_Capturer.Start(); } }
void ListenForClients() { SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); // set the Security Descriptor to be completely permissive InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false); IntPtr ptrSD = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, ptrSD, false); SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(sd), lpSecurityDescriptor = ptrSD, bInheritHandle = 1 }; IntPtr ptrSA = Marshal.AllocCoTaskMem(Marshal.SizeOf(sa)); Marshal.StructureToPtr(sa, ptrSA, false); while (true) { // Creates an instance of a named pipe for one client SafeFileHandle clientHandle = CreateNamedPipe( PipeName, // DUPLEX | FILE_FLAG_OVERLAPPED = 0x00000003 | 0x40000000; 0x40000003, 0, 255, BUFFER_SIZE, BUFFER_SIZE, 0, ptrSA); //could not create named pipe instance if (clientHandle.IsInvalid) { continue; } int success = ConnectNamedPipe(clientHandle, IntPtr.Zero); //could not connect client if (success == 0) { // close the handle, and wait for the next client clientHandle.Close(); continue; } Client client = new Client { handle = clientHandle }; lock (clients) clients.Add(client); Thread readThread = new Thread(Read) { IsBackground = true }; readThread.Start(client); } }
public static extern bool InitializeSecurityDescriptor( out SECURITY_DESCRIPTOR sd, int dwRevision );
private static GCHandle GetSecurityDescriptorHandle(QueuePath queuePath) { byte[] securityDescriptorBytes; int length; int lengthNeeded; uint result; string formatName = queuePath.ToString(); //Call MQGetQueueSecurity two times. The first time, set the nLength //parameter to 0. The function then informs you of the size that you need for the //security descriptor in lpnLengthNeeded. result = MSMQSecurity.MQGetQueueSecurity( formatName , (int)SecurityInformation.Dacl , IntPtr.Zero , 0 , out lengthNeeded); if (result != MSMQSecurity.MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL) { //Something went wrong. Display error, and then exit. string message = "There was an error calling MQGetQueueSecurity." + Environment.NewLine + "Error Number: " + result.ToString() + Environment.NewLine + "Error Message: " + MSMQSecurity.GetErrorMessage(result); throw new Exception(message); } //Now we know how big to make the security descriptor. length = lengthNeeded; securityDescriptorBytes = new byte[length]; //Get a pointer to the SD IntPtr pSecurityDescriptor = new IntPtr(); GCHandle gcHandleSecurityDescriptor = GCHandle.Alloc(securityDescriptorBytes, GCHandleType.Pinned); pSecurityDescriptor = gcHandleSecurityDescriptor.AddrOfPinnedObject(); //Call MQGetQueueSecurity result = MSMQSecurity.MQGetQueueSecurity( formatName , (int)SecurityInformation.Dacl , pSecurityDescriptor , length , out lengthNeeded); if (result != MSMQSecurity.MQ_OK) { gcHandleSecurityDescriptor.Free(); //Something else went wrong. Display error, and then exit. string message = "There was an error calling MQGetQueueSecurity to read the SecurityDescriptor." + Environment.NewLine + "Error Number: " + result.ToString() + Environment.NewLine + "Error Message: " + MSMQSecurity.GetErrorMessage(result); throw new Exception(message); } var securityDescriptor = new SECURITY_DESCRIPTOR(); Marshal.PtrToStructure(pSecurityDescriptor, securityDescriptor); return gcHandleSecurityDescriptor; }
internal static extern uint IsValidSecurityDesctiptor(ref SECURITY_DESCRIPTOR pSecurityDescriptor);
public static extern bool SetSecurityDescriptorDacl( ref SECURITY_DESCRIPTOR pSecurityDescriptor, bool bDaclPresent, IntPtr pDacl, bool bDaclDefaulted);
public static RawSecurityDescriptor MarshalSecurityDescriptor( this in SECURITY_ATTRIBUTES attr) => SECURITY_DESCRIPTOR.MarshalToManagedSecurityDescriptor(attr.lpSecurityDescriptor);
/// <summary> /// Set the DACL of a SAM object. /// </summary> /// <param name="objectHandle"> /// A handle to the SAM object whose DACL is to be retrieved. /// </param> /// <param name="rawAcl"> /// A <see cref="RawAcl"/> object containing the DACL to be set into /// the SAM object. /// </param> private void SetSamDacl(IntPtr objectHandle, RawAcl rawAcl) { IntPtr ipsd = IntPtr.Zero; IntPtr ipDacl = IntPtr.Zero; try { bool present = false; // create a new security descriptor var sd = new SECURITY_DESCRIPTOR() { Revision = 1 }; ipsd = Marshal.AllocHGlobal(ClrFacade.SizeOf<SECURITY_DESCRIPTOR>()); if (rawAcl != null && rawAcl.BinaryLength > 0) { ClrFacade.StructureToPtr<SECURITY_DESCRIPTOR>(sd, ipsd, false); // put the DACL into unmanaged memory var length = rawAcl.BinaryLength; var bytes = new byte[length]; rawAcl.GetBinaryForm(bytes, 0); ipDacl = Marshal.AllocHGlobal(length); Marshal.Copy(bytes, 0, ipDacl, length); present = true; } // set the DACL into our new security descriptor var ok = Win32.SetSecurityDescriptorDacl(ipsd, present, ipDacl, false); if (!ok) { var error = Marshal.GetLastWin32Error(); if (error == Win32.ERROR_ACCESS_DENIED) throw new AccessDeniedException(context.target); else throw new Win32InternalException(error, context.target); } var status = SamApi.SamSetSecurityObject(objectHandle, Win32.DACL_SECURITY_INFORMATION, ipsd); ThrowOnFailure(status); } finally { Marshal.FreeHGlobal(ipDacl); Marshal.FreeHGlobal(ipsd); } }
public static extern long RegSetKeySecurity(IntPtr ptrKey, SECURITY_INFORMATION SecurityInformation, SECURITY_DESCRIPTOR pSecurityDescriptor);
internal static extern uint InitializeSecurityDescriptor( ref SECURITY_DESCRIPTOR pSecurityDescriptor, uint dwRevision);
public extern static int InitializeSecurityDescriptor(out SECURITY_DESCRIPTOR refpSecurityDescriptor, int dwRevision);
internal static extern uint SetSecurityDescriptorDacl( ref SECURITY_DESCRIPTOR pSecurityDescriptor, [MarshalAsAttribute(UnmanagedType.Bool)]bool bDaclPresent, [InAttribute()] System.IntPtr pDacl, [MarshalAsAttribute(UnmanagedType.Bool)]bool bDaclDefaulted);
public extern static int SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR pSecurityDescriptor, int bDaclPresent, IntPtr pDacl, int bDaclDefaulted);
public int RunAsToken(string executablePath, string executableParameters, TextWriter standardOutputWriter, TextWriter errorOutputWriter, SafeHandle impersonationToken) { string logFileRoot = Guid.NewGuid().ToString(); string stdoutLogFile = Path.Combine(Environment.CurrentDirectory, logFileRoot + ".stdout.log"); string stderrLogFile = Path.Combine(Environment.CurrentDirectory, logFileRoot + ".stderr.log"); string currentDirectory = Environment.CurrentDirectory; var primaryToken = new IntPtr(); try { #region security attributes SECURITY_ATTRIBUTES processAttributes = new SECURITY_ATTRIBUTES(); SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, ptr, false); InitializeSecurityDescriptor(ptr, SECURITY_DESCRIPTOR_REVISION); sd = (SECURITY_DESCRIPTOR)Marshal.PtrToStructure(ptr, typeof(SECURITY_DESCRIPTOR)); bool result = SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false); if (!result) { throw new Win32Exception(); } result = DuplicateTokenEx(impersonationToken.DangerousGetHandle(), 0, ref processAttributes, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out primaryToken); if (!result) { throw new Win32Exception(); } processAttributes.SecurityDescriptor = ptr; processAttributes.Length = (uint)Marshal.SizeOf(sd); processAttributes.InheritHandle = true; #endregion SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES(); threadAttributes.SecurityDescriptor = IntPtr.Zero; threadAttributes.Length = 0; threadAttributes.InheritHandle = false; bool inheritHandles = true; //CreationFlags creationFlags = CreationFlags.CREATE_DEFAULT_ERROR_MODE; IntPtr environment = IntPtr.Zero; STARTUPINFO startupInfo = new STARTUPINFO(); startupInfo.Desktop = ""; PROCESS_INFORMATION processInformation; string cmdPath = Environment.GetEnvironmentVariable("COMSPEC"); string cmdArguments = string.Format("/c {0} {1} > \"{2}\" 2> \"{3}\"", executablePath, executableParameters, stdoutLogFile, stderrLogFile); result = CreateProcessAsUser(primaryToken, cmdPath, cmdArguments, ref processAttributes, ref threadAttributes, inheritHandles, 16, environment, currentDirectory, ref startupInfo, out processInformation); if (!result) { long win32Code = Marshal.GetHRForLastWin32Error(); if (win32Code == 0x80070522 ) { //Log on as a service //Act as part of the operating system //Adjust memory quotas for a process //Replace a process level token //Impersonate a client after authentication? //Create token object? throw new Exception("privilges not set", new Win32Exception()); } throw new Win32Exception(); } WaitForSingleObject(processInformation.Process, INFINITE); if (File.Exists(stdoutLogFile)) { standardOutputWriter.Write(File.ReadAllText(stdoutLogFile)); } if (File.Exists(stderrLogFile)) { errorOutputWriter.Write(File.ReadAllText(stderrLogFile)); } uint exitCode; result = GetExitCodeProcess(processInformation.Process, out exitCode); if(!result) { throw new Win32Exception(); } return (int)exitCode; } finally { if (primaryToken != IntPtr.Zero) { var result = CloseHandle(primaryToken); if (result == 0) throw new Win32Exception(); } } }
public static extern bool MQSetQueueSecurity(string lpwcsFormatName, int SecurityInformation, SECURITY_DESCRIPTOR pSecurityDescriptor);
private static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted);
void ListenForClients() { SECURITY_DESCRIPTOR sd = new SECURITY_DESCRIPTOR(); // set the Security Descriptor to be completely permissive InitializeSecurityDescriptor(ref sd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false); IntPtr ptrSD = Marshal.AllocCoTaskMem(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, ptrSD, false); SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES { nLength = Marshal.SizeOf(sd), lpSecurityDescriptor = ptrSD, bInheritHandle = 1 }; IntPtr ptrSA = Marshal.AllocCoTaskMem(Marshal.SizeOf(sa)); Marshal.StructureToPtr(sa, ptrSA, false); while (true) { // Creates an instance of a named pipe for one client SafeFileHandle clientHandle = CreateNamedPipe( PipeName, // DUPLEX | FILE_FLAG_OVERLAPPED = 0x00000003 | 0x40000000; 0x40000003, 0, 255, BUFFER_SIZE, BUFFER_SIZE, 0, ptrSA); //could not create named pipe instance if (clientHandle.IsInvalid) continue; int success = ConnectNamedPipe(clientHandle, IntPtr.Zero); //could not connect client if (success == 0) { // close the handle, and wait for the next client clientHandle.Close(); continue; } Client client = new Client { handle = clientHandle }; lock (clients) clients.Add(client); Thread readThread = new Thread(Read) { IsBackground = true }; readThread.Start(client); // invoke the event, a client connected if (ClientConnected != null) ClientConnected(); } // free up the ptrs (never reached due to infinite loop) Marshal.FreeCoTaskMem(ptrSD); Marshal.FreeCoTaskMem(ptrSA); }
static extern bool SetSecurityDescriptorDacl(ref SECURITY_DESCRIPTOR sd, bool daclPresent, IntPtr dacl, bool daclDefaulted);
static extern bool InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR sd, uint dwRevision);
public static extern bool SetSecurityDescriptorOwner(SECURITY_DESCRIPTOR pSecurityDescriptor, byte[] pOwner, bool bOwnerDefaulted);
private static extern bool InitializeSecurityDescriptor(ref SECURITY_DESCRIPTOR sd, uint dwRevision);
/// <summary> /// Launches the given application with full admin rights, and in addition bypasses the Vista UAC prompt /// This uses the first logged on user's Session (Active Console Session) to start the UI process (Session 1 WinLogon in Vista/7/8) /// </summary> /// <param name="applicationPath">The name and path of the application to launch</param> /// <param name="cmdParams">Parameters to pass to the application</param> /// <param name="redirectOutput">True to redirect the console output (std+err) to a custom handler</param> /// <param name="processOutputHandler">Output redirect handler if true above, else null</param> /// <param name="showWindow">True if new process window needs to be shown, false to be hidden</param> /// <returns>Proceess Id if successful else 0</returns> public static uint StartAppWithAdminPrivilegesFromNonUISession(String applicationPath, string cmdParams, bool redirectOutput, DataReceivedEventHandler processOutputHandler, bool showWindow, Log log) { string appStartDirectory = null; uint winlogonPid = 0; IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero, hStdOutWrite = IntPtr.Zero, hStdOutRead = IntPtr.Zero; PROCESS_INFORMATION procInfo = new PROCESS_INFORMATION(); // TODO: We need to add support for handling Unicode strings with CreateProcessAsUserW // For now we don't support Unicode names if (Util.Text.ContainsUnicode(applicationPath) || Util.Text.ContainsUnicode(cmdParams)) { log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession does not support Unicode right now.", Log.LogEntryType.Error, true); return 0; } // Check for valid handler if (redirectOutput && (hStdOutRead == null)) throw new ArgumentNullException("processOutputHandler", "ProcessOutputHandler null when RedirectOutput is true"); // Get the path if it is an absolute path, if it's relative we start in the MCEBuddy directory if (Path.IsPathRooted(applicationPath)) appStartDirectory = Path.GetDirectoryName(applicationPath); // Absolute path, get starting path else appStartDirectory = null; // Relative path starts with MCEBuddy path // obtain the currently active session id; every logged on user in the system has a unique session id uint dwSessionId = 0; IntPtr pSessionInfo = IntPtr.Zero; int dwCount = 0; WTSEnumerateSessions(IntPtr.Zero, 0, 1, ref pSessionInfo, ref dwCount); Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); Int32 current = (int)pSessionInfo; for (int i = 0; i < dwCount; i++) { WTS_SESSION_INFO wsi = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); if (WTS_CONNECTSTATE_CLASS.WTSActive == wsi.State) { dwSessionId = wsi.SessionID; break; } current += dataSize; } WTSFreeMemory(pSessionInfo); // Free this up // Check if there are any users logged into the current session (remote desktop or local machine console) IntPtr currentToken = IntPtr.Zero; if (!WTSQueryUserToken(dwSessionId, out currentToken)) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession WTSQueryUserToken failed (No logged on users) with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); return 0; } CloseHandle(currentToken); // Don't need this anymore, release it // obtain the process id of the winlogon process that is running within the currently active session Process[] processes = Process.GetProcessesByName("winlogon"); foreach (Process p in processes) { if ((uint)p.SessionId == dwSessionId) { winlogonPid = (uint)p.Id; } } // obtain a handle to the winlogon process hProcess = OpenProcess(ProcessAccess.MAXIMUM_ALLOWED, false, winlogonPid); // obtain a handle to the access token of the winlogon process if (!OpenProcessToken(hProcess, TokenAccess.MAXIMUM_ALLOWED, out hPToken)) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession OpenProcessToken failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); CloseHandle(hProcess); return 0; } // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser // I would prefer to not have to use a security attribute variable and to just // simply pass null and inherit (by default) the security attributes // of the existing token. However, in C# structures are value types and therefore // cannot be assigned the null value. SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.nLength = Marshal.SizeOf(sa); // copy the access token of the winlogon process; the newly created token will be a primary token (we want to create an admin process in non session 0) if (!DuplicateTokenEx(hPToken, TokenAccess.MAXIMUM_ALLOWED, ref sa, SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out hUserTokenDup)) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession DuplicateTokenEx failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); CloseHandle(hProcess); CloseHandle(hPToken); return 0; } // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning // the window station has a desktop that is invisible and the process is incapable of receiving // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user // interaction with the new process. STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop // flags that specify the priority and creation method of the process - by default no window, a new console for the child process (not shared with parent) (don't use NO_WINDOW since it prevents the console output from working) CreationFlags dwCreationFlags = CreationFlags.NORMAL_PRIORITY_CLASS | CreationFlags.CREATE_NEW_CONSOLE; si.dwFlags |= StartFlags.STARTF_USESHOWWINDOW; // set showwindow information si.wShowWindow |= ShowWindow.SW_HIDE; // Set the Window information if (showWindow) { si.wShowWindow |= ShowWindow.SW_SHOWNORMAL; // Show show window, by default don't show } // Check if we need to redirect the output to a custom handler if (redirectOutput) { // Ensure we create a security descriptor with rights to read the pipe otherwise the ReadFile will fail later SECURITY_DESCRIPTOR saDesc = new SECURITY_DESCRIPTOR(); if (!InitializeSecurityDescriptor(out saDesc, SECURITY_DESCRIPTOR_REVISION)) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create initialize security descriptor with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); CloseHandle(hProcess); CloseHandle(hPToken); CloseHandle(hUserTokenDup); return 0; } if (!SetSecurityDescriptorDacl(ref saDesc, true, IntPtr.Zero, false)) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession set security descriptor failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); CloseHandle(hProcess); CloseHandle(hPToken); CloseHandle(hUserTokenDup); return 0; } IntPtr saDescPtr = Marshal.AllocHGlobal(Marshal.SizeOf(saDesc)); Marshal.StructureToPtr(saDesc, saDescPtr, false); SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES(); saAttr.nLength = Marshal.SizeOf(saAttr); saAttr.bInheritHandle = true; saAttr.lpSecurityDescriptor = saDescPtr; // Create a pipe to attach to the StdOut and StdErr outputs if (!CreatePipe(out hStdOutRead, out hStdOutWrite, ref saAttr, 0)) // use default buffer size { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create stdout pipe failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); CloseHandle(hProcess); CloseHandle(hPToken); CloseHandle(hUserTokenDup); return 0; } // Set the StartInfo structure information to use the redirect handles si.dwFlags |= StartFlags.STARTF_USESTDHANDLES; // Use custom redirect handles si.hStdOutput = hStdOutWrite; // Redirect StdOut (write into pipe handle) si.hStdError = hStdOutWrite; // Redirect StdErr (write into pipe handle) } // Create the environment IntPtr lpEnvironment = IntPtr.Zero; if (!CreateEnvironmentBlock(out lpEnvironment, hUserTokenDup, true)) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create environment failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Warning, true); lpEnvironment = IntPtr.Zero; } else dwCreationFlags |= CreationFlags.CREATE_UNICODE_ENVIRONMENT; // When environment is not null, this flag should be set // create a new process in the current user's logon session // Refer to http://stackoverflow.com/questions/4053241/windows-api-createprocess-path-with-space bool success = CreateProcessAsUser(hUserTokenDup, // client's access token applicationPath, // file to execute (no encapsulation) Util.FilePaths.FixSpaces(applicationPath) + " " + cmdParams, // command line - first param (argv[0]) should be encapsulated appPath ref sa, // pointer to process SECURITY_ATTRIBUTES ref sa, // pointer to thread SECURITY_ATTRIBUTES true, // handles are inheritable otherwise we can't redirect output dwCreationFlags, // creation flags lpEnvironment, // pointer to new environment block appStartDirectory, // name of current directory ref si, // pointer to STARTUPINFO structure out procInfo // receives information about new process ); if (!success) { int ret = Marshal.GetLastWin32Error(); log.WriteEntry("StartAppWithAdminPrivilegesFromNonUISession create process failed with error " + ret.ToString() + ". " + WinErrors.GetSystemMessage(ret), Log.LogEntryType.Error, true); } // invalidate the handles DestroyEnvironmentBlock(lpEnvironment); CloseHandle(hProcess); CloseHandle(hPToken); CloseHandle(hUserTokenDup); CloseHandle(hStdOutWrite); // We don't need this, close it now else the thread hangs // If we need to redirect output if (success && redirectOutput) { // Start the thread to read the process output - it'll close the procInfo (thread and process handles), hRead and hWrite handles when it's done Thread readOutput = new Thread(() => PipeReadThread(procInfo, hStdOutRead, processOutputHandler, log)); readOutput.IsBackground = true; // Kill the thread when the process terminates readOutput.Start(); } if (success) return procInfo.dwProcessId; else return 0; }
public static void Start() { if (_listenTask == null) { lock (typeof(Monitor)) { _cancellationTokenSource = new CancellationTokenSource(); bool wasCreated; var ewhSec = new EventWaitHandleSecurity(); ewhSec.AddAccessRule( new EventWaitHandleAccessRule( new SecurityIdentifier(WellKnownSidType.WorldSid, null), EventWaitHandleRights.FullControl, AccessControlType.Allow)); var sessionAckEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_BUFFER_READY", out wasCreated, ewhSec); var sessionReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_DATA_READY", out wasCreated, ewhSec); var globalAckEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_BUFFER_READY", out wasCreated, ewhSec); var globalReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_DATA_READY", out wasCreated, ewhSec); var sd = new SECURITY_DESCRIPTOR(); var sa = new SECURITY_ATTRIBUTES(); // Initialize the security descriptor. if (!Advapi32.InitializeSecurityDescriptor(ref sd, 1)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor.", Marshal.GetLastWin32Error())); } // Set information in a discretionary access control list if (!Advapi32.SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor", Marshal.GetLastWin32Error())); } // Create the event for slot 'DBWIN_BUFFER_READY' sa.nLength = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, sa.lpSecurityDescriptor, false); // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. var sessionSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (sessionSharedFileHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } // Create a view for this file mapping so we can access it var sessionSharedMemoryHandle = Kernel32.MapViewOfFile(sessionSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096); if (sessionSharedMemoryHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. var globalSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "Global\\DBWIN_BUFFER"); if (globalSharedFileHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } // Create a view for this file mapping so we can access it var globalSharedMemoryHandle = Kernel32.MapViewOfFile(globalSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096); if (globalSharedMemoryHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } var queue = new Queue <Tuple <int, DateTime, string> >(); var dataAvailable = new ManualResetEvent(true); _listenTask = Task.Factory.StartNew( () => { // Everything after the first DWORD is our debugging text IntPtr sessionStringPointer; IntPtr globalStringPointer; if (Environment.Is64BitProcess) { sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof(int))); globalStringPointer = new IntPtr(globalSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof(int))); } else { sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof(int))); globalStringPointer = new IntPtr(globalSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof(int))); } while (!_cancellationTokenSource.IsCancellationRequested) { sessionAckEvent.Set(); globalAckEvent.Set(); try { var i = WaitHandle.WaitAny(new[] { sessionReadyEvent, globalReadyEvent, _cancellationTokenSource.Token.WaitHandle }); var now = DateTime.Now; if (i == 0) { lock (queue) { queue.Enqueue(new Tuple <int, DateTime, string>(Marshal.ReadInt32(sessionSharedMemoryHandle), now, Marshal.PtrToStringAnsi(sessionStringPointer))); dataAvailable.Set(); } } if (i == 1) { lock (queue) { queue.Enqueue(new Tuple <int, DateTime, string>(Marshal.ReadInt32(globalSharedMemoryHandle), now, Marshal.PtrToStringAnsi(globalStringPointer))); dataAvailable.Set(); } } } catch { // it's over. _cancellationTokenSource.Cancel(); } } _listenTask = null; // cleanup after stopping. globalAckEvent.Reset(); globalAckEvent.Dispose(); globalAckEvent = null; sessionAckEvent.Reset(); sessionAckEvent.Dispose(); sessionAckEvent = null; globalReadyEvent.Reset(); globalReadyEvent.Dispose(); globalReadyEvent = null; sessionReadyEvent.Reset(); sessionReadyEvent.Dispose(); sessionReadyEvent = null; // Close SharedFile if (sessionSharedFileHandle != IntPtr.Zero) { if (!Kernel32.CloseHandle(sessionSharedFileHandle)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error())); } sessionSharedFileHandle = IntPtr.Zero; } // Unmap SharedMem if (sessionSharedMemoryHandle != IntPtr.Zero) { if (!Kernel32.UnmapViewOfFile(sessionSharedMemoryHandle)) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } sessionSharedMemoryHandle = IntPtr.Zero; } // Close SharedFile if (globalSharedFileHandle != IntPtr.Zero) { if (!Kernel32.CloseHandle(globalSharedFileHandle)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error())); } globalSharedFileHandle = IntPtr.Zero; } // Unmap SharedMem if (globalSharedMemoryHandle != IntPtr.Zero) { if (!Kernel32.UnmapViewOfFile(globalSharedMemoryHandle)) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } globalSharedMemoryHandle = IntPtr.Zero; } }, _cancellationTokenSource.Token); Task.Factory.StartNew(() => { // handle events on seperate task to minimize the work that is done blocking the handles Tuple <int, DateTime, string> item = null; while (WaitHandle.WaitAny(new[] { dataAvailable, _cancellationTokenSource.Token.WaitHandle }) == 0) { lock (queue) { if (queue.Count > 0) { item = queue.Dequeue(); } if (queue.Count == 0) { dataAvailable.Reset(); } } if (item == null || OnOutputDebugString == null) { continue; } try { OnOutputDebugString(new OutputDebugStringEventArgs(item.Item1, item.Item2, item.Item3)); } catch { // if it's taken, good, if not--well too bad! } } }, _cancellationTokenSource.Token); } } }
public static extern bool SetSecurityDescriptorOwner(ref SECURITY_DESCRIPTOR pSecurityDescriptor, IntPtr pOwner, bool bOwnerDefaulted);
public static void Start() { if (_listenTask == null) { lock (typeof (Monitor)) { _cancellationTokenSource = new CancellationTokenSource(); bool wasCreated; var ewhSec = new EventWaitHandleSecurity(); ewhSec.AddAccessRule( new EventWaitHandleAccessRule( new SecurityIdentifier(WellKnownSidType.WorldSid, null), EventWaitHandleRights.FullControl, AccessControlType.Allow)); var sessionAckEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_BUFFER_READY", out wasCreated, ewhSec); var sessionReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "DBWIN_DATA_READY", out wasCreated, ewhSec); var globalAckEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_BUFFER_READY", out wasCreated, ewhSec); var globalReadyEvent = new EventWaitHandle(false, EventResetMode.AutoReset, "Global\\DBWIN_DATA_READY", out wasCreated, ewhSec); var sd = new SECURITY_DESCRIPTOR(); var sa = new SECURITY_ATTRIBUTES(); // Initialize the security descriptor. if (!Advapi32.InitializeSecurityDescriptor(ref sd, 1)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor.", Marshal.GetLastWin32Error())); } // Set information in a discretionary access control list if (!Advapi32.SetSecurityDescriptorDacl(ref sd, true, IntPtr.Zero, false)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to initializes the security descriptor", Marshal.GetLastWin32Error())); } // Create the event for slot 'DBWIN_BUFFER_READY' sa.nLength = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(sd)); Marshal.StructureToPtr(sd, sa.lpSecurityDescriptor, false); // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. var sessionSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "DBWIN_BUFFER"); if (sessionSharedFileHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } // Create a view for this file mapping so we can access it var sessionSharedMemoryHandle = Kernel32.MapViewOfFile(sessionSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096); if (sessionSharedMemoryHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } // Get a handle to the readable shared memory at slot 'DBWIN_BUFFER'. var globalSharedFileHandle = Kernel32.CreateFileMapping(new IntPtr(-1), ref sa, PageProtection.ReadWrite, 0, 4096, "Global\\DBWIN_BUFFER"); if (globalSharedFileHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a file mapping to slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } // Create a view for this file mapping so we can access it var globalSharedMemoryHandle = Kernel32.MapViewOfFile(globalSharedFileHandle, /*SECTION_MAP_READ*/ 0x0004, 0, 0, 4096); if (globalSharedMemoryHandle == IntPtr.Zero) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to create a mapping view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } var queue = new Queue<Tuple<int, DateTime, string>>(); var dataAvailable = new ManualResetEvent(true); _listenTask = Task.Factory.StartNew( () => { // Everything after the first DWORD is our debugging text IntPtr sessionStringPointer; IntPtr globalStringPointer; if (Environment.Is64BitProcess) { sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof (int))); globalStringPointer = new IntPtr(globalSharedMemoryHandle.ToInt64() + Marshal.SizeOf(typeof (int))); } else { sessionStringPointer = new IntPtr(sessionSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof (int))); globalStringPointer = new IntPtr(globalSharedMemoryHandle.ToInt32() + Marshal.SizeOf(typeof (int))); } while (!_cancellationTokenSource.IsCancellationRequested) { sessionAckEvent.Set(); globalAckEvent.Set(); try { var i = WaitHandle.WaitAny(new[] { sessionReadyEvent, globalReadyEvent, _cancellationTokenSource.Token.WaitHandle }); var now = DateTime.Now; if (i == 0) { lock (queue) { queue.Enqueue(new Tuple<int, DateTime, string>(Marshal.ReadInt32(sessionSharedMemoryHandle), now, Marshal.PtrToStringAnsi(sessionStringPointer))); dataAvailable.Set(); } } if (i == 1) { lock (queue) { queue.Enqueue(new Tuple<int, DateTime, string>(Marshal.ReadInt32(globalSharedMemoryHandle), now, Marshal.PtrToStringAnsi(globalStringPointer))); dataAvailable.Set(); } } } catch { // it's over. _cancellationTokenSource.Cancel(); } } _listenTask = null; // cleanup after stopping. globalAckEvent.Reset(); globalAckEvent.Dispose(); globalAckEvent = null; sessionAckEvent.Reset(); sessionAckEvent.Dispose(); sessionAckEvent = null; globalReadyEvent.Reset(); globalReadyEvent.Dispose(); globalReadyEvent = null; sessionReadyEvent.Reset(); sessionReadyEvent.Dispose(); sessionReadyEvent = null; // Close SharedFile if (sessionSharedFileHandle != IntPtr.Zero) { if (!Kernel32.CloseHandle(sessionSharedFileHandle)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error())); } sessionSharedFileHandle = IntPtr.Zero; } // Unmap SharedMem if (sessionSharedMemoryHandle != IntPtr.Zero) { if (!Kernel32.UnmapViewOfFile(sessionSharedMemoryHandle)) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } sessionSharedMemoryHandle = IntPtr.Zero; } // Close SharedFile if (globalSharedFileHandle != IntPtr.Zero) { if (!Kernel32.CloseHandle(globalSharedFileHandle)) { throw new ApplicationException( string.Format("{0}. Last Win32 Error was {1}", "Failed to close handle for 'SharedFile'", Marshal.GetLastWin32Error())); } globalSharedFileHandle = IntPtr.Zero; } // Unmap SharedMem if (globalSharedMemoryHandle != IntPtr.Zero) { if (!Kernel32.UnmapViewOfFile(globalSharedMemoryHandle)) { throw new ApplicationException( string.Format( "{0}. Last Win32 Error was {1}", "Failed to unmap view for slot 'Global\\DBWIN_BUFFER'", Marshal.GetLastWin32Error())); } globalSharedMemoryHandle = IntPtr.Zero; } }, _cancellationTokenSource.Token); Task.Factory.StartNew(() => { // handle events on seperate task to minimize the work that is done blocking the handles Tuple<int, DateTime, string> item = null; while (WaitHandle.WaitAny(new[] { dataAvailable, _cancellationTokenSource.Token.WaitHandle }) == 0) { lock (queue) { if (queue.Count > 0) { item = queue.Dequeue(); } if (queue.Count == 0) { dataAvailable.Reset(); } } if (item == null || OnOutputDebugString == null) { continue; } try { OnOutputDebugString(new OutputDebugStringEventArgs(item.Item1, item.Item2, item.Item3)); } catch { // if it's taken, good, if not--well too bad! } } }, _cancellationTokenSource.Token); } } }
public static extern bool InitializeSecurityDescriptor(SECURITY_DESCRIPTOR SD, int revision);
public static extern bool InitializeSecurityDescriptor(out SECURITY_DESCRIPTOR SecurityDescriptor, uint dwRevision);
public static extern bool QueryServiceObjectSecurity(IntPtr serviceHandle, System.Security.AccessControl.SecurityInfos secInfo, ref SECURITY_DESCRIPTOR lpSecDesrBuf, uint bufSize, out uint bufSizeNeeded);
public static extern bool SetFileSecurity(string lpFileName, UInt32 SecurityInformation, ref SECURITY_DESCRIPTOR pSecurityDescriptor);
public DebugMonitor() { SECURITY_ATTRIBUTES attributes = new SECURITY_ATTRIBUTES(); SECURITY_DESCRIPTOR descriptor = new SECURITY_DESCRIPTOR(); IntPtr sharedFile = IntPtr.Zero; IntPtr pDescriptor = IntPtr.Zero; IntPtr pAttributes = IntPtr.Zero; try { pDescriptor = Marshal.AllocHGlobal(Marshal.SizeOf(descriptor)); pAttributes = Marshal.AllocHGlobal(Marshal.SizeOf(attributes)); attributes.nLength = Marshal.SizeOf(attributes); attributes.bInheritHandle = true; attributes.lpSecurityDescriptor = pDescriptor; if (!InitializeSecurityDescriptor(ref descriptor, 1 /*SECURITY_DESCRIPTOR_REVISION*/)) throw new ApplicationException("InitializeSecurityDescriptor failed: " + Marshal.GetLastWin32Error()); if (!SetSecurityDescriptorDacl(ref descriptor, true, IntPtr.Zero, false)) throw new ApplicationException("SetSecurityDescriptorDacl failed: " + Marshal.GetLastWin32Error()); Marshal.StructureToPtr(descriptor, pDescriptor, false); Marshal.StructureToPtr(attributes, pAttributes, false); bufferEvent = CreateEvent(pAttributes, false, false, "DBWIN_BUFFER_READY"); if (bufferEvent == IntPtr.Zero) throw new ApplicationException("CreateEvent (bufferEvent) failed: " + Marshal.GetLastWin32Error()); if (Marshal.GetLastWin32Error() == 183 /*ERROR_ALREADY_EXISTS*/) throw new AlreadyRunningException(); dataEvent = CreateEvent(pAttributes, false, false, "DBWIN_DATA_READY"); if (dataEvent == IntPtr.Zero) throw new ApplicationException("CreateEvent (dataEvent) failed: " + Marshal.GetLastWin32Error()); sharedFile = CreateFileMapping(new IntPtr(-1), pAttributes, 4 /*PAGE_READWRITE*/, 0, 4096, "DBWIN_BUFFER"); if (sharedFile == IntPtr.Zero) throw new ApplicationException("CreateFileMapping failed: " + Marshal.GetLastWin32Error()); } finally { Marshal.FreeHGlobal(pDescriptor); Marshal.FreeHGlobal(pAttributes); } IntPtr sharedMemory = MapViewOfFile(sharedFile, 4 /*FILE_MAP_READ*/, 0, 0, 512); if (sharedMemory == IntPtr.Zero) throw new ApplicationException("MapViewOfFile failed: " + Marshal.GetLastWin32Error()); // The first 4 bytes are the process ID, and the remaining bytes are the message pPID = sharedMemory; pMessage = new IntPtr((long)sharedMemory + 4); }