1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS net command
4  * FILE:            base/applications/network/net/cmdStart.c
5  * PURPOSE:
6  *
7  * PROGRAMMERS:     Magnus Olsen (greatlord@reactos.org)
8  */
9 
10 #include "net.h"
11 
12 /* Enumerate all running services */
13 static
14 INT
15 EnumerateRunningServices(VOID)
16 {
17     SC_HANDLE hManager = NULL;
18     SC_HANDLE hService = NULL;
19     DWORD dwBufferSize = 0;
20     DWORD dwServiceCount;
21     DWORD dwResumeHandle = 0;
22     LPENUM_SERVICE_STATUSW lpServiceBuffer = NULL;
23     INT i;
24     INT nError = 0;
25     DWORD dwError = ERROR_SUCCESS;
26     BOOL ret;
27 
28     hManager = OpenSCManagerW(NULL,
29                               SERVICES_ACTIVE_DATABASE,
30                               SC_MANAGER_ENUMERATE_SERVICE);
31     if (hManager == NULL)
32     {
33         dwError = GetLastError();
34         nError = 1;
35         goto done;
36     }
37 
38     ret = EnumServicesStatusW(hManager,
39                               SERVICE_WIN32,
40                               SERVICE_ACTIVE,
41                               NULL,
42                               0,
43                               &dwBufferSize,
44                               &dwServiceCount,
45                               &dwResumeHandle);
46     if (ret)
47     {
48         /* Nothing to enumerate ?! */
49         goto done;
50     }
51     dwError = GetLastError();
52     if (dwError != ERROR_INSUFFICIENT_BUFFER)
53         goto done;
54 
55     if (dwBufferSize != 0)
56     {
57         lpServiceBuffer = HeapAlloc(GetProcessHeap(), 0, dwBufferSize);
58         if (lpServiceBuffer != NULL)
59         {
60             if (EnumServicesStatusW(hManager,
61                                     SERVICE_WIN32,
62                                     SERVICE_ACTIVE,
63                                     lpServiceBuffer,
64                                     dwBufferSize,
65                                     &dwBufferSize,
66                                     &dwServiceCount,
67                                     &dwResumeHandle))
68             {
69                 ConPuts(StdOut, L"The following services have been started:\n\n");
70 
71                 for (i = 0; i < dwServiceCount; i++)
72                 {
73                     ConPrintf(StdOut, L"  %s\n", lpServiceBuffer[i].lpDisplayName);
74                 }
75             }
76 
77             HeapFree(GetProcessHeap(), 0, lpServiceBuffer);
78         }
79     }
80 
81 done:
82     if (hService != NULL)
83         CloseServiceHandle(hService);
84 
85     if (hManager != NULL)
86         CloseServiceHandle(hManager);
87 
88      if (dwError != ERROR_SUCCESS)
89     {
90         /* FIXME: Print proper error message */
91         ConPrintf(StdErr, L"Error: %lu\n", dwError);
92     }
93 
94     return nError;
95 }
96 
97 /* Start the service argv[2] */
98 static
99 INT
100 StartOneService(INT argc, WCHAR **argv)
101 {
102     SC_HANDLE hManager = NULL;
103     SC_HANDLE hService = NULL;
104     LPCWSTR *lpArgVectors = NULL;
105     DWORD dwError = ERROR_SUCCESS;
106     INT nError = 0;
107     INT i;
108 
109     hManager = OpenSCManagerW(NULL,
110                               SERVICES_ACTIVE_DATABASE,
111                               SC_MANAGER_ENUMERATE_SERVICE);
112     if (hManager == NULL)
113     {
114         dwError = GetLastError();
115         nError = 1;
116         goto done;
117     }
118 
119     hService = OpenServiceW(hManager,
120                             argv[2],
121                             SERVICE_START);
122     if (hService == NULL)
123     {
124         dwError = GetLastError();
125         nError = 1;
126         goto done;
127     }
128 
129     lpArgVectors = HeapAlloc(GetProcessHeap(),
130                              0,
131                              (argc - 2) * sizeof(LPCWSTR));
132     if (lpArgVectors == NULL)
133     {
134         dwError = GetLastError();
135         nError = 1;
136         goto done;
137     }
138 
139     for (i = 2; i < argc; i++)
140     {
141         lpArgVectors[i - 2] = argv[i];
142     }
143 
144     if (!StartServiceW(hService,
145                        (DWORD)argc - 2,
146                        lpArgVectors))
147     {
148         dwError = GetLastError();
149         nError = 1;
150     }
151 
152 done:
153     if (lpArgVectors != NULL)
154         HeapFree(GetProcessHeap(), 0, (LPVOID)lpArgVectors);
155 
156     if (hService != NULL)
157         CloseServiceHandle(hService);
158 
159     if (hManager != NULL)
160         CloseServiceHandle(hManager);
161 
162     if (dwError != ERROR_SUCCESS)
163     {
164         /* FIXME: Print proper error message */
165         ConPrintf(StdErr, L"Error: %lu\n", dwError);
166     }
167 
168     return nError;
169 }
170 
171 INT
172 cmdStart(INT argc, WCHAR **argv)
173 {
174     INT i;
175 
176     if (argc == 2)
177     {
178         return EnumerateRunningServices();
179     }
180 
181     for (i = 2; i < argc; i++)
182     {
183         if (_wcsicmp(argv[i], L"/help") == 0)
184         {
185             PrintMessageString(4381);
186             ConPuts(StdOut, L"\n");
187             PrintNetMessage(MSG_START_SYNTAX);
188             PrintNetMessage(MSG_START_HELP);
189             return 1;
190         }
191     }
192 
193     return StartOneService(argc, argv);
194 }
195