Leaked source code of windows server 2003
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.
 
 
 
 
 
 

281 lines
9.9 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
StdAfx.cpp
Abstract:
This module contains the implementation for the base
ATL methods.
Author:
Don Dumitru ([email protected])
Revision History:
dondu 12/04/96 created
--*/
// stdafx.cpp : source file that includes just the standard includes
// stdafx.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
#ifdef _ATL_STATIC_REGISTRY
#include <statreg.h>
#include <statreg.cpp>
#endif
#include <atlimpl.cpp>
HRESULT AtlAllocRegMapEx(_ATL_REGMAP_ENTRY **pparmeResult,
const CLSID *pclsid,
CSEOComModule *pmodule,
LPCOLESTR pszIndex,
...) {
LPBYTE pbAdd = NULL; // Working pointer to the next available "scratch space" in the map.
DWORD dwCnt = 0; // The count of entries in the map.
LPOLESTR pszCLSID = NULL; // The CLSID as a string.
LPOLESTR pszTLID = NULL; // The TLID as a string.
LPOLESTR pszAPPID = NULL; // The APPID as a string.
if (!pparmeResult) {
// The caller did not give us a place to return the result.
return (E_POINTER);
}
*pparmeResult = NULL; // For the first time through the loop, the result is NULL.
// We are going to loop through twice. The first time through, we haven't allocate the map yet, so
// we will count all the strings, and add up their lenghts - this will give us the size of the buffer
// we need to allocate for the map. Then the second time through the loop, we will store all the
// strings in the map.
while (1) {
if (pclsid) {
// If we were passed a CLSID, then we want to include that in the map.
if (!*pparmeResult) {
// If this is the first time through, then we need to convert the CLSID to a string.
HRESULT hrRes;
hrRes = StringFromCLSID(*pclsid,&pszCLSID);
if (!SUCCEEDED(hrRes)) {
// We failed to convert the CLSID to a string.
return (hrRes);
}
} else {
// If this isn't the first time through, then we already have the CLSID as a string, so
// we just need to put it in the map.
(*pparmeResult)[dwCnt].szKey = L"CLSID";
(*pparmeResult)[dwCnt].szData = (LPCOLESTR) pbAdd;
wcscpy((LPOLESTR) (*pparmeResult)[dwCnt].szData,pszCLSID);
}
// Whether or not this is the first time through, we increment some stuff based on the size
// of the CLSID string and the fact that we have a CLSID in the map.
pbAdd += (wcslen(pszCLSID)+1) * sizeof(OLECHAR);
dwCnt++;
if (*pparmeResult) {
// If this is not the first time through, make sure we clean up after ourselves.
CoTaskMemFree(pszCLSID);
pszCLSID = NULL;
}
}
if (pmodule) {
// If we were passed a module, then we want to include the TLID and APPID in the map.
if (!*pparmeResult) {
// If this is the first time through, then we need to load the type library, get its
// TLID, and convert it to a string.
USES_CONVERSION;
HRESULT hrRes;
TCHAR szModule[MAX_PATH];
LPOLESTR pszModule;
CComPtr<ITypeLib> pTypeLib;
TLIBATTR *ptlaAttr;
if (!GetModuleFileName(pmodule->GetTypeLibInstance(),
szModule,
sizeof(szModule)/sizeof(TCHAR))) {
hrRes = HRESULT_FROM_WIN32(GetLastError());
if (SUCCEEDED(hrRes)) {
// GetModuleFileName() failed, but GetLastError() didn't report an error - so
// fake it.
hrRes = E_OUTOFMEMORY;
}
CoTaskMemFree(pszCLSID);
return (hrRes);
}
if (pszIndex) {
// If we were passed an index, that means that the type library desired is not the
// first type library in the resources - so append the index to the module name.
lstrcat(szModule,OLE2T(pszIndex));
}
pszModule = T2OLE(szModule);
hrRes = LoadTypeLib(pszModule,&pTypeLib);
if (!SUCCEEDED(hrRes)) {
// If we couldn't load the type library from the module, let's try changing the
// module name to a type library name (change the extension to .TLB) and try to load
// *that*.
LPTSTR pszExt = NULL;
LPTSTR psz;
for (psz=szModule;*psz;psz=CharNext(psz)) {
if (*psz == _T('.')) {
pszExt = psz;
}
}
if (!pszExt) {
pszExt = psz;
}
lstrcpy(pszExt,_T(".tlb"));
pszModule = T2OLE(szModule);
hrRes = LoadTypeLib(pszModule,&pTypeLib);
}
if (!SUCCEEDED(hrRes)) {
// We failed to load the type library.
CoTaskMemFree(pszCLSID);
return (hrRes);
}
hrRes = pTypeLib->GetLibAttr(&ptlaAttr);
if (!SUCCEEDED(hrRes)) {
// We failed to get the type library attributes.
CoTaskMemFree(pszCLSID);
return (hrRes);
}
hrRes = StringFromCLSID(ptlaAttr->guid,&pszTLID);
if (!SUCCEEDED(hrRes)) {
// We failed to convert the TLID to a string.
CoTaskMemFree(pszCLSID);
return (hrRes);
}
} else {
// If this isn't the first time through, then we already have the TLID as a string, so
// we just need to put it in the map.
(*pparmeResult)[dwCnt].szKey = L"LIBID";
(*pparmeResult)[dwCnt].szData = (LPCOLESTR) pbAdd;
wcscpy((LPOLESTR) (*pparmeResult)[dwCnt].szData,pszTLID);
}
// Whether or not this is the first time through, we increment some stuff based on the size
// of the TLID string and the fact that we have a TLID in the map.
pbAdd += (wcslen(pszTLID)+1) * sizeof(OLECHAR);
dwCnt++;
if (*pparmeResult) {
// If this is not the first time through, make sure we clean up after ourselves.
CoTaskMemFree(pszTLID);
pszTLID = NULL;
}
if (!*pparmeResult) {
// If this is the first time through, see if an APPID is provided by the
// module.
const GUID *pappid = pmodule->GetAPPID();
if (pappid) {
// If there is an APPID, convert it to a string.
HRESULT hrRes;
hrRes = StringFromCLSID(*pappid,&pszAPPID);
if (!SUCCEEDED(hrRes)) {
// We failed to convert the APPID to a string.
CoTaskMemFree(pszCLSID);
return (hrRes);
}
}
}
if (pszAPPID) {
// If the module provides an APPID, we need to add it to the map.
if (*pparmeResult) {
// If this isn't the first time through, then we already have the APPID as a string,
// so we just need to put it in the map.
(*pparmeResult)[dwCnt].szKey = L"APPID";
(*pparmeResult)[dwCnt].szData = (LPCOLESTR) pbAdd;
wcscpy((LPOLESTR) (*pparmeResult)[dwCnt].szData,pszAPPID);
}
// Whether or not this is the first time through, we increment some stuff based on the
// size of the APPID string and the fact that we have a APPID in the map.
pbAdd += (wcslen(pszAPPID)+1) * sizeof(OLECHAR);
dwCnt++;
if (*pparmeResult) {
// If this is not the first time through, make sure we clean up after ourselves.
CoTaskMemFree(pszAPPID);
pszAPPID = NULL;
}
}
}
{ // Now we need to go through the varargs. All of the varargs must be LPOLESTR (i.e. they
// must be UNICODE), and they will consist of pairs - the key name followed by the data. If
// either member of the pair is NULL, that signals the end of the varargs.
va_list valArgs;
// Set the va_list to the start of the varargs.
va_start(valArgs,pszIndex);
while (1) {
LPCOLESTR pszKey;
LPCOLESTR pszData;
// Get the first of the pair - this is the key name.
pszKey = va_arg(valArgs,LPCOLESTR);
if (!pszKey) {
break;
}
// Get the second of the pair - this is the data.
pszData = va_arg(valArgs,LPCOLESTR);
if (!pszData) {
break;
}
if (*pparmeResult) {
// If this isn't the first time through, then we need to store the key name to the
// map.
(*pparmeResult)[dwCnt].szKey = (LPCOLESTR) pbAdd;
wcscpy((LPOLESTR) (*pparmeResult)[dwCnt].szKey,pszKey);
}
// Whether or not this is the first time through, we increment some stuff based on the
// size of the string.
pbAdd += (wcslen(pszKey)+1) * sizeof(OLECHAR);
if (*pparmeResult) {
// If this isn't the first time through, then we need to store the data to the map.
(*pparmeResult)[dwCnt].szData = (LPCOLESTR) pbAdd;
wcscpy((LPOLESTR) (*pparmeResult)[dwCnt].szData,pszData);
}
// Whether or not this is the first time through, we increment some stuff based on the
// size of the string and the fact that we have a string in the map.
pbAdd += (wcslen(pszData)+1) * sizeof(OLECHAR);
dwCnt++;
}
// Reset the va_list, for the sake of cleanliness.
va_end(valArgs);
}
if (*pparmeResult) {
// If we have allocated the map, that means that we are finishing the second time through
// the loop - so we are done!
break;
}
if (!*pparmeResult) {
// If we havemn't allocate the map, that means that we are finishing the first time through
// the loop - so we need to allocate the map in preparation for the second time through.
// First we calculate the number of bytes needed for the map - this is one ATL_REGMAP_ENTRY
// for each entry, plus one _ATL_REGMAP_ENTRY which signals the end of the map, plus enough
// space for all of the strings to follow.
DWORD dwBytes = (dwCnt + 1) * sizeof(_ATL_REGMAP_ENTRY) + (DWORD)(pbAdd-(LPBYTE) NULL);
*pparmeResult = (_ATL_REGMAP_ENTRY *) CoTaskMemAlloc(dwBytes);
if (!*pparmeResult) {
// The memory allocation failed.
CoTaskMemFree(pszCLSID);
CoTaskMemFree(pszTLID);
CoTaskMemFree(pszAPPID);
return (E_OUTOFMEMORY);
}
// The memory allocation was successful - fill the memory with zeroes in preparation for
// loading with the values.
memset(*pparmeResult,0,dwBytes);
// Reset the counters to the "beginning" - so that on the second time through, they are used
// to keep track of where each successive value gets stored in the memory block.
pbAdd = ((LPBYTE) *pparmeResult) + (dwCnt + 1) * sizeof(_ATL_REGMAP_ENTRY);
dwCnt = 0;
}
}
return (S_OK);
}