24

I have a hidden file on my USB removable storage (FAT file system).

I'm using Windows 7. If I go to Properties window of this file and then to the Details tab, I will see that the attributes of the file are HX. When I run cmd and use attrib, I was told that file has attribute H. Nothing about X. I've tried help attrib, but still nothing about attribute X.

I know that:

  • H = Hidden
  • S = System
  • A = Archival
  • R = Readonly

However, I have no idea what X stands for. I've also found what the N and E attributes are for.

Wikipedia has no mention of what the X attribute is.

Google found two topics mentioning attribute X:

None of these helped.

I'd like to be able to read/write this flag in C#, but so far I read the documentation for the FileAttributes enumeration and experimented with setting some of listed attributes (using File.GetAttributes & File.SetAttributes methods) on the file.

None of these experiments resulted in attribute X showing up in Properties -> Details. So, I have no idea how to approach it, especially since I still don't know what attribute X means.

So, what is attribute X and how can one set/clear it on the selected file in C#?

Community
  • 1
  • 1
beam022
  • 1,793
  • 4
  • 20
  • 27
  • It seems that all comments got lost - I was asked if attribute X would disappear after performing `chkdsk`. No, I have done the `chkdsk` - no problems were found and attribute X is still there. – beam022 Dec 23 '11 at 17:45
  • 2
    I would guess at an intentionally invalid file attribute. There are two unassigned bits in FAT32, 0x40 and 0x80. This is just a guess. – Hans Passant Dec 23 '11 at 19:19
  • 2
    I suspect Hans is right. Get the file attributes, cast it to `int`, and output it in hex. Then compare the set bits to the File Attribute Constants: http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx. That should tell you which bit is improperly set. If you want to clear the attribute, clear it in that int, cast the int back to a `FileAttributes`, and call `File.SetAttributes`. – Jim Mischel Dec 23 '11 at 20:12
  • 1
    I followed Jim's advice (thanks for step-by-step instructions) and first tried getting and setting attributes for dummy file. Got `0x20` (archive file), then I set it to `0x22` and dummy became hidden. Tried to get attributes of file in question - got `0x42` (device+hidden). Tried to set it to `0x2` (just hidden), but I got stopped by "Access denied". Then I tried to set dummy's attributes to `0x42`. No problems there, however when I check dummy's Details tab, it's only attribute is `H`. And if I get dummy's attributes now, it's just `0x2`. "`0x40` _Reserved; do not use_". Any other way? – beam022 Dec 23 '11 at 21:10
  • See [SetFileAttributes function](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365535%28v=vs.85%29.aspx), section _Remarks_. I know what _do not use_ means, but this file had set `0x40` attribute by other program, I'd like to be able to do the same. Or to set it off. – beam022 Dec 23 '11 at 21:22
  • Update: [this](http://stackoverflow.com/questions/3419527/setting-file-attribute-device-in-visual-studio) might be of some help. – beam022 Oct 24 '12 at 00:32
  • I'm not sure if you *need* to do this in Windows. If not, my answer might help. – Kevin Stricker Oct 25 '12 at 23:33
  • @mootinator doing this in Windows is mandatory for me. – beam022 Mar 05 '13 at 13:33

5 Answers5

1

Unfortunately, the Windows API will prevent you from setting/unsetting FILE_ATTRIBUTE_DEVICE because it isn't meant to be set on files. If you really need the ability to do that you'll have to access the disk directly. I don't really recommend trying to do that in C#.

The quickest possible implementation would probably be to forget about doing it in Windows, download the source for mtools and make a couple of edits to the mattrib source in order to get it working.

eg add to msdos.h:

#define ATTR_DEVICE 0x40
#define IS_DEVICE(entry) (HAS_BIT((entry),ATTR_DEVICE))

Then add the code to mattr.c so you can set the attribute and verify the change:

static int view_attrib(direntry_t *entry, MainParam_t *mp)
{
    ...
    /* Add this if block */
    if(IS_DEVICE(entry))
        putchar('X');
    ...
}


static int concise_view_attrib(direntry_t *entry, MainParam_t *mp)
{
    ...
    /* Add the following if block */
    if(IS_DEVICE(entry))
        putchar('X');
    ...
}

static int letterToCode(int letter)
{
    switch (toupper(letter)) {
        ...
        /* Add the following case */
    case 'X':
        return ATTR_DEVICE;
        ...
    }
}

Then you would just have to setup your drive on mtools and call your newly created mattrib -x command on the file you wish to change.

Kevin Stricker
  • 17,178
  • 5
  • 45
  • 71
1

File Attribute X correspondes to System.IO.FileAttributes.Device which has an integer value of 64 (0x40) using .NET you cannot directly set this value. The problem is that when you call File.SetAttributes(path, fileAttributes) it calls an internal dll import function in Mscorlib.dll, namely the static method Microsoft.Win32.Win32Native.SetFileAttributes, this is a direct dll import of kernel32.dll and is defined as:

// Microsoft.Win32.Win32Native
[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
internal static extern bool SetFileAttributes(string name, int attr);

So put simply, even using kernel32.dll you cannot set this value. See: SetFileAttributes, and System.IO.FileAttributes.

But, you can write code that will effectively do the same as setting or removing this attribute.

Your best and likely only (reasonable) answer would be to keep a template file with the X permission, when you need to set a file to have X you rename the existing file, copy the template X file and then write the other attributes.

For removing the X permission you should read the file and write to a new file and then copy there permissions using a simple call to File.SetAttributes(path, File.GetAttributes(oldPath)); (which won't set the X permission.

This approach is pretty straight forward and would be entirely possible in native .NET (and wouldn't actually look too nasty either, compared to hacking around at the disk level or invoking cgywin - if that would even work).

Seph
  • 8,472
  • 10
  • 63
  • 94
1

Maybe I'm wrong but... I think that X attribute means that the file has extended attributes. Unfortunately, extended attributes can't be modified using C#.

CedX
  • 3,854
  • 2
  • 36
  • 45
  • I think you might be right about extended attributes. I now know that `FILE_ATTRIBUTE_DEVICE 0x40` can't be set using [`SetFileAttribute`](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365535%28v=vs.85%29.aspx), but maybe there is another method to set or clear this attribute using C#. I've read about `EA DATA. SF`, but it seems like I have much more reading to do. Any idea how to access and edit `EA DATA. SF` file from C#? [Implementation of EA on FAT](http://ps-2.kev009.com:8081/tavi/os2pages/eadata.html), [EA - what and how](http://www.howzatt.demon.co.uk/articles/06may93.html) – beam022 Dec 24 '11 at 03:08
  • I tried few file removing tools available out there, but none of them helped to get rid of the file. As for `EA DATA. SF`, I'm not sure that this EA file is on my flash USB drive. **How can check for it's existence**? It's said [here](http://www.cygwin.com/1.5/cygwin-ug-net/using-filemodes.html) that `EA DATA. SF` _file can only be deleted outside of Windows because of its "in use" status_. Is that really a case? And if I can't remove file with attr X, because of `EA DATA. SF`, which I also can't remove because of win7... How can I **make my own `EA DATA. SF`** after formatting flash drive? – beam022 Dec 24 '11 at 10:32
  • The reason I asked how to check for `EA DATA. SF` file existence was because it doesn't show up in explorer (I've set showing hidden and system files on). I've tried `if exist "EA DATA. SF" echo It's here!` in `cmd`, but I didn't get confirmation. Looks like it isn't `EA DATA. SF` file that makes the other file untouchable. I might be wrong, would appreciate help. – beam022 Dec 27 '11 at 20:24
0

I cannot reproduce your issue but as workaround to remove that attribute I think you can try with robocopy:

robocopy xattributefile copyoffile /copy:DT

/copy:DT: Specifies the file properties to be copied.

This should not copy attribute but i don't know if it works with X attribute)

giammin
  • 18,620
  • 8
  • 71
  • 89
0

The X is most likely the execute permissions. icalcs mentions it and you can possibly use this command from C# to set a file attribute, although I am not sure if it will work against a FAT filesystem or not.

neouser99
  • 1,807
  • 1
  • 10
  • 23
  • I don't think that "execute" attribute applies to a Windows file-system like FAT. – CedX Dec 23 '11 at 19:56
  • I've read about `icacls`, tried to use it on file in question, got "Acces denied". Then I experimented a little bit with `icacls` on other files on USB stick, but didn't get very far: when I typed `icacls dummy` all I get is `dummy D:NO_ACCESS_CONTROL`. I couldn't make any changes to ACL of dummy, even though I tried `/grant`, `/deny` and `/remove`. Then I did some searching and found that "acls are first supported by ntfs file system" according to [andreas2610 post](http://social.technet.microsoft.com/Forums/en-US/w7itprosecurity/thread/9e84667f-6eef-4f00-9a75-7c6d1d89a89b/) – beam022 Dec 23 '11 at 20:20