Separated thdb freeing code from ExitThread. Now we only need to call
[wine/wine-kai.git] / dlls / ntdll / rtlstr.c
blob0b4e165295014a87f2d2de6a10a0b136f3b0cc21
1 /*
2 * Rtl string functions
4 * Copyright 1996-1998 Marcus Meissner
5 */
7 #include "config.h"
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 "debug.h"
20 #include "ntddk.h"
22 * STRING FUNCTIONS
25 /**************************************************************************
26 * RtlAnsiStringToUnicodeString [NTDLL.269]
28 DWORD /* NTSTATUS */
29 WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOLEAN doalloc)
31 DWORD unilen = (ansi->Length+1)*sizeof(WCHAR);
33 if (unilen>0xFFFF)
34 return STATUS_INVALID_PARAMETER_2;
35 uni->Length = unilen;
36 if (doalloc) {
37 uni->MaximumLength = unilen;
38 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
39 if (!uni->Buffer)
40 return STATUS_NO_MEMORY;
42 if (unilen>uni->MaximumLength)
43 return STATUS_BUFFER_OVERFLOW;
44 lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
45 return STATUS_SUCCESS;
48 /**************************************************************************
49 * RtlOemStringToUnicodeString [NTDLL.447]
51 DWORD /* NTSTATUS */
52 WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOLEAN doalloc)
54 DWORD unilen = (ansi->Length+1)*sizeof(WCHAR);
56 if (unilen>0xFFFF)
57 return STATUS_INVALID_PARAMETER_2;
58 uni->Length = unilen;
59 if (doalloc) {
60 uni->MaximumLength = unilen;
61 uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen);
62 if (!uni->Buffer)
63 return STATUS_NO_MEMORY;
65 if (unilen>uni->MaximumLength)
66 return STATUS_BUFFER_OVERFLOW;
67 lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
68 return STATUS_SUCCESS;
70 /**************************************************************************
71 * RtlMultiByteToUnicodeN [NTDLL.436]
72 * FIXME: multibyte support
74 DWORD /* NTSTATUS */
75 WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
77 DWORD len;
78 LPWSTR x;
80 len = oemlen;
81 if (unilen/2 < len)
82 len = unilen/2;
83 x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
84 lstrcpynAtoW(x,oemstr,len+1);
85 memcpy(unistr,x,len*2);
86 if (reslen) *reslen = len*2;
87 return 0;
90 /**************************************************************************
91 * RtlOemToUnicodeN [NTDLL.448]
93 DWORD /* NTSTATUS */
94 WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
96 DWORD len;
97 LPWSTR x;
99 len = oemlen;
100 if (unilen/2 < len)
101 len = unilen/2;
102 x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR));
103 lstrcpynAtoW(x,oemstr,len+1);
104 memcpy(unistr,x,len*2);
105 if (reslen) *reslen = len*2;
106 return 0;
109 /**************************************************************************
110 * RtlInitAnsiString [NTDLL.399]
112 VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source)
114 target->Length = target->MaximumLength = 0;
115 target->Buffer = (LPSTR)source;
116 if (!source)
117 return;
118 target->MaximumLength = lstrlenA(target->Buffer);
119 target->Length = target->MaximumLength+1;
121 /**************************************************************************
122 * RtlInitString [NTDLL.402]
124 VOID WINAPI RtlInitString(PSTRING target,LPCSTR source)
126 target->Length = target->MaximumLength = 0;
127 target->Buffer = (LPSTR)source;
128 if (!source)
129 return;
130 target->MaximumLength = lstrlenA(target->Buffer);
131 target->Length = target->MaximumLength+1;
134 /**************************************************************************
135 * RtlInitUnicodeString [NTDLL.403]
137 VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source)
139 target->Length = target->MaximumLength = 0;
140 target->Buffer = (LPWSTR)source;
141 if (!source)
142 return;
143 target->MaximumLength = lstrlenW(target->Buffer)*2;
144 target->Length = target->MaximumLength+2;
147 /**************************************************************************
148 * RtlFreeUnicodeString [NTDLL.377]
150 VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str)
152 if (str->Buffer)
153 HeapFree(GetProcessHeap(),0,str->Buffer);
156 /**************************************************************************
157 * RtlFreeAnsiString [NTDLL.373]
159 VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
161 if( AnsiString->Buffer )
162 HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
166 /**************************************************************************
167 * RtlUnicodeToOemN [NTDLL.515]
169 DWORD /* NTSTATUS */
170 WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
172 DWORD len;
173 LPSTR x;
175 len = oemlen;
176 if (unilen/2 < len)
177 len = unilen/2;
178 x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1);
179 lstrcpynWtoA(x,unistr,len+1);
180 memcpy(oemstr,x,len);
181 if (reslen) *reslen = len;
182 return 0;
185 /**************************************************************************
186 * RtlUnicodeStringToOemString [NTDLL.511]
188 DWORD /* NTSTATUS */
189 WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
191 if (alloc) {
192 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
193 oem->MaximumLength = uni->Length/2+1;
195 oem->Length = uni->Length/2;
196 lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
197 return 0;
200 /**************************************************************************
201 * RtlUnicodeStringToAnsiString [NTDLL.507]
203 DWORD /* NTSTATUS */
204 WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
206 if (alloc) {
207 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
208 oem->MaximumLength = uni->Length/2+1;
210 oem->Length = uni->Length/2;
211 lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
212 return 0;
215 /**************************************************************************
216 * RtlEqualUnicodeString [NTDLL]
218 DWORD WINAPI RtlEqualUnicodeString(PUNICODE_STRING s1,PUNICODE_STRING s2,DWORD x) {
219 FIXME(ntdll,"(%s,%s,%ld),stub!\n",debugstr_w(s1->Buffer),debugstr_w(s2->Buffer),x);
220 return 0;
221 if (s1->Length != s2->Length)
222 return 1;
223 return !lstrncmpW(s1->Buffer,s2->Buffer,s1->Length/2);
226 /**************************************************************************
227 * RtlUpcaseUnicodeString [NTDLL.520]
229 DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOLEAN doalloc)
231 LPWSTR s,t;
232 DWORD i,len;
234 len = src->Length;
235 if (doalloc) {
236 dest->MaximumLength = len;
237 dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len);
238 if (!dest->Buffer)
239 return STATUS_NO_MEMORY;
242 if (dest->MaximumLength < len)
243 return STATUS_BUFFER_OVERFLOW;
244 s=dest->Buffer;t=src->Buffer;
245 /* len is in bytes */
246 for (i=0;i<len/2;i++)
247 s[i] = towupper(t[i]);
248 return STATUS_SUCCESS;
251 /**************************************************************************
252 * RtlxOemStringToUnicodeSize [NTDLL.549]
254 UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str)
256 return str->Length*2+2;
259 /**************************************************************************
260 * RtlxAnsiStringToUnicodeSize [NTDLL.548]
262 UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str)
264 return str->Length*2+2;
267 /**************************************************************************
268 * RtlIsTextUnicode [NTDLL.417]
270 * Apply various feeble heuristics to guess whether
271 * the text buffer contains Unicode.
272 * FIXME: should implement more tests.
274 DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf)
276 LPWSTR s = buf;
277 DWORD flags = -1, out_flags = 0;
279 if (!len)
280 goto out;
281 if (pf)
282 flags = *pf;
284 * Apply various tests to the text string. According to the
285 * docs, each test "passed" sets the corresponding flag in
286 * the output flags. But some of the tests are mutually
287 * exclusive, so I don't see how you could pass all tests ...
290 /* Check for an odd length ... pass if even. */
291 if (!(len & 1))
292 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
294 /* Check for the special unicode marker byte. */
295 if (*s == 0xFEFF)
296 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
299 * Check whether the string passed all of the tests.
301 flags &= ITU_IMPLEMENTED_TESTS;
302 if ((out_flags & flags) != flags)
303 len = 0;
304 out:
305 if (pf)
306 *pf = out_flags;
307 return len;
311 /******************************************************************************
312 * RtlCompareUnicodeString [NTDLL]
314 NTSTATUS WINAPI RtlCompareUnicodeString(
315 PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
317 FIXME(ntdll,"(%s,%s,0x%08x),stub!\n",debugstr_w(String1->Buffer),debugstr_w(String1->Buffer),CaseInSensitive);
318 return 0;