wined3d: Make the device parameter to wined3d_device_get_raster_status() const.
[wine] / programs / net / net.c
1 /*
2  * Copyright 2007 Tim Schwartz
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <windows.h>
20 #include <lm.h>
21 #include <wine/unicode.h>
22 #include <wine/debug.h>
23
24 #include "resources.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(net);
27
28 #define NET_START 0001
29 #define NET_STOP  0002
30
31 static int output_write(const WCHAR* str, int len)
32 {
33     DWORD ret, count;
34     ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str, len, &count, NULL);
35     if (!ret)
36     {
37         DWORD lenA;
38         char* strA;
39
40         /* On Windows WriteConsoleW() fails if the output is redirected. So fall
41          * back to WriteFile(), assuming the console encoding is still the right
42          * one in that case.
43          */
44         lenA = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, len,
45                                    NULL, 0, NULL, NULL);
46         strA = HeapAlloc(GetProcessHeap(), 0, lenA);
47         if (!strA)
48             return 0;
49
50         WideCharToMultiByte(GetConsoleOutputCP(), 0, str, len, strA, lenA,
51                             NULL, NULL);
52         WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), strA, len, &count, FALSE);
53         HeapFree(GetProcessHeap(), 0, strA);
54     }
55     return count;
56 }
57
58 static int output_vprintf(const WCHAR* fmt, va_list va_args)
59 {
60     WCHAR str[8192];
61     int len;
62
63     len = vsnprintfW(str, sizeof(str)/sizeof(*str), fmt, va_args);
64     if (len < 0)
65         WINE_FIXME("String too long.\n");
66     else
67         output_write(str, len);
68     return 0;
69 }
70
71 static int output_printf(const WCHAR* fmt, ...)
72 {
73     va_list arguments;
74
75     va_start(arguments, fmt);
76     output_vprintf(fmt, arguments);
77     va_end(arguments);
78     return 0;
79 }
80
81 static int output_string(int msg, ...)
82 {
83     WCHAR fmt[8192];
84     va_list arguments;
85
86     LoadStringW(GetModuleHandleW(NULL), msg, fmt, sizeof(fmt)/sizeof(fmt[0]));
87     va_start(arguments, msg);
88     output_vprintf(fmt, arguments);
89     va_end(arguments);
90     return 0;
91 }
92
93 static BOOL output_error_string(DWORD error)
94 {
95     LPWSTR pBuffer;
96     if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
97             FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
98             NULL, error, 0, (LPWSTR)&pBuffer, 0, NULL))
99     {
100         output_write(pBuffer, lstrlenW(pBuffer));
101         LocalFree(pBuffer);
102         return TRUE;
103     }
104     return FALSE;
105 }
106
107 static BOOL net_use(int argc, const WCHAR* argv[])
108 {
109     USE_INFO_2 *buffer, *connection;
110     DWORD read, total, resume_handle, rc, i;
111     WCHAR* status[STRING_RECONN-STRING_OK+1];
112     resume_handle = 0;
113     buffer = NULL;
114
115     if(argc<3)
116     {
117         HMODULE hmod = GetModuleHandleW(NULL);
118
119         /* Load the status strings */
120         for (i = 0; i < sizeof(status)/sizeof(*status); i++)
121         {
122             status[i] = HeapAlloc(GetProcessHeap(), 0, 1024 * sizeof(**status));
123             LoadStringW(hmod, STRING_OK+i, status[i], 1024);
124         }
125
126         do {
127             rc = NetUseEnum(NULL, 2, (BYTE **) &buffer, 2048, &read, &total, &resume_handle);
128             if (rc != ERROR_MORE_DATA && rc != ERROR_SUCCESS)
129             {
130                 break;
131             }
132
133             if(total == 0)
134             {
135                 output_string(STRING_NO_ENTRIES);
136                 break;
137             }
138
139             output_string(STRING_USE_HEADER);
140             for (i = 0, connection = buffer; i < read; ++i, ++connection)
141                 output_string(STRING_USE_ENTRY, status[connection->ui2_status], connection->ui2_local,
142                                 connection->ui2_remote, connection->ui2_refcount);
143
144             if (buffer != NULL) NetApiBufferFree(buffer);
145         } while (rc == ERROR_MORE_DATA);
146
147         /* Release the status strings */
148         for (i = 0; i < sizeof(status)/sizeof(*status); i++)
149             HeapFree(GetProcessHeap(), 0, status[i]);
150
151         return TRUE;
152     }
153
154     return FALSE;
155 }
156
157 static BOOL net_enum_services(void)
158 {
159     static const WCHAR runningW[]={' ',' ',' ',' ','%','s','\n',0};
160     SC_HANDLE SCManager;
161     LPENUM_SERVICE_STATUS_PROCESSW services;
162     DWORD size, i, count, resume;
163     BOOL success = FALSE;
164
165     SCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
166     if(!SCManager)
167     {
168         output_string(STRING_NO_SCM);
169         return FALSE;
170     }
171
172     EnumServicesStatusExW(SCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, NULL, 0, &size, &count, NULL, NULL);
173     if(GetLastError() != ERROR_MORE_DATA)
174     {
175         output_error_string(GetLastError());
176         goto end;
177     }
178     services = HeapAlloc(GetProcessHeap(), 0, size);
179     resume = 0;
180     if(!EnumServicesStatusExW(SCManager, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_ACTIVE, (LPBYTE)services, size, &size, &count, &resume, NULL))
181     {
182         output_error_string(GetLastError());
183         goto end;
184     }
185     output_string(STRING_RUNNING_HEADER);
186     for(i = 0; i < count; i++)
187     {
188         output_printf(runningW, services[i].lpDisplayName);
189         WINE_TRACE("service=%s state=%d controls=%x\n",
190                    wine_dbgstr_w(services[i].lpServiceName),
191                    services[i].ServiceStatusProcess.dwCurrentState,
192                    services[i].ServiceStatusProcess.dwControlsAccepted);
193     }
194     success = TRUE;
195
196  end:
197     CloseServiceHandle(SCManager);
198     return success;
199 }
200
201 static BOOL StopService(SC_HANDLE SCManager, SC_HANDLE serviceHandle)
202 {
203     LPENUM_SERVICE_STATUSW dependencies = NULL;
204     DWORD buffer_size = 0;
205     DWORD count = 0, counter;
206     BOOL result;
207     SC_HANDLE dependent_serviceHandle;
208     SERVICE_STATUS_PROCESS ssp;
209
210     result = EnumDependentServicesW(serviceHandle, SERVICE_ACTIVE, dependencies, buffer_size, &buffer_size, &count);
211
212     if(!result && (GetLastError() == ERROR_MORE_DATA))
213     {
214         dependencies = HeapAlloc(GetProcessHeap(), 0, buffer_size);
215         if(EnumDependentServicesW(serviceHandle, SERVICE_ACTIVE, dependencies, buffer_size, &buffer_size, &count))
216         {
217             for(counter = 0; counter < count; counter++)
218             {
219                 output_string(STRING_STOP_DEP, dependencies[counter].lpDisplayName);
220                 dependent_serviceHandle = OpenServiceW(SCManager, dependencies[counter].lpServiceName, SC_MANAGER_ALL_ACCESS);
221                 if(dependent_serviceHandle) result = StopService(SCManager, dependent_serviceHandle);
222                 CloseServiceHandle(dependent_serviceHandle);
223                 if(!result) output_string(STRING_CANT_STOP, dependencies[counter].lpDisplayName);
224            }
225         }
226     }
227
228     if(result) result = ControlService(serviceHandle, SERVICE_CONTROL_STOP, (LPSERVICE_STATUS)&ssp);
229     HeapFree(GetProcessHeap(), 0, dependencies);
230     return result;
231 }
232
233 static BOOL net_service(int operation, const WCHAR* service_name)
234 {
235     SC_HANDLE SCManager, serviceHandle;
236     BOOL result = 0;
237     WCHAR service_display_name[4096];
238     DWORD buffer_size;
239
240     SCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS);
241     if(!SCManager)
242     {
243         output_string(STRING_NO_SCM);
244         return FALSE;
245     }
246     serviceHandle = OpenServiceW(SCManager, service_name, SC_MANAGER_ALL_ACCESS);
247     if(!serviceHandle)
248     {
249         output_string(STRING_NO_SVCHANDLE);
250         CloseServiceHandle(SCManager);
251         return FALSE;
252     }
253
254     buffer_size = sizeof(service_display_name)/sizeof(*service_display_name);
255     GetServiceDisplayNameW(SCManager, service_name, service_display_name, &buffer_size);
256     if (!service_display_name[0]) lstrcpyW(service_display_name, service_name);
257
258     switch(operation)
259     {
260     case NET_START:
261         output_string(STRING_START_SVC, service_display_name);
262         result = StartServiceW(serviceHandle, 0, NULL);
263
264         if(result) output_string(STRING_START_SVC_SUCCESS, service_display_name);
265         else
266         {
267             if (!output_error_string(GetLastError()))
268                 output_string(STRING_START_SVC_FAIL, service_display_name);
269         }
270         break;
271     case NET_STOP:
272         output_string(STRING_STOP_SVC, service_display_name);
273         result = StopService(SCManager, serviceHandle);
274
275         if(result) output_string(STRING_STOP_SVC_SUCCESS, service_display_name);
276         else
277         {
278             if (!output_error_string(GetLastError()))
279                 output_string(STRING_STOP_SVC_FAIL, service_display_name);
280         }
281         break;
282     }
283
284     CloseServiceHandle(serviceHandle);
285     CloseServiceHandle(SCManager);
286     return result;
287 }
288
289 static int arg_is(const WCHAR* str1, const WCHAR* str2)
290 {
291     return CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, str1, -1, str2, -1) == CSTR_EQUAL;
292 }
293
294 int wmain(int argc, const WCHAR* argv[])
295 {
296     static const WCHAR helpW[]={'h','e','l','p',0};
297     static const WCHAR shelpW[]={'/','h','e','l','p',0};
298     static const WCHAR startW[]={'s','t','a','r','t',0};
299     static const WCHAR stopW[]={'s','t','o','p',0};
300     static const WCHAR useW[]={'u','s','e',0};
301
302     if (argc < 2)
303     {
304         output_string(STRING_USAGE);
305         return 1;
306     }
307
308     if(arg_is(argv[1], helpW))
309     {
310         if(argc > 3)
311         {
312             output_string(STRING_USAGE);
313             return 1;
314         }
315         if(argc == 2)
316             output_string(STRING_USAGE);
317         else if(arg_is(argv[2], startW))
318             output_string(STRING_START_USAGE);
319         else if(arg_is(argv[2], stopW))
320             output_string(STRING_STOP_USAGE);
321         else
322             output_string(STRING_USAGE);
323     }
324     else if(arg_is(argv[1], startW))
325     {
326         if(argc > 3)
327         {
328             output_string(STRING_START_USAGE);
329             return 1;
330         }
331         if (argc == 2)
332         {
333             if (!net_enum_services())
334                 return 1;
335         }
336         else if(arg_is(argv[2], shelpW))
337             output_string(STRING_START_USAGE);
338         else if(!net_service(NET_START, argv[2]))
339             return 1;
340     }
341     else if(arg_is(argv[1], stopW))
342     {
343         if(argc != 3)
344         {
345             output_string(STRING_STOP_USAGE);
346             return 1;
347         }
348         if(arg_is(argv[2], shelpW))
349             output_string(STRING_STOP_USAGE);
350         else if(!net_service(NET_STOP, argv[2]))
351             return 1;
352     }
353     else if(arg_is(argv[1], useW))
354     {
355         if(!net_use(argc, argv)) return 1;
356     }
357     else
358         output_string(STRING_USAGE);
359
360     return 0;
361 }