File system support for FindFirstFileEx, limit to directories - c#

I am using the Windows API function FindFirstFileEx because it provides the capability to return just the sub-directories of a given directory (ignoring files). However when I call this function with the required flag, I still receive both files and directories.
The MSDN documentation for the FindExSearchLimitToDirectories flag used by FindFirstFileEx says:
This is an advisory flag. If the file
system supports directory filtering,
the function searches for a file that
matches the specified name and is also
a directory. If the file system does
not support directory filtering, this
flag is silently ignored.
The lpSearchFilter parameter of the
FindFirstFileEx function must be NULL
when this search value is used.
If directory filtering is desired,
this flag can be used on all file
systems, but because it is an advisory
flag and only affects file systems
that support it, the application must
examine the file attribute data stored
in the lpFindFileData parameter of the
FindFirstFileEx function to determine
whether the function has returned a
handle to a directory.
So, what file systems actually support this flag? It would have been sensible to actually list these supported file systems on the same page, but I can't find it.
My development system is Windows XP SP3, NTFS, .NET 3.5.
I know I can check file attributes to determine if a file is a directory, however this means checking the every file/directory. It also defeats the purpose of using FindFirstFileEx in the first place.
Of course there is still the chance I may be doing something incorrectly in my code. The only thing I can see is passing IntPtr.Zero to lpSearchFilter may not be the same as passing NULL (as mentioned in the quote).
Here's an example of the code I'm using:
m_searchDirHandle = WinAPI.FindFirstFileEx(#"C:\Temp\*",
WinAPI.FINDEX_INFO_LEVELS.FindExInfoStandard ,
ref m_findDirData, WinAPI.FINDEX_SEARCH_OPS.FindExSearchLimitToDirectories,
IntPtr.Zero , 0);
if (m_searchDirHandle != WinAPI.INVALID_HANDLE_VALUE)
{
do
{
foundNextDir = WinAPI.FindNextFile(m_searchDirHandle, ref m_findDirData);
} while (foundNextDir);
}

The nearest link I could find was, the list of System Calls by Metasploit...I am taking a stab here but I would imagine that this 'FindFirstFileEx' would somehow be an indirect call to the NT system call equivalent 'NtOpenDirectoryObject', 'NtQueryDirectoryFile', 'NtQueryDirectoryObject'... I hope...if anyone thinks I'm wrong and downvotes to disagree, I will be corrected by whoever disagrees :)
However, I have hit on a few links here
CodeGuru forum on this issue about the flag
Wine has a mailing listed as the flag as no effect?
GenNT mentions that it is apparently limited to NTFS, (there's 3 replies to that posting)
Here on SO, a question on 'How to get list of folders in this folder'
Edit: Just now after mentioning in the comments, I thought it would be fitting enough to add a link to the Linux NTFS driver for capabilities to read the NTFS partition, there is bound to be source version changes to accomodate the different NTFS versions going back to Win2000...
Hope this helps,
Best regards,
Tom.

Related

Detect sorting order in a folder

I want to detect what sorting order I have chosen in a given path. My goal is to sort an array / list the same way.
For example: The path C:\Test is sorted after lowest file size first.
If your question is in regaurds to the file enumeration methods in C#. Then the order of the files is not guaranteed and it depends on the file system. The operating system doesn't remember what you chose in windows explorer when you call the file enumeration methods in C#. Those methods are based on the win32 apis which states the following
The order in which this function returns the file names is dependent
on the file system type. With the NTFS file system and CDFS file
systems, the names are usually returned in alphabetical order. With
FAT file systems, the names are usually returned in the order the
files were written to the disk, which may or may not be in
alphabetical order. However, as stated previously, these behaviors are
not guaranteed.
However if you were an enterprising-young-jedi-coder-with-time-to-burn, you would likely find the sort order for windows explorer (as chosen by you in windows explorer) is likely stored in the registry. You could likely use a registry monitor to identify what is actually accessed and changed (if this is the case).
Personally I think this is likely going to take a long time, and OS dependent and may change with any windows update, for little to no benefit

File.Delete or File.Encrypt to wipe files?

is it possible to use either File.Delete or File.Encrypt to shred files? Or do both functions not overwrite the actual content on disk?
And if they do, does this also work with wear leveling of ssds and similar techniques of other storages? Or is there another function that I should use instead?
I'm trying to improve an open source project which currently stores credentials in plaintext within a file. Because of reasons they are always written to that file (I don't know why Ansible does this, but for now I don't want to touch that part of the code, there may be some valid reason, why that is that way, at least for now) and I can just delete that file afterwards. So is using File.Delete or File.Encrypt the right approach to purge that information off the disk?
Edit: If it is only possible using native API and pinvoke, I'm also fine with that. I'm not limited to only .net, but to C#.
Edit2: To provide some context: The plaintext credentials are saved by the ansible internals as they are passed as a variable for the modules that get executed on the target windows host. This file is responsible for retrieving the variables again: https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1#L287
https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/csharp/Ansible.Basic.cs#L373
There's a possibility that File.Encrypt would do more to help shred data than File.Delete (which definitely does nothing in that regard), but it won't be a reliable approach.
There's a lot going on at both the Operating System and Hardware level that's a couple of abstraction layers separated from the .NET code. For example, your file system may randomly decide to move the location where it's storing your file physically on the disk, so overwriting the place where you currently think the file is might not actually remove traces from where the file was stored previously. Even if you succeed in overwriting the right parts of the file, there's often residual signal on the disk itself that could be picked up by someone with the right equipment. Some file systems don't truly overwrite anything: they just add information every time a change happens, so you can always find out what the disk's contents were at any given point in time.
So if you legitimately cannot prevent a file getting saved, any attempt to truly erase it is going to be imperfect. If you're willing to accept imperfection and only want to mitigate the potential for problems somewhat, you can use a strategy like the ones you've found to try to overwrite the file with garbage data several times and hope for the best.
But I wouldn't be too quick to give up on solving the problem at its source. For example, Ansible's docs mention:
A great alternative to the password lookup plugin, if you don’t need to generate random passwords on a per-host basis, would be to use Vault in playbooks. Read the documentation there and consider using it first, it will be more desirable for most applications.

Enumerating the NTFS MFT: FSCTL_ENUM_USN_DATA and USN_RECORD_V3 support

I'm using FSCTL_ENUM_USN_DATA to enumerate over the NTFS MFT so that I may build a directory database based on USN_RECORD FileReferenceNumbers. I'm constructing this database so that I can monitor file changes on an NTFS drive by using the NTFS USN Change Journal and reading USN_RECORD's (using FileReferenceNumber and ParentFileReferenceNumber, which reference the directory database). See here for info on doing this.
My issue is with the USN Record versions. If you look, USN_RECORD_V2 supports a different datatype for FileReferenceNumbers (DWORDLONG) than USN_RECORD_V3 (FILE_ID_128). This would be fine, if FSCTL_ENUM_USN_DATA supported USN_RECORD_V3. The issue is USN_RECORD_V3 is used in Windows 10, while USN_RECORD_V2 is used in Windows 7.
FSCTL_ENUM_USN_DATA takes in a MFT_ENUM_DATA_V1 or MFT_ENUM_DATA_V0 as its input buffer. I assumed V1 supported FILE_ID_128 FileReferenceNumbers, but this assumption turned out to be incorrect. There seems to be no support for USN_RECORD_V3 and its associated FileReferenceNumber data type. Thus, monitoring changes on an NTFS drive using the NTFS Change Journal on versions of windows that use USN_RECORD_V3 or later is a huge issue right now.
I have found a temporary solution! On Windows 10 when enumerating the MFT, FSCTL_READ_ENUM_DATA only returned USN_RECORD_V2's, giving FileReferenceNumbers of type DWORDLONG. In turn, I was forced to bitshift these DWORDLONG FileReferenceNumbers into a 128 bit buffer so that the directory cache would match the USN_RECORD_V3s returned from the FSCTL_READ_USN_JOURNAL call.
However, I can't help but feel that I'm missing something. Does anyone have any other solutions to this problem, or any alternate approaches that can be taken? Keep in mind, monitoring changes that were made to the drive while the program wasn't running is paramount for my project.

.NET Windows API Check if folder accessed

I am searching for a function that allows me to put a dialog-window(w/ a password query) before the folder is accessed. Is there such a function? Also, this would be great if this protection is there before any program, even Windows Explorer/cmd.exe are allowed to access those files. Is that possible to make?
I'm not using something like IOContainer, passwd. protected ZIPs or any other things that are too slow, because I guess 20GB in one file are a bit overkill and it would take ages to decrypt that file. Is there maybe a VFS solution for C# which supports password protection and can be used as a normal filesystem or folder on the disk?
Thanks!
There exist two options. The simpler one is to have a virtual file system mapped from the file. Our product, SolFS (OS edition), does exactly what you are asking in the second part of your question - it provides a container with optional encryption, which is exposed as a virtual drive so that access to the contents is transparent. Decryption in such systems is done in pages, so 20GB-large file won't be decrypted in whole as you worry.
Another option is to employ a filesystem filter driver, which will intercept requests for directory opening, and will ask the user for a password. This approach is possible (we even have a product for this, called CallbackFilter), but there are two drawbacks in it: first, it's not impossible to remove the driver, leaving the data unprotected. And the second problem is that if you ask the user for a password in a callback, while the OS is waiting for access to the directory, you can end up in a deadlock or a timeout while the user is thinking.
With these two limitations in mind something like SolFS is the preferred and recommended approach.
PS: and we have free non-commercial licenses as well.

C# System.Diagnostics.Process.Start() parameters

Anyone know where a computer keeps what parameters it can accept through this function? For example, I'd like to know what I can send to Winword.exe (Microsoft Word). Or is there an online list of what programs work here?
There's no standard means to query available command line parameters in executables. That's why you have to look online for published lists. For example Microsoft Word.
The Process.Start(..) overloaded methods pass various data into the process but cannot extract it because of the proprietary nature how a Process uses this info.
If you started the processes then Process.StartInfo may provide some useful information about how it was started (but does not reflect possibilities), and won't work as intended if you're just grabbing a process from memory that you didn't start.
Although it's customary for many Windows processes to allow /? to produce a list of parameters, and many systems use -help, /help or --help, etc, the output of even those may differ and be tough to consistently parse for discovery purposes.
Here is a list of accepted arguments for winword.exe Args list.
The command line arguments that an application accepts isn't stored anywhere on your hard drive, unless if there's specific documentation that came along with that product. That being said, google will be your best friend for this. Any app you think can be launched from the command line using different parameters, will have some info on the net.
you can either go to your application's help and find it there, or you can ask good old mr. Google to help you. if you are looking for Windows Word's args list, you can search for it on the support page of Microsoft. I believe there might be some changes from version to version.
Unix has a built-in documentation system for this: man pages. This is just one feature of Unix based OSs that shows how programmer-oriented it is (not a bad thing). Another would be the profileration of packaging and dependency systems.
Alas, no such standard exists for Windows.

Categories