まず、アプリケーションにマニフェストを含めて、管理者権限で実行されるようにする必要があります。次に、APISE_BACKUP_NAME
を使用して特権を有効にする必要があります。AdjustTokenPrivileges
次にFILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE
、フラグを として使用することをお勧めしますsharedMode
。CreateFile
これで、 を使用してディレクトリ ハンドルを開き、 を使用GetFileInformationByHandle
して を取得できるはずですBY_HANDLE_FILE_INFORMATION
。
更新: おそらく、次の簡単なデモ プログラムが役立ちます
#include <windows.h>
#include <tchar.h>
int _tmain()
{
HANDLE hAccessToken = NULL;
HANDLE hFile = INVALID_HANDLE_VALUE;
__try {
LUID luidPrivilege;
DWORD dwErrorCode;
BY_HANDLE_FILE_INFORMATION fiFileInfo;
// -----------------------------------------------------
// first of all we need anable SE_BACKUP_NAME privilege
// -----------------------------------------------------
if (!OpenProcessToken (GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&hAccessToken))
__leave;
if (LookupPrivilegeValue (NULL, SE_BACKUP_NAME, &luidPrivilege)) {
TOKEN_PRIVILEGES tpPrivileges;
tpPrivileges.PrivilegeCount = 1;
tpPrivileges.Privileges[0].Luid = luidPrivilege;
tpPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges (hAccessToken, FALSE, &tpPrivileges,
0, NULL, NULL);
if ((dwErrorCode = GetLastError ()) != ERROR_SUCCESS)
__leave;
}
else
__leave;
// -----------------------------------------------------
// now one can open directory and get
// -----------------------------------------------------
hFile = CreateFile (TEXT("C:\\"),
0, //GENERIC_READ,
0, //FILE_SHARE_READ, //FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
__leave;
if (!GetFileInformationByHandle (hFile, &fiFileInfo))
__leave;
_tprintf(TEXT("VolumeSerialNumber: 0x%08X\n"), fiFileInfo.dwVolumeSerialNumber);
_tprintf(TEXT("FileIndex: 0x%08X%08X\n"), fiFileInfo.nFileIndexHigh, fiFileInfo.nFileIndexLow);
}
__finally {
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle (hFile);
if (hAccessToken != NULL)
CloseHandle (hAccessToken);
}
return 0;
}
プログラムはディレクトリを開きC:\
、NTFS 上のディレクトリを識別するボリューム シリアル番号とファイル インデックスを表示します。プログラムを短くするために、すべてのエラー メッセージを削除しました (__leave
ステートメントを参照)。「UAC実行レベル」として使用する必要がある前にすでに述べたようにrequireAdministrator
(リンカー設定の「マニフェストファイル」部分を参照)。上記のコードはテスト済みで、私で動作します。C# で同じコードを再現できます。