-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathNativeMethodHelpers.cs
More file actions
111 lines (92 loc) · 3.62 KB
/
Copy pathNativeMethodHelpers.cs
File metadata and controls
111 lines (92 loc) · 3.62 KB
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
namespace SyncPro.Adapters.WindowsFileSystem
{
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
internal sealed class NativeMethodHelpers
{
public static byte[] GetDirectoryObjectId(string path)
{
SafeFileHandle handle = null;
IntPtr outBuffer = IntPtr.Zero;
try
{
// Get a handle to the directory
handle = NativeMethods.CreateFile(
path,
NativeMethods.GENERIC_READ,
FileShare.Read,
IntPtr.Zero,
(FileMode) NativeMethods.OPEN_EXISTING,
NativeMethods.FILE_FLAG_BACKUP_SEMANTICS,
IntPtr.Zero);
if (null == handle || handle.IsInvalid)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
// Get the size of the buffer object
NativeMethods.FILE_OBJECTID_BUFFER buffer = default(NativeMethods.FILE_OBJECTID_BUFFER);
int bufferSize = Marshal.SizeOf(buffer);
// Allocate unmanaged memory for the DeviceIoContol() method to write the buffer
outBuffer = Marshal.AllocHGlobal(bufferSize);
uint bytesReturned = default(uint);
// Call DeviceIoControl() to read the object id
bool controlResult = NativeMethods.DeviceIoControl(
handle,
NativeMethods.FSCTL_CREATE_OR_GET_OBJECT_ID,
IntPtr.Zero,
0,
outBuffer,
bufferSize,
ref bytesReturned,
IntPtr.Zero);
if (!controlResult)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
// Convert unmanged to managed memory structure
buffer = (NativeMethods.FILE_OBJECTID_BUFFER) Marshal.PtrToStructure(
outBuffer, typeof(NativeMethods.FILE_OBJECTID_BUFFER));
// Copy the object ID into a dedicated byte array that can be returned
byte[] objectId = new byte[buffer.ObjectId.Length];
buffer.ObjectId.CopyTo(objectId, 0);
return objectId;
}
finally
{
if (outBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(outBuffer);
}
if (handle != null && !handle.IsInvalid && !handle.IsClosed)
{
handle.Close();
}
}
}
public static byte[] GetFileObjectId(string path)
{
FileInfo fi = new FileInfo(path);
FileStream fs = null;
try
{
NativeMethods.BY_HANDLE_FILE_INFORMATION objectFileInfo;
fs = fi.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
#pragma warning disable 618
NativeMethods.GetFileInformationByHandle(fs.Handle, out objectFileInfo);
#pragma warning restore 618
ulong fileIndex = ((ulong)objectFileInfo.FileIndexHigh << 32) + objectFileInfo.FileIndexLow;
return BitConverter.GetBytes(fileIndex);
}
finally
{
if (fs != null)
{
fs.Dispose();
}
}
}
}
}