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.

340 lines
8.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: authdata.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes: CAuthData, CAuthDataArray
  11. //
  12. // Functions: CAuthDataArray::Create (static function)
  13. //
  14. // History: 30-Sep-93 WadeR Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <secpch2.hxx>
  18. #pragma hdrstop
  19. #include <authdata.hxx>
  20. #define PAGE_SIZE 0x1000
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Member: CAuthDataList::Add
  24. //
  25. // Synopsis: Adds a new element to the list
  26. //
  27. // Effects:
  28. //
  29. // Arguments: [adtType] -- Type of new elemebt
  30. // [pbSrc] -- data for new element
  31. // [cbSrc] -- size of new element
  32. //
  33. // Returns: 0 or size required to do this.
  34. //
  35. // History: 30-Sep-93 WadeR Created
  36. //
  37. // Notes: If pbSrc is NULL, it only allocates space and doesn't copy.
  38. //
  39. //----------------------------------------------------------------------------
  40. CAuthData*
  41. CAuthDataList::Add( const AuthDataType adtType,
  42. const BYTE * pbSrc,
  43. ULONG cbSrc )
  44. {
  45. ULONG cbRequired = SizeOfAuthData( cbSrc );
  46. ULONG cbAvail = _cbSize - _cbUsed;
  47. if (cbRequired > cbAvail)
  48. {
  49. return(NULL);
  50. }
  51. CAuthData* padNewElement = (CAuthData*) ((PBYTE) this + _cbUsed );
  52. padNewElement->adtDataType = adtType;
  53. padNewElement->cbData = cbSrc;
  54. if (pbSrc)
  55. RtlCopyMemory( padNewElement->abData, pbSrc, cbSrc );
  56. _cbUsed += cbRequired;
  57. return(padNewElement);
  58. };
  59. //+---------------------------------------------------------------------------
  60. //
  61. // Member: CAuthDataList::Add
  62. //
  63. // Synopsis: Adds the contents of a CAuthDataList to this CAuthDataList
  64. //
  65. // Effects:
  66. //
  67. // Arguments: [cadlList] -- List to add from.
  68. //
  69. // Requires: this list be large enough.
  70. //
  71. // Returns: TRUE if there's room, FALSE otherwise.
  72. //
  73. // Signals: none
  74. //
  75. // History: 01-Apr-94 wader Created
  76. //
  77. // Notes:
  78. //
  79. //----------------------------------------------------------------------------
  80. BOOLEAN
  81. CAuthDataList::Add( const CAuthDataList& cadlList )
  82. {
  83. // Don't need to copy the new header. If CAuthDataList's header
  84. // changes, this must change as well.
  85. DsysAssert( 2*sizeof( ULONG ) == (PBYTE) &cadlList._adData[0] - (PBYTE) &cadlList );
  86. ULONG cbRequired = cadlList._cbUsed - 2 * sizeof( ULONG );
  87. ULONG cbAvail = _cbSize - _cbUsed;
  88. if (cbRequired > cbAvail)
  89. {
  90. return(FALSE);
  91. }
  92. PBYTE pbEnd = ((PBYTE)this) + _cbUsed;
  93. RtlCopyMemory( pbEnd, &cadlList._adData[0], cbRequired );
  94. _cbUsed += cbRequired;
  95. return(TRUE);
  96. }
  97. //+---------------------------------------------------------------------------
  98. //
  99. // Member: CAuthDataList::Create
  100. //
  101. // Synopsis: Creates a new CAuthDataList
  102. //
  103. // Effects: may allocate memory
  104. //
  105. // Arguments: [cbList] -- Size of the list to create (see SizeOfAuthDataList)
  106. // [pbStorage] -- (optional) memory to create it in.
  107. //
  108. // Returns: pointer to newly created list, or NULL if no memory
  109. //
  110. // History: 01-Apr-94 wader Created
  111. //
  112. // Notes: If pnStorage is non-NULL, it builds the list in pbStorage and
  113. // returns pbStorage. If it's null, it allocates space with NEW
  114. // and builds the list there.
  115. //
  116. //----------------------------------------------------------------------------
  117. CAuthDataList *
  118. CAuthDataList::Create( ULONG cbList, PBYTE pbStorage )
  119. {
  120. DsysAssert( cbList >= SizeOfAuthDataList( SizeOfAuthData( 1 )) );
  121. if (pbStorage == NULL)
  122. pbStorage = new BYTE [ cbList ];
  123. CAuthDataList *padlNewList = (CAuthDataList*)pbStorage;
  124. padlNewList->_cbSize = cbList;
  125. padlNewList->_cbUsed = SizeOfAuthDataList(0);
  126. return(padlNewList);
  127. }
  128. //+---------------------------------------------------------------------------
  129. //
  130. // Member: CAuthDataList::FindFirst
  131. //
  132. // Synopsis: Finds the first CAuthData in the CAuthDataList
  133. //
  134. // Arguments: [adtType] -- Type of CAuthData to find.
  135. //
  136. // Returns: pointer to CAuthData, or NULL
  137. //
  138. // History: 01-Apr-94 wader Created
  139. //
  140. // Notes: See header for CAuthDataList for usage.
  141. //
  142. //----------------------------------------------------------------------------
  143. PAuthData
  144. CAuthDataList::FindFirst( AuthDataType adtType ) const
  145. {
  146. //
  147. // Don't need to check that the list contains anything, because
  148. // if the list is empty, padTemp == padTheEnd, and the loop is skipped.
  149. //
  150. const CAuthData *const padTheEnd = (CAuthData *)((PBYTE) this + _cbUsed);
  151. const CAuthData * padTemp = &_adData[0];
  152. if (adtType != Any)
  153. {
  154. while ( (padTemp < padTheEnd ) && (padTemp->adtDataType != adtType) )
  155. {
  156. padTemp = (CAuthData*) ( ((PBYTE) padTemp) +
  157. SizeOfAuthData(padTemp->cbData) );
  158. }
  159. }
  160. if ( padTemp == padTheEnd )
  161. {
  162. return(NULL);
  163. }
  164. else
  165. {
  166. return((PAuthData)padTemp);
  167. }
  168. }
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Member: CAuthDataList::FindNext
  172. //
  173. // Synopsis: Finds the next CAuthData in the CAuthDataList
  174. //
  175. // Effects:
  176. //
  177. // Arguments: [padCurrent] -- Starting CAuthData to search from
  178. // [adtType] -- type to look for
  179. //
  180. // Returns: pointer to CAuthData, or NULL
  181. //
  182. // History: 01-Apr-94 wader Created
  183. //
  184. // Notes: See header for CAuthDataList for usage.
  185. //
  186. //----------------------------------------------------------------------------
  187. PAuthData
  188. CAuthDataList::FindNext( PAuthData padCurrent, AuthDataType adtType ) const
  189. {
  190. //
  191. // Don't need to check that the list contains anything, because
  192. // if the list is empty, padTemp == padTheEnd, and the loop is skipped.
  193. //
  194. const CAuthData *const padTheEnd = (CAuthData *)((PBYTE) this + _cbUsed);
  195. const CAuthData * padTemp = padCurrent;
  196. DsysAssert( padCurrent >= &_adData[0] && padCurrent < padTheEnd );
  197. if (adtType == Any)
  198. {
  199. padTemp = (CAuthData*) ( ((PBYTE) padTemp) +
  200. SizeOfAuthData(padTemp->cbData) );
  201. }
  202. else
  203. {
  204. do
  205. {
  206. padTemp = (CAuthData*) ( ((PBYTE) padTemp) +
  207. SizeOfAuthData(padTemp->cbData) );
  208. } while ( (padTemp < padTheEnd ) && (padTemp->adtDataType != adtType) );
  209. }
  210. if ( padTemp == padTheEnd )
  211. {
  212. return(NULL);
  213. }
  214. else
  215. {
  216. return((PAuthData)padTemp);
  217. }
  218. }
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Member: CAuthDataList::IsValid
  222. //
  223. // Synopsis: Checks to see if this is a valid CAuthDataList.
  224. //
  225. // Effects: none.
  226. //
  227. // Arguments: (none)
  228. //
  229. // Returns: TRUE iff this is valid.
  230. //
  231. // History: 17-May-94 wader Created
  232. //
  233. // Notes: IsBadReadPtr
  234. //
  235. //----------------------------------------------------------------------------
  236. BOOLEAN
  237. CAuthDataList::IsValid() const
  238. {
  239. BOOLEAN fResult = TRUE;
  240. __try
  241. {
  242. const BYTE * p;
  243. //
  244. // Does the size make sense?
  245. //
  246. if (_cbUsed > _cbSize)
  247. {
  248. fResult = FALSE;
  249. }
  250. //
  251. // Probe the end of the data
  252. //
  253. p = ((PBYTE)this) + _cbSize;
  254. (volatile) *p;
  255. //
  256. // Check each entry
  257. //
  258. const CAuthData * const padTheEnd = (CAuthData *)((PBYTE) this + _cbUsed);
  259. const CAuthData * padTemp = &_adData[0];
  260. while ( (padTemp < padTheEnd ) && fResult == TRUE )
  261. {
  262. //
  263. // In the extremely unlikely event that an AuthData spans several
  264. // pages, and some of the pages are missing in the middle, we'll
  265. // probe the middle of it.
  266. //
  267. if (padTemp->cbData > PAGE_SIZE )
  268. {
  269. for (p = padTemp->abData;
  270. p < &padTemp->abData[padTemp->cbData];
  271. p += PAGE_SIZE)
  272. {
  273. (volatile ULONG) *(PULONG) (p);
  274. }
  275. }
  276. padTemp = (CAuthData*) ( ((PBYTE) padTemp) +
  277. SizeOfAuthData(padTemp->cbData) );
  278. }
  279. if (padTemp != padTheEnd)
  280. {
  281. fResult = FALSE;
  282. }
  283. }
  284. __except ( EXCEPTION_EXECUTE_HANDLER )
  285. {
  286. fResult = FALSE;
  287. }
  288. return(fResult);
  289. }