Sets a reparse point. |source| will now point to |target|. Returns true if the call succeeds, false otherwise.
| 82 | // Sets a reparse point. |source| will now point to |target|. Returns true if |
| 83 | // the call succeeds, false otherwise. |
| 84 | bool SetReparsePoint(HANDLE source, const FilePath& target_path) { |
| 85 | std::wstring kPathPrefix = L"\\??\\"; |
| 86 | std::wstring target_str; |
| 87 | // The juction will not work if the target path does not start with \??\ . |
| 88 | if (kPathPrefix != target_path.value().substr(0, kPathPrefix.size())) |
| 89 | target_str += kPathPrefix; |
| 90 | target_str += target_path.value(); |
| 91 | const wchar_t* target = target_str.c_str(); |
| 92 | USHORT size_target = static_cast<USHORT>(wcslen(target)) * sizeof(target[0]); |
| 93 | char buffer[2000] = {0}; |
| 94 | DWORD returned; |
| 95 | |
| 96 | REPARSE_DATA_BUFFER* data = reinterpret_cast<REPARSE_DATA_BUFFER*>(buffer); |
| 97 | |
| 98 | data->ReparseTag = 0xa0000003; |
| 99 | memcpy(data->MountPointReparseBuffer.PathBuffer, target, size_target + 2); |
| 100 | |
| 101 | data->MountPointReparseBuffer.SubstituteNameLength = size_target; |
| 102 | data->MountPointReparseBuffer.PrintNameOffset = size_target + 2; |
| 103 | data->ReparseDataLength = size_target + 4 + 8; |
| 104 | |
| 105 | int data_size = data->ReparseDataLength + 8; |
| 106 | |
| 107 | if (!DeviceIoControl(source, FSCTL_SET_REPARSE_POINT, &buffer, data_size, |
| 108 | NULL, 0, &returned, NULL)) { |
| 109 | return false; |
| 110 | } |
| 111 | return true; |
| 112 | } |
| 113 | |
| 114 | // Delete the reparse point referenced by |source|. Returns true if the call |
| 115 | // succeeds, false otherwise. |
no test coverage detected