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); } } }
protected override bool ReleaseHandle() { return((handle != IntPtr.Zero) && NativeMethods.NetApiBufferFree(handle) == Win32Errors.NERR_Success); }
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); } } }