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.

138 lines
2.9 KiB

  1. /*++
  2. Copyright (c) 2000-2001 Microsoft Corporation
  3. Module Name:
  4. HandleDBCSUserName.cpp
  5. Abstract:
  6. ShFolder.Exe is failing installation when its app path has Hi Ascii characters (typically DBCS).
  7. When app path is double quoted, the bug code is not processed and install will succeed.
  8. This shim wrap the command line app path name with double quote at GetCommandLineA.
  9. Example:
  10. C:\DOCUME~1\DBCS\LOCALS~1\Temp\_ISTMP1.DIR\_ISTMP0.DIR\shfolder.exe /Q:a
  11. "C:\DOCUME~1\DBCS\LOCALS~1\Temp\_ISTMP1.DIR\_ISTMP0.DIR\shfolder.exe" /Q:a
  12. More info:
  13. Self extractor ShFolder.Exe checks its app path name with space char 0x20 on signed char basis.
  14. Hi Ascii character included in path treated below 0x20 and path is chopped at there.
  15. When path has double quote at the top, the problem check is not proceeded.
  16. History:
  17. 04/09/2001 hioh Created
  18. --*/
  19. #include "precomp.h"
  20. IMPLEMENT_SHIM_BEGIN(HandleDBCSUserName)
  21. #include "ShimHookMacro.h"
  22. //
  23. // Add APIs that you wish to hook to this macro construction.
  24. //
  25. APIHOOK_ENUM_BEGIN
  26. APIHOOK_ENUM_ENTRY(GetCommandLineA)
  27. APIHOOK_ENUM_END
  28. char * g_lpszCommandLine = NULL;
  29. CRITICAL_SECTION g_csCmdLine;
  30. class CAutoLock
  31. {
  32. public:
  33. CAutoLock()
  34. {
  35. EnterCriticalSection(&g_csCmdLine);
  36. }
  37. ~CAutoLock()
  38. {
  39. LeaveCriticalSection(&g_csCmdLine);
  40. }
  41. };
  42. /*++
  43. Wrap the application path name with double quote.
  44. --*/
  45. LPSTR
  46. APIHOOK(GetCommandLineA)(
  47. void
  48. )
  49. {
  50. CAutoLock lock;
  51. if (g_lpszCommandLine)
  52. {
  53. // Been here, done that
  54. return g_lpszCommandLine;
  55. }
  56. g_lpszCommandLine = ORIGINAL_API(GetCommandLineA)();
  57. CSTRING_TRY
  58. {
  59. AppAndCommandLine appCmdLine(NULL, g_lpszCommandLine);
  60. // The command line is often only the arguments: no application name
  61. // If the "application name" doesn't exist, don't bother to put quotes
  62. // around it.
  63. DWORD dwAttr = GetFileAttributesW(appCmdLine.GetApplicationName());
  64. if (dwAttr != INVALID_FILE_ATTRIBUTES)
  65. {
  66. CString csDQ = L'"';
  67. CString csCL = csDQ;
  68. CString csNA = appCmdLine.GetCommandlineNoAppName();
  69. csCL += appCmdLine.GetApplicationName();
  70. csCL += csDQ;
  71. if (!csNA.IsEmpty())
  72. { // Add the rest
  73. csCL += L" ";
  74. csCL += csNA;
  75. }
  76. g_lpszCommandLine = csCL.ReleaseAnsi();
  77. }
  78. }
  79. CSTRING_CATCH
  80. {
  81. // Do nothing, g_lpszCommandLine is initialized with good value
  82. }
  83. return g_lpszCommandLine;
  84. }
  85. BOOL
  86. NOTIFY_FUNCTION(
  87. DWORD fdwReason)
  88. {
  89. if (fdwReason == DLL_PROCESS_ATTACH)
  90. {
  91. return InitializeCriticalSectionAndSpinCount(&g_csCmdLine, 0x80000000);
  92. }
  93. return TRUE;
  94. }
  95. /*++
  96. Register hooked functions
  97. --*/
  98. HOOK_BEGIN
  99. CALL_NOTIFY_FUNCTION
  100. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA)
  101. HOOK_END
  102. IMPLEMENT_SHIM_END