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

/*****************************************************************************
*
* Valid.c
*
* Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
*
* Abstract:
*
* Validate services. On a validation error that would not have
* been caught in retail, we throw an exception.
*
* Contents:
*
* fFullValidPhwnd
* fFullValidPpdw
* fFullValidPpfn
* fFullValidReadPx
* fFullValidWritePx
*
*****************************************************************************/
/*
#include "wia.h"
#include <stilog.h>
#include <stiregi.h>
#include <sti.h>
#include <stierr.h>
#include <stiusd.h>
#include "stipriv.h"
#include "debug.h"
*/
#include "sticomm.h"
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresValidInstanceVer |
*
* Check the <t HINSTANCE> and version number received from
* an application.
*
* @parm HINSTANCE | hinst |
*
* Purported module instance handle.
*
* @parm DWORD | dwVersion |
*
* Version the application is asking for.
*
*****************************************************************************/
HRESULT EXTERNAL
hresValidInstanceVer_(HINSTANCE hinst, DWORD dwVersion, LPCSTR s_szProc)
{
HRESULT hres = S_OK;
TCHAR tszScratch[MAX_PATH];
DWORD dwRealVersion = (dwVersion & ~STI_VERSION_FLAG_MASK);
if (GetModuleFileName(hinst, tszScratch, cA(tszScratch) - 1)) {
if (( dwRealVersion <= STI_VERSION) &&(dwRealVersion >= STI_VERSION_MIN_ALLOWED)){
hres = S_OK;
} else {
hres = STIERR_OLD_VERSION;
}
} else {
hres = E_INVALIDARG;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidHwnd |
*
* Validate a window handle completely.
*
* @parm HWND | hwnd |
*
* Window handle to validate.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_HANDLE> if the parameter is invalid.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidHwnd_(HWND hwnd, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
if (IsWindow(hwnd)) {
hres = S_OK;
} else {
// RPF("ERROR %s: arg %d: not a window handle", s_szProc, iarg);
hres = E_HANDLE;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresValidHandle |
*
* Validate a generic handle completely.
*
* @parm HANDLE | handle |
*
* Handle to validate.
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_HANDLE> if the parameter is invalid.
*
*****************************************************************************/
STDMETHODIMP
hresValidHandle(HANDLE handle)
{
HANDLE hTemp;
HRESULT hres;
hres = S_OK;
hTemp = INVALID_HANDLE_VALUE;
// Validate the handle by calling DuplicateHandle. This function
// shouldn't change the state of the handle at all (except some
// internal ref count or something). So if it succeeds, then we
// know we have a valid handle, otherwise, we will call it invalid.
if(!DuplicateHandle(GetCurrentProcess(), handle,
GetCurrentProcess(), &hTemp,
DUPLICATE_SAME_ACCESS,
FALSE,
DUPLICATE_SAME_ACCESS)) {
hres = E_HANDLE;
}
// Now close our duplicate handle
CloseHandle(hTemp);
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidPvCb_ |
*
* Validate that a buffer is readable or writeable.
*
* @parm PV | pv |
*
* Buffer address.
*
* @parm UINT | cb |
*
* Size of buffer in bytes.
*
* @parm PFNBAD | pfnBad |
*
* Function that determines whether the buffer is bad.
* Should be <f IsBadReadPtr> or <f IsBadWritePtr>.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
* High word indicates how many bytes should not be
* scrambled.
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the parameter is invalid.
*
*****************************************************************************/
typedef BOOL (WINAPI *PFNBAD)(PCV pv, UINT_PTR cb);
#ifndef MAXDEBUG
#define hresFullValidPvCb_(pv, cb, pfnBad, z, i) \
_hresFullValidPvCb_(pv, cb, pfnBad) \
#endif
STDMETHODIMP
hresFullValidPvCb_(PCV pv, UINT cb, PFNBAD pfnBad, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
if (!pfnBad(pv, cb)) {
hres = S_OK;
} else {
RPF("ERROR %s: arg %d: invalid pointer", "", LOWORD(iarg));
hres = E_POINTER;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidWritePvCb_ |
*
* Validate that a buffer is writeable. Also scrambles it
* if special goo doesn't need to be done.
*
* @parm PV | pv |
*
* Buffer address.
*
* @parm UINT | cb |
*
* Size of buffer in bytes.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the parameter is invalid.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidWritePvCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
hres = hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadWritePtr, s_szProc, iarg);
#ifdef MAXDEBUG
if (SUCCEEDED(hres) && HIWORD(iarg) == 0) {
ScrambleBuf(pv, cb);
}
#endif
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidReadPvCb_ |
*
* Validate that a buffer is readable.
*
* @parm PV | pv |
*
* Buffer address.
*
* @parm UINT | cb |
*
* Size of buffer in bytes.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the parameter is invalid.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidReadPvCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
{
return hresFullValidPvCb_(pv, cb, (PFNBAD)IsBadReadPtr, s_szProc, iarg);
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidPxCb_ |
*
* Validate that a sized structure is readable or writeable.
*
* @parm PCV | pv |
*
* Structure address. The first field of the structure must
* be a <p dwSize>. If the structure is being validated for
* writing, then all fields beyond the <p dwSize> are scrambled
* in MAXDEBUG.
*
* @parm UINT | cb |
*
* Expected size of the structure.
*
* @parm STRUCTPROC | pfnStruct |
*
* Function which validates that a structure is readable or writable.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the buffer is not readable or writeable.
*
* <c E_INVALIDARG> if the buffer size is incorrect.
*
*****************************************************************************/
typedef STDMETHOD(STRUCTPROC)(PCV pv, UINT cb
RD(comma LPCSTR s_szProc comma int iarg));
#ifndef MAXDEBUG
#define hresFullValidPxCb_(pv, cb, pfnStruct, z, i) \
_hresFullValidPxCb_(pv, cb, pfnStruct) \
#endif
STDMETHODIMP
hresFullValidPxCb_(PCV pv, UINT cb, STRUCTPROC pfnStruct,
LPCSTR s_szProc, int iarg)
{
HRESULT hres;
hres = pfnStruct(pv, cb RD(comma s_szProc comma iarg));
if (SUCCEEDED(hres)) {
if (*(LPDWORD)pv == cb) {
if (HIWORD(iarg)) {
ScrambleBuf(pvAddPvCb(pv, HIWORD(iarg)), cb - HIWORD(iarg));
}
} else {
//RPF("ERROR %s: arg %d: invalid dwSize", s_szProc, LOWORD(iarg));
hres = E_INVALIDARG;
}
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidWritePxCb_ |
*
* Validate that a sized structure is writeable.
*
* @parm PV | pv |
*
* Structure address. The first field of the structure must
* be a <p dwSize>.
*
* @parm UINT | cb |
*
* Expected size of the structure.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the buffer is not writeable.
*
* <c E_INVALIDARG> if the buffer size is incorrect.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidWritePxCb_(PV pv, UINT cb, LPCSTR s_szProc, int iarg)
{
/*
* We need to distinguish hresFullValidWritePvCb_ and
* _hresFullValidWritePvCb_ manually, because the preprocessor
* gets confused.
*
* We also need to put a cbX(DWORD) into the high word of the iarg
* so that the size field won't get demolished.
*/
#ifdef MAXDEBUG
return hresFullValidPxCb_(pv, cb, (STRUCTPROC)hresFullValidWritePvCb_,
s_szProc, MAKELONG(iarg, cbX(DWORD)));
#else
return hresFullValidPxCb_(pv, cb, (STRUCTPROC)_hresFullValidWritePvCb_,
s_szProc, iarg);
#endif
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidReadPxCb_ |
*
* Validate that a sized structure is readable.
*
* @parm PV | pv |
*
* Structure address. The first field of the structure must
* be a <p dwSize>.
*
* @parm UINT | cb |
*
* Expected size of the structure.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the buffer is not readable.
*
* <c E_INVALIDARG> if the buffer size is incorrect.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidReadPxCb_(PCV pv, UINT cb, LPCSTR s_szProc, int iarg)
{
/*
* We need to distinguish hresFullValidReadPvCb_ and
* _hresFullValidReadPvCb_ manually, because the preprocessor
* gets confused.
*/
#ifdef MAXDEBUG
return hresFullValidPxCb_(pv, cb, hresFullValidReadPvCb_, s_szProc, iarg);
#else
return hresFullValidPxCb_(pv, cb, _hresFullValidReadPvCb_, s_szProc, iarg);
#endif
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidFl_ |
*
* Validate that no invalid flags are passed.
*
* @parm DWORD | fl |
*
* Flags passed by the caller.
*
* @parm DWORD | flV |
*
* Flags which are valid.
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_INVALIDARG> if the parameter is invalid.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidFl_(DWORD fl, DWORD flV, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
if ((fl & ~flV) == 0) {
hres = S_OK;
} else {
//RPF("ERROR %s: arg %d: invalid flags", s_szProc, iarg);
hres = E_INVALIDARG;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidPfn_ |
*
* Validate that the parameter is a valid code pointer.
*
* Actually, <f IsValidCodePtr> on Win32 is broken, but
* tough.
*
* @parm FARPROC | pfn |
*
* Procedure to "validate".
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_INVALIDARG> if the parameter is invalid.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidPfn_(FARPROC pfn, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
if (!IsBadCodePtr(pfn)) {
hres = S_OK;
} else {
//RPF("ERROR %s: arg %d: invalid callback address", s_szProc, iarg);
hres = E_INVALIDARG;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidPitf_ |
*
* Validate that the parameter is an interface pointer.
*
* We don't look at it very hard.
*
* @parm PUNK | punk |
*
* <i IUnknown> to "validate".
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the pointer itself is bogus.
*
* <c E_INVALIDARG> if something inside the pointer is bogus.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidPitf_(PUNK punk, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
if (!IsBadReadPtr(punk, cbX(DWORD))) {
IUnknownVtbl *pvtbl = punk->lpVtbl;
if (!IsBadReadPtr(pvtbl, 3 * cbX(DWORD))) {
if (!IsBadCodePtr((FARPROC)pvtbl->QueryInterface) &&
!IsBadCodePtr((FARPROC)pvtbl->AddRef) &&
!IsBadCodePtr((FARPROC)pvtbl->Release)) {
hres = S_OK;
} else {
//RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
hres = E_INVALIDARG;
}
} else {
//RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
hres = E_INVALIDARG;
}
} else {
//RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
hres = E_POINTER;
}
return hres;
}
/*****************************************************************************
*
* @doc INTERNAL
*
* @func HRESULT | hresFullValidPdwOut_ |
*
* Validate that the parameter is a valid place to stick an
* output result. We also smas it to zero.
*
* @parm PV | pdw |
*
* Pointer to "validate".
*
* @parm LPCSTR | s_szProc |
*
* Name of calling procedure.
*
* @parm int | iarg |
*
* Parameter index. (First parameter is 1.)
*
* @returns
*
* <c S_OK> if the parameter is valid.
*
* <c E_POINTER> if the pointer itself is bogus.
*
*****************************************************************************/
STDMETHODIMP
hresFullValidPdwOut_(PV pdw, LPCSTR s_szProc, int iarg)
{
HRESULT hres;
if (!IsBadWritePtr(pdw, 4)) {
*(LPDWORD)pdw = 0;
hres = S_OK;
} else {
//RPF("ERROR %s: arg %d: invalid pointer", s_szProc, iarg);
hres = E_POINTER;
}
return hres;
}