6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
39 ////////////////////////////////////////////////////////////////////////////////
43 static HANDLE hNetworkMonitorThreadEvent
= NULL
; // When this event becomes signaled then we run the monitor thread
46 static BOOL bNetAvailable
= FALSE
;
48 typedef DWORD (WINAPI
*WNetCloseEnum_Ptr
)(HANDLE
);
49 typedef DWORD (WINAPI
*WNetConnectionDialog_Ptr
)(HWND
, DWORD
);
50 typedef DWORD (WINAPI
*WNetDisconnectDialog_Ptr
)(HWND
, DWORD
);
51 typedef DWORD (WINAPI
*WNetConnectionDialog1_Ptr
)(LPCONNECTDLGSTRUCT
);
52 typedef DWORD (WINAPI
*WNetDisconnectDialog1_Ptr
)(LPDISCDLGSTRUCT
);
53 typedef DWORD (WINAPI
*WNetEnumResourceA_Ptr
)(HANDLE
, LPDWORD
, LPVOID
, LPDWORD
);
54 typedef DWORD (WINAPI
*WNetOpenEnumA_Ptr
)(DWORD
, DWORD
, DWORD
, LPNETRESOURCE
, LPHANDLE
);
56 static WNetCloseEnum_Ptr pWNetCloseEnum
;
57 static WNetConnectionDialog_Ptr pWNetConnectionDialog
;
58 static WNetDisconnectDialog_Ptr pWNetDisconnectDialog
;
59 static WNetConnectionDialog1_Ptr pWNetConnectionDialog1
;
60 static WNetDisconnectDialog1_Ptr pWNetDisconnectDialog1
;
61 static WNetEnumResourceA_Ptr pWNetEnumResource
;
62 static WNetOpenEnumA_Ptr pWNetOpenEnum
;
65 ////////////////////////////////////////////////////////////////////////////////
66 // Local module support methods
69 static BOOL
CheckNetworkAvailable(void)
72 hMPR
= LoadLibrary(_T("MPR.DLL"));
74 pWNetCloseEnum
= (WNetCloseEnum_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetCloseEnum");
75 pWNetConnectionDialog
= (WNetConnectionDialog_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetConnectionDialog");
76 pWNetDisconnectDialog
= (WNetDisconnectDialog_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetDisconnectDialog");
77 pWNetConnectionDialog1
= (WNetConnectionDialog1_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetConnectionDialog1");
78 pWNetDisconnectDialog1
= (WNetDisconnectDialog1_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetDisconnectDialog1");
79 pWNetEnumResource
= (WNetEnumResourceA_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetEnumResourceA");
80 pWNetOpenEnum
= (WNetOpenEnumA_Ptr
)(FARPROC
)GetProcAddress(hMPR
, "WNetOpenEnumA");
84 return (hMPR
!= NULL
);
88 static LRESULT CALLBACK
EnumNetConnectionsProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
95 DWORD dwScope, // scope of enumeration
96 DWORD dwType, // resource types to list
97 DWORD dwUsage, // resource usage to list
98 LPNETRESOURCE lpNetResource, // resource structure
99 LPHANDLE lphEnum // enumeration handle buffer
102 result = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, RESOURCEUSAGE_ALL, NULL, &EnumNetConnectionsProc);
105 DWORD
MapNetworkDrives(HWND hWnd
, BOOL connect
)
109 if (!bNetAvailable
) return result
;
112 pWNetConnectionDialog(hWnd
, RESOURCETYPE_DISK
);
114 pWNetDisconnectDialog(hWnd
, RESOURCETYPE_DISK
);
118 NETRESOURCE netResouce
;
119 CONNECTDLGSTRUCT connectDlg
;
121 //netResouce.dwScope;
123 netResouce
.dwDisplayType
= 0;
124 //netResouce.dwUsage;
125 //netResouce.lpLocalName;
126 //netResouce.lpRemoteName;
127 //netResouce.lpComment;
128 //netResouce.lpProvider;
130 //connectDlg.cbStructure;
131 connectDlg
.hwndOwner
= hWnd
;
132 connectDlg
.lpConnRes
= &netResouce
;
133 //connectDlg.dwFlags;
134 //connectDlg.dwDevNum;
136 result
= WNetConnectionDialog1(&connectDlg
);
138 DISCDLGSTRUCT disconnectDlg
;
139 //disconnectDlg.cbStructure;
140 disconnectDlg
.hwndOwner
= hWnd
;
141 //disconnectDlg.lpLocalName;
142 //disconnectDlg.lpRemoteName;
143 //disconnectDlg.dwFlags;
144 result
= pWNetDisconnectDialog1(&disconnectDlg
);
150 ////////////////////////////////////
151 static void NetErrorHandler(HWND hwnd
, DWORD dwResult
, LPTSTR str
)
153 TRACE(_T("NetErrorHandler(0x%08X) %s\n"), dwResult
, str
);
156 static void DisplayStruct(HDC hdc
, LPNETRESOURCE lpnrLocal
)
159 //TRACE(_T("DisplayStruct(%p)\n"), lpnrLocal);
161 switch (lpnrLocal
->dwScope
) {
162 case RESOURCE_CONNECTED
: str
= _T("Enumerate currently connected resources. The dwUsage member cannot be specified."); break;
163 case RESOURCE_GLOBALNET
: str
= _T("Enumerate all resources on the network. The dwUsage member is specified."); break;
164 case RESOURCE_REMEMBERED
: str
= _T("Enumerate remembered (persistent) connections. The dwUsage member cannot be specified."); break;
165 default: str
= _T("Unknown Scope."); break;
167 //TRACE(_T(" %s\n"), str);
169 switch (lpnrLocal
->dwType
) {
170 case RESOURCETYPE_ANY
: str
= _T("All resources."); break;
171 case RESOURCETYPE_DISK
: str
= _T("Disk resources."); break;
172 case RESOURCETYPE_PRINT
: str
= _T("Print resources."); break;
173 default: str
= _T("Unknown Type."); break;
175 //TRACE(_T(" %s\n"), str);
177 switch (lpnrLocal
->dwDisplayType
) {
178 case RESOURCEDISPLAYTYPE_DOMAIN
: str
= _T("The object should be displayed as a domain."); break;
179 case RESOURCEDISPLAYTYPE_SERVER
: str
= _T("The object should be displayed as a server."); break;
180 case RESOURCEDISPLAYTYPE_SHARE
: str
= _T("The object should be displayed as a share."); break;
181 case RESOURCEDISPLAYTYPE_GENERIC
: str
= _T("The method used to display the object does not matter."); break;
182 default: str
= _T("Unknown DisplayType."); break;
184 //TRACE(_T(" %s\n"), str);
186 // switch (lpnrLocal->dwUsage ) {
187 // case RESOURCEUSAGE_CONNECTABLE: str = _T("The resource is a connectable resource; the name pointed to by the lpRemoteName member can be passed to the WNetAddConnection function to make a network connection."); break;
188 // case RESOURCEUSAGE_CONTAINER: str = _T("The resource is a container resource; the name pointed to by the lpRemoteName member can be passed to the WNetOpenEnum function to enumerate the resources in the container."); break;
189 // default: str = _T("Unknown Usage."); break;
191 //TRACE(_T("\tLocalName: %s\tRemoteName: %s"), lpnrLocal->lpLocalName, lpnrLocal->lpRemoteName);
192 //TRACE(_T("\tComment: %s\tProvider: %s\n"), lpnrLocal->lpComment, lpnrLocal->lpProvider);
195 ////////////////////////////////////
197 static BOOL WINAPI
EnumerateFunc(HWND hwnd
, HDC hdc
, LPNETRESOURCE lpnr
)
202 DWORD cbBuffer
= 16384; // 16K is a good size
203 DWORD cEntries
= -1; // enumerate all possible entries
204 LPNETRESOURCE lpnrLocal
; // pointer to enumerated structures
207 if (!bNetAvailable
) return FALSE
;
209 // Call the WNetOpenEnum function to begin the enumeration.
210 dwResult
= pWNetOpenEnum(RESOURCE_GLOBALNET
, // all network resources
211 // RESOURCETYPE_ANY, // all resources
212 RESOURCETYPE_DISK
, // disk resources only, exlude printers
213 0, // enumerate all resources
214 lpnr
, // NULL first time the function is called
215 &hEnum
); // handle to the resource
217 if (dwResult
!= NO_ERROR
) {
218 // Process errors with an application-defined error handler.
219 NetErrorHandler(hwnd
, dwResult
, (LPTSTR
)_T("WNetOpenEnum"));
223 // Call the GlobalAlloc function to allocate resources.
224 lpnrLocal
= (LPNETRESOURCE
)GlobalAlloc(GPTR
, cbBuffer
);
227 // Initialize the buffer.
228 ZeroMemory(lpnrLocal
, cbBuffer
);
230 // Call the WNetEnumResource function to continue the enumeration.
231 dwResultEnum
= pWNetEnumResource(hEnum
, // resource handle
232 &cEntries
, // defined locally as -1
233 lpnrLocal
, // LPNETRESOURCE
234 &cbBuffer
); // buffer size
236 // If the call succeeds, loop through the structures.
237 if (dwResultEnum
== NO_ERROR
) {
238 for (i
= 0; i
< cEntries
; i
++) {
239 // Call an application-defined function to display the contents of the NETRESOURCE structures.
240 DisplayStruct(hdc
, &lpnrLocal
[i
]);
242 // If the NETRESOURCE structure represents a container resource, call the EnumerateFunc function recursively.
243 if (RESOURCEUSAGE_CONTAINER
== (lpnrLocal
[i
].dwUsage
& RESOURCEUSAGE_CONTAINER
))
244 if (!EnumerateFunc(hwnd
, hdc
, &lpnrLocal
[i
])) {
245 //TextOut(hdc, 10, 10, _T("EnumerateFunc returned FALSE."), 29);
246 TRACE(_T("EnumerateFunc returned FALSE.\n"));
251 else if (dwResultEnum
!= ERROR_NO_MORE_ITEMS
) {
252 NetErrorHandler(hwnd
, dwResultEnum
, (LPTSTR
)_T("WNetEnumResource"));
258 while (dwResultEnum
!= ERROR_NO_MORE_ITEMS
);
260 // Call the GlobalFree function to free the memory.
261 GlobalFree((HGLOBAL
)lpnrLocal
);
263 // Call WNetCloseEnum to end the enumeration.
264 dwResult
= pWNetCloseEnum(hEnum
);
266 if (dwResult
!= NO_ERROR
) {
268 NetErrorHandler(hwnd
, dwResult
, (LPTSTR
)_T("WNetCloseEnum"));
276 DWORD WNetConnectionDialog(
277 HWND hwnd, // handle to window owning dialog box
278 DWORD dwType // resource type
282 DWORD WNetAddConnection(
283 LPCTSTR lpRemoteName, // network device name
284 LPCTSTR lpPassword, // password
285 LPCTSTR lpLocalName // local device name
290 DWORD dwScope, // scope of enumeration
291 DWORD dwType, // resource types to list
292 DWORD dwUsage, // resource usage to list
293 LPNETRESOURCE lpNetResource, // resource structure
294 LPHANDLE lphEnum // enumeration handle buffer
298 ////////////////////////////////////////////////////////////////////////////////
300 void NetworkMonitorThreadProc(void *lpParameter
)
302 // ULONG OldProcessorUsage = 0;
303 // ULONG OldProcessCount = 0;
304 HWND hWnd
= (HWND
)lpParameter
;
307 hNetworkMonitorThreadEvent
= CreateEvent(NULL
, TRUE
, TRUE
, _T("Winfile Network Monitor Event"));
309 // If we couldn't create the event then exit the thread
310 if (!hNetworkMonitorThreadEvent
)
317 dwWaitVal
= WaitForSingleObject(hNetworkMonitorThreadEvent
, INFINITE
);
319 // If the wait failed then the event object must have been
320 // closed and the task manager is exiting so exit this thread
321 if (dwWaitVal
== WAIT_FAILED
) {
322 // CloseHandle(hNetworkMonitorThreadEvent); // Should we close the event object handle or not ???
323 // hNetworkMonitorThreadEvent = NULL; // if we do then check what happens when main thread tries to delete it also....
327 if (dwWaitVal
== WAIT_OBJECT_0
) {
329 ResetEvent(hNetworkMonitorThreadEvent
);
332 if ( EnumerateFunc(hWnd
, NULL
, NULL
) ) {
338 if ((ULONG
)SendMessage(hProcessPageListCtrl
, LVM_GETITEMCOUNT
, 0, 0) != PerfDataGetProcessCount())
339 SendMessage(hProcessPageListCtrl
, LVM_SETITEMCOUNT
, PerfDataGetProcessCount(), /*LVSICF_NOINVALIDATEALL|*/LVSICF_NOSCROLL
);
340 if (IsWindowVisible(hProcessPage
))
341 InvalidateRect(hProcessPageListCtrl
, NULL
, FALSE
);
342 if (OldProcessorUsage
!= PerfDataGetProcessorUsage()) {
343 OldProcessorUsage
= PerfDataGetProcessorUsage();
344 wsprintf(text
, _T("CPU Usage: %3d%%"), OldProcessorUsage
);
345 SendMessage(hStatusWnd
, SB_SETTEXT
, 1, (LPARAM
)text
);
347 if (OldProcessCount
!= PerfDataGetProcessCount()) {
348 OldProcessCount
= PerfDataGetProcessCount();
349 wsprintf(text
, _T("Processes: %d"), OldProcessCount
);
350 SendMessage(hStatusWnd
, SB_SETTEXT
, 0, (LPARAM
)text
);
357 BOOL
CreateNetworkMonitorThread(HWND hWnd
)
359 CheckNetworkAvailable();
360 _beginthread(NetworkMonitorThreadProc
, 0, hWnd
);
364 void SignalNetworkMonitorEvent(void)
366 SetEvent(hNetworkMonitorThreadEvent
);
369 BOOL
DestryNetworkMonitorThread(void)
371 CloseHandle(hNetworkMonitorThreadEvent
);
372 hNetworkMonitorThreadEvent
= NULL
;