ee7901e1f2affe923ea8855777ca2a12f33a26a3
[reactos.git] / dll / shellext / shellbtrfs / mountmgr_local.cpp
1 #include "shellext.h"
2 #ifndef __REACTOS__
3 #include "mountmgr.h"
4 #else
5 #include "mountmgr_local.h"
6 #endif
7 #include <mountmgr.h>
8
9 using namespace std;
10
11 mountmgr::mountmgr() {
12 UNICODE_STRING us;
13 OBJECT_ATTRIBUTES attr;
14 IO_STATUS_BLOCK iosb;
15 NTSTATUS Status;
16
17 RtlInitUnicodeString(&us, MOUNTMGR_DEVICE_NAME);
18 InitializeObjectAttributes(&attr, &us, 0, nullptr, nullptr);
19
20 Status = NtOpenFile(&h, FILE_GENERIC_READ | FILE_GENERIC_WRITE, &attr, &iosb,
21 FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT);
22
23 if (!NT_SUCCESS(Status))
24 throw ntstatus_error(Status);
25 }
26
27 mountmgr::~mountmgr() {
28 NtClose(h);
29 }
30
31 void mountmgr::create_point(const wstring_view& symlink, const wstring_view& device) const {
32 NTSTATUS Status;
33 IO_STATUS_BLOCK iosb;
34
35 vector<uint8_t> buf(sizeof(MOUNTMGR_CREATE_POINT_INPUT) + ((symlink.length() + device.length()) * sizeof(WCHAR)));
36 #ifndef __REACTOS__
37 auto mcpi = reinterpret_cast<MOUNTMGR_CREATE_POINT_INPUT*>(buf.data());
38 #else
39 auto mcpi = reinterpret_cast<MOUNTMGR_CREATE_POINT_INPUT*>(&buf[0]);
40 #endif
41
42 mcpi->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT);
43 mcpi->SymbolicLinkNameLength = (USHORT)(symlink.length() * sizeof(WCHAR));
44 mcpi->DeviceNameOffset = (USHORT)(mcpi->SymbolicLinkNameOffset + mcpi->SymbolicLinkNameLength);
45 mcpi->DeviceNameLength = (USHORT)(device.length() * sizeof(WCHAR));
46
47 memcpy((uint8_t*)mcpi + mcpi->SymbolicLinkNameOffset, symlink.data(), symlink.length() * sizeof(WCHAR));
48 memcpy((uint8_t*)mcpi + mcpi->DeviceNameOffset, device.data(), device.length() * sizeof(WCHAR));
49
50 Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_CREATE_POINT,
51 buf.data(), (ULONG)buf.size(), nullptr, 0);
52
53 if (!NT_SUCCESS(Status))
54 throw ntstatus_error(Status);
55 }
56
57 void mountmgr::delete_points(const wstring_view& symlink, const wstring_view& unique_id, const wstring_view& device_name) const {
58 NTSTATUS Status;
59 IO_STATUS_BLOCK iosb;
60
61 vector<uint8_t> buf(sizeof(MOUNTMGR_MOUNT_POINT) + ((symlink.length() + unique_id.length() + device_name.length()) * sizeof(WCHAR)));
62 #ifndef __REACTOS__
63 auto mmp = reinterpret_cast<MOUNTMGR_MOUNT_POINT*>(buf.data());
64 #else
65 auto mmp = reinterpret_cast<MOUNTMGR_MOUNT_POINT*>(&buf[0]);
66 #endif
67
68 memset(mmp, 0, sizeof(MOUNTMGR_MOUNT_POINT));
69
70 if (symlink.length() > 0) {
71 mmp->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
72 mmp->SymbolicLinkNameLength = (USHORT)(symlink.length() * sizeof(WCHAR));
73 memcpy((uint8_t*)mmp + mmp->SymbolicLinkNameOffset, symlink.data(), symlink.length() * sizeof(WCHAR));
74 }
75
76 if (unique_id.length() > 0) {
77 if (mmp->SymbolicLinkNameLength == 0)
78 mmp->UniqueIdOffset = sizeof(MOUNTMGR_MOUNT_POINT);
79 else
80 mmp->UniqueIdOffset = mmp->SymbolicLinkNameOffset + mmp->SymbolicLinkNameLength;
81
82 mmp->UniqueIdLength = (USHORT)(unique_id.length() * sizeof(WCHAR));
83 memcpy((uint8_t*)mmp + mmp->UniqueIdOffset, unique_id.data(), unique_id.length() * sizeof(WCHAR));
84 }
85
86 if (device_name.length() > 0) {
87 if (mmp->SymbolicLinkNameLength == 0 && mmp->UniqueIdOffset == 0)
88 mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
89 else if (mmp->SymbolicLinkNameLength != 0)
90 mmp->DeviceNameOffset = mmp->SymbolicLinkNameOffset + mmp->SymbolicLinkNameLength;
91 else
92 mmp->DeviceNameOffset = mmp->UniqueIdOffset + mmp->UniqueIdLength;
93
94 mmp->DeviceNameLength = (USHORT)(device_name.length() * sizeof(WCHAR));
95 memcpy((uint8_t*)mmp + mmp->DeviceNameOffset, device_name.data(), device_name.length() * sizeof(WCHAR));
96 }
97
98 vector<uint8_t> buf2(sizeof(MOUNTMGR_MOUNT_POINTS));
99 #ifndef __REACTOS__
100 auto mmps = reinterpret_cast<MOUNTMGR_MOUNT_POINTS*>(buf2.data());
101 #else
102 auto mmps = reinterpret_cast<MOUNTMGR_MOUNT_POINTS*>(&buf2[0]);
103 #endif
104
105 Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_DELETE_POINTS,
106 buf.data(), (ULONG)buf.size(), buf2.data(), (ULONG)buf2.size());
107
108 if (Status == STATUS_BUFFER_OVERFLOW) {
109 buf2.resize(mmps->Size);
110
111 Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_DELETE_POINTS,
112 buf.data(), (ULONG)buf.size(), buf2.data(), (ULONG)buf2.size());
113 }
114
115 if (!NT_SUCCESS(Status))
116 throw ntstatus_error(Status);
117 }
118
119 vector<mountmgr_point> mountmgr::query_points(const wstring_view& symlink, const wstring_view& unique_id, const wstring_view& device_name) const {
120 NTSTATUS Status;
121 IO_STATUS_BLOCK iosb;
122 vector<mountmgr_point> v;
123
124 vector<uint8_t> buf(sizeof(MOUNTMGR_MOUNT_POINT) + ((symlink.length() + unique_id.length() + device_name.length()) * sizeof(WCHAR)));
125 #ifndef __REACTOS__
126 auto mmp = reinterpret_cast<MOUNTMGR_MOUNT_POINT*>(buf.data());
127 #else
128 auto mmp = reinterpret_cast<MOUNTMGR_MOUNT_POINT*>(&buf[0]);
129 #endif
130
131 memset(mmp, 0, sizeof(MOUNTMGR_MOUNT_POINT));
132
133 if (symlink.length() > 0) {
134 mmp->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
135 mmp->SymbolicLinkNameLength = (USHORT)(symlink.length() * sizeof(WCHAR));
136 memcpy((uint8_t*)mmp + mmp->SymbolicLinkNameOffset, symlink.data(), symlink.length() * sizeof(WCHAR));
137 }
138
139 if (unique_id.length() > 0) {
140 if (mmp->SymbolicLinkNameLength == 0)
141 mmp->UniqueIdOffset = sizeof(MOUNTMGR_MOUNT_POINT);
142 else
143 mmp->UniqueIdOffset = mmp->SymbolicLinkNameOffset + mmp->SymbolicLinkNameLength;
144
145 mmp->UniqueIdLength = (USHORT)(unique_id.length() * sizeof(WCHAR));
146 memcpy((uint8_t*)mmp + mmp->UniqueIdOffset, unique_id.data(), unique_id.length() * sizeof(WCHAR));
147 }
148
149 if (device_name.length() > 0) {
150 if (mmp->SymbolicLinkNameLength == 0 && mmp->UniqueIdOffset == 0)
151 mmp->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
152 else if (mmp->SymbolicLinkNameLength != 0)
153 mmp->DeviceNameOffset = mmp->SymbolicLinkNameOffset + mmp->SymbolicLinkNameLength;
154 else
155 mmp->DeviceNameOffset = mmp->UniqueIdOffset + mmp->UniqueIdLength;
156
157 mmp->DeviceNameLength = (USHORT)(device_name.length() * sizeof(WCHAR));
158 memcpy((uint8_t*)mmp + mmp->DeviceNameOffset, device_name.data(), device_name.length() * sizeof(WCHAR));
159 }
160
161 vector<uint8_t> buf2(sizeof(MOUNTMGR_MOUNT_POINTS));
162 #ifndef __REACTOS__
163 auto mmps = reinterpret_cast<MOUNTMGR_MOUNT_POINTS*>(buf2.data());
164 #else
165 auto mmps = reinterpret_cast<MOUNTMGR_MOUNT_POINTS*>(&buf2[0]);
166 #endif
167
168 Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS,
169 buf.data(), (ULONG)buf.size(), buf2.data(), (ULONG)buf2.size());
170
171 if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
172 throw ntstatus_error(Status);
173
174 buf2.resize(mmps->Size);
175 #ifndef __REACTOS__
176 mmps = reinterpret_cast<MOUNTMGR_MOUNT_POINTS*>(buf2.data());
177 #else
178 mmps = reinterpret_cast<MOUNTMGR_MOUNT_POINTS*>(&buf2[0]);
179 #endif
180
181 Status = NtDeviceIoControlFile(h, nullptr, nullptr, nullptr, &iosb, IOCTL_MOUNTMGR_QUERY_POINTS,
182 buf.data(), (ULONG)buf.size(), buf2.data(), (ULONG)buf2.size());
183
184 if (!NT_SUCCESS(Status))
185 throw ntstatus_error(Status);
186
187 for (ULONG i = 0; i < mmps->NumberOfMountPoints; i++) {
188 wstring_view mpsl, mpdn;
189 string_view mpuid;
190
191 if (mmps->MountPoints[i].SymbolicLinkNameLength)
192 mpsl = wstring_view((WCHAR*)((uint8_t*)mmps + mmps->MountPoints[i].SymbolicLinkNameOffset), mmps->MountPoints[i].SymbolicLinkNameLength / sizeof(WCHAR));
193
194 if (mmps->MountPoints[i].UniqueIdLength)
195 mpuid = string_view((char*)((uint8_t*)mmps + mmps->MountPoints[i].UniqueIdOffset), mmps->MountPoints[i].UniqueIdLength);
196
197 if (mmps->MountPoints[i].DeviceNameLength)
198 mpdn = wstring_view((WCHAR*)((uint8_t*)mmps + mmps->MountPoints[i].DeviceNameOffset), mmps->MountPoints[i].DeviceNameLength / sizeof(WCHAR));
199
200 v.emplace_back(mpsl, mpuid, mpdn);
201 }
202
203 return v;
204 }