4 * Copyright 1995 Martin von Loewis
5 * Copyright 1998 Justin Bradford
6 * Copyright 1999 Francis Beaudet
7 * Copyright 1999 Sylvain St-Germain
8 * Copyright 2002 Marcus Meissner
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 #include "wine/unicode.h"
42 #include "wine/obj_base.h"
43 #include "wine/obj_clientserver.h"
44 #include "wine/obj_misc.h"
45 #include "wine/obj_marshal.h"
46 #include "wine/obj_storage.h"
47 #include "wine/obj_channel.h"
48 #include "compobj_private.h"
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
54 /****************************************************************************
55 * This section defines variables internal to the COM module.
57 * TODO: Most of these things will have to be made thread-safe.
59 HINSTANCE COMPOBJ_hInstance32
= 0;
61 static HRESULT
COM_GetRegisteredClassObject(REFCLSID rclsid
, DWORD dwClsContext
, LPUNKNOWN
* ppUnk
);
62 static void COM_RevokeAllClasses();
63 static void COM_ExternalLockFreeList();
65 /*****************************************************************************
66 * Appartment management stuff
69 * per Thread values are stored in the TEB on offset 0xF80
71 * see www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm
76 unsigned char threadingModell
; // we use the COINIT flags
77 unsigned long threadID
;
78 long AppartmentLockCount
;
82 OleAppartmentData
*AppartmentData
;
86 static CRITICAL_SECTION csAppartmentData = CRITICAL_SECTION_INIT("csAppartmentData");
89 * the first STA created in a process is the main STA
93 static OleAppartmentData * mainSTA;
97 * a Process can only have one MTA
101 static OleAppartmentData * processMTA;
106 * This lock count counts the number of times CoInitialize is called. It is
107 * decreased every time CoUninitialize is called. When it hits 0, the COM
108 * libraries are freed
110 static LONG s_COMLockCount
= 0;
113 * This linked list contains the list of registered class objects. These
114 * are mostly used to register the factories for out-of-proc servers of OLE
117 * TODO: Make this data structure aware of inter-process communication. This
118 * means that parts of this will be exported to the Wine Server.
120 typedef struct tagRegisteredClass
122 CLSID classIdentifier
;
123 LPUNKNOWN classObject
;
127 HANDLE hThread
; /* only for localserver */
128 struct tagRegisteredClass
* nextClass
;
131 static CRITICAL_SECTION csRegisteredClassList
= CRITICAL_SECTION_INIT("csRegisteredClassList");
132 static RegisteredClass
* firstRegisteredClass
= NULL
;
134 /*****************************************************************************
135 * This section contains OpenDllList definitions
137 * The OpenDllList contains only handles of dll loaded by CoGetClassObject or
138 * other functions what do LoadLibrary _without_ giving back a HMODULE.
139 * Without this list these handles would be freed never.
141 * FIXME: a DLL what says OK whenn asked for unloading is unloaded in the
142 * next unload-call but not before 600 sec.
145 typedef struct tagOpenDll
{
147 struct tagOpenDll
*next
;
150 static CRITICAL_SECTION csOpenDllList
= CRITICAL_SECTION_INIT("csOpenDllList");
151 static OpenDll
*openDllList
= NULL
; /* linked list of open dlls */
153 static void COMPOBJ_DLLList_Add(HANDLE hLibrary
);
154 static void COMPOBJ_DllList_FreeUnused(int Timeout
);
157 /******************************************************************************
158 * Initialize/Uninitialize critical sections.
160 void COMPOBJ_InitProcess( void )
164 void COMPOBJ_UninitProcess( void )
168 /*****************************************************************************
169 * This section contains OpenDllList implemantation
172 static void COMPOBJ_DLLList_Add(HANDLE hLibrary
)
179 EnterCriticalSection( &csOpenDllList
);
181 if (openDllList
== NULL
) {
182 /* empty list -- add first node */
183 openDllList
= (OpenDll
*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll
));
184 openDllList
->hLibrary
=hLibrary
;
185 openDllList
->next
= NULL
;
187 /* search for this dll */
189 for (ptr
= openDllList
; ptr
->next
!= NULL
; ptr
=ptr
->next
) {
190 if (ptr
->hLibrary
== hLibrary
) {
196 /* dll not found, add it */
198 openDllList
= (OpenDll
*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll
));
199 openDllList
->hLibrary
= hLibrary
;
200 openDllList
->next
= tmp
;
204 LeaveCriticalSection( &csOpenDllList
);
207 static void COMPOBJ_DllList_FreeUnused(int Timeout
)
209 OpenDll
*curr
, *next
, *prev
= NULL
;
210 typedef HRESULT(*DllCanUnloadNowFunc
)(void);
211 DllCanUnloadNowFunc DllCanUnloadNow
;
215 EnterCriticalSection( &csOpenDllList
);
217 for (curr
= openDllList
; curr
!= NULL
; ) {
218 DllCanUnloadNow
= (DllCanUnloadNowFunc
) GetProcAddress(curr
->hLibrary
, "DllCanUnloadNow");
220 if ( (DllCanUnloadNow
!= NULL
) && (DllCanUnloadNow() == S_OK
) ) {
223 TRACE("freeing 0x%08x\n", curr
->hLibrary
);
224 FreeLibrary(curr
->hLibrary
);
226 HeapFree(GetProcessHeap(), 0, curr
);
227 if (curr
== openDllList
) {
240 LeaveCriticalSection( &csOpenDllList
);
243 /******************************************************************************
244 * CoBuildVersion [COMPOBJ.1]
245 * CoBuildVersion [OLE32.4]
248 * Current build version, hiword is majornumber, loword is minornumber
250 DWORD WINAPI
CoBuildVersion(void)
252 TRACE("Returning version %d, build %d.\n", rmm
, rup
);
253 return (rmm
<<16)+rup
;
256 /******************************************************************************
257 * CoInitialize [OLE32.26]
259 * Initializes the COM libraries.
263 HRESULT WINAPI
CoInitialize(
264 LPVOID lpReserved
/* [in] pointer to win32 malloc interface
265 (obsolete, should be NULL) */
269 * Just delegate to the newer method.
271 return CoInitializeEx(lpReserved
, COINIT_APARTMENTTHREADED
);
274 /******************************************************************************
275 * CoInitializeEx [OLE32.163]
277 * Initializes the COM libraries. The behavior used to set the win32 IMalloc
278 * used for memory management is obsolete.
281 * S_OK if successful,
282 * S_FALSE if this function was called already.
283 * RPC_E_CHANGED_MODE if a previous call to CoInitialize specified another
287 * Only the single threaded model is supported. As a result RPC_E_CHANGED_MODE
290 * See the windows documentation for more details.
292 HRESULT WINAPI
CoInitializeEx(
293 LPVOID lpReserved
, /* [in] pointer to win32 malloc interface
294 (obsolete, should be NULL) */
295 DWORD dwCoInit
/* [in] A value from COINIT specifies the threading model */
300 TRACE("(%p, %x)\n", lpReserved
, (int)dwCoInit
);
302 if (lpReserved
!=NULL
)
304 ERR("(%p, %x) - Bad parameter passed-in %p, must be an old Windows Application\n", lpReserved
, (int)dwCoInit
, lpReserved
);
308 * Check for unsupported features.
310 if (dwCoInit
!=COINIT_APARTMENTTHREADED
)
312 FIXME(":(%p,%x): unsupported flag %x\n", lpReserved
, (int)dwCoInit
, (int)dwCoInit
);
313 /* Hope for the best and continue anyway */
317 * Check the lock count. If this is the first time going through the initialize
318 * process, we have to initialize the libraries.
320 * And crank-up that lock count.
322 if (InterlockedExchangeAdd(&s_COMLockCount
,1)==0)
325 * Initialize the various COM libraries and data structures.
327 TRACE("() - Initializing the COM libraries\n");
330 RunningObjectTableImpl_Initialize();
340 /***********************************************************************
341 * CoUninitialize [OLE32.47]
343 * This method will release the COM libraries.
345 * See the windows documentation for more details.
347 void WINAPI
CoUninitialize(void)
353 * Decrease the reference count.
354 * If we are back to 0 locks on the COM library, make sure we free
355 * all the associated data structures.
357 lCOMRefCnt
= InterlockedExchangeAdd(&s_COMLockCount
,-1);
361 * Release the various COM libraries and data structures.
363 TRACE("() - Releasing the COM libraries\n");
365 RunningObjectTableImpl_UnInitialize();
367 * Release the references to the registered class objects.
369 COM_RevokeAllClasses();
372 * This will free the loaded COM Dlls.
374 CoFreeAllLibraries();
377 * This will free list of external references to COM objects.
379 COM_ExternalLockFreeList();
382 else if (lCOMRefCnt
<1) {
383 ERR( "CoUninitialize() - not CoInitialized.\n" );
384 InterlockedExchangeAdd(&s_COMLockCount
,1); /* restore the lock count. */
388 /******************************************************************************
389 * CoDisconnectObject [COMPOBJ.15]
390 * CoDisconnectObject [OLE32.8]
392 HRESULT WINAPI
CoDisconnectObject( LPUNKNOWN lpUnk
, DWORD reserved
)
394 TRACE("(%p, %lx)\n",lpUnk
,reserved
);
398 /******************************************************************************
399 * CoCreateGuid[OLE32.6]
402 HRESULT WINAPI
CoCreateGuid(
403 GUID
*pguid
/* [out] points to the GUID to initialize */
405 return UuidCreate(pguid
);
408 /******************************************************************************
409 * CLSIDFromString [OLE32.3]
410 * IIDFromString [OLE32.74]
411 * Converts a unique identifier from its string representation into
415 * If idstr is not a valid CLSID string then it gets treated as a ProgID
420 HRESULT WINAPI
__CLSIDFromStringA(
421 LPCSTR idstr
, /* [in] string representation of guid */
422 CLSID
*id
) /* [out] GUID converted from string */
424 BYTE
*s
= (BYTE
*) idstr
;
429 s
= "{00000000-0000-0000-0000-000000000000}";
430 else { /* validate the CLSID string */
433 return CO_E_CLASSSTRING
;
435 if ((s
[0]!='{') || (s
[9]!='-') || (s
[14]!='-') || (s
[19]!='-') || (s
[24]!='-') || (s
[37]!='}'))
436 return CO_E_CLASSSTRING
;
438 for (i
=1; i
<37; i
++) {
439 if ((i
== 9)||(i
== 14)||(i
== 19)||(i
== 24)) continue;
440 if (!(((s
[i
] >= '0') && (s
[i
] <= '9')) ||
441 ((s
[i
] >= 'a') && (s
[i
] <= 'f')) ||
442 ((s
[i
] >= 'A') && (s
[i
] <= 'F'))))
443 return CO_E_CLASSSTRING
;
447 TRACE("%s -> %p\n", s
, id
);
449 /* quick lookup table */
450 memset(table
, 0, 256);
452 for (i
= 0; i
< 10; i
++) {
455 for (i
= 0; i
< 6; i
++) {
456 table
['A' + i
] = i
+10;
457 table
['a' + i
] = i
+10;
460 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
462 id
->Data1
= (table
[s
[1]] << 28 | table
[s
[2]] << 24 | table
[s
[3]] << 20 | table
[s
[4]] << 16 |
463 table
[s
[5]] << 12 | table
[s
[6]] << 8 | table
[s
[7]] << 4 | table
[s
[8]]);
464 id
->Data2
= table
[s
[10]] << 12 | table
[s
[11]] << 8 | table
[s
[12]] << 4 | table
[s
[13]];
465 id
->Data3
= table
[s
[15]] << 12 | table
[s
[16]] << 8 | table
[s
[17]] << 4 | table
[s
[18]];
467 /* these are just sequential bytes */
468 id
->Data4
[0] = table
[s
[20]] << 4 | table
[s
[21]];
469 id
->Data4
[1] = table
[s
[22]] << 4 | table
[s
[23]];
470 id
->Data4
[2] = table
[s
[25]] << 4 | table
[s
[26]];
471 id
->Data4
[3] = table
[s
[27]] << 4 | table
[s
[28]];
472 id
->Data4
[4] = table
[s
[29]] << 4 | table
[s
[30]];
473 id
->Data4
[5] = table
[s
[31]] << 4 | table
[s
[32]];
474 id
->Data4
[6] = table
[s
[33]] << 4 | table
[s
[34]];
475 id
->Data4
[7] = table
[s
[35]] << 4 | table
[s
[36]];
480 HRESULT WINAPI
CLSIDFromString(
481 LPCOLESTR idstr
, /* [in] string representation of GUID */
482 CLSID
*id
) /* [out] GUID represented by above string */
487 if (!WideCharToMultiByte( CP_ACP
, 0, idstr
, -1, xid
, sizeof(xid
), NULL
, NULL
))
488 return CO_E_CLASSSTRING
;
491 ret
= __CLSIDFromStringA(xid
,id
);
492 if(ret
!= S_OK
) { /* It appears a ProgID is also valid */
493 ret
= CLSIDFromProgID(idstr
, id
);
498 /******************************************************************************
499 * WINE_StringFromCLSID [Internal]
500 * Converts a GUID into the respective string representation.
505 * the string representation and HRESULT
507 HRESULT
WINE_StringFromCLSID(
508 const CLSID
*id
, /* [in] GUID to be converted */
509 LPSTR idstr
/* [out] pointer to buffer to contain converted guid */
511 static const char *hex
= "0123456789ABCDEF";
516 { ERR("called with id=Null\n");
521 sprintf(idstr
, "{%08lX-%04X-%04X-%02X%02X-",
522 id
->Data1
, id
->Data2
, id
->Data3
,
523 id
->Data4
[0], id
->Data4
[1]);
527 for (i
= 2; i
< 8; i
++) {
528 *s
++ = hex
[id
->Data4
[i
]>>4];
529 *s
++ = hex
[id
->Data4
[i
] & 0xf];
535 TRACE("%p->%s\n", id
, idstr
);
541 /******************************************************************************
542 * StringFromCLSID [OLE32.151]
543 * StringFromIID [OLE32.153]
544 * Converts a GUID into the respective string representation.
545 * The target string is allocated using the OLE IMalloc.
547 * the string representation and HRESULT
549 HRESULT WINAPI
StringFromCLSID(
550 REFCLSID id
, /* [in] the GUID to be converted */
551 LPOLESTR
*idstr
/* [out] a pointer to a to-be-allocated pointer pointing to the resulting string */
557 if ((ret
=CoGetMalloc(0,&mllc
)))
560 ret
=WINE_StringFromCLSID(id
,buf
);
562 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, buf
, -1, NULL
, 0 );
563 *idstr
= IMalloc_Alloc( mllc
, len
* sizeof(WCHAR
) );
564 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, *idstr
, len
);
569 /******************************************************************************
570 * StringFromGUID2 [COMPOBJ.76]
571 * StringFromGUID2 [OLE32.152]
573 * Converts a global unique identifier into a string of an API-
574 * specified fixed format. (The usual {.....} stuff.)
577 * The (UNICODE) string representation of the GUID in 'str'
578 * The length of the resulting string, 0 if there was any problem.
581 StringFromGUID2(REFGUID id
, LPOLESTR str
, INT cmax
)
585 if (WINE_StringFromCLSID(id
,xguid
))
587 return MultiByteToWideChar( CP_ACP
, 0, xguid
, -1, str
, cmax
);
590 /******************************************************************************
591 * ProgIDFromCLSID [OLE32.133]
592 * Converts a class id into the respective Program ID. (By using a registry lookup)
593 * RETURNS S_OK on success
594 * riid associated with the progid
597 HRESULT WINAPI
ProgIDFromCLSID(
598 REFCLSID clsid
, /* [in] class id as found in registry */
599 LPOLESTR
*lplpszProgID
/* [out] associated Prog ID */
602 char strCLSID
[50], *buf
, *buf2
;
608 WINE_StringFromCLSID(clsid
, strCLSID
);
610 buf
= HeapAlloc(GetProcessHeap(), 0, strlen(strCLSID
)+14);
611 sprintf(buf
,"CLSID\\%s\\ProgID", strCLSID
);
612 if (RegOpenKeyA(HKEY_CLASSES_ROOT
, buf
, &xhkey
))
613 ret
= REGDB_E_CLASSNOTREG
;
615 HeapFree(GetProcessHeap(), 0, buf
);
619 buf2
= HeapAlloc(GetProcessHeap(), 0, 255);
621 if (RegQueryValueA(xhkey
, NULL
, buf2
, &buf2len
))
622 ret
= REGDB_E_CLASSNOTREG
;
626 if (CoGetMalloc(0,&mllc
))
630 DWORD len
= MultiByteToWideChar( CP_ACP
, 0, buf2
, -1, NULL
, 0 );
631 *lplpszProgID
= IMalloc_Alloc(mllc
, len
* sizeof(WCHAR
) );
632 MultiByteToWideChar( CP_ACP
, 0, buf2
, -1, *lplpszProgID
, len
);
635 HeapFree(GetProcessHeap(), 0, buf2
);
642 /******************************************************************************
643 * CLSIDFromProgID [OLE32.2]
644 * Converts a program id into the respective GUID. (By using a registry lookup)
646 * riid associated with the progid
648 HRESULT WINAPI
CLSIDFromProgID(
649 LPCOLESTR progid
, /* [in] program id as found in registry */
650 LPCLSID riid
) /* [out] associated CLSID */
652 static const WCHAR clsidW
[] = { '\\','C','L','S','I','D',0 };
654 DWORD buf2len
= sizeof(buf2
);
657 WCHAR
*buf
= HeapAlloc( GetProcessHeap(),0,(strlenW(progid
)+8) * sizeof(WCHAR
) );
658 strcpyW( buf
, progid
);
659 strcatW( buf
, clsidW
);
660 if (RegOpenKeyW(HKEY_CLASSES_ROOT
,buf
,&xhkey
))
662 HeapFree(GetProcessHeap(),0,buf
);
663 return CO_E_CLASSSTRING
;
665 HeapFree(GetProcessHeap(),0,buf
);
667 if (RegQueryValueA(xhkey
,NULL
,buf2
,&buf2len
))
670 return CO_E_CLASSSTRING
;
673 return __CLSIDFromStringA(buf2
,riid
);
678 /*****************************************************************************
679 * CoGetPSClsid [OLE32.22]
681 * This function returns the CLSID of the DLL that implements the proxy and stub
682 * for the specified interface.
684 * It determines this by searching the
685 * HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32 in the registry
686 * and any interface id registered by CoRegisterPSClsid within the current process.
688 * FIXME: We only search the registry, not ids registered with CoRegisterPSClsid.
690 HRESULT WINAPI
CoGetPSClsid(
691 REFIID riid
, /* [in] Interface whose proxy/stub CLSID is to be returned */
692 CLSID
*pclsid
) /* [out] Where to store returned proxy/stub CLSID */
698 TRACE("() riid=%s, pclsid=%p\n", debugstr_guid(riid
), pclsid
);
700 /* Get the input iid as a string */
701 WINE_StringFromCLSID(riid
, buf2
);
702 /* Allocate memory for the registry key we will construct.
703 (length of iid string plus constant length of static text */
704 buf
= HeapAlloc(GetProcessHeap(), 0, strlen(buf2
)+27);
707 return (E_OUTOFMEMORY
);
710 /* Construct the registry key we want */
711 sprintf(buf
,"Interface\\%s\\ProxyStubClsid32", buf2
);
714 if (RegOpenKeyA(HKEY_CLASSES_ROOT
, buf
, &xhkey
))
716 HeapFree(GetProcessHeap(),0,buf
);
717 return (E_INVALIDARG
);
719 HeapFree(GetProcessHeap(),0,buf
);
721 /* ... Once we have the key, query the registry to get the
722 value of CLSID as a string, and convert it into a
723 proper CLSID structure to be passed back to the app */
724 buf2len
= sizeof(buf2
);
725 if ( (RegQueryValueA(xhkey
,NULL
,buf2
,&buf2len
)) )
732 /* We have the CLSid we want back from the registry as a string, so
733 lets convert it into a CLSID structure */
734 if ( (__CLSIDFromStringA(buf2
,pclsid
)) != NOERROR
) {
738 TRACE ("() Returning CLSID=%s\n", debugstr_guid(pclsid
));
744 /***********************************************************************
745 * WriteClassStm (OLE32.159)
747 * This function write a CLSID on stream
749 HRESULT WINAPI
WriteClassStm(IStream
*pStm
,REFCLSID rclsid
)
751 TRACE("(%p,%p)\n",pStm
,rclsid
);
756 return IStream_Write(pStm
,rclsid
,sizeof(CLSID
),NULL
);
759 /***********************************************************************
760 * ReadClassStm (OLE32.135)
762 * This function read a CLSID from a stream
764 HRESULT WINAPI
ReadClassStm(IStream
*pStm
,CLSID
*pclsid
)
769 TRACE("(%p,%p)\n",pStm
,pclsid
);
774 res
= IStream_Read(pStm
,(void*)pclsid
,sizeof(CLSID
),&nbByte
);
779 if (nbByte
!= sizeof(CLSID
))
787 * COM_GetRegisteredClassObject
789 * This internal method is used to scan the registered class list to
790 * find a class object.
793 * rclsid Class ID of the class to find.
794 * dwClsContext Class context to match.
795 * ppv [out] returns a pointer to the class object. Complying
796 * to normal COM usage, this method will increase the
797 * reference count on this object.
799 static HRESULT
COM_GetRegisteredClassObject(
804 HRESULT hr
= S_FALSE
;
805 RegisteredClass
* curClass
;
807 EnterCriticalSection( &csRegisteredClassList
);
815 * Iterate through the whole list and try to match the class ID.
817 curClass
= firstRegisteredClass
;
819 while (curClass
!= 0)
822 * Check if we have a match on the class ID.
824 if (IsEqualGUID(&(curClass
->classIdentifier
), rclsid
))
827 * Since we don't do out-of process or DCOM just right away, let's ignore the
832 * We have a match, return the pointer to the class object.
834 *ppUnk
= curClass
->classObject
;
836 IUnknown_AddRef(curClass
->classObject
);
843 * Step to the next class in the list.
845 curClass
= curClass
->nextClass
;
849 LeaveCriticalSection( &csRegisteredClassList
);
851 * If we get to here, we haven't found our class.
857 _LocalServerThread(LPVOID param
) {
860 RegisteredClass
*newClass
= (RegisteredClass
*)param
;
864 unsigned char *buffer
;
866 IClassFactory
*classfac
;
867 LARGE_INTEGER seekto
;
868 ULARGE_INTEGER newpos
;
871 TRACE("Starting threader for %s.\n",debugstr_guid(&newClass
->classIdentifier
));
872 strcpy(pipefn
,PIPEPREF
);
873 WINE_StringFromCLSID(&newClass
->classIdentifier
,pipefn
+strlen(PIPEPREF
));
875 hres
= IUnknown_QueryInterface(newClass
->classObject
,&IID_IClassFactory
,(LPVOID
*)&classfac
);
876 if (hres
) return hres
;
878 hres
= CreateStreamOnHGlobal(0,TRUE
,&pStm
);
880 FIXME("Failed to create stream on hglobal.\n");
883 hres
= CoMarshalInterface(pStm
,&IID_IClassFactory
,(LPVOID
)classfac
,0,NULL
,0);
885 FIXME("CoMarshalInterface failed, %lx!\n",hres
);
888 hres
= IStream_Stat(pStm
,&ststg
,0);
889 if (hres
) return hres
;
891 buflen
= ststg
.cbSize
.s
.LowPart
;
892 buffer
= HeapAlloc(GetProcessHeap(),0,buflen
);
893 seekto
.s
.LowPart
= 0;
894 seekto
.s
.HighPart
= 0;
895 hres
= IStream_Seek(pStm
,seekto
,SEEK_SET
,&newpos
);
897 FIXME("IStream_Seek failed, %lx\n",hres
);
900 hres
= IStream_Read(pStm
,buffer
,buflen
,&res
);
902 FIXME("Stream Read failed, %lx\n",hres
);
905 IStream_Release(pStm
);
908 hPipe
= CreateNamedPipeA(
911 PIPE_TYPE_BYTE
|PIPE_WAIT
,
912 PIPE_UNLIMITED_INSTANCES
,
915 NMPWAIT_USE_DEFAULT_WAIT
,
918 if (hPipe
== INVALID_HANDLE_VALUE
) {
919 FIXME("pipe creation failed for %s, le is %lx\n",pipefn
,GetLastError());
922 if (!ConnectNamedPipe(hPipe
,NULL
)) {
923 ERR("Failure during ConnectNamedPipe %lx, ABORT!\n",GetLastError());
927 WriteFile(hPipe
,buffer
,buflen
,&res
,NULL
);
933 /******************************************************************************
934 * CoRegisterClassObject [OLE32.36]
936 * This method will register the class object for a given class ID.
938 * See the Windows documentation for more details.
940 HRESULT WINAPI
CoRegisterClassObject(
943 DWORD dwClsContext
, /* [in] CLSCTX flags indicating the context in which to run the executable */
944 DWORD flags
, /* [in] REGCLS flags indicating how connections are made */
948 RegisteredClass
* newClass
;
949 LPUNKNOWN foundObject
;
952 TRACE("(%s,%p,0x%08lx,0x%08lx,%p)\n",
953 debugstr_guid(rclsid
),pUnk
,dwClsContext
,flags
,lpdwRegister
);
955 if ( (lpdwRegister
==0) || (pUnk
==0) )
961 * First, check if the class is already registered.
962 * If it is, this should cause an error.
964 hr
= COM_GetRegisteredClassObject(rclsid
, dwClsContext
, &foundObject
);
966 IUnknown_Release(foundObject
);
967 return CO_E_OBJISREG
;
970 newClass
= HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass
));
971 if ( newClass
== NULL
)
972 return E_OUTOFMEMORY
;
974 EnterCriticalSection( &csRegisteredClassList
);
976 newClass
->classIdentifier
= *rclsid
;
977 newClass
->runContext
= dwClsContext
;
978 newClass
->connectFlags
= flags
;
980 * Use the address of the chain node as the cookie since we are sure it's
983 newClass
->dwCookie
= (DWORD
)newClass
;
984 newClass
->nextClass
= firstRegisteredClass
;
987 * Since we're making a copy of the object pointer, we have to increase its
990 newClass
->classObject
= pUnk
;
991 IUnknown_AddRef(newClass
->classObject
);
993 firstRegisteredClass
= newClass
;
994 LeaveCriticalSection( &csRegisteredClassList
);
996 *lpdwRegister
= newClass
->dwCookie
;
998 if (dwClsContext
& CLSCTX_LOCAL_SERVER
) {
1002 newClass
->hThread
=CreateThread(NULL
,0,_LocalServerThread
,newClass
,0,&tid
);
1007 /***********************************************************************
1008 * CoRevokeClassObject [OLE32.40]
1010 * This method will remove a class object from the class registry
1012 * See the Windows documentation for more details.
1014 HRESULT WINAPI
CoRevokeClassObject(
1017 HRESULT hr
= E_INVALIDARG
;
1018 RegisteredClass
** prevClassLink
;
1019 RegisteredClass
* curClass
;
1021 TRACE("(%08lx)\n",dwRegister
);
1023 EnterCriticalSection( &csRegisteredClassList
);
1026 * Iterate through the whole list and try to match the cookie.
1028 curClass
= firstRegisteredClass
;
1029 prevClassLink
= &firstRegisteredClass
;
1031 while (curClass
!= 0)
1034 * Check if we have a match on the cookie.
1036 if (curClass
->dwCookie
== dwRegister
)
1039 * Remove the class from the chain.
1041 *prevClassLink
= curClass
->nextClass
;
1044 * Release the reference to the class object.
1046 IUnknown_Release(curClass
->classObject
);
1049 * Free the memory used by the chain node.
1051 HeapFree(GetProcessHeap(), 0, curClass
);
1058 * Step to the next class in the list.
1060 prevClassLink
= &(curClass
->nextClass
);
1061 curClass
= curClass
->nextClass
;
1065 LeaveCriticalSection( &csRegisteredClassList
);
1067 * If we get to here, we haven't found our class.
1072 /***********************************************************************
1073 * compobj_RegReadPath [internal]
1075 * Reads a registry value and expands it when nessesary
1077 HRESULT
compobj_RegReadPath(char * keyname
, char * valuename
, char * dst
, int dstlen
)
1083 DWORD dwLength
= dstlen
;
1085 if((hres
= RegOpenKeyExA(HKEY_CLASSES_ROOT
, keyname
, 0, KEY_READ
, &key
)) == ERROR_SUCCESS
) {
1086 if( (hres
= RegQueryValueExA(key
, NULL
, NULL
, &keytype
, (LPBYTE
)src
, &dwLength
)) == ERROR_SUCCESS
) {
1087 if (keytype
== REG_EXPAND_SZ
) {
1088 if (dstlen
<= ExpandEnvironmentStringsA(src
, dst
, dstlen
)) hres
= ERROR_MORE_DATA
;
1090 strncpy(dst
, src
, dstlen
);
1098 /***********************************************************************
1099 * CoGetClassObject [COMPOBJ.7]
1100 * CoGetClassObject [OLE32.16]
1102 * FIXME. If request allows of several options and there is a failure
1103 * with one (other than not being registered) do we try the
1104 * others or return failure? (E.g. inprocess is registered but
1105 * the DLL is not found but the server version works)
1107 HRESULT WINAPI
CoGetClassObject(
1108 REFCLSID rclsid
, DWORD dwClsContext
, COSERVERINFO
*pServerInfo
,
1109 REFIID iid
, LPVOID
*ppv
1111 LPUNKNOWN regClassObject
;
1112 HRESULT hres
= E_UNEXPECTED
;
1115 typedef HRESULT (CALLBACK
*DllGetClassObjectFunc
)(REFCLSID clsid
, REFIID iid
, LPVOID
*ppv
);
1116 DllGetClassObjectFunc DllGetClassObject
;
1118 WINE_StringFromCLSID((LPCLSID
)rclsid
,xclsid
);
1120 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid
), debugstr_guid(iid
));
1123 FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo
->pwszName
));
1124 FIXME("\t\tpAuthInfo=%p\n",pServerInfo
->pAuthInfo
);
1128 * First, try and see if we can't match the class ID with one of the
1129 * registered classes.
1131 if (S_OK
== COM_GetRegisteredClassObject(rclsid
, dwClsContext
, ®ClassObject
))
1134 * Get the required interface from the retrieved pointer.
1136 hres
= IUnknown_QueryInterface(regClassObject
, iid
, ppv
);
1139 * Since QI got another reference on the pointer, we want to release the
1140 * one we already have. If QI was unsuccessful, this will release the object. This
1141 * is good since we are not returning it in the "out" parameter.
1143 IUnknown_Release(regClassObject
);
1148 /* first try: in-process */
1149 if ((CLSCTX_INPROC_SERVER
| CLSCTX_INPROC_HANDLER
) & dwClsContext
) {
1150 char keyname
[MAX_PATH
];
1151 char dllpath
[MAX_PATH
+1];
1153 sprintf(keyname
,"CLSID\\%s\\InprocServer32",xclsid
);
1155 if ( compobj_RegReadPath(keyname
, NULL
, dllpath
, sizeof(dllpath
)) != ERROR_SUCCESS
) {
1156 /* failure: CLSID is not found in registry */
1157 WARN("class %s not registred\n", xclsid
);
1158 hres
= REGDB_E_CLASSNOTREG
;
1160 if ((hLibrary
= LoadLibraryExA(dllpath
, 0, LOAD_WITH_ALTERED_SEARCH_PATH
)) == 0) {
1161 /* failure: DLL could not be loaded */
1162 ERR("couldn't load InprocServer32 dll %s\n", dllpath
);
1163 hres
= E_ACCESSDENIED
; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
1164 } else if (!(DllGetClassObject
= (DllGetClassObjectFunc
)GetProcAddress(hLibrary
, "DllGetClassObject"))) {
1165 /* failure: the dll did not export DllGetClassObject */
1166 ERR("couldn't find function DllGetClassObject in %s\n", dllpath
);
1167 FreeLibrary( hLibrary
);
1168 hres
= CO_E_DLLNOTFOUND
;
1170 /* OK: get the ClassObject */
1171 COMPOBJ_DLLList_Add( hLibrary
);
1172 return DllGetClassObject(rclsid
, iid
, ppv
);
1177 /* Next try out of process */
1178 if (CLSCTX_LOCAL_SERVER
& dwClsContext
)
1180 return create_marshalled_proxy(rclsid
,iid
,ppv
);
1183 /* Finally try remote */
1184 if (CLSCTX_REMOTE_SERVER
& dwClsContext
)
1186 FIXME ("CLSCTX_REMOTE_SERVER not supported\n");
1187 hres
= E_NOINTERFACE
;
1192 /***********************************************************************
1193 * CoResumeClassObjects (OLE32.173)
1195 * Resumes classobjects registered with REGCLS suspended
1197 HRESULT WINAPI
CoResumeClassObjects(void)
1203 /***********************************************************************
1204 * GetClassFile (OLE32.67)
1206 * This function supplies the CLSID associated with the given filename.
1208 HRESULT WINAPI
GetClassFile(LPCOLESTR filePathName
,CLSID
*pclsid
)
1212 int nbElm
=0,length
=0,i
=0;
1214 LPOLESTR
*pathDec
=0,absFile
=0,progId
=0;
1215 WCHAR extention
[100]={0};
1219 /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/
1220 if((StgIsStorageFile(filePathName
))==S_OK
){
1222 res
=StgOpenStorage(filePathName
,NULL
,STGM_READ
| STGM_SHARE_DENY_WRITE
,NULL
,0,&pstg
);
1225 res
=ReadClassStg(pstg
,pclsid
);
1227 IStorage_Release(pstg
);
1231 /* if the file is not a storage object then attemps to match various bits in the file against a
1232 pattern in the registry. this case is not frequently used ! so I present only the psodocode for
1235 for(i=0;i<nFileTypes;i++)
1237 for(i=0;j<nPatternsForType;j++){
1242 pat=ReadPatternFromRegistry(i,j);
1243 hFile=CreateFileW(filePathName,,,,,,hFile);
1244 SetFilePosition(hFile,pat.offset);
1245 ReadFile(hFile,buf,pat.size,NULL,NULL);
1246 if (memcmp(buf&pat.mask,pat.pattern.pat.size)==0){
1248 *pclsid=ReadCLSIDFromRegistry(i);
1254 /* if the obove strategies fail then search for the extension key in the registry */
1256 /* get the last element (absolute file) in the path name */
1257 nbElm
=FileMonikerImpl_DecomposePath(filePathName
,&pathDec
);
1258 absFile
=pathDec
[nbElm
-1];
1260 /* failed if the path represente a directory and not an absolute file name*/
1261 if (lstrcmpW(absFile
,(LPOLESTR
)"\\"))
1262 return MK_E_INVALIDEXTENSION
;
1264 /* get the extension of the file */
1265 length
=lstrlenW(absFile
);
1266 for(i
=length
-1; ( (i
>=0) && (extention
[i
]=absFile
[i
]) );i
--);
1268 /* get the progId associated to the extension */
1269 progId
=CoTaskMemAlloc(sizeProgId
);
1271 res
=RegQueryValueW(HKEY_CLASSES_ROOT
,extention
,progId
,&sizeProgId
);
1273 if (res
==ERROR_MORE_DATA
){
1275 progId
= CoTaskMemRealloc(progId
,sizeProgId
);
1276 res
=RegQueryValueW(HKEY_CLASSES_ROOT
,extention
,progId
,&sizeProgId
);
1278 if (res
==ERROR_SUCCESS
)
1279 /* return the clsid associated to the progId */
1280 res
= CLSIDFromProgID(progId
,pclsid
);
1282 for(i
=0; pathDec
[i
]!=NULL
;i
++)
1283 CoTaskMemFree(pathDec
[i
]);
1284 CoTaskMemFree(pathDec
);
1286 CoTaskMemFree(progId
);
1288 if (res
==ERROR_SUCCESS
)
1291 return MK_E_INVALIDEXTENSION
;
1293 /***********************************************************************
1294 * CoCreateInstance [COMPOBJ.13]
1295 * CoCreateInstance [OLE32.7]
1297 HRESULT WINAPI
CoCreateInstance(
1299 LPUNKNOWN pUnkOuter
,
1305 LPCLASSFACTORY lpclf
= 0;
1314 * Initialize the "out" parameter
1319 * Get a class factory to construct the object we want.
1321 hres
= CoGetClassObject(rclsid
,
1328 FIXME("no classfactory created for CLSID %s, hres is 0x%08lx\n",
1329 debugstr_guid(rclsid
),hres
);
1334 * Create the object and don't forget to release the factory
1336 hres
= IClassFactory_CreateInstance(lpclf
, pUnkOuter
, iid
, ppv
);
1337 IClassFactory_Release(lpclf
);
1339 FIXME("no instance created for interface %s of class %s, hres is 0x%08lx\n",
1340 debugstr_guid(iid
), debugstr_guid(rclsid
),hres
);
1345 /***********************************************************************
1346 * CoCreateInstanceEx [OLE32.165]
1348 HRESULT WINAPI
CoCreateInstanceEx(
1350 LPUNKNOWN pUnkOuter
,
1352 COSERVERINFO
* pServerInfo
,
1356 IUnknown
* pUnk
= NULL
;
1359 int successCount
= 0;
1364 if ( (cmq
==0) || (pResults
==NULL
))
1365 return E_INVALIDARG
;
1367 if (pServerInfo
!=NULL
)
1368 FIXME("() non-NULL pServerInfo not supported!\n");
1371 * Initialize all the "out" parameters.
1373 for (index
= 0; index
< cmq
; index
++)
1375 pResults
[index
].pItf
= NULL
;
1376 pResults
[index
].hr
= E_NOINTERFACE
;
1380 * Get the object and get its IUnknown pointer.
1382 hr
= CoCreateInstance(rclsid
,
1392 * Then, query for all the interfaces requested.
1394 for (index
= 0; index
< cmq
; index
++)
1396 pResults
[index
].hr
= IUnknown_QueryInterface(pUnk
,
1397 pResults
[index
].pIID
,
1398 (VOID
**)&(pResults
[index
].pItf
));
1400 if (pResults
[index
].hr
== S_OK
)
1405 * Release our temporary unknown pointer.
1407 IUnknown_Release(pUnk
);
1409 if (successCount
== 0)
1410 return E_NOINTERFACE
;
1412 if (successCount
!=cmq
)
1413 return CO_S_NOTALLINTERFACES
;
1418 /***********************************************************************
1419 * CoLoadLibrary (OLE32.30)
1421 HINSTANCE WINAPI
CoLoadLibrary(LPOLESTR lpszLibName
, BOOL bAutoFree
)
1423 TRACE("(%s, %d)\n", debugstr_w(lpszLibName
), bAutoFree
);
1425 return LoadLibraryExW(lpszLibName
, 0, LOAD_WITH_ALTERED_SEARCH_PATH
);
1428 /***********************************************************************
1429 * CoFreeLibrary [OLE32.13]
1431 * NOTES: don't belive the docu
1433 void WINAPI
CoFreeLibrary(HINSTANCE hLibrary
)
1435 FreeLibrary(hLibrary
);
1439 /***********************************************************************
1440 * CoFreeAllLibraries [OLE32.12]
1442 * NOTES: don't belive the docu
1444 void WINAPI
CoFreeAllLibraries(void)
1450 /***********************************************************************
1451 * CoFreeUnusedLibraries [COMPOBJ.17]
1452 * CoFreeUnusedLibraries [OLE32.14]
1454 * FIXME: Calls to CoFreeUnusedLibraries from any thread always route
1455 * through the main apartment's thread to call DllCanUnloadNow
1457 void WINAPI
CoFreeUnusedLibraries(void)
1459 COMPOBJ_DllList_FreeUnused(0);
1462 /***********************************************************************
1463 * CoFileTimeNow [COMPOBJ.82]
1464 * CoFileTimeNow [OLE32.10]
1467 * the current system time in lpFileTime
1469 HRESULT WINAPI
CoFileTimeNow( FILETIME
*lpFileTime
) /* [out] the current time */
1471 GetSystemTimeAsFileTime( lpFileTime
);
1475 /***********************************************************************
1476 * CoLoadLibrary (OLE32.30)
1478 static void COM_RevokeAllClasses()
1480 EnterCriticalSection( &csRegisteredClassList
);
1482 while (firstRegisteredClass
!=0)
1484 CoRevokeClassObject(firstRegisteredClass
->dwCookie
);
1487 LeaveCriticalSection( &csRegisteredClassList
);
1490 /****************************************************************************
1491 * COM External Lock methods implementation
1493 * This api provides a linked list to managed external references to
1496 * The public interface consists of three calls:
1497 * COM_ExternalLockAddRef
1498 * COM_ExternalLockRelease
1499 * COM_ExternalLockFreeList
1502 #define EL_END_OF_LIST 0
1503 #define EL_NOT_FOUND 0
1506 * Declaration of the static structure that manage the
1507 * external lock to COM objects.
1509 typedef struct COM_ExternalLock COM_ExternalLock
;
1510 typedef struct COM_ExternalLockList COM_ExternalLockList
;
1512 struct COM_ExternalLock
1514 IUnknown
*pUnk
; /* IUnknown referenced */
1515 ULONG uRefCount
; /* external lock counter to IUnknown object*/
1516 COM_ExternalLock
*next
; /* Pointer to next element in list */
1519 struct COM_ExternalLockList
1521 COM_ExternalLock
*head
; /* head of list */
1525 * Declaration and initialization of the static structure that manages
1526 * the external lock to COM objects.
1528 static COM_ExternalLockList elList
= { EL_END_OF_LIST
};
1531 * Private methods used to managed the linked list
1535 static COM_ExternalLock
* COM_ExternalLockLocate(
1536 COM_ExternalLock
*element
,
1539 /****************************************************************************
1540 * Internal - Insert a new IUnknown* to the linked list
1542 static BOOL
COM_ExternalLockInsert(
1545 COM_ExternalLock
*newLock
= NULL
;
1546 COM_ExternalLock
*previousHead
= NULL
;
1549 * Allocate space for the new storage object
1551 newLock
= HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock
));
1553 if (newLock
!=NULL
) {
1554 if ( elList
.head
== EL_END_OF_LIST
) {
1555 elList
.head
= newLock
; /* The list is empty */
1557 /* insert does it at the head */
1558 previousHead
= elList
.head
;
1559 elList
.head
= newLock
;
1562 /* Set new list item data member */
1563 newLock
->pUnk
= pUnk
;
1564 newLock
->uRefCount
= 1;
1565 newLock
->next
= previousHead
;
1572 /****************************************************************************
1573 * Internal - Method that removes an item from the linked list.
1575 static void COM_ExternalLockDelete(
1576 COM_ExternalLock
*itemList
)
1578 COM_ExternalLock
*current
= elList
.head
;
1580 if ( current
== itemList
) {
1581 /* this section handles the deletion of the first node */
1582 elList
.head
= itemList
->next
;
1583 HeapFree( GetProcessHeap(), 0, itemList
);
1586 if ( current
->next
== itemList
){ /* We found the item to free */
1587 current
->next
= itemList
->next
; /* readjust the list pointers */
1588 HeapFree( GetProcessHeap(), 0, itemList
);
1592 /* Skip to the next item */
1593 current
= current
->next
;
1595 } while ( current
!= EL_END_OF_LIST
);
1599 /****************************************************************************
1600 * Internal - Recursivity agent for IUnknownExternalLockList_Find
1602 * NOTES: how long can the list be ?? (recursive!!!)
1604 static COM_ExternalLock
* COM_ExternalLockLocate( COM_ExternalLock
*element
, IUnknown
*pUnk
)
1606 if ( element
== EL_END_OF_LIST
)
1607 return EL_NOT_FOUND
;
1608 else if ( element
->pUnk
== pUnk
) /* We found it */
1610 else /* Not the right guy, keep on looking */
1611 return COM_ExternalLockLocate( element
->next
, pUnk
);
1614 /****************************************************************************
1615 * Public - Method that increments the count for a IUnknown* in the linked
1616 * list. The item is inserted if not already in the list.
1618 static void COM_ExternalLockAddRef(IUnknown
*pUnk
)
1620 COM_ExternalLock
*externalLock
= COM_ExternalLockLocate(elList
.head
, pUnk
);
1623 * Add an external lock to the object. If it was already externally
1624 * locked, just increase the reference count. If it was not.
1625 * add the item to the list.
1627 if ( externalLock
== EL_NOT_FOUND
)
1628 COM_ExternalLockInsert(pUnk
);
1630 externalLock
->uRefCount
++;
1633 * Add an internal lock to the object
1635 IUnknown_AddRef(pUnk
);
1638 /****************************************************************************
1639 * Public - Method that decrements the count for a IUnknown* in the linked
1640 * list. The item is removed from the list if its count end up at zero or if
1643 static void COM_ExternalLockRelease(
1647 COM_ExternalLock
*externalLock
= COM_ExternalLockLocate(elList
.head
, pUnk
);
1649 if ( externalLock
!= EL_NOT_FOUND
) {
1651 externalLock
->uRefCount
--; /* release external locks */
1652 IUnknown_Release(pUnk
); /* release local locks as well */
1654 if ( bRelAll
== FALSE
) break; /* perform single release */
1656 } while ( externalLock
->uRefCount
> 0 );
1658 if ( externalLock
->uRefCount
== 0 ) /* get rid of the list entry */
1659 COM_ExternalLockDelete(externalLock
);
1662 /****************************************************************************
1663 * Public - Method that frees the content of the list.
1665 static void COM_ExternalLockFreeList()
1667 COM_ExternalLock
*head
;
1669 head
= elList
.head
; /* grab it by the head */
1670 while ( head
!= EL_END_OF_LIST
) {
1671 COM_ExternalLockDelete(head
); /* get rid of the head stuff */
1672 head
= elList
.head
; /* get the new head... */
1676 /****************************************************************************
1677 * Public - Method that dump the content of the list.
1679 void COM_ExternalLockDump()
1681 COM_ExternalLock
*current
= elList
.head
;
1683 DPRINTF("\nExternal lock list contains:\n");
1685 while ( current
!= EL_END_OF_LIST
) {
1686 DPRINTF( "\t%p with %lu references count.\n", current
->pUnk
, current
->uRefCount
);
1688 /* Skip to the next item */
1689 current
= current
->next
;
1693 /******************************************************************************
1694 * CoLockObjectExternal [OLE32.31]
1696 HRESULT WINAPI
CoLockObjectExternal(
1697 LPUNKNOWN pUnk
, /* [in] object to be locked */
1698 BOOL fLock
, /* [in] do lock */
1699 BOOL fLastUnlockReleases
) /* [in] unlock all */
1704 * Increment the external lock coutner, COM_ExternalLockAddRef also
1705 * increment the object's internal lock counter.
1707 COM_ExternalLockAddRef( pUnk
);
1710 * Decrement the external lock coutner, COM_ExternalLockRelease also
1711 * decrement the object's internal lock counter.
1713 COM_ExternalLockRelease( pUnk
, fLastUnlockReleases
);
1719 /***********************************************************************
1720 * CoInitializeWOW (OLE32.27)
1722 HRESULT WINAPI
CoInitializeWOW(DWORD x
,DWORD y
) {
1723 FIXME("(0x%08lx,0x%08lx),stub!\n",x
,y
);
1727 static IUnknown
* pUnkState
= 0; /* FIXME: thread local */
1728 static int nStatCounter
= 0; /* global */
1729 static HMODULE hOleAut32
= 0; /* global */
1731 /***********************************************************************
1732 * CoGetState [OLE32.@]
1734 * NOTES: might be incomplete
1736 HRESULT WINAPI
CoGetState(IUnknown
** ppv
)
1741 IUnknown_AddRef(pUnkState
);
1743 FIXME("-- %p\n", *ppv
);
1751 /***********************************************************************
1752 * CoSetState [OLE32.42]
1754 * NOTES: FIXME: protect this with a crst
1756 HRESULT WINAPI
CoSetState(IUnknown
* pv
)
1758 FIXME("(%p),stub!\n", pv
);
1761 IUnknown_AddRef(pv
);
1763 if (nStatCounter
== 1) LoadLibraryA("OLEAUT32.DLL");
1767 TRACE("-- release %p now\n", pUnkState
);
1768 IUnknown_Release(pUnkState
);
1770 if (!nStatCounter
) FreeLibrary(hOleAut32
);
1777 /******************************************************************************
1778 * OleGetAutoConvert [OLE32.104]
1780 HRESULT WINAPI
OleGetAutoConvert(REFCLSID clsidOld
, LPCLSID pClsidNew
)
1788 sprintf(buf
,"CLSID\\");WINE_StringFromCLSID(clsidOld
,&buf
[6]);
1789 if (RegOpenKeyA(HKEY_CLASSES_ROOT
,buf
,&hkey
))
1791 res
= REGDB_E_CLASSNOTREG
;
1795 /* we can just query for the default value of AutoConvertTo key like that,
1796 without opening the AutoConvertTo key and querying for NULL (default) */
1797 if (RegQueryValueA(hkey
,"AutoConvertTo",buf
,&len
))
1799 res
= REGDB_E_KEYMISSING
;
1802 MultiByteToWideChar( CP_ACP
, 0, buf
, -1, wbuf
, sizeof(wbuf
)/sizeof(WCHAR
) );
1803 CLSIDFromString(wbuf
,pClsidNew
);
1805 if (hkey
) RegCloseKey(hkey
);
1809 /******************************************************************************
1810 * OleSetAutoConvert [OLE32.126]
1812 HRESULT WINAPI
OleSetAutoConvert(REFCLSID clsidOld
, REFCLSID clsidNew
)
1815 char buf
[200], szClsidNew
[200];
1818 TRACE("(%s,%s)\n", debugstr_guid(clsidOld
), debugstr_guid(clsidNew
));
1819 sprintf(buf
,"CLSID\\");WINE_StringFromCLSID(clsidOld
,&buf
[6]);
1820 WINE_StringFromCLSID(clsidNew
, szClsidNew
);
1821 if (RegOpenKeyA(HKEY_CLASSES_ROOT
,buf
,&hkey
))
1823 res
= REGDB_E_CLASSNOTREG
;
1826 if (RegSetValueA(hkey
, "AutoConvertTo", REG_SZ
, szClsidNew
, strlen(szClsidNew
)+1))
1828 res
= REGDB_E_WRITEREGDB
;
1833 if (hkey
) RegCloseKey(hkey
);
1837 /******************************************************************************
1838 * CoTreatAsClass [OLE32.46]
1840 HRESULT WINAPI
CoTreatAsClass(REFCLSID clsidOld
, REFCLSID clsidNew
)
1843 char buf
[200], szClsidNew
[200];
1846 FIXME("(%s,%s)\n", debugstr_guid(clsidOld
), debugstr_guid(clsidNew
));
1847 sprintf(buf
,"CLSID\\");WINE_StringFromCLSID(clsidOld
,&buf
[6]);
1848 WINE_StringFromCLSID(clsidNew
, szClsidNew
);
1849 if (RegOpenKeyA(HKEY_CLASSES_ROOT
,buf
,&hkey
))
1851 res
= REGDB_E_CLASSNOTREG
;
1854 if (RegSetValueA(hkey
, "AutoTreatAs", REG_SZ
, szClsidNew
, strlen(szClsidNew
)+1))
1856 res
= REGDB_E_WRITEREGDB
;
1861 if (hkey
) RegCloseKey(hkey
);
1866 /***********************************************************************
1867 * IsEqualGUID [OLE32.76]
1869 * Compares two Unique Identifiers.
1875 BOOL WINAPI
IsEqualGUID(
1876 REFGUID rguid1
, /* [in] unique id 1 */
1877 REFGUID rguid2
/* [in] unique id 2 */
1880 return !memcmp(rguid1
,rguid2
,sizeof(GUID
));
1883 /***********************************************************************
1884 * CoInitializeSecurity [OLE32.164]
1886 HRESULT WINAPI
CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc
, LONG cAuthSvc
,
1887 SOLE_AUTHENTICATION_SERVICE
* asAuthSvc
,
1888 void* pReserved1
, DWORD dwAuthnLevel
,
1889 DWORD dwImpLevel
, void* pReserved2
,
1890 DWORD dwCapabilities
, void* pReserved3
)
1892 FIXME("(%p,%ld,%p,%p,%ld,%ld,%p,%ld,%p) - stub!\n", pSecDesc
, cAuthSvc
,
1893 asAuthSvc
, pReserved1
, dwAuthnLevel
, dwImpLevel
, pReserved2
,
1894 dwCapabilities
, pReserved3
);