/* * Rtl string functions * * Copyright 1996-1998 Marcus Meissner */ #include "config.h" #include <stdlib.h> #include <string.h> #include <ctype.h> #ifdef HAVE_WCTYPE_H # include <wctype.h> #endif #include "wine/winestring.h" #include "heap.h" #include "winnls.h" #include "debugtools.h" #include "ntddk.h" DEFAULT_DEBUG_CHANNEL(ntdll) /* * STRING FUNCTIONS */ /************************************************************************** * RtlAnsiStringToUnicodeString [NTDLL.269] */ DWORD /* NTSTATUS */ WINAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING uni,PANSI_STRING ansi,BOOLEAN doalloc) { DWORD unilen = (ansi->Length+1)*sizeof(WCHAR); if (unilen>0xFFFF) return STATUS_INVALID_PARAMETER_2; uni->Length = unilen; if (doalloc) { uni->MaximumLength = unilen; uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen); if (!uni->Buffer) return STATUS_NO_MEMORY; } if (unilen>uni->MaximumLength) return STATUS_BUFFER_OVERFLOW; lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2); return STATUS_SUCCESS; } /************************************************************************** * RtlOemStringToUnicodeString [NTDLL.447] */ DWORD /* NTSTATUS */ WINAPI RtlOemStringToUnicodeString(PUNICODE_STRING uni,PSTRING ansi,BOOLEAN doalloc) { DWORD unilen = (ansi->Length+1)*sizeof(WCHAR); if (unilen>0xFFFF) return STATUS_INVALID_PARAMETER_2; uni->Length = unilen; if (doalloc) { uni->MaximumLength = unilen; uni->Buffer = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,unilen); if (!uni->Buffer) return STATUS_NO_MEMORY; } if (unilen>uni->MaximumLength) return STATUS_BUFFER_OVERFLOW; lstrcpynAtoW(uni->Buffer,ansi->Buffer,unilen/2); return STATUS_SUCCESS; } /************************************************************************** * RtlMultiByteToUnicodeN [NTDLL.436] * FIXME: multibyte support */ DWORD /* NTSTATUS */ WINAPI RtlMultiByteToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen) { DWORD len; LPWSTR x; len = oemlen; if (unilen/2 < len) len = unilen/2; x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR)); lstrcpynAtoW(x,oemstr,len+1); memcpy(unistr,x,len*2); if (reslen) *reslen = len*2; return 0; } /************************************************************************** * RtlOemToUnicodeN [NTDLL.448] */ DWORD /* NTSTATUS */ WINAPI RtlOemToUnicodeN(LPWSTR unistr,DWORD unilen,LPDWORD reslen,LPSTR oemstr,DWORD oemlen) { DWORD len; LPWSTR x; len = oemlen; if (unilen/2 < len) len = unilen/2; x=(LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(len+1)*sizeof(WCHAR)); lstrcpynAtoW(x,oemstr,len+1); memcpy(unistr,x,len*2); if (reslen) *reslen = len*2; return 0; } /************************************************************************** * RtlInitAnsiString [NTDLL.399] */ VOID WINAPI RtlInitAnsiString(PANSI_STRING target,LPCSTR source) { target->Length = target->MaximumLength = 0; target->Buffer = (LPSTR)source; if (!source) return; target->MaximumLength = lstrlenA(target->Buffer); target->Length = target->MaximumLength+1; } /************************************************************************** * RtlInitString [NTDLL.402] */ VOID WINAPI RtlInitString(PSTRING target,LPCSTR source) { target->Length = target->MaximumLength = 0; target->Buffer = (LPSTR)source; if (!source) return; target->MaximumLength = lstrlenA(target->Buffer); target->Length = target->MaximumLength+1; } /************************************************************************** * RtlInitUnicodeString [NTDLL.403] */ VOID WINAPI RtlInitUnicodeString(PUNICODE_STRING target,LPCWSTR source) { TRACE("%p %p(%s)\n", target, source, debugstr_w(source)); target->Length = target->MaximumLength = 0; target->Buffer = (LPWSTR)source; if (!source) return; target->MaximumLength = lstrlenW(target->Buffer)*2; target->Length = target->MaximumLength+2; } /************************************************************************** * RtlFreeUnicodeString [NTDLL.377] */ VOID WINAPI RtlFreeUnicodeString(PUNICODE_STRING str) { if (str->Buffer) HeapFree(GetProcessHeap(),0,str->Buffer); } /************************************************************************** * RtlFreeAnsiString [NTDLL.373] */ VOID WINAPI RtlFreeAnsiString(PANSI_STRING AnsiString) { if( AnsiString->Buffer ) HeapFree( GetProcessHeap(),0,AnsiString->Buffer ); } /************************************************************************** * RtlUnicodeToOemN [NTDLL.515] */ DWORD /* NTSTATUS */ WINAPI RtlUnicodeToOemN(LPSTR oemstr,DWORD oemlen,LPDWORD reslen,LPWSTR unistr,DWORD unilen) { DWORD len; LPSTR x; len = oemlen; if (unilen/2 < len) len = unilen/2; x=(LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len+1); lstrcpynWtoA(x,unistr,len+1); memcpy(oemstr,x,len); if (reslen) *reslen = len; return 0; } /************************************************************************** * RtlUnicodeStringToOemString [NTDLL.511] */ DWORD /* NTSTATUS */ WINAPI RtlUnicodeStringToOemString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc) { if (alloc) { oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1; oem->MaximumLength = uni->Length/2+1; } oem->Length = uni->Length/2; lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1); return 0; } /************************************************************************** * RtlUnicodeStringToAnsiString [NTDLL.507] */ DWORD /* NTSTATUS */ WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING oem,PUNICODE_STRING uni,BOOLEAN alloc) { if (alloc) { oem->Buffer = (LPSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,uni->Length/2)+1; oem->MaximumLength = uni->Length/2+1; } oem->Length = uni->Length/2; lstrcpynWtoA(oem->Buffer,uni->Buffer,uni->Length/2+1); return 0; } /************************************************************************** * RtlEqualUnicodeString [NTDLL] */ DWORD WINAPI RtlEqualUnicodeString(PUNICODE_STRING s1,PUNICODE_STRING s2,DWORD x) { FIXME("(%s,%s,%ld),stub!\n",debugstr_w(s1->Buffer),debugstr_w(s2->Buffer),x); return 0; if (s1->Length != s2->Length) return 1; return !lstrncmpW(s1->Buffer,s2->Buffer,s1->Length/2); } /************************************************************************** * RtlUpcaseUnicodeString [NTDLL.520] */ DWORD WINAPI RtlUpcaseUnicodeString(PUNICODE_STRING dest,PUNICODE_STRING src,BOOLEAN doalloc) { LPWSTR s,t; DWORD i,len; len = src->Length; if (doalloc) { dest->MaximumLength = len; dest->Buffer = (LPWSTR)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,len); if (!dest->Buffer) return STATUS_NO_MEMORY; } if (dest->MaximumLength < len) return STATUS_BUFFER_OVERFLOW; s=dest->Buffer;t=src->Buffer; /* len is in bytes */ for (i=0;i<len/2;i++) s[i] = towupper(t[i]); return STATUS_SUCCESS; } /************************************************************************** * RtlxOemStringToUnicodeSize [NTDLL.549] */ UINT WINAPI RtlxOemStringToUnicodeSize(PSTRING str) { return str->Length*2+2; } /************************************************************************** * RtlxAnsiStringToUnicodeSize [NTDLL.548] */ UINT WINAPI RtlxAnsiStringToUnicodeSize(PANSI_STRING str) { return str->Length*2+2; } /************************************************************************** * RtlIsTextUnicode [NTDLL.417] * * Apply various feeble heuristics to guess whether * the text buffer contains Unicode. * FIXME: should implement more tests. */ DWORD WINAPI RtlIsTextUnicode(LPVOID buf, DWORD len, DWORD *pf) { LPWSTR s = buf; DWORD flags = -1, out_flags = 0; if (!len) goto out; if (pf) flags = *pf; /* * Apply various tests to the text string. According to the * docs, each test "passed" sets the corresponding flag in * the output flags. But some of the tests are mutually * exclusive, so I don't see how you could pass all tests ... */ /* Check for an odd length ... pass if even. */ if (!(len & 1)) out_flags |= IS_TEXT_UNICODE_ODD_LENGTH; /* Check for the special unicode marker byte. */ if (*s == 0xFEFF) out_flags |= IS_TEXT_UNICODE_SIGNATURE; /* * Check whether the string passed all of the tests. */ flags &= ITU_IMPLEMENTED_TESTS; if ((out_flags & flags) != flags) len = 0; out: if (pf) *pf = out_flags; return len; } /****************************************************************************** * RtlCompareUnicodeString [NTDLL] */ NTSTATUS WINAPI RtlCompareUnicodeString( PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive) { FIXME("(%s,%s,0x%08x),stub!\n",debugstr_w(String1->Buffer),debugstr_w(String1->Buffer),CaseInSensitive); return 0; }