5 #include "mountmgr_local.h"
11 mountmgr::mountmgr() {
13 OBJECT_ATTRIBUTES attr
;
17 RtlInitUnicodeString(&us
, MOUNTMGR_DEVICE_NAME
);
18 InitializeObjectAttributes(&attr
, &us
, 0, nullptr, nullptr);
20 Status
= NtOpenFile(&h
, FILE_GENERIC_READ
| FILE_GENERIC_WRITE
, &attr
, &iosb
,
21 FILE_SHARE_READ
, FILE_SYNCHRONOUS_IO_ALERT
);
23 if (!NT_SUCCESS(Status
))
24 throw ntstatus_error(Status
);
27 mountmgr::~mountmgr() {
31 void mountmgr::create_point(const wstring_view
& symlink
, const wstring_view
& device
) const {
35 vector
<uint8_t> buf(sizeof(MOUNTMGR_CREATE_POINT_INPUT
) + ((symlink
.length() + device
.length()) * sizeof(WCHAR
)));
37 auto mcpi
= reinterpret_cast<MOUNTMGR_CREATE_POINT_INPUT
*>(buf
.data());
39 auto mcpi
= reinterpret_cast<MOUNTMGR_CREATE_POINT_INPUT
*>(&buf
[0]);
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
));
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
));
50 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_CREATE_POINT
,
52 buf
.data(), (ULONG
)buf
.size(), nullptr, 0);
54 &buf
[0], (ULONG
)buf
.size(), nullptr, 0);
57 if (!NT_SUCCESS(Status
))
58 throw ntstatus_error(Status
);
61 void mountmgr::delete_points(const wstring_view
& symlink
, const wstring_view
& unique_id
, const wstring_view
& device_name
) const {
65 vector
<uint8_t> buf(sizeof(MOUNTMGR_MOUNT_POINT
) + ((symlink
.length() + unique_id
.length() + device_name
.length()) * sizeof(WCHAR
)));
67 auto mmp
= reinterpret_cast<MOUNTMGR_MOUNT_POINT
*>(buf
.data());
69 auto mmp
= reinterpret_cast<MOUNTMGR_MOUNT_POINT
*>(&buf
[0]);
72 memset(mmp
, 0, sizeof(MOUNTMGR_MOUNT_POINT
));
74 if (symlink
.length() > 0) {
75 mmp
->SymbolicLinkNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
76 mmp
->SymbolicLinkNameLength
= (USHORT
)(symlink
.length() * sizeof(WCHAR
));
77 memcpy((uint8_t*)mmp
+ mmp
->SymbolicLinkNameOffset
, symlink
.data(), symlink
.length() * sizeof(WCHAR
));
80 if (unique_id
.length() > 0) {
81 if (mmp
->SymbolicLinkNameLength
== 0)
82 mmp
->UniqueIdOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
84 mmp
->UniqueIdOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
86 mmp
->UniqueIdLength
= (USHORT
)(unique_id
.length() * sizeof(WCHAR
));
87 memcpy((uint8_t*)mmp
+ mmp
->UniqueIdOffset
, unique_id
.data(), unique_id
.length() * sizeof(WCHAR
));
90 if (device_name
.length() > 0) {
91 if (mmp
->SymbolicLinkNameLength
== 0 && mmp
->UniqueIdOffset
== 0)
92 mmp
->DeviceNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
93 else if (mmp
->SymbolicLinkNameLength
!= 0)
94 mmp
->DeviceNameOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
96 mmp
->DeviceNameOffset
= mmp
->UniqueIdOffset
+ mmp
->UniqueIdLength
;
98 mmp
->DeviceNameLength
= (USHORT
)(device_name
.length() * sizeof(WCHAR
));
99 memcpy((uint8_t*)mmp
+ mmp
->DeviceNameOffset
, device_name
.data(), device_name
.length() * sizeof(WCHAR
));
102 vector
<uint8_t> buf2(sizeof(MOUNTMGR_MOUNT_POINTS
));
104 auto mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(buf2
.data());
106 auto mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(&buf2
[0]);
109 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_DELETE_POINTS
,
111 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
113 &buf
[0], (ULONG
)buf
.size(), &buf2
[0], (ULONG
)buf2
.size());
116 if (Status
== STATUS_BUFFER_OVERFLOW
) {
117 buf2
.resize(mmps
->Size
);
119 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_DELETE_POINTS
,
121 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
123 &buf
[0], (ULONG
)buf
.size(), &buf2
[0], (ULONG
)buf2
.size());
127 if (!NT_SUCCESS(Status
))
128 throw ntstatus_error(Status
);
131 vector
<mountmgr_point
> mountmgr::query_points(const wstring_view
& symlink
, const wstring_view
& unique_id
, const wstring_view
& device_name
) const {
133 IO_STATUS_BLOCK iosb
;
134 vector
<mountmgr_point
> v
;
136 vector
<uint8_t> buf(sizeof(MOUNTMGR_MOUNT_POINT
) + ((symlink
.length() + unique_id
.length() + device_name
.length()) * sizeof(WCHAR
)));
138 auto mmp
= reinterpret_cast<MOUNTMGR_MOUNT_POINT
*>(buf
.data());
140 auto mmp
= reinterpret_cast<MOUNTMGR_MOUNT_POINT
*>(&buf
[0]);
143 memset(mmp
, 0, sizeof(MOUNTMGR_MOUNT_POINT
));
145 if (symlink
.length() > 0) {
146 mmp
->SymbolicLinkNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
147 mmp
->SymbolicLinkNameLength
= (USHORT
)(symlink
.length() * sizeof(WCHAR
));
148 memcpy((uint8_t*)mmp
+ mmp
->SymbolicLinkNameOffset
, symlink
.data(), symlink
.length() * sizeof(WCHAR
));
151 if (unique_id
.length() > 0) {
152 if (mmp
->SymbolicLinkNameLength
== 0)
153 mmp
->UniqueIdOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
155 mmp
->UniqueIdOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
157 mmp
->UniqueIdLength
= (USHORT
)(unique_id
.length() * sizeof(WCHAR
));
158 memcpy((uint8_t*)mmp
+ mmp
->UniqueIdOffset
, unique_id
.data(), unique_id
.length() * sizeof(WCHAR
));
161 if (device_name
.length() > 0) {
162 if (mmp
->SymbolicLinkNameLength
== 0 && mmp
->UniqueIdOffset
== 0)
163 mmp
->DeviceNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
164 else if (mmp
->SymbolicLinkNameLength
!= 0)
165 mmp
->DeviceNameOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
167 mmp
->DeviceNameOffset
= mmp
->UniqueIdOffset
+ mmp
->UniqueIdLength
;
169 mmp
->DeviceNameLength
= (USHORT
)(device_name
.length() * sizeof(WCHAR
));
170 memcpy((uint8_t*)mmp
+ mmp
->DeviceNameOffset
, device_name
.data(), device_name
.length() * sizeof(WCHAR
));
173 vector
<uint8_t> buf2(sizeof(MOUNTMGR_MOUNT_POINTS
));
175 auto mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(buf2
.data());
177 auto mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(&buf2
[0]);
180 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_QUERY_POINTS
,
182 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
184 &buf
[0], (ULONG
)buf
.size(), &buf2
[0], (ULONG
)buf2
.size());
187 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
188 throw ntstatus_error(Status
);
190 buf2
.resize(mmps
->Size
);
192 mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(buf2
.data());
194 mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(&buf2
[0]);
197 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_QUERY_POINTS
,
199 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
201 &buf
[0], (ULONG
)buf
.size(), &buf2
[0], (ULONG
)buf2
.size());
204 if (!NT_SUCCESS(Status
))
205 throw ntstatus_error(Status
);
207 for (ULONG i
= 0; i
< mmps
->NumberOfMountPoints
; i
++) {
208 wstring_view mpsl
, mpdn
;
211 if (mmps
->MountPoints
[i
].SymbolicLinkNameLength
)
212 mpsl
= wstring_view((WCHAR
*)((uint8_t*)mmps
+ mmps
->MountPoints
[i
].SymbolicLinkNameOffset
), mmps
->MountPoints
[i
].SymbolicLinkNameLength
/ sizeof(WCHAR
));
214 if (mmps
->MountPoints
[i
].UniqueIdLength
)
215 mpuid
= string_view((char*)((uint8_t*)mmps
+ mmps
->MountPoints
[i
].UniqueIdOffset
), mmps
->MountPoints
[i
].UniqueIdLength
);
217 if (mmps
->MountPoints
[i
].DeviceNameLength
)
218 mpdn
= wstring_view((WCHAR
*)((uint8_t*)mmps
+ mmps
->MountPoints
[i
].DeviceNameOffset
), mmps
->MountPoints
[i
].DeviceNameLength
/ sizeof(WCHAR
));
220 v
.emplace_back(mpsl
, mpuid
, mpdn
);