diff options
Diffstat (limited to 'src/engine/dependency.cpp')
-rw-r--r-- | src/engine/dependency.cpp | 349 |
1 files changed, 200 insertions, 149 deletions
diff --git a/src/engine/dependency.cpp b/src/engine/dependency.cpp index af4ab0a1..1c33aaf2 100644 --- a/src/engine/dependency.cpp +++ b/src/engine/dependency.cpp | |||
@@ -10,6 +10,12 @@ const LPCWSTR vcszIgnoreDependenciesDelim = L";"; | |||
10 | 10 | ||
11 | // internal function declarations | 11 | // internal function declarations |
12 | 12 | ||
13 | static HRESULT DetectPackageDependents( | ||
14 | __in BURN_PACKAGE* pPackage, | ||
15 | __in STRINGDICT_HANDLE sdIgnoredDependents, | ||
16 | __in const BURN_REGISTRATION* pRegistration | ||
17 | ); | ||
18 | |||
13 | static HRESULT SplitIgnoreDependencies( | 19 | static HRESULT SplitIgnoreDependencies( |
14 | __in_z LPCWSTR wzIgnoreDependencies, | 20 | __in_z LPCWSTR wzIgnoreDependencies, |
15 | __deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies, | 21 | __deref_inout_ecount_opt(*pcDependencies) DEPENDENCY** prgDependencies, |
@@ -28,11 +34,9 @@ static HRESULT GetIgnoredDependents( | |||
28 | __deref_inout STRINGDICT_HANDLE* psdIgnoredDependents | 34 | __deref_inout STRINGDICT_HANDLE* psdIgnoredDependents |
29 | ); | 35 | ); |
30 | 36 | ||
31 | static HRESULT GetProviderInformation( | 37 | static BOOL GetProviderExists( |
32 | __in HKEY hkRoot, | 38 | __in HKEY hkRoot, |
33 | __in_z LPCWSTR wzProviderKey, | 39 | __in_z LPCWSTR wzProviderKey |
34 | __deref_opt_out_z_opt LPWSTR* psczProviderKey, | ||
35 | __deref_opt_out_z_opt LPWSTR* psczId | ||
36 | ); | 40 | ); |
37 | 41 | ||
38 | static void CalculateDependencyActionStates( | 42 | static void CalculateDependencyActionStates( |
@@ -70,20 +74,18 @@ static void UnregisterPackageDependency( | |||
70 | __in_z LPCWSTR wzDependentProviderKey | 74 | __in_z LPCWSTR wzDependentProviderKey |
71 | ); | 75 | ); |
72 | 76 | ||
73 | static BOOL PackageProviderExists( | ||
74 | __in const BURN_PACKAGE* pPackage | ||
75 | ); | ||
76 | |||
77 | 77 | ||
78 | // functions | 78 | // functions |
79 | 79 | ||
80 | extern "C" void DependencyUninitialize( | 80 | extern "C" void DependencyUninitializeProvider( |
81 | __in BURN_DEPENDENCY_PROVIDER* pProvider | 81 | __in BURN_DEPENDENCY_PROVIDER* pProvider |
82 | ) | 82 | ) |
83 | { | 83 | { |
84 | ReleaseStr(pProvider->sczKey); | 84 | ReleaseStr(pProvider->sczKey); |
85 | ReleaseStr(pProvider->sczVersion); | 85 | ReleaseStr(pProvider->sczVersion); |
86 | ReleaseStr(pProvider->sczDisplayName); | 86 | ReleaseStr(pProvider->sczDisplayName); |
87 | ReleaseDependencyArray(pProvider->rgDependents, pProvider->cDependents); | ||
88 | |||
87 | memset(pProvider, 0, sizeof(BURN_DEPENDENCY_PROVIDER)); | 89 | memset(pProvider, 0, sizeof(BURN_DEPENDENCY_PROVIDER)); |
88 | } | 90 | } |
89 | 91 | ||
@@ -167,45 +169,33 @@ LExit: | |||
167 | return hr; | 169 | return hr; |
168 | } | 170 | } |
169 | 171 | ||
170 | extern "C" HRESULT DependencyDetectProviderKeyPackageId( | 172 | extern "C" HRESULT DependencyInitialize( |
171 | __in const BURN_PACKAGE* pPackage, | 173 | __in BURN_REGISTRATION* pRegistration, |
172 | __deref_opt_out_z_opt LPWSTR* psczProviderKey, | 174 | __in_z_opt LPCWSTR wzIgnoreDependencies |
173 | __deref_opt_out_z_opt LPWSTR* psczId | ||
174 | ) | 175 | ) |
175 | { | 176 | { |
176 | HRESULT hr = E_NOTFOUND; | 177 | HRESULT hr = S_OK; |
177 | LPWSTR wzProviderKey = NULL; | ||
178 | HKEY hkRoot = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
179 | 178 | ||
180 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 179 | // If no parent was specified at all, use the bundle id as the self dependent. |
180 | if (!pRegistration->sczActiveParent) | ||
181 | { | 181 | { |
182 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 182 | pRegistration->wzSelfDependent = pRegistration->sczId; |
183 | |||
184 | // Find the first package id registered for the provider key. | ||
185 | hr = GetProviderInformation(hkRoot, pProvider->sczKey, psczProviderKey, psczId); | ||
186 | if (E_NOTFOUND == hr) | ||
187 | { | ||
188 | continue; | ||
189 | } | ||
190 | ExitOnFailure(hr, "Failed to get the package provider information."); | ||
191 | |||
192 | ExitFunction(); | ||
193 | } | 183 | } |
194 | 184 | else if (*pRegistration->sczActiveParent) // if parent was specified use that as the self dependent. | |
195 | // Older bundles may not have written the id so try the default. | ||
196 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | ||
197 | { | 185 | { |
198 | wzProviderKey = pPackage->Msi.sczProductCode; | 186 | pRegistration->wzSelfDependent = pRegistration->sczActiveParent; |
199 | } | 187 | } |
188 | // else parent:none was used which means we should not register a dependency on ourself. | ||
189 | |||
190 | // The current bundle provider key should always be ignored for dependency checks. | ||
191 | hr = DepDependencyArrayAlloc(&pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies, pRegistration->sczProviderKey, NULL); | ||
192 | ExitOnFailure(hr, "Failed to add the bundle provider key to the list of dependencies to ignore."); | ||
200 | 193 | ||
201 | if (wzProviderKey) | 194 | // Add the list of dependencies to ignore. |
195 | if (wzIgnoreDependencies) | ||
202 | { | 196 | { |
203 | hr = GetProviderInformation(hkRoot, wzProviderKey, psczProviderKey, psczId); | 197 | hr = SplitIgnoreDependencies(wzIgnoreDependencies, &pRegistration->rgIgnoredDependencies, &pRegistration->cIgnoredDependencies); |
204 | if (E_NOTFOUND == hr) | 198 | ExitOnFailure(hr, "Failed to split the list of dependencies to ignore."); |
205 | { | ||
206 | ExitFunction(); | ||
207 | } | ||
208 | ExitOnFailure(hr, "Failed to get the package default provider information."); | ||
209 | } | 199 | } |
210 | 200 | ||
211 | LExit: | 201 | LExit: |
@@ -236,23 +226,77 @@ LExit: | |||
236 | return hr; | 226 | return hr; |
237 | } | 227 | } |
238 | 228 | ||
229 | extern "C" HRESULT DependencyDetect( | ||
230 | __in BURN_ENGINE_STATE* pEngineState | ||
231 | ) | ||
232 | { | ||
233 | HRESULT hr = S_OK; | ||
234 | BURN_REGISTRATION* pRegistration = &pEngineState->registration; | ||
235 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; | ||
236 | BURN_PACKAGE* pPackage = NULL; | ||
237 | |||
238 | // Always leave this empty so that all dependents get detected. Plan will ignore dependents based on its own logic. | ||
239 | hr = DictCreateStringList(&sdIgnoredDependents, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE); | ||
240 | ExitOnFailure(hr, "Failed to create the string dictionary."); | ||
241 | |||
242 | hr = DepCheckDependents(pRegistration->hkRoot, pRegistration->sczProviderKey, 0, sdIgnoredDependents, &pRegistration->rgDependents, &pRegistration->cDependents); | ||
243 | if (E_FILENOTFOUND != hr) | ||
244 | { | ||
245 | ExitOnFailure(hr, "Failed dependents check on bundle"); | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | hr = S_OK; | ||
250 | } | ||
251 | |||
252 | for (DWORD iPackage = 0; iPackage < pEngineState->packages.cPackages; ++iPackage) | ||
253 | { | ||
254 | pPackage = pEngineState->packages.rgPackages + iPackage; | ||
255 | hr = DetectPackageDependents(pPackage, sdIgnoredDependents, pRegistration); | ||
256 | ExitOnFailure(hr, "Failed to detect dependents for package '%ls'", pPackage->sczId); | ||
257 | } | ||
258 | |||
259 | for (DWORD iRelatedBundle = 0; iRelatedBundle < pEngineState->registration.relatedBundles.cRelatedBundles; ++iRelatedBundle) | ||
260 | { | ||
261 | pPackage = &pEngineState->registration.relatedBundles.rgRelatedBundles[iRelatedBundle].package; | ||
262 | hr = DetectPackageDependents(pPackage, sdIgnoredDependents, pRegistration); | ||
263 | ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId); | ||
264 | } | ||
265 | |||
266 | if (pRegistration->wzSelfDependent) | ||
267 | { | ||
268 | for (DWORD i = 0; i < pRegistration->cDependents; ++i) | ||
269 | { | ||
270 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; | ||
271 | |||
272 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->wzSelfDependent, -1, pDependent->sczKey, -1)) | ||
273 | { | ||
274 | pRegistration->fSelfRegisteredAsDependent = TRUE; | ||
275 | break; | ||
276 | } | ||
277 | } | ||
278 | } | ||
279 | |||
280 | LExit: | ||
281 | ReleaseDict(sdIgnoredDependents); | ||
282 | |||
283 | return hr; | ||
284 | } | ||
285 | |||
239 | extern "C" HRESULT DependencyPlanInitialize( | 286 | extern "C" HRESULT DependencyPlanInitialize( |
240 | __in const BURN_ENGINE_STATE* pEngineState, | 287 | __in const BURN_REGISTRATION* pRegistration, |
241 | __in BURN_PLAN* pPlan | 288 | __in BURN_PLAN* pPlan |
242 | ) | 289 | ) |
243 | { | 290 | { |
244 | HRESULT hr = S_OK; | 291 | HRESULT hr = S_OK; |
245 | 292 | ||
246 | // The current bundle provider key should always be ignored for dependency checks. | 293 | // TODO: After adding enumeration to STRINGDICT, a single STRINGDICT_HANDLE can be used everywhere. |
247 | hr = DepDependencyArrayAlloc(&pPlan->rgPlannedProviders, &pPlan->cPlannedProviders, pEngineState->registration.sczProviderKey, NULL); | 294 | for (DWORD i = 0; i < pRegistration->cIgnoredDependencies; ++i) |
248 | ExitOnFailure(hr, "Failed to add the bundle provider key to the list of dependencies to ignore."); | ||
249 | |||
250 | // Add the list of dependencies to ignore to the plan. | ||
251 | if (pEngineState->sczIgnoreDependencies) | ||
252 | { | 295 | { |
253 | // TODO: After adding enumeration to STRINGDICT, a single STRINGDICT_HANDLE can be used everywhere. | 296 | DEPENDENCY* pDependency = pRegistration->rgIgnoredDependencies + i; |
254 | hr = SplitIgnoreDependencies(pEngineState->sczIgnoreDependencies, &pPlan->rgPlannedProviders, &pPlan->cPlannedProviders); | 297 | |
255 | ExitOnFailure(hr, "Failed to split the list of dependencies to ignore."); | 298 | hr = DepDependencyArrayAlloc(&pPlan->rgPlannedProviders, &pPlan->cPlannedProviders, pDependency->sczKey, pDependency->sczName); |
299 | ExitOnFailure(hr, "Failed to add the detected provider to the list of dependencies to ignore."); | ||
256 | } | 300 | } |
257 | 301 | ||
258 | LExit: | 302 | LExit: |
@@ -323,9 +367,6 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
323 | { | 367 | { |
324 | HRESULT hr = S_OK; | 368 | HRESULT hr = S_OK; |
325 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; | 369 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; |
326 | DEPENDENCY* rgDependents = NULL; | ||
327 | UINT cDependents = 0; | ||
328 | HKEY hkHive = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
329 | BURN_DEPENDENCY_ACTION dependencyExecuteAction = BURN_DEPENDENCY_ACTION_NONE; | 370 | BURN_DEPENDENCY_ACTION dependencyExecuteAction = BURN_DEPENDENCY_ACTION_NONE; |
330 | BURN_DEPENDENCY_ACTION dependencyRollbackAction = BURN_DEPENDENCY_ACTION_NONE; | 371 | BURN_DEPENDENCY_ACTION dependencyRollbackAction = BURN_DEPENDENCY_ACTION_NONE; |
331 | 372 | ||
@@ -361,18 +402,31 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
361 | } | 402 | } |
362 | else | 403 | else |
363 | { | 404 | { |
405 | hr = S_OK; | ||
406 | |||
364 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 407 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
365 | { | 408 | { |
366 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 409 | const BURN_DEPENDENCY_PROVIDER* pProvider = pPackage->rgDependencyProviders + i; |
367 | 410 | ||
368 | hr = DepCheckDependents(hkHive, pProvider->sczKey, 0, sdIgnoredDependents, &rgDependents, &cDependents); | 411 | for (DWORD j = 0; j < pProvider->cDependents; ++j) |
369 | if (E_FILENOTFOUND != hr) | ||
370 | { | ||
371 | ExitOnFailure(hr, "Failed dependents check on package provider: %ls", pProvider->sczKey); | ||
372 | } | ||
373 | else | ||
374 | { | 412 | { |
375 | hr = S_OK; | 413 | const DEPENDENCY* pDependency = pProvider->rgDependents + j; |
414 | |||
415 | hr = DictKeyExists(sdIgnoredDependents, pDependency->sczKey); | ||
416 | if (E_NOTFOUND == hr) | ||
417 | { | ||
418 | hr = S_OK; | ||
419 | |||
420 | if (!pPackage->fDependencyManagerWasHere) | ||
421 | { | ||
422 | pPackage->fDependencyManagerWasHere = TRUE; | ||
423 | |||
424 | LogId(REPORT_STANDARD, MSG_DEPENDENCY_PACKAGE_HASDEPENDENTS, pPackage->sczId); | ||
425 | } | ||
426 | |||
427 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_DEPENDENT, pDependency->sczKey, LoggingStringOrUnknownIfNull(pDependency->sczName)); | ||
428 | } | ||
429 | ExitOnFailure(hr, "Failed to check the dictionary of ignored dependents."); | ||
376 | } | 430 | } |
377 | } | 431 | } |
378 | } | 432 | } |
@@ -382,52 +436,46 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
382 | CalculateDependencyActionStates(pPackage, pPlan->action, &dependencyExecuteAction, &dependencyRollbackAction); | 436 | CalculateDependencyActionStates(pPackage, pPlan->action, &dependencyExecuteAction, &dependencyRollbackAction); |
383 | 437 | ||
384 | // If dependents were found, change the action to not uninstall the package. | 438 | // If dependents were found, change the action to not uninstall the package. |
385 | if (0 < cDependents) | 439 | if (pPackage->fDependencyManagerWasHere) |
386 | { | 440 | { |
387 | LogId(REPORT_STANDARD, MSG_DEPENDENCY_PACKAGE_HASDEPENDENTS, pPackage->sczId, cDependents); | ||
388 | |||
389 | for (DWORD i = 0; i < cDependents; ++i) | ||
390 | { | ||
391 | const DEPENDENCY* pDependency = &rgDependents[i]; | ||
392 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_PACKAGE_DEPENDENT, pDependency->sczKey, LoggingStringOrUnknownIfNull(pDependency->sczName)); | ||
393 | } | ||
394 | |||
395 | pPackage->fDependencyManagerWasHere = TRUE; | ||
396 | pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE; | 441 | pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE; |
397 | pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; | 442 | pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; |
398 | } | 443 | } |
399 | // Use the calculated dependency actions as the provider actions if there | 444 | else |
400 | // are any non-imported providers that need to be registered and the package | ||
401 | // is current (not obsolete). | ||
402 | else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE != pPackage->currentState) | ||
403 | { | 445 | { |
404 | BOOL fAllImportedProviders = TRUE; // assume all providers were imported. | 446 | // Use the calculated dependency actions as the provider actions if there |
405 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | 447 | // are any non-imported providers that need to be registered and the package |
448 | // is current (not obsolete). | ||
449 | if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE != pPackage->currentState) | ||
406 | { | 450 | { |
407 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 451 | BOOL fAllImportedProviders = TRUE; // assume all providers were imported. |
408 | if (!pProvider->fImported) | 452 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
409 | { | 453 | { |
410 | fAllImportedProviders = FALSE; | 454 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; |
411 | break; | 455 | if (!pProvider->fImported) |
456 | { | ||
457 | fAllImportedProviders = FALSE; | ||
458 | break; | ||
459 | } | ||
412 | } | 460 | } |
413 | } | ||
414 | 461 | ||
415 | if (!fAllImportedProviders) | 462 | if (!fAllImportedProviders) |
416 | { | 463 | { |
417 | pPackage->providerExecute = dependencyExecuteAction; | 464 | pPackage->providerExecute = dependencyExecuteAction; |
418 | pPackage->providerRollback = dependencyRollbackAction; | 465 | pPackage->providerRollback = dependencyRollbackAction; |
466 | } | ||
419 | } | 467 | } |
420 | } | ||
421 | 468 | ||
422 | // If the package will be removed, add its providers to the growing list in the plan. | 469 | // If the package will be removed, add its providers to the growing list in the plan. |
423 | if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute) | 470 | if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute) |
424 | { | ||
425 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | ||
426 | { | 471 | { |
427 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | 472 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) |
473 | { | ||
474 | const BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | ||
428 | 475 | ||
429 | hr = DepDependencyArrayAlloc(&pPlan->rgPlannedProviders, &pPlan->cPlannedProviders, pProvider->sczKey, NULL); | 476 | hr = DepDependencyArrayAlloc(&pPlan->rgPlannedProviders, &pPlan->cPlannedProviders, pProvider->sczKey, NULL); |
430 | ExitOnFailure(hr, "Failed to add the package provider key \"%ls\" to the planned list.", pProvider->sczKey); | 477 | ExitOnFailure(hr, "Failed to add the package provider key \"%ls\" to the planned list.", pProvider->sczKey); |
478 | } | ||
431 | } | 479 | } |
432 | } | 480 | } |
433 | 481 | ||
@@ -435,7 +483,6 @@ extern "C" HRESULT DependencyPlanPackageBegin( | |||
435 | pPackage->dependencyRollback = dependencyRollbackAction; | 483 | pPackage->dependencyRollback = dependencyRollbackAction; |
436 | 484 | ||
437 | LExit: | 485 | LExit: |
438 | ReleaseDependencyArray(rgDependents, cDependents); | ||
439 | ReleaseDict(sdIgnoredDependents); | 486 | ReleaseDict(sdIgnoredDependents); |
440 | 487 | ||
441 | return hr; | 488 | return hr; |
@@ -652,6 +699,58 @@ extern "C" void DependencyUnregisterBundle( | |||
652 | 699 | ||
653 | // internal functions | 700 | // internal functions |
654 | 701 | ||
702 | |||
703 | static HRESULT DetectPackageDependents( | ||
704 | __in BURN_PACKAGE* pPackage, | ||
705 | __in STRINGDICT_HANDLE sdIgnoredDependents, | ||
706 | __in const BURN_REGISTRATION* pRegistration | ||
707 | ) | ||
708 | { | ||
709 | HRESULT hr = S_OK; | ||
710 | HKEY hkHive = pPackage->fPerMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER; | ||
711 | |||
712 | // There's currently no point in getting the dependents if the scope doesn't match, | ||
713 | // because they will just get ignored. | ||
714 | if (pRegistration->fPerMachine != pPackage->fPerMachine) | ||
715 | { | ||
716 | ExitFunction(); | ||
717 | } | ||
718 | |||
719 | for (DWORD i = 0; i < pPackage->cDependencyProviders; ++i) | ||
720 | { | ||
721 | BURN_DEPENDENCY_PROVIDER* pProvider = &pPackage->rgDependencyProviders[i]; | ||
722 | |||
723 | hr = DepCheckDependents(hkHive, pProvider->sczKey, 0, sdIgnoredDependents, &pProvider->rgDependents, &pProvider->cDependents); | ||
724 | if (E_FILENOTFOUND != hr) | ||
725 | { | ||
726 | ExitOnFailure(hr, "Failed dependents check on package provider: %ls", pProvider->sczKey); | ||
727 | |||
728 | if (!pPackage->fPackageProviderExists && (0 < pProvider->cDependents || GetProviderExists(hkHive, pProvider->sczKey))) | ||
729 | { | ||
730 | pPackage->fPackageProviderExists = TRUE; | ||
731 | } | ||
732 | } | ||
733 | else | ||
734 | { | ||
735 | hr = S_OK; | ||
736 | |||
737 | if (!pPackage->fPackageProviderExists && GetProviderExists(hkHive, pProvider->sczKey)) | ||
738 | { | ||
739 | pPackage->fPackageProviderExists = TRUE; | ||
740 | } | ||
741 | } | ||
742 | } | ||
743 | |||
744 | // Older bundles may not have written the id so try the default. | ||
745 | if (!pPackage->fPackageProviderExists && BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.sczProductCode && GetProviderExists(hkHive, pPackage->Msi.sczProductCode)) | ||
746 | { | ||
747 | pPackage->fPackageProviderExists = TRUE; | ||
748 | } | ||
749 | |||
750 | LExit: | ||
751 | return hr; | ||
752 | } | ||
753 | |||
655 | /******************************************************************** | 754 | /******************************************************************** |
656 | SplitIgnoreDependencies - Splits a semicolon-delimited | 755 | SplitIgnoreDependencies - Splits a semicolon-delimited |
657 | string into a list of unique dependencies to ignore. | 756 | string into a list of unique dependencies to ignore. |
@@ -803,52 +902,16 @@ LExit: | |||
803 | } | 902 | } |
804 | 903 | ||
805 | /******************************************************************** | 904 | /******************************************************************** |
806 | GetProviderId - Gets the ID of the package given the provider key. | 905 | GetProviderExists - Gets whether the provider key is registered. |
807 | 906 | ||
808 | *********************************************************************/ | 907 | *********************************************************************/ |
809 | static HRESULT GetProviderInformation( | 908 | static BOOL GetProviderExists( |
810 | __in HKEY hkRoot, | 909 | __in HKEY hkRoot, |
811 | __in_z LPCWSTR wzProviderKey, | 910 | __in_z LPCWSTR wzProviderKey |
812 | __deref_opt_out_z_opt LPWSTR* psczProviderKey, | ||
813 | __deref_opt_out_z_opt LPWSTR* psczId | ||
814 | ) | 911 | ) |
815 | { | 912 | { |
816 | HRESULT hr = S_OK; | 913 | HRESULT hr = DepGetProviderInformation(hkRoot, wzProviderKey, NULL, NULL, NULL); |
817 | LPWSTR sczId = NULL; | 914 | return SUCCEEDED(hr); |
818 | |||
819 | hr = DepGetProviderInformation(hkRoot, wzProviderKey, &sczId, NULL, NULL); | ||
820 | if (E_NOTFOUND == hr) | ||
821 | { | ||
822 | ExitFunction(); | ||
823 | } | ||
824 | ExitOnFailure(hr, "Failed to get the provider key package id."); | ||
825 | |||
826 | // If the id was registered return it and exit. | ||
827 | if (sczId && *sczId) | ||
828 | { | ||
829 | if (psczProviderKey) | ||
830 | { | ||
831 | hr = StrAllocString(psczProviderKey, wzProviderKey, 0); | ||
832 | ExitOnFailure(hr, "Failed to copy the provider key."); | ||
833 | } | ||
834 | |||
835 | if (psczId) | ||
836 | { | ||
837 | *psczId = sczId; | ||
838 | sczId = NULL; | ||
839 | } | ||
840 | |||
841 | ExitFunction(); | ||
842 | } | ||
843 | else | ||
844 | { | ||
845 | hr = E_NOTFOUND; | ||
846 | } | ||
847 | |||
848 | LExit: | ||
849 | ReleaseStr(sczId); | ||
850 | |||
851 | return hr; | ||
852 | } | 915 | } |
853 | 916 | ||
854 | /******************************************************************** | 917 | /******************************************************************** |
@@ -886,7 +949,7 @@ static void CalculateDependencyActionStates( | |||
886 | switch (pPackage->currentState) | 949 | switch (pPackage->currentState) |
887 | { | 950 | { |
888 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: | 951 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: |
889 | if (!PackageProviderExists(pPackage)) | 952 | if (!pPackage->fPackageProviderExists) |
890 | { | 953 | { |
891 | break; | 954 | break; |
892 | } | 955 | } |
@@ -902,7 +965,7 @@ static void CalculateDependencyActionStates( | |||
902 | switch (pPackage->currentState) | 965 | switch (pPackage->currentState) |
903 | { | 966 | { |
904 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: | 967 | case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: |
905 | if (!PackageProviderExists(pPackage)) | 968 | if (!pPackage->fPackageProviderExists) |
906 | { | 969 | { |
907 | break; | 970 | break; |
908 | } | 971 | } |
@@ -1181,15 +1244,3 @@ static void UnregisterPackageDependency( | |||
1181 | } | 1244 | } |
1182 | } | 1245 | } |
1183 | } | 1246 | } |
1184 | |||
1185 | /******************************************************************** | ||
1186 | PackageProviderExists - Checks if a package provider is registered. | ||
1187 | |||
1188 | *********************************************************************/ | ||
1189 | static BOOL PackageProviderExists( | ||
1190 | __in const BURN_PACKAGE* pPackage | ||
1191 | ) | ||
1192 | { | ||
1193 | HRESULT hr = DependencyDetectProviderKeyPackageId(pPackage, NULL, NULL); | ||
1194 | return SUCCEEDED(hr); | ||
1195 | } | ||