Accessing removable drive in a terminal services session
I have a tray application that registers with the shell to receive notifications when a drive is added to the system or when media is inserted into a drive (via SHChangeNotifyRegister). Upon receipt of those notifications, I attempt to open the drive to query some properties from it. For my testing I am using a simple USB flash drive. This works fine when I am logged on at the physical console, but if I am logged on via remote desktop then the CreateFile call fails with ERROR_ACCESS_DENIED.
I am calling CreateFile as:
CreateFile(szDrive, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0 NULL);
where szDrive is of the form "\\\\.\\G:"
. After this I make a couple of DeviceIoControl calls.
The strange thing is that I have run Process Monitor on this and in the remote desktop scenario there are NO records of CreateFile on the drive from my tray application. I know my tray app is calling it because I write a log file and I see the CreateFile calls for the log file in the Process Monitor log. It's like it's not even getting far enough to be hooked by Process Monitor.
The machine is Windows 7 with all the default settings (i.e. UAC). My account is a local administrator. In both scenarios (local and remote deskto开发者_C百科p) I am running my tray app as standard user (i.e. no elevation). However, if I elevate my tray app then the remote desktop scenario is successful in opening the drive.
This could end up being a scenario that we just won't support, but I would still like to know what's going on here. Any ideas?
EDIT 1: After looking at this again, it seems to happen for ALL drives (not just removable ones). The observed behavior is the same: CreateFile failing with ERROR_ACCESS_DENIED and no logs in Process Monitor.
EDIT 2: It seems the remote logon is being denied read access; if I replace GENERIC_READ with 0 then it successfully opens the drive (though the DeviceIoControl calls fail with ERROR_ACCESS_DENIED). I am playing around with WinObj trying to see if I can give the remote logon read access to the drives.
I believe I have found the answer. From a Microsoft white paper about removable storage devices in Vista:
I/O Manager and Removable Media Device ACLs
When the driver stack creates the device object, the I/O manager sets a default ACL that is based on the device type. The default ACL gives Full access to SYSTEM and Administrators, and it gives only Execute access to everyone else.
- By default in Windows Vista, the I/O manager grants the IU group Full access for device objects for removable media devices such as CD drives and for those disk device objects that have defined FILE_REMOVABLE_MEDIA characteristics. Note: In earlier versions of Windows, the entry for IU was not present in the ACL that was set by the I/O manager. The Windows Vistas I/O manager provides Full access to the IU group, so that applications can receive direct access to a volume without requiring elevation of privilege, as discussed earlier. However, UFD devices that do not set the Removable property do not benefit from this because the I/O manager does not treat them as removable.
- The disk class driver sets the FILE_REMOVABLE_MEDIA characteristic if the identity data—received from the device in response to the SCSI INQUIRY command—has the Removable property set. Because some UFD devices set this property even though they are not truly removable media, the I/O manager treats such devices as removable disks and provides the IU group Read and Write access to the volume.
- By default, the Windows Vista I/O manager gives only Execute access for remotely connected users for removable media device objects (CD devices) and for those disk device objects that have FILE_REMOVABLE_MEDIA characteristics set. Because of this, remote users cannot burn data by using a CD or DVD drive or perform backup to an optical media or format a removable disk. Administrators can set the Removable Storage Access group policy to override the default behavior. When this policy is set, the I/O manager grants Full access to remote user for these devices, allowing read and write capabilities.
So Vista sets ACLs on devices differently for the interactive user vs remote users. I figured it would be something like this.
精彩评论