Один диск как точка повторной обработки

Рассмотрим следующий автономный исходный код, который я экспериментирую с Win 10 Fall Creators Update версии 10.0.16299 Build 16299

    #include <Windows.h>
#include <iostream>
#include <string>
#include <memory>

#if !defined (REPARSE_DATA_BUFFER_HEADER_SIZE)  //

// Note:
// See http://msdn.microsoft.com/en-us/library/ff552012.aspx for information about
// the following structure.
//
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, *PREPARSE_DATA_BUFFER;

#define REPARSE_DATA_BUFFER_HEADER_SIZE  FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
#endif

#if !defined(IO_REPARSE_TAG_CLOUD_7)
#define IO_REPARSE_TAG_CLOUD_7                  (0x9000701AL)
#endif

struct file_handle_close
{
void operator()(void *handle) const
{
if (static_cast<HANDLE>(handle) != INVALID_HANDLE_VALUE)
{
CloseHandle(static_cast<HANDLE>(handle));
}
}
}; // end of file_handle_close structure

typedef std::unique_ptr<void, file_handle_close>  file_handle_uptr;bool is_link(DWORD file_attrib)
{
return ((file_attrib & FILE_ATTRIBUTE_REPARSE_POINT) && !(file_attrib & FILE_ATTRIBUTE_SPARSE_FILE));
} // end of is_link()

union reparse_data_context
{
char                 buff[REPARSE_DATA_BUFFER_HEADER_SIZE + MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
REPARSE_DATA_BUFFER  reparse_data_buff;
}; // end of reparse_data_context unionvoid foo(const std::string& var,const std::wstring& path_name)
{
WIN32_FILE_ATTRIBUTE_DATA attr_ctx;
if (GetFileAttributesExW(path_name.c_str(), GetFileExInfoStandard, &attr_ctx) == 0)
{

DWORD  error_code(GetLastError());
std::cout << "Error occurred "<< error_code << "\n";
}
else
{
std::cout << var << '\n';
std::cout << "attr_ctx.dwFileAttributes  :" << attr_ctx.dwFileAttributes << '\n';
bool islink = is_link(attr_ctx.dwFileAttributes);

if(islink)
{
file_handle_uptr  handle_uptr(CreateFileW(path_name.c_str(),
FILE_READ_EA,
(FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE),
0,
OPEN_EXISTING,
(FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT),
0));
HANDLE  handle(static_cast<HANDLE>(handle_uptr.get()));
if (handle == INVALID_HANDLE_VALUE)
{
std::cout << "CreateFileW failed with : "<<GetLastError()<<'\n';
return;
}

DWORD ret_len;
reparse_data_context rctx;

if(!DeviceIoControl(handle,
FSCTL_GET_REPARSE_POINT,
nullptr,
0,
rctx.buff,
sizeof(rctx),
&ret_len,
nullptr))
{
std::cout << "DeviceIoControl failed with : "<<GetLastError()<<'\n';
return;
}
else
{
ULONG  reparse_tag(reinterpret_cast<const REPARSE_DATA_BUFFER*>(rctx.buff)->ReparseTag);
if (!IsReparseTagMicrosoft(reparse_tag))
{
std::cout << "Not a supported reparse tag" << std::endl;
return;
}
if (reparse_tag == IO_REPARSE_TAG_SYMLINK)
{

std::wstring  target_name;

{
size_t len = static_cast<size_t>((rctx.reparse_data_buff.SymbolicLinkReparseBuffer.PrintNameLength) / sizeof(wchar_t));
const size_t another = len;
std::wcout << "Target " <<  std::wstring(static_cast<wchar_t*>(rctx.reparse_data_buff.SymbolicLinkReparseBuffer.PathBuffer) +
(rctx.reparse_data_buff.SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(wchar_t)),
len);
}

{
size_t len = static_cast<size_t>((rctx.reparse_data_buff.SymbolicLinkReparseBuffer.SubstituteNameLength) / sizeof(wchar_t));

std::wcout << "Target " << std::wstring(static_cast<wchar_t*>(rctx.reparse_data_buff.SymbolicLinkReparseBuffer.PathBuffer) +
(rctx.reparse_data_buff.SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t)),
len);
}
}
else if(reparse_tag == IO_REPARSE_TAG_MOUNT_POINT)
{
// Do something similar to previous block
}
else if(reparse_tag == IO_REPARSE_TAG_CLOUD_7)
{
std::cout << " this is not a valid Reparse Point"<<std::endl;
// How to resolve a target for this ?
}
}
}
else
{
std::cout << var << "  is not a link or junction "<< '\n';
}
}
}

int main()
{
std::wstring path_name = L"C:\\Users\\someuser\\OneDrive";

foo("OneDrive",path_name);
return 0;
}

Это код, который я использую для разрешения цели одного диска, который рассматривается как IO_REPARSE_TAG_CLOUD_7 от GetFileAttributesExW функция.

я знаю это _REPARSE_DATA_STRUCTURE имеет информацию только для SymbolicLinkReparseBuffer а также MountPointReparseBuffer и он не имеет никаких полей, связанных с точками повторной обработки, такими как One Drive.

Я проверил набор драйверов Windows (для обновления создателей осенью) ntifs.h файл, чтобы увидеть, обновлена ​​ли структура для поддержки One Drive. Однако, похоже, это не так.

Я также пытался получить информацию о цели One Drive из SymbolicLinkReparseBuffer а также MountPointReparseBuffer как сделано в первом блоке if. Однако, это закончилось тем, что дало мне мусор.

Вопросы:

1) Как правильно определить цель для REPARSE_POINTS, например, One Drive?

2) Обновление SDK для Windows 10 Fall Creators добавляет больше таких тегов REPARSE_POINT.
Каково общее правило большого пальца, чтобы рассматривать их (то есть источник REPARSE_POINTS), если не удается определить цель для него (например, один диск)? Как файл или как каталог?

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]