7cdfbce1e48934dd074d989580c0c4fca4711762
[reactos.git] / rosapps / winfile / network.c
1 /*
2 * ReactOS winfile
3 *
4 * network.c
5 *
6 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
7 *
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.
12 *
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.
17 *
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.
21 */
22
23 #ifdef _MSC_VER
24 #include "stdafx.h"
25 #else
26 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <stdlib.h>
30 #include <malloc.h>
31 #include <memory.h>
32 #include <tchar.h>
33 #include <process.h>
34 #include <stdio.h>
35 #endif
36
37 #include "main.h"
38 #include "network.h"
39
40 #include "trace.h"
41
42
43 ////////////////////////////////////////////////////////////////////////////////
44 // Global Variables:
45 //
46
47 static HANDLE hNetworkMonitorThreadEvent = NULL; // When this event becomes signaled then we run the monitor thread
48
49 static HMODULE hMPR;
50 static BOOL bNetAvailable = FALSE;
51
52 typedef DWORD (WINAPI *WNetCloseEnum_Ptr)(HANDLE);
53 typedef DWORD (WINAPI *WNetConnectionDialog_Ptr)(HWND, DWORD);
54 typedef DWORD (WINAPI *WNetDisconnectDialog_Ptr)(HWND, DWORD);
55 typedef DWORD (WINAPI *WNetConnectionDialog1_Ptr)(LPCONNECTDLGSTRUCT);
56 typedef DWORD (WINAPI *WNetDisconnectDialog1_Ptr)(LPDISCDLGSTRUCT);
57 typedef DWORD (WINAPI *WNetEnumResourceA_Ptr)(HANDLE, LPDWORD, LPVOID, LPDWORD);
58 typedef DWORD (WINAPI *WNetOpenEnumA_Ptr)(DWORD, DWORD, DWORD, LPNETRESOURCE, LPHANDLE);
59
60 static WNetCloseEnum_Ptr pWNetCloseEnum;
61 static WNetConnectionDialog_Ptr pWNetConnectionDialog;
62 static WNetDisconnectDialog_Ptr pWNetDisconnectDialog;
63 static WNetConnectionDialog1_Ptr pWNetConnectionDialog1;
64 static WNetDisconnectDialog1_Ptr pWNetDisconnectDialog1;
65 static WNetEnumResourceA_Ptr pWNetEnumResource;
66 static WNetOpenEnumA_Ptr pWNetOpenEnum;
67
68
69 ////////////////////////////////////////////////////////////////////////////////
70 // Local module support methods
71 //
72
73 static BOOL CheckNetworkAvailable(void)
74 {
75
76 hMPR = LoadLibrary(_T("MPR.DLL"));
77 if (hMPR) {
78 pWNetCloseEnum = (WNetCloseEnum_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetCloseEnum");
79 pWNetConnectionDialog = (WNetConnectionDialog_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetConnectionDialog");
80 pWNetDisconnectDialog = (WNetDisconnectDialog_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetDisconnectDialog");
81 pWNetConnectionDialog1 = (WNetConnectionDialog1_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetConnectionDialog1");
82 pWNetDisconnectDialog1 = (WNetDisconnectDialog1_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetDisconnectDialog1");
83 pWNetEnumResource = (WNetEnumResourceA_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetEnumResourceA");
84 pWNetOpenEnum = (WNetOpenEnumA_Ptr)(FARPROC)GetProcAddress(hMPR, "WNetOpenEnumA");
85 // FreeLibrary(hMPR);
86 bNetAvailable = TRUE;
87 }
88 return (hMPR != NULL);
89 }
90
91
92 static LRESULT CALLBACK EnumNetConnectionsProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
93 {
94 return 0;
95 }
96
97 /*
98 DWORD WNetOpenEnum(
99 DWORD dwScope, // scope of enumeration
100 DWORD dwType, // resource types to list
101 DWORD dwUsage, // resource usage to list
102 LPNETRESOURCE lpNetResource, // resource structure
103 LPHANDLE lphEnum // enumeration handle buffer
104 );
105
106 result = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_DISK, RESOURCEUSAGE_ALL, NULL, &EnumNetConnectionsProc);
107
108 */
109 DWORD MapNetworkDrives(HWND hWnd, BOOL connect)
110 {
111 DWORD result = 0L;
112
113 if (!bNetAvailable) return result;
114 #if 1
115 if (connect) {
116 pWNetConnectionDialog(hWnd, RESOURCETYPE_DISK);
117 } else {
118 pWNetDisconnectDialog(hWnd, RESOURCETYPE_DISK);
119 }
120 #else
121 if (connect) {
122 NETRESOURCE netResouce;
123 CONNECTDLGSTRUCT connectDlg;
124
125 //netResouce.dwScope;
126 //netResouce.dwType;
127 netResouce.dwDisplayType = 0;
128 //netResouce.dwUsage;
129 //netResouce.lpLocalName;
130 //netResouce.lpRemoteName;
131 //netResouce.lpComment;
132 //netResouce.lpProvider;
133
134 //connectDlg.cbStructure;
135 connectDlg.hwndOwner = hWnd;
136 connectDlg.lpConnRes = &netResouce;
137 //connectDlg.dwFlags;
138 //connectDlg.dwDevNum;
139
140 result = WNetConnectionDialog1(&connectDlg);
141 } else {
142 DISCDLGSTRUCT disconnectDlg;
143 //disconnectDlg.cbStructure;
144 disconnectDlg.hwndOwner = hWnd;
145 //disconnectDlg.lpLocalName;
146 //disconnectDlg.lpRemoteName;
147 //disconnectDlg.dwFlags;
148 result = pWNetDisconnectDialog1(&disconnectDlg);
149 }
150 #endif
151 return result;
152 }
153
154 ////////////////////////////////////
155 static void NetErrorHandler(HWND hwnd, DWORD dwResult, LPTSTR str)
156 {
157 TRACE(_T("NetErrorHandler(0x%08X) %s\n"), dwResult, str);
158 }
159
160 static void DisplayStruct(HDC hdc, LPNETRESOURCE lpnrLocal)
161 {
162 LPTSTR str = NULL;
163 TRACE(_T("DisplayStruct(%p)"), lpnrLocal);
164
165 switch (lpnrLocal->dwScope) {
166 case RESOURCE_CONNECTED: str = _T("Enumerate currently connected resources. The dwUsage member cannot be specified."); break;
167 case RESOURCE_GLOBALNET: str = _T("Enumerate all resources on the network. The dwUsage member is specified."); break;
168 case RESOURCE_REMEMBERED: str = _T("Enumerate remembered (persistent) connections. The dwUsage member cannot be specified."); break;
169 default: str = _T("Unknown Scope."); break;
170 }
171 TRACE(_T(" %s\n"), str);
172
173 switch (lpnrLocal->dwType) {
174 case RESOURCETYPE_ANY: str = _T("All resources."); break;
175 case RESOURCETYPE_DISK: str = _T("Disk resources."); break;
176 case RESOURCETYPE_PRINT: str = _T("Print resources."); break;
177 default: str = _T("Unknown Type."); break;
178 }
179 TRACE(_T(" %s\n"), str);
180
181 switch (lpnrLocal->dwDisplayType) {
182 case RESOURCEDISPLAYTYPE_DOMAIN: str = _T("The object should be displayed as a domain."); break;
183 case RESOURCEDISPLAYTYPE_SERVER: str = _T("The object should be displayed as a server."); break;
184 case RESOURCEDISPLAYTYPE_SHARE: str = _T("The object should be displayed as a share."); break;
185 case RESOURCEDISPLAYTYPE_GENERIC: str = _T("The method used to display the object does not matter."); break;
186 default: str = _T("Unknown DisplayType."); break;
187 }
188 TRACE(_T(" %s\n"), str);
189
190 // switch (lpnrLocal->dwUsage ) {
191 // 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;
192 // 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;
193 // default: str = _T("Unknown Usage."); break;
194 // }
195 TRACE(_T("\tLocalName: %s\tRemoteName: %s"), lpnrLocal->lpLocalName, lpnrLocal->lpRemoteName);
196 TRACE(_T("\tComment: %s\tProvider: %s\n"), lpnrLocal->lpComment, lpnrLocal->lpProvider);
197 }
198
199 ////////////////////////////////////
200
201 static BOOL WINAPI EnumerateFunc(HWND hwnd, HDC hdc, LPNETRESOURCE lpnr)
202 {
203 DWORD dwResult;
204 DWORD dwResultEnum;
205 HANDLE hEnum;
206 DWORD cbBuffer = 16384; // 16K is a good size
207 DWORD cEntries = -1; // enumerate all possible entries
208 LPNETRESOURCE lpnrLocal; // pointer to enumerated structures
209 DWORD i;
210
211 if (!bNetAvailable) return FALSE;
212
213 // Call the WNetOpenEnum function to begin the enumeration.
214 dwResult = pWNetOpenEnum(RESOURCE_GLOBALNET, // all network resources
215 // RESOURCETYPE_ANY, // all resources
216 RESOURCETYPE_DISK, // disk resources only, exlude printers
217 0, // enumerate all resources
218 lpnr, // NULL first time the function is called
219 &hEnum); // handle to the resource
220
221 if (dwResult != NO_ERROR) {
222 // Process errors with an application-defined error handler.
223 NetErrorHandler(hwnd, dwResult, (LPTSTR)_T("WNetOpenEnum"));
224 return FALSE;
225 }
226
227 // Call the GlobalAlloc function to allocate resources.
228 lpnrLocal = (LPNETRESOURCE)GlobalAlloc(GPTR, cbBuffer);
229
230 do {
231 // Initialize the buffer.
232 ZeroMemory(lpnrLocal, cbBuffer);
233
234 // Call the WNetEnumResource function to continue the enumeration.
235 dwResultEnum = pWNetEnumResource(hEnum, // resource handle
236 &cEntries, // defined locally as -1
237 lpnrLocal, // LPNETRESOURCE
238 &cbBuffer); // buffer size
239
240 // If the call succeeds, loop through the structures.
241 if (dwResultEnum == NO_ERROR) {
242 for (i = 0; i < cEntries; i++) {
243 // Call an application-defined function to display the contents of the NETRESOURCE structures.
244 DisplayStruct(hdc, &lpnrLocal[i]);
245
246 // If the NETRESOURCE structure represents a container resource, call the EnumerateFunc function recursively.
247 if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER))
248 if (!EnumerateFunc(hwnd, hdc, &lpnrLocal[i])) {
249 //TextOut(hdc, 10, 10, _T("EnumerateFunc returned FALSE."), 29);
250 TRACE(_T("EnumerateFunc returned FALSE.\n"));
251 }
252 }
253 }
254 // Process errors.
255 else if (dwResultEnum != ERROR_NO_MORE_ITEMS) {
256 NetErrorHandler(hwnd, dwResultEnum, (LPTSTR)_T("WNetEnumResource"));
257 break;
258 }
259 }
260 // End do.
261
262 while (dwResultEnum != ERROR_NO_MORE_ITEMS);
263
264 // Call the GlobalFree function to free the memory.
265 GlobalFree((HGLOBAL)lpnrLocal);
266
267 // Call WNetCloseEnum to end the enumeration.
268 dwResult = pWNetCloseEnum(hEnum);
269
270 if (dwResult != NO_ERROR) {
271 // Process errors.
272 NetErrorHandler(hwnd, dwResult, (LPTSTR)_T("WNetCloseEnum"));
273 return FALSE;
274 }
275 return TRUE;
276 }
277
278 /*
279
280 DWORD WNetConnectionDialog(
281 HWND hwnd, // handle to window owning dialog box
282 DWORD dwType // resource type
283 );
284
285
286 DWORD WNetAddConnection(
287 LPCTSTR lpRemoteName, // network device name
288 LPCTSTR lpPassword, // password
289 LPCTSTR lpLocalName // local device name
290 );
291
292
293 DWORD WNetOpenEnum(
294 DWORD dwScope, // scope of enumeration
295 DWORD dwType, // resource types to list
296 DWORD dwUsage, // resource usage to list
297 LPNETRESOURCE lpNetResource, // resource structure
298 LPHANDLE lphEnum // enumeration handle buffer
299 );
300 */
301
302 ////////////////////////////////////////////////////////////////////////////////
303
304 void NetworkMonitorThreadProc(void *lpParameter)
305 {
306 // ULONG OldProcessorUsage = 0;
307 // ULONG OldProcessCount = 0;
308 HWND hWnd = (HWND)lpParameter;
309
310 // Create the event
311 hNetworkMonitorThreadEvent = CreateEvent(NULL, TRUE, TRUE, "Winfile Network Monitor Event");
312
313 // If we couldn't create the event then exit the thread
314 if (!hNetworkMonitorThreadEvent)
315 return;
316
317 while (1) {
318 DWORD dwWaitVal;
319
320 // Wait on the event
321 dwWaitVal = WaitForSingleObject(hNetworkMonitorThreadEvent, INFINITE);
322
323 // If the wait failed then the event object must have been
324 // closed and the task manager is exiting so exit this thread
325 if (dwWaitVal == WAIT_FAILED) {
326 // CloseHandle(hNetworkMonitorThreadEvent); // Should we close the event object handle or not ???
327 // hNetworkMonitorThreadEvent = NULL; // if we do then check what happens when main thread tries to delete it also....
328 return;
329 }
330
331 if (dwWaitVal == WAIT_OBJECT_0) {
332 // Reset our event
333 ResetEvent(hNetworkMonitorThreadEvent);
334
335
336 if ( EnumerateFunc(hWnd, NULL, NULL) ) {
337
338 }
339
340 #if 0
341 TCHAR text[260];
342 if ((ULONG)SendMessage(hProcessPageListCtrl, LVM_GETITEMCOUNT, 0, 0) != PerfDataGetProcessCount())
343 SendMessage(hProcessPageListCtrl, LVM_SETITEMCOUNT, PerfDataGetProcessCount(), /*LVSICF_NOINVALIDATEALL|*/LVSICF_NOSCROLL);
344 if (IsWindowVisible(hProcessPage))
345 InvalidateRect(hProcessPageListCtrl, NULL, FALSE);
346 if (OldProcessorUsage != PerfDataGetProcessorUsage()) {
347 OldProcessorUsage = PerfDataGetProcessorUsage();
348 wsprintf(text, _T("CPU Usage: %3d%%"), OldProcessorUsage);
349 SendMessage(hStatusWnd, SB_SETTEXT, 1, (LPARAM)text);
350 }
351 if (OldProcessCount != PerfDataGetProcessCount()) {
352 OldProcessCount = PerfDataGetProcessCount();
353 wsprintf(text, _T("Processes: %d"), OldProcessCount);
354 SendMessage(hStatusWnd, SB_SETTEXT, 0, (LPARAM)text);
355 }
356 #endif
357 }
358 }
359 }
360
361 BOOL CreateNetworkMonitorThread(HWND hWnd)
362 {
363 CheckNetworkAvailable();
364 _beginthread(NetworkMonitorThreadProc, 0, hWnd);
365 return TRUE;
366 }
367
368 void SignalNetworkMonitorEvent(void)
369 {
370 SetEvent(hNetworkMonitorThreadEvent);
371 }
372
373 BOOL DestryNetworkMonitorThread(void)
374 {
375 CloseHandle(hNetworkMonitorThreadEvent);
376 hNetworkMonitorThreadEvent = NULL;
377 return TRUE;
378 }
379