diff options
Diffstat (limited to '')
| -rw-r--r-- | src/burn/engine/cache.cpp | 86 |
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 | ); |
| 117 | static HRESULT CopyEngineWithSignatureFixup( | 118 | static 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 | ); |
| 123 | static HRESULT RemoveBundleOrPackage( | 125 | static 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 | ||
| 944 | LExit: | 970 | LExit: |
| 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 | ||
| 2130 | LExit: | 2164 | LExit: |
| 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 | |||
| 2203 | LExit: | 2239 | LExit: |
| 2204 | ReleaseFileHandle(hTarget); | 2240 | ReleaseFileHandle(hTarget); |
| 2205 | 2241 | ||
