Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Filehandle to filename

Posted on 2008-10-21
6
Medium Priority
?
1,760 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
4 Comments
 
LVL 8

Expert Comment

by:rambovn
ID: 22770259
0
 
LVL 41

Accepted Solution

by:
graye earned 2000 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

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

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

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
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 Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
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…

580 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