Obtaining a filename from a file handle (Windows 2000+)

Share your advanced PureBasic knowledge/code with the community.
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Obtaining a filename from a file handle (Windows 2000+)

Post by breeze4me »

Tested with PB 4.30(x86) on XP Pro SP2.

Code: Select all

; Obtaining a filename from a file handle.

Structure FILE_NAME_INFORMATION
  FileNameLength.l
  FileName.s{1024}
EndStructure

Structure IO_STATUS_BLOCK
  StructureUnion
    Status.i
    Pointer.i
  EndStructureUnion
  Information.i
EndStructure

Prototype GetMappedFileName(hProcess, lpv, *lpFilename, nSize.l)
Global GetMappedFileName.GetMappedFileName

If OSVersion() < #PB_OS_Windows_2000
  End
EndIf

If OpenLibrary(0, "Psapi.dll")
  CompilerIf #PB_Compiler_Unicode
    GetMappedFileName = GetFunction(0, "GetMappedFileNameW")
  CompilerElse
    GetMappedFileName = GetFunction(0, "GetMappedFileNameA")
  CompilerEndIf
EndIf

#FileNameInformation = 9
#ObjectNameInformation = 1
#STATUS_SUCCESS = 0

filename.s{#MAX_PATH}

If ReadFile(0, OpenFileRequester("","","",0))
  ;method 1
  If ZwQueryInformationFile_(FileID(0), @io.IO_STATUS_BLOCK, @fi.FILE_NAME_INFORMATION, SizeOf(FILE_NAME_INFORMATION), #FileNameInformation) = #STATUS_SUCCESS
    If fi\FileNameLength > 0
      filename = PeekS(@fi\filename, fi\FileNameLength, #PB_Unicode)
      drv = GetLogicalDrives_()
      For i = 0 To 25
        exist = (drv >> i) & 1
        If exist
          drv$ = Chr('A' + i) + ":"
          If FileSize(drv$ + filename) >= 0
            Debug "method 1"
            Debug filename
            Debug drv$ + filename
            Break
          EndIf
        EndIf
      Next
    EndIf
  EndIf
  
  Debug ""
  filename = ""
  
  ;method 2  -  Problem: If the file size is 0, then it seems to fail.
  ; http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
  If GetMappedFileName
    hFileMap = CreateFileMapping_(FileID(0), 0, #PAGE_READONLY, 0, 1, 0)
    If hFileMap
      pMem = MapViewOfFile_(hFileMap, #FILE_MAP_READ, 0, 0, 1)
      If pMem
        If GetMappedFileName(GetCurrentProcess_(), pMem, @filename, #MAX_PATH)
          If filename
            drv = GetLogicalDrives_()
            devname.s{#MAX_PATH}
            For i = 0 To 25
              exist = (drv >> i) & 1
              If exist
                drv$ = Chr('A' + i) + ":"
                If QueryDosDevice_(drv$, @devname, #MAX_PATH)
                  If FindString(filename, devname, 1)
                    Debug "method 2"
                    Debug filename
                    Debug drv$ + " = " + devname
                    Debug ReplaceString(filename, devname, drv$)
                    Break
                  EndIf
                EndIf
              EndIf
            Next
          EndIf
        EndIf
        UnmapViewOfFile_(pMem)
      EndIf
      CloseHandle_(hFileMap)
    EndIf
  EndIf
  
  Debug ""
  filename = ""
  
  ;method 3
  Structure OBJECT_NAME_INFORMATION ;Name.UNICODE_STRING
    Length.w
    MaximumLength.w
    Buffer.i
  EndStructure
  *name.OBJECT_NAME_INFORMATION = AllocateMemory(1024)
  If ZwQueryObject_(FileID(0), #ObjectNameInformation, *name, 1024, @res) = #STATUS_SUCCESS
    If *name\Length > 0
      filename = PeekS(*name\Buffer, *name\Length, #PB_Unicode)
      drv = GetLogicalDrives_()
      devname.s{#MAX_PATH}
      For i = 0 To 25
        exist = (drv >> i) & 1
        If exist
          drv$ = Chr('A' + i) + ":"
          If QueryDosDevice_(drv$, @devname, #MAX_PATH)
            If FindString(filename, devname, 1)
              Debug "method 3"
              Debug filename
              Debug drv$ + " = " + devname
              Debug ReplaceString(filename, devname, drv$)
              Break
            EndIf
          EndIf
        EndIf
      Next
    EndIf
  EndIf
  CloseFile(0)
EndIf

If IsLibrary(0)
  CloseLibrary(0)
EndIf
eJan
Enthusiast
Enthusiast
Posts: 366
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Post by eJan »

Thanks breeze4me.
Something goes wrong (both run/compiled), 3 methods are displayed then:
Image
Image
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Post by breeze4me »

eJan wrote:Something goes wrong (both run/compiled), 3 methods are displayed then:
Image
Would you add this line at the top of the code?

Code: Select all

SetErrorMode_(#SEM_FAILCRITICALERRORS)
eJan
Enthusiast
Enthusiast
Posts: 366
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Post by eJan »

Yes, now it work without any problems.
Image
jpd
Enthusiast
Enthusiast
Posts: 167
Joined: Fri May 21, 2004 3:31 pm

Post by jpd »

Hi breeze4me,

nice code!

Thanks for sharing.

jpd
PB 5.10 Windows 7 x64 SP1
Post Reply