static BOOL freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, const WCHAR* name, const WCHAR* value, int index) { int length; char* nameA; char* valueA; BOOL ret = TRUE; length = (int) _wcslen(name); nameA = (char*) malloc(length + 1); if (!nameA) return FALSE; WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); nameA[length] = '\0'; length = (int) _wcslen(value); valueA = (char*) malloc(length + 1); if (!valueA) { free(nameA); return FALSE; } WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); valueA[length] = '\0'; if (freerdp_client_rdp_file_set_string(file, nameA, valueA, index) == -1) ret = FALSE; free(nameA); free(valueA); return ret; }
BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext) { int status; UINT32 count; BYTE* buffer; UINT32 length; CONTEXT_HANDLE* handle; rdpRpc* rpc = tsg->rpc; count = _wcslen(tsg->Hostname) + 1; #ifdef WITH_DEBUG_TSG DEBUG_WARN( "ResourceName:\n"); winpr_HexDump((BYTE*) tsg->Hostname, (count - 1) * 2); DEBUG_WARN( "\n"); #endif length = 60 + (count * 2); buffer = (BYTE*) malloc(length); if (!buffer) return FALSE; /* TunnelContext */ handle = (CONTEXT_HANDLE*) tunnelContext; CopyMemory(&buffer[0], &handle->ContextType, 4); /* ContextType */ CopyMemory(&buffer[4], handle->ContextUuid, 16); /* ContextUuid */ /* TSENDPOINTINFO */ *((UINT32*) &buffer[20]) = 0x00020000; /* ResourceNamePtr */ *((UINT32*) &buffer[24]) = 0x00000001; /* NumResourceNames */ *((UINT32*) &buffer[28]) = 0x00000000; /* AlternateResourceNamesPtr */ *((UINT16*) &buffer[32]) = 0x0000; /* NumAlternateResourceNames */ *((UINT16*) &buffer[34]) = 0x0000; /* Pad (2 bytes) */ /* Port (4 bytes) */ *((UINT16*) &buffer[36]) = 0x0003; /* ProtocolId (RDP = 3) */ *((UINT16*) &buffer[38]) = tsg->Port; /* PortNumber (0xD3D = 3389) */ *((UINT32*) &buffer[40]) = 0x00000001; /* NumResourceNames */ *((UINT32*) &buffer[44]) = 0x00020004; /* ResourceNamePtr */ *((UINT32*) &buffer[48]) = count; /* MaxCount */ *((UINT32*) &buffer[52]) = 0; /* Offset */ *((UINT32*) &buffer[56]) = count; /* ActualCount */ CopyMemory(&buffer[60], tsg->Hostname, count * 2); /* Array */ status = rpc_write(rpc, buffer, length, TsProxyCreateChannelOpnum); if (status <= 0) return FALSE; free(buffer); return TRUE; }
int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR* lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) { int status; BOOL allocate = FALSE; if (!lpWideCharStr) return 0; if (!lpMultiByteStr) return 0; if (cchWideChar == -1) cchWideChar = (int)(_wcslen(lpWideCharStr) + 1); if (cbMultiByte == 0) { cbMultiByte = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, NULL, NULL); allocate = TRUE; } if (cbMultiByte < 1) return 0; if (!(*lpMultiByteStr)) allocate = TRUE; if (allocate) { *lpMultiByteStr = (LPSTR) calloc(1, cbMultiByte + 1); if (!(*lpMultiByteStr)) { //SetLastError(ERROR_INSUFFICIENT_BUFFER); return 0; } } status = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, *lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); if ((status != cbMultiByte) && allocate) { status = 0; } if ((status <= 0) && allocate) { free(*lpMultiByteStr); *lpMultiByteStr = NULL; } return status; }
void freerdp_client_parse_rdp_file_string_unicode(rdpFile* file, WCHAR* name, WCHAR* value) { int length; char* nameA; char* valueA; length = _wcslen(name); nameA = (char*) malloc(length + 1); WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); nameA[length] = '\0'; length = _wcslen(value); valueA = (char*) malloc(length + 1); WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); valueA[length] = '\0'; if (!freerdp_client_rdp_file_set_string(file, nameA, valueA)) free(valueA); free(nameA); }
void freerdp_client_parse_rdp_file_integer_unicode(rdpFile* file, WCHAR* name, WCHAR* value, int index) { int length; int ivalue; char* nameA; char* valueA; length = (int) _wcslen(name); nameA = (char*) malloc(length + 1); WideCharToMultiByte(CP_UTF8, 0, name, length, nameA, length, NULL, NULL); nameA[length] = '\0'; length = (int) _wcslen(value); valueA = (char*) malloc(length + 1); WideCharToMultiByte(CP_UTF8, 0, value, length, valueA, length, NULL, NULL); valueA[length] = '\0'; ivalue = atoi(valueA); freerdp_client_rdp_file_set_integer(file, nameA, ivalue, index); free(nameA); free(valueA); }
int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) { int length; BYTE* targetStart; const WCHAR* sourceStart; ConversionResult result; /* If cchWideChar is 0, the function fails */ if (cchWideChar == 0) return 0; /* If cchWideChar is -1, the string is null-terminated */ if (cchWideChar == -1) cchWideChar = _wcslen(lpWideCharStr) + 1; /* * if cbMultiByte is 0, the function returns the required buffer size * in bytes for lpMultiByteStr and makes no use of the output parameter itself. */ if (cbMultiByte == 0) { sourceStart = (WCHAR*) lpWideCharStr; targetStart = (BYTE*) NULL; result = ConvertUTF16toUTF8(&sourceStart, &sourceStart[cchWideChar], &targetStart, NULL, strictConversion); length = targetStart - ((BYTE*) NULL); cbMultiByte = length; } else { sourceStart = (WCHAR*) lpWideCharStr; targetStart = (BYTE*) lpMultiByteStr; result = ConvertUTF16toUTF8(&sourceStart, &sourceStart[cchWideChar], &targetStart, &targetStart[cbMultiByte], strictConversion); length = targetStart - ((BYTE*) lpMultiByteStr); cbMultiByte = length; } return cbMultiByte; }
VOID _RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString) { DestinationString->Buffer = (PWSTR) SourceString; if (!SourceString) { DestinationString->Length = 0; DestinationString->MaximumLength = 0; } else { USHORT length = (USHORT) _wcslen(SourceString); DestinationString->Length = length * 2; DestinationString->MaximumLength = (length + 1) * 2; } }
int ntlm_SetContextServicePrincipalNameW(NTLM_CONTEXT* context, LPWSTR ServicePrincipalName) { if (!ServicePrincipalName) { context->ServicePrincipalName.Buffer = NULL; context->ServicePrincipalName.Length = 0; return 1; } context->ServicePrincipalName.Length = _wcslen(ServicePrincipalName) * 2; context->ServicePrincipalName.Buffer = (PWSTR) malloc(context->ServicePrincipalName.Length + 2); if (!context->ServicePrincipalName.Buffer) return -1; CopyMemory(context->ServicePrincipalName.Buffer, ServicePrincipalName, context->ServicePrincipalName.Length + 2); return 1; }
void wf_add_system_menu(wfContext* wfc) { HMENU hMenu = GetSystemMenu(wfc->hwnd, FALSE); MENUITEMINFO item_info; ZeroMemory(&item_info, sizeof(MENUITEMINFO)); item_info.fMask = MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_DATA; item_info.cbSize = sizeof(MENUITEMINFO); item_info.wID = SYSCOMMAND_ID_SMARTSIZING; item_info.fType = MFT_STRING; item_info.dwTypeData = _wcsdup(_T("Smart sizing")); item_info.cch = (UINT) _wcslen(_T("Smart sizing")); item_info.dwItemData = (ULONG_PTR) wfc; InsertMenuItem(hMenu, 6, TRUE, &item_info); if (wfc->instance->settings->SmartSizing) { CheckMenuItem(hMenu, SYSCOMMAND_ID_SMARTSIZING, MF_CHECKED); } }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { UINT32 index; UINT32 dataLen; UINT32 position; BOOL asciiNames; int formatNameLength; char* szFormatName; WCHAR* wszFormatName; CLIPRDR_FORMAT* formats = NULL; CLIPRDR_FORMAT_LIST formatList; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; UINT error = CHANNEL_RC_OK; dataLen = header->dataLen; asciiNames = (header->msgFlags & CB_ASCII_NAMES) ? TRUE : FALSE; formatList.msgType = CB_FORMAT_LIST; formatList.msgFlags = header->msgFlags; formatList.dataLen = header->dataLen; index = 0; formatList.numFormats = 0; position = Stream_GetPosition(s); if (!header->dataLen) { /* empty format list */ formatList.formats = NULL; formatList.numFormats = 0; } else if (!cliprdr->useLongFormatNames) { formatList.numFormats = (dataLen / 36); if ((formatList.numFormats * 36) != dataLen) { WLog_ERR(TAG, "Invalid short format list length: %d", dataLen); return ERROR_INVALID_PARAMETER; } if (formatList.numFormats) formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; formats[index].formatName = NULL; if (asciiNames) { szFormatName = (char*) Stream_Pointer(s); if (szFormatName[0]) { formats[index].formatName = (char*) malloc(32 + 1); CopyMemory(formats[index].formatName, szFormatName, 32); formats[index].formatName[32] = '\0'; } } else { wszFormatName = (WCHAR*) Stream_Pointer(s); if (wszFormatName[0]) { ConvertFromUnicode(CP_UTF8, 0, wszFormatName, 16, &(formats[index].formatName), 0, NULL, NULL); } } Stream_Seek(s, 32); dataLen -= 32; index++; } } else { while (dataLen) { Stream_Seek(s, 4); /* formatId (4 bytes) */ dataLen -= 4; wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) formatNameLength = 0; else formatNameLength = _wcslen(wszFormatName); Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); formatList.numFormats++; } dataLen = formatList.dataLen; Stream_SetPosition(s, position); if (formatList.numFormats) formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; formats[index].formatName = NULL; wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) formatNameLength = 0; else formatNameLength = _wcslen(wszFormatName); if (formatNameLength) { ConvertFromUnicode(CP_UTF8, 0, wszFormatName, -1, &(formats[index].formatName), 0, NULL, NULL); } Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); index++; } } WLog_DBG(TAG, "ClientFormatList: numFormats: %d", formatList.numFormats); IFCALLRET(context->ClientFormatList, error, context, &formatList); if (error) WLog_ERR(TAG, "ClientFormatList failed with error %lu!", error); for (index = 0; index < formatList.numFormats; index++) { free(formatList.formats[index].formatName); } free(formatList.formats); return error; }
size_t _wslen(const wchar_t *s) { return (_wcslen(s)); }
BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, BYTE* buffer, size_t size) { int length; WCHAR* line; WCHAR* type; WCHAR* context; WCHAR *d1, *d2; WCHAR *beg, *end; WCHAR *name, *value; line = wcstok_s((WCHAR*) buffer, CR_LF_STR_W, &context); while (line != NULL) { length = _wcslen(line); if (length > 1) { beg = line; end = &line[length - 1]; if (beg[0] == '/') { /* FreeRDP option */ freerdp_client_parse_rdp_file_option_unicode(file, line); goto next_line; } d1 = _wcschr(line, ':'); if (!d1) goto next_line; /* not first delimiter */ type = &d1[1]; d2 = _wcschr(type, ':'); if (!d2) goto next_line; /* no second delimiter */ if ((d2 - d1) != 2) goto next_line; /* improper type length */ if (d2 == end) goto next_line; /* no value */ *d1 = 0; *d2 = 0; name = beg; value = &d2[1]; if (*type == 'i') { /* integer type */ freerdp_client_parse_rdp_file_integer_unicode(file, name, value); } else if (*type == 's') { /* string type */ freerdp_client_parse_rdp_file_string_unicode(file, name, value); } else if (*type == 'b') { /* binary type */ } } next_line: line = wcstok_s(NULL, CR_LF_STR_W, &context); } return TRUE; }
int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) { #if !defined(WITH_ICU) int length; const WCHAR* sourceStart; ConversionResult result; BYTE* targetStart; #else char* targetStart; #endif /* If cchWideChar is 0, the function fails */ if ((cchWideChar == 0) || (cchWideChar < -1)) return 0; /* If cchWideChar is -1, the string is null-terminated */ if (cchWideChar == -1) { size_t len = _wcslen(lpWideCharStr); if (len >= INT32_MAX) return 0; cchWideChar = (int)len + 1; } /* * if cbMultiByte is 0, the function returns the required buffer size * in bytes for lpMultiByteStr and makes no use of the output parameter itself. */ #if defined(WITH_ICU) { UErrorCode error; int32_t targetLength; int32_t targetCapacity; switch (CodePage) { case CP_ACP: case CP_UTF8: break; default: WLog_ERR(TAG, "Unsupported encoding %u", CodePage); return 0; } targetStart = lpMultiByteStr; targetCapacity = cbMultiByte; error = U_ZERO_ERROR; if (cbMultiByte == 0) { u_strToUTF8(NULL, 0, &targetLength, lpWideCharStr, cchWideChar, &error); cbMultiByte = targetLength; } else { u_strToUTF8(targetStart, targetCapacity, &targetLength, lpWideCharStr, cchWideChar, &error); cbMultiByte = U_SUCCESS(error) ? targetLength : 0; } } #else if (cbMultiByte == 0) { sourceStart = (WCHAR*) lpWideCharStr; targetStart = (BYTE*) NULL; result = ConvertUTF16toUTF8(&sourceStart, &sourceStart[cchWideChar], &targetStart, NULL, strictConversion); length = targetStart - ((BYTE*) NULL); } else { sourceStart = (WCHAR*) lpWideCharStr; targetStart = (BYTE*) lpMultiByteStr; result = ConvertUTF16toUTF8(&sourceStart, &sourceStart[cchWideChar], &targetStart, &targetStart[cbMultiByte], strictConversion); length = targetStart - ((BYTE*) lpMultiByteStr); } cbMultiByte = (result == conversionOK) ? length : 0; #endif return cbMultiByte; }
static BOOL freerdp_client_parse_rdp_file_buffer_unicode(rdpFile* file, const BYTE* buffer, size_t size) { BOOL rc = FALSE; int index; int length; const WCHAR* line; WCHAR* type; WCHAR* context; WCHAR* d1, *d2; const WCHAR* name, *value; WCHAR* copy = (WCHAR*)calloc(1, size + sizeof(WCHAR)); if (!copy) return FALSE; memcpy(copy, buffer, size); index = 0; line = wcstok_s(copy, CR_LF_STR_W, &context); while (line != NULL) { length = (int) _wcslen(line); if (length > 1) { const WCHAR* beg = line; if (!freerdp_client_parse_rdp_file_add_line_unicode(file, line, index)) goto fail; if (beg[0] == '/') { /* FreeRDP option */ freerdp_client_parse_rdp_file_option_unicode(file, line, index); goto next_line; } d1 = _wcschr(line, ':'); if (!d1) goto next_line; /* not first delimiter */ type = &d1[1]; d2 = _wcschr(type, ':'); if (!d2) goto next_line; /* no second delimiter */ if ((d2 - d1) != 2) goto next_line; /* improper type length */ *d1 = 0; *d2 = 0; name = beg; value = &d2[1]; if (*type == 'i') { /* integer type */ if (!freerdp_client_parse_rdp_file_integer_unicode(file, name, value, index)) goto fail; } else if (*type == 's') { /* string type */ if (!freerdp_client_parse_rdp_file_string_unicode(file, name, value, index)) goto fail; } else if (*type == 'b') { /* binary type */ } } next_line: line = wcstok_s(NULL, CR_LF_STR_W, &context); index++; } rc = TRUE; fail: free(copy); return rc; }
int TestString(int argc, char* argv[]) { WCHAR* p; size_t pos; size_t length; WCHAR* context; /* _wcslen */ length = _wcslen(testStringW); if (length != testStringW_Length) { printf("_wcslen error: length mismatch: Actual: %lu, Expected: %lu\n", (unsigned long) length, (unsigned long) testStringW_Length); return -1; } /* _wcschr */ p = _wcschr(testStringW, 'r'); pos = (p - testStringW); if (pos != 11) { printf("_wcschr error: position mismatch: Actual: %lu, Expected: %u\n", (unsigned long)pos, 11); return -1; } p = _wcschr(&testStringW[pos + 1], 'r'); pos = (p - testStringW); if (pos != 29) { printf("_wcschr error: position mismatch: Actual: %lu, Expected: %u\n", (unsigned long)pos, 29); return -1; } p = _wcschr(&testStringW[pos + 1], 'r'); if (p != NULL) { printf("_wcschr error: return value mismatch: Actual: 0x%08lX, Expected: 0x%08lX\n", (unsigned long) p, (unsigned long) NULL); return -1; } /* wcstok_s */ p = wcstok_s(testTokensW, testDelimiter, &context); if (memcmp(p, testToken1W, sizeof(testToken1W)) != 0) { printf("wcstok_s error: token #1 mismatch\n"); return -1; } p = wcstok_s(NULL, testDelimiter, &context); if (memcmp(p, testToken2W, sizeof(testToken2W)) != 0) { printf("wcstok_s error: token #2 mismatch\n"); return -1; } p = wcstok_s(NULL, testDelimiter, &context); if (memcmp(p, testToken3W, sizeof(testToken3W)) != 0) { printf("wcstok_s error: token #3 mismatch\n"); return -1; } p = wcstok_s(NULL, testDelimiter, &context); if (p != NULL) { printf("wcstok_s error: return value is not NULL\n"); return -1; } return 0; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) { UINT32 index; UINT32 position; BOOL asciiNames; int formatNameLength; char* szFormatName; WCHAR* wszFormatName; CLIPRDR_FORMAT* formats = NULL; CLIPRDR_FORMAT_LIST formatList; CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); UINT error = CHANNEL_RC_OK; if (!context->custom) { WLog_ERR(TAG, "context->custom not set!"); return ERROR_INTERNAL_ERROR; } asciiNames = (msgFlags & CB_ASCII_NAMES) ? TRUE : FALSE; formatList.msgType = CB_FORMAT_LIST; formatList.msgFlags = msgFlags; formatList.dataLen = dataLen; index = 0; formatList.numFormats = 0; position = Stream_GetPosition(s); if (!formatList.dataLen) { /* empty format list */ formatList.formats = NULL; formatList.numFormats = 0; } else if (!cliprdr->useLongFormatNames) { formatList.numFormats = (dataLen / 36); if ((formatList.numFormats * 36) != dataLen) { WLog_ERR(TAG, "Invalid short format list length: %d", dataLen); return ERROR_INTERNAL_ERROR; } if (formatList.numFormats) formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; formats[index].formatName = NULL; if (asciiNames) { szFormatName = (char*) Stream_Pointer(s); if (szFormatName[0]) { formats[index].formatName = (char*) malloc(32 + 1); if (!formats[index].formatName) { WLog_ERR(TAG, "calloc failed!"); error = CHANNEL_RC_NO_MEMORY; goto error_out; } CopyMemory(formats[index].formatName, szFormatName, 32); formats[index].formatName[32] = '\0'; } } else { wszFormatName = (WCHAR*) Stream_Pointer(s); if (wszFormatName[0]) { ConvertFromUnicode(CP_UTF8, 0, wszFormatName, 16, &(formats[index].formatName), 0, NULL, NULL); } } Stream_Seek(s, 32); dataLen -= 32; index++; } } else { while (dataLen) { Stream_Seek(s, 4); /* formatId (4 bytes) */ dataLen -= 4; wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) formatNameLength = 0; else formatNameLength = _wcslen(wszFormatName); Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); formatList.numFormats++; } dataLen = formatList.dataLen; Stream_SetPosition(s, position); if (formatList.numFormats) formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; formats[index].formatName = NULL; wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) formatNameLength = 0; else formatNameLength = _wcslen(wszFormatName); if (formatNameLength) { ConvertFromUnicode(CP_UTF8, 0, wszFormatName, -1, &(formats[index].formatName), 0, NULL, NULL); } Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); index++; } } WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatList: numFormats: %d", formatList.numFormats); if (context->ServerFormatList) { if ((error = context->ServerFormatList(context, &formatList))) WLog_ERR(TAG, "ServerFormatList failed with error %d", error); } error_out: if (formats) { for (index = 0; index < formatList.numFormats; index++) { free(formats[index].formatName); } free(formats); } return error; }
void cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen, UINT16 msgFlags) { CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr); if (context->custom) { UINT32 index; int formatNameLength; CLIPRDR_FORMAT* formats; CLIPRDR_FORMAT_LIST formatList; formatList.msgType = CB_FORMAT_LIST; formatList.msgFlags = msgFlags; formatList.dataLen = dataLen; formatList.cFormats = 0; while (dataLen) { Stream_Seek(s, 4); /* formatId */ dataLen -= 4; formatNameLength = _wcslen((WCHAR*) Stream_Pointer(s)); Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); formatList.cFormats++; } index = 0; dataLen = formatList.dataLen; Stream_Rewind(s, dataLen); formats = (CLIPRDR_FORMAT*) malloc(sizeof(CLIPRDR_FORMAT) * formatList.cFormats); formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId */ dataLen -= 4; formats[index].formatName = NULL; formatNameLength = _wcslen((WCHAR*) Stream_Pointer(s)); if (formatNameLength) { formatNameLength = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), -1, &(formats[index].formatName), 0, NULL, NULL); Stream_Seek(s, formatNameLength * 2); dataLen -= (formatNameLength * 2); } else { Stream_Seek(s, 2); dataLen -= 2; } index++; } if (context->ServerFormatList) context->ServerFormatList(context, &formatList); for (index = 0; index < formatList.cFormats; index++) free(formats[index].formatName); free(formats); } else { int i; UINT32 format; BOOL supported; CLIPRDR_FORMAT_NAME* format_name; RDP_CB_FORMAT_LIST_EVENT* cb_event; cb_event = (RDP_CB_FORMAT_LIST_EVENT*) freerdp_event_new(CliprdrChannel_Class, CliprdrChannel_FormatList, NULL, NULL); if (dataLen > 0) { cb_event->raw_format_data = (BYTE*) malloc(dataLen); memcpy(cb_event->raw_format_data, Stream_Pointer(s), dataLen); cb_event->raw_format_data_size = dataLen; cb_event->raw_format_unicode = (msgFlags & CB_ASCII_NAMES) ? FALSE : TRUE; } if (cliprdr->use_long_format_names) cliprdr_process_long_format_names(cliprdr, s, dataLen, msgFlags); else cliprdr_process_short_format_names(cliprdr, s, dataLen, msgFlags); if (cliprdr->num_format_names > 0) cb_event->formats = (UINT32*) malloc(sizeof(UINT32) * cliprdr->num_format_names); cb_event->num_formats = 0; for (i = 0; i < cliprdr->num_format_names; i++) { supported = TRUE; format_name = &cliprdr->format_names[i]; format = format_name->id; switch (format) { case CB_FORMAT_TEXT: case CB_FORMAT_DIB: case CB_FORMAT_UNICODETEXT: break; default: if (format_name->length > 0) { DEBUG_CLIPRDR("format: %s", format_name->name); if (strcmp(format_name->name, "HTML Format") == 0) { format = CB_FORMAT_HTML; break; } if (strcmp(format_name->name, "PNG") == 0) { format = CB_FORMAT_PNG; break; } if (strcmp(format_name->name, "JFIF") == 0) { format = CB_FORMAT_JPEG; break; } if (strcmp(format_name->name, "GIF") == 0) { format = CB_FORMAT_GIF; break; } } else { supported = FALSE; } break; } if (supported) cb_event->formats[cb_event->num_formats++] = format; if (format_name->length > 0) free(format_name->name); } free(cliprdr->format_names); cliprdr->format_names = NULL; cliprdr->num_format_names = 0; svc_plugin_send_event((rdpSvcPlugin*) cliprdr, (wMessage*) cb_event); cliprdr_send_format_list_response(cliprdr); } }
int convert_utf16_to_utf8(BYTE* lpWideCharStr, BYTE* expected_lpMultiByteStr, int expected_cbMultiByte) { int length; int cchWideChar; int cbMultiByte; LPSTR lpMultiByteStr = NULL; cchWideChar = _wcslen((WCHAR*) lpWideCharStr); cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) lpWideCharStr, -1, NULL, 0, NULL, NULL); printf("WideCharToMultiByte Input UTF16 String:\n"); string_hexdump(lpWideCharStr, (cchWideChar + 1) * sizeof(WCHAR)); printf("WideCharToMultiByte required cbMultiByte: %d\n", cbMultiByte); if (cbMultiByte != expected_cbMultiByte) { printf("WideCharToMultiByte unexpected cbMultiByte: actual: %d expected: %d\n", cbMultiByte, expected_cbMultiByte); return -1; } lpMultiByteStr = (LPSTR) malloc(cbMultiByte); if (!lpMultiByteStr) { printf("WideCharToMultiByte: unable to allocate memory for test\n"); return -1; } lpMultiByteStr[cbMultiByte - 1] = 0xFF; /* should be overwritten if null terminator is inserted properly */ length = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) lpWideCharStr, cchWideChar + 1, lpMultiByteStr, cbMultiByte, NULL, NULL); printf("WideCharToMultiByte converted length (BYTE): %d\n", length); if (!length) { DWORD error = GetLastError(); printf("WideCharToMultiByte error: 0x%08X\n", error); return -1; } if (length != expected_cbMultiByte) { printf("WideCharToMultiByte unexpected converted length (BYTE): actual: %d expected: %d\n", length, expected_cbMultiByte); return -1; } if (strcmp(lpMultiByteStr, (char*) expected_lpMultiByteStr) != 0) { printf("WideCharToMultiByte unexpected string:\n"); printf("UTF16 String:\n"); string_hexdump((BYTE*) lpWideCharStr, (cchWideChar + 1) * sizeof(WCHAR)); printf("UTF8 String (actual):\n"); string_hexdump((BYTE*) lpMultiByteStr, cbMultiByte); printf("UTF8 String (expected):\n"); string_hexdump((BYTE*) expected_lpMultiByteStr, expected_cbMultiByte); return -1; } printf("WideCharToMultiByte Output UTF8 String:\n"); string_hexdump((BYTE*) lpMultiByteStr, cbMultiByte); printf("\n"); free(lpMultiByteStr); return length; }
BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, PTUNNEL_CONTEXT_HANDLE_NOSERIALIZE tunnelContext) { UINT32 pad; int status; BYTE* buffer; UINT32 count; UINT32 length; UINT32 offset; CONTEXT_HANDLE* handle; rdpRpc* rpc = tsg->rpc; count = _wcslen(tsg->MachineName) + 1; offset = 64 + (count * 2); rpc_offset_align(&offset, 4); offset += 4; length = offset; buffer = (BYTE*) malloc(length); /* TunnelContext */ handle = (CONTEXT_HANDLE*) tunnelContext; CopyMemory(&buffer[0], &handle->ContextType, 4); /* ContextType */ CopyMemory(&buffer[4], handle->ContextUuid, 16); /* ContextUuid */ /* 4-byte alignment */ *((UINT32*) &buffer[20]) = TSG_PACKET_TYPE_QUARREQUEST; /* PacketId */ *((UINT32*) &buffer[24]) = TSG_PACKET_TYPE_QUARREQUEST; /* SwitchValue */ *((UINT32*) &buffer[28]) = 0x00020000; /* PacketQuarRequestPtr */ *((UINT32*) &buffer[32]) = 0x00000000; /* Flags */ *((UINT32*) &buffer[36]) = 0x00020004; /* MachineNamePtr */ *((UINT32*) &buffer[40]) = count; /* NameLength */ *((UINT32*) &buffer[44]) = 0x00020008; /* DataPtr */ *((UINT32*) &buffer[48]) = 0; /* DataLength */ /* MachineName */ *((UINT32*) &buffer[52]) = count; /* MaxCount */ *((UINT32*) &buffer[56]) = 0; /* Offset */ *((UINT32*) &buffer[60]) = count; /* ActualCount */ CopyMemory(&buffer[64], tsg->MachineName, count * 2); /* Array */ offset = 64 + (count * 2); /* 4-byte alignment */ pad = rpc_offset_align(&offset, 4); ZeroMemory(&buffer[offset - pad], pad); *((UINT32*) &buffer[offset]) = 0x00000000; /* MaxCount */ offset += 4; status = rpc_write(rpc, buffer, length, TsProxyAuthorizeTunnelOpnum); if (status <= 0) return FALSE; free(buffer); return TRUE; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT cliprdr_server_receive_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header) { UINT32 index; UINT32 dataLen; UINT32 position; BOOL asciiNames; int formatNameLength; char* szFormatName; WCHAR* wszFormatName; CLIPRDR_FORMAT* formats = NULL; CLIPRDR_FORMAT_LIST formatList; UINT error = CHANNEL_RC_OK; dataLen = header->dataLen; asciiNames = (header->msgFlags & CB_ASCII_NAMES) ? TRUE : FALSE; formatList.msgType = CB_FORMAT_LIST; formatList.msgFlags = header->msgFlags; formatList.dataLen = header->dataLen; index = 0; formatList.numFormats = 0; position = Stream_GetPosition(s); if (!header->dataLen) { /* empty format list */ formatList.formats = NULL; formatList.numFormats = 0; } else if (!context->useLongFormatNames) { formatList.numFormats = (dataLen / 36); if ((formatList.numFormats * 36) != dataLen) { WLog_ERR(TAG, "Invalid short format list length: %d", dataLen); return ERROR_INVALID_PARAMETER; } if (formatList.numFormats) formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; formats[index].formatName = NULL; /* According to MS-RDPECLIP 2.2.3.1.1.1 formatName is "a 32-byte block containing * the *null-terminated* name assigned to the Clipboard Format: (32 ASCII 8 characters * or 16 Unicode characters)" * However, both Windows RDSH and mstsc violate this specs as seen in the following * example of a transferred short format name string: [R.i.c.h. .T.e.x.t. .F.o.r.m.a.t.] * These are 16 unicode charaters - *without* terminating null ! */ if (asciiNames) { szFormatName = (char*) Stream_Pointer(s); if (szFormatName[0]) { /* ensure null termination */ formats[index].formatName = (char*) malloc(32 + 1); CopyMemory(formats[index].formatName, szFormatName, 32); formats[index].formatName[32] = '\0'; } } else { wszFormatName = (WCHAR*) Stream_Pointer(s); 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_INVALID_DATA; goto out; } } } Stream_Seek(s, 32); dataLen -= 32; index++; } } else { while (dataLen) { Stream_Seek(s, 4); /* formatId (4 bytes) */ dataLen -= 4; wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) formatNameLength = 0; else formatNameLength = _wcslen(wszFormatName); Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); formatList.numFormats++; } dataLen = formatList.dataLen; Stream_SetPosition(s, position); if (formatList.numFormats) formats = (CLIPRDR_FORMAT*) calloc(formatList.numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) { WLog_ERR(TAG, "calloc failed!"); return CHANNEL_RC_NO_MEMORY; } formatList.formats = formats; while (dataLen) { Stream_Read_UINT32(s, formats[index].formatId); /* formatId (4 bytes) */ dataLen -= 4; formats[index].formatName = NULL; wszFormatName = (WCHAR*) Stream_Pointer(s); if (!wszFormatName[0]) formatNameLength = 0; else formatNameLength = _wcslen(wszFormatName); if (formatNameLength) { if (ConvertFromUnicode(CP_UTF8, 0, wszFormatName, -1, &(formats[index].formatName), 0, NULL, NULL) < 1) { WLog_ERR(TAG, "failed to convert long clipboard format name"); error = ERROR_INVALID_DATA; goto out; } } Stream_Seek(s, (formatNameLength + 1) * 2); dataLen -= ((formatNameLength + 1) * 2); index++; } } WLog_DBG(TAG, "ClientFormatList: numFormats: %d", formatList.numFormats); IFCALLRET(context->ClientFormatList, error, context, &formatList); if (error) WLog_ERR(TAG, "ClientFormatList failed with error %lu!", error); out: for (index = 0; index < formatList.numFormats; index++) { free(formatList.formats[index].formatName); } free(formatList.formats); return error; }