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.

310 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name :
  4. customerror.cxx
  5. Abstract:
  6. Custom Error goo
  7. Author:
  8. Bilal Alam (balam) 10-Mar-2000
  9. Environment:
  10. Win32 - User Mode
  11. Project:
  12. ULW3.DLL
  13. --*/
  14. #include "precomp.hxx"
  15. HRESULT
  16. CUSTOM_ERROR_TABLE::FindCustomError(
  17. USHORT StatusCode,
  18. USHORT SubError,
  19. BOOL * pfIsFile,
  20. STRU * pstrError
  21. )
  22. /*++
  23. Routine Description:
  24. Find the applicable custom error entry for a given status/subcode
  25. Arguments:
  26. StatusCode - Status code
  27. SubError - sub error
  28. pfIsFile - Set to TRUE if this is a file error
  29. pstrError - Error path (URL or file)
  30. Return Value:
  31. HRESULT
  32. --*/
  33. {
  34. LIST_ENTRY * pListEntry;
  35. CUSTOM_ERROR_ENTRY * pCustomEntry = NULL;
  36. BOOL fFound = FALSE;
  37. HRESULT hr = NO_ERROR;
  38. if ( pfIsFile == NULL ||
  39. pstrError == NULL )
  40. {
  41. DBG_ASSERT( FALSE );
  42. return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );
  43. }
  44. for ( pListEntry = _ErrorListHead.Flink;
  45. pListEntry != &_ErrorListHead;
  46. pListEntry = pListEntry->Flink )
  47. {
  48. pCustomEntry = CONTAINING_RECORD( pListEntry,
  49. CUSTOM_ERROR_ENTRY,
  50. _listEntry );
  51. DBG_ASSERT( pCustomEntry != NULL );
  52. if ( pCustomEntry->_StatusCode == StatusCode )
  53. {
  54. if ( pCustomEntry->_SubError == SubError ||
  55. pCustomEntry->_SubError == SUBERROR_WILDCARD )
  56. {
  57. fFound = TRUE;
  58. break;
  59. }
  60. }
  61. }
  62. if ( fFound )
  63. {
  64. hr = pstrError->Copy( pCustomEntry->_strError );
  65. if ( FAILED( hr ) )
  66. {
  67. return hr;
  68. }
  69. *pfIsFile = pCustomEntry->_fIsFile;
  70. return NO_ERROR;
  71. }
  72. else
  73. {
  74. return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
  75. }
  76. }
  77. HRESULT
  78. CUSTOM_ERROR_TABLE::BuildTable(
  79. WCHAR * pszErrorList
  80. )
  81. /*++
  82. Routine Description:
  83. Build custom error table from metabase
  84. Arguments:
  85. pszErrorList - Magic error MULTISZ
  86. Return Value:
  87. HRESULT
  88. --*/
  89. {
  90. WCHAR * pszType;
  91. WCHAR * pszSubError;
  92. WCHAR * pszPath;
  93. WCHAR * pszNewPath;
  94. WCHAR cTemp;
  95. USHORT StatusCode;
  96. USHORT SubError;
  97. BOOL fIsFile;
  98. CUSTOM_ERROR_ENTRY* pNewEntry;
  99. DWORD dwPathLength;
  100. HRESULT hr = NO_ERROR;
  101. for (;;)
  102. {
  103. //
  104. // Get the status code
  105. //
  106. StatusCode = (USHORT) _wtoi( pszErrorList );
  107. if ( StatusCode < 300 )
  108. {
  109. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  110. goto Finished;
  111. }
  112. //
  113. // Now convert the second parameter (the suberror) to a number.
  114. //
  115. pszSubError = wcschr( pszErrorList, L',' );
  116. if ( pszSubError == NULL )
  117. {
  118. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  119. goto Finished;
  120. }
  121. pszSubError++;
  122. while ( SAFEIsSpace( *pszSubError ) )
  123. {
  124. pszSubError++;
  125. }
  126. //
  127. // Either we have a specific sub error or a wildcard (any suberror)
  128. //
  129. if ( *pszSubError == L'*' )
  130. {
  131. SubError = SUBERROR_WILDCARD;
  132. }
  133. else
  134. {
  135. if ( !iswdigit( *pszSubError ) )
  136. {
  137. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  138. goto Finished;
  139. }
  140. SubError = (USHORT) _wtoi( pszSubError );
  141. }
  142. //
  143. // Now find the comma that seperates the number and the type.
  144. //
  145. pszType = wcschr( pszSubError, L',' );
  146. if ( pszType == NULL )
  147. {
  148. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  149. goto Finished;
  150. }
  151. pszType++;
  152. while ( SAFEIsSpace( *pszType ) )
  153. {
  154. pszType++;
  155. }
  156. // We found the end of ws. If this isn't an alphabetic character, it's
  157. // an error. If it is, find the end of the alpha. chars.
  158. if ( !iswalpha( *pszType ) )
  159. {
  160. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  161. goto Finished;
  162. }
  163. pszPath = pszType;
  164. while ( iswalpha( *pszPath ) )
  165. {
  166. pszPath++;
  167. }
  168. cTemp = *pszPath;
  169. *pszPath = L'\0';
  170. //
  171. // What type of custom error is this?
  172. //
  173. if ( !_wcsicmp( pszType, L"FILE" ) )
  174. {
  175. fIsFile = TRUE;
  176. }
  177. else
  178. {
  179. if (!_wcsicmp( pszType, L"URL" ) )
  180. {
  181. fIsFile = FALSE;
  182. }
  183. else
  184. {
  185. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  186. }
  187. }
  188. *pszPath = cTemp;
  189. if ( FAILED( hr ) )
  190. {
  191. goto Finished;
  192. }
  193. //
  194. // Now find the comma that seperates the type from the URL/path.
  195. //
  196. pszPath = wcschr( pszPath, L',' );
  197. if ( pszPath == NULL )
  198. {
  199. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  200. goto Finished;
  201. }
  202. pszPath++;
  203. while ( SAFEIsSpace( *pszPath ) )
  204. {
  205. pszPath++;
  206. }
  207. if ( *pszPath == '\0' )
  208. {
  209. hr = HRESULT_FROM_WIN32( ERROR_INVALID_DATA );
  210. goto Finished;
  211. }
  212. dwPathLength = wcslen( pszPath ) + 1;
  213. //
  214. // OK. Now we can allocate a table entry
  215. //
  216. pNewEntry = new CUSTOM_ERROR_ENTRY;
  217. if ( pNewEntry == NULL )
  218. {
  219. hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
  220. goto Finished;
  221. }
  222. pNewEntry->_StatusCode = StatusCode;
  223. pNewEntry->_SubError = SubError;
  224. pNewEntry->_fIsFile = fIsFile;
  225. hr = pNewEntry->_strError.Copy( pszPath );
  226. if ( FAILED( hr ) )
  227. {
  228. delete pNewEntry;
  229. return hr;
  230. }
  231. //
  232. // Give more specific errors higher priority in lookup
  233. //
  234. if ( SubError == SUBERROR_WILDCARD )
  235. {
  236. InsertTailList( &_ErrorListHead, &pNewEntry->_listEntry );
  237. }
  238. else
  239. {
  240. InsertHeadList( &_ErrorListHead, &pNewEntry->_listEntry );
  241. }
  242. pszErrorList = pszPath + dwPathLength;
  243. if ( *pszErrorList == L'\0' )
  244. {
  245. hr = NO_ERROR;
  246. break;
  247. }
  248. }
  249. Finished:
  250. return hr;
  251. }