windows-nt/Source/XPSP1/NT/windows/appcompat/shims/specific/operationsmanager.cpp

156 lines
4.4 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 2002 Microsoft Corporation
Module Name:
OperationsManager.cpp
Abstract:
The setup for OperationsManager needs to have LoadLibraryCWD applied.
However, the setups name is random, so we need to DeRandomizeExeName.
But, DeRandomizeExe name calls MoveFileEx to set the file to be deleted
upon reboot. The setup program detects that there are pending file
deletions, interprets them as an aborted install, and recommends that
the user stop installation.
This shim will shim RegQueryValueExA, watch for the
"PendingFileRenameOperations" key, and remove any of our de-randomized exes
from the return string.
Notes:
This is an app-specific shim.
History:
05/07/2002 astritz Created
--*/
#include "precomp.h"
#include "StrSafe.h"
IMPLEMENT_SHIM_BEGIN(OperationsManager)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(RegQueryValueExA)
APIHOOK_ENUM_END
/*++
Remove any of our de-randomized exe names from the PendingFileRenameOperations key.
--*/
LONG
APIHOOK(RegQueryValueExA)(
HKEY hKey, // handle to key
LPCSTR lpValueName, // value name
LPDWORD lpReserved, // reserved
LPDWORD lpType, // type buffer
LPBYTE lpData, // data buffer
LPDWORD lpcbData // size of data buffer
)
{
CHAR *pchBuff = NULL;
LONG lRet = ORIGINAL_API(RegQueryValueExA)(hKey, lpValueName, lpReserved,
lpType, lpData, lpcbData);
if (ERROR_SUCCESS == lRet) {
if (CompareStringA(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL),
SORT_DEFAULT), NORM_IGNORECASE, lpValueName, -1,
"PendingFileRenameOperations", -1) == CSTR_EQUAL) {
//
// Since we're only removing strings from the original data, a buffer
// of the original's size will suffice, and we won't overflow it.
//
CHAR *pchSrc = (CHAR *) lpData;
pchBuff = new CHAR [*lpcbData];
if (NULL != pchBuff) {
CHAR *pchDest = pchBuff;
//
// We want to loop through ALL the data in case there is more than
// one instance of our de-randomized name in the data.
//
while (pchSrc <= (CHAR *)lpData + *lpcbData) {
if (*pchSrc == NULL) {
break;
}
CString csSrc(pchSrc);
CString csFile;
csSrc.GetLastPathComponent(csFile);
if (csFile.CompareNoCase(L"MOM_SETUP_DERANDOMIZED.EXE") == 0) {
// Skip this Src File.
pchSrc += strlen(pchSrc) + 1;
if (pchSrc > (CHAR *)lpData + *lpcbData) {
goto Exit;
}
// Skip the Dest file as well (probably an empty string)
pchSrc += strlen(pchSrc) + 1;
} else {
// Copy the src file.
if (FAILED(StringCchCopyExA(pchDest,
*lpcbData - (pchDest - pchBuff), pchSrc,
&pchDest, NULL, 0))) {
goto Exit;
}
pchSrc += strlen(pchSrc) + 1;
if (pchSrc > (CHAR *)lpData + *lpcbData) {
goto Exit;
}
// Copy the dest file.
if (FAILED(StringCchCopyExA(pchDest,
*lpcbData - (pchDest - pchBuff), pchSrc, &pchDest,
NULL, 0))) {
goto Exit;
}
pchSrc += strlen(pchSrc) + 1;
}
}
// Add the extra NULL to terminate the list of strings.
*pchDest++ = NULL;
// Copy our buffer to the returned buffer.
memcpy(lpData, pchBuff, pchDest - pchBuff);
*lpcbData = pchDest - pchBuff;
}
}
}
Exit:
if (NULL != pchBuff) {
delete [] pchBuff;
}
return lRet;
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueExA)
HOOK_END
IMPLEMENT_SHIM_END