Changeset 5602 for trunk/src/ole32/ole32.cpp
- Timestamp:
- Apr 26, 2001, 9:33:15 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ole32/ole32.cpp
r3177 r5602 1 /* $Id: ole32.cpp,v 1.1 4 2000-03-21 00:37:46 davidrExp $ */1 /* $Id: ole32.cpp,v 1.15 2001-04-26 19:32:49 sandervl Exp $ */ 2 2 /* 3 3 * … … 21 21 #include "ole32.h" 22 22 23 #include "oString.h"24 #include "moniker.h" // RunningObjectTableImpl_***25 #include "filemoniker.h" // FileMonikerImpl_***26 27 // ======================================================================28 // Local Data29 // ======================================================================30 typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);31 32 /*33 * This linked list contains the list of registered class objects. These34 * are mostly used to register the factories for out-of-proc servers of OLE35 * objects.36 */37 typedef struct tagRegisteredClass38 {39 CLSID classIdentifier;40 LPUNKNOWN classObject;41 DWORD runContext;42 DWORD connectFlags;43 DWORD dwCookie;44 struct tagRegisteredClass* nextClass;45 } RegisteredClass;46 47 static RegisteredClass* firstRegisteredClass = NULL;48 49 /*50 * COM External Lock structures and methods declaration51 *52 * This api provides a linked list to managed external references to53 * COM objects.54 *55 */56 57 #define EL_END_OF_LIST 058 #define EL_NOT_FOUND 059 60 /*61 * Declaration of the static structure that manage the62 * external lock to COM objects.63 */64 typedef struct COM_ExternalLock COM_ExternalLock;65 typedef struct COM_ExternalLockList COM_ExternalLockList;66 67 struct COM_ExternalLock68 {69 IUnknown *pUnk; /* IUnknown referenced */70 ULONG uRefCount; /* external lock counter to IUnknown object*/71 COM_ExternalLock *next; /* Pointer to next element in list */72 };73 74 struct COM_ExternalLockList75 {76 COM_ExternalLock *head; /* head of list */77 };78 79 /*80 * Declaration and initialization of the static structure that manages81 * the external lock to COM objects.82 */83 static COM_ExternalLockList elList = { EL_END_OF_LIST };84 85 /*86 * Com Library reference count...87 *88 * Used to control loading / unloading of Library resources,89 * Runnng object table, DLL's etc...90 */91 static LONG COM_ref = 0;92 93 // ======================================================================94 // Prototypes.95 // ======================================================================96 static HRESULT COM_GetRegisteredClassObject(97 REFCLSID rclsid,98 DWORD dwClsContext,99 LPUNKNOWN * ppUnk);100 101 static void COM_RevokeAllClasses();102 103 static void COM_ExternalLockFreeList();104 105 static void COM_ExternalLockAddRef(106 IUnknown * pUnk);107 108 static void COM_ExternalLockRelease(109 IUnknown * pUnk,110 BOOL bRelAll);111 112 static BOOL COM_ExternalLockInsert(113 IUnknown * pUnk);114 115 static void COM_ExternalLockDelete(116 COM_ExternalLock * element);117 118 static COM_ExternalLock * COM_ExternalLockFind(119 IUnknown * pUnk);120 121 static COM_ExternalLock * COM_ExternalLockLocate(122 COM_ExternalLock * element,123 IUnknown * pUnk);124 125 // ======================================================================126 // Public API's127 // ======================================================================128 129 // ----------------------------------------------------------------------130 // CoBuildVersion()131 // ----------------------------------------------------------------------132 DWORD WIN32API CoBuildVersion()133 {134 dprintf(("OLE32.CoBuildVersion"));135 return (rmm << 16) + rup;136 }137 138 23 // ---------------------------------------------------------------------- 139 24 // CoDosDateTimeToFileTime … … 150 35 // CoDosDateTimeToFileTime 151 36 // ---------------------------------------------------------------------- 152 HRESULT WIN32API CoFileTimeNow(FILETIME *lpFileTime)153 {154 SYSTEMTIME systime;155 156 dprintf(("OLE32: CoFileTimeNow"));157 158 GetSystemTime(&systime);159 return SystemTimeToFileTime(&systime, lpFileTime);160 }161 162 // ----------------------------------------------------------------------163 // CoDosDateTimeToFileTime164 // ----------------------------------------------------------------------165 37 BOOL WIN32API CoFileTimeToDosDateTime(FILETIME *lpFileTime, LPWORD lpDosDate, 166 38 LPWORD lpDosTime) … … 170 42 return FileTimeToDosDateTime(lpFileTime, lpDosDate, lpDosTime); 171 43 } 172 173 // ----------------------------------------------------------------------174 // CoInitialize()175 // ----------------------------------------------------------------------176 HRESULT WIN32API CoInitialize(LPVOID lpReserved)177 {178 dprintf(("OLE32: CoInitialize\n"));179 180 return CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);181 }182 183 // ----------------------------------------------------------------------184 // CoInitializeEx()185 // ----------------------------------------------------------------------186 HRESULT WIN32API CoInitializeEx(187 LPVOID lpReserved, // [in] pointer to win32 malloc interface188 DWORD dwCoInit) // [in] A value from COINIT specifies the thread189 {190 HRESULT hr;191 192 dprintf(("OLE32: CoInitializeEx(%p, %lx)\n", lpReserved, dwCoInit));193 194 if (lpReserved != NULL)195 {196 dprintf(("Warning: Bad parameter %p, must be an old Windows Application", lpReserved));197 }198 199 /*200 * Check for unsupported features.201 */202 if (dwCoInit != COINIT_APARTMENTTHREADED)203 {204 dprintf(("Warning: Unsupported flag %lx", dwCoInit));205 /* Hope for the best and continue anyway */206 }207 208 /*209 * Initialise the Running Object Table210 */211 hr = S_FALSE;212 if (++COM_ref == 1)213 {214 hr = RunningObjectTableImpl_Initialize();215 if (hr != S_OK)216 --COM_ref;217 }218 219 return hr;220 }221 222 // ----------------------------------------------------------------------223 // CoUninitialize()224 // ----------------------------------------------------------------------225 void WIN32API CoUninitialize(void)226 {227 dprintf(("OLE32: CoUninitialize"));228 229 if (--COM_ref == 0)230 {231 dprintf(("OLE32: Releasing COM libraries"));232 233 RunningObjectTableImpl_UnInitialize();234 235 COM_RevokeAllClasses();236 237 CoFreeAllLibraries();238 239 COM_ExternalLockFreeList();240 }241 }242 243 // ----------------------------------------------------------------------244 // CoCreateInstance245 // ----------------------------------------------------------------------246 HRESULT WIN32API CoCreateInstance247 (REFCLSID rclsid,248 LPUNKNOWN pUnkOuter,249 DWORD dwClsContext,250 REFIID iid,251 LPVOID * ppv)252 {253 HRESULT hres;254 LPCLASSFACTORY lpclf = 0;255 256 oStringA tCLSID(rclsid);257 oStringA tIId(iid);258 259 dprintf(("OLE32: CoCreateInstance"));260 dprintf((" CLSID:%s", (char *)tCLSID));261 dprintf((" IID :%s", (char *)tIId));262 263 // Sanity check264 if (ppv == 0)265 return E_POINTER;266 267 *ppv = 0;268 269 // Get a class factory to construct the object we want.270 hres = CoGetClassObject(rclsid, dwClsContext, NULL, &IID_IClassFactory, (LPVOID *)&lpclf);271 272 if (FAILED(hres))273 return hres;274 275 // Create the object and don't forget to release the factory276 hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv);277 IClassFactory_Release(lpclf);278 279 return hres;280 }281 282 // ----------------------------------------------------------------------283 // CoCreateInstanceEx284 // ----------------------------------------------------------------------285 HRESULT WIN32API CoCreateInstanceEx286 (REFCLSID rclsid,287 LPUNKNOWN pUnkOuter,288 DWORD dwClsContext,289 COSERVERINFO * pServerInfo,290 ULONG cmq,291 MULTI_QI * pResults)292 {293 IUnknown * pUnk = NULL;294 HRESULT hr;295 ULONG index;296 int successCount = 0;297 298 oStringA tCLSID(rclsid);299 300 dprintf(("OLE32: CoCreateInstanceEx"));301 dprintf((" CLSID:%s", (char *)tCLSID));302 303 // Sanity check304 if ( (cmq == 0) || (pResults == NULL))305 return E_INVALIDARG;306 307 if (pServerInfo != NULL)308 dprintf(("OLE32: CoCreateInstanceEx - pServerInfo not supported!"));309 310 // Initialize all the "out" parameters.311 for (index = 0; index < cmq; index++)312 {313 pResults[index].pItf = NULL;314 pResults[index].hr = E_NOINTERFACE;315 }316 317 /*318 * Get the object and get it's IUnknown pointer.319 */320 hr = CoCreateInstance(rclsid, pUnkOuter, dwClsContext, &IID_IUnknown, (VOID**)&pUnk);321 322 if (hr)323 return hr;324 325 /*326 * Then, query for all the interfaces requested.327 */328 for (index = 0; index < cmq; index++)329 {330 pResults[index].hr = IUnknown_QueryInterface(pUnk, pResults[index].pIID, (VOID**)&(pResults[index].pItf));331 332 if (pResults[index].hr == S_OK)333 successCount++;334 }335 336 /*337 * Release our temporary unknown pointer.338 */339 IUnknown_Release(pUnk);340 341 if (successCount == 0)342 return E_NOINTERFACE;343 344 if (successCount != cmq)345 return CO_S_NOTALLINTERFACES;346 347 return S_OK;348 }349 350 // ----------------------------------------------------------------------351 // CoGetClassObject352 // ----------------------------------------------------------------------353 HRESULT WIN32API CoGetClassObject354 (REFCLSID rclsid,355 DWORD dwClsContext,356 LPVOID pvReserved,357 REFIID iid,358 LPVOID * ppv)359 {360 LPUNKNOWN regClassObject;361 HRESULT hres = E_UNEXPECTED;362 363 char dllName[MAX_PATH+1];364 LONG dllNameLen = sizeof(dllName);365 HINSTANCE hLibrary;366 367 DllGetClassObjectFunc DllGetClassObject;368 oStringA tCLSID(rclsid);369 370 #ifdef DEBUG371 oStringA tIId(iid);372 dprintf(("OLE32: CoGetClassObject"));373 dprintf((" CLSID:%s", (char *)tCLSID));374 dprintf((" IID :%s", (char *)tIId));375 #endif376 377 // First, try and see if we can't match the class ID with one of the378 // registered classes.379 if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, ®ClassObject))380 {381 // Get the required interface from the retrieved pointer.382 hres = IUnknown_QueryInterface(regClassObject, iid, ppv);383 384 // Since QI got another reference on the pointer, we want to release the385 // one we already have. If QI was unsuccessful, this will release the object. This386 // is good since we are not returning it in the "out" parameter.387 IUnknown_Release(regClassObject);388 389 return hres;390 }391 392 // out of process and remote servers not supported yet...393 if (dwClsContext & CLSCTX_LOCAL_SERVER)394 {395 dprintf(("OLE32: CoGetClassObject - CLSCTX_LOCAL_SERVER not supported!\n"));396 // return E_ACCESSDENIED;397 dwClsContext |= CLSCTX_INPROC_SERVER; // Kludge as VB uses CLSCTX_LOCAL_SERVER398 }399 400 if (dwClsContext & CLSCTX_REMOTE_SERVER)401 {402 dprintf(("OLE32: CoGetClassObject - CLSCTX_REMOTE_SERVER not supported!\n"));403 return E_ACCESSDENIED;404 }405 406 // Get down to the biz..407 if (dwClsContext & (CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER))408 {409 HKEY CLSIDkey;410 HKEY key;411 412 /* lookup CLSID in registry key HKCR/CLSID */413 hres = RegOpenKeyExA(HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &CLSIDkey);414 if (hres != ERROR_SUCCESS)415 return REGDB_E_READREGDB;416 417 hres = RegOpenKeyExA(CLSIDkey, tCLSID, 0, KEY_QUERY_VALUE, &key);418 if (hres != ERROR_SUCCESS)419 {420 RegCloseKey(CLSIDkey);421 return REGDB_E_CLASSNOTREG;422 }423 424 hres = RegQueryValueA(key, "InprocServer32", dllName, &dllNameLen);425 RegCloseKey(key);426 RegCloseKey(CLSIDkey);427 if (hres != ERROR_SUCCESS)428 {429 dprintf(("OLE32: CoGetClassObject - InprocServer32 not found in registry"));430 return REGDB_E_READREGDB;431 }432 433 dprintf(("OLE32: CoGetClassObject - Registry reports InprocServer32 dll as %s\n", dllName));434 435 /* open dll, call DllGetClassFactory */436 hLibrary = CoLoadLibrary(dllName, TRUE);437 if (hLibrary == 0)438 {439 dprintf(("OLE32: CoGetClassObject - couldn't load %s\n", dllName));440 return E_ACCESSDENIED; /* or should this be CO_E_DLLNOTFOUND? */441 }442 443 DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject");444 if (!DllGetClassObject)445 {446 dprintf(("OLE32: CoGetClassObject - couldn't function DllGetClassObject in %s\n", dllName));447 /* not sure if this should be called here CoFreeLibrary(hLibrary);*/448 return E_ACCESSDENIED;449 }450 451 // Ask the DLL for it's class object. (there was a note here about class452 // factories but this is good.453 return DllGetClassObject(rclsid, iid, ppv);454 }455 return hres;456 }457 458 // ----------------------------------------------------------------------459 // CoLockObjectExternal460 // ----------------------------------------------------------------------461 HRESULT WIN32API CoLockObjectExternal(IUnknown *pUnk, BOOL fLock, BOOL fLastUnlockReleases)462 {463 dprintf(("OLE32: CoLockObjectExternal"));464 465 if (fLock)466 {467 /*468 * Increment the external lock coutner, COM_ExternalLockAddRef also469 * increment the object's internal lock counter.470 */471 COM_ExternalLockAddRef( pUnk);472 }473 else474 {475 /*476 * Decrement the external lock coutner, COM_ExternalLockRelease also477 * decrement the object's internal lock counter.478 */479 COM_ExternalLockRelease( pUnk, fLastUnlockReleases);480 }481 482 return S_OK;483 }484 485 // ----------------------------------------------------------------------486 // CoRegisterClassObject487 // ----------------------------------------------------------------------488 HRESULT WIN32API CoRegisterClassObject(489 REFCLSID rclsid,490 LPUNKNOWN pUnk,491 DWORD dwClsContext, // Context in which to run the executable492 DWORD flags, // how connections are made493 LPDWORD lpdwRegister)494 {495 RegisteredClass * newClass;496 LPUNKNOWN foundObject;497 HRESULT hr;498 oStringA tClsid(rclsid);499 500 dprintf(("OLE32: CoRegisterClassObject(%s)", (char *)tClsid));501 502 // Perform a sanity check on the parameters503 if ((lpdwRegister == 0) || (pUnk == 0))504 return E_INVALIDARG;505 506 // Initialize the cookie (out parameter)507 *lpdwRegister = 0;508 509 // First, check if the class is already registered.510 // If it is, this should cause an error.511 hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);512 if (hr == S_OK)513 {514 // The COM_GetRegisteredClassObject increased the reference count on the515 // object so it has to be released.516 IUnknown_Release(foundObject);517 518 return CO_E_OBJISREG;519 }520 521 // If it is not registered, we must create a new entry for this class and522 // append it to the registered class list.523 // We use the address of the chain node as the cookie since we are sure it's524 // unique.525 newClass = (RegisteredClass *)HeapAlloc(GetProcessHeap(), 0, sizeof(RegisteredClass));526 527 // Initialize the node.528 newClass->classIdentifier = *rclsid;529 newClass->runContext = dwClsContext;530 newClass->connectFlags = flags;531 newClass->dwCookie = (DWORD)newClass;532 newClass->nextClass = firstRegisteredClass;533 534 // Since we're making a copy of the object pointer, we have to increase it's535 // reference count.536 newClass->classObject = pUnk;537 IUnknown_AddRef(newClass->classObject);538 539 firstRegisteredClass = newClass;540 541 // Assign the out parameter (cookie)542 *lpdwRegister = newClass->dwCookie;543 544 return S_OK;545 }546 547 // ----------------------------------------------------------------------548 // CoRevokeClassObject549 //550 // This method will remove a class object from the class registry551 // ----------------------------------------------------------------------552 HRESULT WIN32API CoRevokeClassObject(DWORD dwRegister)553 {554 RegisteredClass * * prevClassLink;555 RegisteredClass * curClass;556 557 dprintf(("OLE32: CoRevokeClassObject"));558 559 // Iterate through the whole list and try to match the cookie.560 curClass = firstRegisteredClass;561 prevClassLink = &firstRegisteredClass;562 563 while (curClass != 0)564 {565 // Check if we have a match on the cookie.566 if (curClass->dwCookie == dwRegister)567 {568 // Remove the class from the chain.569 *prevClassLink = curClass->nextClass;570 571 // Release the reference to the class object.572 IUnknown_Release(curClass->classObject);573 574 // Free the memory used by the chain node.575 HeapFree(GetProcessHeap(), 0, curClass);576 577 return S_OK;578 }579 580 // Step to the next class in the list.581 prevClassLink = &(curClass->nextClass);582 curClass = curClass->nextClass;583 }584 585 return E_INVALIDARG;586 }587 588 // ----------------------------------------------------------------------589 // GetClassFile590 //591 // This function supplies the CLSID associated with the given filename.592 // ----------------------------------------------------------------------593 HRESULT WIN32API GetClassFile(LPOLESTR filePathName, CLSID *pclsid)594 {595 IStorage * pstg = 0;596 HRESULT res;597 int nbElm = 0;598 int length = 0;599 int i = 0;600 LONG sizeProgId = 20;601 LPOLESTR * pathDec = 0;602 LPOLESTR absFile = 0;603 LPOLESTR progId = 0;604 WCHAR extention[100] = {0};605 606 dprintf(("OLE32: GetClassFile"));607 608 // if the file contain a storage object the return the CLSID609 // writen by IStorage_SetClass method610 611 if((StgIsStorageFile(filePathName)) == S_OK)612 {613 res = StgOpenStorage(filePathName, NULL, STGM_READ | STGM_SHARE_DENY_WRITE, NULL, 0, &pstg);614 615 if (SUCCEEDED(res))616 res = ReadClassStg(pstg, pclsid);617 618 IStorage_Release(pstg);619 620 return res;621 }622 623 /* if the obove strategies fail then search for the extension key in the registry */624 625 /* get the last element (absolute file) in the path name */626 nbElm = FileMonikerImpl_DecomposePath(filePathName, &pathDec);627 absFile = pathDec[nbElm-1];628 629 /* failed if the path represente a directory and not an absolute file name*/630 if (lstrcmpW(absFile, (LPOLESTR)"\\"))631 return MK_E_INVALIDEXTENSION;632 633 /* get the extension of the file */634 length = lstrlenW(absFile);635 for(i = length-1; ( (i >= 0) && (extention[i] = absFile[i]) ); i--);636 637 /* get the progId associated to the extension */638 progId = (WCHAR *)CoTaskMemAlloc(sizeProgId);639 640 res = RegQueryValueW(HKEY_CLASSES_ROOT, extention, progId, &sizeProgId);641 642 if (res == ERROR_MORE_DATA)643 {644 CoTaskMemRealloc(progId,sizeProgId);645 646 res = RegQueryValueW(HKEY_CLASSES_ROOT, extention, progId, &sizeProgId);647 }648 if (res == ERROR_SUCCESS)649 /* return the clsid associated to the progId */650 res = CLSIDFromProgID(progId, pclsid);651 652 for(i = 0; pathDec[i] != NULL; i++)653 CoTaskMemFree(pathDec[i]);654 655 CoTaskMemFree(pathDec);656 657 CoTaskMemFree(progId);658 659 if (res == ERROR_SUCCESS)660 return res;661 662 return MK_E_INVALIDEXTENSION;663 }664 // ======================================================================665 // Private functions.666 // ======================================================================667 668 // ----------------------------------------------------------------------669 // COM_GetRegisteredClassObject670 // ----------------------------------------------------------------------671 // This internal method is used to scan the registered class list to672 // find a class object.673 //674 // Params:675 // rclsid Class ID of the class to find.676 // dwClsContext Class context to match.677 // ppv [out] returns a pointer to the class object. Complying678 // to normal COM usage, this method will increase the679 // reference count on this object.680 static HRESULT COM_GetRegisteredClassObject681 (REFCLSID rclsid,682 DWORD dwClsContext,683 LPUNKNOWN * ppUnk)684 {685 RegisteredClass* curClass;686 687 oStringA tCLSID(rclsid);688 689 dprintf(("OLE32: COM_GetRegisteredClassObject"));690 dprintf((" CLSID:%s", (char *)tCLSID));691 692 // Sanity check693 if (ppUnk == 0)694 return E_POINTER;695 696 // Iterate through the whole list and try to match the class ID.697 curClass = firstRegisteredClass;698 699 while (curClass != 0)700 {701 // Check if we have a match on the class ID.702 if (IsEqualGUID(&curClass->classIdentifier, rclsid))703 {704 // Since we don't do out-of process or DCOM just right away,705 // let's ignore the class context.706 707 // We have a match, return the pointer to the class object.708 *ppUnk = curClass->classObject;709 710 IUnknown_AddRef(curClass->classObject);711 712 return S_OK;713 }714 715 // Step to the next class in the list.716 curClass = curClass->nextClass;717 }718 719 // If we get to here, we haven't found our class.720 return S_FALSE;721 }722 723 // ----------------------------------------------------------------------724 // COM_RevokeAllClasses725 // ----------------------------------------------------------------------726 // This method is called when the COM libraries are uninitialized to727 // release all the references to the class objects registered with728 // the library729 static void COM_RevokeAllClasses()730 {731 dprintf(("OLE32: COM_RevokeAllClasses"));732 733 while (firstRegisteredClass != 0)734 {735 CoRevokeClassObject(firstRegisteredClass->dwCookie);736 }737 }738 739 // ----------------------------------------------------------------------740 // COM_ExternalLockAddRef741 // ----------------------------------------------------------------------742 // Method that increments the count for a IUnknown* in the linked743 // list. The item is inserted if not already in the list.744 static void COM_ExternalLockAddRef(IUnknown * pUnk)745 {746 dprintf(("OLE32: COM_ExternalLockAddRef"));747 748 COM_ExternalLock *externalLock = COM_ExternalLockFind(pUnk);749 750 /*751 * Add an external lock to the object. If it was already externally752 * locked, just increase the reference count. If it was not.753 * add the item to the list.754 */755 if ( externalLock == EL_NOT_FOUND )756 COM_ExternalLockInsert(pUnk);757 else758 externalLock->uRefCount++;759 760 /*761 * Add an internal lock to the object762 */763 IUnknown_AddRef(pUnk);764 }765 766 // ----------------------------------------------------------------------767 // COM_ExternalLockRelease768 // ----------------------------------------------------------------------769 // Method that decrements the count for a IUnknown* in the linked770 // list. The item is removed from the list if its count end up at zero or if771 // bRelAll is TRUE.772 static void COM_ExternalLockRelease(IUnknown * pUnk, BOOL bRelAll)773 {774 dprintf(("OLE32: COM_ExternalLockRelease"));775 776 COM_ExternalLock * externalLock = COM_ExternalLockFind(pUnk);777 778 if ( externalLock != EL_NOT_FOUND )779 {780 do781 {782 externalLock->uRefCount--; /* release external locks */783 IUnknown_Release(pUnk); /* release local locks as well */784 785 if ( bRelAll == FALSE )786 break; /* perform single release */787 788 } while ( externalLock->uRefCount > 0 );789 790 if ( externalLock->uRefCount == 0 ) /* get rid of the list entry */791 COM_ExternalLockDelete(externalLock);792 }793 }794 795 // ----------------------------------------------------------------------796 // COM_ExternalLockFreeList797 // ----------------------------------------------------------------------798 // Method that frees the content of the list.799 static void COM_ExternalLockFreeList()800 {801 dprintf(("OLE32: COM_ExternalLockFreeList"));802 803 COM_ExternalLock *head;804 805 head = elList.head; /* grab it by the head */806 while (head != EL_END_OF_LIST)807 {808 COM_ExternalLockDelete(head); /* get rid of the head stuff */809 810 head = elList.head; /* get the new head... */811 }812 }813 814 // ----------------------------------------------------------------------815 // COM_ExternalLockDump816 // ----------------------------------------------------------------------817 // Method that dump the content of the list.818 void COM_ExternalLockDump()819 {820 dprintf(("OLE32: COM_ExternalLockDump"));821 822 COM_ExternalLock *current = elList.head;823 824 printf("External lock list:");825 826 while ( current != EL_END_OF_LIST )827 {828 dprintf((" %p with %lu references count.\n", current->pUnk, current->uRefCount));829 830 /* Skip to the next item */831 current = current->next;832 }833 }834 835 // ----------------------------------------------------------------------836 // COM_ExternalLockFind837 // ----------------------------------------------------------------------838 // Find a IUnknown* in the linked list839 static COM_ExternalLock * COM_ExternalLockFind(IUnknown *pUnk)840 {841 dprintf(("OLE32: COM_ExternalLockFind"));842 843 return COM_ExternalLockLocate(elList.head, pUnk);844 }845 846 // ----------------------------------------------------------------------847 // COM_ExternalLockLocate848 // ----------------------------------------------------------------------849 // Recursivity agent for IUnknownExternalLockList_Find850 static COM_ExternalLock * COM_ExternalLockLocate( COM_ExternalLock * element, IUnknown * pUnk)851 {852 if ( element == EL_END_OF_LIST )853 return EL_NOT_FOUND;854 855 else if ( element->pUnk == pUnk ) /* We found it */856 return element;857 858 else /* Not the right guy, keep on looking */859 return COM_ExternalLockLocate( element->next, pUnk);860 }861 862 // ----------------------------------------------------------------------863 // COM_ExternalLockInsert864 // ----------------------------------------------------------------------865 // Insert a new IUnknown* to the linked list866 static BOOL COM_ExternalLockInsert(IUnknown * pUnk)867 {868 dprintf(("OLE32: COM_ExternalLockInsert"));869 870 COM_ExternalLock * newLock = NULL;871 COM_ExternalLock * previousHead = NULL;872 873 // Allocate space for the new storage object874 newLock = (COM_ExternalLock *)HeapAlloc(GetProcessHeap(), 0, sizeof(COM_ExternalLock));875 876 if (newLock != NULL)877 {878 if ( elList.head == EL_END_OF_LIST )879 elList.head = newLock; /* The list is empty */880 else881 {882 // insert does it at the head883 previousHead = elList.head;884 elList.head = newLock;885 }886 887 /*888 * Set new list item data member889 */890 newLock->pUnk = pUnk;891 newLock->uRefCount = 1;892 newLock->next = previousHead;893 894 return TRUE;895 }896 897 return FALSE;898 }899 900 // ----------------------------------------------------------------------901 // ExternalLockDelete902 // ----------------------------------------------------------------------903 // Method that removes an item from the linked list.904 static void COM_ExternalLockDelete(COM_ExternalLock * itemList)905 {906 dprintf(("OLE32: ExternalLockDelete"));907 908 COM_ExternalLock *current = elList.head;909 910 if ( current == itemList )911 {912 // this section handles the deletion of the first node913 elList.head = itemList->next;914 HeapFree( GetProcessHeap(), 0, itemList);915 }916 else917 {918 do919 {920 if ( current->next == itemList ) /* We found the item to free */921 {922 current->next = itemList->next; /* readjust the list pointers */923 924 HeapFree( GetProcessHeap(), 0, itemList);925 break;926 }927 928 /* Skip to the next item */929 current = current->next;930 931 } while ( current != EL_END_OF_LIST );932 }933 }
Note:
See TracChangeset
for help on using the changeset viewer.