views:

59

answers:

3

We have an application that allows a user to drag a picture to a window and that window is a drop target (using OLE). When this code is run in the debugger and the Visual Studio instance is run as administrator (right click from desktop) then the target drop is not allowed.

If the exe is run on its own it works fine.

If the visual studio instance is run NOT as an admin the functionality works fine in the debugger. (Same solution/project files/etc)

Win7 OS. Visual Studio 2008. Unmanaged C++

I find it very odd. Not sure why it is happening. In fact I would have guessed the OPPOSITE regarding running VS as an admin.

Has anyone seen this or does anyone have links to workarounds or explanations?

+2  A: 

This is most likely happening due to UIPI (User Interface Privilage Isolation).

In the case where you've launched your processes as Admin (due to the parent process (Visual Studio) being run as admin), UIPI isn't going to let non-elevated (admin) processes send any messages to your app. Drag and Drop between applications is implemented using Windows messages.

To work around this, you can use the ChangeWindowMessageFilterEx() API to opt into the appropriate drag and drop messages.

Bukes
thanks - I will try it out. That looks very promising. Will accept when that proves to be the case.
Tim
Yup. The workaround won't work, D+D doesn't use Windows messages. There is no known workaround for it that I know of.
Hans Passant
@Hans - that is unfortunate.
Tim
@Tim - well, short from the obvious one: just turn UAC off on your dev machine. Surely your program won't run elevated on your customer's machine.
Hans Passant
Here's an authoritative answer to this issue from MSFT: http://blogs.msdn.com/b/patricka/archive/2010/01/28/q-why-doesn-t-drag-and-drop-work-when-my-application-is-running-elevated-a-mandatory-integrity-control-and-uipi.aspx
Bukes
http://blogs.msdn.com/b/patricka/archive/2010/01/28/q-why-doesn-t-drag-and-drop-work-when-my-application-is-running-elevated-a-mandatory-integrity-control-and-uipi.aspx
Tim
@Hans - yeah, but the issue is that we typically run with admin for the visual studio instance as the build process registers COM objects, etc. turning off UAC is exactly what MS tried to get us away from... what a nightmare they created. Crappy foresight.
Tim
@Tim - after almost 4 years, you can still ignore that UAC exists and keep registering COM servers in HKLM. It is up to you. It just won't work so well when you ignore it but still turn it on. It makes little sense to blame MSFT for this.
Hans Passant
@Hans I am not sure what you are talking about. We call regserver from the post build step. Whom else is there to blame but MS? When Raymond Chen suggests some silly things in those links it does not really bode well for them. There is no reason why I should not be able to drag a file from explorer onto my app running at a higher privilege than explorer. How else am I supposed to register a COM server? This is so silly.
Tim
In my experience, registering COM objects as part of the BUILD process is bad form - especially if your organization uses a separate build lab/build machines. BUILDing a project should not modify global machine settings.
Bukes
@Bukes - it is something I inherited. Do you know of another simpler way to ensure that the DLLs you just built are the ones that will be run when debugging the app you are working on in the VS solution? I can't think of one offhand...
Tim
A: 

Unfortunately this looks like a flaw in the OS:

http://blogs.msdn.com/b/patricka/archive/2010/01/28/q-why-doesn-t-drag-and-drop-work-when-my-application-is-running-elevated-a-mandatory-integrity-control-and-uipi.aspx

Oh well.

I find this whole issue appalling. MS has screwed up on this IMO. Essentially we can't debug an app correctly if I want to run MSVC in elevated mode (for example when I build the solution it registers COM servers).

http://social.msdn.microsoft.com/forums/en-US/windowsuidevelopment/thread/2fa935cf-be57-4bcc-9b96-7ee5a6b2b7a5/

Tim
That blog does a terrible job of explaining the rationale. Drag-and-drop uses a COM object and ends up running code of the drag-process in the context of the drop-process. If the drop-process has greater permissions, then it would be a privilege escalation vulnerability.
Ben Voigt
OK, that is more enlightening, but then MS should have fixed the mechanism and allowed this behavior. Basically we are stuck with broken functionality because of bad design/implementation. And rather than own up to it or fix it the answer is - "well, don't mix privilege levels." Not a good response IMO. But thanks for the explanation.
Tim
+1  A: 

If you want to really and truly fix it, then you would need to

  1. Detect when your process is running elevated
  2. Spawn a non-elevated helper process which registers as the drop target
  3. Pass the dropped data through IPC to the elevated process, using a method that's safe to use across privilege boundaries (i.e. no active objects which carry code)

This is a LOT of extra work when the workaround could be as simple as dropping from another elevated app (to get an elevated Explorer, just call up the File->Open dialog of any elevated app), but has the advantage that drag-and-drop will work properly if any of your customers ever run the app elevated.

Ben Voigt
Thanks. We don't expect end users to run this with elevated privileges. The workaround you suggest might work. Thanks
Tim