blob: 18710a701c58fc5cea45df1bd0884a4fc3309085 [file] [log] [blame]
/*
* 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 "crtdll.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 !CRTDLL_wcsncmp(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;
}