Added DebugBreak.
[wine] / dlls / ntdll / rtlstr.c
1 /*
2  *      Rtl string functions
3  *
4  *      Copyright 1996-1998 Marcus Meissner
5  */
6
7 #include "config.h"
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #ifdef HAVE_WCTYPE_H
13 # include <wctype.h>
14 #endif
15 #include "wine/winestring.h"
16 #include "heap.h"
17 #include "winnls.h"
18 #include "debugtools.h"
19
20 #include "ntddk.h"
21
22 DEFAULT_DEBUG_CHANNEL(ntdll)
23 /*
24  *      STRING FUNCTIONS
25  */
26
27 /**************************************************************************
28  *                 RtlAnsiStringToUnicodeString         [NTDLL.269]
29  */
30 DWORD /* NTSTATUS */ 
31 WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOLEAN doalloc)
32 {
33         DWORD   unilen = (ansi->Length+1)*sizeof(WCHAR);
34
35         if (unilen>0xFFFF)
36                 return STATUS_INVALID_PARAMETER_2;
37         uni->Length = unilen;
38         if (doalloc) {
39                 uni->MaximumLength = unilen;
40                 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
41                 if (!uni->Buffer)
42                         return STATUS_NO_MEMORY;
43         }
44         if (unilen>uni->MaximumLength)
45                 return STATUS_BUFFER_OVERFLOW;
46         lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
47         return STATUS_SUCCESS;
48 }
49
50 /**************************************************************************
51  *                 RtlOemStringToUnicodeString          [NTDLL.447]
52  */
53 DWORD /* NTSTATUS */ 
54 WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOLEAN doalloc)
55 {
56         DWORD   unilen = (ansi->Length+1)*sizeof(WCHAR);
57
58         if (unilen>0xFFFF)
59                 return STATUS_INVALID_PARAMETER_2;
60         uni->Length = unilen;
61         if (doalloc) {
62                 uni->MaximumLength = unilen;
63                 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
64                 if (!uni->Buffer)
65                         return STATUS_NO_MEMORY;
66         }
67         if (unilen>uni->MaximumLength)
68                 return STATUS_BUFFER_OVERFLOW;
69         lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
70         return STATUS_SUCCESS;
71 }
72 /**************************************************************************
73  *                 RtlMultiByteToUnicodeN               [NTDLL.436]
74  * FIXME: multibyte support
75  */
76 DWORD /* NTSTATUS */ 
77 WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
78 {
79         DWORD   len;
80         LPWSTR  x;
81
82         len = oemlen;
83         if (unilen/2 < len)
84                 len = unilen/2;
85         x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
86         lstrcpynAtoW(x,oemstr,len+1);
87         memcpy(unistr,x,len*2);
88         if (reslen) *reslen = len*2;
89         return 0;
90 }
91
92 /**************************************************************************
93  *                 RtlOemToUnicodeN                     [NTDLL.448]
94  */
95 DWORD /* NTSTATUS */ 
96 WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
97 {
98         DWORD   len;
99         LPWSTR  x;
100
101         len = oemlen;
102         if (unilen/2 < len)
103                 len = unilen/2;
104         x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
105         lstrcpynAtoW(x,oemstr,len+1);
106         memcpy(unistr,x,len*2);
107         if (reslen) *reslen = len*2;
108         return 0;
109 }
110
111 /**************************************************************************
112  *                 RtlInitAnsiString                    [NTDLL.399]
113  */
114 VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source)
115 {
116         target->Length = target->MaximumLength = 0;
117         target->Buffer = (LPSTR)source;
118         if (!source)
119                 return;
120         target->MaximumLength = lstrlenA(target->Buffer);
121         target->Length = target->MaximumLength+1;
122 }
123 /**************************************************************************
124  *                 RtlInitString                        [NTDLL.402]
125  */
126 VOID WINAPI RtlInitString(PSTRING target,LPCSTR source)
127 {
128         target->Length = target->MaximumLength = 0;
129         target->Buffer = (LPSTR)source;
130         if (!source)
131                 return;
132         target->MaximumLength = lstrlenA(target->Buffer);
133         target->Length = target->MaximumLength+1;
134 }
135
136 /**************************************************************************
137  *                 RtlInitUnicodeString                 [NTDLL.403]
138  */
139 VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source)
140 {
141         TRACE("%p %p(%s)\n", target, source, debugstr_w(source));
142         
143         target->Length = target->MaximumLength = 0;
144         target->Buffer = (LPWSTR)source;
145         if (!source)
146                 return;
147         target->MaximumLength = lstrlenW(target->Buffer)*2;
148         target->Length = target->MaximumLength+2;
149 }
150
151 /**************************************************************************
152  *                 RtlFreeUnicodeString                 [NTDLL.377]
153  */
154 VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str)
155 {
156         if (str->Buffer)
157                 HeapFree(GetProcessHeap(),0,str->Buffer);
158 }
159
160 /**************************************************************************
161  * RtlFreeAnsiString [NTDLL.373]
162  */
163 VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
164 {
165     if( AnsiString->Buffer )
166         HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
167 }
168
169
170 /**************************************************************************
171  *                 RtlUnicodeToOemN                     [NTDLL.515]
172  */
173 DWORD /* NTSTATUS */ 
174 WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
175 {
176         DWORD   len;
177         LPSTR   x;
178
179         len = oemlen;
180         if (unilen/2 < len)
181                 len = unilen/2;
182         x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1);
183         lstrcpynWtoA(x,unistr,len+1);
184         memcpy(oemstr,x,len);
185         if (reslen) *reslen = len;
186         return 0;
187 }
188
189 /**************************************************************************
190  *                 RtlUnicodeStringToOemString          [NTDLL.511]
191  */
192 DWORD /* NTSTATUS */ 
193 WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
194 {
195         if (alloc) {
196                 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
197                 oem->MaximumLength = uni->Length/2+1;
198         }
199         oem->Length = uni->Length/2;
200         lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
201         return 0;
202 }
203
204 /**************************************************************************
205  *                 RtlUnicodeStringToAnsiString         [NTDLL.507]
206  */
207 DWORD /* NTSTATUS */ 
208 WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
209 {
210         if (alloc) {
211                 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
212                 oem->MaximumLength = uni->Length/2+1;
213         }
214         oem->Length = uni->Length/2;
215         lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
216         return 0;
217 }
218
219 /**************************************************************************
220  *                 RtlEqualUnicodeString                [NTDLL]
221  */
222 DWORD WINAPI RtlEqualUnicodeString(PUNICODE_STRING s1,PUNICODE_STRING s2,DWORD x) {
223         FIXME("(%s,%s,%ld),stub!\n",debugstr_w(s1->Buffer),debugstr_w(s2->Buffer),x);
224         return 0;
225         if (s1->Length != s2->Length)
226                 return 1;
227         return !lstrncmpW(s1->Buffer,s2->Buffer,s1->Length/2);
228 }
229
230 /**************************************************************************
231  *                 RtlUpcaseUnicodeString               [NTDLL.520]
232  */
233 DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOLEAN doalloc)
234 {
235         LPWSTR  s,t;
236         DWORD   i,len;
237
238         len = src->Length;
239         if (doalloc) {
240                 dest->MaximumLength = len; 
241                 dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len);
242                 if (!dest->Buffer)
243                         return STATUS_NO_MEMORY;
244
245         }
246         if (dest->MaximumLength < len)
247                 return STATUS_BUFFER_OVERFLOW;
248         s=dest->Buffer;t=src->Buffer;
249         /* len is in bytes */
250         for (i=0;i<len/2;i++)
251                 s[i] = towupper(t[i]);
252         return STATUS_SUCCESS;
253 }
254
255 /**************************************************************************
256  *                 RtlxOemStringToUnicodeSize           [NTDLL.549]
257  */
258 UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str)
259 {
260         return str->Length*2+2;
261 }
262
263 /**************************************************************************
264  *                 RtlxAnsiStringToUnicodeSize          [NTDLL.548]
265  */
266 UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str)
267 {
268         return str->Length*2+2;
269 }
270
271 /**************************************************************************
272  *                 RtlIsTextUnicode                     [NTDLL.417]
273  *
274  *      Apply various feeble heuristics to guess whether
275  *      the text buffer contains Unicode.
276  *      FIXME: should implement more tests.
277  */
278 DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf)
279 {
280         LPWSTR s = buf;
281         DWORD flags = -1, out_flags = 0;
282
283         if (!len)
284                 goto out;
285         if (pf)
286                 flags = *pf;
287         /*
288          * Apply various tests to the text string. According to the
289          * docs, each test "passed" sets the corresponding flag in
290          * the output flags. But some of the tests are mutually
291          * exclusive, so I don't see how you could pass all tests ...
292          */
293
294         /* Check for an odd length ... pass if even. */
295         if (!(len & 1))
296                 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
297
298         /* Check for the special unicode marker byte. */
299         if (*s == 0xFEFF)
300                 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
301
302         /*
303          * Check whether the string passed all of the tests.
304          */
305         flags &= ITU_IMPLEMENTED_TESTS;
306         if ((out_flags & flags) != flags)
307                 len = 0;
308 out:
309         if (pf)
310                 *pf = out_flags;
311         return len;
312 }
313
314
315 /******************************************************************************
316  *      RtlCompareUnicodeString [NTDLL] 
317  */
318 NTSTATUS WINAPI RtlCompareUnicodeString(
319         PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive) 
320 {
321         FIXME("(%s,%s,0x%08x),stub!\n",debugstr_w(String1->Buffer),debugstr_w(String1->Buffer),CaseInSensitive);
322         return 0;
323 }
324
325