スポンサーリンク
ホーム»Qt逆引きマニュアル»Windows関連» Windowsファイルまたはフォルダが、シンボリックリンクあるいはジャンクションであるか判定

Windowsファイルまたはフォルダが、シンボリックリンクあるいはジャンクションであるか判定

当サイトは、アフィリエイト広告を利用しています

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);

コメント

タイトルとURLをコピーしました