diff --git a/channels/client/addin.c b/channels/client/addin.c index 4663e38d9..563a33afd 100644 --- a/channels/client/addin.c +++ b/channels/client/addin.c @@ -148,8 +148,10 @@ error_out: static HANDLE FindFirstFileUTF8(LPCSTR pszSearchPath, WIN32_FIND_DATAW* FindData) { HANDLE hdl = INVALID_HANDLE_VALUE; - WCHAR* wpath = NULL; - if (ConvertToUnicode(CP_UTF8, 0, pszSearchPath, -1, &wpath, 0) <= 0) + if (!pszSearchPath) + return hdl; + WCHAR* wpath = ConvertUtf8ToWCharAlloc(pszSearchPath, NULL); + if (!wpath) return hdl; hdl = FindFirstFileW(wpath, FindData); @@ -254,7 +256,9 @@ static FREERDP_ADDIN** freerdp_channels_list_dynamic_addins(LPCSTR pszName, LPCS goto error_out; } - if (ConvertFromUnicode(CP_UTF8, 0, FindData.cFileName, -1, &cFileName, 0, NULL, NULL) <= 0) + cFileName = + ConvertWCharNToUtf8Alloc(FindData.cFileName, ARRAYSIZE(FindData.cFileName), NULL); + if (!cFileName) goto skip; nDashes = 0; diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index db3ee0e63..74aedc303 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -619,9 +619,7 @@ static UINT cliprdr_client_capabilities(CliprdrClientContext* context, static UINT cliprdr_temp_directory(CliprdrClientContext* context, const CLIPRDR_TEMP_DIRECTORY* tempDirectory) { - int length; wStream* s; - WCHAR* wszTempDir = NULL; cliprdrPlugin* cliprdr; WINPR_ASSERT(context); @@ -630,7 +628,8 @@ static UINT cliprdr_temp_directory(CliprdrClientContext* context, cliprdr = (cliprdrPlugin*)context->handle; WINPR_ASSERT(cliprdr); - s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, 260 * sizeof(WCHAR)); + const size_t tmpDirCharLen = sizeof(tempDirectory->szTempDir) / sizeof(WCHAR); + s = cliprdr_packet_new(CB_TEMP_DIRECTORY, 0, tmpDirCharLen * sizeof(WCHAR)); if (!s) { @@ -638,19 +637,13 @@ static UINT cliprdr_temp_directory(CliprdrClientContext* context, return ERROR_INTERNAL_ERROR; } - length = ConvertToUnicode(CP_UTF8, 0, tempDirectory->szTempDir, -1, &wszTempDir, 0); - - if (length < 0) + if (Stream_Write_UTF16_String_From_UTF8(s, tmpDirCharLen - 1, tempDirectory->szTempDir, + ARRAYSIZE(tempDirectory->szTempDir), TRUE) < 0) return ERROR_INTERNAL_ERROR; - /* Path must be 260 UTF16 characters with '\0' termination. * ensure this here */ - if (length >= 260) - length = 259; + Stream_Write_UINT16(s, 0); - Stream_Write_UTF16_String(s, wszTempDir, length); - Stream_Zero(s, 520 - (length * sizeof(WCHAR))); - free(wszTempDir); WLog_Print(cliprdr->log, WLOG_DEBUG, "TempDirectory: %s", tempDirectory->szTempDir); return cliprdr_packet_send(cliprdr, s); } diff --git a/channels/cliprdr/cliprdr_common.c b/channels/cliprdr/cliprdr_common.c index 305f3abe6..59f015f64 100644 --- a/channels/cliprdr/cliprdr_common.c +++ b/channels/cliprdr/cliprdr_common.c @@ -185,9 +185,7 @@ wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, { wStream* s; UINT32 index; - int cchWideChar; - LPWSTR lpWideCharStr; - int formatNameSize; + size_t formatNameSize = 0; char* szFormatName; WCHAR* wszFormatName; BOOL asciiNames = FALSE; @@ -234,20 +232,21 @@ wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, wszFormatName = NULL; if (szFormatName) - formatNameSize = - ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, 0); - - if (formatNameSize < 0) { - Stream_Free(s, TRUE); - return NULL; + wszFormatName = ConvertUtf8ToWCharAlloc(szFormatName, &formatNameSize); + + if (!wszFormatName) + { + Stream_Free(s, TRUE); + return NULL; + } } if (formatNameSize > 15) formatNameSize = 15; /* size in bytes instead of wchar */ - formatNameSize *= 2; + formatNameSize *= sizeof(WCHAR); if (wszFormatName) Stream_Write(s, wszFormatName, (size_t)formatNameSize); @@ -264,14 +263,15 @@ wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, { format = (CLIPRDR_FORMAT*)&(formatList->formats[index]); length += 4; - formatNameSize = 2; + formatNameSize = sizeof(WCHAR); if (format->formatName) - formatNameSize = - MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0) * 2; - - if (formatNameSize < 0) - return NULL; + { + SSIZE_T size = ConvertUtf8ToWChar(format->formatName, NULL, 0); + if (size < 0) + return NULL; + formatNameSize = (size_t)size * sizeof(WCHAR); + } length += (UINT32)formatNameSize; } @@ -300,17 +300,12 @@ wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, return NULL; } - lpWideCharStr = (LPWSTR)Stream_Pointer(s); - cchWideChar = (int)(rem / 2); - formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, - lpWideCharStr, cchWideChar) * - 2; - if (formatNameSize < 0) + const size_t len = strnlen(format->formatName, rem / sizeof(WCHAR)); + if (Stream_Write_UTF16_String_From_UTF8(s, len, format->formatName, len, TRUE) < 0) { Stream_Free(s, TRUE); return NULL; } - Stream_Seek(s, (size_t)formatNameSize); } else { @@ -478,16 +473,11 @@ UINT cliprdr_read_format_list(wStream* s, CLIPRDR_FORMAT_LIST* formatList, BOOL { if (wszFormatName[0]) { - /* ConvertFromUnicode always returns a null-terminated - * string on success, even if the source string isn't. - */ - if (ConvertFromUnicode(CP_UTF8, 0, wszFormatName, 16, - &(formats[index].formatName), 0, NULL, NULL) < 1) - { - WLog_ERR(TAG, "failed to convert short clipboard format name"); - error = ERROR_INTERNAL_ERROR; + CLIPRDR_FORMAT* format = &formats[index]; + + format->formatName = ConvertWCharNToUtf8Alloc(wszFormatName, 16, NULL); + if (!format->formatName) goto error_out; - } } } @@ -543,13 +533,10 @@ UINT cliprdr_read_format_list(wStream* s, CLIPRDR_FORMAT_LIST* formatList, BOOL if (formatNameLength) { - if (ConvertFromUnicode(CP_UTF8, 0, wszFormatName, formatNameLength, - &format->formatName, 0, NULL, NULL) < 1) - { - WLog_ERR(TAG, "failed to convert long clipboard format name"); - error = ERROR_INTERNAL_ERROR; + format->formatName = + ConvertWCharNToUtf8Alloc(wszFormatName, formatNameLength, NULL); + if (!format->formatName) goto error_out; - } } index++; diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 27634cf8b..09208b31d 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -629,10 +629,9 @@ static UINT cliprdr_server_receive_temporary_directory(CliprdrServerContext* con return ERROR_INVALID_DATA; } - memset(cliprdr->temporaryDirectory, 0, ARRAYSIZE(cliprdr->temporaryDirectory)); - - if (ConvertFromUnicode(CP_UTF8, 0, wszTempDir, -1, &(cliprdr->temporaryDirectory), - ARRAYSIZE(cliprdr->temporaryDirectory), NULL, NULL) < 1) + if (ConvertWCharNToUtf8(wszTempDir, ARRAYSIZE(cliprdr->temporaryDirectory), + cliprdr->temporaryDirectory, + ARRAYSIZE(cliprdr->temporaryDirectory)) < 0) { WLog_ERR(TAG, "failed to convert temporary directory name"); return ERROR_INVALID_DATA; diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index 57f2e0fd3..cde947bbd 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -44,13 +44,12 @@ #include "drive_file.h" #ifdef WITH_DEBUG_RDPDR -#define DEBUG_WSTR(msg, wstr) \ - do \ - { \ - LPSTR lpstr; \ - ConvertFromUnicode(CP_UTF8, 0, wstr, -1, &lpstr, 0, NULL, NULL); \ - WLog_DBG(TAG, msg, lpstr); \ - free(lpstr); \ +#define DEBUG_WSTR(msg, wstr) \ + do \ + { \ + char lpstr[1024] = { 0 }; \ + ConvertWCharToUtf8(wstr, lpstr, ARRAYSIZE(lpstr)); \ + WLog_DBG(TAG, msg, lpstr); \ } while (0) #else #define DEBUG_WSTR(msg, wstr) \ @@ -121,8 +120,7 @@ static WCHAR* drive_file_combine_fullpath(const WCHAR* base_path, const WCHAR* p if (_wcsstr(&fullpath[base_path_length], dotdot)) { char abuffer[MAX_PATH] = { 0 }; - ConvertFromUnicode(CP_UTF8, 0, &fullpath[base_path_length], -1, (char**)&abuffer, - ARRAYSIZE(abuffer) - 1, NULL, NULL); + ConvertWCharToUtf8(&fullpath[base_path_length], abuffer, ARRAYSIZE(abuffer)); WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' from server, aborting!", &abuffer[base_path_length]); diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c index 574ca77b0..a376af58e 100644 --- a/channels/drive/client/drive_main.c +++ b/channels/drive/client/drive_main.c @@ -62,8 +62,6 @@ typedef struct rdpContext* rdpcontext; } DRIVE_DEVICE; -static UINT sys_code_page = 0; - static DWORD drive_map_windows_err(DWORD fs_errno) { DWORD rc; @@ -443,10 +441,6 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* { UINT32 FsInformationClass; wStream* output = NULL; - char* volumeLabel = { "FREERDP" }; - char* diskType = { "FAT32" }; - WCHAR* outStr = NULL; - int length; DWORD lpSectorsPerCluster; DWORD lpBytesPerSector; DWORD lpNumberOfFreeClusters; @@ -468,20 +462,16 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* switch (FsInformationClass) { case FileFsVolumeInformation: - + { /* http://msdn.microsoft.com/en-us/library/cc232108.aspx */ - if ((length = ConvertToUnicode(sys_code_page, 0, volumeLabel, -1, &outStr, 0) * 2) <= 0) - { - WLog_ERR(TAG, "ConvertToUnicode failed!"); - return CHANNEL_RC_NO_MEMORY; - } + const WCHAR volumeLabel[] = { 'F', 'R', 'E', 'E', 'R', 'D', 'P', '\0' }; + const size_t length = 17ul + sizeof(volumeLabel); - Stream_Write_UINT32(output, 17 + length); /* Length */ + Stream_Write_UINT32(output, length); /* Length */ - if (!Stream_EnsureRemainingCapacity(output, 17 + length)) + if (!Stream_EnsureRemainingCapacity(output, length)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); - free(outStr); return CHANNEL_RC_NO_MEMORY; } @@ -490,12 +480,12 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* Stream_Write_UINT32(output, wfad.ftCreationTime.dwHighDateTime); /* VolumeCreationTime */ Stream_Write_UINT32(output, lpNumberOfFreeClusters & 0xffff); /* VolumeSerialNumber */ - Stream_Write_UINT32(output, length); /* VolumeLabelLength */ + Stream_Write_UINT32(output, sizeof(volumeLabel)); /* VolumeLabelLength */ Stream_Write_UINT8(output, 0); /* SupportsObjects */ /* Reserved(1), MUST NOT be added! */ - Stream_Write(output, outStr, length); /* VolumeLabel (Unicode) */ - free(outStr); - break; + Stream_Write(output, volumeLabel, sizeof(volumeLabel)); /* VolumeLabel (Unicode) */ + } + break; case FileFsSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232107.aspx */ @@ -514,19 +504,14 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* break; case FileFsAttributeInformation: - + { /* http://msdn.microsoft.com/en-us/library/cc232101.aspx */ - if ((length = ConvertToUnicode(sys_code_page, 0, diskType, -1, &outStr, 0) * 2) <= 0) - { - WLog_ERR(TAG, "ConvertToUnicode failed!"); - return CHANNEL_RC_NO_MEMORY; - } + const WCHAR diskType[] = { 'F', 'A', 'T', '3', '2', '\0' }; + const size_t length = 12ul + sizeof(diskType); + Stream_Write_UINT32(output, length); /* Length */ - Stream_Write_UINT32(output, 12 + length); /* Length */ - - if (!Stream_EnsureRemainingCapacity(output, 12 + length)) + if (!Stream_EnsureRemainingCapacity(output, length)) { - free(outStr); WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } @@ -534,10 +519,10 @@ static UINT drive_process_irp_query_volume_information(DRIVE_DEVICE* drive, IRP* Stream_Write_UINT32(output, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ Stream_Write_UINT32(output, MAX_PATH); /* MaximumComponentNameLength */ - Stream_Write_UINT32(output, length); /* FileSystemNameLength */ - Stream_Write(output, outStr, length); /* FileSystemName (Unicode) */ - free(outStr); - break; + Stream_Write_UINT32(output, sizeof(diskType)); /* FileSystemNameLength */ + Stream_Write(output, diskType, sizeof(diskType)); /* FileSystemName (Unicode) */ + } + break; case FileFsFullSizeInformation: /* http://msdn.microsoft.com/en-us/library/cc232104.aspx */ @@ -947,9 +932,9 @@ static UINT drive_register_drive_path(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, if ((pathLength > 1) && (path[pathLength - 1] == '/')) pathLength--; - if (ConvertToUnicode(sys_code_page, 0, path, pathLength, &drive->path, 0) <= 0) + drive->path = ConvertUtf8NToWCharAlloc(path, pathLength, NULL); + if (!drive->path) { - WLog_ERR(TAG, "ConvertToUnicode failed!"); error = CHANNEL_RC_NO_MEMORY; goto out_error; } @@ -1018,8 +1003,6 @@ UINT drive_DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) WINPR_ASSERT(drive); #ifndef WIN32 - sys_code_page = CP_UTF8; - if (strcmp(drive->Path, "*") == 0) { /* all drives */ @@ -1047,8 +1030,6 @@ UINT drive_DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) error = drive_register_drive_path(pEntryPoints, drive->device.Name, drive->Path, drive->automount); #else - sys_code_page = GetACP(); - /* Special case: path[0] == '*' -> export all drives */ /* Special case: path[0] == '%' -> user home dir */ if (strcmp(drive->Path, "%") == 0) diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c index 46396a683..dbf49322e 100644 --- a/channels/parallel/client/parallel_main.c +++ b/channels/parallel/client/parallel_main.c @@ -80,7 +80,6 @@ typedef struct static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) { char* path = NULL; - int status; WCHAR* ptr; UINT32 PathLength; if (!Stream_SafeSeek(irp->input, 28)) @@ -90,17 +89,14 @@ static UINT parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, 4)) return ERROR_INVALID_DATA; Stream_Read_UINT32(irp->input, PathLength); + if (PathLength < sizeof(WCHAR)) + return ERROR_INVALID_DATA; ptr = (WCHAR*)Stream_Pointer(irp->input); if (!Stream_SafeSeek(irp->input, PathLength)) return ERROR_INVALID_DATA; - status = ConvertFromUnicode(CP_UTF8, 0, ptr, PathLength / 2, &path, 0, NULL, NULL); - - if (status < 1) - if (!(path = (char*)calloc(1, 1))) - { - WLog_ERR(TAG, "calloc failed!"); - return CHANNEL_RC_NO_MEMORY; - } + path = ConvertWCharNToUtf8Alloc(ptr, PathLength / sizeof(WCHAR), NULL); + if (!path) + return CHANNEL_RC_NO_MEMORY; parallel->id = irp->devman->id_sequence++; parallel->file = open(parallel->path, O_RDWR); diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index 08e57d751..459221c60 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -291,7 +291,6 @@ static BOOL printer_load_from_config(const rdpSettings* settings, rdpPrinter* pr WCHAR* wname = NULL; size_t wlen; char* path = NULL; - int rc; UINT32 flags = 0; void* DriverName = NULL; UINT32 DriverNameLen = 0; @@ -302,17 +301,17 @@ static BOOL printer_load_from_config(const rdpSettings* settings, rdpPrinter* pr UINT32 PrinterNameLen = 0; WCHAR* wptr = NULL; - if (!settings || !printer) + if (!settings || !printer || !printer->name) return FALSE; - rc = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &wname, 0); + wname = ConvertUtf8ToWCharAlloc(printer->name, &wlen); - if (rc <= 0) + if (!wname) goto fail; - wlen = _wcslen(wname) + 1; + wlen++; path = get_printer_config_path(settings, wname, wlen * sizeof(WCHAR)); - PrinterNameLen = (wlen + 1) * sizeof(WCHAR); + PrinterNameLen = wlen * sizeof(WCHAR); if (!path) goto fail; @@ -326,8 +325,11 @@ static BOOL printer_load_from_config(const rdpSettings* settings, rdpPrinter* pr if (!printer_read_setting(path, PRN_CONF_DRIVER, &DriverName, &DriverNameLen)) { - DriverNameLen = - ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, (LPWSTR*)&DriverName, 0) * 2 + 1; + size_t len = 0; + DriverName = ConvertUtf8ToWCharAlloc(printer->driver, &len); + if (!DriverName) + goto fail; + DriverNameLen = (len + 1) * sizeof(WCHAR); } if (!printer_read_setting(path, PRN_CONF_DATA, &CachedPrinterConfigData, &CachedFieldsLen)) @@ -385,19 +387,18 @@ static BOOL printer_save_default_config(const rdpSettings* settings, rdpPrinter* WCHAR* driver = NULL; size_t wlen, dlen; char* path = NULL; - int rc; - if (!settings || !printer) + if (!settings || !printer || !printer->name || !printer->driver) return FALSE; - rc = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &wname, 0); + wname = ConvertUtf8ToWCharAlloc(printer->name, NULL); - if (rc <= 0) + if (wname) goto fail; - rc = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &driver, 0); + driver = ConvertUtf8ToWCharAlloc(printer->driver, NULL); - if (rc <= 0) + if (driver) goto fail; wlen = _wcslen(wname) + 1; diff --git a/channels/printer/client/win/printer_win.c b/channels/printer/client/win/printer_win.c index d8b01a025..fa8408dad 100644 --- a/channels/printer/client/win/printer_win.c +++ b/channels/printer/client/win/printer_win.c @@ -237,16 +237,19 @@ static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, cons { rdpWinPrinter* win_printer; DWORD needed = 0; - int status; PRINTER_INFO_2* prninfo = NULL; + if (!name) + return NULL; + win_printer = (rdpWinPrinter*)calloc(1, sizeof(rdpWinPrinter)); if (!win_printer) return NULL; win_printer->printer.backend = &win_driver->driver; win_printer->printer.id = win_driver->id_sequence++; - if (ConvertFromUnicode(CP_UTF8, 0, name, -1, &win_printer->printer.name, 0, NULL, NULL) < 1) + win_printer->printer.name = ConvertWCharToUtf8Alloc(name, NULL); + if (!win_printer->printer.name) goto fail; if (!win_printer->printer.name) @@ -277,13 +280,11 @@ static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, cons } if (drivername) - status = ConvertFromUnicode(CP_UTF8, 0, drivername, -1, &win_printer->printer.driver, 0, - NULL, NULL); + win_printer->printer.driver = ConvertWCharToUtf8Alloc(drivername, NULL); else - status = ConvertFromUnicode(CP_UTF8, 0, prninfo->pDriverName, -1, - &win_printer->printer.driver, 0, NULL, NULL); + win_printer->printer.driver = ConvertWCharToUtf8Alloc(prninfo->pDriverName, NULL); GlobalFree(prninfo); - if (!win_printer->printer.driver || (status <= 0)) + if (!win_printer->printer.driver) goto fail; win_printer->printer.AddRef(&win_printer->printer); @@ -393,13 +394,13 @@ static rdpPrinter* printer_win_get_printer(rdpPrinterDriver* driver, const char* if (name) { - ConvertToUnicode(CP_UTF8, 0, name, -1, &nameW, 0); + nameW = ConvertUtf8ToWCharAlloc(name, NULL); if (!nameW) return NULL; } if (driverName) { - ConvertToUnicode(CP_UTF8, 0, driverName, -1, &driverNameW, 0); + driverNameW = ConvertUtf8ToWCharAlloc(driverName, NULL); if (!driverNameW) return NULL; } diff --git a/channels/rail/server/rail_main.c b/channels/rail/server/rail_main.c index fe0384356..403cb6753 100644 --- a/channels/rail/server/rail_main.c +++ b/channels/rail/server/rail_main.c @@ -665,36 +665,26 @@ static UINT rail_read_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)exeLen + workLen + argLen)) return ERROR_INVALID_DATA; + if (exeLen > 0) { - const int len = exeLen / sizeof(WCHAR); - int rc; - const WCHAR* str = (const WCHAR*)Stream_Pointer(s); - rc = ConvertFromUnicode(CP_UTF8, 0, str, len, &exec->RemoteApplicationProgram, 0, NULL, - NULL); - if (rc != len) + const SSIZE_T len = exeLen / sizeof(WCHAR); + exec->RemoteApplicationProgram = Stream_Read_UTF16_String_As_UTF8(s, len, NULL); + if (!exec->RemoteApplicationProgram) goto fail; - Stream_Seek(s, exeLen); } + if (workLen > 0) { - const int len = workLen / sizeof(WCHAR); - int rc; - - const WCHAR* str = (const WCHAR*)Stream_Pointer(s); - rc = ConvertFromUnicode(CP_UTF8, 0, str, len, &exec->RemoteApplicationProgram, 0, NULL, - NULL); - if (rc != len) + const SSIZE_T len = workLen / sizeof(WCHAR); + exec->RemoteApplicationWorkingDir = Stream_Read_UTF16_String_As_UTF8(s, len, NULL); + if (!exec->RemoteApplicationWorkingDir) goto fail; - Stream_Seek(s, workLen); } + if (argLen > 0) { - const int len = argLen / sizeof(WCHAR); - int rc; - const WCHAR* str = (const WCHAR*)Stream_Pointer(s); - rc = ConvertFromUnicode(CP_UTF8, 0, str, len, &exec->RemoteApplicationProgram, 0, NULL, - NULL); - if (rc != len) + const SSIZE_T len = argLen / sizeof(WCHAR); + exec->RemoteApplicationArguments = Stream_Read_UTF16_String_As_UTF8(s, len, NULL); + if (!exec->RemoteApplicationArguments) goto fail; - Stream_Seek(s, argLen); } return CHANNEL_RC_OK; diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index b8155a45e..aabe3ab3e 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -502,7 +502,8 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr) if (device_ext->path == NULL) continue; - if (ConvertFromUnicode(CP_UTF8, 0, device_ext->path, -1, &path, 0, NULL, FALSE) <= 0) + path = ConvertWCharToUtf8Alloc(device_ext->path, NULL); + if (!path) continue; /* not plugable device */ @@ -809,7 +810,6 @@ static BOOL device_already_plugged(rdpdrPlugin* rdpdr, const hotplug_dev* device { BOOL rc = FALSE; WCHAR* path = NULL; - int status; if (!rdpdr || !device) return TRUE; @@ -817,9 +817,10 @@ static BOOL device_already_plugged(rdpdrPlugin* rdpdr, const hotplug_dev* device return TRUE; WINPR_ASSERT(rdpdr->devman); + WINPR_ASSERT(device->path); - status = ConvertToUnicode(CP_UTF8, 0, device->path, -1, &path, 0); - if (status <= 0) + path = ConvertUtf8ToWCharAlloc(device->path, NULL); + if (!path) return TRUE; rc = device_foreach(rdpdr, TRUE, device_not_plugged, path); @@ -836,7 +837,6 @@ struct hotplug_delete_arg static BOOL hotplug_delete_foreach(ULONG_PTR key, void* element, void* data) { - int rc; char* path = NULL; BOOL dev_found = FALSE; struct hotplug_delete_arg* arg = (struct hotplug_delete_arg*)data; @@ -850,9 +850,9 @@ static BOOL hotplug_delete_foreach(ULONG_PTR key, void* element, void* data) !device_ext->automount) return TRUE; - rc = ConvertFromUnicode(CP_UTF8, 0, device_ext->path, -1, &path, 0, NULL, NULL); - - if ((rc <= 0) || !path) + WINPR_ASSERT(device_ext->path); + path = ConvertWCharToUtf8Alloc(device_ext->path, NULL); + if (!path) return FALSE; /* not plugable device */ @@ -1162,7 +1162,7 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) { wStream* s; WCHAR* computerNameW = NULL; - int computerNameLenW; + size_t computerNameLenW; WINPR_ASSERT(rdpdr); @@ -1172,10 +1172,12 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) GetComputerNameA(rdpdr->computerName, &size); } - computerNameLenW = ConvertToUnicode(CP_UTF8, 0, rdpdr->computerName, -1, &computerNameW, 0) * 2; + WINPR_ASSERT(rdpdr->computerName); + computerNameW = ConvertUtf8ToWCharAlloc(rdpdr->computerName, &computerNameLenW); + computerNameLenW *= sizeof(WCHAR); WINPR_ASSERT(computerNameLenW >= 0); - s = StreamPool_Take(rdpdr->pool, 16U + (size_t)computerNameLenW); + s = StreamPool_Take(rdpdr->pool, 16U + computerNameLenW); if (!s) { diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index d506f5650..8c0bc7cd2 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -241,8 +241,9 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context if (UnicodeFlag) { - if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)Stream_Pointer(s), -1, - &(context->priv->ClientComputerName), 0, NULL, NULL) < 1) + context->priv->ClientComputerName = + Stream_Read_UTF16_String_As_UTF8(s, ComputerNameLen / sizeof(WCHAR), NULL); + if (!context->priv->ClientComputerName) { WLog_ERR(TAG, "failed to convert client computer name"); return ERROR_INVALID_DATA; @@ -251,6 +252,7 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context else { context->priv->ClientComputerName = _strdup((char*)Stream_Pointer(s)); + Stream_Seek(s, ComputerNameLen); if (!context->priv->ClientComputerName) { @@ -259,7 +261,6 @@ static UINT rdpdr_server_receive_client_name_request(RdpdrServerContext* context } } - Stream_Seek(s, ComputerNameLen); WLog_DBG(TAG, "ClientComputerName: %s", context->priv->ClientComputerName); return CHANNEL_RC_OK; } @@ -2057,7 +2058,6 @@ static void rdpdr_server_write_device_iorequest(wStream* s, UINT32 deviceId, UIN static UINT rdpdr_server_read_file_directory_information(wStream* s, FILE_DIRECTORY_INFORMATION* fdi) { - int rc; UINT32 fileNameLength; WINPR_ASSERT(fdi); ZeroMemory(fdi, sizeof(FILE_DIRECTORY_INFORMATION)); @@ -2079,12 +2079,9 @@ static UINT rdpdr_server_read_file_directory_information(wStream* s, if (!Stream_CheckAndLogRequiredLength(TAG, s, fileNameLength)) return ERROR_INVALID_DATA; - WINPR_ASSERT(fileNameLength / 2U <= INT_MAX); - WINPR_ASSERT(sizeof(fdi->FileName) < INT_MAX); - rc = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)Stream_Pointer(s), (int)fileNameLength / 2, - fdi->FileName, (int)sizeof(fdi->FileName), NULL, NULL); - WINPR_ASSERT(rc >= 0); - Stream_Seek(s, fileNameLength); + if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, fileNameLength / sizeof(WCHAR), fdi->FileName, + ARRAYSIZE(fdi->FileName)) < 0) + return ERROR_INVALID_DATA; return CHANNEL_RC_OK; } @@ -2127,13 +2124,9 @@ static UINT rdpdr_server_send_device_create_request(RdpdrServerContext* context, WINPR_ASSERT(pathLength <= UINT32_MAX); Stream_Write_UINT32(s, (UINT32)pathLength); /* PathLength (4 bytes) */ /* Convert the path to Unicode. */ - { - int rc; - WINPR_ASSERT(pathLength <= INT_MAX); - rc = MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR)Stream_Pointer(s), (int)pathLength); - WINPR_ASSERT(rc >= 0); - } - Stream_Seek(s, pathLength); + if (Stream_Write_UTF16_String_From_UTF8(s, pathLength / sizeof(WCHAR), path, + pathLength / sizeof(WCHAR), TRUE) < 0) + return ERROR_INTERNAL_ERROR; return rdpdr_seal_send_free_request(context, s); } @@ -2262,11 +2255,9 @@ static UINT rdpdr_server_send_device_query_directory_request(RdpdrServerContext* /* Convert the path to Unicode. */ if (pathLength > 0) { - int rc; - WINPR_ASSERT(pathLength <= INT_MAX); - rc = MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR)Stream_Pointer(s), (int)pathLength); - WINPR_ASSERT(rc >= 0); - Stream_Seek(s, pathLength); + if (Stream_Write_UTF16_String_From_UTF8(s, pathLength / sizeof(WCHAR), path, + pathLength / sizeof(WCHAR), TRUE) < 0) + return ERROR_INTERNAL_ERROR; } return rdpdr_seal_send_free_request(context, s); @@ -2312,11 +2303,9 @@ static UINT rdpdr_server_send_device_file_rename_request(RdpdrServerContext* con /* Convert the path to Unicode. */ if (pathLength > 0) { - int rc; - WINPR_ASSERT(pathLength < INT_MAX); - rc = MultiByteToWideChar(CP_ACP, 0, path, -1, (LPWSTR)Stream_Pointer(s), (int)pathLength); - WINPR_ASSERT(rc >= 0); - Stream_Seek(s, pathLength); + if (Stream_Write_UTF16_String_From_UTF8(s, pathLength / sizeof(WCHAR), path, + pathLength / sizeof(WCHAR), TRUE) < 0) + return ERROR_INTERNAL_ERROR; } return rdpdr_seal_send_free_request(context, s); diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index 500768a1d..4a2590a8a 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -135,9 +135,7 @@ static UINT remdesk_generate_expert_blob(remdeskPlugin* remdesk) */ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { - int status; UINT32 ChannelNameLen; - char* pChannelName = NULL; WINPR_ASSERT(s); WINPR_ASSERT(header); @@ -160,20 +158,10 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head return ERROR_INVALID_DATA; } - if (!Stream_CheckAndLogRequiredLength(TAG, s, ChannelNameLen)) - return ERROR_INVALID_DATA; - - ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); - pChannelName = (char*)header->ChannelName; - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)Stream_Pointer(s), ChannelNameLen / 2, - &pChannelName, 32, NULL, NULL); - Stream_Seek(s, ChannelNameLen); - - if (status <= 0) - { - WLog_ERR(TAG, "ConvertFromUnicode failed!"); + if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, ChannelNameLen / sizeof(WCHAR), + header->ChannelName, + ARRAYSIZE(header->ChannelName)) < 0) return ERROR_INTERNAL_ERROR; - } return CHANNEL_RC_OK; } @@ -358,12 +346,11 @@ static UINT remdesk_recv_ctl_result_pdu(remdeskPlugin* remdesk, wStream* s, */ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) { - int status; - UINT error; + UINT error = ERROR_INTERNAL_ERROR; wStream* s = NULL; - int cbExpertBlobW = 0; + size_t cbExpertBlobW = 0; WCHAR* expertBlobW = NULL; - int cbRaConnectionStringW = 0; + size_t cbRaConnectionStringW = 0; WCHAR* raConnectionStringW = NULL; REMDESK_CTL_AUTHENTICATE_PDU pdu = { 0 }; rdpSettings* settings; @@ -382,25 +369,19 @@ static UINT remdesk_send_ctl_authenticate_pdu(remdeskPlugin* remdesk) WINPR_ASSERT(settings); pdu.raConnectionString = settings->RemoteAssistanceRCTicket; - status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); + raConnectionStringW = ConvertUtf8ToWCharAlloc(pdu.raConnectionString, &cbRaConnectionStringW); - if (status <= 0) - { - WLog_ERR(TAG, "ConvertToUnicode failed!"); - return ERROR_INTERNAL_ERROR; - } - - cbRaConnectionStringW = status * 2; - status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0); - - if (status <= 0) - { - WLog_ERR(TAG, "ConvertToUnicode failed!"); - error = ERROR_INTERNAL_ERROR; + if (!raConnectionStringW || (cbRaConnectionStringW > UINT32_MAX / sizeof(WCHAR))) goto out; - } - cbExpertBlobW = status * 2; + cbRaConnectionStringW = cbRaConnectionStringW * sizeof(WCHAR); + + expertBlobW = ConvertUtf8ToWCharAlloc(pdu.expertBlob, &cbExpertBlobW); + + if (!expertBlobW || (cbExpertBlobW > UINT32_MAX / sizeof(WCHAR))) + goto out; + + cbExpertBlobW = cbExpertBlobW * sizeof(WCHAR); remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_AUTHENTICATE, cbRaConnectionStringW + cbExpertBlobW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.ch.DataLength); @@ -434,12 +415,12 @@ out: */ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) { - int status; UINT error; + size_t length; wStream* s = NULL; - int cbRaConnectionStringW = 0; + size_t cbRaConnectionStringW = 0; WCHAR* raConnectionStringW = NULL; - REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu; + REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu = { 0 }; rdpSettings* settings; WINPR_ASSERT(remdesk); @@ -448,15 +429,12 @@ static UINT remdesk_send_ctl_remote_control_desktop_pdu(remdeskPlugin* remdesk) WINPR_ASSERT(settings); pdu.raConnectionString = settings->RemoteAssistanceRCTicket; - status = ConvertToUnicode(CP_UTF8, 0, pdu.raConnectionString, -1, &raConnectionStringW, 0); + raConnectionStringW = ConvertUtf8ToWCharAlloc(pdu.raConnectionString, &length); - if (status <= 0) - { - WLog_ERR(TAG, "ConvertToUnicode failed!"); + if (!raConnectionStringW) return ERROR_INTERNAL_ERROR; - } - cbRaConnectionStringW = status * 2; + cbRaConnectionStringW = length * sizeof(WCHAR); remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_REMOTE_CONTROL_DESKTOP, cbRaConnectionStringW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.ch.DataLength); @@ -488,12 +466,11 @@ out: */ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) { - int status; - UINT error; + UINT error = ERROR_INTERNAL_ERROR; wStream* s; - int cbExpertBlobW = 0; + size_t cbExpertBlobW = 0; WCHAR* expertBlobW = NULL; - REMDESK_CTL_VERIFY_PASSWORD_PDU pdu; + REMDESK_CTL_VERIFY_PASSWORD_PDU pdu = { 0 }; WINPR_ASSERT(remdesk); @@ -504,15 +481,12 @@ static UINT remdesk_send_ctl_verify_password_pdu(remdeskPlugin* remdesk) } pdu.expertBlob = remdesk->ExpertBlob; - status = ConvertToUnicode(CP_UTF8, 0, pdu.expertBlob, -1, &expertBlobW, 0); + expertBlobW = ConvertUtf8ToWCharAlloc(pdu.expertBlob, &cbExpertBlobW); - if (status <= 0) - { - WLog_ERR(TAG, "ConvertToUnicode failed!"); - return ERROR_INTERNAL_ERROR; - } + if (!expertBlobW || (cbExpertBlobW > UINT32_MAX / sizeof(WCHAR))) + goto out; - cbExpertBlobW = status * 2; + cbExpertBlobW = cbExpertBlobW * sizeof(WCHAR); remdesk_prepare_ctl_header(&(pdu.ctlHeader), REMDESK_CTL_VERIFY_PASSWORD, cbExpertBlobW); s = Stream_New(NULL, REMDESK_CHANNEL_CTL_SIZE + pdu.ctlHeader.ch.DataLength); diff --git a/channels/remdesk/server/remdesk_main.c b/channels/remdesk/server/remdesk_main.c index 88bc8384d..faf219341 100644 --- a/channels/remdesk/server/remdesk_main.c +++ b/channels/remdesk/server/remdesk_main.c @@ -48,9 +48,7 @@ static UINT remdesk_virtual_channel_write(RemdeskServerContext* context, wStream */ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* header) { - int status; UINT32 ChannelNameLen; - char* pChannelName = NULL; if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return CHANNEL_RC_NO_MEMORY; @@ -70,21 +68,11 @@ static UINT remdesk_read_channel_header(wStream* s, REMDESK_CHANNEL_HEADER* head return ERROR_INVALID_DATA; } - if (!Stream_CheckAndLogRequiredLength(TAG, s, ChannelNameLen)) + if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, ChannelNameLen / sizeof(WCHAR), + header->ChannelName, + ARRAYSIZE(header->ChannelName)) < 0) return ERROR_INVALID_DATA; - ZeroMemory(header->ChannelName, sizeof(header->ChannelName)); - pChannelName = (char*)header->ChannelName; - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)Stream_Pointer(s), ChannelNameLen / 2, - &pChannelName, 32, NULL, NULL); - Stream_Seek(s, ChannelNameLen); - - if (status <= 0) - { - WLog_ERR(TAG, "ConvertFromUnicode failed!"); - return ERROR_INVALID_DATA; - } - return CHANNEL_RC_OK; } @@ -267,11 +255,10 @@ static UINT remdesk_recv_ctl_version_info_pdu(RemdeskServerContext* context, wSt static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) { - int status; - int cchStringW; + SSIZE_T cchStringW; WCHAR* pStringW; UINT32 msgLength; - int cbRaConnectionStringW = 0; + SSIZE_T cbRaConnectionStringW = 0; WCHAR* raConnectionStringW = NULL; REMDESK_CTL_REMOTE_CONTROL_DESKTOP_PDU pdu; UINT error; @@ -291,15 +278,10 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co cchStringW++; cbRaConnectionStringW = cchStringW * 2; - pdu.raConnectionString = NULL; - status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW, cbRaConnectionStringW / 2, - &pdu.raConnectionString, 0, NULL, NULL); - - if (status <= 0) - { - WLog_ERR(TAG, "ConvertFromUnicode failed!"); + pdu.raConnectionString = + ConvertWCharNToUtf8Alloc(raConnectionStringW, cbRaConnectionStringW / sizeof(WCHAR), NULL); + if (!pdu.raConnectionString) return ERROR_INTERNAL_ERROR; - } WLog_INFO(TAG, "RaConnectionString: %s", pdu.raConnectionString); free(pdu.raConnectionString); @@ -318,7 +300,6 @@ static UINT remdesk_recv_ctl_remote_control_desktop_pdu(RemdeskServerContext* co static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) { - int status; int cchStringW; WCHAR* pStringW; UINT32 msgLength; @@ -358,23 +339,14 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt cchStringW++; cbExpertBlobW = cchStringW * 2; - pdu.raConnectionString = NULL; - status = ConvertFromUnicode(CP_UTF8, 0, raConnectionStringW, cbRaConnectionStringW / 2, - &pdu.raConnectionString, 0, NULL, NULL); - - if (status <= 0) - { - WLog_ERR(TAG, "ConvertFromUnicode failed!"); + pdu.raConnectionString = + ConvertWCharNToUtf8Alloc(raConnectionStringW, cbRaConnectionStringW / sizeof(WCHAR), NULL); + if (!pdu.raConnectionString) return ERROR_INTERNAL_ERROR; - } - pdu.expertBlob = NULL; - status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, - NULL, NULL); - - if (status <= 0) + pdu.expertBlob = ConvertWCharNToUtf8Alloc(expertBlobW, cbExpertBlobW / sizeof(WCHAR), NULL); + if (!pdu.expertBlob) { - WLog_ERR(TAG, "ConvertFromUnicode failed!"); free(pdu.raConnectionString); return ERROR_INTERNAL_ERROR; } @@ -393,8 +365,7 @@ static UINT remdesk_recv_ctl_authenticate_pdu(RemdeskServerContext* context, wSt static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, wStream* s, REMDESK_CHANNEL_HEADER* header) { - int status; - int cbExpertBlobW = 0; + SSIZE_T cbExpertBlobW = 0; WCHAR* expertBlobW = NULL; REMDESK_CTL_VERIFY_PASSWORD_PDU pdu; UINT error; @@ -402,17 +373,12 @@ static UINT remdesk_recv_ctl_verify_password_pdu(RemdeskServerContext* context, if (!Stream_CheckAndLogRequiredLength(TAG, s, 8)) return ERROR_INVALID_DATA; - pdu.expertBlob = NULL; expertBlobW = (WCHAR*)Stream_Pointer(s); cbExpertBlobW = header->DataLength - 4; - status = ConvertFromUnicode(CP_UTF8, 0, expertBlobW, cbExpertBlobW / 2, &pdu.expertBlob, 0, - NULL, NULL); - if (status <= 0) - { - WLog_ERR(TAG, "ConvertFromUnicode failed!"); + pdu.expertBlob = ConvertWCharNToUtf8Alloc(expertBlobW, cbExpertBlobW / sizeof(WCHAR), NULL); + if (pdu.expertBlob) return ERROR_INTERNAL_ERROR; - } WLog_INFO(TAG, "ExpertBlob: %s", pdu.expertBlob); diff --git a/channels/urbdrc/client/urbdrc_main.c b/channels/urbdrc/client/urbdrc_main.c index 9a5ffbd52..feda4abac 100644 --- a/channels/urbdrc/client/urbdrc_main.c +++ b/channels/urbdrc/client/urbdrc_main.c @@ -43,25 +43,6 @@ #include -static BOOL Stream_Write_UTF16_String_From_Utf8(wStream* s, const char* utf8, size_t len) -{ - BOOL ret; - WCHAR* utf16; - int rc; - - if (len > INT_MAX) - return FALSE; - - rc = ConvertToUnicode(CP_UTF8, 0, utf8, (int)len, &utf16, 0); - - if (rc < 0) - return FALSE; - - ret = Stream_Write_UTF16_String(s, utf16, (size_t)rc); - free(utf16); - return ret; -} - static IWTSVirtualChannel* get_channel(IUDEVMAN* idevman) { IWTSVirtualChannelManager* channel_mgr; @@ -323,34 +304,50 @@ static UINT urdbrc_send_usb_device_add(GENERIC_CHANNEL_CALLBACK* callback, IUDEV Stream_Write_UINT32(out, 0x00000001); /* NumUsbDevice */ Stream_Write_UINT32(out, pdev->get_UsbDevice(pdev)); /* UsbDevice */ Stream_Write_UINT32(out, (UINT32)InstanceIdLen + 1); /* cchDeviceInstanceId */ - Stream_Write_UTF16_String_From_Utf8(out, strInstanceId, InstanceIdLen); + if (Stream_Write_UTF16_String_From_UTF8(out, InstanceIdLen, strInstanceId, InstanceIdLen, + TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); Stream_Write_UINT32(out, HardwareIdsLen[0] + HardwareIdsLen[1] + 3); /* cchHwIds */ - /* HardwareIds 1 */ - Stream_Write_UTF16_String_From_Utf8(out, HardwareIds[0], HardwareIdsLen[0]); + /* HardwareIds 1 */ + if (Stream_Write_UTF16_String_From_UTF8(out, HardwareIdsLen[0], HardwareIds[0], + HardwareIdsLen[0], TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); - Stream_Write_UTF16_String_From_Utf8(out, HardwareIds[1], HardwareIdsLen[1]); + if (Stream_Write_UTF16_String_From_UTF8(out, HardwareIdsLen[1], HardwareIds[1], + HardwareIdsLen[1], TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); Stream_Write_UINT16(out, 0); /* add "\0" */ Stream_Write_UINT32(out, (UINT32)cchCompatIds); /* cchCompatIds */ /* CompatibilityIds */ - Stream_Write_UTF16_String_From_Utf8(out, CompatibilityIds[0], CompatibilityIdLen[0]); + if (Stream_Write_UTF16_String_From_UTF8(out, CompatibilityIdLen[0], CompatibilityIds[0], + CompatibilityIdLen[0], TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); - Stream_Write_UTF16_String_From_Utf8(out, CompatibilityIds[1], CompatibilityIdLen[1]); + if (Stream_Write_UTF16_String_From_UTF8(out, CompatibilityIdLen[1], CompatibilityIds[1], + CompatibilityIdLen[1], TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); - Stream_Write_UTF16_String_From_Utf8(out, CompatibilityIds[2], CompatibilityIdLen[2]); + if (Stream_Write_UTF16_String_From_UTF8(out, CompatibilityIdLen[2], CompatibilityIds[2], + CompatibilityIdLen[2], TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); if (pdev->isCompositeDevice(pdev)) { - Stream_Write_UTF16_String_From_Utf8(out, composite_str, composite_len); + if (Stream_Write_UTF16_String_From_UTF8(out, composite_len, composite_str, composite_len, + TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); } Stream_Write_UINT16(out, 0x0000); /* add "\0" */ Stream_Write_UINT32(out, (UINT32)ContainerIdLen + 1); /* cchContainerId */ /* ContainerId */ - Stream_Write_UTF16_String_From_Utf8(out, strContainerId, ContainerIdLen); + if (Stream_Write_UTF16_String_From_UTF8(out, ContainerIdLen, strContainerId, ContainerIdLen, + TRUE) < 0) + goto fail; Stream_Write_UINT16(out, 0); /* USB_DEVICE_CAPABILITIES 28 bytes */ Stream_Write_UINT32(out, 0x0000001c); /* CbSize */ @@ -368,6 +365,10 @@ static UINT urdbrc_send_usb_device_add(GENERIC_CHANNEL_CALLBACK* callback, IUDEV Stream_Write_UINT32(out, 0x50); /* NoAckIsochWriteJitterBufferSizeInMs, >=10 or <=512 */ return stream_write_and_free(callback->plugin, callback->channel, out); + +fail: + Stream_Free(out, TRUE); + return ERROR_INTERNAL_ERROR; } /** diff --git a/client/Wayland/wlf_cliprdr.c b/client/Wayland/wlf_cliprdr.c index b07fc7fb5..7cf23ed1e 100644 --- a/client/Wayland/wlf_cliprdr.c +++ b/client/Wayland/wlf_cliprdr.c @@ -621,7 +621,6 @@ static UINT wlf_cliprdr_server_format_data_request(CliprdrClientContext* context, const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest) { - int cnv; UINT rc = CHANNEL_RC_OK; BYTE* data; LPWSTR cdata; @@ -673,16 +672,16 @@ wlf_cliprdr_server_format_data_request(CliprdrClientContext* context, rc = ERROR_INTERNAL_ERROR; else { - cdata = NULL; - cnv = ConvertToUnicode(CP_UTF8, 0, (LPCSTR)data, (int)size, &cdata, 0); + size_t len = 0; + cdata = ConvertUtf8NToWCharAlloc(data, size, &len); free(data); data = NULL; - if (cnv < 0) + if (len == 0) rc = ERROR_INTERNAL_ERROR; else { - size = (size_t)cnv; + size = (size_t)len; data = (BYTE*)cdata; size *= sizeof(WCHAR); } @@ -715,7 +714,6 @@ static UINT wlf_cliprdr_server_format_data_response(CliprdrClientContext* context, const CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { - int cnv; UINT rc = ERROR_INTERNAL_ERROR; UINT32 size; LPSTR cdata = NULL; @@ -741,16 +739,14 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context, switch (clipboard->responseFormat) { case CF_UNICODETEXT: - cnv = ConvertFromUnicode(CP_UTF8, 0, wdata, (int)(size / sizeof(WCHAR)), &cdata, 0, - NULL, NULL); - - if (cnv < 0) + cdata = ConvertWCharNToUtf8Alloc(wdata, size / sizeof(WCHAR), NULL); + if (!cdata) return ERROR_INTERNAL_ERROR; data = cdata; size = 0; - if (cnv > 0) - size = (UINT32)strnlen(data, (size_t)cnv); + if (cdata) + size = (UINT32)strnlen(data, size); break; default: diff --git a/client/Windows/wf_client.c b/client/Windows/wf_client.c index b541f633f..038472eb5 100644 --- a/client/Windows/wf_client.c +++ b/client/Windows/wf_client.c @@ -328,10 +328,7 @@ static WCHAR* wf_window_get_title(rdpSettings* settings) name = settings->ServerHostname; if (settings->WindowTitle) - { - ConvertToUnicode(CP_UTF8, 0, settings->WindowTitle, -1, &windowTitle, 0); - return windowTitle; - } + return ConvertUtf8ToWCharAlloc(settings->WindowTitle, NULL); port = (settings->ServerPort != 3389); size = strlen(name) + 16 + wcslen(prefix); diff --git a/client/Windows/wf_cliprdr.c b/client/Windows/wf_cliprdr.c index e4e63f88f..ca7772668 100644 --- a/client/Windows/wf_cliprdr.c +++ b/client/Windows/wf_cliprdr.c @@ -1902,16 +1902,10 @@ static UINT wf_cliprdr_server_format_list(CliprdrClientContext* context, if (format->formatName) { - int size = MultiByteToWideChar(CP_UTF8, 0, format->formatName, - strlen(format->formatName), NULL, 0); - mapping->name = calloc(size + 1, sizeof(WCHAR)); + mapping->name = ConvertUtf8ToWCharAlloc(format->formatName, NULL); if (mapping->name) - { - MultiByteToWideChar(CP_UTF8, 0, format->formatName, strlen(format->formatName), - mapping->name, size); mapping->local_format_id = RegisterClipboardFormatW((LPWSTR)mapping->name); - } } else { diff --git a/client/Windows/wf_defaults.c b/client/Windows/wf_defaults.c index 221d7a3ce..f0b4c3d0f 100644 --- a/client/Windows/wf_defaults.c +++ b/client/Windows/wf_defaults.c @@ -72,8 +72,8 @@ static void AddDefaultSettings_I(rdpSettings* settings, size_t idHostname, size_ TargetName[len - 1] = 0; - int result = ConvertToUnicode(CP_UTF8, 0, TargetName, -1, &TargetNameW, 0); - if (result <= 0) + TargetNameW = ConvertUtf8ToWCharAlloc(TargetName, NULL); + if (!TargetNameW) goto fail; if (!CredReadW(TargetNameW, CRED_TYPE_GENERIC, 0, &Credential)) @@ -85,9 +85,8 @@ static void AddDefaultSettings_I(rdpSettings* settings, size_t idHostname, size_ if (PasswordW) { - result = ConvertFromUnicode(CP_UTF8, 0, PasswordW, -1, &Password, 0, NULL, NULL); - if (result) - freerdp_settings_set_string(settings, idPassword, Password); + if (!freerdp_settings_set_string_from_utf16(settings, idPassword, PasswordW)) + goto fail; } } @@ -97,9 +96,8 @@ static void AddDefaultSettings_I(rdpSettings* settings, size_t idHostname, size_ if (UserNameW) { - result = ConvertFromUnicode(CP_UTF8, 0, UserNameW, -1, &UserName, 0, NULL, NULL); - if (result) - freerdp_settings_set_string(settings, idUsername, UserName); + if (!freerdp_settings_set_string_from_utf16(settings, idUsername, UserNameW)) + goto fail; } } diff --git a/client/Windows/wf_rail.c b/client/Windows/wf_rail.c index c1fde2a4b..16c646194 100644 --- a/client/Windows/wf_rail.c +++ b/client/Windows/wf_rail.c @@ -179,9 +179,8 @@ static void PrintRailWindowState(const WINDOW_ORDER_INFO* orderInfo, if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE) { - char* title = NULL; - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, NULL); + char* title = ConvertWCharNToUtf8Alloc(windowState->titleInfo.string, + windowState->titleInfo.length / sizeof(WCHAR), NULL); WLog_INFO(TAG, "\tTitleInfo: %s (length = %hu)", title, windowState->titleInfo.length); free(title); } @@ -462,9 +461,9 @@ static BOOL wf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* /* error handled below */ } } - else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, - NULL) < 1) + else if (!(title = ConvertWCharNToUtf8Alloc( + windowState->titleInfo.string, + windowState->titleInfo.length / sizeof(WCHAR), NULL))) { WLog_ERR(TAG, "failed to convert window title"); /* error handled below */ @@ -484,7 +483,7 @@ static BOOL wf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* return FALSE; } - ConvertToUnicode(CP_UTF8, 0, railWindow->title, -1, &titleW, 0); + titleW = ConvertUtf8ToWCharAlloc(railWindow->title, NULL); hInstance = GetModuleHandle(NULL); wndClassEx.cbSize = sizeof(WNDCLASSEX); @@ -589,8 +588,9 @@ static BOOL wf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* return FALSE; } } - else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) + else if (!(title = ConvertWCharNToUtf8Alloc(windowState->titleInfo.string, + windowState->titleInfo.length / sizeof(WCHAR), + NULL))) { WLog_ERR(TAG, "failed to convert window title"); return FALSE; @@ -598,7 +598,7 @@ static BOOL wf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* free(railWindow->title); railWindow->title = title; - ConvertToUnicode(CP_UTF8, 0, railWindow->title, -1, &titleW, 0); + titleW = ConvertUtf8ToWCharAlloc(railWindow->title, NULL); SetWindowTextW(railWindow->hWnd, titleW); free(titleW); } diff --git a/client/X11/xf_cliprdr.c b/client/X11/xf_cliprdr.c index 7060ad094..a88c90d35 100644 --- a/client/X11/xf_cliprdr.c +++ b/client/X11/xf_cliprdr.c @@ -1932,15 +1932,15 @@ xf_cliprdr_server_format_data_request(CliprdrClientContext* context, } #ifdef WITH_FUSE -static char* xf_cliprdr_fuse_split_basename(char* name, int len) +static const char* xf_cliprdr_fuse_split_basename(const char* name, size_t len) { - int s = len - 1; WINPR_ASSERT(name || (len <= 0)); - for (; s >= 0; s--) + for (size_t s = len; s > 0; s--) { - if (*(name + s) == '\\') + char c = name[s - 1]; + if (c == '\\') { - return name + s; + return &name[s - 1]; } } return NULL; @@ -2025,13 +2025,13 @@ static BOOL xf_cliprdr_fuse_create_nodes(xfClipboard* clipboard, wStream* s, siz } free(curName); - size_t curLen = _wcsnlen(descriptor->cFileName, ARRAYSIZE(descriptor->cFileName)); - int newLen = ConvertFromUnicode(CP_UTF8, 0, descriptor->cFileName, (int)curLen, &curName, 0, - NULL, NULL); + curName = + ConvertWCharNToUtf8Alloc(descriptor->cFileName, ARRAYSIZE(descriptor->cFileName), NULL); if (!curName) break; - char* split_point = xf_cliprdr_fuse_split_basename(curName, newLen); + const char* split_point = xf_cliprdr_fuse_split_basename( + curName, strnlen(curName, ARRAYSIZE(descriptor->cFileName))); UINT64 ticks; xfCliprdrFuseInode* parent; diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index ce5c6b19c..e5ddb69f3 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -295,8 +295,14 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* /* Ensure window always gets a window title */ if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { + union + { + WCHAR* wc; + BYTE* b; + } cnv; char* title = NULL; + cnv.b = windowState->titleInfo.string; if (windowState->titleInfo.length == 0) { if (!(title = _strdup(""))) @@ -305,9 +311,8 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* /* error handled below */ } } - else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, - NULL) < 1) + else if (!(title = ConvertWCharNToUtf8Alloc( + cnv.wc, windowState->titleInfo.length / sizeof(WCHAR), NULL))) { WLog_ERR(TAG, "failed to convert window title"); /* error handled below */ @@ -390,7 +395,13 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { char* title = NULL; + union + { + WCHAR* wc; + BYTE* b; + } cnv; + cnv.b = windowState->titleInfo.string; if (windowState->titleInfo.length == 0) { if (!(title = _strdup(""))) @@ -399,8 +410,8 @@ static BOOL xf_rail_window_common(rdpContext* context, const WINDOW_ORDER_INFO* return FALSE; } } - else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)windowState->titleInfo.string, - windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1) + else if (!(title = ConvertWCharNToUtf8Alloc( + cnv.wc, windowState->titleInfo.length / sizeof(WCHAR), NULL))) { WLog_ERR(TAG, "failed to convert window title"); return FALSE; diff --git a/client/common/client.c b/client/common/client.c index 2f1a78562..7ad69c06f 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -528,11 +528,9 @@ BOOL client_cli_choose_smartcard(SmartcardCertInfo** cert_list, DWORD count, DWO for (DWORD i = 0; i < count; i++) { const SmartcardCertInfo* cert = cert_list[i]; - char* reader = NULL; - char* container_name = NULL; + char* reader = ConvertWCharToUtf8Alloc(cert->reader, NULL); + char* container_name = ConvertWCharToUtf8Alloc(cert->containerName, NULL); - ConvertFromUnicode(CP_UTF8, 0, cert->reader, -1, &reader, 0, NULL, NULL); - ConvertFromUnicode(CP_UTF8, 0, cert->containerName, -1, &container_name, 0, NULL, NULL); printf("[%" PRIu32 "] %s\n\tReader: %s\n\tUser: %s@%s\n\tSubject: %s\n\tIssuer: %s\n\tUPN: %s\n", i, container_name, reader, cert->userHint, cert->domainHint, cert->subject, @@ -865,8 +863,8 @@ BOOL client_cli_present_gateway_message(freerdp* instance, UINT32 type, BOOL isD printf("%.*S\n", (int)length, message); #else { - LPSTR msg; - if (ConvertFromUnicode(CP_UTF8, 0, message, (int)(length / 2), &msg, 0, NULL, NULL) < 1) + LPSTR msg = ConvertWCharNToUtf8Alloc(message, length / sizeof(WCHAR), NULL); + if (!msg) { printf("Failed to convert message!\n"); return FALSE; diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 7e7720988..d69417b04 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -2059,7 +2059,7 @@ static int parse_kbd_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT_ if (option_starts_with("remap:", val)) { /* Append this new occurance to the already existing list */ - char* now = strdup(&val[6]); + char* now = _strdup(&val[6]); const char* old = freerdp_settings_get_string(settings, FreeRDP_KeyboardRemappingList); diff --git a/client/common/file.c b/client/common/file.c index 791b87746..5e21ab914 100644 --- a/client/common/file.c +++ b/client/common/file.c @@ -694,15 +694,11 @@ BOOL freerdp_client_parse_rdp_file_buffer_ex(rdpFile* file, const BYTE* buffer, if ((buffer[0] == BOM_UTF16_LE[0]) && (buffer[1] == BOM_UTF16_LE[1])) { - int clength; LPCWSTR uc = (LPCWSTR)(&buffer[2]); - size = size / 2 - 1; + size = size / sizeof(WCHAR) - 1; - if (size > INT_MAX) - return FALSE; - - clength = (int)size; - if (ConvertFromUnicode(CP_UTF8, 0, uc, clength, ©, 0, NULL, NULL) < 0) + copy = ConvertWCharNToUtf8Alloc(uc, size, NULL); + if (!copy) { WLog_ERR(TAG, "Failed to convert RDP file from UCS2 to UTF8"); return FALSE; @@ -1125,22 +1121,19 @@ BOOL freerdp_client_write_rdp_file(const rdpFile* file, const char* name, BOOL u { if (unicode) { - int length; + size_t len = 0; + unicodestr = ConvertUtf8NToWCharAlloc(buffer, size, &len); - if (size > INT_MAX) + if (!unicodestr) { free(buffer); - free(unicodestr); fclose(fp); return FALSE; } - length = (int)size; - ConvertToUnicode(CP_UTF8, 0, buffer, length, &unicodestr, 0); - /* Write multi-byte header */ - if ((length < 0) || (fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp) != 2) || - (fwrite(unicodestr, 2, (size_t)length, fp) != (size_t)length)) + if ((fwrite(BOM_UTF16_LE, sizeof(BYTE), 2, fp) != 2) || + (fwrite(unicodestr, sizeof(WCHAR), len, fp) != len)) { free(buffer); free(unicodestr); diff --git a/client/common/smartcard_cli.c b/client/common/smartcard_cli.c index 5fcf98c3c..1d3683971 100644 --- a/client/common/smartcard_cli.c +++ b/client/common/smartcard_cli.c @@ -39,19 +39,16 @@ BOOL freerdp_smartcard_list(const rdpSettings* settings) printf("%" PRIu32 ": %s\n", i, info->subject); - if (WideCharToMultiByte(CP_UTF8, 0, info->csp, -1, asciiStr, sizeof(asciiStr), NULL, NULL) > - 0) + if (ConvertWCharToUtf8(info->csp, asciiStr, ARRAYSIZE(asciiStr))) printf("\t* CSP: %s\n", asciiStr); - if (WideCharToMultiByte(CP_UTF8, 0, info->reader, -1, asciiStr, sizeof(asciiStr), NULL, - NULL) > 0) + if (ConvertWCharToUtf8(info->reader, asciiStr, ARRAYSIZE(asciiStr))) printf("\t* reader: %s\n", asciiStr); #ifndef _WIN32 printf("\t* slotId: %" PRIu32 "\n", info->slotId); printf("\t* pkinitArgs: %s\n", info->pkinitArgs); #endif - if (WideCharToMultiByte(CP_UTF8, 0, info->containerName, -1, asciiStr, sizeof(asciiStr), - NULL, NULL) > 0) + if (ConvertWCharToUtf8(info->containerName, asciiStr, ARRAYSIZE(asciiStr))) printf("\t* containerName: %s\n", asciiStr); if (info->upn) printf("\t* UPN: %s\n", info->upn); diff --git a/libfreerdp/common/assistance.c b/libfreerdp/common/assistance.c index edc7f539d..efc2cbaa3 100644 --- a/libfreerdp/common/assistance.c +++ b/libfreerdp/common/assistance.c @@ -545,7 +545,6 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas size_t* pEncryptedSize) { BOOL rc; - int status; size_t cbPasswordW; size_t cbPassStubW; size_t EncryptedSize; @@ -554,25 +553,18 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas BYTE* pbIn = NULL; BYTE* pbOut = NULL; size_t cbOut, cbIn, cbFinal; - WCHAR* PasswordW = NULL; - WCHAR* PassStubW = NULL; - status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0); + WCHAR* PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW); + WCHAR* PassStubW = ConvertUtf8ToWCharAlloc(passStub, &cbPassStubW); - if (status <= 0) - return NULL; - - cbPasswordW = (size_t)(status - 1) * 2UL; + if (!PasswordW || !PassStubW) + goto fail; + cbPasswordW = (cbPasswordW) * sizeof(WCHAR); + cbPassStubW = (cbPassStubW) * sizeof(WCHAR); if (!winpr_Digest(WINPR_MD_MD5, (BYTE*)PasswordW, cbPasswordW, (BYTE*)PasswordHash, sizeof(PasswordHash))) goto fail; - status = ConvertToUnicode(CP_UTF8, 0, passStub, -1, &PassStubW, 0); - - if (status <= 0) - goto fail; - - cbPassStubW = (size_t)(status - 1) * 2UL; EncryptedSize = cbPassStubW + 4; pbIn = (BYTE*)calloc(1, EncryptedSize); pbOut = (BYTE*)calloc(1, EncryptedSize); @@ -626,8 +618,7 @@ static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* pas BOOL rc = FALSE; int status = 0; size_t cbPasswordW; - int cchOutW = 0; - WCHAR* pbOutW = NULL; + size_t cchOutW = 0; WINPR_CIPHER_CTX* aesDec = NULL; WCHAR* PasswordW = NULL; BYTE* pbIn = NULL; @@ -640,15 +631,14 @@ static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* pas if (!file || !password) return FALSE; - status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0); - - if (status <= 0) + PasswordW = ConvertUtf8ToWCharAlloc(password, &cbPasswordW); + if (!PasswordW) { WLog_ERR(TAG, "Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed"); return FALSE; } - cbPasswordW = (size_t)(status - 1) * 2UL; + cbPasswordW = (cbPasswordW) * sizeof(WCHAR); if (!winpr_Digest(WINPR_MD_SHA1, (BYTE*)PasswordW, cbPasswordW, PasswordHash, sizeof(PasswordHash))) @@ -683,17 +673,17 @@ static BOOL freerdp_assistance_decrypt2(rdpAssistanceFile* file, const char* pas cbOut += cbFinal; cbFinal = 0; - pbOutW = (WCHAR*)pbOut; - if (cbOut > INT_MAX / 2) - goto fail; + union + { + const WCHAR* wc; + const BYTE* b; + } cnv; - cchOutW = (int)cbOut / 2; - file->ConnectionString2 = NULL; - status = - ConvertFromUnicode(CP_UTF8, 0, pbOutW, cchOutW, &file->ConnectionString2, 0, NULL, NULL); - - if (status <= 0) + cnv.b = pbOut; + cchOutW = cbOut / sizeof(WCHAR); + file->ConnectionString2 = ConvertWCharNToUtf8Alloc(cnv.wc, cchOutW, NULL); + if (!file->ConnectionString2) { WLog_ERR(TAG, "Failed to parse ASSISTANCE file: Conversion from UCS2 to UTF8 failed"); goto fail; diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 9c9373578..17f2d67f5 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -151,8 +151,6 @@ static BOOL rdp_capability_set_finish(wStream* s, UINT16 header, UINT16 type) static BOOL rdp_apply_general_capability_set(rdpSettings* settings, const rdpSettings* src) { - UINT16 extraFlags; - WINPR_ASSERT(settings); WINPR_ASSERT(src); @@ -1446,17 +1444,11 @@ static BOOL rdp_read_input_capability_set(wStream* s, rdpSettings* settings) Stream_Read_UINT32(s, settings->KeyboardFunctionKey); /* keyboardFunctionKeys (4 bytes) */ { - BOOL res; - char* str = NULL; - int rc = ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR)Stream_Pointer(s), 64 / sizeof(WCHAR), - &str, -1, NULL, NULL); - if (rc < 0) + char str[65] = { 0 }; + if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 64 / sizeof(WCHAR), str, ARRAYSIZE(str)) < 0) return FALSE; - res = freerdp_settings_set_string(settings, FreeRDP_ImeFileName, str); - free(str); - if (!res) + if (!freerdp_settings_set_string(settings, FreeRDP_ImeFileName, str)) return FALSE; - Stream_Seek(s, 64); /* imeFileName (64 bytes) */ } settings->FastPathInput = inputFlags & (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2); diff --git a/libfreerdp/core/credssp_auth.c b/libfreerdp/core/credssp_auth.c index b6e39e557..da5976ba1 100644 --- a/libfreerdp/core/credssp_auth.c +++ b/libfreerdp/core/credssp_auth.c @@ -166,7 +166,7 @@ static BOOL credssp_auth_client_init_cred_attributes(rdpCredsspAuth* auth) { #ifdef UNICODE SecPkgCredentials_KdcUrlW secAttr = { NULL }; - ConvertToUnicode(CP_UTF8, 0, auth->kerberosSettings.kdcUrl, -1, &secAttr.KdcUrl, 0); + secAttr.KdcUrl = ConvertUtf8ToWCharAlloc(auth->kerberosSettings.kdcUrl, NULL); if (!secAttr.KdcUrl) return FALSE; @@ -597,7 +597,10 @@ const char* credssp_auth_pkg_name(rdpCredsspAuth* auth) WINPR_ASSERT(auth && auth->info); #ifdef UNICODE if (!auth->pkgNameA) - ConvertFromUnicode(CP_UTF8, 0, auth->info->Name, -1, &auth->pkgNameA, 0, NULL, NULL); + { + WINPR_ASSERT(auth->info->Name); + auth->pkgNameA = ConvertUtf8ToWCharAlloc(auth->info->Name, NULL); + } return auth->pkgNameA; #else return auth->info->Name; @@ -823,9 +826,7 @@ static BOOL credssp_auth_setup_identity(rdpCredsspAuth* auth) if (settings->AuthenticationPackageList) { - ConvertToUnicode(CP_UTF8, 0, settings->AuthenticationPackageList, -1, &auth->package_list, - 0); - + auth->package_list = ConvertUtf8ToWCharAlloc(settings->AuthenticationPackageList, NULL); if (!auth->package_list) return FALSE; } @@ -839,11 +840,7 @@ static BOOL credssp_auth_setup_identity(rdpCredsspAuth* auth) static TCHAR* tcs_strdup_from_char(const char* str) { #ifdef UNICODE - TCHAR* ret; - if (ConvertToUnicode(CP_UTF8, 0, str, -1, &ret, 0) <= 0) - return NULL; - - return ret; + return ConvertUtf8ToWCharAlloc(str, NULL); #else return _strdup(str); #endif @@ -872,15 +869,13 @@ BOOL credssp_auth_set_spn(rdpCredsspAuth* auth, const char* service, const char* sprintf_s(auth->spn, length, "%s/%s", service, hostname); #else { - TCHAR* serviceW = NULL; - TCHAR* hostnameW = NULL; + TCHAR* serviceW = ConvertUtf8ToWCharAlloc(service, NULL); + TCHAR* hostnameW = ConvertUtf8ToWCharAlloc(hostname, NULL); - if (ConvertToUnicode(CP_UTF8, 0, service, -1, &serviceW, 0) <= 0) - return FALSE; - - if (ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameW, 0) <= 0) + if (!serviceW || !hostnameW) { free(serviceW); + free(hostnameW); return FALSE; } diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index 9feebdea1..53769890d 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -1037,17 +1037,16 @@ static BOOL rdg_send_tunnel_request(rdpRdg* rdg) UINT32 packetSize = 16; UINT16 fieldsPresent = 0; WCHAR* PAACookie = NULL; - int PAACookieLen = 0; + size_t PAACookieLen = 0; const UINT32 capabilities = HTTP_CAPABILITY_TYPE_QUAR_SOH | HTTP_CAPABILITY_MESSAGING_CONSENT_SIGN | HTTP_CAPABILITY_MESSAGING_SERVICE_MSG; if (rdg->extAuth == HTTP_EXTENDED_AUTH_PAA) { - PAACookieLen = - ConvertToUnicode(CP_UTF8, 0, rdg->settings->GatewayAccessToken, -1, &PAACookie, 0); + PAACookie = ConvertUtf8ToWCharAlloc(rdg->settings->GatewayAccessToken, &PAACookieLen); - if (!PAACookie || (PAACookieLen < 0) || (PAACookieLen > UINT16_MAX / 2)) + if (!PAACookie || (PAACookieLen > UINT16_MAX / sizeof(WCHAR))) { free(PAACookie); return FALSE; @@ -1095,18 +1094,20 @@ static BOOL rdg_send_tunnel_authorization(rdpRdg* rdg) { wStream* s; BOOL status; - WCHAR* clientName = NULL; - UINT32 packetSize; - int clientNameLen = - ConvertToUnicode(CP_UTF8, 0, rdg->settings->ClientHostname, -1, &clientName, 0); + WINPR_ASSERT(rdg); + size_t clientNameLen = 0; + WCHAR* clientName = + freerdp_settings_get_string_as_utf16(rdg->settings, FreeRDP_ClientHostname, &clientNameLen); - if (!clientName || (clientNameLen < 0) || (clientNameLen > UINT16_MAX / 2)) + if (!clientName || (clientNameLen >= UINT16_MAX / sizeof(WCHAR))) { free(clientName); return FALSE; } - packetSize = 12 + (UINT32)clientNameLen * sizeof(WCHAR); + clientNameLen++; // length including terminating '\0' + + size_t packetSize = 12ull + clientNameLen * sizeof(WCHAR); s = Stream_New(NULL, packetSize); if (!s) @@ -1119,7 +1120,7 @@ static BOOL rdg_send_tunnel_authorization(rdpRdg* rdg) Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */ Stream_Write_UINT32(s, packetSize); /* PacketLength (4 bytes) */ Stream_Write_UINT16(s, 0); /* FieldsPresent (2 bytes) */ - Stream_Write_UINT16(s, (UINT16)clientNameLen * 2); /* Client name string length */ + Stream_Write_UINT16(s, (UINT16)clientNameLen * sizeof(WCHAR)); /* Client name string length */ Stream_Write_UTF16_String(s, clientName, (size_t)clientNameLen); Stream_SealLength(s); status = rdg_write_packet(rdg, s); @@ -1139,13 +1140,18 @@ static BOOL rdg_send_channel_create(rdpRdg* rdg) wStream* s = NULL; BOOL status = FALSE; WCHAR* serverName = NULL; - int serverNameLen = - ConvertToUnicode(CP_UTF8, 0, rdg->settings->ServerHostname, -1, &serverName, 0); - UINT32 packetSize = 16 + ((UINT32)serverNameLen) * 2; + size_t serverNameLen = 0; - if ((serverNameLen < 0) || (serverNameLen > UINT16_MAX / 2)) + WINPR_ASSERT(rdg); + serverName = + freerdp_settings_get_string_as_utf16(rdg->settings, FreeRDP_ServerHostname, &serverNameLen); + ConvertUtf8ToWCharAlloc(rdg->settings->ServerHostname, &serverNameLen); + + if (!serverName || (serverNameLen >= UINT16_MAX / sizeof(WCHAR))) goto fail; + serverNameLen++; // length including terminating '\0' + size_t packetSize = 16ull + serverNameLen * sizeof(WCHAR); s = Stream_New(NULL, packetSize); if (!s) @@ -1158,7 +1164,7 @@ static BOOL rdg_send_channel_create(rdpRdg* rdg) Stream_Write_UINT8(s, 0); /* Number of alternative resources (1 byte) */ Stream_Write_UINT16(s, (UINT16)rdg->settings->ServerPort); /* Resource port (2 bytes) */ Stream_Write_UINT16(s, 3); /* Protocol number (2 bytes) */ - Stream_Write_UINT16(s, (UINT16)serverNameLen * 2); + Stream_Write_UINT16(s, (UINT16)serverNameLen * sizeof(WCHAR)); Stream_Write_UTF16_String(s, serverName, (size_t)serverNameLen); Stream_SealLength(s); status = rdg_write_packet(rdg, s); diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 6eeaf476f..e61809913 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -427,8 +427,8 @@ static BOOL tsg_packet_quarrequest_to_string(char** buffer, size_t* length, { if (caps->nameLength > INT_MAX) return FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, caps->machineName, (int)caps->nameLength, &name, 0, NULL, - NULL) < 0) + name = ConvertWCharNToUtf8Alloc(caps->machineName, caps->nameLength, NULL); + if (!name) return FALSE; } @@ -529,8 +529,8 @@ static BOOL tsg_packet_quarenc_response_to_string(char** buffer, size_t* length, { if (caps->certChainLen > INT_MAX) return FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, caps->certChainData, (int)caps->certChainLen, &strdata, - 0, NULL, NULL) <= 0) + strdata = ConvertWCharNToUtf8Alloc(caps->certChainData, caps->certChainLen, NULL); + if (!strdata) return FALSE; } @@ -1660,9 +1660,8 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (!TsProxyReadPacketSTringMessage(tsg, pdu->s, &packetStringMessage)) goto fail; - ConvertFromUnicode(CP_UTF8, 0, packetStringMessage.msgBuffer, - packetStringMessage.msgBytes / 2, &messageText, 0, NULL, NULL); - + messageText = ConvertWCharNToUtf8Alloc( + packetStringMessage.msgBuffer, packetStringMessage.msgBytes / sizeof(WCHAR), NULL); WLog_INFO(TAG, "Consent Message: %s", messageText); free(messageText); @@ -1683,9 +1682,8 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu) if (!TsProxyReadPacketSTringMessage(tsg, pdu->s, &packetStringMessage)) goto fail; - ConvertFromUnicode(CP_UTF8, 0, packetStringMessage.msgBuffer, - packetStringMessage.msgBytes / 2, &messageText, 0, NULL, NULL); - + messageText = ConvertWCharNToUtf8Alloc( + packetStringMessage.msgBuffer, packetStringMessage.msgBytes / sizeof(WCHAR), NULL); WLog_INFO(TAG, "Service Message: %s", messageText); free(messageText); @@ -2330,17 +2328,15 @@ DWORD tsg_get_event_handles(rdpTsg* tsg, HANDLE* events, DWORD count) static BOOL tsg_set_hostname(rdpTsg* tsg, const char* hostname) { free(tsg->Hostname); - tsg->Hostname = NULL; - ConvertToUnicode(CP_UTF8, 0, hostname, -1, &tsg->Hostname, 0); - return TRUE; + tsg->Hostname = ConvertUtf8ToWCharAlloc(hostname, NULL); + return tsg->Hostname != NULL; } static BOOL tsg_set_machine_name(rdpTsg* tsg, const char* machineName) { free(tsg->MachineName); - tsg->MachineName = NULL; - ConvertToUnicode(CP_UTF8, 0, machineName, -1, &tsg->MachineName, 0); - return TRUE; + tsg->MachineName = ConvertUtf8ToWCharAlloc(machineName, NULL); + return tsg->MachineName != NULL; } BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, DWORD timeout) diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index 941e489c6..34ba5e53a 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -876,8 +876,7 @@ static BOOL updateEarlyServerCaps(rdpSettings* settings, UINT32 earlyCapabilityF BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) { char buffer[2048] = { 0 }; - char strbuffer[65] = { 0 }; - char* strptr = strbuffer; + char strbuffer[130] = { 0 }; UINT32 version; BYTE connectionType = 0; UINT32 clientColorDepth; @@ -913,15 +912,16 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) Stream_Read_UINT32(s, settings->ClientBuild); /* ClientBuild (4 bytes) */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ - if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)Stream_Pointer(s), 32 / 2, &strptr, - ARRAYSIZE(strbuffer), NULL, NULL) < 1) + if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 32 / sizeof(WCHAR), strbuffer, + ARRAYSIZE(strbuffer)) < 0) { WLog_ERR(TAG, "failed to convert client host name"); return FALSE; } - Stream_Seek(s, 32); - freerdp_settings_set_string(settings, FreeRDP_ClientHostname, strbuffer); + if (!freerdp_settings_set_string(settings, FreeRDP_ClientHostname, strbuffer)) + return FALSE; + Stream_Read_UINT32(s, settings->KeyboardType); /* KeyboardType (4 bytes) */ Stream_Read_UINT32(s, settings->KeyboardSubType); /* KeyboardSubType (4 bytes) */ Stream_Read_UINT32(s, settings->KeyboardFunctionKey); /* KeyboardFunctionKey (4 bytes) */ @@ -980,15 +980,15 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength) if (blockLength < 64) break; - if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)Stream_Pointer(s), 64 / 2, &strptr, - ARRAYSIZE(strbuffer), NULL, NULL) < 1) + if (Stream_Read_UTF16_String_As_UTF8_Buffer(s, 64 / sizeof(WCHAR), strbuffer, + ARRAYSIZE(strbuffer)) < 0) { WLog_ERR(TAG, "failed to convert the client product identifier"); return FALSE; } - Stream_Seek(s, 64); /* clientDigProductId (64 bytes) */ - freerdp_settings_set_string(settings, FreeRDP_ClientProductId, strbuffer); + if (!freerdp_settings_set_string(settings, FreeRDP_ClientProductId, strbuffer)) + return FALSE; blockLength -= 64; if (blockLength < 1) @@ -1122,13 +1122,13 @@ BOOL gcc_write_client_core_data(wStream* s, const rdpMcs* mcs) { char buffer[2048] = { 0 }; WCHAR* clientName = NULL; - int clientNameLength; + size_t clientNameLength; BYTE connectionType; UINT16 highColorDepth; UINT16 supportedColorDepths; UINT16 earlyCapabilityFlags; WCHAR* clientDigProductId = NULL; - int clientDigProductIdLength; + size_t clientDigProductIdLength; rdpContext* context; rdpSettings* settings; @@ -1143,9 +1143,10 @@ BOOL gcc_write_client_core_data(wStream* s, const rdpMcs* mcs) if (!gcc_write_user_data_header(s, CS_CORE, 234)) return FALSE; - clientNameLength = ConvertToUnicode(CP_UTF8, 0, settings->ClientHostname, -1, &clientName, 0); - clientDigProductIdLength = - ConvertToUnicode(CP_UTF8, 0, settings->ClientProductId, -1, &clientDigProductId, 0); + clientName = ConvertUtf8ToWCharAlloc(settings->ClientHostname, &clientNameLength); + clientDigProductId = + ConvertUtf8ToWCharAlloc(settings->ClientProductId, &clientDigProductIdLength); + Stream_Write_UINT32(s, settings->RdpVersion); /* Version */ Stream_Write_UINT16(s, settings->DesktopWidth); /* DesktopWidth */ Stream_Write_UINT16(s, settings->DesktopHeight); /* DesktopHeight */ diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 3c7dff586..56ba1c00c 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -86,7 +86,6 @@ static BOOL rdp_read_info_null_string(UINT32 flags, wStream* s, size_t cbLen, CH if (cbLen > 0) { - WCHAR domain[512 / sizeof(WCHAR) + sizeof(WCHAR)] = { 0 }; /* cbDomain is the size in bytes of the character data in the Domain field. * This size excludes (!) the length of the mandatory null terminator. * Maximum value including the mandatory null terminator: 512 @@ -97,18 +96,19 @@ static BOOL rdp_read_info_null_string(UINT32 flags, wStream* s, size_t cbLen, CH return FALSE; } - Stream_Read(s, domain, cbLen); - if (unicode) { - if (ConvertFromUnicode(CP_UTF8, 0, domain, cbLen, &ret, 0, NULL, NULL) < 1) - { - WLog_ERR(TAG, "failed to convert Domain string"); + size_t len = 0; + ret = Stream_Read_UTF16_String_As_UTF8(s, cbLen / sizeof(WCHAR), &len); + if (!ret && (cbLen > 0)) return FALSE; - } } else { + const char* domain = Stream_Pointer(s); + if (!Stream_SafeSeek(s, cbLen)) + return FALSE; + ret = calloc(cbLen + 1, nullSize); if (!ret) return FALSE; @@ -442,27 +442,27 @@ end: static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s) { BOOL ret = FALSE; - int rc; UINT16 clientAddressFamily; WCHAR* clientAddress = NULL; - UINT16 cbClientAddress; + size_t cbClientAddress; WCHAR* clientDir = NULL; - UINT16 cbClientDir; + size_t cbClientDir; UINT16 cbAutoReconnectCookie; rdpSettings* settings; if (!rdp || !rdp->settings || !s) return FALSE; settings = rdp->settings; clientAddressFamily = settings->IPv6Enabled ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET; - rc = ConvertToUnicode(CP_UTF8, 0, settings->ClientAddress, -1, &clientAddress, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbClientAddress = (UINT16)rc * 2; + clientAddress = ConvertUtf8ToWCharAlloc(settings->ClientAddress, &cbClientAddress); - rc = ConvertToUnicode(CP_UTF8, 0, settings->ClientDir, -1, &clientDir, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) + if (cbClientAddress > (UINT16_MAX / sizeof(WCHAR))) goto fail; - cbClientDir = (UINT16)rc * 2; + cbClientAddress = (UINT16)cbClientAddress * sizeof(WCHAR); + + clientDir = ConvertUtf8ToWCharAlloc(settings->ClientDir, &cbClientDir); + if (cbClientDir > (UINT16_MAX / sizeof(WCHAR))) + goto fail; + cbClientDir = (UINT16)cbClientDir * sizeof(WCHAR); if (settings->ServerAutoReconnectCookie->cbLen > UINT16_MAX) goto fail; @@ -499,21 +499,17 @@ static BOOL rdp_write_extended_info_packet(rdpRdp* rdp, wStream* s) if (settings->EarlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) { - WCHAR DynamicDSTTimeZoneKeyName[254] = { 0 }; - LPWSTR ptr = DynamicDSTTimeZoneKeyName; - - if (!Stream_EnsureRemainingCapacity(s, 10 + sizeof(DynamicDSTTimeZoneKeyName))) + if (!Stream_EnsureRemainingCapacity(s, 10 + 254 * sizeof(WCHAR))) goto fail; /* skip reserved1 and reserved2 fields */ Stream_Seek(s, 4); - rc = ConvertToUnicode(CP_UTF8, 0, settings->DynamicDSTTimeZoneKeyName, -1, &ptr, - ARRAYSIZE(DynamicDSTTimeZoneKeyName)); - if (rc < 0) + size_t rlen = strnlen(settings->DynamicDSTTimeZoneKeyName, 254); + Stream_Write_UINT16(s, (UINT16)rlen); + if (Stream_Write_UTF16_String_From_UTF8( + s, rlen / sizeof(WCHAR), settings->DynamicDSTTimeZoneKeyName, rlen, FALSE) < 0) goto fail; - Stream_Write_UINT16(s, (UINT16)rc); - Stream_Write_UTF16_String(s, ptr, (size_t)rc); Stream_Write_UINT16(s, settings->DynamicDaylightTimeDisabled ? 0x01 : 0x00); } @@ -558,8 +554,11 @@ static BOOL rdp_read_info_string(UINT32 flags, wStream* s, size_t cbLenNonNull, if (unicode) { - if (ConvertFromUnicode(CP_UTF8, 0, domain, -1, &ret, 0, NULL, NULL) < 1) + size_t len = 0; + ret = ConvertWCharNToUtf8Alloc(domain, ARRAYSIZE(domain), &len); + if (!ret || (len == 0)) { + free(ret); WLog_ERR(TAG, "failed to convert Domain string"); return FALSE; } @@ -673,15 +672,15 @@ static BOOL rdp_write_info_packet(rdpRdp* rdp, wStream* s) BOOL ret = FALSE; UINT32 flags; WCHAR* domainW = NULL; - UINT16 cbDomain = 0; + size_t cbDomain = 0; WCHAR* userNameW = NULL; - UINT16 cbUserName = 0; + size_t cbUserName = 0; WCHAR* passwordW = NULL; - UINT16 cbPassword = 0; + size_t cbPassword = 0; WCHAR* alternateShellW = NULL; - UINT16 cbAlternateShell = 0; + size_t cbAlternateShell = 0; WCHAR* workingDirW = NULL; - UINT16 cbWorkingDir = 0; + size_t cbWorkingDir = 0; BOOL usedPasswordCookie = FALSE; rdpSettings* settings; @@ -689,6 +688,7 @@ static BOOL rdp_write_info_packet(rdpRdp* rdp, wStream* s) return FALSE; settings = rdp->settings; + WINPR_ASSERT(settings); flags = INFO_MOUSE | INFO_UNICODE | INFO_LOGONERRORS | INFO_MAXIMIZESHELL | INFO_ENABLEWINDOWSKEY | INFO_DISABLECTRLALTDEL | INFO_MOUSE_HAS_WHEEL | @@ -745,32 +745,18 @@ static BOOL rdp_write_info_packet(rdpRdp* rdp, wStream* s) } } - if (settings->Domain) - { - const int rc = ConvertToUnicode(CP_UTF8, 0, settings->Domain, -1, &domainW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbDomain = (UINT16)rc * 2; - } - else - { - domainW = NULL; - cbDomain = 0; - } - - /* excludes (!) the length of the mandatory null terminator */ - cbDomain = cbDomain >= 2 ? cbDomain - 2 : cbDomain; + domainW = freerdp_settings_get_string_as_utf16(settings, FreeRDP_Domain, &cbDomain); + if (cbDomain > UINT16_MAX / sizeof(WCHAR)) + goto fail; + cbDomain *= sizeof(WCHAR); /* user name provided by the expert for connecting to the novice computer */ - { - const int rc = ConvertToUnicode(CP_UTF8, 0, settings->Username, -1, &userNameW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbUserName = (UINT16)rc * 2; - } - /* excludes (!) the length of the mandatory null terminator */ - cbUserName = cbUserName >= 2 ? cbUserName - 2 : cbUserName; + userNameW = freerdp_settings_get_string_as_utf16(settings, FreeRDP_Username, &cbUserName); + if (cbUserName > UINT16_MAX / sizeof(WCHAR)) + goto fail; + cbUserName *= sizeof(WCHAR); + const char* pin = "*"; if (!settings->RemoteAssistanceMode) { /* Ignore redirection password if we´re using smartcard and have the pin as password */ @@ -792,82 +778,54 @@ static BOOL rdp_write_info_packet(rdpRdp* rdp, wStream* s) cbPassword = (UINT16)settings->RedirectionPasswordLength; } else - { - const int rc = ConvertToUnicode(CP_UTF8, 0, settings->Password, -1, &passwordW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbPassword = (UINT16)rc * 2; - } + pin = freerdp_settings_get_string(settings, FreeRDP_Password); } + + if (!usedPasswordCookie && pin) + { + passwordW = ConvertUtf8ToWCharAlloc(pin, &cbPassword); + if (cbPassword > UINT16_MAX / sizeof(WCHAR)) + goto fail; + cbPassword = (UINT16)cbPassword * sizeof(WCHAR); + } + + const char* rain = freerdp_settings_get_string(settings, FreeRDP_RemoteAssistancePassword); + if (!settings->RemoteAssistanceMode) + rain = freerdp_settings_get_string(settings, FreeRDP_AlternateShell); else { /* This field MUST be filled with "*" */ - const int rc = ConvertToUnicode(CP_UTF8, 0, "*", -1, &passwordW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbPassword = (UINT16)rc * 2; - } - - /* excludes (!) the length of the mandatory null terminator */ - cbPassword = cbPassword >= 2 ? cbPassword - 2 : cbPassword; - - if (!settings->RemoteAssistanceMode) - { - const int rc = - ConvertToUnicode(CP_UTF8, 0, settings->AlternateShell, -1, &alternateShellW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbAlternateShell = (UINT16)rc * 2; - } - else - { - int rc; if (settings->RemoteAssistancePassStub) - { - /* This field MUST be filled with "*" */ - rc = ConvertToUnicode(CP_UTF8, 0, "*", -1, &alternateShellW, 0); - } - else - { - /* This field must contain the remote assistance password */ - rc = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistancePassword, -1, - &alternateShellW, 0); - } - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbAlternateShell = (UINT16)rc * 2; + rain = "*"; } - - /* excludes (!) the length of the mandatory null terminator */ - cbAlternateShell = cbAlternateShell >= 2 ? cbAlternateShell - 2 : cbAlternateShell; - - if (!settings->RemoteAssistanceMode) + if (rain) { - const int rc = - ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDirW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) + alternateShellW = ConvertUtf8ToWCharAlloc(rain, &cbAlternateShell); + if (!alternateShellW || (cbAlternateShell > (UINT16_MAX / sizeof(WCHAR)))) goto fail; - cbWorkingDir = (UINT16)rc * 2; - } - else - { - /* Remote Assistance Session Id */ - const int rc = - ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistanceSessionId, -1, &workingDirW, 0); - if ((rc < 0) || (rc > (UINT16_MAX / 2))) - goto fail; - cbWorkingDir = (UINT16)rc * 2; + cbAlternateShell = (UINT16)cbAlternateShell * sizeof(WCHAR); } - /* excludes (!) the length of the mandatory null terminator */ - cbWorkingDir = cbWorkingDir >= 2 ? cbWorkingDir - 2 : cbWorkingDir; + size_t inputId = FreeRDP_RemoteAssistanceSessionId; + if (!freerdp_settings_get_bool(settings, FreeRDP_RemoteAssistanceMode)) + inputId = FreeRDP_ShellWorkingDirectory; + + workingDirW = freerdp_settings_get_string_as_utf16(settings, inputId, &cbWorkingDir); + if (cbWorkingDir > (UINT16_MAX / sizeof(WCHAR))) + goto fail; + cbWorkingDir = (UINT16)cbWorkingDir * sizeof(WCHAR); + + if (!Stream_EnsureRemainingCapacity(s, 18ull + cbDomain + cbUserName + cbPassword + + cbAlternateShell + cbWorkingDir + 5 * sizeof(WCHAR))) + goto fail; + Stream_Write_UINT32(s, settings->KeyboardCodePage); /* CodePage (4 bytes) */ Stream_Write_UINT32(s, flags); /* flags (4 bytes) */ - Stream_Write_UINT16(s, cbDomain); /* cbDomain (2 bytes) */ - Stream_Write_UINT16(s, cbUserName); /* cbUserName (2 bytes) */ - Stream_Write_UINT16(s, cbPassword); /* cbPassword (2 bytes) */ - Stream_Write_UINT16(s, cbAlternateShell); /* cbAlternateShell (2 bytes) */ - Stream_Write_UINT16(s, cbWorkingDir); /* cbWorkingDir (2 bytes) */ + Stream_Write_UINT16(s, (UINT32)cbDomain); /* cbDomain (2 bytes) */ + Stream_Write_UINT16(s, (UINT32)cbUserName); /* cbUserName (2 bytes) */ + Stream_Write_UINT16(s, (UINT32)cbPassword); /* cbPassword (2 bytes) */ + Stream_Write_UINT16(s, (UINT32)cbAlternateShell); /* cbAlternateShell (2 bytes) */ + Stream_Write_UINT16(s, (UINT32)cbWorkingDir); /* cbWorkingDir (2 bytes) */ Stream_Write(s, domainW, cbDomain); @@ -966,6 +924,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s) BOOL rdp_send_client_info(rdpRdp* rdp) { wStream* s; + WINPR_ASSERT(rdp); rdp->sec_flags |= SEC_INFO_PKT; s = rdp_send_stream_init(rdp); @@ -975,7 +934,11 @@ BOOL rdp_send_client_info(rdpRdp* rdp) return FALSE; } - rdp_write_info_packet(rdp, s); + if (!rdp_write_info_packet(rdp, s)) + { + Stream_Release(s); + return FALSE; + } return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); } @@ -1016,7 +979,9 @@ static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info) goto fail; } - if (ConvertFromUnicode(CP_UTF8, 0, ptrconv.wp, -1, &info->domain, 0, NULL, FALSE) < 1) + size_t len = 0; + info->domain = ConvertWCharNToUtf8Alloc(ptrconv.wp, cbDomain / sizeof(WCHAR), &len); + if (!info->domain || (len == 0)) { WLog_ERR(TAG, "failed to convert the Domain string"); goto fail; @@ -1045,7 +1010,9 @@ static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info) goto fail; } - if (ConvertFromUnicode(CP_UTF8, 0, ptrconv.wp, -1, &info->username, 0, NULL, FALSE) < 1) + size_t len = 0; + info->username = ConvertWCharNToUtf8Alloc(ptrconv.wp, cbUserName / sizeof(WCHAR), &len); + if (!info->username || (len == 0)) { WLog_ERR(TAG, "failed to convert the UserName string"); goto fail; @@ -1138,7 +1105,9 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) goto fail; } - if (ConvertFromUnicode(CP_UTF8, 0, domain, -1, &info->domain, 0, NULL, FALSE) < 1) + size_t len = 0; + info->domain = ConvertWCharNToUtf8Alloc(domain, cbDomain / sizeof(WCHAR), &len); + if (!info->domain || (len == 0)) { WLog_ERR(TAG, "failed to convert the Domain string"); goto fail; @@ -1173,9 +1142,11 @@ static BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info* info) goto fail; } - if (ConvertFromUnicode(CP_UTF8, 0, user, -1, &info->username, 0, NULL, FALSE) < 1) + size_t len = 0; + info->username = ConvertWCharNToUtf8Alloc(user, cbUserName / sizeof(WCHAR), &len); + if (!info->username || (len == 0)) { - WLog_ERR(TAG, "failed to convert the Domain string"); + WLog_ERR(TAG, "failed to convert the UserName string"); goto fail; } } @@ -1368,51 +1339,33 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s) static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info) { + const size_t charLen = 52 / sizeof(WCHAR); + const size_t userCharLen = 512 / sizeof(WCHAR); + size_t sz = 4 + 52 + 4 + 512 + 4; - int ilen; - UINT32 len; - WCHAR* wString = NULL; + size_t len; if (!Stream_EnsureRemainingCapacity(s, sz)) return FALSE; /* domain */ - ilen = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0); - - if (ilen < 0) + len = strnlen(info->domain, charLen + 1); + if (len > charLen) return FALSE; - len = (UINT32)ilen * 2; - - if (len > 52) - { - free(wString); + Stream_Write_UINT32(s, len * sizeof(WCHAR)); + if (Stream_Write_UTF16_String_From_UTF8(s, charLen, info->domain, len, TRUE) < 0) return FALSE; - } - Stream_Write_UINT32(s, len); - Stream_Write(s, wString, len); - Stream_Seek(s, 52 - len); - free(wString); /* username */ - wString = NULL; - ilen = ConvertToUnicode(CP_UTF8, 0, info->username, -1, &wString, 0); - - if (ilen < 0) + len = strnlen(info->username, userCharLen + 1); + if (len > userCharLen) return FALSE; - len = (UINT32)ilen * 2; - - if (len > 512) - { - free(wString); + Stream_Write_UINT32(s, len * sizeof(WCHAR)); + if (Stream_Write_UTF16_String_From_UTF8(s, userCharLen, info->username, len, TRUE) < 0) return FALSE; - } - Stream_Write_UINT32(s, len); - Stream_Write(s, wString, len); - Stream_Seek(s, 512 - len); - free(wString); /* sessionId */ Stream_Write_UINT32(s, info->sessionId); return TRUE; @@ -1421,8 +1374,6 @@ static BOOL rdp_write_logon_info_v1(wStream* s, logon_info* info) static BOOL rdp_write_logon_info_v2(wStream* s, logon_info* info) { size_t domainLen, usernameLen; - int len; - WCHAR* wString = NULL; if (!Stream_EnsureRemainingCapacity(s, logonInfoV2TotalSize)) return FALSE; @@ -1434,30 +1385,20 @@ static BOOL rdp_write_logon_info_v2(wStream* s, logon_info* info) */ Stream_Write_UINT32(s, logonInfoV2Size); Stream_Write_UINT32(s, info->sessionId); - domainLen = strlen(info->domain); - if (domainLen > UINT32_MAX) + domainLen = strnlen(info->domain, UINT32_MAX); + if (domainLen >= UINT32_MAX / sizeof(WCHAR)) return FALSE; - Stream_Write_UINT32(s, (UINT32)(domainLen + 1) * 2); - usernameLen = strlen(info->username); - if (usernameLen > UINT32_MAX) + Stream_Write_UINT32(s, (UINT32)(domainLen + 1) * sizeof(WCHAR)); + usernameLen = strnlen(info->username, UINT32_MAX); + if (usernameLen >= UINT32_MAX / sizeof(WCHAR)) return FALSE; - Stream_Write_UINT32(s, (UINT32)(usernameLen + 1) * 2); + Stream_Write_UINT32(s, (UINT32)(usernameLen + 1) * sizeof(WCHAR)); Stream_Seek(s, logonInfoV2ReservedSize); - len = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0); - - if (len < 0) + if (Stream_Write_UTF16_String_From_UTF8(s, domainLen + 1, info->domain, domainLen, TRUE) < 0) return FALSE; - - Stream_Write(s, wString, (size_t)len * 2); - free(wString); - wString = NULL; - len = ConvertToUnicode(CP_UTF8, 0, info->username, -1, &wString, 0); - - if (len < 0) + if (Stream_Write_UTF16_String_From_UTF8(s, usernameLen + 1, info->username, usernameLen, TRUE) < + 0) return FALSE; - - Stream_Write(s, wString, (size_t)len * 2); - free(wString); return TRUE; } diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index ca8468063..057fe399c 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -367,11 +367,13 @@ static void license_print_product_info(const LICENSE_PRODUCT_INFO* productInfo) char* ProductId = NULL; WINPR_ASSERT(productInfo); + WINPR_ASSERT(productInfo->pbCompanyName); + WINPR_ASSERT(productInfo->pbProductId); - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)productInfo->pbCompanyName, - productInfo->cbCompanyName / 2, &CompanyName, 0, NULL, NULL); - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)productInfo->pbProductId, productInfo->cbProductId / 2, - &ProductId, 0, NULL, NULL); + CompanyName = ConvertWCharToUtf8Alloc(productInfo->pbCompanyName, + productInfo->cbCompanyName / sizeof(WCHAR)); + ProductId = + ConvertWCharToUtf8Alloc(productInfo->pbProductId, productInfo->cbProductId / sizeof(WCHAR)); WLog_INFO(TAG, "ProductInfo:"); WLog_INFO(TAG, "\tdwVersion: 0x%08" PRIX32 "", productInfo->dwVersion); WLog_INFO(TAG, "\tCompanyName: %s", CompanyName); @@ -2683,7 +2685,7 @@ BOOL license_server_send_request(rdpLicense* license) BOOL license_server_configure(rdpLicense* license) { - int len; + size_t len; wStream* s; UINT32 algs[] = { KEY_EXCHANGE_ALG_RSA }; UINT32 x; @@ -2715,17 +2717,15 @@ BOOL license_server_configure(rdpLicense* license) return FALSE; license->ProductInfo->dwVersion = ProductVersion; - len = ConvertToUnicode(CP_UTF8, 0, CompanyName, -1, - (WCHAR**)&license->ProductInfo->pbCompanyName, 0); - if (!license->ProductInfo->pbCompanyName) + license->ProductInfo->pbCompanyName = (BYTE*)ConvertUtf8ToWCharAlloc(CompanyName, &len); + if (!license->ProductInfo->pbCompanyName || (len > UINT32_MAX / sizeof(WCHAR))) return FALSE; - license->ProductInfo->cbCompanyName = len * sizeof(WCHAR); + license->ProductInfo->cbCompanyName = (UINT32)len * sizeof(WCHAR); - len = ConvertToUnicode(CP_UTF8, 0, ProductName, -1, (WCHAR**)&license->ProductInfo->pbProductId, - 0); - if (!license->ProductInfo->pbProductId) + license->ProductInfo->pbProductId = (BYTE*)ConvertUtf8ToWCharAlloc(ProductName, &len); + if (!license->ProductInfo->pbProductId || (len > UINT32_MAX / sizeof(WCHAR))) return FALSE; - license->ProductInfo->cbProductId = len * sizeof(WCHAR); + license->ProductInfo->cbProductId = (UINT32)len * sizeof(WCHAR); if (!license_read_binary_blob_data(license->KeyExchangeList, BB_KEY_EXCHG_ALG_BLOB, algs, sizeof(algs))) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 5c7acc2bc..8e279e4ca 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -388,9 +388,16 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego) if (nego->PreconnectionBlob) { - cchPCB = (UINT16)ConvertToUnicode(CP_UTF8, 0, nego->PreconnectionBlob, -1, &wszPCB, 0); + size_t len = 0; + wszPCB = ConvertUtf8ToWCharAlloc(nego->PreconnectionBlob, &len); + if (len > UINT16_MAX - 1) + { + free(wszPCB); + return FALSE; + } + cchPCB = len; cchPCB += 1; /* zero-termination */ - cbSize += cchPCB * 2; + cbSize += cchPCB * sizeof(WCHAR); } s = Stream_New(NULL, cbSize); @@ -410,7 +417,7 @@ BOOL nego_send_preconnection_pdu(rdpNego* nego) if (wszPCB) { - Stream_Write(s, wszPCB, cchPCB * 2); /* wszPCB */ + Stream_Write(s, wszPCB, cchPCB * sizeof(WCHAR)); /* wszPCB */ free(wszPCB); } diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 4e655502c..c5ebcaacf 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -208,13 +208,13 @@ static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla) if (!settings->CspName) { - if (nla->smartcardCert->csp && ConvertFromUnicode(CP_UTF8, 0, nla->smartcardCert->csp, -1, - &settings->CspName, 0, NULL, FALSE) <= 0) + if (nla->smartcardCert->csp && !freerdp_settings_set_string_from_utf16( + settings, FreeRDP_CspName, nla->smartcardCert->csp)) { WLog_ERR(TAG, "unable to set CSP name"); goto out; } - else if (!(settings->CspName = _strdup(MS_SCARD_PROV_A))) + else if (!freerdp_settings_set_string(settings, FreeRDP_CspName, MS_SCARD_PROV_A)) { WLog_ERR(TAG, "unable to set CSP name"); goto out; @@ -223,8 +223,8 @@ static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla) if (!settings->ReaderName && nla->smartcardCert->reader) { - if (ConvertFromUnicode(CP_UTF8, 0, nla->smartcardCert->reader, -1, &settings->ReaderName, 0, - NULL, NULL) < 0) + if (!freerdp_settings_set_string_from_utf16(settings, FreeRDP_ReaderName, + nla->smartcardCert->reader)) { WLog_ERR(TAG, "unable to copy reader name"); goto out; @@ -233,8 +233,8 @@ static BOOL nla_adjust_settings_from_smartcard(rdpNla* nla) if (!settings->ContainerName && nla->smartcardCert->containerName) { - if (ConvertFromUnicode(CP_UTF8, 0, nla->smartcardCert->containerName, -1, - &settings->ContainerName, 0, NULL, NULL) < 0) + if (!freerdp_settings_set_string_from_utf16(settings, FreeRDP_ContainerName, + nla->smartcardCert->containerName)) { WLog_ERR(TAG, "unable to copy container name"); goto out; @@ -1162,20 +1162,20 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla) { 3, FreeRDP_ContainerName }, { 4, FreeRDP_CspName } }; WinPrAsn1_OctetString octet_string = { 0 }; - char* str; - BOOL res; + BOOL ret; /* TSSmartCardCreds */ if (!WinPrAsn1EncSeqContainer(enc)) goto out; /* pin [0] OCTET STRING */ - str = freerdp_settings_get_string_writable(settings, FreeRDP_Password); - octet_string.len = - ConvertToUnicode(CP_UTF8, 0, str, -1, (LPWSTR*)&octet_string.data, 0) * sizeof(WCHAR); - res = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string); + size_t s; + octet_string.data = + (BYTE*)freerdp_settings_get_string_as_utf16(settings, FreeRDP_Password, &s); + octet_string.len = s * sizeof(WCHAR); + ret = WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) > 0; free(octet_string.data); - if (!res) + if (!ret) goto out; /* cspData [1] SEQUENCE */ @@ -1187,15 +1187,17 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla) freerdp_settings_get_uint32(settings, FreeRDP_KeySpec))) goto out; - for (int i = 0; i < ARRAYSIZE(cspData_fields); i++) + for (size_t i = 0; i < ARRAYSIZE(cspData_fields); i++) { - str = freerdp_settings_get_string_writable(settings, cspData_fields[i].setting_id); - octet_string.len = - ConvertToUnicode(CP_UTF8, 0, str, -1, (LPWSTR*)&octet_string.data, 0) * - sizeof(WCHAR); + size_t len; + + octet_string.data = (BYTE*)freerdp_settings_get_string_as_utf16( + settings, cspData_fields[i].setting_id, &len); + octet_string.len = len * sizeof(WCHAR); if (octet_string.len) { - ret = WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string); + ret = WinPrAsn1EncContextualOctetString(enc, cspData_fields[i].tag, &octet_string) > + 0; free(octet_string.data); if (!ret) goto out; @@ -1232,11 +1234,11 @@ static BOOL nla_encode_ts_credentials(rdpNla* nla) password.data = (BYTE*)nla->identity->Password; } - if (!WinPrAsn1EncContextualOctetString(enc, 0, &domain)) + if (WinPrAsn1EncContextualOctetString(enc, 0, &domain) == 0) goto out; - if (!WinPrAsn1EncContextualOctetString(enc, 1, &username)) + if (WinPrAsn1EncContextualOctetString(enc, 1, &username) == 0) goto out; - if (!WinPrAsn1EncContextualOctetString(enc, 2, &password)) + if (WinPrAsn1EncContextualOctetString(enc, 2, &password) == 0) goto out; /* End TSPasswordCreds */ @@ -1340,7 +1342,7 @@ BOOL nla_send(rdpNla* nla) /* negoToken [0] OCTET STRING */ octet_string.data = buffer->pvBuffer; octet_string.len = buffer->cbBuffer; - if (!WinPrAsn1EncContextualOctetString(enc, 0, &octet_string)) + if (WinPrAsn1EncContextualOctetString(enc, 0, &octet_string) == 0) goto fail; /* End negoTokens (SEQUENCE OF SEQUENCE) */ @@ -1354,7 +1356,7 @@ BOOL nla_send(rdpNla* nla) WLog_DBG(TAG, " ----->> auth info"); octet_string.data = nla->authInfo.pvBuffer; octet_string.len = nla->authInfo.cbBuffer; - if (!WinPrAsn1EncContextualOctetString(enc, 2, &octet_string)) + if (WinPrAsn1EncContextualOctetString(enc, 2, &octet_string) == 0) goto fail; sspi_SecBufferFree(&nla->authInfo); } @@ -1365,7 +1367,7 @@ BOOL nla_send(rdpNla* nla) WLog_DBG(TAG, " ----->> public key auth"); octet_string.data = nla->pubKeyAuth.pvBuffer; octet_string.len = nla->pubKeyAuth.cbBuffer; - if (!WinPrAsn1EncContextualOctetString(enc, 3, &octet_string)) + if (WinPrAsn1EncContextualOctetString(enc, 3, &octet_string) == 0) goto fail; sspi_SecBufferFree(&nla->pubKeyAuth); } @@ -1385,7 +1387,7 @@ BOOL nla_send(rdpNla* nla) WLog_DBG(TAG, " ----->> client nonce"); octet_string.data = nla->ClientNonce.pvBuffer; octet_string.len = nla->ClientNonce.cbBuffer; - if (!WinPrAsn1EncContextualOctetString(enc, 5, &octet_string)) + if (WinPrAsn1EncContextualOctetString(enc, 5, &octet_string) == 0) goto fail; } diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 8de025676..69648e7e8 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -824,7 +824,8 @@ static state_run_t peer_recv_callback_internal(rdpTransport* transport, wStream* if (SelectedProtocol & PROTOCOL_HYBRID) { - SEC_WINNT_AUTH_IDENTITY* identity = nego_get_identity(rdp->nego); + SEC_WINNT_AUTH_IDENTITY_INFO* identity = + (SEC_WINNT_AUTH_IDENTITY_INFO*)nego_get_identity(rdp->nego); sspi_CopyAuthIdentity(&client->identity, identity); IFCALLRET(client->Logon, client->authenticated, client, &client->identity, TRUE); @@ -1250,10 +1251,11 @@ static BOOL freerdp_peer_send_server_redirection_pdu( if (targetNetAddress) { + size_t len = 0; redirFlags |= LB_TARGET_NET_ADDRESS; - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetNetAddress, -1, &targetNetAddressW, 0); - targetNetAddressLength = (strlen(targetNetAddress) + 1) * sizeof(WCHAR); + targetNetAddressW = ConvertUtf8ToWCharAlloc(targetNetBiosName, &len); + targetNetAddressLength = (len + 1) * sizeof(WCHAR); length += 4 + targetNetAddressLength; } @@ -1268,50 +1270,55 @@ static BOOL freerdp_peer_send_server_redirection_pdu( if (userName) { + size_t len = 0; redirFlags |= LB_USERNAME; - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)userName, -1, &userNameW, 0); - userNameLength = (strlen(userName) + 1) * sizeof(WCHAR); + userNameW = ConvertUtf8ToWCharAlloc(userName, &len); + userNameLength = (len + 1) * sizeof(WCHAR); length += 4 + userNameLength; } if (domain) { + size_t len = 0; redirFlags |= LB_DOMAIN; - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)domain, -1, &domainW, 0); - domainLength = (strlen(domain) + 1) * sizeof(WCHAR); + domainW = ConvertUtf8ToWCharAlloc(domain, &len); + domainLength = (len + 1) * sizeof(WCHAR); length += 4 + domainLength; } if (password) { + size_t len = 0; redirFlags |= LB_PASSWORD; - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)password, -1, &passwordW, 0); - passwordLength = (strlen(password) + 1) * sizeof(WCHAR); + passwordW = ConvertUtf8ToWCharAlloc(password, &len); + passwordLength = (len + 1) * sizeof(WCHAR); length += 4 + passwordLength; } if (targetFQDN) { + size_t len = 0; redirFlags |= LB_TARGET_FQDN; - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetFQDN, -1, &targetFQDNW, 0); - targetFQDNLength = (strlen(targetFQDN) + 1) * sizeof(WCHAR); + targetFQDNW = ConvertUtf8ToWCharAlloc(targetFQDN, &len); + targetFQDNLength = (len + 1) * sizeof(WCHAR); length += 4 + targetFQDNLength; } if (targetNetBiosName) { + size_t len = 0; redirFlags |= LB_TARGET_NETBIOS_NAME; - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetNetBiosName, -1, &targetNetBiosNameW, 0); - targetNetBiosNameLength = (strlen(targetNetBiosName) + 1) * sizeof(WCHAR); + targetNetBiosNameW = ConvertUtf8ToWCharAlloc(targetNetBiosName, &len); + targetNetBiosNameLength = (len + 1) * sizeof(WCHAR); length += 4 + targetNetBiosNameLength; } @@ -1333,9 +1340,9 @@ static BOOL freerdp_peer_send_server_redirection_pdu( targetNetAddressesWLength = calloc(targetNetAddressesCount, sizeof(UINT32)); for (i = 0; i < targetNetAddressesCount; i++) { - ConvertToUnicode(CP_UTF8, 0, (LPCSTR)targetNetAddresses[i], -1, &targetNetAddressesW[i], - 0); - targetNetAddressesWLength[i] = (strlen(targetNetAddresses[i]) + 1) * sizeof(WCHAR); + size_t len = 0; + targetNetAddressesW[i] = ConvertUtf8ToWCharAlloc(targetNetAddresses[i], &len); + targetNetAddressesWLength[i] = (len + 1) * sizeof(WCHAR); targetNetAddressesLength += 4 + targetNetAddressesWLength[i]; } diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index 6932ee1ff..adc948208 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -128,7 +128,8 @@ static BOOL rdp_redirection_read_unicode_string(wStream* s, char** str, size_t m return FALSE; } - if (ConvertFromUnicode(CP_UTF8, 0, wstr, -1, str, 0, NULL, NULL) < 1) + *str = ConvertWCharNToUtf8Alloc(wstr, length / sizeof(WCHAR), NULL); + if (!*str) { WLog_ERR(TAG, "rdp_redirection_read_string failure: string conversion failed"); return FALSE; diff --git a/libfreerdp/core/smartcardlogon.c b/libfreerdp/core/smartcardlogon.c index beb8f5895..03a9976b7 100644 --- a/libfreerdp/core/smartcardlogon.c +++ b/libfreerdp/core/smartcardlogon.c @@ -224,8 +224,8 @@ static BOOL list_provider_keys(const rdpSettings* settings, NCRYPT_PROV_HANDLE p if (!cert) goto out; - if (ConvertFromUnicode(CP_UTF8, 0, keyName->pszName, -1, &cert->keyName, 0, NULL, NULL) <= - 0) + cert->keyName = ConvertWCharToUtf8Alloc(keyName->pszName, NULL); + if (!cert->keyName) goto endofloop; WLog_DBG(TAG, "opening key %s", cert->keyName); @@ -431,17 +431,16 @@ static BOOL smartcard_hw_enumerateCerts(const rdpSettings* settings, LPCWSTR csp if (reader) { - int res; size_t readerSz = strlen(reader); char* scopeStr = malloc(4 + readerSz + 1 + 1); if (!scopeStr) goto out; _snprintf(scopeStr, readerSz + 5, "\\\\.\\%s\\", reader); - res = ConvertToUnicode(CP_UTF8, 0, scopeStr, -1, &scope, 0); + scope = ConvertUtf8NToWCharAlloc(scopeStr, readerSz + 5, NULL); free(scopeStr); - if (res <= 0) + if (!scope) goto out; } @@ -483,8 +482,7 @@ static BOOL smartcard_hw_enumerateCerts(const rdpSettings* settings, LPCWSTR csp char providerNameStr[256] = { 0 }; const NCryptProviderName* name = &names[i]; - if (WideCharToMultiByte(CP_UTF8, 0, name->pszName, -1, providerNameStr, - sizeof(providerNameStr), NULL, FALSE) <= 0) + if (ConvertWCharToUtf8(name->pszName, providerNameStr, ARRAYSIZE(providerNameStr)) < 0) { _snprintf(providerNameStr, sizeof(providerNameStr), ""); WLog_ERR(TAG, "unable to convert provider name to char*, will show it as '%s'", @@ -576,10 +574,12 @@ static SmartcardCertInfo* smartcardCertInfo_New(const char* privKeyPEM, const ch goto fail; } - if (ConvertToUnicode(CP_UTF8, 0, "FreeRDP Emulator", -1, &cert->reader, 0) < 0) + cert->reader = ConvertUtf8ToWCharAlloc("FreeRDP Emulator", NULL); + if (!cert->reader) goto fail; - if (ConvertToUnicode(CP_UTF8, 0, "Private Key 00", -1, &cert->containerName, 0) < 0) + cert->containerName = ConvertUtf8ToWCharAlloc("Private Key 00", NULL); + if (!cert->containerName) goto fail; /* compute PKINIT args FILE:, @@ -682,7 +682,7 @@ BOOL smartcard_enumerateCerts(const rdpSettings* settings, SmartcardCertInfo*** if (freerdp_settings_get_bool(settings, FreeRDP_SmartcardEmulation)) return smartcard_sw_enumerateCerts(settings, scCerts, retCount); - if (CspName && ConvertToUnicode(CP_UTF8, 0, CspName, -1, &csp, 0) <= 0) + if (CspName && (!(csp = ConvertUtf8ToWCharAlloc(CspName, NULL)))) { WLog_ERR(TAG, "error while converting CSP to WCHAR"); return FALSE; diff --git a/libfreerdp/core/window.c b/libfreerdp/core/window.c index ddca3bf34..a64371f97 100644 --- a/libfreerdp/core/window.c +++ b/libfreerdp/core/window.c @@ -70,7 +70,7 @@ BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string) BOOL utf8_string_to_rail_string(const char* string, RAIL_UNICODE_STRING* unicode_string) { WCHAR* buffer = NULL; - int length = 0; + size_t len = 0; free(unicode_string->string); unicode_string->string = NULL; unicode_string->length = 0; @@ -78,16 +78,16 @@ BOOL utf8_string_to_rail_string(const char* string, RAIL_UNICODE_STRING* unicode if (!string || strlen(string) < 1) return TRUE; - length = ConvertToUnicode(CP_UTF8, 0, string, -1, &buffer, 0); + buffer = ConvertUtf8ToWCharAlloc(string, &len); - if ((length < 0) || ((size_t)length * sizeof(WCHAR) > UINT16_MAX)) + if (!buffer || (len * sizeof(WCHAR) > UINT16_MAX)) { free(buffer); return FALSE; } unicode_string->string = (BYTE*)buffer; - unicode_string->length = (UINT16)length * sizeof(WCHAR); + unicode_string->length = (UINT16)len * sizeof(WCHAR); return TRUE; } diff --git a/libfreerdp/crypto/ber.c b/libfreerdp/crypto/ber.c index 9e1d55b20..9189a3f6c 100644 --- a/libfreerdp/crypto/ber.c +++ b/libfreerdp/crypto/ber.c @@ -402,10 +402,11 @@ size_t ber_write_char_to_unicode_octet_string(wStream* s, const char* str) size_t size = 0; size_t length = strlen(str) + 1; size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); - size += ber_write_length(s, length * 2); - MultiByteToWideChar(CP_UTF8, 0, str, length, (LPWSTR)Stream_Pointer(s), length * 2); - Stream_Seek(s, length * 2); - return size + length * 2; + size += ber_write_length(s, length * sizeof(WCHAR)); + + if (Stream_Write_UTF16_String_From_UTF8(s, length, str, length, TRUE) < 0) + return 0; + return size + length * sizeof(WCHAR); } size_t ber_write_contextual_unicode_octet_string(wStream* s, BYTE tag, LPWSTR str) @@ -429,10 +430,10 @@ size_t ber_write_contextual_char_to_unicode_octet_string(wStream* s, BYTE tag, c ret = ber_write_contextual_tag(s, tag, inner_len, TRUE); ret += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, FALSE); - ret += ber_write_length(s, len * 2); - if (MultiByteToWideChar(CP_UTF8, 0, str, len, (LPWSTR)Stream_Pointer(s), len * 2) < 0) + ret += ber_write_length(s, len * sizeof(WCHAR)); + + if (Stream_Write_UTF16_String_From_UTF8(s, len, str, len, TRUE) < 0) return 0; - Stream_Seek(s, len * 2); return ret + len; } @@ -461,23 +462,16 @@ BOOL ber_read_unicode_octet_string(wStream* s, LPWSTR* str) BOOL ber_read_char_from_unicode_octet_string(wStream* s, char** str) { - size_t length, outLen; + size_t length; char* ptr; + *str = NULL; if (!ber_read_octet_string_tag(s, &length)) return FALSE; - if (!Stream_CheckAndLogRequiredLength(TAG, s, length)) - return FALSE; - - outLen = (length / 2) + 1; - ptr = malloc(outLen); + ptr = Stream_Read_UTF16_String_As_UTF8(s, length / sizeof(WCHAR), NULL); if (!ptr) return FALSE; - ptr[outLen - 1] = 0; - - WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)Stream_Pointer(s), length, ptr, outLen, NULL, FALSE); - Stream_Seek(s, length); *str = ptr; return TRUE; } diff --git a/libfreerdp/crypto/certificate.c b/libfreerdp/crypto/certificate.c index 0d3336cb1..0df4d283b 100644 --- a/libfreerdp/crypto/certificate.c +++ b/libfreerdp/crypto/certificate.c @@ -72,9 +72,10 @@ static HANDLE open_file(const char* name, DWORD dwDesiredAccess, DWORD dwShareMo DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes) { HANDLE fp; - WCHAR* wfile = NULL; - int rc = ConvertToUnicode(CP_UTF8, 0, name, -1, &wfile, 0); - if (rc <= 0) + if (!name) + return INVALID_HANDLE_VALUE; + WCHAR* wfile = ConvertUtf8ToWCharAlloc(name, NULL); + if (!wfile) return INVALID_HANDLE_VALUE; fp = CreateFileW(wfile, dwDesiredAccess, 0, NULL, dwCreationDisposition, dwFlagsAndAttributes, @@ -124,10 +125,12 @@ static void certificate_store_uninit(rdpCertificateStore* certificate_store) static BOOL ensure_path_exists(const char* path) { BOOL res = FALSE; - WCHAR* wpath = NULL; + if (!path) + return FALSE; /* Use wide character functions to allow proper unicode handling on windows */ - int rc = ConvertToUnicode(CP_UTF8, 0, path, -1, &wpath, 0); - if (rc <= 0) + WCHAR* wpath = ConvertUtf8ToWCharAlloc(path, NULL); + + if (!wpath) return FALSE; if (!PathFileExistsW(wpath)) @@ -368,7 +371,7 @@ static WCHAR* certificate_get_cert_file_name(rdpCertificateStore* store, if (!pem) goto fail; - ConvertToUnicode(CP_UTF8, 0, pem, -1, &wpem, 0); + wpem = ConvertUtf8ToWCharAlloc(pem, NULL); fail: free(pem); winpr_Digest_Free(ctx); diff --git a/libfreerdp/utils/smartcard_call.c b/libfreerdp/utils/smartcard_call.c index f13109a6f..f4a526970 100644 --- a/libfreerdp/utils/smartcard_call.c +++ b/libfreerdp/utils/smartcard_call.c @@ -289,17 +289,15 @@ static DWORD filter_device_by_name_a(wLinkedList* list, LPSTR* mszReaders, DWORD static DWORD filter_device_by_name_w(wLinkedList* list, LPWSTR* mszReaders, DWORD cchReaders) { - int res; DWORD rc; LPSTR readers = NULL; if (LinkedList_Count(list) < 1) return cchReaders; - res = ConvertFromUnicode(CP_UTF8, 0, *mszReaders, (int)cchReaders, &readers, 0, NULL, NULL); + readers = ConvertWCharNToUtf8Alloc(*mszReaders, cchReaders, NULL); - /* When res==0, readers may have been set to NULL by ConvertFromUnicode */ - if ((res < 0) || ((DWORD)res != cchReaders) || (readers == 0)) + if (!readers) { free(readers); return 0; @@ -308,9 +306,9 @@ static DWORD filter_device_by_name_w(wLinkedList* list, LPWSTR* mszReaders, DWOR free(*mszReaders); *mszReaders = NULL; rc = filter_device_by_name_a(list, &readers, cchReaders); - res = ConvertToUnicode(CP_UTF8, 0, readers, (int)rc, mszReaders, 0); - if ((res < 0) || ((DWORD)res != rc)) + *mszReaders = ConvertUtf8NToWCharAlloc(readers, rc, NULL); + if (!*mszReaders) rc = 0; free(readers); diff --git a/libfreerdp/utils/smartcard_pack.c b/libfreerdp/utils/smartcard_pack.c index 693c5c750..582fd7241 100644 --- a/libfreerdp/utils/smartcard_pack.c +++ b/libfreerdp/utils/smartcard_pack.c @@ -323,7 +323,7 @@ static LONG smartcard_ndr_read_u(wStream* s, UUID** data) static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL unicode) { - size_t index, length; + size_t index, length = 0; union { const void* pv; @@ -342,33 +342,24 @@ static char* smartcard_convert_string_list(const void* in, size_t bytes, BOOL un if (unicode) { - length = (bytes / sizeof(WCHAR)) - 1; - WINPR_ASSERT(length < INT_MAX); - - mszA = (char*)calloc(length + 1, sizeof(char)); + mszA = ConvertWCharNToUtf8Alloc(string.wz, bytes / sizeof(WCHAR), &length); if (!mszA) return NULL; - if (ConvertFromUnicode(CP_UTF8, 0, string.wz, (int)length, &mszA, (int)length + 1, NULL, - NULL) != (int)length) - { - free(mszA); - return NULL; - } } else { - length = bytes; - mszA = (char*)calloc(length, sizeof(char)); + mszA = (char*)calloc(bytes, sizeof(char)); if (!mszA) return NULL; - CopyMemory(mszA, string.sz, length - 1); - mszA[length - 1] = '\0'; + CopyMemory(mszA, string.sz, bytes - 1); + mszA[bytes - 1] = '\0'; + length = strnlen(mszA, bytes); } - for (index = 0; index < length - 1; index++) + for (index = 1; index < length; index++) { - if (mszA[index] == '\0') - mszA[index] = ','; + if (mszA[index - 1] == '\0') + mszA[index - 1] = ','; } return mszA; @@ -394,9 +385,14 @@ static char* smartcard_msz_dump_a(const char* msz, size_t len, char* buffer, siz static char* smartcard_msz_dump_w(const WCHAR* msz, size_t len, char* buffer, size_t bufferLen) { - char* sz = NULL; - ConvertFromUnicode(CP_UTF8, 0, msz, (int)len, &sz, 0, NULL, NULL); - smartcard_msz_dump_a(sz, len, buffer, bufferLen); + size_t szlen = 0; + if (!msz) + return NULL; + char* sz = ConvertWCharNToUtf8Alloc(msz, len, &szlen); + if (!sz) + return NULL; + + smartcard_msz_dump_a(sz, szlen, buffer, bufferLen); free(sz); return buffer; } @@ -471,16 +467,16 @@ static void smartcard_trace_context_and_string_call_w(const char* name, const REDIR_SCARDCONTEXT* phContext, const WCHAR* sz) { - char* tmp = NULL; + char tmp[1024] = { 0 }; if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; + if (sz) + ConvertWCharToUtf8(sz, tmp, ARRAYSIZE(tmp)); + WLog_LVL(TAG, g_LogLevel, "%s {", name); smartcard_log_context(TAG, phContext); - ConvertFromUnicode(CP_UTF8, 0, sz, -1, &tmp, 0, NULL, NULL); WLog_LVL(TAG, g_LogLevel, " sz=%s", tmp); - free(tmp); - WLog_LVL(TAG, g_LogLevel, "}"); } @@ -515,7 +511,6 @@ static void smartcard_trace_get_status_change_w_call(const GetStatusChangeW_Call UINT32 index; char* szEventState; char* szCurrentState; - LPSCARD_READERSTATEW readerState; if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; @@ -528,9 +523,11 @@ static void smartcard_trace_get_status_change_w_call(const GetStatusChangeW_Call for (index = 0; index < call->cReaders; index++) { - char* szReaderA = NULL; - readerState = &call->rgReaderStates[index]; - ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &szReaderA, 0, NULL, NULL); + const LPSCARD_READERSTATEW readerState = &call->rgReaderStates[index]; + char szReaderA[1024] = { 0 }; + + ConvertWCharToUtf8(readerState->szReader, szReaderA, ARRAYSIZE(szReaderA)); + WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, szReaderA, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); @@ -541,7 +538,6 @@ static void smartcard_trace_get_status_change_w_call(const GetStatusChangeW_Call szEventState, readerState->dwEventState); free(szCurrentState); free(szEventState); - free(szReaderA); } WLog_LVL(TAG, g_LogLevel, "}"); @@ -800,21 +796,20 @@ static void smartcard_trace_context_and_two_strings_a_call(const ContextAndTwoSt static void smartcard_trace_context_and_two_strings_w_call(const ContextAndTwoStringW_Call* call) { - CHAR* sz1 = NULL; - CHAR* sz2 = NULL; + char sz1[1024] = { 0 }; + char sz2[1024] = { 0 }; if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; + if (call->sz1) + ConvertWCharToUtf8(call->sz1, sz1, ARRAYSIZE(sz1)); + if (call->sz2) + ConvertWCharToUtf8(call->sz2, sz2, ARRAYSIZE(sz2)); WLog_LVL(TAG, g_LogLevel, "ContextAndTwoStringW_Call {"); smartcard_log_context(TAG, &call->handles.hContext); - ConvertFromUnicode(CP_UTF8, 0, call->sz1, -1, &sz1, 0, NULL, NULL); - ConvertFromUnicode(CP_UTF8, 0, call->sz2, -1, &sz2, 0, NULL, NULL); WLog_LVL(TAG, g_LogLevel, " sz1=%s", sz1); WLog_LVL(TAG, g_LogLevel, " sz2=%s", sz2); - free(sz1); - free(sz2); - WLog_LVL(TAG, g_LogLevel, "}"); } @@ -855,17 +850,18 @@ static void smartcard_trace_write_cache_a_call(const WriteCacheA_Call* call) static void smartcard_trace_write_cache_w_call(const WriteCacheW_Call* call) { - char* tmp = NULL; - char buffer[1024]; + char tmp[1024] = { 0 }; + char buffer[1024] = { 0 }; if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); - ConvertFromUnicode(CP_UTF8, 0, call->szLookupName, -1, &tmp, 0, NULL, NULL); + if (call->szLookupName) + ConvertWCharToUtf8(call->szLookupName, tmp, ARRAYSIZE(tmp)); WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", tmp); - free(tmp); + smartcard_log_context(TAG, &call->Common.handles.hContext); WLog_DBG( TAG, "..CardIdentifier=%s", @@ -901,17 +897,17 @@ static void smartcard_trace_read_cache_a_call(const ReadCacheA_Call* call) static void smartcard_trace_read_cache_w_call(const ReadCacheW_Call* call) { - char* tmp = NULL; - char buffer[1024]; + char tmp[1024] = { 0 }; + char buffer[1024] = { 0 }; if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; WLog_LVL(TAG, g_LogLevel, "GetTransmitCount_Call {"); - - ConvertFromUnicode(CP_UTF8, 0, call->szLookupName, -1, &tmp, 0, NULL, NULL); + if (call->szLookupName) + ConvertWCharToUtf8(call->szLookupName, tmp, ARRAYSIZE(tmp)); WLog_LVL(TAG, g_LogLevel, " szLookupName=%s", tmp); - free(tmp); + smartcard_log_context(TAG, &call->Common.handles.hContext); WLog_DBG( TAG, "..CardIdentifier=%s", @@ -1006,12 +1002,13 @@ static void smartcard_trace_locate_cards_by_atr_w_call(const LocateCardsByATRW_C for (index = 0; index < call->cReaders; index++) { - char buffer[1024]; - char* tmp = NULL; + char buffer[1024] = { 0 }; + char tmp[1024] = { 0 }; const LPSCARD_READERSTATEW readerState = (const LPSCARD_READERSTATEW)&call->rgReaderStates[index]; - ConvertFromUnicode(CP_UTF8, 0, readerState->szReader, -1, &tmp, 0, NULL, NULL); + if (readerState->szReader) + ConvertWCharToUtf8(readerState->szReader, tmp, ARRAYSIZE(tmp)); WLog_LVL(TAG, g_LogLevel, "\t[%" PRIu32 "]: szReader: %s cbAtr: %" PRIu32 "", index, tmp, readerState->cbAtr); szCurrentState = SCardGetReaderStateString(readerState->dwCurrentState); @@ -1027,7 +1024,6 @@ static void smartcard_trace_locate_cards_by_atr_w_call(const LocateCardsByATRW_C free(szCurrentState); free(szEventState); - free(tmp); } WLog_LVL(TAG, g_LogLevel, "}"); @@ -1302,12 +1298,13 @@ static void smartcard_trace_connect_a_call(const ConnectA_Call* call) static void smartcard_trace_connect_w_call(const ConnectW_Call* call) { - char* szReaderA = NULL; + char szReaderA[1024] = { 0 }; if (!WLog_IsLevelActive(WLog_Get(TAG), g_LogLevel)) return; - ConvertFromUnicode(CP_UTF8, 0, call->szReader, -1, &szReaderA, 0, NULL, NULL); + if (call->szReader) + ConvertWCharToUtf8(call->szReader, szReaderA, ARRAYSIZE(szReaderA)); WLog_LVL(TAG, g_LogLevel, "ConnectW_Call {"); smartcard_log_context(TAG, &call->Common.handles.hContext); @@ -1318,7 +1315,6 @@ static void smartcard_trace_connect_w_call(const ConnectW_Call* call) SCardGetProtocolString(call->Common.dwPreferredProtocols), call->Common.dwPreferredProtocols); WLog_LVL(TAG, g_LogLevel, "}"); - free(szReaderA); } static void smartcard_trace_hcard_and_disposition_call(const HCardAndDisposition_Call* call, diff --git a/server/shadow/Win/win_wds.c b/server/shadow/Win/win_wds.c index 40608faf4..197e61fb7 100644 --- a/server/shadow/Win/win_wds.c +++ b/server/shadow/Win/win_wds.c @@ -732,7 +732,7 @@ int win_shadow_wds_init(winShadowSubsystem* subsystem) } { - int status1 = -1, status2 = -1; + int status2 = -1; char* ConnectionString2; BSTR bstrConnectionString; hr = subsystem->pInvitation->lpVtbl->get_ConnectionString(subsystem->pInvitation, @@ -744,14 +744,12 @@ int win_shadow_wds_init(winShadowSubsystem* subsystem) return -1; } - status1 = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)bstrConnectionString, - ((UINT32*)bstrConnectionString)[-1], &(ConnectionString2), 0, - NULL, NULL); + ConnectionString2 = ConvertWCharToUtf8Alloc(bstrConnectionString, NULL); SysFreeString(bstrConnectionString); status2 = freerdp_assistance_set_connection_string2(file, ConnectionString2, "Shadow123!"); free(ConnectionString2); - if ((status1 < 1) || (status2 < 1)) + if ((!ConnectionString2) || (status2 < 1)) { WLog_ERR(TAG, "failed to convert connection string"); return -1; diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 79861509e..c7451fc15 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -626,31 +626,13 @@ static BOOL shadow_client_logon(freerdp_peer* peer, const SEC_WINNT_AUTH_IDENTIT if (identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) { if (identity->User) - { - int r; - WINPR_ASSERT(identity->UserLength <= INT_MAX); - r = ConvertFromUnicode(CP_UTF8, 0, identity->User, (int)identity->UserLength, &user, 0, - NULL, NULL); - WINPR_ASSERT(r > 0); - } + user = ConvertWCharNToUtf8Alloc(identity->User, identity->UserLength, NULL); if (identity->Domain) - { - int r; - WINPR_ASSERT(identity->DomainLength <= INT_MAX); - r = ConvertFromUnicode(CP_UTF8, 0, identity->Domain, (int)identity->DomainLength, - &domain, 0, NULL, NULL); - WINPR_ASSERT(r > 0); - } + domain = ConvertWCharNToUtf8Alloc(identity->Domain, identity->DomainLength, NULL); if (identity->Password) - { - int r; - WINPR_ASSERT(identity->PasswordLength <= INT_MAX); - r = ConvertFromUnicode(CP_UTF8, 0, identity->Password, (int)identity->PasswordLength, - &password, 0, NULL, NULL); - WINPR_ASSERT(r > 0); - } + password = ConvertWCharNToUtf8Alloc(identity->Password, identity->PasswordLength, NULL); } else { diff --git a/winpr/libwinpr/clipboard/synthetic.c b/winpr/libwinpr/clipboard/synthetic.c index eb4623b0a..eab143133 100644 --- a/winpr/libwinpr/clipboard/synthetic.c +++ b/winpr/libwinpr/clipboard/synthetic.c @@ -39,24 +39,17 @@ static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) { - int size; + size_t size; char* pDstData = NULL; if (formatId == CF_UNICODETEXT) { - size_t wsize; - char* str = NULL; - - if (*pSize > INT32_MAX) - return NULL; - - wsize = _wcsnlen(data, (*pSize) / 2); - size = ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR)data, wsize, (CHAR**)&str, 0, NULL, NULL); + char* str = ConvertWCharNToUtf8Alloc(data, *pSize / sizeof(WCHAR), &size); if (!str) return NULL; - pDstData = ConvertLineEndingToCRLF((const char*)str, &size); + pDstData = ConvertLineEndingToCRLF(str, &size); free(str); *pSize = size; return pDstData; @@ -67,8 +60,8 @@ static void* clipboard_synthesize_cf_text(wClipboard* clipboard, UINT32 formatId (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || (formatId == ClipboardGetFormatId(clipboard, "STRING"))) { - size = (INT64)*pSize; - pDstData = ConvertLineEndingToCRLF((const char*)data, &size); + size = *pSize; + pDstData = ConvertLineEndingToCRLF(data, &size); if (!pDstData) return NULL; @@ -120,8 +113,7 @@ static void* clipboard_synthesize_cf_locale(wClipboard* clipboard, UINT32 format static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) { - int size; - int status; + size_t size; char* crlfStr = NULL; WCHAR* pDstData = NULL; @@ -131,22 +123,26 @@ static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 f (formatId == ClipboardGetFormatId(clipboard, "TEXT")) || (formatId == ClipboardGetFormatId(clipboard, "STRING"))) { + size_t len = 0; if (!pSize || (*pSize > INT32_MAX)) return NULL; - size = (int)*pSize; + size = *pSize; crlfStr = ConvertLineEndingToCRLF((const char*)data, &size); if (!crlfStr) return NULL; - status = ConvertToUnicode(CP_UTF8, 0, crlfStr, size, &pDstData, 0); + pDstData = ConvertUtf8NToWCharAlloc(crlfStr, size, &len); free(crlfStr); - if (status <= 0) + if ((len < 1) || (len > UINT32_MAX / sizeof(WCHAR))) + { + free(pDstData); return NULL; + } - *pSize = status * 2; + *pSize = len * sizeof(WCHAR); } return (void*)pDstData; @@ -161,14 +157,12 @@ static void* clipboard_synthesize_cf_unicodetext(wClipboard* clipboard, UINT32 f static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) { - INT64 size; + size_t size; char* pDstData = NULL; if (formatId == CF_UNICODETEXT) { - size_t wsize = _wcsnlen(data, (*pSize) / 2); - size = - ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR)data, wsize, (CHAR**)&pDstData, 0, NULL, NULL); + pDstData = ConvertWCharNToUtf8Alloc(data, *pSize / sizeof(WCHAR), &size); if (!pDstData) return NULL; @@ -188,14 +182,14 @@ static void* clipboard_synthesize_utf8_string(wClipboard* clipboard, UINT32 form (formatId == ClipboardGetFormatId(clipboard, "STRING"))) { int rc; - size = (INT64)*pSize; + size = *pSize; pDstData = (char*)malloc(size); if (!pDstData) return NULL; CopyMemory(pDstData, data, size); - rc = ConvertLineEndingToLF((char*)pDstData, (int)size); + rc = ConvertLineEndingToLF(pDstData, size); if (rc < 0) { free(pDstData); @@ -371,10 +365,11 @@ static void* clipboard_synthesize_html_format(wClipboard* clipboard, UINT32 form /* Check if we have WCHAR, convert to UTF-8 */ if ((pSrcData.cpb[0] == 0xFF) && (pSrcData.cpb[1] == 0xFE)) { - char* utfString = NULL; - ConvertFromUnicode(CP_UTF8, 0, &pSrcData.pv[1], (int)(SrcSize - 2) / 2, &utfString, - 0, NULL, NULL); + char* utfString = + ConvertWCharNToUtf8Alloc(&pSrcData.pv[1], SrcSize / sizeof(WCHAR), NULL); free(pSrcData.pv); + if (!utfString) + goto fail; pSrcData.cpc = utfString; } } diff --git a/winpr/libwinpr/clipboard/synthetic_file.c b/winpr/libwinpr/clipboard/synthetic_file.c index ea57d83eb..758f5bb05 100644 --- a/winpr/libwinpr/clipboard/synthetic_file.c +++ b/winpr/libwinpr/clipboard/synthetic_file.c @@ -487,10 +487,10 @@ static BOOL process_uri(wClipboard* clipboard, const char* uri, size_t uri_len) * '\0' and '/' bytes. But we need to make some decision here. * Assuming UTF-8 is currently the most sane thing. */ - if (ConvertToUnicode(CP_UTF8, 0, name, -1, &wname, 0)) - { + wname = ConvertUtf8ToWCharAlloc(name, NULL); + if (wname) result = process_file_name(clipboard, wname, clipboard->localFiles); - } + free(name); free(wname); } @@ -830,13 +830,14 @@ static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32 /* Get total size of file/folder names under first level folder only */ for (x = 0; x < count; x++) { - if (_wcschr(descriptors[x].cFileName, backslash) == NULL) + const FILEDESCRIPTORW* dsc = &descriptors[x]; + + if (_wcschr(dsc->cFileName, backslash) == NULL) { - size_t curLen = _wcsnlen(descriptors[x].cFileName, ARRAYSIZE(descriptors[x].cFileName)); - alloc += WideCharToMultiByte(CP_UTF8, 0, descriptors[x].cFileName, (int)curLen, NULL, 0, - NULL, NULL); - /* # (1 char) -> %23 (3 chars) , the first char is replaced inplace */ - alloc += count_special_chars(descriptors[x].cFileName) * 2; + alloc += ARRAYSIZE(dsc->cFileName) * + 8; /* Overallocate, just take the biggest value the result path can have */ + /* # (1 char) -> %23 (3 chars) , the first char is replaced inplace */ + alloc += count_special_chars(dsc->cFileName) * 2; alloc += decoration_len; } } @@ -855,19 +856,19 @@ static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32 for (x = 0; x < count; x++) { + const FILEDESCRIPTORW* dsc = &descriptors[x]; BOOL fail = TRUE; - if (_wcschr(descriptors[x].cFileName, backslash) != NULL) + if (_wcschr(dsc->cFileName, backslash) != NULL) { continue; } - int rc; - const FILEDESCRIPTORW* cur = &descriptors[x]; - size_t curLen = _wcsnlen(cur->cFileName, ARRAYSIZE(cur->cFileName)); - char* curName = NULL; + int rc = -1; + char curName[520] = { 0 }; const char* stop_at = NULL; const char* previous_at = NULL; - rc = ConvertFromUnicode(CP_UTF8, 0, cur->cFileName, (int)curLen, &curName, 0, NULL, NULL); - if (rc < 0) + + if (ConvertWCharNToUtf8(dsc->cFileName, ARRAYSIZE(dsc->cFileName), curName, + ARRAYSIZE(curName)) < 0) goto loop_fail; rc = _snprintf(&dst[pos], alloc - pos, "%s%s/", lineprefix, clipboard->delegate.basePath); @@ -905,10 +906,8 @@ static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32 if ((rc < 0) || fail) { free(dst); - free(curName); return NULL; } - free(curName); pos += (size_t)rc; } diff --git a/winpr/libwinpr/clipboard/test/TestClipboardFormats.c b/winpr/libwinpr/clipboard/test/TestClipboardFormats.c index 3cfa3714a..cede9c104 100644 --- a/winpr/libwinpr/clipboard/test/TestClipboardFormats.c +++ b/winpr/libwinpr/clipboard/test/TestClipboardFormats.c @@ -66,8 +66,8 @@ int TestClipboardFormats(int argc, char* argv[]) WCHAR* pDstData; DstSize = 0; pDstData = (WCHAR*)ClipboardGetData(clipboard, CF_UNICODETEXT, &DstSize); - pSrcData = NULL; - ConvertFromUnicode(CP_UTF8, 0, pDstData, -1, &pSrcData, 0, NULL, NULL); + pSrcData = ConvertWCharNToUtf8Alloc(pDstData, DstSize / sizeof(WCHAR), NULL); + fprintf(stderr, "ClipboardGetData (synthetic): %s\n", pSrcData); free(pDstData); free(pSrcData); diff --git a/winpr/libwinpr/crypto/hmac_md5.c b/winpr/libwinpr/crypto/hmac_md5.c index 100c212f1..5550bbd06 100644 --- a/winpr/libwinpr/crypto/hmac_md5.c +++ b/winpr/libwinpr/crypto/hmac_md5.c @@ -3,6 +3,7 @@ #include "hmac_md5.h" #include "md5.h" +#include void hmac_md5_init(WINPR_HMAC_MD5_CTX* ctx, const unsigned char* key, size_t key_len) { diff --git a/winpr/libwinpr/dsparse/dsparse.c b/winpr/libwinpr/dsparse/dsparse.c index 95eeb22bf..9099bcb73 100644 --- a/winpr/libwinpr/dsparse/dsparse.c +++ b/winpr/libwinpr/dsparse/dsparse.c @@ -53,7 +53,7 @@ DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName char* InstanceNameA = NULL; char* ReferrerA = NULL; char* pszSpnA = NULL; - DWORD length; + size_t length; WINPR_ASSERT(ServiceClass); WINPR_ASSERT(ServiceName); @@ -65,26 +65,26 @@ DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName if (ServiceClass) { - int rc = ConvertFromUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassA, 0, NULL, NULL); - if (rc <= 0) + ServiceClassA = ConvertWCharToUtf8Alloc(ServiceClass, NULL); + if (!ServiceClassA) goto fail; } if (ServiceName) { - int rc = ConvertFromUnicode(CP_UTF8, 0, ServiceName, -1, &ServiceNameA, 0, NULL, NULL); - if (rc <= 0) + ServiceNameA = ConvertWCharToUtf8Alloc(ServiceName, NULL); + if (!ServiceNameA) goto fail; } if (InstanceName) { - int rc = ConvertFromUnicode(CP_UTF8, 0, InstanceName, -1, &InstanceNameA, 0, NULL, NULL); - if (rc <= 0) + InstanceNameA = ConvertWCharToUtf8Alloc(InstanceName, NULL); + if (!InstanceNameA) goto fail; } if (Referrer) { - int rc = ConvertFromUnicode(CP_UTF8, 0, Referrer, -1, &ReferrerA, 0, NULL, NULL); - if (rc <= 0) + ReferrerA = ConvertWCharToUtf8Alloc(Referrer, NULL); + if (!ReferrerA) goto fail; } res = DsMakeSpnA(ServiceClassA, ServiceNameA, InstanceNameA, InstancePort, ReferrerA, @@ -92,8 +92,7 @@ DWORD DsMakeSpnW(LPCWSTR ServiceClass, LPCWSTR ServiceName, LPCWSTR InstanceName if (res == ERROR_SUCCESS) { - int rc = ConvertToUnicode(CP_UTF8, 0, pszSpnA, *pcSpnLength, &pszSpn, length); - if (rc <= 0) + if (ConvertUtf8NToWChar(pszSpnA, *pcSpnLength, pszSpn, length) < 0) res = ERROR_OUTOFMEMORY; } diff --git a/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c b/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c index 26e6f0019..55b7ca83b 100644 --- a/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c +++ b/winpr/libwinpr/dsparse/test/TestDsMakeSpn.c @@ -105,20 +105,22 @@ static BOOL test_DsMakeSpnW(void) if (_wcscmp(Spn, testSpn) != 0) { - char buffer1[8192]; - char buffer2[8192]; + char buffer1[8192] = { 0 }; + char buffer2[8192] = { 0 }; char* SpnA = buffer1; char* testSpnA = buffer2; - ConvertFromUnicode(CP_UTF8, 0, Spn, -1, &SpnA, sizeof(SpnA), NULL, NULL); - ConvertFromUnicode(CP_UTF8, 0, testSpn, -1, &testSpnA, sizeof(testSpnA), NULL, NULL); + + ConvertWCharToUtf8(Spn, SpnA, ARRAYSIZE(buffer1)); + ConvertWCharToUtf8(testSpn, testSpnA, ARRAYSIZE(buffer2)); printf("DsMakeSpnW: SPN mismatch: Actual: %s, Expected: %s\n", SpnA, testSpnA); goto fail; } { - char buffer[8192]; + char buffer[8192] = { 0 }; char* SpnA = buffer; - ConvertFromUnicode(CP_UTF8, 0, Spn, -1, &SpnA, sizeof(SpnA), NULL, NULL); + + ConvertWCharToUtf8(Spn, SpnA, ARRAYSIZE(buffer)); printf("DsMakeSpnW: %s\n", SpnA); } diff --git a/winpr/libwinpr/environment/environment.c b/winpr/libwinpr/environment/environment.c index 81c2f174d..3186dc639 100644 --- a/winpr/libwinpr/environment/environment.c +++ b/winpr/libwinpr/environment/environment.c @@ -649,14 +649,14 @@ char** EnvironmentBlockToEnvpA(LPCH lpszEnvironmentBlock) DWORD GetEnvironmentVariableX(const char* lpName, char* lpBuffer, DWORD nSize) { - int status; DWORD result = 0; DWORD nSizeW = 0; LPWSTR lpNameW = NULL; LPWSTR lpBufferW = NULL; LPSTR lpBufferA = lpBuffer; - if (ConvertToUnicode(CP_UTF8, 0, lpName, -1, &lpNameW, 0) < 1) + lpNameW = ConvertUtf8ToWCharAlloc(lpName, NULL); + if (!lpNameW) goto cleanup; if (!lpBuffer) @@ -669,16 +669,17 @@ DWORD GetEnvironmentVariableX(const char* lpName, char* lpBuffer, DWORD nSize) result = GetEnvironmentVariableW(lpNameW, lpBufferMaxW, nSizeW); - status = ConvertFromUnicode(CP_UTF8, 0, lpBufferMaxW, _wcsnlen(lpBufferMaxW, nSizeW) + 1, - &lpTmpBuffer, sizeof(lpBufferMaxA), NULL, NULL); + SSIZE_T rc = + ConvertWCharNToUtf8(lpBufferMaxW, nSizeW, lpTmpBuffer, ARRAYSIZE(lpBufferMaxA)); + if ((rc < 0) || (rc >= UINT32_MAX)) + goto cleanup; - if (status > 0) - result = (DWORD)status; + result = (DWORD)rc + 1; } else { - nSizeW = nSize + 1; - lpBufferW = calloc(nSizeW, 2); + nSizeW = nSize; + lpBufferW = calloc(nSizeW + 1, sizeof(WCHAR)); if (!lpBufferW) goto cleanup; @@ -688,10 +689,11 @@ DWORD GetEnvironmentVariableX(const char* lpName, char* lpBuffer, DWORD nSize) if (result == 0) goto cleanup; - status = ConvertFromUnicode(CP_UTF8, 0, lpBufferW, -1, &lpBufferA, nSize, NULL, NULL); + SSIZE_T rc = ConvertWCharNToUtf8(lpBufferW, nSizeW, lpBufferA, nSize); + if ((rc < 0) || (rc > UINT32_MAX)) + goto cleanup; - if (status > 0) - result = (DWORD)(status - 1); + result = (DWORD)rc; } cleanup: diff --git a/winpr/libwinpr/file/file.c b/winpr/libwinpr/file/file.c index 9ae8eb2c6..b48a312ed 100644 --- a/winpr/libwinpr/file/file.c +++ b/winpr/libwinpr/file/file.c @@ -1020,8 +1020,11 @@ BOOL GetDiskFreeSpaceW(LPCWSTR lpwRootPathName, LPDWORD lpSectorsPerCluster, { LPSTR lpRootPathName; BOOL ret; + if (!lpwRootPathName) + return FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, lpwRootPathName, -1, &lpRootPathName, 0, NULL, NULL) <= 0) + lpRootPathName = ConvertWCharToUtf8Alloc(lpwRootPathName, NULL); + if (!lpRootPathName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -1213,9 +1216,10 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { HANDLE hFile; - WCHAR* lpFileNameW = NULL; + if (!lpFileName) + return NULL; - ConvertToUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameW, 0); + WCHAR* lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, NULL); if (!lpFileNameW) return NULL; @@ -1284,13 +1288,12 @@ DWORD GetFullPathNameA(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lpBuffer, L WCHAR* lpFileNameW = NULL; WCHAR* lpBufferW = NULL; WCHAR* lpFilePartW = NULL; - DWORD nBufferLengthW = nBufferLength * 2; + DWORD nBufferLengthW = nBufferLength * sizeof(WCHAR); if (!lpFileName || (nBufferLength < 1)) return 0; - ConvertToUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameW, 0); - + lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, NULL); if (!lpFileNameW) return 0; @@ -1301,7 +1304,7 @@ DWORD GetFullPathNameA(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lpBuffer, L dwStatus = GetFullPathNameW(lpFileNameW, nBufferLengthW, lpBufferW, &lpFilePartW); - ConvertFromUnicode(CP_UTF8, 0, lpBufferW, nBufferLengthW, &lpBuffer, nBufferLength, NULL, NULL); + ConvertWCharNToUtf8(lpBufferW, nBufferLengthW / sizeof(WCHAR), lpBuffer, nBufferLength); if (lpFilePart) lpFilePart = lpBuffer + (lpFilePartW - lpBufferW); @@ -1434,10 +1437,12 @@ FILE* winpr_fopen(const char* path, const char* mode) if (!path || !mode) return NULL; - if (ConvertToUnicode(CP_UTF8, 0, path, -1, &lpPathW, 0) < 1) + lpPathW = ConvertUtf8ToWCharAlloc(path, NULL); + if (!lpPathW) goto cleanup; - if (ConvertToUnicode(CP_UTF8, 0, mode, -1, &lpModeW, 0) < 1) + lpModeW = ConvertUtf8ToWCharAlloc(mode, NULL); + if (!lpModeW) goto cleanup; result = _wfopen(lpPathW, lpModeW); diff --git a/winpr/libwinpr/file/generic.c b/winpr/libwinpr/file/generic.c index 9bcc8f9dc..400803bcd 100644 --- a/winpr/libwinpr/file/generic.c +++ b/winpr/libwinpr/file/generic.c @@ -274,14 +274,20 @@ HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { - LPSTR lpFileNameA = NULL; - HANDLE hdl; - - if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameA, 0, NULL, NULL) < 1) + HANDLE hdl = NULL; + if (!lpFileName) return NULL; + char* lpFileNameA = ConvertWCharToUtf8Alloc(lpFileName, NULL); + + if (!lpFileNameA) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto fail; + } hdl = CreateFileA(lpFileNameA, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); +fail: free(lpFileNameA); return hdl; } @@ -295,13 +301,16 @@ BOOL DeleteFileA(LPCSTR lpFileName) BOOL DeleteFileW(LPCWSTR lpFileName) { - LPSTR lpFileNameA = NULL; + if (!lpFileName) + return FALSE; + LPSTR lpFileNameA = ConvertWCharToUtf8Alloc(lpFileName, NULL); BOOL rc = FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameA, 0, NULL, NULL) < 1) - return FALSE; + if (!lpFileNameA) + goto fail; rc = DeleteFileA(lpFileNameA); +fail: free(lpFileNameA); return rc; } @@ -493,9 +502,11 @@ BOOL WINAPI GetFileAttributesExW(LPCWSTR lpFileName, GET_FILEEX_INFO_LEVELS fInf LPVOID lpFileInformation) { BOOL ret; - LPSTR lpCFileName; + if (!lpFileName) + return FALSE; + LPSTR lpCFileName = ConvertWCharToUtf8Alloc(lpFileName, NULL); - if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL) <= 0) + if (!lpCFileName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -521,9 +532,10 @@ DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName) DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName) { DWORD ret; - LPSTR lpCFileName; - - if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL) <= 0) + if (!lpFileName) + return FALSE; + LPSTR lpCFileName = ConvertWCharToUtf8Alloc(lpFileName, NULL); + if (!lpCFileName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -643,6 +655,9 @@ BOOL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes) BOOL ret; LPSTR lpCFileName; + if (!lpFileName) + return FALSE; + if (dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) { char buffer[8192] = { 0 }; @@ -651,7 +666,8 @@ BOOL SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes) WLog_WARN(TAG, "[%s] Unsupported flags %s, ignoring!", __FUNCTION__, flags); } - if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpCFileName, 0, NULL, NULL) <= 0) + lpCFileName = ConvertWCharToUtf8Alloc(lpFileName, NULL); + if (!lpCFileName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -1032,9 +1048,6 @@ HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData) static BOOL ConvertFindDataAToW(LPWIN32_FIND_DATAA lpFindFileDataA, LPWIN32_FIND_DATAW lpFindFileDataW) { - size_t length; - WCHAR* unicodeFileName; - if (!lpFindFileDataA || !lpFindFileDataW) return FALSE; @@ -1046,35 +1059,23 @@ static BOOL ConvertFindDataAToW(LPWIN32_FIND_DATAA lpFindFileDataA, lpFindFileDataW->nFileSizeLow = lpFindFileDataA->nFileSizeLow; lpFindFileDataW->dwReserved0 = lpFindFileDataA->dwReserved0; lpFindFileDataW->dwReserved1 = lpFindFileDataA->dwReserved1; - unicodeFileName = NULL; - length = ConvertToUnicode(CP_UTF8, 0, lpFindFileDataA->cFileName, -1, &unicodeFileName, 0); - if (length == 0) + if (ConvertUtf8NToWChar(lpFindFileDataA->cFileName, ARRAYSIZE(lpFindFileDataA->cFileName), + lpFindFileDataW->cFileName, ARRAYSIZE(lpFindFileDataW->cFileName)) < 0) return FALSE; - if (length > MAX_PATH) - length = MAX_PATH; - - CopyMemory(lpFindFileDataW->cFileName, unicodeFileName, length * sizeof(WCHAR)); - free(unicodeFileName); - length = - ConvertToUnicode(CP_UTF8, 0, lpFindFileDataA->cAlternateFileName, -1, &unicodeFileName, 0); - - if (length == 0) - return TRUE; - - if (length > 14) - length = 14; - - CopyMemory(lpFindFileDataW->cAlternateFileName, unicodeFileName, length * sizeof(WCHAR)); - free(unicodeFileName); - return TRUE; + return ConvertUtf8NToWChar(lpFindFileDataA->cAlternateFileName, + ARRAYSIZE(lpFindFileDataA->cAlternateFileName), + lpFindFileDataW->cAlternateFileName, + ARRAYSIZE(lpFindFileDataW->cAlternateFileName)) >= 0; } HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData) { LPSTR utfFileName = NULL; HANDLE h; + if (!lpFileName) + return FALSE; LPWIN32_FIND_DATAA fd = (LPWIN32_FIND_DATAA)calloc(1, sizeof(WIN32_FIND_DATAA)); if (!fd) @@ -1083,7 +1084,8 @@ HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData) return INVALID_HANDLE_VALUE; } - if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &utfFileName, 0, NULL, NULL) <= 0) + utfFileName = ConvertWCharToUtf8Alloc(lpFileName, NULL); + if (!utfFileName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); free(fd); @@ -1246,16 +1248,19 @@ BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttribu BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { - char* utfPathName = NULL; - BOOL ret; + if (!lpPathName) + return FALSE; + char* utfPathName = ConvertWCharToUtf8Alloc(lpPathName, NULL); + BOOL ret = FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, lpPathName, -1, &utfPathName, 0, NULL, NULL) <= 0) + if (!utfPathName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + goto fail; } ret = CreateDirectoryA(utfPathName, lpSecurityAttributes); +fail: free(utfPathName); return ret; } @@ -1274,16 +1279,19 @@ BOOL RemoveDirectoryA(LPCSTR lpPathName) BOOL RemoveDirectoryW(LPCWSTR lpPathName) { - char* utfPathName = NULL; - BOOL ret; + if (!lpPathName) + return FALSE; + char* utfPathName = ConvertWCharToUtf8Alloc(lpPathName, NULL); + BOOL ret = FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, lpPathName, -1, &utfPathName, 0, NULL, NULL) <= 0) + if (!utfPathName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + goto fail; } ret = RemoveDirectoryA(utfPathName); +fail: free(utfPathName); return ret; } @@ -1321,25 +1329,21 @@ BOOL MoveFileExA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwFlags) BOOL MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags) { - LPSTR lpCExistingFileName; - LPSTR lpCNewFileName; - BOOL ret; + if (!lpExistingFileName || !lpNewFileName) + return FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpCExistingFileName, 0, NULL, - NULL) <= 0) + LPSTR lpCExistingFileName = ConvertWCharToUtf8Alloc(lpExistingFileName, NULL); + LPSTR lpCNewFileName = ConvertWCharToUtf8Alloc(lpNewFileName, NULL); + BOOL ret = FALSE; + + if (!lpCExistingFileName || !lpCNewFileName) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - if (ConvertFromUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpCNewFileName, 0, NULL, NULL) <= 0) - { - free(lpCExistingFileName); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; + goto fail; } ret = MoveFileExA(lpCExistingFileName, lpCNewFileName, dwFlags); +fail: free(lpCNewFileName); free(lpCExistingFileName); return ret; @@ -1361,6 +1365,8 @@ BOOL MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName) int UnixChangeFileMode(const char* filename, int flags) { + if (!filename) + return -1; #ifndef _WIN32 mode_t fl = 0; fl |= (flags & 0x4000) ? S_ISUID : 0; @@ -1378,9 +1384,9 @@ int UnixChangeFileMode(const char* filename, int flags) return chmod(filename, fl); #else int rc; - WCHAR* wfl = NULL; + WCHAR* wfl = ConvertUtf8ToWCharAlloc(filename, NULL); - if (ConvertToUnicode(CP_UTF8, 0, filename, -1, &wfl, 0) <= 0) + if (!wfl) return -1; /* Check for unsupported flags. */ diff --git a/winpr/libwinpr/file/test/TestFileDeleteFile.c b/winpr/libwinpr/file/test/TestFileDeleteFile.c index 8e352ae99..10146bff5 100644 --- a/winpr/libwinpr/file/test/TestFileDeleteFile.c +++ b/winpr/libwinpr/file/test/TestFileDeleteFile.c @@ -7,7 +7,7 @@ int TestFileDeleteFile(int argc, char* argv[]) { - BOOL rc; + BOOL rc = FALSE; int fd; char validA[] = "/tmp/valid-test-file-XXXXXX"; char validW[] = "/tmp/valid-test-file-XXXXXX"; @@ -41,8 +41,9 @@ int TestFileDeleteFile(int argc, char* argv[]) if (fd < 0) return -1; - ConvertToUnicode(CP_UTF8, 0, validW, -1, &validWW, 0); - rc = DeleteFileW(validWW); + validWW = ConvertUtf8NToWCharAlloc(validW, ARRAYSIZE(validW), NULL); + if (validWW) + rc = DeleteFileW(validWW); free(validWW); if (!rc) return -1; diff --git a/winpr/libwinpr/file/test/TestFileFindFirstFile.c b/winpr/libwinpr/file/test/TestFileFindFirstFile.c index d8015b55d..afd60721f 100644 --- a/winpr/libwinpr/file/test/TestFileFindFirstFile.c +++ b/winpr/libwinpr/file/test/TestFileFindFirstFile.c @@ -11,26 +11,22 @@ static TCHAR testFile1[] = _T("TestFile1"); int TestFileFindFirstFile(int argc, char* argv[]) { char* str; - int length; + size_t length = 0; HANDLE hFind; LPTSTR BasePath; WIN32_FIND_DATA FindData; - TCHAR FilePath[PATHCCH_MAX_CCH]; + TCHAR FilePath[PATHCCH_MAX_CCH] = { 0 }; WINPR_UNUSED(argc); str = argv[1]; #ifdef UNICODE - length = MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), NULL, 0); - BasePath = (WCHAR*)calloc((length + 1), sizeof(WCHAR)); + BasePath = ConvertUtf8ToWChar(str, &length); if (!BasePath) { _tprintf(_T("Unable to allocate memory\n")); return -1; } - - MultiByteToWideChar(CP_UTF8, 0, str, length, (LPWSTR)BasePath, length * sizeof(WCHAR)); - BasePath[length] = 0; #else BasePath = _strdup(str); diff --git a/winpr/libwinpr/file/test/TestFileFindNextFile.c b/winpr/libwinpr/file/test/TestFileFindNextFile.c index 8df377a81..d4ea912e5 100644 --- a/winpr/libwinpr/file/test/TestFileFindNextFile.c +++ b/winpr/libwinpr/file/test/TestFileFindNextFile.c @@ -12,26 +12,22 @@ static TCHAR testDirectory2File2[] = _T("TestDirectory2File2"); int TestFileFindNextFile(int argc, char* argv[]) { char* str; - int length; + size_t length = 0; BOOL status; HANDLE hFind; LPTSTR BasePath; WIN32_FIND_DATA FindData; - TCHAR FilePath[PATHCCH_MAX_CCH]; + TCHAR FilePath[PATHCCH_MAX_CCH] = { 0 }; WINPR_UNUSED(argc); str = argv[1]; #ifdef UNICODE - length = MultiByteToWideChar(CP_UTF8, 0, str, strlen(str), NULL, 0); - BasePath = (WCHAR*)calloc((length + 1), sizeof(WCHAR)); + BasePath = ConvertUtf8ToWChar(str, &length); if (!BasePath) { _tprintf(_T("Unable to allocate memory")); return -1; } - - MultiByteToWideChar(CP_UTF8, 0, str, length, (LPWSTR)BasePath, length * sizeof(WCHAR)); - BasePath[length] = 0; #else BasePath = _strdup(str); diff --git a/winpr/libwinpr/file/test/TestSetFileAttributes.c b/winpr/libwinpr/file/test/TestSetFileAttributes.c index e81c89c82..45dfa5990 100644 --- a/winpr/libwinpr/file/test/TestSetFileAttributes.c +++ b/winpr/libwinpr/file/test/TestSetFileAttributes.c @@ -45,12 +45,12 @@ static BOOL test_SetFileAttributesA(void) for (x = 0; x < ARRAYSIZE(allflags); x++) { const DWORD flag = allflags[x]; - rc = SetFileAttributesA(NULL, flag); - if (rc) + const BOOL brc = SetFileAttributesA(NULL, flag); + if (brc) goto fail; - rc = SetFileAttributesA(name, flag); - if (rc) + const BOOL crc = SetFileAttributesA(name, flag); + if (crc) goto fail; } @@ -64,8 +64,8 @@ static BOOL test_SetFileAttributesA(void) { DWORD attr; const DWORD flag = flags[x]; - rc = SetFileAttributesA(name, flag); - if (!rc) + const BOOL brc = SetFileAttributesA(name, flag); + if (!brc) goto fail; attr = GetFileAttributesA(name); @@ -76,6 +76,8 @@ static BOOL test_SetFileAttributesA(void) } } + rc = TRUE; + fail: DeleteFileA(name); free(name); @@ -93,17 +95,19 @@ static BOOL test_SetFileAttributesW(void) if (!base) goto fail; - ConvertToUnicode(CP_UTF8, 0, base, -1, &name, 0); + name = ConvertUtf8ToWCharAlloc(base, NULL); + if (!name) + goto fail; for (x = 0; x < ARRAYSIZE(allflags); x++) { const DWORD flag = allflags[x]; - rc = SetFileAttributesW(NULL, flag); - if (rc) + const BOOL brc = SetFileAttributesW(NULL, flag); + if (brc) goto fail; - rc = SetFileAttributesW(name, flag); - if (rc) + const BOOL crc = SetFileAttributesW(name, flag); + if (crc) goto fail; } @@ -117,8 +121,8 @@ static BOOL test_SetFileAttributesW(void) { DWORD attr; const DWORD flag = flags[x]; - rc = SetFileAttributesW(name, flag); - if (!rc) + const BOOL brc = SetFileAttributesW(name, flag); + if (!brc) goto fail; attr = GetFileAttributesW(name); @@ -129,6 +133,7 @@ static BOOL test_SetFileAttributesW(void) } } + rc = TRUE; fail: DeleteFileW(name); free(name); diff --git a/winpr/libwinpr/io/device.c b/winpr/libwinpr/io/device.c index 30ce40dae..c8f75e5ce 100644 --- a/winpr/libwinpr/io/device.c +++ b/winpr/libwinpr/io/device.c @@ -148,9 +148,8 @@ NTSTATUS _IoCreateDeviceEx(PDRIVER_OBJECT_EX DriverObject, ULONG DeviceExtension if (!pDeviceObjectEx) return STATUS_NO_MEMORY; - ConvertFromUnicode(CP_UTF8, 0, DeviceName->Buffer, DeviceName->Length / 2, - &(pDeviceObjectEx->DeviceName), 0, NULL, NULL); - + pDeviceObjectEx->DeviceName = + ConvertWCharNToUtf8Alloc(DeviceName->Buffer, DeviceName->Length / sizeof(WCHAR), NULL); if (!pDeviceObjectEx->DeviceName) { free(pDeviceObjectEx); diff --git a/winpr/libwinpr/library/library.c b/winpr/libwinpr/library/library.c index 1677688ca..bfaca784a 100644 --- a/winpr/libwinpr/library/library.c +++ b/winpr/libwinpr/library/library.c @@ -113,9 +113,8 @@ HMODULE LoadLibraryA(LPCSTR lpLibFileName) if (!lpLibFileName) return NULL; - status = ConvertToUnicode(CP_UTF8, 0, lpLibFileName, -1, &filenameW, 0); - - if (status < 1) + filenameW = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL); + if (filenameW) return NULL; hModule = LoadLibraryW(filenameW); @@ -138,14 +137,14 @@ HMODULE LoadLibraryA(LPCSTR lpLibFileName) HMODULE LoadLibraryW(LPCWSTR lpLibFileName) { + if (!lpLibFileName) + return NULL; #if defined(_UWP) return LoadPackagedLibrary(lpLibFileName, 0); #else - char* name = NULL; HMODULE module; - int rc = ConvertFromUnicode(CP_UTF8, 0, lpLibFileName, -1, &name, 0, NULL, NULL); - - if (rc < 0) + char* name = ConvertWCharToUtf8Alloc(lpLibFileName, NULL); + if (!name) return NULL; module = LoadLibraryA(name); @@ -232,6 +231,12 @@ HMODULE GetModuleHandleW(LPCWSTR lpModuleName) DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize) { DWORD status; + if (!lpFilename) + { + SetLastError(ERROR_INTERNAL_ERROR); + return 0; + } + char* name = calloc(nSize, sizeof(char)); if (!name) { @@ -248,9 +253,7 @@ DWORD GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSize) if (status > 0) { - int rc = ConvertToUnicode(CP_UTF8, 0, name, (int)status, &lpFilename, (int)nSize); - - if (rc < 0) + if (ConvertUtf8NToWChar(name, status, lpFilename, nSize) < 0) { free(name); SetLastError(ERROR_INTERNAL_ERROR); @@ -345,11 +348,14 @@ DWORD GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize) HMODULE LoadLibraryX(LPCSTR lpLibFileName) { + if (!lpLibFileName) + return NULL; + #if defined(_WIN32) HMODULE hm = NULL; - WCHAR* wstr = NULL; - int rc = ConvertToUnicode(CP_UTF8, 0, lpLibFileName, -1, &wstr, 0); - if (rc > 0) + WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL); + + if (wstr) hm = LoadLibraryW(wstr); free(wstr); return hm; @@ -360,11 +366,12 @@ HMODULE LoadLibraryX(LPCSTR lpLibFileName) HMODULE LoadLibraryExX(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { + if (!lpLibFileName) + return NULL; #if defined(_WIN32) HMODULE hm = NULL; - WCHAR* wstr = NULL; - int rc = ConvertToUnicode(CP_UTF8, 0, lpLibFileName, -1, &wstr, 0); - if (rc > 0) + WCHAR* wstr = ConvertUtf8ToWCharAlloc(lpLibFileName, NULL); + if (wstr) hm = LoadLibraryExW(wstr, hFile, dwFlags); free(wstr); return hm; diff --git a/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c b/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c index 33f764d40..d05310806 100644 --- a/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c +++ b/winpr/libwinpr/ncrypt/ncrypt_pkcs11.c @@ -533,7 +533,7 @@ static BOOL convertKeyType(CK_KEY_TYPE k, LPWSTR dest, DWORD len, DWORD* outlen) static void wprintKeyName(LPWSTR str, CK_SLOT_ID slotId, CK_BYTE* id, CK_ULONG idLen) { - char asciiName[128]; + char asciiName[128] = { 0 }; char* ptr = asciiName; const CK_BYTE* bytePtr; CK_ULONG i; @@ -551,7 +551,8 @@ static void wprintKeyName(LPWSTR str, CK_SLOT_ID slotId, CK_BYTE* id, CK_ULONG i for (i = 0; i < idLen; i++, id++, ptr += 2) snprintf(ptr, 3, "%.2x", *id); - MultiByteToWideChar(CP_UTF8, 0, asciiName, strlen(asciiName), str, (strlen(asciiName) + 1)); + ConvertUtf8NToWChar(asciiName, ARRAYSIZE(asciiName), str, + strnlen(asciiName, ARRAYSIZE(asciiName)) + 1); } static size_t parseHex(const char* str, const char* end, CK_BYTE* target) @@ -611,8 +612,7 @@ static SECURITY_STATUS parseKeyName(LPCWSTR pszKeyName, CK_SLOT_ID* slotId, CK_B char asciiKeyName[128] = { 0 }; char* pos; - if (WideCharToMultiByte(CP_UTF8, 0, pszKeyName, _wcslen(pszKeyName) + 1, asciiKeyName, - sizeof(asciiKeyName) - 1, "?", FALSE) <= 0) + if (ConvertWCharToUtf8(pszKeyName, asciiKeyName, ARRAYSIZE(asciiKeyName)) < 0) return NTE_BAD_KEY; if (*asciiKeyName != '\\') @@ -661,10 +661,9 @@ static SECURITY_STATUS NCryptP11EnumKeys(NCRYPT_PROV_HANDLE hProvider, LPCWSTR p * card reader */ char asciiScope[128 + 6] = { 0 }; - int asciiScopeLen; + size_t asciiScopeLen; - if (WideCharToMultiByte(CP_UTF8, 0, pszScope, _wcslen(pszScope) + 1, asciiScope, - sizeof(asciiScope) - 1, "?", NULL) <= 0) + if (ConvertWCharToUtf8(pszScope, asciiScope, ARRAYSIZE(asciiScope)) < 0) return NTE_INVALID_PARAMETER; if (strstr(asciiScope, "\\\\.\\") != asciiScope) @@ -846,14 +845,15 @@ static SECURITY_STATUS get_piv_container_name(NCryptP11KeyHandle* key, BYTE* piv return NTE_BAD_KEY; fix_padded_string((char*)slot_info.slotDescription, sizeof(slot_info.slotDescription)); - if (ConvertToUnicode( - CP_UTF8, 0, (char*)slot_info.slotDescription, - strnlen((char*)slot_info.slotDescription, sizeof(slot_info.slotDescription)), &reader, - 0) < 0) - return NTE_NO_MEMORY; + reader = ConvertUtf8NToWCharAlloc((char*)slot_info.slotDescription, + ARRAYSIZE(slot_info.slotDescription), NULL); + ret = NTE_NO_MEMORY; + if (!reader) + goto out; + ret = NTE_BAD_KEY; if (SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &context) != SCARD_S_SUCCESS) - return NTE_BAD_KEY; + goto out; if (SCardConnectW(context, reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_Tx, &card, &proto) != SCARD_S_SUCCESS) @@ -893,11 +893,18 @@ static SECURITY_STATUS get_piv_container_name(NCryptP11KeyHandle* key, BYTE* piv piv_tag[1], piv_tag[2]); /* And convert it to UTF-16 */ - if (MultiByteToWideChar(CP_UTF8, 0, container_name, PIV_CONTAINER_NAME_LEN, (WCHAR*)output, - output_len) == PIV_CONTAINER_NAME_LEN) + union + { + WCHAR* wc; + BYTE* b; + } cnv; + cnv.b = output; + if (ConvertUtf8NToWChar(container_name, ARRAYSIZE(container_name), cnv.wc, + output_len / sizeof(WCHAR)) > 0) ret = ERROR_SUCCESS; out: + free(reader); if (card) SCardDisconnect(card, SCARD_LEAVE_CARD); if (context) @@ -968,11 +975,17 @@ static SECURITY_STATUS NCryptP11KeyGetProperties(NCryptP11KeyHandle* keyHandle, *pcbResult = 2 * (strnlen((char*)slotInfo.slotDescription, SLOT_DESC_SZ) + 1); if (pbOutput) { + union + { + WCHAR* wc; + BYTE* b; + } cnv; + cnv.b = pbOutput; if (cbOutput < *pcbResult) return NTE_NO_MEMORY; - if (MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)slotInfo.slotDescription, -1, - (LPWSTR)pbOutput, cbOutput) <= 0) + if (ConvertUtf8ToWChar((char*)slotInfo.slotDescription, cnv.wc, + cbOutput / sizeof(WCHAR)) < 0) return NTE_NO_MEMORY; } return ERROR_SUCCESS; @@ -1071,11 +1084,18 @@ static SECURITY_STATUS NCryptP11KeyGetProperties(NCryptP11KeyHandle* keyHandle, /* Otherwise, at least for GIDS cards the label will be the correct value */ if (ret == NTE_NOT_FOUND) { - *pcbResult = - MultiByteToWideChar(CP_UTF8, 0, label, attr.ulValueLen, (LPWSTR)pbOutput, - pbOutput ? cbOutput / sizeof(WCHAR) : 0) * - sizeof(WCHAR); - ret = ERROR_SUCCESS; + union + { + WCHAR* wc; + BYTE* b; + } cnv; + const size_t olen = pbOutput ? cbOutput / sizeof(WCHAR) : 0; + cnv.b = pbOutput; + SSIZE_T size = ConvertUtf8NToWChar(label, attr.ulValueLen, cnv.wc, olen); + if (size < 0) + ret = ERROR_CONVERT_TO_LARGE; + else + ret = ERROR_SUCCESS; } } diff --git a/winpr/libwinpr/ncrypt/test/TestNCryptProviders.c b/winpr/libwinpr/ncrypt/test/TestNCryptProviders.c index b13deb720..be35a9175 100644 --- a/winpr/libwinpr/ncrypt/test/TestNCryptProviders.c +++ b/winpr/libwinpr/ncrypt/test/TestNCryptProviders.c @@ -30,16 +30,19 @@ int TestNCryptProviders(int argc, char* argv[]) DWORD nproviders, i; NCryptProviderName* providers; + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + status = NCryptEnumStorageProviders(&nproviders, &providers, NCRYPT_SILENT_FLAG); if (status != ERROR_SUCCESS) return -1; for (i = 0; i < nproviders; i++) { - char providerNameStr[256]; + const NCryptProviderName* provider = &providers[i]; + char providerNameStr[256] = { 0 }; - WideCharToMultiByte(CP_UTF8, 0, providers[i].pszName, -1, providerNameStr, - sizeof(providerNameStr), NULL, FALSE); + ConvertWCharToUtf8(provider->pszName, providerNameStr, ARRAYSIZE(providerNameStr)); printf("%d: %s\n", i, providerNameStr); } diff --git a/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c b/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c index 70e7db884..688745668 100644 --- a/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c +++ b/winpr/libwinpr/ncrypt/test/TestNCryptSmartcard.c @@ -74,18 +74,18 @@ int TestNCryptSmartcard(int argc, char* argv[]) for (j = 0; j < providerCount; j++) { + const NCryptProviderName* name = &names[j]; NCRYPT_PROV_HANDLE provider; char providerNameStr[256] = { 0 }; PVOID enumState = NULL; size_t i = 0; NCryptKeyName* keyName = NULL; - if (WideCharToMultiByte(CP_UTF8, 0, names[j].pszName, -1, providerNameStr, - sizeof(providerNameStr), NULL, FALSE) <= 0) + if (ConvertWCharToUtf8(name->pszName, providerNameStr, ARRAYSIZE(providerNameStr)) < 0) continue; printf("provider %ld: %s\n", j, providerNameStr); - status = NCryptOpenStorageProvider(&provider, names[j].pszName, 0); + status = NCryptOpenStorageProvider(&provider, name->pszName, 0); if (status != ERROR_SUCCESS) continue; @@ -98,8 +98,7 @@ int TestNCryptSmartcard(int argc, char* argv[]) WCHAR reader[1024] = { 0 }; PBYTE certBytes = NULL; - if (WideCharToMultiByte(CP_UTF8, 0, keyName->pszName, -1, keyNameStr, - sizeof(keyNameStr), NULL, FALSE) <= 0) + if (ConvertWCharToUtf8(keyName->pszName, keyNameStr, ARRAYSIZE(keyNameStr)) < 0) continue; printf("\tkey %ld: %s\n", i, keyNameStr); @@ -116,9 +115,9 @@ int TestNCryptSmartcard(int argc, char* argv[]) if (status == ERROR_SUCCESS) { char readerStr[1024] = { 0 }; - if (WideCharToMultiByte(CP_UTF8, 0, reader, cbOutput, readerStr, sizeof(readerStr), - NULL, FALSE) > 0) - printf("\treader: %s\n", readerStr); + + ConvertWCharNToUtf8(reader, cbOutput, readerStr, ARRAYSIZE(readerStr)); + printf("\treader: %s\n", readerStr); } cbOutput = 0; diff --git a/winpr/libwinpr/path/shell.c b/winpr/libwinpr/path/shell.c index f37791244..58813bea0 100644 --- a/winpr/libwinpr/path/shell.c +++ b/winpr/libwinpr/path/shell.c @@ -543,7 +543,8 @@ BOOL PathMakePathW(LPCWSTR path, LPSECURITY_ATTRIBUTES lpAttributes) #endif - if (ConvertFromUnicode(CP_UTF8, 0, path, -1, &dup, 0, NULL, NULL) <= 0) + dup = ConvertWCharToUtf8Alloc(path, NULL); + if (!dup) return FALSE; #ifdef __OS2__ @@ -586,12 +587,16 @@ BOOL PathIsRelativeA(LPCSTR pszPath) BOOL PathIsRelativeW(LPCWSTR pszPath) { LPSTR lpFileNameA = NULL; - BOOL ret; + BOOL ret = FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, pszPath, -1, &lpFileNameA, 0, NULL, NULL) < 1) - return FALSE; + if (!pszPath) + goto fail; + lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL); + if (!lpFileNameA) + goto fail; ret = PathIsRelativeA(lpFileNameA); +fail: free(lpFileNameA); return ret; } @@ -609,12 +614,16 @@ BOOL PathFileExistsA(LPCSTR pszPath) BOOL PathFileExistsW(LPCWSTR pszPath) { LPSTR lpFileNameA = NULL; - BOOL ret; + BOOL ret = FALSE; - if (ConvertFromUnicode(CP_UTF8, 0, pszPath, -1, &lpFileNameA, 0, NULL, NULL) < 1) - return FALSE; + if (!pszPath) + goto fail; + lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL); + if (!lpFileNameA) + goto fail; ret = winpr_PathFileExists(lpFileNameA); +fail: free(lpFileNameA); return ret; } @@ -644,12 +653,14 @@ BOOL PathIsDirectoryEmptyA(LPCSTR pszPath) BOOL PathIsDirectoryEmptyW(LPCWSTR pszPath) { LPSTR lpFileNameA = NULL; - BOOL ret; - - if (ConvertFromUnicode(CP_UTF8, 0, pszPath, -1, &lpFileNameA, 0, NULL, NULL) < 1) - return FALSE; - + BOOL ret = FALSE; + if (!pszPath) + goto fail; + lpFileNameA = ConvertWCharToUtf8Alloc(pszPath, NULL); + if (!lpFileNameA) + goto fail; ret = PathIsDirectoryEmptyA(lpFileNameA); +fail: free(lpFileNameA); return ret; } @@ -674,10 +685,11 @@ BOOL winpr_MoveFile(LPCSTR lpExistingFileName, LPCSTR lpNewFileName) if (!lpExistingFileName || !lpNewFileName) return FALSE; - if (ConvertToUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpExistingFileNameW, 0) < 1) + lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL); + if (!lpExistingFileNameW) goto cleanup; - - if (ConvertToUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpNewFileNameW, 0) < 1) + lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL); + if (!lpNewFileNameW) goto cleanup; result = MoveFileW(lpExistingFileNameW, lpNewFileNameW); @@ -701,10 +713,11 @@ BOOL winpr_MoveFileEx(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, DWORD dwF if (!lpExistingFileName || !lpNewFileName) return FALSE; - if (ConvertToUnicode(CP_UTF8, 0, lpExistingFileName, -1, &lpExistingFileNameW, 0) < 1) + lpExistingFileNameW = ConvertUtf8ToWCharAlloc(lpExistingFileName, NULL); + if (!lpExistingFileNameW) goto cleanup; - - if (ConvertToUnicode(CP_UTF8, 0, lpNewFileName, -1, &lpNewFileNameW, 0) < 1) + lpNewFileNameW = ConvertUtf8ToWCharAlloc(lpNewFileName, NULL); + if (!lpNewFileNameW) goto cleanup; result = MoveFileExW(lpExistingFileNameW, lpNewFileNameW, dwFlags); @@ -726,7 +739,8 @@ BOOL winpr_DeleteFile(const char* lpFileName) if (lpFileName) { - if (ConvertToUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameW, 0) < 1) + lpFileNameW = ConvertUtf8ToWCharAlloc(lpFileName, NULL); + if (!lpFileNameW) goto cleanup; } @@ -748,7 +762,8 @@ BOOL winpr_RemoveDirectory(LPCSTR lpPathName) if (lpPathName) { - if (ConvertToUnicode(CP_UTF8, 0, lpPathName, -1, &lpPathNameW, 0) < 1) + lpPathNameW = ConvertUtf8ToWCharAlloc(lpPathName, NULL); + if (!lpPathNameW) goto cleanup; } @@ -762,17 +777,19 @@ cleanup: BOOL winpr_PathFileExists(const char* pszPath) { + if (!pszPath) + return FALSE; #ifndef _WIN32 return PathFileExistsA(pszPath); #else - WCHAR* pszPathW = NULL; + WCHAR* pathW = ConvertUtf8ToWCharAlloc(pszPath, NULL); BOOL result = FALSE; - if (ConvertToUnicode(CP_UTF8, 0, pszPath, -1, &pszPathW, 0) < 1) + if (!pathW) return FALSE; - result = PathFileExistsW(pszPathW); - free(pszPathW); + result = PathFileExistsW(pathW); + free(pathW); return result; #endif @@ -780,13 +797,15 @@ BOOL winpr_PathFileExists(const char* pszPath) BOOL winpr_PathMakePath(const char* path, LPSECURITY_ATTRIBUTES lpAttributes) { + if (!path) + return FALSE; #ifndef _WIN32 return PathMakePathA(path, lpAttributes); #else - WCHAR* pathW = NULL; + WCHAR* pathW = ConvertUtf8ToWCharAlloc(path, NULL); BOOL result = FALSE; - if (ConvertToUnicode(CP_UTF8, 0, path, -1, &pathW, 0) < 1) + if (!pathW) return FALSE; result = SHCreateDirectoryExW(NULL, pathW, lpAttributes) == ERROR_SUCCESS; diff --git a/winpr/libwinpr/path/test/TestPathShell.c b/winpr/libwinpr/path/test/TestPathShell.c index 37feadc2e..11b3144fe 100644 --- a/winpr/libwinpr/path/test/TestPathShell.c +++ b/winpr/libwinpr/path/test/TestPathShell.c @@ -30,6 +30,7 @@ int TestPathShell(int argc, char* argv[]) if (!path) { + fprintf(stderr, "GetKnownPath(%d) failed\n", id); rc = -1; } else @@ -43,6 +44,7 @@ int TestPathShell(int argc, char* argv[]) if (!path) { + fprintf(stderr, "GetKnownSubPath(%d) failed\n", id); rc = -1; } else diff --git a/winpr/libwinpr/registry/registry.c b/winpr/libwinpr/registry/registry.c index ad480754e..853db4638 100644 --- a/winpr/libwinpr/registry/registry.c +++ b/winpr/libwinpr/registry/registry.c @@ -238,9 +238,8 @@ LONG RegOpenCurrentUser(REGSAM samDesired, PHKEY phkResult) LONG RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) { LONG rc; - char* str = NULL; - int res = ConvertFromUnicode(CP_UTF8, 0, lpSubKey, -1, &str, 0, NULL, NULL); - if (res < 0) + char* str = ConvertWCharToUtf8Alloc(lpSubKey, NULL); + if (!str) return ERROR_FILE_NOT_FOUND; rc = RegOpenKeyExA(hKey, str, ulOptions, samDesired, phkResult); @@ -369,7 +368,8 @@ LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWOR key = (RegKey*)hKey; WINPR_ASSERT(key); - if (ConvertFromUnicode(CP_UTF8, 0, lpValueName, -1, &valueName, 0, NULL, NULL) <= 0) + valueName = ConvertWCharToUtf8Alloc(lpValueName, NULL); + if (!valueName) goto end; pValue = key->values; @@ -394,14 +394,20 @@ LONG RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWOR if (lpData != NULL) { DWORD size; + union + { + WCHAR* wc; + BYTE* b; + } cnv; WINPR_ASSERT(lpcbData); + cnv.b = lpData; size = *lpcbData; *lpcbData = (DWORD)length; if (size < length) return ERROR_MORE_DATA; - ConvertToUnicode(CP_UTF8, 0, pValue->data.string, length, (WCHAR**)&lpData, - length); + if (ConvertUtf8NToWChar(pValue->data.string, length, cnv.wc, length) < 0) + return ERROR_OUTOFMEMORY; } else if (lpcbData) *lpcbData = (UINT32)length; diff --git a/winpr/libwinpr/shell/shell.c b/winpr/libwinpr/shell/shell.c index 2eff439e9..112e31793 100644 --- a/winpr/libwinpr/shell/shell.c +++ b/winpr/libwinpr/shell/shell.c @@ -129,7 +129,8 @@ BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchS if (bStatus) { - MultiByteToWideChar(CP_ACP, 0, lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize); + SSIZE_T size = ConvertUtf8NToWChar(lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize); + bStatus = size >= 0; } if (lpProfileDirA) diff --git a/winpr/libwinpr/smartcard/smartcard_pcsc.c b/winpr/libwinpr/smartcard/smartcard_pcsc.c index f934f6f6c..986ddc20e 100644 --- a/winpr/libwinpr/smartcard/smartcard_pcsc.c +++ b/winpr/libwinpr/smartcard/smartcard_pcsc.c @@ -850,11 +850,13 @@ static LONG WINAPI PCSC_SCardListReaderGroupsW(SCARDCONTEXT hContext, LPWSTR msz if (status == SCARD_S_SUCCESS) { - int rc = ConvertToUnicode(CP_UTF8, 0, *pMszGroupsA, (int)*pcchGroups, conv.lppstr, 0); - if (rc < 0) + size_t size = 0; + WCHAR* str = ConvertUtf8NToWCharAlloc(*pMszGroupsA, *pcchGroups, &size); + if (!str) return SCARD_E_NO_MEMORY; - *pcchGroups = (DWORD)rc; - PCSC_AddMemoryBlock(hContext, conv.lpstr); + *conv.lppstr = str; + *pcchGroups = (DWORD)size; + PCSC_AddMemoryBlock(hContext, str); PCSC_SCardFreeMemory_Internal(hContext, *pMszGroupsA); } @@ -989,17 +991,25 @@ static LONG WINAPI PCSC_SCardListReadersW(SCARDCONTEXT hContext, LPCWSTR mszGrou mszGroups = NULL; /* mszGroups is not supported by pcsc-lite */ if (mszGroups) - ConvertFromUnicode(CP_UTF8, 0, mszGroups, -1, (char**)&mszGroupsA, 0, NULL, NULL); - - status = PCSC_SCardListReaders_Internal(hContext, mszGroupsA, (LPSTR)&mszReadersA, pcchReaders); + { + mszGroupsA = ConvertWCharToUtf8Alloc(mszGroups, NULL); + if (!mszGroups) + return SCARD_E_NO_MEMORY; + } if (status == SCARD_S_SUCCESS) { - int rc = ConvertToUnicode(CP_UTF8, 0, *pMszReadersA, (int)*pcchReaders, conv.lppstr, 0); - if (rc < 0) + size_t size = 0; + WCHAR* str = ConvertUtf8NToWCharAlloc(*pMszReadersA, *pcchReaders, &size); + + if (!str || (size > UINT32_MAX)) + { + free(mszGroupsA); return SCARD_E_NO_MEMORY; - *pcchReaders = (DWORD)rc; - PCSC_AddMemoryBlock(hContext, conv.lpstr); + } + *conv.lppstr = str; + *pcchReaders = (DWORD)size; + PCSC_AddMemoryBlock(hContext, str); PCSC_SCardFreeMemory_Internal(hContext, *pMszReadersA); } @@ -1150,7 +1160,8 @@ static LONG WINAPI PCSC_SCardListCardsW(SCARDCONTEXT hContext, LPCBYTE pbAtr, if (cardName) { size_t toCopy = strlen(cardName) + 1; - MultiByteToWideChar(CP_UTF8, 0, cardName, -1, output, toCopy); + if (ConvertUtf8ToWChar(cardName, output, toCopy) < 0) + return SCARD_F_INTERNAL_ERROR; output += toCopy; } @@ -1650,14 +1661,15 @@ static LONG WINAPI PCSC_SCardGetStatusChangeW(SCARDCONTEXT hContext, DWORD dwTim for (index = 0; index < cReaders; index++) { - states[index].szReader = NULL; - ConvertFromUnicode(CP_UTF8, 0, rgReaderStates[index].szReader, -1, - (char**)&(states[index].szReader), 0, NULL, NULL); - states[index].pvUserData = rgReaderStates[index].pvUserData; - states[index].dwCurrentState = rgReaderStates[index].dwCurrentState; - states[index].dwEventState = rgReaderStates[index].dwEventState; - states[index].cbAtr = rgReaderStates[index].cbAtr; - CopyMemory(&(states[index].rgbAtr), &(rgReaderStates[index].rgbAtr), 36); + const LPSCARD_READERSTATEW curReader = &rgReaderStates[index]; + LPSCARD_READERSTATEA cur = &states[index]; + + cur->szReader = ConvertWCharToUtf8Alloc(curReader->szReader, NULL); + cur->pvUserData = curReader->pvUserData; + cur->dwCurrentState = curReader->dwCurrentState; + cur->dwEventState = curReader->dwEventState; + cur->cbAtr = curReader->cbAtr; + CopyMemory(&(cur->rgbAtr), &(curReader->rgbAtr), ARRAYSIZE(cur->rgbAtr)); } status = PCSC_SCardGetStatusChange_Internal(hContext, dwTimeout, states, cReaders); @@ -1766,7 +1778,11 @@ static LONG WINAPI PCSC_SCardConnectW(SCARDCONTEXT hContext, LPCWSTR szReader, D return SCARD_E_INVALID_HANDLE; if (szReader) - ConvertFromUnicode(CP_UTF8, 0, szReader, -1, &szReaderA, 0, NULL, NULL); + { + szReaderA = ConvertWCharToUtf8Alloc(szReader, NULL); + if (!szReaderA) + return SCARD_E_INSUFFICIENT_BUFFER; + } status = PCSC_SCardConnect_Internal(hContext, szReaderA, dwShareMode, dwPreferredProtocols, phCard, pdwActiveProtocol); @@ -2020,17 +2036,17 @@ static LONG WINAPI PCSC_SCardStatus_Internal(SCARDHANDLE hCard, LPSTR mszReaderN if (unicode) { - int pcsc_cchReaderLenW = - ConvertToUnicode(CP_UTF8, 0, tReader, (int)*pcchReaderLen, &conv.pw, 0); + size_t size = 0; + conv.pw = ConvertUtf8NToWCharAlloc(tReader, *pcchReaderLen, &size); - if ((pcsc_cchReaderLenW <= 0) || (conv.pw == NULL)) + if (conv.pw == NULL) { status = ERROR_NOT_ENOUGH_MEMORY; goto out_fail; } free(tReader); - conv.pw[pcsc_cchReaderLen - 1] = L'\0'; + PCSC_AddMemoryBlock(hContext, conv.pw); *dst.ppw = conv.pw; } @@ -2444,8 +2460,7 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA if (status != SCARD_S_SUCCESS) return status; - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)pbAttrW, (int)*pcbAttrLen, (char**)&namePCSC, 0, - NULL, NULL); + namePCSC = ConvertWCharNToUtf8Alloc(pbAttrW, *pcbAttrLen, NULL); PCSC_SCardFreeMemory_Internal(hContext, pbAttrW); } else @@ -2462,20 +2477,21 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA if (dwAttrId == SCARD_ATTR_DEVICE_FRIENDLY_NAME_W) { - WCHAR* friendlyNameW = NULL; + size_t size = 0; + WCHAR* friendlyNameW = ConvertUtf8ToWCharAlloc(namePCSC, &size); /* length here includes null terminator */ - int rc = ConvertToUnicode(CP_UTF8, 0, (char*)namePCSC, -1, &friendlyNameW, 0); - if ((rc < 0) || (!friendlyNameW)) + + if (!friendlyNameW) status = SCARD_E_NO_MEMORY; else { - length = (size_t)rc; + length = size; if (cbAttrLen == SCARD_AUTOALLOCATE) { - WINPR_ASSERT(length <= UINT32_MAX / 2); + WINPR_ASSERT(length <= UINT32_MAX / sizeof(WCHAR)); *conv.ppw = friendlyNameW; - *pcbAttrLen = (UINT32)length * 2U; + *pcbAttrLen = (UINT32)length * sizeof(WCHAR); PCSC_AddMemoryBlock(hContext, friendlyNameW); } else @@ -2484,9 +2500,9 @@ static LONG WINAPI PCSC_SCardGetAttrib_FriendlyName(SCARDHANDLE hCard, DWORD dwA status = SCARD_E_INSUFFICIENT_BUFFER; else { - WINPR_ASSERT(length <= UINT32_MAX / 2); - CopyMemory(pbAttr, (BYTE*)friendlyNameW, (length * 2)); - *pcbAttrLen = (UINT32)length * 2U; + WINPR_ASSERT(length <= UINT32_MAX / sizeof(WCHAR)); + CopyMemory(pbAttr, (BYTE*)friendlyNameW, (length * sizeof(WCHAR))); + *pcbAttrLen = (UINT32)length * sizeof(WCHAR); } free(friendlyNameW); } @@ -2772,6 +2788,9 @@ static LONG WINAPI PCSC_SCardDlgExtendedError(void) static char* card_id_and_name_a(const UUID* CardIdentifier, LPCSTR LookupName) { + WINPR_ASSERT(CardIdentifier); + WINPR_ASSERT(LookupName); + size_t len = strlen(LookupName) + 34; char* id = malloc(len); if (!id) @@ -2788,9 +2807,9 @@ static char* card_id_and_name_a(const UUID* CardIdentifier, LPCSTR LookupName) static char* card_id_and_name_w(const UUID* CardIdentifier, LPCWSTR LookupName) { char* res; - char* tmp = NULL; - - ConvertFromUnicode(CP_UTF8, 0, LookupName, -1, &tmp, 0, NULL, NULL); + char* tmp = ConvertWCharToUtf8Alloc(LookupName, NULL); + if (!tmp) + return NULL; res = card_id_and_name_a(CardIdentifier, tmp); free(tmp); return res; diff --git a/winpr/libwinpr/sspi/Kerberos/kerberos.c b/winpr/libwinpr/sspi/Kerberos/kerberos.c index 2380c9825..cb99936c6 100644 --- a/winpr/libwinpr/sspi/Kerberos/kerberos.c +++ b/winpr/libwinpr/sspi/Kerberos/kerberos.c @@ -369,9 +369,17 @@ static SECURITY_STATUS SEC_ENTRY kerberos_AcquireCredentialsHandleW( char* package = NULL; if (pszPrincipal) - ConvertFromUnicode(CP_UTF8, 0, pszPrincipal, -1, &principal, 0, NULL, NULL); + { + principal = ConvertWCharToUtf8Alloc(pszPrincipal, NULL); + if (!principal) + return SEC_E_INSUFFICIENT_MEMORY; + } if (pszPackage) - ConvertFromUnicode(CP_UTF8, 0, pszPackage, -1, &package, 0, NULL, NULL); + { + package = ConvertWCharToUtf8Alloc(pszPackage, NULL); + if (!package) + return SEC_E_INSUFFICIENT_MEMORY; + } status = kerberos_AcquireCredentialsHandleA(principal, package, fCredentialUse, pvLogonID, pAuthData, @@ -989,7 +997,11 @@ static SECURITY_STATUS SEC_ENTRY kerberos_InitializeSecurityContextW( char* target_name = NULL; if (pszTargetName) - ConvertFromUnicode(CP_UTF8, 0, pszTargetName, -1, &target_name, 0, NULL, NULL); + { + target_name = ConvertWCharToUtf8Alloc(pszTargetName, NULL); + if (!target_name) + return SEC_E_INSUFFICIENT_MEMORY; + } status = kerberos_InitializeSecurityContextA(phCredential, phContext, target_name, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, @@ -1367,9 +1379,7 @@ static SECURITY_STATUS SEC_ENTRY kerberos_SetCredentialsAttributesX(PCredHandle if (KdcUrl) { - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)KdcUrl, -1, &credentials->kdc_url, 0, NULL, - NULL); - + credentials->kdc_url = ConvertWCharToUtf8Alloc(KdcUrl, NULL); if (!credentials->kdc_url) return SEC_E_INSUFFICIENT_MEMORY; } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 784ecb297..dd150b978 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -45,7 +45,6 @@ static char* NTLM_PACKAGE_NAME = "NTLM"; static int ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) { - int status; char* ws = Workstation; DWORD nSize = 0; CHAR* computerName; @@ -78,17 +77,16 @@ static int ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) return -1; } - context->Workstation.Buffer = NULL; - status = ConvertToUnicode(CP_UTF8, 0, ws, -1, &context->Workstation.Buffer, 0); + size_t len = 0; + context->Workstation.Buffer = ConvertUtf8ToWCharAlloc(ws, &len); if (!Workstation) free(ws); - if (status <= 0) + if (!context->Workstation.Buffer || (len > UINT16_MAX / sizeof(WCHAR))) return -1; - context->Workstation.Length = (USHORT)(status - 1); - context->Workstation.Length *= 2; + context->Workstation.Length = (USHORT)(len * sizeof(WCHAR)); return 1; } @@ -116,7 +114,6 @@ static int ntlm_SetContextServicePrincipalNameW(NTLM_CONTEXT* context, LPWSTR Se static int ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName) { - int status; char* name = TargetName; DWORD nSize = 0; CHAR* computerName = NULL; @@ -151,18 +148,21 @@ static int ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName) CharUpperA(name); } - context->TargetName.pvBuffer = NULL; - status = ConvertToUnicode(CP_UTF8, 0, name, -1, (LPWSTR*)&context->TargetName.pvBuffer, 0); + size_t len = 0; + context->TargetName.pvBuffer = ConvertUtf8ToWCharAlloc(name, &len); - if (status <= 0) + if (!context->TargetName.pvBuffer || (len > UINT16_MAX / sizeof(WCHAR))) { + free(context->TargetName.pvBuffer); + context->TargetName.pvBuffer = NULL; + if (!TargetName) free(name); return -1; } - context->TargetName.cbBuffer = (USHORT)((status - 1) * 2); + context->TargetName.cbBuffer = (USHORT)(len * sizeof(WCHAR)); if (!TargetName) free(name); @@ -350,23 +350,30 @@ static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA( void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { - SECURITY_STATUS status; + SECURITY_STATUS status = SEC_E_INSUFFICIENT_MEMORY; SEC_WCHAR* principal = NULL; SEC_WCHAR* package = NULL; if (pszPrincipal) - ConvertToUnicode(CP_UTF8, 0, pszPrincipal, -1, &principal, 0); + { + principal = ConvertUtf8ToWCharAlloc(pszPrincipal, NULL); + if (!principal) + goto fail; + } if (pszPackage) - ConvertToUnicode(CP_UTF8, 0, pszPackage, -1, &package, 0); + { + package = ConvertUtf8ToWCharAlloc(pszPackage, NULL); + if (!package) + goto fail; + } status = ntlm_AcquireCredentialsHandleW(principal, package, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); - if (principal) - free(principal); - if (package) - free(package); +fail: + free(principal); + free(package); return status; } @@ -676,7 +683,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA( if (pszTargetName) { - if (ConvertToUnicode(CP_UTF8, 0, pszTargetName, -1, &pszTargetNameW, 0) <= 0) + pszTargetNameW = ConvertUtf8ToWCharAlloc(pszTargetName, NULL); + if (!pszTargetNameW) return SEC_E_INTERNAL_ERROR; } @@ -779,37 +787,28 @@ static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phCont } else if (ulAttribute == SECPKG_ATTR_AUTH_IDENTITY) { - int status; - char* UserA = NULL; - char* DomainA = NULL; SSPI_CREDENTIALS* credentials; + const SecPkgContext_AuthIdentity empty = { 0 }; SecPkgContext_AuthIdentity* AuthIdentity = (SecPkgContext_AuthIdentity*)pBuffer; + + WINPR_ASSERT(AuthIdentity); + *AuthIdentity = empty; + context->UseSamFileDatabase = FALSE; credentials = context->credentials; - ZeroMemory(AuthIdentity, sizeof(SecPkgContext_AuthIdentity)); - UserA = AuthIdentity->User; if (credentials->identity.UserLength > 0) { - WINPR_ASSERT(credentials->identity.UserLength <= INT_MAX); - status = - ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)credentials->identity.User, - (int)credentials->identity.UserLength, &UserA, 256, NULL, NULL); - - if (status <= 0) + if (ConvertWCharNToUtf8(credentials->identity.User, credentials->identity.UserLength, + AuthIdentity->User, ARRAYSIZE(AuthIdentity->User)) <= 0) return SEC_E_INTERNAL_ERROR; } - DomainA = AuthIdentity->Domain; - if (credentials->identity.DomainLength > 0) { - WINPR_ASSERT(credentials->identity.DomainLength <= INT_MAX); - status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)credentials->identity.Domain, - (int)credentials->identity.DomainLength, &DomainA, 256, - NULL, NULL); - - if (status <= 0) + if (ConvertWCharNToUtf8(credentials->identity.Domain, + credentials->identity.DomainLength, AuthIdentity->Domain, + ARRAYSIZE(AuthIdentity->Domain)) <= 0) return SEC_E_INTERNAL_ERROR; } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index bf7755f6b..db65487c2 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -301,7 +301,7 @@ static BOOL ntlm_av_pair_add_copy(NTLM_AV_PAIR* pAvPairList, size_t cbAvPairList static int ntlm_get_target_computer_name(PUNICODE_STRING pName, COMPUTER_NAME_FORMAT type) { char* name; - int status; + int status = -1; DWORD nSize = 0; CHAR* computerName; @@ -332,15 +332,18 @@ static int ntlm_get_target_computer_name(PUNICODE_STRING pName, COMPUTER_NAME_FO if (type == ComputerNameNetBIOS) CharUpperA(name); - status = ConvertToUnicode(CP_UTF8, 0, name, -1, &pName->Buffer, 0); + size_t len = 0; + pName->Buffer = ConvertUtf8ToWCharAlloc(name, &len); - if (status <= 0) + if (!pName->Buffer || (len == 0) || (len > UINT16_MAX / sizeof(WCHAR))) { + free(pName->Buffer); + pName->Buffer = NULL; free(name); return status; } - pName->Length = (USHORT)((status - 1) * 2); + pName->Length = (USHORT)((len) * sizeof(WCHAR)); pName->MaximumLength = pName->Length; free(name); return 1; diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 44aa1dc6e..98b4a574e 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -319,11 +319,10 @@ fail: static int ntlm_convert_password_hash(NTLM_CONTEXT* context, BYTE* hash) { - int status; int i; - char* PasswordHash = NULL; + char PasswordHash[32] = { 0 }; INT64 PasswordHashLength = 0; - SSPI_CREDENTIALS* credentials; + SSPI_CREDENTIALS* credentials = NULL; WINPR_ASSERT(context); WINPR_ASSERT(hash); @@ -332,17 +331,16 @@ static int ntlm_convert_password_hash(NTLM_CONTEXT* context, BYTE* hash) /* Password contains a password hash of length (PasswordLength - * SSPI_CREDENTIALS_HASH_LENGTH_OFFSET) */ PasswordHashLength = credentials->identity.PasswordLength - SSPI_CREDENTIALS_HASH_LENGTH_OFFSET; - WINPR_ASSERT(PasswordHashLength >= 0); - WINPR_ASSERT(PasswordHashLength <= INT_MAX); - status = ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR)credentials->identity.Password, - (int)PasswordHashLength, &PasswordHash, 0, NULL, NULL); - if (status <= 0) + WINPR_ASSERT(PasswordHashLength >= 0); + WINPR_ASSERT(PasswordHashLength < ARRAYSIZE(PasswordHash)); + if (ConvertWCharNToUtf8(credentials->identity.Password, PasswordHashLength, PasswordHash, + ARRAYSIZE(PasswordHash)) <= 0) return -1; CharUpperBuffA(PasswordHash, (DWORD)PasswordHashLength); - for (i = 0; i < 32; i += 2) + for (i = 0; i < ARRAYSIZE(PasswordHash); i += 2) { BYTE hn = (BYTE)(PasswordHash[i] > '9' ? PasswordHash[i] - 'A' + 10 : PasswordHash[i] - '0'); @@ -351,7 +349,6 @@ static int ntlm_convert_password_hash(NTLM_CONTEXT* context, BYTE* hash) hash[i / 2] = (BYTE)((hn << 4) | ln); } - free(PasswordHash); return 1; } diff --git a/winpr/libwinpr/sspi/Negotiate/negotiate.c b/winpr/libwinpr/sspi/Negotiate/negotiate.c index 38621a9df..d9dd73d78 100644 --- a/winpr/libwinpr/sspi/Negotiate/negotiate.c +++ b/winpr/libwinpr/sspi/Negotiate/negotiate.c @@ -388,7 +388,7 @@ static BOOL negotiate_write_neg_token(PSecBuffer output_buffer, NegToken* token) /* mechToken [2] OCTET STRING */ if (token->mechToken.cbBuffer) { - if (!WinPrAsn1EncContextualOctetString(enc, 2, &mechToken)) + if (WinPrAsn1EncContextualOctetString(enc, 2, &mechToken) == 0) goto cleanup; WLog_DBG(TAG, "\tmechToken [2] (%li bytes)", token->mechToken.cbBuffer); } @@ -396,7 +396,7 @@ static BOOL negotiate_write_neg_token(PSecBuffer output_buffer, NegToken* token) /* mechListMIC [3] OCTET STRING */ if (token->mic.cbBuffer) { - if (!WinPrAsn1EncContextualOctetString(enc, 3, &mechListMic)) + if (WinPrAsn1EncContextualOctetString(enc, 3, &mechListMic) == 0) goto cleanup; WLog_DBG(TAG, "\tmechListMIC [3] (%li bytes)", token->mic.cbBuffer); } @@ -881,7 +881,8 @@ static SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA( if (pszTargetName) { - if (ConvertToUnicode(CP_UTF8, 0, pszTargetName, -1, &pszTargetNameW, 0) <= 0) + pszTargetNameW = ConvertUtf8ToWCharAlloc(pszTargetName, NULL); + if (!pszTargetNameW) return SEC_E_INTERNAL_ERROR; } diff --git a/winpr/libwinpr/sspi/Schannel/schannel.c b/winpr/libwinpr/sspi/Schannel/schannel.c index 3f2cb99cf..f8e6465ac 100644 --- a/winpr/libwinpr/sspi/Schannel/schannel.c +++ b/winpr/libwinpr/sspi/Schannel/schannel.c @@ -168,8 +168,11 @@ static SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleA( SECURITY_STATUS status; SEC_WCHAR* pszPrincipalW = NULL; SEC_WCHAR* pszPackageW = NULL; - ConvertToUnicode(CP_UTF8, 0, pszPrincipal, -1, &pszPrincipalW, 0); - ConvertToUnicode(CP_UTF8, 0, pszPackage, -1, &pszPackageW, 0); + if (pszPrincipal) + pszPrincipalW = ConvertUtf8ToWCharAlloc(pszPrincipal, NULL); + if (pszPackage) + pszPackageW = ConvertUtf8ToWCharAlloc(pszPackage, NULL); + status = schannel_AcquireCredentialsHandleW(pszPrincipalW, pszPackageW, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); @@ -238,7 +241,9 @@ static SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextA( if (pszTargetName != NULL) { - ConvertToUnicode(CP_UTF8, 0, pszTargetName, -1, &pszTargetNameW, 0); + pszTargetNameW = ConvertUtf8ToWCharAlloc(pszTargetName, NULL); + if (!pszTargetNameW) + return SEC_E_INSUFFICIENT_MEMORY; } status = schannel_InitializeSecurityContextW( diff --git a/winpr/libwinpr/sspi/sspi_winpr.c b/winpr/libwinpr/sspi/sspi_winpr.c index c7d721897..acd0c49df 100644 --- a/winpr/libwinpr/sspi/sspi_winpr.c +++ b/winpr/libwinpr/sspi/sspi_winpr.c @@ -376,15 +376,14 @@ int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, c const char* password) { int rc; - int unicodePasswordLenW; - LPWSTR unicodePassword = NULL; - unicodePasswordLenW = ConvertToUnicode(CP_UTF8, 0, password, -1, &unicodePassword, 0); + size_t unicodePasswordLenW = 0; + LPWSTR unicodePassword = ConvertUtf8ToWCharAlloc(password, &unicodePasswordLenW); - if (unicodePasswordLenW <= 0) + if (!unicodePassword || (unicodePasswordLenW == 0)) return -1; rc = sspi_SetAuthIdentityWithUnicodePassword(identity, user, domain, unicodePassword, - (ULONG)(unicodePasswordLenW - 1)); + (ULONG)(unicodePasswordLenW)); free(unicodePassword); return rc; } @@ -393,30 +392,28 @@ int sspi_SetAuthIdentityWithUnicodePassword(SEC_WINNT_AUTH_IDENTITY* identity, c const char* domain, LPWSTR password, ULONG passwordLength) { - int status; - sspi_FreeAuthIdentity(identity); identity->Flags &= ~SEC_WINNT_AUTH_IDENTITY_ANSI; identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE; - if (user) + if (user && (strlen(user) > 0)) { - status = ConvertToUnicode(CP_UTF8, 0, user, -1, (LPWSTR*)&(identity->User), 0); - - if (status <= 0) + size_t len = 0; + identity->User = ConvertUtf8ToWCharAlloc(user, &len); + if (!identity->User || (len == 0) || (len > ULONG_MAX)) return -1; - identity->UserLength = (ULONG)(status - 1); + identity->UserLength = (ULONG)len; } - if (domain) + if (domain && (strlen(domain) > 0)) { - status = ConvertToUnicode(CP_UTF8, 0, domain, -1, (LPWSTR*)&(identity->Domain), 0); - - if (status <= 0) + size_t len = 0; + identity->Domain = ConvertUtf8ToWCharAlloc(domain, &len); + if (!identity->Domain || (len == 0) || (len > ULONG_MAX)) return -1; - identity->DomainLength = (ULONG)(status - 1); + identity->DomainLength = len; } identity->Password = (UINT16*)calloc(1, (passwordLength + 1) * sizeof(WCHAR)); @@ -666,26 +663,23 @@ BOOL sspi_CopyAuthIdentityFieldsA(const SEC_WINNT_AUTH_IDENTITY_INFO* identity, if (!sspi_GetAuthIdentityPasswordW((void*)identity, &PasswordW, &PasswordLength)) goto cleanup; - if (UserW && UserLength) + if (UserW && (UserLength > 0)) { - ConvertFromUnicode(CP_UTF8, 0, UserW, UserLength, pUser, 0, NULL, NULL); - + *pUser = ConvertWCharNToUtf8Alloc(UserW, UserLength, NULL); if (!(*pUser)) goto cleanup; } - if (DomainW && DomainLength) + if (DomainW && (DomainLength > 0)) { - ConvertFromUnicode(CP_UTF8, 0, DomainW, DomainLength, pDomain, 0, NULL, NULL); - + *pDomain = ConvertWCharNToUtf8Alloc(DomainW, DomainLength, NULL); if (!(*pDomain)) goto cleanup; } - if (PasswordW && PasswordLength) + if (PasswordW && (PasswordLength > 0)) { - ConvertFromUnicode(CP_UTF8, 0, PasswordW, PasswordLength, pPassword, 0, NULL, NULL); - + *pPassword = ConvertWCharNToUtf8Alloc(PasswordW, PasswordLength, NULL); if (!(*pPassword)) goto cleanup; } @@ -727,27 +721,29 @@ BOOL sspi_CopyAuthIdentityFieldsW(const SEC_WINNT_AUTH_IDENTITY_INFO* identity, if (!sspi_GetAuthIdentityPasswordA((void*)identity, &PasswordA, &PasswordLength)) goto cleanup; - if (UserA && UserLength) + if (UserA && (UserLength > 0)) { - ConvertToUnicode(CP_UTF8, 0, UserA, UserLength, pUser, 0); + WCHAR* ptr = ConvertUtf8NToWCharAlloc(UserA, UserLength, NULL); + *pUser = ptr; - if (!(*pUser)) + if (!ptr) goto cleanup; } - if (DomainA && DomainLength) + if (DomainA && (DomainLength > 0)) { - ConvertToUnicode(CP_UTF8, 0, DomainA, DomainLength, pDomain, 0); - - if (!(*pDomain)) + WCHAR* ptr = ConvertUtf8NToWCharAlloc(DomainA, DomainLength, NULL); + *pDomain = ptr; + if (!ptr) goto cleanup; } - if (PasswordA && PasswordLength) + if (PasswordA && (PasswordLength > 0)) { - ConvertToUnicode(CP_UTF8, 0, PasswordA, PasswordLength, pPassword, 0); + WCHAR* ptr = ConvertUtf8NToWCharAlloc(PasswordA, PasswordLength, NULL); - if (!(*pPassword)) + *pPassword = ptr; + if (!ptr) goto cleanup; } @@ -837,11 +833,8 @@ BOOL sspi_CopyAuthPackageListA(const SEC_WINNT_AUTH_IDENTITY_INFO* identity, cha PackageListLength = ((SEC_WINNT_AUTH_IDENTITY_EX2*)pAuthData)->PackageListLength / 2; } - if (PackageListW && PackageListLength) - { - ConvertFromUnicode(CP_UTF8, 0, PackageListW, PackageListLength, &PackageList, 0, NULL, - NULL); - } + if (PackageListW && (PackageListLength > 0)) + PackageList = ConvertWCharNToUtf8Alloc(PackageListW, PackageListLength, NULL); } if (PackageList) @@ -1032,12 +1025,15 @@ static const SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameW(const static const SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameA(const SEC_CHAR* Name) { - int status; SEC_WCHAR* NameW = NULL; - const SecurityFunctionTableW* table; - status = ConvertToUnicode(CP_UTF8, 0, Name, -1, &NameW, 0); + const SecurityFunctionTableW* table = NULL; - if (status <= 0) + if (!Name) + return NULL; + + NameW = ConvertUtf8ToWCharAlloc(Name, NULL); + + if (!NameW) return NULL; table = sspi_GetSecurityFunctionTableWByNameW(NameW); diff --git a/winpr/libwinpr/sspi/test/TestNTLM.c b/winpr/libwinpr/sspi/test/TestNTLM.c index b0b5c54a2..7c7f0336a 100644 --- a/winpr/libwinpr/sspi/test/TestNTLM.c +++ b/winpr/libwinpr/sspi/test/TestNTLM.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -99,7 +100,10 @@ typedef struct static int test_ntlm_client_init(TEST_NTLM_CLIENT* ntlm, const char* user, const char* domain, const char* password) { - SECURITY_STATUS status; + SECURITY_STATUS status = SEC_E_INTERNAL_ERROR; + + WINPR_ASSERT(ntlm); + SecInvalidateHandle(&(ntlm->context)); ntlm->table = InitSecurityInterfaceEx(TEST_SSPI_INTERFACE); sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password); @@ -204,8 +208,9 @@ static void test_ntlm_client_uninit(TEST_NTLM_CLIENT* ntlm) static int test_ntlm_client_authenticate(TEST_NTLM_CLIENT* ntlm) { - SECURITY_STATUS status; + SECURITY_STATUS status = SEC_E_INTERNAL_ERROR; + WINPR_ASSERT(ntlm); if (ntlm->outputBuffer[0].pvBuffer) { free(ntlm->outputBuffer[0].pvBuffer); @@ -265,8 +270,7 @@ static int test_ntlm_client_authenticate(TEST_NTLM_CLIENT* ntlm) static TEST_NTLM_CLIENT* test_ntlm_client_new(void) { - TEST_NTLM_CLIENT* ntlm; - ntlm = (TEST_NTLM_CLIENT*)calloc(1, sizeof(TEST_NTLM_CLIENT)); + TEST_NTLM_CLIENT* ntlm = (TEST_NTLM_CLIENT*)calloc(1, sizeof(TEST_NTLM_CLIENT)); if (!ntlm) return NULL; @@ -308,7 +312,10 @@ typedef struct static int test_ntlm_server_init(TEST_NTLM_SERVER* ntlm) { - SECURITY_STATUS status; + SECURITY_STATUS status = SEC_E_INTERNAL_ERROR; + + WINPR_ASSERT(ntlm); + ntlm->UseNtlmV2Hash = TRUE; SecInvalidateHandle(&(ntlm->context)); ntlm->table = InitSecurityInterfaceEx(TEST_SSPI_INTERFACE); @@ -375,7 +382,10 @@ static void test_ntlm_server_uninit(TEST_NTLM_SERVER* ntlm) static int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm) { - SECURITY_STATUS status; + SECURITY_STATUS status = SEC_E_INTERNAL_ERROR; + + WINPR_ASSERT(ntlm); + ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION; ntlm->inputBufferDesc.cBuffers = 1; ntlm->inputBufferDesc.pBuffers = ntlm->inputBuffer; @@ -431,8 +441,7 @@ static int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm) static TEST_NTLM_SERVER* test_ntlm_server_new(void) { - TEST_NTLM_SERVER* ntlm; - ntlm = (TEST_NTLM_SERVER*)calloc(1, sizeof(TEST_NTLM_SERVER)); + TEST_NTLM_SERVER* ntlm = (TEST_NTLM_SERVER*)calloc(1, sizeof(TEST_NTLM_SERVER)); if (!ntlm) return NULL; diff --git a/winpr/libwinpr/sspicli/sspicli.c b/winpr/libwinpr/sspicli/sspicli.c index 66d2e0347..12b54568d 100644 --- a/winpr/libwinpr/sspicli/sspicli.c +++ b/winpr/libwinpr/sspicli/sspicli.c @@ -250,7 +250,6 @@ BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize) { - int res; BOOL rc = FALSE; char* name; @@ -264,7 +263,7 @@ BOOL GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG if (!GetUserNameExA(NameFormat, name, nSize)) goto fail; - res = ConvertToUnicode(CP_UTF8, 0, name, -1, &lpNameBuffer, *nSize); + const SSIZE_T res = ConvertUtf8ToWChar(name, lpNameBuffer, *nSize); if (res < 0) goto fail; diff --git a/winpr/libwinpr/synch/event.c b/winpr/libwinpr/synch/event.c index 28bbae3bf..41322d917 100644 --- a/winpr/libwinpr/synch/event.c +++ b/winpr/libwinpr/synch/event.c @@ -274,9 +274,8 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, if (lpName) { - int rc = ConvertFromUnicode(CP_UTF8, 0, lpName, -1, &name, 0, NULL, NULL); - - if (rc < 0) + name = ConvertWCharToUtf8Alloc(lpName, NULL); + if (!name) return NULL; } diff --git a/winpr/libwinpr/synch/mutex.c b/winpr/libwinpr/synch/mutex.c index 747e864af..bce9aa98c 100644 --- a/winpr/libwinpr/synch/mutex.c +++ b/winpr/libwinpr/synch/mutex.c @@ -124,9 +124,8 @@ HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, if (lpName) { - int rc = ConvertFromUnicode(CP_UTF8, 0, lpName, -1, &name, 0, NULL, NULL); - - if (rc < 0) + name = ConvertWCharToUtf8Alloc(lpName, NULL); + if (!name) return NULL; } diff --git a/winpr/libwinpr/synch/timer.c b/winpr/libwinpr/synch/timer.c index ff5b873a8..c3a37ab3e 100644 --- a/winpr/libwinpr/synch/timer.c +++ b/winpr/libwinpr/synch/timer.c @@ -377,13 +377,15 @@ fail: HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCWSTR lpTimerName) { - int rc; HANDLE handle; LPSTR name = NULL; - rc = ConvertFromUnicode(CP_UTF8, 0, lpTimerName, -1, &name, 0, NULL, NULL); - if (rc < 0) - return NULL; + if (lpTimerName) + { + name = ConvertWCharToUtf8Alloc(lpTimerName, NULL); + if (!name) + return NULL; + } handle = CreateWaitableTimerA(lpTimerAttributes, bManualReset, name); free(name); @@ -405,13 +407,15 @@ HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCSTR lp HANDLE CreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes, LPCWSTR lpTimerName, DWORD dwFlags, DWORD dwDesiredAccess) { - int rc; HANDLE handle; LPSTR name = NULL; - rc = ConvertFromUnicode(CP_UTF8, 0, lpTimerName, -1, &name, 0, NULL, NULL); - if (rc < 0) - return NULL; + if (lpTimerName) + { + name = ConvertWCharToUtf8Alloc(lpTimerName, NULL); + if (!name) + return NULL; + } handle = CreateWaitableTimerExA(lpTimerAttributes, name, dwFlags, dwDesiredAccess); free(name); diff --git a/winpr/libwinpr/sysinfo/sysinfo.c b/winpr/libwinpr/sysinfo/sysinfo.c index 758cff565..c674dd1ec 100644 --- a/winpr/libwinpr/sysinfo/sysinfo.c +++ b/winpr/libwinpr/sysinfo/sysinfo.c @@ -402,7 +402,11 @@ BOOL GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize) rc = GetComputerNameA(buffer, lpnSize); if (rc && (*lpnSize > 0)) - ConvertToUnicode(CP_UTF8, 0, buffer, (int)*lpnSize, &lpBuffer, (int)*lpnSize); + { + const SSIZE_T res = ConvertUtf8NToWChar(buffer, *lpnSize, lpBuffer, *lpnSize); + rc = res > 0; + } + free(buffer); return rc; @@ -520,7 +524,10 @@ BOOL GetComputerNameExW(COMPUTER_NAME_FORMAT NameType, LPWSTR lpBuffer, LPDWORD rc = GetComputerNameExA(NameType, lpABuffer, lpnSize); if (rc && (*lpnSize > 0)) - ConvertToUnicode(CP_UTF8, 0, lpABuffer, *lpnSize, &lpBuffer, *lpnSize); + { + const SSIZE_T res = ConvertUtf8NToWChar(lpABuffer, *lpnSize, lpBuffer, *lpnSize); + rc = res > 0; + } free(lpABuffer); return rc; diff --git a/winpr/libwinpr/timezone/timezone.c b/winpr/libwinpr/timezone/timezone.c index 04f59bcfa..d130d739f 100644 --- a/winpr/libwinpr/timezone/timezone.c +++ b/winpr/libwinpr/timezone/timezone.c @@ -417,27 +417,23 @@ DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation) if (dtz != NULL) { - int status; + const TIME_ZONE_INFORMATION empty = { 0 }; + WLog_DBG(TAG, "tz: Bias=%" PRId32 " sn='%s' dln='%s'", dtz->Bias, dtz->StandardName, dtz->DaylightName); - tz->Bias = dtz->Bias; - tz->StandardBias = 0; - tz->DaylightBias = 0; - ZeroMemory(tz->StandardName, sizeof(tz->StandardName)); - ZeroMemory(tz->DaylightName, sizeof(tz->DaylightName)); - status = MultiByteToWideChar(CP_UTF8, 0, dtz->StandardName, -1, tz->StandardName, - sizeof(tz->StandardName) / sizeof(WCHAR) - 1); - if (status < 1) + *tz = empty; + tz->Bias = dtz->Bias; + + if (ConvertUtf8ToWChar(dtz->StandardName, tz->StandardName, ARRAYSIZE(tz->StandardName)) < + 0) { WLog_ERR(TAG, "StandardName conversion failed - using default"); goto out_error; } - status = MultiByteToWideChar(CP_UTF8, 0, dtz->DaylightName, -1, tz->DaylightName, - sizeof(tz->DaylightName) / sizeof(WCHAR) - 1); - - if (status < 1) + if (ConvertUtf8ToWChar(dtz->DaylightName, tz->DaylightName, ARRAYSIZE(tz->DaylightName)) < + 0) { WLog_ERR(TAG, "DaylightName conversion failed - using default"); goto out_error; diff --git a/winpr/libwinpr/utils/ntlm.c b/winpr/libwinpr/utils/ntlm.c index 4aee62351..f682f0555 100644 --- a/winpr/libwinpr/utils/ntlm.c +++ b/winpr/libwinpr/utils/ntlm.c @@ -47,17 +47,16 @@ BOOL NTOWFv1A(LPSTR Password, UINT32 PasswordLength, BYTE* NtHash) { LPWSTR PasswordW = NULL; BOOL result = FALSE; + size_t pwdCharLength = 0; if (!NtHash) return FALSE; - if (!(PasswordW = (LPWSTR)calloc(PasswordLength, 2))) + PasswordW = ConvertUtf8NToWCharAlloc(Password, PasswordLength, &pwdCharLength); + if (!PasswordW) return FALSE; - WINPR_ASSERT(PasswordLength <= INT_MAX); - MultiByteToWideChar(CP_ACP, 0, Password, (int)PasswordLength, PasswordW, (int)PasswordLength); - - if (!NTOWFv1W(PasswordW, PasswordLength * 2, NtHash)) + if (!NTOWFv1W(PasswordW, pwdCharLength * sizeof(WCHAR), NtHash)) goto out_fail; result = TRUE; @@ -94,26 +93,22 @@ BOOL NTOWFv2A(LPSTR Password, UINT32 PasswordLength, LPSTR User, UINT32 UserLeng LPWSTR DomainW = NULL; LPWSTR PasswordW = NULL; BOOL result = FALSE; + size_t userCharLength = 0; + size_t domainCharLength = 0; + size_t pwdCharLength = 0; if (!NtHash) return FALSE; - UserW = (LPWSTR)calloc(UserLength, 2); - DomainW = (LPWSTR)calloc(DomainLength, 2); - PasswordW = (LPWSTR)calloc(PasswordLength, 2); + UserW = ConvertUtf8NToWCharAlloc(User, UserLength, &userCharLength); + DomainW = ConvertUtf8NToWCharAlloc(Domain, DomainLength, &domainCharLength); + PasswordW = ConvertUtf8NToWCharAlloc(Password, PasswordLength, &pwdCharLength); if (!UserW || !DomainW || !PasswordW) goto out_fail; - WINPR_ASSERT(UserLength <= INT_MAX); - WINPR_ASSERT(DomainLength <= INT_MAX); - WINPR_ASSERT(PasswordLength <= INT_MAX); - MultiByteToWideChar(CP_ACP, 0, User, (int)UserLength, UserW, (int)UserLength); - MultiByteToWideChar(CP_ACP, 0, Domain, (int)DomainLength, DomainW, (int)DomainLength); - MultiByteToWideChar(CP_ACP, 0, Password, (int)PasswordLength, PasswordW, (int)PasswordLength); - - if (!NTOWFv2W(PasswordW, PasswordLength * 2, UserW, UserLength * 2, DomainW, DomainLength * 2, - NtHash)) + if (!NTOWFv2W(PasswordW, pwdCharLength * sizeof(WCHAR), UserW, userCharLength * sizeof(WCHAR), + DomainW, domainCharLength * sizeof(WCHAR), NtHash)) goto out_fail; result = TRUE; @@ -163,22 +158,19 @@ BOOL NTOWFv2FromHashA(BYTE* NtHashV1, LPSTR User, UINT32 UserLength, LPSTR Domai LPWSTR UserW = NULL; LPWSTR DomainW = NULL; BOOL result = FALSE; - + size_t userCharLength = 0; + size_t domainCharLength = 0; if (!NtHash) return FALSE; - UserW = (LPWSTR)calloc(UserLength, 2); - DomainW = (LPWSTR)calloc(DomainLength, 2); + UserW = ConvertUtf8NToWCharAlloc(User, UserLength, &userCharLength); + DomainW = ConvertUtf8NToWCharAlloc(Domain, DomainLength, &domainCharLength); if (!UserW || !DomainW) goto out_fail; - WINPR_ASSERT(UserLength <= INT_MAX); - WINPR_ASSERT(DomainLength <= INT_MAX); - MultiByteToWideChar(CP_ACP, 0, User, (int)UserLength, UserW, (int)UserLength); - MultiByteToWideChar(CP_ACP, 0, Domain, (int)DomainLength, DomainW, (int)DomainLength); - - if (!NTOWFv2FromHashW(NtHashV1, UserW, UserLength * 2, DomainW, DomainLength * 2, NtHash)) + if (!NTOWFv2FromHashW(NtHashV1, UserW, userCharLength * sizeof(WCHAR), DomainW, + domainCharLength * sizeof(WCHAR), NtHash)) goto out_fail; result = TRUE; diff --git a/winpr/libwinpr/utils/sam.c b/winpr/libwinpr/utils/sam.c index 7d1695fd8..b0f3f76eb 100644 --- a/winpr/libwinpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -331,21 +331,19 @@ fail: WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPCWSTR User, UINT32 UserLength, LPCWSTR Domain, UINT32 DomainLength) { - int rc; WINPR_SAM_ENTRY* entry = NULL; char* utfUser = NULL; char* utfDomain = NULL; - const UINT32 UserCharLength = UserLength / sizeof(WCHAR); - const UINT32 DomainCharLength = DomainLength / sizeof(WCHAR); - if ((UserCharLength > INT_MAX) || (DomainCharLength > INT_MAX)) + size_t userCharLen = 0; + size_t domainCharLen = 0; + + utfUser = ConvertWCharNToUtf8Alloc(User, UserLength / sizeof(WCHAR), &userCharLen); + if (!utfUser) goto fail; - rc = ConvertFromUnicode(CP_UTF8, 0, User, (int)UserCharLength, &utfUser, 0, NULL, NULL); - if ((rc < 0) || ((size_t)rc != UserCharLength)) + utfDomain = ConvertWCharNToUtf8Alloc(Domain, DomainLength / sizeof(WCHAR), &domainCharLen); + if (!utfDomain) goto fail; - rc = ConvertFromUnicode(CP_UTF8, 0, Domain, (int)DomainCharLength, &utfDomain, 0, NULL, NULL); - if ((rc < 0) || ((size_t)rc != DomainCharLength)) - goto fail; - entry = SamLookupUserA(sam, utfUser, UserCharLength, utfDomain, DomainCharLength); + entry = SamLookupUserA(sam, utfUser, userCharLen, utfDomain, domainCharLen); fail: free(utfUser); free(utfDomain);