private uint WaitForAll(uint dwTimeout) { return(SafeNativeMethods.WaitForMultipleObjects(this.nativeHandles, true, dwTimeout)); }
private static void FillRectanglesImpl(Graphics g, Color color, Rectangle[] rects) { uint nativeColor = (uint)(color.R + (color.G << 8) + (color.B << 16)); IntPtr hdc = IntPtr.Zero; IntPtr brush = IntPtr.Zero; IntPtr oldObject = IntPtr.Zero; try { hdc = g.GetHdc(); brush = SafeNativeMethods.CreateSolidBrush(nativeColor); if (brush == IntPtr.Zero) { NativeMethods.ThrowOnWin32Error("CreateSolidBrush returned NULL"); } oldObject = SafeNativeMethods.SelectObject(hdc, brush); foreach (Rectangle rect in rects) { NativeStructs.RECT nativeRect; nativeRect.left = rect.Left; nativeRect.top = rect.Top; nativeRect.right = rect.Right; nativeRect.bottom = rect.Bottom; int result = SafeNativeMethods.FillRect(hdc, ref nativeRect, brush); if (result == 0) { NativeMethods.ThrowOnWin32Error("FillRect returned zero"); } } } finally { if (oldObject != IntPtr.Zero) { SafeNativeMethods.SelectObject(hdc, oldObject); oldObject = IntPtr.Zero; } if (brush != IntPtr.Zero) { SafeNativeMethods.DeleteObject(brush); brush = IntPtr.Zero; } if (hdc != IntPtr.Zero) { g.ReleaseHdc(hdc); hdc = IntPtr.Zero; } } GC.KeepAlive(g); }
/// <summary> /// Waits for any of the WaitHandles to be signaled. /// </summary> /// <returns> /// The index of the first item in the array that completed the wait operation. /// If this value is outside the bounds of the array, it is an indication of an /// error. /// </returns> public int WaitAny() { int returnVal = (int)SafeNativeMethods.WaitForMultipleObjects(this.nativeHandles, false, NativeConstants.INFINITE); return(returnVal); }
internal unsafe static void GetRegionScans(IntPtr hRgn, out Rectangle[] scans, out int area) { uint bytes = 0; int countdown = screwUpMax; int error = 0; // HACK: It seems that sometimes the GetRegionData will return ERROR_INVALID_HANDLE // even though the handle (the HRGN) is fine. Maybe the function is not // re-entrant? I'm not sure, but trying it again seems to fix it. while (countdown > 0) { bytes = SafeNativeMethods.GetRegionData(hRgn, 0, (NativeStructs.RGNDATA *)IntPtr.Zero); error = Marshal.GetLastWin32Error(); if (bytes == 0) { --countdown; System.Threading.Thread.Sleep(5); } else { break; } } // But if we retry several times and it still messes up then we will finally give up. if (bytes == 0) { throw new Win32Exception(error, "GetRegionData returned " + bytes.ToString() + ", GetLastError() = " + error.ToString()); } byte *data; // Up to 512 bytes, allocate on the stack. Otherwise allocate from the heap. if (bytes <= 512) { byte *data1 = stackalloc byte[(int)bytes]; data = data1; } else { data = (byte *)Memory.Allocate(bytes).ToPointer(); } try { NativeStructs.RGNDATA *pRgnData = (NativeStructs.RGNDATA *)data; uint result = SafeNativeMethods.GetRegionData(hRgn, bytes, pRgnData); if (result != bytes) { throw new OutOfMemoryException("SafeNativeMethods.GetRegionData returned 0"); } NativeStructs.RECT *pRects = NativeStructs.RGNDATA.GetRectsPointer(pRgnData); scans = new Rectangle[pRgnData->rdh.nCount]; area = 0; for (int i = 0; i < scans.Length; ++i) { scans[i] = Rectangle.FromLTRB(pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom); area += scans[i].Width * scans[i].Height; } pRects = null; pRgnData = null; } finally { if (bytes > 512) { Memory.Free(new IntPtr(data)); } } }
private static void DrawPolyLineImpl(Graphics g, Color color, Point[] points) { if (points.Length < 1) { return; } uint nativeColor = (uint)(color.R + (color.G << 8) + (color.B << 16)); IntPtr hdc = IntPtr.Zero; IntPtr pen = IntPtr.Zero; IntPtr oldObject = IntPtr.Zero; try { hdc = g.GetHdc(); pen = SafeNativeMethods.CreatePen(NativeConstants.PS_SOLID, 1, nativeColor); if (pen == IntPtr.Zero) { NativeMethods.ThrowOnWin32Error("CreatePen returned NULL"); } oldObject = SafeNativeMethods.SelectObject(hdc, pen); NativeStructs.POINT pt; bool bResult = SafeNativeMethods.MoveToEx(hdc, points[0].X, points[0].Y, out pt); if (!bResult) { NativeMethods.ThrowOnWin32Error("MoveToEx returned false"); } for (int i = 1; i < points.Length; ++i) { bResult = SafeNativeMethods.LineTo(hdc, points[i].X, points[i].Y); if (!bResult) { NativeMethods.ThrowOnWin32Error("LineTo returned false"); } } } finally { if (oldObject != IntPtr.Zero) { SafeNativeMethods.SelectObject(hdc, oldObject); oldObject = IntPtr.Zero; } if (pen != IntPtr.Zero) { SafeNativeMethods.DeleteObject(pen); pen = IntPtr.Zero; } if (hdc != IntPtr.Zero) { g.ReleaseHdc(hdc); hdc = IntPtr.Zero; } } GC.KeepAlive(g); }
private static int ExecRequireNonAdmin(IWin32Window parent, string exePath, string args, out IntPtr hProcess) { int nError = NativeConstants.ERROR_SUCCESS; string commandLine = "\"" + exePath + "\"" + (args == null ? "" : (" " + args)); string dir; try { dir = Path.GetDirectoryName(exePath); } catch (Exception) { dir = null; } IntPtr hWndShell = IntPtr.Zero; IntPtr hShellProcess = IntPtr.Zero; IntPtr hShellProcessToken = IntPtr.Zero; IntPtr hTokenCopy = IntPtr.Zero; IntPtr bstrExePath = IntPtr.Zero; IntPtr bstrCommandLine = IntPtr.Zero; IntPtr bstrDir = IntPtr.Zero; NativeStructs.PROCESS_INFORMATION procInfo = new NativeStructs.PROCESS_INFORMATION(); try { hWndShell = SafeNativeMethods.FindWindowW("Progman", null); if (hWndShell == IntPtr.Zero) { NativeMethods.ThrowOnWin32Error("FindWindowW() returned NULL"); } uint dwPID; uint dwThreadId = SafeNativeMethods.GetWindowThreadProcessId(hWndShell, out dwPID); if (0 == dwPID) { NativeMethods.ThrowOnWin32Error("GetWindowThreadProcessId returned 0", NativeErrors.ERROR_FILE_NOT_FOUND); } hShellProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_QUERY_INFORMATION, false, dwPID); if (IntPtr.Zero == hShellProcess) { NativeMethods.ThrowOnWin32Error("OpenProcess() returned NULL"); } bool optResult = NativeMethods.OpenProcessToken( hShellProcess, NativeConstants.TOKEN_ASSIGN_PRIMARY | NativeConstants.TOKEN_DUPLICATE | NativeConstants.TOKEN_QUERY, out hShellProcessToken); if (!optResult) { NativeMethods.ThrowOnWin32Error("OpenProcessToken() returned FALSE"); } bool dteResult = NativeMethods.DuplicateTokenEx( hShellProcessToken, NativeConstants.MAXIMUM_ALLOWED, IntPtr.Zero, NativeConstants.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, NativeConstants.TOKEN_TYPE.TokenPrimary, out hTokenCopy); if (!dteResult) { NativeMethods.ThrowOnWin32Error("DuplicateTokenEx() returned FALSE"); } bstrExePath = Marshal.StringToBSTR(exePath); bstrCommandLine = Marshal.StringToBSTR(commandLine); bstrDir = Marshal.StringToBSTR(dir); bool cpwtResult = NativeMethods.CreateProcessWithTokenW( hTokenCopy, 0, bstrExePath, bstrCommandLine, 0, IntPtr.Zero, bstrDir, IntPtr.Zero, out procInfo); if (cpwtResult) { hProcess = procInfo.hProcess; procInfo.hProcess = IntPtr.Zero; nError = NativeConstants.ERROR_SUCCESS; } else { hProcess = IntPtr.Zero; nError = Marshal.GetLastWin32Error(); } } catch (Win32Exception ex) { Tracing.Ping(ex.ToString()); nError = ex.ErrorCode; hProcess = IntPtr.Zero; } finally { if (bstrExePath != IntPtr.Zero) { Marshal.FreeBSTR(bstrExePath); bstrExePath = IntPtr.Zero; } if (bstrCommandLine != IntPtr.Zero) { Marshal.FreeBSTR(bstrCommandLine); bstrCommandLine = IntPtr.Zero; } if (bstrDir != IntPtr.Zero) { Marshal.FreeBSTR(bstrDir); bstrDir = IntPtr.Zero; } if (hShellProcess != IntPtr.Zero) { SafeNativeMethods.CloseHandle(hShellProcess); hShellProcess = IntPtr.Zero; } if (hShellProcessToken != IntPtr.Zero) { SafeNativeMethods.CloseHandle(hShellProcessToken); hShellProcessToken = IntPtr.Zero; } if (hTokenCopy != IntPtr.Zero) { SafeNativeMethods.CloseHandle(hTokenCopy); hTokenCopy = IntPtr.Zero; } if (procInfo.hThread != IntPtr.Zero) { SafeNativeMethods.CloseHandle(procInfo.hThread); procInfo.hThread = IntPtr.Zero; } if (procInfo.hProcess != IntPtr.Zero) { SafeNativeMethods.CloseHandle(procInfo.hProcess); procInfo.hProcess = IntPtr.Zero; } } return(nError); }
/// <summary> /// Manages some special handling of window messages. /// </summary> /// <param name="m"></param> /// <returns>true if the message was handled, false if the caller should handle the message.</returns> public bool HandleParentWndProc(ref Message m) { bool returnVal = true; switch (m.Msg) { case NativeConstants.WM_NCPAINT: goto default; case NativeConstants.WM_NCACTIVATE: if (this.forceActiveTitleBar && m.WParam == IntPtr.Zero) { if (ignoreNcActivate > 0) { --ignoreNcActivate; goto default; } else if (Form.ActiveForm != this.host || // Gets rid of: if you have the form active, then click on the desktop --> desktop refreshes !this.host.Visible) // Gets rid of: desktop refresh on exit { goto default; } else { // Only 'lock' for the topmost form in the application. Otherwise you get the whole system // refreshing (i.e. the dreaded "repaint the whole desktop 5 times" glitch) when you do things // like minimize the window // And only lock if we aren't minimized. Otherwise the desktop refreshes. bool locked = false; if (this.host.Owner == null && this.host.WindowState != FormWindowState.Minimized) { //UI.SetControlRedraw(this.host, false); locked = true; } this.realParentWndProc(ref m); SafeNativeMethods.SendMessageW(this.host.Handle, NativeConstants.WM_NCACTIVATE, new IntPtr(1), IntPtr.Zero); if (locked) { //UI.SetControlRedraw(this.host, true); //this.host.Invalidate(true); } break; } } else { goto default; } case NativeConstants.WM_ACTIVATE: goto default; case NativeConstants.WM_ACTIVATEAPP: this.realParentWndProc(ref m); // Check if the app is being deactivated if (this.forceActiveTitleBar && m.WParam == IntPtr.Zero) { // If so, put our titlebar in the inactive state SafeNativeMethods.PostMessageW(this.host.Handle, NativeConstants.WM_NCACTIVATE, IntPtr.Zero, IntPtr.Zero); ++ignoreNcActivate; } if (m.WParam == new IntPtr(1)) { foreach (Form childForm in this.host.OwnedForms) { FormEx childFormEx = FindFormEx(childForm); if (childFormEx != null) { if (childFormEx.ForceActiveTitleBar && childForm.IsHandleCreated) { SafeNativeMethods.PostMessageW(childForm.Handle, NativeConstants.WM_NCACTIVATE, new IntPtr(1), IntPtr.Zero); } } } FormEx ownerEx = FindFormEx(this.host.Owner); if (ownerEx != null) { if (ownerEx.ForceActiveTitleBar && this.host.Owner.IsHandleCreated) { SafeNativeMethods.PostMessageW(this.host.Owner.Handle, NativeConstants.WM_NCACTIVATE, new IntPtr(1), IntPtr.Zero); } } } break; default: returnVal = false; break; } GC.KeepAlive(this.host); return(returnVal); }
/// <summary> /// Uses the shell to execute the command. This method must only be used by Paint.NET /// and not by plugins. /// </summary> /// <param name="parent"> /// The window that is currently in the foreground. This may be null if requireAdmin /// is false and the executable that exePath refers to is not marked (e.g. via a /// manifest) as requiring administrator privilege. /// </param> /// <param name="exePath"> /// The path to the executable to launch. /// </param> /// <param name="args"> /// The command-line arguments for the executable. /// </param> /// <param name="execPrivilege"> /// The privileges to execute the new process with. /// If the executable is already marked as requiring administrator privilege /// (e.g. via a "requiresAdministrator" UAC manifest), this parameter should be /// set to AsInvokerOrAsManifest. /// </param> /// <remarks> /// If administrator privilege is required, a consent UI may be displayed asking the /// user to approve the action. A parent window must be provided in this case so that /// the consent UI will know where to position itself. Administrator privilege is /// required if execPrivilege is set to RequireAdmin, or if the executable being launched /// has a manifest declaring that it requires this privilege and if the operating /// system recognizes the manifest. /// </remarks> /// <exception cref="ArgumentException"> /// execPrivilege was RequireAdmin, but parent was null. /// </exception> /// <exception cref="SecurityException"> /// execPrivilege was RequireAdmin, but the user does not have this privilege, nor do they /// have the ability to acquire or elevate to obtain this privilege. /// </exception> /// <exception cref="Win32Exception"> /// There was an error launching the program. /// </exception> public static void Execute( IWin32Window parent, string exePath, string args, ExecutePrivilege execPrivilege, ExecuteWaitType execWaitType) { if (exePath == null) { throw new ArgumentNullException("exePath"); } if (execPrivilege == ExecutePrivilege.RequireAdmin && parent == null) { throw new ArgumentException("If requireAdmin is true, a parent window must be provided"); } // If this action requires admin privilege, but the user does not have this // privilege and is not capable of acquiring this privilege, then we will // throw an exception. if (execPrivilege == ExecutePrivilege.RequireAdmin && !Security.IsAdministrator && !Security.CanElevateToAdministrator) { throw new SecurityException("Executable requires administrator privilege, but user is not an administrator and cannot elevate"); } ExecuteHandOff executeHandOff = null; switch (execPrivilege) { case ExecutePrivilege.AsInvokerOrAsManifest: executeHandOff = new ExecuteHandOff(ExecAsInvokerOrAsManifest); break; case ExecutePrivilege.RequireAdmin: executeHandOff = new ExecuteHandOff(ExecRequireAdmin); break; case ExecutePrivilege.RequireNonAdminIfPossible: if (Security.CanLaunchNonAdminProcess) { executeHandOff = new ExecuteHandOff(ExecRequireNonAdmin); } else { executeHandOff = new ExecuteHandOff(ExecAsInvokerOrAsManifest); } break; default: throw new InvalidEnumArgumentException("ExecutePrivilege"); } string updateMonitorExePath = null; if (execWaitType == ExecuteWaitType.RelaunchPdnOnExit) { RelaunchPdnHelperPart1(out updateMonitorExePath); } IntPtr hProcess = IntPtr.Zero; int nResult = executeHandOff(parent, exePath, args, out hProcess); if (nResult == NativeConstants.ERROR_SUCCESS) { if (execWaitType == ExecuteWaitType.WaitForExit) { SafeNativeMethods.WaitForSingleObject(hProcess, NativeConstants.INFINITE); } else if (execWaitType == ExecuteWaitType.RelaunchPdnOnExit) { bool bResult2 = SafeNativeMethods.SetHandleInformation( hProcess, NativeConstants.HANDLE_FLAG_INHERIT, NativeConstants.HANDLE_FLAG_INHERIT); RelaunchPdnHelperPart2(updateMonitorExePath, hProcess); // Ensure that we don't close the process handle right away in the next few lines of code. // It must be inherited by the child process. Yes, this is technically a leak but we are // planning to terminate in just a moment anyway. hProcess = IntPtr.Zero; } else if (execWaitType == ExecuteWaitType.ReturnImmediately) { } if (hProcess != IntPtr.Zero) { SafeNativeMethods.CloseHandle(hProcess); hProcess = IntPtr.Zero; } } else { if (nResult == NativeConstants.ERROR_CANCELLED || nResult == NativeConstants.ERROR_TIMEOUT) { // no problem } else { NativeMethods.ThrowOnWin32Error("ExecuteHandoff failed", nResult); } if (updateMonitorExePath != null) { try { File.Delete(updateMonitorExePath); } catch (Exception) { } updateMonitorExePath = null; } } GC.KeepAlive(parent); }
// TODO: get rid of this somehow! (this will happen when Layers window is rewritten, post-3.0) public static bool HideHorizontalScrollBar(Control c) { return(SafeNativeMethods.ShowScrollBar(c.Handle, NativeConstants.SB_HORZ, false)); }
/// <summary> /// Sets the control's redraw state. /// </summary> /// <param name="control">The control whose state should be modified.</param> /// <param name="enabled">The new state for redrawing ability.</param> /// <remarks> /// Note to implementors: This method is used by SuspendControlPainting() and ResumeControlPainting(). /// This may be implemented as a no-op. /// </remarks> private static void SetControlRedrawImpl(Control control, bool enabled) { SafeNativeMethods.SendMessageW(control.Handle, NativeConstants.WM_SETREDRAW, enabled ? new IntPtr(1) : IntPtr.Zero, IntPtr.Zero); GC.KeepAlive(control); }
public static void SetToZero(void *dst, ulong length) { SafeNativeMethods.memset(dst, 0, new UIntPtr(length)); }
/// <summary> /// Copies bytes from one area of memory to another. Since this function only /// takes pointers, it can not do any bounds checking. /// </summary> /// <param name="dst">The starting address of where to copy bytes to.</param> /// <param name="src">The starting address of where to copy bytes from.</param> /// <param name="length">The number of bytes to copy</param> public static void Copy(void *dst, void *src, ulong length) { SafeNativeMethods.memcpy(dst, src, new UIntPtr(length)); }