[.NET] - Allow file drop with UAC turned on.

Discussion in 'Mixed Languages' started by Josh Cell, May 18, 2013.

  1. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,513
    7,174
    120
    #1 Josh Cell, May 18, 2013
    Last edited by a moderator: Apr 20, 2017
    Well, I am having troubles with these UAC rules.

    Simply I can not drop any file to any form when it is activated and when the program is running as admin.

    I have tried many ways to bypass it but currently is not working on Windows 8.

    Here is my fail ways:

    Code:
            [DllImport("user32.dll", SetLastError = true)]
            static extern bool ChangeWindowMessageFilter(uint message, uint dwFlag);
    
            private const uint WM_DROPFILES = 0x233;
            private const uint WM_COPYDATA = 0x004A;
            private const uint WM_COPYGLOBALDATA = 0x0049;
            private const uint MSGFLT_ADD = 1;
    
            [DllImport("shell32.dll")]
            static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);
    
                ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
                ChangeWindowMessageFilter(WM_COPYDATA, MSGFLT_ADD);
                ChangeWindowMessageFilter(WM_COPYGLOBALDATA, MSGFLT_ADD);
                DragAcceptFiles(this.Handle, true);
    FROM: http://helgeklein.com/blog/2010/03/...n-elevated-mfc-application-on-vistawindows-7/

    And

    Code:
    using System;
    using System.IO;
    using System.Reflection;
    using System.Security;
    using System.Security.Permissions;
    using System.Collections;
    using System.Security.Policy;
    
    [assembly: AssemblyVersion("1.1.0.0")]
    namespace ShadowLauncher {
        static class Program {
            [STAThread]
            static int Main(string[] args) {
                if (args.Length == 0 || !File.Exists(args[0]))
                    return 1;
    
                var assembly = args[0];
                var realArgs = new string[args.Length - 1];
                if (realArgs.Length > 0)
                    Array.Copy(args, 1, realArgs, 0, realArgs.Length);
    
                var permissions = new PermissionSet(PermissionState.Unrestricted);
    
                AppDomain.CreateDomain(Path.GetFileNameWithoutExtension(assembly),
                    AppDomain.CurrentDomain.Evidence,
                    new AppDomainSetup {
                        ShadowCopyFiles = "true",
                        ConfigurationFile = assembly + ".config",
                        ApplicationBase = Path.GetDirectoryName(Path.GetFullPath(assembly))
                    },
                    permissions
                ).ExecuteAssembly(assembly, AppDomain.CurrentDomain.Evidence, realArgs);
                return 0;
            }
        }
    }
    FROM: http://stackoverflow.com/questions/...on-dragdrop-doesnt-work-when-called-in-memory

    Code:
     
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, ChangeWindowMessageFilterExAction action, ref CHANGEFILTERSTRUCT changeInfo);
    
            public enum MessageFilterInfo : uint
            {
                None = 0, AlreadyAllowed = 1, AlreadyDisAllowed = 2, AllowedHigher = 3
            };
    
            public enum ChangeWindowMessageFilterExAction : uint
            {
                Reset = 0, Allow = 1, DisAllow = 2
            };
    
            [StructLayout(LayoutKind.Sequential)]
            public struct CHANGEFILTERSTRUCT
            {
                public uint size;
                public MessageFilterInfo info;
            }
    
    
               ChangeWindowMessageFilterEx(this.Handle, WM_DROPFILES, ChangeWindowMessageFilterExAction.Allow, ref T);
    
                ChangeWindowMessageFilterEx(this.Handle, WM_COPYDATA, ChangeWindowMessageFilterExAction.Allow, ref T);
                ChangeWindowMessageFilterEx(this.Handle, WM_COPYGLOBALDATA, ChangeWindowMessageFilterExAction.Allow, ref T);
    I also have tried to modify these codes, add all that before and after invoking the main window and nothing else.

    Can anyone help me? :worthy::worthy::worthy:
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. Alphawaves

    Alphawaves Super Moderator/Developer
    Staff Member

    Aug 11, 2008
    6,250
    22,354
    210
    #2 Alphawaves, May 18, 2013
    Last edited by a moderator: Apr 20, 2017
    From here:
    http://www.mpgh.net/forum/33-visual...r-prevents-drag-drop-working.html#post7218272

    I converted it to c#
    Code:
    public class ElevatedDragDropManager : IMessageFilter
        {
    
            #region "P/Invoke"
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, ChangeWindowMessageFilterExAction action, ref CHANGEFILTERSTRUCT changeInfo);
    
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags);
    
            [DllImport("shell32.dll")]
            private static extern void DragAcceptFiles(IntPtr hwnd, bool fAccept);
    
            [DllImport("shell32.dll")]
            private static extern uint DragQueryFile(IntPtr hDrop, uint iFile, [Out()]
    StringBuilder lpszFile, uint cch);
    
            [DllImport("shell32.dll")]
            private static extern bool DragQueryPoint(IntPtr hDrop, ref POINT lppt);
    
            [DllImport("shell32.dll")]
            private static extern void DragFinish(IntPtr hDrop);
    
            [StructLayout(LayoutKind.Sequential)]
            private struct POINT
            {
                public int X;
    
                public int Y;
                public POINT(int newX, int newY)
                {
                    X = newX;
                    Y = newY;
                }
    
                public static implicit operator System.Drawing.Point(POINT p)
                {
                    return new System.Drawing.Point(p.X, p.Y);
                }
    
                public static implicit operator POINT(System.Drawing.Point p)
                {
                    return new POINT(p.X, p.Y);
                }
            }
    
            private enum MessageFilterInfo : uint
            {
                None,
                AlreadyAllowed,
                AlreadyDisAllowed,
                AllowedHigher
            }
    
            private enum ChangeWindowMessageFilterExAction : uint
            {
                Reset,
                Allow,
                Disallow
            }
    
            private enum ChangeWindowMessageFilterFlags : uint
            {
                Add = 1,
                Remove = 2
            }
    
            [StructLayout(LayoutKind.Sequential)]
            private struct CHANGEFILTERSTRUCT
            {
                public uint cbSize;
                public MessageFilterInfo ExtStatus;
            }
            #endregion
    
            public static ElevatedDragDropManager Instance = new ElevatedDragDropManager();
            public event EventHandler<ElevatedDragDropArgs> ElevatedDragDrop;
    
            private const uint WM_DROPFILES = 0x233;
            private const uint WM_COPYDATA = 0x4a;
    
            private const uint WM_COPYGLOBALDATA = 0x49;
            private readonly bool IsVistaOrHigher = Environment.OSVersion.Version.Major >= 6;
    
            private readonly bool Is7OrHigher = (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1) || Environment.OSVersion.Version.Major > 6;
            protected ElevatedDragDropManager()
            {
                Application.AddMessageFilter(this);
            }
    
            public void EnableDragDrop(IntPtr hWnd)
            {
                if (Is7OrHigher)
                {
                    CHANGEFILTERSTRUCT changeStruct = new CHANGEFILTERSTRUCT();
                    changeStruct.cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(CHANGEFILTERSTRUCT)));
                    ChangeWindowMessageFilterEx(hWnd, WM_DROPFILES, ChangeWindowMessageFilterExAction.Allow, ref changeStruct);
                    ChangeWindowMessageFilterEx(hWnd, WM_COPYDATA, ChangeWindowMessageFilterExAction.Allow, ref changeStruct);
                    ChangeWindowMessageFilterEx(hWnd, WM_COPYGLOBALDATA, ChangeWindowMessageFilterExAction.Allow, ref changeStruct);
                }
                else if (IsVistaOrHigher)
                {
                    ChangeWindowMessageFilter(WM_DROPFILES, ChangeWindowMessageFilterFlags.Add);
                    ChangeWindowMessageFilter(WM_COPYDATA, ChangeWindowMessageFilterFlags.Add);
                    ChangeWindowMessageFilter(WM_COPYGLOBALDATA, ChangeWindowMessageFilterFlags.Add);
                }
    
                DragAcceptFiles(hWnd, true);
            }
    
            public bool PreFilterMessage(ref Message m)
            {
                if (m.Msg == WM_DROPFILES)
                {
                    HandleDragDropMessage(m);
                    return true;
                }
    
                return false;
            }
    
            private void HandleDragDropMessage(Message m)
            {
                dynamic sb = new StringBuilder(260);
                uint numFiles = DragQueryFile(m.WParam, 0xffffffffu, sb, 0);
                dynamic list = new List<string>();
    
                for (uint i = 0; i <= numFiles - 1; i++)
                {
                    if (DragQueryFile(m.WParam, i, sb, Convert.ToUInt32(sb.Capacity) * 2) > 0)
                    {
                        list.Add(sb.ToString());
                    }
                }
    
                POINT p = default(POINT);
                DragQueryPoint(m.WParam, ref p);
                DragFinish(m.WParam);
    
                dynamic args = new ElevatedDragDropArgs();
                args.HWnd = m.HWnd;
                args.Files = list;
                args.X = p.X;
                args.Y = p.Y;
    
                if (ElevatedDragDrop != null)
                {
                    ElevatedDragDrop(this, args);
                }
            }
        }
    
        public class ElevatedDragDropArgs : EventArgs
        {
            public IntPtr HWnd
            {
                get { return m_HWnd; }
                set { m_HWnd = value; }
            }
            private IntPtr m_HWnd;
            public List<string> Files
            {
                get { return m_Files; }
                set { m_Files = value; }
            }
            private List<string> m_Files;
            public int X
            {
                get { return m_X; }
                set { m_X = value; }
            }
            private int m_X;
            public int Y
            {
                get { return m_Y; }
                set { m_Y = value; }
            }
    
            private int m_Y;
            public ElevatedDragDropArgs()
            {
                Files = new List<string>();
            }
        }
    
    Usage:
    Code:
      private void Form1_ElevatedDragDrop(System.Object sender, ElevatedDragDropArgs e)
            {
                // Add the files to listview
                if (e.HWnd == listView1.Handle)
                {
                    foreach (string file in e.Files)
                    {
                        listView1.Items.Add(file);
                    }
                }
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                ElevatedDragDropManager.Instance.EnableDragDrop(listView1.Handle);
                // Enable elevated drag drop on listView1. Note that I used the Handle property
                ElevatedDragDropManager.Instance.ElevatedDragDrop += Form1_ElevatedDragDrop;
            }
    

    Made an example for you:

    http://www.datafilehost.com/d/2938557e
     
  3. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,513
    7,174
    120
    @Alpha,

    Thank you so much. It really has been solved my issue... :hug2::hug2::hug2::hug2::hug2::hug2::hug2::hug2::hug2::hug2:
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. Alphawaves

    Alphawaves Super Moderator/Developer
    Staff Member

    Aug 11, 2008
    6,250
    22,354
    210
  5. Josh Cell

    Josh Cell MDL Developer

    Jan 8, 2011
    3,513
    7,174
    120
    I have find a mistake when using these WinAPI hooks:

    You really need to disable the AllowDrop property or you will fire your mind searching the issue as me never solving the problem.. :eek::mad::eek:

    But it is OK now, many thanks bro. :hug2::hug2::hug2::hug2::hug2::hug2::hug2:
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. delphifocus

    delphifocus MDL Novice

    Mar 9, 2013
    13
    2
    0
    Alphawaves: The was file deleted by the file host, can you re-upload it? Thanks a lot
     
  7. delphifocus

    delphifocus MDL Novice

    Mar 9, 2013
    13
    2
    0
    Link was updated on #2 and works fine until now, thanks to Alphawaves.