⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dict.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

#include "aspmain.h"
const BOOL c_fUseCollections = TRUE;
const char cszDomain[]  = "; domain=";
const char cszPath[]    = "; path=";
const char cszPathDefault[]    = "; path=/";
const char cszExpires[] = "; expires";


int DBCSEncodeLen(const char *szSrc);


CRequestDictionary * CreateCRequestDictionary(DICT_TYPE dt, CASPState *pASPState, PSTR pszData)
{
	CRequestDictionary *pDict = NULL;

	if (FAILED (CoCreateInstance(CLSID_RequestDictionary,NULL,CLSCTX_INPROC_SERVER,IID_IRequestDictionary,(void**) &pDict)))
		return NULL;

	pDict->m_dictType = dt;
	pDict->m_pASPState = pASPState;
	pDict->m_pszRawData = pszData;		
	
	if (pszData)
		pDict->ParseInput();

	return pDict;
}

CRequestDictionary::CRequestDictionary() 
				    : CPtrMapper(0)
{
//	m_cRef = 0;
	m_pszRawData = NULL;
}

// We inherit from CPtrMapper class, which handles the deallocation of the list
CRequestDictionary::~CRequestDictionary()		
{
//	MyFree(m_pszRawData);	// don't free this, because we never made a copy of 
							// the data in the first place.
}


//  CRequestDictionary::get_Item
//  This is called when accessing a collection object (Request.QueryString/Form/Cookies),
//  Response.Cookies.  

//  If there is no argument, for example <% var = Request.Cookies %>, then 
//  varKey is of type VT_ERROR.  Like IIS, we return the raw, unformatted string
//  in this case, except for Response.Cookies, which doesn't support being accessed
//  raw.  

//  If the argument is an integer, the i(th) element is returned.  This is 
//  only valid for Form and QueryString objects.  (ie Request.Form(1) )
//  The element is a CRequestStrList, not the string itself, because subindexing
//  is possible and we need an object to handle this.  (ie Request.Form(1)(2) would
//  get the 2nd element of the 1st var declared in the Post input)

//  If the argument is a string, the string is looked up in the table that was
//  created on CookieParse or PostParse.  Again a CRequestStrList class element
//  is returned.

//  If no string exists, or if there is no data in the VT_ERROR case, then 
//  we return a CRequestStrList that is specified as an empty string.  We have
//  only one such object per request.  The reason we return this object rather
//  than an VT_EMPTY variant is that we still need to support methods such 
//  as Request.Form("No-Data").Count.  Without an object, the value is the string "",
//  it needs to be the integer 0.



STDMETHODIMP CRequestDictionary::get_Item(VARIANT varKey, VARIANT* pvarReturn)
{
	DEBUG_CODE_INIT;
	HRESULT ret = DISP_E_EXCEPTION;

    VariantInit(pvarReturn);
    VARIANT *pvarKey = &varKey;
	BSTR bstr = NULL;
	int iIndex;
	CRequestStrList *pStrList = NULL;
	DWORD vt;
	
	//  For Request.Cookies we convert from ANSI, otherwise change from DBCS.
	//  This is like ASP on IIS.	
	LONG lCodePage = (m_dictType == REQUEST_COOKIE_TYPE) ? CP_ACP : m_pASPState->m_lCodePage;

    // Use VariantResolveDispatch which will:
    //
    //     *  Copy BYREF variants for us using VariantCopyInd
    //     *  handle E_OUTOFMEMORY for us
    //     *  get the default value from an IDispatch, which seems
    //        like an appropriate conversion.
    //
    VARIANT varKeyCopy;
    VariantInit(&varKeyCopy);
    vt = V_VT(pvarKey);

    if ((vt != VT_BSTR) && (vt != VT_I2) && (vt != VT_I4))
	{
        if (FAILED(VariantResolveDispatch(&varKeyCopy, &varKey)))
		{
			ASP_ERR(IDS_E_PARSER);
			myleave(811);
		}
        pvarKey = &varKeyCopy;
	}
    vt = V_VT(pvarKey);

	switch (vt)
	{
	case VT_I1:  case VT_I2:               case VT_I8:
	case VT_UI1: case VT_UI2: case VT_UI4: case VT_UI8:
	case VT_R4:  case VT_R8:
		// Coerce all integral types to VT_I4
		if (FAILED(VariantChangeTypeEx(pvarKey, pvarKey, lCodePage, 0, VT_I4)))
		{
			ASP_ERR(IDS_E_UNKNOWN);
			myleave(811);
		}
		vt = VT_I4;
	}

	// directly accessing object, no arguments.  
	// This is only valid for Request objects.  It gives the user
	// the original, unformatted/unparsed string from the client.
	if (  VT_ERROR == vt)
	{
		// This would be made on <% var = Response.Cookies %> (or Request.ServerVariables), no raw dumping.  Like IIS.
		if ( RESPONSE_COOKIE_TYPE == m_dictType || SERVER_VARIABLE_TYPE == m_dictType )
		{
			ASP_ERR(IDS_E_EXPECTED_STRING);
			myleave(802);
		}	

		if (m_pszRawData)
		{					
			if ( FAILED( SysAllocStringFromSz(m_pszRawData, 0, &bstr, lCodePage)))
			{
				ASP_ERR(IDS_E_NOMEM);
				myleave(803);
			}

			V_VT(pvarReturn) = VT_BSTR;
			V_BSTR(pvarReturn) = bstr;
		}
		else		//  no data of requested type, ie Request.Form but not POST data sent
		{
			//  Point it at the empty string object, only one of these per ASP session
			V_VT(pvarReturn) = VT_DISPATCH;		
			m_pASPState->m_pEmptyString->QueryInterface(IID_IRequestStrList, (void **) (&V_DISPATCH(pvarReturn)));
		}
	}
	else if (VT_I4 == vt)		//lookup based on index 
	{
		// Can't index cookies or server variables based on an integer
		if ( RESPONSE_COOKIE_TYPE == m_dictType ||
			 REQUEST_COOKIE_TYPE  == m_dictType ||
			 SERVER_VARIABLE_TYPE == m_dictType )
		{
			ASP_ERR(IDS_E_EXPECTED_STRING);
			myleave(804);
		}	

		iIndex = V_I4(pvarKey);
		if (iIndex <= 0 ||
			iIndex > m_nEntries)
		{
			ASP_ERR(IDS_E_BAD_INDEX);
			myleave(804);
		}

		pStrList = (CRequestStrList *)  (m_pMapInfo[iIndex - 1].pbData);
        pStrList->QueryInterface(IID_IRequestStrList, (void **) (&V_DISPATCH(pvarReturn)));
		V_VT(pvarReturn) = VT_DISPATCH;		
	}	// VT_I4
	else if (VT_BSTR == vt)		// Lookup based on string.
	{
		if (SERVER_VARIABLE_TYPE == m_dictType) 
		{
			GetServerVariables(V_BSTR(pvarKey),pvarReturn);
		}
		else if (Lookup( V_BSTR(pvarKey), (void **) &pStrList))
		{
			pStrList->QueryInterface(IID_IRequestStrList, (void **) (&V_DISPATCH(pvarReturn)));
			V_VT(pvarReturn) = VT_DISPATCH;			
		}		
		else
		{	
			m_pASPState->m_pEmptyString->QueryInterface(IID_IRequestStrList, (void **) (&V_DISPATCH(pvarReturn)));
			V_VT(pvarReturn) = VT_DISPATCH;
		}
	}	// VT_BSTR
	//  vt not an integer or string.  We follow IIS's lead as far as what error to report.
	else		
	{	
		ASP_ERR(IDS_E_EXPECTED_STRING);		
		myleave(806);
	}

	ret = S_OK;
done:
	DEBUGMSG_ERR(ZONE_ERROR,(L"ASP: CRequestDictionary::get_Item failed, err = %d, GLE=%X\r\n",
							  err,GetLastError()));
	
	VariantClear(&varKeyCopy);
	return ret;
}

//  put_Item.  Used for assigning values to Cookie response data.

//  This will be called on cases 
//  Response.Cookies = "Value"
//  Response.Cookies("index") = "Value"

//  It will NOT be called on Response.Cookies("index1")("index2") = "value",
//  instead this will be a CRequestDictionary::get_Item with "index1", then
//  a CRequestStrList::put_Item with "index2", and "value" through object created


STDMETHODIMP CRequestDictionary::put_Item(VARIANT varKey, BSTR bstrValue)
{
	DEBUG_CODE_INIT;
	VARIANT *pvarKey = &varKey;
    HRESULT ret = DISP_E_EXCEPTION;
	int iIndex =0;
	WCHAR *wszValue = NULL;
	WCHAR *wszName  = NULL;
	CRequestStrList *pStrList = NULL;
	DWORD vt;

    VARIANT varKeyCopy;
    VariantInit(&varKeyCopy);
    vt = V_VT(pvarKey);

	if (NULL == bstrValue)
		myretleave(S_OK,809);

	if (m_dictType != RESPONSE_COOKIE_TYPE)
	{
		ASP_ERR(IDS_E_READ_ONLY);
		myleave(810);
	}
	
	if (TRUE == m_pASPState->m_fSentHeaders)
	{
		ASP_ERR(IDS_E_SENT_HEADERS);
		myleave(808);
	}

    // Use VariantResolveDispatch which will:
    //
    //     *  Copy BYREF variants for us using VariantCopyInd
    //     *  handle E_OUTOFMEMORY for us
    //     *  get the default value from an IDispatch, which seems
    //        like an appropriate conversion.
    //
    if ((vt != VT_BSTR) && (vt != VT_I2) && (vt != VT_I4))
	{
        if (FAILED(VariantResolveDispatch(&varKeyCopy, &varKey)))
		{
			ASP_ERR(IDS_E_PARSER);
			myleave(811);
		}
        pvarKey = &varKeyCopy;
	}
    vt = V_VT(pvarKey);

	// this would correspond to Response.Cookies = "Value", or Response.Cookies(5) = "value",
	// No support in IIS or in CE ASP.
	if (vt != VT_BSTR)
	{
		ASP_ERR(IDS_E_EXPECTED_STRING);
		myleave(812);
	}

	if (NULL == (wszValue = MySzDupW(bstrValue)))
	{
		ASP_ERR(IDS_E_NOMEM);
		myleave(817);
	}

	if ( Lookup( V_BSTR(pvarKey), (void**) &pStrList))
	{
		if (FALSE == pStrList->AddStringToArray(wszValue))
		{
			ASP_ERR(IDS_E_NOMEM);
			myleave(815);
		}
		// Do NOT add reference here, we're just overwriting it!
	}
	else 	// new element
	{
		if (NULL == (wszName = MySzDupW( V_BSTR(pvarKey))))
		{
			ASP_ERR(IDS_E_NOMEM);
			myleave(818);
		}
		pStrList = CreateCRequestStrList(m_pASPState,wszValue,m_dictType);
		
		if ( NULL == pStrList || FALSE == Set(wszName, (void *) pStrList))
		{
			MyFree(wszName);
			ASP_ERR(IDS_E_NOMEM);
			myleave(816);
		}
	}		
	
	ret = S_OK;
done:
	DEBUGMSG_ERR(ZONE_ERROR,(L"ASP: CRequestDictionary::put_Item failed, err = %d, GLE=%X\r\n",
							 err, GetLastError()));

	if (FAILED(ret))
		MyFree(wszValue);
		
	VariantClear(&varKeyCopy);
	return ret;
}

STDMETHODIMP CRequestDictionary::get_Count(int* cStrRet)
{
	if (SERVER_VARIABLE_TYPE == m_dictType)
		return E_NOTIMPL;
	
	*cStrRet = m_nEntries;
	return S_OK;
}

// Note: WinCE does not support enumeration through collection objects in ASP, unlike IIS.
STDMETHODIMP CRequestDictionary::get_Key(VARIANT VarKey, VARIANT* pvar)
{
	ASP_ERR(IDS_E_NOT_IMPL);
	return E_NOTIMPL;
}

STDMETHODIMP CRequestDictionary::get__NewEnum(IUnknown** ppEnumReturn)
{
	ASP_ERR(IDS_E_NOT_IMPL);
	return E_NOTIMPL;
}

//  CRequest::ParseInput()
//  This takes the raw data receieved from the POST, query string, or incoming cookies
//  and breaks it into individual items that can be more easily indexed.
BOOL CRequestDictionary::ParseInput()
{
	DEBUG_CODE_INIT;
	PSTR pszName = NULL;
	PSTR pszValue = NULL;
	CRequestStrList *pStrList = NULL;
	PSTR pszTrav = NULL;	
	PSTR pszTempRawData = NULL;
	WCHAR *wszName = NULL;		// Don't free at end of function
	WCHAR *wszValue = NULL;		// Don't free at end of function

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -