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.

381 lines
9.3 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: cua.cpp
  7. //
  8. // Contents: CCryptUrlArray implementation
  9. //
  10. // History: 16-Sep-97 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Member: CCryptUrlArray::CCryptUrlArray, public
  17. //
  18. // Synopsis: Constructor
  19. //
  20. //----------------------------------------------------------------------------
  21. CCryptUrlArray::CCryptUrlArray (ULONG cMinUrls, ULONG cGrowUrls, BOOL& rfResult)
  22. {
  23. rfResult = TRUE;
  24. m_cGrowUrls = cGrowUrls;
  25. m_cua.cUrl = 0;
  26. m_cua.rgwszUrl = new LPWSTR [cMinUrls];
  27. if ( m_cua.rgwszUrl != NULL )
  28. {
  29. memset( m_cua.rgwszUrl, 0, sizeof(LPWSTR)*cMinUrls );
  30. m_cArray = cMinUrls;
  31. }
  32. else
  33. {
  34. SetLastError( (DWORD) E_OUTOFMEMORY );
  35. rfResult = FALSE;
  36. }
  37. }
  38. //+---------------------------------------------------------------------------
  39. //
  40. // Member: CCryptUrlArray::CCryptUrlArray, public
  41. //
  42. // Synopsis: Constructor
  43. //
  44. //----------------------------------------------------------------------------
  45. CCryptUrlArray::CCryptUrlArray (PCRYPT_URL_ARRAY pcua, ULONG cGrowUrls)
  46. {
  47. m_cGrowUrls = cGrowUrls;
  48. m_cua.cUrl = pcua->cUrl;
  49. m_cua.rgwszUrl = pcua->rgwszUrl;
  50. m_cArray = pcua->cUrl;
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Member: CCryptUrlArray::AllocUrl, public, static
  55. //
  56. // Synopsis: allocate an URL using the same allocator used for ::AddUrl
  57. // copies. This means that the resulting URL can be added
  58. // without copying.
  59. //
  60. //----------------------------------------------------------------------------
  61. LPWSTR
  62. CCryptUrlArray::AllocUrl (ULONG cw)
  63. {
  64. return( (LPWSTR)CryptMemAlloc( cw * sizeof( WCHAR ) ) );
  65. }
  66. //+---------------------------------------------------------------------------
  67. //
  68. // Member: CCryptUrlArray::ReallocUrl, public, static
  69. //
  70. // Synopsis: see ::AllocUrl
  71. //
  72. //----------------------------------------------------------------------------
  73. LPWSTR
  74. CCryptUrlArray::ReallocUrl (LPWSTR pwszUrl, ULONG cw)
  75. {
  76. return( (LPWSTR)CryptMemRealloc( pwszUrl, cw * sizeof( WCHAR ) ) );
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // Member: CCryptUrlArray::FreeUrl, public, static
  81. //
  82. // Synopsis: free URL allocated using ::AllocBlob or ::ReallocBlob
  83. //
  84. //----------------------------------------------------------------------------
  85. VOID
  86. CCryptUrlArray::FreeUrl (LPWSTR pwszUrl)
  87. {
  88. CryptMemFree( pwszUrl );
  89. }
  90. //+---------------------------------------------------------------------------
  91. //
  92. // Member: CCryptUrlArray::AddUrl, public
  93. //
  94. // Synopsis: add an URL to the array
  95. //
  96. //----------------------------------------------------------------------------
  97. BOOL
  98. CCryptUrlArray::AddUrl (LPWSTR pwszUrl, BOOL fCopyUrl)
  99. {
  100. BOOL fResult = TRUE;
  101. LPWSTR pwszToUse;
  102. //
  103. // If we need to copy the URL, do so
  104. //
  105. if ( fCopyUrl == TRUE )
  106. {
  107. ULONG cw = wcslen( pwszUrl ) + 1;
  108. pwszToUse = AllocUrl( cw );
  109. if ( pwszToUse != NULL )
  110. {
  111. memcpy( pwszToUse, pwszUrl, cw * sizeof( WCHAR ) );
  112. }
  113. else
  114. {
  115. SetLastError( (DWORD) E_OUTOFMEMORY );
  116. return( FALSE );
  117. }
  118. }
  119. else
  120. {
  121. pwszToUse = pwszUrl;
  122. }
  123. //
  124. // If we need to grow the array, do so
  125. //
  126. if ( m_cArray == m_cua.cUrl )
  127. {
  128. fResult = GrowArray();
  129. }
  130. //
  131. // Add the URL to the array
  132. //
  133. if ( fResult == TRUE )
  134. {
  135. m_cua.rgwszUrl[m_cua.cUrl] = pwszToUse;
  136. m_cua.cUrl += 1;
  137. }
  138. else if ( fCopyUrl == TRUE )
  139. {
  140. FreeUrl( pwszToUse );
  141. }
  142. return( fResult );
  143. }
  144. //+---------------------------------------------------------------------------
  145. //
  146. // Member: CCryptUrlArray::GetUrl, public
  147. //
  148. // Synopsis: get an URL from the array
  149. //
  150. //----------------------------------------------------------------------------
  151. LPWSTR
  152. CCryptUrlArray::GetUrl (ULONG Index)
  153. {
  154. assert( m_cua.cUrl > Index );
  155. return( m_cua.rgwszUrl[Index] );
  156. }
  157. //+---------------------------------------------------------------------------
  158. //
  159. // Member: CCryptUrlArray::GetUrlCount, public
  160. //
  161. // Synopsis: get the count of URLs in the array
  162. //
  163. //----------------------------------------------------------------------------
  164. ULONG
  165. CCryptUrlArray::GetUrlCount ()
  166. {
  167. return( m_cua.cUrl );
  168. }
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Member: CCryptUrlArray::GetArrayInNativeForm, public
  172. //
  173. // Synopsis: get the array in native form
  174. //
  175. //----------------------------------------------------------------------------
  176. VOID
  177. CCryptUrlArray::GetArrayInNativeForm (PCRYPT_URL_ARRAY pcua)
  178. {
  179. pcua->cUrl = m_cua.cUrl;
  180. pcua->rgwszUrl = m_cua.rgwszUrl;
  181. }
  182. //+---------------------------------------------------------------------------
  183. //
  184. // Member: CCryptUrlArray::GetArrayInSingleBufferEncodedForm, public
  185. //
  186. // Synopsis: get the array encoded in a single buffer
  187. //
  188. //----------------------------------------------------------------------------
  189. BOOL
  190. CCryptUrlArray::GetArrayInSingleBufferEncodedForm (
  191. PCRYPT_URL_ARRAY* ppcua,
  192. ULONG* pcb
  193. )
  194. {
  195. ULONG cbStruct;
  196. ULONG cbPointers;
  197. ULONG cbData;
  198. ULONG cb;
  199. ULONG cbSize;
  200. ULONG cCount;
  201. PCRYPT_URL_ARRAY pcua = NULL;
  202. ULONG cbUrl;
  203. //
  204. // Calculate the buffer size we will need and allocate it
  205. //
  206. cbStruct = sizeof( CRYPT_URL_ARRAY );
  207. cbPointers = m_cua.cUrl * sizeof( LPWSTR );
  208. for ( cCount = 0, cbData = 0; cCount < m_cua.cUrl; cCount++ )
  209. {
  210. cbData += ( wcslen( m_cua.rgwszUrl[cCount] ) + 1 ) * sizeof( WCHAR );
  211. }
  212. cbSize = cbStruct + cbPointers + cbData;
  213. if ( ppcua == NULL )
  214. {
  215. if ( pcb != NULL )
  216. {
  217. *pcb = cbSize;
  218. return( TRUE );
  219. }
  220. SetLastError( (DWORD) E_INVALIDARG );
  221. return( FALSE );
  222. }
  223. if ( *ppcua == NULL )
  224. {
  225. pcua = (PCRYPT_URL_ARRAY)CryptMemAlloc( cbSize );
  226. if ( pcua == NULL )
  227. {
  228. SetLastError( (DWORD) E_OUTOFMEMORY );
  229. return( FALSE );
  230. }
  231. }
  232. else
  233. {
  234. if ( pcb == NULL )
  235. {
  236. SetLastError( (DWORD) E_INVALIDARG );
  237. return( FALSE );
  238. }
  239. else if ( *pcb < cbSize )
  240. {
  241. SetLastError( (DWORD) E_INVALIDARG );
  242. return( FALSE );
  243. }
  244. pcua = *ppcua;
  245. }
  246. //
  247. // Fill in the data
  248. //
  249. pcua->cUrl = m_cua.cUrl;
  250. pcua->rgwszUrl = (LPWSTR *)((LPBYTE)pcua+cbStruct);
  251. for ( cCount = 0, cb = 0; cCount < m_cua.cUrl; cCount++ )
  252. {
  253. pcua->rgwszUrl[cCount] = (LPWSTR)((LPBYTE)pcua+cbStruct+cbPointers+cb);
  254. cbUrl = ( wcslen( m_cua.rgwszUrl[cCount] ) + 1 ) * sizeof( WCHAR );
  255. memcpy( pcua->rgwszUrl[cCount], m_cua.rgwszUrl[cCount], cbUrl );
  256. cb += cbUrl;
  257. }
  258. if ( *ppcua != pcua )
  259. {
  260. *ppcua = pcua;
  261. if ( pcb != NULL )
  262. {
  263. *pcb = cbSize;
  264. }
  265. }
  266. return( TRUE );
  267. }
  268. //+---------------------------------------------------------------------------
  269. //
  270. // Member: CCryptUrlArray::FreeArray, public
  271. //
  272. // Synopsis: free the URL array
  273. //
  274. //----------------------------------------------------------------------------
  275. VOID
  276. CCryptUrlArray::FreeArray (BOOL fFreeUrls)
  277. {
  278. if ( fFreeUrls == TRUE )
  279. {
  280. ULONG cCount;
  281. for ( cCount = 0; cCount < m_cua.cUrl; cCount++ )
  282. {
  283. FreeUrl( m_cua.rgwszUrl[cCount] );
  284. }
  285. }
  286. delete m_cua.rgwszUrl;
  287. }
  288. //+---------------------------------------------------------------------------
  289. //
  290. // Member: CCryptUrlArray::GrowArray, private
  291. //
  292. // Synopsis: grow the URL array
  293. //
  294. //----------------------------------------------------------------------------
  295. BOOL
  296. CCryptUrlArray::GrowArray ()
  297. {
  298. ULONG cNewArray;
  299. LPWSTR* rgwsz;
  300. //
  301. // Check if we are allowed to grow
  302. //
  303. //
  304. if ( m_cGrowUrls == 0 )
  305. {
  306. SetLastError( (DWORD) E_INVALIDARG );
  307. return( FALSE );
  308. }
  309. //
  310. // Allocate and initialize the new array
  311. //
  312. cNewArray = m_cArray + m_cGrowUrls;
  313. rgwsz = new LPWSTR [cNewArray];
  314. if ( rgwsz == NULL )
  315. {
  316. SetLastError( (DWORD) E_OUTOFMEMORY );
  317. return( FALSE );
  318. }
  319. memset( rgwsz, 0, cNewArray * sizeof( LPWSTR ) );
  320. //
  321. // Copy the old to the new
  322. //
  323. memcpy( rgwsz, m_cua.rgwszUrl, m_cua.cUrl*sizeof( LPWSTR ) );
  324. //
  325. // Free the old and use the new
  326. //
  327. delete m_cua.rgwszUrl;
  328. m_cua.rgwszUrl = rgwsz;
  329. m_cArray = cNewArray;
  330. return( TRUE );
  331. }