private static DfsInfo GetDfsInfoInternal(bool getFromClient, string dfsName, string serverName, string shareName)
        {
            if (!Filesystem.NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher);
            }

            if (Utils.IsNullOrWhiteSpace(dfsName))
            {
                throw new ArgumentNullException("dfsName");
            }

            serverName = Utils.IsNullOrWhiteSpace(serverName) ? null : serverName;
            shareName  = Utils.IsNullOrWhiteSpace(shareName) ? null : shareName;

            // MSDN: This buffer is allocated by the system (the API).
            var buffer = IntPtr.Zero;

            try
            {
                // Level 4 = DFS_INFO_4

                uint lastError = getFromClient
               ? NativeMethods.NetDfsGetClientInfo(dfsName, serverName, shareName, 4, out buffer)
               : NativeMethods.NetDfsGetInfo(dfsName, null, null, 4, out buffer);

                if (lastError == Win32Errors.NERR_Success)
                {
                    return(new DfsInfo(Utils.MarshalPtrToStructure <NativeMethods.DfsInfo4>(0, buffer)));
                }

                throw new NetworkInformationException((int)lastError);
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                {
                    NativeMethods.NetApiBufferFree(buffer);
                }
            }
        }
Beispiel #2
0
 protected override bool ReleaseHandle()
 {
     return((handle != IntPtr.Zero) && NativeMethods.NetApiBufferFree(handle) == Win32Errors.NERR_Success);
 }
Beispiel #3
0
        private static IEnumerable <TStruct> EnumerateNetworkObjectInternal <TStruct, TNative>(FunctionData functionData, Func <TNative, IntPtr, TStruct> createTStruct, EnumerateNetworkObjectDelegate enumerateNetworkObject, bool continueOnException)
        {
            Type objectType;
            int  objectSize;
            bool isString;

            switch (functionData.EnumType)
            {
            // Logical Drives
            case 1:
                objectType = typeof(IntPtr);
                isString   = true;
                objectSize = Marshal.SizeOf(objectType) + 2;
                break;

            default:
                objectType = typeof(TNative);
                isString   = objectType == typeof(string);
                objectSize = isString ? 0 : Marshal.SizeOf(objectType);
                break;
            }


            var buffer = IntPtr.Zero;

            try
            {
                uint lastError;
                do
                {
                    uint entriesRead;
                    uint totalEntries;
                    uint resumeHandle;

                    lastError = enumerateNetworkObject(functionData, out buffer, NativeMethods.MaxPreferredLength, out entriesRead, out totalEntries, out resumeHandle);

                    switch (lastError)
                    {
                    case Win32Errors.NERR_Success:
                    case Win32Errors.ERROR_MORE_DATA:
                        if (entriesRead > 0)
                        {
                            for (long i = 0, itemOffset = buffer.ToInt64(); i < entriesRead; i++, itemOffset += objectSize)
                            {
                                yield return((TStruct)(isString
                              ? Marshal.PtrToStringUni(new IntPtr(itemOffset))
                              : (object)createTStruct((TNative)Marshal.PtrToStructure(new IntPtr(itemOffset), objectType), buffer)));
                            }
                        }
                        break;

                    case Win32Errors.ERROR_BAD_NETPATH:
                        break;

                    // Observed when ShareInfo503 is requested, but not supported/possible.
                    case Win32Errors.RPC_X_BAD_STUB_DATA:
                        yield break;
                    }
                } while (lastError == Win32Errors.ERROR_MORE_DATA);

                if (lastError != Win32Errors.NO_ERROR && !continueOnException)
                {
                    throw new NetworkInformationException((int)lastError);
                }
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                {
                    NativeMethods.NetApiBufferFree(buffer);
                }
            }
        }
        internal static ShareInfo GetShareInfoInternal(ShareInfoLevel shareLevel, string host, string share, bool continueOnException)
        {
            if (Utils.IsNullOrWhiteSpace(share))
            {
                return(null);
            }

            // When host == null, the local computer is used.
            // However, the resulting OpenResourceInfo.Host property will be empty.
            // So, explicitly state Environment.MachineName to prevent this.
            // Furthermore, the UNC prefix: \\ is not required and always removed.
            string stripUnc = Utils.IsNullOrWhiteSpace(host)
            ? Environment.MachineName
            : Path.GetRegularPathInternal(host, GetFullPathOptions.CheckInvalidPathChars).Replace(Path.UncPrefix, string.Empty);

            bool fallback = false;


startNetShareGetInfo:

            var buffer = IntPtr.Zero;

            try
            {
                uint structureLevel = Convert.ToUInt16(shareLevel, CultureInfo.InvariantCulture);

                uint lastError = NativeMethods.NetShareGetInfo(stripUnc, share, structureLevel, out buffer);

                switch (lastError)
                {
                case Win32Errors.NERR_Success:
                    switch (shareLevel)
                    {
                    case ShareInfoLevel.Info1005:
                        return(new ShareInfo(stripUnc, shareLevel, Utils.MarshalPtrToStructure <NativeMethods.ShareInfo1005>(0, buffer))
                        {
                            NetFullPath = Path.CombineInternal(false, Path.UncPrefix + stripUnc, share)
                        });

                    case ShareInfoLevel.Info503:
                        return(new ShareInfo(stripUnc, shareLevel, Utils.MarshalPtrToStructure <NativeMethods.ShareInfo503>(0, buffer)));

                    case ShareInfoLevel.Info2:
                        return(new ShareInfo(stripUnc, shareLevel, Utils.MarshalPtrToStructure <NativeMethods.ShareInfo2>(0, buffer)));

                    case ShareInfoLevel.Info1:
                        return(new ShareInfo(stripUnc, shareLevel, Utils.MarshalPtrToStructure <NativeMethods.ShareInfo1>(0, buffer)));
                    }
                    break;


                // Observed when ShareInfo503 is requested, but not supported/possible.
                // Fall back on ShareInfo2 structure and try again.
                case Win32Errors.RPC_X_BAD_STUB_DATA:

                case Win32Errors.ERROR_ACCESS_DENIED:
                    if (!fallback && shareLevel != ShareInfoLevel.Info2)
                    {
                        NativeMethods.NetApiBufferFree(buffer);

                        shareLevel = ShareInfoLevel.Info2;
                        fallback   = true;
                        goto startNetShareGetInfo;
                    }
                    break;


                default:
                    if (!continueOnException)
                    {
                        throw new NetworkInformationException((int)lastError);
                    }
                    break;
                }

                return(null);
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                {
                    NativeMethods.NetApiBufferFree(buffer);
                }
            }
        }