|
|
/*++
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
|