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.

678 lines
16 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. /*
  22. #include "wia.h"
  23. #include <stilog.h>
  24. #include <stiregi.h>
  25. #include <sti.h>
  26. #include <stierr.h>
  27. #include <stiusd.h>
  28. #include "stipriv.h"
  29. #include "debug.h"
  30. */
  31. #include "sticomm.h"
  32. /*****************************************************************************
  33. *
  34. * @doc INTERNAL
  35. *
  36. * @func HRESULT | hresValidInstanceVer |
  37. *
  38. * Check the <t HINSTANCE> and version number received from
  39. * an application.
  40. *
  41. * @parm HINSTANCE | hinst |
  42. *
  43. * Purported module instance handle.
  44. *
  45. * @parm DWORD | dwVersion |
  46. *
  47. * Version the application is asking for.
  48. *
  49. *****************************************************************************/
  50. HRESULT EXTERNAL
  51. hresValidInstanceVer_(HINSTANCE hinst, DWORD dwVersion, LPCSTR s_szProc)
  52. {
  53. HRESULT hres = S_OK;
  54. TCHAR tszScratch[MAX_PATH];
  55. DWORD dwRealVersion = (dwVersion & ~STI_VERSION_FLAG_MASK);
  56. if (GetModuleFileName(hinst, tszScratch, cA(tszScratch) - 1)) {
  57. if (( dwRealVersion <= STI_VERSION) &&(dwRealVersion >= STI_VERSION_MIN_ALLOWED)){
  58. hres = S_OK;
  59. } else {
  60. hres = STIERR_OLD_VERSION;
  61. }
  62. } else {
  63. hres = E_INVALIDARG;
  64. }
  65. return hres;
  66. }
  67. /*****************************************************************************
  68. *
  69. * @doc INTERNAL
  70. *
  71. * @func HRESULT | hresFullValidHwnd |
  72. *
  73. * Validate a window handle completely.
  74. *
  75. * @parm HWND | hwnd |
  76. *
  77. * Window handle to validate.
  78. *
  79. * @parm LPCSTR | s_szProc |
  80. *
  81. * Name of calling procedure.
  82. *
  83. * @parm int | iarg |
  84. *
  85. * Parameter index. (First parameter is 1.)
  86. *
  87. * @returns
  88. *
  89. * <c S_OK> if the parameter is valid.
  90. *
  91. * <c E_HANDLE> if the parameter is invalid.
  92. *
  93. *****************************************************************************/
  94. STDMETHODIMP
  95. hresFullValidHwnd_(HWND hwnd, LPCSTR s_szProc, int iarg)
  96. {
  97. HRESULT hres;
  98. if (IsWindow(hwnd)) {
  99. hres = S_OK;
  100. } else {
  101. // RPF("ERROR %s: arg %d: not a window handle", s_szProc, iarg);
  102. hres = E_HANDLE;
  103. }
  104. return hres;
  105. }
  106. /*****************************************************************************
  107. *
  108. * @doc INTERNAL
  109. *
  110. * @func HRESULT | hresValidHandle |
  111. *
  112. * Validate a generic handle completely.
  113. *
  114. * @parm HANDLE | handle |
  115. *
  116. * Handle to validate.
  117. *
  118. * @returns
  119. *
  120. * <c S_OK> if the parameter is valid.
  121. *
  122. * <c E_HANDLE> if the parameter is invalid.
  123. *
  124. *****************************************************************************/
  125. STDMETHODIMP
  126. hresValidHandle(HANDLE handle)
  127. {
  128. HANDLE hTemp;
  129. HRESULT hres;
  130. hres = S_OK;
  131. hTemp = INVALID_HANDLE_VALUE;
  132. // Validate the handle by calling DuplicateHandle. This function
  133. // shouldn't change the state of the handle at all (except some
  134. // internal ref count or something). So if it succeeds, then we
  135. // know we have a valid handle, otherwise, we will call it invalid.
  136. if(!DuplicateHandle(GetCurrentProcess(), handle,
  137. GetCurrentProcess(), &hTemp,
  138. DUPLICATE_SAME_ACCESS,
  139. FALSE,
  140. DUPLICATE_SAME_ACCESS)) {
  141. hres = E_HANDLE;
  142. }
  143. // Now close our duplicate handle
  144. CloseHandle(hTemp);
  145. return hres;
  146. }
  147. /*****************************************************************************
  148. *
  149. * @doc INTERNAL
  150. *
  151. * @func HRESULT | hresFullValidPvCb_ |
  152. *
  153. * Validate that a buffer is readable or writeable.
  154. *
  155. * @parm PV | pv |
  156. *
  157. * Buffer address.
  158. *
  159. * @parm UINT | cb |
  160. *
  161. * Size of buffer in bytes.
  162. *
  163. * @parm PFNBAD | pfnBad |
  164. *
  165. * Function that determines whether the buffer is bad.
  166. * Should be <f IsBadReadPtr> or <f IsBadWritePtr>.
  167. *
  168. * @parm LPCSTR | s_szProc |
  169. *
  170. * Name of calling procedure.
  171. *
  172. * @parm int | iarg |
  173. *
  174. * Parameter index. (First parameter is 1.)
  175. * High word indicates how many bytes should not be
  176. * scrambled.
  177. *
  178. * @returns
  179. *
  180. * <c S_OK> if the parameter is valid.
  181. *
  182. * <c E_POINTER> if the parameter is invalid.
  183. *
  184. *****************************************************************************/
  185. typedef BOOL (WINAPI *PFNBAD)(PCV pv, UINT_PTR cb);
  186. #ifndef MAXDEBUG
  187. #define hresFullValidPvCb_(pv, cb, pfnBad, z, i) \
  188. _hresFullValidPvCb_(pv, cb, pfnBad) \
  189. #endif
  190. STDMETHODIMP
  191. hresFullValidPvCb_(PCV pv, UINT cb, PFNBAD pfnBad, LPCSTR s_szProc, int iarg)
  192. {
  193. HRESULT hres;
  194. if (!pfnBad(pv, cb)) {
  195. hres = S_OK;
  196. } else {
  197. RPF("ERROR %s: arg %d: invalid pointer", "", LOWORD(iarg));
  198. hres = E_POINTER;
  199. }
  200. return hres;
  201. }
  202. /*****************************************************************************
  203. *
  204. * @doc INTERNAL
  205. *
  206. * @func HRESULT | hresFullValidWritePvCb_ |
  207. *
  208. * Validate that a buffer is writeable. Also scrambles it
  209. * if special goo doesn't need to be done.
  210. *
  211. * @parm PV | pv |
  212. *
  213. * Buffer address.
  214. *
  215. * @parm UINT | cb |
  216. *
  217. * Size of buffer in bytes.
  218. *
  219. * @parm LPCSTR | s_szProc |
  220. *
  221. * Name of calling procedure.
  222. *
  223. * @parm int | iarg |
  224. *
  225. * Parameter index. (First parameter is 1.)
  226. *
  227. * @returns
  228. *
  229. * <c S_OK> if the parameter is valid.
  230. *
  231. * <c E_POINTER> if the parameter is invalid.
  232. *
  233. *****************************************************************************/
  234. STDMETHODIMP
  235. hresFullValidWritePvCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  236. {
  237. HRESULT hres;
  238. hres = hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadWritePtr, s_szProc, iarg);
  239. #ifdef MAXDEBUG
  240. if (SUCCEEDED(hres) && HIWORD(iarg) == 0) {
  241. ScrambleBuf(pv, cb);
  242. }
  243. #endif
  244. return hres;
  245. }
  246. /*****************************************************************************
  247. *
  248. * @doc INTERNAL
  249. *
  250. * @func HRESULT | hresFullValidReadPvCb_ |
  251. *
  252. * Validate that a buffer is readable.
  253. *
  254. * @parm PV | pv |
  255. *
  256. * Buffer address.
  257. *
  258. * @parm UINT | cb |
  259. *
  260. * Size of buffer in bytes.
  261. *
  262. * @parm LPCSTR | s_szProc |
  263. *
  264. * Name of calling procedure.
  265. *
  266. * @parm int | iarg |
  267. *
  268. * Parameter index. (First parameter is 1.)
  269. *
  270. * @returns
  271. *
  272. * <c S_OK> if the parameter is valid.
  273. *
  274. * <c E_POINTER> if the parameter is invalid.
  275. *
  276. *****************************************************************************/
  277. STDMETHODIMP
  278. hresFullValidReadPvCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
  279. {
  280. return hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadReadPtr, s_szProc, iarg);
  281. }
  282. /*****************************************************************************
  283. *
  284. * @doc INTERNAL
  285. *
  286. * @func HRESULT | hresFullValidPxCb_ |
  287. *
  288. * Validate that a sized structure is readable or writeable.
  289. *
  290. * @parm PCV | pv |
  291. *
  292. * Structure address. The first field of the structure must
  293. * be a <p dwSize>. If the structure is being validated for
  294. * writing, then all fields beyond the <p dwSize> are scrambled
  295. * in MAXDEBUG.
  296. *
  297. * @parm UINT | cb |
  298. *
  299. * Expected size of the structure.
  300. *
  301. * @parm STRUCTPROC | pfnStruct |
  302. *
  303. * Function which validates that a structure is readable or writable.
  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 readable or writeable.
  318. *
  319. * <c E_INVALIDARG> if the buffer size is incorrect.
  320. *
  321. *****************************************************************************/
  322. typedef STDMETHOD(STRUCTPROC)(PCV pv, UINT cb
  323. RD(comma LPCSTR s_szProc comma int iarg));
  324. #ifndef MAXDEBUG
  325. #define hresFullValidPxCb_(pv, cb, pfnStruct, z, i) \
  326. _hresFullValidPxCb_(pv, cb, pfnStruct) \
  327. #endif
  328. STDMETHODIMP
  329. hresFullValidPxCb_(PCV pv, UINT cb, STRUCTPROC pfnStruct,
  330. LPCSTR s_szProc, int iarg)
  331. {
  332. HRESULT hres;
  333. hres = pfnStruct(pv, cb RD(comma s_szProc comma iarg));
  334. if (SUCCEEDED(hres)) {
  335. if (*(LPDWORD)pv == cb) {
  336. if (HIWORD(iarg)) {
  337. ScrambleBuf(pvAddPvCb(pv, HIWORD(iarg)), cb - HIWORD(iarg));
  338. }
  339. } else {
  340. //RPF("ERROR %s: arg %d: invalid dwSize", s_szProc, LOWORD(iarg));
  341. hres = E_INVALIDARG;
  342. }
  343. }
  344. return hres;
  345. }
  346. /*****************************************************************************
  347. *
  348. * @doc INTERNAL
  349. *
  350. * @func HRESULT | hresFullValidWritePxCb_ |
  351. *
  352. * Validate that a sized structure is writeable.
  353. *
  354. * @parm PV | pv |
  355. *
  356. * Structure address. The first field of the structure must
  357. * be a <p dwSize>.
  358. *
  359. * @parm UINT | cb |
  360. *
  361. * Expected size of the structure.
  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. hresFullValidWritePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
  382. {
  383. /*
  384. * We need to distinguish hresFullValidWritePvCb_ and
  385. * _hresFullValidWritePvCb_ manually, because the preprocessor
  386. * gets confused.
  387. *
  388. * We also need to put a cbX(DWORD) into the high word of the iarg
  389. * so that the size field won't get demolished.
  390. */
  391. #ifdef MAXDEBUG
  392. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)hresFullValidWritePvCb_,
  393. s_szProc, MAKELONG(iarg, cbX(DWORD)));
  394. #else
  395. return hresFullValidPxCb_(pv, cb, (STRUCTPROC)_hresFullValidWritePvCb_,
  396. s_szProc, iarg);
  397. #endif
  398. }
  399. /*****************************************************************************
  400. *
  401. * @doc INTERNAL
  402. *
  403. * @func HRESULT | hresFullValidReadPxCb_ |
  404. *
  405. * Validate that a sized structure is readable.
  406. *
  407. * @parm PV | pv |
  408. *
  409. * Structure address. The first field of the structure must
  410. * be a <p dwSize>.
  411. *
  412. * @parm UINT | cb |
  413. *
  414. * Expected size of the structure.
  415. *
  416. * @parm LPCSTR | s_szProc |
  417. *
  418. * Name of calling procedure.
  419. *
  420. * @parm int | iarg |
  421. *
  422. * Parameter index. (First parameter is 1.)
  423. *
  424. * @returns
  425. *
  426. * <c S_OK> if the parameter is valid.
  427. *
  428. * <c E_POINTER> if the buffer is not readable.
  429. *
  430. * <c E_INVALIDARG> if the buffer size is incorrect.
  431. *
  432. *****************************************************************************/
  433. STDMETHODIMP
  434. hresFullValidReadPxCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
  435. {
  436. /*
  437. * We need to distinguish hresFullValidReadPvCb_ and
  438. * _hresFullValidReadPvCb_ manually, because the preprocessor
  439. * gets confused.
  440. */
  441. #ifdef MAXDEBUG
  442. return hresFullValidPxCb_(pv, cb, hresFullValidReadPvCb_, s_szProc, iarg);
  443. #else
  444. return hresFullValidPxCb_(pv, cb, _hresFullValidReadPvCb_, s_szProc, iarg);
  445. #endif
  446. }
  447. /*****************************************************************************
  448. *
  449. * @doc INTERNAL
  450. *
  451. * @func HRESULT | hresFullValidFl_ |
  452. *
  453. * Validate that no invalid flags are passed.
  454. *
  455. * @parm DWORD | fl |
  456. *
  457. * Flags passed by the caller.
  458. *
  459. * @parm DWORD | flV |
  460. *
  461. * Flags which are valid.
  462. *
  463. * @parm LPCSTR | s_szProc |
  464. *
  465. * Name of calling procedure.
  466. *
  467. * @parm int | iarg |
  468. *
  469. * Parameter index. (First parameter is 1.)
  470. *
  471. * @returns
  472. *
  473. * <c S_OK> if the parameter is valid.
  474. *
  475. * <c E_INVALIDARG> if the parameter is invalid.
  476. *
  477. *****************************************************************************/
  478. STDMETHODIMP
  479. hresFullValidFl_(DWORD fl, DWORD flV, LPCSTR s_szProc, int iarg)
  480. {
  481. HRESULT hres;
  482. if ((fl & ~flV) == 0) {
  483. hres = S_OK;
  484. } else {
  485. //RPF("ERROR %s: arg %d: invalid flags", s_szProc, iarg);
  486. hres = E_INVALIDARG;
  487. }
  488. return hres;
  489. }
  490. /*****************************************************************************
  491. *
  492. * @doc INTERNAL
  493. *
  494. * @func HRESULT | hresFullValidPfn_ |
  495. *
  496. * Validate that the parameter is a valid code pointer.
  497. *
  498. * Actually, <f IsValidCodePtr> on Win32 is broken, but
  499. * tough.
  500. *
  501. * @parm FARPROC | pfn |
  502. *
  503. * Procedure to "validate".
  504. *
  505. * @parm LPCSTR | s_szProc |
  506. *
  507. * Name of calling procedure.
  508. *
  509. * @parm int | iarg |
  510. *
  511. * Parameter index. (First parameter is 1.)
  512. *
  513. * @returns
  514. *
  515. * <c S_OK> if the parameter is valid.
  516. *
  517. * <c E_INVALIDARG> if the parameter is invalid.
  518. *
  519. *****************************************************************************/
  520. STDMETHODIMP
  521. hresFullValidPfn_(FARPROC pfn, LPCSTR s_szProc, int iarg)
  522. {
  523. HRESULT hres;
  524. if (!IsBadCodePtr(pfn)) {
  525. hres = S_OK;
  526. } else {
  527. //RPF("ERROR %s: arg %d: invalid callback address", s_szProc, iarg);
  528. hres = E_INVALIDARG;
  529. }
  530. return hres;
  531. }
  532. /*****************************************************************************
  533. *
  534. * @doc INTERNAL
  535. *
  536. * @func HRESULT | hresFullValidPitf_ |
  537. *
  538. * Validate that the parameter is an interface pointer.
  539. *
  540. * We don't look at it very hard.
  541. *
  542. * @parm PUNK | punk |
  543. *
  544. * <i IUnknown> to "validate".
  545. *
  546. * @parm LPCSTR | s_szProc |
  547. *
  548. * Name of calling procedure.
  549. *
  550. * @parm int | iarg |
  551. *
  552. * Parameter index. (First parameter is 1.)
  553. *
  554. * @returns
  555. *
  556. * <c S_OK> if the parameter is valid.
  557. *
  558. * <c E_POINTER> if the pointer itself is bogus.
  559. *
  560. * <c E_INVALIDARG> if something inside the pointer is bogus.
  561. *
  562. *****************************************************************************/
  563. STDMETHODIMP
  564. hresFullValidPitf_(PUNK punk, LPCSTR s_szProc, int iarg)
  565. {
  566. HRESULT hres;
  567. if (!IsBadReadPtr(punk, cbX(DWORD))) {
  568. IUnknownVtbl *pvtbl = punk->lpVtbl;
  569. if (!IsBadReadPtr(pvtbl, 3 * cbX(DWORD))) {
  570. if (!IsBadCodePtr((FARPROC)pvtbl->QueryInterface) &&
  571. !IsBadCodePtr((FARPROC)pvtbl->AddRef) &&
  572. !IsBadCodePtr((FARPROC)pvtbl->Release)) {
  573. hres = S_OK;
  574. } else {
  575. //RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  576. hres = E_INVALIDARG;
  577. }
  578. } else {
  579. //RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  580. hres = E_INVALIDARG;
  581. }
  582. } else {
  583. //RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  584. hres = E_POINTER;
  585. }
  586. return hres;
  587. }
  588. /*****************************************************************************
  589. *
  590. * @doc INTERNAL
  591. *
  592. * @func HRESULT | hresFullValidPdwOut_ |
  593. *
  594. * Validate that the parameter is a valid place to stick an
  595. * output result. We also smas it to zero.
  596. *
  597. * @parm PV | pdw |
  598. *
  599. * Pointer to "validate".
  600. *
  601. * @parm LPCSTR | s_szProc |
  602. *
  603. * Name of calling procedure.
  604. *
  605. * @parm int | iarg |
  606. *
  607. * Parameter index. (First parameter is 1.)
  608. *
  609. * @returns
  610. *
  611. * <c S_OK> if the parameter is valid.
  612. *
  613. * <c E_POINTER> if the pointer itself is bogus.
  614. *
  615. *****************************************************************************/
  616. STDMETHODIMP
  617. hresFullValidPdwOut_(PV pdw, LPCSTR s_szProc, int iarg)
  618. {
  619. HRESULT hres;
  620. if (!IsBadWritePtr(pdw, 4)) {
  621. *(LPDWORD)pdw = 0;
  622. hres = S_OK;
  623. } else {
  624. //RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
  625. hres = E_POINTER;
  626. }
  627. return hres;
  628. }