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.

170 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. SearchPathInAppPaths.cpp
  5. Abstract:
  6. An application might use SearchPath to determine if a specific EXE is found
  7. in the current path. Some applications have registered their path with the
  8. shell in "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths"
  9. If SearchPath fails, we'll check to see if the applications has registered a path.
  10. History:
  11. 03/03/2000 robkenny Created
  12. --*/
  13. #include "precomp.h"
  14. #include <stdio.h>
  15. IMPLEMENT_SHIM_BEGIN(SearchPathInAppPaths)
  16. #include "ShimHookMacro.h"
  17. APIHOOK_ENUM_BEGIN
  18. APIHOOK_ENUM_ENTRY(SearchPathA)
  19. APIHOOK_ENUM_END
  20. /*++
  21. Grab an entry from the registry, expand if REG_EXPAND_SZ.
  22. Return a full path in lpBuffer, and a pointer to the file part.
  23. Return the number of chars copied into lpBuffer, including NULL terminator.
  24. --*/
  25. DWORD
  26. GetPathFromRegistryA(
  27. HKEY hKey, // handle to key
  28. LPCSTR lpKeyPath, // value name
  29. LPCSTR lpValueName, // value name
  30. DWORD nBufferLength, // size of buffer
  31. LPSTR lpBuffer, // found file name buffer
  32. LPSTR *lpFilePart // file component (optional)
  33. )
  34. {
  35. DWORD returnValue = 0;
  36. HKEY hkPathKey;
  37. LONG success;
  38. success = RegOpenKeyExA(hKey, lpKeyPath, 0, KEY_QUERY_VALUE, &hkPathKey);
  39. if (success == ERROR_SUCCESS)
  40. {
  41. DWORD appPathsKeyType;
  42. char appPathsData[MAX_PATH];
  43. DWORD appPathsDataSize = MAX_PATH;
  44. appPathsData[0] = 0;
  45. success = RegQueryValueExA(
  46. hkPathKey, lpValueName, NULL, &appPathsKeyType, (BYTE *)appPathsData,
  47. &appPathsDataSize);
  48. if (success == ERROR_SUCCESS)
  49. {
  50. if (appPathsKeyType == REG_EXPAND_SZ)
  51. {
  52. // Gotta expand the env. vars
  53. char expandedAppPathsData[MAX_PATH];
  54. DWORD dwChars = ExpandEnvironmentStringsA(appPathsData, expandedAppPathsData, MAX_PATH);
  55. if (dwChars > 0)
  56. {
  57. returnValue = GetFullPathNameA(expandedAppPathsData, nBufferLength, lpBuffer, lpFilePart);
  58. }
  59. }
  60. else if (appPathsKeyType == REG_SZ)
  61. {
  62. returnValue = GetFullPathNameA(appPathsData, nBufferLength, lpBuffer, lpFilePart);
  63. }
  64. }
  65. RegCloseKey(hkPathKey);
  66. }
  67. return returnValue;
  68. }
  69. DWORD
  70. APIHOOK(SearchPathA)(
  71. LPCSTR lpPath, // search path
  72. LPCSTR lpFileName, // file name
  73. LPCSTR lpExtension, // file extension
  74. DWORD nBufferLength, // size of buffer
  75. LPSTR lpBuffer, // found file name buffer
  76. LPSTR *lpFilePart // file component
  77. )
  78. {
  79. DWORD returnValue = ORIGINAL_API(SearchPathA)(
  80. lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, lpFilePart);
  81. if (returnValue == 0)
  82. {
  83. // Search failed, look in the registry.
  84. // First look for lpFileName. If that fails, append lpExtension and look again.
  85. CSTRING_TRY
  86. {
  87. CString csFile(lpFileName);
  88. CString csReg(L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\");
  89. csReg.AppendPath(csFile);
  90. DWORD success;
  91. success = GetPathFromRegistryA(HKEY_LOCAL_MACHINE,
  92. csReg.GetAnsi(),
  93. NULL, // (Default) entry
  94. nBufferLength,
  95. lpBuffer,
  96. lpFilePart);
  97. if (success > 0)
  98. {
  99. // SearchPath returns the number of chars, not including the NULL terminator
  100. returnValue = success - 1;
  101. }
  102. else
  103. {
  104. // Try appending the extension onto the path
  105. CString csExt(lpExtension);
  106. csReg += csExt;
  107. success = GetPathFromRegistryA(HKEY_LOCAL_MACHINE,
  108. csReg.GetAnsi(),
  109. NULL, // (Default) entry
  110. nBufferLength,
  111. lpBuffer,
  112. lpFilePart);
  113. if (success > 0)
  114. {
  115. // SearchPath returns the number of chars, not including the NULL terminator
  116. returnValue = success - 1;
  117. }
  118. }
  119. }
  120. CSTRING_CATCH
  121. {
  122. // Do nothing
  123. }
  124. }
  125. return returnValue;
  126. }
  127. /*++
  128. Register hooked functions
  129. --*/
  130. HOOK_BEGIN
  131. APIHOOK_ENTRY(KERNEL32.DLL, SearchPathA)
  132. HOOK_END
  133. IMPLEMENT_SHIM_END