1c2c66affSColin Finck /* 2c2c66affSColin Finck * PROJECT: ReactOS Services 3c2c66affSColin Finck * LICENSE: GPL - See COPYING in the top level directory 4c2c66affSColin Finck * FILE: base/applications/sc/sc.c 5c2c66affSColin Finck * PURPOSE: parse command line 6c2c66affSColin Finck * COPYRIGHT: Copyright 2005 - 2006 Ged Murphy <gedmurphy@gmail.com> 7c2c66affSColin Finck * 8c2c66affSColin Finck */ 9c2c66affSColin Finck 10c2c66affSColin Finck #include "sc.h" 11c2c66affSColin Finck 12c2c66affSColin Finck SC_HANDLE hSCManager; 13c2c66affSColin Finck 14c2c66affSColin Finck VOID 15c2c66affSColin Finck ReportLastError(VOID) 16c2c66affSColin Finck { 17c2c66affSColin Finck LPVOID lpMsgBuf; 18c2c66affSColin Finck DWORD RetVal; 19c2c66affSColin Finck 20c2c66affSColin Finck DWORD ErrorCode = GetLastError(); 21c2c66affSColin Finck if (ErrorCode != ERROR_SUCCESS) 22c2c66affSColin Finck { 23c2c66affSColin Finck RetVal = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 24c2c66affSColin Finck FORMAT_MESSAGE_FROM_SYSTEM | 25c2c66affSColin Finck FORMAT_MESSAGE_IGNORE_INSERTS, 26c2c66affSColin Finck NULL, 27c2c66affSColin Finck ErrorCode, 28c2c66affSColin Finck MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ 29c2c66affSColin Finck (LPTSTR) &lpMsgBuf, 30c2c66affSColin Finck 0, 31c2c66affSColin Finck NULL ); 32c2c66affSColin Finck 33c2c66affSColin Finck if (RetVal != 0) 34c2c66affSColin Finck { 35c2c66affSColin Finck _tprintf(_T("%s"), (LPTSTR)lpMsgBuf); 36c2c66affSColin Finck LocalFree(lpMsgBuf); 37c2c66affSColin Finck } 38c2c66affSColin Finck } 39c2c66affSColin Finck } 40c2c66affSColin Finck 41c2c66affSColin Finck 42c2c66affSColin Finck static INT 43c2c66affSColin Finck ScControl(LPCTSTR Server, // remote machine name 44c2c66affSColin Finck LPCTSTR Command, // sc command 45c2c66affSColin Finck LPCTSTR *ServiceArgs, // any options 46c2c66affSColin Finck DWORD ArgCount) // argument counter 47c2c66affSColin Finck { 48c2c66affSColin Finck LPCTSTR ServiceName = NULL; 49c2c66affSColin Finck 50c2c66affSColin Finck if (Server) 51c2c66affSColin Finck { 52c2c66affSColin Finck _tprintf(_T("Remote service control is not yet implemented\n")); 53c2c66affSColin Finck return 2; 54c2c66affSColin Finck } 55c2c66affSColin Finck 56c2c66affSColin Finck if (!lstrcmpi(Command, _T("query"))) 57c2c66affSColin Finck { 58c2c66affSColin Finck Query(ServiceArgs, 59c2c66affSColin Finck ArgCount, 60c2c66affSColin Finck FALSE); 61c2c66affSColin Finck } 62c2c66affSColin Finck else if (!lstrcmpi(Command, _T("queryex"))) 63c2c66affSColin Finck { 64c2c66affSColin Finck Query(ServiceArgs, 65c2c66affSColin Finck ArgCount, 66c2c66affSColin Finck TRUE); 67c2c66affSColin Finck } 68c2c66affSColin Finck else if (!lstrcmpi(Command, _T("start"))) 69c2c66affSColin Finck { 70c2c66affSColin Finck if (ArgCount > 0) 71c2c66affSColin Finck { 72c2c66affSColin Finck ServiceName = *ServiceArgs++; 73c2c66affSColin Finck ArgCount--; 74c2c66affSColin Finck 75c2c66affSColin Finck Start(ServiceName, 76c2c66affSColin Finck ServiceArgs, 77c2c66affSColin Finck ArgCount); 78c2c66affSColin Finck } 79c2c66affSColin Finck else 80c2c66affSColin Finck StartUsage(); 81c2c66affSColin Finck } 82c2c66affSColin Finck else if (!lstrcmpi(Command, _T("pause"))) 83c2c66affSColin Finck { 84c2c66affSColin Finck if (ArgCount > 0) 85c2c66affSColin Finck { 86c2c66affSColin Finck ServiceName = *ServiceArgs++; 87c2c66affSColin Finck ArgCount--; 88c2c66affSColin Finck 89c2c66affSColin Finck Control(SERVICE_CONTROL_PAUSE, 90c2c66affSColin Finck ServiceName, 91c2c66affSColin Finck ServiceArgs, 92c2c66affSColin Finck ArgCount); 93c2c66affSColin Finck } 94c2c66affSColin Finck else 95c2c66affSColin Finck PauseUsage(); 96c2c66affSColin Finck } 97c2c66affSColin Finck else if (!lstrcmpi(Command, _T("interrogate"))) 98c2c66affSColin Finck { 99c2c66affSColin Finck if (ArgCount > 0) 100c2c66affSColin Finck { 101c2c66affSColin Finck ServiceName = *ServiceArgs++; 102c2c66affSColin Finck ArgCount--; 103c2c66affSColin Finck 104c2c66affSColin Finck Control(SERVICE_CONTROL_INTERROGATE, 105c2c66affSColin Finck ServiceName, 106c2c66affSColin Finck ServiceArgs, 107c2c66affSColin Finck ArgCount); 108c2c66affSColin Finck } 109c2c66affSColin Finck else 110c2c66affSColin Finck InterrogateUsage(); 111c2c66affSColin Finck } 112c2c66affSColin Finck else if (!lstrcmpi(Command, _T("stop"))) 113c2c66affSColin Finck { 114c2c66affSColin Finck if (ArgCount > 0) 115c2c66affSColin Finck { 116c2c66affSColin Finck ServiceName = *ServiceArgs++; 117c2c66affSColin Finck ArgCount--; 118c2c66affSColin Finck 119c2c66affSColin Finck Control(SERVICE_CONTROL_STOP, 120c2c66affSColin Finck ServiceName, 121c2c66affSColin Finck ServiceArgs, 122c2c66affSColin Finck ArgCount); 123c2c66affSColin Finck } 124c2c66affSColin Finck else 125c2c66affSColin Finck StopUsage(); 126c2c66affSColin Finck } 127c2c66affSColin Finck else if (!lstrcmpi(Command, _T("continue"))) 128c2c66affSColin Finck { 129c2c66affSColin Finck if (ArgCount > 0) 130c2c66affSColin Finck { 131c2c66affSColin Finck ServiceName = *ServiceArgs++; 132c2c66affSColin Finck ArgCount--; 133c2c66affSColin Finck 134c2c66affSColin Finck Control(SERVICE_CONTROL_CONTINUE, 135c2c66affSColin Finck ServiceName, 136c2c66affSColin Finck ServiceArgs, 137c2c66affSColin Finck ArgCount); 138c2c66affSColin Finck } 139c2c66affSColin Finck else 140c2c66affSColin Finck ContinueUsage(); 141c2c66affSColin Finck } 142c2c66affSColin Finck else if (!lstrcmpi(Command, _T("delete"))) 143c2c66affSColin Finck { 144c2c66affSColin Finck if (ArgCount > 0) 145c2c66affSColin Finck { 146c2c66affSColin Finck ServiceName = *ServiceArgs++; 147c2c66affSColin Finck ArgCount--; 148c2c66affSColin Finck 149c2c66affSColin Finck Delete(ServiceName); 150c2c66affSColin Finck } 151c2c66affSColin Finck else 152c2c66affSColin Finck DeleteUsage(); 153c2c66affSColin Finck } 154c2c66affSColin Finck else if (!lstrcmpi(Command, _T("create"))) 155c2c66affSColin Finck { 156c2c66affSColin Finck Create(ServiceArgs, ArgCount); 157c2c66affSColin Finck } 158c2c66affSColin Finck else if (!lstrcmpi(Command, _T("control"))) 159c2c66affSColin Finck { 160*a0d412b7SEric Kohl INT ControlCode = 0; 161c2c66affSColin Finck 162c2c66affSColin Finck if (ArgCount > 1) 163c2c66affSColin Finck { 164c2c66affSColin Finck ServiceName = *ServiceArgs++; 165c2c66affSColin Finck ArgCount--; 166c2c66affSColin Finck 167*a0d412b7SEric Kohl if (!lstrcmpi(ServiceArgs[0], _T("paramchange"))) 168*a0d412b7SEric Kohl ControlCode = SERVICE_CONTROL_PARAMCHANGE; 169*a0d412b7SEric Kohl else if (!lstrcmpi(ServiceArgs[0], _T("netbindadd"))) 170*a0d412b7SEric Kohl ControlCode = SERVICE_CONTROL_NETBINDADD; 171*a0d412b7SEric Kohl else if (!lstrcmpi(ServiceArgs[0], _T("netbindremove"))) 172*a0d412b7SEric Kohl ControlCode = SERVICE_CONTROL_NETBINDREMOVE; 173*a0d412b7SEric Kohl else if (!lstrcmpi(ServiceArgs[0], _T("netbindenable"))) 174*a0d412b7SEric Kohl ControlCode = SERVICE_CONTROL_NETBINDENABLE; 175*a0d412b7SEric Kohl else if (!lstrcmpi(ServiceArgs[0], _T("netbinddisable"))) 176*a0d412b7SEric Kohl ControlCode = SERVICE_CONTROL_NETBINDDISABLE; 177*a0d412b7SEric Kohl else 178*a0d412b7SEric Kohl { 179*a0d412b7SEric Kohl ControlCode = _ttoi(ServiceArgs[0]); 180*a0d412b7SEric Kohl if ((ControlCode < 128) && (ControlCode > 255)) 181*a0d412b7SEric Kohl ControlCode = 0; 182*a0d412b7SEric Kohl } 183*a0d412b7SEric Kohl 184c2c66affSColin Finck ServiceArgs++; 185c2c66affSColin Finck ArgCount--; 186c2c66affSColin Finck 187*a0d412b7SEric Kohl if (ControlCode != 0) 188*a0d412b7SEric Kohl Control(ControlCode, 189c2c66affSColin Finck ServiceName, 190c2c66affSColin Finck ServiceArgs, 191c2c66affSColin Finck ArgCount); 192c2c66affSColin Finck else 193c2c66affSColin Finck ControlUsage(); 194c2c66affSColin Finck } 195c2c66affSColin Finck else 196c2c66affSColin Finck ControlUsage(); 197c2c66affSColin Finck } 198c2c66affSColin Finck else if (!lstrcmpi(Command, _T("sdshow"))) 199c2c66affSColin Finck { 200c2c66affSColin Finck if (ArgCount > 0) 201c2c66affSColin Finck { 202c2c66affSColin Finck ServiceName = *ServiceArgs++; 203c2c66affSColin Finck ArgCount--; 204c2c66affSColin Finck 205c2c66affSColin Finck SdShow(ServiceName); 206c2c66affSColin Finck } 207c2c66affSColin Finck else 208c2c66affSColin Finck SdShowUsage(); 209c2c66affSColin Finck } 210c2c66affSColin Finck else if (!lstrcmpi(Command, _T("sdset"))) 211c2c66affSColin Finck { 212c2c66affSColin Finck LPCTSTR SecurityDescriptor; 213c2c66affSColin Finck 214c2c66affSColin Finck if (ArgCount > 1) 215c2c66affSColin Finck { 216c2c66affSColin Finck ServiceName = *ServiceArgs++; 217c2c66affSColin Finck ArgCount--; 218c2c66affSColin Finck 219c2c66affSColin Finck SecurityDescriptor = *ServiceArgs++; 220c2c66affSColin Finck ArgCount--; 221c2c66affSColin Finck 222c2c66affSColin Finck SdSet(ServiceName, SecurityDescriptor); 223c2c66affSColin Finck } 224c2c66affSColin Finck else 225c2c66affSColin Finck SdSetUsage(); 226c2c66affSColin Finck } 227c2c66affSColin Finck else if (!lstrcmpi(Command, _T("qc"))) 228c2c66affSColin Finck { 229c2c66affSColin Finck if (ArgCount > 0) 230c2c66affSColin Finck { 231c2c66affSColin Finck ServiceName = *ServiceArgs++; 232c2c66affSColin Finck ArgCount--; 233c2c66affSColin Finck 234c2c66affSColin Finck QueryConfig(ServiceName); 235c2c66affSColin Finck } 236c2c66affSColin Finck else 237c2c66affSColin Finck QueryConfigUsage(); 238c2c66affSColin Finck } 239c2c66affSColin Finck else if (!lstrcmpi(Command, _T("qdescription"))) 240c2c66affSColin Finck { 241c2c66affSColin Finck if (ArgCount > 0) 242c2c66affSColin Finck { 243c2c66affSColin Finck ServiceName = *ServiceArgs++; 244c2c66affSColin Finck ArgCount--; 245c2c66affSColin Finck 246c2c66affSColin Finck QueryDescription(ServiceName); 247c2c66affSColin Finck } 248c2c66affSColin Finck else 249c2c66affSColin Finck QueryDescriptionUsage(); 250c2c66affSColin Finck } 251c2c66affSColin Finck else if (!lstrcmpi(Command, _T("qfailure"))) 252c2c66affSColin Finck { 253c2c66affSColin Finck if (ArgCount > 0) 254c2c66affSColin Finck { 255c2c66affSColin Finck ServiceName = *ServiceArgs++; 256c2c66affSColin Finck ArgCount--; 257c2c66affSColin Finck 258c2c66affSColin Finck QueryFailure(ServiceName); 259c2c66affSColin Finck } 260c2c66affSColin Finck else 261c2c66affSColin Finck QueryFailureUsage(); 262c2c66affSColin Finck } 263c2c66affSColin Finck else if (!lstrcmpi(Command, _T("description"))) 264c2c66affSColin Finck { 265c2c66affSColin Finck LPCTSTR Description = NULL; 266c2c66affSColin Finck 267c2c66affSColin Finck if (ArgCount > 0) 268c2c66affSColin Finck { 269c2c66affSColin Finck ServiceName = *ServiceArgs++; 270c2c66affSColin Finck ArgCount--; 271c2c66affSColin Finck 272c2c66affSColin Finck if (ArgCount > 0) 273c2c66affSColin Finck { 274c2c66affSColin Finck Description = *ServiceArgs++; 275c2c66affSColin Finck ArgCount--; 276c2c66affSColin Finck } 277c2c66affSColin Finck 278c2c66affSColin Finck SetDescription(ServiceName, Description); 279c2c66affSColin Finck } 280c2c66affSColin Finck else 281c2c66affSColin Finck SetDescriptionUsage(); 282c2c66affSColin Finck } 283c2c66affSColin Finck else if (!lstrcmpi(Command, _T("config"))) 284c2c66affSColin Finck { 285c2c66affSColin Finck SetConfig(ServiceArgs, ArgCount); 286c2c66affSColin Finck } 287c2c66affSColin Finck else if (!lstrcmpi(Command, _T("failure"))) 288c2c66affSColin Finck { 289c2c66affSColin Finck SetFailure(ServiceArgs, ArgCount); 290c2c66affSColin Finck } 291c2c66affSColin Finck else if (!lstrcmpi(Command, _T("GetDisplayName"))) 292c2c66affSColin Finck { 293c2c66affSColin Finck if (ArgCount > 0) 294c2c66affSColin Finck { 295c2c66affSColin Finck ServiceName = *ServiceArgs++; 296c2c66affSColin Finck ArgCount--; 297c2c66affSColin Finck 298c2c66affSColin Finck GetDisplayName(ServiceName); 299c2c66affSColin Finck } 300c2c66affSColin Finck else 301c2c66affSColin Finck GetDisplayNameUsage(); 302c2c66affSColin Finck } 303c2c66affSColin Finck else if (!lstrcmpi(Command, _T("GetKeyName"))) 304c2c66affSColin Finck { 305c2c66affSColin Finck if (ArgCount > 0) 306c2c66affSColin Finck { 307c2c66affSColin Finck ServiceName = *ServiceArgs++; 308c2c66affSColin Finck ArgCount--; 309c2c66affSColin Finck 310c2c66affSColin Finck GetKeyName(ServiceName); 311c2c66affSColin Finck } 312c2c66affSColin Finck else 313c2c66affSColin Finck GetKeyNameUsage(); 314c2c66affSColin Finck } 315c2c66affSColin Finck else if (!lstrcmpi(Command, _T("EnumDepend"))) 316c2c66affSColin Finck { 317c2c66affSColin Finck if (ArgCount > 0) 318c2c66affSColin Finck { 319c2c66affSColin Finck ServiceName = *ServiceArgs++; 320c2c66affSColin Finck ArgCount--; 321c2c66affSColin Finck 322c2c66affSColin Finck EnumDepend(ServiceName); 323c2c66affSColin Finck } 324c2c66affSColin Finck else 325c2c66affSColin Finck EnumDependUsage(); 326c2c66affSColin Finck } 327c2c66affSColin Finck else 328c2c66affSColin Finck { 329c2c66affSColin Finck MainUsage(); 330c2c66affSColin Finck } 331c2c66affSColin Finck 332c2c66affSColin Finck return 0; 333c2c66affSColin Finck } 334c2c66affSColin Finck 335c2c66affSColin Finck int _tmain(int argc, LPCTSTR argv[]) 336c2c66affSColin Finck { 337c2c66affSColin Finck LPCTSTR Server = NULL; // remote machine 338c2c66affSColin Finck LPCTSTR Command = NULL; // sc command 339c2c66affSColin Finck LPCTSTR *Args = NULL; // Any remaining args 340c2c66affSColin Finck 341c2c66affSColin Finck if (argc < 2) 342c2c66affSColin Finck { 343c2c66affSColin Finck MainUsage(); 344c2c66affSColin Finck return -1; 345c2c66affSColin Finck } 346c2c66affSColin Finck 347c2c66affSColin Finck /* get server name */ 348c2c66affSColin Finck if ((argv[1][0] == '\\') && (argv[1][1] == '\\')) 349c2c66affSColin Finck { 350c2c66affSColin Finck if (argc < 3) 351c2c66affSColin Finck { 352c2c66affSColin Finck MainUsage(); 353c2c66affSColin Finck return -1; 354c2c66affSColin Finck } 355c2c66affSColin Finck 356c2c66affSColin Finck Server = argv[1]; 357c2c66affSColin Finck Command = argv[2]; 358c2c66affSColin Finck if (argc > 3) 359c2c66affSColin Finck Args = &argv[3]; 360c2c66affSColin Finck 361c2c66affSColin Finck return ScControl(Server, 362c2c66affSColin Finck Command, 363c2c66affSColin Finck Args, 364c2c66affSColin Finck argc-3); 365c2c66affSColin Finck } 366c2c66affSColin Finck else 367c2c66affSColin Finck { 368c2c66affSColin Finck Command = argv[1]; 369c2c66affSColin Finck if (argc > 2) 370c2c66affSColin Finck Args = &argv[2]; 371c2c66affSColin Finck 372c2c66affSColin Finck return ScControl(Server, 373c2c66affSColin Finck Command, 374c2c66affSColin Finck Args, 375c2c66affSColin Finck argc-2); 376c2c66affSColin Finck } 377c2c66affSColin Finck } 378