Windowsファイルまたはフォルダが、シンボリックリンクあるいはジャンクションであるか判定する。
REPARSE_DATA_BUFFER構造体が定義されているntifs.hが読み込めなかったため、
ヘッダーファイルで構造体を定義しています。
※以下のサイトを参考にさせて頂きました。
環境:QT5.5
リンク
http://doc.qt.io/qt-5/qstring.html
インクルードファイル
#include
構造体定義
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;
コード
// ファイルパスを設定(結果はジャンクションになる)
QString strPath = "C:/ProgramData/Application Data";
int ret;
HANDLE hToken;
HANDLE hDir;
TOKEN_PRIVILEGES tp;
LPCWSTR path_buf = reinterpret_cast(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);
コメント