| /* | |
| * OLE2DISP library | |
| * | |
| * Copyright 1995 Martin von Loewis | |
| */ | |
| #include <string.h> | |
| #include "winerror.h" | |
| #include "ole2.h" | |
| #include "oleauto.h" | |
| #include "wine/obj_base.h" | |
| #include "heap.h" | |
| #include "ldt.h" | |
| #include "debug.h" | |
| DEFAULT_DEBUG_CHANNEL(ole) | |
| /* This implementation of the BSTR API is 16-bit only. It | |
| represents BSTR as a 16:16 far pointer, and the strings | |
| as ISO-8859 */ | |
| /****************************************************************************** | |
| * BSTR_AllocBytes [Internal] | |
| */ | |
| static BSTR16 BSTR_AllocBytes(int n) | |
| { | |
| void *ptr = SEGPTR_ALLOC(n); | |
| return (BSTR16)SEGPTR_GET(ptr); | |
| } | |
| /****************************************************************************** | |
| * BSTR_Free [INTERNAL] | |
| */ | |
| static void BSTR_Free(BSTR16 in) | |
| { | |
| SEGPTR_FREE( PTR_SEG_TO_LIN(in) ); | |
| } | |
| /****************************************************************************** | |
| * BSTR_GetAddr [INTERNAL] | |
| */ | |
| static void* BSTR_GetAddr(BSTR16 in) | |
| { | |
| return in ? PTR_SEG_TO_LIN(in) : 0; | |
| } | |
| /****************************************************************************** | |
| * SysAllocString16 [OLE2DISP.2] | |
| */ | |
| BSTR16 WINAPI SysAllocString16(LPCOLESTR16 in) | |
| { | |
| BSTR16 out=BSTR_AllocBytes(strlen(in)+1); | |
| if(!out)return 0; | |
| strcpy(BSTR_GetAddr(out),in); | |
| return out; | |
| } | |
| /****************************************************************************** | |
| * SysAllocString32 [OLEAUT32.2] | |
| */ | |
| BSTR WINAPI SysAllocString(LPCOLESTR in) | |
| { | |
| /* Delegate this to the SysAllocStringLen32 method. */ | |
| return SysAllocStringLen(in, lstrlenW(in)); | |
| } | |
| /****************************************************************************** | |
| * SysReAllocString16 [OLE2DISP.3] | |
| */ | |
| INT16 WINAPI SysReAllocString16(LPBSTR16 old,LPCOLESTR16 in) | |
| { | |
| BSTR16 new=SysAllocString16(in); | |
| BSTR_Free(*old); | |
| *old=new; | |
| return 1; | |
| } | |
| /****************************************************************************** | |
| * SysReAllocString32 [OLEAUT32.3] | |
| */ | |
| INT WINAPI SysReAllocString(LPBSTR old,LPCOLESTR in) | |
| { | |
| /* | |
| * Sanity check | |
| */ | |
| if (old==NULL) | |
| return 0; | |
| /* | |
| * Make sure we free the old string. | |
| */ | |
| if (*old!=NULL) | |
| SysFreeString(*old); | |
| /* | |
| * Allocate the new string | |
| */ | |
| *old = SysAllocString(in); | |
| return 1; | |
| } | |
| /****************************************************************************** | |
| * SysAllocStringLen16 [OLE2DISP.4] | |
| */ | |
| BSTR16 WINAPI SysAllocStringLen16(const char *in, int len) | |
| { | |
| BSTR16 out=BSTR_AllocBytes(len+1); | |
| if(!out)return 0; | |
| strcpy(BSTR_GetAddr(out),in); | |
| return out; | |
| } | |
| /****************************************************************************** | |
| * SysAllocStringLen32 [OLEAUT32.4] | |
| * | |
| * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation | |
| * section, he describes the DWORD value placed before the BSTR data type. | |
| * he describes it as a "DWORD count of characters". By experimenting with | |
| * a windows application, this count seems to be a DWORD count of bytes in | |
| * the string. Meaning that the count is double the number of wide | |
| * characters in the string. | |
| */ | |
| BSTR WINAPI SysAllocStringLen(const OLECHAR *in, unsigned int len) | |
| { | |
| DWORD bufferSize; | |
| DWORD* newBuffer; | |
| WCHAR* stringBuffer; | |
| /* | |
| * Find the lenth of the buffer passed-in in bytes. | |
| */ | |
| bufferSize = len * sizeof (WCHAR); | |
| /* | |
| * Allocate a new buffer to hold the string. | |
| * dont't forget to keep an empty spot at the begining of the | |
| * buffer for the character count and an extra character at the | |
| * end for the NULL. | |
| */ | |
| newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(), | |
| 0, | |
| bufferSize + sizeof(WCHAR) + sizeof(DWORD)); | |
| /* | |
| * If the memory allocation failed, return a null pointer. | |
| */ | |
| if (newBuffer==0) | |
| return 0; | |
| /* | |
| * Copy the length of the string in the placeholder. | |
| */ | |
| *newBuffer = bufferSize; | |
| /* | |
| * Skip the byte count. | |
| */ | |
| newBuffer++; | |
| /* | |
| * Copy the information in the buffer. | |
| * Since it is valid to pass a NULL pointer here, we'll initialize the | |
| * buffer to nul if it is the case. | |
| */ | |
| if (in != 0) | |
| memcpy(newBuffer, in, bufferSize); | |
| else | |
| memset(newBuffer, 0, bufferSize); | |
| /* | |
| * Make sure that there is a nul character at the end of the | |
| * string. | |
| */ | |
| stringBuffer = (WCHAR*)newBuffer; | |
| stringBuffer[len] = L'\0'; | |
| return (LPWSTR)stringBuffer; | |
| } | |
| /****************************************************************************** | |
| * SysReAllocStringLen16 [OLE2DISP.5] | |
| */ | |
| int WINAPI SysReAllocStringLen16(BSTR16 *old,const char *in,int len) | |
| { | |
| BSTR16 new=SysAllocStringLen16(in,len); | |
| BSTR_Free(*old); | |
| *old=new; | |
| return 1; | |
| } | |
| /****************************************************************************** | |
| * SysReAllocStringLen32 [OLEAUT32.5] | |
| */ | |
| int WINAPI SysReAllocStringLen(BSTR* old, const OLECHAR* in, unsigned int len) | |
| { | |
| /* | |
| * Sanity check | |
| */ | |
| if (old==NULL) | |
| return 0; | |
| /* | |
| * Make sure we free the old string. | |
| */ | |
| if (*old!=NULL) | |
| SysFreeString(*old); | |
| /* | |
| * Allocate the new string | |
| */ | |
| *old = SysAllocStringLen(in, len); | |
| return 1; | |
| } | |
| /****************************************************************************** | |
| * SysFreeString16 [OLE2DISP.6] | |
| */ | |
| void WINAPI SysFreeString16(BSTR16 in) | |
| { | |
| BSTR_Free(in); | |
| } | |
| /****************************************************************************** | |
| * SysFreeString32 [OLEAUT32.6] | |
| */ | |
| void WINAPI SysFreeString(BSTR in) | |
| { | |
| DWORD* bufferPointer; | |
| /* | |
| * 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 | |
| * before the string. | |
| */ | |
| bufferPointer = (DWORD*)in; | |
| bufferPointer--; | |
| /* | |
| * Free the memory from it's "real" origin. | |
| */ | |
| HeapFree(GetProcessHeap(), 0, bufferPointer); | |
| } | |
| /****************************************************************************** | |
| * SysStringLen16 [OLE2DISP.7] | |
| */ | |
| int WINAPI SysStringLen16(BSTR16 str) | |
| { | |
| return strlen(BSTR_GetAddr(str)); | |
| } | |
| /****************************************************************************** | |
| * SysStringLen32 [OLEAUT32.7] | |
| * | |
| * The Windows documentation states that the length returned by this function | |
| * 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 | |
| * string was allocated with a SysAllocStringLen method call. | |
| */ | |
| int WINAPI SysStringLen(BSTR str) | |
| { | |
| DWORD* bufferPointer; | |
| /* | |
| * The length of the string (in bytes) is contained in a DWORD placed | |
| * just before the BSTR pointer | |
| */ | |
| bufferPointer = (DWORD*)str; | |
| bufferPointer--; | |
| return (int)(*bufferPointer/sizeof(WCHAR)); | |
| } | |
| /****************************************************************************** | |
| * SysStringByteLen [OLEAUT32.149] | |
| * | |
| * The Windows documentation states that the length returned by this function | |
| * 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 | |
| * string was allocated with a SysAllocStringLen method call. | |
| */ | |
| int WINAPI SysStringByteLen(BSTR str) | |
| { | |
| return SysStringLen(str)*sizeof(WCHAR); | |
| } | |
| /****************************************************************************** | |
| * CreateDispTypeInfo [OLE2DISP.31] | |
| */ | |
| HRESULT WINAPI CreateDispTypeInfo16( | |
| INTERFACEDATA *pidata, | |
| LCID lcid, | |
| ITypeInfo **pptinfo | |
| ) { | |
| FIXME(ole,"(%p,%ld,%p),stub\n",pidata,lcid,pptinfo); | |
| return 0; | |
| } | |
| /****************************************************************************** | |
| * RegisterActiveObject [OLE2DISP.35] | |
| */ | |
| HRESULT WINAPI RegisterActiveObject16( | |
| IUnknown *punk, REFCLSID rclsid, DWORD dwFlags, unsigned long *pdwRegister | |
| ) { | |
| char buf[80]; | |
| WINE_StringFromCLSID(rclsid,buf); | |
| FIXME(ole,"(%p,%s,0x%08lx,%p):stub\n",punk,buf,dwFlags,pdwRegister); | |
| return 0; | |
| } | |
| /****************************************************************************** | |
| * OleTranslateColor [OLEAUT32.421] | |
| * | |
| * Converts an OLE_COLOR to a COLORREF. | |
| * See the documentation for conversion rules. | |
| * pColorRef can be NULL. In that case the user only wants to test the | |
| * conversion. | |
| */ | |
| INT WINAPI OleTranslateColor( | |
| LONG clr, | |
| HPALETTE hpal, | |
| COLORREF* pColorRef) | |
| { | |
| COLORREF colorref; | |
| BYTE b = HIBYTE(HIWORD(clr)); | |
| TRACE(ole,"(%08lx, %d, %p):stub\n", clr, hpal, pColorRef); | |
| /* | |
| * In case pColorRef is NULL, provide our own to simplify the code. | |
| */ | |
| if (pColorRef == NULL) | |
| pColorRef = &colorref; | |
| switch (b) | |
| { | |
| case 0x00: | |
| { | |
| if (hpal != 0) | |
| *pColorRef = PALETTERGB(GetRValue(clr), | |
| GetGValue(clr), | |
| GetBValue(clr)); | |
| else | |
| *pColorRef = clr; | |
| break; | |
| } | |
| case 0x01: | |
| { | |
| if (hpal != 0) | |
| { | |
| PALETTEENTRY pe; | |
| /* | |
| * Validate the palette index. | |
| */ | |
| if (GetPaletteEntries(hpal, LOWORD(clr), 1, &pe) == 0) | |
| return E_INVALIDARG; | |
| } | |
| *pColorRef = clr; | |
| break; | |
| } | |
| case 0x02: | |
| *pColorRef = clr; | |
| break; | |
| case 0x80: | |
| { | |
| int index = LOBYTE(LOWORD(clr)); | |
| /* | |
| * Validate GetSysColor index. | |
| */ | |
| if ((index < COLOR_SCROLLBAR) || (index > COLOR_GRADIENTINACTIVECAPTION)) | |
| return E_INVALIDARG; | |
| *pColorRef = GetSysColor(index); | |
| break; | |
| } | |
| default: | |
| return E_INVALIDARG; | |
| } | |
| return S_OK; | |
| } | |
| /****************************************************************************** | |
| * SysAllocStringByteLen [OLEAUT32.150] | |
| * | |
| */ | |
| BSTR WINAPI SysAllocStringByteLen(char *in, int len) | |
| { | |
| DWORD* newBuffer; | |
| char* stringBuffer; | |
| /* | |
| * Allocate a new buffer to hold the string. | |
| * dont't forget to keep an empty spot at the begining of the | |
| * buffer for the character count and an extra character at the | |
| * end for the NULL. | |
| */ | |
| newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(), | |
| 0, | |
| len + sizeof(WCHAR) + sizeof(DWORD)); | |
| /* | |
| * If the memory allocation failed, return a null pointer. | |
| */ | |
| if (newBuffer==0) | |
| return 0; | |
| /* | |
| * Copy the length of the string in the placeholder. | |
| */ | |
| *newBuffer = len; | |
| /* | |
| * Skip the byte count. | |
| */ | |
| newBuffer++; | |
| /* | |
| * Copy the information in the buffer. | |
| * Since it is valid to pass a NULL pointer here, we'll initialize the | |
| * buffer to nul if it is the case. | |
| */ | |
| if (in != 0) | |
| memcpy(newBuffer, in, len); | |
| /* | |
| * Make sure that there is a nul character at the end of the | |
| * string. | |
| */ | |
| stringBuffer = (char *)newBuffer; | |
| stringBuffer[len] = 0; | |
| stringBuffer[len+1] = 0; | |
| return (LPWSTR)stringBuffer; | |
| } | |