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.

504 lines
14 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1998 - 1998.
  5. //
  6. // File: expparam.hxx
  7. //
  8. // Contents: Standard Parameter validation for Exposed Interfaces
  9. //
  10. // History: 11-Feb-98 BChapman Created
  11. //
  12. //---------------------------------------------------------------
  13. #ifndef _EXPPARAM_HXX_
  14. #define _EXPPARAM_HXX_
  15. #include <docfilep.hxx>
  16. #include <funcs.hxx>
  17. //
  18. // I can't actually inherit from the real interfaces and declare the
  19. // methods "static inline" like I want, because "virtual" is incompatible with
  20. // both "static" and "inline". So don't inherit in the final version.
  21. //
  22. #if 0
  23. #define PUBLIC_INHERIT :public IStorage, public IStream, \
  24. public ILockBytes, public IEnumSTATSTG
  25. #define METHODIMP STDMETHODIMP
  26. #define METHODIMP_(x) STDMETHODIMP_(x)
  27. #else
  28. #define PUBLIC_INHERIT
  29. #define METHODIMP static inline STDMETHODIMP
  30. #define METHODIMP_(x) static inline STDMETHODIMP_(x)
  31. #endif
  32. #define ChkErr(x) { HRESULT sc; if( FAILED( sc = (x) ) ) return sc; }
  33. #if DBG == 1
  34. #define EXP_VALIDATE(comp, x) \
  35. { \
  36. if (FAILED(sc = CExpParameterValidate::x)) \
  37. { \
  38. comp##DebugOut(( DEB_ERROR, \
  39. "Parameter Error %lX at %s:%d\n", \
  40. sc, __FILE__, __LINE__)); \
  41. return sc; \
  42. } \
  43. }
  44. #else
  45. #define EXP_VALIDATE(comp, x) \
  46. { \
  47. if (FAILED(sc = CExpParameterValidate::x))\
  48. return sc; \
  49. }
  50. #endif // DBG
  51. class CExpParameterValidate PUBLIC_INHERIT
  52. {
  53. public:
  54. //
  55. // The IUnknown methods First.
  56. //
  57. METHODIMP QueryInterface( REFIID riid,
  58. void** ppvObject )
  59. {
  60. ChkErr( ValidateOutPtrBuffer( ppvObject ) );
  61. *ppvObject = NULL;
  62. ChkErr( ValidateIid( riid ) );
  63. return S_OK;
  64. }
  65. #if 0
  66. //
  67. // Addref and Release are troublesome because they don't
  68. // return HRESULTS. Luckly they have no parameters and are
  69. // therefore unnecessary.
  70. //
  71. METHODIMP_(ULONG) AddRef( void )
  72. {
  73. return S_OK;
  74. }
  75. METHODIMP_(ULONG) Release( void )
  76. {
  77. return S_OK;
  78. }
  79. #endif
  80. //
  81. // All the other methods in Alphabetical Order.
  82. //
  83. // IEnumSTATSTG
  84. METHODIMP Clone( IEnumSTATSTG** ppenum )
  85. {
  86. ChkErr( ValidateOutPtrBuffer( ppenum ) );
  87. *ppenum = NULL;
  88. return S_OK;
  89. }
  90. // IStream
  91. METHODIMP Clone( IStream** ppstm)
  92. {
  93. ChkErr( ValidateOutPtrBuffer( ppstm ) );
  94. *ppstm = NULL;
  95. return S_OK;
  96. }
  97. // IStream
  98. METHODIMP CopyTo( IStream* pstm,
  99. ULARGE_INTEGER cb,
  100. ULARGE_INTEGER* pcbRead,
  101. ULARGE_INTEGER* pcbWritten )
  102. {
  103. if( NULL != pcbRead )
  104. {
  105. ChkErr( ValidateOutBuffer( pcbRead, sizeof( ULARGE_INTEGER ) ) );
  106. pcbRead->QuadPart = 0;
  107. }
  108. if( NULL != pcbWritten )
  109. {
  110. ChkErr( ValidateOutBuffer( pcbWritten, sizeof(ULARGE_INTEGER) ) );
  111. pcbWritten->QuadPart = 0;
  112. }
  113. ChkErr( ValidateInterface(pstm, IID_IStream) );
  114. return S_OK;
  115. }
  116. // IStorage
  117. METHODIMP CopyTo( DWORD ciidExclude,
  118. const IID* rgiidExclude,
  119. SNB snbExclude,
  120. IStorage* pstgDest)
  121. {
  122. DWORD i;
  123. ChkErr( ValidateInterface( pstgDest, IID_IStorage ) );
  124. if( NULL != rgiidExclude )
  125. {
  126. Win4Assert(sizeof(IID)*ciidExclude <= 0xffffUL);
  127. ChkErr( ValidateBuffer( rgiidExclude,
  128. (size_t)(sizeof(IID)*ciidExclude ) ) );
  129. //
  130. // This check may be useless. I think it is checking if the address
  131. // of given stack variable is a valid address (duh!)
  132. // This check has been in the code a long time make sure in the debugger!
  133. //
  134. for (i = 0; i < ciidExclude; i++)
  135. ChkErr(ValidateIid(rgiidExclude[i]));
  136. }
  137. if( NULL != snbExclude )
  138. ChkErr( ValidateSNB( snbExclude ) );
  139. return S_OK;
  140. }
  141. // IStream, IStorage
  142. METHODIMP Commit( DWORD grfCommitFlags )
  143. {
  144. ChkErr( VerifyCommitFlags( grfCommitFlags ) );
  145. return S_OK;
  146. }
  147. // IStorage
  148. METHODIMP CreateStorage( const OLECHAR* pwcsName,
  149. DWORD grfMode,
  150. DWORD reserved1,
  151. DWORD reserved2,
  152. IStorage** ppstg)
  153. {
  154. ChkErr( ValidateOutPtrBuffer( ppstg ) );
  155. *ppstg = NULL;
  156. ChkErr( CheckName(pwcsName) );
  157. if( reserved1 != 0 || reserved2 != 0 )
  158. return STG_E_INVALIDPARAMETER;
  159. ChkErr( VerifyPerms( grfMode, FALSE ) );
  160. if( grfMode & ( STGM_PRIORITY | STGM_DELETEONRELEASE ) )
  161. return STG_E_INVALIDFUNCTION;
  162. return S_OK;
  163. }
  164. // IStorage
  165. METHODIMP CreateStream( const OLECHAR* pwcsName,
  166. DWORD grfMode,
  167. DWORD reserved1,
  168. DWORD reserved2,
  169. IStream** ppstm)
  170. {
  171. ChkErr( ValidateOutPtrBuffer( ppstm ) );
  172. *ppstm = NULL;
  173. ChkErr( CheckName( pwcsName ) );
  174. if( reserved1 != 0 || reserved2 != 0 )
  175. return STG_E_INVALIDPARAMETER;
  176. ChkErr( VerifyPerms( grfMode, FALSE ) );
  177. if( grfMode & ( STGM_CONVERT | STGM_TRANSACTED | STGM_PRIORITY |
  178. STGM_DELETEONRELEASE ) )
  179. {
  180. return STG_E_INVALIDFUNCTION;
  181. }
  182. return S_OK;
  183. }
  184. // IStorage
  185. METHODIMP DestroyElement( const OLECHAR* pwcsName )
  186. {
  187. ChkErr( CheckName( pwcsName ) );
  188. return S_OK;
  189. }
  190. // IStorage
  191. METHODIMP EnumElements( DWORD reserved1,
  192. void* reserved2,
  193. DWORD reserved3,
  194. IEnumSTATSTG** ppenum)
  195. {
  196. ChkErr( ValidateOutPtrBuffer( ppenum ) );
  197. *ppenum = NULL;
  198. if( reserved1 != 0 || reserved2 != NULL || reserved3 != 0 )
  199. return STG_E_INVALIDPARAMETER;
  200. return S_OK;
  201. }
  202. // ILockBytes
  203. METHODIMP Flush( void )
  204. {
  205. return S_OK;
  206. }
  207. // IStream, ILockBytes
  208. METHODIMP LockRegion( ULARGE_INTEGER libOffset,
  209. ULARGE_INTEGER cb,
  210. DWORD dwLockType )
  211. {
  212. ChkErr( VerifyLockType( dwLockType ) );
  213. return S_OK;
  214. }
  215. // IStorage
  216. METHODIMP MoveElementTo( const OLECHAR* pwcsName,
  217. IStorage* pstgDest,
  218. const OLECHAR* pwcsNewName,
  219. DWORD grfFlags)
  220. {
  221. ChkErr( CheckName( pwcsName ) );
  222. ChkErr( CheckName( pwcsNewName ) );
  223. ChkErr( VerifyMoveFlags( grfFlags ) );
  224. ChkErr( ValidateInterface( pstgDest, IID_IStorage ) );
  225. return S_OK;
  226. }
  227. // IEnumSTATSTG
  228. METHODIMP Next( ULONG celt,
  229. STATSTG FAR *rgelt,
  230. ULONG *pceltFetched)
  231. {
  232. if (pceltFetched)
  233. {
  234. ChkErr( ValidateOutBuffer( pceltFetched, sizeof(ULONG) ) );
  235. *pceltFetched = 0;
  236. }
  237. else if (celt != 1)
  238. return STG_E_INVALIDPARAMETER;
  239. ChkErr( ValidateOutBuffer( rgelt, sizeof(STATSTGW)*celt) );
  240. memset( rgelt, 0, (size_t)(sizeof(STATSTGW)*celt ) );
  241. return S_OK;
  242. }
  243. // IStorage
  244. METHODIMP OpenStorage( const OLECHAR* pwcsName,
  245. IStorage* pstgPriority,
  246. DWORD grfMode,
  247. SNB snbExclude,
  248. DWORD reserved,
  249. IStorage** ppstg)
  250. {
  251. ChkErr( ValidateOutPtrBuffer( ppstg ) );
  252. *ppstg = NULL;
  253. ChkErr( CheckName( pwcsName ) );
  254. if( reserved != 0)
  255. return STG_E_INVALIDPARAMETER;
  256. ChkErr( VerifyPerms( grfMode, FALSE ) );
  257. if( grfMode & (STGM_CREATE | STGM_CONVERT ) )
  258. return STG_E_INVALIDFLAG;
  259. if( NULL != pstgPriority
  260. || ( grfMode & ( STGM_PRIORITY | STGM_DELETEONRELEASE ) ) )
  261. {
  262. return STG_E_INVALIDFUNCTION;
  263. }
  264. return S_OK;
  265. }
  266. // IStorage
  267. METHODIMP OpenStream( const OLECHAR* pwcsName,
  268. void* reserved1,
  269. DWORD grfMode,
  270. DWORD reserved2,
  271. IStream** ppstm)
  272. {
  273. ChkErr(ValidateOutPtrBuffer(ppstm));
  274. *ppstm = NULL;
  275. ChkErr( CheckName( pwcsName ) );
  276. if( reserved1 != NULL || reserved2 != 0 )
  277. return STG_E_INVALIDPARAMETER;
  278. ChkErr( VerifyPerms( grfMode, FALSE ) );
  279. if( grfMode & (STGM_CREATE | STGM_CONVERT ) )
  280. return STG_E_INVALIDFLAG;
  281. if( grfMode & (STGM_TRANSACTED | STGM_PRIORITY |
  282. STGM_DELETEONRELEASE ) )
  283. return STG_E_INVALIDFUNCTION;
  284. return S_OK;
  285. }
  286. // IStream
  287. METHODIMP Read( void* pv,
  288. ULONG cb,
  289. ULONG* pcbRead)
  290. {
  291. if (NULL != pcbRead)
  292. {
  293. ChkErr( ValidateOutBuffer( pcbRead, sizeof(ULONG) ) );
  294. *pcbRead = 0;
  295. }
  296. ChkErr( ValidateHugeOutBuffer( pv, cb ) );
  297. return S_OK;
  298. }
  299. // ILockBytes
  300. METHODIMP ReadAt( ULARGE_INTEGER ulOffset,
  301. void* pv,
  302. ULONG cb,
  303. ULONG* pcbRead )
  304. {
  305. if (NULL != pcbRead)
  306. {
  307. ChkErr( ValidateOutBuffer( pcbRead, sizeof(ULONG) ) );
  308. *pcbRead = 0;
  309. }
  310. ChkErr( ValidateHugeOutBuffer( pv, cb ) );
  311. return S_OK;
  312. }
  313. // IStorage
  314. METHODIMP RenameElement( const OLECHAR* pwcsOldName,
  315. const OLECHAR* pwcsNewName)
  316. {
  317. ChkErr( CheckName( pwcsOldName ) );
  318. ChkErr( CheckName( pwcsNewName ) );
  319. return S_OK;
  320. }
  321. // IEnumSTATSTG
  322. METHODIMP Reset()
  323. {
  324. return S_OK;
  325. }
  326. // IStream, IStorage
  327. METHODIMP Revert( void )
  328. {
  329. return S_OK;
  330. }
  331. // IStream
  332. METHODIMP Seek( LARGE_INTEGER dlibMove,
  333. DWORD dwOrigin,
  334. ULARGE_INTEGER* plibNewPosition )
  335. {
  336. if( plibNewPosition )
  337. {
  338. ChkErr( ValidateOutBuffer( plibNewPosition, sizeof(ULARGE_INTEGER ) ) );
  339. plibNewPosition->QuadPart = 0;
  340. }
  341. switch( dwOrigin )
  342. {
  343. case STREAM_SEEK_SET:
  344. case STREAM_SEEK_CUR:
  345. case STREAM_SEEK_END:
  346. break;
  347. default:
  348. return STG_E_INVALIDFUNCTION;
  349. }
  350. return S_OK;
  351. }
  352. // IStorage
  353. METHODIMP SetClass( REFCLSID clsid)
  354. {
  355. ChkErr( ValidateBuffer( &clsid, sizeof( CLSID ) ) );
  356. return S_OK;
  357. }
  358. // IStorage
  359. METHODIMP SetElementTimes( const OLECHAR* pwcsName,
  360. const FILETIME* pctime,
  361. const FILETIME* patime,
  362. const FILETIME* pmtime)
  363. {
  364. if( NULL != pwcsName )
  365. ChkErr( CheckName( pwcsName ) );
  366. if( NULL != pctime )
  367. ChkErr( ValidateBuffer( pctime, sizeof( FILETIME ) ) );
  368. if( NULL != patime )
  369. ChkErr( ValidateBuffer( patime, sizeof( FILETIME ) ) );
  370. if( NULL != pmtime )
  371. ChkErr( ValidateBuffer( pmtime, sizeof( FILETIME ) ) );
  372. return S_OK;
  373. }
  374. // IStream, ILockBytes
  375. METHODIMP SetSize( ULARGE_INTEGER libNewSize )
  376. {
  377. return S_OK;
  378. }
  379. // IStorage
  380. METHODIMP SetStateBits( DWORD grfStateBits,
  381. DWORD grfMask )
  382. {
  383. // We could insist that both args be 0.
  384. // But we never have in the past.
  385. return S_OK;
  386. }
  387. // IEnumSTATSTG
  388. METHODIMP Skip( ULONG celt )
  389. {
  390. // I would like to do some sanity testing but the value
  391. // isn't even signed. All bit values are technically valid.
  392. return S_OK;
  393. }
  394. // IStream, IStorage, ILockBytes
  395. METHODIMP Stat( STATSTG* pstatstg,
  396. DWORD grfStatFlag )
  397. {
  398. ChkErr( ValidateOutBuffer( pstatstg, sizeof( STATSTGW ) ) );
  399. ChkErr( VerifyStatFlag( grfStatFlag ) );
  400. return S_OK;
  401. }
  402. // IStream, ILockBytes
  403. METHODIMP UnlockRegion( ULARGE_INTEGER libOffset,
  404. ULARGE_INTEGER cb,
  405. DWORD dwLockType )
  406. {
  407. ChkErr( VerifyLockType( dwLockType ) );
  408. return S_OK;
  409. }
  410. // IStream
  411. METHODIMP Write( const void* pv,
  412. ULONG cb,
  413. ULONG* pcbWritten )
  414. {
  415. if (NULL != pcbWritten)
  416. {
  417. ChkErr( ValidateOutBuffer( pcbWritten, sizeof(ULONG) ) );
  418. *pcbWritten = 0;
  419. }
  420. ChkErr( ValidateHugeBuffer( pv, cb ) );
  421. return S_OK;
  422. }
  423. // ILockBytes
  424. METHODIMP WriteAt( ULARGE_INTEGER ulOffset,
  425. const void *pv,
  426. ULONG cb,
  427. ULONG *pcbWritten )
  428. {
  429. if (NULL != pcbWritten)
  430. {
  431. ChkErr( ValidateOutBuffer( pcbWritten, sizeof(ULONG) ) );
  432. *pcbWritten = 0;
  433. }
  434. ChkErr( ValidateHugeBuffer( pv, cb ) );
  435. return S_OK;
  436. }
  437. };
  438. #endif // _EXPPARAM_HXX_