using System; using System.Runtime.InteropServices; using System.Text; using Vanara.InteropServices; namespace Vanara.PInvoke { public static partial class Kernel32 { /// The maximum number of characters supported using the "\\?\" syntax for a file path. public const uint PATHCCH_MAX_CCH = 0x8000; /// Flags used by PathCch functions. [PInvokeData("pathcch.h", MSDNShortId = "3179fe78-a969-4ee2-a50b-5f4f7d4dad71")] [Flags] public enum PATHCCH_OPTIONS { /// Do not allow for the construction of \\?\ paths (ie, long paths) longer than MAX_PATH. PATHCCH_NONE = 0x0000000, /// Allow the building of \\?\ paths longer than MAX_PATH. PATHCCH_ALLOW_LONG_PATHS = 0x00000001, /// /// Forces the API to treat the caller as long path enabled, independent of the PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. Note /// This value is available starting in Windows 10, version 1703. /// PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS = 0x00000002, /// /// Forces the API to treat the caller as long path disabled, independent of the Note This value is available starting in Windows /// 10, version 1703. /// PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS = 0x00000004, /// /// Disables the normalization of path segments that includes removing trailing dots and spaces. Note This value is available /// starting in Windows 10, version 1703. /// PATHCCH_DO_NOT_NORMALIZE_SEGMENTS = 0x00000008, /// /// Converts the input path into the extended length DOS device path form (with the \\?\ prefix) Note This value is available /// starting in Windows 10, version 1703. /// PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH = 0x00000010, /// /// When combining or normalizing a path, ensure there is a trailing backslash. Note This value is available starting in Windows /// 10, version 1703. /// PATHCCH_ENSURE_TRAILING_SLASH = 0x00000020, } /// /// Converts a path string into a canonical form. /// /// This function differs from PathCchCanonicalize and PathCchCanonicalizeEx in that it returns the result on the heap. This means /// that the caller does not have to declare the size of the returned string and reduces stack use. /// /// This function differs from PathCanonicalize in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function, PathCchCanonicalize, or PathCchCanonicalizeEx, should be used in place of PathCanonicalize. /// /// /// A pointer to a buffer that contains the original string. This value cannot be NULL. /// /// /// One or more of the following flags: /// /// /// Value /// Meaning /// /// /// PATHCCH_NONE 0x0000000 /// Do not allow for the construction of \\?\ paths (ie, long paths) longer than MAX_PATH. /// /// /// PATHCCH_ALLOW_LONG_PATHS 0x00000001 /// Allow the building of \\?\ paths longer than MAX_PATH. /// /// /// PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS 0x00000002 /// /// Forces the API to treat the caller as long path enabled, independent of the PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. Note This /// value is available starting in Windows 10, version 1703. /// /// /// /// PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS 0x00000004 /// /// Forces the API to treat the caller as long path disabled, independent of the Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// PATHCCH_DO_NOT_NORMALIZE_SEGMENTS 0x00000008 /// /// Disables the normalization of path segments that includes removing trailing dots and spaces. Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH 0x00000010 /// /// Converts the input path into the extended length DOS device path form (with the \\?\ prefix) Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_TRAILING_SLASH 0x00000020 /// /// When combining or normalizing a path, ensure there is a trailing backslash. Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// /// /// /// The address of a pointer to a buffer that, when this function returns successfully, receives the canonicalized path string. It is /// the responsibility of the caller to free this resource, when it is no longer needed, by calling the LocalFree function. This /// value cannot be NULL. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// This function supports these alternate path forms: /// /// /// \\?\ /// /// /// \\?\\UNC\ /// /// /// \\?\Volume{guid}\ /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathalloccanonicalize HRESULT PathAllocCanonicalize( // PCWSTR pszPathIn, ULONG dwFlags, PWSTR *ppszPathOut ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "3179fe78-a969-4ee2-a50b-5f4f7d4dad71")] public static extern HRESULT PathAllocCanonicalize(string pszPathIn, PATHCCH_OPTIONS dwFlags, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LocalStringMarshaler))] out string ppszPathOut); /// /// /// Concatenates two path fragments into a single path. This function also canonicalizes any relative path elements, replacing path /// elements such as "." and "..". /// /// /// This function differs from PathCchCombine and PathCchCombineEx in that it returns the result on the heap. This means that the /// caller does not have to declare the size of the returned string and reduces stack use. /// /// This function differs from PathCombine in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function, PathCchCombine, or PathCchCombineEx, should be used in place of PathCombine. /// /// /// A pointer to the first path string. /// /// /// /// A pointer to the second path string. If this path begins with a single backslash, it is combined with only the root of the path /// pointed to by pszPathIn. If this path is fully qualified, it is copied directly to the output buffer without being combined with /// the other path. /// /// /// /// One or more of the following flags: /// /// /// Value /// Meaning /// /// /// PATHCCH_NONE 0x0000000 /// Do not allow for the construction of \\?\ paths (ie, long paths) longer than MAX_PATH. /// /// /// PATHCCH_ALLOW_LONG_PATHS 0x00000001 /// Allow the construction of \\?\ paths longer than MAX_PATH. /// /// /// PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS 0x00000002 /// /// Forces the API to treat the caller as long path enabled, independent of the PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. Note This /// value is available starting in Windows 10, version 1703. /// /// /// /// PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS 0x00000004 /// /// Forces the API to treat the caller as long path disabled, independent of the Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// PATHCCH_DO_NOT_NORMALIZE_SEGMENTS 0x00000008 /// /// Disables the normalization of path segments that includes removing trailing dots and spaces. Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH 0x00000010 /// /// Converts the input path into the extended length DOS device path form (with the \\?\ prefix) Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_TRAILING_SLASH 0x00000020 /// /// When combining or normalizing a path, ensure there is a trailing backslash. Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// /// /// /// The address of a pointer to a buffer that, when this function returns successfully, receives the combined path string. It is the /// responsibility of the caller to free this resource, when it is no longer needed, by calling the LocalFree function. This value /// cannot be NULL. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// /// /// While either pszPathIn or pszMore can NULL, they cannot both be NULL. /// This function supports these alternate path forms: /// /// /// \\?\ /// /// /// \\?\\UNC\ /// /// /// \\?\Volume{guid}\ /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathalloccombine HRESULT PathAllocCombine( PCWSTR // pszPathIn, PCWSTR pszMore, ULONG dwFlags, PWSTR *ppszPathOut ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "dd619138-f867-4517-bc67-a52c598efad0")] public static extern HRESULT PathAllocCombine(string pszPathIn, string pszMore, PATHCCH_OPTIONS dwFlags, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LocalStringMarshaler))] out string ppszPathOut); /// /// /// Adds a backslash to the end of a string to create the correct syntax for a path. If the source path already has a trailing /// backslash, no backslash will be added. /// /// This function differs from PathCchAddBackslash in that you are restricted to a final path of length MAX_PATH. /// This function differs from PathAddBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchAddBackslashEx, should be used in place of PathAddBackslash to prevent the possibility of a /// buffer overrun. /// /// /// /// /// A pointer to the path string. When this function returns successfully, the buffer contains the string with the appended /// backslash. This value should not be NULL. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// This function returns S_OK if the function was successful, S_FALSE if the path string already ends in a backslash, or an error /// code otherwise. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchaddbackslash HRESULT PathCchAddBackslash( PWSTR // pszPath, SizeT cchPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "b50677cd-8815-4d84-b70a-c83863378c56")] public static extern HRESULT PathCchAddBackslash(StringBuilder pszPath, SizeT cchPath); /// /// /// Adds a backslash to the end of a string to create the correct syntax for a path. If the source path already has a trailing /// backslash, no backslash will be added. /// /// /// This function differs from PathCchAddBackslash in that it can return a pointer to the new end of the string and report the number /// of unused characters remaining in the buffer. /// /// This function differs from PathAddBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchAddBackslashEx, should be used in place of PathAddBackslash to prevent the /// possibility of a buffer overrun. /// /// /// /// /// A pointer to the path string. When this function returns successfully, the buffer contains the string with the appended /// backslash. This value should not be NULL. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A value that, when this function returns successfully, receives the address of a pointer to the terminating null character at the /// end of the string. /// /// /// /// /// A pointer to a value that, when this function returns successfully, is set to the number of unused characters in the destination /// buffer, including the terminating null character. /// /// /// /// /// This function returns S_OK if the function was successful, S_FALSE if the path string already ends in a backslash, or an error /// code otherwise. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchaddbackslashex HRESULT PathCchAddBackslashEx( PWSTR // pszPath, SizeT cchPath, PWSTR *ppszEnd, SizeT *pcchRemaining ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "89adf45f-f16d-49d1-9e76-b57b73b4d4c3")] public static extern HRESULT PathCchAddBackslashEx(StringBuilder pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining); /// /// /// Adds a backslash to the end of a string to create the correct syntax for a path. If the source path already has a trailing /// backslash, no backslash will be added. /// /// /// This function differs from PathCchAddBackslash in that it can return a pointer to the new end of the string and report the number /// of unused characters remaining in the buffer. /// /// This function differs from PathAddBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchAddBackslashEx, should be used in place of PathAddBackslash to prevent the /// possibility of a buffer overrun. /// /// /// /// /// A pointer to the path string. When this function returns successfully, the buffer contains the string with the appended /// backslash. This value should not be NULL. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A value that, when this function returns successfully, receives the address of a pointer to the terminating null character at the /// end of the string. /// /// /// /// /// A pointer to a value that, when this function returns successfully, is set to the number of unused characters in the destination /// buffer, including the terminating null character. /// /// /// /// /// This function returns S_OK if the function was successful, S_FALSE if the path string already ends in a backslash, or an error /// code otherwise. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchaddbackslashex HRESULT PathCchAddBackslashEx( PWSTR // pszPath, SizeT cchPath, PWSTR *ppszEnd, SizeT *pcchRemaining ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "89adf45f-f16d-49d1-9e76-b57b73b4d4c3")] public static extern HRESULT PathCchAddBackslashEx(IntPtr pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining); /// /// Adds a file name extension to a path string. /// This function differs from PathAddExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function should be used in place of PathAddExtension to prevent the possibility of a buffer overrun. /// /// /// /// A pointer to the path string. When this function returns successfully, the buffer contains the string with the appended /// extension. This value should not be NULL. /// /// /// Note If the original string already has a file name extension present, no new extension will be added and the original /// string will be unchanged. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A pointer to the file name extension string. This string can be given either with or without a preceding period (".ext" or "ext"). /// /// /// /// This function returns an HRESULT code, including the following. /// /// /// Return code /// Description /// /// /// S_OK /// /// The function succeeded. Note that this also includes the case of an empty extension, such as a period with no characters /// following it. In that case, the original string is returned unaltered. /// /// /// /// E_INVALIDARG /// /// This value can be caused by several things, such as the pszPath param being set to NULL, the cchPath being set to 0 or a value /// greater than PATHCCH_MAX_CCH, or the extension string containing illegal characters or otherwise not being a valid extension. /// /// /// /// S_FALSE /// The original string already has an extension. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// The buffer is too small to hold the returned string. /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchaddextension HRESULT PathCchAddExtension( PWSTR // pszPath, SizeT cchPath, PCWSTR pszExt ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "c37b438b-39e7-4f24-b076-2401900dab71")] public static extern HRESULT PathCchAddExtension(StringBuilder pszPath, SizeT cchPath, string pszExt); /// /// Appends one path to the end of another. /// This function differs from PathCchAppendEx in that you are restricted to a final path of length MAX_PATH. /// This function differs from PathAppend in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchAppendEx, should be used in place of PathAppend to prevent the possibility of a buffer overrun. /// /// /// /// /// A pointer to a buffer that, on entry, contains the original path. When this function returns successfully, the buffer contains /// the original path plus the appended path. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A pointer to the path to append to the end of the path pointed to by pszPath. UNC paths and paths beginning with the "\?" /// sequence are accepted and recognized as fully-qualified paths. These paths replace the string pointed to by pszPath instead of /// being appended to it. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT code, including the following. /// /// /// Return code /// Description /// /// /// E_INVALIDARG /// Either pszPath or pszMore is NULL, cchPath is 0, or cchPath is greater than PATHCCH_MAX_CCH. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// The resulting string would exceed PATHCCH_MAX_CCH. /// /// /// E_OUTOFMEMORY /// The function could not allocate a buffer of the neccessary size. /// /// /// /// /// This function inserts a backslash between the two strings, if one is not already present. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchappend HRESULT PathCchAppend( PWSTR pszPath, SizeT // cchPath, PCWSTR pszMore ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "b64884ad-15c7-495e-8037-34daf68f8cf7")] public static extern HRESULT PathCchAppend(StringBuilder pszPath, SizeT cchPath, string pszMore); /// /// Appends one path to the end of another. /// This function differs from PathCchAppend in that it allows for a longer final path to be constructed. /// This function differs from PathAppend in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchAppend, should be used in place of PathAppend to prevent the possibility of a buffer overrun. /// /// /// /// /// A pointer to a buffer that, on entry, contains the original path. When this function returns successfully, the buffer contains /// the original path plus the appended path. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A pointer the path to append to the end of the path pointed to by pszPath. UNC paths and paths that begin with the sequence \?\ /// are accepted and recognized as fully-qualified paths. These paths replace the string pointed to by pszPath instead of being /// appended to it. /// /// /// /// One or more of the following flags: /// /// /// Value /// Meaning /// /// /// PATHCCH_NONE 0x0000000 /// Do not allow for the construction of \\?\ paths (ie, long paths) longer than MAX_PATH. /// /// /// PATHCCH_ALLOW_LONG_PATHS 0x00000001 /// Allow the building of \\?\ paths longer than MAX_PATH. /// /// /// PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS 0x00000002 /// /// Forces the API to treat the caller as long path enabled, independent of the PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. Note This /// value is available starting in Windows 10, version 1703. /// /// /// /// PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS 0x00000004 /// /// Forces the API to treat the caller as long path disabled, independent of the Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// PATHCCH_DO_NOT_NORMALIZE_SEGMENTS 0x00000008 /// /// Disables the normalization of path segments that includes removing trailing dots and spaces. Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH 0x00000010 /// /// Converts the input path into the extended length DOS device path form (with the \\?\ prefix) Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT code, including the following. /// /// /// Return code /// Description /// /// /// E_INVALIDARG /// Either pszPath or pszMore is NULL, cchPath is 0, or cchPath is greater than PATHCCH_MAX_CCH. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// The resulting string would exceed PATHCCH_MAX_CCH. /// /// /// E_OUTOFMEMORY /// The function could not allocate a buffer of the neccessary size. /// /// /// /// /// This function inserts a backslash between the two strings, if one is not already present. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchappendex HRESULT PathCchAppendEx( PWSTR pszPath, // SizeT cchPath, PCWSTR pszMore, ULONG dwFlags ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "5421c666-1c8a-4ae8-baba-9e6f69c877df")] public static extern HRESULT PathCchAppendEx(StringBuilder pszPath, SizeT cchPath, string pszMore, PATHCCH_OPTIONS dwFlags); /// /// Converts a path string into a canonical form. /// This function differs from PathCchCanonicalizeEx in that you are restricted to a final path of length MAX_PATH. /// /// This function differs from PathAllocCanonicalize in that the caller must declare the size of the returned string, which is stored /// on the stack. /// /// This function differs from PathCanonicalize in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, PathCchCanonicalizeEx, or PathAllocCanonicalize should be used in place of PathCanonicalize to prevent /// the possibility of a buffer overrun. /// /// /// /// A pointer to a buffer that, when this function returns successfully, receives the canonicalized path string. /// /// /// The size of the buffer pointed to by pszPathOut, in characters. /// /// /// /// A pointer to the original path string. If this value points to an empty string, or results in an empty string once the "." and /// ".." elements are removed, a single backslash is copied to the buffer pointed to by pszPathOut. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT code, including the following. /// /// /// Return code /// Description /// /// /// E_INVALIDARG /// The cchPathOut value is greater than PATHCCH_MAX_CCH. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// A path segment exceeds the standard path segment length limit of 256 characters. /// /// /// E_OUTOFMEMORY /// The function could not allocate a buffer of the neccessary size. /// /// /// /// /// /// This function responds to the strings "." and ".." embedded in a path. The ".." string indicates to remove the immediately /// preceding path segment. The "." string indicates to skip over the next path segment. Note that the root segment of the path /// cannot be removed. If there are more ".." strings than there are path segments, the function returns S_OK and the buffer pointed /// to by pszPathOut contains a single backslash, "". /// /// /// All trailing periods are removed from the path, except when preceded by the "" wild card character. In that case, a single period /// is retained after the '' character, but all other trailing periods are removed. /// /// If the resulting path is a root drive ("x:"), a backslash is appended ("x:"). /// The following examples show the effect of these strings. /// /// /// Original string /// Canonicalized string /// /// /// C:\name_1\.\name_2\..\name_3 /// C:\name_1\name_3 /// /// /// C:\name_1\..\name_2\.\name_3 /// C:\name_2\name_3 /// /// /// C:\name_1\name_2\.\name_3\..\name_4 /// C:\name_1\name_2\name_4 /// /// /// C:\name_1\.\name_2\.\name_3\..\name_4\.. /// C:\name_1\name_2 /// /// /// C:\name_1\*... /// C:\name_1\*. /// /// /// C:\.. /// C:\ /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchcanonicalize HRESULT PathCchCanonicalize( PWSTR // pszPathOut, SizeT cchPathOut, PCWSTR pszPathIn ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "25ff08b2-5978-4d44-9877-ba4230ef7d12")] public static extern HRESULT PathCchCanonicalize(StringBuilder pszPathOut, SizeT cchPathOut, string pszPathIn); /// /// Simplifies a path by removing navigation elements such as "." and ".." to produce a direct, well-formed path. /// This function differs from PathCchCanonicalize in that it allows for a longer final path to be constructed. /// /// This function differs from PathAllocCanonicalize in that the caller must declare the size of the returned string, which is stored /// on the stack. /// /// This function differs from PathCanonicalize in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, PathCchCanonicalize, or PathAllocCanonicalize should be used in place of PathCanonicalize to prevent /// the possibility of a buffer overrun. /// /// /// /// A pointer to a buffer that, when this function returns successfully, receives the edited path string. /// /// /// The size of the buffer pointed to by pszPathOut, in characters. /// /// /// /// A pointer to the original path string. If this value is NULL, points to an empty string, or results in an empty string /// once the "." and ".." elements are removed, a single backslash is copied to the buffer pointed to by pszPathOut. /// /// /// /// One or more of the following flags: /// /// /// Value /// Meaning /// /// /// PATHCCH_NONE 0x0000000 /// Do not allow for the construction of \\?\ paths (ie, long paths) longer than MAX_PATH. /// /// /// PATHCCH_ALLOW_LONG_PATHS 0x00000001 /// /// Allow the building of \\?\ paths longer than MAX_PATH. Note that cchPathOut must be greater than MAX_PATH. If it is not, this /// flag is ignored. /// /// /// /// PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS 0x00000002 /// /// Forces the API to treat the caller as long path enabled, independent of the PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. Note This /// value is available starting in Windows 10, version 1703. /// /// /// /// PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS 0x00000004 /// /// Forces the API to treat the caller as long path disabled, independent of the Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// PATHCCH_DO_NOT_NORMALIZE_SEGMENTS 0x00000008 /// /// Disables the normalization of path segments that includes removing trailing dots and spaces. Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH 0x00000010 /// /// Converts the input path into the extended length DOS device path form (with the \\?\ prefix) Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_TRAILING_SLASH 0x00000020 /// /// When combining or normalizing a path, ensure there is a trailing backslash. Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT code, including but not limited to the following. /// /// /// /// Return code /// Description /// /// /// E_INVALIDARG /// The cchPathOut value is greater than PATHCCH_MAX_CCH. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// /// A path segment has more than PATHCCH_MAX_CCH characters, or, if the PATHCCH_ALLOW_LONG_PATHS flag is not set, exceeds the /// standard path segment length limit of 256 characters. /// /// /// /// E_OUTOFMEMORY /// The function could not allocate a buffer of the neccessary size. /// /// /// /// /// /// This function responds to the strings "." and ".." embedded in a path. The ".." string indicates to remove the immediately /// preceding path segment. The "." string indicates to skip over the next path segment. Note that the root segment of the path /// cannot be removed. If there are more ".." strings than there are path segments, the function returns S_OK and the buffer pointed /// to by pszPathOut contains a single backslash, "". /// /// /// All trailing periods are removed from the path, except when preceded by the "" wild card character. In that case, a single period /// is retained after the '' character, but all other trailing periods are removed. /// /// If the resulting path is a root drive ("x:"), a backslash is appended ("x:"). /// The following examples show the effect of these strings. /// /// /// Original string /// Canonicalized string /// /// /// C:\name_1\.\name_2\..\name_3 /// C:\name_1\name_3 /// /// /// C:\name_1\..\name_2\.\name_3 /// C:\name_2\name_3 /// /// /// C:\name_1\name_2\.\name_3\..\name_4 /// C:\name_1\name_2\name_4 /// /// /// C:\name_1\.\name_2\.\name_3\..\name_4\.. /// C:\name_1\name_2 /// /// /// C:\name_1\*... /// C:\name_1\*. /// /// /// C:\.. /// C:\ /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchcanonicalizeex HRESULT PathCchCanonicalizeEx( PWSTR // pszPathOut, SizeT cchPathOut, PCWSTR pszPathIn, ULONG dwFlags ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "fd7b8ce0-3c67-48fb-8e7e-521a6b438676")] public static extern HRESULT PathCchCanonicalizeEx(StringBuilder pszPathOut, SizeT cchPathOut, string pszPathIn, PATHCCH_OPTIONS dwFlags); /// /// /// Combines two path fragments into a single path. This function also canonicalizes any relative path elements, removing "." and /// ".." elements to simplify the final path. /// /// This function differs from PathCchCombineEx in that you are restricted to a final path of length MAX_PATH. /// /// This function differs from PathAllocCombine in that the caller must declare the size of the returned string, which is stored on /// the stack. /// /// This function differs from PathCombine in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, PathCchCombineEx, or PathAllocCombine should be used in place of PathCombine to prevent the /// possibility of a buffer overrun. /// /// /// /// /// A pointer to a buffer that, when this function returns successfully, receives the combined path string. This parameter can point /// to the same buffer as pszPathIn or pszMore. /// /// /// /// The size of the buffer pointed to by pszPathOut, in characters. /// /// /// A pointer to the first path string. This value can be NULL. /// /// /// /// A pointer to the second path string. If this path begins with a single backslash, it is combined with only the root of the path /// pointed to by pszPathIn. If this path is fully qualfied, it is copied directly to the output buffer without being combined with /// the other path. This value can be NULL. /// /// /// /// This function returns an HRESULT code, including the following. /// /// /// Return code /// Description /// /// /// S_OK /// /// The function succeeded. Note that this also includes the case of an empty extension, such as a period with no characters /// following it. In that case, the original string is returned unaltered. /// /// /// /// E_INVALIDARG /// /// This value can be caused by several things, such as the pszPathOut param being set to NULL, or the cchPathOut value being set to /// 0 or a value greater than PATHCCH_MAX_CCH. /// /// /// /// E_OUTOFMEMORY /// The function could not allocate enough memory to perform the operation. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// The size of one or both of the original paths exceeded PATHCCH_MAX_CCH. /// /// /// /// /// /// If both pszPathIn and pszMore are NULL or point to empty strings, a single backslash is copied to the buffer pointed to by pszPathOut. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchcombine HRESULT PathCchCombine( PWSTR pszPathOut, // SizeT cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "506a4165-f572-4521-958f-56a0296f9c05")] public static extern HRESULT PathCchCombine(StringBuilder pszPathOut, SizeT cchPathOut, string pszPathIn, string pszMore); /// /// /// Combines two path fragments into a single path. This function also canonicalizes any relative path elements, removing "." and /// ".." elements to simplify the final path. /// /// This function differs from PathCchCombine in that it allows for a longer final path to be constructed. /// /// This function differs from PathAllocCombine in that the caller must declare the size of the returned string, which is stored on /// the stack. /// /// This function differs from PathCombine in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, PathCchCombine, or PathAllocCombine should be used in place of PathCombine to prevent the possibility /// of a buffer overrun. /// /// /// /// /// A pointer to a buffer that, when this function returns successfully, receives the combined path string. This parameter can point /// to the same buffer as pszPathIn or pszMore. /// /// /// /// The size of the buffer pointed to by pszPathOut, in characters. /// /// /// A pointer to the first path string. This value can be NULL. /// /// /// /// A pointer to the second path string. If this path begins with a single backslash, it is combined with only the root of the path /// pointed to by pszPathIn. If this path is fully qualfied, it is copied directly to the output buffer without being combined with /// the other path. This value can be NULL. /// /// /// /// One or more of the following flags: /// /// /// Value /// Meaning /// /// /// PATHCCH_NONE 0x0000000 /// Do not allow for the construction of \\?\ paths (ie, long paths) longer than MAX_PATH. /// /// /// PATHCCH_ALLOW_LONG_PATHS 0x00000001 /// /// Allow the construction of \\?\ paths longer than MAX_PATH. Note that cchPathOut must be greater than MAX_PATH. Note that /// cchPathOut must be greater than MAX_PATH. If it is not, this flag is ignored. /// /// /// /// PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS 0x00000002 /// /// Forces the API to treat the caller as long path enabled, independent of the PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. Note This /// value is available starting in Windows 10, version 1703. /// /// /// /// PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS 0x00000004 /// /// Forces the API to treat the caller as long path disabled, independent of the Note This value is available starting in Windows 10, /// version 1703. /// /// /// /// PATHCCH_DO_NOT_NORMALIZE_SEGMENTS 0x00000008 /// /// Disables the normalization of path segments that includes removing trailing dots and spaces. Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH 0x00000010 /// /// Converts the input path into the extended length DOS device path form (with the \\?\ prefix) Note This value is available /// starting in Windows 10, version 1703. /// /// /// /// /// /// This function returns an HRESULT code, including the following. /// /// /// Return code /// Description /// /// /// S_OK /// /// The function succeeded. Note that this also includes the case of an empty extension, such as a period with no characters /// following it. In that case, the original string is returned unaltered. /// /// /// /// E_INVALIDARG /// /// This value can be caused by several things, such as the pszPathOut param being set to NULL, or the cchPathOut value being set to /// 0 or a value greater than PATHCCH_MAX_CCH. /// /// /// /// E_OUTOFMEMORY /// The function could not allocate enough memory to perform the operation. /// /// /// PATHCCH_E_FILENAME_TOO_LONG /// The size of one or both of the original paths exceeded PATHCCH_MAX_CCH. /// /// /// /// /// /// If both pszPathIn and pszMore are NULL or point to empty strings, a single backslash is copied to the buffer pointed to by pszPathOut. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchcombineex HRESULT PathCchCombineEx( PWSTR // pszPathOut, SizeT cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, ULONG dwFlags ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "798c2e49-04a5-4270-b584-41faf1519e4b")] public static extern HRESULT PathCchCombineEx(StringBuilder pszPathOut, SizeT cchPathOut, string pszPathIn, string pszMore, PATHCCH_OPTIONS dwFlags); /// /// /// Searches a path to find its file name extension, such as ".exe" or ".ini". This function does not search for a specific /// extension; it searches for the presence of any extension. /// /// This function differs from PathFindExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function should be used in place of PathFindExtension to prevent the possibility of a buffer overrun. /// /// /// A pointer to the path to search. /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// The address of a pointer that, when this function returns successfully, points to the "." character that precedes the extension /// within pszPath. If no extension is found, it points to the string's terminating null character. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchfindextension HRESULT PathCchFindExtension( PCWSTR // pszPath, SizeT cchPath, PCWSTR *ppszExt ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "dac6cf02-7b53-449c-b788-4a7b6d1622ed")] public static extern HRESULT PathCchFindExtension(string pszPath, SizeT cchPath, out IntPtr ppszExt); /// /// /// Searches a path to find its file name extension, such as ".exe" or ".ini". This function does not search for a specific /// extension; it searches for the presence of any extension. /// /// This function differs from PathFindExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function should be used in place of PathFindExtension to prevent the possibility of a buffer overrun. /// /// /// A pointer to the path to search. /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// The address of a pointer that, when this function returns successfully, points to the "." character that precedes the extension /// within pszPath. If no extension is found, it points to the string's terminating null character. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchfindextension HRESULT PathCchFindExtension( PCWSTR // pszPath, SizeT cchPath, PCWSTR *ppszExt ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "dac6cf02-7b53-449c-b788-4a7b6d1622ed")] public static extern HRESULT PathCchFindExtension(IntPtr pszPath, SizeT cchPath, out IntPtr ppszExt); /// /// Determines whether a path string refers to the root of a volume. /// This function differs from PathIsRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// /// A pointer to the path string. /// /// /// Returns TRUE if the specified path is a root, or FALSE otherwise. /// /// /// The following table shows the PathCchIsRoot return value for various paths. /// /// /// Path /// PathCchIsRoot /// /// /// "c:\" /// TRUE /// /// /// "c:" /// FALSE /// /// /// "c:\path1" /// FALSE /// /// /// "\path1" /// TRUE /// /// /// "path1" /// FALSE /// /// /// "\\path1\path2" /// TRUE /// /// /// "\\path1\path2\" /// FALSE /// /// /// "\\path1\path2\path3" /// FALSE /// /// /// "\\path1" /// TRUE /// /// /// "\\path1\" /// FALSE /// /// /// "\\" /// TRUE /// /// /// "\\?\UNC\" /// TRUE /// /// /// "\\?\UNC\path1\path2" /// TRUE /// /// /// "\\?\UNC\path1\path2\" /// FALSE /// /// /// "\\?\UNC\path1\path2\path3" /// FALSE /// /// /// "\\?\UNC\path1" /// TRUE /// /// /// "\\?\UNC\path1\" /// FALSE /// /// /// "\\?\c:\" /// TRUE /// /// /// "\\?\c:" /// FALSE /// /// /// "\\?\c:\path1" /// FALSE /// /// /// "\\?\Volume{guid}\" /// TRUE /// /// /// "\\?\Volume{guid}" /// FALSE /// /// /// "\\?\Volume{guid}\path1" /// FALSE /// /// /// NULL /// FALSE /// /// /// "" /// FALSE /// /// /// /// This function returns TRUE for paths such as "", "X:" or "\server<i>share". Paths such as "..\path2" or "\server" /// return FALSE. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchisroot BOOL PathCchIsRoot( PCWSTR pszPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "b9770030-b298-47f8-98a7-3ce9b4d44dd1")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PathCchIsRoot(string pszPath); /// /// Removes the trailing backslash from the end of a path string. /// This function differs from PathRemoveBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchRemoveBackslashEx, should be used in place of PathRemoveBackslash to prevent the possibility /// of a buffer overrun. /// /// /// /// /// A pointer to the path string. When this function returns successfully, the string contains the path with any trailing backslash /// removed. If no trailing backslash was found, the string is unchanged. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// This function returns S_OK if the function was successful, S_FALSE if the string was a root path or if no backslash was found, or /// an error code otherwise. /// /// /// /// This function will not remove the backslash from a root path string, such as "C:". /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchremovebackslash HRESULT PathCchRemoveBackslash( // PWSTR pszPath, SizeT cchPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "61afc20e-ee6c-46ad-a058-64c57de41ba4")] public static extern HRESULT PathCchRemoveBackslash(StringBuilder pszPath, SizeT cchPath); /// /// Removes the trailing backslash from the end of a path string. /// /// This function differs from PathCchRemoveBackslash in that it can return a pointer to the new end of the string and report the /// number of unused characters remaining in the buffer. /// /// This function differs from PathRemoveBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchRemoveBackslash, should be used in place of PathRemoveBackslash to prevent the possibility /// of a buffer overrun. /// /// /// /// /// A pointer to the path string. When this function returns successfully, the string contains the path with any trailing backslash /// removed. If no trailing backslash was found, the string is unchanged. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A value that, when this function returns successfully, receives the address of a pointer to end of the new string. If the string /// is a root path such as "C:", the pointer points to the backslash; otherwise the pointer points to the string's terminating null character. /// /// /// /// /// A pointer to a value that, when this function returns successfully, receives the number of unused characters in the destination /// buffer, including the terminating null character. If the string is a root path such as "C:", this count includes the backslash in /// that string. /// /// /// /// /// This function returns S_OK if the function was successful, S_FALSE if the string was a root path or if no backslash was found, or /// an error code otherwise. /// /// /// /// This function will not remove the backslash from a root path string, such as "C:". /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchremovebackslashex HRESULT PathCchRemoveBackslashEx( // PWSTR pszPath, SizeT cchPath, PWSTR *ppszEnd, SizeT *pcchRemaining ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "250c2faa-94bb-42c1-97d4-37f8f59dbde6")] public static extern HRESULT PathCchRemoveBackslashEx(StringBuilder pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining); /// /// Removes the trailing backslash from the end of a path string. /// /// This function differs from PathCchRemoveBackslash in that it can return a pointer to the new end of the string and report the /// number of unused characters remaining in the buffer. /// /// This function differs from PathRemoveBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// Note This function, or PathCchRemoveBackslash, should be used in place of PathRemoveBackslash to prevent the possibility /// of a buffer overrun. /// /// /// /// /// A pointer to the path string. When this function returns successfully, the string contains the path with any trailing backslash /// removed. If no trailing backslash was found, the string is unchanged. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A value that, when this function returns successfully, receives the address of a pointer to end of the new string. If the string /// is a root path such as "C:", the pointer points to the backslash; otherwise the pointer points to the string's terminating null character. /// /// /// /// /// A pointer to a value that, when this function returns successfully, receives the number of unused characters in the destination /// buffer, including the terminating null character. If the string is a root path such as "C:", this count includes the backslash in /// that string. /// /// /// /// /// This function returns S_OK if the function was successful, S_FALSE if the string was a root path or if no backslash was found, or /// an error code otherwise. /// /// /// /// This function will not remove the backslash from a root path string, such as "C:". /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchremovebackslashex HRESULT PathCchRemoveBackslashEx( // PWSTR pszPath, SizeT cchPath, PWSTR *ppszEnd, SizeT *pcchRemaining ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "250c2faa-94bb-42c1-97d4-37f8f59dbde6")] public static extern HRESULT PathCchRemoveBackslashEx(IntPtr pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining); /// /// Removes the file name extension from a path, if one is present. /// This function differs from PathRemoveExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function, should be used in place of PathRemoveExtension to prevent the possibility of a buffer overrun. /// /// /// /// A pointer to the path string. When this function returns successfully, the string contains the path with any extension removed. /// If no extension was found, the string is unchanged. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// This function returns S_OK if the function was successful, S_FALSE if no extension was found, or an error code otherwise. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchremoveextension HRESULT PathCchRemoveExtension( // PWSTR pszPath, SizeT cchPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "9adfb054-6d62-41bb-9036-0bf670ea24b2")] public static extern HRESULT PathCchRemoveExtension(StringBuilder pszPath, SizeT cchPath); /// /// /// Removes the last element in a path string, whether that element is a file name or a directory name. The element's leading /// backslash is also removed. /// /// This function differs from PathRemoveFileSpec in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function should be used in place of PathRemoveFileSpec to prevent the possibility of a buffer overrun. /// /// /// /// A pointer to the fully-qualified path string. When this function returns successfully, the string will have had its last element /// and its leading backslash removed. This function does not affect root paths such as "C:". In the case of a root path, the path /// string is returned unaltered. If a path string ends with a trailing backslash, only that backslash is removed. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// This function returns S_OK if the function was successful, S_FALSE if there was nothing to remove, or an error code otherwise. /// /// /// The following table shows the effect of this function on a selection of path strings. /// /// /// Original String /// Returned String /// /// /// "C:\path1" /// "C:\" /// /// /// "C:\path1\path2" /// "C:\path1" /// /// /// "C:\path1\" /// "C:\path1" /// /// /// "\\path1\path2\path3" /// "\\path1\path2" /// /// /// "\path1" /// "\" /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchremovefilespec HRESULT PathCchRemoveFileSpec( PWSTR // pszPath, SizeT cchPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "c37aeddc-ed24-4828-b92b-bce0e6384726")] public static extern HRESULT PathCchRemoveFileSpec(StringBuilder pszPath, SizeT cchPath); /// /// /// Replaces a file name's extension at the end of a path string with a new extension. If the path string does not end with an /// extension, the new extension is added. /// /// This function differs from PathRenameExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function should be used in place of PathRenameExtension to prevent the possibility of a buffer overrun. /// /// /// /// A pointer to the path string. When this function returns successfully, this value points to the same string, but with the renamed /// or added extension. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// A pointer to the new extension string. The leading '.' character is optional. In the case of an empty string (""), any existing /// extension in the path string is removed. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchrenameextension HRESULT PathCchRenameExtension( // PWSTR pszPath, SizeT cchPath, PCWSTR pszExt ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "79cd9499-03b7-4482-abd3-a42edd1b2b67")] public static extern HRESULT PathCchRenameExtension(StringBuilder pszPath, SizeT cchPath, string pszExt); /// /// /// Retrieves a pointer to the first character in a path following the drive letter or Universal Naming Convention (UNC) server/share /// path elements. /// /// This function differs from PathSkipRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// /// A pointer to the path string. /// /// /// /// The address of a pointer that, when this function returns successfully, points to the first character in a path following the /// drive letter or UNC server/share path elements. If the path consists of only a root, this value will point to the string's /// terminating null character. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchskiproot HRESULT PathCchSkipRoot( PCWSTR pszPath, // PCWSTR *ppszRootEnd ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "187bc49e-c5ae-42b8-acbd-a765f871d73b")] public static extern HRESULT PathCchSkipRoot(string pszPath, out IntPtr ppszRootEnd); /// /// /// Retrieves a pointer to the first character in a path following the drive letter or Universal Naming Convention (UNC) server/share /// path elements. /// /// This function differs from PathSkipRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// /// /// A pointer to the path string. /// /// /// /// The address of a pointer that, when this function returns successfully, points to the first character in a path following the /// drive letter or UNC server/share path elements. If the path consists of only a root, this value will point to the string's /// terminating null character. /// /// /// /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchskiproot HRESULT PathCchSkipRoot( PCWSTR pszPath, // PCWSTR *ppszRootEnd ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "187bc49e-c5ae-42b8-acbd-a765f871d73b")] public static extern HRESULT PathCchSkipRoot(IntPtr pszPath, out IntPtr ppszRootEnd); /// /// Removes the "\?" prefix, if present, from a file path. /// /// /// /// A pointer to the path string. When this function returns successfully, the same path string will have had the prefix removed, if /// the prefix was present. If no prefix was present, the string will be unchanged. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// This function returns S_OK if the prefix was removed, S_FALSE if the path did not have a prefix to remove, or an HRESULT failure code. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchstripprefix HRESULT PathCchStripPrefix( PWSTR // pszPath, SizeT cchPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "2e50b23e-2725-4200-bd5e-845ff3458026")] public static extern HRESULT PathCchStripPrefix(StringBuilder pszPath, SizeT cchPath); /// /// Removes all file and directory elements in a path except for the root information. /// This function differs from PathStripToRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes. /// Note This function should be used in place of PathStripToRoot to prevent the possibility of a buffer overrun. /// /// /// /// A pointer to the path string. When this function returns successfully, this string contains only the root information taken from /// that path. /// /// /// /// The size of the buffer pointed to by pszPath, in characters. /// /// /// /// This function returns S_OK if the path was truncated, S_FALSE if the path was already just a root, or an HRESULT failure code. /// /// /// /// Some examples of the effect of this function: /// /// /// Initial string /// Final string /// /// /// "C:\path1\path2\file" /// "C:\" /// /// /// "\\path1\path2\path3" /// "\\path1\path2" /// /// /// "\path1" /// "\" /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathcchstriptoroot HRESULT PathCchStripToRoot( PWSTR // pszPath, SizeT cchPath ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "e0539478-8c64-4445-ab99-22f1df70afe8")] public static extern HRESULT PathCchStripToRoot(StringBuilder pszPath, SizeT cchPath); /// /// Determines if a path string is a valid Universal Naming Convention (UNC) path, as opposed to a path based on a drive letter. /// This function differs from PathIsUNC in that it also allows you to extract the name of the server from the path. /// /// /// A pointer to the path string. /// /// /// /// A pointer to a string that, when this function returns successfully, receives the server portion of the UNC path. This value can /// be NULL if you don't need this information. /// /// /// /// Returns TRUE if the string is a valid UNC path; otherwise, FALSE. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathisuncex BOOL PathIsUNCEx( PCWSTR pszPath, PCWSTR // *ppszServer ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "3b2a4158-63ec-49eb-a031-7493d02f2caa")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PathIsUNCEx(string pszPath, out IntPtr ppszServer); /// /// Determines if a path string is a valid Universal Naming Convention (UNC) path, as opposed to a path based on a drive letter. /// This function differs from PathIsUNC in that it also allows you to extract the name of the server from the path. /// /// /// A pointer to the path string. /// /// /// /// A pointer to a string that, when this function returns successfully, receives the server portion of the UNC path. This value can /// be NULL if you don't need this information. /// /// /// /// Returns TRUE if the string is a valid UNC path; otherwise, FALSE. /// // https://docs.microsoft.com/en-us/windows/desktop/api/pathcch/nf-pathcch-pathisuncex BOOL PathIsUNCEx( PCWSTR pszPath, PCWSTR // *ppszServer ); [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)] [PInvokeData("pathcch.h", MSDNShortId = "3b2a4158-63ec-49eb-a031-7493d02f2caa")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool PathIsUNCEx(IntPtr pszPath, out IntPtr ppszServer); } }