|
|
/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
seo.cpp
Abstract:
This module contains the implementation for the Server Extension Object service.
Author:
Don Dumitru (dondu@microsoft.com)
Revision History:
dondu 10/11/96 created dondu 11/26/96 major rewrite andyj 02/03/97 Added CSEOMimeDictionary support andyj 02/12/97 Converted PropertyBag's to Dictonary's andyj 04/11/97 Added CSEOGenericMoniker
--*/
// SEO.cpp : Implementation of DLL Exports.
// Note: Proxy/Stub Information
// To build a separate proxy/stub DLL,
// <<TBD>>.
#include "stdafx.h"
//#define IID_DEFINED
#include "initguid.h"
#define SEODLLDEF // identifiers get exported through the .DEF file
#include "seodefs.h"
#include "mimeole.h"
#include "String"
#include "MEMBAG.h"
#include "IADMW.H" // Needed by METABAG.H
#include "METABAG.H"
#include "SEO_i.c"
#include "regprop.h"
//#include "mimebag.h"
#include "item.h"
#include "fhash.h"
#include "router.h"
#include "rwnew.h"
#include "seolock.h"
#include "subdict.h"
#include "stream.h"
#include "events.h"
#include "gmoniker.h"
#include "seolib.h"
CSEOComModule _Module;
BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_CSEORegDictionary, CSEORegDictionary) // OBJECT_ENTRY(CLSID_CSEOMimeDictionary, CSEOMimeDictionary)
OBJECT_ENTRY(CLSID_CSEOMemDictionary, CSEOMemDictionary) OBJECT_ENTRY(CLSID_CSEOMetaDictionary, CSEOMetaDictionary) OBJECT_ENTRY(CLSID_CSEODictionaryItem, CSEODictionaryItem) OBJECT_ENTRY(CLSID_CSEORouter, CSEORouter) OBJECT_ENTRY(CLSID_CEventLock, CEventLock) OBJECT_ENTRY(CLSID_CSEOStream, CSEOStream) OBJECT_ENTRY(CLSID_CEventManager, CEventManager) OBJECT_ENTRY(CLSID_CSEOGenericMoniker, CSEOGenericMoniker) OBJECT_ENTRY(CLSID_CEventMetabaseDatabaseManager, CEventMetabaseDatabaseManager) OBJECT_ENTRY(CLSID_CEventBindingManager, CEventBindingManager) OBJECT_ENTRY(CLSID_CEventUtil, CEventUtil) OBJECT_ENTRY(CLSID_CEventComCat, CEventComCat) OBJECT_ENTRY(CLSID_CEventRouter, CEventRouter) OBJECT_ENTRY(CLSID_CEventServiceObject, CEventServiceObject) END_OBJECT_MAP()
ALLOC_DEBUG_MODULE
/////////////////////////////////////////////////////////////////////////////
// CSEOComModule
static GUID g_appidSEO = { /* 064b2506-630b-11d2-a028-00c04fa37348 */ 0x064b2506, 0x630b, 0x11d2, {0xa0, 0x28, 0x00, 0xc0, 0x4f, 0xa3, 0x73, 0x48} };
const GUID *CSEOComModule::GetAPPID() {
return (&g_appidSEO); }
HRESULT CSEOComModule::WriteAPPID() { CStringGUID guid; LPSTR pszKey; CRegKey rk; LONG lRes; HRESULT hrRes = S_OK;
guid = *GetAPPID(); if (!guid) { return (CO_E_CLASSSTRING); } pszKey = (LPSTR) alloca(strlen("AppID\\")+strlen(guid)+1); if (!pszKey) { return (E_OUTOFMEMORY); } strcpy(pszKey,"AppID\\"); strcat(pszKey,guid); lRes = rk.Create(HKEY_CLASSES_ROOT,pszKey); if (lRes != ERROR_SUCCESS) { return (HRESULT_FROM_WIN32(lRes)); } lRes = rk.SetValue("Server Extension Objects"); if (lRes != ERROR_SUCCESS) { hrRes = HRESULT_FROM_WIN32(lRes); goto exit; } lRes = rk.SetValue("","DllSurrogate"); if (lRes != ERROR_SUCCESS) { hrRes = HRESULT_FROM_WIN32(lRes); goto exit; } exit: rk.Close(); if (!SUCCEEDED(hrRes)) { EraseAPPID(); } return (hrRes); }
HRESULT CSEOComModule::EraseAPPID() { CStringGUID guid; LPSTR pszKey; CRegKey rk; LONG lRes; HRESULT hrRes = S_OK;
guid = *GetAPPID(); if (!guid) { return (CO_E_CLASSSTRING); } pszKey = (LPSTR) alloca(strlen(guid)+strlen("AppID\\")+1); if (!pszKey) { return (E_OUTOFMEMORY); } strcpy(pszKey,"AppID\\"); strcat(pszKey,guid); lRes = rk.Open(HKEY_CLASSES_ROOT,""); if (lRes != ERROR_SUCCESS) { return (HRESULT_FROM_WIN32(lRes)); } lRes = rk.RecurseDeleteKey(pszKey); if (lRes != ERROR_SUCCESS) { hrRes = HRESULT_FROM_WIN32(lRes); goto exit; } exit: rk.Close(); return (hrRes); }
/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved) {
if (dwReason == DLL_PROCESS_ATTACH) { _Module.Init(ObjectMap,hInstance); INIT_DEBUG_MODULE DisableThreadLibraryCalls(hInstance); } else if (dwReason == DLL_PROCESS_DETACH) { TERM_DEBUG_MODULE _Module.Term(); if (!lpvReserved) { // lpvReserved is NULL when called because of FreeLibrary, and
// non-NULL when called during normal process termination. We
// only want to perform this operation during FreeLibrary,
// because we are calling into another .DLL and we only want to
// do that if we are sure that the other .DLL hasn't already
// terminated.
MyMallocTerm(); } } return (TRUE); // ok
}
/////////////////////////////////////////////////////////////////////////////
// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void) {
TraceFunctEnter("DllCanUnloadNow"); HRESULT hRes = (_Module.GetLockCount()==0) ? S_OK : S_FALSE; DebugTrace(0,"Returns %s.",(hRes==S_OK)?"S_OK":"S_FALSE"); TraceFunctLeave(); return (hRes); }
/////////////////////////////////////////////////////////////////////////////
// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) {
TraceFunctEnter("DllGetClassObject"); HRESULT hRes = _Module.GetClassObject(rclsid,riid,ppv); DebugTrace(0,"Returns 0x%08x.",hRes); TraceFunctLeave(); return (hRes); }
/////////////////////////////////////////////////////////////////////////////
// DllRegisterServer - Adds entries to the system registry
STDAPI DllRegisterServer(void) {
TraceFunctEnter("DllRegisterServer"); // registers object, typelib and all interfaces in typelib
HRESULT hRes = _Module.WriteAPPID(); if (SUCCEEDED(hRes)) { hRes = _Module.RegisterServer(TRUE); if (!SUCCEEDED(hRes)) { _Module.UnregisterServer(); _Module.EraseAPPID(); } } DebugTrace(0,"Returns 0x%08x.",hRes); TraceFunctLeave(); return (hRes); }
/////////////////////////////////////////////////////////////////////////////
// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void) {
TraceFunctEnter("DllUnregisterServer"); _Module.UnregisterServer(); _Module.EraseAPPID(); DebugTrace(0,"Returns S_OK"); TraceFunctLeave(); return (S_OK); }
SEODLLDEF HRESULT STDAPICALLTYPE MCISInitSEOA(LPCSTR pszService, DWORD dwVirtualServer, ISEORouter **ppshHandle) { TraceFunctEnter("MCISInitSEOA"); HRESULT hrRes; CComPtr<ISEODictionary> pdictTmp; CComPtr<ISEORouter> prouterResult;
if (!ppshHandle) { return (E_POINTER); } *ppshHandle = NULL; hrRes = MCISGetBindingInMetabaseA(pszService,dwVirtualServer,GUID_NULL,NULL,TRUE,FALSE,&pdictTmp); if (!SUCCEEDED(hrRes)) { TraceFunctLeave(); return (hrRes); } hrRes = CComObject<CSEORouter>::_CreatorClass::CreateInstance(NULL, IID_ISEORouter, (LPVOID *) &prouterResult); if (!SUCCEEDED(hrRes)) { TraceFunctLeave(); return (hrRes); } hrRes = prouterResult->put_Database(pdictTmp); if (!SUCCEEDED(hrRes)) { TraceFunctLeave(); return (hrRes); } *ppshHandle = prouterResult; (*ppshHandle)->AddRef(); TraceFunctLeave(); return (S_OK); }
SEODLLDEF HRESULT STDAPICALLTYPE MCISInitSEOW(LPCWSTR pszService, DWORD dwVirtualServer, ISEORouter **ppshHandle) { TraceFunctEnter("MCISInitSEOW"); HRESULT hrRes; CComPtr<ISEODictionary> pdictTmp; CComPtr<ISEORouter> prouterResult;
if (!ppshHandle) { return (E_POINTER); } *ppshHandle = NULL; hrRes = MCISGetBindingInMetabaseW(pszService,dwVirtualServer,GUID_NULL,NULL,TRUE,FALSE,&pdictTmp); if (!SUCCEEDED(hrRes)) { TraceFunctLeave(); return (hrRes); } hrRes = CComObject<CSEORouter>::_CreatorClass::CreateInstance(NULL, IID_ISEORouter, (LPVOID *) &prouterResult); if (!SUCCEEDED(hrRes)) { TraceFunctLeave(); return (hrRes); } hrRes = prouterResult->put_Database(pdictTmp); if (!SUCCEEDED(hrRes)) { TraceFunctLeave(); return (hrRes); } *ppshHandle = prouterResult; (*ppshHandle)->AddRef(); TraceFunctLeave(); return (S_OK); }
static HRESULT GetSubDictA(ISEODictionary *pdictBase, LPCSTR pszName, LPCSTR *ppszSubName, ISEODictionary **ppdictResult) { HRESULT hrRes; LPSTR pszNameCopy = (LPSTR) _alloca((strlen(pszName)+1)*sizeof(CHAR)); LPSTR pszNameCurr; CComPtr<ISEODictionary> pdictCurr = pdictBase; LPSTR pszSlash;
if (!ppdictResult) { return (E_POINTER); } *ppdictResult = NULL; if (!pdictBase || !pszName || !ppszSubName) { return (E_POINTER); } strcpy(pszNameCopy,pszName); pszNameCurr = pszNameCopy; while ((pszSlash=strchr(pszNameCurr,'\\'))!=NULL) { CComPtr<ISEODictionary> pdictSub;
*pszSlash = 0; pdictSub.Release(); hrRes = pdictCurr->GetInterfaceA(pszNameCurr,IID_ISEODictionary,(IUnknown **) &pdictSub); if (!SUCCEEDED(hrRes) && (hrRes != SEO_E_NOTPRESENT)) { return (hrRes); } if (!SUCCEEDED(hrRes)) { hrRes = CComObject<CSEOMemDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionary, (LPVOID *) &pdictSub); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = pdictCurr->SetInterfaceA(pszNameCurr,pdictSub); if (!SUCCEEDED(hrRes)) { return (hrRes); } } pdictCurr = pdictSub; pszNameCurr = pszSlash + 1; } *ppszSubName = pszName + (pszNameCurr - pszNameCopy); *ppdictResult = pdictCurr; (*ppdictResult)->AddRef(); return (S_OK); }
static HRESULT GetSubDictW(ISEODictionary *pdictBase, LPCWSTR pszName, LPCWSTR *ppszSubName, ISEODictionary **ppdictResult) { HRESULT hrRes; LPWSTR pszNameCopy = (LPWSTR) _alloca((wcslen(pszName)+1)*sizeof(WCHAR)); LPWSTR pszNameCurr; CComPtr<ISEODictionary> pdictCurr = pdictBase; LPWSTR pszSlash;
if (!ppdictResult) { return (E_POINTER); } *ppdictResult = NULL; if (!pdictBase || !pszName || !ppszSubName) { return (E_POINTER); } wcscpy(pszNameCopy,pszName); pszNameCurr = pszNameCopy; while ((pszSlash=wcschr(pszNameCurr,'\\'))!=NULL) { CComPtr<ISEODictionary> pdictSub;
*pszSlash = 0; pdictSub.Release(); hrRes = pdictCurr->GetInterfaceW(pszNameCurr,IID_ISEODictionary,(IUnknown **) &pdictSub); if (!SUCCEEDED(hrRes) && (hrRes != SEO_E_NOTPRESENT)) { return (hrRes); } if (!SUCCEEDED(hrRes)) { hrRes = CComObject<CSEOMemDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionary, (LPVOID *) &pdictSub); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = pdictCurr->SetInterfaceW(pszNameCurr,pdictSub); if (!SUCCEEDED(hrRes)) { return (hrRes); } } pdictCurr = pdictSub; pszNameCurr = pszSlash + 1; } *ppszSubName = pszName + (pszNameCurr - pszNameCopy); *ppdictResult = pdictCurr; (*ppdictResult)->AddRef(); return (S_OK); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateDictionaryFromMultiSzA( DWORD dwCount, LPCSTR *ppszNames, LPCSTR *ppszValues, BOOL bCopy, BOOL bReadOnly, ISEODictionary **ppdictResult) { HRESULT hrRes; DWORD dwIdx; CComPtr<ISEODictionary> pdictTmp;
if (!ppdictResult) { return (E_POINTER); } *ppdictResult = NULL; if (!ppszNames || !ppszValues) { return (E_POINTER); } hrRes = CComObject<CSEOMemDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionary, (LPVOID *) &pdictTmp); if (!SUCCEEDED(hrRes)) { return (hrRes); } for (dwIdx=0;dwIdx<dwCount;dwIdx++) { if (!ppszNames[dwIdx] || !ppszNames[dwIdx][0]) { return (E_POINTER); } LPCSTR pszSubString; CComPtr<ISEODictionary> pdictSub; LPCSTR pszSubName;
pdictSub.Release(); hrRes = GetSubDictA(pdictTmp,ppszNames[dwIdx],&pszSubName,&pdictSub); pszSubString = ppszValues[dwIdx]; if (pszSubString[strlen(pszSubString)+1]) { CComPtr<ISEODictionaryItem> pitemValue;
hrRes = CComObject<CSEODictionaryItem>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionaryItem, (LPVOID *) &pitemValue); if (!SUCCEEDED(hrRes)) { return (hrRes); } while (*pszSubString) { hrRes = pitemValue->AddStringA((DWORD) -1,pszSubString); if (!SUCCEEDED(hrRes)) { return (hrRes); } pszSubString += strlen(pszSubString) + 1; } hrRes = pdictSub->SetInterfaceA(pszSubName,pitemValue); if (!SUCCEEDED(hrRes)) { return (hrRes); } } else { hrRes = pdictSub->SetStringA(pszSubName,(strlen(pszSubString)+1)*sizeof(CHAR),pszSubString); if (!SUCCEEDED(hrRes)) { return (hrRes); } } } *ppdictResult = pdictTmp; (*ppdictResult)->AddRef(); return (S_OK); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateDictionaryFromMultiSzW( DWORD dwCount, LPCWSTR *ppszNames, LPCWSTR *ppszValues, BOOL bCopy, BOOL bReadOnly, ISEODictionary **ppdictResult) {
HRESULT hrRes; DWORD dwIdx; CComPtr<ISEODictionary> pdictTmp;
if (!ppdictResult) { return (E_POINTER); } *ppdictResult = NULL; if (!ppszNames || !ppszValues) { return (E_POINTER); } hrRes = CComObject<CSEOMemDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionary, (LPVOID *) &pdictTmp); if (!SUCCEEDED(hrRes)) { return (hrRes); } for (dwIdx=0;dwIdx<dwCount;dwIdx++) { if (!ppszNames[dwIdx] || !ppszNames[dwIdx][0]) { return (E_POINTER); } LPCWSTR pszSubString; CComPtr<ISEODictionary> pdictSub; LPCWSTR pszSubName;
pdictSub.Release(); hrRes = GetSubDictW(pdictTmp,ppszNames[dwIdx],&pszSubName,&pdictSub); pszSubString = ppszValues[dwIdx]; if (pszSubString[wcslen(pszSubString)+1]) { CComPtr<ISEODictionaryItem> pitemValue;
hrRes = CComObject<CSEODictionaryItem>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionaryItem, (LPVOID *) &pitemValue); if (!SUCCEEDED(hrRes)) { return (hrRes); } while (*pszSubString) { hrRes = pitemValue->AddStringW((DWORD) -1,pszSubString); if (!SUCCEEDED(hrRes)) { return (hrRes); } pszSubString += wcslen(pszSubString) + 1; } hrRes = pdictSub->SetInterfaceW(pszSubName,pitemValue); if (!SUCCEEDED(hrRes)) { return (hrRes); } } else { hrRes = pdictSub->SetStringW(pszSubName,(wcslen(pszSubString)+1)*sizeof(CHAR),pszSubString); if (!SUCCEEDED(hrRes)) { return (hrRes); } } } *ppdictResult = pdictTmp; (*ppdictResult)->AddRef(); return (S_OK); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateMultiSzFromDictionaryA( ISEODictionary *pdictDictionary, DWORD *pdwCount, LPSTR **pppszNames, LPSTR **pppszValues) {
return (E_NOTIMPL); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateMultiSzFromDictionaryW( ISEODictionary *pdictDictionary, DWORD *pdwCount, LPWSTR **pppszNames, LPWSTR **pppszValues) {
return (E_NOTIMPL); }
#define DW2W(x) _itow(x,(LPWSTR) _alloca(11*sizeof(WCHAR)),10)
SEODLLDEF HRESULT STDAPICALLTYPE MCISGetBindingInMetabaseA( LPCSTR pszService, DWORD dwVirtualServer, REFGUID guidEventSource, LPCSTR pszBinding, BOOL bCreate, BOOL fLock, ISEODictionary **ppdictResult) { USES_CONVERSION;
return (MCISGetBindingInMetabaseW(pszService?A2W(pszService):NULL, dwVirtualServer, guidEventSource, pszBinding?A2W(pszBinding):NULL, bCreate, fLock, ppdictResult)); }
SEODLLDEF HRESULT STDAPICALLTYPE MCISGetBindingInMetabaseW( LPCWSTR pszService, DWORD dwVirtualServer, REFGUID guidEventSource, LPCWSTR pszBinding, BOOL bCreate, BOOL fLock, ISEODictionary **ppdictResult) { HRESULT hrRes; CComPtr<ISEOInitObject> pinitRoot; CComPtr<ISEODictionary> pdictTmp; CComQIPtr<IPropertyBag,&IID_IPropertyBag> ppropTmp; CComQIPtr<ISEODictionary,&IID_ISEODictionary> pdictRoot; CComBSTR bstrPath;
if (!ppdictResult) { return (E_POINTER); } *ppdictResult = NULL; if (!pszService) { return (E_POINTER); } if ((guidEventSource != GUID_NULL) && !pszBinding && !bCreate) { return (E_INVALIDARG); } hrRes = CComObject<CSEOMetaDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEOInitObject, (LPVOID *) &pinitRoot); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = CComObject<CSEOMemDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionary, (LPVOID *) &pdictTmp); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = pdictTmp->SetStringW(L"MetabasePath",1,L""); if (!SUCCEEDED(hrRes)) { return (hrRes); } ppropTmp = pdictTmp; if (!ppropTmp) { return (E_NOINTERFACE); } hrRes = pinitRoot->Load(ppropTmp,NULL); if (!SUCCEEDED(hrRes)) { return (hrRes); } pdictRoot = pinitRoot; if (!pdictRoot) { return (E_NOINTERFACE); } bstrPath = "LM/"; bstrPath.Append(pszService); bstrPath.Append("/"); bstrPath.Append(DW2W(dwVirtualServer)); bstrPath.Append("/SEO"); if (guidEventSource != GUID_NULL) { CStringGUID objGuid;
bstrPath.Append("/BindingPoints/"); objGuid = guidEventSource; if (!objGuid) { return (E_INVALIDARG); } bstrPath.Append((LPCOLESTR) objGuid); bstrPath.Append("/Bindings/"); if (pszBinding) { bstrPath.Append(pszBinding); } else { if (!objGuid.CalcNew()) { return (E_FAIL); } bstrPath.Append((LPCOLESTR) objGuid); } } again: hrRes = pdictRoot->GetInterfaceW(bstrPath,IID_ISEODictionary,(IUnknown **) ppdictResult); if (SUCCEEDED(hrRes) || (hrRes != SEO_E_NOTPRESENT) || !bCreate) { return (hrRes); } // We got an SEO_E_NOTPRESENT error, and the caller specified bCreate==TRUE, so we need
// to create the sub-key. We do this by writing an empty dictionary to the sub-key - we'll
// empty the dictionary we used to initialize the root, and write that to the sub-key.
CComVariant varEmpty; hrRes = pdictTmp->SetVariantW(L"MetabasePath",&varEmpty); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = pdictRoot->SetInterfaceW(bstrPath,pdictTmp); if (!SUCCEEDED(hrRes)) { return (hrRes); } bCreate = FALSE; goto again; }
SEODLLDEF HRESULT STDAPICALLTYPE SEOListenForEvent( ISEORouter *piRouter, HANDLE hEvent, ISEOEventSink *psinkEventSink, BOOL bOnce, DWORD *pdwListenHandle) {
return (E_NOTIMPL); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCancelListenForEvent( DWORD dwHandle) {
return (E_NOTIMPL); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateIStreamFromFileA( HANDLE hFile, LPCSTR pszFile, IStream **ppstreamResult) { HRESULT hrRes; CComObject<CSEOStream> *pStream; ULARGE_INTEGER libOffset;
if (!ppstreamResult) { return (E_POINTER); } *ppstreamResult = NULL; hrRes = CComObject<CSEOStream>::CreateInstance(&pStream); if (!SUCCEEDED(hrRes)) { return (hrRes); } pStream->AddRef(); libOffset.QuadPart = 0; hrRes = pStream->Init(hFile,pszFile,libOffset,NULL); if (SUCCEEDED(hrRes)) { hrRes = pStream->QueryInterface(IID_IStream,(LPVOID *) ppstreamResult); } pStream->Release(); return (hrRes); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateIStreamFromFileW( HANDLE hFile, LPCWSTR pszFile, IStream **ppstreamResult) { HRESULT hrRes; CComObject<CSEOStream> *pStream; ULARGE_INTEGER libOffset;
if (!ppstreamResult) { return (E_POINTER); } *ppstreamResult = NULL; hrRes = CComObject<CSEOStream>::CreateInstance(&pStream); if (!SUCCEEDED(hrRes)) { return (hrRes); } pStream->AddRef(); libOffset.QuadPart = 0; hrRes = pStream->Init(hFile,pszFile,libOffset,NULL); if (SUCCEEDED(hrRes)) { hrRes = pStream->QueryInterface(IID_IStream,(LPVOID *) ppstreamResult); } pStream->Release(); return (hrRes); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCopyDictionary(ISEODictionary *pdictIn, ISEODictionary **ppdictResult) { HRESULT hrRes; CComPtr<ISEODictionary> pdictTmp;
if (!ppdictResult) { return (E_POINTER); } *ppdictResult = NULL; hrRes = CComObject<CSEOMemDictionary>::_CreatorClass::CreateInstance(NULL, IID_ISEODictionary, (LPVOID *) &pdictTmp); if (!SUCCEEDED(hrRes)) { return (hrRes); } if (pdictIn) { CComPtr<IUnknown> punkEnum;
hrRes = pdictIn->get__NewEnum(&punkEnum); if (!SUCCEEDED(hrRes)) { return (hrRes); } CComQIPtr<IEnumVARIANT,&IID_IEnumVARIANT> pevEnum(punkEnum); if (!pevEnum) { return (E_NOINTERFACE); } VARIANT varName; VariantInit(&varName); while ((hrRes=pevEnum->Next(1,&varName,NULL))==S_OK) { VARIANT varValue;
VariantInit(&varValue); hrRes = pdictIn->get_Item(&varName,&varValue); if (!SUCCEEDED(hrRes) || (varValue.vt == VT_EMPTY)) { VariantClear(&varName); return (hrRes); } hrRes = VariantChangeType(&varValue,&varValue,0,VT_UNKNOWN); if (SUCCEEDED(hrRes)) { CComQIPtr<ISEODictionary,&IID_ISEODictionary> pdictSub(varValue.punkVal);
if (pdictSub) { CComPtr<ISEODictionary> pdictSubCopy;
hrRes = SEOCopyDictionary(pdictSub,&pdictSubCopy); if (!SUCCEEDED(hrRes)) { VariantClear(&varName); return (hrRes); } varValue.punkVal->Release(); varValue.punkVal = pdictSubCopy; varValue.punkVal->AddRef(); } } hrRes = pdictTmp->put_Item(&varName,&varValue); VariantClear(&varName); VariantClear(&varValue); if (!SUCCEEDED(hrRes)) { return (hrRes); } } if (hrRes == S_FALSE) { hrRes = S_OK; } } *ppdictResult = pdictTmp; (*ppdictResult)->AddRef(); return (hrRes); }
static HRESULT ReadLineFromStream(IStream *pstreamIn, LPSTR *ppszLine) { HRESULT hrRes; const int c_iAllocSize = 512; LPSTR pszTmp = NULL; LPSTR pszCurr = NULL; LPSTR pszEnd = NULL; BOOL bInEscape = FALSE; BOOL bEOF = FALSE;
if (!pstreamIn || !ppszLine) { return (E_POINTER); } CoTaskMemFree(*ppszLine); *ppszLine = NULL; while (1) { if (pszCurr == pszEnd) { LPSTR pszNew = (LPSTR) CoTaskMemRealloc(pszTmp,((pszCurr-pszTmp)+c_iAllocSize)*sizeof(*pszTmp));
if (!pszNew) { CoTaskMemFree(pszTmp); return (E_OUTOFMEMORY); } pszCurr = pszNew + (pszCurr-pszTmp); pszEnd = pszCurr + c_iAllocSize; pszTmp = pszNew; } hrRes = pstreamIn->Read(pszCurr,sizeof(*pszCurr),NULL); if (!SUCCEEDED(hrRes)) { CoTaskMemFree(pszTmp); return (hrRes); } if (hrRes == S_FALSE) { // end-of-file - pretend like non-escaped '\n'
bInEscape = FALSE; *pszCurr = '\n'; bEOF = TRUE; } if (*pszCurr == '\r') { // always eat carriage returns - even escaped ones
continue; } if (bInEscape) { switch (*pszCurr) {
case 'n': // escape-n becomes linefeed
*pszCurr = '\n'; break;
case 'r': // escape-r becomes carriage return
*pszCurr = '\r'; break;
case '\n': // escaped-linefeed means line continuation
pszCurr--; break;
// for now, don't allow embedded NULLs - this is because we return a NULL-terminated string
// case '0':
// // escape-0 means embedded NULL
// *pszCurr = 0;
// break;
case 0: // escape-NULL - just eat
pszCurr--; break;
default: // escape-(anything else) is just passed through
break; } bInEscape = FALSE; } else { BOOL bFinished = FALSE;
switch (*pszCurr) {
case '\\': // first character of escape sequence
pszCurr--; bInEscape = TRUE; break;
case '\n': // end-of-line
bFinished = TRUE; break;
case 0: // non-escaped NULL - just eat
pszCurr--; break; } if (bFinished) { break; } } pszCurr++; } *pszCurr = 0; *ppszLine = pszTmp; return (bEOF?S_FALSE:S_OK); }
static HRESULT SEOCreateMultiSzFromIStreamA(IStream *pstreamIn, DWORD *pdwCount, LPSTR **pppszNames, LPSTR **pppszValues) { HRESULT hrRes; LPSTR *ppszLines = NULL; DWORD dwLines = NULL;
if (!pstreamIn || !pdwCount || !pppszNames || !pppszValues) { return (E_POINTER); } *pdwCount = 0; *pppszNames = NULL; *pppszValues = NULL; while (1) { LPSTR *ppszNew = (LPSTR *) CoTaskMemRealloc(ppszLines,sizeof(*ppszLines)*(dwLines+1));
if (!ppszNew) { hrRes = E_OUTOFMEMORY; break; } ppszLines = ppszNew; ppszLines[dwLines] = NULL; hrRes = ReadLineFromStream(pstreamIn,&ppszLines[dwLines]); if (!SUCCEEDED(hrRes)) { break; } if (!ppszLines[dwLines][0] || (ppszLines[dwLines][0] == '#') || !strchr(ppszLines[dwLines],'=')) { if (hrRes == S_FALSE) { break; } CoTaskMemFree(ppszLines[dwLines]); continue; } dwLines++; } if (SUCCEEDED(hrRes)) { DWORD dwIdx; LPSTR pszNameCurr = NULL; LPSTR pszValueCurr = NULL;
hrRes = S_OK; while (1) { for (dwIdx=0;dwIdx<dwLines;dwIdx++) { LPSTR pszEquals = strchr(ppszLines[dwIdx],'=');
if (*pppszNames) { (*pppszNames)[dwIdx] = pszNameCurr; memcpy(pszNameCurr, ppszLines[dwIdx], (pszEquals-ppszLines[dwIdx])*sizeof(*pszNameCurr)); (*pppszValues)[dwIdx] = pszValueCurr; strcpy(pszValueCurr,pszEquals+1); } pszNameCurr += pszEquals - ppszLines[dwIdx] + 1; pszValueCurr += strlen(pszEquals+1) + 1 + 1; // multi-sz, so is double-NULL terminated
} if (*pppszNames) { *pdwCount = dwLines; break; } if (!*pppszNames) { DWORD dwNameBytes = dwLines * sizeof(*pppszNames) + ((LPBYTE) pszNameCurr - (LPBYTE) NULL); DWORD dwValueBytes = dwLines * sizeof(*pppszValues) + ((LPBYTE) pszValueCurr - (LPBYTE) NULL);
*pppszNames = (LPSTR *) CoTaskMemAlloc(dwNameBytes); *pppszValues = (LPSTR *) CoTaskMemAlloc(dwValueBytes); if (!*pppszNames || !*pppszValues) { hrRes = E_OUTOFMEMORY; break; } memset(*pppszNames,0,dwNameBytes); memset(*pppszValues,0,dwValueBytes); pszNameCurr = (LPSTR) ((LPBYTE) *pppszNames + dwLines * sizeof(*pppszNames)); pszValueCurr = (LPSTR) ((LPBYTE) *pppszValues + dwLines * sizeof(*pppszValues)); } } } if (!SUCCEEDED(hrRes)) { *pdwCount = 0; CoTaskMemFree(*pppszNames); CoTaskMemFree(*pppszValues); } for (DWORD dwIdx=0;dwIdx<dwLines;dwIdx++) { CoTaskMemFree(ppszLines[dwIdx]); } CoTaskMemFree(ppszLines); return (hrRes); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOCreateDictionaryFromIStream(IStream *pstreamIn, ISEODictionary **ppdictResult) { HRESULT hrRes; DWORD dwCount; LPSTR *ppszNames; LPSTR *ppszValues;
if (!ppdictResult) { return (E_POINTER); } hrRes = SEOCreateMultiSzFromIStreamA(pstreamIn,&dwCount,&ppszNames,&ppszValues); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = SEOCreateDictionaryFromMultiSzA(dwCount, (LPCSTR *) ppszNames, (LPCSTR *) ppszValues, TRUE, FALSE, ppdictResult); CoTaskMemFree(ppszNames); CoTaskMemFree(ppszValues); return (hrRes); }
static HRESULT SEOWriteMultiSzToIStreamA(DWORD dwCount, LPCSTR *ppszNames, LPCSTR *ppszValues, IStream *pstreamOut) {
return (E_NOTIMPL); }
SEODLLDEF HRESULT STDAPICALLTYPE SEOWriteDictionaryToIStream(ISEODictionary *pdictIn, IStream *pstreamOut) { HRESULT hrRes; DWORD dwCount; LPSTR *ppszNames; LPSTR *ppszValues;
if (!pstreamOut) { return (E_POINTER); } hrRes = SEOCreateMultiSzFromDictionaryA(pdictIn,&dwCount,&ppszNames,&ppszValues); if (!SUCCEEDED(hrRes)) { return (hrRes); } hrRes = SEOWriteMultiSzToIStreamA(dwCount,(LPCSTR *) ppszNames,(LPCSTR *) ppszValues,pstreamOut); CoTaskMemFree(ppszNames); CoTaskMemFree(ppszValues); return (hrRes); }
|