Skip to content
This repository has been archived by the owner on Jul 26, 2023. It is now read-only.

Add cabinet API #471

Merged
merged 6 commits into from
Jul 1, 2020
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,16 @@ Library | Package name | NuGet | Description
-------------|------------------|-------------|-------------
advapi32.dll |`PInvoke.AdvApi32`| [![NuGet](https://buildstats.info/nuget/PInvoke.AdvApi32)](https://www.nuget.org/packages/PInvoke.AdvApi32)|Windows Advanced Services
bcrypt.dll |`PInvoke.BCrypt` | [![NuGet](https://buildstats.info/nuget/PInvoke.BCrypt)](https://www.nuget.org/packages/PInvoke.BCrypt)|[Windows Cryptography API: Next Generation][CNG]
cabinet.dll |`PInvoke.Cabinet` | [![NuGet](https://buildstats.info/nuget/PInvoke.Cabinet)](https://www.nuget.org/packages/PInvoke.Cabinet)|[Cabinet API Functions][Cabinet]
crypt32.dll |`PInvoke.Crypt32` | [![NuGet](https://buildstats.info/nuget/PInvoke.Crypt32)](https://www.nuget.org/packages/PInvoke.Crypt32)|[Windows Cryptography API][Crypt32]
DwmApi.dll |`PInvoke.DwmApi` | [![NuGet](https://buildstats.info/nuget/PInvoke.DwmApi)](https://www.nuget.org/packages/PInvoke.DwmApi)|[Desktop Window Manager][DwmApi]
fusion.dll |`PInvoke.Fusion` | [![NuGet](https://buildstats.info/nuget/PInvoke.Fusion)](https://www.nuget.org/packages/PInvoke.Fusion)|.NET Framework Fusion
gdi32.dll |`PInvoke.Gdi32` | [![NuGet](https://buildstats.info/nuget/PInvoke.Gdi32)](https://www.nuget.org/packages/PInvoke.Gdi32)|[Windows Graphics Device Interface][Gdi]
hid.dll |`PInvoke.Hid` | [![NuGet](https://buildstats.info/nuget/PInvoke.Hid)](https://www.nuget.org/packages/PInvoke.Hid)|[Windows Human Interface Devices][Hid]
kernel32.dll |`PInvoke.Kernel32`| [![NuGet](https://buildstats.info/nuget/PInvoke.Kernel32)](https://www.nuget.org/packages/PInvoke.Kernel32)|Windows Kernel API
magnification.dll |`PInvoke.Magnification`| [![NuGet](https://buildstats.info/nuget/PInvoke.Magnification)](https://www.nuget.org/packages/PInvoke.Magnification)|[Windows Magnification API][Magnification]
mscoree.dll |`PInvoke.MSCorEE` | [![NuGet](https://buildstats.info/nuget/PInvoke.MSCorEE)](https://www.nuget.org/packages/PInvoke.MSCorEE)|.NET Framework CLR host
msi.dll |`PInvoke.Msi` | [![NuGet](https://buildstats.info/nuget/PInvoke.Msi)](https://www.nuget.org/packages/PInvoke.Msi)|[Microsoft Installer][Msi]
fusion.dll |`PInvoke.Fusion` | [![NuGet](https://buildstats.info/nuget/PInvoke.Fusion)](https://www.nuget.org/packages/PInvoke.Fusion)|.NET Framework Fusion
ncrypt.dll |`PInvoke.NCrypt` | [![NuGet](https://buildstats.info/nuget/PInvoke.NCrypt)](https://www.nuget.org/packages/PInvoke.NCrypt)|[Windows Cryptography API: Next Generation][CNG]
netapi32.dll |`PInvoke.NetApi32`| [![NuGet](https://buildstats.info/nuget/PInvoke.NetApi32)](https://www.nuget.org/packages/PInvoke.NetApi32)|[Network Management][NetApi32]
ntdll.dll |`PInvoke.NTDll` | [![NuGet](https://buildstats.info/nuget/PInvoke.NTDll)](https://www.nuget.org/packages/PInvoke.NTDll)|Windows NTDll
Expand Down Expand Up @@ -126,5 +127,6 @@ For more information see the [.NET Foundation Code of Conduct](https://dotnetfou
[NetApi32]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa370680.aspx
[Shell32]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb773177.aspx
[WtsApi32]: https://msdn.microsoft.com/en-us/library/aa383468(v=vs.85).aspx
[Cabinet]: https://docs.microsoft.com/en-us/windows/win32/devnotes/cabinet-api-functions

[PInvokeCoverageReport]: https://github.com/dotnet/pinvoke/wiki/coverage
10 changes: 10 additions & 0 deletions src/Cabinet.Tests/Cabinet.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netcoreapp2.1</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Cabinet\Cabinet.csproj" />
<ProjectReference Include="..\Kernel32\Kernel32.csproj" />
<ProjectReference Include="..\Windows.Core\Windows.Core.csproj" />
</ItemGroup>
</Project>
104 changes: 104 additions & 0 deletions src/Cabinet.Tests/CabinetFacts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.IO;
using System.Runtime.InteropServices;
using PInvoke;
using Xunit;

public unsafe class CabinetFacts : IDisposable
{
private readonly Cabinet.FNALLOC fdiAllocMemDelegate;
private readonly Cabinet.FNFREE fdiFreeMemDelegate;
private readonly Cabinet.FNOPEN fdiOpenStreamDelegate;
private readonly Cabinet.FNREAD fdiReadStreamDelegate;
private readonly Cabinet.FNWRITE fdiWriteStreamDelegate;
private readonly Cabinet.FNCLOSE fdiCloseStreamDelegate;
private readonly Cabinet.FNSEEK fdiSeekStreamDelegate;

private readonly Cabinet.ERF* erf;

public CabinetFacts()
{
this.erf = (Cabinet.ERF*)Marshal.AllocHGlobal(sizeof(Cabinet.ERF));

this.fdiAllocMemDelegate = this.AllocMem;
this.fdiFreeMemDelegate = this.FreeMem;
this.fdiOpenStreamDelegate = this.Open;
this.fdiReadStreamDelegate = this.Read;
this.fdiWriteStreamDelegate = this.Write;
this.fdiCloseStreamDelegate = this.Close;
this.fdiSeekStreamDelegate = this.Seek;
}

[Fact]
public void CreateDisposeContext()
{
var handle = Cabinet.FDICreate(
this.fdiAllocMemDelegate,
this.fdiFreeMemDelegate,
this.fdiOpenStreamDelegate,
this.fdiReadStreamDelegate,
this.fdiWriteStreamDelegate,
this.fdiCloseStreamDelegate,
this.fdiSeekStreamDelegate,
Cabinet.CpuType.Unknown,
this.erf);

handle.Dispose();
}

public void Dispose()
{
Marshal.FreeHGlobal((IntPtr)this.erf);
}

private IntPtr AllocMem(int byteCount) => Marshal.AllocHGlobal((IntPtr)byteCount);

private void FreeMem(IntPtr memPointer) => Marshal.FreeHGlobal(memPointer);

private int Open(string path, int openFlags, int shareMode)
{
var handle = Kernel32.CreateFile(path, (Kernel32.ACCESS_MASK)Kernel32.ACCESS_MASK.GenericRight.GENERIC_READ, Kernel32.FileShare.FILE_SHARE_READ, IntPtr.Zero, Kernel32.CreationDisposition.OPEN_EXISTING, Kernel32.CreateFileFlags.FILE_ATTRIBUTE_NORMAL, Kernel32.SafeObjectHandle.Null);
return (int)handle.DangerousGetHandle();
}

private int Read(int streamHandle, void* memory, int cb)
{
int? read = 0;
Kernel32.ReadFile(
new Kernel32.SafeObjectHandle(new IntPtr(streamHandle), ownsHandle: false),
memory,
cb,
ref read,
null);
return read.Value;
}

private int Write(int streamHandle, void* memory, int cb)
{
int? written = 0;
Kernel32.WriteFile(
new Kernel32.SafeObjectHandle(new IntPtr(streamHandle), ownsHandle: false),
memory,
cb,
ref written,
null);
return written.Value;
}

private uint Seek(int streamHandle, int offset, SeekOrigin seekOrigin)
{
return Kernel32.SetFilePointer(
new Kernel32.SafeObjectHandle(new IntPtr(streamHandle)),
offset,
out long _,
seekOrigin) ? 0u : 1u;
}

private uint Close(int streamHandle)
{
return Kernel32.CloseHandle(new IntPtr(streamHandle)) ? 0u : 1u;
}
}
35 changes: 35 additions & 0 deletions src/Cabinet/Cabinet+CpuType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
using System.Diagnostics.CodeAnalysis;

/// <content>
/// Contains the <see cref="CpuType"/> nested type.
/// </content>
public partial class Cabinet
{
/// <summary>
/// In the 16-bit version of FDI, specifies the CPU type and can be any of the following values.
/// </summary>
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element must begin with upper-case letter", Justification = "Native naming convention")]
public enum CpuType : int
{
/// <summary>
/// FDI should determine the CPU type.
/// </summary>
Unknown = -1,

/// <summary>
/// Only 80286 instructions can be used.
/// </summary>
_80286 = 0,

/// <summary>
/// 80386 instructions can be used.
/// </summary>
_80386 = 1,
}
}
}
33 changes: 33 additions & 0 deletions src/Cabinet/Cabinet+ERF.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
/// <content>
/// Contains the <see cref="ERF"/> nested type.
/// </content>
public partial class Cabinet
{
/// <summary>
/// The ERF structure contains error information from FCI/FDI. The caller should not modify this structure.
/// </summary>
/// <seealso href="https://docs.microsoft.com/en-us/windows/win32/api/fdi_fci_types/ns-fdi_fci_types-erf"/>
public struct ERF
{
/// <summary>
/// An FCI/FDI error code.
/// </summary>
public FdiError Oper;

/// <summary>
/// An optional error value filled in by FCI/FDI. For FCI, this is usually the C runtime errno value.
/// </summary>
public int Type;

/// <summary>
/// A flag that indicates an error. If <see langword="true"/>, an error is present.
/// </summary>
public int Error;
}
}
}
78 changes: 78 additions & 0 deletions src/Cabinet/Cabinet+FdiError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
/// <content>
/// Contains the <see cref="FdiError"/> nested type.
/// </content>
public partial class Cabinet
{
/// <summary>
/// Error values for FDI.
/// </summary>
/// <seealso href="https://docs.microsoft.com/en-us/windows/win32/api/fdi_fci_types/ns-fdi_fci_types-erf#members"/>
public enum FdiError : int
{
/// <summary>
/// No error.
/// </summary>
FDIERROR_NONE = 0x00,

/// <summary>
/// The cabinet file was not found.
/// </summary>
FDIERROR_CABINET_NOT_FOUND = 0x01,

/// <summary>
/// The cabinet file does not have the correct format.
/// </summary>
FDIERROR_NOT_A_CABINET = 0x02,

/// <summary>
/// The cabinet file has an unknown version number.
/// </summary>
FDIERROR_UNKNOWN_CABINET_VERSION = 0x03,

/// <summary>
/// The cabinet file is corrupt.
/// </summary>
FDIERROR_CORRUPT_CABINET = 0x04,

/// <summary>
/// Insufficient memory.
/// </summary>
FDIERROR_ALLOC_FAIL = 0x05,

/// <summary>
/// Unknown compression type used in the cabinet folder.
/// </summary>
FDIERROR_BAD_COMPR_TYPE = 0x06,

/// <summary>
/// Failure decompressing data from the cabinet file.
/// </summary>
FDIERROR_MDI_FAIL = 0x07,

/// <summary>
/// Failure writing to the target file.
/// </summary>
FDIERROR_TARGET_FILE = 0x08,

/// <summary>
/// The cabinets within a set do not have the same RESERVE sizes.
/// </summary>
FDIERROR_RESERVE_MISMATCH = 0x09,

/// <summary>
/// The cabinet returned by fdintNEXT_CABINET is incorrect.
/// </summary>
FDIERROR_WRONG_CABINET = 0x0A,

/// <summary>
/// FDI aborted.
/// </summary>
FDIERROR_USER_ABORT = 0x0B,
}
}
}
33 changes: 33 additions & 0 deletions src/Cabinet/Cabinet+FdiHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright © .NET Foundation and Contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace PInvoke
{
using Microsoft.Win32.SafeHandles;

/// <content>
/// Contains the <see cref="FdiHandle"/> nested type.
/// </content>
public partial class Cabinet
{
/// <summary>
/// Represents a handle used by the FDI API.
/// </summary>
public class FdiHandle : SafeHandleZeroOrMinusOneIsInvalid
{
/// <summary>
/// Initializes a new instance of the <see cref="FdiHandle"/> class.
/// </summary>
public FdiHandle()
: base(true)
{
}

/// <inheritdoc/>
protected override bool ReleaseHandle()
{
return Cabinet.FDIDestroy(this.handle);
}
}
}
}
Loading