using System;
using System.Runtime.InteropServices;
using System.Threading;
using Vanara.InteropServices;
using static Vanara.PInvoke.Kernel32;
using USN = System.Int64;
namespace Vanara.PInvoke
{
/// Functions, structures and constants from CldApi.dll.
public static partial class CldApi
{
/// Callback function for .
/// The callback information.
/// The callback parameters.
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void CF_CALLBACK(in CF_CALLBACK_INFO CallbackInfo, in CF_CALLBACK_PARAMETERS CallbackParameters);
private delegate HRESULT GetInfoFunc(TParam p1, TEnum InfoClass, IntPtr InfoBuffer, uint InfoBufferLength, out uint ReturnedLength) where TEnum : Enum;
///
/// Closes the file or directory handle returned by CfOpenFileWithOplock. This should not be used with standard Win32 file handles,
/// only on handles used within CfApi.h.
///
/// The file or directory handle to be closed.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfclosehandle void CfCloseHandle( HANDLE FileHandle );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "ECBEF685-0769-4AEA-8A0F-D5FBB70CBB09")]
public static extern void CfCloseHandle(HCFFILE FileHandle);
/// Initiates bi-directional communication between a sync provider and the sync filter API.
/// The path to the sync root.
/// The callback table to be registered.
/// A callback context used by the platform anytime a specified callback function is invoked.
/// Provides additional information when a callback is invoked.
/// A connection key representing the communication channel with the sync filter.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// This initiates a bi-directional communication channel between the sync provider and the sync filter. A sync provider typically
/// calls this API soon after startup, once it has been initialized and is ready to service requests.
///
///
/// The sync root must be registered prior to being connected. For a given SyncRootPath, there can be at most one connection
/// established at any given time.
///
///
/// The sync provider should have WRITE_DATA or WRITE_DAC access to the sync root to be connected or the API will be failed with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfconnectsyncroot HRESULT CfConnectSyncRoot( LPCWSTR
// SyncRootPath, const CF_CALLBACK_REGISTRATION *CallbackTable, LPCVOID CallbackContext, CF_CONNECT_FLAGS ConnectFlags,
// CF_CONNECTION_KEY *ConnectionKey );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "287DA978-9797-48DF-9C90-BA53BB82475C")]
public static extern HRESULT CfConnectSyncRoot([MarshalAs(UnmanagedType.LPWStr)] string SyncRootPath, [In, MarshalAs(UnmanagedType.LPArray)] CF_CALLBACK_REGISTRATION[] CallbackTable,
[In, Optional] IntPtr CallbackContext, CF_CONNECT_FLAGS ConnectFlags, out CF_CONNECTION_KEY ConnectionKey);
/// Converts a normal file/directory to a placeholder file/directory.
/// Handle to the file or directory to be converted.
///
/// A user mode buffer that contains the opaque file or directory information supplied by the caller. Optional if the caller is not
/// dehydrating the file at the same time, or if the caller is converting a directory. Cannot exceed 4KB in size.
///
/// Length, in bytes, of the FileIdentity.
/// Placeholder conversion flags.
/// The final USN value after convert actions are performed.
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfConvertToPlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// In the file case, the caller must acquire an exclusive handle to the file if it also intends to dehydrate the file at the same
/// time or data corruption can occur. To minimize the impact on user applications it is highly recommended that the caller obtain
/// the exclusiveness using proper oplocks (via CfOpenFileWithOplock) as opposed to using a share-nothing handle.
///
/// To convert a placeholder:
///
/// -
///
/// The file or directory to be converted must be contained in a registered sync root tree; it can be the sync root directory
/// itself, or any descendant directory; otherwise, the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT).
///
///
/// -
///
/// If dehydration is requested, the sync root must be registered with a valid hydration policy that is not
/// CF_HYDRATION_POLICY_ALWAYS_FULL; otherwise the call will be failed with HRESULT(ERROR_CLOUD_FILE_NOT_SUPPORTED).
///
///
/// -
/// If dehydration is requested, the placeholder must not be pinned locally or the call with be failed with HRESULT(ERROR_CLOUD_FILE_PINNED).
///
/// -
/// If dehydration is requested, the placeholder must be in sync or the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_IN_SYNC).
///
/// -
///
/// The caller must have WRITE_DATA or WRITE_DAC access to the file or directory to be converted. Otherwise the operation will be
/// failed with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
///
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfconverttoplaceholder HRESULT CfConvertToPlaceholder( HANDLE
// FileHandle, LPCVOID FileIdentity, DWORD FileIdentityLength, CF_CONVERT_FLAGS ConvertFlags, USN *ConvertUsn, LPOVERLAPPED
// Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "FDDE9CB0-E1A2-46D6-94E0-228495675271")]
public static extern HRESULT CfConvertToPlaceholder(HFILE FileHandle, [In, Optional] IntPtr FileIdentity, uint FileIdentityLength, CF_CONVERT_FLAGS ConvertFlags, out USN ConvertUsn, [In, Out, Optional] IntPtr Overlapped);
/// Converts a normal file/directory to a placeholder file/directory.
/// Handle to the file or directory to be converted.
///
/// A user mode buffer that contains the opaque file or directory information supplied by the caller. Optional if the caller is not
/// dehydrating the file at the same time, or if the caller is converting a directory. Cannot exceed 4KB in size.
///
/// Length, in bytes, of the FileIdentity.
/// Placeholder conversion flags.
/// The final USN value after convert actions are performed.
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfConvertToPlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// In the file case, the caller must acquire an exclusive handle to the file if it also intends to dehydrate the file at the same
/// time or data corruption can occur. To minimize the impact on user applications it is highly recommended that the caller obtain
/// the exclusiveness using proper oplocks (via CfOpenFileWithOplock) as opposed to using a share-nothing handle.
///
/// To convert a placeholder:
///
/// -
///
/// The file or directory to be converted must be contained in a registered sync root tree; it can be the sync root directory
/// itself, or any descendant directory; otherwise, the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT).
///
///
/// -
///
/// If dehydration is requested, the sync root must be registered with a valid hydration policy that is not
/// CF_HYDRATION_POLICY_ALWAYS_FULL; otherwise the call will be failed with HRESULT(ERROR_CLOUD_FILE_NOT_SUPPORTED).
///
///
/// -
/// If dehydration is requested, the placeholder must not be pinned locally or the call with be failed with HRESULT(ERROR_CLOUD_FILE_PINNED).
///
/// -
/// If dehydration is requested, the placeholder must be in sync or the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_IN_SYNC).
///
/// -
///
/// The caller must have WRITE_DATA or WRITE_DAC access to the file or directory to be converted. Otherwise the operation will be
/// failed with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
///
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfconverttoplaceholder HRESULT CfConvertToPlaceholder( HANDLE
// FileHandle, LPCVOID FileIdentity, DWORD FileIdentityLength, CF_CONVERT_FLAGS ConvertFlags, USN *ConvertUsn, LPOVERLAPPED
// Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "FDDE9CB0-E1A2-46D6-94E0-228495675271")]
public static unsafe extern HRESULT CfConvertToPlaceholder(HFILE FileHandle, [In, Optional] IntPtr FileIdentity, uint FileIdentityLength, CF_CONVERT_FLAGS ConvertFlags,
[Out, Optional] USN* ConvertUsn, [In, Out, Optional] NativeOverlapped* Overlapped);
/// Creates one or more new placeholder files or directories under a sync root tree.
/// Local directory path under which placeholders are created.
///
/// On successful creation, the PlaceholderArray contains the final USN value and a STATUS_OK message. On return, this array
/// contains an HRESULT value describing whether the placeholder was created or not.
///
/// The count of placeholders in the PlaceholderArray.
/// Flags for configuring the creation of a placeholder.
/// The number of entries processed, including failed entries.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// Creating a placeholder with this function is preferred compared to creating a new file with CreateFile and then converting it to
/// a placeholder with CfConvertToPlaceholder; both for efficiency and because it eliminates the time window where the file is not a
/// placeholder. The function can also create multiple files or directories in a batch, which can also be more efficient.
///
///
/// This function is useful when performing an initial sync of files or directories from the cloud down to the client, or when
/// syncing down a newly created single file or directory from the cloud.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfcreateplaceholders HRESULT CfCreatePlaceholders( LPCWSTR
// BaseDirectoryPath, CF_PLACEHOLDER_CREATE_INFO *PlaceholderArray, DWORD PlaceholderCount, CF_CREATE_FLAGS CreateFlags, PDWORD
// EntriesProcessed );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "96A6F62E-7F14-40B5-AB57-260DC9B1DF89")]
public static extern HRESULT CfCreatePlaceholders([MarshalAs(UnmanagedType.LPWStr)] string BaseDirectoryPath, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] CF_PLACEHOLDER_CREATE_INFO[] PlaceholderArray,
uint PlaceholderCount, CF_CREATE_FLAGS CreateFlags, out uint EntriesProcessed);
///
/// Dehydrates a placeholder file by ensuring that the specified byte range is not present on-disk in the placeholder. This is valid
/// for files only.
///
/// [in] A handle to the placeholder file.
/// [in] The starting point offset of the placeholder file data.
///
/// [in] The length, in bytes, of the placeholder file whose data must be invalidated locally on the disk after the API completes
/// successfully. A length of -1 signifies end of file.
///
/// [in] Placeholder dehydration flags.
///
///
/// [in, out, optional] When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfDehydratePlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// This function does not return a value.
///
///
/// The caller must acquire an exclusive handle to the file or data corruption can occur. To minimize the impact on user
/// applications it is highly recommended that the caller obtain the exclusiveness using proper oplocks (via
/// CfOpenFileWithOplock) as opposed to using a share-nothing handle.
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/previous-versions/mt827480(v=vs.85) void STDAPI CfDehydratePlaceholder( _In_ HANDLE FileHandle,
// _In_ LARGE_INTEGER StartingOffset, _In_ LARGE_INTEGER Length, _In_ CF_HYDRATE_FLAGS DehydrateFlags, _Inout_opt_ LPOVERLAPPED
// Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("CfApi.h")]
public static extern HRESULT CfDehydratePlaceholder(HFILE FileHandle, long StartingOffset, long Length, CF_DEHYDRATE_FLAGS DehydrateFlags, [In, Out, Optional] IntPtr Overlapped);
///
/// Dehydrates a placeholder file by ensuring that the specified byte range is not present on-disk in the placeholder. This is valid
/// for files only.
///
/// [in] A handle to the placeholder file.
/// [in] The starting point offset of the placeholder file data.
///
/// [in] The length, in bytes, of the placeholder file whose data must be invalidated locally on the disk after the API completes
/// successfully. A length of -1 signifies end of file.
///
/// [in] Placeholder dehydration flags.
///
///
/// [in, out, optional] When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfDehydratePlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// This function does not return a value.
///
///
/// The caller must acquire an exclusive handle to the file or data corruption can occur. To minimize the impact on user
/// applications it is highly recommended that the caller obtain the exclusiveness using proper oplocks (via
/// CfOpenFileWithOplock) as opposed to using a share-nothing handle.
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/previous-versions/mt827480(v=vs.85) void STDAPI CfDehydratePlaceholder( _In_ HANDLE FileHandle,
// _In_ LARGE_INTEGER StartingOffset, _In_ LARGE_INTEGER Length, _In_ CF_HYDRATE_FLAGS DehydrateFlags, _Inout_opt_ LPOVERLAPPED
// Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("CfApi.h")]
public static unsafe extern HRESULT CfDehydratePlaceholder(HFILE FileHandle, long StartingOffset, long Length, CF_DEHYDRATE_FLAGS DehydrateFlags, [In, Out] NativeOverlapped* Overlapped);
/// Disconnects a communication channel created by CfConnectSyncRoot.
/// The connection key returned from CfConnectSyncRoot that is now used to disconnect the sync root.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// This removes the communication channel with the platform that was previously established using CfConnectSyncRoot.
///
/// A sync provider can still receive callbacks during the CfDisconnectSyncRoot call, and the provider is free to choose
/// whether the call needs to fail or be serviced. Either choice will not cause disruptions to the sync provider.
///
///
/// After a call to CfDisconnectSyncRoot returns, the sync provider will no longer receive callbacks and the platform will
/// fail any operation that depends on said callbacks.
///
///
/// A sync provider should have WRITE_DATA or WRITE_DAC access to the sync root to be disconnected or a call to
/// CfDisconnectSyncRoot will be failed with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED). Also, if the sync root has not been
/// previously connected, the call will be failed with invalid parameters.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfdisconnectsyncroot HRESULT CfDisconnectSyncRoot(
// CF_CONNECTION_KEY ConnectionKey );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "AB09804A-257B-49A2-861E-B6E102D45182")]
public static extern HRESULT CfDisconnectSyncRoot(CF_CONNECTION_KEY ConnectionKey);
///
/// The main entry point for all connection key based placeholder operations. It is intended to be used by a sync provider to
/// respond to various callbacks from the platform.
///
/// Information about an operation on a placeholder.
/// Parameters of an operation on a placeholder.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// A valid call to CfExecute will reset the timers of all pending callback requests that belong to the same sync provider process.
///
///
/// CfExecute takes two variable-sized arguments, i.e., CF_OPERATION_INFO and CF_OPERATION_PARAMETERS, with one identifying
/// the operation type and the other supplying detailed operation parameters. Both arguments start with a StructSize field at
/// the beginning of the corresponding structures. Callers of CfExecute are responsible for accurate accounting of the
/// structure size.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfexecute HRESULT CfExecute( const CF_OPERATION_INFO *OpInfo,
// CF_OPERATION_PARAMETERS *OpParams );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "6AC8958D-B060-4468-9811-9BAB0E6A06D3")]
public static extern HRESULT CfExecute(in CF_OPERATION_INFO OpInfo, ref CF_OPERATION_PARAMETERS OpParams);
/// Allows the sync provider to query the current correlation vector for a given placeholder file.
/// The handle to the placeholder file.
/// The correlation vector for the FileHandle.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetcorrelationvector HRESULT CfGetCorrelationVector( HANDLE
// FileHandle, PCORRELATION_VECTOR CorrelationVector );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "3DB0AAFE-82DC-4707-8DB6-C52D4A9B2771")]
public static extern HRESULT CfGetCorrelationVector(HFILE FileHandle, out CORRELATION_VECTOR CorrelationVector);
/// Gets various characteristics of a placeholder file or folder.
/// A handle to the placeholder whose information will be queried.
/// Placeholder information. This can be set to either CF_PLACEHOLDER_STANDARD_INFO or CF_PLACEHOLDER_BASIC_INFO.
/// A pointer to a buffer that will receive information.
/// The length of the InfoBuffer, in bytes.
/// The number of bytes returned in the InfoBuffer.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetplaceholderinfo HRESULT CfGetPlaceholderInfo( HANDLE
// FileHandle, CF_PLACEHOLDER_INFO_CLASS InfoClass, PVOID InfoBuffer, DWORD InfoBufferLength, PDWORD ReturnedLength );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "D82269CF-8056-46CF-9832-AAE8767A854B")]
public static extern HRESULT CfGetPlaceholderInfo(HFILE FileHandle, CF_PLACEHOLDER_INFO_CLASS InfoClass, [Out] IntPtr InfoBuffer, uint InfoBufferLength, out uint ReturnedLength);
/// Gets various characteristics of a placeholder file or folder.
/// The type of information to retrieve.
/// A handle to the placeholder whose information will be queried.
/// The requested information.
[PInvokeData("cfapi.h", MSDNShortId = "D82269CF-8056-46CF-9832-AAE8767A854B")]
public static T CfGetPlaceholderInfo(HFILE FileHandle) where T : struct => GetInfo(CfGetPlaceholderInfo, FileHandle);
/// Gets range information about a placeholder file or folder.
/// The handle of the placeholder file to be queried.
/// Types of the range of placeholder data.
/// Offset of the starting point of the range of data.
/// Length of the range of data.
/// Pointer to a buffer to receive the data.
/// Length, in bytes, of InfoBuffer.
/// The length of the returned range of placeholder data in the InfoBuffer.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// Unlike most placeholder APIs that take a file handle, this one does not modify the file in any way, therefore the file handle
/// only requires READ_ATTRIBUTES access.
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetplaceholderrangeinfo HRESULT CfGetPlaceholderRangeInfo(
// HANDLE FileHandle, CF_PLACEHOLDER_RANGE_INFO_CLASS InfoClass, LARGE_INTEGER StartingOffset, LARGE_INTEGER Length, PVOID
// InfoBuffer, DWORD InfoBufferLength, PDWORD ReturnedLength );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "B7FE94BC-DC59-407D-85A6-9657E38975AB")]
public static extern HRESULT CfGetPlaceholderRangeInfo(HFILE FileHandle, CF_PLACEHOLDER_RANGE_INFO_CLASS InfoClass, long StartingOffset, long Length, [Out] IntPtr InfoBuffer, uint InfoBufferLength, out uint ReturnedLength);
/// Gets a set of placeholder states based on the FileAttributes and ReparseTag values of the file.
/// The file attribute information.
/// The reparse tag information from a file.
/// Can include CF_PLACEHOLDER_STATE; The placeholder state.
///
/// The FileAttributes and ReparseTag can be obtained by listing the directory containing the file or by directly querying
/// FileAttributeTagInfo on the file.
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetplaceholderstatefromattributetag CF_PLACEHOLDER_STATE
// CfGetPlaceholderStateFromAttributeTag( DWORD FileAttributes, DWORD ReparseTag );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "D7B4FB60-3388-489F-9F55-153B53BBDA9F")]
public static extern CF_PLACEHOLDER_STATE CfGetPlaceholderStateFromAttributeTag(FileFlagsAndAttributes FileAttributes, uint ReparseTag);
/// Gets a set of placeholder states based on the various information of the file.
/// An info buffer about the file.
/// An info class so the function knows how to interpret the InfoBuffer.
/// Can include CF_PLACEHOLDER_STATE; The placeholder state.
///
///
/// The input is a buffer containing information returned by GetFileInformationByHandleEx, and the corresponding InfoClass so the
/// API knows how to interpret the buffer.
///
///
/// Not all information classes supported by GetFileInformationByHandleEx are supported by this API. If the FileAttributes and
/// ReparseTag can’t be extracted from a given information class, this API will return CF_PLACEHOLDER_STATE_INVALID and set last
/// error properly.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetplaceholderstatefromfileinfo CF_PLACEHOLDER_STATE
// CfGetPlaceholderStateFromFileInfo( LPCVOID InfoBuffer, FILE_INFO_BY_HANDLE_CLASS InfoClass );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "33DB8FAC-D2C9-4BBB-8505-1D9A680EA2BF")]
public static extern CF_PLACEHOLDER_STATE CfGetPlaceholderStateFromFileInfo(IntPtr InfoBuffer, FILE_INFO_BY_HANDLE_CLASS InfoClass);
/// Gets a set of placeholder states based on the WIN32_FIND_DATA structure.
/// The find data information on the file.
/// Can include CF_PLACEHOLDER_STATE; The placeholder state.
/// The WIN32_FIND_DATA structure is obtained from the Win32 FindFirstFile/FindNextFile functions.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetplaceholderstatefromfinddata CF_PLACEHOLDER_STATE
// CfGetPlaceholderStateFromFindData( const WIN32_FIND_DATA *FindData );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "1A8104BC-E9D1-4846-B91F-4CBEDB1FC542")]
public static extern CF_PLACEHOLDER_STATE CfGetPlaceholderStateFromFindData(in WIN32_FIND_DATA FindData);
/// Gets the platform version information.
/// The platform version information. See CF_PLATFORM_INFO for more details.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetplatforminfo HRESULT CfGetPlatformInfo( CF_PLATFORM_INFO
// *PlatformVersion );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "BCF51702-87C1-405B-A3FF-98F5D0DDA8D5")]
public static extern HRESULT CfGetPlatformInfo(out CF_PLATFORM_INFO PlatformVersion);
/// Gets various characteristics of the sync root containing a given file specified by a file handle.
/// Handle of the file under the sync root whose information is to be queried.
/// Types of sync root information.
/// A pointer to a buffer that will receive the sync root information.
/// Length, in bytes, of the InfoBuffer.
/// The number of bytes returned in the InfoBuffer.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// Unlike most placeholder APIs that take a file handle, this one does not modify the file in any way, therefore the file handle
/// only requires READ_ATTRIBUTES access.
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetsyncrootinfobyhandle HRESULT CfGetSyncRootInfoByHandle(
// HANDLE FileHandle, CF_SYNC_ROOT_INFO_CLASS InfoClass, PVOID InfoBuffer, DWORD InfoBufferLength, DWORD *ReturnedLength );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "EC96CB4E-6BCE-49D9-9CDA-A24A9303B5CF")]
public static extern HRESULT CfGetSyncRootInfoByHandle(HFILE FileHandle, CF_SYNC_ROOT_INFO_CLASS InfoClass, [Out] IntPtr InfoBuffer, uint InfoBufferLength, out uint ReturnedLength);
/// Gets various characteristics of the sync root containing a given file specified by a file handle.
/// The type of information to retrieve.
/// Handle of the file under the sync root whose information is to be queried.
/// The requested sync root information.
[PInvokeData("cfapi.h", MSDNShortId = "EC96CB4E-6BCE-49D9-9CDA-A24A9303B5CF")]
public static T CfGetSyncRootInfoByHandle(HFILE FileHandle) where T : struct => GetInfo(CfGetSyncRootInfoByHandle, FileHandle);
/// Gets various sync root information given a file under the sync root.
/// A fully qualified path to a file whose sync root information is to be queried
/// Types of sync root information.
/// A pointer to a buffer that will receive the sync root information.
/// Length, in bytes, of the InfoBuffer.
///
/// Length, in bytes, of the returned sync root information. Refer to CfRegisterSyncRoot for details about the sync root information.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetsyncrootinfobypath HRESULT CfGetSyncRootInfoByPath(
// LPCWSTR FilePath, CF_SYNC_ROOT_INFO_CLASS InfoClass, PVOID InfoBuffer, DWORD InfoBufferLength, DWORD *ReturnedLength );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "0FEEF910-3545-4D94-BFF9-88AEE084F454")]
public static extern HRESULT CfGetSyncRootInfoByPath([MarshalAs(UnmanagedType.LPWStr)] string FilePath, CF_SYNC_ROOT_INFO_CLASS InfoClass, [Out] IntPtr InfoBuffer, uint InfoBufferLength, out uint ReturnedLength);
/// Gets various sync root information given a file under the sync root.
/// The type of information to retrieve.
/// A fully qualified path to a file whose sync root information is to be queried
/// The requested sync root information.
/// Supplied type parameter is not supported. - T
[PInvokeData("cfapi.h", MSDNShortId = "0FEEF910-3545-4D94-BFF9-88AEE084F454")]
public static T CfGetSyncRootInfoByPath(string FilePath) where T : struct => GetInfo(CfGetSyncRootInfoByPath, FilePath);
/// Initiates a transfer of data into a placeholder file or folder.
/// The file handle of the placeholder.
/// An opaque handle to the placeholder to be serviced.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// CfGetTransferKey is used as an alternative to CfHydratePlaceholder to proactively initiate data transfer into a placeholder.
///
///
/// A sync provider should have READ_DATA or WRITE_DAC access to the file whose transfer key is to be obtained or
/// CfGetTransferKey will be failed with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
///
/// The TransferKey is valid as long as the FileHandle used to obtain it remains open. The sync provider must pass the TransferKey
/// to CfExecute to perform the desired operation on the placholder file or folder. When a TransferKey is no longer being used, it
/// must be released using CfReleaseTransferKey.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgettransferkey HRESULT CfGetTransferKey( HANDLE FileHandle,
// CF_TRANSFER_KEY *TransferKey );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "07DDC46A-0C10-4677-A4B0-5A0406BBDAB7")]
public static extern HRESULT CfGetTransferKey(HFILE FileHandle, out CF_TRANSFER_KEY TransferKey);
/// Converts a protected handle to a Win32 handle so that it can be used with all handle-based Win32 APIs.
/// The protected handle to be converted.
/// The corresponding Win32 handle.
///
///
/// The caller must have referenced the protected handle prior to this call using CfReferenceProtectedHandle to ensure that the use
/// of the Win32 handle is tracked, and the Win32 API call that consumes the Win32 handle is synchronized with the oplock break
/// notification acknowledgment.
///
/// The caller must release the reference on the protected handle after being done with the Win32 handle using CfReleaseProtectedHandle.
/// In no circumstances should the caller close the Win32 handle returned using CfCloseHandle.
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfgetwin32handlefromprotectedhandle HANDLE
// CfGetWin32HandleFromProtectedHandle( HANDLE ProtectedHandle );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "8C54B6F3-7709-4021-8965-E96B74DD3319")]
public static extern HFILE CfGetWin32HandleFromProtectedHandle(HCFFILE ProtectedHandle);
///
/// Hydrates a placeholder file by ensuring that the specified byte range is present on-disk in the placeholder. This is valid for
/// files only.
///
/// Handle of the placeholder file to be hydrated. An attribute or no-access handle is sufficient.
/// The starting point offset of the placeholder file data.
///
/// The length, in bytes, of the placeholder file whose data must be available locally on the disk after the API completes
/// successfully. A length of -1 signifies end of file.
///
/// Placeholder hydration flags.
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfHydratePlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// The caller must have READ_DATA or WRITE_DAC access to the placeholder to be hydrated.
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfhydrateplaceholder HRESULT CfHydratePlaceholder( HANDLE
// FileHandle, LARGE_INTEGER StartingOffset, LARGE_INTEGER Length, CF_HYDRATE_FLAGS HydrateFlags, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "4FFD7580-BF59-48D0-B6D7-516559914096")]
public static extern HRESULT CfHydratePlaceholder(HFILE FileHandle, long StartingOffset = 0, long Length = -1, CF_HYDRATE_FLAGS HydrateFlags = 0, [In, Out] IntPtr Overlapped = default);
///
/// Hydrates a placeholder file by ensuring that the specified byte range is present on-disk in the placeholder. This is valid for
/// files only.
///
/// Handle of the placeholder file to be hydrated. An attribute or no-access handle is sufficient.
/// The starting point offset of the placeholder file data.
///
/// The length, in bytes, of the placeholder file whose data must be available locally on the disk after the API completes
/// successfully. A length of -1 signifies end of file.
///
/// Placeholder hydration flags.
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfHydratePlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// The caller must have READ_DATA or WRITE_DAC access to the placeholder to be hydrated.
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfhydrateplaceholder HRESULT CfHydratePlaceholder( HANDLE
// FileHandle, LARGE_INTEGER StartingOffset, LARGE_INTEGER Length, CF_HYDRATE_FLAGS HydrateFlags, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "4FFD7580-BF59-48D0-B6D7-516559914096")]
public static unsafe extern HRESULT CfHydratePlaceholder(HFILE FileHandle, long StartingOffset, long Length, CF_HYDRATE_FLAGS HydrateFlags, [In, Out] NativeOverlapped* Overlapped);
///
/// Opens an asynchronous opaque handle to a file or directory (for both normal and placeholder files) and sets up a proper oplock
/// on it based on the open flags.
///
/// Fully qualified path to the file or directory to be opened.
/// Flags to specify permissions on opening the file.
///
/// An opaque handle to the file or directory that is just opened. Note that this is not a normal Win32 handle and hence cannot be
/// used with non-CfApi Win32 APIs directly.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// When the oplock is broken, the API will handle the break notification automatically on behalf of the caller by draining all
/// active requests and then closing the underneath Win32 handle.
///
///
/// This aims to removing the complexity related to oplock usages. The caller must close the handle returned by
/// CfOpenFileWithOplock with CfCloseHandle.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfopenfilewithoplock HRESULT CfOpenFileWithOplock( LPCWSTR
// FilePath, CF_OPEN_FILE_FLAGS Flags, PHANDLE ProtectedHandle );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "AFC48080-3B4A-4F6B-9122-25C2A025EA95")]
public static extern HRESULT CfOpenFileWithOplock([MarshalAs(UnmanagedType.LPWStr)] string FilePath, CF_OPEN_FILE_FLAGS Flags, out SafeHCFFILE ProtectedHandle);
/// Queries a sync provider to get the status of the provider.
/// A connection key representing a communication channel with the sync filter.
/// The current status of the sync provider.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfquerysyncproviderstatus HRESULT CfQuerySyncProviderStatus(
// CF_CONNECTION_KEY ConnectionKey, CF_SYNC_PROVIDER_STATUS *ProviderStatus );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "02E6197B-D84A-4E3F-A74C-F5DACAA60AF9")]
public static extern HRESULT CfQuerySyncProviderStatus(CF_CONNECTION_KEY ConnectionKey, out CF_SYNC_PROVIDER_STATUS ProviderStatus);
/// Allows the caller to reference a protected handle to a Win32 handle which can be used with non-CfApi Win32 APIs.
/// The protected handle of a placeholder file.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// Every CfReferenceProtectedHandle call must be matched with a CfReleaseProtectedHandle call. It is not recommended to
/// reference a protected handle for a long period of time, as doing so will prevent the oplock break notification from being acknowledged.
///
///
/// The caller should instead break up long running tasks into smaller sub-tasks and reference/release the protected handle for each sub-task.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfreferenceprotectedhandle BOOLEAN CfReferenceProtectedHandle(
// HANDLE ProtectedHandle );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "C6281FD6-3A37-4D90-9B19-03DD23949C39")]
[return: MarshalAs(UnmanagedType.U1)]
public static extern bool CfReferenceProtectedHandle(HCFFILE ProtectedHandle);
/// Performs a one time sync root registration.
/// The path to the sync root to be registered.
/// Contains information about the sync provider and sync root to be registered.
/// The policies of the sync root to be registered.
/// Flags for registering previous and new sync roots.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// This can be used at a sync provider install time, first time set up for an individual user, or when a user configures another
/// sync root (if this scenario is supported).
///
///
/// This performs a one time sync root registration, which allows a sync provider to utilize an entire directory tree structure.
/// Note that no two sync roots directory trees can overlap with one another.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfregistersyncroot HRESULT CfRegisterSyncRoot( LPCWSTR
// SyncRootPath, const CF_SYNC_REGISTRATION *Registration, const CF_SYNC_POLICIES *Policies, CF_REGISTER_FLAGS RegisterFlags );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "FAD56873-8812-42DC-9975-9507F73BD9E3")]
public static extern HRESULT CfRegisterSyncRoot([MarshalAs(UnmanagedType.LPWStr)] string SyncRootPath, in CF_SYNC_REGISTRATION Registration, in CF_SYNC_POLICIES Policies, CF_REGISTER_FLAGS RegisterFlags);
/// Releases a protected handle referenced by CfReferenceProtectedHandle.
/// The protected handle to be released.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfreleaseprotectedhandle void CfReleaseProtectedHandle( HANDLE
// ProtectedHandle );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "BB63C5EE-92D7-4051-8198-09F50BBC75C5")]
public static extern void CfReleaseProtectedHandle(HCFFILE ProtectedHandle);
/// Releases a transfer key obtained by CfGetTransferKey.
/// The file handle of the placeholder.
/// An opaque handle to the placeholder.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfreleasetransferkey void CfReleaseTransferKey( HANDLE
// FileHandle, CF_TRANSFER_KEY *TransferKey );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "53B40C34-EB1F-445B-B1B3-B539C2FADECE")]
public static extern void CfReleaseTransferKey(HFILE FileHandle, in CF_TRANSFER_KEY TransferKey);
/// Allows a sync provider to report progress out-of-band.
/// A connection key representing a communication channel with the sync filter.
/// An opaque handle to the placeholder.
/// The total progress of the sync provider in response to a fetch data callback.
/// The completed progress of the sync provider in response to a fetch data callback.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfreportproviderprogress HRESULT CfReportProviderProgress(
// CF_CONNECTION_KEY ConnectionKey, CF_TRANSFER_KEY TransferKey, LARGE_INTEGER ProviderProgressTotal, LARGE_INTEGER
// ProviderProgressCompleted );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "33AB46FD-200E-40FF-B061-5842C6433069")]
public static extern HRESULT CfReportProviderProgress(CF_CONNECTION_KEY ConnectionKey, CF_TRANSFER_KEY TransferKey, long ProviderProgressTotal, long ProviderProgressCompleted);
///
/// Allows a sync provider to notify the platform of its status on a specified sync root without having to connect with a call to
/// CfConnectSyncRoot first.
///
/// Path to the sync root.
///
/// The sync status to report; if null, clears the previously-saved sync status. For more information, see the Remarks
/// section, below.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// When a non-null CF_SYNC_STATUS is provided in the SyncStatus parameter, the information will be remembered on the sync root
/// until it is cleared explicitly by the sync provider or when the machine reboots. The platform will query this information upon
/// any failed operations on a cloud file placeholder, using the following process:
///
///
/// -
///
///
/// -
///
///
/// -
///
///
///
///
/// CfReportSyncStatus clears the previously-saved sync status when being called with a null sync status. No change
/// will be made to the existing sync status if the function call fails.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfreportsyncstatus HRESULT CfReportSyncStatus( LPCWSTR
// SyncRootPath, CF_SYNC_STATUS *SyncStatus );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "DC77D18A-CBF4-4172-815A-AB49A48D10B3")]
public static extern HRESULT CfReportSyncStatus([MarshalAs(UnmanagedType.LPWStr)] string SyncRootPath, in CF_SYNC_STATUS SyncStatus);
///
/// Allows a sync provider to notify the platform of its status on a specified sync root without having to connect with a call to
/// CfConnectSyncRoot first.
///
/// Path to the sync root.
///
/// The sync status to report; if null, clears the previously-saved sync status. For more information, see the Remarks
/// section, below.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// When a non-null CF_SYNC_STATUS is provided in the SyncStatus parameter, the information will be remembered on the sync root
/// until it is cleared explicitly by the sync provider or when the machine reboots. The platform will query this information upon
/// any failed operations on a cloud file placeholder, using the following process:
///
///
/// -
///
///
/// -
///
///
/// -
///
///
///
///
/// CfReportSyncStatus clears the previously-saved sync status when being called with a null sync status. No change
/// will be made to the existing sync status if the function call fails.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfreportsyncstatus HRESULT CfReportSyncStatus( LPCWSTR
// SyncRootPath, CF_SYNC_STATUS *SyncStatus );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "DC77D18A-CBF4-4172-815A-AB49A48D10B3")]
public static extern HRESULT CfReportSyncStatus([MarshalAs(UnmanagedType.LPWStr)] string SyncRootPath, [In, Optional] IntPtr SyncStatus);
///
/// Reverts a placeholder back to a regular file, stripping away all special characteristics such as the reparse tag, the file
/// identity, etc.
///
///
/// A handle to the file or directory placeholder that is about to be reverted to normal file or directory. An attribute or
/// no-access handle is sufficient.
///
/// Placeholder revert flags.
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfRevertPlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// The caller must have WRITE_DATA or WRITE_DAC access to the placeholder to be reverted.
///
/// If the placeholder is not already fully hydrated at the time of the call, then the filter will send a FETCH_DATA callback to the
/// sync provider to hydrate the file. If the file can’t be hydrated, the revert will fail.
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfrevertplaceholder HRESULT CfRevertPlaceholder( HANDLE
// FileHandle, CF_REVERT_FLAGS RevertFlags, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "D5404BB6-A066-4B5F-A355-A11A107610CE")]
public static extern HRESULT CfRevertPlaceholder(HFILE FileHandle, CF_REVERT_FLAGS RevertFlags, [In, Out, Optional] IntPtr Overlapped);
///
/// Reverts a placeholder back to a regular file, stripping away all special characteristics such as the reparse tag, the file
/// identity, etc.
///
///
/// A handle to the file or directory placeholder that is about to be reverted to normal file or directory. An attribute or
/// no-access handle is sufficient.
///
/// Placeholder revert flags.
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfRevertPlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// The caller must have WRITE_DATA or WRITE_DAC access to the placeholder to be reverted.
///
/// If the placeholder is not already fully hydrated at the time of the call, then the filter will send a FETCH_DATA callback to the
/// sync provider to hydrate the file. If the file can’t be hydrated, the revert will fail.
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfrevertplaceholder HRESULT CfRevertPlaceholder( HANDLE
// FileHandle, CF_REVERT_FLAGS RevertFlags, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "D5404BB6-A066-4B5F-A355-A11A107610CE")]
public static unsafe extern HRESULT CfRevertPlaceholder(HFILE FileHandle, CF_REVERT_FLAGS RevertFlags, [In, Out] NativeOverlapped* Overlapped);
///
/// Allows a sync provider to instruct the platform to use a specific correlation vector for telemetry purposes on a placeholder
/// file. This is optional.
///
/// The handle to the placeholder file.
/// A specific correlation vector to be associated with the FileHandle.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// The platform automatically assigns a correlation vector to each file when it is first opened, and provides this correlation
/// vector with each callback to the sync provider as part of the common CF_CALLBACK_INFO. It is suggested that the sync engine call
/// this function to increment the last digit of the correlation vector “clock” as the sync provider progresses through internal
/// stages (as defined by the sync provider) of satisfying the request.
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfsetcorrelationvector HRESULT CfSetCorrelationVector( HANDLE
// FileHandle, const PCORRELATION_VECTOR CorrelationVector );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "B9B05D24-BEE5-4BE6-95D5-C28466D69543")]
public static extern HRESULT CfSetCorrelationVector(HFILE FileHandle, in CORRELATION_VECTOR CorrelationVector);
/// Sets the in-sync state for a placeholder file or folder.
/// A handle to the placeholder. The caller must have WRITE_DATA or WRITE_DAC access to the placeholder.
/// The in-sync state. See CF_IN_SYNC_STATE for more details.
/// The in-sync state flags. See CF_SET_IN_SYNC_FLAGS for more details.
///
/// When specified, this instructs the platform to only perform in-sync setting if the file still has the same USN value as the one
/// passed in. Passing a pointer to a USN value of 0 on input is the same as passing a NULL pointer. On return, this is the final
/// USN value after setting the in-sync state.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfsetinsyncstate HRESULT CfSetInSyncState( HANDLE FileHandle,
// CF_IN_SYNC_STATE InSyncState, CF_SET_IN_SYNC_FLAGS InSyncFlags, USN *InSyncUsn );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "1CB7955D-E530-4F34-8D67-BC608F8B6AF1")]
public static extern HRESULT CfSetInSyncState(HFILE FileHandle, CF_IN_SYNC_STATE InSyncState, CF_SET_IN_SYNC_FLAGS InSyncFlags, ref USN InSyncUsn);
/// Sets the in-sync state for a placeholder file or folder.
/// A handle to the placeholder. The caller must have WRITE_DATA or WRITE_DAC access to the placeholder.
/// The in-sync state. See CF_IN_SYNC_STATE for more details.
/// The in-sync state flags. See CF_SET_IN_SYNC_FLAGS for more details.
///
/// When specified, this instructs the platform to only perform in-sync setting if the file still has the same USN value as the one
/// passed in. Passing a pointer to a USN value of 0 on input is the same as passing a NULL pointer. On return, this is the final
/// USN value after setting the in-sync state.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfsetinsyncstate HRESULT CfSetInSyncState( HANDLE FileHandle,
// CF_IN_SYNC_STATE InSyncState, CF_SET_IN_SYNC_FLAGS InSyncFlags, USN *InSyncUsn );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "1CB7955D-E530-4F34-8D67-BC608F8B6AF1")]
public static extern HRESULT CfSetInSyncState(HFILE FileHandle, CF_IN_SYNC_STATE InSyncState, CF_SET_IN_SYNC_FLAGS InSyncFlags, [In, Optional] IntPtr InSyncUsn);
///
/// This sets the pin state of a placeholder, used to represent a user’s intent. Any application (not just the sync provider) can
/// call this function.
///
/// The handle of the placeholder file. The caller must have READ_DATA or WRITE_DAC access to the placeholder.
/// The pin state of the placeholder file.
/// The pin state flags.
/// Allows the call to be performed asynchronously. See the Remarks section for more details.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the call asynchronously.
///
/// The caller must have initialized the overlapped structure with an event to wait on. If this returns
/// HRESULT_FROM_WIN32(ERROR_IO_PENDING), the caller can then wait using GetOverlappedResult. If not specified, the platform will
/// perform the API call synchronously, regardless of how the handle was created.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfsetpinstate HRESULT CfSetPinState( HANDLE FileHandle,
// CF_PIN_STATE PinState, CF_SET_PIN_FLAGS PinFlags, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "8B279914-E23A-479B-8621-E83DE1978597")]
public static extern HRESULT CfSetPinState(HFILE FileHandle, CF_PIN_STATE PinState, CF_SET_PIN_FLAGS PinFlags, [In, Out, Optional] IntPtr Overlapped);
///
/// This sets the pin state of a placeholder, used to represent a user’s intent. Any application (not just the sync provider) can
/// call this function.
///
/// The handle of the placeholder file. The caller must have READ_DATA or WRITE_DAC access to the placeholder.
/// The pin state of the placeholder file.
/// The pin state flags.
/// Allows the call to be performed asynchronously. See the Remarks section for more details.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the call asynchronously.
///
/// The caller must have initialized the overlapped structure with an event to wait on. If this returns
/// HRESULT_FROM_WIN32(ERROR_IO_PENDING), the caller can then wait using GetOverlappedResult. If not specified, the platform will
/// perform the API call synchronously, regardless of how the handle was created.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfsetpinstate HRESULT CfSetPinState( HANDLE FileHandle,
// CF_PIN_STATE PinState, CF_SET_PIN_FLAGS PinFlags, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "8B279914-E23A-479B-8621-E83DE1978597")]
public static unsafe extern HRESULT CfSetPinState(HFILE FileHandle, CF_PIN_STATE PinState, CF_SET_PIN_FLAGS PinFlags, [In, Out] NativeOverlapped* Overlapped);
/// Unregisters a previously registered sync root.
/// The path to the sync root to be unregistered.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
///
/// Unregisters a sync root that was registered with CfRegisterSyncRoot. This is typically called at the sync provider uninstall
/// time, when a user account is deleted, or when a user opts to no longer sync a directory tree (if supported by the sync provider).
///
///
/// The sync provider should have WRITE_DATA or WRITE_DAC access to the sync root to be unregistered, or unregistration will fail
/// with: HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
/// Unregisters a sync root by traversing the directory tree of the sync root.
/// For placeholder files:
///
/// -
/// If a placeholder file is fully hydrated, it is reverted back to a "normal" file.
///
/// -
/// If a placeholder file is not hydrated, it is permanently deleted from the local machine.
///
///
/// For placeholder directories:
///
/// -
/// If a placeholder directory is fully populated, it is reverted back to a "normal" directory.
///
/// -
/// If a placeholder directory is not fully populated, the directory is permanently deleted from the local machine.
///
///
///
/// Note If the placeholder files or directories cannot be reverted or deleted, it will be skipped, and the unregistering
/// process will continue until the full sync root tree has been traversed.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfunregistersyncroot HRESULT CfUnregisterSyncRoot( LPCWSTR
// SyncRootPath );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "B4DA85DB-A63A-45EB-9F71-9395AC026A0C")]
public static extern HRESULT CfUnregisterSyncRoot([MarshalAs(UnmanagedType.LPWStr)] string SyncRootPath);
/// Updates characteristics of the placeholder file or directory.
/// A handle to the file or directory whose metadata is to be updated.
///
/// File system metadata to be updated for the placeholder. Values of 0 for the metadata indicate there are no updates.
///
///
/// A user mode buffer that contains file or directory information supplied by the caller. Should not exceed 4KB in size.
///
/// Length, in bytes, of the FileIdentity.
///
/// A range of an existing placeholder that will no longer be considered valid after the call to CfUpdatePlaceholder.
///
/// The count of a series of discrete DehydrateRangeArray partitions of placeholder data.
/// Update flags for placeholders.
///
///
/// On input, UpdateUsn instructs the platform to only perform the update if the file still has the same USN value as the one passed
/// in. This serves a similar purpose to CF_UPDATE_FLAG_VERIFY_IN_SYNC but also encompasses local metadata changes.
///
/// On return, UpdateUsn receives the final USN value after update actions were performed.
///
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfUpdatePlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// To update a placeholder:
///
/// -
///
/// The placeholder to be updated must be contained in a registered sync root tree; it can be the sync root directory itself, or any
/// descendant directory; otherwise, the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT).
///
///
/// -
///
/// If dehydration is requested, the sync root must be registered with a valid hydration policy that is not
/// CF_HYDRATION_POLICY_ALWAYS_FULL; otherwise the call will be failed with HRESULT(ERROR_CLOUD_FILE_NOT_SUPPORTED).
///
///
/// -
/// If dehydration is requested, the placeholder must not be pinned locally or the call with be failed with HRESULT(ERROR_CLOUD_FILE_PINNED).
///
/// -
/// If dehydration is requested, the placeholder must be in sync or the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_IN_SYNC).
///
/// -
///
/// The caller must have WRITE_DATA or WRITE_DAC access to the placeholder to be updated. Otherwise the operation will be failed
/// with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
///
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfupdateplaceholder HRESULT CfUpdatePlaceholder( HANDLE
// FileHandle, const CF_FS_METADATA *FsMetadata, LPCVOID FileIdentity, DWORD FileIdentityLength, const CF_FILE_RANGE
// *DehydrateRangeArray, DWORD DehydrateRangeCount, CF_UPDATE_FLAGS UpdateFlags, USN *UpdateUsn, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "13F2BF9A-505F-4CFB-B008-7DDE85A3C581")]
public static extern HRESULT CfUpdatePlaceholder(HFILE FileHandle, in CF_FS_METADATA FsMetadata, [In] IntPtr FileIdentity, uint FileIdentityLength,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] CF_FILE_RANGE[] DehydrateRangeArray, uint DehydrateRangeCount, CF_UPDATE_FLAGS UpdateFlags,
ref USN UpdateUsn, [In, Out, Optional] IntPtr Overlapped);
/// Updates characteristics of the placeholder file or directory.
/// A handle to the file or directory whose metadata is to be updated.
///
/// File system metadata to be updated for the placeholder. Values of 0 for the metadata indicate there are no updates.
///
///
/// A user mode buffer that contains file or directory information supplied by the caller. Should not exceed 4KB in size.
///
/// Length, in bytes, of the FileIdentity.
///
/// A range of an existing placeholder that will no longer be considered valid after the call to CfUpdatePlaceholder.
///
/// The count of a series of discrete DehydrateRangeArray partitions of placeholder data.
/// Update flags for placeholders.
///
///
/// On input, UpdateUsn instructs the platform to only perform the update if the file still has the same USN value as the one passed
/// in. This serves a similar purpose to CF_UPDATE_FLAG_VERIFY_IN_SYNC but also encompasses local metadata changes.
///
/// On return, UpdateUsn receives the final USN value after update actions were performed.
///
///
///
/// When specified and combined with an asynchronous FileHandle, Overlapped allows the platform to perform the
/// CfUpdatePlaceholder call asynchronously. See the Remarks for more details.
///
/// If not specified, the platform will perform the API call synchronously, regardless of how the handle was created.
///
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
///
/// To update a placeholder:
///
/// -
///
/// The placeholder to be updated must be contained in a registered sync root tree; it can be the sync root directory itself, or any
/// descendant directory; otherwise, the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_UNDER_SYNC_ROOT).
///
///
/// -
///
/// If dehydration is requested, the sync root must be registered with a valid hydration policy that is not
/// CF_HYDRATION_POLICY_ALWAYS_FULL; otherwise the call will be failed with HRESULT(ERROR_CLOUD_FILE_NOT_SUPPORTED).
///
///
/// -
/// If dehydration is requested, the placeholder must not be pinned locally or the call with be failed with HRESULT(ERROR_CLOUD_FILE_PINNED).
///
/// -
/// If dehydration is requested, the placeholder must be in sync or the call with be failed with HRESULT(ERROR_CLOUD_FILE_NOT_IN_SYNC).
///
/// -
///
/// The caller must have WRITE_DATA or WRITE_DAC access to the placeholder to be updated. Otherwise the operation will be failed
/// with HRESULT(ERROR_CLOUD_FILE_ACCESS_DENIED).
///
///
///
///
/// If the API returns HRESULT_FROM_WIN32(ERROR_IO_PENDING) when using Overlapped asynchronously, the caller can then wait using GetOverlappedResult.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfupdateplaceholder HRESULT CfUpdatePlaceholder( HANDLE
// FileHandle, const CF_FS_METADATA *FsMetadata, LPCVOID FileIdentity, DWORD FileIdentityLength, const CF_FILE_RANGE
// *DehydrateRangeArray, DWORD DehydrateRangeCount, CF_UPDATE_FLAGS UpdateFlags, USN *UpdateUsn, LPOVERLAPPED Overlapped );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "13F2BF9A-505F-4CFB-B008-7DDE85A3C581")]
public static unsafe extern HRESULT CfUpdatePlaceholder(HFILE FileHandle, in CF_FS_METADATA FsMetadata, [In] IntPtr FileIdentity, uint FileIdentityLength,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] CF_FILE_RANGE[] DehydrateRangeArray, uint DehydrateRangeCount, CF_UPDATE_FLAGS UpdateFlags,
ref USN UpdateUsn, [In, Out] NativeOverlapped* Overlapped);
/// Updates the current status of the sync provider.
/// A connection key representing a communication channel with the sync filter.
/// The current status of the sync provider.
/// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
// https://docs.microsoft.com/en-us/windows/win32/api/cfapi/nf-cfapi-cfupdatesyncproviderstatus HRESULT CfUpdateSyncProviderStatus(
// CF_CONNECTION_KEY ConnectionKey, CF_SYNC_PROVIDER_STATUS ProviderStatus );
[DllImport(Lib.CldApi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("cfapi.h", MSDNShortId = "E0CB6CA2-439A-4919-95EF-B519ABBBB085")]
public static extern HRESULT CfUpdateSyncProviderStatus(CF_CONNECTION_KEY ConnectionKey, CF_SYNC_PROVIDER_STATUS ProviderStatus);
private static T GetInfo(GetInfoFunc func, TParam firstParam) where TEnum : struct, Enum where T : struct
{
if (!CorrespondingTypeAttribute.CanGet(typeof(T), out var infoClass))
throw new ArgumentException("Supplied type parameter is not supported.", nameof(T));
using var mem = SafeHGlobalHandle.CreateFromStructure();
var hr = func(firstParam, infoClass, mem, mem.Size, out var len);
while (hr == (HRESULT)(Win32Error)Win32Error.ERROR_MORE_DATA && mem.Size < 1024 * 32)
{
mem.Size = len * 4;
hr = func(firstParam, infoClass, mem, mem.Size, out len);
}
hr.ThrowIfFailed();
return mem.ToStructure();
}
/// Provides a handle to a CF opened file.
[StructLayout(LayoutKind.Sequential)]
public struct HCFFILE : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HCFFILE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HCFFILE NULL => new HCFFILE(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HCFFILE h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HCFFILE(IntPtr h) => new HCFFILE(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HCFFILE h1, HCFFILE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HCFFILE h1, HCFFILE h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HCFFILE h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a for that is disposed using .
public class SafeHCFFILE : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHCFFILE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHCFFILE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HCFFILE(SafeHCFFILE h) => h.handle;
///
protected override bool InternalReleaseHandle() { CfCloseHandle(handle); return true; }
}
}
}