- Timestamp:
- Jul 17, 2012 12:27:22 PM (13 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/VirtualBoxImpl.h
r42129 r42177 222 222 ComObjPtr<Machine> *machine = NULL); 223 223 224 HRESULT validateMachineGroup(const Utf8Str &aGroup); 224 225 HRESULT convertMachineGroups(ComSafeArrayIn(IN_BSTR, aMachineGroups), StringsList *pllMachineGroups); 225 226 … … 314 315 HRESULT unregisterDHCPServer(DHCPServer *aDHCPServer, 315 316 bool aSaveRegistry = true); 316 317 317 318 void decryptSettings(); 318 319 void decryptMediumSettings(Medium *pMedium); -
trunk/src/VBox/Main/src-server/MachineImpl.cpp
r42129 r42177 315 315 316 316 mUserData->s.strName = strName; 317 317 318 318 mUserData->s.llGroups = llGroups; 319 319 … … 8942 8942 if ( mUserData->s.fNameSync 8943 8943 && mUserData.isBackedUp() 8944 && mUserData.backedUpData()->s.strName != mUserData->s.strName 8944 && ( mUserData.backedUpData()->s.strName != mUserData->s.strName 8945 || mUserData.backedUpData()->s.llGroups.front() != mUserData->s.llGroups.front()) 8945 8946 ) 8946 8947 { … … 8958 8959 Utf8Str name = mUserData.backedUpData()->s.strName; 8959 8960 Utf8Str newName = mUserData->s.strName; 8961 Utf8Str group = mUserData.backedUpData()->s.llGroups.front(); 8962 if (group == "/") 8963 group.setNull(); 8964 Utf8Str newGroup = mUserData->s.llGroups.front(); 8965 if (newGroup == "/") 8966 newGroup.setNull(); 8960 8967 8961 8968 configFile = mData->m_strConfigFileFull; 8962 8969 8963 /* first, rename the directory if it matches the machine name */ 8970 /* first, rename the directory if it matches the group and machine name */ 8971 Utf8Str groupPlusName = Utf8StrFmt("%s%c%s", 8972 group.c_str(), RTPATH_DELIMITER, name.c_str()); 8973 Utf8Str newGroupPlusName = Utf8StrFmt("%s%c%s", 8974 newGroup.c_str(), RTPATH_DELIMITER, newName.c_str()); 8964 8975 configDir = configFile; 8965 8976 configDir.stripFilename(); 8966 8977 newConfigDir = configDir; 8967 if (!strcmp(RTPathFilename(configDir.c_str()), name.c_str())) 8978 if ( configDir.length() >= groupPlusName.length() 8979 && configDir.substr(configDir.length() - groupPlusName.length(), groupPlusName.length()).equals(groupPlusName.c_str())) 8968 8980 { 8969 newConfigDir .stripFilename();8970 newConfigDir.append(RTPATH_DELIMITER);8971 newConfigDir.append(new Name);8981 newConfigDir = newConfigDir.substr(0, configDir.length() - groupPlusName.length()); 8982 Utf8Str newConfigBaseDir(newConfigDir); 8983 newConfigDir.append(newGroupPlusName); 8972 8984 /* new dir and old dir cannot be equal here because of 'if' 8973 8985 * above and because name != newName */ … … 8977 8989 /* perform real rename only if the machine is not new */ 8978 8990 vrc = RTPathRename(configDir.c_str(), newConfigDir.c_str(), 0); 8991 if (vrc == VERR_FILE_NOT_FOUND) 8992 { 8993 /* create the parent directory, then retry renaming */ 8994 Utf8Str parent(newConfigDir); 8995 parent.stripFilename(); 8996 (void)RTDirCreateFullPath(parent.c_str(), 0700); 8997 vrc = RTPathRename(configDir.c_str(), newConfigDir.c_str(), 0); 8998 } 8979 8999 if (RT_FAILURE(vrc)) 8980 9000 { … … 8985 9005 vrc); 8986 9006 break; 9007 } 9008 /* delete subdirectories which are no longer needed */ 9009 Utf8Str dir(configDir); 9010 dir.stripFilename(); 9011 while (dir != newConfigBaseDir && dir != ".") 9012 { 9013 vrc = RTDirRemove(dir.c_str()); 9014 if (RT_FAILURE(vrc)) 9015 break; 9016 dir.stripFilename(); 8987 9017 } 8988 9018 dirRenamed = true; -
trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
r42168 r42177 1375 1375 BSTR *aFilename) 1376 1376 { 1377 /// @todo implement aGroup1378 NOREF(aGroup);1379 1377 LogFlowThisFuncEnter(); 1380 1378 LogFlowThisFunc(("aName=\"%ls\",aBaseFolder=\"%ls\"\n", aName, aBaseFolder)); … … 1386 1384 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 1387 1385 1386 Utf8Str strGroup(aGroup); 1387 if (strGroup.isEmpty()) 1388 strGroup = "/"; 1389 HRESULT rc = validateMachineGroup(strGroup); 1390 if (FAILED(rc)) 1391 return rc; 1392 1388 1393 /* Compose the settings file name using the following scheme: 1389 1394 * 1390 * <base_folder> /<machine_name>/<machine_name>.xml1395 * <base_folder><group>/<machine_name>/<machine_name>.xml 1391 1396 * 1392 1397 * If a non-null and non-empty base folder is specified, the default … … 1405 1410 calculateFullPath(strBase, strBase); 1406 1411 1407 Bstr bstrSettingsFile = BstrFmt("%s%c%s%c%s.vbox", 1412 /* eliminate toplevel group to avoid // in the result */ 1413 if (strGroup == "/") 1414 strGroup.setNull(); 1415 Bstr bstrSettingsFile = BstrFmt("%s%s%c%s%c%s.vbox", 1408 1416 strBase.c_str(), 1417 strGroup.c_str(), 1409 1418 RTPATH_DELIMITER, 1410 1419 strName.c_str(), 1411 1420 RTPATH_DELIMITER, 1412 1421 strName.c_str()); 1413 1414 #if 0 /* Try to get a unique name. */1415 for (unsigned i = 1; RTFileExists(bstrSettingsFile.c_str() && i < 100; ++i)1416 bstrSettingsFile = BstrFmt("%s%c%s%u%c%s%u.vbox",1417 strBase.c_str(),1418 RTPATH_DELIMITER,1419 strName.c_str(), i,1420 RTPATH_DELIMITER,1421 strName.c_str());1422 #endif1423 1422 1424 1423 bstrSettingsFile.detachTo(aFilename); … … 3022 3021 } 3023 3022 3023 static HRESULT validateMachineGroupHelper(const Utf8Str &aGroup) 3024 { 3025 /* empty strings are invalid */ 3026 if (aGroup.isEmpty()) 3027 return E_INVALIDARG; 3028 /* the toplevel group is valid */ 3029 if (aGroup == "/") 3030 return S_OK; 3031 /* any other strings of length 1 are invalid */ 3032 if (aGroup.length() == 1) 3033 return E_INVALIDARG; 3034 /* must start with a slash */ 3035 if (aGroup.c_str()[0] != '/') 3036 return E_INVALIDARG; 3037 /* must not end with a slash */ 3038 if (aGroup.c_str()[aGroup.length() - 1] == '/') 3039 return E_INVALIDARG; 3040 /* check the group components */ 3041 const char *pStr = aGroup.c_str() + 1; /* first char is /, skip it */ 3042 while (pStr) 3043 { 3044 char *pSlash = RTStrStr(pStr, "/"); 3045 if (pSlash) 3046 { 3047 /* no empty components (or // sequences in other words) */ 3048 if (pSlash == pStr) 3049 return E_INVALIDARG; 3050 /* check if the machine name rules are violated, because that means 3051 * the group components is too close to the limits. */ 3052 Utf8Str tmp((const char *)pStr, (size_t)(pSlash - pStr)); 3053 Utf8Str tmp2(tmp); 3054 sanitiseMachineFilename(tmp); 3055 if (tmp != tmp2) 3056 return E_INVALIDARG; 3057 pStr = pSlash + 1; 3058 } 3059 else 3060 { 3061 /* check if the machine name rules are violated, because that means 3062 * the group components is too close to the limits. */ 3063 Utf8Str tmp(pStr); 3064 Utf8Str tmp2(tmp); 3065 sanitiseMachineFilename(tmp); 3066 if (tmp != tmp2) 3067 return E_INVALIDARG; 3068 pStr = NULL; 3069 } 3070 } 3071 return S_OK; 3072 } 3073 3074 /** 3075 * Validates a machine group. 3076 * 3077 * @param aMachineGroup Machine group. 3078 * 3079 * @return S_OK or E_INVALIDARG 3080 */ 3081 HRESULT VirtualBox::validateMachineGroup(const Utf8Str &aGroup) 3082 { 3083 HRESULT rc = validateMachineGroupHelper(aGroup); 3084 if (FAILED(rc)) 3085 rc = setError(rc, 3086 tr("Invalid machine group '%s'"), 3087 aGroup.c_str()); 3088 return rc; 3089 } 3090 3024 3091 /** 3025 3092 * Takes a list of machine groups, and sanitizes/validates it. … … 3030 3097 * @return S_OK or E_INVALIDARG 3031 3098 */ 3032 3033 3099 HRESULT VirtualBox::convertMachineGroups(ComSafeArrayIn(IN_BSTR, aMachineGroups), StringsList *pllMachineGroups) 3034 3100 { … … 3042 3108 if (group.length() == 0) 3043 3109 group = "/"; 3044 /* must start with a slash */ 3045 if (group.c_str()[0] != '/') 3046 return E_INVALIDARG; 3047 /* must not end with a slash */ 3048 if (group.length() > 1 && group.c_str()[group.length() - 1] == '/') 3049 return E_INVALIDARG; 3050 3051 /** @todo validate each component of the group hierarchy */ 3110 3111 HRESULT rc = validateMachineGroup(group); 3112 if (FAILED(rc)) 3113 return rc; 3052 3114 3053 3115 /* no duplicates please */
Note:
See TracChangeset
for help on using the changeset viewer.