using System; using System.Runtime.InteropServices; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; namespace Vanara.PInvoke { /// Functions, structures and constants from ProjectedFSLib.dll. public static partial class ProjectedFSLib { /// Notifies the provider that an operation by an earlier invocation of a callback should be canceled. /// /// Information about the operation. The following /// callbackData /// members are necessary to implement this callback: /// /// None /// /// /// Every invocation of a provider callback has a callbackData parameter with a CommandId field. If a provider supplies an /// implementation of this callback, it should keep track of the CommandId values of callbacks that it processes /// asynchronously, i.e. callbacks from which it has returned HRESULT_FROM_WIN32(ERROR_IO_PENDING) but not yet completed by /// calling PrjCompleteCommand. If the provider receives this callback, it indicates that the I/O that caused the earlier callback /// to be invoked was canceled, either explicitly or because the thread it was issued on terminated. The provider should cancel /// processing the callback invocation identified by CommandId as soon as possible. /// /// /// Calling PrjCompleteCommand for the CommandId in this callback's callbackData is not an error, however it is a no-op /// because the I/O that caused the callback invocation identified by CommandId has already ended. /// /// /// ProjFS will invoke PRJ_CANCEL_COMMAND_CB for a given CommandId only after the callback to be canceled is invoked. However /// if the provider is configured to allow more than one concurrently running worker thread, the cancellation and original /// invocation may run concurrently. The provider must be able to handle this situation. /// /// /// This callback is optional. If the provider does not supply an implementation of this callback, none of the other callbacks will /// be cancellable. The provider will process all callbacks synchronously. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_cancel_command_cb PRJ_CANCEL_COMMAND_CB // PrjCancelCommandCb; void PrjCancelCommandCb( const PRJ_CALLBACK_DATA *callbackData ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "8C646A8C-7C55-4F54-965A-04ACAC64C65D")] public delegate void PRJ_CANCEL_COMMAND_CB(in PRJ_CALLBACK_DATA callbackData); /// Informs the provider that a directory enumeration is over. /// /// Information about the operation. /// /// The provider can access this buffer only while the callback is running. If it wishes to pend the operation and it requires data /// from this buffer, it must make its own copy of it. /// /// /// /// An identifier for this enumeration session. See the Remarks section of PRJ_START_DIRECTORY_ENUMERATION_CB for more information. /// /// /// /// /// Return code /// Description /// /// /// S_OK /// The provider successfully completed the operation. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// The provider should not return any other value from this callback. /// /// /// For a user-initiated enumeration ProjFS invokes this callback when the file handle used to enumerate the directory is closed. /// For a ProjFS-initiated enumeration, this callback is invoked when ProjFS completes the enumeration. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_end_directory_enumeration_cb // PRJ_END_DIRECTORY_ENUMERATION_CB PrjEndDirectoryEnumerationCb; HRESULT PrjEndDirectoryEnumerationCb( const PRJ_CALLBACK_DATA // *callbackData, const GUID *enumerationId ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "E9DA86AC-E884-4DB3-977D-6D8EDA2A8E12")] public delegate HRESULT PRJ_END_DIRECTORY_ENUMERATION_CB(in PRJ_CALLBACK_DATA callbackData, in Guid enumerationId); /// Requests directory enumeration information from the provider. /// /// Information about the operation. The following /// callbackData /// members are necessary to implement this callback: /// /// The provider can access this buffer only while the callback is running. If it wishes to pend the operation and it requires data /// from this buffer, it must make its own copy of it. /// /// /// An identifier for this enumeration session. /// /// /// A pointer to a null-terminated Unicode string specifying a search expression. The search expression may include wildcard /// characters. The provider should use the PrjDoesNameContainWildCards function to determine whether wildcards are present in /// searchExpression, and it should use the PrjFileNameMatch function to determine whether an entry in its backing store /// matches a search expression containing wildcards. /// /// This parameter is optional and may be NULL. /// /// /// If this parameter is not NULL, the provider must return only those directory entries whose names match the search expression. /// /// /// If this parameter is NULL, the provider must return all directory entries. /// /// /// /// The provider should capture the value of this parameter on the first invocation of this callback for an enumeration session and /// use it on subsequent invocations, ignoring this parameter on those invocations unless PRJ_CB_DATA_FLAG_ENUM_RESTART_SCAN /// is specified in the Flags member of callbackData. In that case the provider must re-capture the value of searchExpression. /// /// /// /// An opaque handle to a structure that receives the results of the enumeration from the provider. The provider uses the /// PrjFillDirEntryBuffer routine to fill the structure. /// /// /// /// /// Return code /// Description /// /// /// S_OK /// /// The provider successfully added at least one entry to dirEntryBufferHandle, or no entries in the provider’s store match searchExpression. /// /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) /// The provider received this error from PrjFillDirEntryBuffer for the first file or directory it tried to add to dirEntryBufferHandle. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// An appropriate HRESULT error code if the provider fails the operation. /// /// /// ProjFS invokes this callback one or more times after invoking PRJ_START_DIRECTORY_ENUMERATION_CB. See the Remarks section of /// PRJ_START_DIRECTORY_ENUMERATION_CB for more information. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_get_directory_enumeration_cb // PRJ_GET_DIRECTORY_ENUMERATION_CB PrjGetDirectoryEnumerationCb; HRESULT PrjGetDirectoryEnumerationCb( const PRJ_CALLBACK_DATA // *callbackData, const GUID *enumerationId, PCWSTR searchExpression, PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "45E7E7F9-9E54-44C8-9915-43CCECF85DB6")] public delegate HRESULT PRJ_GET_DIRECTORY_ENUMERATION_CB(in PRJ_CALLBACK_DATA callbackData, in Guid enumerationId, [MarshalAs(UnmanagedType.LPWStr)] string searchExpression, PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle); /// Requests the contents of a file's primary data stream. /// /// Information about the operation. The following /// callbackData /// members are necessary to implement this callback: /// /// The provider can access this buffer only while the callback is running. If it wishes to pend the operation and it requires data /// from this buffer, it must make its own copy of it. /// /// /// /// Offset of the requested data, in bytes, from the beginning of the file. The provider must return file data starting at or before /// this offset /// /// /// Number of bytes of file data requested. The provider must return at least this many bytes of file data beginning with byteOffset. /// /// /// /// /// Return code /// Description /// /// /// S_OK /// The provider successfully returned all the requested data. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// An appropriate HRESULT error code if the provider fails the operation. /// /// /// When ProjFS receives the data it will write it to the file to convert it into a hydrated placeholder. /// /// To handle this callback, the provider issues one or more calls to PrjWriteFileData to give ProjFS the requested contents of the /// file's primary data stream. Then the provider completes the callback. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_get_file_data_cb PRJ_GET_FILE_DATA_CB // PrjGetFileDataCb; HRESULT PrjGetFileDataCb( const PRJ_CALLBACK_DATA *callbackData, UINT64 byteOffset, UINT32 length ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "8F3EEC96-70C2-40ED-BDF3-B6E979EF1F7E")] public delegate HRESULT PRJ_GET_FILE_DATA_CB(in PRJ_CALLBACK_DATA callbackData, ulong byteOffset, uint length); /// Requests information for a file or directory from the provider. /// /// Information about the operation. The following /// callbackData /// members are necessary to implement this callback: /// /// The provider can access this buffer only while the callback is running. If it wishes to pend the operation and it requires data /// from this buffer, it must make its own copy of it. /// /// /// /// /// /// Return code /// Description /// /// /// S_OK /// The file exists in the provider's store and it successfully gave the file's information to ProjFS. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /// The file does not exist in the provider's store. /// /// /// Another appropriate HRESULT error code if the provider fails the operation. /// /// /// ProjFS will use the information provided in this callback to create a placeholder for the requested item. /// /// To handle this callback, the provider calls PrjWritePlaceholderInfo to give ProjFS the information for the requested file name. /// Then the provider completes the callback. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_get_placeholder_info_cb // PRJ_GET_PLACEHOLDER_INFO_CB PrjGetPlaceholderInfoCb; HRESULT PrjGetPlaceholderInfoCb( const PRJ_CALLBACK_DATA *callbackData ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "1BC7C1FA-1BAB-48FB-85C2-34EC3B1B4167")] public delegate HRESULT PRJ_GET_PLACEHOLDER_INFO_CB(in PRJ_CALLBACK_DATA callbackData); /// Delivers notifications to the provider about file system operations. /// /// Information about the operation. The following /// callbackData /// members are necessary to implement this callback: /// /// The provider can access this buffer only while the callback is running. If it wishes to pend the operation and it requires data /// from this buffer, it must make its own copy of it. /// /// /// TRUE if the FilePathName field in callbackData refers to a directory, FALSE otherwise. /// A PRJ_NOTIFICATIONvalue specifying the notification. /// /// If notification is PRJ_NOTIFICATION_PRE_RENAME or PRJ_NOTIFICATION_PRE_SET_HARDLINK, this points to a /// null-terminated Unicode string specifying the path, relative to the virtualization root, of the target of the rename or /// set-hardlink operation. /// /// /// A pointer to a PRJ_NOTIFICATION_PARAMETERS union specifying extra parameters for certain values of notification: /// PRJ_NOTIFICATION_FILE_OPENED /// , /// PRJ_NOTIFICATION_NEW_FILE_CREATED /// , or /// PRJ_NOTIFICATION_FILE_OVERWRITTEN /// PRJ_NOTIFICATION_FILE_RENAMED /// PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_DELETED /// /// /// The fields of the FileDeletedOnHandleClose member are specified. These fields are: NotificationMask /// /// /// /// /// /// /// Return code /// Description /// /// /// S_OK /// The provider successfully processed the notification. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// /// An appropriate HRESULT error code if the provider fails the operation. For pre-operation notifications (operations with "PRE" in /// their name), if the provider returns a failure code ProjFS will fail the corresponding operation with the provided error code. /// /// /// /// This callback is optional. If the provider does not supply an implementation of this callback, it will not receive notifications. /// The provider registers for the notifications it wishes to receive when it calls PrjStartVirtualizing. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_notification_cb PRJ_NOTIFICATION_CB // PrjNotificationCb; HRESULT PrjNotificationCb( const PRJ_CALLBACK_DATA *callbackData, BOOLEAN isDirectory, PRJ_NOTIFICATION // notification, PCWSTR destinationFileName, PRJ_NOTIFICATION_PARAMETERS *operationParameters ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "7F149A78-2668-4BF2-88D3-1E40CA469AA6")] public delegate HRESULT PRJ_NOTIFICATION_CB(in PRJ_CALLBACK_DATA callbackData, [MarshalAs(UnmanagedType.U1)] bool isDirectory, PRJ_NOTIFICATION notification, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, ref PRJ_NOTIFICATION_PARAMETERS operationParameters); /// Determines whether a given file path exists in the provider's backing store. /// Information about the operation. /// /// /// /// Return code /// Description /// /// /// S_OK /// The queried file path exists in the provider's store. /// /// /// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /// The queried file path does not exist in the provider's store. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// An appropriate HRESULT error code if the provider fails the operation. /// /// /// /// This callback is optional. If the provider does not supply an implementation of this callback, ProjFS will invoke the provider’s /// directory enumeration callbacks to determine the existence of a file path in the provider's store. /// /// /// The provider should use PrjFileNameCompare as the comparison routine when searching its backing store for the specified file. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_query_file_name_cb PRJ_QUERY_FILE_NAME_CB // PrjQueryFileNameCb; HRESULT PrjQueryFileNameCb( const PRJ_CALLBACK_DATA *callbackData ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "1B218D41-AF24-48C2-9E11-7E0455CE15AC")] public delegate HRESULT PRJ_QUERY_FILE_NAME_CB(in PRJ_CALLBACK_DATA callbackData); /// Informs the provider that a directory enumeration is starting. /// /// Information about the operation. The following /// callbackData /// members are necessary to implement this callback: /// /// The provider can access this buffer only while the callback is running. If it wishes to pend the operation and it requires data /// from this buffer, it must make its own copy of it. /// /// /// An identifier for this enumeration session. /// /// /// /// Return code /// Description /// /// /// S_OK /// The provider successfully completed the operation. /// /// /// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /// The directory to be enumerated does not exist in the provider’s backing store. /// /// /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) /// The provider wishes to complete the operation at a later time. /// /// /// An appropriate HRESULT error code if the provider fails the operation. /// /// /// ProjFS requests a directory enumeration from the provider by first invoking this callback, then one or more /// PRJ_GET_DIRECTORY_ENUMERATION_CB callbacks, then the PRJ_END_DIRECTORY_ENUMERATION_CB callback. Because multiple enumerations /// may occur in parallel in the same location, ProjFS uses the enumerationId argument to associate the callback invocations into a /// single enumeration session, meaning that a given set of calls to the enumeration callbacks will use the same value for /// enumerationId for the same session. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nc-projectedfslib-prj_start_directory_enumeration_cb // PRJ_START_DIRECTORY_ENUMERATION_CB PrjStartDirectoryEnumerationCb; HRESULT PrjStartDirectoryEnumerationCb( const // PRJ_CALLBACK_DATA *callbackData, const GUID *enumerationId ) {...} [PInvokeData("projectedfslib.h", MSDNShortId = "09F284D4-BF39-42C9-A89B-DDC8201362EE")] public delegate HRESULT PRJ_START_DIRECTORY_ENUMERATION_CB(in PRJ_CALLBACK_DATA callbackData, in Guid enumerationId); /// Flags controlling what is returned in the enumeration. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_callback_data_flags typedef enum // PRJ_CALLBACK_DATA_FLAGS { PRJ_CB_DATA_FLAG_ENUM_RESTART_SCAN, PRJ_CB_DATA_FLAG_ENUM_RETURN_SINGLE_ENTRY } ; [PInvokeData("projectedfslib.h", MSDNShortId = "5046714B-64AC-458D-93C7-013B1466C655")] [Flags] public enum PRJ_CALLBACK_DATA_FLAGS { /// Start the scan at the first entry in the directory. PRJ_CB_DATA_FLAG_ENUM_RESTART_SCAN = 0x1, /// Return only one entry from the enumeration. PRJ_CB_DATA_FLAG_ENUM_RETURN_SINGLE_ENTRY = 0x2, } /// Specifies command types. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_complete_command_type typedef enum // PRJ_COMPLETE_COMMAND_TYPE { PRJ_COMPLETE_COMMAND_TYPE_NOTIFICATION, PRJ_COMPLETE_COMMAND_TYPE_ENUMERATION } ; [PInvokeData("projectedfslib.h", MSDNShortId = "AE9CD44C-0E68-4E35-8A7E-89B33E796AF0")] public enum PRJ_COMPLETE_COMMAND_TYPE { /// The provider is completing a call to its PRJ_NOTIFICATION_CB callback. PRJ_COMPLETE_COMMAND_TYPE_NOTIFICATION = 1, /// The provider is completing a call to its PRJ_GET_DIRECTORY_ENUMERATION_CB callback. PRJ_COMPLETE_COMMAND_TYPE_ENUMERATION, } /// Specifies extended information types for PRJ_EXTENDED_INFO. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_ext_info_type typedef enum // PRJ_EXT_INFO_TYPE { PRJ_EXT_INFO_TYPE_SYMLINK } ; [PInvokeData("projectedfslib.h", MSDNShortId = "NE:projectedfslib.PRJ_EXT_INFO_TYPE")] public enum PRJ_EXT_INFO_TYPE { /// This PRJ_EXTENDED_INFO specifies the target of a symbolic link. PRJ_EXT_INFO_TYPE_SYMLINK = 1 } /// The state of an item. /// /// The PRJ_FILE_STATE_FULL and PRJ_FILE_STATE_TOMBSTONE bits will not appear in combination with each other or any other bit. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_file_state typedef enum PRJ_FILE_STATE { // PRJ_FILE_STATE_PLACEHOLDER, PRJ_FILE_STATE_HYDRATED_PLACEHOLDER, PRJ_FILE_STATE_DIRTY_PLACEHOLDER, PRJ_FILE_STATE_FULL, // PRJ_FILE_STATE_TOMBSTONE } ; [PInvokeData("projectedfslib.h", MSDNShortId = "9474C21B-47D4-468F-A970-0B0CBCF357A3")] [Flags] public enum PRJ_FILE_STATE : uint { /// The item is a placeholder. PRJ_FILE_STATE_PLACEHOLDER = 0x01, /// The item is a hydrated placeholder, i.e., the item's content has been written to disk. PRJ_FILE_STATE_HYDRATED_PLACEHOLDER = 0x02, /// The placeholder item's metadata has been modified. PRJ_FILE_STATE_DIRTY_PLACEHOLDER = 0x04, /// The item is full. PRJ_FILE_STATE_FULL = 0x08, /// The item is a tombstone. PRJ_FILE_STATE_TOMBSTONE = 0x10, } /// A notification value specified when sending the PRJ_NOTIFICATION_CB callback. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_notification typedef enum // PRJ_NOTIFICATION { PRJ_NOTIFICATION_FILE_OPENED, PRJ_NOTIFICATION_NEW_FILE_CREATED, PRJ_NOTIFICATION_FILE_OVERWRITTEN, // PRJ_NOTIFICATION_PRE_DELETE, PRJ_NOTIFICATION_PRE_RENAME, PRJ_NOTIFICATION_PRE_SET_HARDLINK, PRJ_NOTIFICATION_FILE_RENAMED, // PRJ_NOTIFICATION_HARDLINK_CREATED, PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_NO_MODIFICATION, // PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_MODIFIED, PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_DELETED, // PRJ_NOTIFICATION_FILE_PRE_CONVERT_TO_FULL } ; [PInvokeData("projectedfslib.h", MSDNShortId = "A1DC0CAF-0101-4410-86A6-5839A8C20988")] [Flags] public enum PRJ_NOTIFICATION : uint { /// /// - Indicates that a handle has been created to an existing file or folder.- The provider can specify a new notification mask /// for this file or folder when responding to the notification. /// PRJ_NOTIFICATION_FILE_OPENED = 0x00000002, /// /// - A new file or folder has been created.- The provider can specify a new notification mask for this file or folder when /// responding to the notification. /// PRJ_NOTIFICATION_NEW_FILE_CREATED = 0x00000004, /// /// - An existing file has been overwritten or superceded.- The provider can specify a new notification mask for this file or /// folder when responding to the notification. /// PRJ_NOTIFICATION_FILE_OVERWRITTEN = 0x00000008, /// /// - A file or folder is about to be deleted.- If the provider returns an error HRESULT code from the callback, the delete will /// not take effect. /// PRJ_NOTIFICATION_PRE_DELETE = 0x00000010, /// /// - A file or folder is about to be renamed.- If the provider returns an error HRESULT code from the callback, the rename will /// not take effect.- If the callbackData->FilePathName parameter of PRJ_NOTIFICATION_CB is an empty string, this indicates /// that the rename is moving the file/directory from outside the virtualization instance. In that case, this notification will /// always be sent if the provider has registered a PRJ_NOTIFICATION_CB callback, even if the provider did not specify this bit /// when registering the subtree containing the destination path. However if the provider specified /// PRJ_NOTIFICATION_SUPPRESS_NOTIFICATIONS when registering the subtree containing the destination path, the notification will /// be suppressed. - If the destinationFileName parameter of PRJ_NOTIFICATION_CB is an empty string, this indicates that the /// rename is moving the file/folder out of the virtualization instance. - If both the callbackData->FilePathName and /// destinationFileName parameters of PRJ_NOTIFICATION_CB are non-empty strings, this indicates that the rename is within the /// virtualization instance. If the provider specified different notification masks for the source and destination paths in the /// NotificationMappings member of the options parameter of PrjStartVirtualizing, then this notification will be sent if the /// provider specified this bit when registering either the source or destination paths. /// PRJ_NOTIFICATION_PRE_RENAME = 0x00000020, /// /// - A hard link is about to be created for the file.- If the provider returns an error HRESULT code from the callback, the /// hard link operation will not take effect. - If the callbackData->FilePathName parameter of PRJ_NOTIFICATION_CB is an /// empty string, this indicates that the hard link name will be created inside the virtualization instance, i.e. a new hard /// link is being created inside the virtualization instance to a file that exists outside the virtualization instance. In that /// case, this notification will always be sent if the provider has registered a PRJ_NOTIFICATION_CB callback, even if the /// provider did not specify this bit when registering the subtree where the new hard link name will be. However if the provider /// specified PRJ_NOTIFICATION_SUPPRESS_NOTIFICATIONS when registering the subtree containing the destination path, the /// notification will be suppressed.- If the destinationFileName parameter of PRJ_NOTIFICATION_CB is an empty string, this /// indicates that the hard link name will be created outside the virtualization instance, i.e. a new hard link is being created /// outside the virtualization instance for a file that exists inside the virtualization instance. - If both the /// callbackData->FilePathName and destinationFileName parameters of PRJ_NOTIFICATION_CB are non-empty strings, this /// indicates that the new hard link will be created within the virtualization instance for a file that exists within the /// virtualization instance. If the provider specified different notification masks for the source and destination paths in the /// NotificationMappings member of the options parameter of PrjStartVirtualizing, then this notification will be sent if the /// provider specified this bit when registering either the source or destination paths. /// PRJ_NOTIFICATION_PRE_SET_HARDLINK = 0x00000040, /// /// - Indicates that a file/folder has been renamed. The file/folder may have been moved into the virtualization instance.- If /// the callbackData->FilePathName parameter of PRJ_NOTIFICATION_CB is an empty string, this indicates that the rename moved /// the file/directory from outside the virtualization instance. In that case ProjFS will always send this notification if the /// provider has registered a PRJ_NOTIFICATION_CB callback, even if the provider did not specify this bit when registering the /// subtree containing the destination path. - If the destinationFileName parameter of PRJ_NOTIFICATION_CB is an empty string, /// this indicates that the rename moved the file/directory out of the virtualization instance. - If both the /// callbackData->FilePathName and destinationFileName parameters of PRJ_NOTIFICATION_CB are non-empty strings, this /// indicates that the rename was within the virtualization instance. If the provider specified different notification masks for /// the source and destination paths in the NotificationMappings member of the options parameter of PrjStartVirtualizing, then /// ProjFS will send this notification if the provider specified this bit when registering either the source or destination /// paths.- The provider can specify a new notification mask for this file/directory when responding to the notification. /// PRJ_NOTIFICATION_FILE_RENAMED = 0x00000080, /// /// - Indicates that a hard link has been created for the file. - If the callbackData->FilePathName parameter of /// PRJ_NOTIFICATION_CB is an empty string, this indicates that the hard link name was created inside the virtualization /// instance, i.e. a new hard link was created inside the virtualization instance to a file that exists outside the /// virtualization instance. In that case ProjFS will always send this notification if the provider has registered a /// PRJ_NOTIFICATION_CB callback, even if the provider did not specify this bit when registering the subtree where the new hard /// link name will be. - If the destinationFileName parameter of PRJ_NOTIFICATION_CB is an empty string, this indicates that the /// hard link name was created outside the virtualization instance, i.e. a new hard link was created outside the virtualization /// instance for a file that exists inside the virtualization instance. - If both the callbackData->FilePathName and /// destinationFileName parameters of PRJ_NOTIFICATION_CB are non-empty strings, this indicates that the a new hard link was /// created within the virtualization instance for a file that exists within the virtualization instance. If the provider /// specified different notification masks for the source and destination paths in the NotificationMappings member of the /// options parameter of PrjStartVirtualizing, then ProjFS will send this notification if the provider specified this bit when /// registering either the source or destination paths. /// PRJ_NOTIFICATION_HARDLINK_CREATED = 0x00000100, /// /// - A handle has been closed on the file/folder, and the file's content was not modified while the handle was open, and the /// file/folder was not deleted /// PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_NO_MODIFICATION = 0x00000200, /// - A handle has been closed on the file, and that the file's content was modified while the handle was open. PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_MODIFIED = 0x00000400, /// /// - A handle has been closed on the file/folder, and that it was deleted as part of closing the handle. - If the provider also /// registered to receive PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_MODIFIED notifications, and the file was modified using the /// handle whose close resulted in deleting the file, then the operationParameters->FileDeletedOnHandleClose.IsFileModified /// parameter of PRJ_NOTIFICATION_CB will be TRUE. This applies only to files, not directories /// PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_DELETED = 0x00000800, /// /// - The file is about to be expanded from a placeholder to a full file, i.e. its contents are likely to be modified.- If the /// provider returns an error HRESULT code from the callback, the file will not be expanded to a full file, and the I/O that /// triggered the conversion will fail.- If there are multiple racing I/Os that would expand the same file, the provider will /// receive this notification value only once for the file. /// PRJ_NOTIFICATION_FILE_PRE_CONVERT_TO_FULL = 0x00001000, } /// Types of notifications describing a change to the file or folder. /// /// /// ProjFS can send notifications of file system activity to a provider. When the provider starts a virtualization instance it /// specifies which notifications it wishes to receive. It may also specify a new set of notifications for a file when it is created /// or renamed. The provider must register a PRJ_NOTIFICATION_CB notification callback routine in the callbacks parameter of /// PrjStartVirtualizing in order to receive notifications. /// /// /// ProjFS sends notifications for files and directories within an active virtualization root. That is, ProjFS will send /// notifications for the virtualization root and its descendants. Symbolic links and junctions within the virtualization root are /// not traversed when determining what constitutes a descendant of the virtualization root. /// /// /// ProjFS sends notifications only for the primary data stream of a file. ProjFS does not send notifications for operations on /// alternate data streams. /// /// /// ProjFS does not send notifications for an inactive virtualization instance. A virtualization instance is inactive if any one of /// the following is true: /// /// /// /// The provider has not yet started it by calling PrjStartVirtualizing. /// /// /// The provider has stopped the instance by calling PrjStopVirtualizing. /// /// /// The provider process has exited /// /// /// /// The provider may specify which notifications it wishes to receive when starting a virtualization instance, or in response to a /// notification that allows a new notification mask to be set. /// /// /// The provider specifies a default set of notifications that it wants ProjFS to send for the virtualization instance when it /// starts the instance. This set of notifications is provided in the NotificationMappings member of the options parameter of /// PrjStartVirtualizing, which may specify different notification masks for different subtrees of the virtualization instance. /// /// /// The provider may choose to supply a different notification mask in response to a notification of file open, create, /// supersede/overwrite, or rename. ProjFS will continue to send these notifications for the given file until all handles to the /// file are closed. After that it will revert to the default set of notifications. Naturally if the default set of notifications /// does not specify that ProjFS should notify for open, create, etc., the provider will not get the opportunity to specify a /// different mask for those operations. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_notify_types typedef enum // PRJ_NOTIFY_TYPES { PRJ_NOTIFY_NONE, PRJ_NOTIFY_SUPPRESS_NOTIFICATIONS, PRJ_NOTIFY_FILE_OPENED, PRJ_NOTIFY_NEW_FILE_CREATED, // PRJ_NOTIFY_FILE_OVERWRITTEN, PRJ_NOTIFY_PRE_DELETE, PRJ_NOTIFY_PRE_RENAME, PRJ_NOTIFY_PRE_SET_HARDLINK, PRJ_NOTIFY_FILE_RENAMED, // PRJ_NOTIFY_HARDLINK_CREATED, PRJ_NOTIFY_FILE_HANDLE_CLOSED_NO_MODIFICATION, PRJ_NOTIFY_FILE_HANDLE_CLOSED_FILE_MODIFIED, // PRJ_NOTIFY_FILE_HANDLE_CLOSED_FILE_DELETED, PRJ_NOTIFY_FILE_PRE_CONVERT_TO_FULL, PRJ_NOTIFY_USE_EXISTING_MASK } ; [PInvokeData("projectedfslib.h", MSDNShortId = "AB19AD36-44FB-4CA8-9101-4EEF2646A46C")] [Flags] public enum PRJ_NOTIFY_TYPES : uint { /// No notification. PRJ_NOTIFY_NONE = 0x00000000, /// /// If specified on virtualization instance start:- This indicates that notifications should not be sent for the virtualization /// instance, or a specified subtree of the instance.If specified in response to a notification:- This indicates that /// notifications should not be sent for the specified file or folder until all handles to it are closed. /// PRJ_NOTIFY_SUPPRESS_NOTIFICATIONS = 0x00000001, /// /// If specified on virtualization instance start:- This indicates that the provider should be notified when a handle is created /// to an existing file or folder.If specified in response to a notification:- This indicates that the provider should be /// notified if any further handles are created to the file or folder. /// PRJ_NOTIFY_FILE_OPENED = 0x00000002, /// /// If specified on virtualization instance start:- The provider should be notified when a new file or folder is created.If /// specified in response to a notification:- No effect. /// PRJ_NOTIFY_NEW_FILE_CREATED = 0x00000004, /// /// If specified on virtualization instance start:- Indicates that the provider should be notified when an existing when an /// existing file is overwritten or superceded.If specified in response to a notification:- Indicates that the provider should /// be notified when the file or folder is overwritten or superceded. /// PRJ_NOTIFY_FILE_OVERWRITTEN = 0x00000008, /// /// If specified on virtualization instance start:- Indicates that the provider should be notified when a file or folder is /// about to be deleted.If specified in response to a notification:- Indicates that the provider should be notified when a file /// or folder is about to be deleted. /// PRJ_NOTIFY_PRE_DELETE = 0x00000010, /// /// If specified on virtualization instance start:- Indicates that the provider should be notified when a file or folder is /// about to be renamed.If specified in response to a notification:- Indicates that the provider should be notified when a file /// or folder is about to be renamed. /// PRJ_NOTIFY_PRE_RENAME = 0x00000020, /// /// If specified on virtualization instance start:- Indicates that the provider should be notified when a hard link is about to /// be created for a file.If specified in response to a notification:- Indicates that the provider should be notified when a /// hard link is about to be created for a file. /// PRJ_NOTIFY_PRE_SET_HARDLINK = 0x00000040, /// /// If specified on virtualization instance start:- Indicates that the provider should be notified that a file or folder has /// been renamed.If specified in response to a notification:- Indicates that the provider should be notified when a file or /// folder has been renamed. /// PRJ_NOTIFY_FILE_RENAMED = 0x00000080, /// /// If specified on virtualization instance start:- Indicates that the provider should be notified that a hard link has been /// created for a file.If specified in response to a notification:- Indicates that the provider should be notified that a hard /// link has been created for the file. /// PRJ_NOTIFY_HARDLINK_CREATED = 0x00000100, /// /// If specified on virtualization instance start:- The provider should be notified when a handle is closed on a file/folder and /// the closing handle neither modified nor deleted it.If specified in response to a notification:- The provider should be /// notified when handles are closed for the file/folder and there were no modifications or deletions associated with the /// closing handle. /// PRJ_NOTIFY_FILE_HANDLE_CLOSED_NO_MODIFICATION = 0x00000200, /// /// If specified on virtualization instance start:- The provider should be notified when a handle is closed on a file/folder and /// the closing handle was used to modify it.If specified in response to a notification:- The provider should be notified when a /// handle is closed on the file/folder and the closing handle was used to modify it. /// PRJ_NOTIFY_FILE_HANDLE_CLOSED_FILE_MODIFIED = 0x00000400, /// /// If specified on virtualization instance start:- The provider should be notified when a handle is closed on a file/folder and /// it is deleted as part of closing the handle.If specified in response to a notification:- The provider should be notified /// when a handle is closed on the file/folder and it is deleted as part of closing the handle. /// PRJ_NOTIFY_FILE_HANDLE_CLOSED_FILE_DELETED = 0x00000800, /// /// If specified on virtualization instance start:- The provider should be notified when it is about to convert a placeholder to /// a full file.If specified in response to a notification:- The provider should be notified when it is about to convert the /// placeholder to a full file, assuming it is a placeholder and not already a full file. /// PRJ_NOTIFY_FILE_PRE_CONVERT_TO_FULL = 0x00001000, /// /// If specified on virtualization instance start:- This value is not valid on virtualization instance start.If specified in /// response to a notification:- Continue to use the existing set of notifications for this file/folder. /// PRJ_NOTIFY_USE_EXISTING_MASK = 0xFFFFFFFF, } /// Defines the length of a placeholder identifier. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_placeholder_id typedef enum // PRJ_PLACEHOLDER_ID { PRJ_PLACEHOLDER_ID_LENGTH } ; [PInvokeData("projectedfslib.h", MSDNShortId = "6E8574B4-C83D-4B0C-9B80-5ACD0BC45C1C")] public enum PRJ_PLACEHOLDER_ID { /// The length of a placeholder identifier. PRJ_PLACEHOLDER_ID_LENGTH = 128, } /// Flags to provide when starting a virtualization instance. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_startvirtualizing_flags typedef enum // PRJ_STARTVIRTUALIZING_FLAGS { PRJ_FLAG_NONE, PRJ_FLAG_USE_NEGATIVE_PATH_CACHE } ; [PInvokeData("projectedfslib.h", MSDNShortId = "AF67668B-E9BC-4320-AB1F-1E78CA700D8E")] [Flags] public enum PRJ_STARTVIRTUALIZING_FLAGS { /// No flags. PRJ_FLAG_NONE = 0x0, /// /// Specifies that ProjFS should maintain a "negative path cache" for the virtualization instance. If the negative path cache is /// active, then if the provider indicates that a file path does not exist by returning HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) /// from its PRJ_GET_PLACEHOLDER_INFO_CB callback, ProjFS will fail subsequent opens of that path without calling the /// PRJ_GET_PLACEHOLDER_INFO_CB callback again. To resume receiving the PRJ_GET_PLACEHOLDER_INFO_CB for paths the provider has /// indicated do not exist, the provider must call PrjClearNegativePathCache. /// PRJ_FLAG_USE_NEGATIVE_PATH_CACHE = 0x1, } /// Descriptions for the reason an update failed. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_update_failure_causes typedef enum // PRJ_UPDATE_FAILURE_CAUSES { PRJ_UPDATE_FAILURE_CAUSE_NONE, PRJ_UPDATE_FAILURE_CAUSE_DIRTY_METADATA, // PRJ_UPDATE_FAILURE_CAUSE_DIRTY_DATA, PRJ_UPDATE_FAILURE_CAUSE_TOMBSTONE, PRJ_UPDATE_FAILURE_CAUSE_READ_ONLY } ; [PInvokeData("projectedfslib.h", MSDNShortId = "8C3375C5-507C-4336-8F6A-DE509F3F20D2")] [Flags] public enum PRJ_UPDATE_FAILURE_CAUSES { /// The update did not fail. PRJ_UPDATE_FAILURE_CAUSE_NONE = 0x00, /// /// The item was a dirty placeholder (hydrated or not), and the provider did not specify PRJ_UPDATE_ALLOW_DIRTY_METADATA in PRJ_UPDATE_TYPES. /// PRJ_UPDATE_FAILURE_CAUSE_DIRTY_METADATA = 0x01, /// The item was a full file and the provider did not specify PRJ_UPDATE_ALLOW_DIRTY_DATA in PRJ_UPDATE_TYPES. PRJ_UPDATE_FAILURE_CAUSE_DIRTY_DATA = 0x02, /// The item was a tombstone and the provider did not specify PRJ_UPDATE_ALLOW_TOMBSTONE in PRJ_UPDATE_TYPES. PRJ_UPDATE_FAILURE_CAUSE_TOMBSTONE = 0x04, /// The item had the DOS read-only bit set and the provider did not specify PRJ_UPDATE_ALLOW_READ_ONLY in PRJ_UPDATE_TYPES. PRJ_UPDATE_FAILURE_CAUSE_READ_ONLY = 0x08, } /// Flags to specify whether updates will be allowed given the state of a file or directory on disk. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ne-projectedfslib-prj_update_types typedef enum // PRJ_UPDATE_TYPES { PRJ_UPDATE_NONE, PRJ_UPDATE_ALLOW_DIRTY_METADATA, PRJ_UPDATE_ALLOW_DIRTY_DATA, PRJ_UPDATE_ALLOW_TOMBSTONE, // PRJ_UPDATE_RESERVED1, PRJ_UPDATE_RESERVED2, PRJ_UPDATE_ALLOW_READ_ONLY, PRJ_UPDATE_MAX_VAL } ; [PInvokeData("projectedfslib.h", MSDNShortId = "E0E6F600-3B06-42D0-A87F-FAB4990562D0")] [Flags] public enum PRJ_UPDATE_TYPES { /// Allow update only if the item is a placeholder (whether hydrated or not). PRJ_UPDATE_NONE = 0x00000000, /// Allow update if the item is a placeholder or a dirty placeholder. PRJ_UPDATE_ALLOW_DIRTY_METADATA = 0x00000001, /// Allow update if the item is a placeholder or if it is a full file. PRJ_UPDATE_ALLOW_DIRTY_DATA = 0x00000002, /// Allow update if the item is a placeholder or if it is a tombstone. PRJ_UPDATE_ALLOW_TOMBSTONE = 0x00000004, /// Reserved for future use. PRJ_UPDATE_RESERVED1 = 0x00000008, /// Reserved for future use. PRJ_UPDATE_RESERVED2 = 0x00000010, /// Allow update regardless of whether the DOS read-only bit is set on the item. PRJ_UPDATE_ALLOW_READ_ONLY = 0x00000020, /// Maximum value. PRJ_UPDATE_MAX_VAL = (PRJ_UPDATE_ALLOW_READ_ONLY << 1), } /// Allocates a buffer that meets the memory alignment requirements of the virtualization instance's storage device. /// Opaque handle for the virtualization instance. /// The size of the buffer required, in bytes. /// Returns NULL if the buffer could not be allocated. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjallocatealignedbuffer void * // PrjAllocateAlignedBuffer( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, size_t size ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "49B723CC-976D-44C6-91D9-0FB26CFD45CA")] public static extern IntPtr PrjAllocateAlignedBuffer(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, SizeT size); /// Purges the virtualization instance's negative path cache, if it is active. /// Opaque handle for the virtualization instance. /// /// Optional pointer to a variable that receives the number of paths that were in the cache before it was purged. /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// If the negative path cache is active, then if the provider indicates that a file path does not exist by returning /// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) from its PRJ_GET_PLACEHOLDER_INFO_CB callback, ProjFS will fail subsequent opens of /// that path without calling the PRJ_GET_PLACEHOLDER_INFO_CB callback again. This helps improve performance of virtualization /// instances that host workloads that frequently probe for the presence of a file by trying to open it. /// /// /// To resume receiving the PRJ_GET_PLACEHOLDER_INFO_CB callback for paths the provider has indicated do not exist, the provider /// must call this routine. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjclearnegativepathcache HRESULT // PrjClearNegativePathCache( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, UINT32 *totalEntryNumber ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "90E37386-C647-476C-A53D-C479411DF8F9")] public static extern HRESULT PrjClearNegativePathCache(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, out uint totalEntryNumber); /// Indicates that the provider has completed processing a callback from which it had previously returned HRESULT_FROM_WIN32(ERROR_IO_PENDING). /// /// Opaque handle for the virtualization instance. This must be the value from the VirtualizationInstanceHandle member of the /// callbackData passed to the provider in the callback that is being complete. /// /// /// A value identifying the callback invocation that the provider is completing. This must be the value from the CommandId member of /// the callbackData passed to the provider in the callback that is being completed. /// /// The final HRESULT of the operation. /// Optional pointer to extended parameters required for completing certain callbacks. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjcompletecommand HRESULT // PrjCompleteCommand( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, INT32 commandId, HRESULT // completionResult, PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS *extendedParameters ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "9A47FAB5-A085-41C9-861C-E74F2F5AF474")] public static extern HRESULT PrjCompleteCommand(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, int commandId, HRESULT completionResult, in PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS extendedParameters); /// Indicates that the provider has completed processing a callback from which it had previously returned HRESULT_FROM_WIN32(ERROR_IO_PENDING). /// /// Opaque handle for the virtualization instance. This must be the value from the VirtualizationInstanceHandle member of the /// callbackData passed to the provider in the callback that is being complete. /// /// /// A value identifying the callback invocation that the provider is completing. This must be the value from the CommandId member of /// the callbackData passed to the provider in the callback that is being completed. /// /// The final HRESULT of the operation. /// Optional pointer to extended parameters required for completing certain callbacks. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjcompletecommand HRESULT // PrjCompleteCommand( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, INT32 commandId, HRESULT // completionResult, PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS *extendedParameters ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "9A47FAB5-A085-41C9-861C-E74F2F5AF474")] public static extern HRESULT PrjCompleteCommand(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, int commandId, HRESULT completionResult, [Optional] IntPtr extendedParameters); /// Enables a provider to delete an item that has been cached on the local file system. /// An opaque handle for the virtualization instance. /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the file or directory to be deleted. /// /// Flags to control the delete operation should be allowed given the state of the file. /// Optional pointer to receive a code describing the reason a delete failed. /// /// If an HRESULT_FROM_WIN32(ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION) error is returned, the update failed due to the /// item's state and the value of updateFlags. failureReason, if specified, will describe the reason for the failure. /// /// /// If the item is still in the provider's backing store, deleting it from the local file system changes it to a virtual item. /// This routine cannot be called on a virtual file/directory. /// /// If the file/directory to be deleted is in any state other than "placeholder", the provider must specify an appropriate /// combination of PRJ_UPDATE_TYPES values in the updateFlags parameter. This helps guard against accidental loss of data. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjdeletefile HRESULT PrjDeleteFile( // PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, PCWSTR destinationFileName, PRJ_UPDATE_TYPES updateFlags, // PRJ_UPDATE_FAILURE_CAUSES *failureReason ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "4F3529FC-5658-4768-AC72-29178C9595F0")] public static extern HRESULT PrjDeleteFile(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, PRJ_UPDATE_TYPES updateFlags, out PRJ_UPDATE_FAILURE_CAUSES failureReason); /// Determines whether a name contains wildcard characters. /// A null-terminated Unicode string to check for wildcard characters. /// True if fileName contains wildcards, False otherwise. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjdoesnamecontainwildcards BOOLEAN // PrjDoesNameContainWildCards( LPCWSTR fileName ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "AE1896D4-0DFB-477F-ADD8-C6C14DAD27CD")] [return: MarshalAs(UnmanagedType.U1)] public static extern bool PrjDoesNameContainWildCards([MarshalAs(UnmanagedType.LPWStr)] string fileName); /// Compares two file names and returns a value that indicates their relative collation order. /// A null-terminated Unicode string specifying the first name to compare. /// A null-terminated Unicode string specifying the second name to compare. /// /// /// /// <0 indicates fileName1 is before fileName2 in collation order /// /// /// 0 indicates fileName1 is equal to fileName2 /// /// /// >0 indicates fileName1 is after fileName2 in collation order /// /// /// /// The provider may use this routine to determine how to sort file names in the same order that the file system does. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfilenamecompare int PrjFileNameCompare( // PCWSTR fileName1, PCWSTR fileName2 ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "A20C2E31-918D-4AE8-9C54-D88BB5DC21E7")] public static extern int PrjFileNameCompare([MarshalAs(UnmanagedType.LPWStr)] string fileName1, [MarshalAs(UnmanagedType.LPWStr)] string fileName2); /// Determines whether a file name matches a search pattern. /// /// A null-terminated Unicode string of at most MAX_PATH characters specifying the file name to check against pattern. /// /// /// A null-terminated Unicode string of at most MAX_PATH characters specifying the pattern to compare against fileNameToCheck. /// /// True if fileNameToCheck matches pattern, False otherwise. /// /// The provider must use this routine when processing a PRJ_GET_DIRECTORY_ENUMERATION_CB callback to determine whether a name in /// its backing store matches the searchExpression passed to the callback. This routine performs pattern matching in the same way /// the file system does when it is processing a directory enumeration /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfilenamematch BOOLEAN PrjFileNameMatch( // PCWSTR fileNameToCheck, PCWSTR pattern ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "2BE57189-0F68-4CCD-8796-964EFDE0A02E")] [return: MarshalAs(UnmanagedType.U1)] public static extern bool PrjFileNameMatch([MarshalAs(UnmanagedType.LPWStr)] string fileNameToCheck, [MarshalAs(UnmanagedType.LPWStr)] string pattern); /// Provides information for one file or directory to an enumeration. /// A pointer to a null-terminated string that contains the name of the entry /// Basic information about the entry to be filled. /// An opaque handle to a structure that receives information about the filled entries. /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) indicates that dirEntryBufferHandle doesn't have enough space for the new entry. /// /// /// /// The provider uses this routine to service a PRJ_GET_DIRECTORY_ENUMERATION_CB callback. When processing the callback, the /// provider calls this routine for each matching file or directory in the enumeration. /// /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) when adding an entry to the enumeration, the provider /// returns S_OK from the callback and waits for the next PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// The provider resumes filling the enumeration with the entry it was trying to add when it got HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER). /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) for the first file or directory in the enumeration, the /// provider must return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) from its PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfilldirentrybuffer HRESULT // PrjFillDirEntryBuffer( PCWSTR fileName, PRJ_FILE_BASIC_INFO *fileBasicInfo, PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "CBCB0A0E-9227-42EF-B747-62783400AD16")] public static extern HRESULT PrjFillDirEntryBuffer([MarshalAs(UnmanagedType.LPWStr)] string fileName, in PRJ_FILE_BASIC_INFO fileBasicInfo, PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle); /// Provides information for one file or directory to an enumeration. /// A pointer to a null-terminated string that contains the name of the entry /// Basic information about the entry to be filled. /// An opaque handle to a structure that receives information about the filled entries. /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) indicates that dirEntryBufferHandle doesn't have enough space for the new entry. /// /// /// /// The provider uses this routine to service a PRJ_GET_DIRECTORY_ENUMERATION_CB callback. When processing the callback, the /// provider calls this routine for each matching file or directory in the enumeration. /// /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) when adding an entry to the enumeration, the provider /// returns S_OK from the callback and waits for the next PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// The provider resumes filling the enumeration with the entry it was trying to add when it got HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER). /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) for the first file or directory in the enumeration, the /// provider must return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) from its PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfilldirentrybuffer HRESULT // PrjFillDirEntryBuffer( PCWSTR fileName, PRJ_FILE_BASIC_INFO *fileBasicInfo, PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "CBCB0A0E-9227-42EF-B747-62783400AD16")] public static extern HRESULT PrjFillDirEntryBuffer([MarshalAs(UnmanagedType.LPWStr)] string fileName, [Optional] IntPtr fileBasicInfo, PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle); /// Provides information for one file or directory to an enumeration and allows the caller to specify extended information. /// An opaque handle to a structure that receives information about the filled entries. /// A pointer to a null-terminated string that contains the name of the entry /// Basic information about the entry to be filled. /// A pointer to a PRJ_EXTENDED_INFO struct specifying extended information about the entry to be filled. /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) indicates that dirEntryBufferHandle doesn't have enough space for the new entry. /// /// E_INVALIDARG indicates that extendedInfo.InfoType is unrecognized. /// /// /// /// The provider uses this routine to service a PRJ_GET_DIRECTORY_ENUMERATION_CB callback. When processing the callback, the /// provider calls this routine for each matching file or directory in the enumeration. This routine allows the provider to specify /// extended information about the file or directory, such as whether it is a symbolic link. /// /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) when adding an entry to the enumeration, the provider /// returns S_OK from the callback and waits for the next PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// The provider resumes filling the enumeration with the entry it was trying to add when it got HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER). /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) for the first file or directory in the enumeration, the /// provider must return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) from its PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// Symbolic Links /// /// To specify that this directory entry is for a symbolic link, the provider formats a buffer with a single PRJ_EXTENDED_INFO /// struct and passes a pointer to it in the parameter. The provider sets the struct's fields as follows: /// /// /// /// extendedInfo.InfoType = PRJ_EXT_INFO_TYPE_SYMLINK /// /// /// extendedInfo.NextInfoOffset = 0 /// /// /// extendedInfo.Symlink.TargetName = <path to the target of the symbolic link> /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfilldirentrybuffer2 HRESULT // PrjFillDirEntryBuffer2( PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle, PCWSTR fileName, PRJ_FILE_BASIC_INFO *fileBasicInfo, // PRJ_EXTENDED_INFO *extendedInfo ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "NF:projectedfslib.PrjFillDirEntryBuffer2")] public static extern HRESULT PrjFillDirEntryBuffer2(PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle, [MarshalAs(UnmanagedType.LPWStr)] string fileName, in PRJ_FILE_BASIC_INFO fileBasicInfo, in PRJ_EXTENDED_INFO extendedInfo); /// Provides information for one file or directory to an enumeration and allows the caller to specify extended information. /// An opaque handle to a structure that receives information about the filled entries. /// A pointer to a null-terminated string that contains the name of the entry /// Basic information about the entry to be filled. /// A pointer to a PRJ_EXTENDED_INFO struct specifying extended information about the entry to be filled. /// /// /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) indicates that dirEntryBufferHandle doesn't have enough space for the new entry. /// /// E_INVALIDARG indicates that extendedInfo.InfoType is unrecognized. /// /// /// /// The provider uses this routine to service a PRJ_GET_DIRECTORY_ENUMERATION_CB callback. When processing the callback, the /// provider calls this routine for each matching file or directory in the enumeration. This routine allows the provider to specify /// extended information about the file or directory, such as whether it is a symbolic link. /// /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) when adding an entry to the enumeration, the provider /// returns S_OK from the callback and waits for the next PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// The provider resumes filling the enumeration with the entry it was trying to add when it got HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER). /// /// If this routine returns HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) for the first file or directory in the enumeration, the /// provider must return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) from its PRJ_GET_DIRECTORY_ENUMERATION_CB callback. /// /// Symbolic Links /// /// To specify that this directory entry is for a symbolic link, the provider formats a buffer with a single PRJ_EXTENDED_INFO /// struct and passes a pointer to it in the parameter. The provider sets the struct's fields as follows: /// /// /// /// extendedInfo.InfoType = PRJ_EXT_INFO_TYPE_SYMLINK /// /// /// extendedInfo.NextInfoOffset = 0 /// /// /// extendedInfo.Symlink.TargetName = <path to the target of the symbolic link> /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfilldirentrybuffer2 HRESULT // PrjFillDirEntryBuffer2( PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle, PCWSTR fileName, PRJ_FILE_BASIC_INFO *fileBasicInfo, // PRJ_EXTENDED_INFO *extendedInfo ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "NF:projectedfslib.PrjFillDirEntryBuffer2")] public static extern HRESULT PrjFillDirEntryBuffer2(PRJ_DIR_ENTRY_BUFFER_HANDLE dirEntryBufferHandle, [MarshalAs(UnmanagedType.LPWStr)] string fileName, [In, Optional] IntPtr fileBasicInfo, [In, Optional] IntPtr extendedInfo); /// Frees an allocated buffer. /// The buffer to free. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjfreealignedbuffer void // PrjFreeAlignedBuffer( void *buffer ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "EE5AC099-CB39-48B1-BB7B-8C9B436AA4A3")] public static extern void PrjFreeAlignedBuffer(IntPtr buffer); /// Gets the on-disk file state for a file or directory. /// /// A null-terminated Unicode string specifying the full path to the file whose state is to be queried. /// /// This is a combination of one or more PRJ_FILE_STATE values describing the file state. /// /// HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) indicates destinationFileName does not exist. HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) /// indicates that an intermediate component of the path to destinationFileName does not exist. /// /// /// /// This routine tells the caller what the ProjFS caching state is of the specified file or directory. For example, the caller can /// use this routine to determine whether the given item is a placeholder or full file. /// /// /// A running provider should be cautious if using this routine on files or directories within one of its virtualization instances, /// as it may cause callbacks to be invoked in the provider. Depending on the design of the provider this may lead to deadlocks. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjgetondiskfilestate HRESULT // PrjGetOnDiskFileState( PCWSTR destinationFileName, PRJ_FILE_STATE *fileState ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "E302C472-1360-43D9-8AB9-26C93F97F00F")] public static extern HRESULT PrjGetOnDiskFileState([MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, out PRJ_FILE_STATE fileState); /// Retrieves information about the virtualization instance. /// An opaque handle for the virtualization instance. /// /// On input points to a buffer to fill with information about the virtualization instance. On successful return the buffer is /// filled in. /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// ProjFS callback routines provide the virtualization instance handle in their callbackData parameters. A provider that manages /// multiple virtualization instances can use the InstanceID field of virtualizationInstanceInfo to identify which of its /// virtualization instances is receiving the callback. /// /// /// The provider can use the WriteAlignment member of virtualizationInstanceInfo to determine the correct values to use for the /// byteOffset and length parameters of PrjWriteFileData. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjgetvirtualizationinstanceinfo HRESULT // PrjGetVirtualizationInstanceInfo( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, // PRJ_VIRTUALIZATION_INSTANCE_INFO *virtualizationInstanceInfo ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "0C04D13F-862C-4E4C-9BC1-13E6FAC86E99")] public static extern HRESULT PrjGetVirtualizationInstanceInfo(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, out PRJ_VIRTUALIZATION_INSTANCE_INFO virtualizationInstanceInfo); /// Converts an existing directory to a directory placeholder. /// A null-terminated Unicode string specifying the full path to the virtualization root. /// /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the directory to convert to a placeholder. /// /// /// If this parameter is not specified or is an empty string, then this means the caller wants to designate rootPathName as the /// virtualization root. The provider only needs to do this one time, upon establishing a new virtualization instance. /// /// /// /// Optional version information for the target placeholder. The provider chooses what information to put in the /// PRJ_PLACEHOLDER_VERSION_INFO structure. If not specified, the placeholder gets zeros for its version information. /// /// A value that identifies the virtualization instance. /// /// HRESULT_FROM_WIN32(ERROR_REPARSE_POINT_ENCOUNTERED) typically means the directory at targetPathName has a reparse point on it. /// HRESULT_FROM_WIN32(ERROR_DIRECTORY) typically means the targetPathName does not specify a directory. /// /// The provider must use this API to designate the virtualization root before calling PrjStartVirtualizing. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjmarkdirectoryasplaceholder HRESULT // PrjMarkDirectoryAsPlaceholder( PCWSTR rootPathName, PCWSTR targetPathName, const PRJ_PLACEHOLDER_VERSION_INFO *versionInfo, const // GUID *virtualizationInstanceID ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "6C92275E-B9A6-4556-A709-8EFBAEDB94B5")] public static extern HRESULT PrjMarkDirectoryAsPlaceholder([MarshalAs(UnmanagedType.LPWStr)] string rootPathName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string targetPathName, in PRJ_PLACEHOLDER_VERSION_INFO versionInfo, in Guid virtualizationInstanceID); /// Converts an existing directory to a directory placeholder. /// A null-terminated Unicode string specifying the full path to the virtualization root. /// /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the directory to convert to a placeholder. /// /// /// If this parameter is not specified or is an empty string, then this means the caller wants to designate rootPathName as the /// virtualization root. The provider only needs to do this one time, upon establishing a new virtualization instance. /// /// /// /// Optional version information for the target placeholder. The provider chooses what information to put in the /// PRJ_PLACEHOLDER_VERSION_INFO structure. If not specified, the placeholder gets zeros for its version information. /// /// A value that identifies the virtualization instance. /// /// HRESULT_FROM_WIN32(ERROR_REPARSE_POINT_ENCOUNTERED) typically means the directory at targetPathName has a reparse point on it. /// HRESULT_FROM_WIN32(ERROR_DIRECTORY) typically means the targetPathName does not specify a directory. /// /// The provider must use this API to designate the virtualization root before calling PrjStartVirtualizing. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjmarkdirectoryasplaceholder HRESULT // PrjMarkDirectoryAsPlaceholder( PCWSTR rootPathName, PCWSTR targetPathName, const PRJ_PLACEHOLDER_VERSION_INFO *versionInfo, const // GUID *virtualizationInstanceID ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "6C92275E-B9A6-4556-A709-8EFBAEDB94B5")] public static extern HRESULT PrjMarkDirectoryAsPlaceholder([MarshalAs(UnmanagedType.LPWStr)] string rootPathName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string targetPathName, [Optional] IntPtr versionInfo, in Guid virtualizationInstanceID); /// /// Configures a ProjFS virtualization instance and starts it, making it available to service I/O and invoke callbacks on the provider. /// /// /// Pointer to a null-terminated unicode string specifying the full path to the virtualization root directory. /// /// The provider must have called PrjMarkDirectoryAsPlaceholder passing the specified path as the rootPathName parameter and NULL as /// the targetPathName parameter before calling this routine. This only needs to be done once to designate the path as the /// virtualization root directory /// /// /// /// Pointer to a PRJ_CALLBACKS structure that has been initialized with PrjCommandCallbacksInit and filled in with pointers to the /// provider's callback functions. /// /// /// Pointer to context information defined by the provider for each instance. This parameter is optional and can be NULL. If it is /// specified, ProjFS will return it in the InstanceContext member of PRJ_CALLBACK_DATA when invoking provider callback routines. /// /// An optional pointer to a PRJ_STARTVIRTUALIZING_OPTIONS. /// /// On success returns an opaque handle to the ProjFS virtualization instance. The provider passes this value when calling functions /// that require a PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT as input. /// /// /// The error, HRESULT_FROM_WIN32(ERROR_REPARSE_TAG_MISMATCH), indicates that virtualizationRootPath has not been configured as a /// virtualization root. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjstartvirtualizing HRESULT // PrjStartVirtualizing( PCWSTR virtualizationRootPath, const PRJ_CALLBACKS *callbacks, const void *instanceContext, const // PRJ_STARTVIRTUALIZING_OPTIONS *options, PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT *namespaceVirtualizationContext ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "466347B7-1D7D-4C7D-B17C-1E5E1A2223C1")] public static extern HRESULT PrjStartVirtualizing([MarshalAs(UnmanagedType.LPWStr)] string virtualizationRootPath, in PRJ_CALLBACKS callbacks, [In, Optional] IntPtr instanceContext, in PRJ_STARTVIRTUALIZING_OPTIONS options, out PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext); /// /// Configures a ProjFS virtualization instance and starts it, making it available to service I/O and invoke callbacks on the provider. /// /// /// Pointer to a null-terminated unicode string specifying the full path to the virtualization root directory. /// /// The provider must have called PrjMarkDirectoryAsPlaceholder passing the specified path as the rootPathName parameter and NULL as /// the targetPathName parameter before calling this routine. This only needs to be done once to designate the path as the /// virtualization root directory /// /// /// /// Pointer to a PRJ_CALLBACKS structure that has been initialized with PrjCommandCallbacksInit and filled in with pointers to the /// provider's callback functions. /// /// /// Pointer to context information defined by the provider for each instance. This parameter is optional and can be NULL. If it is /// specified, ProjFS will return it in the InstanceContext member of PRJ_CALLBACK_DATA when invoking provider callback routines. /// /// An optional pointer to a PRJ_STARTVIRTUALIZING_OPTIONS. /// /// On success returns an opaque handle to the ProjFS virtualization instance. The provider passes this value when calling functions /// that require a PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT as input. /// /// /// The error, HRESULT_FROM_WIN32(ERROR_REPARSE_TAG_MISMATCH), indicates that virtualizationRootPath has not been configured as a /// virtualization root. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjstartvirtualizing HRESULT // PrjStartVirtualizing( PCWSTR virtualizationRootPath, const PRJ_CALLBACKS *callbacks, const void *instanceContext, const // PRJ_STARTVIRTUALIZING_OPTIONS *options, PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT *namespaceVirtualizationContext ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "466347B7-1D7D-4C7D-B17C-1E5E1A2223C1")] public static extern HRESULT PrjStartVirtualizing([MarshalAs(UnmanagedType.LPWStr)] string virtualizationRootPath, in PRJ_CALLBACKS callbacks, [In, Optional] IntPtr instanceContext, [Optional] IntPtr options, out PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext); /// /// Stops a running ProjFS virtualization instance, making it unavailable to service I/O or involve callbacks on the provider. /// /// An opaque handle for the virtualization instance. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjstopvirtualizing void PrjStopVirtualizing( // PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "D01BF7C5-1EAC-446A-BCE5-A6EF46A5443D")] public static extern void PrjStopVirtualizing(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext); /// Enables a provider to update an item that has been cached on the local file system. /// Opague handle for the virtualization instance. /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the file or directory to be updated. /// /// /// A pointer to a PRJ_PLACEHOLDER_INFO buffer containing the updated metadata for the file or directory. /// /// If placeholderInfo->VersionInfo.ContentID contains a content identifier that is the same as the content identifier already on /// the file/directory, the call succeeds and no update takes place. Otherwise, if the call succeeds then /// placeholderInfo->VersionInfo.ContentID replaces the existing content identifier on the file. /// /// /// The size in bytes of the buffer pointed to by placeholderInfo. /// /// Flags to control updates. /// /// If the item is a dirty placeholder, full file, or tombstone, and the provider does not specify the appropriate flag(s), this /// routine will fail to update the placeholder /// /// /// Optional pointer to receive a code describing the reason an update failed. /// /// If an HRESULT_FROM_WIN32(ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION) error is returned, the update failed due to the /// item's state and the value of updateFlags. failureReason, if specified, will describe the reason for the failure. /// /// /// /// The provider uses this routine to update an item in the local file system if the item's information has changed in the /// provider’s backing store and the updates should be reflected in the items cached in the local file system. /// /// /// This routine cannot be called on a virtual file/directory. If the file/directory to be updated is in any state other than /// "placeholder", the provider must specify an appropriate combination of PRJ_UPDATE_TYPES values in the updateFlags parameter. /// This helps guard against accidental loss of data, since upon successful return from this routine the item becomes a placeholder /// with the updated metadata; any metadata that had been changed since the placeholder was created, or any file data it contained /// is discarded. /// /// /// The provider uses the local file system as a cache of the items that it manages. An item (file or directory) can be in one of /// six states on the local file system. /// /// /// Virtual - The item does not exist locally on disk. It is projected, i.e. synthesized, during enumerations of its parent /// directory. Virtual items are merged with any items that may exist on disk to present the full contents of the parent directory. /// /// /// Placeholder - For files: The file's content (primary data stream) is not present on the disk. The file’s metadata (name, size, /// timestamps, attributes, etc.) is cached on the disk. For directories: Some or all of the directory’s immediate descendants (the /// files and directories in the directory) are not present on the disk, i.e. they are still virtual. The directory’s metadata /// (name, timestamps, attributes, etc.) is cached on the disk. /// /// /// Hydrated placeholder - For files: The file’s content and metadata have been cached to the disk. Also referred to as a "partial /// file". For directories: Directories are never hydrated placeholders. A directory that was created on disk as a placeholder never /// becomes a hydrated placeholder directory. This allows the provider to add or remove items from the directory in its backing /// store and have those changes be reflected in the local cache. /// /// /// Dirty placeholder (hydrated or not) - The item's metadata has been locally modified and is no longer a cache of its state in the /// provider's store. Note that creating or deleting a file or directory under a placeholder directory causes that placeholder /// directory to become dirty. /// /// /// Full file/directory - For files: The file's content (primary data stream) has been modified. The file is no longer a cache of /// its state in the provider's store. Files that have been created on the local file system (i.e. that do not exist in the /// provider's store at all) are also considered to be full files. For directories: Directories that have been created on the local /// file system (i.e. that do not exist in the provider's store at all) are considered to be full directories. A directory that was /// created on disk as a placeholder never becomes a full directory. /// /// /// Tombstone - A special hidden placeholder that represents an item that has been deleted from the local file system. When a /// directory is enumerated ProjFS merges the set of local items (placeholders, full files, etc.) with the set of virtual projected /// items. If an item appears in both the local and projected sets, the local item takes precedence. If a file does not exist, there /// is no local state, so it would appear in the enumeration. However if that item had been deleted, having it appear in the /// enumeration would be unexpected. Replacing a deleted item with a tombstone result in the following effects: /// /// /// /// Enumerations to not reveal the item /// /// /// File opens that expect the item to exist fail with e.g. "file not found". /// /// /// /// File creates that expect to succeed only if the item does not exist succeed; ProjFS removes the tombstone as part of the operation. /// /// /// /// /// To illustrate the above states, consider the following sequence, given a ProjFS provider that has a single file "foo.txt" /// located in the virtualization root C:\root. /// /// /// /// /// An app enumerates C:\root. It sees the virtual file "foo.txt". Since the file has not yet been accessed, the file does not exist /// on disk. /// /// /// /// The app opens a handle to C:\root\foo.txt. ProjFS tells the provider to create a placeholder for it. /// /// /// /// The app reads the content of the file. The provider provides the file content to ProjFS and it is cached to C:\root\foo.txt. The /// file is now a hydrated placeholder. /// /// /// /// The app updates the Last Modified timestamp. The file is now a dirty hydrated placeholder. /// /// /// The app opens a handle for write access to the file. C:\root\foo.txt is now a full file. /// /// /// /// The app deletes C:\root\foo.txt. ProjFS replaces the file with a tombstone. Now when the app enumerates C:\root it does not see /// foo.txt. If it tries to open the file, the open fails with ERROR_FILE_NOT_FOUND. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjupdatefileifneeded HRESULT // PrjUpdateFileIfNeeded( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, PCWSTR destinationFileName, const // PRJ_PLACEHOLDER_INFO *placeholderInfo, UINT32 placeholderInfoSize, PRJ_UPDATE_TYPES updateFlags, PRJ_UPDATE_FAILURE_CAUSES // *failureReason ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "182C9C5E-ABBC-4A7C-99E4-D019B7E237CE")] public static extern HRESULT PrjUpdateFileIfNeeded(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, in PRJ_PLACEHOLDER_INFO placeholderInfo, uint placeholderInfoSize, [Optional] PRJ_UPDATE_TYPES updateFlags, out PRJ_UPDATE_FAILURE_CAUSES failureReason); /// Enables a provider to update an item that has been cached on the local file system. /// Opague handle for the virtualization instance. /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the file or directory to be updated. /// /// /// A pointer to a PRJ_PLACEHOLDER_INFO buffer containing the updated metadata for the file or directory. /// /// If placeholderInfo->VersionInfo.ContentID contains a content identifier that is the same as the content identifier already on /// the file/directory, the call succeeds and no update takes place. Otherwise, if the call succeeds then /// placeholderInfo->VersionInfo.ContentID replaces the existing content identifier on the file. /// /// /// The size in bytes of the buffer pointed to by placeholderInfo. /// /// Flags to control updates. /// /// If the item is a dirty placeholder, full file, or tombstone, and the provider does not specify the appropriate flag(s), this /// routine will fail to update the placeholder /// /// /// Optional pointer to receive a code describing the reason an update failed. /// /// If an HRESULT_FROM_WIN32(ERROR_FILE_SYSTEM_VIRTUALIZATION_INVALID_OPERATION) error is returned, the update failed due to the /// item's state and the value of updateFlags. failureReason, if specified, will describe the reason for the failure. /// /// /// /// The provider uses this routine to update an item in the local file system if the item's information has changed in the /// provider’s backing store and the updates should be reflected in the items cached in the local file system. /// /// /// This routine cannot be called on a virtual file/directory. If the file/directory to be updated is in any state other than /// "placeholder", the provider must specify an appropriate combination of PRJ_UPDATE_TYPES values in the updateFlags parameter. /// This helps guard against accidental loss of data, since upon successful return from this routine the item becomes a placeholder /// with the updated metadata; any metadata that had been changed since the placeholder was created, or any file data it contained /// is discarded. /// /// /// The provider uses the local file system as a cache of the items that it manages. An item (file or directory) can be in one of /// six states on the local file system. /// /// /// Virtual - The item does not exist locally on disk. It is projected, i.e. synthesized, during enumerations of its parent /// directory. Virtual items are merged with any items that may exist on disk to present the full contents of the parent directory. /// /// /// Placeholder - For files: The file's content (primary data stream) is not present on the disk. The file’s metadata (name, size, /// timestamps, attributes, etc.) is cached on the disk. For directories: Some or all of the directory’s immediate descendants (the /// files and directories in the directory) are not present on the disk, i.e. they are still virtual. The directory’s metadata /// (name, timestamps, attributes, etc.) is cached on the disk. /// /// /// Hydrated placeholder - For files: The file’s content and metadata have been cached to the disk. Also referred to as a "partial /// file". For directories: Directories are never hydrated placeholders. A directory that was created on disk as a placeholder never /// becomes a hydrated placeholder directory. This allows the provider to add or remove items from the directory in its backing /// store and have those changes be reflected in the local cache. /// /// /// Dirty placeholder (hydrated or not) - The item's metadata has been locally modified and is no longer a cache of its state in the /// provider's store. Note that creating or deleting a file or directory under a placeholder directory causes that placeholder /// directory to become dirty. /// /// /// Full file/directory - For files: The file's content (primary data stream) has been modified. The file is no longer a cache of /// its state in the provider's store. Files that have been created on the local file system (i.e. that do not exist in the /// provider's store at all) are also considered to be full files. For directories: Directories that have been created on the local /// file system (i.e. that do not exist in the provider's store at all) are considered to be full directories. A directory that was /// created on disk as a placeholder never becomes a full directory. /// /// /// Tombstone - A special hidden placeholder that represents an item that has been deleted from the local file system. When a /// directory is enumerated ProjFS merges the set of local items (placeholders, full files, etc.) with the set of virtual projected /// items. If an item appears in both the local and projected sets, the local item takes precedence. If a file does not exist, there /// is no local state, so it would appear in the enumeration. However if that item had been deleted, having it appear in the /// enumeration would be unexpected. Replacing a deleted item with a tombstone result in the following effects: /// /// /// /// Enumerations to not reveal the item /// /// /// File opens that expect the item to exist fail with e.g. "file not found". /// /// /// /// File creates that expect to succeed only if the item does not exist succeed; ProjFS removes the tombstone as part of the operation. /// /// /// /// /// To illustrate the above states, consider the following sequence, given a ProjFS provider that has a single file "foo.txt" /// located in the virtualization root C:\root. /// /// /// /// /// An app enumerates C:\root. It sees the virtual file "foo.txt". Since the file has not yet been accessed, the file does not exist /// on disk. /// /// /// /// The app opens a handle to C:\root\foo.txt. ProjFS tells the provider to create a placeholder for it. /// /// /// /// The app reads the content of the file. The provider provides the file content to ProjFS and it is cached to C:\root\foo.txt. The /// file is now a hydrated placeholder. /// /// /// /// The app updates the Last Modified timestamp. The file is now a dirty hydrated placeholder. /// /// /// The app opens a handle for write access to the file. C:\root\foo.txt is now a full file. /// /// /// /// The app deletes C:\root\foo.txt. ProjFS replaces the file with a tombstone. Now when the app enumerates C:\root it does not see /// foo.txt. If it tries to open the file, the open fails with ERROR_FILE_NOT_FOUND. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjupdatefileifneeded HRESULT // PrjUpdateFileIfNeeded( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, PCWSTR destinationFileName, const // PRJ_PLACEHOLDER_INFO *placeholderInfo, UINT32 placeholderInfoSize, PRJ_UPDATE_TYPES updateFlags, PRJ_UPDATE_FAILURE_CAUSES // *failureReason ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "182C9C5E-ABBC-4A7C-99E4-D019B7E237CE")] public static extern HRESULT PrjUpdateFileIfNeeded(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, [In] IntPtr placeholderInfo, uint placeholderInfoSize, [Optional] PRJ_UPDATE_TYPES updateFlags, out PRJ_UPDATE_FAILURE_CAUSES failureReason); /// TBD /// /// Opaque handle for the virtualization instance. /// /// If the provider is servicing a PRJ_GET_FILE_DATA_CB callback, this must be the value from the VirtualizationInstanceHandle /// member of the callbackData passed to the provider in the callback. /// /// /// /// Identifier for the data stream to write to. /// /// If the provider is servicing a PRJ_GET_FILE_DATA_CB callback, this must be the value from the DataStreamId member of the /// callbackData passed to the provider in the callback. /// /// /// /// Pointer to a buffer containing the data to write. The buffer must be at least as large as the value of the length parameter in /// bytes. The provider should use PrjAllocateAlignedBuffer to ensure that the buffer meets the storage device’s alignment requirements. /// /// Byte offset from the beginning of the file at which to write the data. /// The number of bytes to write to the file. /// /// HRESULT_FROM_WIN32(ERROR_OFFSET_ALIGNMENT_VIOLATION) indicates that the user's handle was opened for unbuffered I/O and /// byteOffset is not aligned to the sector size of the storage device. /// /// /// The provider uses this routine to provide the data requested in an invocation of its PRJ_GET_FILE_DATA_CB callback. /// /// The provider’s PRJ_GET_FILE_DATA_CB callback is invoked when the system needs to ensure that a file contains data. When the /// provider calls PrjWriteFileData to supply the requested data the system uses the user’s FILE_OBJECT to write that data to the /// file. However the system cannot control whether that FILE_OBJECT was opened for buffered or unbuffered I/O. If the FILE_OBJECT /// was opened for unbuffered I/O, reads and writes to the file must adhere to certain alignment requirements. The provider can meet /// those alignment requirements by doing two things: /// /// /// /// Use PrjAllocateAlignedBuffer to allocate the buffer to pass to buffer. /// /// /// /// Ensure that byteOffset and length are integer multiples of the storage device’s alignment requirement (length does not have to /// meet this requirement if byteOffset + length is equal to the end of the file). The provider can use /// PrjGetVirtualizationInstanceInfo to retrieve the storage device’s alignment requirement. /// /// /// /// /// The system leaves it up to the provider to calculate proper alignment because when processing a PRJ_GET_FILE_DATA_CB callback /// the provider may opt to return the requested data across multiple PrjWriteFileData calls, each returning part of the total /// requested data. /// /// /// Note that if the provider is going to write the entire file in a single call to PrjWriteFileData, i.e. from byteOffset = 0 to /// length = size of the file, the provider does not have to do any alignment calculations. However it must still use /// PrjAllocateAlignedBuffer to ensure that buffer meets the storage device’s alignment requirements. See the File Buffering topic /// for more information on buffered vs unbuffered I/O. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjwritefiledata HRESULT PrjWriteFileData( // PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, const GUID *dataStreamId, void *buffer, UINT64 byteOffset, // UINT32 length ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "A09D8E74-D574-41C6-A586-86E03839DA89")] public static extern HRESULT PrjWriteFileData(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, in Guid dataStreamId, [In] IntPtr buffer, ulong byteOffset, uint length); /// Sends file or directory metadata to ProjFS. /// /// Opaque handle for the virtualization instance. This must be the value from the VirtualizationInstanceHandle member of the /// callbackData passed to the provider in the PRJ_GET_PLACEHOLDER_INFO_CB callback. /// /// /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the file or directory for which to /// create a placeholder. /// /// /// This must be a match to the FilePathName member of the callbackData parameter passed to the provider in the /// PRJ_GET_PLACEHOLDER_INFO_CB callback. The provider should use the PrjFileNameCompare function to determine whether the two names match. /// /// /// For example, if the PRJ_GET_PLACEHOLDER_INFO_CB callback specifies “dir1\dir1\FILE.TXT” in callbackData->FilePathName, and /// the provider’s backing store contains a file called “File.txt” in the dir1\dir2 directory, and PrjFileNameCompare returns 0 when /// comparing the names “FILE.TXT” and “File.txt”, then the provider specifies “dir1\dir2\File.txt” as the value of this parameter. /// /// /// A pointer to the metadata for the file or directory. /// Size in bytes of the buffer pointed to by placeholderInfo. /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// The provider uses this routine to provide the data requested in an invocation of its PRJ_GET_PLACEHOLDER_INFO_CB callback, or it /// may use it to proactively lay down a placeholder. /// /// /// The EaInformation, SecurityInformation, and StreamsInformation members of PRJ_PLACEHOLDER_INFO are optional. If the provider /// does not wish to provide extended attributes, custom security descriptors, or alternate data streams, it must set these fields /// to 0. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjwriteplaceholderinfo HRESULT // PrjWritePlaceholderInfo( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, PCWSTR destinationFileName, const // PRJ_PLACEHOLDER_INFO *placeholderInfo, UINT32 placeholderInfoSize ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "EAEA2D05-2FCF-46A7-AEBD-9CF085D868E1")] public static extern HRESULT PrjWritePlaceholderInfo(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, in PRJ_PLACEHOLDER_INFO placeholderInfo, uint placeholderInfoSize); /// Sends file or directory metadata to ProjFS and allows the caller to specify extended information. /// /// Opaque handle for the virtualization instance. This must be the value from the VirtualizationInstanceHandle member of the /// callbackData passed to the provider in the PRJ_GET_PLACEHOLDER_INFO_CB callback. /// /// /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the file or directory for which to /// create a placeholder. /// /// /// This must be a match to the FilePathName member of the callbackData parameter passed to the provider in the /// PRJ_GET_PLACEHOLDER_INFO_CB callback. The provider should use the PrjFileNameCompare function to determine whether the two names match. /// /// /// For example, if the PRJ_GET_PLACEHOLDER_INFO_CB callback specifies “dir1\dir1\FILE.TXT” in callbackData->FilePathName, and /// the provider’s backing store contains a file called “File.txt” in the dir1\dir2 directory, and PrjFileNameCompare returns 0 when /// comparing the names “FILE.TXT” and “File.txt”, then the provider specifies “dir1\dir2\File.txt” as the value of this parameter. /// /// /// A pointer to the metadata for the file or directory. Type: . /// Size in bytes of the buffer pointed to by placeholderInfo. /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// The provider uses this routine to provide the data requested in an invocation of its PRJ_GET_PLACEHOLDER_INFO_CB callback, or it /// may use it to proactively lay down a placeholder. /// /// /// The EaInformation, SecurityInformation, and StreamsInformation members of PRJ_PLACEHOLDER_INFO are optional. If the provider /// does not wish to provide extended attributes, custom security descriptors, or alternate data streams, it must set these fields /// to 0. /// /// Symbolic Links /// /// To specify that this placeholder is to be a symbolic link, the provider formats a buffer with a single PRJ_EXTENDED_INFO struct /// and passes a pointer to it in the parameter. The provider sets the struct's fields as follows: /// /// /// /// extendedInfo.InfoType = PRJ_EXT_INFO_TYPE_SYMLINK /// /// /// extendedInfo.NextInfoOffset = 0 /// /// /// extendedInfo.Symlink.TargetName = <path to the target of the symbolic link> /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjwriteplaceholderinfo2 HRESULT // PrjWritePlaceholderInfo2( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, PCWSTR destinationFileName, const // PRJ_PLACEHOLDER_INFO *placeholderInfo, UINT32 placeholderInfoSize, const PRJ_EXTENDED_INFO *ExtendedInfo ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "NF:projectedfslib.PrjWritePlaceholderInfo2")] public static extern HRESULT PrjWritePlaceholderInfo2(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, IntPtr placeholderInfo, uint placeholderInfoSize, in PRJ_EXTENDED_INFO ExtendedInfo); /// Sends file or directory metadata to ProjFS and allows the caller to specify extended information. /// /// Opaque handle for the virtualization instance. This must be the value from the VirtualizationInstanceHandle member of the /// callbackData passed to the provider in the PRJ_GET_PLACEHOLDER_INFO_CB callback. /// /// /// /// A null-terminated Unicode string specifying the path, relative to the virtualization root, to the file or directory for which to /// create a placeholder. /// /// /// This must be a match to the FilePathName member of the callbackData parameter passed to the provider in the /// PRJ_GET_PLACEHOLDER_INFO_CB callback. The provider should use the PrjFileNameCompare function to determine whether the two names match. /// /// /// For example, if the PRJ_GET_PLACEHOLDER_INFO_CB callback specifies “dir1\dir1\FILE.TXT” in callbackData->FilePathName, and /// the provider’s backing store contains a file called “File.txt” in the dir1\dir2 directory, and PrjFileNameCompare returns 0 when /// comparing the names “FILE.TXT” and “File.txt”, then the provider specifies “dir1\dir2\File.txt” as the value of this parameter. /// /// /// A pointer to the metadata for the file or directory. Type: . /// Size in bytes of the buffer pointed to by placeholderInfo. /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// The provider uses this routine to provide the data requested in an invocation of its PRJ_GET_PLACEHOLDER_INFO_CB callback, or it /// may use it to proactively lay down a placeholder. /// /// /// The EaInformation, SecurityInformation, and StreamsInformation members of PRJ_PLACEHOLDER_INFO are optional. If the provider /// does not wish to provide extended attributes, custom security descriptors, or alternate data streams, it must set these fields /// to 0. /// /// Symbolic Links /// /// To specify that this placeholder is to be a symbolic link, the provider formats a buffer with a single PRJ_EXTENDED_INFO struct /// and passes a pointer to it in the parameter. The provider sets the struct's fields as follows: /// /// /// /// extendedInfo.InfoType = PRJ_EXT_INFO_TYPE_SYMLINK /// /// /// extendedInfo.NextInfoOffset = 0 /// /// /// extendedInfo.Symlink.TargetName = <path to the target of the symbolic link> /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/nf-projectedfslib-prjwriteplaceholderinfo2 HRESULT // PrjWritePlaceholderInfo2( PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, PCWSTR destinationFileName, const // PRJ_PLACEHOLDER_INFO *placeholderInfo, UINT32 placeholderInfoSize, const PRJ_EXTENDED_INFO *ExtendedInfo ); [DllImport(Lib.ProjectedFSLib, SetLastError = false, ExactSpelling = true)] [PInvokeData("projectedfslib.h", MSDNShortId = "NF:projectedfslib.PrjWritePlaceholderInfo2")] public static extern HRESULT PrjWritePlaceholderInfo2(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT namespaceVirtualizationContext, [MarshalAs(UnmanagedType.LPWStr)] string destinationFileName, [In] IntPtr placeholderInfo, uint placeholderInfoSize, [In, Optional] IntPtr ExtendedInfo); /// Defines the standard information passed to a provider for every operation callback. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_callback_data typedef struct // PRJ_CALLBACK_DATA { UINT32 Size; PRJ_CALLBACK_DATA_FLAGS Flags; PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT // NamespaceVirtualizationContext; INT32 CommandId; GUID FileId; GUID DataStreamId; PCWSTR FilePathName; // PRJ_PLACEHOLDER_VERSION_INFO *VersionInfo; UINT32 TriggeringProcessId; PCWSTR TriggeringProcessImageFileName; void // *InstanceContext; } PRJ_CALLBACK_DATA; [PInvokeData("projectedfslib.h", MSDNShortId = "569204FF-97F5-4FE2-9885-94C88AB5A6FE")] [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct PRJ_CALLBACK_DATA { /// /// Size in bytes of this structure. The provider must not attempt to access any field of this structure that is located beyond /// this value. /// public uint Size; /// Callback-specific flags. public PRJ_CALLBACK_DATA_FLAGS Flags; /// public PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT NamespaceVirtualizationContext; /// /// A value that uniquely identifies a particular invocation of a callback. The provider uses this value: /// /// /// In calls to PrjCompleteCommand to signal completion of a callback from which it earlier returned HRESULT_FROM_WIN32(ERROR_IO_PENDING). /// /// /// /// When ProjFS sends a PRJ_CANCEL_COMMAND_CB callback. The commandId in the PRJ_CANCEL_COMMAND_CB call identifies an earlier /// invocation of a callback that the provider should cancel. /// /// /// /// public int CommandId; /// A value that uniquely identifies the file handle for the callback. public Guid FileId; /// A value that uniquely identifies an open data stream for the callback. public Guid DataStreamId; /// /// The path to the target file. This is a null-terminated string of Unicode characters. This path is always specified relative /// to the virtualization root. /// [MarshalAs(UnmanagedType.LPWStr)] public string FilePathName; /// Version information if the target of the callback is a placeholder or partial file. public IntPtr VersionInfo; /// /// The process identifier for the process that triggered this callback. If this information is not available, this will be 0. /// Callbacks that supply this information include: PRJ_GET_PLACEHOLDER_INFO_CB, PRJ_GET_FILE_DATA_CB, and PRJ_NOTIFICATION_CB. /// public uint TriggeringProcessId; /// /// A null-terminated Unicode string specifying the image file name corresponding to TriggeringProcessId. If TriggeringProcessId /// is 0 this will be NULL. /// [MarshalAs(UnmanagedType.LPWStr)] public string TriggeringProcessImageFileName; /// /// /// A pointer to context information defined by the provider. The provider passes this context in the instanceContext parameter /// of PrjStartVirtualizing. /// /// If the provider did not specify such a context, this value will be NULL. /// public IntPtr InstanceContext; } /// A set of callback routines to where the provider stores its implementation of the callback. /// /// /// The provider must supply implementations for StartDirectoryEnumerationCallback, EndDirectoryEnumerationCallback, /// GetDirectoryEnumerationCallback, GetPlaceholderInformationCallback, and GetFileDataCallback. /// /// The QueryFileNameCallback, NotifyOperationCallback, and CancelCommandCallback callbacks are optional. /// /// /// /// If the provider does not supply an implementation of QueryFileNameCallback, ProjFS will invoke the directory enumeration /// callbacks to determine the existence of a file path in the provider's store. /// /// /// /// If the provider does not supply an implementation of NotifyOperationCallback, it will not get any notifications from ProjFS. /// /// /// /// If the provider does not supply an implementation of CancelCommandCallback, none of the other callbacks will be cancellable. The /// provider will process all callbacks synchronously. /// /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_callbacks typedef struct PRJ_CALLBACKS { // PRJ_START_DIRECTORY_ENUMERATION_CB *StartDirectoryEnumerationCallback; PRJ_END_DIRECTORY_ENUMERATION_CB // *EndDirectoryEnumerationCallback; PRJ_GET_DIRECTORY_ENUMERATION_CB *GetDirectoryEnumerationCallback; PRJ_GET_PLACEHOLDER_INFO_CB // *GetPlaceholderInfoCallback; PRJ_GET_FILE_DATA_CB *GetFileDataCallback; PRJ_QUERY_FILE_NAME_CB *QueryFileNameCallback; // PRJ_NOTIFICATION_CB *NotificationCallback; PRJ_CANCEL_COMMAND_CB *CancelCommandCallback; } PRJ_CALLBACKS; [PInvokeData("projectedfslib.h", MSDNShortId = "2FFF6A39-92C0-4BD1-B293-AC5650B2575C")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_CALLBACKS { /// A pointer to the StartDirectoryEnumerationCallback. [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_START_DIRECTORY_ENUMERATION_CB StartDirectoryEnumerationCallback; /// A pointer to the EndDirectoryEnumerationCallback. [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_END_DIRECTORY_ENUMERATION_CB EndDirectoryEnumerationCallback; /// A pointer to the GetDirectoryEnumerationCallback. [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_GET_DIRECTORY_ENUMERATION_CB GetDirectoryEnumerationCallback; /// [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_GET_PLACEHOLDER_INFO_CB GetPlaceholderInfoCallback; /// A pointer to the GetFileDataCallback. [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_GET_FILE_DATA_CB GetFileDataCallback; /// A pointer to the QueryFileNameCallback. [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_QUERY_FILE_NAME_CB QueryFileNameCallback; /// [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_NOTIFICATION_CB NotificationCallback; /// A pointer to the CancelCommandCallback. [MarshalAs(UnmanagedType.FunctionPtr)] public PRJ_CANCEL_COMMAND_CB CancelCommandCallback; } /// Specifies parameters required for completing certain callbacks. /// /// /// For any callback except PRJ_CANCEL_COMMAND_CB, the provider may opt to process the callback asynchronously. To do so it returns /// HRESULT_FROM_WIN32(ERROR_IO_PENDING) from the callback. Once the provider has finished processing the callback. /// /// /// If the provider calls this function for the commandId passed by the PRJ_CANCEL_COMMAND_CB callback it is not an error, however /// it is a no-op because the I/O that caused the callback invocation identified by commandId has already ended. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_complete_command_extended_parameters // typedef struct PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS { PRJ_COMPLETE_COMMAND_TYPE CommandType; union { struct { // PRJ_NOTIFY_TYPES NotificationMask; } Notification; struct { PRJ_DIR_ENTRY_BUFFER_HANDLE DirEntryBufferHandle; } Enumeration; } // DUMMYUNIONNAME; } PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS; [PInvokeData("projectedfslib.h", MSDNShortId = "1E13CED8-41DF-4206-AA60-751424424011")] [StructLayout(LayoutKind.Explicit)] public struct PRJ_COMPLETE_COMMAND_EXTENDED_PARAMETERS { /// [FieldOffset(0)] public PRJ_COMPLETE_COMMAND_TYPE CommandType; /// A new set of notifications the provider wishes to receive. [FieldOffset(4)] public PRJ_NOTIFY_TYPES NotificationMask; /// /// An opaque handle to a directory entry buffer. This must be the value passed in the dirEntryBufferHandle parameter of the /// PRJ_GET_DIRECTORY_ENUMERATION_CB callback being completed. /// [FieldOffset(4)] public PRJ_DIR_ENTRY_BUFFER_HANDLE DirEntryBufferHandle; } /// Provides a handle to a directory entry buffer. [StructLayout(LayoutKind.Sequential)] public struct PRJ_DIR_ENTRY_BUFFER_HANDLE : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public PRJ_DIR_ENTRY_BUFFER_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static PRJ_DIR_ENTRY_BUFFER_HANDLE NULL => new PRJ_DIR_ENTRY_BUFFER_HANDLE(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(PRJ_DIR_ENTRY_BUFFER_HANDLE h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator PRJ_DIR_ENTRY_BUFFER_HANDLE(IntPtr h) => new PRJ_DIR_ENTRY_BUFFER_HANDLE(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(PRJ_DIR_ENTRY_BUFFER_HANDLE h1, PRJ_DIR_ENTRY_BUFFER_HANDLE h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(PRJ_DIR_ENTRY_BUFFER_HANDLE h1, PRJ_DIR_ENTRY_BUFFER_HANDLE h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is PRJ_DIR_ENTRY_BUFFER_HANDLE h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// /// A provider uses PRJ_EXTENDED_INFO to provide extended information about a file when calling PrjFillDirEntryBuffer2 or PrjWritePlaceholderInfo2. /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_extended_info typedef struct // PRJ_EXTENDED_INFO { PRJ_EXT_INFO_TYPE InfoType; ULONG NextInfoOffset; union { struct { PCWSTR TargetName; } Symlink; } // DUMMYUNIONNAME; } PRJ_EXTENDED_INFO; [PInvokeData("projectedfslib.h", MSDNShortId = "NS:projectedfslib.PRJ_EXTENDED_INFO")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_EXTENDED_INFO { /// A PRJ_EXT_INFO value describing what kind of extended information this structure contains. public PRJ_EXT_INFO_TYPE InfoType; /// /// Offset in bytes from the beginning of this structure to the next PRJ_EXTENDED_INFO structure. If this is the last structure /// in the buffer this value must be 0. /// public uint NextInfoOffset; /// This PRJ_EXTENDED_INFO specifies the target of a symbolic link. public SYMLINK Symlink; /// This PRJ_EXTENDED_INFO specifies the target of a symbolic link. [StructLayout(LayoutKind.Sequential)] public struct SYMLINK { /// Specifies the name of the target of a symbolic link. [MarshalAs(UnmanagedType.LPWStr)] public string TargetName; } } /// Basic information about an item. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_file_basic_info typedef struct // PRJ_FILE_BASIC_INFO { BOOLEAN IsDirectory; INT64 FileSize; LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; // LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; UINT32 FileAttributes; } PRJ_FILE_BASIC_INFO; [PInvokeData("projectedfslib.h", MSDNShortId = "5B5D157E-DEAF-47F2-BDB2-2CF3D307CB7F")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_FILE_BASIC_INFO { /// Specifies whether the item is a directory. [MarshalAs(UnmanagedType.U1)] public bool IsDirectory; /// Size of the item, in bytes. public long FileSize; /// Creation time of the item. public FILETIME CreationTime; /// Last time the item was accessed. public FILETIME LastAccessTime; /// Last time the item was written to. public FILETIME LastWriteTime; /// The last time the item was changed. public FILETIME ChangeTime; /// Attributes of the item. public FileFlagsAndAttributes FileAttributes; } /// Provides a handle to a namespace virtualization context. [StructLayout(LayoutKind.Sequential)] public struct PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT(IntPtr preexistingHandle) => handle = preexistingHandle; /// /// Returns an invalid handle by instantiating a object with . /// public static PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT NULL => new PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT(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(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT(IntPtr h) => new PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT h1, PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT h1, PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is PRJ_NAMESPACE_VIRTUALIZATION_CONTEXT h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// /// Describes a notification mapping, which is a pairing between a directory (referred to as a "notification root") and a set of /// notifications, expressed as a bit mask. /// /// /// /// PRJ_NOTIFICATION_MAPPING describes a "notification mapping", which is a pairing between a directory (referred to as a /// "notification root") and a set of notifications, expressed as a bit mask, which ProjFS should send for that directory and its /// descendants. A notification mapping can also be established for a single file. /// /// /// The provider puts an array of zero or more PRJ_NOTIFICATION_MAPPING structures in the NotificationMappings member of the options /// parameter of PrjStartVirtualizing to configure notifications for the virtualization root. /// /// /// If the provider does not specify any notification mappings, ProjFS will default to sending the notifications /// PRJ_NOTIFICATION_FILE_OPENED, PRJ_NOTIFICATION_NEW_FILE_CREATED, and PRJ_NOTIFICATION_FILE_OVERWRITTEN for all files and /// directories in the virtualization instance. /// /// /// The directory or file is specified relative to the virtualization root, with an empty string representing the virtualization /// root itself. /// /// /// If the provider specifies multiple notification mappings, and some are descendants of others, the mappings must be specified in /// descending depth. Notification mappings at deeper levels override higher-level ones for their descendants. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_notification_mapping typedef struct // PRJ_NOTIFICATION_MAPPING { PRJ_NOTIFY_TYPES NotificationBitMask; PCWSTR NotificationRoot; } PRJ_NOTIFICATION_MAPPING; [PInvokeData("projectedfslib.h", MSDNShortId = "758E1ADB-8C16-46D9-B796-57C0B875790D")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_NOTIFICATION_MAPPING { /// A bit mask representing a set of notifications. public PRJ_NOTIFY_TYPES NotificationBitMask; /// The directory that the notification mapping is paired to. [MarshalAs(UnmanagedType.LPWStr)] public string NotificationRoot; } /// Extra parameters for notifications. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_notification_parameters typedef union // PRJ_NOTIFICATION_PARAMETERS { struct { PRJ_NOTIFY_TYPES NotificationMask; } PostCreate; struct { PRJ_NOTIFY_TYPES // NotificationMask; } FileRenamed; struct { BOOLEAN IsFileModified; } FileDeletedOnHandleClose; } PRJ_NOTIFICATION_PARAMETERS; [PInvokeData("projectedfslib.h", MSDNShortId = "596DC712-C6DD-4834-9E0F-CA21B0BC3BB3")] [StructLayout(LayoutKind.Explicit)] public struct PRJ_NOTIFICATION_PARAMETERS { /// /// Upon return from the PRJ_NOTIFICATION_CB callback, the provider may specify a new set of notifications that it wishes to /// receive for the file here. If the provider sets this value to 0, it is equivalent to specifying PRJ_NOTIFICATION_USE_EXISTING_MASK. /// [FieldOffset(0)] public PRJ_NOTIFY_TYPES PostCreate_NotificationMask; /// /// Upon return from the PRJ_NOTIFICATION_CB callback, the provider may specify a new set of notifications that it wishes to /// receive for the file here. If the provider sets this value to 0, it is equivalent to specifying PRJ_NOTIFICATION_USE_EXISTING_MASK. /// [FieldOffset(0)] public PRJ_NOTIFY_TYPES FileRenamed_NotificationMask; /// /// If the provider registered for PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_MODIFIED as well as /// PRJ_NOTIFICATION_FILE_HANDLE_CLOSED_FILE_DELETED, this field is set to TRUE if the file was modified before it was deleted. /// [FieldOffset(0)] public BOOLEAN FileDeletedOnHandleClose_IsFileModified; } /// A buffer of metadata for the placeholder file or directory. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_placeholder_info typedef struct // PRJ_PLACEHOLDER_INFO { PRJ_FILE_BASIC_INFO FileBasicInfo; struct { UINT32 EaBufferSize; UINT32 OffsetToFirstEa; } EaInformation; // struct { UINT32 SecurityBufferSize; UINT32 OffsetToSecurityDescriptor; } SecurityInformation; struct { UINT32 // StreamsInfoBufferSize; UINT32 OffsetToFirstStreamInfo; } StreamsInformation; PRJ_PLACEHOLDER_VERSION_INFO VersionInfo; UINT8 // VariableData[1]; } PRJ_PLACEHOLDER_INFO; [PInvokeData("projectedfslib.h", MSDNShortId = "84F510F6-7192-4B0D-A063-CE99B54ED7DD")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_PLACEHOLDER_INFO { /// /// A structure that supplies basic information about the item: the size of the file in bytes (should be zero if the IsDirectory /// field is set to TRUE), the item’s timestamps, and its attributes. /// public PRJ_FILE_BASIC_INFO FileBasicInfo; /// A structure that supplies extended attribute (EA) information about the item. public EAINFORMATION EaInformation; /// Supplies custom security descriptor information about the item. public SECURITYINFORMATION SecurityInformation; /// Supplies information about alternate data streams for the item. public STREAMSINFORMATION StreamsInformation; /// public PRJ_PLACEHOLDER_VERSION_INFO VersionInfo; /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public byte[] VariableData; /// A structure that supplies extended attribute (EA) information about the item. [StructLayout(LayoutKind.Sequential)] public struct EAINFORMATION { /// /// The size in bytes of the extended attribute buffer. If there is no extended attribute information, this must be set to 0. /// public uint EaBufferSize; /// /// The offset, in bytes, from the start of the PRJ_PLACEHOLDER_INFO structure to the first FILE_FULL_EA_INFORMATION entry. /// public uint OffsetToFirstEa; } /// Supplies custom security descriptor information about the item. [StructLayout(LayoutKind.Sequential)] public struct SECURITYINFORMATION { /// /// The size, in bytes, of the custom security descriptor. If there is no custom security descriptor, this must be set to 0. /// public uint SecurityBufferSize; /// /// Specifies the offset, in bytes, from the start of the PRJ_PLACEHOLDER_INFO structure to the SECURITY_DESCRIPTOR structure. /// public uint OffsetToSecurityDescriptor; } /// Supplies information about alternate data streams for the item. [StructLayout(LayoutKind.Sequential)] public struct STREAMSINFORMATION { /// /// The size, in bytes, of alternate data stream information for the placeholder. If there are no alternate data streams, /// this must be set to 0. /// public uint StreamsInfoBufferSize; /// /// The offset, in bytes, from the start of the PRJ_PLACEHOLDER_INFO structure to the first FILE_STREAM_INFORMATION entry. /// public uint OffsetToFirstStreamInfo; } } /// Information that uniquely identifies the contents of a placeholder file. /// /// /// A provider uses PRJ_PLACEHOLDER_VERSION_INFO to provide information that uniquely identifies the contents of a /// placeholder file. ProjFS stores the contents of this struct with the file and returns it when invoking callbacks. /// /// /// PRJ_PLACEHOLDER_VERSION_INFO.ProviderID is a provider-specific identifier. The provider may use this value as its own /// unique identifier, for example as a version number for the format of the ContentID field. /// /// /// PRJ_PLACEHOLDER_VERSION_INFO.ContentID is a content identifier, generated by the provider. This value is used to /// distinguish different versions of the same file, i.e. different file contents and/or metadata (e.g. timestamps) for the same /// file path. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_placeholder_version_info typedef struct // PRJ_PLACEHOLDER_VERSION_INFO { UINT8 ProviderID[PRJ_PLACEHOLDER_ID_LENGTH]; UINT8 ContentID[PRJ_PLACEHOLDER_ID_LENGTH]; } PRJ_PLACEHOLDER_VERSION_INFO; [PInvokeData("projectedfslib.h", MSDNShortId = "4F2156AC-087B-4FF6-8566-25D9DC2A8C06")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_PLACEHOLDER_VERSION_INFO { /// A provider specific identifier. [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)PRJ_PLACEHOLDER_ID.PRJ_PLACEHOLDER_ID_LENGTH)] public byte[] ProviderID; /// A content identifier, generated by the provider. [MarshalAs(UnmanagedType.ByValArray, SizeConst = (int)PRJ_PLACEHOLDER_ID.PRJ_PLACEHOLDER_ID_LENGTH)] public byte[] ContentID; } /// Options to provide when starting a virtualization instance. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_startvirtualizing_options typedef struct // PRJ_STARTVIRTUALIZING_OPTIONS { PRJ_STARTVIRTUALIZING_FLAGS Flags; UINT32 PoolThreadCount; UINT32 ConcurrentThreadCount; // PRJ_NOTIFICATION_MAPPING *NotificationMappings; UINT32 NotificationMappingsCount; } PRJ_STARTVIRTUALIZING_OPTIONS; [PInvokeData("projectedfslib.h", MSDNShortId = "5FF20B04-29A6-4310-ACD6-35E189B87C9E")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_STARTVIRTUALIZING_OPTIONS { /// A flag for starting virtualization. public PRJ_STARTVIRTUALIZING_FLAGS Flags; /// The number of threads the provider wants to create to service callbacks. public uint PoolThreadCount; /// The maximum number of threads the provider wants to run concurrently to process callbacks. public uint ConcurrentThreadCount; /// /// An array of zero or more notification mappings. See the Remarks section of PRJ_NOTIFICATION MAPPING for more details. /// public IntPtr NotificationMappings; /// The number of notification mappings provided in NotificationMappings. public uint NotificationMappingsCount; } /// Information about a virtualization instance. // https://docs.microsoft.com/en-us/windows/win32/api/projectedfslib/ns-projectedfslib-prj_virtualization_instance_info typedef // struct PRJ_VIRTUALIZATION_INSTANCE_INFO { GUID InstanceID; UINT32 WriteAlignment; } PRJ_VIRTUALIZATION_INSTANCE_INFO; [PInvokeData("projectedfslib.h", MSDNShortId = "B6532FDF-F190-4C10-BF5C-96BDF477BB4A")] [StructLayout(LayoutKind.Sequential)] public struct PRJ_VIRTUALIZATION_INSTANCE_INFO { /// An ID corresponding to a specific virtualization instance. public Guid InstanceID; /// The value used for the byteOffset and length parameters of PrjWriteFileData. public uint WriteAlignment; } } }