views:

2795

answers:

2

When I download my program from my website to my windows 2003 machine, it has a block on it and you have to right click on the exe, then properties, then select the button "Unblock".

I would like to add detection in my installer for when the file is blocked and hence doesn't have enough permissions.

But I can't eaisly reproduce getting my exe in this state where it needs to be unblocked.

How can I get the unblock to appear on my exe so I can test this functionality?

+4  A: 

This is done using NTFS File Streams. There is a stream named "Zone.Identifier" added to downloaded files. When IE7 downloads certain types of file that stream contains:

[ZoneTransfer]
ZoneId=3

The simplest way to set it is to create a text file with those contents in it, and use more to add it to the alternate stream.

Zone.Identifier.txt:

[ZoneTransfer]
ZoneId=3

Command:

more Zone.Identifier.txt > file.exe:Zone.Identifier

Then, the way for you to check it would be to try to open the Zone.Identifier stream and look for ZoneId=3, or simply assume that if the stream exists at all that your user will receive that warning.

It's also important to note that this has nothing to do with permissions. Administrators see the same warning; it's to do entirely with the source and type of file. The entire stream goes away when users uncheck the "Always ask before opening this file" box and then click Run.

HitScan
Great information, thanks for your help.
Brian R. Bondy
+3  A: 

There is a supported API for this, documented on MSDN. Search on MSDN for "Persistent Zone Identifier Object". Basically you CoCreateInstance with CLSID_PersistentZoneIdentifier and request an IPersistFile interface. You then call IPersistFile::Load with the name of the file in question. Next, QI for an IZoneIdentifier interface and use IZoneIdentifier::GetId to obtain the zone of the file. If there was no "mark of the web", you should get URLZONE_LOCAL_MACHINE. The ZoneId of 3 mentioned in the other reply is URLZONE_INTERNET. (The enumeration is called URLZONE and is also documented on MSDN, or see sdk\inc\urlmon.h.) You can remove or change the "mark of the web" by calling IZoneIdentifier::Remove or IZoneIdentifier::SetId and then call IPersistFile::Save. There are more details about all of this on MSDN. Good luck!