Ignore:
Timestamp:
Nov 12, 2002, 6:07:48 PM (23 years ago)
Author:
sandervl
Message:

Wine resync

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ole32/compobj.c

    r8620 r9400  
    4646#include "wine/obj_storage.h"
    4747#include "wine/obj_channel.h"
    48 #include "wine/winbase16.h"
    4948#include "compobj_private.h"
    50 #include "ifs.h"
    5149
    5250#include "wine/debug.h"
    5351
    5452WINE_DEFAULT_DEBUG_CHANNEL(ole);
    55 
    56 /****************************************************************************
    57  *  COM External Lock structures and methods declaration
    58  *
    59  *  This api provides a linked list to managed external references to
    60  *  COM objects.
    61  *
    62  *  The public interface consists of three calls:
    63  *      COM_ExternalLockAddRef
    64  *      COM_ExternalLockRelease
    65  *      COM_ExternalLockFreeList
    66  */
    67 
    68 #define EL_END_OF_LIST 0
    69 #define EL_NOT_FOUND   0
    70 
    71 /*
    72  * Declaration of the static structure that manage the
    73  * external lock to COM  objects.
    74  */
    75 typedef struct COM_ExternalLock     COM_ExternalLock;
    76 typedef struct COM_ExternalLockList COM_ExternalLockList;
    77 
    78 struct COM_ExternalLock
    79 {
    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_ExternalLockList
    86 {
    87   COM_ExternalLock *head;     /* head of list */
    88 };
    89 
    90 /*
    91  * Declaration and initialization of the static structure that manages
    92  * 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 list
    98  */
    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 list
    106  */
    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);
    11953
    12054/****************************************************************************
     
    12357 * TODO: Most of these things will have to be made thread-safe.
    12458 */
    125 HINSTANCE16     COMPOBJ_hInstance = 0;
    12659HINSTANCE       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
     61static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN*  ppUnk);
     62static void COM_RevokeAllClasses();
     63static 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
     75typedef struct {
     76        unsigned char           threadingModell;        /* we use the COINIT flags */
     77        unsigned long           threadID;
     78        long                    AppartmentLockCount;
     79} OleAppartmentData;
     80
     81typedef struct {
     82        OleAppartmentData       *AppartmentData;
     83} OleThreadData;
     84
     85/* not jet used
     86static 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
     93static OleAppartmentData * mainSTA;
     94*/
     95
     96/*
     97 * a Process can only have one MTA
     98 */
     99
     100/* not jet used
     101static OleAppartmentData * processMTA;
     102*/
     103
    134104
    135105/*
     
    159129} RegisteredClass;
    160130
    161 static CRITICAL_SECTION csRegisteredClassList;
     131static CRITICAL_SECTION csRegisteredClassList = CRITICAL_SECTION_INIT("csRegisteredClassList");
    162132static RegisteredClass* firstRegisteredClass = NULL;
    163133
    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
    168145typedef struct tagOpenDll {
    169146  HINSTANCE hLibrary;
     
    171148} OpenDll;
    172149
    173 static CRITICAL_SECTION csOpenDllList;
     150static CRITICAL_SECTION csOpenDllList = CRITICAL_SECTION_INIT("csOpenDllList");
    174151static OpenDll *openDllList = NULL; /* linked list of open dlls */
    175152
    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();
     153static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
     154static void COMPOBJ_DllList_FreeUnused(int Timeout);
    185155
    186156
     
    190160void COMPOBJ_InitProcess( void )
    191161{
    192     InitializeCriticalSection( &csRegisteredClassList );
    193     InitializeCriticalSection( &csOpenDllList );
    194162}
    195163
    196164void COMPOBJ_UninitProcess( void )
    197165{
    198     DeleteCriticalSection( &csRegisteredClassList );
    199     DeleteCriticalSection( &csOpenDllList );
     166}
     167
     168/*****************************************************************************
     169 * This section contains OpenDllList implemantation
     170 */
     171
     172static 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
     207static 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 );
    200241}
    201242
     
    211252    TRACE("Returning version %d, build %d.\n", rmm, rup);
    212253    return (rmm<<16)+rup;
    213 }
    214 
    215 /******************************************************************************
    216  *              CoInitialize    [COMPOBJ.2]
    217  * Set the win16 IMalloc used for memory management
    218  */
    219 HRESULT WINAPI CoInitialize16(
    220         LPVOID lpReserved       /* [in] pointer to win16 malloc interface */
    221 ) {
    222     currentMalloc16 = (LPMALLOC16)lpReserved;
    223     return S_OK;
    224254}
    225255
     
    306336
    307337  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 I
    314  *   believe is the correct spelling
    315  */
    316 void WINAPI CoUninitialize16(void)
    317 {
    318   TRACE("()\n");
    319   CoFreeAllLibraries();
    320338}
    321339
     
    368386}
    369387
    370 #ifndef __WIN32OS2__
    371 /***********************************************************************
    372  *           CoGetMalloc    [COMPOBJ.4]
    373  * RETURNS
    374  *      The current win16 IMalloc
    375  */
    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 #endif
    386 /******************************************************************************
    387  *              CoGetMalloc     [OLE32.20]
    388  *
    389  * RETURNS
    390  *      The current win32 IMalloc
    391  */
    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 in
    409      * CoGetMalloc16 */
    410     *lpMalloc = IMalloc16_Constructor();
    411     return S_OK;
    412 }
    413 #endif
    414388/******************************************************************************
    415389 *              CoDisconnectObject      [COMPOBJ.15]
     
    420394    TRACE("(%p, %lx)\n",lpUnk,reserved);
    421395    return S_OK;
    422 }
    423 
    424 /***********************************************************************
    425  *           IsEqualGUID [COMPOBJ.18]
    426  *
    427  * Compares two Unique Identifiers.
    428  *
    429  * RETURNS
    430  *      TRUE if equal
    431  */
    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 into
    442  * the GUID struct.
    443  *
    444  * Class id: DWORD-WORD-WORD-BYTES[2]-BYTES[6]
    445  *
    446  * RETURNS
    447  *      the converted GUID
    448  */
    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;
    531396}
    532397
     
    553418 *      the converted GUID
    554419 */
     420HRESULT 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
    555482HRESULT WINAPI CLSIDFromString(
    556483        LPCOLESTR idstr,        /* [in] string representation of GUID */
     
    562489    if (!WideCharToMultiByte( CP_ACP, 0, idstr, -1, xid, sizeof(xid), NULL, NULL ))
    563490        return CO_E_CLASSSTRING;
    564     ret = CLSIDFromString16(xid,id);
     491
     492
     493    ret = __CLSIDFromStringA(xid,id);
    565494    if(ret != S_OK) { /* It appears a ProgID is also valid */
    566495        ret = CLSIDFromProgID(idstr, id);
     
    610539  return S_OK;
    611540}
    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
    655543/******************************************************************************
    656544 *              StringFromCLSID [OLE32.151]
     
    755643
    756644/******************************************************************************
    757  *              CLSIDFromProgID [COMPOBJ.61]
    758  * Converts a program id into the respective GUID. (By using a registry lookup)
    759  * RETURNS
    760  *      riid associated with the progid
    761  */
    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 /******************************************************************************
    788645 *              CLSIDFromProgID [OLE32.2]
    789646 * Converts a program id into the respective GUID. (By using a registry lookup)
     
    816673    }
    817674    RegCloseKey(xhkey);
    818     return CLSIDFromString16(buf2,riid);
     675    return __CLSIDFromStringA(buf2,riid);
    819676}
    820677
     
    877734    /* We have the CLSid we want back from the registry as a string, so
    878735       lets convert it into a CLSID structure */
    879     if ( (CLSIDFromString16(buf2,pclsid)) != NOERROR)
    880     {
     736    if ( (__CLSIDFromStringA(buf2,pclsid)) != NOERROR) {
    881737       return E_INVALIDARG;
    882738    }
     
    928784        return S_OK;
    929785}
    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
    1011788/***
    1012789 * COM_GetRegisteredClassObject
     
    12961073
    12971074/***********************************************************************
     1075 *      compobj_RegReadPath     [internal]
     1076 *
     1077 *      Reads a registry value and expands it when nessesary
     1078 */
     1079HRESULT 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/***********************************************************************
    12981101 *           CoGetClassObject [COMPOBJ.7]
    12991102 *           CoGetClassObject [OLE32.16]
     
    13111114    HRESULT     hres = E_UNEXPECTED;
    13121115    char        xclsid[80];
    1313     WCHAR ProviderName[MAX_PATH+1];
    1314     DWORD ProviderNameLen = sizeof(ProviderName);
    13151116    HINSTANCE hLibrary;
    13161117#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);
    13191119#else
    1320     typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid,
    1321                              REFIID iid, LPVOID *ppv);
     1120    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
    13221121#endif
    13231122    DllGetClassObjectFunc DllGetClassObject;
     
    13251124    WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
    13261125
    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));
    13311127
    13321128    if (pServerInfo) {
     
    13561152    }
    13571153
    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);
    13691164            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          }
    13761180        }
    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    }
    13921182
    13931183    /* Next try out of process */
     
    14261216    IStorage *pstg=0;
    14271217    HRESULT res;
    1428     int nbElm=0,length=0,i=0;
    1429     LONG sizeProgId=20;
     1218    int nbElm, length, i;
     1219    LONG sizeProgId;
    14301220    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);
    14341226
    14351227    /* if the file contain a storage object the return the CLSID writen by IStorage_SetClass method*/
     
    14751267
    14761268    /* failed if the path represente a directory and not an absolute file name*/
    1477     if (lstrcmpW(absFile,(LPOLESTR)"\\"))
     1269    if (!lstrcmpW(absFile, bkslashW))
    14781270        return MK_E_INVALIDEXTENSION;
    14791271
    14801272    /* get the extension of the file */
     1273    extension = NULL;
    14811274    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);
    14831282
    14841283    /* 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
    14941287    if (res==ERROR_SUCCESS)
    14951288        /* return the clsid associated to the progId */
     
    15071300    return MK_E_INVALIDEXTENSION;
    15081301}
    1509 /******************************************************************************
    1510  *              CoRegisterMessageFilter [COMPOBJ.27]
    1511  */
    1512 HRESULT WINAPI CoRegisterMessageFilter16(
    1513         LPMESSAGEFILTER lpMessageFilter,
    1514         LPMESSAGEFILTER *lplpMessageFilter
    1515 ) {
    1516         FIXME("(%p,%p),stub!\n",lpMessageFilter,lplpMessageFilter);
    1517         return 0;
    1518 }
    1519 
    15201302/***********************************************************************
    15211303 *           CoCreateInstance [COMPOBJ.13]
     
    16441426
    16451427/***********************************************************************
     1428 *           CoLoadLibrary (OLE32.30)
     1429 */
     1430HINSTANCE 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/***********************************************************************
    16461438 *           CoFreeLibrary [OLE32.13]
     1439 *
     1440 * NOTES: don't belive the docu
    16471441 */
    16481442void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
    16491443{
    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);
    16831445}
    16841446
     
    16861448/***********************************************************************
    16871449 *           CoFreeAllLibraries [OLE32.12]
     1450 *
     1451 * NOTES: don't belive the docu
    16881452 */
    16891453void WINAPI CoFreeAllLibraries(void)
    16901454{
    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}
    17041457
    17051458
     
    17071460 *           CoFreeUnusedLibraries [COMPOBJ.17]
    17081461 *           CoFreeUnusedLibraries [OLE32.14]
     1462 *
     1463 * FIXME: Calls to CoFreeUnusedLibraries from any thread always route
     1464 * through the main apartment's thread to call DllCanUnloadNow
    17091465 */
    17101466void WINAPI CoFreeUnusedLibraries(void)
    17111467{
    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);
    17331469}
    17341470
     
    17471483
    17481484/***********************************************************************
    1749  *           CoTaskMemAlloc (OLE32.43)
    1750  * RETURNS
    1751  *      pointer to newly allocated block
    1752  */
    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  * RETURNS
    1782  *      pointer to newly allocated block
    1783  */
    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 /***********************************************************************
    17981485 *           CoLoadLibrary (OLE32.30)
    17991486 */
    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;
     1487static 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 */
     1518typedef struct COM_ExternalLock     COM_ExternalLock;
     1519typedef struct COM_ExternalLockList COM_ExternalLockList;
     1520
     1521struct 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
     1528struct 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 */
     1537static COM_ExternalLockList elList = { EL_END_OF_LIST };
     1538
     1539/*
     1540 * Private methods used to managed the linked list
     1541 */
     1542
     1543
     1544static COM_ExternalLock* COM_ExternalLockLocate(
     1545  COM_ExternalLock *element,
     1546  IUnknown         *pUnk);
     1547
     1548/****************************************************************************
     1549 * Internal - Insert a new IUnknown* to the linked list
     1550 */
     1551static 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 */
    18201565    } 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 */
     1584static 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 */
     1613static 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 */
     1627static 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 */
     1652static 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 */
     1674static 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 */
     1688void 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  }
    18611700}
    18621701
     
    18701709{
    18711710
    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 */
     1731HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y) {
     1732    FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
     1733    return 0;
     1734}
     1735
     1736static IUnknown * pUnkState = 0; /* FIXME: thread local */
     1737static int nStatCounter = 0;     /* global */
     1738static HMODULE hOleAut32 = 0;    /* global */
     1739
     1740/***********************************************************************
     1741 *           CoGetState [OLE32.24]
     1742 *
     1743 * NOTES: might be incomplete
     1744 */
     1745HRESULT 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
    19011760/***********************************************************************
    19021761 *           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 */
     1765HRESULT 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
    21571785
    21581786/******************************************************************************
     
    21841812    CLSIDFromString(wbuf,pClsidNew);
    21851813done:
    2186   if (hkey) RegCloseKey(hkey);
    2187 
    2188   return res;
     1814    if (hkey) RegCloseKey(hkey);
     1815    return res;
    21891816}
    21901817
     
    22621889    return !memcmp(rguid1,rguid2,sizeof(GUID));
    22631890}
     1891
     1892/***********************************************************************
     1893 *           CoInitializeSecurity [OLE32.164]
     1894 */
     1895HRESULT 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.