Authors: Chris Morgan <cmorgan@wpi.edu>, James Abbatiello <abbeyj@wpi.edu>
[wine.git] / dlls / ntdll / rtlstr.c
blob223e5671d9e3d3956554f6d84eb8d598fc40d97d
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 "debugtools.h"
20 #include "ntddk.h"
22 DEFAULT_DEBUG_CHANNEL(ntdll)
24 * STRING FUNCTIONS
27 /**************************************************************************
28 * RtlAnsiStringToUnicodeString [NTDLL.269]
30 DWORD /* NTSTATUS */
31 WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOLEAN doalloc)
33 DWORD unilen = (ansi->Length+1)*sizeof(WCHAR);
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;
44 if (unilen>uni->MaximumLength)
45 return STATUS_BUFFER_OVERFLOW;
46 lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
47 return STATUS_SUCCESS;
50 /**************************************************************************
51 * RtlOemStringToUnicodeString [NTDLL.447]
53 DWORD /* NTSTATUS */
54 WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOLEAN doalloc)
56 DWORD unilen = (ansi->Length+1)*sizeof(WCHAR);
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;
67 if (unilen>uni->MaximumLength)
68 return STATUS_BUFFER_OVERFLOW;
69 lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2);
70 return STATUS_SUCCESS;
72 /**************************************************************************
73 * RtlMultiByteToUnicodeN [NTDLL.436]
74 * FIXME: multibyte support
76 DWORD /* NTSTATUS */
77 WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
79 DWORD len;
80 LPWSTR x;
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;
92 /**************************************************************************
93 * RtlOemToUnicodeN [NTDLL.448]
95 DWORD /* NTSTATUS */
96 WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen)
98 DWORD len;
99 LPWSTR x;
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;
111 /**************************************************************************
112 * RtlInitAnsiString [NTDLL.399]
114 VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source)
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;
123 /**************************************************************************
124 * RtlInitString [NTDLL.402]
126 VOID WINAPI RtlInitString(PSTRING target,LPCSTR source)
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;
136 /**************************************************************************
137 * RtlInitUnicodeString [NTDLL.403]
139 VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source)
141 TRACE("%p %p(%s)\n", target, source, debugstr_w(source));
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;
151 /**************************************************************************
152 * RtlFreeUnicodeString [NTDLL.377]
154 VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str)
156 if (str->Buffer)
157 HeapFree(GetProcessHeap(),0,str->Buffer);
160 /**************************************************************************
161 * RtlFreeAnsiString [NTDLL.373]
163 VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
165 if( AnsiString->Buffer )
166 HeapFree( GetProcessHeap(),0,AnsiString->Buffer );
170 /**************************************************************************
171 * RtlUnicodeToOemN [NTDLL.515]
173 DWORD /* NTSTATUS */
174 WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen)
176 DWORD len;
177 LPSTR x;
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;
189 /**************************************************************************
190 * RtlUnicodeStringToOemString [NTDLL.511]
192 DWORD /* NTSTATUS */
193 WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
195 if (alloc) {
196 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
197 oem->MaximumLength = uni->Length/2+1;
199 oem->Length = uni->Length/2;
200 lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
201 return 0;
204 /**************************************************************************
205 * RtlUnicodeStringToAnsiString [NTDLL.507]
207 DWORD /* NTSTATUS */
208 WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc)
210 if (alloc) {
211 oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1;
212 oem->MaximumLength = uni->Length/2+1;
214 oem->Length = uni->Length/2;
215 lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1);
216 return 0;
219 /**************************************************************************
220 * RtlEqualUnicodeString [NTDLL]
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);
230 /**************************************************************************
231 * RtlUpcaseUnicodeString [NTDLL.520]
233 DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOLEAN doalloc)
235 LPWSTR s,t;
236 DWORD i,len;
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;
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;
255 /**************************************************************************
256 * RtlxOemStringToUnicodeSize [NTDLL.549]
258 UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str)
260 return str->Length*2+2;
263 /**************************************************************************
264 * RtlxAnsiStringToUnicodeSize [NTDLL.548]
266 UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str)
268 return str->Length*2+2;
271 /**************************************************************************
272 * RtlIsTextUnicode [NTDLL.417]
274 * Apply various feeble heuristics to guess whether
275 * the text buffer contains Unicode.
276 * FIXME: should implement more tests.
278 DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf)
280 LPWSTR s = buf;
281 DWORD flags = -1, out_flags = 0;
283 if (!len)
284 goto out;
285 if (pf)
286 flags = *pf;
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 ...
294 /* Check for an odd length ... pass if even. */
295 if (!(len & 1))
296 out_flags |= IS_TEXT_UNICODE_ODD_LENGTH;
298 /* Check for the special unicode marker byte. */
299 if (*s == 0xFEFF)
300 out_flags |= IS_TEXT_UNICODE_SIGNATURE;
303 * Check whether the string passed all of the tests.
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;
315 /******************************************************************************
316 * RtlCompareUnicodeString [NTDLL]
318 NTSTATUS WINAPI RtlCompareUnicodeString(
319 PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
321 FIXME("(%s,%s,0x%08x),stub!\n",debugstr_w(String1->Buffer),debugstr_w(String1->Buffer),CaseInSensitive);
322 return 0;