|
Strange - it works for me using mapped network drives or UNC paths. Vinzy was having a problem (below) with mapped network drives, but fixed it using the UNC path.
I've tried recompiling everything with .NET 4, and it doesn't seem to make any difference.
Are you sure that drive N: is using NTFS, and that you have sufficient permissions to access it? I've not done much with VMWare, but are there any settings on the host which could be blocking access?
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi, thank you somuch for the quick answer
I am still investigating the cause of my problems, but it can sum up the following special circumstances in my testbed:
1. My Visual Studio is running inside a VMWare which hosts Win XP32
2. Drive N:\ is a mapped network drive inside the VMWare
3. The Filesystem is definitely NTFS and the user in XP is admin
4. The host system of the VMWare image is Windows 7 x64
5. The "physical drive" on the host has the same drive letter N:\
The special thing about this drive N:\ is that it is connected via LAN to the host machine, but this happens fully transparent via drivers, which can "fool" the OS and even the most sophisticated HDD recovery software I have used so far. They all believe that it is a physical HDD installed in the host itself. So I guess this is not the problem. (btw. it ia a "NetDisk" 351UNE by IOCell)
I am going to do a test outside the VMWare and will report after that what I found out.
My guess is that the software will work properly even on the LAN drive N:\, and I will try to run it on another network drive which is not connected via driver but via network drive mapping only.
It will take a while until I have transferred all necessary programs to the outer world, but I will tell you ASAP
UPDATE #1:
I used the compiled x32 executables on my windows 7 x64 on the Pseudo-Network Drive N:\ and it worked fine, nothing to complain
Because of this we can be sure that the drive itself is not the problem, i.e. the LAN-to-Localdrive drivers work perfectly, as does your example in this case!
Still to be done: use a real mapped network drive outside of the vmware and do the same test. Currently I work on my network to provide such an environment, my first test with a mapped Buffalo LAN Drive failed due to other reasons (UNC path was not available, I don't know why, working on it Stupid me! Buffalo uses a Linux filesystem, no NTFS ).
stay tuned...
UPDATE #2:
Sorry for the delay, I am absorbed at the moment by business-needs, but will come back to my problem ASAP .
Believe it or not: my current problem in testing your code on a real mapped network drive is to find a second network device to share some folders from...
I have only one big machine at home and have everything else virtualized!
So you may understand why I want to make it run inside a VM Ware! LOL!
My current guess is: VMWare is doing something strange to mapped NTFS Network drives!
UPDATE #3:
Ok, here we go.
I tried a mapped network drive OUTSIDE of a VMWare and it worked, as you expected (with UNC names only of course).
No I am really frustrated... by the VMWare, not by your code Obviously there is a difference between mapped drives in a "real" environment and such a construct in a virtualized environment.
So I have to investigate further how to circumvent my problem. Until I found a cure, I sadly cannot use your code as intended!
Thank you so much for this great piece of software and your effort to help me! If I find a solution, I will post it here, promised!!
Keep on coding
LZ
PS: I just realized that any file that is copied from inside a VMWare to the outside world via a mapped Network drive, loses all alternate streams! Phew....
modified on Saturday, June 19, 2010 8:41 AM
|
|
|
|
|
Thought it's been almost two years now, but I think posting this will help others looking at this articles.
Folders shared via VMWare Workstation is not the same as folders shared via Windows. You should understand that sharing folders from your host computer in vmware Workstation doesn't DIRECTLY uses the NetBios protocol to communicate between host and guest OS.
Didn't you notice that sharing folders from VMWare Workstation doesn't require you to have a network link between the the host and guest? So, don't blame VMWare Workstation
|
|
|
|
|
Thank you for posting this article in the first place and then updating it even to 64bit! I was just about to code an ADS lib (for 64bit) myself, when I thought "have a look if it hasn't been done before"
I am going to use ADS for keeping track of FileMetaData which shall not be held in a database but as close to the files as possible to make sure the user can move the files around as he or she likes.
I know that ADS works only on NTFS file systems, but I think we will have to stick with that filesystem for a while anyway Do you think ADS will have some future or equivalent if Microsoft might introduce their WinFS some day?
I love the idea of storing custom MetaData in a file without interfering with any app that does not no anything about it!!
LZ
|
|
|
|
|
It would be nice if the library mapped the error code to the appropriate exception. Check out Microsoft's source code for .NET to see how this is done. Specifically, the WinIOError function of the __Error.cs file. (Using .NET Reflector, do a "Search Member" for WinIOError .)
internal static void WinIOError() {
int errorCode = Marshal.GetLastWin32Error();
WinIOError(errorCode, String.Empty);
}
internal static void WinIOError(int errorCode, String maybeFullPath) {
bool isInvalidPath = errorCode == Win32Native.ERROR_INVALID_NAME || errorCode == Win32Native.ERROR_BAD_PATHNAME;
String str = GetDisplayablePath(maybeFullPath, isInvalidPath);
switch (errorCode) {
case Win32Native.ERROR_FILE_NOT_FOUND:
if (str.Length == 0)
throw new FileNotFoundException(Environment.GetResourceString("IO.FileNotFound"));
else
throw new FileNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.FileNotFound_FileName"), str), str);
case Win32Native.ERROR_PATH_NOT_FOUND:
if (str.Length == 0)
throw new DirectoryNotFoundException(Environment.GetResourceString("IO.PathNotFound_NoPathName"));
else
throw new DirectoryNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.PathNotFound_Path"), str));
case Win32Native.ERROR_ACCESS_DENIED:
if (str.Length == 0)
throw new UnauthorizedAccessException(Environment.GetResourceString("UnauthorizedAccess_IODenied_NoPathName"));
else
throw new UnauthorizedAccessException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("UnauthorizedAccess_IODenied_Path"), str));
case Win32Native.ERROR_ALREADY_EXISTS:
if (str.Length == 0)
goto default;
throw new IOException(Environment.GetResourceString("IO.IO_AlreadyExists_Name", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
case Win32Native.ERROR_FILENAME_EXCED_RANGE:
throw new PathTooLongException(Environment.GetResourceString("IO.PathTooLong"));
case Win32Native.ERROR_INVALID_DRIVE:
throw new DriveNotFoundException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.DriveNotFound_Drive"), str));
case Win32Native.ERROR_INVALID_PARAMETER:
throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
case Win32Native.ERROR_SHARING_VIOLATION:
if (str.Length == 0)
throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_NoFileName"), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
else
throw new IOException(Environment.GetResourceString("IO.IO_SharingViolation_File", str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
case Win32Native.ERROR_FILE_EXISTS:
if (str.Length == 0)
goto default;
throw new IOException(String.Format(CultureInfo.CurrentCulture, Environment.GetResourceString("IO.IO_FileExists_Name"), str), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
case Win32Native.ERROR_OPERATION_ABORTED:
throw new OperationCanceledException();
default:
throw new IOException(Win32Native.GetMessage(errorCode), Win32Native.MakeHRFromErrorCode(errorCode), maybeFullPath);
}
}
|
|
|
|
|
Thanks for the feedback. I've finally got around to submitting an update to resolve this and the other issue you reported (ASCII codes 1-31 in stream names).
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
ValidateStreamName incorrectly uses Path.GetInvalidFileNameChars to validate a stream name. A stream is allow characters whose integer representations are between 1 and 31. I have included a fix, as shown below.
private static char[] _invalidStreamNameChars;
public static char[] GetInvalidStreamNameChar() {
if (_invalidStreamNameChars == null) {
List<char> oResult = new List<char>();
foreach (char i in System.IO.Path.GetInvalidFileNameChars()) {
if ((i > 0) && (i < 32)) {
} else {
oResult.Add(i);
}
}
_invalidStreamNameChars = oResult.ToArray();
}
return _invalidStreamNameChars;
}
public static void ValidateStreamName(string streamName)
{
if (!string.IsNullOrEmpty(streamName) && -1 != streamName.IndexOfAny(GetInvalidStreamNameChar()))
{
throw new ArgumentException(Resources.Error_InvalidFileChars);
}
}
|
|
|
|
|
Hi,
I am having problems accessing the alternate data stream of a network shared drive. I get the error "The filename, directory name, or volume label syntax is incorrect" when I use the method FileSystem.AlternateDataStreamExists("z:\\", "xx"). Am I doing something wrong in here. Thanks in advance for your help.
--
Vinzy
|
|
|
|
|
The AlternateDataStreamExists method uses the GetFileAttributes API to determine whether a stream exists. According to the documentation[^]:
If you call GetFileAttributes for a network share, the function fails, and GetLastError returns ERROR_BAD_NETPATH . You must specify a path to a subfolder on that share.
However, I haven't been able to reproduce your error message. I've tried calling AlternateDataStreamExists with a mapped network drive and a UNC path, and both work as expected. If I pass a drive which isn't mapped, I get "The system cannot find the path specified". If I pass a UNC path without a share name, I get "The UNC path should be of the form \\server\share".
I'm running Windows 7, but I've just tried running a simplified version of the code on a Windows 2000 virtual PC and I get the same results. I've included the code below.
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
static class Program
{
private const int ErrorFileNotFound = 2;
[DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int GetFileAttributes(string fileName);
private static int SafeGetFileAttributes(string fileName)
{
if (string.IsNullOrEmpty(fileName)) throw new ArgumentNullException("fileName");
int result = GetFileAttributes(fileName);
if (-1 == result)
{
int errorCode = Marshal.GetLastWin32Error();
if (ErrorFileNotFound != errorCode) ThrowLastWin32Error();
}
return result;
}
private static void ThrowLastWin32Error()
{
int error = Marshal.GetLastWin32Error();
if (0 != error)
{
int hr = Marshal.GetHRForLastWin32Error();
if (0 > hr) Marshal.ThrowExceptionForHR(hr);
throw new Win32Exception(error);
}
}
static void Main()
{
try
{
int attributes = SafeGetFileAttributes("z:\\");
if (-1 == attributes)
{
Console.WriteLine("Drive not found");
}
else
{
Console.WriteLine("Drive found");
attributes = SafeGetFileAttributes("z:\\:xx");
if (-1 == attributes)
{
Console.WriteLine("ADS not found");
}
else
{
Console.WriteLine("ADS found");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi,
Thanks for your reply. I really appreciate it.
The problem that I was having was only when I tried to access the alternate stream of the network drive.
I figured out a work around for it by finding the UNC of the network drive and then using it. It works great now. Ref: http://www.wiredprairie.us/blog/index.php/archives/22[^]
--
Vinzy
|
|
|
|
|
Strange - it works for me whether I use the UNC path or the mapped network drive.
Glad you found a workaround.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
hi,
i am a newer,and i don't know how to use it.
how can i compile all the files in "Trinet.Core.IO.Ntfs" folder?
by the way i am using powershell
thanks
|
|
|
|
|
There is a pre-compiled version in the "bin" folder. Alternatively, you can build the solution using Visual Studio 2008, or from the command line using msbuild[^].
In PowerShell, make sure you're in the "Trinet.Core.IO.Ntfs" folder. To build the 32-bit version, run:
& $env:systemroot\Microsoft.NET\Framework\v3.5\msbuild.exe Trinet.Core.IO.Ntfs.sln
If you're on a 64-bit version of Windows, you can build a 64-bit version using:
& $env:systemroot\Microsoft.NET\Framework64\v3.5\msbuild.exe Trinet.Core.IO.Ntfs.sln
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
thanks a lot
some more
documentation in doc folder are not available
can you update?
thans again
|
|
|
|
|
The CHM file is probably blocked because you downloaded it from the Internet. To unblock it, right-click on the file and choose "Properties". At the bottom of the General tab, you will see "Security: This file came from another computer...", with an "Unblock" button next to it. Click the unblock button, and you should be able to open the file.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
That's ironic, because the alternate data stream is what's causing the block on the CHM file.
Another fix is to copy the blocked file to a thumb drive (or any FAT volumne), and then back to the NTFS volume. That should effectively remove the offending alternate data streams.
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass." - Dale Earnhardt, 1997
|
|
|
|
|
Does FileInfo have a method called ListAlternateDataStreams()? I can't seem to find your version either.
...................
FileInfo file = new FileInfo(path);
foreach (AlternateDataStreamInfo s in file.ListAlternateDataStreams())
...................
|
|
|
|
|
It's an extension method[^] defined in the Trinet.Core.IO.Ntfs.FileSystem class. Assuming you're using the .NET 3.5 compiler, you just need to add using Trinet.Core.IO.Ntfs; to the top of your code file (or Imports Trinet.Core.IO.Ntfs for VB).
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Dear friend,
i am very sorry if i am wrong. because i am new to this.
please tell me how to change the File summary information ??
i could not understand your code.
My Problem is i have own file type and i want to change the file summary through c# can u please tell me how to do that?
i searched in Google
"http://forums.asp.net/p/1050538/1483362.aspx#1483362"
from here i came to your article.
Thank you.
Joe.I
|
|
|
|
|
This is quite a complicated topic:
- For compound files, such as Office documents, the summary information is stored in the file.
- Office 2007 files can be manipulated with the OpenXML SDK[^];
- For older file versions, you need to use the DSOFile[^] component;
- In Vista, most of the summary information is stored within the file; this is why the available fields varies depending on the file type.
- In older versions of Windows, the information is stored in an alternate data stream, and can be manipulated via the IPropertySetStorage[^] interface.
Unfortunately, I've not done much work with these components, so you'd probably be better off asking in the forums.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thanks For your Replay.
the funnything is i have posted my question in codeproject forum
and one again gave me like to your artical.
http://www.codeproject.com/Forums/1649/Csharp.aspx?fid=1649&select=3102914&fr=1#xx3102914xx
any way thank u friend for your help.
and i shall work on it.
By
Joe
|
|
|
|
|
Hi,
I need a simple sample code to writing a alternative data stream called test with this value "hello ADS" for a file and a simple code for reading the value of that data stream (test).
Is there anybody can write it for me here.
thanks
modified on Wednesday, June 10, 2009 3:24 AM
|
|
|
|
|
Try this:
using System;
using System.IO;
using Trinet.Core.IO.Ntfs;
static class Program
{
static void Main()
{
try
{
string fileName = Path.GetFullPath("Your File Path Here");
if (!File.Exists(fileName))
{
Console.WriteLine("Test file not found.");
}
else
{
WriteTestStream(fileName);
ReadTestStream(fileName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
static void WriteTestStream(string fileName)
{
var info = FileSystem.GetAlternateDataStream(fileName, "Test");
using (var fileStream = info.OpenWrite())
using (var writer = new StreamWriter(fileStream))
{
writer.Write("hello ADS");
}
}
static void ReadTestStream(string fileName)
{
var info = FileSystem.GetAlternateDataStream(fileName, "Test");
if (info.Exists)
{
Console.WriteLine("Alternate data stream found:");
using (var reader = info.OpenText())
{
Console.WriteLine(reader.ReadToEnd());
}
}
else
{
Console.WriteLine("Alternate data stream not found: {0}", info);
}
}
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you very much.
|
|
|
|
|
On Vista SP1 it simply does not return any metadata (Count == 0), however metadata actually exists.
|
|
|
|
|