discodowney
discodowney

Reputation: 1507

Creating a file exceeding filepath limit

I have a test that creates a series of folders in a loop until it exceeds the MAX_PATH (260). This returns ERROR_PATH_NOT_FOUND(0x3). We have a build machine that runs this test but on the build machine it returns ERROR_FILENAME_EXCED_RANGE (0xce).

My machine is Windows 7 but the build machine is Vista. Could that be why they return different values? If not, does anyone know why this might happen?

EDIT: I am expecting to get an error, im testing a file system driver. I just do not understand why i am getting two different error codes from the same test on different machines. Here is the code

homeDir << "C:\Users\me\TestFolder";

string childDir = "\\LongChildDirectoryName";
string dir = homeDir.str();
DWORD lastErr = ERROR_SUCCESS;
while(lastErr == ERROR_SUCCESS) 
{
    int len = dir.size();
    if(len > (MAX_PATH - 12))
    {
        CuFail(tc, "Filepath greater than max allowed should be");
    }

    dir += childDir;

    if(!CreateDirectory(dir.c_str(), NULL))
    {
        lastErr = GetLastError();
        if (lastErr == ERROR_ALREADY_EXISTS)
            lastErr = ERROR_SUCCESS;
    }
}
CuAssert(tc, "Check error is ERROR_PATH_NOT_FOUND", lastErr == ERROR_PATH_NOT_FOUND);

Upvotes: 1

Views: 1177

Answers (2)

Carey Gregory
Carey Gregory

Reputation: 6846

The logic is flawed. If homeDir.str() returns a name that doesn't exist, the return value from CreateDirectory will be ERROR_PATH_NOT_FOUND. You can demonstrate the problem by simply doing this:

string childDir("\\LongChildDirectoryName");
string dir("foo");

The CreateDirectory call will then get the path foo\LongChildDirectoryName, and if foo doesn't exist, you get ERROR_PATH_NOT_FOUND. The fix is simply to add this before the while loop:

CreateDirectory(dir.c_str(), NULL);

You also need to move the length check after the strings have been concatenated, not before. Using the "\\?\" syntax Alex suggested would also be a good idea.

Upvotes: 1

Alexey Frunze
Alexey Frunze

Reputation: 62068

To use longer paths you need to use the "wide" version of CreateFile(), CreateFileW().

See this MSDN article on the topic:

HANDLE WINAPI CreateFile(
  __in      LPCTSTR lpFileName,
  __in      DWORD dwDesiredAccess,
  __in      DWORD dwShareMode,
  __in_opt  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  __in      DWORD dwCreationDisposition,
  __in      DWORD dwFlagsAndAttributes,
  __in_opt  HANDLE hTemplateFile
);

lpFileName [in]

    The name of the file or device to be created or opened.

    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. For more information, see Naming Files,
Paths, and Namespaces.

Upvotes: 0

Related Questions