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.

237 lines
6.2 KiB

  1. //
  2. // native.cpp in shell\lib
  3. //
  4. // common Utility functions that need to be compiled for
  5. // both UNICODE and ANSI
  6. //
  7. #include "stock.h"
  8. #pragma hdrstop
  9. #include <vdate.h>
  10. #include "shellp.h"
  11. #include <regstr.h>
  12. // get the name and flags of an absolute IDlist
  13. // in:
  14. // dwFlags SHGDN_ flags as hints to the name space GetDisplayNameOf() function
  15. //
  16. // in/out:
  17. // *pdwAttribs (optional) return flags
  18. STDAPI SHGetNameAndFlags(LPCITEMIDLIST pidl, DWORD dwFlags, LPTSTR pszName, UINT cchName, DWORD *pdwAttribs)
  19. {
  20. if (pszName)
  21. {
  22. VDATEINPUTBUF(pszName, TCHAR, cchName);
  23. *pszName = 0;
  24. }
  25. HRESULT hrInit = SHCoInitialize();
  26. IShellFolder *psf;
  27. LPCITEMIDLIST pidlLast;
  28. HRESULT hr = SHBindToIDListParent(pidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast);
  29. if (SUCCEEDED(hr))
  30. {
  31. if (pszName)
  32. hr = DisplayNameOf(psf, pidlLast, dwFlags, pszName, cchName);
  33. if (SUCCEEDED(hr) && pdwAttribs)
  34. {
  35. RIP(*pdwAttribs); // this is an in-out param
  36. *pdwAttribs = SHGetAttributes(psf, pidlLast, *pdwAttribs);
  37. }
  38. psf->Release();
  39. }
  40. SHCoUninitialize(hrInit);
  41. return hr;
  42. }
  43. STDAPI_(DWORD) GetUrlScheme(LPCTSTR pszUrl)
  44. {
  45. if (pszUrl)
  46. {
  47. PARSEDURL pu;
  48. pu.cbSize = sizeof(pu);
  49. if (SUCCEEDED(ParseURL(pszUrl, &pu)))
  50. return pu.nScheme;
  51. }
  52. return URL_SCHEME_INVALID;
  53. }
  54. //
  55. // returns
  56. //
  57. // TRUE if the key is present and nonzero.
  58. // FALSE if the key is present and zero.
  59. // -1 if the key is not present.
  60. //
  61. BOOL GetExplorerUserSetting(HKEY hkeyRoot, LPCTSTR pszSubKey, LPCTSTR pszValue)
  62. {
  63. TCHAR szPath[MAX_PATH];
  64. TCHAR szPathExplorer[MAX_PATH];
  65. DWORD cbSize = ARRAYSIZE(szPath);
  66. DWORD dwType;
  67. PathCombine(szPathExplorer, REGSTR_PATH_EXPLORER, pszSubKey);
  68. if (ERROR_SUCCESS == SHGetValue(hkeyRoot, szPathExplorer, pszValue,
  69. &dwType, szPath, &cbSize))
  70. {
  71. // Zero in the DWORD case or NULL in the string case
  72. // indicates that this item is not available.
  73. if (dwType == REG_DWORD)
  74. return *((DWORD*)szPath) != 0;
  75. else
  76. return (TCHAR)szPath[0] != 0;
  77. }
  78. return -1;
  79. }
  80. //
  81. // This function allows a feature to be controlled by both a user setting
  82. // or a policy restriction. The policy restriction is first checked.
  83. //
  84. // If the value is 1, then the action is restricted.
  85. // If the value is 2, then the action is allowed.
  86. // If the value is absent or 0, then we look at the user setting.
  87. //
  88. // If the user setting is present, then ROUS_KEYALLOWS and ROUS_KEYRESTRICTS
  89. // controls the return value. ROUS_KEYALLOWS means that a nonzero user
  90. // setting allows the action. ROUS_KEYRESTRICTS means that a nonzero user
  91. // setting restricts the action.
  92. //
  93. // If the user setting is absent, then ROUS_DEFAULTALLOW and
  94. // ROUS_DESFAULTRESTRICT controls the default return value.
  95. //
  96. STDAPI_(BOOL) IsRestrictedOrUserSetting(HKEY hkeyRoot, RESTRICTIONS rest, LPCTSTR pszSubKey, LPCTSTR pszValue, UINT flags)
  97. {
  98. // See if the system policy restriction trumps
  99. DWORD dwRest = SHRestricted(rest);
  100. if (dwRest == 1)
  101. return TRUE;
  102. if (dwRest == 2)
  103. return FALSE;
  104. //
  105. // Restriction not in place or defers to user setting.
  106. //
  107. BOOL fValidKey = GetExplorerUserSetting(hkeyRoot, pszSubKey, pszValue);
  108. switch (fValidKey)
  109. {
  110. case 0: // Key is present and zero
  111. if (flags & ROUS_KEYRESTRICTS)
  112. return FALSE; // restriction not present
  113. else
  114. return TRUE; // ROUS_KEYALLOWS, value is 0 -> restricted
  115. case 1: // Key is present and nonzero
  116. if (flags & ROUS_KEYRESTRICTS)
  117. return TRUE; // restriction present -> restricted
  118. else
  119. return FALSE; // ROUS_KEYALLOWS, value is 1 -> not restricted
  120. default:
  121. ASSERT(0); // _GetExplorerUserSetting returns exactly 0, 1 or -1.
  122. // Fall through
  123. case -1: // Key is not present
  124. return (flags & ROUS_DEFAULTRESTRICT);
  125. }
  126. /*NOTREACHED*/
  127. }
  128. //
  129. // Repair font attributes that don't work on certain languages.
  130. //
  131. STDAPI_(void) SHAdjustLOGFONT(IN OUT LOGFONT *plf)
  132. {
  133. ASSERT(plf);
  134. //
  135. // FE fonts don't look good in bold since the glyphs are intricate
  136. // and converting them to bold turns them into a black blob.
  137. //
  138. if (plf->lfCharSet == SHIFTJIS_CHARSET||
  139. plf->lfCharSet == HANGEUL_CHARSET ||
  140. plf->lfCharSet == GB2312_CHARSET ||
  141. plf->lfCharSet == CHINESEBIG5_CHARSET)
  142. {
  143. if (plf->lfWeight > FW_NORMAL)
  144. plf->lfWeight = FW_NORMAL;
  145. }
  146. }
  147. //
  148. // Some of our registry keys were used prior to MUI, so for compat
  149. // reasons, apps have to put non-MUI strings there; otherwise,
  150. // downlevel clients will display at-signs which is kinda ugly.
  151. //
  152. // So the solution for these keys is to store the non-MUI string
  153. // in the legacy location, but put the MUI version in the
  154. // "LocalizedString" value.
  155. //
  156. STDAPI SHLoadLegacyRegUIString(HKEY hk, LPCTSTR pszSubkey, LPTSTR pszOutBuf, UINT cchOutBuf)
  157. {
  158. HKEY hkClose = NULL;
  159. ASSERT(cchOutBuf);
  160. pszOutBuf[0] = TEXT('\0');
  161. if (pszSubkey && *pszSubkey)
  162. {
  163. DWORD dwError = RegOpenKeyEx(hk, pszSubkey, 0, KEY_QUERY_VALUE, &hkClose);
  164. if (dwError != ERROR_SUCCESS)
  165. {
  166. return HRESULT_FROM_WIN32(dwError);
  167. }
  168. hk = hkClose;
  169. }
  170. HRESULT hr = SHLoadRegUIString(hk, TEXT("LocalizedString"), pszOutBuf, cchOutBuf);
  171. if (FAILED(hr) || pszOutBuf[0] == TEXT('\0'))
  172. {
  173. hr = SHLoadRegUIString(hk, TEXT(""), pszOutBuf, cchOutBuf);
  174. }
  175. if (hkClose)
  176. {
  177. RegCloseKey(hkClose);
  178. }
  179. return hr;
  180. }
  181. STDAPI_(TCHAR) SHFindMnemonic(LPCTSTR psz)
  182. {
  183. ASSERT(psz);
  184. TCHAR tchDefault = *psz; // Default is first character
  185. LPCTSTR pszAmp;
  186. while ((pszAmp = StrChr(psz, TEXT('&'))) != NULL)
  187. {
  188. switch (pszAmp[1])
  189. {
  190. case TEXT('&'): // Skip over &&
  191. psz = pszAmp + 2;
  192. continue;
  193. case TEXT('\0'): // Ignore trailing ampersand
  194. return tchDefault;
  195. default:
  196. return pszAmp[1];
  197. }
  198. }
  199. return tchDefault;
  200. }