Changeset 43967 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- Nov 26, 2012 7:35:33 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 82312
- Location:
- trunk/src/VBox/Frontends/VBoxAutostart
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxAutostart/Makefile.kmk
r43909 r43967 20 20 21 21 ifeq ($(KBUILD_TARGET),win) 22 # PROGRAMS += VBoxAutostartSvc 23 # VBoxAutostart_TEMPLATE = VBOXMAINCLIENTEXE 24 # VBoxAutostart_SOURCES = \ 25 # VBoxAutostartStart.cpp \ 26 # VBoxAutostartStop.cpp \ 27 # VBoxAutostartUtils.cpp \ 28 # VBoxAutostart-win.cpp 22 PROGRAMS += VBoxAutostartSvc 23 VBoxAutostartSvc_TEMPLATE = VBOXMAINCLIENTEXE 24 VBoxAutostartSvc_SOURCES = \ 25 VBoxAutostartCfg.cpp \ 26 VBoxAutostartStart.cpp \ 27 VBoxAutostartStop.cpp \ 28 VBoxAutostartUtils.cpp \ 29 VBoxAutostart-win.cpp 29 30 else 30 31 PROGRAMS += VBoxAutostart -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart-posix.cpp
r43909 r43967 243 243 } 244 244 245 DECLHIDDEN(void) serviceLog(const char *pszFormat, ...)245 DECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType) 246 246 { 247 247 va_list args; 248 va_start(args, pszFormat); 249 char *psz = NULL; 250 RTStrAPrintfV(&psz, pszFormat, args); 251 va_end(args); 252 253 LogRel(("%s", psz)); 254 255 RTStrFree(psz); 248 249 if ( enmLogType == AUTOSTARTLOGTYPE_VERBOSE 250 && !g_fVerbose) 251 return; 252 253 LogRel(("%s", pszMsg)); 256 254 } 257 255 … … 335 333 336 334 RTStrmPrintf(g_pStdErr, "\nUse environment variable VBOXAUTOSTART_RELEASE_LOG for logging options.\n"); 337 }338 339 /**340 * Creates all global COM objects.341 *342 * @return HRESULT343 */344 static int autostartSetup()345 {346 serviceLogVerbose(("Setting up ...\n"));347 348 /*349 * Setup VirtualBox + session interfaces.350 */351 HRESULT rc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam());352 if (SUCCEEDED(rc))353 {354 rc = g_pSession.createInprocObject(CLSID_Session);355 if (FAILED(rc))356 RTMsgError("Failed to create a session object (rc=%Rhrc)!", rc);357 }358 else359 RTMsgError("Failed to get VirtualBox object (rc=%Rhrc)!", rc);360 361 if (FAILED(rc))362 return VERR_COM_OBJECT_NOT_FOUND;363 364 return VINF_SUCCESS;365 }366 367 static void autostartShutdown()368 {369 serviceLogVerbose(("Shutting down ...\n"));370 371 g_pSession.setNull();372 g_pVirtualBox.setNull();373 335 } 374 336 … … 583 545 #endif 584 546 585 /* 586 * Initialize COM. 587 */ 588 using namespace com; 589 HRESULT hrc = com::Initialize(); 590 # ifdef VBOX_WITH_XPCOM 591 if (hrc == NS_ERROR_FILE_ACCESS_DENIED) 592 { 593 char szHome[RTPATH_MAX] = ""; 594 com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome)); 595 return RTMsgErrorExit(RTEXITCODE_FAILURE, 596 "Failed to initialize COM because the global settings directory '%s' is not accessible!", szHome); 597 } 598 # endif 599 if (FAILED(hrc)) 600 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM (%Rhrc)!", hrc); 601 602 hrc = g_pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient); 603 if (FAILED(hrc)) 604 { 605 RTMsgError("Failed to create the VirtualBoxClient object (%Rhrc)!", hrc); 606 com::ErrorInfo info; 607 if (!info.isFullAvailable() && !info.isBasicAvailable()) 608 { 609 com::GluePrintRCMessage(hrc); 610 RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start."); 611 } 612 else 613 com::GluePrintErrorInfo(info); 614 return RTEXITCODE_FAILURE; 615 } 616 547 /* Set up COM */ 617 548 rc = autostartSetup(); 618 549 if (RT_FAILURE(rc)) … … 632 563 633 564 autostartShutdown(); 634 635 g_pVirtualBoxClient.setNull();636 637 com::Shutdown();638 639 565 return rcExit; 640 566 } -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart-win.cpp
r43911 r43967 29 29 *******************************************************************************/ 30 30 #include <Windows.h> 31 32 #include <VBox/com/com.h> 33 #include <VBox/com/string.h> 34 #include <VBox/com/Guid.h> 35 #include <VBox/com/array.h> 36 #include <VBox/com/ErrorInfo.h> 37 #include <VBox/com/errorprint.h> 38 39 #include <VBox/com/EventQueue.h> 40 #include <VBox/com/listeners.h> 41 #include <VBox/com/VirtualBox.h> 31 42 32 43 #include <VBox/log.h> … … 38 49 #include <iprt/getopt.h> 39 50 #include <iprt/semaphore.h> 51 #include <iprt/thread.h> 40 52 41 53 #include "VBoxAutostart.h" … … 49 61 #define AUTOSTART_SERVICE_DISPLAY_NAME "VirtualBox Autostart Service" 50 62 63 ComPtr<IVirtualBoxClient> g_pVirtualBoxClient = NULL; 64 bool g_fVerbose = false; 65 ComPtr<IVirtualBox> g_pVirtualBox = NULL; 66 ComPtr<ISession> g_pSession = NULL; 51 67 52 68 /******************************************************************************* … … 66 82 static SC_HANDLE autostartSvcWinOpenSCManager(const char *pszAction, DWORD dwAccess); 67 83 84 /** 85 * Print out progress on the console. 86 * 87 * This runs the main event queue every now and then to prevent piling up 88 * unhandled things (which doesn't cause real problems, just makes things 89 * react a little slower than in the ideal case). 90 */ 91 DECLHIDDEN(HRESULT) showProgress(ComPtr<IProgress> progress) 92 { 93 using namespace com; 94 95 BOOL fCompleted = FALSE; 96 ULONG ulCurrentPercent = 0; 97 ULONG ulLastPercent = 0; 98 99 ULONG ulLastOperationPercent = (ULONG)-1; 100 101 ULONG ulLastOperation = (ULONG)-1; 102 Bstr bstrOperationDescription; 103 104 EventQueue::getMainEventQueue()->processEventQueue(0); 105 106 ULONG cOperations = 1; 107 HRESULT hrc = progress->COMGETTER(OperationCount)(&cOperations); 108 if (FAILED(hrc)) 109 return hrc; 110 111 /* setup signal handling if cancelable */ 112 bool fCanceledAlready = false; 113 BOOL fCancelable; 114 hrc = progress->COMGETTER(Cancelable)(&fCancelable); 115 if (FAILED(hrc)) 116 fCancelable = FALSE; 117 118 hrc = progress->COMGETTER(Completed(&fCompleted)); 119 while (SUCCEEDED(hrc)) 120 { 121 progress->COMGETTER(Percent(&ulCurrentPercent)); 122 123 if (fCompleted) 124 break; 125 126 /* process async cancelation */ 127 if (!fCanceledAlready) 128 { 129 hrc = progress->Cancel(); 130 if (SUCCEEDED(hrc)) 131 fCanceledAlready = true; 132 } 133 134 /* make sure the loop is not too tight */ 135 progress->WaitForCompletion(100); 136 137 EventQueue::getMainEventQueue()->processEventQueue(0); 138 hrc = progress->COMGETTER(Completed(&fCompleted)); 139 } 140 141 /* complete the line. */ 142 LONG iRc = E_FAIL; 143 hrc = progress->COMGETTER(ResultCode)(&iRc); 144 if (SUCCEEDED(hrc)) 145 { 146 hrc = iRc; 147 } 148 149 return hrc; 150 } 151 152 DECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType) 153 { 154 HANDLE hEventLog = RegisterEventSourceA(NULL /* local computer */, "VBoxAutostartSvc"); 155 AssertReturnVoid(hEventLog != NULL); 156 WORD wType = 0; 157 const char *apsz[2]; 158 apsz[0] = "VBoxAutostartSvc"; 159 apsz[1] = pszMsg; 160 161 switch (enmLogType) 162 { 163 case AUTOSTARTLOGTYPE_INFO: 164 wType = 0; 165 break; 166 case AUTOSTARTLOGTYPE_ERROR: 167 wType = EVENTLOG_ERROR_TYPE; 168 break; 169 case AUTOSTARTLOGTYPE_WARNING: 170 wType = EVENTLOG_WARNING_TYPE; 171 break; 172 case AUTOSTARTLOGTYPE_VERBOSE: 173 if (!g_fVerbose) 174 return; 175 wType = EVENTLOG_INFORMATION_TYPE; 176 break; 177 default: 178 AssertMsgFailed(("Invalid log type %d\n", enmLogType)); 179 } 180 181 BOOL fRc = ReportEventA(hEventLog, /* hEventLog */ 182 wType, /* wType */ 183 0, /* wCategory */ 184 0 /** @todo mc */, /* dwEventID */ 185 NULL, /* lpUserSid */ 186 RT_ELEMENTS(apsz), /* wNumStrings */ 187 0, /* dwDataSize */ 188 apsz, /* lpStrings */ 189 NULL); /* lpRawData */ 190 AssertMsg(fRc, ("%d\n", GetLastError())); 191 DeregisterEventSource(hEventLog); 192 } 68 193 69 194 /** … … 119 244 return NULL; 120 245 121 SC_HANDLE hSvc = OpenService (hSCM, SUPSVC_SERVICE_NAME, dwSVCAccess);246 SC_HANDLE hSvc = OpenServiceA(hSCM, AUTOSTART_SERVICE_NAME, dwSVCAccess); 122 247 if (hSvc) 123 248 { … … 156 281 } 157 282 158 159 160 void autostartSvcOsLogErrorStr(const char *pszMsg)161 {162 HANDLE hEventLog = RegisterEventSource(NULL /* local computer */, "VBoxAutostartSvc");163 AssertReturnVoid(hEventLog != NULL);164 const char *apsz[2];165 apsz[0] = "VBoxAutostartSvc";166 apsz[1] = pszMsg;167 BOOL fRc = ReportEvent(hEventLog, /* hEventLog */168 EVENTLOG_ERROR_TYPE, /* wType */169 0, /* wCategory */170 0 /** @todo mc */, /* dwEventID */171 NULL, /* lpUserSid */172 RT_ELEMENTS(apsz), /* wNumStrings */173 0, /* dwDataSize */174 apsz, /* lpStrings */175 NULL); /* lpRawData */176 AssertMsg(fRc, ("%d\n", GetLastError()));177 DeregisterEventSource(hEventLog);178 }179 180 181 283 static RTEXITCODE autostartSvcWinInterrogate(int argc, char **argv) 182 284 { … … 210 312 { 211 313 RTPrintf("VBoxAutostartSvc: The \"start\" action is not implemented.\n"); 212 return RTEXITCODE_ FAILURE;314 return RTEXITCODE_SUCCESS; 213 315 } 214 316 … … 259 361 }; 260 362 int ch; 363 unsigned iArg = 0; 261 364 RTGETOPTUNION Value; 262 365 RTGETOPTSTATE GetState; 263 366 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 264 367 while ((ch = RTGetOpt(&GetState, &Value))) 368 { 265 369 switch (ch) 266 370 { … … 274 378 } 275 379 380 iArg++; 381 } 382 276 383 /* 277 384 * Create the service. … … 279 386 int rc = RTEXITCODE_FAILURE; 280 387 SC_HANDLE hSvc = autostartSvcWinOpenService("delete", SERVICE_CHANGE_CONFIG, DELETE, 281 1, ERROR_SERVICE_DOES_NOT_EXIST);388 1, ERROR_SERVICE_DOES_NOT_EXIST); 282 389 if (hSvc) 283 390 { 284 391 if (DeleteService(hSvc)) 285 392 { 286 RTPrintf("Successfully deleted the %s service.\n", SUPSVC_SERVICE_NAME);393 RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME); 287 394 rc = RTEXITCODE_SUCCESS; 288 395 } … … 295 402 296 403 if (fVerbose) 297 RTPrintf("The service %s was not installed, nothing to be done.", SUPSVC_SERVICE_NAME);404 RTPrintf("The service %s was not installed, nothing to be done.", AUTOSTART_SERVICE_NAME); 298 405 else 299 RTPrintf("Successfully deleted the %s service.\n", SUPSVC_SERVICE_NAME);406 RTPrintf("Successfully deleted the %s service.\n", AUTOSTART_SERVICE_NAME); 300 407 rc = RTEXITCODE_SUCCESS; 301 408 } … … 319 426 const char *pszUser = NULL; 320 427 const char *pszPwd = NULL; 321 static const RT OPTIONDEF s_aOptions[] =428 static const RTGETOPTDEF s_aOptions[] = 322 429 { 323 430 { "--verbose", 'v', RTGETOPT_REQ_NOTHING }, 324 { "--user", 'u', RTGETOPT_REQ_STRIN },325 { "--password", 'p', RTGETOPT_REQ_STRIN }431 { "--user", 'u', RTGETOPT_REQ_STRING }, 432 { "--password", 'p', RTGETOPT_REQ_STRING } 326 433 }; 327 434 int iArg = 0; 328 435 int ch; 329 436 RTGETOPTUNION Value; 330 while ((ch = RTGetOpt(argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value))) 437 RTGETOPTSTATE GetState; 438 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 439 while ((ch = RTGetOpt(&GetState, &Value))) 440 { 331 441 switch (ch) 332 442 { … … 337 447 pszUser = Value.psz; 338 448 break; 339 case 'p' 449 case 'p': 340 450 pszPwd = Value.psz; 341 451 break; … … 343 453 return autostartSvcDisplayGetOptError("create", ch, argc, argv, iArg, &Value); 344 454 } 455 iArg++; 456 } 345 457 if (iArg != argc) 346 458 return autostartSvcDisplayTooManyArgsError("create", argc, argv, iArg); … … 349 461 * Create the service. 350 462 */ 351 intrc = RTEXITCODE_FAILURE;463 RTEXITCODE rc = RTEXITCODE_FAILURE; 352 464 SC_HANDLE hSCM = autostartSvcWinOpenSCManager("create", SC_MANAGER_CREATE_SERVICE); /*SC_MANAGER_ALL_ACCESS*/ 353 465 if (hSCM) 354 466 { 355 467 char szExecPath[MAX_PATH]; 356 if (GetModuleFileName (NULL /* the executable */, szExecPath, sizeof(szExecPath)))468 if (GetModuleFileNameA(NULL /* the executable */, szExecPath, sizeof(szExecPath))) 357 469 { 358 470 if (fVerbose) 359 471 RTPrintf("Creating the %s service, binary \"%s\"...\n", 360 SUPSVC_SERVICE_NAME, szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */361 362 SC_HANDLE hSvc = CreateService (hSCM, /* hSCManager */363 SUPSVC_SERVICE_NAME,/* lpServiceName */364 SUPSVC_SERVICE_DISPLAY_NAME,/* lpDisplayName */365 SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, /* dwDesiredAccess */366 SERVICE_WIN32_OWN_PROCESS, /* dwServiceType ( | SERVICE_INTERACTIVE_PROCESS? ) */367 SERVICE_DEMAND_START/*_AUTO*/,/* dwStartType */368 SERVICE_ERROR_NORMAL, /* dwErrorControl */369 szExecPath, /* lpBinaryPathName */370 NULL, /* lpLoadOrderGroup */371 NULL, /* lpdwTagId */372 NULL, /* lpDependencies */373 pszUser, /* lpServiceStartName (NULL => LocalSystem) */374 pszPwd); /* lpPassword */472 AUTOSTART_SERVICE_NAME, szExecPath); /* yea, the binary name isn't UTF-8, but wtf. */ 473 474 SC_HANDLE hSvc = CreateServiceA(hSCM, /* hSCManager */ 475 AUTOSTART_SERVICE_NAME, /* lpServiceName */ 476 AUTOSTART_SERVICE_DISPLAY_NAME, /* lpDisplayName */ 477 SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG, /* dwDesiredAccess */ 478 SERVICE_WIN32_OWN_PROCESS, /* dwServiceType ( | SERVICE_INTERACTIVE_PROCESS? ) */ 479 SERVICE_AUTO_START, /* dwStartType */ 480 SERVICE_ERROR_NORMAL, /* dwErrorControl */ 481 szExecPath, /* lpBinaryPathName */ 482 NULL, /* lpLoadOrderGroup */ 483 NULL, /* lpdwTagId */ 484 NULL, /* lpDependencies */ 485 pszUser, /* lpServiceStartName (NULL => LocalSystem) */ 486 pszPwd); /* lpPassword */ 375 487 if (hSvc) 376 488 { 377 RTPrintf("Successfully created the %s service.\n", SUPSVC_SERVICE_NAME);489 RTPrintf("Successfully created the %s service.\n", AUTOSTART_SERVICE_NAME); 378 490 /** @todo Set the service description or it'll look weird in the vista service manager. 379 491 * Anything else that should be configured? Start access or something? */ … … 482 594 */ 483 595 autostartSvcWinSetServiceStatus(SERVICE_STOP_PENDING, 3000, NO_ERROR); 484 int rc = autostartSvcTryStopServices(); 485 if (RT_SUCCESS(rc)) 486 { 487 /* 488 * Notify the main thread that we're done, it will wait for the 489 * real services to stop, destroy them, and finally set the windows 490 * service status to SERVICE_STOPPED and return. 491 */ 492 rc = RTSemEventMultiSignal(g_hSupSvcWinEvent); 493 if (RT_FAILURE(rc)) 494 autostartSvcLogError("SERVICE_CONTROL_STOP: RTSemEventMultiSignal failed, %Rrc\n", rc); 495 } 596 /* 597 * Notify the main thread that we're done, it will wait for the 598 * VMs to stop, and set the windows service status to SERVICE_STOPPED 599 * and return. 600 */ 601 int rc = RTSemEventMultiSignal(g_hSupSvcWinEvent); 602 if (RT_FAILURE(rc)) 603 autostartSvcLogError("SERVICE_CONTROL_STOP: RTSemEventMultiSignal failed, %Rrc\n", rc); 604 496 605 return NO_ERROR; 497 606 } … … 522 631 } 523 632 633 static int autostartWorker(RTTHREAD ThreadSelf, void *pvUser) 634 { 635 int rc = autostartSetup(); 636 637 /** @todo: Implement config options. */ 638 rc = autostartStartMain(NULL); 639 if (RT_FAILURE(rc)) 640 autostartSvcLogError("Starting VMs failed, rc=%Rrc", rc); 641 642 return rc; 643 } 524 644 525 645 /** … … 532 652 * @param papszArgs Argument vector. 533 653 */ 534 static VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LP STR *papszArgs)654 static VOID WINAPI autostartSvcWinServiceMain(DWORD cArgs, LPTSTR *papszArgs) 535 655 { 536 656 LogFlowFuncEnter(); … … 540 660 */ 541 661 Assert(g_u32SupSvcWinStatus == SERVICE_STOPPED); 542 g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerEx (SUPSVC_SERVICE_NAME, autostartSvcWinServiceCtrlHandlerEx, NULL);662 g_hSupSvcWinCtrlHandler = RegisterServiceCtrlHandlerExA(AUTOSTART_SERVICE_NAME, autostartSvcWinServiceCtrlHandlerEx, NULL); 543 663 if (g_hSupSvcWinCtrlHandler) 544 664 { … … 546 666 if (autostartSvcWinSetServiceStatus(SERVICE_START_PENDING, 3000, NO_ERROR)) 547 667 { 548 /* 549 * Parse arguments. 550 */ 551 static const RTOPTIONDEF s_aOptions[] = 552 { 553 { "--dummy", 'd', RTGETOPT_REQ_NOTHING } 554 }; 555 int iArg = 1; /* the first arg is the service name */ 556 int ch; 557 int rc = 0; 558 RTGETOPTUNION Value; 559 while ( !rc 560 && (ch = RTGetOpt(cArgs, papszArgs, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value))) 561 switch (ch) 562 { 563 default: rc = autostartSvcLogGetOptError("main", ch, cArgs, papszArgs, iArg, &Value); break; 564 } 565 if (iArg != cArgs) 566 rc = autostartSvcLogTooManyArgsError("main", cArgs, papszArgs, iArg); 567 if (!rc) 668 if (cArgs == 1) 568 669 { 569 670 /* … … 574 675 if (RT_SUCCESS(rc)) 575 676 { 576 rc = autostartSvcCreateAndStartServices(); 577 if (RT_SUCCESS(rc)) 677 /* 678 * Update the status and enter the work loop. 679 */ 680 if (autostartSvcWinSetServiceStatus(SERVICE_RUNNING, 0, 0)) 578 681 { 579 /* 580 * Update the status and enter the work loop. 581 * 582 * The work loop is just a dummy wait here as the services run 583 * in independent threads. 584 */ 585 if (autostartSvcWinSetServiceStatus(SERVICE_RUNNING, 0, 0)) 682 LogFlow(("autostartSvcWinServiceMain: calling RTSemEventMultiWait\n")); 683 RTTHREAD hWorker; 684 RTThreadCreate(&hWorker, autostartWorker, NULL, 0, RTTHREADTYPE_DEFAULT, 0, "WorkerThread"); 685 686 LogFlow(("autostartSvcWinServiceMain: woke up\n")); 687 err = NO_ERROR; 688 rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT); 689 if (RT_SUCCESS(rc)) 586 690 { 587 LogFlow(("autostartSvcWinServiceMain: calling RTSemEventMultiWait\n")); 588 /** @todo: Implement autostart */ 589 rc = RTSemEventMultiWait(g_hSupSvcWinEvent, RT_INDEFINITE_WAIT); 590 if (RT_SUCCESS(rc)) 591 { 592 LogFlow(("autostartSvcWinServiceMain: woke up\n")); 593 err = NO_ERROR; 594 } 595 else 596 autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc); 691 LogFlow(("autostartSvcWinServiceMain: woke up\n")); 692 /** @todo: Autostop part. */ 693 err = NO_ERROR; 597 694 } 598 695 else 599 { 600 err = GetLastError(); 601 autostartSvcLogError("SetServiceStatus failed, err=%d", err); 602 } 603 604 /* 605 * Destroy the service instances, stopping them if 606 * they're still running (weird failure cause). 607 */ 608 autostartSvcStopAndDestroyServices(); 696 autostartSvcLogError("RTSemEventWait failed, rc=%Rrc", rc); 697 698 autostartShutdown(); 699 } 700 else 701 { 702 err = GetLastError(); 703 autostartSvcLogError("SetServiceStatus failed, err=%d", err); 609 704 } 610 705 … … 615 710 autostartSvcLogError("RTSemEventMultiCreate failed, rc=%Rrc", rc); 616 711 } 617 /* else: bad args */ 712 else 713 autostartSvcLogTooManyArgsError("main", cArgs, NULL, 0); 618 714 } 619 715 else … … 626 722 else 627 723 autostartSvcLogError("RegisterServiceCtrlHandlerEx failed, err=%d", GetLastError()); 724 628 725 LogFlowFuncLeave(); 629 726 } … … 649 746 * Parse the arguments. 650 747 */ 651 static const RT OPTIONDEF s_aOptions[] =748 static const RTGETOPTDEF s_aOptions[] = 652 749 { 653 750 { "--dummy", 'd', RTGETOPT_REQ_NOTHING } … … 656 753 int ch; 657 754 RTGETOPTUNION Value; 658 while ((ch = RTGetOpt(argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value))) 755 RTGETOPTSTATE GetState; 756 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 757 while ((ch = RTGetOpt(&GetState, &Value))) 659 758 switch (ch) 660 759 { … … 670 769 static SERVICE_TABLE_ENTRY const s_aServiceStartTable[] = 671 770 { 672 { SUPSVC_SERVICE_NAME, autostartSvcWinServiceMain },771 { _T(AUTOSTART_SERVICE_NAME), autostartSvcWinServiceMain }, 673 772 { NULL, NULL} 674 773 }; … … 683 782 { 684 783 case ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: 685 autostartSvc DisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n");784 autostartSvcWinServiceMain(0, NULL);//autostartSvcDisplayError("Cannot run a service from the command line. Use the 'start' action to start it the right way.\n"); 686 785 break; 687 786 default: … … 704 803 */ 705 804 bool fBrief = false; 706 static const RT OPTIONDEF s_aOptions[] =805 static const RTGETOPTDEF s_aOptions[] = 707 806 { 708 807 { "--brief", 'b', RTGETOPT_REQ_NOTHING } … … 711 810 int ch; 712 811 RTGETOPTUNION Value; 713 while ((ch = RTGetOpt(argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), &iArg, &Value))) 812 RTGETOPTSTATE GetState; 813 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS); 814 while ((ch = RTGetOpt(&GetState, &Value))) 714 815 switch (ch) 715 816 { … … 731 832 "All rights reserved.\n", 732 833 VBOX_VERSION_STRING); 733 return 0;834 return RTEXITCODE_SUCCESS; 734 835 } 735 836 … … 758 859 "VBoxAutostartSvc <install|/RegServer|/i>\n" 759 860 " Installs the service.\n" 760 "VBoxAutostartSvc < install|delete|/UnregServer|/u>\n"861 "VBoxAutostartSvc <uninstall|delete|/UnregServer|/u>\n" 761 862 " Uninstalls the service.\n" 762 863 ); … … 774 875 * @param argv Argument vector. 775 876 */ 776 RTEXITCODEmain(int argc, char **argv)877 int main(int argc, char **argv) 777 878 { 778 879 /* … … 783 884 { 784 885 autostartSvcLogError("RTR3InitExe failed with rc=%Rrc", rc); 785 return 1; 786 } 886 return RTEXITCODE_FAILURE; 887 } 888 889 RTThreadSleep(10 * 1000); 787 890 788 891 /* -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostart.h
r43378 r43967 22 22 * Header Files * 23 23 *******************************************************************************/ 24 #include <iprt/getopt.h> 25 #include <iprt/types.h> 26 24 27 #include <VBox/cdefs.h> 25 28 #include <VBox/types.h> … … 93 96 94 97 /** Flag whether we are in verbose logging mode. */ 95 extern bool g_fVerbose;98 extern bool g_fVerbose; 96 99 /** Handle to the VirtualBox interface. */ 97 extern ComPtr<IVirtualBox> g_pVirtualBox;100 extern ComPtr<IVirtualBox> g_pVirtualBox; 98 101 /** Handle to the session interface. */ 99 extern ComPtr<ISession> g_pSession; 100 101 /** 102 * Log information in verbose mode. 103 */ 104 #define serviceLogVerbose(a) if (g_fVerbose) { serviceLog a; } 105 106 /** 107 * Log messages to the release log. 102 extern ComPtr<ISession> g_pSession; 103 /** handle to the VirtualBox interface. */ 104 extern ComPtr<IVirtualBoxClient> g_pVirtualBoxClient; 105 /** 106 * System log type. 107 */ 108 typedef enum AUTOSTARTLOGTYPE 109 { 110 /** Invalid log type. */ 111 AUTOSTARTLOGTYPE_INVALID = 0, 112 /** Log info message. */ 113 AUTOSTARTLOGTYPE_INFO, 114 /** Log error message. */ 115 AUTOSTARTLOGTYPE_ERROR, 116 /** Log warning message. */ 117 AUTOSTARTLOGTYPE_WARNING, 118 /** Log verbose message, only if verbose mode is activated. */ 119 AUTOSTARTLOGTYPE_VERBOSE, 120 /** Famous 32bit hack. */ 121 AUTOSTARTLOGTYPE_32BIT_HACK = 0x7fffffff 122 } AUTOSTARTLOGTYPE; 123 124 /** 125 * Log messages to the system and release log. 108 126 * 109 127 * @returns nothing. 110 * @param pszFormat Format string. 111 */ 112 DECLHIDDEN(void) serviceLog(const char *pszFormat, ...); 128 * @param pszMsg Message to log. 129 * @param enmLogType Log type to use. 130 */ 131 DECLHIDDEN(void) autostartSvcOsLogStr(const char *pszMsg, AUTOSTARTLOGTYPE enmLogType); 113 132 114 133 /** … … 173 192 DECLHIDDEN(RTEXITCODE) autostartStopMain(PCFGAST pCfgAst); 174 193 194 /** 195 * Logs a verbose message to the appropriate system log. 196 * 197 * @param pszFormat The log string. No trailing newline. 198 * @param ... Format arguments. 199 */ 200 DECLHIDDEN(void) autostartSvcLogVerboseV(const char *pszFormat, va_list va); 201 202 /** 203 * Logs a verbose message to the appropriate system log. 204 * 205 * @param pszFormat The log string. No trailing newline. 206 * @param ... Format arguments. 207 */ 208 DECLHIDDEN(void) autostartSvcLogVerbose(const char *pszFormat, ...); 209 210 /** 211 * Logs a warning message to the appropriate system log. 212 * 213 * @param pszFormat The log string. No trailing newline. 214 * @param ... Format arguments. 215 */ 216 DECLHIDDEN(void) autostartSvcLogWarningV(const char *pszFormat, va_list va); 217 218 /** 219 * Logs a warning message to the appropriate system log. 220 * 221 * @param pszFormat The log string. No trailing newline. 222 * @param ... Format arguments. 223 */ 224 DECLHIDDEN(void) autostartSvcLogWarning(const char *pszFormat, ...); 225 226 /** 227 * Logs a info message to the appropriate system log. 228 * 229 * @param pszFormat The log string. No trailing newline. 230 * @param ... Format arguments. 231 */ 232 DECLHIDDEN(void) autostartSvcLogInfoV(const char *pszFormat, va_list va); 233 234 /** 235 * Logs a info message to the appropriate system log. 236 * 237 * @param pszFormat The log string. No trailing newline. 238 * @param ... Format arguments. 239 */ 240 DECLHIDDEN(void) autostartSvcLogInfo(const char *pszFormat, ...); 241 242 /** 243 * Logs the message to the appropriate system log. 244 * 245 * In debug builds this will also put it in the debug log. 246 * 247 * @param pszFormat The log string. No trailing newline. 248 * @param ... Format arguments. 249 * 250 * @todo This should later be replaced by the release logger and callback destination(s). 251 */ 252 DECLHIDDEN(void) autostartSvcLogErrorV(const char *pszFormat, va_list va); 253 254 /** 255 * Logs the error message to the appropriate system log. 256 * 257 * In debug builds this will also put it in the debug log. 258 * 259 * @param pszFormat The log string. No trailing newline. 260 * @param ... Format arguments. 261 * 262 * @todo This should later be replaced by the release logger and callback destination(s). 263 */ 264 DECLHIDDEN(void) autostartSvcLogError(const char *pszFormat, ...); 265 266 /** 267 * Deals with RTGetOpt failure, bitching in the system log. 268 * 269 * @returns 1 270 * @param pszAction The action name. 271 * @param rc The RTGetOpt return value. 272 * @param argc The argument count. 273 * @param argv The argument vector. 274 * @param iArg The argument index. 275 * @param pValue The value returned by RTGetOpt. 276 */ 277 DECLHIDDEN(RTEXITCODE) autostartSvcLogGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue); 278 279 /** 280 * Bitch about too many arguments (after RTGetOpt stops) in the system log. 281 * 282 * @returns 1 283 * @param pszAction The action name. 284 * @param argc The argument count. 285 * @param argv The argument vector. 286 * @param iArg The argument index. 287 */ 288 DECLHIDDEN(RTEXITCODE) autostartSvcLogTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg); 289 290 /** 291 * Prints an error message to the screen. 292 * 293 * @param pszFormat The message format string. 294 * @param va Format arguments. 295 */ 296 DECLHIDDEN(void) autostartSvcDisplayErrorV(const char *pszFormat, va_list va); 297 298 /** 299 * Prints an error message to the screen. 300 * 301 * @param pszFormat The message format string. 302 * @param ... Format arguments. 303 */ 304 DECLHIDDEN(void) autostartSvcDisplayError(const char *pszFormat, ...); 305 306 /** 307 * Deals with RTGetOpt failure. 308 * 309 * @returns 1 310 * @param pszAction The action name. 311 * @param rc The RTGetOpt return value. 312 * @param argc The argument count. 313 * @param argv The argument vector. 314 * @param iArg The argument index. 315 * @param pValue The value returned by RTGetOpt. 316 */ 317 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue); 318 319 /** 320 * Bitch about too many arguments (after RTGetOpt stops). 321 * 322 * @returns RTEXITCODE_FAILURE 323 * @param pszAction The action name. 324 * @param argc The argument count. 325 * @param argv The argument vector. 326 * @param iArg The argument index. 327 */ 328 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg); 329 330 DECLHIDDEN(int) autostartSetup(); 331 332 DECLHIDDEN(void) autostartShutdown(); 333 175 334 #endif /* __VBoxAutostart_h__ */ 176 335 -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStart.cpp
r42732 r43967 72 72 if (uStartupDelay) 73 73 { 74 serviceLogVerbose(("Delay starting for %d seconds ...\n", uStartupDelay));74 autostartSvcLogVerbose("Delay starting for %d seconds ...\n", uStartupDelay); 75 75 vrc = RTThreadSleep(uStartupDelay * 1000); 76 76 } … … 129 129 if ((*it).uStartupDelay > uDelayCurr) 130 130 { 131 serviceLogVerbose(("Delay starting of the next VMs for %d seconds ...\n",132 (*it).uStartupDelay - uDelayCurr));131 autostartSvcLogVerbose("Delay starting of the next VMs for %d seconds ...\n", 132 (*it).uStartupDelay - uDelayCurr); 133 133 RTThreadSleep(((*it).uStartupDelay - uDelayCurr) * 1000); 134 134 uDelayCurr = (*it).uStartupDelay; … … 142 142 if (SUCCEEDED(rc) && !progress.isNull()) 143 143 { 144 serviceLogVerbose(("Waiting for VM \"%ls\" to power on...\n", (*it).strId.raw()));144 autostartSvcLogVerbose("Waiting for VM \"%ls\" to power on...\n", (*it).strId.raw()); 145 145 CHECK_ERROR(progress, WaitForCompletion(-1)); 146 146 if (SUCCEEDED(rc)) … … 162 162 } 163 163 else 164 serviceLogVerbose(("VM \"%ls\" has been successfully started.\n", (*it).strId.raw()));164 autostartSvcLogVerbose("VM \"%ls\" has been successfully started.\n", (*it).strId.raw()); 165 165 } 166 166 } -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartStop.cpp
r43909 r43967 202 202 CHECK_ERROR_BREAK(console, PowerButton()); 203 203 204 serviceLog("Waiting for VM \"%ls\" to power off...\n", (*it).strId.raw());204 autostartSvcLogInfo("Waiting for VM \"%ls\" to power off...\n", (*it).strId.raw()); 205 205 206 206 do … … 213 213 { 214 214 /* Use save state instead and log this to the console. */ 215 serviceLog("The guest of VM \"%ls\" does not support ACPI shutdown or is currently paused, saving state...\n",216 (*it).strId.raw());215 autostartSvcLogWarning("The guest of VM \"%ls\" does not support ACPI shutdown or is currently paused, saving state...\n", 216 (*it).strId.raw()); 217 217 rc = autostartSaveVMState(console); 218 218 } … … 220 220 } 221 221 default: 222 serviceLog("Unknown autostop type for VM \"%ls\"\n", (*it).strId.raw());222 autostartSvcLogWarning("Unknown autostop type for VM \"%ls\"\n", (*it).strId.raw()); 223 223 } 224 224 g_pSession->UnlockMachine(); -
trunk/src/VBox/Frontends/VBoxAutostart/VBoxAutostartUtils.cpp
r43912 r43967 24 24 #include <VBox/com/errorprint.h> 25 25 26 #include <VBox/err.h> 27 26 28 #include <iprt/message.h> 27 29 #include <iprt/thread.h> 28 30 #include <iprt/stream.h> 29 31 #include <iprt/log.h> 32 #include <iprt/path.h> 30 33 31 34 #include <algorithm> … … 87 90 } 88 91 92 DECLHIDDEN(void) autostartSvcLogErrorV(const char *pszFormat, va_list va) 93 { 94 if (*pszFormat) 95 { 96 char *pszMsg = NULL; 97 if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1) 98 { 99 autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_ERROR); 100 RTStrFree(pszMsg); 101 } 102 else 103 autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_ERROR); 104 } 105 } 106 107 DECLHIDDEN(void) autostartSvcLogError(const char *pszFormat, ...) 108 { 109 va_list va; 110 va_start(va, pszFormat); 111 autostartSvcLogErrorV(pszFormat, va); 112 va_end(va); 113 } 114 115 DECLHIDDEN(void) autostartSvcLogVerboseV(const char *pszFormat, va_list va) 116 { 117 if (*pszFormat) 118 { 119 char *pszMsg = NULL; 120 if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1) 121 { 122 autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_VERBOSE); 123 RTStrFree(pszMsg); 124 } 125 else 126 autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_VERBOSE); 127 } 128 } 129 130 DECLHIDDEN(void) autostartSvcLogVerbose(const char *pszFormat, ...) 131 { 132 va_list va; 133 va_start(va, pszFormat); 134 autostartSvcLogVerboseV(pszFormat, va); 135 va_end(va); 136 } 137 138 DECLHIDDEN(void) autostartSvcLogWarningV(const char *pszFormat, va_list va) 139 { 140 if (*pszFormat) 141 { 142 char *pszMsg = NULL; 143 if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1) 144 { 145 autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_WARNING); 146 RTStrFree(pszMsg); 147 } 148 else 149 autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_WARNING); 150 } 151 } 152 153 DECLHIDDEN(void) autostartSvcLogInfo(const char *pszFormat, ...) 154 { 155 va_list va; 156 va_start(va, pszFormat); 157 autostartSvcLogInfoV(pszFormat, va); 158 va_end(va); 159 } 160 161 DECLHIDDEN(void) autostartSvcLogInfoV(const char *pszFormat, va_list va) 162 { 163 if (*pszFormat) 164 { 165 char *pszMsg = NULL; 166 if (RTStrAPrintfV(&pszMsg, pszFormat, va) != -1) 167 { 168 autostartSvcOsLogStr(pszMsg, AUTOSTARTLOGTYPE_INFO); 169 RTStrFree(pszMsg); 170 } 171 else 172 autostartSvcOsLogStr(pszFormat, AUTOSTARTLOGTYPE_INFO); 173 } 174 } 175 176 DECLHIDDEN(void) autostartSvcLogWarning(const char *pszFormat, ...) 177 { 178 va_list va; 179 va_start(va, pszFormat); 180 autostartSvcLogWarningV(pszFormat, va); 181 va_end(va); 182 } 183 184 DECLHIDDEN(RTEXITCODE) autostartSvcLogGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue) 185 { 186 NOREF(pValue); 187 autostartSvcLogError("%s - RTGetOpt failure, %Rrc (%d): %s", 188 pszAction, rc, rc, iArg < argc ? argv[iArg] : "<null>"); 189 return RTEXITCODE_FAILURE; 190 } 191 192 DECLHIDDEN(RTEXITCODE) autostartSvcLogTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg) 193 { 194 Assert(iArg < argc); 195 autostartSvcLogError("%s - Too many arguments: %s", pszAction, argv[iArg]); 196 for ( ; iArg < argc; iArg++) 197 LogRel(("arg#%i: %s\n", iArg, argv[iArg])); 198 return RTEXITCODE_FAILURE; 199 } 200 201 DECLHIDDEN(void) autostartSvcDisplayErrorV(const char *pszFormat, va_list va) 202 { 203 RTStrmPrintf(g_pStdErr, "VBoxSupSvc error: "); 204 RTStrmPrintfV(g_pStdErr, pszFormat, va); 205 Log(("autostartSvcDisplayErrorV: %s", pszFormat)); /** @todo format it! */ 206 } 207 208 DECLHIDDEN(void) autostartSvcDisplayError(const char *pszFormat, ...) 209 { 210 va_list va; 211 va_start(va, pszFormat); 212 autostartSvcDisplayErrorV(pszFormat, va); 213 va_end(va); 214 } 215 216 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayGetOptError(const char *pszAction, int rc, int argc, char **argv, int iArg, PCRTGETOPTUNION pValue) 217 { 218 autostartSvcDisplayError("%s - RTGetOpt failure, %Rrc (%d): %s\n", 219 pszAction, rc, rc, iArg < argc ? argv[iArg] : "<null>"); 220 return RTEXITCODE_FAILURE; 221 } 222 223 DECLHIDDEN(RTEXITCODE) autostartSvcDisplayTooManyArgsError(const char *pszAction, int argc, char **argv, int iArg) 224 { 225 Assert(iArg < argc); 226 autostartSvcDisplayError("%s - Too many arguments: %s\n", pszAction, argv[iArg]); 227 return RTEXITCODE_FAILURE; 228 } 229 230 DECLHIDDEN(int) autostartSetup() 231 { 232 autostartSvcOsLogStr("Setting up ...\n", AUTOSTARTLOGTYPE_VERBOSE); 233 234 /* 235 * Initialize COM. 236 */ 237 using namespace com; 238 HRESULT hrc = com::Initialize(); 239 # ifdef VBOX_WITH_XPCOM 240 if (hrc == NS_ERROR_FILE_ACCESS_DENIED) 241 { 242 char szHome[RTPATH_MAX] = ""; 243 com::GetVBoxUserHomeDirectory(szHome, sizeof(szHome)); 244 return RTMsgErrorExit(RTEXITCODE_FAILURE, 245 "Failed to initialize COM because the global settings directory '%s' is not accessible!", szHome); 246 } 247 # endif 248 if (FAILED(hrc)) 249 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to initialize COM (%Rhrc)!", hrc); 250 251 hrc = g_pVirtualBoxClient.createInprocObject(CLSID_VirtualBoxClient); 252 if (FAILED(hrc)) 253 { 254 RTMsgError("Failed to create the VirtualBoxClient object (%Rhrc)!", hrc); 255 com::ErrorInfo info; 256 if (!info.isFullAvailable() && !info.isBasicAvailable()) 257 { 258 com::GluePrintRCMessage(hrc); 259 RTMsgError("Most likely, the VirtualBox COM server is not running or failed to start."); 260 } 261 else 262 com::GluePrintErrorInfo(info); 263 return RTEXITCODE_FAILURE; 264 } 265 266 /* 267 * Setup VirtualBox + session interfaces. 268 */ 269 HRESULT rc = g_pVirtualBoxClient->COMGETTER(VirtualBox)(g_pVirtualBox.asOutParam()); 270 if (SUCCEEDED(rc)) 271 { 272 rc = g_pSession.createInprocObject(CLSID_Session); 273 if (FAILED(rc)) 274 RTMsgError("Failed to create a session object (rc=%Rhrc)!", rc); 275 } 276 else 277 RTMsgError("Failed to get VirtualBox object (rc=%Rhrc)!", rc); 278 279 if (FAILED(rc)) 280 return VERR_COM_OBJECT_NOT_FOUND; 281 282 return VINF_SUCCESS; 283 } 284 285 DECLHIDDEN(void) autostartShutdown() 286 { 287 autostartSvcOsLogStr("Shutting down ...\n", AUTOSTARTLOGTYPE_VERBOSE); 288 289 g_pSession.setNull(); 290 g_pVirtualBox.setNull(); 291 g_pVirtualBoxClient.setNull(); 292 com::Shutdown(); 293 } 294
Note:
See TracChangeset
for help on using the changeset viewer.