mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-03 06:13:40 +01:00
Cleanup
This commit is contained in:
parent
bb76f0eea4
commit
6c8c42ca05
3 changed files with 225 additions and 135 deletions
175
Dalamud/Utility/TerraFxCom/TerraFxComInterfaceExtensions.cs
Normal file
175
Dalamud/Utility/TerraFxCom/TerraFxComInterfaceExtensions.cs
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using TerraFX.Interop.Windows;
|
||||
|
||||
using static TerraFX.Interop.Windows.Windows;
|
||||
|
||||
namespace Dalamud.Utility.TerraFxCom;
|
||||
|
||||
/// <summary>Utilities for <see cref="IUnknown"/> and its derivatives.</summary>
|
||||
internal static unsafe partial class TerraFxComInterfaceExtensions
|
||||
{
|
||||
/// <summary>Creates a new instance of <see cref="IStream"/> from a file path.</summary>
|
||||
/// <param name="path">The file path.</param>
|
||||
/// <param name="mode">The file open mode.</param>
|
||||
/// <param name="access">The file access mode.</param>
|
||||
/// <param name="share">The file share mode.</param>
|
||||
/// <param name="attributes">The file attributes.</param>
|
||||
/// <returns>The new instance of <see cref="IStream"/>.</returns>
|
||||
public static ComPtr<IStream> CreateIStreamFromFile(
|
||||
string path,
|
||||
FileMode mode,
|
||||
FileAccess access,
|
||||
FileShare share,
|
||||
FileAttributes attributes = FileAttributes.Normal)
|
||||
{
|
||||
var grfMode = 0u;
|
||||
bool fCreate;
|
||||
switch (mode)
|
||||
{
|
||||
case FileMode.CreateNew:
|
||||
fCreate = true;
|
||||
grfMode |= STGM.STGM_FAILIFTHERE;
|
||||
break;
|
||||
case FileMode.Create:
|
||||
fCreate = true;
|
||||
grfMode |= STGM.STGM_CREATE;
|
||||
break;
|
||||
case FileMode.Open:
|
||||
fCreate = false;
|
||||
grfMode |= STGM.STGM_FAILIFTHERE; // yes
|
||||
break;
|
||||
case FileMode.OpenOrCreate:
|
||||
throw new NotSupportedException(
|
||||
$"${FileMode.OpenOrCreate} is not supported. It might be, but it needs testing.");
|
||||
case FileMode.Append:
|
||||
throw new NotSupportedException($"${FileMode.Append} is not supported.");
|
||||
case FileMode.Truncate:
|
||||
throw new NotSupportedException($"${FileMode.Truncate} is not supported.");
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
|
||||
}
|
||||
|
||||
switch (access)
|
||||
{
|
||||
case FileAccess.Read:
|
||||
grfMode |= STGM.STGM_READ;
|
||||
break;
|
||||
case FileAccess.Write:
|
||||
grfMode |= STGM.STGM_WRITE;
|
||||
break;
|
||||
case FileAccess.ReadWrite:
|
||||
grfMode |= STGM.STGM_READWRITE;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(access), access, null);
|
||||
}
|
||||
|
||||
switch (share)
|
||||
{
|
||||
case FileShare.None:
|
||||
grfMode |= STGM.STGM_SHARE_EXCLUSIVE;
|
||||
break;
|
||||
case FileShare.Read:
|
||||
grfMode |= STGM.STGM_SHARE_DENY_WRITE;
|
||||
break;
|
||||
case FileShare.Write:
|
||||
grfMode |= STGM.STGM_SHARE_DENY_READ;
|
||||
break;
|
||||
case FileShare.ReadWrite:
|
||||
grfMode |= STGM.STGM_SHARE_DENY_NONE;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"Only ${FileShare.Read} and ${FileShare.Write} are supported.");
|
||||
}
|
||||
|
||||
using var stream = default(ComPtr<IStream>);
|
||||
fixed (char* pPath = path)
|
||||
{
|
||||
SHCreateStreamOnFileEx(
|
||||
(ushort*)pPath,
|
||||
grfMode,
|
||||
(uint)attributes,
|
||||
fCreate,
|
||||
null,
|
||||
stream.GetAddressOf()).ThrowOnError();
|
||||
}
|
||||
|
||||
var res = default(ComPtr<IStream>);
|
||||
stream.As(ref res).ThrowOnError();
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>Calls <see cref="IPropertyBag2.Write"/>.</summary>
|
||||
/// <param name="obj">The property bag.</param>
|
||||
/// <param name="name">The name of the item to be interpreted as a VARIANT.</param>
|
||||
/// <param name="value">The new value, to be interpreted as a <see cref="VARIANT"/>.</param>
|
||||
/// <returns>Return value from <inheritdoc cref="IPropertyBag2.Write"/>.</returns>
|
||||
public static HRESULT Write(ref this IPropertyBag2 obj, string name, object? value)
|
||||
{
|
||||
VARIANT varValue;
|
||||
// Marshal calls VariantInit.
|
||||
Marshal.GetNativeVariantForObject(value, (nint)(&varValue));
|
||||
try
|
||||
{
|
||||
fixed (char* pName = name)
|
||||
{
|
||||
var option = new PROPBAG2 { pstrName = (ushort*)pName };
|
||||
return obj.Write(1, &option, &varValue);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
VariantClear(&varValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Calls <inheritdoc cref="IWICMetadataQueryWriter.SetMetadataByName"/>.</summary>
|
||||
/// <param name="obj">The object.</param>
|
||||
/// <param name="name">The name of the metadata.</param>
|
||||
/// <param name="value">The new value, to be interpreted as a <see cref="PROPVARIANT"/>.</param>
|
||||
/// <returns>Return value from <inheritdoc cref="IWICMetadataQueryWriter.SetMetadataByName"/>.</returns>
|
||||
public static HRESULT SetMetadataByName(ref this IWICMetadataQueryWriter obj, string name, object? value)
|
||||
{
|
||||
VARIANT varValue;
|
||||
// Marshal calls VariantInit.
|
||||
Marshal.GetNativeVariantForObject(value, (nint)(&varValue));
|
||||
try
|
||||
{
|
||||
PROPVARIANT propVarValue;
|
||||
var propVarRes = VariantToPropVariant(&varValue, &propVarValue);
|
||||
if (propVarRes < 0)
|
||||
return propVarRes;
|
||||
|
||||
try
|
||||
{
|
||||
fixed (char* pName = name)
|
||||
return obj.SetMetadataByName((ushort*)pName, &propVarValue);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_ = PropVariantClear(&propVarValue);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_ = VariantClear(&varValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Calls <inheritdoc cref="IWICMetadataQueryWriter.SetMetadataByName"/>.</summary>
|
||||
/// <param name="obj">The object.</param>
|
||||
/// <param name="name">The name of the metadata.</param>
|
||||
/// <returns>Return value from <inheritdoc cref="IWICMetadataQueryWriter.SetMetadataByName"/>.</returns>
|
||||
public static HRESULT RemoveMetadataByName(ref this IWICMetadataQueryWriter obj, string name)
|
||||
{
|
||||
fixed (char* pName = name)
|
||||
return obj.RemoveMetadataByName((ushort*)pName);
|
||||
}
|
||||
|
||||
[LibraryImport("propsys.dll")]
|
||||
private static partial int VariantToPropVariant(
|
||||
void* pVarIn,
|
||||
void* pPropVarOut);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue