aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/cache.cpp')
-rw-r--r--src/burn/engine/cache.cpp86
1 files changed, 61 insertions, 25 deletions
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp
index 5a8388c4..16db4a81 100644
--- a/src/burn/engine/cache.cpp
+++ b/src/burn/engine/cache.cpp
@@ -112,13 +112,15 @@ static HRESULT CopyEngineToWorkingFolder(
112 __in_z LPCWSTR wzWorkingFolderName, 112 __in_z LPCWSTR wzWorkingFolderName,
113 __in_z LPCWSTR wzExecutableName, 113 __in_z LPCWSTR wzExecutableName,
114 __in BURN_SECTION* pSection, 114 __in BURN_SECTION* pSection,
115 __deref_out_z_opt LPWSTR* psczEngineWorkingPath 115 __out_z LPWSTR* psczEngineWorkingPath,
116 __out HANDLE* phEngineWorkingFile
116 ); 117 );
117static HRESULT CopyEngineWithSignatureFixup( 118static HRESULT CopyEngineWithSignatureFixup(
118 __in HANDLE hEngineFile, 119 __in HANDLE hEngineFile,
119 __in_z LPCWSTR wzEnginePath, 120 __in_z LPCWSTR wzEnginePath,
120 __in_z LPCWSTR wzTargetPath, 121 __in_z LPCWSTR wzTargetPath,
121 __in BURN_SECTION* pSection 122 __in BURN_SECTION* pSection,
123 __out HANDLE* phEngineFile
122 ); 124 );
123static HRESULT RemoveBundleOrPackage( 125static HRESULT RemoveBundleOrPackage(
124 __in BURN_CACHE* pCache, 126 __in BURN_CACHE* pCache,
@@ -915,33 +917,59 @@ extern "C" HRESULT CacheBundleToWorkingDirectory(
915 __in BOOL fElevated, 917 __in BOOL fElevated,
916 __in BURN_CACHE* pCache, 918 __in BURN_CACHE* pCache,
917 __in_z LPCWSTR wzExecutableName, 919 __in_z LPCWSTR wzExecutableName,
918 __in BURN_SECTION* pSection, 920 __in BURN_SECTION* pSection
919 __deref_out_z_opt LPWSTR* psczEngineWorkingPath
920 ) 921 )
921{ 922{
922 Assert(pCache->fInitializedCache); 923 Assert(pCache->fInitializedCache);
923 924
924 HRESULT hr = S_OK; 925 HRESULT hr = S_OK;
925 LPWSTR sczSourcePath = NULL; 926 LPWSTR sczSourcePath = NULL;
927 LPWSTR sczEngineWorkingPath = NULL;
928 HANDLE hEngineWorkingFile = INVALID_HANDLE_VALUE;
929
930 // If we already cached the engine, bail.
931 if (pCache->sczBundleEngineWorkingPath && INVALID_HANDLE_VALUE != pCache->hBundleEngineWorkingFile)
932 {
933 ExitFunction();
934 }
926 935
927 // Initialize the source. 936 // Initialize the source.
928 hr = PathForCurrentProcess(&sczSourcePath, NULL); 937 hr = PathForCurrentProcess(&sczSourcePath, NULL);
929 ExitOnFailure(hr, "Failed to get current process path."); 938 ExitOnFailure(hr, "Failed to get current process path.");
930 939
931 // If the bundle is running out of the package cache then we don't need to copy it to 940 // If the bundle is running out of the package cache then we don't need to copy it to
932 // the working folder since we feel safe in the package cache and will run from there. 941 // the working folder (and we don't need to lock the file either) since we feel safe
942 // in the package cache and will run from there.
933 if (CacheBundleRunningFromCache(pCache)) 943 if (CacheBundleRunningFromCache(pCache))
934 { 944 {
935 hr = StrAllocString(psczEngineWorkingPath, sczSourcePath, 0); 945 hr = StrAllocString(&sczEngineWorkingPath, sczSourcePath, 0);
936 ExitOnFailure(hr, "Failed to use current process path as target path."); 946 ExitOnFailure(hr, "Failed to copy current process path as bundle engine working path.");
937 } 947 }
938 else // otherwise, carry on putting the bundle in the working folder. 948 else // otherwise, carry on putting the bundle in the working folder and lock it.
939 { 949 {
940 hr = CopyEngineToWorkingFolder(fElevated, pCache, sczSourcePath, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName, pSection, psczEngineWorkingPath); 950 hr = CopyEngineToWorkingFolder(fElevated, pCache, sczSourcePath, BUNDLE_WORKING_FOLDER_NAME, wzExecutableName, pSection, &sczEngineWorkingPath, &hEngineWorkingFile);
941 ExitOnFailure(hr, "Failed to copy engine to working folder."); 951 ExitOnFailure(hr, "Failed to copy engine to working folder.");
942 } 952
953 // Close the engine file handle (if we opened it) then reopen it read-only as quickly as possible to lock it.
954 ReleaseFileHandle(hEngineWorkingFile);
955
956 hr = FileCreateWithRetry(sczEngineWorkingPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 30, 100, &hEngineWorkingFile);
957 ExitOnFailure(hr, "Failed to lock bundle engine file: %ls", sczEngineWorkingPath);
958 }
959
960 // Clean out any previous values (there shouldn't be any).
961 ReleaseNullStr(pCache->sczBundleEngineWorkingPath);
962 ReleaseFileHandle(pCache->hBundleEngineWorkingFile);
963
964 pCache->sczBundleEngineWorkingPath = sczEngineWorkingPath;
965 sczEngineWorkingPath = NULL;
966
967 pCache->hBundleEngineWorkingFile = hEngineWorkingFile;
968 hEngineWorkingFile = INVALID_HANDLE_VALUE;
943 969
944LExit: 970LExit:
971 ReleaseFileHandle(hEngineWorkingFile);
972 ReleaseStr(sczEngineWorkingPath);
945 ReleaseStr(sczSourcePath); 973 ReleaseStr(sczSourcePath);
946 974
947 return hr; 975 return hr;
@@ -1206,9 +1234,14 @@ extern "C" HRESULT CacheRemoveBaseWorkingFolder(
1206 1234
1207 if (pCache->fInitializedBaseWorkingFolder) 1235 if (pCache->fInitializedBaseWorkingFolder)
1208 { 1236 {
1237 // Release the engine file handle if it is open to ensure the working folder can be deleted.
1238 ReleaseFileHandle(pCache->hBundleEngineWorkingFile);
1239
1209 // Try to clean out everything in the working folder. 1240 // Try to clean out everything in the working folder.
1210 hr = DirEnsureDeleteEx(pCache->sczBaseWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE); 1241 hr = DirEnsureDeleteEx(pCache->sczBaseWorkingFolder, DIR_DELETE_FILES | DIR_DELETE_RECURSE | DIR_DELETE_SCHEDULE);
1211 TraceError(hr, "Could not delete bundle engine working folder."); 1242 TraceError(hr, "Could not delete bundle engine working folder.");
1243
1244 pCache->fInitializedBaseWorkingFolder = FALSE;
1212 } 1245 }
1213 1246
1214 return hr; 1247 return hr;
@@ -1396,6 +1429,8 @@ extern "C" void CacheUninitialize(
1396 ReleaseStr(pCache->sczBaseWorkingFolder); 1429 ReleaseStr(pCache->sczBaseWorkingFolder);
1397 ReleaseStr(pCache->sczAcquisitionFolder); 1430 ReleaseStr(pCache->sczAcquisitionFolder);
1398 ReleaseStr(pCache->sczSourceProcessFolder); 1431 ReleaseStr(pCache->sczSourceProcessFolder);
1432 ReleaseStr(pCache->sczBundleEngineWorkingPath)
1433 ReleaseFileHandle(pCache->hBundleEngineWorkingFile)
1399 1434
1400 memset(pCache, 0, sizeof(BURN_CACHE)); 1435 memset(pCache, 0, sizeof(BURN_CACHE));
1401} 1436}
@@ -2094,16 +2129,15 @@ static HRESULT CopyEngineToWorkingFolder(
2094 __in_z LPCWSTR wzWorkingFolderName, 2129 __in_z LPCWSTR wzWorkingFolderName,
2095 __in_z LPCWSTR wzExecutableName, 2130 __in_z LPCWSTR wzExecutableName,
2096 __in BURN_SECTION* pSection, 2131 __in BURN_SECTION* pSection,
2097 __deref_out_z_opt LPWSTR* psczEngineWorkingPath 2132 __out_z LPWSTR* psczEngineWorkingPath,
2133 __out HANDLE* phEngineWorkingFile
2098 ) 2134 )
2099{ 2135{
2100 HRESULT hr = S_OK; 2136 HRESULT hr = S_OK;
2101 LPWSTR sczWorkingFolder = NULL; 2137 LPWSTR sczWorkingFolder = NULL;
2102 LPWSTR sczTargetDirectory = NULL; 2138 LPWSTR sczTargetDirectory = NULL;
2103 LPWSTR sczTargetPath = NULL; 2139 LPWSTR sczTargetPath = NULL;
2104 LPWSTR sczSourceDirectory = NULL; 2140 HANDLE hTargetFile = INVALID_HANDLE_VALUE;
2105 LPWSTR sczPayloadSourcePath = NULL;
2106 LPWSTR sczPayloadTargetPath = NULL;
2107 2141
2108 hr = CacheEnsureBaseWorkingFolder(fElevated, pCache, &sczWorkingFolder); 2142 hr = CacheEnsureBaseWorkingFolder(fElevated, pCache, &sczWorkingFolder);
2109 ExitOnFailure(hr, "Failed to create working path to copy engine."); 2143 ExitOnFailure(hr, "Failed to create working path to copy engine.");
@@ -2118,19 +2152,17 @@ static HRESULT CopyEngineToWorkingFolder(
2118 ExitOnFailure(hr, "Failed to combine working path with engine file name."); 2152 ExitOnFailure(hr, "Failed to combine working path with engine file name.");
2119 2153
2120 // Copy the engine without any attached containers to the working path. 2154 // Copy the engine without any attached containers to the working path.
2121 hr = CopyEngineWithSignatureFixup(pSection->hEngineFile, wzSourcePath, sczTargetPath, pSection); 2155 hr = CopyEngineWithSignatureFixup(pSection->hEngineFile, wzSourcePath, sczTargetPath, pSection, &hTargetFile);
2122 ExitOnFailure(hr, "Failed to copy engine: '%ls' to working path: %ls", wzSourcePath, sczTargetPath); 2156 ExitOnFailure(hr, "Failed to copy engine: '%ls' to working path: %ls", wzSourcePath, sczTargetPath);
2123 2157
2124 if (psczEngineWorkingPath) 2158 *psczEngineWorkingPath = sczTargetPath;
2125 { 2159 sczTargetPath = NULL;
2126 hr = StrAllocString(psczEngineWorkingPath, sczTargetPath, 0); 2160
2127 ExitOnFailure(hr, "Failed to copy target path for engine working path."); 2161 *phEngineWorkingFile = hTargetFile;
2128 } 2162 hTargetFile = INVALID_HANDLE_VALUE;
2129 2163
2130LExit: 2164LExit:
2131 ReleaseStr(sczPayloadTargetPath); 2165 ReleaseFileHandle(hTargetFile);
2132 ReleaseStr(sczPayloadSourcePath);
2133 ReleaseStr(sczSourceDirectory);
2134 ReleaseStr(sczTargetPath); 2166 ReleaseStr(sczTargetPath);
2135 ReleaseStr(sczTargetDirectory); 2167 ReleaseStr(sczTargetDirectory);
2136 ReleaseStr(sczWorkingFolder); 2168 ReleaseStr(sczWorkingFolder);
@@ -2143,7 +2175,8 @@ static HRESULT CopyEngineWithSignatureFixup(
2143 __in HANDLE hEngineFile, 2175 __in HANDLE hEngineFile,
2144 __in_z LPCWSTR wzEnginePath, 2176 __in_z LPCWSTR wzEnginePath,
2145 __in_z LPCWSTR wzTargetPath, 2177 __in_z LPCWSTR wzTargetPath,
2146 __in BURN_SECTION* pSection 2178 __in BURN_SECTION* pSection,
2179 __out HANDLE* phEngineFile
2147 ) 2180 )
2148{ 2181{
2149 HRESULT hr = S_OK; 2182 HRESULT hr = S_OK;
@@ -2151,7 +2184,7 @@ static HRESULT CopyEngineWithSignatureFixup(
2151 LARGE_INTEGER li = { }; 2184 LARGE_INTEGER li = { };
2152 DWORD dwZeroOriginals[3] = { }; 2185 DWORD dwZeroOriginals[3] = { };
2153 2186
2154 hTarget = ::CreateFileW(wzTargetPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); 2187 hTarget = ::CreateFileW(wzTargetPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2155 if (INVALID_HANDLE_VALUE == hTarget) 2188 if (INVALID_HANDLE_VALUE == hTarget)
2156 { 2189 {
2157 ExitWithLastError(hr, "Failed to create engine file at path: %ls", wzTargetPath); 2190 ExitWithLastError(hr, "Failed to create engine file at path: %ls", wzTargetPath);
@@ -2200,6 +2233,9 @@ static HRESULT CopyEngineWithSignatureFixup(
2200 ExitOnFailure(hr, "Failed to zero out original data offset."); 2233 ExitOnFailure(hr, "Failed to zero out original data offset.");
2201 } 2234 }
2202 2235
2236 *phEngineFile = hTarget;
2237 hTarget = INVALID_HANDLE_VALUE;
2238
2203LExit: 2239LExit:
2204 ReleaseFileHandle(hTarget); 2240 ReleaseFileHandle(hTarget);
2205 2241