Changeset 105658 in vbox
- Timestamp:
- Aug 13, 2024 10:35:19 AM (9 months ago)
- svn:sync-xref-src-repo-rev:
- 164351
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/Main/include/NvramStoreImpl.h ¶
r105627 r105658 122 122 123 123 int i_loadStoreFromTar(RTVFSFSSTREAM hVfsFssTar); 124 int i_loadStoreFromDir(RTVFSDIR hVfsDir, const char *pszNamespace); 124 125 int i_saveStoreAsTar(const char *pszPath); 126 int i_saveStoreAsDir(const char *pszPath); 125 127 126 128 int i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf); -
TabularUnified trunk/src/VBox/Main/src-all/NvramStoreImpl.cpp ¶
r105628 r105658 49 49 #include <iprt/efi.h> 50 50 #include <iprt/file.h> 51 #include <iprt/path.h> 51 52 #include <iprt/vfs.h> 52 53 #include <iprt/zip.h> … … 714 715 715 716 #endif /* VBOX_WITH_FULL_VM_ENCRYPTION */ 717 718 /** 719 * Loads the NVRAM store from the given VFS directory handle. 720 * 721 * @returns IPRT status code. 722 * @param hVfsDir Handle to the NVRAM root VFS directory. 723 * @param pszNamespace The namespace to load the content for. 724 */ 725 int NvramStore::i_loadStoreFromDir(RTVFSDIR hVfsDir, const char *pszNamespace) 726 { 727 int vrc = VINF_SUCCESS; 728 729 RTVFSDIR hNamespaceDir = NIL_RTVFSDIR; 730 vrc = RTVfsDirOpenDir(hVfsDir, pszNamespace, 0 /*fFlags*/, &hNamespaceDir); 731 if (RT_SUCCESS(vrc)) 732 { 733 for (;;) 734 { 735 RTDIRENTRYEX DirEntry; /* ASSUMES that no entry has a longer name than what RTDIRENTRYEX provides by default. */ 736 size_t cbDir = sizeof(DirEntry); 737 vrc = RTVfsDirReadEx(hNamespaceDir, &DirEntry, &cbDir, RTFSOBJATTRADD_NOTHING); 738 if (RT_FAILURE(vrc)) 739 { 740 if (vrc == VERR_NO_MORE_FILES) 741 vrc = VINF_SUCCESS; 742 break; 743 } 744 745 if (RT_SUCCESS(vrc)) 746 { 747 switch (DirEntry.Info.Attr.fMode & RTFS_TYPE_MASK) 748 { 749 case RTFS_TYPE_FILE: 750 { 751 LogRel(("NvramStore: Loading '%s' from directory '%s'\n", DirEntry.szName, pszNamespace)); 752 753 RTVFSIOSTREAM hVfsIosEntry; 754 vrc = RTVfsDirOpenFileAsIoStream(hNamespaceDir, DirEntry.szName, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, &hVfsIosEntry); 755 if (RT_SUCCESS(vrc)) 756 { 757 RTVFSIOSTREAM hVfsIosDecrypted = NIL_RTVFSIOSTREAM; 758 759 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 760 PCVBOXCRYPTOIF pCryptoIf = NULL; 761 SecretKey *pKey = NULL; 762 763 if ( m->bd->strKeyId.isNotEmpty() 764 && m->bd->strKeyStore.isNotEmpty()) 765 vrc = i_setupEncryptionOrDecryption(hVfsIosEntry, false /*fEncrypt*/, 766 &pCryptoIf, &pKey, &hVfsIosDecrypted); 767 #endif 768 if (RT_SUCCESS(vrc)) 769 { 770 RTVFSFILE hVfsFileEntry; 771 vrc = RTVfsMemorizeIoStreamAsFile(hVfsIosDecrypted != NIL_RTVFSIOSTREAM 772 ? hVfsIosDecrypted 773 : hVfsIosEntry, 774 RTFILE_O_READ | RTFILE_O_WRITE, &hVfsFileEntry); 775 if (RT_SUCCESS(vrc)) 776 m->mapNvram[Utf8StrFmt("%s/%s", pszNamespace, DirEntry.szName)] = hVfsFileEntry; 777 } 778 779 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 780 if (hVfsIosDecrypted != NIL_RTVFSIOSTREAM) 781 i_releaseEncryptionOrDecryptionResources(hVfsIosDecrypted, pCryptoIf, pKey); 782 #endif 783 784 RTVfsIoStrmRelease(hVfsIosEntry); 785 } 786 else 787 LogRel(("Failed to open '%s' in NVRAM store '%s', vrc=%Rrc\n", DirEntry.szName, pszNamespace, vrc)); 788 789 break; 790 } 791 case RTFS_TYPE_DIRECTORY: 792 break; 793 default: 794 vrc = VERR_NOT_SUPPORTED; 795 break; 796 } 797 } 798 799 if (RT_FAILURE(vrc)) 800 break; 801 } 802 803 RTVfsDirRelease(hNamespaceDir); 804 } 805 806 return vrc; 807 } 808 716 809 717 810 /** … … 830 923 } 831 924 } 925 else if (vrc == VERR_IS_A_DIRECTORY) /* Valid if the NVRAM was saved with VBoxInternal2/SaveNvramContentAsDirectory 1. */ 926 { 927 RTVFSDIR hNvramDir = NIL_RTVFSDIR; 928 vrc = RTVfsDirOpenNormal(pszPath, 0 /*fFlags*/, &hNvramDir); 929 if (RT_SUCCESS(vrc)) 930 { 931 for (;;) 932 { 933 RTDIRENTRYEX DirEntry; /* ASSUMES that no entry has a longer name than what RTDIRENTRYEX provides by default. */ 934 size_t cbDir = sizeof(DirEntry); 935 936 vrc = RTVfsDirReadEx(hNvramDir, &DirEntry, &cbDir, RTFSOBJATTRADD_NOTHING); 937 if (RT_FAILURE(vrc)) 938 { 939 if (vrc == VERR_NO_MORE_FILES) 940 vrc = VINF_SUCCESS; 941 break; 942 } 943 944 /* This ASSUMES that the structure follows the <namespace>/<file> naming scheme. */ 945 if (RT_SUCCESS(vrc)) 946 { 947 switch (DirEntry.Info.Attr.fMode & RTFS_TYPE_MASK) 948 { 949 case RTFS_TYPE_FILE: 950 break; 951 case RTFS_TYPE_DIRECTORY: 952 { 953 if ( (DirEntry.szName[0] == '.' && DirEntry.szName[1] == '\0') 954 || (DirEntry.szName[0] == '.' && DirEntry.szName[1] == '.' && DirEntry.szName[2] == '\0')) 955 break; 956 957 vrc = i_loadStoreFromDir(hNvramDir, DirEntry.szName); 958 break; 959 } 960 default: 961 vrc = VERR_NOT_SUPPORTED; 962 break; 963 } 964 } 965 966 if (RT_FAILURE(vrc)) 967 break; 968 } 969 970 RTVfsDirRelease(hNvramDir); 971 } 972 else 973 LogRelMax(10, ("NVRAM store '%s' couldn't be opened as a directory, vrc=%Rrc\n", pszPath, vrc)); 974 975 } 832 976 else if (vrc == VERR_FILE_NOT_FOUND) /* Valid for the first run where no NVRAM file is there. */ 833 977 vrc = VINF_SUCCESS; … … 905 1049 906 1050 1051 /** 1052 * Saves the NVRAM store as a directory tree. 1053 */ 1054 int NvramStore::i_saveStoreAsDir(const char *pszPath) 1055 { 1056 int vrc = VINF_SUCCESS; 1057 if (RTDirExists(pszPath)) 1058 vrc = RTDirRemoveRecursive(pszPath, RTDIRRMREC_F_CONTENT_AND_DIR); 1059 else if (RTPathExists(pszPath)) 1060 vrc = RTPathUnlink(pszPath, 0 /*fUnlink*/); 1061 if (RT_FAILURE(vrc)) 1062 { 1063 LogRel(("Failed to delete existing NVRAM store '%s': %Rrc\n", vrc)); 1064 return vrc; 1065 } 1066 1067 vrc = RTDirCreate(pszPath, 0700 /*fMode*/, RTDIRCREATE_FLAGS_NOT_CONTENT_INDEXED_NOT_CRITICAL); 1068 if (RT_SUCCESS(vrc)) 1069 { 1070 NvramStoreIter it = m->mapNvram.begin(); 1071 1072 while (it != m->mapNvram.end()) 1073 { 1074 /** @todo r=aeichner This is pretty in-efficient but not called often (not at all by default) 1075 * and there aren't many entries anyway. */ 1076 char szPathOut[RTPATH_MAX]; 1077 char szPathFile[RTPATH_MAX]; 1078 1079 /* Construct the path excluding the filename. */ 1080 vrc = RTStrCopy(szPathFile, sizeof(szPathFile), it->first.c_str()); 1081 if (RT_FAILURE(vrc)) 1082 break; 1083 RTPathStripFilename(szPathFile); 1084 vrc = RTPathJoin(szPathOut, sizeof(szPathOut), pszPath, szPathFile); 1085 if (RT_FAILURE(vrc)) 1086 break; 1087 1088 /* Create the directory structure. */ 1089 vrc = RTDirCreateFullPathEx(szPathOut, 0700 /*fMode*/, RTDIRCREATE_FLAGS_NOT_CONTENT_INDEXED_NOT_CRITICAL); 1090 if (RT_FAILURE(vrc)) 1091 break; 1092 1093 vrc = RTVfsFileSeek(it->second, 0 /*offSeek*/, RTFILE_SEEK_BEGIN, NULL /*poffActual*/); 1094 AssertRC(vrc); 1095 1096 /* Construct path, including the filename now. */ 1097 vrc = RTPathJoin(szPathOut, sizeof(szPathOut), pszPath, it->first.c_str()); 1098 if (RT_FAILURE(vrc)) 1099 break; 1100 1101 /* Write the file, encrypting it if required. */ 1102 RTVFSFILE hVfsFile; 1103 vrc = RTVfsFileOpenNormal(szPathOut, RTFILE_O_WRITE | RTFILE_O_DENY_WRITE | RTFILE_O_CREATE_REPLACE, 1104 &hVfsFile); 1105 if (RT_SUCCESS(vrc)) 1106 { 1107 RTVFSIOSTREAM hVfsIos = RTVfsFileToIoStream(hVfsFile); 1108 RTVFSIOSTREAM hVfsIosEncrypted = NIL_RTVFSIOSTREAM; 1109 1110 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 1111 PCVBOXCRYPTOIF pCryptoIf = NULL; 1112 SecretKey *pKey = NULL; 1113 1114 if ( m->bd->strKeyId.isNotEmpty() 1115 && m->bd->strKeyStore.isNotEmpty()) 1116 vrc = i_setupEncryptionOrDecryption(hVfsIos, true /*fEncrypt*/, 1117 &pCryptoIf, &pKey, &hVfsIosEncrypted); 1118 #endif 1119 1120 if (RT_SUCCESS(vrc)) 1121 { 1122 RTVFSIOSTREAM hVfsIosSrc = RTVfsFileToIoStream(it->second); 1123 vrc = RTVfsUtilPumpIoStreams(hVfsIosSrc, 1124 hVfsIosEncrypted != NIL_RTVFSIOSTREAM 1125 ? hVfsIosEncrypted 1126 : hVfsIos, 0 /*cbBufHint*/); 1127 RTVfsIoStrmRelease(hVfsIosSrc); 1128 #ifdef VBOX_WITH_FULL_VM_ENCRYPTION 1129 if (hVfsIosEncrypted != NIL_RTVFSIOSTREAM) 1130 i_releaseEncryptionOrDecryptionResources(hVfsIosEncrypted, pCryptoIf, pKey); 1131 #endif 1132 } 1133 1134 RTVfsIoStrmRelease(hVfsIos); 1135 RTVfsFileRelease(hVfsFile); 1136 } 1137 1138 it++; 1139 } 1140 1141 /* Cleanup in case of error. */ 1142 if (RT_FAILURE(vrc)) 1143 { 1144 int vrc2 = RTDirRemoveRecursive(pszPath, RTDIRRMREC_F_CONTENT_AND_DIR); 1145 if (RT_FAILURE(vrc2)) 1146 LogRel(("Cleaning up NVRAM store '%s' failed with %Rrc (after creation failed with %Rrc)\n", vrc2, vrc)); 1147 } 1148 } 1149 else 1150 LogRel(("NVRAM store '%s' directory creation failed: %Rrc\n", pszPath, vrc)); 1151 1152 return vrc; 1153 } 1154 1155 907 1156 int NvramStore::i_retainCryptoIf(PCVBOXCRYPTOIF *ppCryptoIf) 908 1157 { … … 1001 1250 } 1002 1251 else if (m->mapNvram.size()) 1003 vrc = i_saveStoreAsTar(strPath.c_str()); 1252 { 1253 /* Check whether the NVRAM content is supposed to be saved under a directory. */ 1254 #ifndef VBOX_COM_INPROC 1255 Machine * const pMachine = m->pParent; 1256 #else 1257 const ComPtr<IMachine> &pMachine = m->pParent->i_machine(); 1258 #endif 1259 1260 Bstr bstrName("VBoxInternal2/SaveNvramContentAsDirectory"); 1261 Bstr bstrValue; 1262 HRESULT hrc = pMachine->GetExtraData(bstrName.raw(), bstrValue.asOutParam()); 1263 if (FAILED(hrc)) 1264 throw hrc; 1265 1266 bool fSaveAsDir = fSaveAsDir = bstrValue == "1"; 1267 1268 if (fSaveAsDir) 1269 vrc = i_saveStoreAsDir(strPath.c_str()); 1270 else 1271 vrc = i_saveStoreAsTar(strPath.c_str()); 1272 } 1004 1273 /* else: No NVRAM content to store so we are done here. */ 1005 1274 } -
TabularUnified trunk/src/VBox/Main/src-server/MachineImpl.cpp ¶
r105605 r105658 9561 9561 newNVRAMFile.stripSuffix(); 9562 9562 newNVRAMFile += ".nvram"; 9563 RT FileRename(NVRAMFile.c_str(), newNVRAMFile.c_str(), 0);9563 RTPathRename(NVRAMFile.c_str(), newNVRAMFile.c_str(), 0); 9564 9564 } 9565 9565 } … … 9610 9610 RTFileRename(newConfigFile.c_str(), configFile.c_str(), 0); 9611 9611 if (NVRAMFile.isNotEmpty() && newNVRAMFile.isNotEmpty()) 9612 RT FileRename(newNVRAMFile.c_str(), NVRAMFile.c_str(), 0);9612 RTPathRename(newNVRAMFile.c_str(), NVRAMFile.c_str(), 0); 9613 9613 } 9614 9614 if (dirRenamed)
Note:
See TracChangeset
for help on using the changeset viewer.