Thank you very much, I have succeeded in resolving my problem , thank you a
lot !
I implemented it by a class like below:
.h
#pragma once
//
// Here below typedefs are copied from NTDDK.
typedef LONG NTSTATUS;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef enum _FILE_INFORMATION_CLASS {
// end_wdm
FileDirectoryInformation = 1,
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4 wdm
FileStandardInformation, // 5 wdm
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14 wdm
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20 wdm
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileMaximumInformation
// begin_wdm
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _FILE_NAME_INFORMATION {
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;
typedef NTSTATUS (NTAPI * PFNNTQUERYINFOFILE)( HANDLE, PIO_STATUS_BLOCK,
PVOID, ULONG, FILE_INFORMATION_CLASS );
class CObtainFileInfo
{
public:
CObtainFileInfo(void);
~CObtainFileInfo(void);
public:
BOOL GetFileNameByHandle( HANDLE hFile, LPSTR lpszNameBuf, DWORD dwSize );
private:
BOOL GetFileVolByHandle( HANDLE hFile, LPSTR lpszVol, DWORD dwSize, bool
bEgnoreFloppy=true );
private:
HMODULE m_hNtDll;
PFNNTQUERYINFOFILE m_lpfnQueryInfoFile;
};
.cpp
#include “StdAfx.h”
#include “.\obtainfileinfo.h”
#include <assert.h>
CObtainFileInfo::CObtainFileInfo(void)
: m_hNtDll( NULL )
, m_lpfnQueryInfoFile( NULL )
{
m_hNtDll = ::LoadLibrary( “NTDLL.dll” );
if( m_hNtDll )
{
m_lpfnQueryInfoFile = (PFNNTQUERYINFOFILE)::GetProcAddress( m_hNtDll,
“NtQueryInformationFile” );
if( !m_lpfnQueryInfoFile)
OutputDebugString( “Get NtQueryInformationFile API pointer failed\n” );
}
else
{
OutputDebugString( “Load NTDLL.dll failed\n” );
}
}
CObtainFileInfo::~CObtainFileInfo(void)
{
if( m_hNtDll )
::FreeLibrary( m_hNtDll );
}
#define FILEINFO_BUF_LEN(len) len-(1/for terminator/+2/for prefix
volume/)sizeof(WCHAR)
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
BOOL CObtainFileInfo::GetFileNameByHandle( HANDLE hFile, LPSTR lpszNameBuf,
DWORD dwSize )
{
if( hFile == INVALID_HANDLE_VALUE || !lpszNameBuf || dwSize==0 )
return FALSE;
if( !m_lpfnQueryInfoFile )
return FALSE;
IO_STATUS_BLOCK io;
FILE_NAME_INFORMATION * pFni = (PFILE_NAME_INFORMATION)new
TCHAR[MAX_PATH2];
if( !pFni )
return FALSE;
memset( pFni, 0, 2MAX_PATH );
__try
{
NTSTATUS status = (m_lpfnQueryInfoFile)( hFile, &io, pFni,
FILEINFO_BUF_LEN(2MAX_PATH), FileNameInformation );
if( !NT_SUCCESS(status) )
{
//delete[] pFni;
OutputDebugString( “NtQueryInformationFile failed\n” );
return FALSE;
}
//
// WCHAR to ANSI string
char ansi[MAX_PATH2];
memset( ansi, 0, sizeof(ansi) );
BOOL bDef;
int bytes = WideCharToMultiByte( CP_ACP, 0, pFni->FileName, -1, ansi,
sizeof(ansi), NULL, &bDef );//include the terminator.
assert( bytes < sizeof(ansi) );
if( dwSize < strlen(ansi)+2 )
{
OutputDebugString( “Insufficient memory for getting file name from
hanel.\n”);
return FALSE;
}
TCHAR vol[3];
memset( vol, 0, sizeof(vol) );
if( !GetFileVolByHandle(hFile, vol, sizeof(vol) ) )
return FALSE;
lpszNameBuf = ‘\0’;
_tcscpy( lpszNameBuf, vol );
if( ansi[0] != ‘\’ )
_tcscat( lpszNameBuf, “\” );
_tcscat( lpszNameBuf, ansi );
return TRUE;
}
__finally
{
delete[] pFni;
}
return FALSE;
}
BOOL CObtainFileInfo::GetFileVolByHandle( HANDLE hFile, LPSTR lpszVol, DWORD
dwSize,
bool bEgnoreFloppy/ =true /)
{
ASSERT( hFile != INVALID_HANDLE_VALUE && dwSize >= 3 );
HANDLE hVol = INVALID_HANDLE_VALUE;
__try
{
::SetErrorMode( SEM_FAILCRITICALERRORS );
//
// Get file volume
BY_HANDLE_FILE_INFORMATION bhfi;
BOOL bOk = GetFileInformationByHandle( hFile, &bhfi );
if( !bOk )
{
//delete[] pFni;
OutputDebugString( “GetFileInformationByHandle failed\n” );
return FALSE;
}
TCHAR szDriveSet[MAX_PATH2];
memset( szDriveSet, 0, sizeof(szDriveSet) );
::GetLogicalDriveStrings( sizeof(szDriveSet)-1, szDriveSet );
TCHAR szDrive[4] = _T(" :\"); //such as “C:”
TCHAR * p = szDriveSet;
do
{
szDrive[0] = *p; //copy the drive set.
if( bEgnoreFloppy && (szDrive[0] == ‘A’ || szDrive[0] == ‘a’) )
{
while( *p++ );
continue;
}
DWORD dwVolSn = 0;
::GetVolumeInformation( szDrive, NULL, 0, &dwVolSn, NULL, NULL, NULL,
0 );
if( dwVolSn == bhfi.dwVolumeSerialNumber )
{
_tcsncpy( lpszVol, szDrive, 2 );
return TRUE;
}
//
// Extract the next logical drive set.
while( *p++ );
} while( *p );
}
__finally
{
::SetErrorMode( 0 ); //set error mode to system default.
}
return FALSE;
}</assert.h>