はじめに
VC++でファイルハンドルからファイル名などのファイル情報を取り出したい。
たとえば、CloseHandleのラッパー関数があって、すべての呼び出し元はこのラッパー関数を使っていたとします。ラッパー関数内でファイルハンドルからファイル情報を取得できれば、どのファイルのファイルハンドルを閉じたかログに出力したりできるようになると考えました。
BOOL CloseHandleWrapper(HANDLE h) { // なんらかの処理 // close Handle BOOL ret = CloseHandle(h); return ret; }
ファイルハンドルからファイル情報を取得する
GetFileInformationByHandleというAPIを使うと、ファイルハンドルからファイル情報を取得できそうだったのですが、残念ながらファイル名は取得できません。
そのかわりに、nFileIndexHighとnFileIndexLowの2つの値が取得できます。
nFileIndexHigh
The high-order part of a unique identifier that is associated with a file. For more information, see nFileIndexLow.
nFileIndexLow
The low-order part of a unique identifier that is associated with a file.
MSDNにはunique identifierの一部とあり、同じファイルであればこの2つの値も一致するはずです。逆に異なるファイルであれば、nFileIndexHighとnFileIndexLowも異なります。
サンプルプログラム
以下のようなサンプルプログラムを作って、GetFileInformationByHandleを使ってみました。
#include "afx.h" #include <windows.h> BOOL CloseHandleWrapper(HANDLE); BOOL CloseHandleWrapper(HANDLE h) { BY_HANDLE_FILE_INFORMATION fi1; GetFileInformationByHandle(h, &fi1); printf("fi1.nFileIndexHigh::%ld fi1.nFileIndexLow::%ld\n", fi1.nFileIndexHigh, fi1.nFileIndexLow); // close Handle BOOL ret = CloseHandle(h); GetFileInformationByHandle(h, &fi1); printf("fi1.nFileIndexHigh::%ld fi1.nFileIndexLow::%ld\n", fi1.nFileIndexHigh, fi1.nFileIndexLow); return ret; } int _tmain(int argc, _TCHAR *argv[]) { // 1.open file HANDLE handle1 = CreateFile("c:\\test1.txt" , GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); if (handle1 == INVALID_HANDLE_VALUE) { return 1; } // 2.seek file BOOL ret = SetFilePointer(handle1, NULL, NULL, FILE_END); if (ret == INVALID_SET_FILE_POINTER) { CloseHandleWrapper(handle1); return 1; } // 3. write file DWORD dw = 0; ret = WriteFile(handle1, "Hellow World\n", sizeof("Hellow World"), &dw, NULL); if (ret == FALSE) { CloseHandleWrapper(handle1); return 1; } // 4. close Handle ret = CloseHandleWrapper(handle1); if (ret == FALSE) { return 1; } handle1 = NULL; // 1.open file HANDLE handle2 = CreateFile("c:\\test2.txt" , GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ , NULL , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL); if (handle2 == INVALID_HANDLE_VALUE) { return 1; } // 2.seek file ret = SetFilePointer(handle2, NULL, NULL, FILE_END); if (ret == INVALID_SET_FILE_POINTER) { CloseHandleWrapper(handle2); return 1; } // 3. write file dw = 0; ret = WriteFile(handle2, "Hellow World\n", sizeof("Hellow World"), &dw, NULL); if (ret == FALSE) { CloseHandleWrapper(handle2); return 1; } // 4. close Handle ret = CloseHandleWrapper(handle2); if (ret == FALSE) { return 1; } handle2 = NULL; }
実行結果
サンプルプログラムを実行した結果、確かに2つのファイルでは、nFileIndexHighとnFileIndexLowは異なります。
test1.txtは、fi1.nFileIndexHigh::3473408 fi1.nFileIndexLow::73864。test2.txtは、fi1.nFileIndexHigh::9240576 fi1.nFileIndexLow::75317という結果でした。
fi1.nFileIndexHigh::3473408 fi1.nFileIndexLow::73864 fi1.nFileIndexHigh::3473408 fi1.nFileIndexLow::73864 fi1.nFileIndexHigh::9240576 fi1.nFileIndexLow::75317 fi1.nFileIndexHigh::9240576 fi1.nFileIndexLow::75317