ZoneStripper.exe

You've downloaded the latest, coolest utility (for example, this one) :) with source code. The source code is sitting on your local hard drive yet when you launch the solution in Visual Studio .NET 2003, you receive the warning:

The project location is not fully trusted by the .NET runtime. This is usually because it is either a network share or mapped to a network share not on the local machine. If the output path is under the project location, your code will not execute as fully trusted and you may receive unexpected security exceptions.

Your first thought is probably "What the heck? The solution is on my local drive!" What is causing this odd behaviour, you wonder? Let's look at Windows XP SP2 and how it handles Zone Identifiers.

Implementation Details

Windows XP SP2 writes a Zone Identifier on all downloaded files. So your zip file is marked as originating from the Internet. When you unzip the archive, your zip file manager has conveniently written the Zone Identifier to each file contained in the archive. Thus your solution file is marked as originating from the Internet and is thus not fully trusted. This behaviour can also occur if you copy the code from a network share to your local drive using Windows XP SP2. ZoneStripper removes the Zone Identifier from files and directories so that the solution can be loaded into Visual Studio .NET without the security warning.

How does Windows XP SP2 record the Zone Identifier? The Zone Identifier is saved into an Alternate Data Stream (Zone.Identifier) on NTFS. One way to remove the Zone Identifier is to move the files onto a FAT partition and then move it back to your NTFS drive. (FAT doesn't support Alternate Data Streams and so the Alternate Data Stream is ignored when copying files onto a FAT partition.) The other option is to delete the Zone.Identifier Alternate Data Stream, which is what ZoneStripper does. To see the Alternate Data Stream, simply type the following:

notepad.exe Readme.htm:Zone.Identifier

Unfortunately the .NET Framework's System.IO classes are not Alternate Data Stream-aware. So you must use P/Invoke to call the underlying Win32 API CreateFile (to determine if the Zone.Identifier stream exists) and DeleteFile (to delete the Zone.Identifier stream).

Build

To build, simply load the solution src\ZoneStripper.sln into Visual Studio .NET 2003 and compile. You'll probably want to run ZoneStripper on the src\ directory to avoid the Visual Studio .NET 2003 warning.

Usage

ZoneStripper.exe [-r] names

where -r optionally recurses subdirectories (ignored if only files listed) and names is a space-separated list of directories and/or files

Known Issues

Occassionally ZoneStripper will encounter an "Access denied" error on a particular file, even when you have full rights to the file and it is not locked. Closing all open applications and/or rebooting and re-running ZoneStripper produces the same error and always on the same file(s). v1.0.1.0 logs the problem to the console, but continues processing additional files.

Version History

1.0.1.0 On an UnauthorizedAccessException (typically due to an "Access denied" error), ZoneStripper now prints the file/directory name and error message, but continues processing additional files/directories. Previously ZoneStripper reported the error and stopped processing additional files.
1.0.0.0 Initial Release

Acknowledgements

Thank you to Jason Kaczor for alerting me to the mysterious "Access Denied" error.

Contact

Please contact James Kovacs [jkovacs@post.harvard.edu] with suggestions, comments, or bug fixes. The official home of this utility is http://www.jameskovacs.com.

Copyright

Copyright © 2004-2005 James Kovacs. All rights reserved. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.