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.

162 lines
4.9 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 2000
  6. //
  7. // File: modulepath.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #pragma once
  11. #if !defined(__MODULEPATH_H_INCLUDED__)
  12. #define __MODULEPATH_H_INCLUDED__
  13. #include "cstr.h"
  14. /***************************************************************************\
  15. *
  16. * Class: CModulePath
  17. *
  18. * PURPOSE: groups static methods needed to set correct module paths in the registry
  19. * Having a class here (not functions) allows to link only one instance
  20. * of the methods per module.
  21. * NOTE: it uses global _Module, which is different for each DLL.
  22. *
  23. \***************************************************************************/
  24. class CModulePath
  25. {
  26. public:
  27. /***************************************************************************\
  28. *
  29. * METHOD: MakeAbsoluteModulePath
  30. *
  31. * PURPOSE: makes absolute path by prepending the directory of current module.
  32. * If file is in system directory and platform supports that,
  33. * method replaces path with "%SystemRoot%\system32" or similar.
  34. *
  35. * PARAMETERS:
  36. * const CStr& str - module name.
  37. *
  38. * RETURNS:
  39. * CStr - result path (empty if cannot be calculated)
  40. *
  41. \***************************************************************************/
  42. static CStr MakeAbsoluteModulePath(const CStr& str)
  43. {
  44. // if the string contains path - do not change it
  45. CStr strModulePath;
  46. if ( ( str.Find(_T('\\')) != -1 ) || ( str.Find(_T('/')) != -1 ) )
  47. {
  48. strModulePath = str;
  49. }
  50. else
  51. {
  52. /*
  53. * get a buffer for the module filename; if it failed,
  54. * return empty string
  55. */
  56. LPTSTR pszModulePath = strModulePath.GetBuffer(_MAX_PATH);
  57. if (pszModulePath == NULL)
  58. return _T("");
  59. // else append the module directory
  60. DWORD dwPathLen = ::GetModuleFileName(_Module.GetModuleInstance(),
  61. pszModulePath,
  62. _MAX_PATH );
  63. strModulePath.ReleaseBuffer();
  64. // if encountered problems with a path - return empty string
  65. if ( dwPathLen == 0 )
  66. return _T("");
  67. int iLastSlashPos = strModulePath.ReverseFind(_T('\\'));
  68. // if we cannot separate the filename - cannot append it to the file
  69. if (iLastSlashPos == -1)
  70. return _T("");
  71. //not subtract the file name
  72. strModulePath = strModulePath.Left(iLastSlashPos + 1) + str;
  73. }
  74. // now see it it matches system directory ...
  75. // get system dir
  76. CStr strSystemPath;
  77. LPTSTR pszSystemPath = strSystemPath.GetBuffer(_MAX_PATH);
  78. if (pszSystemPath == NULL)
  79. return strModulePath;
  80. DWORD dwPathLen = ::GetSystemDirectory( pszSystemPath, _MAX_PATH);
  81. strSystemPath.ReleaseBuffer();
  82. // if encountered problems with system path - return what we have
  83. if ( dwPathLen == 0 )
  84. return strModulePath;
  85. // now compare the path and substitute with the environment variable
  86. // [ if path is not in the system dir - use the value we already have ]
  87. if ( PlatformSupports_REG_EXPAND_SZ_Values() &&
  88. (_tcsnicmp( strSystemPath, strModulePath, strSystemPath.GetLength() ) == 0) )
  89. {
  90. CStr strSystemVariable = (IsNTPlatform() ? _T("%SystemRoot%\\System32") :
  91. _T("%WinDir%\\System"));
  92. // path is in the system dir - replace it with environment var
  93. strModulePath = strSystemVariable + strModulePath.Mid(strSystemPath.GetLength());
  94. }
  95. return strModulePath;
  96. }
  97. /***************************************************************************\
  98. *
  99. * METHOD: IsNTPlatform
  100. *
  101. * PURPOSE: checks current platform
  102. *
  103. * RETURNS:
  104. * bool - true if application is running on NT platform
  105. *
  106. \***************************************************************************/
  107. static bool IsNTPlatform()
  108. {
  109. // Find out OS version.
  110. OSVERSIONINFO versInfo;
  111. versInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  112. BOOL bStat = ::GetVersionEx(&versInfo);
  113. ASSERT(bStat);
  114. return (versInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
  115. }
  116. /***************************************************************************\
  117. *
  118. * METHOD: PlatformSupports_REG_EXPAND_SZ_Values
  119. *
  120. * PURPOSE: checks current platform capabilities
  121. *
  122. * RETURNS:
  123. * bool - true if platform supports REG_EXPAND_SZ values in registry
  124. *
  125. \***************************************************************************/
  126. static bool PlatformSupports_REG_EXPAND_SZ_Values()
  127. {
  128. // Find out OS version.
  129. OSVERSIONINFO versInfo;
  130. versInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  131. BOOL bStat = ::GetVersionEx(&versInfo);
  132. ASSERT(bStat);
  133. // NT supports it...
  134. if (versInfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
  135. return true;
  136. // for 9x to support REG_EXPAND_SZ it should be Win98 at least
  137. // But even on winME OLE does not support REG_EXPAND_SZ (despite the OS does)
  138. // so we put the absolute path anyway
  139. return false;
  140. }
  141. };
  142. #endif // !defined(__MODULEPATH_H_INCLUDED__)