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
)));
36 auto mcpi
= reinterpret_cast<MOUNTMGR_CREATE_POINT_INPUT
*>(buf
.data());
38 mcpi
->SymbolicLinkNameOffset
= sizeof(MOUNTMGR_CREATE_POINT_INPUT
);
39 mcpi
->SymbolicLinkNameLength
= (USHORT
)(symlink
.length() * sizeof(WCHAR
));
40 mcpi
->DeviceNameOffset
= (USHORT
)(mcpi
->SymbolicLinkNameOffset
+ mcpi
->SymbolicLinkNameLength
);
41 mcpi
->DeviceNameLength
= (USHORT
)(device
.length() * sizeof(WCHAR
));
43 memcpy((uint8_t*)mcpi
+ mcpi
->SymbolicLinkNameOffset
, symlink
.data(), symlink
.length() * sizeof(WCHAR
));
44 memcpy((uint8_t*)mcpi
+ mcpi
->DeviceNameOffset
, device
.data(), device
.length() * sizeof(WCHAR
));
46 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_CREATE_POINT
,
47 buf
.data(), (ULONG
)buf
.size(), nullptr, 0);
49 if (!NT_SUCCESS(Status
))
50 throw ntstatus_error(Status
);
53 void mountmgr::delete_points(const wstring_view
& symlink
, const wstring_view
& unique_id
, const wstring_view
& device_name
) const {
57 vector
<uint8_t> buf(sizeof(MOUNTMGR_MOUNT_POINT
) + ((symlink
.length() + unique_id
.length() + device_name
.length()) * sizeof(WCHAR
)));
58 auto mmp
= reinterpret_cast<MOUNTMGR_MOUNT_POINT
*>(buf
.data());
60 memset(mmp
, 0, sizeof(MOUNTMGR_MOUNT_POINT
));
62 if (symlink
.length() > 0) {
63 mmp
->SymbolicLinkNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
64 mmp
->SymbolicLinkNameLength
= (USHORT
)(symlink
.length() * sizeof(WCHAR
));
65 memcpy((uint8_t*)mmp
+ mmp
->SymbolicLinkNameOffset
, symlink
.data(), symlink
.length() * sizeof(WCHAR
));
68 if (unique_id
.length() > 0) {
69 if (mmp
->SymbolicLinkNameLength
== 0)
70 mmp
->UniqueIdOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
72 mmp
->UniqueIdOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
74 mmp
->UniqueIdLength
= (USHORT
)(unique_id
.length() * sizeof(WCHAR
));
75 memcpy((uint8_t*)mmp
+ mmp
->UniqueIdOffset
, unique_id
.data(), unique_id
.length() * sizeof(WCHAR
));
78 if (device_name
.length() > 0) {
79 if (mmp
->SymbolicLinkNameLength
== 0 && mmp
->UniqueIdOffset
== 0)
80 mmp
->DeviceNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
81 else if (mmp
->SymbolicLinkNameLength
!= 0)
82 mmp
->DeviceNameOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
84 mmp
->DeviceNameOffset
= mmp
->UniqueIdOffset
+ mmp
->UniqueIdLength
;
86 mmp
->DeviceNameLength
= (USHORT
)(device_name
.length() * sizeof(WCHAR
));
87 memcpy((uint8_t*)mmp
+ mmp
->DeviceNameOffset
, device_name
.data(), device_name
.length() * sizeof(WCHAR
));
90 vector
<uint8_t> buf2(sizeof(MOUNTMGR_MOUNT_POINTS
));
91 auto mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(buf2
.data());
93 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_DELETE_POINTS
,
94 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
96 if (Status
== STATUS_BUFFER_OVERFLOW
) {
97 buf2
.resize(mmps
->Size
);
99 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_DELETE_POINTS
,
100 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
103 if (!NT_SUCCESS(Status
))
104 throw ntstatus_error(Status
);
107 vector
<mountmgr_point
> mountmgr::query_points(const wstring_view
& symlink
, const wstring_view
& unique_id
, const wstring_view
& device_name
) const {
109 IO_STATUS_BLOCK iosb
;
110 vector
<mountmgr_point
> v
;
112 vector
<uint8_t> buf(sizeof(MOUNTMGR_MOUNT_POINT
) + ((symlink
.length() + unique_id
.length() + device_name
.length()) * sizeof(WCHAR
)));
113 auto mmp
= reinterpret_cast<MOUNTMGR_MOUNT_POINT
*>(buf
.data());
115 memset(mmp
, 0, sizeof(MOUNTMGR_MOUNT_POINT
));
117 if (symlink
.length() > 0) {
118 mmp
->SymbolicLinkNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
119 mmp
->SymbolicLinkNameLength
= (USHORT
)(symlink
.length() * sizeof(WCHAR
));
120 memcpy((uint8_t*)mmp
+ mmp
->SymbolicLinkNameOffset
, symlink
.data(), symlink
.length() * sizeof(WCHAR
));
123 if (unique_id
.length() > 0) {
124 if (mmp
->SymbolicLinkNameLength
== 0)
125 mmp
->UniqueIdOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
127 mmp
->UniqueIdOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
129 mmp
->UniqueIdLength
= (USHORT
)(unique_id
.length() * sizeof(WCHAR
));
130 memcpy((uint8_t*)mmp
+ mmp
->UniqueIdOffset
, unique_id
.data(), unique_id
.length() * sizeof(WCHAR
));
133 if (device_name
.length() > 0) {
134 if (mmp
->SymbolicLinkNameLength
== 0 && mmp
->UniqueIdOffset
== 0)
135 mmp
->DeviceNameOffset
= sizeof(MOUNTMGR_MOUNT_POINT
);
136 else if (mmp
->SymbolicLinkNameLength
!= 0)
137 mmp
->DeviceNameOffset
= mmp
->SymbolicLinkNameOffset
+ mmp
->SymbolicLinkNameLength
;
139 mmp
->DeviceNameOffset
= mmp
->UniqueIdOffset
+ mmp
->UniqueIdLength
;
141 mmp
->DeviceNameLength
= (USHORT
)(device_name
.length() * sizeof(WCHAR
));
142 memcpy((uint8_t*)mmp
+ mmp
->DeviceNameOffset
, device_name
.data(), device_name
.length() * sizeof(WCHAR
));
145 vector
<uint8_t> buf2(sizeof(MOUNTMGR_MOUNT_POINTS
));
146 auto mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(buf2
.data());
148 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_QUERY_POINTS
,
149 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
151 if (!NT_SUCCESS(Status
) && Status
!= STATUS_BUFFER_OVERFLOW
)
152 throw ntstatus_error(Status
);
154 buf2
.resize(mmps
->Size
);
155 mmps
= reinterpret_cast<MOUNTMGR_MOUNT_POINTS
*>(buf2
.data());
157 Status
= NtDeviceIoControlFile(h
, nullptr, nullptr, nullptr, &iosb
, IOCTL_MOUNTMGR_QUERY_POINTS
,
158 buf
.data(), (ULONG
)buf
.size(), buf2
.data(), (ULONG
)buf2
.size());
160 if (!NT_SUCCESS(Status
))
161 throw ntstatus_error(Status
);
163 for (ULONG i
= 0; i
< mmps
->NumberOfMountPoints
; i
++) {
164 wstring_view mpsl
, mpdn
;
167 if (mmps
->MountPoints
[i
].SymbolicLinkNameLength
)
168 mpsl
= wstring_view((WCHAR
*)((uint8_t*)mmps
+ mmps
->MountPoints
[i
].SymbolicLinkNameOffset
), mmps
->MountPoints
[i
].SymbolicLinkNameLength
/ sizeof(WCHAR
));
170 if (mmps
->MountPoints
[i
].UniqueIdLength
)
171 mpuid
= string_view((char*)((uint8_t*)mmps
+ mmps
->MountPoints
[i
].UniqueIdOffset
), mmps
->MountPoints
[i
].UniqueIdLength
);
173 if (mmps
->MountPoints
[i
].DeviceNameLength
)
174 mpdn
= wstring_view((WCHAR
*)((uint8_t*)mmps
+ mmps
->MountPoints
[i
].DeviceNameOffset
), mmps
->MountPoints
[i
].DeviceNameLength
/ sizeof(WCHAR
));
177 v
.emplace_back(mpsl
, mpuid
, mpdn
);
179 v
.push_back(mountmgr_point(mpsl
, mpuid
, mpdn
));