Added support for BITS peer caching

pull/328/head
dahall 2022-07-25 14:09:39 -06:00
parent 294b956f83
commit 2f98621983
6 changed files with 429 additions and 3 deletions

View File

@ -492,6 +492,19 @@ namespace Vanara.IO
[DefaultValue(false)]
public bool OwnerIsElevated => RunAction(() => IJob4.GetOwnerElevationState());
/// <summary>
/// Gets or sets flags that determine if the files of the job can be cached and served to peers and if BITS can download content for
/// the job from peers.
/// </summary>
/// <returns>
/// Flags that determine if the files of the job can be cached and served to peers and if BITS can download content for the job from peers.
/// </returns>
public PeerCaching PeerCachingEnablment
{
get => (PeerCaching)IJob4.GetPeerCachingFlags();
set => IJob4.SetPeerCachingFlags((BG_JOB_ENABLE_PEERCACHING)value);
}
/// <summary>
/// Gets or sets the priority level for the job. The priority level determines when the job is processed relative to other jobs in
/// the transfer queue.

View File

@ -50,7 +50,7 @@ namespace Vanara.IO
}
}
private static IBackgroundCopyManager IMgr => ciMgr.Item;
internal static IBackgroundCopyManager IMgr => ciMgr.Item;
/// <summary>Copies an existing file to a new file using BITS. Overwriting a file of the same name is not allowed.</summary>
/// <param name="sourceFileName">The file to copy.</param>

View File

@ -157,6 +157,60 @@ namespace Vanara.IO
Proxy = BG_AUTH_TARGET.BG_AUTH_TARGET_PROXY
}
/// <summary>
/// Flags that determine if the files of the job can be cached and served to peers and if BITS can download content for the job from peers.
/// </summary>
[Flags]
public enum BackgroundCopyJobEnablePeerCaching
{
/// <summary>
/// The job can download content from peers.
/// <para>
/// The job will not download from a peer unless both the client computer and the job allow Background Intelligent Transfer Service
/// (BITS) to download files from a peer. To enable the client computer to download files from a peer, set the EnablePeerCaching
/// group policy or call the <see cref="PeerCacheAdministration.ConfigurationFlags"/> property and set the <see
/// cref="PeerCaching.Enable"/> flag.
/// </para>
/// <para>
/// If one of the following conditions exists, BITS will stop the download and reschedule the job to begin transferring from either a
/// peer or the origin server, depending on the value for the job and the cache:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// This value for the cache is <see langword="true"/> and the value for the job toggles between <see langword="true"/> and <see langword="false"/>.
/// </term>
/// </item>
/// <item>
/// <term>
/// This value for the job property is <see langword="true"/> and the value for the cache toggles between <see langword="true"/> and
/// <see langword="false"/>.
/// </term>
/// </item>
/// </list>
/// <para>The download will then resume from where it left off before BITS stopped the job.</para>
/// <para><c>BITS 4.0:</c> This flag is deprecated.</para>
/// </summary>
EnableClient = BG_JOB_ENABLE_PEERCACHING.BG_JOB_ENABLE_PEERCACHING_CLIENT,
/// <summary>
/// The files of the job can be cached and served to peers.
/// <para>
/// BITS will not cache the files and serve them to peers unless both the client computer and job allow BITS to cache and serve the
/// files. To allow BITS to cache and serve the files on the client computer, set the EnablePeerCaching group policy or call the <see
/// cref="PeerCacheAdministration.ConfigurationFlags"/> property and set the <see cref="PeerCaching.EnableServer"/> flag.
/// </para>
/// <para><c>BITS 4.0:</c> This flag is deprecated.</para>
/// </summary>
EnableServer = BG_JOB_ENABLE_PEERCACHING.BG_JOB_ENABLE_PEERCACHING_SERVER,
/// <summary>
/// BITS will not use Windows BranchCache for transfer jobs. This setting does not affect the use of Windows BranchCache by
/// applications other than BITS.
/// </summary>
DisableBranchCache = BG_JOB_ENABLE_PEERCACHING.BG_JOB_DISABLE_BRANCH_CACHE,
}
/// <summary>Defines the constant values that specify the priority level of a job.</summary>
public enum BackgroundCopyJobPriority
{
@ -294,4 +348,47 @@ namespace Vanara.IO
/// <summary>Specifies that the job uploads a file to the server and receives a reply file from the server application.</summary>
UploadReply = BG_JOB_TYPE.BG_JOB_TYPE_UPLOAD_REPLY
}
/// <summary>Flags that determine if the computer serves content to peers and can download content from peers.</summary>
[Flags]
public enum PeerCaching
{
/// <summary>
/// The computer can download content from peers.
/// <para>
/// BITS will not download files from a peer unless both the client computer and the job permit BITS to download files from a peer.
/// To permits the job to download files from a peer, use the <see cref="BackgroundCopyJob.PeerCachingEnablment"/> property and set
/// the <see cref="BackgroundCopyJobEnablePeerCaching.EnableClient"/> flag.
/// </para>
/// <para>
/// Note that changing this value can affect all jobs on the computer. If one of the following conditions exists, BITS will stop the
/// download and reschedule the job to begin transferring from either a peer or the origin server, depending on the value for the job
/// and the cache:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// This value for the cache is <see langword="true"/> and the value for the job toggles between <see langword="true"/> and <see langword="false"/>.
/// </term>
/// </item>
/// <item>
/// <term>
/// This value for the job property is <see langword="true"/> and the value for the cache toggles between <see langword="true"/> and
/// <see langword="false"/>.
/// </term>
/// </item>
/// </list>
/// <para>The download will then resume from where it left off before BITS stopped the job.</para>
/// </summary>
Enable = BG_ENABLE_PEERCACHING.BG_ENABLE_PEERCACHING_CLIENT,
/// <summary>
/// The computer can serve content to peers.
/// <para>
/// BITS will not cache the files and serve them to peers unless both the client computer and job permit BITS to cache and serve
/// files. To permit the job to cache files for a job, use the <see cref="BackgroundCopyJob.PeerCachingEnablment"/> property and set
/// the <see cref="BackgroundCopyJobEnablePeerCaching.EnableServer"/> flag.
/// </para>
/// </summary>
EnableServer = BG_ENABLE_PEERCACHING.BG_ENABLE_PEERCACHING_SERVER,
}
}

View File

@ -0,0 +1,191 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Vanara.Collections;
using Vanara.Extensions;
using Vanara.InteropServices;
using Vanara.PInvoke;
using static Vanara.PInvoke.BITS;
namespace Vanara.IO;
/// <summary>Use <c>PeerCacheAdministration</c> to manage the pool of peers from which you can download content.</summary>
public static class PeerCacheAdministration
{
internal static readonly ComReleaser<IBitsPeerCacheAdministration> ciCacheAdmin = ComReleaserFactory.Create((IBitsPeerCacheAdministration)BackgroundCopyManager.IMgr);
/// <summary>
/// Gets or sets the configuration flags that determine if the computer serves content to peers and can download content from peers.
/// </summary>
/// <value>Flags that determine if the computer serves content to peers and can download content from peers.</value>
public static PeerCaching ConfigurationFlags
{
get => (PeerCaching)ciCacheAdmin.Item.GetConfigurationFlags();
set => ciCacheAdmin.Item.SetConfigurationFlags((BG_ENABLE_PEERCACHING)value);
}
/// <summary>Gets or sets the maximum size of the cache.</summary>
/// <value>Maximum size of the cache, as a percentage of available hard disk drive space.</value>
public static uint MaximumCacheSize
{
get => ciCacheAdmin.Item.GetMaximumCacheSize();
set => ciCacheAdmin.Item.SetMaximumCacheSize(value);
}
/// <summary>Gets or sets the age by when files are removed from the cache.</summary>
/// <value>Age. If the last time that the file was accessed is older than this age, BITS removes the file from the cache.</value>
public static TimeSpan MaximumContentAge
{
get => TimeSpan.FromSeconds(ciCacheAdmin.Item.GetMaximumContentAge());
set => ciCacheAdmin.Item.SetMaximumContentAge((uint)value.TotalSeconds);
}
/// <summary>Gets a <see cref="CachePeers"/> instance that you use to enumerate the peers that can serve content.</summary>
/// <value>A <see cref="CachePeers"/> instance that you use to enumerate the peers that can serve content.</value>
public static CachePeers Peers { get; } = new CachePeers();
/// <summary>
/// Gets a <see cref="PeerCacheRecords"/> instance that you use to enumerate the records in the cache. The enumeration is a snapshot of
/// the records in the cache.
/// </summary>
/// <value>A <see cref="PeerCacheRecords"/> instance that you use to enumerate the records in the cache.</value>
public static PeerCacheRecords Records { get; } = new PeerCacheRecords();
/// <summary>Deletes all cache records and the file from the cache for the given URL.</summary>
/// <param name="url">
/// Null-terminated string that contains the URL of the file whose cache records and file you want to delete from the cache.
/// </param>
public static void DeleteUrl(string url) => ciCacheAdmin.Item.DeleteUrl(url);
/// <summary>Provides the ability to enumerate the list of peers that BITS has discovered.</summary>
public class CachePeers : IReadOnlyCollection<CachePeer>
{
/// <summary>Gets the number of elements in the collection.</summary>
public int Count => EnumPeers().Count();
/// <summary>Removes all peers from the list of peers that can serve content.</summary>
public static void Clear() => ciCacheAdmin.Item.ClearPeers();
/// <summary>Returns an enumerator that iterates through the collection.</summary>
/// <returns>An enumerator that can be used to iterate through the collection.</returns>
public IEnumerator<CachePeer> GetEnumerator()
{
ciCacheAdmin.Item.DiscoverPeers();
return EnumPeers().GetEnumerator();
}
/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private IEnumerable<CachePeer> EnumPeers() => IEnumFromCom<IBitsPeer>.Create(ciCacheAdmin.Item.EnumPeers()).Select(i => new CachePeer(i));
}
/// <summary>Provides the ability to enumerate the records of the cache.</summary>
public class PeerCacheRecords : IReadOnlyList<PeerCacheRecord>
{
internal PeerCacheRecords() { }
/// <summary>Gets the number of elements in the collection.</summary>
public int Count => EnumRecords().Count();
/// <summary>Gets the <see cref="PeerCacheRecord"/> at the specified index.</summary>
/// <value>The <see cref="PeerCacheRecord"/>.</value>
/// <param name="index">The index.</param>
/// <returns>A <see cref="PeerCacheRecord"/> instance of the cache record.</returns>
public PeerCacheRecord this[int index] => EnumRecords().ElementAt(index);
/// <summary>Gets a record from the cache.</summary>
/// <param name="id">Identifier of the record to get from the cache.</param>
/// <returns>A <see cref="PeerCacheRecord"/> instance of the cache record.</returns>
public PeerCacheRecord this[Guid id] => new(ciCacheAdmin.Item.GetRecord(id));
/// <summary>Removes all the records and files from the cache.</summary>
public void Clear() => ciCacheAdmin.Item.ClearRecords();
/// <summary>Determines whether this collection contains the specified record.</summary>
/// <param name="item">The record.</param>
/// <returns><see langword="true"/> if the specified item is contained in the collection; otherwise, <see langword="false"/>.</returns>
public bool Contains(PeerCacheRecord item) => EnumRecords().Contains(item);
/// <summary>Returns an enumerator that iterates through the collection.</summary>
/// <returns>An enumerator that can be used to iterate through the collection.</returns>
public IEnumerator<PeerCacheRecord> GetEnumerator() => EnumRecords().GetEnumerator();
/// <summary>Searches for the specified record and returns the zero-based index of the first occurrence within the colection.</summary>
/// <param name="item">The record to locate in the collection. The value can be <see langword="null"/>.</param>
/// <returns>The zero-based index of the first occurrence of <paramref name="item"/> within the entire collection, if found; otherwise, -1.</returns>
public int IndexOf(PeerCacheRecord item) => EnumRecords().SelectMany((value, index) => value == item ? new[] { index } : Enumerable.Empty<int>()).DefaultIfEmpty(-1).First();
/// <summary>Deletes a record and file from the cache.</summary>
/// <param name="item">The record to delete from the cache.</param>
public bool Remove(PeerCacheRecord item) { try { ciCacheAdmin.Item.DeleteRecord(item.Id); return true; } catch { return false; } }
/// <summary>Removes the element at the specified index of the collection.</summary>
/// <param name="index">The zero-based index of the element to remove.</param>
public void RemoveAt(int index) => Remove(EnumRecords().ElementAt(index));
/// <inheritdoc/>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private IEnumerable<PeerCacheRecord> EnumRecords() => IEnumFromCom<IBitsPeerCacheRecord>.Create(ciCacheAdmin.Item.EnumRecords()).Select(i => new PeerCacheRecord(i));
}
}
/// <summary>Provides information about a peer in the neighborhood.</summary>
public class CachePeer
{
private readonly ComReleaser<IBitsPeer> ciPeer;
internal CachePeer(IBitsPeer peer) => ciPeer = ComReleaserFactory.Create(peer);
private CachePeer() => throw new NotImplementedException();
/// <summary>Determines whether the peer is authenticated.</summary>
/// <returns><see langword="true"/> if the peer is authenticated, otherwise, <see langword="false"/>.</returns>
public bool IsAuthenticated => ciPeer.Item.IsAuthenticated();
/// <summary>Determines whether the peer is available (online) to serve content.</summary>
/// <returns><see langword="true"/> if the peer is available to serve content, otherwise, <see langword="false"/>.</returns>
public bool IsAvailable => ciPeer.Item.IsAvailable();
/// <summary>Gets the server principal name that uniquely identifies the peer.</summary>
/// <returns>The server principal name of the peer. The principal name is of the form, server$.domain.suffix.</returns>
public string Name => ciPeer.Item.GetPeerName();
}
/// <summary>Provides information about a file in the BITS peer cache.</summary>
public class PeerCacheRecord
{
private readonly ComReleaser<IBitsPeerCacheRecord> ciRecord;
internal PeerCacheRecord(IBitsPeerCacheRecord bitsPeerCacheRecord) => ciRecord = ComReleaserFactory.Create(bitsPeerCacheRecord);
private PeerCacheRecord() => throw new NotImplementedException();
/// <summary>Gets the date and time that the file was last modified on the server.</summary>
/// <value>Date and time that the file was last modified on the server.</value>
public DateTime FileModificationTime => ciRecord.Item.GetFileModificationTime().ToDateTime();
/// <summary>Gets the ranges of the file that are in the cache.</summary>
/// <value>Array of structures that specify the ranges of the file that are in the cache.</value>
public BackgroundCopyFileRange[] FileRanges => Array.ConvertAll(ciRecord.Item.GetFileRanges(), i => (BackgroundCopyFileRange)i);
/// <summary>Gets the size of the file.</summary>
/// <value>Size of the file, in bytes.</value>
public ulong FileSize => ciRecord.Item.GetFileSize();
/// <summary>Gets the record identifier.</summary>
/// <value>The identifier.</value>
public Guid Id => ciRecord.Item.GetId();
/// <summary>Determines whether the file has been validated.</summary>
/// <value><see langword="true"/> if file has been validated; otherwise <see langword="false"/>.</value>
public bool IsFileValidated => ciRecord.Item.IsFileValidated() == HRESULT.S_OK;
/// <summary>Gets the date and time that the file was last accessed.</summary>
/// <value>Date and time that the file was last accessed.</value>
public DateTime LastAccessTime => ciRecord.Item.GetLastAccessTime().ToDateTime();
/// <summary>Gets the origin URL of the cached file.</summary>
/// <value>String that contains the origin URL of the cached file.</value>
public string OriginUrl => ciRecord.Item.GetOriginUrl();
}

View File

@ -19,6 +19,7 @@ BackgroundCopyACLFlags, BackgroundCopyCost, BackgroundCopyErrorContext, Backgrou
</PackageReleaseNotes>
<PackageReadmeFile>pkgreadme.md</PackageReadmeFile>
<RootNamespace>Vanara.IO</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PInvoke\BITS\Vanara.PInvoke.BITS.csproj" />

View File

@ -134,6 +134,7 @@ namespace Vanara.PInvoke
}
/// <summary>Flags that determine if the computer serves content to peers and can download content from peers.</summary>
[Flags]
public enum BG_ENABLE_PEERCACHING
{
/// <summary>
@ -258,6 +259,7 @@ namespace Vanara.PInvoke
/// <summary>
/// Flags that determine if the files of the job can be cached and served to peers and if BITS can download content for the job from peers.
/// </summary>
[Flags]
public enum BG_JOB_ENABLE_PEERCACHING
{
/// <summary>
@ -2856,9 +2858,50 @@ namespace Vanara.PInvoke
/// Sets flags that determine if the files of the job can be cached and served to peers and if the job can download content from peers.
/// </summary>
/// <param name="Flags">
/// <para>
/// Flags that determine if the files of the job can be cached and served to peers and if the job can download content from
/// peers. The following flags can be set:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_CLIENT</c> 0x0001</term>
/// <term>
/// The job can download content from peers. The job will not download from a peer unless both the client computer and the job
/// allow Background Intelligent Transfer Service (BITS) to download files from a peer. To enable the client computer to download
/// files from a peer, set the EnablePeerCaching group policy or call the IBitsPeerCacheAdministration::SetConfigurationFlags
/// method and set the BG_ENABLE_PEERCACHING_CLIENT flag. If one of the following conditions exists, BITS will stop the download
/// and reschedule the job to begin transferring from either a peer or the origin server, depending on the value for the job and
/// the cache:The download will then resume from where it left off before BITS stopped the job. <c>BITS 4.0:</c> This flag is deprecated.
/// </term>
/// </item>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_SERVER</c> 0x0002</term>
/// <term>
/// The files of the job can be cached and served to peers. BITS will not cache the files and serve them to peers unless both the
/// client computer and job allow BITS to cache and serve the files. To allow BITS to cache and serve the files on the client
/// computer, set the EnablePeerCaching group policy or call the IBitsPeerCacheAdministration::SetConfigurationFlags method and
/// set the BG_ENABLE_PEERCACHING_SERVER flag. <c>BITS 4.0:</c> This flag is deprecated.
/// </term>
/// </item>
/// <item>
/// <term><c>BG_JOB_DISABLE_BRANCH_CACHE</c> 0x0004</term>
/// <term>
/// BITS will not use Windows BranchCache for transfer jobs. This setting does not affect the use of Windows BranchCache by
/// applications other than BITS.
/// </term>
/// </item>
/// </list>
/// </param>
/// <remarks>
/// Setting these flags has meaning only if the peer caching has been enabled by either setting the EnablePeerCaching group
/// policy or calling the IBitsPeerCacheAdministration::SetConfigurationFlags.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/bits3_0/nf-bits3_0-ibackgroundcopyjob4-setpeercachingflags
// HRESULT SetPeerCachingFlags( [in] DWORD Flags );
void SetPeerCachingFlags(BG_JOB_ENABLE_PEERCACHING Flags);
/// <summary>
@ -2866,9 +2909,31 @@ namespace Vanara.PInvoke
/// the job from peers.
/// </summary>
/// <returns>
/// <para>
/// Flags that determine if the files of the job can be cached and served to peers and if BITS can download content for the job
/// from peers. The following flags can be set:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_CLIENT</c> 0x0001</term>
/// <term>The job can download content from peers.</term>
/// </item>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_SERVER</c> 0x0002</term>
/// <term>The files of the job can be cached and served to peers.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// BITS can download from peers only if peercaching is enabled both at the computer level and at the job level; this API affects
/// only the job level. For details, see IBackgroundCopyJob4::SetPeerCachingFlags.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/bits3_0/nf-bits3_0-ibackgroundcopyjob4-getpeercachingflags
// HRESULT GetPeerCachingFlags( [out] DWORD *pFlags );
BG_JOB_ENABLE_PEERCACHING GetPeerCachingFlags();
/// <summary>Gets the integrity level of the token of the owner that created or took ownership of the job.</summary>
@ -3291,9 +3356,48 @@ namespace Vanara.PInvoke
/// Sets flags that determine if the files of the job can be cached and served to peers and if the job can download content from peers.
/// </summary>
/// <param name="Flags">
/// <para>
/// Flags that determine if the files of the job can be cached and served to peers and if the job can download content from
/// peers. The following flags can be set:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_CLIENT</c> 0x0001</term>
/// <term>
/// The job can download content from peers. The job will not download from a peer unless both the client computer and the job
/// allow Background Intelligent Transfer Service (BITS) to download files from a peer. To enable the client computer to download
/// files from a peer, set the EnablePeerCaching group policy or call the IBitsPeerCacheAdministration::SetConfigurationFlags
/// method and set the BG_ENABLE_PEERCACHING_CLIENT flag. If one of the following conditions exists, BITS will stop the download
/// and reschedule the job to begin transferring from either a peer or the origin server, depending on the value for the job and
/// the cache:The download will then resume from where it left off before BITS stopped the job. <c>BITS 4.0:</c> This flag is deprecated.
/// </term>
/// </item>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_SERVER</c> 0x0002</term>
/// <term>
/// The files of the job can be cached and served to peers. BITS will not cache the files and serve them to peers unless both the
/// client computer and job allow BITS to cache and serve the files. To allow BITS to cache and serve the files on the client
/// computer, set the EnablePeerCaching group policy or call the IBitsPeerCacheAdministration::SetConfigurationFlags method and
/// set the BG_ENABLE_PEERCACHING_SERVER flag. <c>BITS 4.0:</c> This flag is deprecated.
/// </term>
/// </item>
/// <item>
/// <term><c>BG_JOB_DISABLE_BRANCH_CACHE</c> 0x0004</term>
/// <term>
/// BITS will not use Windows BranchCache for transfer jobs. This setting does not affect the use of Windows BranchCache by
/// applications other than BITS.
/// </term>
/// </item>
/// </list>
/// </param>
/// <remarks>
/// Setting these flags has meaning only if the peer caching has been enabled by either setting the EnablePeerCaching group
/// policy or calling the IBitsPeerCacheAdministration::SetConfigurationFlags.
/// </remarks>
new void SetPeerCachingFlags(BG_JOB_ENABLE_PEERCACHING Flags);
/// <summary>
@ -3301,9 +3405,29 @@ namespace Vanara.PInvoke
/// the job from peers.
/// </summary>
/// <returns>
/// <para>
/// Flags that determine if the files of the job can be cached and served to peers and if BITS can download content for the job
/// from peers. The following flags can be set:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_CLIENT</c> 0x0001</term>
/// <term>The job can download content from peers.</term>
/// </item>
/// <item>
/// <term><c>BG_JOB_ENABLE_PEERCACHING_SERVER</c> 0x0002</term>
/// <term>The files of the job can be cached and served to peers.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// BITS can download from peers only if peercaching is enabled both at the computer level and at the job level; this API affects
/// only the job level. For details, see IBackgroundCopyJob4::SetPeerCachingFlags.
/// </remarks>
new BG_JOB_ENABLE_PEERCACHING GetPeerCachingFlags();
/// <summary>Gets the integrity level of the token of the owner that created or took ownership of the job.</summary>
@ -4495,7 +4619,7 @@ namespace Vanara.PInvoke
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa964302(v=vs.85).aspx
[PInvokeData("Bits3_0.h", MSDNShortId = "aa964302")]
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("659CDEA4-489E-11D9-A9CD-000D56965251")]
public interface IEnumBitsPeerCacheRecords
public interface IEnumBitsPeerCacheRecords : Vanara.Collections.ICOMEnum<IBitsPeerCacheRecord>
{
/// <summary>
/// Retrieves a specified number of items in the enumeration sequence. If there are fewer than the requested number of elements
@ -4544,7 +4668,7 @@ namespace Vanara.PInvoke
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa964308(v=vs.85).aspx
[PInvokeData("Bits3_0.h", MSDNShortId = "aa964308")]
[ComImport, Guid("659CDEA5-489E-11D9-A9CD-000D56965251"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IEnumBitsPeers
public interface IEnumBitsPeers : Vanara.Collections.ICOMEnum<IBitsPeer>
{
/// <summary>
/// Retrieves a specified number of items in the enumeration sequence. If there are fewer than the requested number of elements