Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. EmulateGetCommandLine.cpp
  5. Abstract:
  6. This app uses GetCommandLine() to figure out what the drive letter of the
  7. CD-ROM is. Unfortunately the behaviour of this API is different from Win9x
  8. to NT:
  9. Original command line:
  10. E:\Final Doom\Doom95.exe -dm -cdrom
  11. NT's GetCommandLine() returns:
  12. Doom95.exe -dm -cdrom
  13. Win9x's GetCommandLine() returns:
  14. E:\FINALD~1\DOOM95.EXE -dm -cdrom
  15. This app returns short pathnames for GetCommandLine and GetModuleFileName.
  16. Notes:
  17. This is a general purpose shim.
  18. Created:
  19. 01/03/2000 markder Created
  20. 09/26/2000 mnikkel GetModuleFileName added
  21. 11/10/2000 robkenny Fixed PREFIX bugs, removed W routines.
  22. 11/21/2000 prashkud Fixed the GetCommandLineA hook bug when the CommandLine
  23. had the executable name/path with spaces. Used
  24. AppAndCommandLine functions.
  25. 02/27/2001 robkenny Converted to use CString
  26. 05/02/2001 pierreys If buffer is too small, GetModuleFileNameA puts \0 at end of it like 9X.
  27. --*/
  28. #include "precomp.h"
  29. IMPLEMENT_SHIM_BEGIN(EmulateGetCommandLine)
  30. #include "ShimHookMacro.h"
  31. APIHOOK_ENUM_BEGIN
  32. APIHOOK_ENUM_ENTRY(GetCommandLineA)
  33. APIHOOK_ENUM_ENTRY(GetModuleFileNameA)
  34. APIHOOK_ENUM_END
  35. char * g_lpszCommandLine = NULL;
  36. /*++
  37. This stub function appends the commandline returned from GetCommandLine() to a
  38. pre-determined path to emulate Win9x behavior.
  39. --*/
  40. LPSTR
  41. APIHOOK(GetCommandLineA)(
  42. void
  43. )
  44. {
  45. // Been here, done that
  46. if (g_lpszCommandLine)
  47. {
  48. return g_lpszCommandLine;
  49. }
  50. LPSTR lpszOrig = ORIGINAL_API(GetCommandLineA)();
  51. // Seperate the app name and command line
  52. AppAndCommandLine AppCmdLine(NULL, lpszOrig);
  53. CSTRING_TRY
  54. {
  55. // retrieve the original command line
  56. CString csAppName(AppCmdLine.GetApplicationName());
  57. if (csAppName.Find(L' ') == -1)
  58. {
  59. // If no spaces in app name, return the original command line.
  60. g_lpszCommandLine = lpszOrig;
  61. }
  62. else
  63. {
  64. // Spaces found so return short app path name
  65. // and rest of original command line
  66. csAppName.GetShortPathName();
  67. csAppName += L" ";
  68. csAppName += AppCmdLine.GetCommandlineNoAppName();
  69. g_lpszCommandLine = csAppName.ReleaseAnsi();
  70. LOGN( eDbgLevelError,
  71. "[GetCommandLineA] Changed Command Line from <%s> to <%s>.",
  72. lpszOrig, g_lpszCommandLine);
  73. }
  74. }
  75. CSTRING_CATCH
  76. {
  77. g_lpszCommandLine = lpszOrig;
  78. }
  79. return g_lpszCommandLine;
  80. }
  81. /*++
  82. This stub function returns the short pathname on the call to GetModuleFileName
  83. to emulate Win9x behavior.
  84. --*/
  85. DWORD
  86. APIHOOK(GetModuleFileNameA)(
  87. HMODULE hModule, // handle to module
  88. LPSTR lpFilename, // file name of module
  89. DWORD nSize // size of buffer
  90. )
  91. {
  92. CHAR szExeFileNameLong[MAX_PATH];
  93. CHAR szExeFileNameLong2[MAX_PATH];
  94. DWORD len;
  95. len=ORIGINAL_API(GetModuleFileNameA)(
  96. hModule,
  97. szExeFileNameLong,
  98. sizeof(szExeFileNameLong));
  99. CSTRING_TRY
  100. {
  101. CString csAppName(szExeFileNameLong);
  102. if (csAppName.Find(L' ') > -1)
  103. {
  104. // Spaces found so return short app path name
  105. len = GetShortPathNameA( szExeFileNameLong,
  106. szExeFileNameLong2,
  107. sizeof(szExeFileNameLong2));
  108. LOGN(
  109. eDbgLevelError,
  110. "[GetModuleFileNameA] Changed <%s> to <%s>.",
  111. szExeFileNameLong, szExeFileNameLong2);
  112. RtlCopyMemory(szExeFileNameLong, szExeFileNameLong2, len+1);
  113. }
  114. //
  115. // From 9X's PELDR.C. If the buffer has no room for the '\0', 9X stuff the 0 at the
  116. // last byte.
  117. //
  118. if (nSize) {
  119. // len = pmte->iFileNameLen;
  120. if (len >= nSize) {
  121. len = nSize - 1;
  122. LOGN(eDbgLevelError,
  123. "[GetModuleFileNameA] Will shorten <%s> to %d characters.",
  124. szExeFileNameLong, len);
  125. }
  126. RtlCopyMemory(lpFilename, szExeFileNameLong /* pmte->cfhid.lpFilename */, len);
  127. lpFilename[len] = 0;
  128. }
  129. // Returned the double buffered name len.
  130. return len;
  131. }
  132. CSTRING_CATCH
  133. {
  134. // If error return original api.
  135. return ORIGINAL_API(GetModuleFileNameA)(
  136. hModule,
  137. lpFilename,
  138. nSize);
  139. }
  140. }
  141. /*++
  142. Register hooked functions
  143. --*/
  144. HOOK_BEGIN
  145. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA)
  146. APIHOOK_ENTRY(KERNEL32.DLL, GetModuleFileNameA)
  147. HOOK_END
  148. IMPLEMENT_SHIM_END