1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4// ===========================================================================
5// File: ildbsymbols.cpp
6//
7
8// ===========================================================================
9
10#include "pch.h"
11
12#include "classfactory.h"
13
14// GUID identifying the ILDB format version.
15extern "C" const GUID ILDB_VERSION_GUID = {0x9e02e5b6, 0x8aef, 0x4d06, { 0x82, 0xe8, 0xe, 0x9b, 0x45, 0x49, 0x97, 0x16} };
16
17// Version used for the "first source release", no longer supported.
18extern "C" const GUID ILDB_VERSION_GUID_FSR = {0xCB2F6723, 0xAB3A, 0x11d, { 0x9C, 0x40, 0x00, 0xC0, 0x4F, 0xA3, 0x0A, 0x3E} };
19
20// This map contains the list of coclasses which are exported from this module.
21const COCLASS_REGISTER g_CoClasses[] =
22{
23// pClsid szProgID pfnCreateObject
24 { &CLSID_CorSymReader_SxS, W("CorSymReader"), SymReader::NewSymReader},
25 { &CLSID_CorSymWriter_SxS, W("CorSymWriter"), SymWriter::NewSymWriter},
26 { &CLSID_CorSymBinder_SxS, W("CorSymBinder"), SymBinder::NewSymBinder},
27 { NULL, NULL, NULL }
28};
29
30STDAPI IldbSymbolsGetClassObject(REFCLSID rclsid, REFIID riid, void** ppvObject)
31{
32 CIldbClassFactory *pClassFactory; // To create class factory object.
33 const COCLASS_REGISTER *pCoClass; // Loop control.
34 HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
35
36 _ASSERTE(IsValidCLSID(rclsid));
37 _ASSERTE(IsValidIID(riid));
38 _ASSERTE(IsValidWritePtr(ppvObject, void*));
39
40 if (ppvObject)
41 {
42 *ppvObject = NULL;
43
44 // Scan for the right one.
45 for (pCoClass=g_CoClasses; pCoClass->pClsid; pCoClass++)
46 {
47 if (*pCoClass->pClsid == rclsid)
48 {
49 // Allocate the new factory object.
50 pClassFactory = NEW(CIldbClassFactory(pCoClass));
51 if (!pClassFactory)
52 return (E_OUTOFMEMORY);
53
54 // Pick the v-table based on the caller's request.
55 hr = pClassFactory->QueryInterface(riid, ppvObject);
56
57 // Always release the local reference, if QI failed it will be
58 // the only one and the object gets freed.
59 pClassFactory->Release();
60 break;
61 }
62 }
63 }
64 else
65 {
66 hr = E_INVALIDARG;
67 }
68
69 return hr;
70}
71
72/* ------------------------------------------------------------------------- *
73 * CIldbClassFactory class
74 * ------------------------------------------------------------------------- */
75
76//*****************************************************************************
77// QueryInterface is called to pick a v-table on the co-class.
78//*****************************************************************************
79HRESULT STDMETHODCALLTYPE CIldbClassFactory::QueryInterface(
80 REFIID riid,
81 void **ppvObject)
82{
83 HRESULT hr;
84
85 if (ppvObject == NULL)
86 {
87 return E_INVALIDARG;
88 }
89
90 // Avoid confusion.
91 *ppvObject = NULL;
92
93 // Pick the right v-table based on the IID passed in.
94 if (riid == IID_IUnknown)
95 *ppvObject = (IUnknown *) this;
96 else if (riid == IID_IClassFactory)
97 *ppvObject = (IClassFactory *) this;
98
99 // If successful, add a reference for out pointer and return.
100 if (*ppvObject)
101 {
102 hr = S_OK;
103 AddRef();
104 }
105 else
106 hr = E_NOINTERFACE;
107 return (hr);
108}
109
110
111//*****************************************************************************
112// CreateInstance is called to create a new instance of the coclass for which
113// this class was created in the first place. The returned pointer is the
114// v-table matching the IID if there.
115//*****************************************************************************
116HRESULT STDMETHODCALLTYPE CIldbClassFactory::CreateInstance(
117 IUnknown *pUnkOuter,
118 REFIID riid,
119 void **ppvObject)
120{
121 HRESULT hr;
122
123 _ASSERTE(IsValidIID(riid));
124 _ASSERTE(IsValidWritePtr(ppvObject, void*));
125
126 // Avoid confusion.
127 *ppvObject = NULL;
128 _ASSERTE(m_pCoClass);
129
130 // Aggregation is not supported by these objects.
131 if (pUnkOuter)
132 return (CLASS_E_NOAGGREGATION);
133
134 // Ask the object to create an instance of itself, and check the iid.
135 hr = (*m_pCoClass->pfnCreateObject)(riid, ppvObject);
136 return (hr);
137}
138
139// Version of CreateInstance called directly from clients
140STDAPI IldbSymbolsCreateInstance(REFCLSID rclsid, REFIID riid, void** ppvIUnknown)
141{
142 IClassFactory *pClassFactory = NULL;
143 HRESULT hr = IldbSymbolsGetClassObject(rclsid, IID_IClassFactory, (void**)&pClassFactory);
144 if (SUCCEEDED(hr))
145 hr = pClassFactory->CreateInstance(NULL, riid, ppvIUnknown);
146 if (pClassFactory)
147 pClassFactory->Release();
148 return hr;
149}
150
151HRESULT STDMETHODCALLTYPE CIldbClassFactory::LockServer(
152 BOOL fLock)
153{
154 return (S_OK);
155}
156