📄 utility.cpp
字号:
//
// 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.
//
/*--
Module Name: utility.cpp
Abstract: utility fcns
--*/
// #include "script.h"
#include "aspmain.h"
//****************************************************************
// ASP specific fcns / data
//****************************************************************
//****************************************************************
// Generic String manipulation fcns
//****************************************************************
const char cszEmpty[] = "";
PSTR MySzDupA(PCSTR pszIn, int iLen)
{
if(!pszIn) return NULL;
if(!iLen) iLen = strlen(pszIn);
PSTR pszOut=MySzAllocA(iLen);
if(pszOut) {
memcpy(pszOut, pszIn, iLen);
pszOut[iLen] = 0;
}
return pszOut;
}
PWSTR MySzDupW(PCWSTR wszIn, int iLen)
{
if(!wszIn) return NULL;
if(!iLen) iLen = wcslen(wszIn);
PWSTR wszOut=MySzAllocW(iLen);
if(wszOut) {
memcpy(wszOut, wszIn, sizeof(WCHAR)*iLen);
wszOut[iLen] = 0;
}
return wszOut;
}
PSTR MySzDupWtoA(PCWSTR wszIn, int iInLen, LONG lCodePage)
{
PSTR pszOut = 0;
int iOutLen = WideCharToMultiByte(lCodePage, 0, wszIn, iInLen, 0, 0, 0, 0);
if(!iOutLen)
goto error;
pszOut = MySzAllocA(iOutLen);
if(!pszOut)
goto error;
if(WideCharToMultiByte(lCodePage, 0, wszIn, iInLen, pszOut, iOutLen, 0, 0))
return pszOut;
error:
MyFree(pszOut);
return FALSE;
}
PWSTR MySzDupAtoW(PCSTR pszIn, int iInLen)
{
PWSTR pwszOut = 0;
int iOutLen = MultiByteToWideChar(CP_ACP, 0, pszIn, iInLen, 0, 0);
if(!iOutLen)
goto error;
pwszOut = MySzAllocW(iOutLen);
if(!pwszOut)
goto error;
if(MultiByteToWideChar(CP_ACP, 0, pszIn, iInLen, pwszOut, iOutLen))
return pwszOut;
error:
DEBUGMSG(ZONE_ERROR, (L"ASP: MySzDupAtoW(%a, %d) failed. pOut=%0x08x GLE=%d\r\n", pszIn, iInLen, pwszOut, GetLastError()));
MyFree(pwszOut);
return FALSE;
}
/*===================================================================
VariantResolveDispatch
Convert an IDispatch VARIANT to a (non-Dispatch) VARIANT by
invoking its default property until the object that remains
is not an IDispatch. If the original VARIANT is not an IDispatch
then the behavior is identical to VariantCopyInd(), with the
exception that arrays are copied.
Parameters:
pVarOut - if successful, the return value is placed here
pVarIn - the variant to copy
GUID *iidObj - the calling interface (for error reporting)
nObjID - the Object's name from the resource file
pVarOut need not be initialized. Since pVarOut is a new
variant, the caller must VariantClear this object.
Returns:
The result of calling IDispatch::Invoke. (either NOERROR or
the error resulting from the call to Invoke) may also return
E_OUTOFMEMORY if an allocation fails
This function always calls Exception() if an error occurs -
this is because we need to call Exception() if an IDispatch
method raises an exception. Instead of having the client
worry about whether we called Exception() on its behalf or
not, we always raise the exception.
===================================================================*/
HRESULT VariantResolveDispatch(VARIANT *pVarOut, VARIANT *pVarIn)
{
VARIANT varResolved; // value of IDispatch::Invoke
DISPPARAMS dispParamsNoArgs = {NULL, NULL, 0, 0};
EXCEPINFO ExcepInfo;
HRESULT hrCopy;
DEBUGCHK (pVarIn != NULL && pVarOut != NULL);
VariantInit(pVarOut);
if (V_VT(pVarIn) & VT_BYREF)
hrCopy = VariantCopyInd(pVarOut, pVarIn);
else
hrCopy = VariantCopy(pVarOut, pVarIn);
if (FAILED(hrCopy))
{
// ExceptionId(iidObj, nObjID, (hrCopy == E_OUTOFMEMORY)? IDE_OOM : IDE_UNEXPECTED);
return hrCopy;
}
// follow the IDispatch chain.
//
while (V_VT(pVarOut) == VT_DISPATCH)
{
HRESULT hrInvoke = S_OK;
// If the variant is equal to Nothing, then it can be argued
// with certainty that it does not have a default property!
// hence we return DISP_E_MEMBERNOTFOUND for this case.
//
if (V_DISPATCH(pVarOut) == NULL)
hrInvoke = DISP_E_MEMBERNOTFOUND;
else
{
VariantInit(&varResolved);
hrInvoke = V_DISPATCH(pVarOut)->Invoke(
DISPID_VALUE,
IID_NULL,
LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET | DISPATCH_METHOD,
&dispParamsNoArgs,
&varResolved,
&ExcepInfo,
NULL);
}
if (FAILED(hrInvoke))
{
if (hrInvoke == DISP_E_EXCEPTION)
{
//
// forward the ExcepInfo from Invoke to caller's ExcepInfo
//
// Exception(iidObj, ExcepInfo.bstrSource, ExcepInfo.bstrDescription);
SysFreeString(ExcepInfo.bstrHelpFile);
}
else
{
}
// ExceptionId(iidObj, nObjID, IDE_UTIL_NO_VALUE);
VariantClear(pVarOut);
return hrInvoke;
}
// The correct code to restart the loop is:
//
// VariantClear(pVar)
// VariantCopy(pVar, &varResolved);
// VariantClear(&varResolved);
//
// however, the same affect can be achieved by:
//
// VariantClear(pVar)
// *pVar = varResolved;
// VariantInit(&varResolved)
//
// this avoids a copy. The equivalence rests in the fact that
// *pVar will contain the pointers of varResolved, after we
// trash varResolved (WITHOUT releasing strings or dispatch
// pointers), so the net ref count is unchanged. For strings,
// there is still only one pointer to the string.
//
// NOTE: the next interation of the loop will do the VariantInit.
//
VariantClear(pVarOut);
*pVarOut = varResolved;
}
return S_OK;
}
/*============================================================================
SysAllocStringFromSz
Allocate a System BSTR and copy the given ANSI string into it.
Parameters:
sz - The string to copy (Note: this IS an "sz", we will stop at the first NULL)
cch - the number of ANSI characters in szT. If 0, will calculate size.
BSTR *pbstrRet - the returned BSTR
lCodePage - the codepage for conversion
Returns:
Allocated BSTR in return value
NOERROR on success, E_OUTOFMEMORY on OOM
Side effects:
Allocates memory. Caller must deallocate
============================================================================*/
HRESULT SysAllocStringFromSz
(
CHAR *sz,
DWORD cch,
BSTR *pbstrRet,
UINT lCodePage
)
{
BSTR bstrRet;
DEBUGCHK(pbstrRet != NULL);
if (sz == NULL)
{
*pbstrRet = NULL;
return(NOERROR);
}
// If they passed 0, then determine string length
if (cch == 0)
cch = strlen(sz);
// Allocate a string of the desired length
// SysAllocStringLen allocates enough room for unicode characters plus a null
// Given a NULL string it will just allocate the space
bstrRet = SysAllocStringLen(NULL, cch);
if (bstrRet == NULL)
return(E_OUTOFMEMORY);
// If we were given "", we will have cch=0. return the empty bstr
// otherwise, really copy/convert the string
// NOTE we pass -1 as 4th parameter of MulitByteToWideChar for DBCS support
if (cch != 0)
{
UINT cchTemp = 0;
if (MultiByteToWideChar(lCodePage, 0, sz, -1, bstrRet, cch+1) == 0)
{
SysFreeString(bstrRet);
return(HRESULT_FROM_WIN32(GetLastError()));
}
// If there are some DBCS characters in the sz(Input), then, the character count of BSTR(DWORD) is
// already set to cch(strlen(sz)) in SysAllocStringLen(NULL, cch), we cannot change the count,
// and later call of SysStringLen(bstr) always returns the number of characters specified in the
// cch parameter at allocation time. Bad, because one DBCS character(2 bytes) will convert
// to one UNICODE character(2 bytes), not 2 UNICODE characters(4 bytes).
// Example: For input sz contains only one DBCS character, we want to see SysStringLen(bstr)
// = 1, not 2.
bstrRet[cch] = 0;
cchTemp = wcslen(bstrRet);
if (cchTemp < cch)
{
BSTR bstrTemp = SysAllocString(bstrRet);
SysFreeString(bstrRet);
bstrRet = bstrTemp;
cch = cchTemp;
if (bstrTemp == NULL)
return E_OUTOFMEMORY;
}
}
bstrRet[cch] = 0;
*pbstrRet = bstrRet;
return(NOERROR);
}
int URLEncodeLen(const char *szSrc)
{
int cbURL = 1; // add terminator now
if (!szSrc)
return 0;
while (*szSrc)
{
if (*szSrc & 0x80) // encode foreign characters
cbURL += 3;
else if (*szSrc == ' ') // encoded space requires only one character
++cbURL;
else if (!isalnum(*szSrc)) // encode non-alphabetic characters
cbURL += 3;
else
++cbURL;
++szSrc;
}
return cbURL;
}
/*===================================================================
URLEncode
URL Encode a string by changing space characters to '+' and escaping
non-alphanumeric characters in hex.
Parameters:
szDest - Pointer to the buffer to store the URLEncoded string
szSrc - Pointer to the source buffer
Returns:
A pointer to the NUL terminator is returned.
===================================================================*/
char *URLEncode(char *szDest, const char *szSrc)
{
char hex[] = "0123456789ABCDEF";
if (!szDest)
return NULL;
if (!szSrc)
{
*szDest = '\0';
return szDest;
}
while (*szSrc)
{
if (*szSrc == ' ')
{
*szDest++ = '+';
++szSrc;
}
else if ( (*szSrc & 0x80) || !isalnum(*szSrc) )
{
*szDest++ = '%';
*szDest++ = hex[BYTE(*szSrc) >> 4];
*szDest++ = hex[*szSrc++ & 0x0F];
}
else
*szDest++ = *szSrc++;
}
*szDest = '\0';
return szDest;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -