Commit 67d1c088 authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

Document BSTR functions, add SetOANoCache().

parent 821b228c
...@@ -43,13 +43,51 @@ extern const GUID CLSID_PSOAInterface; ...@@ -43,13 +43,51 @@ extern const GUID CLSID_PSOAInterface;
/* IDispatch marshaler */ /* IDispatch marshaler */
extern const GUID CLSID_PSDispatch; extern const GUID CLSID_PSDispatch;
static BOOL BSTR_bCache = TRUE; /* Cache allocations to minimise alloc calls? */
/******************************************************************************
* BSTR {OLEAUT32}
*
* NOTES
* BSTR is a simple typedef for a wide-character string used as the principle
* string type in ole automation. When encapsulated in a Variant type they are
* automatically copied and destroyed as the variant is processed.
*
* The low level BSTR Api allows manipulation of these strings and is used by
* higher level Api calls to manage the strings transparently to the caller.
*
* Internally the BSTR type is allocated with space for a DWORD byte count before
* the string data begins. This is undocumented and non-system code should not
* access the count directly. Use SysStringLen() or SysStringByteLen()
* instead. Note that the byte count does not include the terminating NUL.
*
* To create a new BSTR, use SysAllocString(), SysAllocStringLen() or
* SysAllocStringByteLen(). To change the size of an existing BSTR, use SysReAllocString()
* or SysReAllocStringLen(). Finally to destroy a string use SysFreeString().
*
* BSTR's are cached by Ole Automation by default. To override this behaviour
* either set the environment variable 'OANOCACHE', or call SetOaNoCache().
*
* SEE ALSO
* 'Inside OLE, second edition' by Kraig Brockshmidt.
*/
/****************************************************************************** /******************************************************************************
* SysStringLen [OLEAUT32.7] * SysStringLen [OLEAUT32.7]
* *
* The Windows documentation states that the length returned by this function * Get the allocated length of a BSTR in wide characters.
* is not necessarely the same as the length returned by the _lstrlenW method. *
* It is the same number that was passed in as the "len" parameter if the * PARAMS
* string was allocated with a SysAllocStringLen method call. * str [I] BSTR to find the length of
*
* RETURNS
* The allocated length of str, or 0 if str is NULL.
*
* NOTES
* See BSTR.
* The returned length may be different from the length of the string as
* calculated by lstrlenW(), since it returns the length that was used to
* allocate the string by SysAllocStringLen().
*/ */
int WINAPI SysStringLen(BSTR str) int WINAPI SysStringLen(BSTR str)
{ {
...@@ -70,10 +108,16 @@ int WINAPI SysStringLen(BSTR str) ...@@ -70,10 +108,16 @@ int WINAPI SysStringLen(BSTR str)
/****************************************************************************** /******************************************************************************
* SysStringByteLen [OLEAUT32.149] * SysStringByteLen [OLEAUT32.149]
* *
* The Windows documentation states that the length returned by this function * Get the allocated length of a BSTR in bytes.
* is not necessarely the same as the length returned by the _lstrlenW method. *
* It is the same number that was passed in as the "len" parameter if the * PARAMS
* string was allocated with a SysAllocStringLen method call. * str [I] BSTR to find the length of
*
* RETURNS
* The allocated length of str, or 0 if str is NULL.
*
* NOTES
* See SysStringLen(), BSTR().
*/ */
int WINAPI SysStringByteLen(BSTR str) int WINAPI SysStringByteLen(BSTR str)
{ {
...@@ -94,34 +138,57 @@ int WINAPI SysStringByteLen(BSTR str) ...@@ -94,34 +138,57 @@ int WINAPI SysStringByteLen(BSTR str)
/****************************************************************************** /******************************************************************************
* SysAllocString [OLEAUT32.2] * SysAllocString [OLEAUT32.2]
* *
* MSDN (October 2001) states that this returns a NULL value if the argument * Create a BSTR from an OLESTR.
* is a zero-length string. This does not appear to be true; certainly it *
* returns a value under Win98 (Oleaut32.dll Ver 2.40.4515.0) * PARAMS
* str [I] Source to create BSTR from
*
* RETURNS
* Success: A BSTR allocated with SysAllocStringLen().
* Failure: NULL, if oleStr is NULL.
*
* NOTES
* See BSTR.
* MSDN (October 2001) incorrectly states that NULL is returned if oleStr has
* a length of 0. Native Win32 and this implementation both return a valid
* empty BSTR in this case.
*/ */
BSTR WINAPI SysAllocString(LPCOLESTR in) BSTR WINAPI SysAllocString(LPCOLESTR str)
{ {
if (!in) return 0; if (!str) return 0;
/* Delegate this to the SysAllocStringLen32 method. */ /* Delegate this to the SysAllocStringLen32 method. */
return SysAllocStringLen(in, lstrlenW(in)); return SysAllocStringLen(str, lstrlenW(str));
} }
/****************************************************************************** /******************************************************************************
* SysFreeString [OLEAUT32.6] * SysFreeString [OLEAUT32.6]
*
* Free a BSTR.
*
* PARAMS
* str [I] BSTR to free.
*
* RETURNS
* Nothing.
*
* NOTES
* See BSTR.
* str may be NULL, in which case this function does nothing.
*/ */
void WINAPI SysFreeString(BSTR in) void WINAPI SysFreeString(BSTR str)
{ {
DWORD* bufferPointer; DWORD* bufferPointer;
/* NULL is a valid parameter */ /* NULL is a valid parameter */
if(!in) return; if(!str) return;
/* /*
* We have to be careful when we free a BSTR pointer, it points to * We have to be careful when we free a BSTR pointer, it points to
* the beginning of the string but it skips the byte count contained * the beginning of the string but it skips the byte count contained
* before the string. * before the string.
*/ */
bufferPointer = (DWORD*)in; bufferPointer = (DWORD*)str;
bufferPointer--; bufferPointer--;
...@@ -134,14 +201,20 @@ void WINAPI SysFreeString(BSTR in) ...@@ -134,14 +201,20 @@ void WINAPI SysFreeString(BSTR in)
/****************************************************************************** /******************************************************************************
* SysAllocStringLen [OLEAUT32.4] * SysAllocStringLen [OLEAUT32.4]
* *
* In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation * Create a BSTR from an OLESTR of a given wide character length.
* section, he describes the DWORD value placed *before* the BSTR data type. *
* he describes it as a "DWORD count of characters". By experimenting with * PARAMS
* a windows application, this count seems to be a DWORD count of bytes in * str [I] Source to create BSTR from
* the string. Meaning that the count is double the number of wide * len [I] Length of oleStr in wide characters
* characters in the string. *
* RETURNS
* Success: A newly allocated BSTR from SysAllocStringByteLen()
* Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
*
* NOTES
* See BSTR(), SysAllocStringByteLen().
*/ */
BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len) BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
{ {
DWORD bufferSize; DWORD bufferSize;
DWORD* newBuffer; DWORD* newBuffer;
...@@ -183,8 +256,8 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len) ...@@ -183,8 +256,8 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
* Since it is valid to pass a NULL pointer here, we'll initialize the * Since it is valid to pass a NULL pointer here, we'll initialize the
* buffer to nul if it is the case. * buffer to nul if it is the case.
*/ */
if (in != 0) if (str != 0)
memcpy(newBuffer, in, bufferSize); memcpy(newBuffer, str, bufferSize);
else else
memset(newBuffer, 0, bufferSize); memset(newBuffer, 0, bufferSize);
...@@ -200,8 +273,23 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len) ...@@ -200,8 +273,23 @@ BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len)
/****************************************************************************** /******************************************************************************
* SysReAllocStringLen [OLEAUT32.5] * SysReAllocStringLen [OLEAUT32.5]
*
* Change the length of a previously created BSTR.
*
* PARAMS
* old [O] BSTR to change the length of
* str [I] New source for pbstr
* len [I] Length of oleStr in wide characters
*
* RETURNS
* Success: 1. The size of pbstr is updated.
* Failure: 0, if len >= 0x80000000 or memory allocation fails.
*
* NOTES
* See BSTR(), SysAllocStringByteLen().
* *pbstr may be changed by this function.
*/ */
int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len) int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* str, unsigned int len)
{ {
/* /*
* Sanity check * Sanity check
...@@ -214,8 +302,8 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len) ...@@ -214,8 +302,8 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD)); DWORD *ptr = HeapReAlloc(GetProcessHeap(),0,((DWORD*)*old)-1,newbytelen+sizeof(WCHAR)+sizeof(DWORD));
*old = (BSTR)(ptr+1); *old = (BSTR)(ptr+1);
*ptr = newbytelen; *ptr = newbytelen;
if (in) { if (str) {
memcpy(*old, in, newbytelen); memcpy(*old, str, newbytelen);
(*old)[len] = 0; (*old)[len] = 0;
} else { } else {
/* Subtle hidden feature: The old string data is still there /* Subtle hidden feature: The old string data is still there
...@@ -227,7 +315,7 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len) ...@@ -227,7 +315,7 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
/* /*
* Allocate the new string * Allocate the new string
*/ */
*old = SysAllocStringLen(in, len); *old = SysAllocStringLen(str, len);
} }
return 1; return 1;
...@@ -236,8 +324,24 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len) ...@@ -236,8 +324,24 @@ int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len)
/****************************************************************************** /******************************************************************************
* SysAllocStringByteLen [OLEAUT32.150] * SysAllocStringByteLen [OLEAUT32.150]
* *
*/ * Create a BSTR from an OLESTR of a given byte length.
BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len) *
* PARAMS
* str [I] Source to create BSTR from
* len [I] Length of oleStr in bytes
*
* RETURNS
* Success: A newly allocated BSTR
* Failure: NULL, if len is >= 0x80000000, or memory allocation fails.
*
* NOTES
* -If len is 0 or oleStr is NULL the resulting string is empty ("").
* -This function always NUL terminates the resulting BSTR.
* -oleStr may be either an LPCSTR or LPCOLESTR, since it is copied
* without checking for a terminating NUL.
* See BSTR.
*/
BSTR WINAPI SysAllocStringByteLen(LPCSTR str, UINT len)
{ {
DWORD* newBuffer; DWORD* newBuffer;
char* stringBuffer; char* stringBuffer;
...@@ -273,8 +377,8 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len) ...@@ -273,8 +377,8 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len)
* Since it is valid to pass a NULL pointer here, we'll initialize the * Since it is valid to pass a NULL pointer here, we'll initialize the
* buffer to nul if it is the case. * buffer to nul if it is the case.
*/ */
if (in != 0) if (str != 0)
memcpy(newBuffer, in, len); memcpy(newBuffer, str, len);
/* /*
* Make sure that there is a nul character at the end of the * Make sure that there is a nul character at the end of the
...@@ -289,8 +393,21 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len) ...@@ -289,8 +393,21 @@ BSTR WINAPI SysAllocStringByteLen(LPCSTR in, UINT len)
/****************************************************************************** /******************************************************************************
* SysReAllocString [OLEAUT32.3] * SysReAllocString [OLEAUT32.3]
*
* Change the length of a previously created BSTR.
*
* PARAMS
* old [I/O] BSTR to change the length of
* str [I] New source for pbstr
*
* RETURNS
* Success: 1
* Failure: 0.
*
* NOTES
* See BSTR(), SysAllocStringStringLen().
*/ */
INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in) INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR str)
{ {
/* /*
* Sanity check * Sanity check
...@@ -307,11 +424,30 @@ INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in) ...@@ -307,11 +424,30 @@ INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in)
/* /*
* Allocate the new string * Allocate the new string
*/ */
*old = SysAllocString(in); *old = SysAllocString(str);
return 1; return 1;
} }
/******************************************************************************
* SetOaNoCache (OLEAUT32.327)
*
* Instruct Ole Automation not to cache BSTR allocations.
*
* PARAMS
* None.
*
* RETURNS
* Nothing.
*
* NOTES
* See BSTR.
*/
void WINAPI SetOaNoCache(void)
{
BSTR_bCache = FALSE;
}
static WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */ static WCHAR _delimiter[2] = {'!',0}; /* default delimiter apparently */
static WCHAR *pdelimiter = &_delimiter[0]; static WCHAR *pdelimiter = &_delimiter[0];
......
...@@ -316,6 +316,7 @@ ...@@ -316,6 +316,7 @@
321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer 321 stdcall -private DllUnregisterServer() OLEAUT32_DllUnregisterServer
322 stub GetRecordInfoFromGuids # stdcall (ptr long long long ptr ptr) 322 stub GetRecordInfoFromGuids # stdcall (ptr long long long ptr ptr)
323 stub GetRecordInfoFromTypeInfo # stdcall (ptr ptr) 323 stub GetRecordInfoFromTypeInfo # stdcall (ptr ptr)
327 stdcall SetOaNoCache()
330 stdcall VarDateFromUdate(ptr long ptr) 330 stdcall VarDateFromUdate(ptr long ptr)
331 stdcall VarUdateFromDate(double long ptr) 331 stdcall VarUdateFromDate(double long ptr)
332 stub GetAltMonthNames 332 stub GetAltMonthNames
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment