Как получить имя файла из дескриптора файла в Windows, используя C? - PullRequest
2 голосов
/ 28 ноября 2010

Я пытаюсь получить имя файла из заданного дескриптора файла.

Я видел, что GetFileInformationByHandle может быть полезным, но возвращаемая структура не содержит никакой информации об имени файла (http://msdn.microsoft.com/en-us/library/aa363788%28v=VS.85%29.aspx).

Как я могу это сделать?

EDIT:

Я пытался установить API Windows FileID, чтобы GetFileInformationByHandleEx работал в Windows XP. Но при включении fileextd.h я получаю следующие ошибки

c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(16) : error C2011: '_FILE_INFO_BY_HANDLE_CLASS' : 'enum' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13900) : see declaration of '_FILE_INFO_BY_HANDLE_CLASS'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(32) : error C2011: '_FILE_BASIC_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13917) : see declaration of '_FILE_BASIC_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(40) : error C2011: '_FILE_STANDARD_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13925) : see declaration of '_FILE_STANDARD_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(48) : error C2011: '_FILE_NAME_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13933) : see declaration of '_FILE_NAME_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(53) : error C2011: '_FILE_RENAME_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13938) : see declaration of '_FILE_RENAME_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(60) : error C2011: '_FILE_ALLOCATION_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13945) : see declaration of '_FILE_ALLOCATION_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(64) : error C2011: '_FILE_END_OF_FILE_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13949) : see declaration of '_FILE_END_OF_FILE_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(68) : error C2011: '_FILE_STREAM_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13953) : see declaration of '_FILE_STREAM_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(76) : error C2011: '_FILE_COMPRESSION_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13961) : see declaration of '_FILE_COMPRESSION_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(85) : error C2011: '_FILE_ATTRIBUTE_TAG_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13970) : see declaration of '_FILE_ATTRIBUTE_TAG_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(90) : error C2011: '_FILE_DISPOSITION_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13975) : see declaration of '_FILE_DISPOSITION_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(94) : error C2011: '_FILE_ID_BOTH_DIR_INFO' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(13979) : see declaration of '_FILE_ID_BOTH_DIR_INFO'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(130) : error C2011: '_FILE_ID_TYPE' : 'enum' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(14026) : see declaration of '_FILE_ID_TYPE'
c:\programmi\microsoft visual studio 9.0\vc\include\fileextd.h(135) : error C2011: 'FILE_ID_DESCRIPTOR' : 'struct' type redefinition
        c:\programmi\microsoft sdks\windows\v6.1\include\winbase.h(14032) : see declaration of 'FILE_ID_DESCRIPTOR'
c:\documents and settings\lab\documenti\visual studio 2008\projects\sandbox\sandbox\funcs_files.cpp(26) : error C2079: 'lpFileInformation' uses undefined struct '_FILE_NAME_INFO'
c:\documents and settings\lab\documenti\visual studio 2008\projects\sandbox\sandbox\funcs_files.cpp(35) : error C2228: left of '.FileName' must have class/struct/union
        type is 'int'

Из следующего кода:

#include <windows.h>
#include <fileextd.h>

LPVOID GetFileNameFromHandle(HANDLE hFile) {
    FILE_NAME_INFO lpFileInformation;
    BOOL bWorked;

    bWorked = GetFileInformationByHandleEx(
        hFile,
        FileNameInfo,
        &lpFileInformation,
        sizeof(FILE_NAME_INFO));

    return lpFileInformation.FileName;
}

Ответы [ 5 ]

2 голосов
/ 21 июля 2015
BOOL    GetFileNameFromHandle(HANDLE hFile, TCHAR *pszFileName, const unsigned int uiMaxLen)
{
    pszFileName[0]=0;

    std::unique_ptr<BYTE[]> ptrcFni(new BYTE[_MAX_PATH * sizeof(TCHAR) + sizeof(FILE_NAME_INFO)]);
    FILE_NAME_INFO *pFni = reinterpret_cast<FILE_NAME_INFO *>(ptrcFni.get());

    BOOL b = GetFileInformationByHandleEx(hFile, 
                                        FileNameInfo,
                                        pFni,
                                        sizeof(FILE_NAME_INFO) + (_MAX_PATH * sizeof(TCHAR)) );
    if ( b )
    {
#ifdef  _UNICODE
         wcsncpy_s(pszFileName, 
                min(uiMaxLen, (pFni->FileNameLength / sizeof(pFni->FileName[0])) + 1 ), 
                pFni->FileName, 
                _TRUNCATE);
#else
        strncpy_s(pszFileName, 
                min(uiMaxLen, (pFni->FileNameLength / sizeof(pFni->FileName[0])) + 1), 
                CW2A(pFni->FileName), 
                _TRUNCATE);
#endif
    }
    return b;
}
2 голосов
/ 28 ноября 2010

Привет, если вам нужно имя файла из дескриптора, вы можете прочитать эту статью MS http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx или используйте этот GetFileInformationByHandleEx

1 голос
/ 13 марта 2011

Существует правильный способ сделать это, который работает в Windows XP, как для файлов, так и для каталогов; Я объяснил это в другом посте здесь .

0 голосов
/ 13 ноября 2017

Для Vista и более поздних версий взгляните на GetFinalPathNameByHandle (например, mehrdad wrote)

Это более удобный IMO и позволяет больше настроек, чем GetFileInformationByHandleEx , и это устраняет необходимость выделения нестандартного размера FILE_NAME_INFO struct.

Пример:

DWORD size = GetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
if (size == 0) return L"(NOT FOUND)";
std::wstring fname(size, L'0');
size = GetFinalPathNameByHandleW(handle, &fname.front(), size, VOLUME_NAME_DOS);

Обратите внимание , к нему будет добавлено \\?\ возвращаемому имени.

(Я использовал C ++ std :: wstring, чтобы избежать использования шаблона C для обработки памяти. Используйте malloc для ваших нужд).

0 голосов
/ 28 ноября 2010

Откуда вы взяли дескриптор файла? Если вы уверены, что это не дескриптор именованного канала, вы можете использовать NtQueryObject для запроса имени файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...