source: trunk/src/ole32/old/ole2.cpp

Last change on this file was 5601, checked in by sandervl, 24 years ago

created

File size: 13.3 KB
RevLine 
[5601]1/* $Id: ole2.cpp,v 1.1 2001-04-26 19:26:12 sandervl Exp $ */
2/*
3 *
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 */
7/*
8 * OLE functions.
9 *
10 * 2/9/99
11 *
12 * Copyright 1999 David J. Raison
13 *
14 * Some portions from Wine Implementation (2/9/99)
15 * Copyright 1995 Martin von Loewis
16 * Copyright 1999 Francis Beaudet
17 * Copyright 1999 Noel Borthwick
18 */
19
20#include "ole32.h"
21#include "commctrl.h"
22#include "oString.h"
23#include "heapstring.h"
24#include <assert.h>
25
26// ======================================================================
27// Local Data
28// ======================================================================
29
30/*
31 * This is the lock count on the OLE library. It is controlled by the
32 * OLEInitialize/OLEUninitialize methods.
33 */
34static ULONG OLE_moduleLockCount = 0;
35
36
37// ======================================================================
38// Prototypes.
39// ======================================================================
40static void OLEUTL_ReadRegistryDWORDValue(HKEY regKey, DWORD* pdwValue);
41
42// These are the prototypes of the utility methods used to manage a shared menu
43extern void OLEMenu_Initialize();
44extern void OLEMenu_UnInitialize();
45
46// These are the prototypes of the OLE Clipboard initialization methods (in clipboard.c)
47extern void OLEClipbrd_UnInitialize();
48extern void OLEClipbrd_Initialize();
49
50// These are the prototypes of the utility methods used for OLE Drag n Drop
51extern void OLEDD_Initialize();
52extern void OLEDD_UnInitialize();
53
54// ======================================================================
55// Public API's
56// ======================================================================
57
58// ----------------------------------------------------------------------
59// OleBuildVersion()
60// ----------------------------------------------------------------------
61DWORD WIN32API OleBuildVersion(void)
62{
63 dprintf(("OLE32.OleBuildVersion"));
64 return (rmm<<16)+rup;
65}
66
67// ----------------------------------------------------------------------
68// OleInitialize()
69// ----------------------------------------------------------------------
70HRESULT WIN32API OleInitialize(LPVOID reserved)
71{
72 HRESULT hr;
73
74 dprintf(("OLE32: OleInitialize"));
75
76 // The first duty of the OleInitialize is to initialize the COM libraries.
77 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
78 if (FAILED(hr))
79 return hr;
80
81 // Then, it has to initialize the OLE specific modules.
82 // This includes:
83 // Clipboard
84 // Drag and Drop
85 // Object linking and Embedding
86 // In-place activation
87 if (++OLE_moduleLockCount == 1)
88 {
89 dprintf((" First time through - Initializing"));
90
91 // OLE Clipboard
92 OLEClipbrd_Initialize();
93
94 // Drag and Drop
95 OLEDD_Initialize();
96
97 // OLE shared menu
98 OLEMenu_Initialize();
99 }
100
101 return hr;
102}
103
104// ----------------------------------------------------------------------
105// CoGetCurrentProcess()
106// ----------------------------------------------------------------------
107DWORD WIN32API CoGetCurrentProcess()
108{
109 dprintf(("OLE32: CoGetCurrentProcess"));
110 return GetCurrentProcessId();
111}
112
113// ----------------------------------------------------------------------
114// OleUninitialize()
115// ----------------------------------------------------------------------
116void WIN32API OleUninitialize(void)
117{
118 dprintf(("OLE32: OleUninitialize"));
119
120 // If we hit the bottom of the lock stack, free the libraries.
121 if (--OLE_moduleLockCount == 0)
122 {
123 dprintf((" no more references - Terminating"));
124
125 // OLE Clipboard
126 OLEClipbrd_UnInitialize();
127
128 // Drag and Drop
129 OLEDD_UnInitialize();
130
131 // OLE shared menu
132 OLEMenu_UnInitialize();
133 }
134
135 // Then, uninitialize the COM libraries.
136 CoUninitialize();
137}
138
139// ----------------------------------------------------------------------
140// OleRegGetUserType()
141// ----------------------------------------------------------------------
142// This implementation of OleRegGetUserType ignores the dwFormOfType
143// parameter and always returns the full name of the object. This is
144// not too bad since this is the case for many objects because of the
145// way they are registered.
146// ----------------------------------------------------------------------
147HRESULT WIN32API OleRegGetUserType
148 (REFCLSID clsid,
149 DWORD dwFormOfType,
150 LPOLESTR * pszUserType)
151
152{
153 oStringA tCLSID;
154 DWORD dwKeyType;
155 DWORD cbData;
156 HKEY clsidKey;
157 LONG hres;
158 LPSTR buffer;
159
160 dprintf(("OLE32: OleRegGetUserType"));
161
162 *pszUserType = NULL;
163
164 // Build the key name we're looking for
165 tCLSID = "CLSID\\";
166 tCLSID += clsid;
167 tCLSID += "\\";
168
169 // Open the class id Key
170 hres = RegOpenKeyA(HKEY_CLASSES_ROOT, tCLSID, &clsidKey);
171 if (hres != ERROR_SUCCESS)
172 return REGDB_E_CLASSNOTREG;
173
174 // Retrieve the size of the name string.
175 cbData = 0;
176 hres = RegQueryValueExA(clsidKey, "", NULL, &dwKeyType, NULL, &cbData);
177 if (hres != ERROR_SUCCESS)
178 {
179 RegCloseKey(clsidKey);
180 return REGDB_E_READREGDB;
181 }
182
183 // Allocate a buffer for the registry value.
184 buffer = (LPSTR)HeapAlloc(GetProcessHeap(), 0, cbData);
185
186 if (buffer == NULL)
187 {
188 RegCloseKey(clsidKey);
189 return E_OUTOFMEMORY;
190 }
191
192 hres = RegQueryValueExA(HKEY_CLASSES_ROOT, "", NULL, &dwKeyType, (LPBYTE)buffer, &cbData);
193 RegCloseKey(clsidKey);
194 if (hres != ERROR_SUCCESS)
195 {
196 HeapFree(GetProcessHeap(), 0, buffer);
197 return REGDB_E_READREGDB;
198 }
199
200 // Allocate a buffer for the return value.
201 *pszUserType = (LPOLESTR)CoTaskMemAlloc(cbData * 2);
202
203 if (*pszUserType == NULL)
204 {
205 HeapFree(GetProcessHeap(), 0, buffer);
206 return E_OUTOFMEMORY;
207 }
208
209 // Copy & convert to unicode...
210 lstrcpyAtoW(*pszUserType, buffer);
211 HeapFree(GetProcessHeap(), 0, buffer);
212
213 return S_OK;
214}
215
216// ----------------------------------------------------------------------
217// OleRegGetMiscStatus()
218// ----------------------------------------------------------------------
219HRESULT WIN32API OleRegGetMiscStatus
220 (REFCLSID clsid,
221 DWORD dwAspect,
222 DWORD * pdwStatus)
223{
224 oStringA tStr;
225 HKEY clsidKey;
226 HKEY miscStatusKey;
227 HKEY aspectKey;
228 LONG result;
229
230 dprintf(("OLE32: OleRegGetMiscStatus"));
231
232 // Initialize the out parameter.
233 *pdwStatus = 0;
234
235 // Build the key name we're looking for
236 tStr = "CLSID\\";
237 tStr += clsid;
238 tStr += "\\";
239 dprintf((" Key : %s", (char *)tStr));
240
241 // Open the class id Key
242 result = RegOpenKeyA(HKEY_CLASSES_ROOT, tStr, &clsidKey);
243
244 if (result != ERROR_SUCCESS)
245 return REGDB_E_CLASSNOTREG;
246
247 // Get the MiscStatus
248 result = RegOpenKeyA(clsidKey, "MiscStatus", &miscStatusKey);
249
250 if (result != ERROR_SUCCESS)
251 {
252 RegCloseKey(clsidKey);
253 return REGDB_E_READREGDB;
254 }
255
256 // Read the default value
257 OLEUTL_ReadRegistryDWORDValue(miscStatusKey, pdwStatus);
258
259 // Open the key specific to the requested aspect.
260 oStringA tKey(dwAspect);
261 dprintf((" Aspect: %s", (char *)tKey));
262
263 result = RegOpenKeyA(miscStatusKey, tKey, &aspectKey);
264
265 if (result == ERROR_SUCCESS)
266 {
267 OLEUTL_ReadRegistryDWORDValue(aspectKey, pdwStatus);
268 RegCloseKey(aspectKey);
269 }
270
271 // Cleanup
272 RegCloseKey(miscStatusKey);
273 RegCloseKey(clsidKey);
274
275 return S_OK;
276}
277
278// ----------------------------------------------------------------------
279// OleSetContainedObject()
280// ----------------------------------------------------------------------
281HRESULT WIN32API OleSetContainedObject
282 (LPUNKNOWN pUnknown,
283 BOOL fContained)
284{
285 IRunnableObject * runnable = NULL;
286 HRESULT hres;
287
288 dprintf(("OLE32: OleSetContainedObject"));
289
290 hres = IUnknown_QueryInterface(pUnknown, &IID_IRunnableObject, (void**)&runnable);
291
292 if (SUCCEEDED(hres))
293 {
294 hres = IRunnableObject_SetContainedObject(runnable, fContained);
295
296 IRunnableObject_Release(runnable);
297
298 return hres;
299 }
300
301 return S_OK;
302}
303
304// ----------------------------------------------------------------------
305// OleLoad()
306// ----------------------------------------------------------------------
307HRESULT WIN32API OleLoad
308 (LPSTORAGE pStg,
309 REFIID riid,
310 LPOLECLIENTSITE pClientSite,
311 LPVOID * ppvObj)
312{
313 IPersistStorage * persistStorage = NULL;
314 IOleObject * oleObject = NULL;
315 STATSTG storageInfo;
316 HRESULT hres;
317
318 dprintf(("OLE32: OleLoad"));
319
320 // TODO, Conversion ... OleDoAutoConvert
321
322 // Get the class ID for the object.
323 hres = IStorage_Stat(pStg, &storageInfo, STATFLAG_NONAME);
324
325 // Now, try and create the handler for the object
326 hres = CoCreateInstance(&storageInfo.clsid,
327 NULL,
328 CLSCTX_INPROC_HANDLER,
329 &IID_IOleObject,
330 (void**)&oleObject);
331
332 // If that fails, as it will most times, load the default OLE handler.
333 if (FAILED(hres))
334 {
335 hres = OleCreateDefaultHandler(&storageInfo.clsid,
336 NULL,
337 &IID_IOleObject,
338 (void**)&oleObject);
339 }
340
341 // If we couldn't find a handler... this is bad. Abort the whole thing.
342 if (FAILED(hres))
343 return hres;
344
345 // Inform the new object of it's client site.
346 hres = IOleObject_SetClientSite(oleObject, pClientSite);
347
348 // Initialize the object with it's IPersistStorage interface.
349 hres = IOleObject_QueryInterface(oleObject, &IID_IPersistStorage, (void**)&persistStorage);
350
351 if (SUCCEEDED(hres))
352 {
353 IPersistStorage_Load(persistStorage, pStg);
354
355 IPersistStorage_Release(persistStorage);
356 persistStorage = NULL;
357 }
358
359 // Return the requested interface to the caller.
360 hres = IOleObject_QueryInterface(oleObject, riid, ppvObj);
361
362 // Cleanup interfaces used internally
363 IOleObject_Release(oleObject);
364
365 return hres;
366}
367
368// ----------------------------------------------------------------------
369// OleSave()
370// ----------------------------------------------------------------------
371HRESULT WIN32API OleSave
372 (LPPERSISTSTORAGE pPS,
373 LPSTORAGE pStg,
374 BOOL fSameAsLoad)
375{
376 HRESULT hres;
377 CLSID objectClass;
378
379 dprintf(("OLE32: OleSave"));
380
381 // First, we transfer the class ID (if available)
382 hres = IPersistStorage_GetClassID(pPS, &objectClass);
383
384 if (SUCCEEDED(hres))
385 WriteClassStg(pStg, &objectClass);
386
387 // Then, we ask the object to save itself to the
388 // storage. If it is successful, we commit the storage.
389 hres = IPersistStorage_Save(pPS, pStg, fSameAsLoad);
390
391 if (SUCCEEDED(hres))
392 IStorage_Commit(pStg, STGC_DEFAULT);
393
394 return hres;
395}
396
397// ----------------------------------------------------------------------
398// ReleaseStgMedium()
399// ----------------------------------------------------------------------
400void WIN32API ReleaseStgMedium(STGMEDIUM * pmedium)
401{
402 switch (pmedium->tymed)
403 {
404 case TYMED_HGLOBAL:
405 {
406 if ( (pmedium->pUnkForRelease == 0) && (pmedium->u.hGlobal != 0) )
407 GlobalFree(pmedium->u.hGlobal);
408
409 pmedium->u.hGlobal = 0;
410 break;
411 }
412 case TYMED_FILE:
413 {
414 if (pmedium->u.lpszFileName != 0)
415 {
416 if (pmedium->pUnkForRelease == 0)
417 DeleteFileW(pmedium->u.lpszFileName);
418
419 CoTaskMemFree(pmedium->u.lpszFileName);
420 }
421
422 pmedium->u.lpszFileName = 0;
423 break;
424 }
425 case TYMED_ISTREAM:
426 {
427 if (pmedium->u.pstm != 0)
428 IStream_Release(pmedium->u.pstm);
429
430 pmedium->u.pstm = 0;
431 break;
432 }
433 case TYMED_ISTORAGE:
434 {
435 if (pmedium->u.pstg != 0)
436 IStorage_Release(pmedium->u.pstg);
437
438 pmedium->u.pstg = 0;
439 break;
440 }
441 case TYMED_GDI:
442 {
443 if ( (pmedium->pUnkForRelease == 0) && (pmedium->u.hGlobal != 0) )
444 DeleteObject(pmedium->u.hGlobal);
445
446 pmedium->u.hGlobal = 0;
447 break;
448 }
449 case TYMED_MFPICT:
450 {
451 if ( (pmedium->pUnkForRelease == 0) && (pmedium->u.hMetaFilePict != 0) )
452 {
453 DeleteMetaFile(pmedium->u.hMetaFilePict);
454 GlobalFree(pmedium->u.hMetaFilePict);
455 }
456
457 pmedium->u.hMetaFilePict = 0;
458 break;
459 }
460 case TYMED_ENHMF:
461 {
462 if ( (pmedium->pUnkForRelease == 0) && (pmedium->u.hEnhMetaFile != 0) )
463 DeleteEnhMetaFile(pmedium->u.hEnhMetaFile);
464
465 pmedium->u.hEnhMetaFile = 0;
466 break;
467 }
468 case TYMED_NULL:
469 // Do nothing
470 break;
471
472 default:
473 break;
474 }
475
476 // After cleaning up, the unknown is released
477 if (pmedium->pUnkForRelease != 0)
478 {
479 IUnknown_Release(pmedium->pUnkForRelease);
480 pmedium->pUnkForRelease = 0;
481 }
482}
483
484// ======================================================================
485// Private functions.
486// ======================================================================
487
488/***
489 * OLEUTL_ReadRegistryDWORDValue
490 *
491 * This method will read the default value of the registry key in
492 * parameter and extract a DWORD value from it. The registry key value
493 * can be in a string key or a DWORD key.
494 *
495 * params:
496 * regKey - Key to read the default value from
497 * pdwValue - Pointer to the location where the DWORD
498 * value is returned. This value is not modified
499 * if the value is not found.
500 */
501
502static void OLEUTL_ReadRegistryDWORDValue(
503 HKEY regKey,
504 DWORD* pdwValue)
505{
506 char buffer[20];
507 DWORD dwKeyType;
508 DWORD cbData = 20;
509 LONG lres;
510
511 lres = RegQueryValueExA(regKey,
512 "",
513 NULL,
514 &dwKeyType,
515 (LPBYTE)buffer,
516 &cbData);
517
518 if (lres == ERROR_SUCCESS)
519 {
520 switch (dwKeyType)
521 {
522 case REG_DWORD:
523 *pdwValue = *(DWORD*)buffer;
524 break;
525 case REG_EXPAND_SZ:
526 case REG_MULTI_SZ:
527 case REG_SZ:
528 *pdwValue = (DWORD)strtoul(buffer, NULL, 10);
529 break;
530 }
531 }
532}
533
Note: See TracBrowser for help on using the repository browser.