示例#1
0
        /// <summary>The <c>WNetEnumResources</c> function enumerates network resources.</summary>
        /// <param name="root">
        /// <para>
        /// Pointer to a <c>NETRESOURCE</c> structure that specifies the container to enumerate. If the dwScope parameter is not
        /// RESOURCE_GLOBALNET, this parameter must be <c>NULL</c>.
        /// </para>
        /// <para>
        /// If this parameter is <c>NULL</c>, the root of the network is assumed. (The system organizes a network as a hierarchy; the root is
        /// the topmost container in the network.)
        /// </para>
        /// <para>
        /// If this parameter is not <c>NULL</c>, it must point to a <c>NETRESOURCE</c> structure. This structure can be filled in by the
        /// application or it can be returned by a call to the <c>WNetEnumResource</c> function. The <c>NETRESOURCE</c> structure must
        /// specify a container resource; that is, the RESOURCEUSAGE_CONTAINER value must be specified in the dwUsage parameter.
        /// </para>
        /// <para>
        /// To enumerate all network resources, an application can begin the enumeration by calling <c>WNetOpenEnum</c> with the
        /// lpNetResource parameter set to <c>NULL</c>, and then use the returned handle to call <c>WNetEnumResource</c> to enumerate
        /// resources. If one of the resources in the <c>NETRESOURCE</c> array returned by the <c>WNetEnumResource</c> function is a
        /// container resource, you can call <c>WNetOpenEnum</c> to open the resource for further enumeration.
        /// </para>
        /// </param>
        /// <param name="dwScope">
        /// <para>Scope of the enumeration. This parameter can be one of the following values.</para>
        /// <para>
        /// <list type="table">
        /// <listheader>
        /// <term>Value</term>
        /// <term>Meaning</term>
        /// </listheader>
        /// <item>
        /// <term>RESOURCE_CONNECTED</term>
        /// <term>
        /// Enumerate all currently connected resources. The function ignores the dwUsage parameter. For more information, see the following
        /// Remarks section.
        /// </term>
        /// </item>
        /// <item>
        /// <term>RESOURCE_CONTEXT</term>
        /// <term>
        /// Enumerate only resources in the network context of the caller. Specify this value for a Network Neighborhood view. The function
        /// ignores the dwUsage parameter.
        /// </term>
        /// </item>
        /// <item>
        /// <term>RESOURCE_GLOBALNET</term>
        /// <term>Enumerate all resources on the network.</term>
        /// </item>
        /// <item>
        /// <term>RESOURCE_REMEMBERED</term>
        /// <term>Enumerate all remembered (persistent) connections. The function ignores the dwUsage parameter.</term>
        /// </item>
        /// </list>
        /// </para>
        /// </param>
        /// <param name="dwType">
        /// <para>Resource types to be enumerated. This parameter can be a combination of the following values.</para>
        /// <para>
        /// <list type="table">
        /// <listheader>
        /// <term>Value</term>
        /// <term>Meaning</term>
        /// </listheader>
        /// <item>
        /// <term>RESOURCETYPE_ANY</term>
        /// <term>All resources. This value cannot be combined with RESOURCETYPE_DISK or RESOURCETYPE_PRINT.</term>
        /// </item>
        /// <item>
        /// <term>RESOURCETYPE_DISK</term>
        /// <term>All disk resources.</term>
        /// </item>
        /// <item>
        /// <term>RESOURCETYPE_PRINT</term>
        /// <term>All print resources.</term>
        /// </item>
        /// </list>
        /// </para>
        /// <para>If a network provider cannot distinguish between print and disk resources, it can enumerate all resources.</para>
        /// </param>
        /// <param name="dwUsage">
        /// <para>Resource usage type to be enumerated. This parameter can be a combination of the following values.</para>
        /// <para>
        /// <list type="table">
        /// <listheader>
        /// <term>Value</term>
        /// <term>Meaning</term>
        /// </listheader>
        /// <item>
        /// <term>0</term>
        /// <term>All resources.</term>
        /// </item>
        /// <item>
        /// <term>RESOURCEUSAGE_CONNECTABLE</term>
        /// <term>All connectable resources.</term>
        /// </item>
        /// <item>
        /// <term>RESOURCEUSAGE_CONTAINER</term>
        /// <term>All container resources.</term>
        /// </item>
        /// <item>
        /// <term>RESOURCEUSAGE_ATTACHED</term>
        /// <term>
        /// Setting this value forces WNetOpenEnum to fail if the user is not authenticated. The function fails even if the network allows
        /// enumeration without authentication.
        /// </term>
        /// </item>
        /// <item>
        /// <term>RESOURCEUSAGE_ALL</term>
        /// <term>Setting this value is equivalent to setting RESOURCEUSAGE_CONNECTABLE, RESOURCEUSAGE_CONTAINER, and RESOURCEUSAGE_ATTACHED.</term>
        /// </item>
        /// </list>
        /// </para>
        /// <para>
        /// This parameter is ignored unless the dwScope parameter is equal to RESOURCE_GLOBALNET. For more information, see the following
        /// Remarks section.
        /// </para>
        /// </param>
        /// <param name="recurseContainers">if set to <see langword="true"/> [recurse containers].</param>
        /// <returns>The enumeration results. The results are returned as a list of <c>NETRESOURCE</c> structures.</returns>
        public static IEnumerable <NETRESOURCE> WNetEnumResources([Optional] NETRESOURCE root, NETRESOURCEScope dwScope = NETRESOURCEScope.RESOURCE_GLOBALNET, NETRESOURCEType dwType = NETRESOURCEType.RESOURCETYPE_ANY, NETRESOURCEUsage dwUsage = 0, bool recurseContainers = false)
        {
            var err = WNetOpenEnum(dwScope, dwType, dwUsage, root, out var h);

            if (err == Win32Error.ERROR_NOT_CONTAINER || err == Win32Error.ERROR_NO_NETWORK)
            {
                yield break;
            }
            else
            {
                err.WNetThrowIfFailed();
            }

            using (h)
            {
                var count = -1;
                var sz    = 4096U;
                using var mem = new SafeHGlobalHandle((int)sz);
                do
                {
                    mem.Zero();
                    sz  = mem.Size;
                    err = WNetEnumResource(h, ref count, mem, ref sz);
                    if (err.Succeeded)
                    {
                        foreach (var e in mem.ToEnumerable <NETRESOURCE>(count))
                        {
                            yield return(e);

                            if (recurseContainers && e.dwUsage.IsFlagSet(NETRESOURCEUsage.RESOURCEUSAGE_CONTAINER))
                            {
                                foreach (var ce in WNetEnumResources(e, dwScope, dwType, dwUsage, recurseContainers))
                                {
                                    yield return(ce);
                                }
                            }
                        }
                    }
                    else if (err != Win32Error.ERROR_NO_MORE_ITEMS)
                    {
                        err.WNetThrowIfFailed("Last resource = " + (root is null ? "" : $"Type:{root.dwDisplayType}=Prov:{root.lpProvider}; Rem:{root.lpRemoteName}"));
                    }
                }while (err != Win32Error.ERROR_NO_MORE_ITEMS);
            }
        }
示例#2
0
        public static IEnumerable <NETRESOURCE> WNetEnumResources([Optional] NETRESOURCE root, NETRESOURCEScope dwScope = NETRESOURCEScope.RESOURCE_GLOBALNET, NETRESOURCEType dwType = NETRESOURCEType.RESOURCETYPE_ANY, NETRESOURCEUsage dwUsage = 0, bool recurseContainers = false)
        {
            var err = WNetOpenEnum(dwScope, dwType, dwUsage, root, out var h);

            if (err == Win32Error.ERROR_NOT_CONTAINER || err == Win32Error.ERROR_NO_NETWORK)
            {
                yield break;
            }
            else if (err.Failed)
            {
                throw err.GetException();
            }

            using (h)
            {
                var count = -1;
                var sz    = 16 * 1024U;
                using (var mem = new SafeHGlobalHandle((int)sz))
                {
                    do
                    {
                        err = WNetEnumResource(h, ref count, (IntPtr)mem, ref sz);
                        if (err == Win32Error.ERROR_SUCCESS)
                        {
                            foreach (var e in mem.ToEnumerable <NETRESOURCE>((int)count))
                            {
                                yield return(e);

                                if (recurseContainers && e.dwUsage.IsFlagSet(NETRESOURCEUsage.RESOURCEUSAGE_CONTAINER))
                                {
                                    foreach (var ce in WNetEnumResources(e, dwScope, dwType, dwUsage, recurseContainers))
                                    {
                                        yield return(ce);
                                    }
                                }
                            }
                        }
                        else if (err == Win32Error.ERROR_NO_MORE_ITEMS)
                        {
                            break;
                        }
                        else
                        {
                            throw err.GetException();
                        }
                        mem.Zero();
                    }while (true);
                }
            }
        }