You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
474 lines
19 KiB
474 lines
19 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sxssfc_repairshortnames.cpp
|
|
|
|
Abstract:
|
|
|
|
after textmode setup extracts asms*.cab and write hivesxs.inf,
|
|
write the correct shortnames into the registry
|
|
|
|
Author:
|
|
|
|
Jay Krell (Jaykrell) June 2002
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "stdinc.h"
|
|
#include "recover.h"
|
|
#include "cassemblyrecoveryinfo.h"
|
|
#include "sxssfcscan.h"
|
|
|
|
BOOL
|
|
SxspSetupGetSourceInfo(
|
|
HINF InfHandle, // handle to the INF file
|
|
UINT SourceId, // ID of the source media
|
|
UINT InfoDesired, // information to retrieve
|
|
CBaseStringBuffer &buff,
|
|
LPDWORD RequiredSize // optional, buffer size needed
|
|
)
|
|
{
|
|
FN_PROLOG_WIN32
|
|
CStringBufferAccessor acc;
|
|
DWORD RequiredSize2 = 0;
|
|
BOOL fTooSmall = FALSE;
|
|
|
|
if (RequiredSize == NULL)
|
|
{
|
|
RequiredSize = &RequiredSize2;
|
|
}
|
|
|
|
acc.Attach(&buff);
|
|
|
|
IFW32FALSE_EXIT_UNLESS2(
|
|
::SetupGetSourceInfoW(
|
|
InfHandle,
|
|
SourceId,
|
|
InfoDesired,
|
|
acc,
|
|
acc.GetBufferCchAsDWORD(),
|
|
RequiredSize
|
|
),
|
|
LIST_1(ERROR_INSUFFICIENT_BUFFER),
|
|
fTooSmall);
|
|
|
|
if (fTooSmall)
|
|
{
|
|
acc.Detach();
|
|
|
|
IFW32FALSE_EXIT(buff.Win32ResizeBuffer(*RequiredSize + 1, eDoNotPreserveBufferContents));
|
|
|
|
acc.Attach(&buff);
|
|
|
|
IFW32FALSE_EXIT(
|
|
::SetupGetSourceInfoW(
|
|
InfHandle,
|
|
SourceId,
|
|
InfoDesired,
|
|
acc,
|
|
acc.GetBufferCchAsDWORD(),
|
|
RequiredSize
|
|
));
|
|
}
|
|
|
|
FN_EPILOG
|
|
}
|
|
|
|
BOOL
|
|
SxspGetWindowsSetupPrompt(
|
|
CBaseStringBuffer &rbuffWinsxsRoot
|
|
)
|
|
//
|
|
// This code is based closely on code in base\ntsetup\syssetup\copy.c
|
|
// Legacy wfp is a little different, it opens layout.inf, but the results
|
|
// should be the same.
|
|
//
|
|
{
|
|
FN_PROLOG_WIN32
|
|
|
|
CFusionSetupInfFile InfFile;
|
|
CStringBuffer InfPath;
|
|
const static UNICODE_STRING inf = RTL_CONSTANT_STRING(L"inf");
|
|
const static UNICODE_STRING filename_inf = RTL_CONSTANT_STRING(L"layout.inf");
|
|
UINT SourceId = 0;
|
|
const PCWSTR SystemRoot = USER_SHARED_DATA->NtSystemRoot;
|
|
|
|
IFW32FALSE_EXIT(InfPath.Win32Assign(SystemRoot, ::wcslen(SystemRoot)));
|
|
IFW32FALSE_EXIT(InfPath.Win32AppendPathElement(&inf));
|
|
IFW32FALSE_EXIT(InfPath.Win32AppendPathElement(&filename_inf));
|
|
IFW32FALSE_EXIT(InfFile.Win32SetupOpenInfFileW(InfPath, NULL, INF_STYLE_WIN4, NULL));
|
|
IFW32FALSE_EXIT(::SetupGetSourceFileLocationW(InfFile, NULL, L"shell32.dll", &SourceId, NULL, 0, NULL));
|
|
IFW32FALSE_EXIT(::SxspSetupGetSourceInfo(InfFile, SourceId, SRCINFO_DESCRIPTION, rbuffWinsxsRoot, NULL));
|
|
|
|
FN_EPILOG
|
|
}
|
|
|
|
BOOL
|
|
SxspModifyRegistryData(
|
|
DWORD Flags
|
|
)
|
|
{
|
|
//
|
|
// In postbuild we run sxsofflineinstall.
|
|
// This includes creating hivesxs.inf to populate the registry
|
|
// with data needed for windows file protection.
|
|
//
|
|
// The data includes short names, but we don't know the short names
|
|
// until textmode setup. The code in textmode setup is fairly generic
|
|
// and just expands .cabs.
|
|
//
|
|
// We do not need the short names to be correct until we expect
|
|
// bogus file changes against short file names to induce recovery
|
|
// of assemblies. It is reasonable to assume that these won't happen
|
|
// until setup is done and the system is running.
|
|
//
|
|
// Therefore it is sufficient to fixup the shortnames after textmode setup,
|
|
// such as in a RunOnce entry.
|
|
//
|
|
|
|
/*
|
|
Here is an example of what we are fixing up.
|
|
[AddReg]
|
|
HKLM,"\Software\Microsoft\Windows\CurrentVersion\SideBySide\Installations
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","Identity",0x00001000,"Microsoft.Windows.Common-Controls,processorArchitecture="IA64",publicKeyToken="6595b64144ccf1df",type="win32",version="5.82.0.0""
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","Catalog",0x00011001,0x00000001
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","ManifestSHA1Hash",0x00001001,3b,26,4a,90,08,0f,6a,dd,b6,00,55,5b,a5,a4,9e,21,ad,e3,90,84
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","ShortName",0x00001000,"IA64_M~2.0_X"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","ShortCatalogName",0x00001000,"IA64_M~4.CAT"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","ShortManifestName",0x00001000,"IA64_M~4.MAN"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","PublicKeyToken",0x00001001,65,95,b6,41,44,cc,f1,df
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5","Codebase",0x00001000,"x-ms-windows-source:W_fusi_bin.IA64chk/asms/58200/Msft/Windows/Common/Controls/Controls.man"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5\Codebases\OS","Prompt",0x00001000,"(textmode setup placeholder)"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5\Codebases\OS","URL",0x00001000,"x-ms-windows-source:W_fusi_bin.IA64chk/asms/58200/Msft/Windows/Common/Controls/Controls.man"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5\Files\0","",0x00001000,"comctl32.dll"
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5\Files\0","SHA1",0x00001001,76,c3,6e,4c,c4,10,14,7f,38,c8,bc,cd,4b,4f,b2,90,d8,0a,7c,d7
|
|
HKLM,"\...\IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5\References","OS",0x00001000,"Foom"
|
|
IA64_Microsoft.Windows.Common-Controls_6595b64144ccf1df_5.82.0.0_x-ww_B9C4A0A5
|
|
*/
|
|
BOOL fSuccess = FALSE;
|
|
FN_TRACE_WIN32(fSuccess);
|
|
|
|
CFusionRegKey regkeyInstallations;
|
|
CFusionRegKey regkeyInstallation;
|
|
DWORD dwRegSubKeyIndex = 0;
|
|
BOOL fNoMoreItems = FALSE;
|
|
FILETIME LastWriteFileTimeIgnored = { 0 };
|
|
CTinyStringBuffer buffInstallationName;
|
|
CTinyStringBuffer buffWinsxsRoot;
|
|
CTinyStringBuffer *buffLongFullPath = NULL;
|
|
CTinyStringBuffer buffShortFullPath;
|
|
CTinyStringBuffer buffShortPathLastElement;
|
|
CTinyStringBuffer buffTextualIdentity;
|
|
CTinyStringBuffer buffEmpty;
|
|
CTinyStringBuffer buffWindowsSetupPrompt;
|
|
CTinyStringBuffer buffCurrentPromptInRegistry;
|
|
CTinyStringBuffer buffFullPathToManifest;
|
|
CTinyStringBuffer buffFullPathToCatalog;
|
|
CTinyStringBuffer buffFullPathToPayloadDirectory;
|
|
SIZE_T i = 0;
|
|
const bool fRepairAll = ((Flags & SXSP_MODIFY_REGISTRY_DATA_FLAG_REPAIR_ALL) != 0);
|
|
const bool fRepairShort = fRepairAll || ((Flags & SXSP_MODIFY_REGISTRY_DATA_FLAG_REPAIR_SHORT_NAMES) != 0);
|
|
const bool fDeleteShort = ((Flags & SXSP_MODIFY_REGISTRY_DATA_FLAG_DELETE_SHORT_NAMES) != 0);
|
|
const bool fRepairPrompt = fRepairAll || ((Flags & SXSP_MODIFY_REGISTRY_DATA_FLAG_REPAIR_OFFLINE_INSTALL_REFRESH_PROMPTS) != 0);
|
|
const bool fValidate = ((Flags & SXSP_MODIFY_REGISTRY_DATA_VALIDATE) != 0);
|
|
#if DBG
|
|
bool fDbgPrintBecauseHashValidationFailed = false;
|
|
#endif
|
|
|
|
PARAMETER_CHECK(Flags != 0);
|
|
PARAMETER_CHECK((Flags & ~SXSP_MODIFY_REGISTRY_DATA_FLAG_VALID_FLAGS) == 0);
|
|
|
|
IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(buffWinsxsRoot));
|
|
IFW32FALSE_EXIT(::SxspOpenAssemblyInstallationKey(0, KEY_READ | KEY_SET_VALUE | FUSIONP_KEY_WOW64_64KEY, regkeyInstallations));
|
|
|
|
if (fRepairPrompt)
|
|
{
|
|
IFW32FALSE_EXIT(::SxspGetWindowsSetupPrompt(buffWindowsSetupPrompt));
|
|
}
|
|
|
|
for ((dwRegSubKeyIndex = 0), (fNoMoreItems = FALSE); !fNoMoreItems ; ++dwRegSubKeyIndex)
|
|
{
|
|
bool fNotFound = false;
|
|
CSmartAssemblyIdentity AssemblyIdentity;
|
|
PROBING_ATTRIBUTE_CACHE AttributeCache = { 0 };
|
|
CFusionRegKey codebase_os;
|
|
|
|
IFW32FALSE_EXIT(
|
|
regkeyInstallations.EnumKey(
|
|
dwRegSubKeyIndex,
|
|
buffInstallationName,
|
|
&LastWriteFileTimeIgnored,
|
|
&fNoMoreItems));
|
|
if (fNoMoreItems)
|
|
{
|
|
break;
|
|
}
|
|
|
|
IFW32FALSE_EXIT(
|
|
regkeyInstallations.OpenSubKey(
|
|
regkeyInstallation,
|
|
buffInstallationName,
|
|
KEY_READ | KEY_SET_VALUE | ((fRepairPrompt || fValidate) ? KEY_ENUMERATE_SUB_KEYS : 0)
|
|
));
|
|
IFW32FALSE_EXIT(
|
|
regkeyInstallation.GetValue(
|
|
CSMD_TOPLEVEL_IDENTITY,
|
|
buffTextualIdentity
|
|
));
|
|
|
|
IFW32FALSE_EXIT(::SxspCreateAssemblyIdentityFromTextualString(buffTextualIdentity, &AssemblyIdentity));
|
|
|
|
typedef struct _SXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME
|
|
{
|
|
BOOL (*GeneratePathFunction)(
|
|
IN const CBaseStringBuffer &AssemblyRootDirectory,
|
|
IN PCASSEMBLY_IDENTITY pAssemblyIdentity,
|
|
IN OUT PPROBING_ATTRIBUTE_CACHE ppac,
|
|
IN OUT CBaseStringBuffer &PathBuffer
|
|
);
|
|
PCWSTR RegistryValueName;
|
|
} SXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME, *PSXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME;
|
|
typedef const SXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME *PCSXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME;
|
|
|
|
const static SXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME s_rgFunctionRegistryValueName[] =
|
|
{
|
|
//
|
|
// Note that policies are not currently wfp protected,
|
|
// but it's easy and obvious to put reasonable data
|
|
// in the registry for them.
|
|
//
|
|
{ &::SxspGenerateSxsPath_FullPathToManifestOrPolicyFile, CSMD_TOPLEVEL_SHORTMANIFEST },
|
|
{ &::SxspGenerateSxsPath_FullPathToCatalogFile, CSMD_TOPLEVEL_SHORTCATALOG },
|
|
{ &::SxspGenerateSxsPath_FullPathToPayloadOrPolicyDirectory, CSMD_TOPLEVEL_SHORTNAME }
|
|
};
|
|
CBaseStringBuffer * const rgpbuffFullPaths[] =
|
|
{
|
|
&buffFullPathToManifest,
|
|
&buffFullPathToCatalog,
|
|
&buffFullPathToPayloadDirectory
|
|
};
|
|
|
|
//
|
|
// first generate all three fullpaths
|
|
//
|
|
for (i = 0 ; i != NUMBER_OF(s_rgFunctionRegistryValueName) ; ++i)
|
|
{
|
|
const PCSXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME p = &s_rgFunctionRegistryValueName[i];
|
|
CBaseStringBuffer * const pbuffLongFullPath = rgpbuffFullPaths[i];
|
|
|
|
IFW32FALSE_EXIT((*p->GeneratePathFunction)(
|
|
buffWinsxsRoot,
|
|
AssemblyIdentity,
|
|
&AttributeCache,
|
|
*pbuffLongFullPath));
|
|
IFW32FALSE_EXIT(pbuffLongFullPath->Win32RemoveTrailingPathSeparators());
|
|
}
|
|
|
|
//
|
|
// optionally repair short names
|
|
//
|
|
if (fRepairShort)
|
|
{
|
|
for (i = 0 ; i != NUMBER_OF(s_rgFunctionRegistryValueName) ; ++i)
|
|
{
|
|
const PCSXSP_GENERATE_PATH_FUNCTION_REGISTRY_VALUE_NAME p = &s_rgFunctionRegistryValueName[i];
|
|
CBaseStringBuffer * const pbuffLongFullPath = rgpbuffFullPaths[i];
|
|
{
|
|
DWORD dwWin32Error = NO_ERROR;
|
|
|
|
IFW32FALSE_EXIT(
|
|
::SxspGetShortPathName(
|
|
*pbuffLongFullPath,
|
|
buffShortFullPath,
|
|
dwWin32Error,
|
|
static_cast<SIZE_T>(4),
|
|
ERROR_PATH_NOT_FOUND,
|
|
ERROR_FILE_NOT_FOUND,
|
|
ERROR_BAD_NET_NAME,
|
|
ERROR_BAD_NETPATH));
|
|
if (dwWin32Error == NO_ERROR)
|
|
{
|
|
IFW32FALSE_EXIT(buffShortFullPath.Win32GetLastPathElement(buffShortPathLastElement));
|
|
IFW32FALSE_EXIT(regkeyInstallation.SetValue(p->RegistryValueName, buffShortPathLastElement));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// optionally delete short names
|
|
//
|
|
if (fDeleteShort)
|
|
{
|
|
for (i = 0 ; i != NUMBER_OF(s_rgFunctionRegistryValueName) ; ++i)
|
|
{
|
|
IFW32FALSE_EXIT(regkeyInstallation.DeleteValue(s_rgFunctionRegistryValueName[i].RegistryValueName));
|
|
}
|
|
}
|
|
|
|
//
|
|
// validate hashes and repair prompts
|
|
// BE SURE TO validate hashes first, as we filter what assemblies
|
|
// to repair based on the placeholder prompt
|
|
//
|
|
IFW32FALSE_EXIT_UNLESS2(
|
|
regkeyInstallation.OpenSubKey(
|
|
codebase_os,
|
|
CSMD_TOPLEVEL_CODEBASES L"\\" SXS_INSTALL_REFERENCE_SCHEME_OSINSTALL_STRING,
|
|
KEY_READ | KEY_SET_VALUE),
|
|
LIST_2(ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND),
|
|
fNotFound);
|
|
//
|
|
// OpenSubKey actually eats some errors, so you can't trust
|
|
// fNotFound or the BOOL returned.
|
|
//
|
|
if (!fNotFound && codebase_os.IsValid())
|
|
{
|
|
fNotFound = false;
|
|
IFW32FALSE_EXIT_UNLESS2(
|
|
codebase_os.GetValue(
|
|
CSMD_CODEBASES_PROMPTSTRING,
|
|
buffCurrentPromptInRegistry),
|
|
LIST_2(ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND),
|
|
fNotFound);
|
|
if (!fNotFound)
|
|
{
|
|
if (::FusionpEqualStringsI(
|
|
buffCurrentPromptInRegistry,
|
|
SXSP_OFFLINE_INSTALL_REFRESH_PROMPT_PLACEHOLDER,
|
|
NUMBER_OF(SXSP_OFFLINE_INSTALL_REFRESH_PROMPT_PLACEHOLDER) - 1))
|
|
{
|
|
|
|
if (fValidate)
|
|
{
|
|
CAssemblyRecoveryInfo AssemblyRecoveryInfo;
|
|
bool fNoAssembly = false;
|
|
DWORD dwResult = 0;
|
|
|
|
IFW32FALSE_EXIT(AssemblyRecoveryInfo.Initialize());
|
|
IFW32FALSE_EXIT(AssemblyRecoveryInfo.AssociateWithAssembly(buffInstallationName, fNoAssembly));
|
|
IFW32FALSE_EXIT(::SxspValidateEntireAssembly(
|
|
SXS_VALIDATE_ASM_FLAG_CHECK_EVERYTHING,
|
|
AssemblyRecoveryInfo,
|
|
dwResult,
|
|
AssemblyIdentity
|
|
));
|
|
if (dwResult != SXS_VALIDATE_ASM_FLAG_VALID_PERFECT)
|
|
{
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_SETUPLOG,
|
|
"The assembly %ls contains file hash errors.\n",
|
|
static_cast<PCWSTR>(buffTextualIdentity));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL %s: The assembly %ls contains file hash errors.\n",
|
|
__FUNCTION__,
|
|
static_cast<PCWSTR>(buffTextualIdentity));
|
|
::FusionpSetLastWin32Error(ERROR_SXS_FILE_HASH_MISMATCH);
|
|
#if DBG
|
|
fDbgPrintBecauseHashValidationFailed = true;
|
|
#endif
|
|
goto Exit;
|
|
}
|
|
}
|
|
if (fRepairPrompt)
|
|
{
|
|
IFW32FALSE_EXIT(
|
|
codebase_os.SetValue(
|
|
CSMD_CODEBASES_PROMPTSTRING,
|
|
buffWindowsSetupPrompt));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fSuccess = TRUE;
|
|
Exit:
|
|
if ((!fSuccess && ::FusionpDbgWouldPrintAtFilterLevel(FUSION_DBG_LEVEL_ERROR))
|
|
#if DBG
|
|
|| fDbgPrintBecauseHashValidationFailed
|
|
#endif
|
|
)
|
|
{
|
|
//
|
|
// multiple dbgprints due to 511 limit
|
|
// use tick count to link together seperate prints
|
|
//
|
|
CSxsPreserveLastError ple;
|
|
DWORD TickCount = ::GetTickCount();
|
|
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx error 0x%lx\n", __FUNCTION__, TickCount, ple.LastError());
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx dwRegSubKeyIndex 0x%lx\n", __FUNCTION__, TickCount, dwRegSubKeyIndex);
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx i 0x%Ix\n", __FUNCTION__, TickCount, i);
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffInstallationName %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffInstallationName));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffTextualIdentity %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffTextualIdentity));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffFullPathToManifest %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffFullPathToManifest));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffFullPathToCatalog %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffFullPathToCatalog));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffFullPathToPayloadDirectory %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffFullPathToPayloadDirectory));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffShortFullPath %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffShortFullPath));
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_ERROR,
|
|
"SXS.DLL: %s 0x%lx buffShortPathLastElement %ls\n", __FUNCTION__, TickCount, static_cast<PCWSTR>(buffShortPathLastElement));
|
|
|
|
ple.Restore();
|
|
}
|
|
|
|
return fSuccess;
|
|
}
|
|
|
|
BOOL
|
|
SxspDeleteShortNamesInRegistry(
|
|
VOID
|
|
)
|
|
{
|
|
return ::SxspModifyRegistryData(SXSP_MODIFY_REGISTRY_DATA_FLAG_DELETE_SHORT_NAMES);
|
|
}
|
|
|
|
STDAPI
|
|
DllInstall(
|
|
BOOL fInstall,
|
|
PCWSTR pszCmdLine
|
|
)
|
|
{
|
|
FN_PROLOG_HR
|
|
|
|
//
|
|
// Just ignore uninstall requests.
|
|
//
|
|
if (!fInstall)
|
|
{
|
|
FN_SUCCESSFUL_EXIT();
|
|
}
|
|
|
|
//
|
|
// It doesn't look like guimode setup ever passes in
|
|
// anything for pszCmdLine, so we don't look at it.
|
|
//
|
|
IFW32FALSE_EXIT(::SxspModifyRegistryData(SXSP_MODIFY_REGISTRY_DATA_FLAG_REPAIR_ALL | SXSP_MODIFY_REGISTRY_DATA_VALIDATE));
|
|
|
|
FN_EPILOG
|
|
}
|