Esempio n. 1
0
 private uint WaitForAll(uint dwTimeout)
 {
     return(SafeNativeMethods.WaitForMultipleObjects(this.nativeHandles, true, dwTimeout));
 }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        /// <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);
        }
Esempio n. 4
0
        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));
                }
            }
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        /// <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);
        }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 9
0
 // 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));
 }
Esempio n. 10
0
 /// <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);
 }
Esempio n. 11
0
 public static void SetToZero(void *dst, ulong length)
 {
     SafeNativeMethods.memset(dst, 0, new UIntPtr(length));
 }
Esempio n. 12
0
 /// <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));
 }