Remodef form, added state class to save and load previous execution state.
[LanSpider.git] / LanSpider / NetworkBrowser.cs
blobf260dc9a205b04dd031d03b4ac3412148455cac3
1 using System;
2 using System.Collections.Generic;
3 using System.Runtime.InteropServices;
4 using System.Security;
5 using System.Windows.Forms;
7 namespace LanSpider
9 /// <summary>
10 /// Gets a list of machines and open shares on LAN. Uses DllImport of Netapi32.dll.
11 /// </summary>
12 public sealed class NetworkBrowser
14 #region Dll Imports
16 /// <summary>
17 /// Netapi32.dll : Get list of servers on the network.
18 /// </summary>
19 [DllImport( "Netapi32", CharSet = CharSet.Auto, SetLastError = true ), SuppressUnmanagedCodeSecurity]
20 private static extern int NetServerEnum(
21 string ServerNane, // must be null
22 int dwLevel,
23 ref IntPtr pBuf,
24 int dwPrefMaxLen,
25 out int dwEntriesRead,
26 out int dwTotalEntries,
27 int dwServerType,
28 string domain, // null for login domain
29 out int dwResumeHandle
32 /// <summary>
33 /// Netapi32.dll : Get list of shares on given machine.
34 /// </summary>
35 /// <returns></returns>
36 [DllImport( "Netapi32", CharSet = CharSet.Auto, SetLastError = true ), SuppressUnmanagedCodeSecurity]
37 private static extern int NetShareEnum(
38 string servername,
39 int level,
40 ref IntPtr bufptr,
41 int prefmaxlen,
42 out int entriesread,
43 out int totalentries,
44 out int resume_handle
48 /// <summary>
49 /// Netapi32.dll : The NetApiBufferFree function frees the memory
50 /// that the NetApiBufferAllocate function allocates.
51 /// Call NetApiBufferFree to free the memory that other network management functions return.
52 /// </summary>
53 [DllImport( "Netapi32", SetLastError = true ), SuppressUnmanagedCodeSecurity]
54 private static extern int NetApiBufferFree(
55 IntPtr pBuf );
57 /// <summary>
58 /// ServerInfo structure holds information on network servers returned by <see cref="NetServerEnum"/>.
59 /// </summary>
60 [StructLayout( LayoutKind.Sequential )]
61 private struct _SERVER_INFO_100
63 internal int sv100_platform_id;
64 [MarshalAs( UnmanagedType.LPWStr )] internal string sv100_name;
67 /// <summary>
68 /// ShareInfo1 structure hold share infomation as returned by <see cref="NetShareEnum"/> level 1.
69 /// </summary>
70 [StructLayout( LayoutKind.Sequential )]
71 private struct _SHARE_INFO_1
73 [MarshalAs( UnmanagedType.LPWStr )] internal string shi1_netname;
75 internal uint shi1_type;
76 [MarshalAs( UnmanagedType.LPWStr )] internal string shi1_remark;
79 #endregion
81 #region Constants
83 private const int MAX_PREFERRED_LENGTH = -1;
85 private const int SV_TYPE_WORKSTATION = 1;
86 private const int SV_TYPE_SERVER = 2;
88 private const uint STYPE_DISKTREE = 0;
89 private const uint STYPE_PRINTQ = 1;
90 private const uint STYPE_DEVICE = 2;
91 private const uint STYPE_IPC = 3;
93 private const uint STYPE_SPECIAL = 0x80000000;
94 private const uint STYPE_TEMPORARY = 0x40000000;
96 #endregion
98 #region Public Methods
100 /// <summary>
101 /// Get list of share names available on given server.
102 /// </summary>
103 /// <param name="serverName">Network machine name.</param>
104 /// <returns>List of shares on server.</returns>
105 public static IEnumerable<string> GetShares( string serverName )
107 IntPtr buffer = IntPtr.Zero;
108 IntPtr tmpBuffer;
109 int entriesRead;
110 int totalEntries;
111 int resHandle;
113 List<string> shares = new List<string>();
114 int sizeofInfo = Marshal.SizeOf( typeof( _SHARE_INFO_1 ) );
118 int ret = NetShareEnum( serverName, 1, ref buffer, MAX_PREFERRED_LENGTH, out entriesRead,
119 out totalEntries,
120 out resHandle );
122 if ( ret == 0 )
124 for ( int i = 0; i < totalEntries; i++ )
126 // Get next pointer to share info structure
127 tmpBuffer = new IntPtr( (int) buffer + ( i * sizeofInfo ) );
129 // Get structure from pointer
130 _SHARE_INFO_1 shareInfo =
131 (_SHARE_INFO_1) Marshal.PtrToStructure( tmpBuffer, typeof( _SHARE_INFO_1 ) );
133 // Skipe special types of shares
134 if ( ( shareInfo.shi1_type & STYPE_TEMPORARY ) == STYPE_TEMPORARY
135 || ( shareInfo.shi1_type & STYPE_IPC ) == STYPE_IPC
136 || ( shareInfo.shi1_type & STYPE_DEVICE ) == STYPE_DEVICE
137 || ( shareInfo.shi1_type & STYPE_PRINTQ ) == STYPE_PRINTQ
138 || ( shareInfo.shi1_type & STYPE_SPECIAL ) == STYPE_SPECIAL
139 || shareInfo.shi1_remark == "Printer Drivers" )
141 continue;
144 shares.Add( shareInfo.shi1_netname );
148 catch ( Exception ex )
150 MessageBox.Show( "Problem with acessing " +
151 "remote shares in NetworkBrowser " +
152 "\r\n\r\n\r\n" + ex.Message,
153 "Error", MessageBoxButtons.OK,
154 MessageBoxIcon.Error );
155 return null;
157 finally
159 // Free allocated memory
160 NetApiBufferFree( buffer );
163 return shares;
166 /// <summary>
167 /// Get the list of network machine of types serves and workstation.
168 /// </summary>
169 /// <returns>List of machines in network.</returns>
170 public static IEnumerable<string> GetNetworkComputers()
172 IntPtr buffer = IntPtr.Zero;
173 IntPtr tmpBuffer;
174 int entriesRead;
175 int totalEntries;
176 int resHandle;
177 int sizeofInfo = Marshal.SizeOf( typeof( _SERVER_INFO_100 ) );
178 string[] networkComputers = null;
181 // Get list of machines
182 int ret = NetServerEnum( null, 100, ref buffer,MAX_PREFERRED_LENGTH,out entriesRead,out totalEntries, SV_TYPE_WORKSTATION |SV_TYPE_SERVER, null, out resHandle );
184 if ( ret == 0 )
186 networkComputers = new string[totalEntries];
187 for ( int i = 0; i < totalEntries; i++ )
189 // Get next pointer to server info structure
190 tmpBuffer = new IntPtr( (int) buffer +( i * sizeofInfo ) );
192 // Get structure from pointer
193 _SERVER_INFO_100 svrInfo = (_SERVER_INFO_100)Marshal.PtrToStructure( tmpBuffer,typeof( _SERVER_INFO_100 ) );
195 networkComputers[ i ] = svrInfo.sv100_name;
199 catch ( Exception ex )
201 MessageBox.Show( "Problem with acessing " +
202 "network computers in NetworkBrowser " +
203 "\r\n\r\n\r\n" + ex.Message,
204 "Error", MessageBoxButtons.OK,
205 MessageBoxIcon.Error );
206 return null;
208 finally
210 // Free allocated memory
211 NetApiBufferFree( buffer );
214 return networkComputers;
217 #endregion