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.

847 lines
22 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 DIRECTINPUT_VERSION < 0x0400
  109. if (pfnBad(pv, cb)) {
  110. #else
  111. if (!pfnBad(pv, LOWORD(cb))) {
  112. #endif
  113. hres = S_OK;
  114. } else {
  115. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, LOWORD(iarg));
  116. hres = E_POINTER;
  117. }
  118. return hres;
  119. }
  120. /*****************************************************************************
  121. *
  122. * @doc INTERNAL
  123. *
  124. * @func HRESULT | hresFullValidWritePvCb_ |
  125. *
  126. * Validate that a buffer is writeable. Also scrambles it
  127. * if special goo doesn't need to be done.
  128. *
  129. * @parm PV | pv |
  130. *
  131. * Buffer address.
  132. *
  133. * @parm UINT | cb |
  134. *
  135. * Size of buffer in bytes.
  136. *
  137. * @parm LPCSTR | s_szProc |
  138. *
  139. * Name of calling procedure.
  140. *
  141. * @parm int | iarg |
  142. *
  143. * Parameter index. (First parameter is 1.)
  144. *
  145. * @returns
  146. *
  147. * <c S_OK> if the parameter is valid.
  148. *
  149. * <c E_POINTER> if the parameter is invalid.
  150. *
  151. *****************************************************************************/
  152. STDMETHODIMP
  153. hresFullValidWritePvCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  154. {
  155. HRESULT hres;
  156. hres = hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadWritePtr, s_szProc, iarg);
  157. #ifdef XDEBUG
  158. if (SUCCEEDED(hres) && HIWORD(iarg) == 0) {
  159. ScrambleBuf(pv, cb);
  160. }
  161. #endif
  162. return hres;
  163. }
  164. /*****************************************************************************
  165. *
  166. * @doc INTERNAL
  167. *
  168. * @func HRESULT | hresFullValidReadPvCb_ |
  169. *
  170. * Validate that a buffer is readable.
  171. *
  172. * @parm PV | pv |
  173. *
  174. * Buffer address.
  175. *
  176. * @parm UINT | cb |
  177. *
  178. * Size of buffer in bytes.
  179. *
  180. * @parm LPCSTR | s_szProc |
  181. *
  182. * Name of calling procedure.
  183. *
  184. * @parm int | iarg |
  185. *
  186. * Parameter index. (First parameter is 1.)
  187. *
  188. * @returns
  189. *
  190. * <c S_OK> if the parameter is valid.
  191. *
  192. * <c E_POINTER> if the parameter is invalid.
  193. *
  194. *****************************************************************************/
  195. STDMETHODIMP
  196. hresFullValidReadPvCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
  197. {
  198. return hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadReadPtr, s_szProc, iarg);
  199. }
  200. /*****************************************************************************
  201. *
  202. * @doc INTERNAL
  203. *
  204. * @func HRESULT | hresFullValidPxCb_ |
  205. *
  206. * Validate that a sized structure is readable or writeable.
  207. *
  208. * @parm PCV | pv |
  209. *
  210. * Structure address. The first field of the structure must
  211. * be a <p dwSize>. If the structure is being validated for
  212. * writing, then all fields beyond the <p dwSize> are scrambled
  213. * in XDEBUG.
  214. *
  215. * @parm UINT | cbHiLo |
  216. *
  217. * Expected sizes of the structure. One valid size is in the
  218. * low word. An optional alternate valid size is in the high
  219. * word. (The alternate valid size is needed because some
  220. * structures changed size between DirectX 3 and DirectX 5.)
  221. *
  222. * @parm STRUCTPROC | pfnStruct |
  223. *
  224. * Function which validates that a structure is readable or writable.
  225. *
  226. * @parm LPCSTR | s_szProc |
  227. *
  228. * Name of calling procedure.
  229. *
  230. * @parm int | iarg |
  231. *
  232. * Parameter index. (First parameter is 1.)
  233. *
  234. * @returns
  235. *
  236. * <c S_OK> if the parameter is valid.
  237. *
  238. * <c E_POINTER> if the buffer is not readable or writeable.
  239. *
  240. * <c E_INVALIDARG> if the buffer size is incorrect.
  241. *
  242. *****************************************************************************/
  243. typedef STDMETHOD(STRUCTPROC)(PCV pv, UINT cb
  244. RD(comma LPCSTR s_szProc comma int iarg));
  245. #ifndef XDEBUG
  246. #define hresFullValidPxCb_(pv, cbHiLo, pfnStruct, z, i) \
  247. _hresFullValidPxCb_(pv, cbHiLo, pfnStruct) \
  248. #endif
  249. STDMETHODIMP
  250. hresFullValidPxCb_(PCV pv, UINT cbHiLo, STRUCTPROC pfnStruct,
  251. LPCSTR s_szProc, int iarg)
  252. {
  253. HRESULT hres;
  254. /*
  255. * Raymond frequently suffers a brain lapse and passes
  256. * a cbX(LPMUMBLE) instead of a cbX(MUMBLE).
  257. */
  258. AssertF(LOWORD(cbHiLo) != cbX(DWORD));
  259. AssertF(HIWORD(cbHiLo) != cbX(DWORD));
  260. if (!IsBadReadPtr(pv, cbX(DWORD))) {
  261. DWORD cbIn = *(LPDWORD)pv;
  262. /*
  263. * The leading "cbIn &&" prevents the HIWORD(cbHiLo)==0 case from
  264. * accidentally allowing a size of zero to sneak past.
  265. */
  266. if (cbIn && (cbIn == LOWORD(cbHiLo) || cbIn == HIWORD(cbHiLo))) {
  267. hres = pfnStruct(pv, cbIn RD(comma s_szProc comma iarg));
  268. if (SUCCEEDED(hres)) {
  269. if (HIWORD(iarg)) {
  270. ScrambleBuf(pvAddPvCb(pv, HIWORD(iarg)),
  271. cbIn - HIWORD(iarg));
  272. }
  273. }
  274. } else {
  275. RPF("ERROR %s: arg %d: invalid dwSize", s_szProc, LOWORD(iarg));
  276. hres = E_INVALIDARG;
  277. }
  278. } else {
  279. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, LOWORD(iarg));
  280. hres = E_POINTER;
  281. }
  282. return hres;
  283. }
  284. /*****************************************************************************
  285. *
  286. * @doc INTERNAL
  287. *
  288. * @func HRESULT | hresFullValidWritePxCb_ |
  289. *
  290. * Validate that a sized structure is writeable. The contents
  291. * of the structure are scrambled before returning.
  292. *
  293. * @parm PV | pv |
  294. *
  295. * Structure address. The first field of the structure must
  296. * be a <p dwSize>.
  297. *
  298. * @parm UINT | cbHiLo |
  299. *
  300. * Expected sizes of the structure. One valid size is in the
  301. * low word. An optional alternate valid size is in the high
  302. * word. (The alternate valid size is needed because some
  303. * structures changed size between DirectX 3 and DirectX 5.)
  304. *
  305. * @parm LPCSTR | s_szProc |
  306. *
  307. * Name of calling procedure.
  308. *
  309. * @parm int | iarg |
  310. *
  311. * Parameter index. (First parameter is 1.)
  312. *
  313. * @returns
  314. *
  315. * <c S_OK> if the parameter is valid.
  316. *
  317. * <c E_POINTER> if the buffer is not writeable.
  318. *
  319. * <c E_INVALIDARG> if the buffer size is incorrect.
  320. *
  321. *****************************************************************************/
  322. STDMETHODIMP
  323. hresFullValidWritePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  324. {
  325. /*
  326. * We need to distinguish hresFullValidWritePvCb_ and
  327. * _hresFullValidWritePvCb_ manually, because the preprocessor
  328. * gets confused.
  329. *
  330. * We also need to put a cbX(DWORD) into the high word of the iarg
  331. * so that the size field won't get demolished.
  332. */
  333. #ifdef XDEBUG
  334. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)hresFullValidWritePvCb_,
  335. s_szProc, MAKELONG(iarg, cbX(DWORD)));
  336. #else
  337. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)_hresFullValidWritePvCb_,
  338. s_szProc, iarg);
  339. #endif
  340. }
  341. #ifdef XDEBUG
  342. /*****************************************************************************
  343. *
  344. * @doc INTERNAL
  345. *
  346. * @func HRESULT | hresFullValidWriteNoScramblePxCb_ |
  347. *
  348. * Validate that a sized structure is writeable. The contents
  349. * of the structure are not scrambled.
  350. *
  351. * @parm PV | pv |
  352. *
  353. * Structure address. The first field of the structure must
  354. * be a <p dwSize>.
  355. *
  356. * @parm UINT | cbHiLo |
  357. *
  358. * Expected sizes of the structure. One valid size is in the
  359. * low word. An optional alternate valid size is in the high
  360. * word. (The alternate valid size is needed because some
  361. * structures changed size between DirectX 3 and DirectX 5.)
  362. *
  363. * @parm LPCSTR | s_szProc |
  364. *
  365. * Name of calling procedure.
  366. *
  367. * @parm int | iarg |
  368. *
  369. * Parameter index. (First parameter is 1.)
  370. *
  371. * @returns
  372. *
  373. * <c S_OK> if the parameter is valid.
  374. *
  375. * <c E_POINTER> if the buffer is not writeable.
  376. *
  377. * <c E_INVALIDARG> if the buffer size is incorrect.
  378. *
  379. *****************************************************************************/
  380. STDMETHODIMP
  381. hresFullValidWriteNoScramblePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  382. {
  383. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)hresFullValidWritePvCb_,
  384. s_szProc, MAKELONG(iarg, cb));
  385. }
  386. #endif
  387. /*****************************************************************************
  388. *
  389. * @doc INTERNAL
  390. *
  391. * @func HRESULT | hresFullValidReadPxCb_ |
  392. *
  393. * Validate that a sized structure is readable.
  394. *
  395. * @parm PV | pv |
  396. *
  397. * Structure address. The first field of the structure must
  398. * be a <p dwSize>.
  399. *
  400. * @parm UINT | cbHiLo |
  401. *
  402. * Expected sizes of the structure. One valid size is in the
  403. * low word. An optional alternate valid size is in the high
  404. * word. (The alternate valid size is needed because some
  405. * structures changed size between DirectX 3 and DirectX 5.)
  406. *
  407. * @parm LPCSTR | s_szProc |
  408. *
  409. * Name of calling procedure.
  410. *
  411. * @parm int | iarg |
  412. *
  413. * Parameter index. (First parameter is 1.)
  414. *
  415. * @returns
  416. *
  417. * <c S_OK> if the parameter is valid.
  418. *
  419. * <c E_POINTER> if the buffer is not readable.
  420. *
  421. * <c E_INVALIDARG> if the buffer size is incorrect.
  422. *
  423. *****************************************************************************/
  424. STDMETHODIMP
  425. hresFullValidReadPxCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
  426. {
  427. /*
  428. * We need to distinguish hresFullValidReadPvCb_ and
  429. * _hresFullValidReadPvCb_ manually, because the preprocessor
  430. * gets confused.
  431. */
  432. #ifdef XDEBUG
  433. return hresFullValidPxCb_(pv, cb, hresFullValidReadPvCb_, s_szProc, iarg);
  434. #else
  435. return hresFullValidPxCb_(pv, cb, _hresFullValidReadPvCb_, s_szProc, iarg);
  436. #endif
  437. }
  438. /*****************************************************************************
  439. *
  440. * @doc INTERNAL
  441. *
  442. * @func HRESULT | hresFullValidFl_ |
  443. *
  444. * Validate that no invalid flags are passed.
  445. *
  446. * @parm DWORD | fl |
  447. *
  448. * Flags passed by the caller.
  449. *
  450. * @parm DWORD | flV |
  451. *
  452. * Flags which are valid.
  453. *
  454. * @parm LPCSTR | s_szProc |
  455. *
  456. * Name of calling procedure.
  457. *
  458. * @parm int | iarg |
  459. *
  460. * Parameter index. (First parameter is 1.)
  461. *
  462. * @returns
  463. *
  464. * <c S_OK> if the parameter is valid.
  465. *
  466. * <c E_INVALIDARG> if the parameter is invalid.
  467. *
  468. *****************************************************************************/
  469. STDMETHODIMP
  470. hresFullValidFl_(DWORD fl, DWORD flV, LPCSTR s_szProc, int iarg)
  471. {
  472. HRESULT hres;
  473. if ((fl & ~flV) == 0) {
  474. hres = S_OK;
  475. } else {
  476. RPF("ERROR %s: arg %d: invalid flags", s_szProc, iarg);
  477. hres = E_INVALIDARG;
  478. }
  479. return hres;
  480. }
  481. /*****************************************************************************
  482. *
  483. * @doc INTERNAL
  484. *
  485. * @func HRESULT | hresFullValidPfn_ |
  486. *
  487. * Validate that the parameter is a valid code pointer.
  488. *
  489. * Actually, <f IsValidCodePtr> on Win32 is broken, but
  490. * tough.
  491. *
  492. * @parm FARPROC | pfn |
  493. *
  494. * Procedure to "validate".
  495. *
  496. * @parm LPCSTR | s_szProc |
  497. *
  498. * Name of calling procedure.
  499. *
  500. * @parm int | iarg |
  501. *
  502. * Parameter index. (First parameter is 1.)
  503. *
  504. * @returns
  505. *
  506. * <c S_OK> if the parameter is valid.
  507. *
  508. * <c E_INVALIDARG> if the parameter is invalid.
  509. *
  510. *****************************************************************************/
  511. STDMETHODIMP
  512. hresFullValidPfn_(FARPROC pfn, LPCSTR s_szProc, int iarg)
  513. {
  514. HRESULT hres;
  515. if (!IsBadCodePtr(pfn)) {
  516. hres = S_OK;
  517. } else {
  518. RPF("ERROR %s: arg %d: invalid callback address", s_szProc, iarg);
  519. hres = E_INVALIDARG;
  520. }
  521. return hres;
  522. }
  523. /*****************************************************************************
  524. *
  525. * @doc INTERNAL
  526. *
  527. * @func HRESULT | hresFullValidPitf_ |
  528. *
  529. * Validate that the parameter is an interface pointer.
  530. *
  531. * We don't look at it very hard.
  532. *
  533. * @parm PUNK | punk |
  534. *
  535. * <i IUnknown> to "validate".
  536. *
  537. * @parm LPCSTR | s_szProc |
  538. *
  539. * Name of calling procedure.
  540. *
  541. * @parm int | iarg |
  542. *
  543. * Parameter index. (First parameter is 1.)
  544. *
  545. * @returns
  546. *
  547. * <c S_OK> if the parameter is valid.
  548. *
  549. * <c E_POINTER> if the pointer itself is bogus.
  550. *
  551. * <c E_INVALIDARG> if something inside the pointer is bogus.
  552. *
  553. *****************************************************************************/
  554. STDMETHODIMP
  555. hresFullValidPitf_(PUNK punk, LPCSTR s_szProc, int iarg)
  556. {
  557. HRESULT hres;
  558. if (!IsBadReadPtr(punk, cbX(*punk))) {
  559. IUnknownVtbl *pvtbl = punk->lpVtbl;
  560. if (!IsBadReadPtr(pvtbl, cbX(*pvtbl))) {
  561. if (!IsBadCodePtr((FARPROC)pvtbl->QueryInterface) &&
  562. !IsBadCodePtr((FARPROC)pvtbl->AddRef) &&
  563. !IsBadCodePtr((FARPROC)pvtbl->Release)) {
  564. hres = S_OK;
  565. } else {
  566. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  567. hres = E_INVALIDARG;
  568. }
  569. } else {
  570. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  571. hres = E_INVALIDARG;
  572. }
  573. } else {
  574. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  575. hres = E_POINTER;
  576. }
  577. return hres;
  578. }
  579. /*****************************************************************************
  580. *
  581. * @doc INTERNAL
  582. *
  583. * @func HRESULT | hresFullValidPcbOut_ |
  584. *
  585. * Validate that the parameter is a valid place to stick an
  586. * output result. We also smas it to zero.
  587. *
  588. * @parm PV | pcb |
  589. *
  590. * Pointer to "validate".
  591. *
  592. * @parm UINT | cb |
  593. *
  594. * Size of data pcb points to.
  595. *
  596. * @parm LPCSTR | s_szProc |
  597. *
  598. * Name of calling procedure.
  599. *
  600. * @parm int | iarg |
  601. *
  602. * Parameter index. (First parameter is 1.)
  603. *
  604. * @returns
  605. *
  606. * <c S_OK> if the parameter is valid.
  607. *
  608. * <c E_POINTER> if the pointer itself is bogus.
  609. *
  610. *****************************************************************************/
  611. STDMETHODIMP
  612. hresFullValidPcbOut_(PV pcb, UINT cb, LPCSTR s_szProc, int iarg)
  613. {
  614. HRESULT hres;
  615. if (!IsBadWritePtr(pcb, cb)) {
  616. memset(pcb,0,cb);
  617. hres = S_OK;
  618. } else {
  619. RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  620. hres = E_POINTER;
  621. }
  622. return hres;
  623. }
  624. /*****************************************************************************
  625. *
  626. * @doc INTERNAL
  627. *
  628. * @func HRESULT | hresFullValidReadStrA_ |
  629. *
  630. * Validate that the parameter is a valid readable
  631. * ANSI string of maximum length <p cch>.
  632. *
  633. * Note that we cannot use <f IsBadStringPtr> because
  634. * <f IsBadStringPtr> handles the "string too long"
  635. * case incorrectly. Instead, we use <f lstrlenA>.
  636. *
  637. * @parm LPCSTR | psz |
  638. *
  639. * String to "validate".
  640. *
  641. * @parm UINT | cch |
  642. *
  643. * Maximum string length, including null terminator.
  644. *
  645. * @parm LPCSTR | s_szProc |
  646. *
  647. * Name of calling procedure.
  648. *
  649. * @parm int | iarg |
  650. *
  651. * Parameter index. (First parameter is 1.)
  652. *
  653. * @returns
  654. *
  655. * <c S_OK> if the parameter is valid.
  656. *
  657. * <c E_INVALIDARG> if the pointer itself is bogus.
  658. *
  659. *****************************************************************************/
  660. STDMETHODIMP
  661. hresFullValidReadStrA_(LPCSTR psz, UINT cch, LPCSTR s_szProc, int iarg)
  662. {
  663. HRESULT hres;
  664. UINT cchT;
  665. /*
  666. * lstrlenA returns 0 if the parameter is invalid.
  667. * It also returns 0 if the string is null.
  668. */
  669. cchT = (UINT)lstrlenA(psz);
  670. if (cchT == 0) {
  671. /*
  672. * The ambiguous case. See if it's really a null string.
  673. */
  674. if (IsBadReadPtr(psz, cbCch(1)) || psz[0]) {
  675. RPF("ERROR %s: arg %d: invalid ANSI string", s_szProc, iarg);
  676. hres = E_INVALIDARG;
  677. } else {
  678. hres = S_OK;
  679. }
  680. } else if (cchT < cch) {
  681. hres = S_OK;
  682. } else {
  683. RPF("ERROR %s: arg %d: invalid ANSI string", s_szProc, iarg);
  684. hres = E_INVALIDARG;
  685. }
  686. return hres;
  687. }
  688. /*****************************************************************************
  689. *
  690. * @doc INTERNAL
  691. *
  692. * @func HRESULT | hresFullValidReadStrW_ |
  693. *
  694. * Validate that the parameter is a valid readable
  695. * UNICODE string of maximum length <p cwch>.
  696. *
  697. * Note that we cannot use <f IsBadStringPtr> because
  698. * <f IsBadStringPtr> handles the "string too long"
  699. * case incorrectly. Instead, we use <f lstrlenW>.
  700. *
  701. * @parm LPCWSTR | pwsz |
  702. *
  703. * String to "validate".
  704. *
  705. * @parm UINT | cwch |
  706. *
  707. * Maximum string length, including null terminator.
  708. *
  709. * @parm LPCSTR | s_szProc |
  710. *
  711. * Name of calling procedure.
  712. *
  713. * @parm int | iarg |
  714. *
  715. * Parameter index. (First parameter is 1.)
  716. *
  717. * @returns
  718. *
  719. * <c S_OK> if the parameter is valid.
  720. *
  721. * <c E_INVALIDARG> if the pointer itself is bogus.
  722. *
  723. *****************************************************************************/
  724. STDMETHODIMP
  725. hresFullValidReadStrW_(LPCWSTR pwsz, UINT cwch, LPCSTR s_szProc, int iarg)
  726. {
  727. HRESULT hres;
  728. UINT cwchT;
  729. hres = E_INVALIDARG;
  730. /*
  731. * lstrlenW returns 0 if the parameter is invalid.
  732. * It also returns 0 if the string is null.
  733. */
  734. cwchT = (UINT)lstrlenW(pwsz);
  735. if (cwchT == 0) {
  736. /*
  737. * The ambiguous case. See if it's really a null string.
  738. */
  739. if (IsBadReadPtr(pwsz, cbCwch(1)) || pwsz[0]) {
  740. RPF("ERROR %s: arg %d: invalid UNICODE string", s_szProc, iarg);
  741. hres = E_INVALIDARG;
  742. } else {
  743. hres = S_OK;
  744. }
  745. } else if (cwchT < cwch) {
  746. hres = S_OK;
  747. } else {
  748. RPF("ERROR %s: arg %d: invalid UNICODE string", s_szProc, iarg);
  749. hres = E_INVALIDARG;
  750. }
  751. return hres;
  752. }
  753. /*****************************************************************************
  754. *
  755. * @doc INTERNAL
  756. *
  757. * @func HRESULT | hresFullValidPesc_ |
  758. *
  759. * Validate that the parameter is a valid <t DIEFFESCAPE>
  760. * structure.
  761. *
  762. * This is merely a wrapper around other validation methods.
  763. *
  764. * @parm LPDIEFFESCAPE | pesc |
  765. *
  766. * Structure to "validate".
  767. *
  768. * @returns
  769. *
  770. * <c S_OK> if the parameter is valid.
  771. *
  772. * <c E_INVALIDARG> if the pointer itself is bogus.
  773. *
  774. *****************************************************************************/
  775. STDMETHODIMP
  776. hresFullValidPesc_(LPDIEFFESCAPE pesc, LPCSTR s_szProc, int iarg)
  777. {
  778. HRESULT hres;
  779. if (SUCCEEDED(hres = hresFullValidWriteNoScramblePxCb(pesc, DIEFFESCAPE,
  780. iarg)) &&
  781. SUCCEEDED(hres = hresFullValidReadPvCb(pesc->lpvInBuffer,
  782. pesc->cbInBuffer, iarg)) &&
  783. SUCCEEDED(hres = hresFullValidWriteNoScramblePvCb(pesc->lpvOutBuffer,
  784. pesc->cbOutBuffer, iarg))) {
  785. } else {
  786. }
  787. return hres;
  788. }