mirror of https://github.com/dahall/Vanara.git
Fixed and extended functions from PathCch.h
parent
19d8a8d396
commit
6649425ebb
|
@ -332,6 +332,54 @@ namespace Vanara.PInvoke
|
||||||
[PInvokeData("pathcch.h", MSDNShortId = "89adf45f-f16d-49d1-9e76-b57b73b4d4c3")]
|
[PInvokeData("pathcch.h", MSDNShortId = "89adf45f-f16d-49d1-9e76-b57b73b4d4c3")]
|
||||||
public static extern HRESULT PathCchAddBackslashEx(StringBuilder pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining);
|
public static extern HRESULT PathCchAddBackslashEx(StringBuilder pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// <para>This function differs from PathAddBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
/// <para>
|
||||||
|
/// <c>Note</c> This function, or <c>PathCchAddBackslashEx</c>, should be used in place of PathAddBackslash to prevent the
|
||||||
|
/// possibility of a buffer overrun.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pszPath">
|
||||||
|
/// <para>
|
||||||
|
/// 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 <c>NULL</c>.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="cchPath">
|
||||||
|
/// <para>The size of the buffer pointed to by pszPath, in characters.</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="ppszEnd">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="pcchRemaining">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </returns>
|
||||||
|
// 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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Adds a file name extension to a path string.</para>
|
/// <para>Adds a file name extension to a path string.</para>
|
||||||
/// <para>This function differs from PathAddExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
/// <para>This function differs from PathAddExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
@ -1028,6 +1076,35 @@ namespace Vanara.PInvoke
|
||||||
[PInvokeData("pathcch.h", MSDNShortId = "dac6cf02-7b53-449c-b788-4a7b6d1622ed")]
|
[PInvokeData("pathcch.h", MSDNShortId = "dac6cf02-7b53-449c-b788-4a7b6d1622ed")]
|
||||||
public static extern HRESULT PathCchFindExtension(string pszPath, SizeT cchPath, out IntPtr ppszExt);
|
public static extern HRESULT PathCchFindExtension(string pszPath, SizeT cchPath, out IntPtr ppszExt);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// <para>This function differs from PathFindExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
/// <para><c>Note</c> This function should be used in place of PathFindExtension to prevent the possibility of a buffer overrun.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pszPath">
|
||||||
|
/// <para>A pointer to the path to search.</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="cchPath">
|
||||||
|
/// <para>The size of the buffer pointed to by pszPath, in characters.</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="ppszExt">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para>
|
||||||
|
/// </returns>
|
||||||
|
// 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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Determines whether a path string refers to the root of a volume.</para>
|
/// <para>Determines whether a path string refers to the root of a volume.</para>
|
||||||
/// <para>This function differs from PathIsRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
/// <para>This function differs from PathIsRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
@ -1238,6 +1315,55 @@ namespace Vanara.PInvoke
|
||||||
[PInvokeData("pathcch.h", MSDNShortId = "250c2faa-94bb-42c1-97d4-37f8f59dbde6")]
|
[PInvokeData("pathcch.h", MSDNShortId = "250c2faa-94bb-42c1-97d4-37f8f59dbde6")]
|
||||||
public static extern HRESULT PathCchRemoveBackslashEx(StringBuilder pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining);
|
public static extern HRESULT PathCchRemoveBackslashEx(StringBuilder pszPath, SizeT cchPath, out IntPtr ppszEnd, out SizeT pcchRemaining);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Removes the trailing backslash from the end of a path string.</para>
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// <para>This function differs from PathRemoveBackslash in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
/// <para>
|
||||||
|
/// <c>Note</c> This function, or PathCchRemoveBackslash, should be used in place of PathRemoveBackslash to prevent the possibility
|
||||||
|
/// of a buffer overrun.
|
||||||
|
/// </para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pszPath">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="cchPath">
|
||||||
|
/// <para>The size of the buffer pointed to by pszPath, in characters.</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="ppszEnd">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="pcchRemaining">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// <para>This function will not remove the backslash from a root path string, such as "C:".</para>
|
||||||
|
/// </remarks>
|
||||||
|
// 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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Removes the file name extension from a path, if one is present.</para>
|
/// <para>Removes the file name extension from a path, if one is present.</para>
|
||||||
/// <para>This function differs from PathRemoveExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
/// <para>This function differs from PathRemoveExtension in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
@ -1375,6 +1501,32 @@ namespace Vanara.PInvoke
|
||||||
[PInvokeData("pathcch.h", MSDNShortId = "187bc49e-c5ae-42b8-acbd-a765f871d73b")]
|
[PInvokeData("pathcch.h", MSDNShortId = "187bc49e-c5ae-42b8-acbd-a765f871d73b")]
|
||||||
public static extern HRESULT PathCchSkipRoot(string pszPath, out IntPtr ppszRootEnd);
|
public static extern HRESULT PathCchSkipRoot(string pszPath, out IntPtr ppszRootEnd);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// Retrieves a pointer to the first character in a path following the drive letter or Universal Naming Convention (UNC) server/share
|
||||||
|
/// path elements.
|
||||||
|
/// </para>
|
||||||
|
/// <para>This function differs from PathSkipRoot in that it accepts paths with "\", "\?" and "\?\UNC" prefixes.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pszPath">
|
||||||
|
/// <para>A pointer to the path string.</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="ppszRootEnd">
|
||||||
|
/// <para>
|
||||||
|
/// 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.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>If this function succeeds, it returns <c>S_OK</c>. Otherwise, it returns an <c>HRESULT</c> error code.</para>
|
||||||
|
/// </returns>
|
||||||
|
// 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);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <para>Removes the "\?" prefix, if present, from a file path.</para>
|
/// <para>Removes the "\?" prefix, if present, from a file path.</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1465,6 +1617,29 @@ namespace Vanara.PInvoke
|
||||||
[DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
[DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||||
[PInvokeData("pathcch.h", MSDNShortId = "3b2a4158-63ec-49eb-a031-7493d02f2caa")]
|
[PInvokeData("pathcch.h", MSDNShortId = "3b2a4158-63ec-49eb-a031-7493d02f2caa")]
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
public static extern bool PathIsUNCEx(string pszPath, ref StringBuilder ppszServer);
|
public static extern bool PathIsUNCEx(string pszPath, out IntPtr ppszServer);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>Determines if a path string is a valid Universal Naming Convention (UNC) path, as opposed to a path based on a drive letter.</para>
|
||||||
|
/// <para>This function differs from PathIsUNC in that it also allows you to extract the name of the server from the path.</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pszPath">
|
||||||
|
/// <para>A pointer to the path string.</para>
|
||||||
|
/// </param>
|
||||||
|
/// <param name="ppszServer">
|
||||||
|
/// <para>
|
||||||
|
/// A pointer to a string that, when this function returns successfully, receives the server portion of the UNC path. This value can
|
||||||
|
/// be <c>NULL</c> if you don't need this information.
|
||||||
|
/// </para>
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// <para>Returns <c>TRUE</c> if the string is a valid UNC path; otherwise, <c>FALSE</c>.</para>
|
||||||
|
/// </returns>
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,253 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using Vanara.Extensions;
|
||||||
|
using Vanara.InteropServices;
|
||||||
|
using static Vanara.PInvoke.AdvApi32;
|
||||||
|
using static Vanara.PInvoke.Kernel32;
|
||||||
|
|
||||||
|
namespace Vanara.PInvoke.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class PathCchTests
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void PathAllocCanonicalizeTest()
|
||||||
|
{
|
||||||
|
Assert.That(PathAllocCanonicalize(@"C:\name_1\.\name_2\..\name_3", PATHCCH_OPTIONS.PATHCCH_NONE, out var ret), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(ret, Is.EqualTo(@"C:\name_1\name_3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LocalStringMarshalerTest()
|
||||||
|
{
|
||||||
|
var originalByteCount = GC.GetTotalMemory(true);
|
||||||
|
for (int i = 0; i < 5000; i++)
|
||||||
|
{
|
||||||
|
PathAllocCanonicalize(@"C:\name_1\.\name_2\..\name_3", PATHCCH_OPTIONS.PATHCCH_NONE, out var ret);
|
||||||
|
Assert.That(ret, Is.EqualTo(@"C:\name_1\name_3"));
|
||||||
|
}
|
||||||
|
GC.Collect();
|
||||||
|
GC.WaitForPendingFinalizers();
|
||||||
|
GC.Collect();
|
||||||
|
var finalByteCount = GC.GetTotalMemory(true);
|
||||||
|
Assert.That(Math.Abs(finalByteCount - originalByteCount), Is.LessThan(2000));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathAllocCombineTest()
|
||||||
|
{
|
||||||
|
Assert.That(PathAllocCombine(@"C:\name_1\.\name_2\..", @"name_3", PATHCCH_OPTIONS.PATHCCH_NONE, out var ret), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(ret, Is.EqualTo(@"C:\name_1\name_3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchAddBackslashTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\", 100);
|
||||||
|
Assert.That(PathCchAddBackslash(sb, sb.Capacity), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\"));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"C:\Temp", 100);
|
||||||
|
Assert.That(PathCchAddBackslash(sb, sb.Capacity), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchAddBackslashExTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\", 64);
|
||||||
|
Assert.That(PathCchAddBackslashEx(sb, sb.Capacity, out var end, out var rem), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\"));
|
||||||
|
Assert.That(end, Is.Not.EqualTo(IntPtr.Zero));
|
||||||
|
Assert.That(rem, Is.LessThan(60));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"C:\Temp", 64);
|
||||||
|
Assert.That(PathCchAddBackslashEx(sb, sb.Capacity, out end, out rem), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\"));
|
||||||
|
Assert.That(rem, Is.LessThan(60));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchAddBackslashExTest2()
|
||||||
|
{
|
||||||
|
var sb = new SafeCoTaskMemString(@"C:\Temp\", 64);
|
||||||
|
Assert.That(PathCchAddBackslashEx((IntPtr)sb, sb.Capacity, out var end, out var rem), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\"));
|
||||||
|
Assert.That(end, Is.EqualTo(sb.DangerousGetHandle().Offset(sb.Length * 2)));
|
||||||
|
|
||||||
|
sb = new SafeCoTaskMemString(@"C:\Temp", 64);
|
||||||
|
Assert.That(PathCchAddBackslashEx((IntPtr)sb, sb.Size, out end, out rem), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\"));
|
||||||
|
Assert.That(end, Is.EqualTo(sb.DangerousGetHandle().Offset(sb.Length * 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchAddExtensionTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\Dog", 64);
|
||||||
|
Assert.That(PathCchAddExtension(sb, sb.Capacity, "txt"), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\Dog.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchAppendTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\Dog", 64);
|
||||||
|
Assert.That(PathCchAppend(sb, sb.Capacity, "txt"), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\Dog\txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchAppendExTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\Dog", 64);
|
||||||
|
Assert.That(PathCchAppendEx(sb, sb.Capacity, "txt", PATHCCH_OPTIONS.PATHCCH_ENSURE_TRAILING_SLASH), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\Dog\txt\"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchCanonicalizeTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(64);
|
||||||
|
Assert.That(PathCchCanonicalize(sb, sb.Capacity, @"C:\name_1\.\name_2\..\name_3"), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\name_1\name_3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchCanonicalizeExTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(64);
|
||||||
|
Assert.That(PathCchCanonicalizeEx(sb, sb.Capacity, @"C:\name_1\.\name_2\..\name_3", PATHCCH_OPTIONS.PATHCCH_ENSURE_TRAILING_SLASH), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\name_1\name_3\"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchCombineTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(64);
|
||||||
|
Assert.That(PathCchCombine(sb, sb.Capacity, @"C:\name_1\.\name_2\..", @"name_3"), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\name_1\name_3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchCombineExTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(64);
|
||||||
|
Assert.That(PathCchCombineEx(sb, sb.Capacity, @"C:\name_1\.\name_2\..", @"name_3", PATHCCH_OPTIONS.PATHCCH_ENSURE_TRAILING_SLASH), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\name_1\name_3\"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchFindExtensionTest()
|
||||||
|
{
|
||||||
|
var sb = new SafeCoTaskMemString(@"C:\Temp\dog.txt", 64);
|
||||||
|
Assert.That(PathCchFindExtension((IntPtr)sb, sb.Capacity, out var ptr), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(ptr, Is.EqualTo(sb.DangerousGetHandle().Offset(22)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchIsRootTest()
|
||||||
|
{
|
||||||
|
Assert.That(PathCchIsRoot(@"C:\"), Is.True);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchRemoveBackslashTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\", 64);
|
||||||
|
Assert.That(PathCchRemoveBackslash(sb, sb.Capacity), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp"));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"C:\Temp", 64);
|
||||||
|
Assert.That(PathCchRemoveBackslash(sb, sb.Capacity), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchRemoveBackslashExTest()
|
||||||
|
{
|
||||||
|
var sb = new SafeCoTaskMemString(@"C:\Temp\", 64);
|
||||||
|
Assert.That(PathCchRemoveBackslashEx((IntPtr)sb, sb.Capacity, out var end, out var rem), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp"));
|
||||||
|
Assert.That(end, Is.EqualTo(sb.DangerousGetHandle().Offset(14)));
|
||||||
|
|
||||||
|
sb = new SafeCoTaskMemString(@"C:\Temp", 64);
|
||||||
|
Assert.That(PathCchRemoveBackslashEx((IntPtr)sb, sb.Capacity, out end, out rem), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp"));
|
||||||
|
Assert.That(end, Is.EqualTo(sb.DangerousGetHandle().Offset(14)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchRemoveExtensionTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\dog.txt", 64);
|
||||||
|
Assert.That(PathCchRemoveExtension(sb, sb.Capacity), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\dog"));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"C:\Temp\dog", 64);
|
||||||
|
Assert.That(PathCchRemoveExtension(sb, sb.Capacity), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\dog"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchRemoveFileSpecTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\foo\bar.txt", 64);
|
||||||
|
Assert.That(PathCchRemoveFileSpec(sb, sb.Capacity), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchRenameExtensionTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\Temp\dog.txt", 64);
|
||||||
|
Assert.That(PathCchRenameExtension(sb, sb.Capacity, "doc"), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\dog.doc"));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"C:\Temp\dog", 64);
|
||||||
|
Assert.That(PathCchRenameExtension(sb, sb.Capacity, "txt"), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\Temp\dog.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchSkipRootTest()
|
||||||
|
{
|
||||||
|
var sb = new SafeCoTaskMemString(@"C:\Temp\", 64);
|
||||||
|
Assert.That(PathCchSkipRoot((IntPtr)sb, out var end), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(end, Is.EqualTo(sb.DangerousGetHandle().Offset(6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchStripPrefixTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"\\?\C:\foo\bar.txt", 64);
|
||||||
|
Assert.That(PathCchStripPrefix(sb, sb.Capacity), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\foo\bar.txt"));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"C:\foo\bar.txt", 64);
|
||||||
|
Assert.That(PathCchStripPrefix(sb, sb.Capacity), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\foo\bar.txt"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathCchStripToRootTest()
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder(@"C:\foo\bar.txt", 64);
|
||||||
|
Assert.That(PathCchStripToRoot(sb, sb.Capacity), Is.EqualTo((HRESULT)0));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"C:\"));
|
||||||
|
|
||||||
|
sb = new StringBuilder(@"\\path1\path2", 64);
|
||||||
|
Assert.That(PathCchStripToRoot(sb, sb.Capacity), Is.EqualTo((HRESULT)HRESULT.S_FALSE));
|
||||||
|
Assert.That(sb.ToString(), Is.EqualTo(@"\\path1\path2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void PathIsUNCExTest()
|
||||||
|
{
|
||||||
|
Assert.That(PathIsUNCEx(@"\\path1\path2\path3", out var svr), Is.True);
|
||||||
|
Assert.That(Marshal.PtrToStringUni(svr), Is.EqualTo(@"path1\path2\path3"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue