forked from Chuyu-Team/CPPHelper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
VirtDiskHelper.h
110 lines (71 loc) · 1.78 KB
/
VirtDiskHelper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#pragma once
#include "BaseFunction.h"
#include <virtdisk.h>
#pragma comment(lib,"VirtDisk.lib")
#include <Sddl.h>
_Check_return_ _Success_(return != INVALID_HANDLE_VALUE)
static HANDLE AttachVirtualDisk(
_In_z_ LPCWSTR VirtualDiskPath,
_In_ bool ReadOnly
)
{
OPEN_VIRTUAL_DISK_PARAMETERS openParameters = {};
VIRTUAL_DISK_ACCESS_MASK accessMask;
if (StrCmpI(PathFindExtension(VirtualDiskPath), L".iso") == 0)
{
openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_1;
accessMask = VIRTUAL_DISK_ACCESS_READ;
}
else
{
openParameters.Version = OPEN_VIRTUAL_DISK_VERSION_2;
openParameters.Version2.GetInfoOnly = FALSE;
accessMask = VIRTUAL_DISK_ACCESS_NONE;
}
HANDLE vhdHandle = INVALID_HANDLE_VALUE;
VIRTUAL_STORAGE_TYPE storageType = { VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN };
auto opStatus = OpenVirtualDisk(
&storageType,
VirtualDiskPath,
accessMask,
OPEN_VIRTUAL_DISK_FLAG_NONE,
&openParameters,
&vhdHandle);
if (opStatus)
{
SetLastError(opStatus);
return INVALID_HANDLE_VALUE;
}
PSECURITY_DESCRIPTOR sd = NULL;
if (!::ConvertStringSecurityDescriptorToSecurityDescriptor(
L"O:BAG:BAD:(A;;GA;;;WD)",
SDDL_REVISION_1,
&sd,
NULL))
{
opStatus = ::GetLastError_s();
goto Cleanup;
}
ATTACH_VIRTUAL_DISK_PARAMETERS attachParameters = { ATTACH_VIRTUAL_DISK_VERSION_1 };
ATTACH_VIRTUAL_DISK_FLAG attachFlags= ReadOnly? (ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER| ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY) : ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER;
opStatus = AttachVirtualDisk(
vhdHandle,
sd,
attachFlags,
0,
&attachParameters,
NULL);
if (opStatus != ERROR_SUCCESS)
{
goto Cleanup;
}
else
{
return vhdHandle;
}
Cleanup:
CloseHandle(vhdHandle);
LocalFree(sd);
SetLastError(opStatus);
return INVALID_HANDLE_VALUE;
}