Solved

Filehandle to filename

Posted on 2008-10-21
6
1,664 Views
Last Modified: 2013-12-04
Is there a way to find the filename based on a filehandle in c#?

I have a IntPtr containing a filehandle to an open file, and I want to know what the name of that file is.
I did not open the file myself, and only have a function that receives the handle. But I am only interested in processing some files, based on how they are named.

The attached code always prints [Unknown]
SafeFileHandle sh = new SafeFileHandle(InFile, false);
FileStream f = new FileStream(sh, FileAccess.Read);
System.Console.WriteLine(f.Name);

Open in new window

0
Comment
Question by:wiredpea
  • 2
6 Comments
 
LVL 8

Expert Comment

by:rambovn
ID: 22770259
0
 
LVL 41

Accepted Solution

by:
graye earned 500 total points
ID: 22786881
Getting the name of the file based upon it's handle is a bit difficult and requires some *very* low-level API calls.
Take a look at this VB.Net example:

Imports System.Runtime.InteropServices
Module HandleToName
    'typedef struct _UNICODE_STRING {
    '  USHORT Length;
    '  USHORT MaximumLength;
    '  PWSTR Buffer;
    '} UNICODE_STRING, *PUNICODE_STRING; 
    Structure UNICODE_STRING
        Dim Length As Short
        Dim MaximumLength As Short
        Dim Buffer As String
    End Structure
 
    'typedef struct _OBJECT_NAME_INFORMATION {
    '    UNICODE_STRING ObjectName;
    '} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
    Structure OBJECT_NAME_INFORMATION
        Dim ObjectName As UNICODE_STRING
    End Structure
 
    'NTSTATUS STDCALL NtQueryObject (
    '  IN HANDLE  ObjectHandle,  
    '  IN OBJECT_INFORMATION_CLASS  ObjectInformationClass,  
    '  OUT PVOID  ObjectInformation,  
    '  IN ULONG  Length,  
    '  OUT PULONG ResultLength  OPTIONAL 
    ')  
    Declare Function NtQueryObject Lib "ntdll" ( _
        ByVal ObjectHandle As IntPtr, _
        ByVal ObjectInformationClass As Integer, _
        ByRef ObjectInformation As Byte, _
        ByVal ObjectInformationLength As Integer, _
        ByRef ReturnLength As Integer _
    ) As Integer
 
    Const ObjectNameInformation As Integer = 1
    Const STATUS_SUCCESS As Integer = 0
    Const STATUS_BUFFER_OVERFLOW As Integer = -2147483643 '&H80000005L
    Const STATUS_INFO_LENGTH_MISMATCH As Integer = -1073741820 '&HC0000004L
 
    Function GetFileName(ByVal hObject As IntPtr) As String
        Dim dwSize, ntReturn As Integer
        Dim buf(1024) As Byte
        Dim pObjectInfo As New OBJECT_NAME_INFORMATION
        Dim ans, temp As String
 
        ans = ""
        dwSize = Marshal.SizeOf(pObjectInfo)
 
        ' do a dry run...
        ntReturn = NtQueryObject(hObject, ObjectNameInformation, buf(0), dwSize, dwSize)
        If ntReturn = STATUS_BUFFER_OVERFLOW Then
            ' do it again for real
            ntReturn = NtQueryObject(hObject, ObjectNameInformation, buf(0), dwSize, dwSize)
        End If
 
        If ntReturn = STATUS_SUCCESS Then
            ' Marshalling unmanaged strings inside structures is a bit tough, so
            ' since this is a simple one, we cheat and get the parts from a byte
            ' buffer
            pObjectInfo.ObjectName.Length = BitConverter.ToInt16(buf, 0)
            pObjectInfo.ObjectName.MaximumLength = BitConverter.ToInt16(buf, 4)
            pObjectInfo.ObjectName.Buffer = System.Text.Encoding.Unicode.GetString(buf, 8, pObjectInfo.ObjectName.Length)
            ans = pObjectInfo.ObjectName.Buffer
        End If
 
        ' let's weed out a few things that we're not really interested in.  If the
        ' device doesn't map to a drive letter, then return an empty string.
        temp = TranslateToDriveLetter(ans)
        If temp <> ans Then
            Return temp
        Else
            Return ""
        End If
    End Function
End Module

Open in new window

0
 
LVL 2

Expert Comment

by:Castorix
ID: 22789331
The right api is NtQueryInformationFile()
or GetFinalPathNameByHandle()  on Vista, which is a wrapper for NtQueryInformationFile ()
0
 
LVL 41

Expert Comment

by:graye
ID: 22789696
However, NtQueryInformationFile will deadlock if it can't successfully read from a locked stream.   The above doesn't suffer from that annoying side effect
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question