Even if you open a file with GUID, you can still get its name, or at least one of its names

Raymond Chen

Raymond

Some time ago, I showed how you could eschew file names entirely and use GUIDs to open your files. But even if you choose to open the file with a GUID, you can still get its name.

Take the second program from that earlier article and make these changes:

#define UNICODE
#define _UNICODE
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <ole2.h>

int __cdecl _tmain(int argc, PTSTR *argv)
{
 HANDLE hRoot = CreateFile(_T("C:\\"), 0,
                 FILE_SHARE_READ | FILE_SHARE_WRITE |
                 FILE_SHARE_DELETE, NULL,
                 OPEN_EXISTING,
                 FILE_FLAG_BACKUP_SEMANTICS, NULL);
 if (hRoot != INVALID_HANDLE_VALUE) {
  FILE_ID_DESCRIPTOR desc;
  desc.dwSize = sizeof(desc);
  desc.Type = ObjectIdType;
  if (SUCCEEDED(CLSIDFromString(argv[1], &desc.ObjectId))) {
   HANDLE h = OpenFileById(hRoot, &desc, GENERIC_READ,
                 FILE_SHARE_READ | FILE_SHARE_WRITE |
                 FILE_SHARE_DELETE, NULL, 0);
   if (h != INVALID_HANDLE_VALUE) {
    TCHAR buffer[MAX_PATH];
    DWORD result = GetFinalPathNameByHandle(h,
                                buffer, ARRAYSIZE(buffer));
    if (result > 0 && result < ARRAYSIZE(buffer)) {
     _tprintf(_T("Final path is %s\n"), buffer);
    }
    CloseHandle(h);
   }
  }
  CloseHandle(hRoot);
 }
 return 0;
}

There’s a catch: If the file has multiple names (say, due to hard links), then only one of the names is returned, and you don’t get to pick which one. The system will pick one arbitrarily.

You can get the other names with the FindFirstFileName function, which I discussed some time ago.

Raymond Chen
Raymond Chen

Follow Raymond   

7 Comments
Avatar
Ji Luo 2019-04-10 15:31:37
I was curious enough to dig up the new link for {7ecf65a0-4b78-5f9b-e77c-8770091c0100} in the linked article: https://devblogs.microsoft.com/oldnewthing/20040315-00/?p=40253 It's converted from a mocked SID.
Harold H
Harold H 2019-04-10 15:34:16
It seems that the process of transferring old articles over to the new system has changed the formatting, resulting in a sort of Raymond Haiku. https://devblogs.microsoft.com/oldnewthing/?p=10103 A customer asked,“Given a hardlink name,is it possible to get the original file name usedto create it in the first place?”
Avatar
Stuart Dunkeld 2019-04-10 16:52:32
> The system will pick one arbitrarily. "Arbitrariness is the quality of being 'determined by chance, whim, or impulse, and not by necessity, reason, or principle'" So it will pick one at random chance, or by some kind of 'code whim'? I'm hoping not 'by impulse' as that would indicate a little more consciousness than I like to see in operating systems..
Avatar
Jo M 2019-05-02 23:46:10
I wonder why do you insist on showing code for 128 bit GUID instead of 64 bit fileID ? Assume that the scope is NTFS volume in our server. Inside that volume are many files and we want to shortcut the text path into reliable 64 bit number. Assume there are long term files over there. They are never moved and if they would move, that would be inside their volume. can you see the usefulness ?  I would expect GetFileByID to work on these 64 bit numbers. i did try the code with 128 bits and I get error 87. Checked the parameters many times. Does this have to do with admin rights ? I would not think so. Tons of verbiage all over the net about fileID but nobody talks about the usefulness of 64 bit access numbers instead of text pathes on the server. If you address me here, please share similar technique for use on Unix, hence Mac and Linux. Mac wants me to use bookmarks which is self defeating the usefulness. The good news is that Mac is not my first choice for server.