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.
320 lines
7.0 KiB
320 lines
7.0 KiB
/*
|
|
* RUNT.C
|
|
*
|
|
* General-purpose functions and C runtime substitutes.
|
|
*
|
|
* Copyright 1992 - 1996 Microsoft Corporation. All Rights Reserved.
|
|
*/
|
|
|
|
|
|
#include <_apipch.h>
|
|
|
|
#define cbMinEntryID (CbNewENTRYID(sizeof(MAPIUID)))
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#ifndef PSTRCVR
|
|
|
|
/* Functions related to the OLE Component Object model */
|
|
|
|
STDAPI_(ULONG)
|
|
UlRelease(LPVOID punk)
|
|
{
|
|
|
|
if (!punk)
|
|
return 0L;
|
|
|
|
AssertSz(!FBadUnknown((LPUNKNOWN) punk), TEXT("UlRelease: bad object ptr"));
|
|
|
|
return ((LPUNKNOWN)punk)->lpVtbl->Release((LPUNKNOWN)punk);
|
|
}
|
|
|
|
STDAPI_(ULONG)
|
|
UlAddRef(LPVOID punk)
|
|
{
|
|
AssertSz(!FBadUnknown((LPUNKNOWN) punk), TEXT("UlAddRef: bad object ptr"));
|
|
|
|
return ((LPUNKNOWN)punk)->lpVtbl->AddRef((LPUNKNOWN)punk);
|
|
}
|
|
|
|
|
|
/* Functions related to the MAPI interface */
|
|
|
|
/*
|
|
* Retrieve a single property from a MAPIProp interface
|
|
*/
|
|
STDAPI
|
|
HrGetOneProp(LPMAPIPROP pmp, ULONG ulPropTag, LPSPropValue FAR *ppprop)
|
|
{
|
|
ULONG cValues;
|
|
#ifndef WIN16
|
|
SPropTagArray tg = { 1, { ulPropTag } };
|
|
#else
|
|
SPropTagArray tg;
|
|
#endif
|
|
HRESULT hr;
|
|
|
|
#ifdef WIN16 // Set tg member's value.
|
|
tg.cValues = 1;
|
|
tg.aulPropTag[0] = ulPropTag;
|
|
#endif
|
|
|
|
AssertSz(!FBadUnknown((LPUNKNOWN) pmp), TEXT("HrGetOneProp: bad object ptr"));
|
|
// Note: other parameters should be validated in the GetProps
|
|
|
|
hr = pmp->lpVtbl->GetProps(pmp, &tg, MAPI_UNICODE, // ansi
|
|
&cValues, ppprop);
|
|
if (GetScode(hr) == MAPI_W_ERRORS_RETURNED)
|
|
{
|
|
hr = ResultFromScode((*ppprop)->Value.err);
|
|
FreeBufferAndNull(ppprop); // Yes, we do want ppprop, not &ppprop
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
if (hr && GetScode(hr) != MAPI_E_NOT_FOUND) // too noisy
|
|
DebugTraceResult(HrGetOneProp, hr);
|
|
#endif
|
|
return hr;
|
|
}
|
|
|
|
STDAPI
|
|
HrSetOneProp(LPMAPIPROP pmp, LPSPropValue pprop)
|
|
{
|
|
HRESULT hr;
|
|
LPSPropProblemArray pprob = NULL;
|
|
|
|
AssertSz(!FBadUnknown((LPUNKNOWN) pmp), TEXT("HrSetOneProp: bad object ptr"));
|
|
// Note: other parameters should be validated in the SetProps
|
|
|
|
if (HR_SUCCEEDED(hr = pmp->lpVtbl->SetProps(pmp, 1, pprop, &pprob)))
|
|
{
|
|
if (pprob)
|
|
{
|
|
hr = ResultFromScode(pprob->aProblem->scode);
|
|
FreeBufferAndNull(&pprob);
|
|
}
|
|
}
|
|
|
|
// DebugTraceResult(HrSetOneProp, hr); // Too noisy
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*
|
|
* Searches for a given property tag in a property tag array. If the
|
|
* given property tag has type PT_UNSPECIFIED, matches only on the
|
|
* property ID; otherwise, matches on the entire tag.
|
|
*/
|
|
STDAPI_(BOOL)
|
|
FPropExists(LPMAPIPROP pobj, ULONG ulPropTag)
|
|
{
|
|
LPSPropTagArray ptags = NULL;
|
|
int itag;
|
|
BOOL f = PROP_TYPE(ulPropTag) == PT_UNSPECIFIED;
|
|
|
|
AssertSz(!FBadUnknown((LPUNKNOWN) pobj), TEXT("FPropExists: bad object ptr"));
|
|
|
|
#ifdef DEBUG
|
|
{
|
|
HRESULT hr;
|
|
if (hr = pobj->lpVtbl->GetPropList(pobj, MAPI_UNICODE, // ansi
|
|
&ptags)) {
|
|
DebugTraceResult(FPropExists, hr);
|
|
return FALSE;
|
|
}
|
|
}
|
|
#else
|
|
if (pobj->lpVtbl->GetPropList(pobj, MAPI_UNICODE, // ansi
|
|
&ptags)) {
|
|
return(FALSE);
|
|
}
|
|
#endif
|
|
|
|
for (itag = (int)(ptags->cValues - 1); itag >= 0; --itag) {
|
|
if (ptags->aulPropTag[itag] == ulPropTag ||
|
|
(f && PROP_ID(ptags->aulPropTag[itag]) == PROP_ID(ulPropTag))) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
FreeBufferAndNull(&ptags);
|
|
return(itag >= 0);
|
|
}
|
|
|
|
/*
|
|
* Searches for a given property tag in a propset. If the given
|
|
* property tag has type PT_UNSPECIFIED, matches only on the
|
|
* property ID; otherwise, matches on the entire tag.
|
|
*/
|
|
STDAPI_(LPSPropValue)
|
|
PpropFindProp(LPSPropValue rgprop, ULONG cprop, ULONG ulPropTag)
|
|
{
|
|
BOOL f = PROP_TYPE(ulPropTag) == PT_UNSPECIFIED;
|
|
LPSPropValue pprop = rgprop;
|
|
|
|
if (!cprop || !rgprop)
|
|
return NULL;
|
|
|
|
AssertSz(!IsBadReadPtr(rgprop, (UINT)cprop*sizeof(SPropValue)), TEXT("PpropFindProp: rgprop fails address check"));
|
|
|
|
while (cprop--)
|
|
{
|
|
if (pprop->ulPropTag == ulPropTag ||
|
|
(f && PROP_ID(pprop->ulPropTag) == PROP_ID(ulPropTag)))
|
|
return pprop;
|
|
++pprop;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Destroys an SRowSet structure.
|
|
*/
|
|
STDAPI_(void)
|
|
FreeProws(LPSRowSet prows)
|
|
{
|
|
ULONG irow;
|
|
|
|
if (! prows) {
|
|
return;
|
|
}
|
|
|
|
//was: AssertSz(!FBadRowSet(prows), TEXT("FreeProws: prows fails address check"));
|
|
|
|
#ifdef DEBUG
|
|
if (FBadRowSet(prows)) {
|
|
TraceSz( TEXT("FreeProws: prows fails address check"));
|
|
}
|
|
#endif // DEBUG
|
|
|
|
for (irow = 0; irow < prows->cRows; ++irow) {
|
|
MAPIFreeBuffer(prows->aRow[irow].lpProps);
|
|
}
|
|
FreeBufferAndNull(&prows);
|
|
}
|
|
|
|
|
|
/*
|
|
* Destroys an ADRLIST structure.
|
|
*/
|
|
STDAPI_(void)
|
|
FreePadrlist(LPADRLIST padrlist)
|
|
{
|
|
ULONG iEntry;
|
|
|
|
if (padrlist) {
|
|
AssertSz(!FBadAdrList(padrlist), TEXT("FreePadrlist: padrlist fails address check"));
|
|
|
|
for (iEntry = 0; iEntry < padrlist->cEntries; ++iEntry) {
|
|
MAPIFreeBuffer(padrlist->aEntries[iEntry].rgPropVals);
|
|
}
|
|
FreeBufferAndNull(&padrlist);
|
|
}
|
|
}
|
|
|
|
#endif // !PSTRCVR
|
|
|
|
/* C runtime substitutes */
|
|
|
|
//$ BUG? Assumes TEXT("first") byte of DBCS char in low byte of ch
|
|
#if defined UNICODE
|
|
#define FIsNextCh(_sz,_ch) (*_sz == _ch)
|
|
#elif defined OLDSTUFF_DBCS
|
|
#define FIsNextCh(_sz,_ch) (*((LPBYTE)_sz) != (BYTE)_ch && \
|
|
(!IsDBCSLeadByte((BYTE)_ch) || ((LPBYTE)_sz)[1] == (_ch >> 8)))
|
|
#else // string8
|
|
#define FIsNextCh(_sz,_ch) (*_sz == _ch)
|
|
#endif
|
|
|
|
#if defined(DOS)
|
|
#define TCharNext(sz) ((sz) + 1)
|
|
#else
|
|
#define TCharNext(sz) CharNext(sz)
|
|
#endif
|
|
|
|
|
|
#ifndef PSTRCVR
|
|
|
|
STDAPI_(unsigned int)
|
|
UFromSz(LPCTSTR sz)
|
|
{
|
|
unsigned int u = 0;
|
|
unsigned int ch;
|
|
|
|
AssertSz(!IsBadStringPtr(sz, 0xFFFF), TEXT("UFromSz: sz fails address check"));
|
|
|
|
while ((ch = *sz) >= '0' && ch <= '9') {
|
|
u = u * 10 + ch - '0';
|
|
sz = TCharNext(sz);
|
|
}
|
|
|
|
return u;
|
|
}
|
|
|
|
#if 0
|
|
// Original version from Dinarte's book: uses 1-relative indexes
|
|
STDAPI_(void)
|
|
ShellSort(LPVOID pv, UINT cv, LPVOID pvT, UINT cb, PFNSGNCMP fpCmp)
|
|
{
|
|
UINT i, j, h;
|
|
|
|
for (h = 1; h <= cv / 9; h = 3*h+1)
|
|
;
|
|
for (; h > 0; h /= 3)
|
|
{
|
|
for (i = h + 1; i <= cv; ++i)
|
|
{
|
|
MemCopy(pvT, (LPBYTE)pv + i*cb, cb);
|
|
j = i;
|
|
while (j > h && (*fpCmp)((LPBYTE)pv+(j-h)*cb, pvT) > 0)
|
|
{
|
|
MemCopy((LPBYTE)pv + j*cb, (LPBYTE)pv + (j-h)*cb, cb);
|
|
j -= h;
|
|
}
|
|
MemCopy((LPBYTE)pv+j*cb, pvT, cb);
|
|
}
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
#define pELT(_i) ((LPBYTE)pv + (_i-1)*cb)
|
|
STDAPI_(void)
|
|
ShellSort(LPVOID pv, UINT cv, LPVOID pvT, UINT cb, PFNSGNCMP fpCmp)
|
|
{
|
|
UINT i, j, h;
|
|
|
|
AssertSz(!IsBadWritePtr(pv, cv*cb), TEXT("ShellSort: pv fails address check"));
|
|
AssertSz(!IsBadCodePtr((FARPROC) fpCmp), TEXT("ShellSort: fpCmp fails address check"));
|
|
|
|
for (h = 1; h <= cv / 9; h = 3*h+1)
|
|
;
|
|
for (; h > 0; h /= 3)
|
|
{
|
|
for (i = h+1; i <= cv; ++i)
|
|
{
|
|
MemCopy(pvT, pELT(i), cb);
|
|
j = i;
|
|
while (j > h && (*fpCmp)(pELT(j-h), pvT) > 0)
|
|
{
|
|
MemCopy(pELT(j), pELT(j-h), cb);
|
|
j -= h;
|
|
}
|
|
MemCopy(pELT(j), pvT, cb);
|
|
}
|
|
}
|
|
}
|
|
#undef pELT
|
|
|
|
#endif
|
|
|
|
#endif // !PSTRCVR
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|