Implemented some CRTDLL string functions.
[wine] / ole / ole2disp.c
1 /*
2  *      OLE2DISP library
3  *
4  *      Copyright 1995  Martin von Loewis
5  */
6
7 #include <string.h>
8 #include "windows.h"
9 #include "winerror.h"
10 #include "ole.h"
11 #include "ole2.h"
12 #include "oleauto.h"
13 #include "wtypes.h"
14 #include "wine/obj_base.h"
15 #include "objbase.h"
16 #include "heap.h"
17 #include "ldt.h"
18 #include "debug.h"
19
20 /* This implementation of the BSTR API is 16-bit only. It
21    represents BSTR as a 16:16 far pointer, and the strings
22    as ISO-8859 */
23
24 /******************************************************************************
25  *              BSTR_AllocBytes [Internal]
26  */
27 static BSTR16 BSTR_AllocBytes(int n)
28 {
29     void *ptr = SEGPTR_ALLOC(n);
30     return (BSTR16)SEGPTR_GET(ptr);
31 }
32
33 /******************************************************************************
34  * BSTR_Free [INTERNAL]
35  */
36 static void BSTR_Free(BSTR16 in)
37 {
38     SEGPTR_FREE( PTR_SEG_TO_LIN(in) );
39 }
40
41 /******************************************************************************
42  * BSTR_GetAddr [INTERNAL]
43  */
44 static void* BSTR_GetAddr(BSTR16 in)
45 {
46     return in ? PTR_SEG_TO_LIN(in) : 0;
47 }
48
49 /******************************************************************************
50  *              SysAllocString16        [OLE2DISP.2]
51  */
52 BSTR16 WINAPI SysAllocString16(LPOLESTR16 in)
53 {
54         BSTR16 out=BSTR_AllocBytes(strlen(in)+1);
55         if(!out)return 0;
56         strcpy(BSTR_GetAddr(out),in);
57         return out;
58 }
59
60 /******************************************************************************
61  *              SysAllocString32        [OLEAUT32.2]
62  */
63 BSTR32 WINAPI SysAllocString32(LPOLESTR32 in)
64 {
65     /* Delegate this to the SysAllocStringLen32 method. */
66     return SysAllocStringLen32(in, lstrlen32W(in));
67 }
68
69 /******************************************************************************
70  *              SysReAllocString16      [OLE2DISP.3]
71  */
72 INT16 WINAPI SysReAllocString16(LPBSTR16 old,LPOLESTR16 in)
73 {
74         BSTR16 new=SysAllocString16(in);
75         BSTR_Free(*old);
76         *old=new;
77         return 1;
78 }
79
80 /******************************************************************************
81  *              SysReAllocString32      [OLEAUT32.3]
82  */
83 INT32 WINAPI SysReAllocString32(LPBSTR32 old,LPOLESTR32 in)
84 {
85     /*
86      * Sanity check
87      */
88     if (old==NULL) 
89       return 0;
90
91     /*
92      * Make sure we free the old string.
93      */
94     if (*old!=NULL)      
95       SysFreeString32(*old);
96
97     /*
98      * Allocate the new string
99      */
100     *old = SysAllocString32(in);
101
102      return 1;
103 }
104
105 /******************************************************************************
106  *              SysAllocStringLen16     [OLE2DISP.4]
107  */
108 BSTR16 WINAPI SysAllocStringLen16(char *in, int len)
109 {
110         BSTR16 out=BSTR_AllocBytes(len+1);
111         if(!out)return 0;
112         strcpy(BSTR_GetAddr(out),in);
113         return out;
114 }
115
116 /******************************************************************************
117  *             SysAllocStringLen32     [OLEAUT32.4]
118  *
119  * In "Inside OLE, second edition" by Kraig Brockshmidt. In the Automation
120  * section, he describes the DWORD value placed before the BSTR data type.
121  * he describes it as a "DWORD count of characters". By experimenting with
122  * a windows application, this count seems to be a DWORD count of bytes in
123  * the string. Meaning that the count is double the number of wide 
124  * characters in the string.
125  */
126 BSTR32 WINAPI SysAllocStringLen32(WCHAR *in, int len)
127 {
128     DWORD  bufferSize;
129     DWORD* newBuffer;
130     WCHAR* stringBuffer;
131
132     /*
133      * Find the lenth of the buffer passed-in in bytes.
134      */
135     bufferSize = len * sizeof (WCHAR);
136
137     /*
138      * Allocate a new buffer to hold the string.
139      * dont't forget to keep an empty spot at the begining of the
140      * buffer for the character count and an extra character at the
141      * end for the NULL.
142      */
143     newBuffer = (DWORD*)HeapAlloc(GetProcessHeap(),
144                                  0,
145                                  bufferSize + sizeof(WCHAR) + sizeof(DWORD));
146
147     /*
148      * If the memory allocation failed, return a null pointer.
149      */
150     if (newBuffer==0)
151       return 0;
152
153     /*
154      * Copy the length of the string in the placeholder.
155      */
156     *newBuffer = bufferSize;
157
158     /*
159      * Skip the byte count.
160      */
161     newBuffer++;
162
163     /*
164      * Copy the information in the buffer.
165      * Since it is valid to pass a NULL pointer here, we'll initialize the
166      * buffer to nul if it is the case.
167      */
168     if (in != 0)
169       memcpy(newBuffer, in, bufferSize);
170     else
171       memset(newBuffer, 0, bufferSize);
172
173     /*
174      * Make sure that there is a nul character at the end of the
175      * string.
176      */
177     stringBuffer = (WCHAR*)newBuffer;
178     stringBuffer[len] = L'\0';
179
180     return (LPWSTR)stringBuffer;
181 }
182
183 /******************************************************************************
184  *              SysReAllocStringLen16   [OLE2DISP.5]
185  */
186 int WINAPI SysReAllocStringLen16(BSTR16 *old,char *in,int len)
187 {
188         BSTR16 new=SysAllocStringLen16(in,len);
189         BSTR_Free(*old);
190         *old=new;
191         return 1;
192 }
193
194  
195 /******************************************************************************
196  *             SysReAllocStringLen32   [OLEAUT32.5]
197  */
198 int WINAPI SysReAllocStringLen32(BSTR32* old, WCHAR* in, int len)
199 {
200     /*
201      * Sanity check
202      */
203     if (old==NULL) 
204       return 0;
205
206     /*
207      * Make sure we free the old string.
208      */
209     if (*old!=NULL)      
210       SysFreeString32(*old);
211
212     /*
213      * Allocate the new string
214      */
215     *old = SysAllocStringLen32(in, len);
216
217     return 1;
218 }
219
220 /******************************************************************************
221  *              SysFreeString16 [OLE2DISP.6]
222  */
223 void WINAPI SysFreeString16(BSTR16 in)
224 {
225         BSTR_Free(in);
226 }
227
228 /******************************************************************************
229  *              SysFreeString32 [OLEAUT32.6]
230  */
231 void WINAPI SysFreeString32(BSTR32 in)
232 {
233     DWORD* bufferPointer;
234
235     /*
236      * We have to be careful when we free a BSTR pointer, it points to
237      * the beginning of the string but it skips the byte count contained
238      * before the string.
239      */
240     bufferPointer = (DWORD*)in;
241
242     bufferPointer--;
243
244     /*
245      * Free the memory from it's "real" origin.
246      */
247     HeapFree(GetProcessHeap(), 0, bufferPointer);
248 }
249
250 /******************************************************************************
251  *              SysStringLen16  [OLE2DISP.7]
252  */
253 int WINAPI SysStringLen16(BSTR16 str)
254 {
255         return strlen(BSTR_GetAddr(str));
256 }
257
258 /******************************************************************************
259  *             SysStringLen32  [OLEAUT32.7]
260  *
261  * The Windows documentation states that the length returned by this function
262  * is not necessarely the same as the length returned by the _lstrlenW method.
263  * It is the same number that was passed in as the "len" parameter if the
264  * string was allocated with a SysAllocStringLen method call.
265  */
266 int WINAPI SysStringLen32(BSTR32 str)
267 {
268     DWORD* bufferPointer;
269
270     /*
271      * The length of the string (in bytes) is contained in a DWORD placed 
272      * just before the BSTR pointer
273      */
274     bufferPointer = (DWORD*)str;
275
276     bufferPointer--;
277
278     return (int)(*bufferPointer/sizeof(WCHAR));
279 }
280
281 /******************************************************************************
282  *             SysStringByteLen  [OLEAUT32.149]
283  *
284  * The Windows documentation states that the length returned by this function
285  * is not necessarely the same as the length returned by the _lstrlenW method.
286  * It is the same number that was passed in as the "len" parameter if the
287  * string was allocated with a SysAllocStringLen method call.
288  */
289 int WINAPI SysStringByteLen(BSTR32 str)
290 {
291   return SysStringLen32(str)*sizeof(WCHAR);
292 }
293
294 /******************************************************************************
295  * CreateDispTypeInfo [OLE2DISP.31]
296  */
297 OLESTATUS WINAPI CreateDispTypeInfo(
298         INTERFACEDATA *pidata,
299         LCID lcid,
300         LPVOID **pptinfo /*ITypeInfo*/ 
301 ) {
302         FIXME(ole,"(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
303         return 0;
304 }
305
306 /******************************************************************************
307  * RegisterActiveObject [OLE2DISP.35]
308  */
309 OLESTATUS WINAPI RegisterActiveObject(
310         IUnknown * punk,REFCLSID rclsid,DWORD dwFlags, DWORD * pdwRegister
311 ) {
312         char    buf[80];
313         WINE_StringFromCLSID(rclsid,buf);
314         FIXME(ole,"(%p,%s,0x%08lx,%p):stub\n",punk,buf,dwFlags,pdwRegister);
315         return 0;
316 }
317
318 /******************************************************************************
319  *              OleTranslateColor       [OLEAUT32.421]
320  */
321 INT32 WINAPI OleTranslateColor(
322   LONG clr,
323   HPALETTE32  hpal,
324   COLORREF* pColorRef)
325 {
326   FIXME(ole,"():stub\n");
327
328   *pColorRef = clr;
329
330   return S_OK;
331 }
332
333
334
335