Ignore:
Timestamp:
Jul 12, 1999, 2:21:37 AM (26 years ago)
Author:
davidr
Message:

Updated clsid handling to correctly draw textual clsid's
Fixed GUID instansiation.
Moved initialisation to OLE32.CPP
Added many new APIs incl. CoCreateInstance & CoGetClassObject.
Many partially implemented stubs completed and moved to OLE32.CPP
Running Object Table implemented (Moniker.cpp)
IMalloc & Task Memory implemented.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ole32/ole32.cpp

    r200 r291  
     1/*
     2 *
     3 * Project Odin Software License can be found in LICENSE.TXT
     4 *
     5 */
     6/*
     7 * COM/OLE misc. functions.
     8 *
     9 * 1/7/99
     10 *
     11 * Copyright 1999 David J. Raison
     12 *
     13 * Some portions from Wine Implementation
     14 *   Copyright 1995  Martin von Loewis
     15 *   Copyright 1998  Justin Bradford
     16 *   Copyright 1999  Francis Beaudet
     17 *   Copyright 1999  Sylvain St-Germain
     18 */
     19
     20#include "ole32.h"
     21
     22#include "oString.h"
     23#include "moniker.h"    // RunningObjectTableImpl_***
     24
     25// ======================================================================
     26// Local Data
     27// ======================================================================
     28typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
     29
    130/*
     31 * This linked list contains the list of registered class objects. These
     32 * are mostly used to register the factories for out-of-proc servers of OLE
     33 * objects.
     34 */
     35typedef struct tagRegisteredClass
     36{
     37  CLSID     classIdentifier;
     38  LPUNKNOWN classObject;
     39  DWORD     runContext;
     40  DWORD     connectFlags;
     41  DWORD     dwCookie;
     42  struct tagRegisteredClass* nextClass;
     43} RegisteredClass;
     44
     45static RegisteredClass* firstRegisteredClass = NULL;
     46
     47/*
     48 * COM External Lock structures and methods declaration
    249 *
    3  * Project Odin Software License can be found in LICENSE.TXT
     50 * This api provides a linked list to managed external references to
     51 * COM objects.
    452 *
    553 */
     54
     55#define EL_END_OF_LIST 0
     56#define EL_NOT_FOUND   0
     57
    658/*
    7  * Win32 OLE stubs for OS/2
     59 * Declaration of the static structure that manage the
     60 * external lock to COM  objects.
     61 */
     62typedef struct COM_ExternalLock     COM_ExternalLock;
     63typedef struct COM_ExternalLockList COM_ExternalLockList;
     64
     65struct COM_ExternalLock
     66{
     67    IUnknown         *pUnk;     /* IUnknown referenced */
     68    ULONG            uRefCount; /* external lock counter to IUnknown object*/
     69    COM_ExternalLock *next;     /* Pointer to next element in list */
     70};
     71
     72struct COM_ExternalLockList
     73{
     74    COM_ExternalLock *head;     /* head of list */
     75};
     76
     77/*
     78 * Declaration and initialization of the static structure that manages
     79 * the external lock to COM objects.
     80 */
     81static COM_ExternalLockList elList = { EL_END_OF_LIST };
     82
     83/*
     84 * This open DLL table belongs in a per process table, but my guess is that
     85 * it shouldn't live in the kernel, so I'll put them out here in DLL
     86 * space assuming that there is one OLE32 per process.
     87 */
     88typedef struct tagOpenDll
     89{
     90    char *      DllName;                /* really only needed for debugging */
     91    HINSTANCE   hLibrary;
     92    struct tagOpenDll * next;
     93} OpenDll;
     94
     95static OpenDll * openDllList = NULL;    /* linked list of open dlls */
     96
     97/*
     98 * Com Library reference count...
    899 *
    9  * 1998/06/12
    10  *
    11  * Copyright 1998 Sander van Leeuwen
     100 * Used to control loading / unloading of Library resources,
     101 * Runnng object table, DLL's etc...
    12102 */
    13 
    14 #include "ole32.h"
     103static LONG     COM_ref = 0;
     104
     105// ======================================================================
     106// Prototypes.
     107// ======================================================================
     108static HRESULT COM_GetRegisteredClassObject(
     109        REFCLSID        rclsid,
     110        DWORD           dwClsContext,
     111        LPUNKNOWN *     ppUnk);
     112
     113static void COM_RevokeAllClasses();
     114
     115static void COM_ExternalLockFreeList();
     116
     117static void COM_ExternalLockAddRef(
     118        IUnknown * pUnk);
     119
     120static void COM_ExternalLockRelease(
     121        IUnknown *      pUnk,
     122        BOOL            bRelAll);
     123
     124static BOOL COM_ExternalLockInsert(
     125        IUnknown * pUnk);
     126
     127static void COM_ExternalLockDelete(
     128        COM_ExternalLock * element);
     129
     130static COM_ExternalLock * COM_ExternalLockFind(
     131        IUnknown *      pUnk);
     132
     133static COM_ExternalLock * COM_ExternalLockLocate(
     134        COM_ExternalLock * element,
     135        IUnknown *      pUnk);
     136
     137// ======================================================================
     138// Public API's
     139// ======================================================================
    15140
    16141// ----------------------------------------------------------------------
     
    20145{
    21146    dprintf(("OLE32.CoBuildVersion\n"));
    22     return (rmm<<16)+rup;
    23 }
    24 
     147    return (rmm << 16) + rup;
     148}
     149
     150// ----------------------------------------------------------------------
     151// CoDosDateTimeToFileTime
     152// ----------------------------------------------------------------------
     153BOOL WIN32API CoDosDateTimeToFileTime(WORD nDosDate, WORD nDosTime,
     154                                         FILETIME *lpFileTime)
     155{
     156    dprintf(("OLE32: CoDosDateTimeToFileTime"));
     157
     158    return DosDateTimeToFileTime(nDosDate, nDosTime, lpFileTime);
     159}
     160
     161// ----------------------------------------------------------------------
     162// CoDosDateTimeToFileTime
     163// ----------------------------------------------------------------------
     164HRESULT WIN32API CoFileTimeNow(FILETIME *lpFileTime)
     165{
     166    SYSTEMTIME systime;
     167
     168    dprintf(("OLE32: CoFileTimeNow"));
     169
     170    GetSystemTime(&systime);
     171    return SystemTimeToFileTime(&systime, lpFileTime);
     172}
     173
     174// ----------------------------------------------------------------------
     175// CoDosDateTimeToFileTime
     176// ----------------------------------------------------------------------
     177BOOL WIN32API CoFileTimeToDosDateTime(FILETIME *lpFileTime, LPWORD lpDosDate,
     178                                         LPWORD lpDosTime)
     179{
     180    dprintf(("OLE32: CoFileTimeToDosDateTime"));
     181
     182    return FileTimeToDosDateTime(lpFileTime, lpDosDate, lpDosTime);
     183}
     184
     185// ----------------------------------------------------------------------
     186// CoInitialize()
     187// ----------------------------------------------------------------------
     188HRESULT WIN32API CoInitialize(LPVOID lpReserved)
     189{
     190    dprintf(("OLE32: CoInitialize\n"));
     191
     192    return CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
     193}
     194
     195// ----------------------------------------------------------------------
     196// CoInitializeEx()
     197// ----------------------------------------------------------------------
     198HRESULT WIN32API CoInitializeEx(
     199        LPVOID  lpReserved,     // [in] pointer to win32 malloc interface
     200        DWORD   dwCoInit)       // [in] A value from COINIT specifies the thread
     201{
     202    HRESULT             hr;
     203
     204    dprintf(("OLE32: CoInitializeEx(%p, %lx)\n", lpReserved, dwCoInit));
     205
     206    if (lpReserved != NULL)
     207    {
     208        dprintf(("Warning: Bad parameter %p, must be an old Windows Application", lpReserved));
     209    }
     210
     211    /*
     212     * Check for unsupported features.
     213     */
     214    if (dwCoInit != COINIT_APARTMENTTHREADED)
     215    {
     216        dprintf(("Warning: Unsupported flag %lx", dwCoInit));
     217        /* Hope for the best and continue anyway */
     218    }
     219
     220    /*
     221     * Initialise the Running Object Table
     222     */
     223    hr = S_FALSE;
     224    if (++COM_ref == 1)
     225    {
     226        hr = RunningObjectTableImpl_Initialize();
     227        if (hr != S_OK)
     228            --COM_ref;
     229    }
     230
     231    return hr;
     232}
     233
     234// ----------------------------------------------------------------------
     235// CoUninitialize()
     236// ----------------------------------------------------------------------
     237void WIN32API CoUninitialize(void)
     238{
     239    dprintf(("OLE32: CoUninitialize"));
     240
     241    if (--COM_ref == 0)
     242    {
     243        dprintf(("OLE32: Releasing COM libraries"));
     244
     245        RunningObjectTableImpl_UnInitialize();
     246
     247        COM_RevokeAllClasses();
     248
     249        CoFreeAllLibraries();
     250       
     251        COM_ExternalLockFreeList();
     252    }
     253}
     254
     255// ----------------------------------------------------------------------
     256// CoCreateInstance
     257// ----------------------------------------------------------------------
     258HRESULT WIN32API CoCreateInstance
     259   (REFCLSID            rclsid,
     260    LPUNKNOWN           pUnkOuter,
     261    DWORD               dwClsContext,
     262    REFIID              iid,
     263    LPVOID *            ppv)
     264{
     265    HRESULT hres;
     266    LPCLASSFACTORY lpclf = 0;
     267
     268    oStringA            tCLSID(rclsid);
     269    oStringA            tIId(iid);
     270
     271    dprintf(("OLE32: CoCreateInstance"));
     272    dprintf(("       CLSID:%s", (char *)tCLSID));
     273    dprintf(("       IID  :%s", (char *)tIId));
     274
     275    // Sanity check
     276    if (ppv == 0)
     277        return E_POINTER;
     278
     279    *ppv = 0;
     280
     281    // Get a class factory to construct the object we want.
     282    hres = CoGetClassObject(rclsid, dwClsContext, NULL, &IID_IClassFactory, (LPVOID *)&lpclf);
     283
     284    if (FAILED(hres))
     285        return hres;
     286
     287    // Create the object and don't forget to release the factory
     288    hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv);
     289    IClassFactory_Release(lpclf);
     290
     291    return hres;
     292}
     293
     294// ----------------------------------------------------------------------
     295// CoCreateInstanceEx
     296// ----------------------------------------------------------------------
     297HRESULT WIN32API CoCreateInstanceEx
     298   (REFCLSID            rclsid,
     299    LPUNKNOWN           pUnkOuter,
     300    DWORD               dwClsContext,
     301    COSERVERINFO *      pServerInfo,
     302    ULONG               cmq,
     303    MULTI_QI *          pResults)
     304{
     305    IUnknown *          pUnk = NULL;
     306    HRESULT             hr;
     307    ULONG               index;
     308    int                 successCount = 0;
     309
     310    oStringA            tCLSID(rclsid);
     311
     312    dprintf(("OLE32: CoCreateInstanceEx"));
     313    dprintf(("       CLSID:%s", (char *)tCLSID));
     314
     315    // Sanity check
     316    if ( (cmq == 0) || (pResults == NULL))
     317        return E_INVALIDARG;
     318
     319    if (pServerInfo != NULL)
     320        dprintf(("OLE32: CoCreateInstanceEx - pServerInfo not supported!"));
     321
     322    // Initialize all the "out" parameters.
     323    for (index = 0; index < cmq; index++)
     324    {
     325        pResults[index].pItf = NULL;
     326        pResults[index].hr   = E_NOINTERFACE;
     327    }
     328
     329    /*
     330    * Get the object and get it's IUnknown pointer.
     331    */
     332    hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, &IID_IUnknown, (VOID**)&pUnk);
     333
     334    if (hr)
     335        return hr;
     336
     337    /*
     338    * Then, query for all the interfaces requested.
     339    */
     340    for (index = 0; index < cmq; index++)
     341    {
     342        pResults[index].hr = IUnknown_QueryInterface(pUnk, pResults[index].pIID, (VOID**)&(pResults[index].pItf));
     343
     344        if (pResults[index].hr == S_OK)
     345            successCount++;
     346    }
     347
     348    /*
     349    * Release our temporary unknown pointer.
     350    */
     351    IUnknown_Release(pUnk);
     352
     353    if (successCount == 0)
     354        return E_NOINTERFACE;
     355
     356    if (successCount != cmq)
     357        return CO_S_NOTALLINTERFACES;
     358
     359    return S_OK;
     360}
     361
     362// ----------------------------------------------------------------------
     363// CoGetClassObject
     364// ----------------------------------------------------------------------
     365HRESULT WIN32API CoGetClassObject
     366   (REFCLSID            rclsid,
     367    DWORD               dwClsContext,
     368    LPVOID              pvReserved,
     369    REFIID              iid,
     370    LPVOID *            ppv)
     371{
     372    LPUNKNOWN           regClassObject;
     373    HRESULT             hres = E_UNEXPECTED;
     374
     375    char                dllName[MAX_PATH+1];
     376    LONG                dllNameLen = sizeof(dllName);
     377    HINSTANCE           hLibrary;
     378
     379    DllGetClassObjectFunc DllGetClassObject;
     380    oStringA            tCLSID(rclsid);
     381
     382#ifdef DEBUG
     383    oStringA            tIId(iid);
     384    dprintf(("OLE32: CoGetClassObject"));
     385    dprintf(("       CLSID:%s", (char *)tCLSID));
     386    dprintf(("       IID  :%s", (char *)tIId));
     387#endif
     388
     389    // First, try and see if we can't match the class ID with one of the
     390    // registered classes.
     391    if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, &regClassObject))
     392    {
     393        // Get the required interface from the retrieved pointer.
     394        hres = IUnknown_QueryInterface(regClassObject, iid, ppv);
     395
     396        // Since QI got another reference on the pointer, we want to release the
     397        // one we already have. If QI was unsuccessful, this will release the object. This
     398        // is good since we are not returning it in the "out" parameter.
     399        IUnknown_Release(regClassObject);
     400
     401        return hres;
     402    }
     403
     404    // out of process and remote servers not supported yet...
     405    if (dwClsContext & CLSCTX_LOCAL_SERVER)
     406    {
     407        dprintf(("OLE32: CoGetClassObject - CLSCTX_LOCAL_SERVER not supported!\n"));
     408        return E_ACCESSDENIED;
     409    }
     410
     411    if (dwClsContext & CLSCTX_REMOTE_SERVER)
     412    {
     413        dprintf(("OLE32: CoGetClassObject - CLSCTX_REMOTE_SERVER not supported!\n"));
     414        return E_ACCESSDENIED;
     415    }
     416
     417    // Get down to the biz..
     418    if (dwClsContext & (CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER))
     419    {
     420        HKEY    CLSIDkey;
     421        HKEY    key;
     422
     423        /* lookup CLSID in registry key HKCR/CLSID */
     424        hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &CLSIDkey);
     425        if (hres != ERROR_SUCCESS)
     426            return REGDB_E_READREGDB;
     427
     428        hres = RegOpenKeyExA(CLSIDkey, tCLSID, 0, KEY_QUERY_VALUE, &key);
     429        if (hres != ERROR_SUCCESS)
     430        {
     431            RegCloseKey(CLSIDkey);
     432            return REGDB_E_CLASSNOTREG;
     433        }
     434
     435        hres = RegQueryValueA(key, "InprocServer32", dllName, &dllNameLen);
     436        RegCloseKey(key);
     437        RegCloseKey(CLSIDkey);
     438        if (hres != ERROR_SUCCESS)
     439        {
     440            dprintf(("OLE32: CoGetClassObject - InprocServer32 not found in registry"));
     441            return REGDB_E_READREGDB;
     442        }
     443
     444        dprintf(("OLE32: CoGetClassObject - Registry reports InprocServer32 dll as %s\n", dllName));
     445
     446        /* open dll, call DllGetClassFactory */
     447        hLibrary = CoLoadLibrary(dllName, TRUE);
     448        if (hLibrary == 0)
     449        {
     450            dprintf(("OLE32: CoGetClassObject - couldn't load %s\n", dllName));
     451            return E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */
     452        }
     453
     454        DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject");
     455        if (!DllGetClassObject)
     456        {
     457            dprintf(("OLE32: CoGetClassObject - couldn't function DllGetClassObject in %s\n", dllName));
     458            /* not sure if this should be called here CoFreeLibrary(hLibrary);*/
     459            return E_ACCESSDENIED;
     460        }
     461
     462        // Ask the DLL for it's class object. (there was a note here about class
     463        // factories but this is good.
     464        return DllGetClassObject(rclsid, iid, ppv);
     465    }
     466    return hres;
     467}
     468
     469// ======================================================================
     470// Private functions.
     471// ======================================================================
     472
     473// ----------------------------------------------------------------------
     474// COM_GetRegisteredClassObject
     475// ----------------------------------------------------------------------
     476// This internal method is used to scan the registered class list to
     477// find a class object.
     478//
     479// Params:
     480//   rclsid        Class ID of the class to find.
     481//   dwClsContext  Class context to match.
     482//   ppv           [out] returns a pointer to the class object. Complying
     483//                 to normal COM usage, this method will increase the
     484//                 reference count on this object.
     485static HRESULT COM_GetRegisteredClassObject
     486   (REFCLSID            rclsid,
     487    DWORD               dwClsContext,
     488    LPUNKNOWN *         ppUnk)
     489{
     490    RegisteredClass* curClass;
     491
     492    oStringA            tCLSID(rclsid);
     493
     494    dprintf(("OLE32: COM_GetRegisteredClassObject"));
     495    dprintf(("       CLSID:%s", (char *)tCLSID));
     496
     497    // Sanity check
     498    if (ppUnk == 0)
     499        return E_POINTER;
     500
     501    // Iterate through the whole list and try to match the class ID.
     502    curClass = firstRegisteredClass;
     503
     504    while (curClass != 0)
     505    {
     506        // Check if we have a match on the class ID.
     507        if (IsEqualGUID(curClass->classIdentifier, rclsid))
     508        {
     509            // Since we don't do out-of process or DCOM just right away,
     510            // let's ignore the class context.
     511
     512            // We have a match, return the pointer to the class object.
     513            *ppUnk = curClass->classObject;
     514
     515            IUnknown_AddRef(curClass->classObject);
     516
     517            return S_OK;
     518        }
     519
     520    // Step to the next class in the list.
     521    curClass = curClass->nextClass;
     522    }
     523
     524    // If we get to here, we haven't found our class.
     525    return S_FALSE;
     526}
     527
     528// ----------------------------------------------------------------------
     529// COM_RevokeAllClasses
     530// ----------------------------------------------------------------------
     531// This method is called when the COM libraries are uninitialized to
     532// release all the references to the class objects registered with
     533// the library
     534static void COM_RevokeAllClasses()
     535{
     536    dprintf(("OLE32: COM_RevokeAllClasses"));
     537
     538    while (firstRegisteredClass != 0)
     539    {
     540        CoRevokeClassObject(firstRegisteredClass->dwCookie);
     541    }
     542}
     543
     544// ----------------------------------------------------------------------
     545// COM_ExternalLockAddRef
     546// ----------------------------------------------------------------------
     547// Method that increments the count for a IUnknown* in the linked
     548// list.  The item is inserted if not already in the list.
     549static void COM_ExternalLockAddRef(IUnknown * pUnk)
     550{
     551    dprintf(("OLE32: COM_ExternalLockAddRef"));
     552
     553    COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk);
     554
     555    /*
     556     * Add an external lock to the object. If it was already externally
     557     * locked, just increase the reference count. If it was not.
     558     * add the item to the list.
     559     */
     560    if ( externalLock == EL_NOT_FOUND )
     561        COM_ExternalLockInsert(pUnk);
     562    else
     563        externalLock->uRefCount++;
     564
     565    /*
     566     * Add an internal lock to the object
     567     */
     568    IUnknown_AddRef(pUnk);
     569}
     570
     571// ----------------------------------------------------------------------
     572// COM_ExternalLockRelease
     573// ----------------------------------------------------------------------
     574// Method that decrements the count for a IUnknown* in the linked
     575// list.  The item is removed from the list if its count end up at zero or if
     576// bRelAll is TRUE.
     577static void COM_ExternalLockRelease(IUnknown * pUnk, BOOL bRelAll)
     578{
     579    dprintf(("OLE32: COM_ExternalLockRelease"));
     580
     581    COM_ExternalLock * externalLock = COM_ExternalLockFind(pUnk);
     582
     583    if ( externalLock != EL_NOT_FOUND )
     584    {
     585        do
     586        {
     587            externalLock->uRefCount--;  /* release external locks      */
     588            IUnknown_Release(pUnk);     /* release local locks as well */
     589
     590            if ( bRelAll == FALSE )
     591                break;  /* perform single release */
     592
     593        } while ( externalLock->uRefCount > 0 ); 
     594
     595        if ( externalLock->uRefCount == 0 )  /* get rid of the list entry */
     596            COM_ExternalLockDelete(externalLock);
     597    }
     598}
     599
     600// ----------------------------------------------------------------------
     601// COM_ExternalLockFreeList
     602// ----------------------------------------------------------------------
     603// Method that frees the content of the list.
     604static void COM_ExternalLockFreeList()
     605{
     606    dprintf(("OLE32: COM_ExternalLockFreeList"));
     607
     608    COM_ExternalLock *head;
     609
     610    head = elList.head;                 /* grab it by the head             */
     611    while (head != EL_END_OF_LIST)
     612    {
     613        COM_ExternalLockDelete(head);     /* get rid of the head stuff       */
     614
     615        head = elList.head;               /* get the new head...             */
     616    }
     617}
     618
     619// ----------------------------------------------------------------------
     620// COM_ExternalLockDump
     621// ----------------------------------------------------------------------
     622// Method that dump the content of the list.
     623void COM_ExternalLockDump()
     624{
     625    dprintf(("OLE32: COM_ExternalLockDump"));
     626
     627    COM_ExternalLock *current = elList.head;
     628
     629    printf("External lock list:");
     630
     631    while ( current != EL_END_OF_LIST )
     632    {
     633        dprintf(("    %p with %lu references count.\n", current->pUnk, current->uRefCount));
     634
     635        /* Skip to the next item */
     636        current = current->next;
     637    }
     638}
     639
     640// ----------------------------------------------------------------------
     641// COM_ExternalLockFind
     642// ----------------------------------------------------------------------
     643// Find a IUnknown* in the linked list
     644static COM_ExternalLock * COM_ExternalLockFind(IUnknown *pUnk)
     645{
     646    dprintf(("OLE32: COM_ExternalLockFind"));
     647
     648    return COM_ExternalLockLocate(elList.head, pUnk);
     649}
     650
     651// ----------------------------------------------------------------------
     652// COM_ExternalLockLocate
     653// ----------------------------------------------------------------------
     654// Recursivity agent for IUnknownExternalLockList_Find
     655static COM_ExternalLock * COM_ExternalLockLocate( COM_ExternalLock * element, IUnknown * pUnk)
     656{
     657  if ( element == EL_END_OF_LIST ) 
     658    return EL_NOT_FOUND;
     659
     660  else if ( element->pUnk == pUnk )    /* We found it */
     661    return element;
     662
     663  else                                 /* Not the right guy, keep on looking */
     664    return COM_ExternalLockLocate( element->next, pUnk);
     665}
     666
     667// ----------------------------------------------------------------------
     668// COM_ExternalLockInsert
     669// ----------------------------------------------------------------------
     670// Insert a new IUnknown* to the linked list
     671static BOOL COM_ExternalLockInsert(IUnknown * pUnk)
     672{
     673    dprintf(("OLE32: COM_ExternalLockInsert"));
     674
     675    COM_ExternalLock *  newLock      = NULL;
     676    COM_ExternalLock *  previousHead = NULL;
     677
     678    // Allocate space for the new storage object
     679    newLock = (COM_ExternalLock *)HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));
     680
     681    if (newLock != NULL)
     682    {
     683        if ( elList.head == EL_END_OF_LIST )
     684            elList.head = newLock;    /* The list is empty */
     685        else
     686        {
     687            // insert does it at the head
     688            previousHead  = elList.head;
     689            elList.head = newLock;
     690        }
     691
     692        /*
     693         * Set new list item data member
     694         */
     695        newLock->pUnk      = pUnk;
     696        newLock->uRefCount = 1;
     697        newLock->next      = previousHead;
     698
     699        return TRUE;
     700    }
     701
     702    return FALSE;
     703}
     704
     705// ----------------------------------------------------------------------
     706// ExternalLockDelete
     707// ----------------------------------------------------------------------
     708// Method that removes an item from the linked list.
     709static void COM_ExternalLockDelete(COM_ExternalLock * itemList)
     710{
     711    dprintf(("OLE32: ExternalLockDelete"));
     712
     713    COM_ExternalLock *current = elList.head;
     714
     715    if ( current == itemList )
     716    {
     717        // this section handles the deletion of the first node
     718        elList.head = itemList->next;
     719        HeapFree( GetProcessHeap(), 0, itemList); 
     720    }
     721    else
     722    {
     723        do
     724        {
     725            if ( current->next == itemList )   /* We found the item to free  */
     726            {
     727                current->next = itemList->next;  /* readjust the list pointers */
     728
     729                HeapFree( GetProcessHeap(), 0, itemList); 
     730                break;
     731            }
     732
     733            /* Skip to the next item */
     734            current = current->next;
     735
     736        } while ( current != EL_END_OF_LIST );
     737    }
     738}
Note: See TracChangeset for help on using the changeset viewer.