diff options
Diffstat (limited to '')
| -rw-r--r-- | src/burn/engine/bootstrapperapplication.cpp | 8 | ||||
| -rw-r--r-- | src/burn/engine/cache.cpp | 86 | ||||
| -rw-r--r-- | src/burn/engine/cache.h | 7 | ||||
| -rw-r--r-- | src/burn/engine/container.cpp | 18 | ||||
| -rw-r--r-- | src/burn/engine/container.h | 5 | ||||
| -rw-r--r-- | src/burn/engine/core.cpp | 14 | ||||
| -rw-r--r-- | src/burn/engine/core.h | 1 | ||||
| -rw-r--r-- | src/burn/engine/elevation.cpp | 4 | ||||
| -rw-r--r-- | src/burn/engine/engine.cpp | 3 | ||||
| -rw-r--r-- | src/burn/engine/payload.cpp | 14 | ||||
| -rw-r--r-- | src/burn/engine/payload.h | 1 | ||||
| -rw-r--r-- | src/burn/engine/plan.cpp | 1 | ||||
| -rw-r--r-- | src/burn/test/BurnUnitTest/ElevationTest.cpp | 2 | ||||
| -rw-r--r-- | src/burn/test/BurnUnitTest/ExitCodeTest.cpp | 2 |
14 files changed, 122 insertions, 44 deletions
diff --git a/src/burn/engine/bootstrapperapplication.cpp b/src/burn/engine/bootstrapperapplication.cpp index 947b3720..dc3bd5da 100644 --- a/src/burn/engine/bootstrapperapplication.cpp +++ b/src/burn/engine/bootstrapperapplication.cpp | |||
| @@ -306,6 +306,14 @@ EXTERN_C HRESULT BootstrapperApplicationRemove( | |||
| 306 | { | 306 | { |
| 307 | HRESULT hr = S_OK; | 307 | HRESULT hr = S_OK; |
| 308 | 308 | ||
| 309 | // Release any open file handles so we can try to recursively delete the temp folder. | ||
| 310 | for (DWORD i = 0; i < pUserExperience->payloads.cPayloads; ++i) | ||
| 311 | { | ||
| 312 | BURN_PAYLOAD* pPayload = pUserExperience->payloads.rgPayloads + i; | ||
| 313 | |||
| 314 | ReleaseFileHandle(pPayload->hLocalFile); | ||
| 315 | } | ||
| 316 | |||
| 309 | // Remove temporary UX directory | 317 | // Remove temporary UX directory |
| 310 | if (pUserExperience->sczTempDirectory) | 318 | if (pUserExperience->sczTempDirectory) |
| 311 | { | 319 | { |
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 | ||
diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h index cce35df0..c2e6e157 100644 --- a/src/burn/engine/cache.h +++ b/src/burn/engine/cache.h | |||
| @@ -49,6 +49,10 @@ typedef struct _BURN_CACHE | |||
| 49 | // Only valid after CacheEnsureBaseWorkingFolder | 49 | // Only valid after CacheEnsureBaseWorkingFolder |
| 50 | BOOL fInitializedBaseWorkingFolder; | 50 | BOOL fInitializedBaseWorkingFolder; |
| 51 | LPWSTR sczBaseWorkingFolder; | 51 | LPWSTR sczBaseWorkingFolder; |
| 52 | |||
| 53 | // Only valid after CacheBundleToWorkingDirectory | ||
| 54 | LPWSTR sczBundleEngineWorkingPath; | ||
| 55 | HANDLE hBundleEngineWorkingFile; | ||
| 52 | } BURN_CACHE; | 56 | } BURN_CACHE; |
| 53 | 57 | ||
| 54 | typedef struct _BURN_CACHE_MESSAGE | 58 | typedef struct _BURN_CACHE_MESSAGE |
| @@ -175,8 +179,7 @@ HRESULT CacheBundleToWorkingDirectory( | |||
| 175 | __in BOOL fElvated, | 179 | __in BOOL fElvated, |
| 176 | __in BURN_CACHE* pCache, | 180 | __in BURN_CACHE* pCache, |
| 177 | __in_z LPCWSTR wzExecutableName, | 181 | __in_z LPCWSTR wzExecutableName, |
| 178 | __in BURN_SECTION* pSection, | 182 | __in BURN_SECTION* pSection |
| 179 | __deref_out_z_opt LPWSTR* psczEngineWorkingPath | ||
| 180 | ); | 183 | ); |
| 181 | HRESULT CacheLayoutBundle( | 184 | HRESULT CacheLayoutBundle( |
| 182 | __in_z LPCWSTR wzExecutableName, | 185 | __in_z LPCWSTR wzExecutableName, |
diff --git a/src/burn/engine/container.cpp b/src/burn/engine/container.cpp index e6b91532..fad010cf 100644 --- a/src/burn/engine/container.cpp +++ b/src/burn/engine/container.cpp | |||
| @@ -326,6 +326,24 @@ extern "C" HRESULT ContainerStreamToBuffer( | |||
| 326 | return hr; | 326 | return hr; |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | extern "C" HRESULT ContainerStreamToHandle( | ||
| 330 | __in BURN_CONTAINER_CONTEXT* pContext, | ||
| 331 | __in HANDLE hFile | ||
| 332 | ) | ||
| 333 | { | ||
| 334 | HRESULT hr = S_OK; | ||
| 335 | |||
| 336 | switch (pContext->type) | ||
| 337 | { | ||
| 338 | case BURN_CONTAINER_TYPE_CABINET: | ||
| 339 | hr = CabExtractStreamToHandle(pContext, hFile); | ||
| 340 | break; | ||
| 341 | } | ||
| 342 | |||
| 343 | //LExit: | ||
| 344 | return hr; | ||
| 345 | } | ||
| 346 | |||
| 329 | extern "C" HRESULT ContainerSkipStream( | 347 | extern "C" HRESULT ContainerSkipStream( |
| 330 | __in BURN_CONTAINER_CONTEXT* pContext | 348 | __in BURN_CONTAINER_CONTEXT* pContext |
| 331 | ) | 349 | ) |
diff --git a/src/burn/engine/container.h b/src/burn/engine/container.h index a38afa90..5306e7db 100644 --- a/src/burn/engine/container.h +++ b/src/burn/engine/container.h | |||
| @@ -48,6 +48,7 @@ enum BURN_CAB_OPERATION | |||
| 48 | BURN_CAB_OPERATION_NEXT_STREAM, | 48 | BURN_CAB_OPERATION_NEXT_STREAM, |
| 49 | BURN_CAB_OPERATION_STREAM_TO_FILE, | 49 | BURN_CAB_OPERATION_STREAM_TO_FILE, |
| 50 | BURN_CAB_OPERATION_STREAM_TO_BUFFER, | 50 | BURN_CAB_OPERATION_STREAM_TO_BUFFER, |
| 51 | BURN_CAB_OPERATION_STREAM_TO_HANDLE, | ||
| 51 | BURN_CAB_OPERATION_SKIP_STREAM, | 52 | BURN_CAB_OPERATION_SKIP_STREAM, |
| 52 | BURN_CAB_OPERATION_CLOSE, | 53 | BURN_CAB_OPERATION_CLOSE, |
| 53 | }; | 54 | }; |
| @@ -184,6 +185,10 @@ HRESULT ContainerStreamToBuffer( | |||
| 184 | __out BYTE** ppbBuffer, | 185 | __out BYTE** ppbBuffer, |
| 185 | __out SIZE_T* pcbBuffer | 186 | __out SIZE_T* pcbBuffer |
| 186 | ); | 187 | ); |
| 188 | HRESULT ContainerStreamToHandle( | ||
| 189 | __in BURN_CONTAINER_CONTEXT* pContext, | ||
| 190 | __in HANDLE hFile | ||
| 191 | ); | ||
| 187 | HRESULT ContainerSkipStream( | 192 | HRESULT ContainerSkipStream( |
| 188 | __in BURN_CONTAINER_CONTEXT* pContext | 193 | __in BURN_CONTAINER_CONTEXT* pContext |
| 189 | ); | 194 | ); |
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 3fe9b586..b20f7f0c 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
| @@ -586,11 +586,8 @@ extern "C" HRESULT CoreElevate( | |||
| 586 | while (INVALID_HANDLE_VALUE == pEngineState->companionConnection.hPipe) | 586 | while (INVALID_HANDLE_VALUE == pEngineState->companionConnection.hPipe) |
| 587 | { | 587 | { |
| 588 | // If the elevated companion pipe isn't created yet, let's make that happen. | 588 | // If the elevated companion pipe isn't created yet, let's make that happen. |
| 589 | if (!pEngineState->sczBundleEngineWorkingPath) | 589 | hr = CacheBundleToWorkingDirectory(pEngineState->internalCommand.fInitiallyElevated, &pEngineState->cache, pEngineState->registration.sczExecutableName, &pEngineState->section); |
| 590 | { | 590 | ExitOnFailure(hr, "Failed to cache engine to working directory."); |
| 591 | hr = CacheBundleToWorkingDirectory(pEngineState->internalCommand.fInitiallyElevated, &pEngineState->cache, pEngineState->registration.sczExecutableName, &pEngineState->section, &pEngineState->sczBundleEngineWorkingPath); | ||
| 592 | ExitOnFailure(hr, "Failed to cache engine to working directory."); | ||
| 593 | } | ||
| 594 | 591 | ||
| 595 | hr = ElevationElevate(pEngineState, reason, hwndParent); | 592 | hr = ElevationElevate(pEngineState, reason, hwndParent); |
| 596 | if (E_SUSPECTED_AV_INTERFERENCE == hr && 1 > cAVRetryAttempts) | 593 | if (E_SUSPECTED_AV_INTERFERENCE == hr && 1 > cAVRetryAttempts) |
| @@ -695,11 +692,8 @@ extern "C" HRESULT CoreApply( | |||
| 695 | ::InitializeCriticalSection(&applyContext.csApply); | 692 | ::InitializeCriticalSection(&applyContext.csApply); |
| 696 | 693 | ||
| 697 | // Ensure the engine is cached to the working path. | 694 | // Ensure the engine is cached to the working path. |
| 698 | if (!pEngineState->sczBundleEngineWorkingPath) | 695 | hr = CacheBundleToWorkingDirectory(pEngineState->internalCommand.fInitiallyElevated, &pEngineState->cache, pEngineState->registration.sczExecutableName, &pEngineState->section); |
| 699 | { | 696 | ExitOnFailure(hr, "Failed to cache engine to working directory."); |
| 700 | hr = CacheBundleToWorkingDirectory(pEngineState->internalCommand.fInitiallyElevated, &pEngineState->cache, pEngineState->registration.sczExecutableName, &pEngineState->section, &pEngineState->sczBundleEngineWorkingPath); | ||
| 701 | ExitOnFailure(hr, "Failed to cache engine to working directory."); | ||
| 702 | } | ||
| 703 | 697 | ||
| 704 | // Elevate. | 698 | // Elevate. |
| 705 | if (pEngineState->plan.fPerMachine) | 699 | if (pEngineState->plan.fPerMachine) |
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 787100b7..c5d0a370 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h | |||
| @@ -172,7 +172,6 @@ typedef struct _BURN_ENGINE_STATE | |||
| 172 | BURN_REDIRECTED_LOGGING_CONTEXT elevatedLoggingContext; | 172 | BURN_REDIRECTED_LOGGING_CONTEXT elevatedLoggingContext; |
| 173 | HANDLE hUnelevatedLoggingThread; | 173 | HANDLE hUnelevatedLoggingThread; |
| 174 | 174 | ||
| 175 | LPWSTR sczBundleEngineWorkingPath; | ||
| 176 | BURN_PIPE_CONNECTION companionConnection; | 175 | BURN_PIPE_CONNECTION companionConnection; |
| 177 | BURN_PIPE_CONNECTION embeddedConnection; | 176 | BURN_PIPE_CONNECTION embeddedConnection; |
| 178 | 177 | ||
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index 85d5a543..90e9db01 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
| @@ -1677,8 +1677,8 @@ static HRESULT LaunchElevatedProcess( | |||
| 1677 | 1677 | ||
| 1678 | // Since ShellExecuteEx doesn't support passing inherited handles, don't bother with CoreAppendFileHandleSelfToCommandLine. | 1678 | // Since ShellExecuteEx doesn't support passing inherited handles, don't bother with CoreAppendFileHandleSelfToCommandLine. |
| 1679 | // We could fallback to using ::DuplicateHandle to inject the file handle later if necessary. | 1679 | // We could fallback to using ::DuplicateHandle to inject the file handle later if necessary. |
| 1680 | hr = ShelExec(pEngineState->sczBundleEngineWorkingPath, sczParameters, L"runas", NULL, SW_SHOWNA, hwndParent, &hProcess); | 1680 | hr = ShelExec(pEngineState->cache.sczBundleEngineWorkingPath, sczParameters, L"runas", NULL, SW_SHOWNA, hwndParent, &hProcess); |
| 1681 | ExitOnFailure(hr, "Failed to launch elevated child process: %ls", pEngineState->sczBundleEngineWorkingPath); | 1681 | ExitOnFailure(hr, "Failed to launch elevated child process: %ls", pEngineState->cache.sczBundleEngineWorkingPath); |
| 1682 | 1682 | ||
| 1683 | pConnection->dwProcessId = ::GetProcessId(hProcess); | 1683 | pConnection->dwProcessId = ::GetProcessId(hProcess); |
| 1684 | pConnection->hProcess = hProcess; | 1684 | pConnection->hProcess = hProcess; |
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp index 5fec289d..2232358d 100644 --- a/src/burn/engine/engine.cpp +++ b/src/burn/engine/engine.cpp | |||
| @@ -364,6 +364,8 @@ static HRESULT InitializeEngineState( | |||
| 364 | HANDLE hSectionFile = hEngineFile; | 364 | HANDLE hSectionFile = hEngineFile; |
| 365 | HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE; | 365 | HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE; |
| 366 | 366 | ||
| 367 | pEngineState->cache.hBundleEngineWorkingFile = INVALID_HANDLE_VALUE; | ||
| 368 | |||
| 367 | pEngineState->hUnelevatedLoggingThread = INVALID_HANDLE_VALUE; | 369 | pEngineState->hUnelevatedLoggingThread = INVALID_HANDLE_VALUE; |
| 368 | pEngineState->elevatedLoggingContext.hPipe = INVALID_HANDLE_VALUE; | 370 | pEngineState->elevatedLoggingContext.hPipe = INVALID_HANDLE_VALUE; |
| 369 | pEngineState->elevatedLoggingContext.hThread = INVALID_HANDLE_VALUE; | 371 | pEngineState->elevatedLoggingContext.hThread = INVALID_HANDLE_VALUE; |
| @@ -413,7 +415,6 @@ static void UninitializeEngineState( | |||
| 413 | 415 | ||
| 414 | BurnPipeConnectionUninitialize(&pEngineState->embeddedConnection); | 416 | BurnPipeConnectionUninitialize(&pEngineState->embeddedConnection); |
| 415 | BurnPipeConnectionUninitialize(&pEngineState->companionConnection); | 417 | BurnPipeConnectionUninitialize(&pEngineState->companionConnection); |
| 416 | ReleaseStr(pEngineState->sczBundleEngineWorkingPath) | ||
| 417 | 418 | ||
| 418 | ReleaseHandle(pEngineState->hMessageWindowThread); | 419 | ReleaseHandle(pEngineState->hMessageWindowThread); |
| 419 | 420 | ||
diff --git a/src/burn/engine/payload.cpp b/src/burn/engine/payload.cpp index 1d8328e3..270da6aa 100644 --- a/src/burn/engine/payload.cpp +++ b/src/burn/engine/payload.cpp | |||
| @@ -239,6 +239,7 @@ extern "C" void PayloadUninitialize( | |||
| 239 | ReleaseMem(pPayload->pbCertificateRootThumbprint); | 239 | ReleaseMem(pPayload->pbCertificateRootThumbprint); |
| 240 | ReleaseMem(pPayload->pbCertificateRootPublicKeyIdentifier); | 240 | ReleaseMem(pPayload->pbCertificateRootPublicKeyIdentifier); |
| 241 | ReleaseStr(pPayload->sczSourcePath); | 241 | ReleaseStr(pPayload->sczSourcePath); |
| 242 | ReleaseFileHandle(pPayload->hLocalFile); | ||
| 242 | ReleaseStr(pPayload->sczLocalFilePath); | 243 | ReleaseStr(pPayload->sczLocalFilePath); |
| 243 | ReleaseStr(pPayload->sczFailedLocalAcquisitionPath); | 244 | ReleaseStr(pPayload->sczFailedLocalAcquisitionPath); |
| 244 | ReleaseStr(pPayload->downloadSource.sczUrl); | 245 | ReleaseStr(pPayload->downloadSource.sczUrl); |
| @@ -278,6 +279,7 @@ extern "C" HRESULT PayloadExtractUXContainer( | |||
| 278 | LPWSTR sczStreamName = NULL; | 279 | LPWSTR sczStreamName = NULL; |
| 279 | LPWSTR sczDirectory = NULL; | 280 | LPWSTR sczDirectory = NULL; |
| 280 | BURN_PAYLOAD* pPayload = NULL; | 281 | BURN_PAYLOAD* pPayload = NULL; |
| 282 | HANDLE hTargetFile = INVALID_HANDLE_VALUE; | ||
| 281 | 283 | ||
| 282 | // extract all payloads | 284 | // extract all payloads |
| 283 | for (;;) | 285 | for (;;) |
| @@ -306,9 +308,18 @@ extern "C" HRESULT PayloadExtractUXContainer( | |||
| 306 | hr = DirEnsureExists(sczDirectory, NULL); | 308 | hr = DirEnsureExists(sczDirectory, NULL); |
| 307 | ExitOnFailure(hr, "Failed to ensure directory exists"); | 309 | ExitOnFailure(hr, "Failed to ensure directory exists"); |
| 308 | 310 | ||
| 309 | hr = ContainerStreamToFile(pContainerContext, pPayload->sczLocalFilePath); | 311 | hTargetFile = ::CreateFileW(pPayload->sczLocalFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); |
| 312 | ExitOnInvalidHandleWithLastError(hTargetFile, hr, "Failed to create file: %ls", pPayload->sczLocalFilePath); | ||
| 313 | |||
| 314 | hr = ContainerStreamToHandle(pContainerContext, hTargetFile); | ||
| 310 | ExitOnFailure(hr, "Failed to extract file."); | 315 | ExitOnFailure(hr, "Failed to extract file."); |
| 311 | 316 | ||
| 317 | // Reopen the payload for read-only access to prevent the file from being removed or tampered with while the BA is running. | ||
| 318 | ReleaseFileHandle(hTargetFile); | ||
| 319 | |||
| 320 | hr = FileCreateWithRetry(pPayload->sczLocalFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 30, 100, &pPayload->hLocalFile); | ||
| 321 | ExitOnFailure(hr, "Failed to open file: %ls", pPayload->sczLocalFilePath); | ||
| 322 | |||
| 312 | // flag that the payload has been acquired | 323 | // flag that the payload has been acquired |
| 313 | pPayload->state = BURN_PAYLOAD_STATE_ACQUIRED; | 324 | pPayload->state = BURN_PAYLOAD_STATE_ACQUIRED; |
| 314 | } | 325 | } |
| @@ -326,6 +337,7 @@ extern "C" HRESULT PayloadExtractUXContainer( | |||
| 326 | } | 337 | } |
| 327 | 338 | ||
| 328 | LExit: | 339 | LExit: |
| 340 | ReleaseFileHandle(hTargetFile); | ||
| 329 | ReleaseStr(sczStreamName); | 341 | ReleaseStr(sczStreamName); |
| 330 | ReleaseStr(sczDirectory); | 342 | ReleaseStr(sczDirectory); |
| 331 | 343 | ||
diff --git a/src/burn/engine/payload.h b/src/burn/engine/payload.h index 351fd058..4c21ae54 100644 --- a/src/burn/engine/payload.h +++ b/src/burn/engine/payload.h | |||
| @@ -57,6 +57,7 @@ typedef struct _BURN_PAYLOAD | |||
| 57 | // mutable members | 57 | // mutable members |
| 58 | BURN_PAYLOAD_STATE state; | 58 | BURN_PAYLOAD_STATE state; |
| 59 | LPWSTR sczLocalFilePath; // location of extracted or downloaded copy | 59 | LPWSTR sczLocalFilePath; // location of extracted or downloaded copy |
| 60 | HANDLE hLocalFile; | ||
| 60 | 61 | ||
| 61 | LPWSTR sczUnverifiedPath; | 62 | LPWSTR sczUnverifiedPath; |
| 62 | DWORD cRemainingInstances; | 63 | DWORD cRemainingInstances; |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 47b1c621..7994dd32 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
| @@ -2117,6 +2117,7 @@ static void ResetPlannedPayloadsState( | |||
| 2117 | pPayload->cRemainingInstances = 0; | 2117 | pPayload->cRemainingInstances = 0; |
| 2118 | pPayload->state = BURN_PAYLOAD_STATE_NONE; | 2118 | pPayload->state = BURN_PAYLOAD_STATE_NONE; |
| 2119 | pPayload->fFailedVerificationFromAcquisition = FALSE; | 2119 | pPayload->fFailedVerificationFromAcquisition = FALSE; |
| 2120 | ReleaseFileHandle(pPayload->hLocalFile); | ||
| 2120 | ReleaseNullStr(pPayload->sczLocalFilePath); | 2121 | ReleaseNullStr(pPayload->sczLocalFilePath); |
| 2121 | ReleaseNullStr(pPayload->sczFailedLocalAcquisitionPath); | 2122 | ReleaseNullStr(pPayload->sczFailedLocalAcquisitionPath); |
| 2122 | } | 2123 | } |
diff --git a/src/burn/test/BurnUnitTest/ElevationTest.cpp b/src/burn/test/BurnUnitTest/ElevationTest.cpp index f9ae2579..81e9f93e 100644 --- a/src/burn/test/BurnUnitTest/ElevationTest.cpp +++ b/src/burn/test/BurnUnitTest/ElevationTest.cpp | |||
| @@ -55,7 +55,7 @@ namespace Bootstrapper | |||
| 55 | BURN_PIPE_CONNECTION* pConnection = &engineState.companionConnection; | 55 | BURN_PIPE_CONNECTION* pConnection = &engineState.companionConnection; |
| 56 | DWORD dwResult = S_OK; | 56 | DWORD dwResult = S_OK; |
| 57 | 57 | ||
| 58 | engineState.sczBundleEngineWorkingPath = L"tests\\ignore\\this\\path\\to\\burn.exe"; | 58 | engineState.cache.sczBundleEngineWorkingPath = L"tests\\ignore\\this\\path\\to\\burn.exe"; |
| 59 | 59 | ||
| 60 | try | 60 | try |
| 61 | { | 61 | { |
diff --git a/src/burn/test/BurnUnitTest/ExitCodeTest.cpp b/src/burn/test/BurnUnitTest/ExitCodeTest.cpp index c742543b..9b66f4c0 100644 --- a/src/burn/test/BurnUnitTest/ExitCodeTest.cpp +++ b/src/burn/test/BurnUnitTest/ExitCodeTest.cpp | |||
| @@ -105,7 +105,7 @@ static void LoadEngineState( | |||
| 105 | { (DWORD)HRESULT_FROM_WIN32(ERROR_FAIL_REBOOT_INITIATED), HRESULT_FROM_WIN32(ERROR_FAIL_REBOOT_INITIATED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" }, | 105 | { (DWORD)HRESULT_FROM_WIN32(ERROR_FAIL_REBOOT_INITIATED), HRESULT_FROM_WIN32(ERROR_FAIL_REBOOT_INITIATED), BOOTSTRAPPER_APPLY_RESTART_NONE, L"Custom" }, |
| 106 | }; | 106 | }; |
| 107 | 107 | ||
| 108 | engineState.sczBundleEngineWorkingPath = L"tests\\ignore\\this\\path\\to\\burn.exe"; | 108 | engineState.cache.sczBundleEngineWorkingPath = L"tests\\ignore\\this\\path\\to\\burn.exe"; |
| 109 | 109 | ||
| 110 | try | 110 | try |
| 111 | { | 111 | { |
