Changeset 33898 in vbox
- Timestamp:
- Nov 9, 2010 1:49:22 PM (14 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
-
Frontends/VBoxManage/VBoxManageGuestCtrl.cpp (modified) (4 diffs)
-
Main/GuestImpl.cpp (modified) (3 diffs)
-
Main/idl/VirtualBox.xidl (modified) (2 diffs)
-
Main/include/GuestImpl.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
r33841 r33898 95 95 " --username <name> --password <password>\n" 96 96 " [--dryrun] [--recursive] [--verbose] [--flags <flags>]\n" 97 "\n" 98 " createdirectory <vmname>|<uuid>\n" 99 " <directory to create on guest>\n" 100 " --username <name> --password <password>\n" 101 " [--parents] [--mode <mode>]\n" 97 102 "\n" 98 103 " updateadditions <vmname>|<uuid>\n" … … 593 598 return VERR_NO_MEMORY; 594 599 } 595 600 596 601 pNode->Node.pPrev = NULL; 597 602 pNode->Node.pNext = NULL; … … 1237 1242 } 1238 1243 1244 static int handleCtrlCreateDirectory(HandlerArg *a) 1245 { 1246 /* 1247 * Check the syntax. We can deduce the correct syntax from the number of 1248 * arguments. 1249 */ 1250 if (a->argc < 2) /* At least the directory we want to create should be present :-). */ 1251 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 1252 1253 Utf8Str Utf8Directory(a->argv[1]); 1254 Utf8Str Utf8UserName; 1255 Utf8Str Utf8Password; 1256 uint32_t uFlags = CreateDirectoryFlag_None; 1257 uint32_t uMode = 0; 1258 bool fVerbose = false; 1259 1260 /* Iterate through all possible commands (if available). */ 1261 bool usageOK = true; 1262 for (int i = 3; usageOK && i < a->argc; i++) 1263 { 1264 if ( !strcmp(a->argv[i], "--username") 1265 || !strcmp(a->argv[i], "--user")) 1266 { 1267 if (i + 1 >= a->argc) 1268 usageOK = false; 1269 else 1270 { 1271 Utf8UserName = a->argv[i + 1]; 1272 ++i; 1273 } 1274 } 1275 else if ( !strcmp(a->argv[i], "--password") 1276 || !strcmp(a->argv[i], "--pwd")) 1277 { 1278 if (i + 1 >= a->argc) 1279 usageOK = false; 1280 else 1281 { 1282 Utf8Password = a->argv[i + 1]; 1283 ++i; 1284 } 1285 } 1286 else if ( !strcmp(a->argv[i], "--parents") 1287 || !strcmp(a->argv[i], "-p")) 1288 { 1289 uFlags |= CreateDirectoryFlag_Parents; 1290 } 1291 else if ( !strcmp(a->argv[i], "--mode") 1292 || !strcmp(a->argv[i], "-m")) 1293 { 1294 if (i + 1 >= a->argc) 1295 usageOK = false; 1296 else 1297 { 1298 uMode = atoi(a->argv[i + 1]); 1299 ++i; 1300 } 1301 } 1302 else if (!strcmp(a->argv[i], "--flags")) 1303 { 1304 if (i + 1 >= a->argc) 1305 usageOK = false; 1306 else 1307 { 1308 /* Nothing to do here yet. */ 1309 ++i; 1310 } 1311 } 1312 /** @todo Add force flag for overwriting existing stuff. */ 1313 else if (!strcmp(a->argv[i], "--verbose")) 1314 fVerbose = true; 1315 else 1316 return errorSyntax(USAGE_GUESTCONTROL, 1317 "Invalid parameter '%s'", Utf8Str(a->argv[i]).c_str()); 1318 } 1319 1320 if (!usageOK) 1321 return errorSyntax(USAGE_GUESTCONTROL, "Incorrect parameters"); 1322 1323 if (Utf8Directory.isEmpty()) 1324 return errorSyntax(USAGE_GUESTCONTROL, 1325 "No directory specified!"); 1326 1327 if (Utf8UserName.isEmpty()) 1328 return errorSyntax(USAGE_GUESTCONTROL, 1329 "No user name specified!"); 1330 1331 /* Lookup VM. */ 1332 ComPtr<IMachine> machine; 1333 /* Assume it's an UUID. */ 1334 HRESULT rc; 1335 CHECK_ERROR(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), 1336 machine.asOutParam())); 1337 if (FAILED(rc)) 1338 return 1; 1339 1340 /* Machine is running? */ 1341 MachineState_T machineState; 1342 CHECK_ERROR_RET(machine, COMGETTER(State)(&machineState), 1); 1343 if (machineState != MachineState_Running) 1344 { 1345 RTMsgError("Machine \"%s\" is not running!\n", a->argv[0]); 1346 return 1; 1347 } 1348 1349 /* Open a session for the VM. */ 1350 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); 1351 1352 do 1353 { 1354 /* Get the associated console. */ 1355 ComPtr<IConsole> console; 1356 CHECK_ERROR_BREAK(a->session, COMGETTER(Console)(console.asOutParam())); 1357 /* ... and session machine */ 1358 ComPtr<IMachine> sessionMachine; 1359 CHECK_ERROR_BREAK(a->session, COMGETTER(Machine)(sessionMachine.asOutParam())); 1360 1361 ComPtr<IGuest> guest; 1362 CHECK_ERROR_BREAK(console, COMGETTER(Guest)(guest.asOutParam())); 1363 1364 ComPtr<IProgress> progress; 1365 rc = guest->CreateDirectory(Bstr(Utf8Directory).raw(), 1366 Bstr(Utf8UserName).raw(), Bstr(Utf8Password).raw(), 1367 uMode, uFlags, progress.asOutParam()); 1368 if (FAILED(rc)) 1369 { 1370 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 1371 * because it contains more accurate info about what went wrong. */ 1372 ErrorInfo info(guest, COM_IIDOF(IGuest)); 1373 if (info.isFullAvailable()) 1374 { 1375 if (rc == VBOX_E_IPRT_ERROR) 1376 RTMsgError("%ls.", info.getText().raw()); 1377 else 1378 RTMsgError("%ls (%Rhrc).", info.getText().raw(), info.getResultCode()); 1379 } 1380 } 1381 else 1382 { 1383 /* Setup signal handling if cancelable. */ 1384 ASSERT(progress); 1385 bool fCanceledAlready = false; 1386 BOOL fCancelable; 1387 HRESULT hrc = progress->COMGETTER(Cancelable)(&fCancelable); 1388 if (FAILED(hrc)) 1389 fCancelable = FALSE; 1390 if (fCancelable) 1391 { 1392 signal(SIGINT, ctrlCopySignalHandler); 1393 #ifdef SIGBREAK 1394 signal(SIGBREAK, ctrlCopySignalHandler); 1395 #endif 1396 } 1397 1398 /* Wait for process to exit ... */ 1399 BOOL fCompleted = FALSE; 1400 BOOL fCanceled = FALSE; 1401 while ( SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))) 1402 && !fCompleted) 1403 { 1404 /* Process async cancelation */ 1405 if (g_fCopyCanceled && !fCanceledAlready) 1406 { 1407 hrc = progress->Cancel(); 1408 if (SUCCEEDED(hrc)) 1409 fCanceledAlready = TRUE; 1410 else 1411 g_fCopyCanceled = false; 1412 } 1413 1414 /* Progress canceled by Main API? */ 1415 if ( SUCCEEDED(progress->COMGETTER(Canceled(&fCanceled))) 1416 && fCanceled) 1417 { 1418 break; 1419 } 1420 } 1421 1422 /* Undo signal handling */ 1423 if (fCancelable) 1424 { 1425 signal(SIGINT, SIG_DFL); 1426 #ifdef SIGBREAK 1427 signal(SIGBREAK, SIG_DFL); 1428 #endif 1429 } 1430 1431 if (fCanceled) 1432 { 1433 //RTPrintf("Copy operation canceled!\n"); 1434 } 1435 else if ( fCompleted 1436 && SUCCEEDED(rc)) 1437 { 1438 LONG iRc = false; 1439 CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc); 1440 if (FAILED(iRc)) 1441 { 1442 com::ProgressErrorInfo info(progress); 1443 if ( info.isFullAvailable() 1444 || info.isBasicAvailable()) 1445 { 1446 /* If we got a VBOX_E_IPRT error we handle the error in a more gentle way 1447 * because it contains more accurate info about what went wrong. */ 1448 if (info.getResultCode() == VBOX_E_IPRT_ERROR) 1449 RTMsgError("%ls.", info.getText().raw()); 1450 else 1451 { 1452 RTMsgError("Copy operation error details:"); 1453 GluePrintErrorInfo(info); 1454 } 1455 } 1456 } 1457 } 1458 } 1459 1460 a->session->UnlockMachine(); 1461 } while (0); 1462 return SUCCEEDED(rc) ? 0 : 1; 1463 } 1464 1239 1465 static int handleCtrlUpdateAdditions(HandlerArg *a) 1240 1466 { … … 1388 1614 return handleCtrlExecProgram(&arg); 1389 1615 } 1390 else if (!strcmp(a->argv[0], "copyto")) 1616 else if ( !strcmp(a->argv[0], "copyto") 1617 || !strcmp(a->argv[0], "cp")) 1391 1618 { 1392 1619 return handleCtrlCopyTo(&arg); 1620 } 1621 else if ( !strcmp(a->argv[0], "createdirectory") 1622 || !strcmp(a->argv[0], "createdir") 1623 || !strcmp(a->argv[0], "mkdir")) 1624 { 1625 return handleCtrlCreateDirectory(&arg); 1393 1626 } 1394 1627 else if ( !strcmp(a->argv[0], "updateadditions") -
trunk/src/VBox/Main/GuestImpl.cpp
r33776 r33898 2316 2316 if (RTStrPrintf(szOutput, sizeof(szOutput), "--output=%s", Utf8Dest.c_str())) 2317 2317 { 2318 /* 2319 * Normalize path slashes, based on the detected guest. 2320 */ 2321 Utf8Str osType = mData.mOSTypeId; 2322 if ( osType.contains("Microsoft", Utf8Str::CaseInsensitive) 2323 || osType.contains("Windows", Utf8Str::CaseInsensitive)) 2324 { 2325 /* We have a Windows guest. */ 2326 RTPathChangeToDosSlashes(szOutput, true /* Force conversion. */); 2327 } 2328 else /* ... or something which isn't from Redmond ... */ 2329 { 2330 RTPathChangeToUnixSlashes(szOutput, true /* Force conversion. */); 2331 } 2332 2318 2333 args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */ 2319 2334 args.push_back(Bstr(szOutput).raw()); /* We want to write a file ... */ … … 2326 2341 if (SUCCEEDED(rc)) 2327 2342 { 2328 LogRel(("Copying file \"%s\" to guest \"%s\" ...\n",2329 Utf8Source.c_str(), Utf8Dest.c_str() ));2343 LogRel(("Copying file \"%s\" to guest \"%s\" (%u bytes) ...\n", 2344 Utf8Source.c_str(), Utf8Dest.c_str(), cbSize)); 2330 2345 /* 2331 2346 * Okay, since we gathered all stuff we need until now to start the … … 2389 2404 } 2390 2405 RTFileClose(fileSource); 2406 } 2407 } 2408 } 2409 catch (std::bad_alloc &) 2410 { 2411 rc = E_OUTOFMEMORY; 2412 } 2413 return rc; 2414 #endif /* VBOX_WITH_GUEST_CONTROL */ 2415 } 2416 2417 STDMETHODIMP Guest::CreateDirectory(IN_BSTR aDirectory, 2418 IN_BSTR aUserName, IN_BSTR aPassword, 2419 ULONG aMode, ULONG aFlags, 2420 IProgress **aProgress) 2421 { 2422 #ifndef VBOX_WITH_GUEST_CONTROL 2423 ReturnComNotImplemented(); 2424 #else /* VBOX_WITH_GUEST_CONTROL */ 2425 using namespace guestControl; 2426 2427 CheckComArgStrNotEmptyOrNull(aDirectory); 2428 2429 /* Do not allow anonymous executions (with system rights). */ 2430 if (RT_UNLIKELY((aUserName) == NULL || *(aUserName) == '\0')) 2431 return setError(E_INVALIDARG, tr("No user name specified")); 2432 2433 LogRel(("Creating guest directory \"%s\" as user \"%s\" ...\n", 2434 Utf8Str(aDirectory).c_str(), Utf8Str(aUserName).c_str())); 2435 2436 return createDirectoryInternal(aDirectory, 2437 aUserName, aPassword, 2438 aMode, aFlags, aProgress, NULL /* rc */); 2439 #endif 2440 } 2441 2442 STDMETHODIMP Guest::createDirectoryInternal(IN_BSTR aDirectory, 2443 IN_BSTR aUserName, IN_BSTR aPassword, 2444 ULONG aMode, ULONG aFlags, 2445 IProgress **aProgress, int *pRC) 2446 { 2447 #ifndef VBOX_WITH_GUEST_CONTROL 2448 ReturnComNotImplemented(); 2449 #else /* VBOX_WITH_GUEST_CONTROL */ 2450 using namespace guestControl; 2451 2452 CheckComArgStrNotEmptyOrNull(aDirectory); 2453 CheckComArgOutPointerValid(aProgress); 2454 2455 AutoCaller autoCaller(this); 2456 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 2457 2458 /* Validate flags. */ 2459 if (aFlags != CreateDirectoryFlag_None) 2460 { 2461 if (!(aFlags & CreateDirectoryFlag_Parents)) 2462 { 2463 return setError(E_INVALIDARG, tr("Unknown flags (%#x)"), aFlags); 2464 } 2465 } 2466 2467 HRESULT rc = S_OK; 2468 2469 try 2470 { 2471 Utf8Str Utf8Directory(aDirectory); 2472 Utf8Str Utf8UserName(aUserName); 2473 Utf8Str Utf8Password(aPassword); 2474 2475 com::SafeArray<IN_BSTR> args; 2476 com::SafeArray<IN_BSTR> env; 2477 2478 /* 2479 * Prepare tool command line. 2480 */ 2481 args.push_back(Bstr(VBOXSERVICE_TOOL_CAT).raw()); /* The actual (internal) tool to use (as argv[0]). */ 2482 if (aFlags & CreateDirectoryFlag_Parents) 2483 args.push_back(Bstr("--parents").raw()); /* We also want to create the parent directories. */ 2484 if (aMode > 0) 2485 { 2486 args.push_back(Bstr("--mode").raw()); /* Set the creation mode. */ 2487 2488 char szMode[16]; 2489 if (RTStrPrintf(szMode, sizeof(szMode), "%o", aMode)) 2490 args.push_back(Bstr(szMode).raw()); 2491 else 2492 rc = setError(VBOX_E_IPRT_ERROR, tr("Error preparing command line")); 2493 } 2494 args.push_back(Bstr(Utf8Directory).raw()); /* The directory we want to create. */ 2495 2496 /* 2497 * Execute guest process. 2498 */ 2499 ComPtr<IProgress> execProgress; 2500 ULONG uPID; 2501 if (SUCCEEDED(rc)) 2502 { 2503 rc = ExecuteProcess(Bstr(VBOXSERVICE_TOOL_CAT).raw(), 2504 ExecuteProcessFlag_None, 2505 ComSafeArrayAsInParam(args), 2506 ComSafeArrayAsInParam(env), 2507 Bstr(Utf8UserName).raw(), 2508 Bstr(Utf8Password).raw(), 2509 5 * 1000 /* Wait 5s for getting the process started. */, 2510 &uPID, execProgress.asOutParam()); 2511 } 2512 2513 if (SUCCEEDED(rc)) 2514 { 2515 /* Wait for process to exit ... */ 2516 BOOL fCompleted = FALSE; 2517 BOOL fCanceled = FALSE; 2518 2519 while ( SUCCEEDED(execProgress->COMGETTER(Completed(&fCompleted))) 2520 && !fCompleted) 2521 { 2522 /* Progress canceled by Main API? */ 2523 if ( SUCCEEDED(execProgress->COMGETTER(Canceled(&fCanceled))) 2524 && fCanceled) 2525 { 2526 break; 2527 } 2528 } 2529 2530 if (SUCCEEDED(rc)) 2531 { 2532 /* Return the progress to the caller. */ 2533 execProgress.queryInterfaceTo(aProgress); 2391 2534 } 2392 2535 } -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r33848 r33898 7697 7697 </enum> 7698 7698 7699 <enum 7700 name="CreateDirectoryFlag" 7701 uuid="26ff5bdd-c81f-4304-857b-b8be5e3f9cd6" 7702 > 7703 <desc> 7704 Directory creation flags. 7705 </desc> 7706 7707 <const name="None" value="0"> 7708 <desc>No flag set.</desc> 7709 </const> 7710 7711 <const name="Parents" value="1"> 7712 <desc>No error if existing, make parent directories as needed.</desc> 7713 </const> 7714 </enum> 7715 7699 7716 <interface 7700 7717 name="IGuest" extends="$unknown" 7701 uuid=" ded6983f-5c81-4bf9-90af-73f65fd9b728"7718 uuid="1039b0cc-9bc1-4c6d-8d12-864aa48aa5b9" 7702 7719 wsmap="managed" 7703 7720 > … … 8023 8040 <desc> 8024 8041 Copy flags. 8042 </desc> 8043 </param> 8044 <param name="progress" type="IProgress" dir="return"> 8045 <desc>Progress object to track the operation completion.</desc> 8046 </param> 8047 </method> 8048 8049 <method name="createDirectory"> 8050 <desc> 8051 Creates a directory on the guest. 8052 8053 <result name="VBOX_E_IPRT_ERROR"> 8054 Error while creating directory. 8055 </result> 8056 8057 </desc> 8058 <param name="directory" type="wstring" dir="in"> 8059 <desc> 8060 Directory to create. 8061 </desc> 8062 </param> 8063 <param name="userName" type="wstring" dir="in"> 8064 <desc> 8065 User name under which the directory creation will be executed; the 8066 user has to exist and have the appropriate rights to create the 8067 desired directory. 8068 </desc> 8069 </param> 8070 <param name="password" type="wstring" dir="in"> 8071 <desc> 8072 Password of the user account specified. 8073 </desc> 8074 </param> 8075 <param name="mode" type="unsigned long" dir="in"> 8076 <desc> 8077 File mode. 8078 </desc> 8079 </param> 8080 <param name="flags" type="unsigned long" dir="in"> 8081 <desc> 8082 Additional flags. Not used at the moment and must be set to 0. 8025 8083 </desc> 8026 8084 </param> -
trunk/src/VBox/Main/include/GuestImpl.h
r33776 r33898 102 102 STDMETHOD(GetProcessStatus)(ULONG aPID, ULONG *aExitCode, ULONG *aFlags, ULONG *aStatus); 103 103 STDMETHOD(CopyToGuest)(IN_BSTR aSource, IN_BSTR aDest, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aFlags, IProgress **aProgress); 104 STDMETHOD(CreateDirectory)(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, ULONG aMode, ULONG aFlags, IProgress **aProgress); 104 105 STDMETHOD(InternalGetStatistics)(ULONG *aCpuUser, ULONG *aCpuKernel, ULONG *aCpuIdle, 105 106 ULONG *aMemTotal, ULONG *aMemFree, ULONG *aMemBalloon, ULONG *aMemShared, ULONG *aMemCache, … … 112 113 IN_BSTR aUserName, IN_BSTR aPassword, 113 114 ULONG aTimeoutMS, ULONG *aPID, IProgress **aProgress, int *pRC); 115 HRESULT createDirectoryInternal(IN_BSTR aDirectory, IN_BSTR aUserName, IN_BSTR aPassword, 116 ULONG aMode, ULONG aFlags, IProgress **aProgress, int *pRC); 114 117 void setAdditionsInfo(Bstr aInterfaceVersion, VBOXOSTYPE aOsType); 115 118 void setAdditionsInfo2(Bstr aAdditionsVersion, Bstr aVersionName, Bstr aRevision);
Note:
See TracChangeset
for help on using the changeset viewer.

