Leaked source code of windows server 2003
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.3 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 = MAXDWORD;
  55. *pchBadEnd = MAXDWORD;
  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. URL_TYPE_FORMATS const *pFormatEntry = g_URLFormatTable;
  88. while (NULL != pFormatEntry->pwszFormat)
  89. {
  90. if (UrlType == pFormatEntry->UrlType)
  91. {
  92. return pFormatEntry;
  93. }
  94. ++pFormatEntry;
  95. }
  96. return NULL;
  97. }
  98. ENUM_URL_TYPE
  99. DetermineURLType(
  100. ENUM_URL_TYPE *pAllowedUrls,
  101. DWORD cAllowedUrls,
  102. WCHAR *pwszURL)
  103. {
  104. DWORD i;
  105. DWORD dwFlag;
  106. URL_TYPE_FORMATS const *pFormatEntry = NULL;
  107. for (i = 0; i < cAllowedUrls; ++i)
  108. {
  109. pFormatEntry = GetURLFormatTableEntry(pAllowedUrls[i]);
  110. if (NULL != pFormatEntry)
  111. {
  112. //compare if match format
  113. if (0 == _wcsnicmp(pwszURL, pFormatEntry->pwszFormat,
  114. wcslen(pFormatEntry->pwszFormat)))
  115. {
  116. //match, done
  117. return pAllowedUrls[i];
  118. }
  119. }
  120. }
  121. //got here, no format match, try local path
  122. if (myIsFullPath(pwszURL, &dwFlag))
  123. {
  124. //it is a valid path
  125. if (UNC_PATH == dwFlag)
  126. {
  127. return URL_TYPE_UNC;
  128. }
  129. else
  130. {
  131. CSASSERT(LOCAL_PATH == dwFlag);
  132. return URL_TYPE_LOCAL;
  133. }
  134. }
  135. return URL_TYPE_UNKNOWN;
  136. }
  137. typedef struct _URL_ENABLE_MASK
  138. {
  139. ENUM_URL_TYPE UrlType;
  140. DWORD dwEnableMask;
  141. } URL_ENABLE_MASK;
  142. URL_ENABLE_MASK g_UrlEnableMaskTable[] =
  143. {
  144. {URL_TYPE_HTTP, CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCERTOCSP},
  145. {URL_TYPE_FILE, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCERTOCSP|CSURL_SERVERPUBLISHDELTA},
  146. {URL_TYPE_LDAP, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCRLCDP|CSURL_ADDTOCERTOCSP|CSURL_SERVERPUBLISHDELTA},
  147. {URL_TYPE_FTP, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCERTOCSP|CSURL_SERVERPUBLISHDELTA},
  148. {URL_TYPE_LOCAL, CSURL_SERVERPUBLISH |CSURL_SERVERPUBLISHDELTA},
  149. {URL_TYPE_UNC, CSURL_SERVERPUBLISH|CSURL_ADDTOCERTCDP|CSURL_ADDTOFRESHESTCRL|CSURL_ADDTOCERTOCSP|CSURL_SERVERPUBLISHDELTA},
  150. };
  151. DWORD
  152. DetermineURLEnableMask(
  153. IN ENUM_URL_TYPE UrlType)
  154. {
  155. DWORD i;
  156. DWORD dwMask = 0x0;
  157. for (i = 0; i < ARRAYSIZE(g_UrlEnableMaskTable); ++i)
  158. {
  159. if (UrlType == g_UrlEnableMaskTable[i].UrlType)
  160. {
  161. dwMask = g_UrlEnableMaskTable[i].dwEnableMask;
  162. break;
  163. }
  164. }
  165. return dwMask;
  166. }
  167. HRESULT
  168. ExpandDisplayString(
  169. IN LPCWSTR szContractedString,
  170. OUT LPWSTR* ppszDisplayString)
  171. {
  172. HRESULT hr;
  173. DWORD dwChars;
  174. int i;
  175. LPCWSTR args[ARRAYSIZE(g_displayStrings)];
  176. for (i=0; i<ARRAYSIZE(g_displayStrings); i++)
  177. {
  178. args[i] = *g_displayStrings[i].pcstrExpansionString;
  179. }
  180. dwChars = FormatMessage(
  181. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_FROM_STRING,
  182. szContractedString,
  183. 0, //msgid
  184. 0, //langid
  185. (LPWSTR)ppszDisplayString,
  186. 1, // minimum chars to alloc
  187. (va_list *)args);
  188. if (dwChars == 0)
  189. {
  190. hr = GetLastError();
  191. hr = HRESULT_FROM_WIN32(hr);
  192. goto Ret;
  193. }
  194. hr = S_OK;
  195. Ret:
  196. return hr;
  197. }
  198. HRESULT
  199. ContractDisplayString(
  200. IN LPCWSTR szDisplayString,
  201. OUT LPWSTR* ppContractedString)
  202. {
  203. HRESULT hr;
  204. int i;
  205. *ppContractedString = (LPWSTR)LocalAlloc(LMEM_FIXED, (wcslen(szDisplayString)+1) * sizeof(WCHAR));
  206. if (*ppContractedString == NULL)
  207. {
  208. hr = E_OUTOFMEMORY;
  209. goto Ret;
  210. }
  211. wcscpy(*ppContractedString, szDisplayString);
  212. for (i=0; i<ARRAYSIZE(g_displayStrings); i++)
  213. {
  214. DWORD chContractedToken, chExpansionString;
  215. LPWSTR pszFound = wcsstr(*ppContractedString, *g_displayStrings[i].pcstrExpansionString);
  216. while(pszFound)
  217. {
  218. // calc commonly used values
  219. chContractedToken = wcslen(g_displayStrings[i].szContractedToken);
  220. chExpansionString = wcslen(*g_displayStrings[i].pcstrExpansionString);
  221. // replace with token
  222. CopyMemory(pszFound, g_displayStrings[i].szContractedToken, chContractedToken*sizeof(WCHAR));
  223. // slide rest of string left
  224. MoveMemory(
  225. &pszFound[chContractedToken], // destination
  226. &pszFound[chExpansionString], // source
  227. (wcslen(&pszFound[chExpansionString])+1) *sizeof(WCHAR) );
  228. // step Found over insertion
  229. pszFound += chContractedToken;
  230. // find any other ocurrences after this one
  231. pszFound = wcsstr(pszFound, *g_displayStrings[i].pcstrExpansionString);
  232. }
  233. }
  234. hr = S_OK;
  235. Ret:
  236. return hr;
  237. }