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.

157 lines
3.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. ProfilesGetFolderPath.cpp
  5. Abstract:
  6. This DLL hooks shell32!SHGetFolderLocation, shell32!SHGetSpecialFolderLocation, and
  7. shell32!SHGetFolderPathA. Any application that is looking for a per-user CSIDL will
  8. be returned the corosponding all-users location instead.
  9. This shim is designed to fool install apps that call shell32.dll api's to obtain
  10. shell folder locations.
  11. History:
  12. 08/07/2000 reinerf Created
  13. 05/11/2001 markder Modified Removed Desktop redirection as it makes the shim
  14. too invasive.
  15. --*/
  16. #include "precomp.h"
  17. IMPLEMENT_SHIM_BEGIN(ProfilesGetFolderPath)
  18. #include "ShimHookMacro.h"
  19. APIHOOK_ENUM_BEGIN
  20. APIHOOK_ENUM_ENTRY(SHGetFolderLocation)
  21. APIHOOK_ENUM_ENTRY(SHGetSpecialFolderLocation)
  22. APIHOOK_ENUM_ENTRY(SHGetFolderPathA)
  23. APIHOOK_ENUM_END
  24. int
  25. TranslateCSIDL(
  26. int nFolder
  27. )
  28. {
  29. switch (nFolder) {
  30. case CSIDL_STARTMENU:
  31. DPFN(
  32. eDbgLevelInfo,
  33. "[TranslateCSIDL] overriding CSIDL_STARTMENU with CSIDL_COMMON_STARTMENU\n");
  34. return CSIDL_COMMON_STARTMENU;
  35. break;
  36. case CSIDL_STARTUP:
  37. DPFN(
  38. eDbgLevelInfo,
  39. "[TranslateCSIDL] overriding CSIDL_STARTUP with CSIDL_COMMON_STARTUP\n");
  40. return CSIDL_COMMON_STARTUP;
  41. break;
  42. case CSIDL_PROGRAMS:
  43. DPFN(
  44. eDbgLevelInfo,
  45. "[TranslateCSIDL] overriding CSIDL_PROGRAMS with CSIDL_COMMON_PROGRAMS\n");
  46. return CSIDL_COMMON_PROGRAMS;
  47. break;
  48. default:
  49. return nFolder;
  50. }
  51. }
  52. HRESULT
  53. APIHOOK(SHGetSpecialFolderLocation)(
  54. HWND hwndOwner,
  55. int nFolder,
  56. LPITEMIDLIST* ppidl
  57. )
  58. {
  59. return ORIGINAL_API(SHGetSpecialFolderLocation)(hwndOwner,
  60. TranslateCSIDL(nFolder),
  61. ppidl);
  62. }
  63. HRESULT
  64. APIHOOK(SHGetFolderLocation)(
  65. HWND hwndOwner,
  66. int nFolder,
  67. HANDLE hToken,
  68. DWORD dwReserved,
  69. LPITEMIDLIST* ppidl
  70. )
  71. {
  72. return ORIGINAL_API(SHGetFolderLocation)(hwndOwner,
  73. TranslateCSIDL(nFolder),
  74. hToken,
  75. dwReserved,
  76. ppidl);
  77. }
  78. HRESULT
  79. APIHOOK(SHGetFolderPathA)(
  80. HWND hwndOwner,
  81. int nFolder,
  82. HANDLE hToken,
  83. DWORD dwFlags,
  84. LPSTR pszPath
  85. )
  86. {
  87. return ORIGINAL_API(SHGetFolderPathA)(hwndOwner,
  88. TranslateCSIDL(nFolder),
  89. hToken,
  90. dwFlags,
  91. pszPath);
  92. }
  93. // Register hooked functions
  94. BOOL
  95. NOTIFY_FUNCTION(
  96. DWORD fdwReason
  97. )
  98. {
  99. if (fdwReason == DLL_PROCESS_ATTACH) {
  100. OSVERSIONINFOEX osvi = {0};
  101. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  102. if (GetVersionEx((OSVERSIONINFO*)&osvi)) {
  103. if (!((VER_SUITE_TERMINAL & osvi.wSuiteMask) &&
  104. !(VER_SUITE_SINGLEUSERTS & osvi.wSuiteMask))) {
  105. //
  106. // Only install hooks if we are not on a "Terminal Server"
  107. // (aka "Application Server") machine.
  108. //
  109. APIHOOK_ENTRY(SHELL32.DLL, SHGetFolderLocation);
  110. APIHOOK_ENTRY(SHELL32.DLL, SHGetSpecialFolderLocation);
  111. APIHOOK_ENTRY(SHELL32.DLL, SHGetFolderPathA);
  112. }
  113. }
  114. }
  115. return TRUE;
  116. }
  117. HOOK_BEGIN
  118. CALL_NOTIFY_FUNCTION
  119. HOOK_END
  120. IMPLEMENT_SHIM_END