Changeset 9400 for trunk/src/ole32/compobj.c
- Timestamp:
- Nov 12, 2002, 6:07:48 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ole32/compobj.c
r8620 r9400 46 46 #include "wine/obj_storage.h" 47 47 #include "wine/obj_channel.h" 48 #include "wine/winbase16.h"49 48 #include "compobj_private.h" 50 #include "ifs.h"51 49 52 50 #include "wine/debug.h" 53 51 54 52 WINE_DEFAULT_DEBUG_CHANNEL(ole); 55 56 /****************************************************************************57 * COM External Lock structures and methods declaration58 *59 * This api provides a linked list to managed external references to60 * COM objects.61 *62 * The public interface consists of three calls:63 * COM_ExternalLockAddRef64 * COM_ExternalLockRelease65 * COM_ExternalLockFreeList66 */67 68 #define EL_END_OF_LIST 069 #define EL_NOT_FOUND 070 71 /*72 * Declaration of the static structure that manage the73 * external lock to COM objects.74 */75 typedef struct COM_ExternalLock COM_ExternalLock;76 typedef struct COM_ExternalLockList COM_ExternalLockList;77 78 struct COM_ExternalLock79 {80 IUnknown *pUnk; /* IUnknown referenced */81 ULONG uRefCount; /* external lock counter to IUnknown object*/82 COM_ExternalLock *next; /* Pointer to next element in list */83 };84 85 struct COM_ExternalLockList86 {87 COM_ExternalLock *head; /* head of list */88 };89 90 /*91 * Declaration and initialization of the static structure that manages92 * the external lock to COM objects.93 */94 static COM_ExternalLockList elList = { EL_END_OF_LIST };95 96 /*97 * Public Interface to the external lock list98 */99 static void COM_ExternalLockFreeList();100 static void COM_ExternalLockAddRef(IUnknown *pUnk);101 static void COM_ExternalLockRelease(IUnknown *pUnk, BOOL bRelAll);102 void COM_ExternalLockDump(); /* testing purposes, not static to avoid warning */103 104 /*105 * Private methods used to managed the linked list106 */107 static BOOL COM_ExternalLockInsert(108 IUnknown *pUnk);109 110 static void COM_ExternalLockDelete(111 COM_ExternalLock *element);112 113 static COM_ExternalLock* COM_ExternalLockFind(114 IUnknown *pUnk);115 116 static COM_ExternalLock* COM_ExternalLockLocate(117 COM_ExternalLock *element,118 IUnknown *pUnk);119 53 120 54 /**************************************************************************** … … 123 57 * TODO: Most of these things will have to be made thread-safe. 124 58 */ 125 HINSTANCE16 COMPOBJ_hInstance = 0;126 59 HINSTANCE COMPOBJ_hInstance32 = 0; 127 static int COMPOBJ_Attach = 0; 128 129 LPMALLOC16 currentMalloc16=NULL; 130 LPMALLOC currentMalloc32=NULL; 131 132 HTASK16 hETask = 0; 133 WORD Table_ETask[62]; 60 61 static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk); 62 static void COM_RevokeAllClasses(); 63 static void COM_ExternalLockFreeList(); 64 65 /***************************************************************************** 66 * Appartment management stuff 67 * 68 * NOTE: 69 * per Thread values are stored in the TEB on offset 0xF80 70 * 71 * see www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm 72 * 73 */ 74 75 typedef struct { 76 unsigned char threadingModell; /* we use the COINIT flags */ 77 unsigned long threadID; 78 long AppartmentLockCount; 79 } OleAppartmentData; 80 81 typedef struct { 82 OleAppartmentData *AppartmentData; 83 } OleThreadData; 84 85 /* not jet used 86 static CRITICAL_SECTION csAppartmentData = CRITICAL_SECTION_INIT("csAppartmentData"); 87 */ 88 /* 89 * the first STA created in a process is the main STA 90 */ 91 92 /* not jet used 93 static OleAppartmentData * mainSTA; 94 */ 95 96 /* 97 * a Process can only have one MTA 98 */ 99 100 /* not jet used 101 static OleAppartmentData * processMTA; 102 */ 103 134 104 135 105 /* … … 159 129 } RegisteredClass; 160 130 161 static CRITICAL_SECTION csRegisteredClassList ;131 static CRITICAL_SECTION csRegisteredClassList = CRITICAL_SECTION_INIT("csRegisteredClassList"); 162 132 static RegisteredClass* firstRegisteredClass = NULL; 163 133 164 /* this open DLL table belongs in a per process table, but my guess is that 165 * it shouldn't live in the kernel, so I'll put them out here in DLL 166 * space assuming that there is one OLE32 per process. 167 */ 134 /***************************************************************************** 135 * This section contains OpenDllList definitions 136 * 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. 140 * 141 * FIXME: a DLL what says OK whenn asked for unloading is unloaded in the 142 * next unload-call but not before 600 sec. 143 */ 144 168 145 typedef struct tagOpenDll { 169 146 HINSTANCE hLibrary; … … 171 148 } OpenDll; 172 149 173 static CRITICAL_SECTION csOpenDllList ;150 static CRITICAL_SECTION csOpenDllList = CRITICAL_SECTION_INIT("csOpenDllList"); 174 151 static OpenDll *openDllList = NULL; /* linked list of open dlls */ 175 152 176 /***************************************************************************** 177 * This section contains prototypes to internal methods for this 178 * module 179 */ 180 static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, 181 DWORD dwClsContext, 182 LPUNKNOWN* ppUnk); 183 184 static void COM_RevokeAllClasses(); 153 static void COMPOBJ_DLLList_Add(HANDLE hLibrary); 154 static void COMPOBJ_DllList_FreeUnused(int Timeout); 185 155 186 156 … … 190 160 void COMPOBJ_InitProcess( void ) 191 161 { 192 InitializeCriticalSection( &csRegisteredClassList );193 InitializeCriticalSection( &csOpenDllList );194 162 } 195 163 196 164 void COMPOBJ_UninitProcess( void ) 197 165 { 198 DeleteCriticalSection( &csRegisteredClassList ); 199 DeleteCriticalSection( &csOpenDllList ); 166 } 167 168 /***************************************************************************** 169 * This section contains OpenDllList implemantation 170 */ 171 172 static void COMPOBJ_DLLList_Add(HANDLE hLibrary) 173 { 174 OpenDll *ptr; 175 OpenDll *tmp; 176 177 TRACE("\n"); 178 179 EnterCriticalSection( &csOpenDllList ); 180 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; 186 } else { 187 /* search for this dll */ 188 int found = FALSE; 189 for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) { 190 if (ptr->hLibrary == hLibrary) { 191 found = TRUE; 192 break; 193 } 194 } 195 if (!found) { 196 /* dll not found, add it */ 197 tmp = openDllList; 198 openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll)); 199 openDllList->hLibrary = hLibrary; 200 openDllList->next = tmp; 201 } 202 } 203 204 LeaveCriticalSection( &csOpenDllList ); 205 } 206 207 static void COMPOBJ_DllList_FreeUnused(int Timeout) 208 { 209 OpenDll *curr, *next, *prev = NULL; 210 typedef HRESULT(*DllCanUnloadNowFunc)(void); 211 DllCanUnloadNowFunc DllCanUnloadNow; 212 213 TRACE("\n"); 214 215 EnterCriticalSection( &csOpenDllList ); 216 217 for (curr = openDllList; curr != NULL; ) { 218 DllCanUnloadNow = (DllCanUnloadNowFunc) GetProcAddress(curr->hLibrary, "DllCanUnloadNow"); 219 220 if ( (DllCanUnloadNow != NULL) && (DllCanUnloadNow() == S_OK) ) { 221 next = curr->next; 222 223 TRACE("freeing 0x%08x\n", curr->hLibrary); 224 FreeLibrary(curr->hLibrary); 225 226 HeapFree(GetProcessHeap(), 0, curr); 227 if (curr == openDllList) { 228 openDllList = next; 229 } else { 230 prev->next = next; 231 } 232 233 curr = next; 234 } else { 235 prev = curr; 236 curr = curr->next; 237 } 238 } 239 240 LeaveCriticalSection( &csOpenDllList ); 200 241 } 201 242 … … 211 252 TRACE("Returning version %d, build %d.\n", rmm, rup); 212 253 return (rmm<<16)+rup; 213 }214 215 /******************************************************************************216 * CoInitialize [COMPOBJ.2]217 * Set the win16 IMalloc used for memory management218 */219 HRESULT WINAPI CoInitialize16(220 LPVOID lpReserved /* [in] pointer to win16 malloc interface */221 ) {222 currentMalloc16 = (LPMALLOC16)lpReserved;223 return S_OK;224 254 } 225 255 … … 306 336 307 337 return hr; 308 }309 310 /***********************************************************************311 * CoUninitialize [COMPOBJ.3]312 * Don't know what it does.313 * 3-Nov-98 -- this was originally misspelled, I changed it to what I314 * believe is the correct spelling315 */316 void WINAPI CoUninitialize16(void)317 {318 TRACE("()\n");319 CoFreeAllLibraries();320 338 } 321 339 … … 368 386 } 369 387 370 #ifndef __WIN32OS2__371 /***********************************************************************372 * CoGetMalloc [COMPOBJ.4]373 * RETURNS374 * The current win16 IMalloc375 */376 HRESULT WINAPI CoGetMalloc16(377 DWORD dwMemContext, /* [in] unknown */378 LPMALLOC16 * lpMalloc /* [out] current win16 malloc interface */379 ) {380 if(!currentMalloc16)381 currentMalloc16 = IMalloc16_Constructor();382 *lpMalloc = currentMalloc16;383 return S_OK;384 }385 #endif386 /******************************************************************************387 * CoGetMalloc [OLE32.20]388 *389 * RETURNS390 * The current win32 IMalloc391 */392 HRESULT WINAPI CoGetMalloc(393 DWORD dwMemContext, /* [in] unknown */394 LPMALLOC *lpMalloc /* [out] current win32 malloc interface */395 ) {396 if(!currentMalloc32)397 currentMalloc32 = IMalloc_Constructor();398 *lpMalloc = currentMalloc32;399 return S_OK;400 }401 #ifndef __WIN32OS2__402 /***********************************************************************403 * CoCreateStandardMalloc [COMPOBJ.71]404 */405 HRESULT WINAPI CoCreateStandardMalloc16(DWORD dwMemContext,406 LPMALLOC16 *lpMalloc)407 {408 /* FIXME: docu says we shouldn't return the same allocator as in409 * CoGetMalloc16 */410 *lpMalloc = IMalloc16_Constructor();411 return S_OK;412 }413 #endif414 388 /****************************************************************************** 415 389 * CoDisconnectObject [COMPOBJ.15] … … 420 394 TRACE("(%p, %lx)\n",lpUnk,reserved); 421 395 return S_OK; 422 }423 424 /***********************************************************************425 * IsEqualGUID [COMPOBJ.18]426 *427 * Compares two Unique Identifiers.428 *429 * RETURNS430 * TRUE if equal431 */432 BOOL16 WINAPI IsEqualGUID16(433 GUID* g1, /* [in] unique id 1 */434 GUID* g2 /* [in] unique id 2 */435 ) {436 return !memcmp( g1, g2, sizeof(GUID) );437 }438 439 /******************************************************************************440 * CLSIDFromString [COMPOBJ.20]441 * Converts a unique identifier from its string representation into442 * the GUID struct.443 *444 * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]445 *446 * RETURNS447 * the converted GUID448 */449 HRESULT WINAPI CLSIDFromString16(450 LPCOLESTR16 idstr, /* [in] string representation of guid */451 CLSID *id /* [out] GUID converted from string */452 ) {453 BYTE *s = (BYTE *) idstr;454 BYTE *p;455 int i;456 BYTE table[256];457 458 if (!s)459 s = "{00000000-0000-0000-0000-000000000000}";460 else { /* validate the CLSID string */461 462 if (strlen(s) != 38)463 return CO_E_CLASSSTRING;464 465 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}'))466 return CO_E_CLASSSTRING;467 468 for (i=1; i<37; i++)469 {470 if ((i == 9)||(i == 14)||(i == 19)||(i == 24)) continue;471 if (!(((s[i] >= '0') && (s[i] <= '9')) ||472 ((s[i] >= 'a') && (s[i] <= 'f')) ||473 ((s[i] >= 'A') && (s[i] <= 'F')))474 )475 return CO_E_CLASSSTRING;476 }477 }478 479 TRACE("%s -> %p\n", s, id);480 481 /* quick lookup table */482 memset(table, 0, 256);483 484 for (i = 0; i < 10; i++) {485 table['0' + i] = i;486 }487 for (i = 0; i < 6; i++) {488 table['A' + i] = i+10;489 table['a' + i] = i+10;490 }491 492 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */493 494 p = (BYTE *) id;495 496 s++; /* skip leading brace */497 for (i = 0; i < 4; i++) {498 p[3 - i] = table[*s]<<4 | table[*(s+1)];499 s += 2;500 }501 p += 4;502 s++; /* skip - */503 504 for (i = 0; i < 2; i++) {505 p[1-i] = table[*s]<<4 | table[*(s+1)];506 s += 2;507 }508 p += 2;509 s++; /* skip - */510 511 for (i = 0; i < 2; i++) {512 p[1-i] = table[*s]<<4 | table[*(s+1)];513 s += 2;514 }515 p += 2;516 s++; /* skip - */517 518 /* these are just sequential bytes */519 for (i = 0; i < 2; i++) {520 *p++ = table[*s]<<4 | table[*(s+1)];521 s += 2;522 }523 s++; /* skip - */524 525 for (i = 0; i < 6; i++) {526 *p++ = table[*s]<<4 | table[*(s+1)];527 s += 2;528 }529 530 return S_OK;531 396 } 532 397 … … 553 418 * the converted GUID 554 419 */ 420 HRESULT WINAPI __CLSIDFromStringA( 421 LPCSTR idstr, /* [in] string representation of guid */ 422 CLSID *id) /* [out] GUID converted from string */ 423 { 424 BYTE *s = (BYTE *) idstr; 425 int i; 426 BYTE table[256]; 427 428 if (!s) 429 s = "{00000000-0000-0000-0000-000000000000}"; 430 else { /* validate the CLSID string */ 431 432 if (strlen(s) != 38) 433 return CO_E_CLASSSTRING; 434 435 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') || (s[24]!='-') || (s[37]!='}')) 436 return CO_E_CLASSSTRING; 437 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; 444 } 445 } 446 447 TRACE("%s -> %p\n", s, id); 448 449 /* quick lookup table */ 450 memset(table, 0, 256); 451 452 for (i = 0; i < 10; i++) { 453 table['0' + i] = i; 454 } 455 for (i = 0; i < 6; i++) { 456 table['A' + i] = i+10; 457 table['a' + i] = i+10; 458 } 459 460 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ 461 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]]; 466 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]]; 476 477 return S_OK; 478 } 479 480 /*****************************************************************************/ 481 555 482 HRESULT WINAPI CLSIDFromString( 556 483 LPCOLESTR idstr, /* [in] string representation of GUID */ … … 562 489 if (!WideCharToMultiByte( CP_ACP, 0, idstr, -1, xid, sizeof(xid), NULL, NULL )) 563 490 return CO_E_CLASSSTRING; 564 ret = CLSIDFromString16(xid,id); 491 492 493 ret = __CLSIDFromStringA(xid,id); 565 494 if(ret != S_OK) { /* It appears a ProgID is also valid */ 566 495 ret = CLSIDFromProgID(idstr, id); … … 610 539 return S_OK; 611 540 } 612 #ifndef __WIN32OS2__ 613 /****************************************************************************** 614 * StringFromCLSID [COMPOBJ.19] 615 * Converts a GUID into the respective string representation. 616 * The target string is allocated using the OLE IMalloc. 617 * RETURNS 618 * the string representation and HRESULT 619 */ 620 HRESULT WINAPI StringFromCLSID16( 621 REFCLSID id, /* [in] the GUID to be converted */ 622 LPOLESTR16 *idstr /* [out] a pointer to a to-be-allocated segmented pointer pointing to the resulting string */ 623 624 ) { 625 extern BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags, 626 DWORD cbArgs, LPVOID pArgs, LPDWORD pdwRetCode ); 627 LPMALLOC16 mllc; 628 HRESULT ret; 629 DWORD args[2]; 630 631 ret = CoGetMalloc16(0,&mllc); 632 if (ret) return ret; 633 634 args[0] = (DWORD)mllc; 635 args[1] = 40; 636 637 /* No need for a Callback entry, we have WOWCallback16Ex which does 638 * everything we need. 639 */ 640 if (!K32WOWCallback16Ex( 641 (DWORD)((ICOM_VTABLE(IMalloc16)*)MapSL( 642 (SEGPTR)ICOM_VTBL(((LPMALLOC16)MapSL((SEGPTR)mllc)))) 643 )->Alloc, 644 WCB16_CDECL, 645 2*sizeof(DWORD), 646 (LPVOID)args, 647 (LPDWORD)idstr 648 )) { 649 WARN("CallTo16 IMalloc16 failed\n"); 650 return E_FAIL; 651 } 652 return WINE_StringFromCLSID(id,MapSL((SEGPTR)*idstr)); 653 } 654 #endif 541 542 655 543 /****************************************************************************** 656 544 * StringFromCLSID [OLE32.151] … … 755 643 756 644 /****************************************************************************** 757 * CLSIDFromProgID [COMPOBJ.61]758 * Converts a program id into the respective GUID. (By using a registry lookup)759 * RETURNS760 * riid associated with the progid761 */762 HRESULT WINAPI CLSIDFromProgID16(763 LPCOLESTR16 progid, /* [in] program id as found in registry */764 LPCLSID riid /* [out] associated CLSID */765 ) {766 char *buf,buf2[80];767 DWORD buf2len;768 HRESULT err;769 HKEY xhkey;770 771 buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);772 sprintf(buf,"%s\\CLSID",progid);773 if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {774 HeapFree(GetProcessHeap(),0,buf);775 return CO_E_CLASSSTRING;776 }777 HeapFree(GetProcessHeap(),0,buf);778 buf2len = sizeof(buf2);779 if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {780 RegCloseKey(xhkey);781 return CO_E_CLASSSTRING;782 }783 RegCloseKey(xhkey);784 return CLSIDFromString16(buf2,riid);785 }786 787 /******************************************************************************788 645 * CLSIDFromProgID [OLE32.2] 789 646 * Converts a program id into the respective GUID. (By using a registry lookup) … … 816 673 } 817 674 RegCloseKey(xhkey); 818 return CLSIDFromString16(buf2,riid);675 return __CLSIDFromStringA(buf2,riid); 819 676 } 820 677 … … 877 734 /* We have the CLSid we want back from the registry as a string, so 878 735 lets convert it into a CLSID structure */ 879 if ( (CLSIDFromString16(buf2,pclsid)) != NOERROR) 880 { 736 if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR) { 881 737 return E_INVALIDARG; 882 738 } … … 928 784 return S_OK; 929 785 } 930 #ifndef __WIN32OS2__ 931 /* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */ 932 /*********************************************************************** 933 * LookupETask (COMPOBJ.94) 934 */ 935 HRESULT WINAPI LookupETask16(HTASK16 *hTask,LPVOID p) { 936 FIXME("(%p,%p),stub!\n",hTask,p); 937 if ((*hTask = GetCurrentTask()) == hETask) { 938 memcpy(p, Table_ETask, sizeof(Table_ETask)); 939 } 940 return 0; 941 } 942 943 /* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */ 944 /*********************************************************************** 945 * SetETask (COMPOBJ.95) 946 */ 947 HRESULT WINAPI SetETask16(HTASK16 hTask, LPVOID p) { 948 FIXME("(%04x,%p),stub!\n",hTask,p); 949 hETask = hTask; 950 return 0; 951 } 952 953 /* FIXME: this function is not declared in the WINELIB headers. But where should it go ? */ 954 /*********************************************************************** 955 * CALLOBJECTINWOW (COMPOBJ.201) 956 */ 957 HRESULT WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) { 958 FIXME("(%p,%p),stub!\n",p1,p2); 959 return 0; 960 } 961 962 /****************************************************************************** 963 * CoRegisterClassObject [COMPOBJ.5] 964 * 965 * Don't know where it registers it ... 966 */ 967 HRESULT WINAPI CoRegisterClassObject16( 968 REFCLSID rclsid, 969 LPUNKNOWN pUnk, 970 DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */ 971 DWORD flags, /* [in] REGCLS flags indicating how connections are made */ 972 LPDWORD lpdwRegister 973 ) { 974 char buf[80]; 975 976 WINE_StringFromCLSID(rclsid,buf); 977 978 FIXME("(%s,%p,0x%08lx,0x%08lx,%p),stub\n", 979 buf,pUnk,dwClsContext,flags,lpdwRegister 980 ); 981 return 0; 982 } 983 984 985 /****************************************************************************** 986 * CoRevokeClassObject [COMPOBJ.6] 987 * 988 */ 989 HRESULT WINAPI CoRevokeClassObject16(DWORD dwRegister) /* [in] token on class obj */ 990 { 991 FIXME("(0x%08lx),stub!\n", dwRegister); 992 return 0; 993 } 994 995 /****************************************************************************** 996 * CoFileTimeToDosDateTime [COMPOBJ.30] 997 */ 998 BOOL16 WINAPI CoFileTimeToDosDateTime16(const FILETIME *ft, LPWORD lpDosDate, LPWORD lpDosTime) 999 { 1000 return FileTimeToDosDateTime(ft, lpDosDate, lpDosTime); 1001 } 1002 1003 /****************************************************************************** 1004 * CoDosDateTimeToFileTime [COMPOBJ.31] 1005 */ 1006 BOOL16 WINAPI CoDosDateTimeToFileTime16(WORD wDosDate, WORD wDosTime, FILETIME *ft) 1007 { 1008 return DosDateTimeToFileTime(wDosDate, wDosTime, ft); 1009 } 1010 #endif 786 787 1011 788 /*** 1012 789 * COM_GetRegisteredClassObject … … 1296 1073 1297 1074 /*********************************************************************** 1075 * compobj_RegReadPath [internal] 1076 * 1077 * Reads a registry value and expands it when nessesary 1078 */ 1079 HRESULT compobj_RegReadPath(char * keyname, char * valuename, char * dst, int dstlen) 1080 { 1081 HRESULT hres; 1082 HKEY key; 1083 DWORD keytype; 1084 char src[MAX_PATH]; 1085 DWORD dwLength = dstlen; 1086 1087 if((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, keyname, 0, KEY_READ, &key)) == ERROR_SUCCESS) { 1088 if( (hres = RegQueryValueExA(key, NULL, NULL, &keytype, (LPBYTE)src, &dwLength)) == ERROR_SUCCESS ) { 1089 if (keytype == REG_EXPAND_SZ) { 1090 if (dstlen <= ExpandEnvironmentStringsA(src, dst, dstlen)) hres = ERROR_MORE_DATA; 1091 } else { 1092 strncpy(dst, src, dstlen); 1093 } 1094 } 1095 RegCloseKey (key); 1096 } 1097 return hres; 1098 } 1099 1100 /*********************************************************************** 1298 1101 * CoGetClassObject [COMPOBJ.7] 1299 1102 * CoGetClassObject [OLE32.16] … … 1311 1114 HRESULT hres = E_UNEXPECTED; 1312 1115 char xclsid[80]; 1313 WCHAR ProviderName[MAX_PATH+1];1314 DWORD ProviderNameLen = sizeof(ProviderName);1315 1116 HINSTANCE hLibrary; 1316 1117 #ifdef __WIN32OS2__ 1317 typedef HRESULT (* CALLBACK DllGetClassObjectFunc)(REFCLSID clsid, 1318 REFIID iid, LPVOID *ppv); 1118 typedef HRESULT (* CALLBACK DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv); 1319 1119 #else 1320 typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, 1321 REFIID iid, LPVOID *ppv); 1120 typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv); 1322 1121 #endif 1323 1122 DllGetClassObjectFunc DllGetClassObject; … … 1325 1124 WINE_StringFromCLSID((LPCLSID)rclsid,xclsid); 1326 1125 1327 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", 1328 debugstr_guid(rclsid), 1329 debugstr_guid(iid) 1330 ); 1126 TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid)); 1331 1127 1332 1128 if (pServerInfo) { … … 1356 1152 } 1357 1153 1358 if ((CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER) & dwClsContext) { 1359 HKEY key; 1360 char buf[200]; 1361 1362 memset(ProviderName,0,sizeof(ProviderName)); 1363 sprintf(buf,"CLSID\\%s\\InprocServer32",xclsid); 1364 if (((hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, buf, 0, KEY_READ, &key)) != ERROR_SUCCESS) || 1365 ((hres = RegQueryValueExW(key,NULL,NULL,NULL,(LPBYTE)ProviderName,&ProviderNameLen)), 1366 RegCloseKey (key), 1367 hres != ERROR_SUCCESS)) 1368 { 1154 /* first try: in-process */ 1155 if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext) { 1156 char keyname[MAX_PATH]; 1157 char dllpath[MAX_PATH+1]; 1158 1159 sprintf(keyname,"CLSID\\%s\\InprocServer32",xclsid); 1160 1161 if ( compobj_RegReadPath(keyname, NULL, dllpath, sizeof(dllpath)) != ERROR_SUCCESS) { 1162 /* failure: CLSID is not found in registry */ 1163 WARN("class %s not registred\n", xclsid); 1369 1164 hres = REGDB_E_CLASSNOTREG; 1370 } 1371 /* Don't ask me. MSDN says that CoGetClassObject does NOT call CoLoadLibrary */ 1372 else if ((hLibrary = CoLoadLibrary(ProviderName, TRUE)) == 0) 1373 { 1374 FIXME("couldn't load InprocServer32 dll %s\n", debugstr_w(ProviderName)); 1375 hres = E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */ 1165 } else { 1166 if ((hLibrary = LoadLibraryExA(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0) { 1167 /* failure: DLL could not be loaded */ 1168 ERR("couldn't load InprocServer32 dll %s\n", dllpath); 1169 hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */ 1170 } else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) { 1171 /* failure: the dll did not export DllGetClassObject */ 1172 ERR("couldn't find function DllGetClassObject in %s\n", dllpath); 1173 FreeLibrary( hLibrary ); 1174 hres = CO_E_DLLNOTFOUND; 1175 } else { 1176 /* OK: get the ClassObject */ 1177 COMPOBJ_DLLList_Add( hLibrary ); 1178 return DllGetClassObject(rclsid, iid, ppv); 1179 } 1376 1180 } 1377 else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject"))) 1378 { 1379 /* not sure if this should be called here CoFreeLibrary(hLibrary);*/ 1380 FIXME("couldn't find function DllGetClassObject in %s\n", debugstr_w(ProviderName)); 1381 hres = E_ACCESSDENIED; 1382 } 1383 else 1384 { 1385 /* Ask the DLL for its class object. (there was a note here about 1386 * class factories but this is good. 1387 */ 1388 return DllGetClassObject(rclsid, iid, ppv); 1389 } 1390 } 1391 1181 } 1392 1182 1393 1183 /* Next try out of process */ … … 1426 1216 IStorage *pstg=0; 1427 1217 HRESULT res; 1428 int nbElm =0,length=0,i=0;1429 LONG sizeProgId =20;1218 int nbElm, length, i; 1219 LONG sizeProgId; 1430 1220 LPOLESTR *pathDec=0,absFile=0,progId=0; 1431 WCHAR extention[100]={0}; 1432 1433 TRACE("()\n"); 1221 LPWSTR extension; 1222 static const WCHAR bkslashW[] = {'\\',0}; 1223 static const WCHAR dotW[] = {'.',0}; 1224 1225 TRACE("%s, %p\n", debugstr_w(filePathName), pclsid); 1434 1226 1435 1227 /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/ … … 1475 1267 1476 1268 /* failed if the path represente a directory and not an absolute file name*/ 1477 if ( lstrcmpW(absFile,(LPOLESTR)"\\"))1269 if (!lstrcmpW(absFile, bkslashW)) 1478 1270 return MK_E_INVALIDEXTENSION; 1479 1271 1480 1272 /* get the extension of the file */ 1273 extension = NULL; 1481 1274 length=lstrlenW(absFile); 1482 for(i=length-1; ( (i>=0) && (extention[i]=absFile[i]) );i--); 1275 for(i = length-1; (i >= 0) && *(extension = &absFile[i]) != '.'; i--) 1276 /* nothing */; 1277 1278 if (!extension || !lstrcmpW(extension, dotW)) 1279 return MK_E_INVALIDEXTENSION; 1280 1281 res=RegQueryValueW(HKEY_CLASSES_ROOT, extension, NULL, &sizeProgId); 1483 1282 1484 1283 /* get the progId associated to the extension */ 1485 progId=CoTaskMemAlloc(sizeProgId); 1486 1487 res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId); 1488 1489 if (res==ERROR_MORE_DATA){ 1490 1491 progId = CoTaskMemRealloc(progId,sizeProgId); 1492 res=RegQueryValueW(HKEY_CLASSES_ROOT,extention,progId,&sizeProgId); 1493 } 1284 progId = CoTaskMemAlloc(sizeProgId); 1285 res = RegQueryValueW(HKEY_CLASSES_ROOT, extension, progId, &sizeProgId); 1286 1494 1287 if (res==ERROR_SUCCESS) 1495 1288 /* return the clsid associated to the progId */ … … 1507 1300 return MK_E_INVALIDEXTENSION; 1508 1301 } 1509 /******************************************************************************1510 * CoRegisterMessageFilter [COMPOBJ.27]1511 */1512 HRESULT WINAPI CoRegisterMessageFilter16(1513 LPMESSAGEFILTER lpMessageFilter,1514 LPMESSAGEFILTER *lplpMessageFilter1515 ) {1516 FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);1517 return 0;1518 }1519 1520 1302 /*********************************************************************** 1521 1303 * CoCreateInstance [COMPOBJ.13] … … 1644 1426 1645 1427 /*********************************************************************** 1428 * CoLoadLibrary (OLE32.30) 1429 */ 1430 HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree) 1431 { 1432 TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree); 1433 1434 return LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH); 1435 } 1436 1437 /*********************************************************************** 1646 1438 * CoFreeLibrary [OLE32.13] 1439 * 1440 * NOTES: don't belive the docu 1647 1441 */ 1648 1442 void WINAPI CoFreeLibrary(HINSTANCE hLibrary) 1649 1443 { 1650 OpenDll *ptr, *prev; 1651 OpenDll *tmp; 1652 1653 EnterCriticalSection( &csOpenDllList ); 1654 1655 /* lookup library in linked list */ 1656 prev = NULL; 1657 for (ptr = openDllList; ptr != NULL; ptr=ptr->next) { 1658 if (ptr->hLibrary == hLibrary) { 1659 break; 1660 } 1661 prev = ptr; 1662 } 1663 1664 if (ptr == NULL) { 1665 /* shouldn't happen if user passed in a valid hLibrary */ 1666 goto end; 1667 } 1668 /* assert: ptr points to the library entry to free */ 1669 1670 /* free library and remove node from list */ 1671 FreeLibrary(hLibrary); 1672 if (ptr == openDllList) { 1673 tmp = openDllList->next; 1674 HeapFree(GetProcessHeap(), 0, openDllList); 1675 openDllList = tmp; 1676 } else { 1677 tmp = ptr->next; 1678 HeapFree(GetProcessHeap(), 0, ptr); 1679 prev->next = tmp; 1680 } 1681 end: 1682 LeaveCriticalSection( &csOpenDllList ); 1444 FreeLibrary(hLibrary); 1683 1445 } 1684 1446 … … 1686 1448 /*********************************************************************** 1687 1449 * CoFreeAllLibraries [OLE32.12] 1450 * 1451 * NOTES: don't belive the docu 1688 1452 */ 1689 1453 void WINAPI CoFreeAllLibraries(void) 1690 1454 { 1691 OpenDll *ptr, *tmp; 1692 1693 EnterCriticalSection( &csOpenDllList ); 1694 1695 for (ptr = openDllList; ptr != NULL; ) { 1696 tmp=ptr->next; 1697 CoFreeLibrary(ptr->hLibrary); 1698 ptr = tmp; 1699 } 1700 1701 LeaveCriticalSection( &csOpenDllList ); 1702 } 1703 1455 /* NOP */ 1456 } 1704 1457 1705 1458 … … 1707 1460 * CoFreeUnusedLibraries [COMPOBJ.17] 1708 1461 * CoFreeUnusedLibraries [OLE32.14] 1462 * 1463 * FIXME: Calls to CoFreeUnusedLibraries from any thread always route 1464 * through the main apartment's thread to call DllCanUnloadNow 1709 1465 */ 1710 1466 void WINAPI CoFreeUnusedLibraries(void) 1711 1467 { 1712 OpenDll *ptr, *tmp; 1713 typedef HRESULT(*DllCanUnloadNowFunc)(void); 1714 DllCanUnloadNowFunc DllCanUnloadNow; 1715 1716 EnterCriticalSection( &csOpenDllList ); 1717 1718 for (ptr = openDllList; ptr != NULL; ) { 1719 DllCanUnloadNow = (DllCanUnloadNowFunc) 1720 GetProcAddress(ptr->hLibrary, "DllCanUnloadNow"); 1721 1722 if ( (DllCanUnloadNow != NULL) && 1723 (DllCanUnloadNow() == S_OK) ) { 1724 tmp=ptr->next; 1725 CoFreeLibrary(ptr->hLibrary); 1726 ptr = tmp; 1727 } else { 1728 ptr=ptr->next; 1729 } 1730 } 1731 1732 LeaveCriticalSection( &csOpenDllList ); 1468 COMPOBJ_DllList_FreeUnused(0); 1733 1469 } 1734 1470 … … 1747 1483 1748 1484 /*********************************************************************** 1749 * CoTaskMemAlloc (OLE32.43)1750 * RETURNS1751 * pointer to newly allocated block1752 */1753 LPVOID WINAPI CoTaskMemAlloc(1754 ULONG size /* [in] size of memoryblock to be allocated */1755 ) {1756 LPMALLOC lpmalloc;1757 HRESULT ret = CoGetMalloc(0,&lpmalloc);1758 1759 if (FAILED(ret))1760 return NULL;1761 1762 return IMalloc_Alloc(lpmalloc,size);1763 }1764 /***********************************************************************1765 * CoTaskMemFree (OLE32.44)1766 */1767 VOID WINAPI CoTaskMemFree(1768 LPVOID ptr /* [in] pointer to be freed */1769 ) {1770 LPMALLOC lpmalloc;1771 HRESULT ret = CoGetMalloc(0,&lpmalloc);1772 1773 if (FAILED(ret))1774 return;1775 1776 IMalloc_Free(lpmalloc, ptr);1777 }1778 1779 /***********************************************************************1780 * CoTaskMemRealloc (OLE32.45)1781 * RETURNS1782 * pointer to newly allocated block1783 */1784 LPVOID WINAPI CoTaskMemRealloc(1785 LPVOID pvOld,1786 ULONG size) /* [in] size of memoryblock to be allocated */1787 {1788 LPMALLOC lpmalloc;1789 HRESULT ret = CoGetMalloc(0,&lpmalloc);1790 1791 if (FAILED(ret))1792 return NULL;1793 1794 return IMalloc_Realloc(lpmalloc, pvOld, size);1795 }1796 1797 /***********************************************************************1798 1485 * CoLoadLibrary (OLE32.30) 1799 1486 */ 1800 HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree) 1801 { 1802 HINSTANCE hLibrary; 1803 OpenDll *ptr; 1804 OpenDll *tmp; 1805 1806 TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree); 1807 1808 hLibrary = LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH); 1809 1810 if (!bAutoFree) 1811 return hLibrary; 1812 1813 EnterCriticalSection( &csOpenDllList ); 1814 1815 if (openDllList == NULL) { 1816 /* empty list -- add first node */ 1817 openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll)); 1818 openDllList->hLibrary=hLibrary; 1819 openDllList->next = NULL; 1487 static void COM_RevokeAllClasses() 1488 { 1489 EnterCriticalSection( &csRegisteredClassList ); 1490 1491 while (firstRegisteredClass!=0) 1492 { 1493 CoRevokeClassObject(firstRegisteredClass->dwCookie); 1494 } 1495 1496 LeaveCriticalSection( &csRegisteredClassList ); 1497 } 1498 1499 /**************************************************************************** 1500 * COM External Lock methods implementation 1501 * 1502 * This api provides a linked list to managed external references to 1503 * COM objects. 1504 * 1505 * The public interface consists of three calls: 1506 * COM_ExternalLockAddRef 1507 * COM_ExternalLockRelease 1508 * COM_ExternalLockFreeList 1509 */ 1510 1511 #define EL_END_OF_LIST 0 1512 #define EL_NOT_FOUND 0 1513 1514 /* 1515 * Declaration of the static structure that manage the 1516 * external lock to COM objects. 1517 */ 1518 typedef struct COM_ExternalLock COM_ExternalLock; 1519 typedef struct COM_ExternalLockList COM_ExternalLockList; 1520 1521 struct COM_ExternalLock 1522 { 1523 IUnknown *pUnk; /* IUnknown referenced */ 1524 ULONG uRefCount; /* external lock counter to IUnknown object*/ 1525 COM_ExternalLock *next; /* Pointer to next element in list */ 1526 }; 1527 1528 struct COM_ExternalLockList 1529 { 1530 COM_ExternalLock *head; /* head of list */ 1531 }; 1532 1533 /* 1534 * Declaration and initialization of the static structure that manages 1535 * the external lock to COM objects. 1536 */ 1537 static COM_ExternalLockList elList = { EL_END_OF_LIST }; 1538 1539 /* 1540 * Private methods used to managed the linked list 1541 */ 1542 1543 1544 static COM_ExternalLock* COM_ExternalLockLocate( 1545 COM_ExternalLock *element, 1546 IUnknown *pUnk); 1547 1548 /**************************************************************************** 1549 * Internal - Insert a new IUnknown* to the linked list 1550 */ 1551 static BOOL COM_ExternalLockInsert( 1552 IUnknown *pUnk) 1553 { 1554 COM_ExternalLock *newLock = NULL; 1555 COM_ExternalLock *previousHead = NULL; 1556 1557 /* 1558 * Allocate space for the new storage object 1559 */ 1560 newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock)); 1561 1562 if (newLock!=NULL) { 1563 if ( elList.head == EL_END_OF_LIST ) { 1564 elList.head = newLock; /* The list is empty */ 1820 1565 } else { 1821 /* search for this dll */ 1822 int found = FALSE; 1823 for (ptr = openDllList; ptr->next != NULL; ptr=ptr->next) { 1824 if (ptr->hLibrary == hLibrary) { 1825 found = TRUE; 1826 break; 1827 } 1828 } 1829 if (!found) { 1830 /* dll not found, add it */ 1831 tmp = openDllList; 1832 openDllList = (OpenDll*)HeapAlloc(GetProcessHeap(),0, sizeof(OpenDll)); 1833 openDllList->hLibrary = hLibrary; 1834 openDllList->next = tmp; 1835 } 1836 } 1837 1838 LeaveCriticalSection( &csOpenDllList ); 1839 1840 return hLibrary; 1841 } 1842 1843 /*********************************************************************** 1844 * CoInitializeWOW (OLE32.27) 1845 */ 1846 HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) { 1847 FIXME("(0x%08lx,0x%08lx),stub!\n",x,y); 1848 return 0; 1849 } 1850 1851 /****************************************************************************** 1852 * CoLockObjectExternal [COMPOBJ.63] 1853 */ 1854 HRESULT WINAPI CoLockObjectExternal16( 1855 LPUNKNOWN pUnk, /* [in] object to be locked */ 1856 BOOL16 fLock, /* [in] do lock */ 1857 BOOL16 fLastUnlockReleases /* [in] ? */ 1858 ) { 1859 FIXME("(%p,%d,%d),stub!\n",pUnk,fLock,fLastUnlockReleases); 1860 return S_OK; 1566 /* insert does it at the head */ 1567 previousHead = elList.head; 1568 elList.head = newLock; 1569 } 1570 1571 /* Set new list item data member */ 1572 newLock->pUnk = pUnk; 1573 newLock->uRefCount = 1; 1574 newLock->next = previousHead; 1575 1576 return TRUE; 1577 } 1578 return FALSE; 1579 } 1580 1581 /**************************************************************************** 1582 * Internal - Method that removes an item from the linked list. 1583 */ 1584 static void COM_ExternalLockDelete( 1585 COM_ExternalLock *itemList) 1586 { 1587 COM_ExternalLock *current = elList.head; 1588 1589 if ( current == itemList ) { 1590 /* this section handles the deletion of the first node */ 1591 elList.head = itemList->next; 1592 HeapFree( GetProcessHeap(), 0, itemList); 1593 } else { 1594 do { 1595 if ( current->next == itemList ){ /* We found the item to free */ 1596 current->next = itemList->next; /* readjust the list pointers */ 1597 HeapFree( GetProcessHeap(), 0, itemList); 1598 break; 1599 } 1600 1601 /* Skip to the next item */ 1602 current = current->next; 1603 1604 } while ( current != EL_END_OF_LIST ); 1605 } 1606 } 1607 1608 /**************************************************************************** 1609 * Internal - Recursivity agent for IUnknownExternalLockList_Find 1610 * 1611 * NOTES: how long can the list be ?? (recursive!!!) 1612 */ 1613 static COM_ExternalLock* COM_ExternalLockLocate( COM_ExternalLock *element, IUnknown *pUnk) 1614 { 1615 if ( element == EL_END_OF_LIST ) 1616 return EL_NOT_FOUND; 1617 else if ( element->pUnk == pUnk ) /* We found it */ 1618 return element; 1619 else /* Not the right guy, keep on looking */ 1620 return COM_ExternalLockLocate( element->next, pUnk); 1621 } 1622 1623 /**************************************************************************** 1624 * Public - Method that increments the count for a IUnknown* in the linked 1625 * list. The item is inserted if not already in the list. 1626 */ 1627 static void COM_ExternalLockAddRef(IUnknown *pUnk) 1628 { 1629 COM_ExternalLock *externalLock = COM_ExternalLockLocate(elList.head, pUnk); 1630 1631 /* 1632 * Add an external lock to the object. If it was already externally 1633 * locked, just increase the reference count. If it was not. 1634 * add the item to the list. 1635 */ 1636 if ( externalLock == EL_NOT_FOUND ) 1637 COM_ExternalLockInsert(pUnk); 1638 else 1639 externalLock->uRefCount++; 1640 1641 /* 1642 * Add an internal lock to the object 1643 */ 1644 IUnknown_AddRef(pUnk); 1645 } 1646 1647 /**************************************************************************** 1648 * Public - Method that decrements the count for a IUnknown* in the linked 1649 * list. The item is removed from the list if its count end up at zero or if 1650 * bRelAll is TRUE. 1651 */ 1652 static void COM_ExternalLockRelease( 1653 IUnknown *pUnk, 1654 BOOL bRelAll) 1655 { 1656 COM_ExternalLock *externalLock = COM_ExternalLockLocate(elList.head, pUnk); 1657 1658 if ( externalLock != EL_NOT_FOUND ) { 1659 do { 1660 externalLock->uRefCount--; /* release external locks */ 1661 IUnknown_Release(pUnk); /* release local locks as well */ 1662 1663 if ( bRelAll == FALSE ) break; /* perform single release */ 1664 1665 } while ( externalLock->uRefCount > 0 ); 1666 1667 if ( externalLock->uRefCount == 0 ) /* get rid of the list entry */ 1668 COM_ExternalLockDelete(externalLock); 1669 } 1670 } 1671 /**************************************************************************** 1672 * Public - Method that frees the content of the list. 1673 */ 1674 static void COM_ExternalLockFreeList() 1675 { 1676 COM_ExternalLock *head; 1677 1678 head = elList.head; /* grab it by the head */ 1679 while ( head != EL_END_OF_LIST ) { 1680 COM_ExternalLockDelete(head); /* get rid of the head stuff */ 1681 head = elList.head; /* get the new head... */ 1682 } 1683 } 1684 1685 /**************************************************************************** 1686 * Public - Method that dump the content of the list. 1687 */ 1688 void COM_ExternalLockDump() 1689 { 1690 COM_ExternalLock *current = elList.head; 1691 1692 DPRINTF("\nExternal lock list contains:\n"); 1693 1694 while ( current != EL_END_OF_LIST ) { 1695 DPRINTF( "\t%p with %lu references count.\n", current->pUnk, current->uRefCount); 1696 1697 /* Skip to the next item */ 1698 current = current->next; 1699 } 1861 1700 } 1862 1701 … … 1870 1709 { 1871 1710 1872 if (fLock) 1873 { 1874 /* 1875 * Increment the external lock coutner, COM_ExternalLockAddRef also 1876 * increment the object's internal lock counter. 1877 */ 1878 COM_ExternalLockAddRef( pUnk); 1879 } 1880 else 1881 { 1882 /* 1883 * Decrement the external lock coutner, COM_ExternalLockRelease also 1884 * decrement the object's internal lock counter. 1885 */ 1886 COM_ExternalLockRelease( pUnk, fLastUnlockReleases); 1887 } 1888 1889 return S_OK; 1890 } 1891 1892 /*********************************************************************** 1893 * CoGetState [COMPOBJ.115] 1894 */ 1895 HRESULT WINAPI CoGetState16(LPDWORD state) 1896 { 1897 FIXME("(%p),stub!\n", state); 1898 *state = 0; 1899 return S_OK; 1900 } 1711 if (fLock) { 1712 /* 1713 * Increment the external lock coutner, COM_ExternalLockAddRef also 1714 * increment the object's internal lock counter. 1715 */ 1716 COM_ExternalLockAddRef( pUnk); 1717 } else { 1718 /* 1719 * Decrement the external lock coutner, COM_ExternalLockRelease also 1720 * decrement the object's internal lock counter. 1721 */ 1722 COM_ExternalLockRelease( pUnk, fLastUnlockReleases); 1723 } 1724 1725 return S_OK; 1726 } 1727 1728 /*********************************************************************** 1729 * CoInitializeWOW (OLE32.27) 1730 */ 1731 HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) { 1732 FIXME("(0x%08lx,0x%08lx),stub!\n",x,y); 1733 return 0; 1734 } 1735 1736 static IUnknown * pUnkState = 0; /* FIXME: thread local */ 1737 static int nStatCounter = 0; /* global */ 1738 static HMODULE hOleAut32 = 0; /* global */ 1739 1740 /*********************************************************************** 1741 * CoGetState [OLE32.24] 1742 * 1743 * NOTES: might be incomplete 1744 */ 1745 HRESULT WINAPI CoGetState(IUnknown ** ppv) 1746 { 1747 FIXME("\n"); 1748 1749 if(pUnkState) { 1750 IUnknown_AddRef(pUnkState); 1751 *ppv = pUnkState; 1752 FIXME("-- %p\n", *ppv); 1753 return S_OK; 1754 } 1755 *ppv = NULL; 1756 return E_FAIL; 1757 1758 } 1759 1901 1760 /*********************************************************************** 1902 1761 * CoSetState [OLE32.42] 1903 */ 1904 HRESULT WINAPI CoSetState(LPDWORD state) 1905 { 1906 FIXME("(%p),stub!\n", state); 1907 if (state) *state = 0; 1908 return S_OK; 1909 } 1910 /*********************************************************************** 1911 * CoCreateFreeThreadedMarshaler [OLE32.5] 1912 */ 1913 HRESULT WINAPI CoCreateFreeThreadedMarshaler (LPUNKNOWN punkOuter, LPUNKNOWN* ppunkMarshal) 1914 { 1915 FIXME ("(%p %p): stub\n", punkOuter, ppunkMarshal); 1916 1917 return S_OK; 1918 } 1919 1920 /*** 1921 * COM_RevokeAllClasses 1922 * 1923 * This method is called when the COM libraries are uninitialized to 1924 * release all the references to the class objects registered with 1925 * the library 1926 */ 1927 static void COM_RevokeAllClasses() 1928 { 1929 EnterCriticalSection( &csRegisteredClassList ); 1930 1931 while (firstRegisteredClass!=0) 1932 { 1933 CoRevokeClassObject(firstRegisteredClass->dwCookie); 1934 } 1935 1936 LeaveCriticalSection( &csRegisteredClassList ); 1937 } 1938 1939 /**************************************************************************** 1940 * COM External Lock methods implementation 1941 */ 1942 1943 /**************************************************************************** 1944 * Public - Method that increments the count for a IUnknown* in the linked 1945 * list. The item is inserted if not already in the list. 1946 */ 1947 static void COM_ExternalLockAddRef( 1948 IUnknown *pUnk) 1949 { 1950 COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk); 1951 1952 /* 1953 * Add an external lock to the object. If it was already externally 1954 * locked, just increase the reference count. If it was not. 1955 * add the item to the list. 1956 */ 1957 if ( externalLock == EL_NOT_FOUND ) 1958 COM_ExternalLockInsert(pUnk); 1959 else 1960 externalLock->uRefCount++; 1961 1962 /* 1963 * Add an internal lock to the object 1964 */ 1965 IUnknown_AddRef(pUnk); 1966 } 1967 1968 /**************************************************************************** 1969 * Public - Method that decrements the count for a IUnknown* in the linked 1970 * list. The item is removed from the list if its count end up at zero or if 1971 * bRelAll is TRUE. 1972 */ 1973 static void COM_ExternalLockRelease( 1974 IUnknown *pUnk, 1975 BOOL bRelAll) 1976 { 1977 COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk); 1978 1979 if ( externalLock != EL_NOT_FOUND ) 1980 { 1981 do 1982 { 1983 externalLock->uRefCount--; /* release external locks */ 1984 IUnknown_Release(pUnk); /* release local locks as well */ 1985 1986 if ( bRelAll == FALSE ) 1987 break; /* perform single release */ 1988 1989 } while ( externalLock->uRefCount > 0 ); 1990 1991 if ( externalLock->uRefCount == 0 ) /* get rid of the list entry */ 1992 COM_ExternalLockDelete(externalLock); 1993 } 1994 } 1995 /**************************************************************************** 1996 * Public - Method that frees the content of the list. 1997 */ 1998 static void COM_ExternalLockFreeList() 1999 { 2000 COM_ExternalLock *head; 2001 2002 head = elList.head; /* grab it by the head */ 2003 while ( head != EL_END_OF_LIST ) 2004 { 2005 COM_ExternalLockDelete(head); /* get rid of the head stuff */ 2006 2007 head = elList.head; /* get the new head... */ 2008 } 2009 } 2010 2011 /**************************************************************************** 2012 * Public - Method that dump the content of the list. 2013 */ 2014 void COM_ExternalLockDump() 2015 { 2016 COM_ExternalLock *current = elList.head; 2017 2018 DPRINTF("\nExternal lock list contains:\n"); 2019 2020 while ( current != EL_END_OF_LIST ) 2021 { 2022 DPRINTF( "\t%p with %lu references count.\n", current->pUnk, current->uRefCount); 2023 2024 /* Skip to the next item */ 2025 current = current->next; 2026 } 2027 2028 } 2029 2030 /**************************************************************************** 2031 * Internal - Find a IUnknown* in the linked list 2032 */ 2033 static COM_ExternalLock* COM_ExternalLockFind( 2034 IUnknown *pUnk) 2035 { 2036 return COM_ExternalLockLocate(elList.head, pUnk); 2037 } 2038 2039 /**************************************************************************** 2040 * Internal - Recursivity agent for IUnknownExternalLockList_Find 2041 */ 2042 static COM_ExternalLock* COM_ExternalLockLocate( 2043 COM_ExternalLock *element, 2044 IUnknown *pUnk) 2045 { 2046 if ( element == EL_END_OF_LIST ) 2047 return EL_NOT_FOUND; 2048 2049 else if ( element->pUnk == pUnk ) /* We found it */ 2050 return element; 2051 2052 else /* Not the right guy, keep on looking */ 2053 return COM_ExternalLockLocate( element->next, pUnk); 2054 } 2055 2056 /**************************************************************************** 2057 * Internal - Insert a new IUnknown* to the linked list 2058 */ 2059 static BOOL COM_ExternalLockInsert( 2060 IUnknown *pUnk) 2061 { 2062 COM_ExternalLock *newLock = NULL; 2063 COM_ExternalLock *previousHead = NULL; 2064 2065 /* 2066 * Allocate space for the new storage object 2067 */ 2068 newLock = HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock)); 2069 2070 if (newLock!=NULL) 2071 { 2072 if ( elList.head == EL_END_OF_LIST ) 2073 { 2074 elList.head = newLock; /* The list is empty */ 2075 } 2076 else 2077 { 2078 /* 2079 * insert does it at the head 2080 */ 2081 previousHead = elList.head; 2082 elList.head = newLock; 2083 } 2084 2085 /* 2086 * Set new list item data member 2087 */ 2088 newLock->pUnk = pUnk; 2089 newLock->uRefCount = 1; 2090 newLock->next = previousHead; 2091 2092 return TRUE; 2093 } 2094 else 2095 return FALSE; 2096 } 2097 2098 /**************************************************************************** 2099 * Internal - Method that removes an item from the linked list. 2100 */ 2101 static void COM_ExternalLockDelete( 2102 COM_ExternalLock *itemList) 2103 { 2104 COM_ExternalLock *current = elList.head; 2105 2106 if ( current == itemList ) 2107 { 2108 /* 2109 * this section handles the deletion of the first node 2110 */ 2111 elList.head = itemList->next; 2112 HeapFree( GetProcessHeap(), 0, itemList); 2113 } 2114 else 2115 { 2116 do 2117 { 2118 if ( current->next == itemList ) /* We found the item to free */ 2119 { 2120 current->next = itemList->next; /* readjust the list pointers */ 2121 2122 HeapFree( GetProcessHeap(), 0, itemList); 2123 break; 2124 } 2125 2126 /* Skip to the next item */ 2127 current = current->next; 2128 2129 } while ( current != EL_END_OF_LIST ); 2130 } 2131 } 2132 2133 /*********************************************************************** 2134 * DllEntryPoint [COMPOBJ.116] 2135 * 2136 * Initialization code for the COMPOBJ DLL 2137 * 2138 * RETURNS: 2139 */ 2140 BOOL WINAPI COMPOBJ_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst, WORD ds, WORD HeapSize, DWORD res1, WORD res2) 2141 { 2142 TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n", Reason, hInst, ds, HeapSize, 2143 res1, res2); 2144 switch(Reason) 2145 { 2146 case DLL_PROCESS_ATTACH: 2147 if (!COMPOBJ_Attach++) COMPOBJ_hInstance = hInst; 2148 break; 2149 2150 case DLL_PROCESS_DETACH: 2151 if(!--COMPOBJ_Attach) 2152 COMPOBJ_hInstance = 0; 2153 break; 2154 } 2155 return TRUE; 2156 } 1762 * 1763 * NOTES: FIXME: protect this with a crst 1764 */ 1765 HRESULT WINAPI CoSetState(IUnknown * pv) 1766 { 1767 FIXME("(%p),stub!\n", pv); 1768 1769 if (pv) { 1770 IUnknown_AddRef(pv); 1771 nStatCounter++; 1772 if (nStatCounter == 1) LoadLibraryA("OLEAUT32.DLL"); 1773 } 1774 1775 if (pUnkState) { 1776 TRACE("-- release %p now\n", pUnkState); 1777 IUnknown_Release(pUnkState); 1778 nStatCounter--; 1779 if (!nStatCounter) FreeLibrary(hOleAut32); 1780 } 1781 pUnkState = pv; 1782 return S_OK; 1783 } 1784 2157 1785 2158 1786 /****************************************************************************** … … 2184 1812 CLSIDFromString(wbuf,pClsidNew); 2185 1813 done: 2186 if (hkey) RegCloseKey(hkey); 2187 2188 return res; 1814 if (hkey) RegCloseKey(hkey); 1815 return res; 2189 1816 } 2190 1817 … … 2262 1889 return !memcmp(rguid1,rguid2,sizeof(GUID)); 2263 1890 } 1891 1892 /*********************************************************************** 1893 * CoInitializeSecurity [OLE32.164] 1894 */ 1895 HRESULT WINAPI CoInitializeSecurity(PSECURITY_DESCRIPTOR pSecDesc, LONG cAuthSvc, 1896 SOLE_AUTHENTICATION_SERVICE* asAuthSvc, 1897 void* pReserved1, DWORD dwAuthnLevel, 1898 DWORD dwImpLevel, void* pReserved2, 1899 DWORD dwCapabilities, void* pReserved3) 1900 { 1901 FIXME("(%p,%ld,%p,%p,%ld,%ld,%p,%ld,%p) - stub!\n", pSecDesc, cAuthSvc, 1902 asAuthSvc, pReserved1, dwAuthnLevel, dwImpLevel, pReserved2, 1903 dwCapabilities, pReserved3); 1904 return S_OK; 1905 }
Note:
See TracChangeset
for help on using the changeset viewer.