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.

646 lines
14 KiB

  1. //-------------------------------------------------------------
  2. inline void *
  3. AdvanceBuffer(
  4. void * Buffer,
  5. size_t Bytes
  6. )
  7. /*
  8. Adds a given number of bytes to a pointer, returning the result.
  9. The original pointer is not changed.
  10. */
  11. {
  12. char * buf = reinterpret_cast<char *>( Buffer );
  13. return (buf + Bytes);
  14. }
  15. inline void
  16. ScrubBuffer(
  17. void * Buffer,
  18. size_t Length
  19. )
  20. {
  21. MySecureZeroMemory( Buffer, Length );
  22. }
  23. inline void
  24. ScrubStringW(
  25. LPWSTR String
  26. )
  27. {
  28. if (String == 0)
  29. {
  30. return;
  31. }
  32. //
  33. // The volatile attribute ensures that the loop cannot be optimized away.
  34. //
  35. volatile wchar_t * p = String;
  36. while (*p != 0)
  37. {
  38. *p = 0;
  39. ++p;
  40. }
  41. }
  42. inline void
  43. ScrubBasicCredentials(
  44. BG_BASIC_CREDENTIALS & cred
  45. )
  46. {
  47. ScrubStringW( cred.UserName );
  48. ScrubStringW( cred.Password );
  49. }
  50. inline void
  51. ScrubCredentials(
  52. BG_AUTH_CREDENTIALS & val
  53. )
  54. {
  55. switch (val.Scheme)
  56. {
  57. case BG_AUTH_SCHEME_BASIC:
  58. case BG_AUTH_SCHEME_DIGEST:
  59. case BG_AUTH_SCHEME_NTLM:
  60. case BG_AUTH_SCHEME_NEGOTIATE:
  61. case BG_AUTH_SCHEME_PASSPORT:
  62. ScrubBasicCredentials( val.Credentials.Basic );
  63. break;
  64. default:
  65. ASSERT( 0 && "unknown auth scheme" );
  66. THROW_HRESULT( E_FAIL );
  67. }
  68. }
  69. class CMarshalCursor
  70. {
  71. public:
  72. CMarshalCursor( void * Buffer, size_t Length )
  73. {
  74. m_BufferStart = Buffer;
  75. m_BufferCurrent = Buffer;
  76. m_Length = Length;
  77. }
  78. void * GetBufferStart()
  79. {
  80. return m_BufferStart;
  81. }
  82. void * GetBufferCurrent()
  83. {
  84. return m_BufferCurrent;
  85. }
  86. void * Advance( size_t Length )
  87. {
  88. if (GetLengthRemaining() < Length)
  89. {
  90. THROW_HRESULT( E_INVALIDARG );
  91. }
  92. m_BufferCurrent = AdvanceBuffer( m_BufferCurrent, Length );
  93. }
  94. size_t GetLengthUsed()
  95. {
  96. char * b1 = reinterpret_cast<char *>( m_BufferStart );
  97. char * b2 = reinterpret_cast<char *>( m_BufferCurrent );
  98. return (b2-b1);
  99. }
  100. size_t GetLengthRemaining()
  101. {
  102. return m_Length - GetLengthUsed();
  103. }
  104. CMarshalCursor GetSubCursor()
  105. {
  106. CMarshalCursor SubCursor( m_BufferCurrent, GetLengthRemaining() );
  107. return SubCursor;
  108. }
  109. void CommitSubCursor( CMarshalCursor & SubCursor )
  110. {
  111. if (SubCursor.m_BufferStart < m_BufferStart ||
  112. SubCursor.m_BufferCurrent > AdvanceBuffer( m_BufferStart, m_Length ))
  113. {
  114. THROW_HRESULT( E_INVALIDARG );
  115. }
  116. m_BufferCurrent = SubCursor.m_BufferCurrent;
  117. }
  118. void Rewind()
  119. {
  120. m_BufferCurrent = m_BufferStart;
  121. }
  122. void Scrub()
  123. {
  124. ScrubBuffer( m_BufferStart, GetLengthUsed() );
  125. }
  126. void ScrubUnusedSpace()
  127. {
  128. ScrubBuffer( m_BufferCurrent, GetLengthRemaining() );
  129. }
  130. inline void Read( void * Buffer, size_t Length );
  131. inline void Write( const void * Buffer, size_t Length );
  132. private:
  133. void * m_BufferStart;
  134. void * m_BufferCurrent;
  135. size_t m_Length;
  136. };
  137. void CMarshalCursor::Write( const void * Buffer, size_t Length )
  138. {
  139. if (GetLengthRemaining() < Length)
  140. {
  141. THROW_HRESULT( E_INVALIDARG );
  142. }
  143. memcpy( m_BufferCurrent, Buffer, Length );
  144. m_BufferCurrent = AdvanceBuffer( m_BufferCurrent, Length );
  145. }
  146. void CMarshalCursor::Read( void * Buffer, size_t Length )
  147. {
  148. if (GetLengthRemaining() < Length)
  149. {
  150. THROW_HRESULT( E_INVALIDARG );
  151. }
  152. memcpy( Buffer, m_BufferCurrent, Length );
  153. m_BufferCurrent = AdvanceBuffer( m_BufferCurrent, Length );
  154. }
  155. class CBufferMarshaller
  156. {
  157. public:
  158. CBufferMarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  159. {
  160. }
  161. CBufferMarshaller( CMarshalCursor & Cursor, const void * Buffer, size_t Length ) : m_Cursor( Cursor )
  162. {
  163. Marshal( Buffer, Length );
  164. }
  165. void Marshal( const void * Buffer, size_t Length )
  166. {
  167. m_Cursor.Write( Buffer, Length );
  168. }
  169. protected:
  170. CMarshalCursor & m_Cursor;
  171. };
  172. class CBufferUnmarshaller
  173. {
  174. public:
  175. CBufferUnmarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  176. {
  177. }
  178. CBufferUnmarshaller( CMarshalCursor & Cursor, void * Buffer, size_t Length ) : m_Cursor( Cursor )
  179. {
  180. Unmarshal( Buffer, Length );
  181. }
  182. void Unmarshal( void * Buffer, size_t Length )
  183. {
  184. m_Cursor.Read( Buffer, Length );
  185. }
  186. protected:
  187. CMarshalCursor & m_Cursor;
  188. };
  189. template<class T> class CBasicMarshaller
  190. {
  191. public:
  192. CBasicMarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  193. {
  194. }
  195. CBasicMarshaller( CMarshalCursor & Cursor, const T & val ) : m_Cursor( Cursor )
  196. {
  197. Marshal( val );
  198. }
  199. static size_t Size( const T & val )
  200. {
  201. return sizeof(T);
  202. }
  203. virtual void Marshal( const T & val )
  204. {
  205. m_Cursor.Write( &val, sizeof(T));
  206. }
  207. protected:
  208. CMarshalCursor & m_Cursor;
  209. };
  210. template<class T> class CBasicUnmarshaller
  211. {
  212. public:
  213. CBasicUnmarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  214. {
  215. }
  216. CBasicUnmarshaller( CMarshalCursor & Cursor, T & val ) : m_Cursor( Cursor )
  217. {
  218. Unmarshal( val );
  219. }
  220. void Unmarshal( T & val )
  221. {
  222. m_Cursor.Read( &val, sizeof(T));
  223. }
  224. protected:
  225. CMarshalCursor & m_Cursor;
  226. };
  227. typedef CBasicMarshaller<DWORD> CDwordMarshaller;
  228. typedef CBasicMarshaller<BG_AUTH_SCHEME> CSchemeMarshaller;
  229. typedef CBasicMarshaller<BG_AUTH_TARGET> CTargetMarshaller;
  230. typedef CBasicUnmarshaller<DWORD> CDwordUnmarshaller;
  231. typedef CBasicUnmarshaller<BG_AUTH_SCHEME> CSchemeUnmarshaller;
  232. typedef CBasicUnmarshaller<BG_AUTH_TARGET> CTargetUnmarshaller;
  233. class CUnicodeStringMarshaller
  234. {
  235. public:
  236. CUnicodeStringMarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  237. {
  238. }
  239. CUnicodeStringMarshaller( CMarshalCursor & Cursor, const LPWSTR & val ) : m_Cursor( Cursor )
  240. {
  241. Marshal( val );
  242. }
  243. static size_t Size( const LPWSTR & val )
  244. {
  245. DWORD StringBytes;
  246. if (val)
  247. {
  248. StringBytes = sizeof(wchar_t) * (1+wcslen(val));
  249. }
  250. else
  251. {
  252. StringBytes = 0;
  253. }
  254. return CDwordMarshaller::Size( StringBytes ) + StringBytes;
  255. }
  256. void Marshal( const LPWSTR & val )
  257. {
  258. CMarshalCursor Cursor = m_Cursor.GetSubCursor();
  259. try
  260. {
  261. DWORD StringBytes;
  262. if (val)
  263. {
  264. StringBytes = sizeof(wchar_t) * (1+wcslen(val));
  265. CDwordMarshaller m1( Cursor, StringBytes );
  266. CBufferMarshaller m2( Cursor, val, StringBytes );
  267. }
  268. else
  269. {
  270. StringBytes = 0;
  271. CDwordMarshaller m1( Cursor, StringBytes );
  272. }
  273. m_Cursor.CommitSubCursor( Cursor );
  274. }
  275. catch ( ComError err )
  276. {
  277. m_Cursor.Scrub();
  278. throw;
  279. }
  280. }
  281. protected:
  282. CMarshalCursor & m_Cursor;
  283. };
  284. class CUnicodeStringUnmarshaller
  285. {
  286. public:
  287. CUnicodeStringUnmarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  288. {
  289. }
  290. CUnicodeStringUnmarshaller( CMarshalCursor & Cursor, LPWSTR & val ) : m_Cursor( Cursor )
  291. {
  292. Unmarshal( val );
  293. }
  294. void Unmarshal( LPWSTR & val )
  295. {
  296. CMarshalCursor Cursor = m_Cursor.GetSubCursor();
  297. try
  298. {
  299. DWORD StringBytes;
  300. val = 0;
  301. CDwordUnmarshaller m1( Cursor, StringBytes );
  302. if (StringBytes)
  303. {
  304. val = reinterpret_cast<LPWSTR>( new char[ StringBytes ] );
  305. CBufferUnmarshaller m2( Cursor, val, StringBytes );
  306. }
  307. m_Cursor.CommitSubCursor( Cursor );
  308. }
  309. catch ( ComError err )
  310. {
  311. delete val;
  312. val = 0;
  313. throw;
  314. }
  315. }
  316. protected:
  317. CMarshalCursor & m_Cursor;
  318. };
  319. class CBasicCredentialsMarshaller
  320. {
  321. public:
  322. CBasicCredentialsMarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  323. {
  324. }
  325. CBasicCredentialsMarshaller( CMarshalCursor & Cursor, const BG_BASIC_CREDENTIALS & val ) : m_Cursor( Cursor )
  326. {
  327. Marshal( val );
  328. }
  329. static size_t Size( const BG_BASIC_CREDENTIALS & val )
  330. {
  331. return CUnicodeStringMarshaller::Size( val.UserName )
  332. + CUnicodeStringMarshaller::Size( val.Password );
  333. }
  334. void Marshal( const BG_BASIC_CREDENTIALS & val )
  335. {
  336. CMarshalCursor Cursor = m_Cursor.GetSubCursor();
  337. try
  338. {
  339. CUnicodeStringMarshaller m1( Cursor, val.UserName );
  340. CUnicodeStringMarshaller m2( Cursor, val.Password );
  341. m_Cursor.CommitSubCursor( Cursor );
  342. }
  343. catch ( ComError err )
  344. {
  345. Cursor.Scrub();
  346. throw;
  347. }
  348. }
  349. protected:
  350. CMarshalCursor & m_Cursor;
  351. };
  352. class CBasicCredentialsUnmarshaller
  353. {
  354. public:
  355. CBasicCredentialsUnmarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  356. {
  357. }
  358. CBasicCredentialsUnmarshaller( CMarshalCursor & Cursor, BG_BASIC_CREDENTIALS & val ) : m_Cursor( Cursor )
  359. {
  360. Unmarshal( val );
  361. }
  362. void Unmarshal( BG_BASIC_CREDENTIALS & val )
  363. {
  364. val.UserName = 0;
  365. val.Password = 0;
  366. CMarshalCursor Cursor = m_Cursor.GetSubCursor();
  367. try
  368. {
  369. CUnicodeStringUnmarshaller m1( Cursor, val.UserName );
  370. CUnicodeStringUnmarshaller m2( Cursor, val.Password );
  371. m_Cursor.CommitSubCursor( Cursor );
  372. }
  373. catch ( ComError err )
  374. {
  375. ScrubStringW( val.UserName );
  376. delete val.UserName;
  377. ScrubStringW( val.Password );
  378. delete val.Password;
  379. throw;
  380. }
  381. }
  382. protected:
  383. CMarshalCursor & m_Cursor;
  384. };
  385. class CAuthCredentialsMarshaller
  386. {
  387. public:
  388. CAuthCredentialsMarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  389. {
  390. }
  391. CAuthCredentialsMarshaller( CMarshalCursor & Cursor, const BG_AUTH_CREDENTIALS * val ) : m_Cursor( Cursor )
  392. {
  393. Marshal( val );
  394. }
  395. static size_t Size( const BG_AUTH_CREDENTIALS * val )
  396. {
  397. switch (val->Scheme)
  398. {
  399. case BG_AUTH_SCHEME_BASIC:
  400. case BG_AUTH_SCHEME_DIGEST:
  401. case BG_AUTH_SCHEME_NTLM:
  402. case BG_AUTH_SCHEME_NEGOTIATE:
  403. case BG_AUTH_SCHEME_PASSPORT:
  404. {
  405. return CDwordMarshaller::Size( val->Scheme )
  406. + CDwordMarshaller::Size( val->Target )
  407. + CBasicCredentialsMarshaller::Size( val->Credentials.Basic );
  408. }
  409. default:
  410. ASSERT( 0 && "size: unknown auth scheme" );
  411. throw ComError( E_FAIL );
  412. }
  413. }
  414. void Marshal( const BG_AUTH_CREDENTIALS * val )
  415. {
  416. CMarshalCursor Cursor = m_Cursor.GetSubCursor();
  417. try
  418. {
  419. CSchemeMarshaller m1( Cursor, val->Scheme );
  420. CTargetMarshaller m2( Cursor, val->Target );
  421. switch (val->Scheme)
  422. {
  423. case BG_AUTH_SCHEME_BASIC:
  424. case BG_AUTH_SCHEME_DIGEST:
  425. case BG_AUTH_SCHEME_NTLM:
  426. case BG_AUTH_SCHEME_NEGOTIATE:
  427. case BG_AUTH_SCHEME_PASSPORT:
  428. {
  429. CBasicCredentialsMarshaller m3( Cursor, val->Credentials.Basic );
  430. break;
  431. }
  432. default:
  433. ASSERT( 0 && "marshal: unknown auth scheme" );
  434. throw ComError( E_FAIL );
  435. }
  436. m_Cursor.CommitSubCursor( Cursor );
  437. }
  438. catch ( ComError err )
  439. {
  440. Cursor.Scrub();
  441. throw;
  442. }
  443. }
  444. protected:
  445. CMarshalCursor & m_Cursor;
  446. };
  447. class CAuthCredentialsUnmarshaller
  448. {
  449. public:
  450. CAuthCredentialsUnmarshaller( CMarshalCursor & Cursor ) : m_Cursor( Cursor )
  451. {
  452. }
  453. CAuthCredentialsUnmarshaller( CMarshalCursor & Cursor, BG_AUTH_CREDENTIALS & val ) : m_Cursor( Cursor )
  454. {
  455. Unmarshal( val );
  456. }
  457. CAuthCredentialsUnmarshaller( CMarshalCursor & Cursor, BG_AUTH_CREDENTIALS ** val ) : m_Cursor( Cursor )
  458. {
  459. Unmarshal( val );
  460. }
  461. void Unmarshal( BG_AUTH_CREDENTIALS & val )
  462. {
  463. CMarshalCursor Cursor = m_Cursor.GetSubCursor();
  464. try
  465. {
  466. CSchemeUnmarshaller m1( Cursor, val.Scheme );
  467. CTargetUnmarshaller m2( Cursor, val.Target );
  468. switch (val.Scheme)
  469. {
  470. case BG_AUTH_SCHEME_BASIC:
  471. case BG_AUTH_SCHEME_DIGEST:
  472. case BG_AUTH_SCHEME_NTLM:
  473. case BG_AUTH_SCHEME_NEGOTIATE:
  474. case BG_AUTH_SCHEME_PASSPORT:
  475. {
  476. CBasicCredentialsUnmarshaller m3( Cursor, val.Credentials.Basic );
  477. break;
  478. }
  479. default:
  480. ASSERT( 0 && "unmarshal: unknown auth scheme" );
  481. THROW_HRESULT( E_FAIL );
  482. }
  483. m_Cursor.CommitSubCursor( Cursor );
  484. }
  485. catch ( ComError err )
  486. {
  487. throw;
  488. }
  489. }
  490. void Unmarshal( BG_AUTH_CREDENTIALS ** ppval )
  491. {
  492. BG_AUTH_CREDENTIALS * pval = 0;
  493. try
  494. {
  495. pval = new BG_AUTH_CREDENTIALS;
  496. Unmarshal( *pval );
  497. *ppval = pval;
  498. }
  499. catch ( ComError err )
  500. {
  501. delete pval;
  502. throw;
  503. }
  504. }
  505. protected:
  506. CMarshalCursor & m_Cursor;
  507. };