VirtualBox

Ignore:
Timestamp:
Aug 7, 2016 1:38:41 PM (8 years ago)
Author:
vboxsync
Message:

VBoxStub: Fixed buggy ExtractFile function (blaming do-break-while-false loops again). Shut up incorrect MSC warning about using pHeader uninitialized in WinMain due to convoluted code structure, caused by putting to much code in WinMain.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Installer/win/Stub/VBoxStub.cpp

    r63130 r63131  
    284284                       const char *pszTempFile)
    285285{
     286#if 0 /* Another example of how unnecessarily complicated things get with
     287         do-break-while-false and you end up with buggy code using uninitialized
     288         variables. */
    286289    int rc;
    287290    RTFILE fh;
     
    290293    do
    291294    {
    292         AssertMsgBreak(pszResourceName, ("Resource pointer invalid!\n"));
    293         AssertMsgBreak(pszTempFile, ("Temp file pointer invalid!"));
     295        AssertMsgBreak(pszResourceName, ("Resource pointer invalid!\n")); /* rc is not initialized here, we'll return garbage. */
     296        AssertMsgBreak(pszTempFile, ("Temp file pointer invalid!"));      /* Ditto. */
    294297
    295298        /* Read the data of the built-in resource. */
     
    316319    } while (0);
    317320
    318     if (RTFileIsValid(fh))
     321    if (RTFileIsValid(fh)) /* fh is unused uninitalized (MSC agrees) */
    319322        RTFileClose(fh);
    320323
     
    324327            RTFileDelete(pszTempFile);
    325328    }
     329
     330#else /* This is exactly the same as above, except no bug and better assertion
     331         message.  Note only the return-success statment is indented, indicating
     332         that the whole do-break-while-false approach was totally unnecessary.   */
     333
     334    AssertPtrReturn(pszResourceName, VERR_INVALID_POINTER);
     335    AssertPtrReturn(pszTempFile, VERR_INVALID_POINTER);
     336
     337    /* Read the data of the built-in resource. */
     338    PVOID pvData = NULL;
     339    DWORD dwDataSize = 0;
     340    int rc = FindData(pszResourceName, &pvData, &dwDataSize);
     341    AssertMsgRCReturn(rc, ("Could not read resource data: %Rrc\n", rc), rc);
     342
     343    /* Create new (and replace an old) file. */
     344    RTFILE hFile;
     345    rc = RTFileOpen(&hFile, pszTempFile,
     346                      RTFILE_O_CREATE_REPLACE
     347                    | RTFILE_O_WRITE
     348                    | RTFILE_O_DENY_NOT_DELETE
     349                    | RTFILE_O_DENY_WRITE);
     350    AssertMsgRCReturn(rc, ("Could not open '%s' for writing: %Rrc\n", pszTempFile, rc), rc);
     351
     352    /* Write contents to new file. */
     353    size_t cbWritten = 0;
     354    rc = RTFileWrite(hFile, pvData, dwDataSize, &cbWritten);
     355    AssertMsgStmt(cbWritten == dwDataSize || RT_FAILURE_NP(rc), ("%#zx vs %#x\n", cbWritten, dwDataSize), rc = VERR_WRITE_ERROR);
     356
     357    int rc2 = RTFileClose(hFile);
     358    AssertRC(rc2);
     359
     360    if (RT_SUCCESS(rc))
     361        return VINF_SUCCESS;
     362
     363    RTFileDelete(pszTempFile);
     364
     365#endif
    326366    return rc;
    327367}
     
    340380                   const char         *pszTempFile)
    341381{
    342     return ExtractFile(pPackage->szResourceName,
    343                        pszTempFile);
     382    return ExtractFile(pPackage->szResourceName, pszTempFile);
    344383}
    345384
     
    10021041        vrc = VERR_PARSE_ERROR;
    10031042
     1043/** @todo
     1044 *
     1045 *  Split the remainder up in functions and simplify the code flow!!
     1046 *
     1047 *   */
     1048
    10041049#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0501
    10051050# ifdef VBOX_STUB_WITH_OWN_CONSOLE /* Use an own console window if run in debug mode. */
     
    10631108
    10641109    /* Read our manifest. */
    1065     PVBOXSTUBPKGHEADER pHeader;
    10661110    if (RT_SUCCESS(vrc))
    10671111    {
     1112        PVBOXSTUBPKGHEADER pHeader;
    10681113        vrc = FindData("MANIFEST", (PVOID *)&pHeader, NULL);
    1069         if (RT_FAILURE(vrc))
     1114        if (RT_SUCCESS(vrc))
     1115        {
     1116            /** @todo If we could, we should validate the header. Only the magic isn't
     1117             *        commonly defined, nor the version number... */
     1118
     1119            RTListInit(&g_TmpFiles);
     1120
     1121            /*
     1122             * Up to this point, we haven't done anything that requires any cleanup.
     1123             * From here on, we do everything in function so we can counter clean up.
     1124             */
     1125            bool fCreatedExtractDir;
     1126            rcExit = ExtractFiles(pHeader->byCntPkgs, szExtractPath,
     1127                                  fExtractOnly, &fCreatedExtractDir);
     1128            if (rcExit == RTEXITCODE_SUCCESS)
     1129            {
     1130                if (fExtractOnly)
     1131                    ShowInfo("Files were extracted to: %s", szExtractPath);
     1132                else
     1133                {
     1134                    rcExit = CopyCustomDir(szExtractPath);
     1135    #ifdef VBOX_WITH_CODE_SIGNING
     1136                    if (rcExit == RTEXITCODE_SUCCESS && fEnableSilentCert && g_fSilent)
     1137                        rcExit = InstallCertificate();
     1138    #endif
     1139                    unsigned iPackage = 0;
     1140                    while (   iPackage < pHeader->byCntPkgs
     1141                           && rcExit == RTEXITCODE_SUCCESS)
     1142                    {
     1143                        rcExit = ProcessPackage(iPackage, szExtractPath,
     1144                                                szMSIArgs, fEnableLogging);
     1145                        iPackage++;
     1146                    }
     1147
     1148                    /* Don't fail if cleanup fail. At least for now. */
     1149                    CleanUp(   !fEnableLogging
     1150                            && fCreatedExtractDir ? szExtractPath : NULL);
     1151                }
     1152            }
     1153
     1154            /* Free any left behind cleanup records (not strictly needed). */
     1155            PSTUBCLEANUPREC pCur, pNext;
     1156            RTListForEachSafe(&g_TmpFiles, pCur, pNext, STUBCLEANUPREC, ListEntry)
     1157            {
     1158                RTListNodeRemove(&pCur->ListEntry);
     1159                RTMemFree(pCur);
     1160            }
     1161        }
     1162        else
    10701163            rcExit = ShowError("Internal package error: Manifest not found (%Rrc)", vrc);
    1071     }
    1072     if (RT_SUCCESS(vrc))
    1073     {
    1074         /** @todo If we could, we should validate the header. Only the magic isn't
    1075          *        commonly defined, nor the version number... */
    1076 
    1077         RTListInit(&g_TmpFiles);
    1078 
    1079         /*
    1080          * Up to this point, we haven't done anything that requires any cleanup.
    1081          * From here on, we do everything in function so we can counter clean up.
    1082          */
    1083         bool fCreatedExtractDir;
    1084         rcExit = ExtractFiles(pHeader->byCntPkgs, szExtractPath,
    1085                               fExtractOnly, &fCreatedExtractDir);
    1086         if (rcExit == RTEXITCODE_SUCCESS)
    1087         {
    1088             if (fExtractOnly)
    1089                 ShowInfo("Files were extracted to: %s", szExtractPath);
    1090             else
    1091             {
    1092                 rcExit = CopyCustomDir(szExtractPath);
    1093 #ifdef VBOX_WITH_CODE_SIGNING
    1094                 if (rcExit == RTEXITCODE_SUCCESS && fEnableSilentCert && g_fSilent)
    1095                     rcExit = InstallCertificate();
    1096 #endif
    1097                 unsigned iPackage = 0;
    1098                 while (   iPackage < pHeader->byCntPkgs
    1099                        && rcExit == RTEXITCODE_SUCCESS)
    1100                 {
    1101                     rcExit = ProcessPackage(iPackage, szExtractPath,
    1102                                             szMSIArgs, fEnableLogging);
    1103                     iPackage++;
    1104                 }
    1105 
    1106                 /* Don't fail if cleanup fail. At least for now. */
    1107                 CleanUp(   !fEnableLogging
    1108                         && fCreatedExtractDir ? szExtractPath : NULL);
    1109             }
    1110         }
    1111 
    1112         /* Free any left behind cleanup records (not strictly needed). */
    1113         PSTUBCLEANUPREC pCur, pNext;
    1114         RTListForEachSafe(&g_TmpFiles, pCur, pNext, STUBCLEANUPREC, ListEntry)
    1115         {
    1116             RTListNodeRemove(&pCur->ListEntry);
    1117             RTMemFree(pCur);
    1118         }
    11191164    }
    11201165
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette