|
|
/*++
Copyright (c) 2000-2001 Microsoft Corporation
Module Name:
EmulateGetCommandLine.cpp
Abstract:
This app uses GetCommandLine() to figure out what the drive letter of the CD-ROM is. Unfortunately the behaviour of this API is different from Win9x to NT:
Original command line: E:\Final Doom\Doom95.exe -dm -cdrom
NT's GetCommandLine() returns: Doom95.exe -dm -cdrom
Win9x's GetCommandLine() returns: E:\FINALD~1\DOOM95.EXE -dm -cdrom
This app returns short pathnames for GetCommandLine and GetModuleFileName.
Notes:
This is a general purpose shim.
Created:
01/03/2000 markder Created 09/26/2000 mnikkel GetModuleFileName added 11/10/2000 robkenny Fixed PREFIX bugs, removed W routines. 11/21/2000 prashkud Fixed the GetCommandLineA hook bug when the CommandLine had the executable name/path with spaces. Used AppAndCommandLine functions. 02/27/2001 robkenny Converted to use CString 05/02/2001 pierreys If buffer is too small, GetModuleFileNameA puts \0 at end of it like 9X.
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(EmulateGetCommandLine) #include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN APIHOOK_ENUM_ENTRY(GetCommandLineA) APIHOOK_ENUM_ENTRY(GetModuleFileNameA) APIHOOK_ENUM_END
char * g_lpszCommandLine = NULL;
/*++
This stub function appends the commandline returned from GetCommandLine() to a pre-determined path to emulate Win9x behavior.
--*/
LPSTR APIHOOK(GetCommandLineA)( void ) { // Been here, done that
if (g_lpszCommandLine) { return g_lpszCommandLine; }
LPSTR lpszOrig = ORIGINAL_API(GetCommandLineA)(); // Seperate the app name and command line
AppAndCommandLine AppCmdLine(NULL, lpszOrig);
CSTRING_TRY { // retrieve the original command line
CString csAppName(AppCmdLine.GetApplicationName());
if (csAppName.Find(L' ') == -1) { // If no spaces in app name, return the original command line.
g_lpszCommandLine = lpszOrig; } else { // Spaces found so return short app path name
// and rest of original command line
csAppName.GetShortPathName(); csAppName += L" "; csAppName += AppCmdLine.GetCommandlineNoAppName(); g_lpszCommandLine = csAppName.ReleaseAnsi();
LOGN( eDbgLevelError, "[GetCommandLineA] Changed Command Line from <%s> to <%s>.", lpszOrig, g_lpszCommandLine); } } CSTRING_CATCH { g_lpszCommandLine = lpszOrig; }
return g_lpszCommandLine; }
/*++
This stub function returns the short pathname on the call to GetModuleFileName to emulate Win9x behavior.
--*/
DWORD APIHOOK(GetModuleFileNameA)( HMODULE hModule, // handle to module
LPSTR lpFilename, // file name of module
DWORD nSize // size of buffer
) { CHAR szExeFileNameLong[MAX_PATH]; CHAR szExeFileNameLong2[MAX_PATH]; DWORD len;
len=ORIGINAL_API(GetModuleFileNameA)( hModule, szExeFileNameLong, sizeof(szExeFileNameLong));
CSTRING_TRY { CString csAppName(szExeFileNameLong);
if (csAppName.Find(L' ') > -1) { // Spaces found so return short app path name
len = GetShortPathNameA( szExeFileNameLong, szExeFileNameLong2, sizeof(szExeFileNameLong2));
LOGN( eDbgLevelError, "[GetModuleFileNameA] Changed <%s> to <%s>.", szExeFileNameLong, szExeFileNameLong2);
RtlCopyMemory(szExeFileNameLong, szExeFileNameLong2, len+1); }
//
// From 9X's PELDR.C. If the buffer has no room for the '\0', 9X stuff the 0 at the
// last byte.
//
if (nSize) { // len = pmte->iFileNameLen;
if (len >= nSize) { len = nSize - 1; LOGN(eDbgLevelError, "[GetModuleFileNameA] Will shorten <%s> to %d characters.", szExeFileNameLong, len); }
RtlCopyMemory(lpFilename, szExeFileNameLong /* pmte->cfhid.lpFilename */, len); lpFilename[len] = 0; }
// Returned the double buffered name len.
return len; } CSTRING_CATCH { // If error return original api.
return ORIGINAL_API(GetModuleFileNameA)( hModule, lpFilename, nSize);
} }
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA) APIHOOK_ENTRY(KERNEL32.DLL, GetModuleFileNameA)
HOOK_END
IMPLEMENT_SHIM_END
|