簡體   English   中英

在C / C ++中創建Windows NTFS目錄聯結時出現問題

[英]Issue creating Windows NTFS directory junction in C/C++

我正在嘗試使用Visual C ++做到這一點。 這段代碼似乎創建了一個具有正確目標集的聯結,但是聯結的大小為0,當我單擊它時,我得到:

錯誤信息

這是代碼:

#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <ole2.h>
#include <errno.h>

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;
    };
} REPARSE_DATA_BUFFER;

#define REPARSE_MOUNTPOINT_HEADER_SIZE 8

bool createJunction(WCHAR *linkPath, WCHAR *newTargetPath) {
    int create_status = CreateDirectory(linkPath, NULL);

    // If the directory already existed, treat it as a success.
    if (create_status == 0 && (GetLastError() != ERROR_ALREADY_EXISTS || (GetFileAttributesW(linkPath) & FILE_ATTRIBUTE_DIRECTORY) != 0))
        return false;

    HANDLE handle = CreateFile(linkPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
    if (handle == INVALID_HANDLE_VALUE)
    {
        _tprintf(_T("Could not open dir '%s'; error: %d\n"), linkPath, GetLastError());
        CloseHandle(handle);
        return false;
    }

    int target_len = wcslen(newTargetPath);
    if (target_len > MAX_PATH - 1) {
        CloseHandle(handle);
        return false;
    }

    int reparse_data_buffer_size = sizeof REPARSE_DATA_BUFFER + 2 * MAX_PATH * sizeof WCHAR;
    REPARSE_DATA_BUFFER* reparse_data_buffer = static_cast<REPARSE_DATA_BUFFER*>(calloc(reparse_data_buffer_size, 1));

    reparse_data_buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
    wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer, newTargetPath);
    wcscpy(reparse_data_buffer->MountPointReparseBuffer.PathBuffer + target_len + 1, newTargetPath);
    reparse_data_buffer->MountPointReparseBuffer.SubstituteNameOffset = 0;
    reparse_data_buffer->MountPointReparseBuffer.SubstituteNameLength = target_len * sizeof(WCHAR);
    reparse_data_buffer->MountPointReparseBuffer.PrintNameOffset = (target_len + 1) * sizeof(WCHAR);
    reparse_data_buffer->MountPointReparseBuffer.PrintNameLength = target_len * sizeof(WCHAR);
    reparse_data_buffer->ReparseDataLength = (target_len + 1) * 2 * sizeof(WCHAR) + REPARSE_MOUNTPOINT_HEADER_SIZE;

    DWORD dummy_received_bytes;
    int result = DeviceIoControl(
        handle,
        FSCTL_SET_REPARSE_POINT,
        reparse_data_buffer,
        reparse_data_buffer->ReparseDataLength + REPARSE_MOUNTPOINT_HEADER_SIZE,
        NULL,
        0,
        &dummy_received_bytes,
        NULL);
    if (CloseHandle(handle) == 0)
        return false;
    free(reparse_data_buffer);

    return (result != 0);
}

int _tmain(int argc, _TCHAR* argv[])
{
    createJunction(L"C:\\Users\\Weston\\Desktop\\New folder\\Junction of asdf", L"C:\\Users\\Weston\\Desktop\\New folder\\asdf");

    _tprintf(_T("Execution complete.\n"));
    getchar();
}

我幾乎可以肯定我沒有在某個地方正確設置大小,但是不確定什么地方。 沒有錯誤或警告,似乎只是創建了大小為0的聯結(具有正確的名稱,目標和聯結類型)。

沒有在目標路徑前加上\\??\\ 這樣做是我要做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM