|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
Casper.cpp
Abstract:
Casper copies a LNK file into %windir%\desktop. This file is hardcoded to point to c:\program files. The EXE that actually places the file into the wrong place is 16-bit, so we cannot use CorrectFilePaths to fix the problem. We hook IPersistFile::Save to accomplish the fixup of the incorrect link, IPersistFile::Save is not modified in any way.
App uses some 16-bit stuff when showing the intro video (see #200495) which we have yet to fix (probably will never fix). After it calls CreateWindowEx to create the "Full-screen animation" window it assigns the return value to a variable. Later on the app plays videos in SmackWin windows. And it checks this var to see if it's 0 - if it is, it calls DestroyWindow on the SmackWin window. Now if the intro video were shown successfully it would have set this var to 0 when the video exits but since in this case the video is not shown, the variable still has the value equal to the "Full-screen animation" window handle. We fix this by setting the return value of the "Full-screen animation" window creation to 0.
History:
1/21/1999 robkenny 03/15/2000 robkenny converted to use the CorrectPathChangesAllUser class 11/07/2000 maonis added hooks for CreateWindowExA and SetFocus (this is for the actual casper.exe) 01/04/2001 maonis tester found more problem with the smackwin windows. rewrote the fix to fix all of them.
--*/
#include "precomp.h"
#include "ClassCFP.h"
IMPLEMENT_SHIM_BEGIN(Casper) #include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN APIHOOK_ENUM_ENTRY(CreateDialogParamA) APIHOOK_ENUM_ENTRY(CreateWindowExA) APIHOOK_ENUM_END
/*++
We return 0 when creating the "Full-screen animation" window.
--*/
HWND APIHOOK(CreateWindowExA)( DWORD dwExStyle, // extended window style
LPCSTR lpClassName, // registered class name
LPCSTR lpWindowName, // window name
DWORD dwStyle, // window style
int x, // horizontal position of window
int y, // vertical position of window
int nWidth, // window width
int nHeight, // window height
HWND hWndParent, // handle to parent or owner window
HMENU hMenu, // menu handle or child identifier
HINSTANCE hInstance, // handle to application instance
LPVOID lpParam // window-creation data
) { HWND hWnd = ORIGINAL_API(CreateWindowExA)( dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
if (lpWindowName) { CSTRING_TRY { CString csWindowName(lpWindowName); if (csWindowName.Compare(L"Full-screen animation") == 0) { hWnd = 0; } } CSTRING_CATCH { // Do nothing
} }
return hWnd; }
/*++
Our path changing class. We want to convert paths to All User
--*/
CorrectPathChangesAllUser * g_PathCorrector = NULL;
static bool g_bLinkCorrected = false;
/*++
Return a pointer to the PathCorrecting object
--*/
inline CorrectPathChangesBase * GetPathcorrecter() { if (g_PathCorrector == NULL) { // Create our correct file path object
g_PathCorrector = new CorrectPathChangesAllUser; g_PathCorrector->AddPathChangeW(L"\\MsM\\", L"\\MorningStar\\" ); }
return g_PathCorrector; }
/*++
Call CorrectPathAllocA and print a debug message if the two strings differ
--*/
WCHAR * CorrectPathAllocDebugW(const WCHAR * uncorrect, const char * debugMsg) { if (uncorrect == NULL) return NULL;
WCHAR * strCorrectFile = GetPathcorrecter()->CorrectPathAllocW(uncorrect);
if (strCorrectFile && uncorrect && _wcsicmp(strCorrectFile, uncorrect) != 0) { DPFN( eDbgLevelInfo, "%s corrected path:\n %S\n %S\n", debugMsg, uncorrect, strCorrectFile); } else // Massive Spew:
{ DPFN( eDbgLevelSpew, "%s unchanged %S\n", debugMsg, uncorrect); }
return strCorrectFile; }
/*++
Casper *copies* a link to %windir%\Desktop; it contains hardcoded paths to incorrect places. Move the link to the proper desktop directory. Correct the Path, Working Directory, and Icon values--all which are wrong.
--*/
void CorrectCasperLink() { if (!g_bLinkCorrected) { // The path to the incorrect desktop link
WCHAR * lpIncorrectCasperPath = GetPathcorrecter()->ExpandEnvironmentValueW(L"%windir%\\Desktop\\casper.lnk");
// Correct the bad desktop link path
WCHAR * lpCorrectCasperPath = GetPathcorrecter()->CorrectPathAllocW(lpIncorrectCasperPath);
DPFN( eDbgLevelInfo, "CorrectCasperLink MoveFileW(%S, %S)\n", lpIncorrectCasperPath, lpCorrectCasperPath); // Move the file to the correct location.
MoveFileW(lpIncorrectCasperPath, lpCorrectCasperPath);
// All finished with the bad path, I never want to see it again.
free(lpIncorrectCasperPath);
HRESULT hres = CoInitialize(NULL); if (SUCCEEDED(hres)) { // Get a pointer to the IShellLink interface.
IShellLinkW *psl; hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (void **)&psl); if (SUCCEEDED(hres)) { // Get a pointer to the IPersistFile interface.
IPersistFile *ppf; hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
if (SUCCEEDED(hres)) { // Load the shortcut.
hres = ppf->Load(lpCorrectCasperPath, STGM_READ); if (SUCCEEDED(hres)) { // We have successfully loaded the link
g_bLinkCorrected = true;
DPFN( eDbgLevelInfo, "CorrectCasperLink %S\n", lpCorrectCasperPath);
// Correct the path to the shortcut target.
WCHAR szBadPath[MAX_PATH]; WCHAR * szCorrectPath;
WIN32_FIND_DATAW wfd; hres = psl->GetPath(szBadPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY); if (SUCCEEDED(hres)) { szCorrectPath = CorrectPathAllocDebugW(szBadPath, "CorrectCasperLink, SetPath"); psl->SetPath(szCorrectPath); free(szCorrectPath); }
// Correct the working directory
hres = psl->GetWorkingDirectory(szBadPath, MAX_PATH); if (SUCCEEDED(hres)) { szCorrectPath = CorrectPathAllocDebugW(szBadPath, "CorrectCasperLink, SetWorkingDirectory"); psl->SetWorkingDirectory(szCorrectPath); free(szCorrectPath); }
// Correct the icon
int iIcon; hres = psl->GetIconLocation(szBadPath, MAX_PATH, &iIcon); if (SUCCEEDED(hres)) { szCorrectPath = CorrectPathAllocDebugW(szBadPath, "CorrectCasperLink, SetIconLocation"); psl->SetIconLocation(szCorrectPath, iIcon); free(szCorrectPath); }
// Save the shortcut.
ppf->Save(NULL, TRUE); } } // Release the pointer to IShellLink.
ppf->Release(); } // Release the pointer to IPersistFile.
psl->Release(); } CoUninitialize(); free(lpCorrectCasperPath); } }
/*++
Do nothing to the CreateDialogParamA call, just an opportunity to correct the casper link
--*/
HWND APIHOOK(CreateDialogParamA)( HINSTANCE hInstance, // handle to module
LPCSTR lpTemplateName, // dialog box template
HWND hWndParent, // handle to owner window
DLGPROC lpDialogFunc, // dialog box procedure
LPARAM dwInitParam // initialization value
) { CorrectCasperLink();
HWND returnValue = ORIGINAL_API(CreateDialogParamA)( hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
return returnValue; }
/*++
Create the appropriate g_PathCorrector Return TRUE if we were successful in creating and initializing.
--*/ BOOL InitPathcorrectorClass() { g_PathCorrector = new CorrectPathChangesAllUser;
if (g_PathCorrector) { return g_PathCorrector->ClassInit(); }
return FALSE; }
/*++
Add all the path corrections to the path corrector. Call after SHIM_STATIC_DLLS_INITIALIZED
--*/ void InitializePathCorrections() { g_PathCorrector->AddPathChangeW(L"\\MsM\\", L"\\MorningStar\\" ); }
BOOL NOTIFY_FUNCTION( DWORD fdwReason ) { BOOL bSuccess = TRUE;
if (fdwReason == DLL_PROCESS_ATTACH) { return InitPathcorrectorClass(); } else if (fdwReason == SHIM_STATIC_DLLS_INITIALIZED) { InitializePathCorrections(); } return bSuccess; }
/*++
Register hooked functions
--*/
HOOK_BEGIN APIHOOK_ENTRY(USER32.DLL, CreateDialogParamA) APIHOOK_ENTRY(USER32.DLL, CreateWindowExA) HOOK_END
IMPLEMENT_SHIM_END
|