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.

282 lines
7.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: urls.cpp
  8. //
  9. //--------------------------------------------------------------------------
  10. #include <stdafx.h>
  11. #include "urls.h"
  12. BOOL
  13. IsValidToken(
  14. IN WCHAR const *pwszToken,
  15. OUT DWORD *pdwTokenLen)
  16. {
  17. BOOL fRet = FALSE;
  18. DWORD i;
  19. DWORD len;
  20. CSASSERT(NULL != pwszToken &&
  21. L'%' == pwszToken[0] &&
  22. NULL != pdwTokenLen);
  23. //init
  24. *pdwTokenLen = 0;
  25. //find out how long the token is
  26. len = wcslen(pwszToken);
  27. *pdwTokenLen = 1; //skip % escape
  28. while (iswdigit(pwszToken[*pdwTokenLen]) && *pdwTokenLen < len)
  29. {
  30. ++(*pdwTokenLen);
  31. }
  32. for (i = 0; i < DISPLAYSTRINGS_TOKEN_COUNT; ++i)
  33. {
  34. if (*pdwTokenLen == wcslen(g_displayStrings[i].szContractedToken) &&
  35. 0 == wcsncmp(pwszToken,
  36. g_displayStrings[i].szContractedToken,
  37. *pdwTokenLen))
  38. {
  39. //found match
  40. fRet = TRUE;
  41. break;
  42. }
  43. }
  44. return fRet;
  45. }
  46. HRESULT ValidateTokens(
  47. IN WCHAR const *pwszURL,
  48. OUT DWORD* pchBadBegin,
  49. OUT DWORD* pchBadEnd)
  50. {
  51. HRESULT hr = S_OK;
  52. WCHAR const *pwszFound = pwszURL;
  53. DWORD dwTokenLen;
  54. *pchBadBegin = -1;
  55. *pchBadEnd = -1;
  56. // look for escape token open marker
  57. while(NULL != (pwszFound = wcschr(pwszFound, L'%')))
  58. {
  59. if (!IsValidToken(pwszFound, &dwTokenLen))
  60. {
  61. *pchBadBegin =
  62. SAFE_SUBTRACT_POINTERS(pwszFound, pwszURL) + 1; //skip %
  63. *pchBadEnd = *pchBadBegin + dwTokenLen - 1;
  64. hr = S_FALSE;
  65. break;
  66. }
  67. pwszFound += dwTokenLen;
  68. }
  69. return hr;
  70. }
  71. typedef struct _URL_TYPE_FORMATS
  72. {
  73. ENUM_URL_TYPE UrlType;
  74. WCHAR const *pwszFormat;
  75. } URL_TYPE_FORMATS;
  76. URL_TYPE_FORMATS const g_URLFormatTable[] =
  77. {
  78. { URL_TYPE_HTTP, L"http:"},
  79. { URL_TYPE_FILE, L"file:"},
  80. { URL_TYPE_LDAP, L"ldap:"},
  81. { URL_TYPE_FTP, L"ftp:"},
  82. { URL_TYPE_UNKNOWN, NULL},
  83. };
  84. URL_TYPE_FORMATS const *GetURLFormatTableEntry(
  85. ENUM_URL_TYPE UrlType)
  86. {
  87. DWORD i;
  88. URL_TYPE_FORMATS const *pFormatEntry = g_URLFormatTable;
  89. while (NULL != pFormatEntry->pwszFormat)
  90. {
  91. if (UrlType == pFormatEntry->UrlType)
  92. {
  93. return pFormatEntry;
  94. }
  95. ++pFormatEntry;
  96. }
  97. return NULL;
  98. }
  99. ENUM_URL_TYPE
  100. DetermineURLType(
  101. ENUM_URL_TYPE *pAllowedUrls,
  102. DWORD cAllowedUrls,
  103. WCHAR *pwszURL)
  104. {
  105. DWORD i;
  106. DWORD dwFlag;
  107. URL_TYPE_FORMATS const *pFormatEntry = NULL;
  108. for (i = 0; i < cAllowedUrls; ++i)
  109. {
  110. pFormatEntry = GetURLFormatTableEntry(pAllowedUrls[i]);
  111. if (NULL != pFormatEntry)
  112. {
  113. //compare if match format
  114. if (0 == _wcsnicmp(pwszURL, pFormatEntry->pwszFormat,
  115. wcslen(pFormatEntry->pwszFormat)))
  116. {
  117. //match, done
  118. return pAllowedUrls[i];
  119. }
  120. }
  121. }
  122. //got here, no format match, try local path
  123. if (myIsFullPath(pwszURL, &dwFlag))
  124. {
  125. //it is a valid path
  126. if (UNC_PATH == dwFlag)
  127. {
  128. return URL_TYPE_UNC;
  129. }
  130. else
  131. {
  132. CSASSERT(LOCAL_PATH == dwFlag);
  133. return URL_TYPE_LOCAL;
  134. }
  135. }
  136. return URL_TYPE_UNKNOWN;
  137. }
  138. typedef struct _URL_ENABLE_MASK
  139. {
  140. ENUM_URL_TYPE UrlType;
  141. DWORD dwEnableMask;
  142. } URL_ENABLE_MASK;
  143. URL_ENABLE_MASK g_UrlEnableMaskTable[] =
  144. {
  145. {URL_TYPE_HTTP, CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCRLCDP|CSURL_ADDTOCERTOCSP},
  146. {URL_TYPE_FILE, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCRLCDP|CSURL_ADDTOCERTOCSP},
  147. {URL_TYPE_LDAP, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCRLCDP|CSURL_ADDTOCERTOCSP},
  148. {URL_TYPE_FTP, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCRLCDP|CSURL_ADDTOCERTOCSP},
  149. {URL_TYPE_LOCAL, CSURL_SERVERPUBLISH },
  150. {URL_TYPE_UNC, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCRLCDP|CSURL_ADDTOCERTOCSP},
  151. };
  152. DWORD
  153. DetermineURLEnableMask(
  154. IN ENUM_URL_TYPE UrlType)
  155. {
  156. DWORD i;
  157. DWORD dwMask = 0x0;
  158. for (i = 0; i < ARRAYSIZE(g_UrlEnableMaskTable); ++i)
  159. {
  160. if (UrlType == g_UrlEnableMaskTable[i].UrlType)
  161. {
  162. dwMask = g_UrlEnableMaskTable[i].dwEnableMask;
  163. break;
  164. }
  165. }
  166. return dwMask;
  167. }
  168. HRESULT
  169. ExpandDisplayString(
  170. IN LPCWSTR szContractedString,
  171. OUT LPWSTR* ppszDisplayString)
  172. {
  173. HRESULT hr;
  174. DWORD dwChars;
  175. int i, iescapedStrings;
  176. LPCWSTR args[ARRAYSIZE(g_displayStrings)];
  177. for (i=0; i<ARRAYSIZE(g_displayStrings); i++)
  178. {
  179. args[i] = *g_displayStrings[i].pcstrExpansionString;
  180. }
  181. dwChars = FormatMessage(
  182. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING,
  183. szContractedString,
  184. 0, //msgid
  185. 0, //langid
  186. (LPWSTR)ppszDisplayString,
  187. 1, // minimum chars to alloc
  188. (va_list *)args);
  189. if (dwChars == 0)
  190. {
  191. hr = GetLastError();
  192. hr = HRESULT_FROM_WIN32(hr);
  193. goto Ret;
  194. }
  195. hr = S_OK;
  196. Ret:
  197. return hr;
  198. }
  199. HRESULT
  200. ContractDisplayString(
  201. IN LPCWSTR szDisplayString,
  202. OUT LPWSTR* ppContractedString)
  203. {
  204. HRESULT hr;
  205. int i;
  206. *ppContractedString = (LPWSTR)LocalAlloc(LMEM_FIXED, (wcslen(szDisplayString)+1) * sizeof(WCHAR));
  207. if (*ppContractedString == NULL)
  208. {
  209. hr = E_OUTOFMEMORY;
  210. goto Ret;
  211. }
  212. wcscpy(*ppContractedString, szDisplayString);
  213. for (i=0; i<ARRAYSIZE(g_displayStrings); i++)
  214. {
  215. DWORD chContractedToken, chExpansionString;
  216. LPWSTR pszFound = wcsstr(*ppContractedString, *g_displayStrings[i].pcstrExpansionString);
  217. while(pszFound)
  218. {
  219. // calc commonly used values
  220. chContractedToken = wcslen(g_displayStrings[i].szContractedToken);
  221. chExpansionString = wcslen(*g_displayStrings[i].pcstrExpansionString);
  222. // replace with token
  223. CopyMemory(pszFound, g_displayStrings[i].szContractedToken, chContractedToken*sizeof(WCHAR));
  224. // slide rest of string left
  225. MoveMemory(
  226. &pszFound[chContractedToken], // destination
  227. &pszFound[chExpansionString], // source
  228. (wcslen(&pszFound[chExpansionString])+1) *sizeof(WCHAR) );
  229. // step Found over insertion
  230. pszFound += chContractedToken;
  231. // find any other ocurrences after this one
  232. pszFound = wcsstr(pszFound, *g_displayStrings[i].pcstrExpansionString);
  233. }
  234. }
  235. hr = S_OK;
  236. Ret:
  237. return hr;
  238. }