Created
September 24, 2014 08:36
-
-
Save sean-m/88e74171cd2d07a4c608 to your computer and use it in GitHub Desktop.
C# native interop function which calls NetDfsEnum and returns a list of structs representing the DFS links. You get the name and a string[] of the link's targets for each DFS link in the namespace. I check and only return the links which are in a valid state.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[DllImport("Netapi32.dll", CharSet = CharSet.Auto/*, SetLastError=true //Return value (NET_API_STATUS) contains error */)] | |
public static extern int NetDfsEnum( | |
[MarshalAs(UnmanagedType.LPWStr)]string DfsName, | |
int Level, | |
int PrefMaxLen, | |
out IntPtr Buffer, | |
[MarshalAs(UnmanagedType.I4)]out int EntriesRead, | |
[MarshalAs(UnmanagedType.I4)]ref int ResumeHandle); | |
const int MAX_PREFERRED_LENGTH = 0xFFFFFFF; | |
const int NERR_Success = 0; | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
public struct DFS_INFO_3 | |
{ | |
[MarshalAs(UnmanagedType.LPWStr)] | |
public string EntryPath; | |
[MarshalAs(UnmanagedType.LPWStr)] | |
public string Comment; | |
public UInt32 State; | |
public UInt32 NumberOfStorages; | |
public IntPtr Storages; | |
} | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | |
public struct DFS_STORAGE_INFO | |
{ | |
public Int32 State; | |
[MarshalAs(UnmanagedType.LPWStr)] | |
public string ServerName; | |
[MarshalAs(UnmanagedType.LPWStr)] | |
public string ShareName; | |
} | |
public struct DFSLink | |
{ | |
public string name; | |
public string[] target; | |
public DFSLink(string Name, string[] Target) { | |
this.name = Name; | |
this.target = Target; | |
} | |
} | |
public static List<DFSLink> GetDfsLinks(string sDFSRoot) { | |
List<DFSLink> links = new List<DFSLink>(); | |
IntPtr pBuffer = new IntPtr(); | |
int entriesRead = 0; | |
int resume = 0; | |
var iResult = NetDfsEnum(sDFSRoot, 3, MAX_PREFERRED_LENGTH, out pBuffer, out entriesRead, ref resume); | |
if (iResult == 0) { | |
// Itterate over entries in namespace | |
for (int j = 0; j < entriesRead; j++) { | |
DFS_INFO_3 oDFSInfo = (DFS_INFO_3)Marshal.PtrToStructure(pBuffer + j * Marshal.SizeOf(typeof(DFS_INFO_3)), typeof(DFS_INFO_3)); | |
if (oDFSInfo.EntryPath == sDFSRoot) { // skip link for namespace | |
continue; | |
} | |
List<string> targets = new List<string>(); | |
for (int i = 0; i < oDFSInfo.NumberOfStorages; i++) { // get targets for link | |
IntPtr pStorage = new IntPtr(oDFSInfo.Storages.ToInt64() + i * Marshal.SizeOf( | |
typeof(DFS_STORAGE_INFO))); | |
DFS_STORAGE_INFO oStorageInfo = (DFS_STORAGE_INFO)Marshal.PtrToStructure(pStorage, | |
typeof(DFS_STORAGE_INFO)); | |
//Get Only Active Hosts | |
if (oStorageInfo.State == 2) { | |
targets.Add(System.IO.Path.Combine(new string[] { @"\\", oStorageInfo.ServerName, oStorageInfo.ShareName })); | |
} | |
} | |
string name = oDFSInfo.EntryPath.Replace(sDFSRoot, ""); | |
if (name.StartsWith("\\")) { | |
name = name.Substring(1); | |
} | |
links.Add(new DFSLink(name, targets.ToArray())); // Collect link info in a nice way | |
} | |
} | |
NetApiBufferFree(pBuffer); | |
return links; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment