w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
access to ntfs stream for a very long filename fails

As the very helpful page on CreateFile says referring to the lpFileName parameter which specifies the filename:

In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "?" to the path.

Since you are contemplating BackupRead obviously you are wanting to access this stream programatically. If so, test things programatically. Trying all these operations from the command prompt is a crap-shoot and will not establish anything more than the ability to perform such operations from the command prompt.

With that in mind, let's try this simple program - boilerplate code removed:

#include "stdafx.h"

int APIENTRY _tWinMain(HINSTANCE,
                       HINSTANCE,
                       LPTSTR,
                       int)
{
    /* This is the name of the file that we will try to create. Please note
that
     * I have hardcoded the path to my user directory (C:Users
ikb), and since 
     * it's unlikely that path exists on your computer, you should probably
put
     * something there that makes sense.
     */
    LPCWSTR lpszFileName = L"\\?\c:\users\nikb\!!!Long long long long "
                           L"long long long long long long long long long
long "
                           L"long long long long long long long long long
long "
                           L"long long long long long long
filename!!!.png:streamname";

    HANDLE hFile = CreateFileW(lpszFileName, GENERIC_WRITE, 0, NULL, 
        CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

    if(hFile != INVALID_HANDLE_VALUE)
    {
        BYTE bBuffer[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'N', 'i', 'k', '!'
};
        DWORD dwSize = 10;

        if(WriteFile(hFile, bBuffer, dwSize, &dwSize, NULL))
            ::MessageBoxW(GetDesktopWindow(), L"Success", L"WriteFile",
MB_OK);
        else
            ::MessageBoxW(GetDesktopWindow(), L"Failure", L"WriteFile",
MB_OK);

        CloseHandle(hFile);
    }

    return 0;

}

This should work just fine. So now, let's make that filename longer by adding a few more words to it. Again, be sure to properly update the path to something valid on your machine.

LPCWSTR lpszFileName = L"\\?\c:\users\nikb\!!!Long long long
long long long long "
                       L"long long long long long long long long long long
long "
                       L"long long long long long long long long long long
long "
                       L"long long long long long long long long long long
long "
                       L"long long long long long long long long long long
long "
                       L"long long long long long long long long long long
long "
                       L"long long long long long long long long long long
long "
                       L"long long filename!!!.png:streamname";

Now that's long. And it will fail. Weird... If we check the output of GetLastError() we will get ERROR_INVALID_NAME so what gives? This should work because it clearly isn't longer then 32,767 characters and we're using the fancy \? syntax to let us specify reeeeeally long paths. Right?

Well... sort of. The MSDN page on CreateFile links to the very helpful page titled Naming Files, Paths and Namespaces. As a matter of fact, even you linked to that page in your question. Which is interesting, because it would have answered your question before you even asked it:

The Windows API has many functions that also have Unicode versions to permit an extended-length path for a maximum total path length of 32,767 characters. This type of path is composed of components separated by backslashes, each up to the value returned in the lpMaximumComponentLength parameter of the GetVolumeInformation function (this value is commonly 255 characters). To specify an extended-length path, use the "?" prefix. For example, "?D:very long path".

So although the path itself may be 32,767 characters long no individual component (i.e. "part") of the path may exceed the largest value allowed by the filesystem. Indeed, if you try to find out what the maximum component length that NTFS reports back, it will be 255.

So the filename is a single component, and a single component may not be longer than 255 characters. The filename which you specified was:

!!!Long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long filename!!!.png:streamname

A quick test shows that this is 264 characters long. And 264, it should come as no surprise, is greater than 255.





© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.