34

Is there a possibility to unblock a file that is downloaded from the internet from within a c# program. Surfing the internet I have learned, that the information is written in an alternative stream of a (NTFS) file that contains the current zone information (value 3 is from the internet and is interpreted as blocked).

Is there a managed possiblity to either clear or change the zone information (unblock) of a file or is there a managed copy function that copies the files without the zone information? If not, how can I do with PInvoke but without including a foreign assembly (I'm not allowed to do this in a current project).

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
HCL
  • 36,053
  • 27
  • 163
  • 213
  • 2
    @Sven: Thanks: I thought that I have exactly this written in my question. Is my english so bad? But thanks anyway... :) – HCL Jun 16 '11 at 15:49
  • No, apparently my reading skills are, though. :) In my defense, it's after midnight here. Fwiw, you'll have to use PInvoke, as the .Net System.IO classes don't support alternate data streams. – Sven Jun 16 '11 at 15:50
  • See http://stackoverflow.com/questions/604960/ntfs-alternate-data-streams-net – stuartd Jun 16 '11 at 15:55

5 Answers5

42

Based on your input I have done the following code:

public class FileUnblocker {
    [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool DeleteFile(string name);

    public bool Unblock(string fileName) {
        return DeleteFile(fileName + ":Zone.Identifier");
    }
}

Thanks to Stuart Dunkeld, Alex K(+1) and Sven to show me the direction.

UPDATE I have posted the code here for a feedback if it would work reliable in production environment. If someone want to use it, check out there.

Community
  • 1
  • 1
HCL
  • 36,053
  • 27
  • 163
  • 213
21

It's stored in the :Zone.Identifier stream (more < c:\theapp.exe:Zone.Identifier) you need to use the native IO routines to manipulate them, here is a managed wrapper.

Alex K.
  • 171,639
  • 30
  • 264
  • 288
  • 4
    While this may work for now, it is an implementation detail. The [Persistent Zone Identifier object](https://msdn.microsoft.com/en-us/library/ms537029(v=vs.85).aspx), as mentioned by @citizenmatt, is the bit responsible for creating these. As such, MS may at any time, via Windows update or OS version, change how/where that data is stored. – Sam Axe Jul 27 '15 at 22:59
6

The official way to manage this identifier is with the PersistentZoneIdentifier COM object: http://msdn.microsoft.com/en-us/library/ms537029(v=vs.85).aspx

citizenmatt
  • 18,085
  • 5
  • 55
  • 60
0

If all you want is to unblock files use a powershell command:

dir -r | unblock-files

change directory to the folder containing the files and run that command. The parameter -r is to list files in all sub-folders.

D. Kermott
  • 1,613
  • 17
  • 24
0

I'm using .net 7, I've found these does the same thing.

Unblock:

void UnblockFile(string filePath)
{
    File.Delete(filePath + ":Zone.Identifier");
}

Block:

void BlockFile(string filePath)
{
    File.WriteAllText(filePath + ":Zone.Identifier", "[ZoneTransfer]\r\nZoneId=3");
}
Ray
  • 1