Changeset 86274 in vbox
- Timestamp:
- Sep 24, 2020 7:52:56 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 140550
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/UnattendedImpl.h
r84645 r86274 78 78 bool i_isGuestOs64Bit() const; 79 79 VBOXOSTYPE i_getGuestOsType() const; 80 Utf8Str const &i_getDetectedOSVersion(); 80 81 81 82 -
trunk/src/VBox/Main/include/UnattendedScript.h
r84564 r86274 95 95 */ 96 96 virtual HRESULT getConditional(const char *pachPlaceholder, size_t cchPlaceholder, bool *pfOutputting); 97 98 99 /** 100 * Get the result of a conditional for special version of guest OS. 101 * 102 * @returns COM status code. 103 * @param pachPlaceholder The placholder string. Not zero terminated. 104 * @param cchPlaceholder The length of the placeholder. 105 * @param cchContent The length of placeholder content. 106 * @param pcchCorrect The length of part which must be excluded from the final content of 107 * the placeholder. 108 * @param pfOutputting Where to return the result of the conditional. 109 * This holds the current outputting state on input 110 * in case someone want to sanity check anything. 111 */ 112 virtual HRESULT getGuestOSConditional(const char *pachPlaceholder, 113 size_t cchPlaceholder, 114 size_t cchContent, 115 size_t *pcchCorrect, 116 bool *pfOutputting); 97 117 }; 98 118 -
trunk/src/VBox/Main/src-server/UnattendedImpl.cpp
r85277 r86274 2682 2682 } 2683 2683 2684 Utf8Str const & Unattended::i_getDetectedOSVersion() 2685 { 2686 Assert(isReadLockedOnCurrentThread()); 2687 return mStrDetectedOSVersion; 2688 } 2689 2684 2690 HRESULT Unattended::i_attachImage(UnattendedInstallationDisk const *pImage, ComPtr<IMachine> const &rPtrSessionMachine, 2685 2691 AutoMultiWriteLock2 &rLock) -
trunk/src/VBox/Main/src-server/UnattendedScript.cpp
r84645 r86274 59 59 static const char s_szPrefixCond[] = "@@VBOX_COND_"; 60 60 static const char s_szPrefixCondEnd[] = "@@VBOX_COND_END@@"; 61 static const char s_szPrefixCondGuestOs[] = "@@VBOX_GUEST_OS_COND_"; 62 static const char s_szPrefixCondGuestOsEnd[] = "@@VBOX_GUEST_OS_COND_END@@"; 61 63 62 64 struct … … 69 71 size_t offTemplate = 0; 70 72 size_t cchTemplate = mStrScriptFullContent.length(); 73 size_t cchInternalCorrect = 0;//used in logic handling the placeholder @@VBOX_GUEST_OS_COND_XXX@@ 71 74 rStrDst.setNull(); 72 75 for (;;) … … 83 86 try 84 87 { 85 rStrDst.append(mStrScriptFullContent, offTemplate , cchToCopy);88 rStrDst.append(mStrScriptFullContent, offTemplate + cchInternalCorrect, cchToCopy - + cchInternalCorrect); 86 89 } 87 90 catch (std::bad_alloc &) … … 92 95 } 93 96 offTemplate += cchToCopy; 97 cchInternalCorrect = 0;//don't forget to reset 94 98 } 95 99 … … 124 128 || pszPlaceholder[cchPlaceholder - 2] != '@' 125 129 || ( strncmp(pszPlaceholder, s_szPrefixInsert, sizeof(s_szPrefixInsert) - 1) != 0 126 && strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1) != 0) ) 130 && strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1) != 0 131 && strncmp(pszPlaceholder, s_szPrefixCondGuestOs, sizeof(s_szPrefixCondGuestOs) - 1) != 0) ) 127 132 { 128 133 hrc = mpSetError->setError(E_FAIL, mpSetError->tr("Malformed template placeholder '%.*s'"), … … 136 141 * @@VBOX_INSERT_XXX@@: 137 142 */ 138 if ( strncmp(pszPlaceholder, s_szPrefixInsert, sizeof(s_szPrefixInsert) - 1) == 0)143 if ( strncmp(pszPlaceholder, s_szPrefixInsert, sizeof(s_szPrefixInsert) - 1) == 0 ) 139 144 { 140 145 /* … … 164 169 * @@VBOX_COND_END@@: Pop one item of the conditional stack. 165 170 */ 166 else if ( cchPlaceholder == sizeof(s_szPrefixCondEnd) - 1U 167 && strncmp(pszPlaceholder, s_szPrefixCondEnd, sizeof(s_szPrefixCondEnd) - 1U) == 0) 171 else if ( strncmp(pszPlaceholder, s_szPrefixCondEnd, sizeof(s_szPrefixCondEnd) - 1U) == 0 ) 168 172 { 169 173 if (cConds > 0) … … 184 188 * one from the condition. 185 189 */ 186 else 187 { 188 Assert(strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1) == 0); 190 else if ( strncmp(pszPlaceholder, s_szPrefixCond, sizeof(s_szPrefixCond) - 1U) == 0 ) 191 { 189 192 if (cConds + 1 < RT_ELEMENTS(aConds)) 190 193 { … … 192 195 bool fNewOutputting = fOutputting; 193 196 hrc = getConditional(pszPlaceholder, cchPlaceholder, &fNewOutputting); 197 if (SUCCEEDED(hrc)) 198 fOutputting = fOutputting && fNewOutputting; 199 else 200 break; 201 cConds++; 202 } 203 else 204 { 205 hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, 206 mpSetError->tr("Too deep conditional nesting at offset %zu (%#zx)"), 207 offPlaceholder, offPlaceholder); 208 break; 209 } 210 } 211 /* 212 * @@VBOX_GUEST_OS_COND_END@@: Pop one item of the conditional stack. 213 */ 214 else if ( strncmp(pszPlaceholder, s_szPrefixCondGuestOsEnd, sizeof(s_szPrefixCondGuestOsEnd) - 1U) == 0 ) 215 { 216 if (cConds > 0) 217 { 218 cConds--; 219 fOutputting = aConds[cConds].fSavedOutputting; 220 } 221 else 222 { 223 hrc = mpSetError->setErrorBoth(E_FAIL, VERR_PARSE_ERROR, 224 mpSetError->tr("%s without @@VBOX_GUEST_OS_COND_XXX@@ at offset %zu (%#zx)"), 225 s_szPrefixCondGuestOsEnd, offPlaceholder, offPlaceholder); 226 break; 227 } 228 } 229 /* 230 * @@VBOX_GUEST_OS_COND_XXX@@: Push the previous outputting state and combine it with the 231 * one from the condition. 232 */ 233 else 234 { 235 Assert(strncmp(pszPlaceholder, s_szPrefixCondGuestOs, sizeof(s_szPrefixCondGuestOs) - 1) == 0); 236 if (cConds + 1 < RT_ELEMENTS(aConds)) 237 { 238 aConds[cConds].fSavedOutputting = fOutputting; 239 bool fNewOutputting = fOutputting; 240 241 //offTemplate is the beginning of content, offEndContent is the end of content 242 //@@PLACEHOLDER_BEGIN@@Content@@PLACEHOLDER_END@@ 243 // ^ ^ 244 // | | 245 // offTemplate offEndContent 246 size_t offEndContent = mStrScriptFullContent.find(s_szPrefix, offTemplate); 247 size_t cchContent = offEndContent - offTemplate - 1; 248 hrc = getGuestOSConditional(pszPlaceholder, cchPlaceholder, cchContent, &cchInternalCorrect, &fNewOutputting); 194 249 if (SUCCEEDED(hrc)) 195 250 fOutputting = fOutputting && fNewOutputting; … … 379 434 else if (IS_PLACEHOLDER_MATCH("OS_ARCH6")) 380 435 rValue = mpUnattended->i_isGuestOs64Bit() ? "x86_64" : "i686"; 436 else if (IS_PLACEHOLDER_MATCH("GUEST_OS_VERSION")) 437 rValue = mpUnattended->i_getDetectedOSVersion(); 438 else if (IS_PLACEHOLDER_MATCH("GUEST_OS_MAJOR_VERSION")) 439 { 440 Utf8Str strOsVer(mpUnattended->i_getDetectedOSVersion()); 441 RTCList<RTCString> partList = strOsVer.split("."); 442 if (partList.size() < 1) 443 { 444 rValue.setNull(); 445 return mpSetError->setErrorBoth(E_FAIL, VERR_NOT_FOUND, mpSetError->tr("Unknown guest OS major version '%s'"), 446 partList.at(0).c_str()); 447 } 448 rValue = partList.at(0); 449 } 381 450 else if (IS_PLACEHOLDER_MATCH("TIME_ZONE_UX")) 382 451 rValue = mpUnattended->i_getTimeZoneInfo() … … 426 495 cchFullPlaceholder, pachPlaceholder); 427 496 } 497 return S_OK; 498 #undef IS_PLACEHOLDER_MATCH 499 } 500 501 HRESULT UnattendedScriptTemplate::getGuestOSConditional(const char *pachPlaceholder, 502 size_t cchPlaceholder, 503 size_t cchContent, 504 size_t *cchCorrect, 505 bool *pfOutputting) 506 { 507 #define IS_PLACEHOLDER_MATCH(a_szMatch) \ 508 ( cchPlaceholder == sizeof("@@VBOX_GUEST_OS_COND_" a_szMatch "@@") - 1U \ 509 && memcmp(pachPlaceholder, "@@VBOX_GUEST_OS_COND_" a_szMatch "@@", sizeof("@@VBOX_GUEST_OS_COND_" a_szMatch "@@") - 1U) == 0) 510 511 if ( IS_PLACEHOLDER_MATCH("VERSION") ) 512 { 513 Utf8Str strT(pachPlaceholder + cchPlaceholder, cchContent); 514 RTCList<RTCString> partList = strT.split("**"); 515 Utf8Str strRequiredOSVersion; 516 if (partList.size() == 2)//when the version is placed together with the placeholder in one line in the file 517 { 518 //The case when the string has been splitted on the 2 parts: 519 //1. OS version 520 //2. Actual content 521 strRequiredOSVersion.assign(partList.at(0)); 522 //cchCorrect = "**" + length of OS version string + "**" 523 *cchCorrect = 2 + partList.at(0).length() + 2;// must be subtracted from the cchContent 524 } 525 else if (partList.size() == 3)//when the version is placed on a standalone line in the file 526 { 527 //The case when the string has been splitted on the 3 parts: 528 //1. Empty string or string with only "\n" 529 //2. OS version 530 //3. Actual content 531 strRequiredOSVersion.assign(partList.at(1)); 532 *cchCorrect = 2 + partList.at(0).length() + partList.at(1).length() + 2;// must be subtracted from the cchContent 533 } 534 else//case with wrong string syntax 535 { 536 *cchCorrect = 0; 537 *pfOutputting = false; 538 LogRel(("Malformed content of the template @@VBOX_GUEST_OS_COND_VERSION@@\n")); 539 return S_OK; 540 } 541 542 if (strRequiredOSVersion.isEmpty()) 543 *pfOutputting = false; 544 else 545 { 546 Utf8Str strDetectedOSVersion = mpUnattended->i_getDetectedOSVersion(); 547 RTCList<RTCString> partListRequired = strRequiredOSVersion.split("."); 548 RTCList<RTCString> partListDetected = strDetectedOSVersion.split("."); 549 *pfOutputting = false;//initially is set to "false" 550 551 /** @todo r=vvp: Should we check the string with a requested OS version for digits? 552 * (with RTLocCIsDigit()) */ 553 //Major version must be presented 554 if ( partListDetected.at(0).toUInt32() >= partListRequired.at(0).toUInt32() )//comparison major versions 555 { 556 //OS major versions are equal or detected guest OS major version is greater. Go further. 557 if (partListDetected.size() > 1 && partListRequired.size() > 1)//comparison minor versions 558 { 559 if (partListDetected.at(1).toUInt32() >= partListRequired.at(1).toUInt32()) 560 //OS minor versions are equal or detected guest OS minor version is greater. Go further. 561 *pfOutputting = true; 562 else 563 //The detected guest OS minor version is less than the requested one. 564 *pfOutputting = false; 565 } 566 else 567 //OS minor versions are absent. 568 *pfOutputting = true; 569 } 570 else 571 //The detected guest OS major version is less than the requested one. 572 *pfOutputting = false; 573 } 574 } 575 else 576 return mpSetError->setErrorBoth(E_FAIL, VERR_NOT_FOUND, mpSetError->tr("Unknown conditional placeholder '%.*s'"), 577 cchPlaceholder, pachPlaceholder); 428 578 return S_OK; 429 579 #undef IS_PLACEHOLDER_MATCH
Note:
See TracChangeset
for help on using the changeset viewer.