source: trunk/src/ole32/new/initialise.cpp@ 3456

Last change on this file since 3456 was 3456, checked in by davidr, 25 years ago

OLE32/NEW: Work-in-progress on adding apartment handling

File size: 5.5 KB
Line 
1/* $Id: initialise.cpp,v 1.1 2000-04-27 22:18:20 davidr Exp $ */
2/*
3 *
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 */
7/*
8 * COM/OLE Startup shutdown.
9 *
10 * 1/7/99
11 *
12 * Copyright 1999 David J. Raison
13 *
14 * Some portions from Wine Implementation
15 * Copyright 1995 Martin von Loewis
16 * Copyright 1998 Justin Bradford
17 * Copyright 1999 Francis Beaudet
18 * Copyright 1999 Sylvain St-Germain
19 */
20
21#include "ole32.h"
22#include <vmutex.h>
23
24#include "oString.h"
25#include "oTls.h"
26#include "apartment.h"
27#include "moniker.h" // RunningObjectTableImpl_***
28#include "filemoniker.h" // FileMonikerImpl_***
29
30extern void COM_RevokeAllClasses();
31extern void COM_ExternalLockFreeList();
32
33// Process wide variables
34Apartment * g_pAptMT;
35Apartment * g_pAptTN;
36Apartment * g_pAptMain;
37Apartment * g_pAptHost;
38
39VMutex g_AptMutex;
40
41LONG g_ComRef = 0;
42VMutex g_ComRefMutex;
43
44// Thread level variables
45oTlsValue<ThreadInfo *> t_pThreadInfo; // ThreadLevel Information
46
47// ----------------------------------------------------------------------
48// CoInitialize()
49// ----------------------------------------------------------------------
50HRESULT WIN32API CoInitialize(LPVOID lpReserved)
51{
52 dprintf(("OLE32: CoInitialize\n"));
53
54 return CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
55}
56
57// ----------------------------------------------------------------------
58// CreateHost
59// ----------------------------------------------------------------------
60static Apartment * CreateHost(void )
61{
62 // Thread Sync. protocol required here.
63 // CreateThread(blah, &g_pAptHost)
64 return new Apartment(APT_HOST);
65}
66
67// ----------------------------------------------------------------------
68// GetDistinguishedApt()
69// ----------------------------------------------------------------------
70static Apartment * GetDistinguishedApt(enAptType aptType)
71{
72 switch (aptType)
73 {
74 case APT_MT:
75 g_AptMutex.enter();
76 if (g_pAptMT == NULL)
77 {
78 g_pAptMT = new Apartment(APT_MT);
79 }
80 g_AptMutex.leave();
81
82 return g_pAptMT;
83
84 case APT_TN:
85 g_AptMutex.enter();
86 if (g_pAptTN == NULL)
87 {
88 g_pAptTN = new Apartment(APT_TN);
89 }
90 g_AptMutex.leave();
91
92 return g_pAptTN;
93
94 case APT_HOST:
95 g_AptMutex.enter();
96 if (g_pAptHost == NULL)
97 {
98 g_pAptHost = CreateHost();
99 if (g_pAptMain == NULL)
100 {
101 g_pAptMain = g_pAptHost;
102 }
103 }
104 g_AptMutex.leave();
105
106 return g_pAptHost;
107
108 case APT_MAIN:
109 {
110 g_AptMutex.enter();
111 if (g_pAptMain == NULL)
112 {
113 g_pAptMain = CreateHost();
114 }
115 g_AptMutex.leave();
116
117 return g_pAptMain;
118 }
119 }
120
121 return NULL;
122}
123
124// ----------------------------------------------------------------------
125// GetSingleThreadedApt()
126// ----------------------------------------------------------------------
127static Apartment * GetSingleThreadedApt()
128{
129 Apartment * retObj;
130
131 g_AptMutex.enter();
132
133 // If Main not defined yet we become main...
134 if (g_pAptMain == NULL)
135 {
136 g_pAptMain = new Apartment(APT_MAIN);
137 retObj = g_pAptMain;
138 }
139 else
140 retObj = new Apartment(APT_ST);
141
142 g_AptMutex.leave();
143 return retObj;
144}
145
146// ----------------------------------------------------------------------
147// CoInitializeEx()
148// ----------------------------------------------------------------------
149HRESULT WIN32API CoInitializeEx(
150 LPVOID lpReserved, // [in] pointer to win32 malloc interface
151 DWORD dwCoInit) // [in] A value from COINIT specifies the thread
152{
153 HRESULT hr;
154
155 dprintf(("OLE32: CoInitializeEx(%p, %lx)\n", lpReserved, dwCoInit));
156
157 // Does com require initialisation?
158 g_ComRefMutex.enter();
159
160 if (++g_ComRef == 1)
161 RunningObjectTableImpl_Initialize();
162
163 g_ComRefMutex.leave();
164
165 // Does this thread require initialisation?
166 if (t_pThreadInfo == NULL) // 1'st time through
167 {
168 ThreadInfo * l_pThreadInfo;
169
170 l_pThreadInfo = new ThreadInfo;
171
172 if (dwCoInit == COINIT_APARTMENTTHREADED)
173 {
174 l_pThreadInfo->SetHomeApt(GetSingleThreadedApt());
175 }
176 else if (dwCoInit == COINIT_MULTITHREADED)
177 {
178 l_pThreadInfo->SetHomeApt(GetDistinguishedApt(APT_MT));
179 }
180 else
181 {
182 delete l_pThreadInfo;
183 return E_INVALIDARG;
184 }
185
186 // Initialise the current object context...
187 l_pThreadInfo->SetCurContext(l_pThreadInfo->GetHomeApt()->GetDefaultContext());
188
189 t_pThreadInfo.SetValue(l_pThreadInfo); // Stash in TLS
190
191 hr = S_OK;
192 }
193 else // Subsequent call for this thread...
194 {
195 if (dwCoInit == COINIT_APARTMENTTHREADED)
196 {
197 if (t_pThreadInfo->GetHomeApt()->GetAptType() == APT_MT)
198 return RPC_E_CHANGED_MODE;
199 }
200 else if (dwCoInit == COINIT_MULTITHREADED)
201 {
202 if (t_pThreadInfo->GetHomeApt()->GetAptType() != APT_MT)
203 return RPC_E_CHANGED_MODE;
204 }
205 else
206 return E_INVALIDARG;
207
208 t_pThreadInfo->AddRef();
209
210 hr = S_FALSE;
211 }
212
213 return hr;
214}
215
216// ----------------------------------------------------------------------
217// CoUninitialize()
218// ----------------------------------------------------------------------
219void WIN32API CoUninitialize(void)
220{
221 dprintf(("OLE32: CoUninitialize"));
222
223 // Does thread require termination?
224 if (t_pThreadInfo == NULL)
225 return;
226
227 if (t_pThreadInfo->Release() == 0)
228 {
229 ThreadInfo * l_ThreadInfo = t_pThreadInfo;
230
231 delete l_ThreadInfo;
232
233 t_pThreadInfo.SetValue(NULL);
234 }
235
236 // Does com require termination?
237 g_ComRefMutex.enter();
238 if (--g_ComRef == 0)
239 {
240 dprintf(("OLE32: Releasing COM libraries"));
241
242 RunningObjectTableImpl_UnInitialize();
243
244 COM_RevokeAllClasses();
245
246 CoFreeAllLibraries();
247
248 COM_ExternalLockFreeList();
249 }
250 g_ComRefMutex.leave();
251}
Note: See TracBrowser for help on using the repository browser.