Windows2003-3790/windows/appcompat/shims/general/movewininitrenametoreg.cpp
2020-09-30 16:53:55 +02:00

191 lines
5.1 KiB
C++

/*++
Copyright (c) 2000-2002 Microsoft Corporation
Module Name:
MoveWinInitRenameToReg.cpp
Abstract:
This shim hooks ExitWindowsEx as well as waits for DLL_PROCESS_DETACH
and then moves the contents of the [Rename] section of wininit.ini
into the registry via MoveFileEx().
History:
07/24/2000 t-adams Created
02/12/2002 mnikkel Modified calls to GetPrivateProfileStringW so default was a
null string, not NULL. Also put in loop for retrieving key values
that increased buffer till value fit instead of using MAX_PATH.
--*/
#include "precomp.h"
#define SIZE_STEP MAX_PATH
IMPLEMENT_SHIM_BEGIN(MoveWinInitRenameToReg)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(ExitWindowsEx)
APIHOOK_ENUM_END
/*++
Abstract:
Moves the entries in the Rename section of WinInit.ini into
the registry via MoveFileEx().
--*/
void MoveWinInitRenameToReg(void)
{
LPWSTR szKeys = NULL;
LPWSTR szFrom = NULL;
DWORD dwKeysSize = 0;
LPWSTR pszTo = NULL;
CString csWinInit;
CString csWinInitBak;
// Construct the paths to wininit.ini and wininit.bak
csWinInit.GetWindowsDirectoryW();
csWinInitBak.GetWindowsDirectoryW();
csWinInit.AppendPath(L"\\wininit.ini");
csWinInitBak.AppendPath(L"\\wininit.bak");
// Make sure wininit.ini exists.
if( GetFileAttributesW(csWinInit) != INVALID_FILE_ATTRIBUTES)
{
// Copy wininit.ini to wininit.bak because we will be destroying
// wininit.ini as we read through its keys and can't simply rename
// it to wininit.bak later. If the backup fails we can still continue.
CopyFileW(csWinInit, csWinInitBak, FALSE);
// Read the "key" names.
// Since we can't know how big the list of keys is going to be,
// continue to try to get the list until GetPrivateProfile string
// returns something other than dwKeysSize-2 (indicating too small
// of a buffer).
do
{
if( NULL != szKeys )
{
free(szKeys);
}
dwKeysSize += SIZE_STEP;
szKeys = (LPWSTR) malloc(dwKeysSize * sizeof(WCHAR));
if( NULL == szKeys )
{
goto Exit;
}
}
while(GetPrivateProfileStringW(L"Rename", NULL, L"", szKeys, dwKeysSize, csWinInit)
== dwKeysSize - 2);
// Traverse through the keys. If there are no keys, szKeys will be a null terminator.
// Delete each key after we read it so that if there are multiple "NUL" keys,
// our calls to GetPrivateProfileStringA won't continue to return only the
// first NUL key's associated value.
pszTo = szKeys;
while(*pszTo != NULL)
{
DWORD dwFromSize = 0;
do
{
if( NULL != szFrom )
{
free(szFrom);
}
dwFromSize += SIZE_STEP;
szFrom = (LPWSTR) malloc(dwFromSize * sizeof(WCHAR));
if( NULL == szFrom )
{
goto Exit;
}
}
while(GetPrivateProfileStringW(L"Rename", pszTo, L"", szFrom, MAX_PATH, csWinInit)
== dwKeysSize - 1);
WritePrivateProfileStringW(L"Rename", pszTo, NULL, csWinInit);
// If pszTo is "NUL", then the intention is to delete the szFrom file, so pass
// NULL to MoveFileExA(). If the move fails we still wish to continue.
if( wcscmp(pszTo, L"NUL") == 0 )
{
MoveFileExW(szFrom, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
}
else
{
MoveFileExW(szFrom, pszTo, MOVEFILE_DELAY_UNTIL_REBOOT);
}
// Move to the next file (key)
pszTo += wcslen(pszTo) + 1;
}
// delete WinInit.ini
DeleteFileW(csWinInit);
}
Exit:
if( NULL != szKeys )
{
free(szKeys);
}
if( NULL != szFrom )
{
free(szFrom);
}
}
/*++
Abstract:
Hook ExitWindowsEx in case the program resets the machine, keeping
us from receiving the DLL_PROCESS_DETACH message. (Shim originally
written for an uninstall program that caused a reset.)
--*/
BOOL
APIHOOK(ExitWindowsEx)(
UINT uFlags,
DWORD dwReserved)
{
MoveWinInitRenameToReg();
return ORIGINAL_API(ExitWindowsEx)(uFlags, dwReserved);
}
/*++
Register hooked functions
--*/
BOOL
NOTIFY_FUNCTION(
DWORD fdwReason)
{
if (fdwReason == DLL_PROCESS_DETACH)
{
MoveWinInitRenameToReg();
}
return TRUE;
}
HOOK_BEGIN
APIHOOK_ENTRY(USER32.DLL, ExitWindowsEx )
CALL_NOTIFY_FUNCTION
HOOK_END
IMPLEMENT_SHIM_END