Windowsファイルまたはフォルダが、シンボリックリンクあるいはジャンクションであるか判定する。
REPARSE_DATA_BUFFER構造体が定義されているntifs.hが読み込めなかったため、
ヘッダーファイルで構造体を定義しています。
※以下のサイトを参考にさせて頂きました。
環境:QT5.5
リンク
http://doc.qt.io/qt-5/qstring.html
インクルードファイル
1 | #include <QString> |
構造体定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; USHORT ReparseDataLength; USHORT Reserved; union { struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; ULONG Flags; WCHAR PathBuffer[1]; } SymbolicLinkReparseBuffer; struct { USHORT SubstituteNameOffset; USHORT SubstituteNameLength; USHORT PrintNameOffset; USHORT PrintNameLength; WCHAR PathBuffer[1]; } MountPointReparseBuffer; struct { UCHAR DataBuffer[1]; } GenericReparseBuffer; } DUMMYUNIONNAME; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; |
コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // ファイルパスを設定(結果はジャンクションになる) QString strPath = "C:/ProgramData/Application Data"; int ret; HANDLE hToken; HANDLE hDir; TOKEN_PRIVILEGES tp; LPCWSTR path_buf = reinterpret_cast<LPCWSTR>(strPath.utf16()); // プロセスに権限付与 ※SE_BACKUP_NAMEがないと Error:5になる。 OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &tp.Privileges[0].Luid); tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); CloseHandle(hToken); // Directory 情報取得 hDir = CreateFile(path_buf, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL); if ( INVALID_HANDLE_VALUE == hDir ) { return false; } BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; DWORD dwRet; REPARSE_DATA_BUFFER &reparseBuf = (REPARSE_DATA_BUFFER &)buf; if ( !DeviceIoControl(hDir, FSCTL_GET_REPARSE_POINT, NULL, 0, &reparseBuf,MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRet, NULL) ) { DWORD dwret = GetLastError(); if ( ERROR_NOT_A_REPARSE_POINT == dwret ) { // REPARSE POINT(シンボリックリンク・ジャンクション)ではない } else { CloseHandle(hDir); return false; } } // タイプを取得 if ( IO_REPARSE_TAG_MOUNT_POINT == reparseBuf.ReparseTag ) { // Junction } else if ( IO_REPARSE_TAG_SYMLINK == reparseBuf.ReparseTag ) { // シンボリックリンク } else { // それ以外 } CloseHandle(hDir); |
コメント