Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does GetFullPathName return the working directory?

Tags:

c++

path

winapi

I stumbled upon a behavior of GetFullPathName() (through the use of QFileInfo::canonicalFilePath()) that I don't quite understand: when I call this function with a string composed of the current drive letter and a colon, it returns the path of the current working directory, while I would expect the path to the drive letter.

The following code exemplifies what I'm talking about:

#include <windows.h>
#include <iostream>
#include <string>

std::string canonicalFilePath(const char *path)
{
    static const std::size_t BufferSize = 300;
    char canonicalPath[BufferSize];

    GetFullPathName(path, BufferSize, canonicalPath, 0);

    return std::string(canonicalPath);
}

int main(int, char **)
{
    SetCurrentDirectory("C:/some/path");
    std::cout << "In C:" << '\n';
    std::cout << "  C   -> " << canonicalFilePath("C")   << '\n'
              << "  C:  -> " << canonicalFilePath("C:")  << '\n'
              << "  C:/ -> " << canonicalFilePath("C:/") << '\n'
              << "  D   -> " << canonicalFilePath("D")   << '\n'
              << "  D:  -> " << canonicalFilePath("D:")  << '\n'
              << "  D:/ -> " << canonicalFilePath("D:/") << '\n';

    SetCurrentDirectory("D:/other/path");
    std::cout << "In D:" << '\n';
    std::cout << "  C   -> " << canonicalFilePath("C")   << '\n'
              << "  C:  -> " << canonicalFilePath("C:")  << '\n'
              << "  C:/ -> " << canonicalFilePath("C:/") << '\n'
              << "  D   -> " << canonicalFilePath("D")   << '\n'
              << "  D:  -> " << canonicalFilePath("D:")  << '\n'
              << "  D:/ -> " << canonicalFilePath("D:/") << '\n';
}

Output:

In C:
  C   -> C:\some\path\C      // ok
  C:  -> C:\some\path        // ? why not C:\ ?
  C:/ -> C:\                 // ok
  D   -> C:\some\path\D      // ok
  D:  -> D:\                 // ok
  D:/ -> D:\                 // ok
In D:
  C   -> D:\other\path\C     // ok
  C:  -> C:\                 // ok
  C:/ -> C:\                 // ok
  D   -> D:\other\path\D     // ok
  D:  -> D:\other\path       // ? why not D:\ ?
  D:/ -> D:\                 // ok

Is this behavior normal? In GetFullPathName documentation, it is stated that

If you specify "U:" the path returned is "U:\"

Why is this not the case if "U" is the current drive letter?

like image 391
Luc Touraille Avatar asked Oct 29 '25 08:10

Luc Touraille


2 Answers

From msdn:

If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter. Note that the current directory may or may not be the root directory depending on what it was set to during the most recent "change directory" operation on that disk.

Examples of this format are as follows:

  1. "C:tmp.txt" refers to a file named "tmp.txt" in the current directory on drive C.
  2. "C:tempdir\tmp.txt" refers to a file in a subdirectory to the current directory on drive C.
like image 77
Ivan Grynko Avatar answered Oct 30 '25 23:10

Ivan Grynko


It has been like that since the old DOS days. If your current directory is on drive D:, then D: will always be your current directory. The case talked about in the documentation is when you pass a drive different from where your current directory is.

like image 22
Some programmer dude Avatar answered Oct 30 '25 23:10

Some programmer dude



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!