-
Notifications
You must be signed in to change notification settings - Fork 3
/
MemoryMappedFileHelper.cs
executable file
·314 lines (280 loc) · 8.69 KB
/
MemoryMappedFileHelper.cs
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
using System;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Security;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Security.Principal;
using System.Security.AccessControl;
namespace QuickIPC
{
#region Enumeration for Win32 macros
[Flags]
public enum MemoryProtection : uint
{
PageNoAccess = 0x01,
PageReadOnly = 0x02,
PageReadWrite = 0x04,
PageWriteCopy = 0x08,
SecImage = 0x1000000,
SecReserve = 0x4000000,
SecCommit = 0x8000000,
SecNoCache = 0x10000000
}
[Flags]
internal enum Win32FileMapAccess: uint
{
FILE_MAP_COPY = 0x0001,
FILE_MAP_WRITE = 0x0002,
FILE_MAP_READ = 0x0004,
FILE_MAP_ALL_ACCESS = 0x000F0000
| FILE_MAP_COPY
| FILE_MAP_WRITE
| FILE_MAP_READ
| 0x0008
| 0x0010
}
[Flags]
internal enum Win32FileAccess : uint
{
GENERIC_READ = 0x80000000,
GENERIC_WRITE = 0x40000000,
GENERIC_EXECUTE = 0x20000000,
GENERIC_ALL = 0x10000000
}
[Flags]
internal enum Win32FileMode : uint
{
CREATE_NEW = 1,
CREATE_ALWAYS = 2,
OPEN_EXISTING = 3,
OPEN_ALWAYS = 4,
TRUNCATE_EXISTING = 5
}
[Flags]
internal enum Win32FileShare : uint
{
FILE_SHARE_READ = 0x00000001,
FILE_SHARE_WRITE = 0x00000002,
FILE_SHARE_DELETE = 0x00000004,
}
[Flags]
internal enum Win32FileAttributes : uint
{
FILE_ATTRIBUTE_READONLY = 0x00000001,
FILE_ATTRIBUTE_HIDDEN = 0x00000002,
FILE_ATTRIBUTE_SYSTEM = 0x00000004,
FILE_ATTRIBUTE_DIRECTORY = 0x00000010,
FILE_ATTRIBUTE_ARCHIVE = 0x00000020,
FILE_ATTRIBUTE_DEVICE = 0x00000040,
FILE_ATTRIBUTE_NORMAL = 0x00000080,
FILE_ATTRIBUTE_TEMPORARY = 0x00000100,
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200,
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400,
FILE_ATTRIBUTE_COMPRESSED = 0x00000800,
FILE_ATTRIBUTE_OFFLINE = 0x00001000,
FILE_ATTRIBUTE_NOTCONTENTINDEXED = 0x00002000,
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
}
#endregion
[StructLayout(LayoutKind.Sequential)]
internal class SECURITY_ATTRIBUTES : IDisposable
{
internal int nLength;
internal IntPtr lpSecurityDescriptor;
internal int bInheritHandle;
/// <summary>
/// NULL SA and Empty SA are two different things. NULL SA writes the current user's security
/// attributes (SID) to the object being secured. Empty SA allows literally everybody to access the
/// object.
/// </summary>
/// <returns></returns>
public static SECURITY_ATTRIBUTES GetNullDacl()
{
// Construct SECURITY_ATTRIBUTES structure
SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
sa.nLength = Marshal.SizeOf(sa);
sa.bInheritHandle = 1;
// Build NULL DACL (Allow everyone full access)
RawSecurityDescriptor gsd = new RawSecurityDescriptor(ControlFlags.DiscretionaryAclPresent,
null,
null,
null,
null);
// Get binary form of the security descriptor and copy it into place
byte[] desc = new byte[gsd.BinaryLength];
gsd.GetBinaryForm(desc, 0);
sa.lpSecurityDescriptor = Marshal.AllocHGlobal(desc.Length);
Marshal.Copy(desc,
0,
sa.lpSecurityDescriptor,
desc.Length);
return sa;
}
public void Dispose()
{
lock (this)
{
if (lpSecurityDescriptor != IntPtr.Zero)
{
Marshal.FreeHGlobal(lpSecurityDescriptor);
lpSecurityDescriptor = IntPtr.Zero;
}
}
}
~SECURITY_ATTRIBUTES()
{
Dispose();
}
}
#region Win32 functions and conversion methods
/// <summary>
/// Memory mapped file helper class that provides the Win32 functions and
/// the conversion methods.
/// </summary>
internal class MemoryMappedFileHelper
{
private const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
/// <summary>
/// Private constructor prevents class from getting created.
/// </summary>
private MemoryMappedFileHelper()
{}
[DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr CreateFileMapping(
IntPtr hFile, // Handle to file
SECURITY_ATTRIBUTES lpAttributes, // Security
MemoryProtection flProtect, // protection
uint dwMaximumSizeHigh, // High-order DWORD of size
uint dwMaximumSizeLow, // Low-order DWORD of size
string lpName // Object name
);
[DllImport("kernel32", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr CreateFile(
string lpFileName, // File name
Win32FileAccess dwDesiredAccess, // Access mode
Win32FileShare dwShareMode, // Share mode
IntPtr lpSecurityAttributes, // SD
Win32FileMode dwCreationDisposition, // How to create
Win32FileAttributes dwFlagsAndAttributes, // File attributes
IntPtr hTemplateFile // Handle to template file
);
[DllImport("kernel32")]
public static extern IntPtr OpenFileMapping(
Win32FileMapAccess dwDesiredAccess, // Access mode
bool isInheritHandle, // Inherit flag
string lpName // Object name
);
[DllImport("kernel32")]
public static extern IntPtr MapViewOfFile(
IntPtr hFileMappingObject, // handle to file-mapping object
Win32FileMapAccess dwDesiredAccess, // Access mode
uint dwFileOffsetHigh, // High-order DWORD of offset
uint dwFileOffsetLow, // Low-order DWORD of offset
uint dwNumberOfBytesToMap // Number of bytes to map
);
[DllImport("kernel32")]
public static extern bool FlushViewOfFile(
IntPtr lpBaseAddress, // Starting address
uint dwNumberOfBytesToFlush // Number of bytes in range
);
[DllImport("kernel32")]
public static extern bool UnmapViewOfFile(
IntPtr lpBaseAddress // Starting address
);
[DllImport("kernel32")]
public static extern uint GetLastError();
[DllImport("kernel32", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hFile);
[DllImport("kernel32")]
public static extern uint FormatMessage(
uint dwFlags, // Source and processing options
IntPtr lpSource, // Message source
uint dwMessageId, // Message identifier
uint dwLanguageId, // Language identifier
StringBuilder lpBuffer, // Message buffer
uint nSize, // Maximum size of message buffer
IntPtr Arguments // Array of message inserts
);
public static Win32FileMapAccess GetWin32FileMapAccess(
MemoryProtection protection )
{
switch ( protection )
{
case MemoryProtection.PageReadOnly:
return Win32FileMapAccess.FILE_MAP_READ;
case MemoryProtection.PageWriteCopy:
return Win32FileMapAccess.FILE_MAP_WRITE;
default:
return Win32FileMapAccess.FILE_MAP_ALL_ACCESS;
}
}
public static Win32FileAccess GetWin32FileAccess( FileAccess access )
{
switch( access )
{
case FileAccess.Read:
return Win32FileAccess.GENERIC_READ;
case FileAccess.Write:
return Win32FileAccess.GENERIC_WRITE;
case FileAccess.ReadWrite:
return Win32FileAccess.GENERIC_READ |
Win32FileAccess.GENERIC_WRITE;
default:
return Win32FileAccess.GENERIC_READ;
}
}
public static Win32FileMode GetWin32FileMode( FileMode mode )
{
switch( mode )
{
case FileMode.Append:
return Win32FileMode.OPEN_ALWAYS;
case FileMode.Create:
return Win32FileMode.CREATE_ALWAYS;
case FileMode.CreateNew:
return Win32FileMode.CREATE_NEW;
case FileMode.Open:
return Win32FileMode.OPEN_EXISTING;
case FileMode.OpenOrCreate:
return Win32FileMode.OPEN_ALWAYS;
case FileMode.Truncate:
return Win32FileMode.TRUNCATE_EXISTING;
default:
return Win32FileMode.OPEN_ALWAYS;
}
}
public static Win32FileShare GetWin32FileShare( FileShare share )
{
switch( share )
{
case FileShare.None:
return 0;
case FileShare.Write:
return Win32FileShare.FILE_SHARE_WRITE;
case FileShare.Read:
return Win32FileShare.FILE_SHARE_READ;
case FileShare.ReadWrite:
return (Win32FileShare.FILE_SHARE_READ |
Win32FileShare.FILE_SHARE_WRITE);
default:
return 0;
}
}
public static string GetWin32ErrorMessage( uint error )
{
StringBuilder buff = new StringBuilder( 1024 );
uint len = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,
IntPtr.Zero,
error,
0,
buff,
1024,
IntPtr.Zero );
return buff.ToString( 0, (int)len );
}
}
#endregion
}