Documentation for CLEANLOCALSTORAGE in OLE Automation

Robert Shearman rob at
Tue Apr 18 18:24:07 CDT 2006


I just thought I'd document the CLEANLOCALSTORAGE use in oleaut32 for 
anyone that wants to implement it, although I can't implement it now for 
obvious reasons.

First of all the background: the reason CLEANLOCALSTORAGE is needed is 
because the structures returned from various Get* functions in ITypeInfo 
and ITypeLib have pointers that have been allocated opaquely and have to 
be freed using the corresponding Release* function. AFAICS, the problem 
is not that the memory will not be freed (the RPC runtime should 
traverse the structure thoroughly and release all of the pointers with 
NdrOleFree), but that some of the memory may not need to be freed (and 
memory corruption could take place if it were).

So what should the various CLEANLOCALSTORAGE functions actually do?

CLEANLOCALSTORAGE_UserFree - nothing, as the marshaled DWORD does not 
need to be freed.
 o DWORD align the buffer.
 o Put the storage type into the buffer and increment it.
 o Call the relevent freer for the storage type, passing in the memory 
 o Release the interface in CLEANLOCALSTORAGE.
 o Set memory pointed to in CLEANLOCALSTORAGE to NULL (so that the 
memory isn't freed again by the RPC runtime).
 o DWORD align the buffer.
 o Take the storage type from the buffer, increment the buffer and put 
the storage type into CLEANLOCALSTORAGE.
 o DWORD align the size and add sizeof(DWORD) to it.

What should each of the Get* functions do that have a corresponding 
Release* function?

 o Put a type into CLEANLOCALSTORAGE (see below for what number this 
should be).
 o AddRef the interface to call the Release* function on and put it into 
 o Put a pointer to a pointer to the structure that is being allocated 

What type number corresponds to what function?
ITypeComp_Bind - 0x66 or 0x76, depending on what is returned.
ITypeInfo_GetTypeAttr - 0x74
ITypeInfo_GetFuncDesc - 0x66
ITypeInfo_GetVarDesc - 0x76
ITypeLib_GetLibAttr - 0x6c

Note: it may be necessary to zero out certain fields of the various 
structures in the stub functions so that bad pointers don't get marshalled.


P.S. Take care to deep free all memory when releasing the pointers on 
the proxy side when implementing the Release*_Proxy functions.

Rob Shearman

More information about the wine-devel mailing list