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.

1125 lines
29 KiB

  1. /*****************************************************************************
  2. *
  3. * Valid.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Validate services. On a validation error that would not have
  10. * been caught in retail, we throw an exception.
  11. *
  12. * Contents:
  13. *
  14. * fFullValidPhwnd
  15. * fFullValidPpdw
  16. * fFullValidPpfn
  17. * fFullValidReadPx
  18. * fFullValidWritePx
  19. *
  20. *****************************************************************************/
  21. #include "dinputpr.h"
  22. /*****************************************************************************
  23. *
  24. * @doc INTERNAL
  25. *
  26. * @func HRESULT | hresFullValidHwnd |
  27. *
  28. * Validate a window handle completely.
  29. *
  30. * @parm HWND | hwnd |
  31. *
  32. * Window handle to validate.
  33. *
  34. * @parm LPCSTR | s_szProc |
  35. *
  36. * Name of calling procedure.
  37. *
  38. * @parm int | iarg |
  39. *
  40. * Parameter index. (First parameter is 1.)
  41. *
  42. * @returns
  43. *
  44. * <c S_OK> if the parameter is valid.
  45. *
  46. * <c E_HANDLE> if the parameter is invalid.
  47. *
  48. *****************************************************************************/
  49. STDMETHODIMP
  50. hresFullValidHwnd_(HWND hwnd, LPCSTR s_szProc, int iarg)
  51. {
  52. HRESULT hres;
  53. if (IsWindow(hwnd)) {
  54. hres = S_OK;
  55. } else {
  56. RPF("ERROR %s: arg %d: not a window handle", s_szProc, iarg);
  57. hres = E_HANDLE;
  58. }
  59. return hres;
  60. }
  61. /*****************************************************************************
  62. *
  63. * @doc INTERNAL
  64. *
  65. * @func HRESULT | hresFullValidPvCb_ |
  66. *
  67. * Validate that a buffer is readable or writeable.
  68. *
  69. * @parm PV | pv |
  70. *
  71. * Buffer address.
  72. *
  73. * @parm UINT | cb |
  74. *
  75. * Size of buffer in bytes.
  76. *
  77. * @parm PFNBAD | pfnBad |
  78. *
  79. * Function that determines whether the buffer is bad.
  80. * Should be <f IsBadReadPtr> or <f IsBadWritePtr>.
  81. *
  82. * @parm LPCSTR | s_szProc |
  83. *
  84. * Name of calling procedure.
  85. *
  86. * @parm int | iarg |
  87. *
  88. * Parameter index. (First parameter is 1.)
  89. * High word indicates how many bytes should not be
  90. * scrambled.
  91. *
  92. * @returns
  93. *
  94. * <c S_OK> if the parameter is valid.
  95. *
  96. * <c E_POINTER> if the parameter is invalid.
  97. *
  98. *****************************************************************************/
  99. typedef BOOL (WINAPI *PFNBAD)(PCV pv, UINT_PTR cb);
  100. #ifndef XDEBUG
  101. #define hresFullValidPvCb_(pv, cb, pfnBad, z, i) \
  102. _hresFullValidPvCb_(pv, cb, pfnBad) \
  103. #endif
  104. STDMETHODIMP
  105. hresFullValidPvCb_(PCV pv, UINT cb, PFNBAD pfnBad, LPCSTR s_szProc, int iarg)
  106. {
  107. HRESULT hres;
  108. if (!pfnBad(pv, LOWORD(cb))) {
  109. hres = S_OK;
  110. } else {
  111. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, LOWORD(iarg));
  112. hres = E_POINTER;
  113. }
  114. return hres;
  115. }
  116. /*****************************************************************************
  117. *
  118. * @doc INTERNAL
  119. *
  120. * @func HRESULT | hresFullValidWritePvCb_ |
  121. *
  122. * Validate that a buffer is writeable. Also scrambles it
  123. * if special goo doesn't need to be done.
  124. *
  125. * @parm PV | pv |
  126. *
  127. * Buffer address.
  128. *
  129. * @parm UINT | cb |
  130. *
  131. * Size of buffer in bytes.
  132. *
  133. * @parm LPCSTR | s_szProc |
  134. *
  135. * Name of calling procedure.
  136. *
  137. * @parm int | iarg |
  138. *
  139. * Parameter index. (First parameter is 1.)
  140. *
  141. * @returns
  142. *
  143. * <c S_OK> if the parameter is valid.
  144. *
  145. * <c E_POINTER> if the parameter is invalid.
  146. *
  147. *****************************************************************************/
  148. STDMETHODIMP
  149. hresFullValidWritePvCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  150. {
  151. HRESULT hres;
  152. hres = hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadWritePtr, s_szProc, iarg);
  153. #ifdef XDEBUG
  154. if (SUCCEEDED(hres) && HIWORD(iarg) == 0) {
  155. ScrambleBuf(pv, cb);
  156. }
  157. #endif
  158. return hres;
  159. }
  160. /*****************************************************************************
  161. *
  162. * @doc INTERNAL
  163. *
  164. * @func HRESULT | hresFullValidWriteLargePvCb_ |
  165. *
  166. * Validate that a large buffer is writeable.
  167. * "Large" means 64K or more.
  168. * Also scrambles it if special goo doesn't need to be done.
  169. *
  170. * @parm PV | pv |
  171. *
  172. * Buffer address.
  173. *
  174. * @parm UINT | cb |
  175. *
  176. * Size of buffer in bytes.
  177. *
  178. * @parm LPCSTR | s_szProc |
  179. *
  180. * Name of calling procedure.
  181. *
  182. * @parm int | iarg |
  183. *
  184. * Parameter index. (First parameter is 1.)
  185. *
  186. * @returns
  187. *
  188. * <c S_OK> if the parameter is valid.
  189. *
  190. * <c E_POINTER> if the parameter is invalid.
  191. *
  192. *****************************************************************************/
  193. STDMETHODIMP
  194. hresFullValidWriteLargePvCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  195. {
  196. HRESULT hres;
  197. if( !IsBadWritePtr( pv, cb ) )
  198. {
  199. hres = S_OK;
  200. } else {
  201. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, LOWORD(iarg));
  202. hres = E_POINTER;
  203. }
  204. #ifdef XDEBUG
  205. if (SUCCEEDED(hres) && HIWORD(iarg) == 0) {
  206. ScrambleBuf(pv, cb);
  207. }
  208. #endif
  209. return hres;
  210. }
  211. /*****************************************************************************
  212. *
  213. * @doc INTERNAL
  214. *
  215. * @func HRESULT | hresFullValidReadPvCb_ |
  216. *
  217. * Validate that a buffer is readable.
  218. *
  219. * @parm PV | pv |
  220. *
  221. * Buffer address.
  222. *
  223. * @parm UINT | cb |
  224. *
  225. * Size of buffer in bytes.
  226. *
  227. * @parm LPCSTR | s_szProc |
  228. *
  229. * Name of calling procedure.
  230. *
  231. * @parm int | iarg |
  232. *
  233. * Parameter index. (First parameter is 1.)
  234. *
  235. * @returns
  236. *
  237. * <c S_OK> if the parameter is valid.
  238. *
  239. * <c E_POINTER> if the parameter is invalid.
  240. *
  241. *****************************************************************************/
  242. STDMETHODIMP
  243. hresFullValidReadPvCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
  244. {
  245. return hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadReadPtr, s_szProc, iarg);
  246. }
  247. /*****************************************************************************
  248. *
  249. * @doc INTERNAL
  250. *
  251. * @func HRESULT | hresFullValidPxCb_ |
  252. *
  253. * Validate that a sized structure is readable or writeable.
  254. *
  255. * @parm PCV | pv |
  256. *
  257. * Structure address. The first field of the structure must
  258. * be a <p dwSize>. If the structure is being validated for
  259. * writing, then all fields beyond the <p dwSize> are scrambled
  260. * in XDEBUG.
  261. *
  262. * @parm UINT | cbHiLo |
  263. *
  264. * Expected sizes of the structure. One valid size is in the
  265. * low word. An optional alternate valid size is in the high
  266. * word. (The alternate valid size is needed because some
  267. * structures changed size between DirectX 3 and DirectX 5.)
  268. *
  269. * @parm STRUCTPROC | pfnStruct |
  270. *
  271. * Function which validates that a structure is readable or writable.
  272. *
  273. * @parm LPCSTR | s_szProc |
  274. *
  275. * Name of calling procedure.
  276. *
  277. * @parm int | iarg |
  278. *
  279. * Parameter index. (First parameter is 1.)
  280. *
  281. * @returns
  282. *
  283. * <c S_OK> if the parameter is valid.
  284. *
  285. * <c E_POINTER> if the buffer is not readable or writeable.
  286. *
  287. * <c E_INVALIDARG> if the buffer size is incorrect.
  288. *
  289. *****************************************************************************/
  290. typedef STDMETHOD(STRUCTPROC)(PCV pv, UINT cb
  291. RD(comma LPCSTR s_szProc comma int iarg));
  292. #ifndef XDEBUG
  293. #define hresFullValidPxCb_(pv, cbHiLo, pfnStruct, z, i) \
  294. _hresFullValidPxCb_(pv, cbHiLo, pfnStruct) \
  295. #endif
  296. STDMETHODIMP
  297. hresFullValidPxCb_(PCV pv, UINT cbHiLo, STRUCTPROC pfnStruct,
  298. LPCSTR s_szProc, int iarg)
  299. {
  300. HRESULT hres;
  301. /*
  302. * Raymond frequently suffers a brain lapse and passes
  303. * a cbX(LPMUMBLE) instead of a cbX(MUMBLE).
  304. */
  305. AssertF(LOWORD(cbHiLo) != cbX(DWORD));
  306. AssertF(HIWORD(cbHiLo) != cbX(DWORD));
  307. if (!IsBadReadPtr(pv, cbX(DWORD))) {
  308. DWORD cbIn = *(LPDWORD)pv;
  309. /*
  310. * The leading "cbIn &&" prevents the HIWORD(cbHiLo)==0 case from
  311. * accidentally allowing a size of zero to sneak past.
  312. */
  313. if (cbIn && (cbIn == LOWORD(cbHiLo) || cbIn == HIWORD(cbHiLo))) {
  314. hres = pfnStruct(pv, cbIn RD(comma s_szProc comma iarg));
  315. if (SUCCEEDED(hres)) {
  316. if (HIWORD(iarg)) {
  317. ScrambleBuf(pvAddPvCb(pv, HIWORD(iarg)),
  318. cbIn - HIWORD(iarg));
  319. }
  320. }
  321. } else {
  322. RPF("ERROR %s: arg %d: invalid dwSize x%x", s_szProc, LOWORD(iarg), cbIn);
  323. hres = E_INVALIDARG;
  324. }
  325. } else {
  326. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, LOWORD(iarg));
  327. hres = E_POINTER;
  328. }
  329. return hres;
  330. }
  331. /*****************************************************************************
  332. *
  333. * @doc INTERNAL
  334. *
  335. * @func HRESULT | hresFullValidPxCb3_ |
  336. *
  337. * Validate that a sized structure is readable or writeable.
  338. *
  339. * @parm PCV | pv |
  340. *
  341. * Structure address. The first field of the structure must
  342. * be a <p dwSize>. If the structure is being validated for
  343. * writing, then all fields beyond the <p dwSize> are scrambled
  344. * in XDEBUG.
  345. *
  346. * @parm UINT | cb |
  347. *
  348. * Expected sizes of the structure.
  349. *
  350. * @parm UINT | cb2 |
  351. *
  352. * Expected sizes of the alternate structure.
  353. *
  354. * @parm UINT | cb3 |
  355. *
  356. * Expected sizes of the alternate structure.
  357. *
  358. * @parm STRUCTPROC | pfnStruct |
  359. *
  360. * Function which validates that a structure is readable or writable.
  361. *
  362. * @parm LPCSTR | s_szProc |
  363. *
  364. * Name of calling procedure.
  365. *
  366. * @parm int | iarg |
  367. *
  368. * Parameter index. (First parameter is 1.)
  369. *
  370. * @returns
  371. *
  372. * <c S_OK> if the parameter is valid.
  373. *
  374. * <c E_POINTER> if the buffer is not readable or writeable.
  375. *
  376. * <c E_INVALIDARG> if the buffer size is incorrect.
  377. *
  378. *****************************************************************************/
  379. #ifndef XDEBUG
  380. #define hresFullValidPxCb3_(pv, cb, cb2, cb3, pfnStruct, z, i) \
  381. _hresFullValidPxCb3_(pv, cb, cb2, cb3, pfnStruct) \
  382. #endif
  383. STDMETHODIMP
  384. hresFullValidPxCb3_(PCV pv, UINT cb, UINT cb2, UINT cb3, STRUCTPROC pfnStruct,
  385. LPCSTR s_szProc, int iarg)
  386. {
  387. HRESULT hres;
  388. /*
  389. * Raymond frequently suffers a brain lapse and passes
  390. * a cbX(LPMUMBLE) instead of a cbX(MUMBLE).
  391. */
  392. AssertF(cb != cbX(DWORD));
  393. AssertF(cb2 != cbX(DWORD));
  394. AssertF(cb3 != cbX(DWORD));
  395. if (!IsBadReadPtr(pv, cbX(DWORD))) {
  396. DWORD cbIn = *(LPDWORD)pv;
  397. /*
  398. * The leading "cbIn &&" prevents the HIWORD(cbHiLo)==0 case from
  399. * accidentally allowing a size of zero to sneak past.
  400. */
  401. if (cbIn && (cbIn == cb || cbIn == cb2 || cbIn == cb3)) {
  402. hres = pfnStruct(pv, cbIn RD(comma s_szProc comma iarg));
  403. if (SUCCEEDED(hres)) {
  404. if (HIWORD(iarg)) {
  405. ScrambleBuf(pvAddPvCb(pv, HIWORD(iarg)),
  406. cbIn - HIWORD(iarg));
  407. }
  408. }
  409. } else {
  410. RPF("ERROR %s: arg %d: invalid dwSize", s_szProc, LOWORD(iarg));
  411. hres = E_INVALIDARG;
  412. }
  413. } else {
  414. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, LOWORD(iarg));
  415. hres = E_POINTER;
  416. }
  417. return hres;
  418. }
  419. /*****************************************************************************
  420. *
  421. * @doc INTERNAL
  422. *
  423. * @func HRESULT | hresFullValidWritePxCb_ |
  424. *
  425. * Validate that a sized structure is writeable. The contents
  426. * of the structure are scrambled before returning.
  427. *
  428. * @parm PV | pv |
  429. *
  430. * Structure address. The first field of the structure must
  431. * be a <p dwSize>.
  432. *
  433. * @parm UINT | cbHiLo |
  434. *
  435. * Expected sizes of the structure. One valid size is in the
  436. * low word. An optional alternate valid size is in the high
  437. * word. (The alternate valid size is needed because some
  438. * structures changed size between DirectX 3 and DirectX 5.)
  439. *
  440. * @parm LPCSTR | s_szProc |
  441. *
  442. * Name of calling procedure.
  443. *
  444. * @parm int | iarg |
  445. *
  446. * Parameter index. (First parameter is 1.)
  447. *
  448. * @returns
  449. *
  450. * <c S_OK> if the parameter is valid.
  451. *
  452. * <c E_POINTER> if the buffer is not writeable.
  453. *
  454. * <c E_INVALIDARG> if the buffer size is incorrect.
  455. *
  456. *****************************************************************************/
  457. STDMETHODIMP
  458. hresFullValidWritePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  459. {
  460. /*
  461. * We need to distinguish hresFullValidWritePvCb_ and
  462. * _hresFullValidWritePvCb_ manually, because the preprocessor
  463. * can't do it.
  464. *
  465. * We also need to put a cbX(DWORD) into the high word of the iarg
  466. * so that the size field won't get demolished.
  467. */
  468. #ifdef XDEBUG
  469. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)hresFullValidWritePvCb_,
  470. s_szProc, MAKELONG(iarg, cbX(DWORD)));
  471. #else
  472. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)_hresFullValidWritePvCb_,
  473. s_szProc, iarg);
  474. #endif
  475. }
  476. /*****************************************************************************
  477. *
  478. * @doc INTERNAL
  479. *
  480. * @func HRESULT | hresFullValidReadPxCb3_ |
  481. *
  482. * Validate that a sized structure is readable. The contents
  483. * of the structure are scrambled before returning.
  484. *
  485. * @parm PV | pv |
  486. *
  487. * Structure address. The first field of the structure must
  488. * be a <p dwSize>.
  489. *
  490. * @parm UINT | cb |
  491. *
  492. * One expected size of the structure.
  493. *
  494. * @parm UINT | cb2 |
  495. *
  496. * Expected sizes of the alternate structure.
  497. *
  498. * @parm UINT | cb3 |
  499. *
  500. * Expected sizes of the alternate structure.
  501. *
  502. * @parm LPCSTR | s_szProc |
  503. *
  504. * Name of calling procedure.
  505. *
  506. * @parm int | iarg |
  507. *
  508. * Parameter index. (First parameter is 1.)
  509. *
  510. * @returns
  511. *
  512. * <c S_OK> if the parameter is valid.
  513. *
  514. * <c E_POINTER> if the buffer is not readable.
  515. *
  516. * <c E_INVALIDARG> if the buffer size is incorrect.
  517. *
  518. *****************************************************************************/
  519. STDMETHODIMP
  520. hresFullValidReadPxCb3_(PV pv, UINT cb, UINT cb2, UINT cb3, LPCSTR s_szProc, int iarg)
  521. {
  522. /*
  523. * We need to distinguish hresFullValidReadPvCb_ and
  524. * _hresFullValidReadPvCb_ manually, because the preprocessor
  525. * can't do it.
  526. */
  527. #ifdef XDEBUG
  528. return hresFullValidPxCb3_(pv, cb, cb2, cb3, (STRUCTPROC)hresFullValidReadPvCb_,
  529. s_szProc, iarg);
  530. #else
  531. return hresFullValidPxCb3_(pv, cb, cb2, cb3, (STRUCTPROC)_hresFullValidReadPvCb_,
  532. s_szProc, iarg);
  533. #endif
  534. }
  535. /*****************************************************************************
  536. *
  537. * @doc INTERNAL
  538. *
  539. * @func HRESULT | hresFullValidWritePxCb3_ |
  540. *
  541. * Validate that a sized structure is writeable. The contents
  542. * of the structure are scrambled before returning.
  543. *
  544. * @parm PV | pv |
  545. *
  546. * Structure address. The first field of the structure must
  547. * be a <p dwSize>.
  548. *
  549. * @parm UINT | cb |
  550. *
  551. * Expected sizes of the structure. One valid size is in the
  552. * low word. An optional alternate valid size is in the high
  553. * word. (The alternate valid size is needed because some
  554. * structures changed size between DirectX 3 and DirectX 5.)
  555. *
  556. * @parm UINT | cb2 |
  557. *
  558. * Expected sizes of the alternate structure.
  559. *
  560. * @parm UINT | cb3 |
  561. *
  562. * Expected sizes of the alternate structure.
  563. *
  564. * @parm LPCSTR | s_szProc |
  565. *
  566. * Name of calling procedure.
  567. *
  568. * @parm int | iarg |
  569. *
  570. * Parameter index. (First parameter is 1.)
  571. *
  572. * @returns
  573. *
  574. * <c S_OK> if the parameter is valid.
  575. *
  576. * <c E_POINTER> if the buffer is not writeable.
  577. *
  578. * <c E_INVALIDARG> if the buffer size is incorrect.
  579. *
  580. *****************************************************************************/
  581. STDMETHODIMP
  582. hresFullValidWritePxCb3_(PV pv, UINT cb, UINT cb2, UINT cb3, LPCSTR s_szProc, int iarg)
  583. {
  584. /*
  585. * We need to distinguish hresFullValidWritePvCb_ and
  586. * _hresFullValidWritePvCb_ manually, because the preprocessor
  587. * can't do it.
  588. *
  589. * We also need to put a cbX(DWORD) into the high word of the iarg
  590. * so that the size field won't get demolished.
  591. */
  592. #ifdef XDEBUG
  593. return hresFullValidPxCb3_(pv, cb, cb2, cb3, (STRUCTPROC)hresFullValidWritePvCb_,
  594. s_szProc, MAKELONG(iarg, cbX(DWORD)));
  595. #else
  596. return hresFullValidPxCb3_(pv, cb, cb2, cb3, (STRUCTPROC)_hresFullValidWritePvCb_,
  597. s_szProc, iarg);
  598. #endif
  599. }
  600. #ifdef XDEBUG
  601. /*****************************************************************************
  602. *
  603. * @doc INTERNAL
  604. *
  605. * @func HRESULT | hresFullValidWriteNoScramblePxCb_ |
  606. *
  607. * Validate that a sized structure is writeable. The contents
  608. * of the structure are not scrambled.
  609. *
  610. * @parm PV | pv |
  611. *
  612. * Structure address. The first field of the structure must
  613. * be a <p dwSize>.
  614. *
  615. * @parm UINT | cbHiLo |
  616. *
  617. * Expected sizes of the structure. One valid size is in the
  618. * low word. An optional alternate valid size is in the high
  619. * word. (The alternate valid size is needed because some
  620. * structures changed size between DirectX 3 and DirectX 5.)
  621. *
  622. * @parm LPCSTR | s_szProc |
  623. *
  624. * Name of calling procedure.
  625. *
  626. * @parm int | iarg |
  627. *
  628. * Parameter index. (First parameter is 1.)
  629. *
  630. * @returns
  631. *
  632. * <c S_OK> if the parameter is valid.
  633. *
  634. * <c E_POINTER> if the buffer is not writeable.
  635. *
  636. * <c E_INVALIDARG> if the buffer size is incorrect.
  637. *
  638. *****************************************************************************/
  639. STDMETHODIMP
  640. hresFullValidWriteNoScramblePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  641. {
  642. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)hresFullValidWritePvCb_,
  643. s_szProc, MAKELONG(iarg, cb));
  644. }
  645. #endif
  646. /*****************************************************************************
  647. *
  648. * @doc INTERNAL
  649. *
  650. * @func HRESULT | hresFullValidReadPxCb_ |
  651. *
  652. * Validate that a sized structure is readable.
  653. *
  654. * @parm PV | pv |
  655. *
  656. * Structure address. The first field of the structure must
  657. * be a <p dwSize>.
  658. *
  659. * @parm UINT | cbHiLo |
  660. *
  661. * Expected sizes of the structure. One valid size is in the
  662. * low word. An optional alternate valid size is in the high
  663. * word. (The alternate valid size is needed because some
  664. * structures changed size between DirectX 3 and DirectX 5.)
  665. *
  666. * @parm LPCSTR | s_szProc |
  667. *
  668. * Name of calling procedure.
  669. *
  670. * @parm int | iarg |
  671. *
  672. * Parameter index. (First parameter is 1.)
  673. *
  674. * @returns
  675. *
  676. * <c S_OK> if the parameter is valid.
  677. *
  678. * <c E_POINTER> if the buffer is not readable.
  679. *
  680. * <c E_INVALIDARG> if the buffer size is incorrect.
  681. *
  682. *****************************************************************************/
  683. STDMETHODIMP
  684. hresFullValidReadPxCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
  685. {
  686. /*
  687. * We need to distinguish hresFullValidReadPvCb_ and
  688. * _hresFullValidReadPvCb_ manually, because the preprocessor
  689. * can't do it.
  690. */
  691. #ifdef XDEBUG
  692. return hresFullValidPxCb_(pv, cb, hresFullValidReadPvCb_, s_szProc, iarg);
  693. #else
  694. return hresFullValidPxCb_(pv, cb, _hresFullValidReadPvCb_, s_szProc, iarg);
  695. #endif
  696. }
  697. /*****************************************************************************
  698. *
  699. * @doc INTERNAL
  700. *
  701. * @func HRESULT | hresFullValidFl_ |
  702. *
  703. * Validate that no invalid flags are passed.
  704. *
  705. * @parm DWORD | fl |
  706. *
  707. * Flags passed by the caller.
  708. *
  709. * @parm DWORD | flV |
  710. *
  711. * Flags which are valid.
  712. *
  713. * @parm LPCSTR | s_szProc |
  714. *
  715. * Name of calling procedure.
  716. *
  717. * @parm int | iarg |
  718. *
  719. * Parameter index. (First parameter is 1.)
  720. *
  721. * @returns
  722. *
  723. * <c S_OK> if the parameter is valid.
  724. *
  725. * <c E_INVALIDARG> if the parameter is invalid.
  726. *
  727. *****************************************************************************/
  728. STDMETHODIMP
  729. hresFullValidFl_(DWORD fl, DWORD flV, LPCSTR s_szProc, int iarg)
  730. {
  731. HRESULT hres;
  732. if ((fl & ~flV) == 0) {
  733. hres = S_OK;
  734. } else {
  735. RPF("ERROR %s: arg %d: invalid flags", s_szProc, iarg);
  736. hres = E_INVALIDARG;
  737. }
  738. return hres;
  739. }
  740. /*****************************************************************************
  741. *
  742. * @doc INTERNAL
  743. *
  744. * @func HRESULT | hresFullValidPfn_ |
  745. *
  746. * Validate that the parameter is a valid code pointer.
  747. *
  748. * Actually, <f IsValidCodePtr> on Win32 is broken, but
  749. * tough.
  750. *
  751. * @parm FARPROC | pfn |
  752. *
  753. * Procedure to "validate".
  754. *
  755. * @parm LPCSTR | s_szProc |
  756. *
  757. * Name of calling procedure.
  758. *
  759. * @parm int | iarg |
  760. *
  761. * Parameter index. (First parameter is 1.)
  762. *
  763. * @returns
  764. *
  765. * <c S_OK> if the parameter is valid.
  766. *
  767. * <c E_INVALIDARG> if the parameter is invalid.
  768. *
  769. *****************************************************************************/
  770. STDMETHODIMP
  771. hresFullValidPfn_(FARPROC pfn, LPCSTR s_szProc, int iarg)
  772. {
  773. HRESULT hres;
  774. if (!IsBadCodePtr(pfn)) {
  775. hres = S_OK;
  776. } else {
  777. RPF("ERROR %s: arg %d: invalid callback address", s_szProc, iarg);
  778. hres = E_INVALIDARG;
  779. }
  780. return hres;
  781. }
  782. /*****************************************************************************
  783. *
  784. * @doc INTERNAL
  785. *
  786. * @func HRESULT | hresFullValidPitf_ |
  787. *
  788. * Validate that the parameter is an interface pointer.
  789. *
  790. * We don't look at it very hard.
  791. *
  792. * @parm PUNK | punk |
  793. *
  794. * <i IUnknown> to "validate".
  795. *
  796. * @parm LPCSTR | s_szProc |
  797. *
  798. * Name of calling procedure.
  799. *
  800. * @parm int | iarg |
  801. *
  802. * Parameter index. (First parameter is 1.)
  803. *
  804. * @returns
  805. *
  806. * <c S_OK> if the parameter is valid.
  807. *
  808. * <c E_POINTER> if the pointer itself is bogus.
  809. *
  810. * <c E_INVALIDARG> if something inside the pointer is bogus.
  811. *
  812. *****************************************************************************/
  813. STDMETHODIMP
  814. hresFullValidPitf_(PUNK punk, LPCSTR s_szProc, int iarg)
  815. {
  816. HRESULT hres;
  817. if (!IsBadReadPtr(punk, cbX(*punk))) {
  818. IUnknownVtbl *pvtbl = punk->lpVtbl;
  819. if (!IsBadReadPtr(pvtbl, cbX(*pvtbl))) {
  820. if (!IsBadCodePtr((FARPROC)pvtbl->QueryInterface) &&
  821. !IsBadCodePtr((FARPROC)pvtbl->AddRef) &&
  822. !IsBadCodePtr((FARPROC)pvtbl->Release)) {
  823. hres = S_OK;
  824. } else {
  825. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  826. hres = E_INVALIDARG;
  827. }
  828. } else {
  829. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  830. hres = E_INVALIDARG;
  831. }
  832. } else {
  833. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  834. hres = E_POINTER;
  835. }
  836. return hres;
  837. }
  838. /*****************************************************************************
  839. *
  840. * @doc INTERNAL
  841. *
  842. * @func HRESULT | hresFullValidPcbOut_ |
  843. *
  844. * Validate that the parameter is a valid place to stick an
  845. * output result. We also smas it to zero.
  846. *
  847. * @parm PV | pcb |
  848. *
  849. * Pointer to "validate".
  850. *
  851. * @parm UINT | cb |
  852. *
  853. * Size of data pcb points to.
  854. *
  855. * @parm LPCSTR | s_szProc |
  856. *
  857. * Name of calling procedure.
  858. *
  859. * @parm int | iarg |
  860. *
  861. * Parameter index. (First parameter is 1.)
  862. *
  863. * @returns
  864. *
  865. * <c S_OK> if the parameter is valid.
  866. *
  867. * <c E_POINTER> if the pointer itself is bogus.
  868. *
  869. *****************************************************************************/
  870. STDMETHODIMP
  871. hresFullValidPcbOut_(PV pcb, UINT cb, LPCSTR s_szProc, int iarg)
  872. {
  873. HRESULT hres;
  874. if (!IsBadWritePtr(pcb, cb)) {
  875. memset(pcb,0,cb);
  876. hres = S_OK;
  877. } else {
  878. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  879. hres = E_POINTER;
  880. }
  881. return hres;
  882. }
  883. /*****************************************************************************
  884. *
  885. * @doc INTERNAL
  886. *
  887. * @func HRESULT | hresFullValidReadStrA_ |
  888. *
  889. * Validate that the parameter is a valid readable
  890. * ANSI string of maximum length <p cch>.
  891. *
  892. * Note that we cannot use <f IsBadStringPtr> because
  893. * <f IsBadStringPtr> handles the "string too long"
  894. * case incorrectly. Instead, we use <f lstrlenA>.
  895. *
  896. * @parm LPCSTR | psz |
  897. *
  898. * String to "validate".
  899. *
  900. * @parm UINT | cch |
  901. *
  902. * Maximum string length, including null terminator.
  903. *
  904. * @parm LPCSTR | s_szProc |
  905. *
  906. * Name of calling procedure.
  907. *
  908. * @parm int | iarg |
  909. *
  910. * Parameter index. (First parameter is 1.)
  911. *
  912. * @returns
  913. *
  914. * <c S_OK> if the parameter is valid.
  915. *
  916. * <c E_INVALIDARG> if the pointer itself is bogus.
  917. *
  918. *****************************************************************************/
  919. STDMETHODIMP
  920. hresFullValidReadStrA_(LPCSTR psz, UINT cch, LPCSTR s_szProc, int iarg)
  921. {
  922. HRESULT hres;
  923. UINT cchT;
  924. /*
  925. * lstrlenA returns 0 if the parameter is invalid.
  926. * It also returns 0 if the string is null.
  927. */
  928. cchT = (UINT)lstrlenA(psz);
  929. if (cchT == 0) {
  930. /*
  931. * The ambiguous case. See if it's really a null string.
  932. */
  933. if (IsBadReadPtr(psz, cbCch(1)) || psz[0]) {
  934. RPF("ERROR %s: arg %d: invalid ANSI string", s_szProc, iarg);
  935. hres = E_INVALIDARG;
  936. } else {
  937. hres = S_OK;
  938. }
  939. } else if (cchT < cch) {
  940. hres = S_OK;
  941. } else {
  942. RPF("ERROR %s: arg %d: invalid ANSI string", s_szProc, iarg);
  943. hres = E_INVALIDARG;
  944. }
  945. return hres;
  946. }
  947. /*****************************************************************************
  948. *
  949. * @doc INTERNAL
  950. *
  951. * @func HRESULT | hresFullValidReadStrW_ |
  952. *
  953. * Validate that the parameter is a valid readable
  954. * UNICODE string of maximum length <p cwch>.
  955. *
  956. * Note that we cannot use <f IsBadStringPtr> because
  957. * <f IsBadStringPtr> handles the "string too long"
  958. * case incorrectly. Instead, we use <f lstrlenW>.
  959. *
  960. * @parm LPCWSTR | pwsz |
  961. *
  962. * String to "validate".
  963. *
  964. * @parm UINT | cwch |
  965. *
  966. * Maximum string length, including null terminator.
  967. *
  968. * @parm LPCSTR | s_szProc |
  969. *
  970. * Name of calling procedure.
  971. *
  972. * @parm int | iarg |
  973. *
  974. * Parameter index. (First parameter is 1.)
  975. *
  976. * @returns
  977. *
  978. * <c S_OK> if the parameter is valid.
  979. *
  980. * <c E_INVALIDARG> if the pointer itself is bogus.
  981. *
  982. *****************************************************************************/
  983. STDMETHODIMP
  984. hresFullValidReadStrW_(LPCWSTR pwsz, UINT cwch, LPCSTR s_szProc, int iarg)
  985. {
  986. HRESULT hres;
  987. UINT cwchT;
  988. hres = E_INVALIDARG;
  989. /*
  990. * lstrlenW returns 0 if the parameter is invalid.
  991. * It also returns 0 if the string is null.
  992. */
  993. cwchT = (UINT)lstrlenW(pwsz);
  994. if (cwchT == 0) {
  995. /*
  996. * The ambiguous case. See if it's really a null string.
  997. */
  998. if (IsBadReadPtr(pwsz, cbCwch(1)) || pwsz[0]) {
  999. RPF("ERROR %s: arg %d: invalid UNICODE string", s_szProc, iarg);
  1000. hres = E_INVALIDARG;
  1001. } else {
  1002. hres = S_OK;
  1003. }
  1004. } else if (cwchT < cwch) {
  1005. hres = S_OK;
  1006. } else {
  1007. RPF("ERROR %s: arg %d: invalid UNICODE string", s_szProc, iarg);
  1008. hres = E_INVALIDARG;
  1009. }
  1010. return hres;
  1011. }
  1012. /*****************************************************************************
  1013. *
  1014. * @doc INTERNAL
  1015. *
  1016. * @func HRESULT | hresFullValidPesc_ |
  1017. *
  1018. * Validate that the parameter is a valid <t DIEFFESCAPE>
  1019. * structure.
  1020. *
  1021. * This is merely a wrapper around other validation methods.
  1022. *
  1023. * @parm LPDIEFFESCAPE | pesc |
  1024. *
  1025. * Structure to "validate".
  1026. *
  1027. * @returns
  1028. *
  1029. * <c S_OK> if the parameter is valid.
  1030. *
  1031. * <c E_INVALIDARG> if the pointer itself is bogus.
  1032. *
  1033. *****************************************************************************/
  1034. STDMETHODIMP
  1035. hresFullValidPesc_(LPDIEFFESCAPE pesc, LPCSTR s_szProc, int iarg)
  1036. {
  1037. HRESULT hres;
  1038. if (SUCCEEDED(hres = hresFullValidWriteNoScramblePxCb(pesc, DIEFFESCAPE,
  1039. iarg)) &&
  1040. SUCCEEDED(hres = hresFullValidReadPvCb(pesc->lpvInBuffer,
  1041. pesc->cbInBuffer, iarg)) &&
  1042. SUCCEEDED(hres = hresFullValidWriteNoScramblePvCb(pesc->lpvOutBuffer,
  1043. pesc->cbOutBuffer, iarg))) {
  1044. } else {
  1045. }
  1046. return hres;
  1047. }