winapiattributesonedriventfsreparsepoint

Getting full file attributes for files managed by Microsoft OneDrive


Microsoft OneDrive allows file to be stored either locally, remotely or in the both ways. This is determined by new file attributes which appeared in the Windows 10:

FILE_ATTRIBUTE_PINNED                0x00080000  
FILE_ATTRIBUTE_UNPINNED              0x00100000  
FILE_ATTRIBUTE_RECALL_ON_OPEN        0x00040000  
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 0x00400000 

as well as some file attributes inherited from previous versions of Windows:

FILE_ATTRIBUTE_SPARSE_FILE           0x00000200
FILE_ATTRIBUTE_REPARSE_POINT         0x00000400  
FILE_ATTRIBUTE_OFFLINE               0x00001000      

Problem is that I cannot find a way to retrieve these new file attributes via Win32 API or NT Native API. I've tried so far:

GetFileAttributes()
FindFirstFile()
NtQueryAttributesFile()

For OneDrive file which was set to be stored always remotely, all these methods return 0x00500020 whilst true attributes are 0x00501620 (REPARSE_POINT, SPARSE_FILE and OFFLINE are masked out). True file attributes can be retrieved using the following PowerShell command:

[Convert]::ToString( (Get-ItemProperty -Path 'C:\Users\username\OneDrive\test.txt').Attributes.Value__, 16 )

attrib.exe system command is also able to display some of these new OneDrive-related file attributes (O for offline, U for unpinned, P for pinned).

Is there a way to retrieve these file attributes in my software? Maybe I need to add something to the manifest?


Solution

  • From MSDN RtlSetThreadPlaceholderCompatibilityMode

    When placeholders are exposed, characteristics such as the presence of a reparse point, the sparse bit, and the offline bit are plainly visible through directory enumeration and other types of file information queries. When placeholders are disguised, these details are completely hidden, making the file look like a normal file.

    Most Windows applications see exposed placeholders by default. For compatibility reasons, Windows may decide that certain applications see disguised placeholders by default.

    I am guessing that Windows has placed your test program in some sort of compatibility mode and is therefore filtering the attributes.

    RtlSetThreadPlaceholderCompatibilityMode