Solved

Filehandle to filename

Posted on 2008-10-21
6
1,641 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
Comment Utility
0
 
LVL 41

Accepted Solution

by:
graye earned 500 total points
Comment Utility
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
Comment Utility
The right api is NtQueryInformationFile()
or GetFinalPathNameByHandle()  on Vista, which is a wrapper for NtQueryInformationFile ()
0
 
LVL 41

Expert Comment

by:graye
Comment Utility
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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

For a while now I'v been searching for a circular progress control, much like the one you get when first starting your Silverlight application. I found a couple that were written in WPF and there were a few written in Silverlight, but all appeared o…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
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…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

743 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now