libwinpr-crt: implement unicode functions
This commit is contained in:
parent
a09dbbd671
commit
5207d65c2a
@ -25,6 +25,10 @@
|
||||
|
||||
#include <winpr/winpr.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winnls.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/string.h>
|
||||
|
||||
#endif /* WINPR_CRT_H */
|
||||
|
@ -27,6 +27,23 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#define CSTR_LESS_THAN 1
|
||||
#define CSTR_EQUAL 2
|
||||
#define CSTR_GREATER_THAN 3
|
||||
|
||||
#define CP_ACP 0
|
||||
#define CP_OEMCP 1
|
||||
#define CP_MACCP 2
|
||||
#define CP_THREAD_ACP 3
|
||||
#define CP_SYMBOL 42
|
||||
#define CP_UTF7 65000
|
||||
#define CP_UTF8 65001
|
||||
|
||||
#define MB_PRECOMPOSED 0x00000001
|
||||
#define MB_COMPOSITE 0x00000002
|
||||
#define MB_USEGLYPHCHARS 0x00000004
|
||||
#define MB_ERR_INVALID_CHARS 0x00000008
|
||||
|
||||
WINPR_API char* _strdup(const char* strSource);
|
||||
WINPR_API wchar_t* _wcsdup(const wchar_t* strSource);
|
||||
|
||||
@ -102,6 +119,12 @@ WINPR_API BOOL IsCharLowerW(WCHAR ch);
|
||||
#define IsCharLower IsCharLowerA
|
||||
#endif
|
||||
|
||||
WINPR_API int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
|
||||
int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
|
||||
|
||||
WINPR_API int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
|
||||
LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_CRT_STRING_H */
|
||||
|
@ -285,4 +285,219 @@ BOOL IsCharLowerW(WCHAR ch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Advanced String Techniques in C++ - Part I: Unicode
|
||||
* http://www.flipcode.com/archives/Advanced_String_Techniques_in_C-Part_I_Unicode.shtml
|
||||
*/
|
||||
|
||||
/*
|
||||
* Conversion *to* Unicode
|
||||
* MultiByteToWideChar: http://msdn.microsoft.com/en-us/library/windows/desktop/dd319072/
|
||||
*/
|
||||
|
||||
int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr,
|
||||
int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar)
|
||||
{
|
||||
size_t ibl;
|
||||
size_t obl;
|
||||
char* pin;
|
||||
char* pout;
|
||||
char* pout0;
|
||||
|
||||
if (lpMultiByteStr == NULL)
|
||||
return 0;
|
||||
|
||||
if (cbMultiByte < 0)
|
||||
cbMultiByte = strlen(lpMultiByteStr) + 1;
|
||||
|
||||
ibl = cbMultiByte;
|
||||
obl = 2 * ibl;
|
||||
|
||||
if (cchWideChar < 1)
|
||||
return (obl / 2);
|
||||
|
||||
pin = (char*) lpMultiByteStr;
|
||||
pout0 = (char*) lpWideCharStr;
|
||||
pout = pout0;
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
{
|
||||
iconv_t* out_iconv_h;
|
||||
|
||||
out_iconv_h = iconv_open(WINDOWS_CODEPAGE, DEFAULT_CODEPAGE);
|
||||
|
||||
if (errno == EINVAL)
|
||||
{
|
||||
printf("Error opening iconv converter to %s from %s\n", WINDOWS_CODEPAGE, DEFAULT_CODEPAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iconv(out_iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
|
||||
{
|
||||
printf("MultiByteToWideChar: iconv() error\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iconv_close(out_iconv_h);
|
||||
}
|
||||
#else
|
||||
while ((ibl > 0) && (obl > 0))
|
||||
{
|
||||
unsigned int wc;
|
||||
|
||||
wc = (unsigned int) (unsigned char) (*pin++);
|
||||
ibl--;
|
||||
|
||||
if (wc >= 0xF0)
|
||||
{
|
||||
wc = (wc - 0xF0) << 18;
|
||||
wc += ((unsigned int) (unsigned char) (*pin++) - 0x80) << 12;
|
||||
wc += ((unsigned int) (unsigned char) (*pin++) - 0x80) << 6;
|
||||
wc += ((unsigned int) (unsigned char) (*pin++) - 0x80);
|
||||
ibl -= 3;
|
||||
}
|
||||
else if (wc >= 0xE0)
|
||||
{
|
||||
wc = (wc - 0xE0) << 12;
|
||||
wc += ((unsigned int) (unsigned char) (*pin++) - 0x80) << 6;
|
||||
wc += ((unsigned int) (unsigned char) (*pin++) - 0x80);
|
||||
ibl -= 2;
|
||||
}
|
||||
else if (wc >= 0xC0)
|
||||
{
|
||||
wc = (wc - 0xC0) << 6;
|
||||
wc += ((unsigned int) (unsigned char) (*pin++) - 0x80);
|
||||
ibl -= 1;
|
||||
}
|
||||
|
||||
if (wc <= 0xFFFF)
|
||||
{
|
||||
*pout++ = (char) (wc & 0xFF);
|
||||
*pout++ = (char) (wc >> 8);
|
||||
obl -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
wc -= 0x10000;
|
||||
*pout++ = (char) ((wc >> 10) & 0xFF);
|
||||
*pout++ = (char) ((wc >> 18) + 0xD8);
|
||||
*pout++ = (char) (wc & 0xFF);
|
||||
*pout++ = (char) (((wc >> 8) & 0x03) + 0xDC);
|
||||
obl -= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ibl > 0)
|
||||
{
|
||||
printf("MultiByteToWideChar: string not fully converted - %d chars left\n", (int) ibl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (pout - pout0) / 2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Conversion *from* Unicode
|
||||
* WideCharToMultiByte: http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130/
|
||||
*/
|
||||
|
||||
int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar,
|
||||
LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar)
|
||||
{
|
||||
char* pout;
|
||||
char* conv_pout;
|
||||
size_t conv_in_len;
|
||||
size_t conv_out_len;
|
||||
unsigned char* conv_pin;
|
||||
|
||||
if (cchWideChar < 1)
|
||||
|
||||
if (cchWideChar == 0)
|
||||
return 0;
|
||||
|
||||
conv_pin = (unsigned char*) lpWideCharStr;
|
||||
conv_in_len = cchWideChar;
|
||||
pout = lpMultiByteStr;
|
||||
conv_pout = pout;
|
||||
conv_out_len = cbMultiByte;
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
{
|
||||
iconv_t* in_iconv_h;
|
||||
|
||||
in_iconv_h = iconv_open(DEFAULT_CODEPAGE, WINDOWS_CODEPAGE);
|
||||
|
||||
if (errno == EINVAL)
|
||||
{
|
||||
printf("Error opening iconv converter to %s from %s\n", DEFAULT_CODEPAGE, WINDOWS_CODEPAGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (iconv(in_iconv_h, (ICONV_CONST char **) &conv_pin, &conv_in_len, &conv_pout, &conv_out_len) == (size_t) - 1)
|
||||
{
|
||||
printf("WideCharToMultiByte: iconv failure\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
iconv_close(in_iconv_h);
|
||||
}
|
||||
#else
|
||||
while (conv_in_len >= 2)
|
||||
{
|
||||
unsigned int wc;
|
||||
|
||||
wc = (unsigned int) (unsigned char) (*conv_pin++);
|
||||
wc += ((unsigned int) (unsigned char) (*conv_pin++)) << 8;
|
||||
conv_in_len -= 2;
|
||||
|
||||
if (wc >= 0xD800 && wc <= 0xDFFF && conv_in_len >= 2)
|
||||
{
|
||||
/* Code points U+10000 to U+10FFFF using surrogate pair */
|
||||
wc = ((wc - 0xD800) << 10) + 0x10000;
|
||||
wc += (unsigned int) (unsigned char) (*conv_pin++);
|
||||
wc += ((unsigned int) (unsigned char) (*conv_pin++) - 0xDC) << 8;
|
||||
conv_in_len -= 2;
|
||||
}
|
||||
|
||||
if (wc <= 0x7F)
|
||||
{
|
||||
*conv_pout++ = (char) wc;
|
||||
conv_out_len--;
|
||||
}
|
||||
else if (wc <= 0x07FF)
|
||||
{
|
||||
*conv_pout++ = (char) (0xC0 + (wc >> 6));
|
||||
*conv_pout++ = (char) (0x80 + (wc & 0x3F));
|
||||
conv_out_len -= 2;
|
||||
}
|
||||
else if (wc <= 0xFFFF)
|
||||
{
|
||||
*conv_pout++ = (char) (0xE0 + (wc >> 12));
|
||||
*conv_pout++ = (char) (0x80 + ((wc >> 6) & 0x3F));
|
||||
*conv_pout++ = (char) (0x80 + (wc & 0x3F));
|
||||
conv_out_len -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*conv_pout++ = (char) (0xF0 + (wc >> 18));
|
||||
*conv_pout++ = (char) (0x80 + ((wc >> 12) & 0x3F));
|
||||
*conv_pout++ = (char) (0x80 + ((wc >> 6) & 0x3F));
|
||||
*conv_pout++ = (char) (0x80 + (wc & 0x3F));
|
||||
conv_out_len -= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (conv_in_len > 0)
|
||||
{
|
||||
printf("WideCharToMultiByte: conversion failure - %d chars left\n", (int) conv_in_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*conv_pout = 0;
|
||||
|
||||
return conv_out_len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <freerdp/crypto/tls.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/credssp.h>
|
||||
|
||||
@ -79,16 +80,17 @@
|
||||
|
||||
void credssp_SetContextIdentity(rdpCredssp* context, char* user, char* domain, char* password)
|
||||
{
|
||||
size_t size;
|
||||
context->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
|
||||
context->identity.User = (uint16*) freerdp_uniconv_out(context->uniconv, user, &size);
|
||||
context->identity.UserLength = (uint32) size;
|
||||
context->identity.UserLength = strlen(user) * 2;
|
||||
context->identity.User = (uint16*) malloc(context->identity.UserLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, user, strlen(user), (LPWSTR) context->identity.User, context->identity.UserLength / 2);
|
||||
|
||||
if (domain)
|
||||
{
|
||||
context->identity.Domain = (uint16*) freerdp_uniconv_out(context->uniconv, domain, &size);
|
||||
context->identity.DomainLength = (uint32) size;
|
||||
context->identity.DomainLength = strlen(user) * 2;
|
||||
context->identity.Domain = (uint16*) malloc(context->identity.DomainLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, user, strlen(user), (LPWSTR) context->identity.Domain, context->identity.DomainLength / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -96,8 +98,9 @@ void credssp_SetContextIdentity(rdpCredssp* context, char* user, char* domain, c
|
||||
context->identity.DomainLength = 0;
|
||||
}
|
||||
|
||||
context->identity.Password = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) password, &size);
|
||||
context->identity.PasswordLength = (uint32) size;
|
||||
context->identity.PasswordLength = strlen(password) * 2;
|
||||
context->identity.Password = (uint16*) malloc(context->identity.PasswordLength);
|
||||
MultiByteToWideChar(CP_ACP, 0, password, strlen(password), (LPWSTR) context->identity.Password, context->identity.PasswordLength / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user