2

I was making a simple program with WinAPI to check if a directory exists, this is the function code:

BOOL directoryExists( LPCSTR path ) {
    DWORD pathAttributes = GetFileAttributes ( path );

    return pathAttributes != INVALID_FILE_ATTRIBUTES 
                  && pathAttributes == FILE_ATTRIBUTE_DIRECTORY;
 }

Then I test it with this line of code in my main:

 std::cout << ( ( directoryExists( "C:\\Users\\Admin\\Desktop" ) ?  
                          "Directory found"  : "Directory not found"  ) 
          << static_cast< char >( 0xA );

It looks like I get "Directory not found" no matter what absolute path I try to input. Anyway with relative paths it succeeds!

Where did I fail? :|

Thanks in advance!

Baffo rasta
  • 320
  • 1
  • 4
  • 17

2 Answers2

7

The return value of GetFileAttributes is a bit field, not a single value, and each file attribute constant contains a bit mask so you should check it like this:

return (INVALID_FILE_ATTRIBUTES != pathAttributes) 
              && (0 != (pathAttributes & FILE_ATTRIBUTE_DIRECTORY));

Also you should use GetFileAttributesW and wide char paths because GetFileAttributesA can not handle Unicode paths.

user7860670
  • 35,849
  • 4
  • 58
  • 84
  • Thanks man, you're absolutely right! I edited as you suggested and everything works now :) I'll accept your answer as soon as possible! – Baffo rasta Apr 15 '17 at 08:28
1

You are not checking FILE_ATTRIBUTE_DIRECTORY bit properly. Try this:

BOOL directoryExists(LPCSTR path)
{
    DWORD attr = GetFileAttributes(path);
    return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
}

int main()
{
    std::cout << (directoryExists("C:\\Users\\Admin\\Desktop\\") ?
        "Directory found" : "Directory not found") << endl;
}
Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • `BOOL` return value in a C++ program? – zett42 Apr 15 '17 at 09:59
  • @zett42 yes, what's the problem? It's Windows.h – Pavel P Apr 15 '17 at 10:09
  • Because C++ has a build-in data type for that. – zett42 Apr 15 '17 at 10:12
  • 1
    @zett42 WinAPI commonly uses BOOL for return types. I'd definitely use `bool` myself, but original code from the author had `BOOL`, I didn't invent that. – Pavel P Apr 15 '17 at 10:21
  • That's a fair point! – zett42 Apr 15 '17 at 10:39
  • @zett42 Is that a so bad practice? I don't have much experience cause I'm just a student, but as far as I've seen many windows.h functions have WINBOOL return type! – Baffo rasta Apr 15 '17 at 12:06
  • @Baffo That's because windows.h is a C API that was invented when [C didn't have a native `bool` type](http://stackoverflow.com/a/1608350/7571258). It's better to use native `bool` type for your own functions because you can't overload on `BOOL` (it will create ambiguity when there is already an `int` overload) for instance. Also template specializations like `std::vector` can be completely different than `std::vector` (which actually is `std::vector`). – zett42 Apr 15 '17 at 12:53
  • @zett42 Nice to know that! I'll swap to bool :) – Baffo rasta Apr 15 '17 at 14:15