static int process_ob_ipinfo(void *in_msg, void *out_msg, int op) { struct hv_kvp_msg *in = in_msg; struct hv_kvp_ip_msg *out = out_msg; int len; switch (op) { case KVP_OP_GET_IP_INFO: /* * Transform all parameters into utf16 encoding. */ len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr, strlen((char *)in->body.kvp_ip_val.ip_addr), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.ip_addr, MAX_IP_ADDR_SIZE); if (len < 0) return len; len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net, strlen((char *)in->body.kvp_ip_val.sub_net), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.sub_net, MAX_IP_ADDR_SIZE); if (len < 0) return len; len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way, strlen((char *)in->body.kvp_ip_val.gate_way), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.gate_way, MAX_GATEWAY_SIZE); if (len < 0) return len; len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr, strlen((char *)in->body.kvp_ip_val.dns_addr), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.dns_addr, MAX_IP_ADDR_SIZE); if (len < 0) return len; len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id, strlen((char *)in->body.kvp_ip_val.adapter_id), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.adapter_id, MAX_IP_ADDR_SIZE); if (len < 0) return len; out->kvp_ip_val.dhcp_enabled = in->body.kvp_ip_val.dhcp_enabled; out->kvp_ip_val.addr_family = in->body.kvp_ip_val.addr_family; } return 0; }
static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings) { struct usb_string_descriptor *s_desc; u32 string_length; /* Serial string: */ s_desc = (struct usb_string_descriptor *)strings->serial; utf8s_to_utf16s(DBC_STRING_SERIAL, strlen(DBC_STRING_SERIAL), UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData, DBC_MAX_STRING_LENGTH); s_desc->bLength = (strlen(DBC_STRING_SERIAL) + 1) * 2; s_desc->bDescriptorType = USB_DT_STRING; string_length = s_desc->bLength; string_length <<= 8; /* Product string: */ s_desc = (struct usb_string_descriptor *)strings->product; utf8s_to_utf16s(DBC_STRING_PRODUCT, strlen(DBC_STRING_PRODUCT), UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData, DBC_MAX_STRING_LENGTH); s_desc->bLength = (strlen(DBC_STRING_PRODUCT) + 1) * 2; s_desc->bDescriptorType = USB_DT_STRING; string_length += s_desc->bLength; string_length <<= 8; /* Manufacture string: */ s_desc = (struct usb_string_descriptor *)strings->manufacturer; utf8s_to_utf16s(DBC_STRING_MANUFACTURER, strlen(DBC_STRING_MANUFACTURER), UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData, DBC_MAX_STRING_LENGTH); s_desc->bLength = (strlen(DBC_STRING_MANUFACTURER) + 1) * 2; s_desc->bDescriptorType = USB_DT_STRING; string_length += s_desc->bLength; string_length <<= 8; /* String0: */ strings->string0[0] = 4; strings->string0[1] = USB_DT_STRING; strings->string0[2] = 0x09; strings->string0[3] = 0x04; string_length += 4; return string_length; }
void asusnls_u2c(char *name) { #ifdef CONFIG_NLS char *codepage; char *xfrstr; struct nls_table *nls; int ret, len; strcpy(codebuf, name); codepage=codebuf+strlen(NLS_NVRAM_U2C); if((xfrstr=strchr(codepage, '_'))) { *xfrstr=NULL; xfrstr++; nls=load_nls(codepage); if(!nls) { printk("NLS table is null!!\n"); } else { len = 0; //if (ret=utf8_mbstowcs(unibuf, xfrstr, strlen(xfrstr))) if (ret=utf8s_to_utf16s(xfrstr, strlen(xfrstr), unibuf)) { int i; for (i = 0; (i < ret) && unibuf[i]; i++) { int charlen; charlen = nls->uni2char(unibuf[i], &name[len], NLS_MAX_CHARSET_SIZE); if (charlen > 0) { len += charlen; } else { strcpy(name, ""); unload_nls(nls); return; } } name[len] = 0; } unload_nls(nls); if(!len) { printk("can not xfr from utf8 to %s\n", codepage); strcpy(name, ""); } } } else { strcpy(name, ""); } #endif }
/* * NAME: cifs_strtoUTF16() * * FUNCTION: Convert character string to unicode string * */ int cifs_strtoUTF16(__le16 *to, const char *from, int len, const struct nls_table *codepage) { int charlen; int i; wchar_t wchar_to; /* needed to quiet sparse */ /* special case for utf8 to handle no plane0 chars */ if (!strcmp(codepage->charset, "utf8")) { /* * convert utf8 -> utf16, we assume we have enough space * as caller should have assumed conversion does not overflow * in destination len is length in wchar_t units (16bits) */ i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN, (wchar_t *) to, len); /* if success terminate and exit */ if (i >= 0) goto success; /* * if fails fall back to UCS encoding as this * function should not return negative values * currently can fail only if source contains * invalid encoded characters */ } for (i = 0; len && *from; i++, from += charlen, len -= charlen) { charlen = codepage->char2uni(from, len, &wchar_to); if (charlen < 1) { cifs_dbg(VFS, "strtoUTF16: char2uni of 0x%x returned %d\n", *from, charlen); /* A question mark */ wchar_to = 0x003f; charlen = 1; } put_unaligned_le16(wchar_to, &to[i]); } success: put_unaligned_le16(0, &to[i]); return i; }
/* * NAME: cifs_strtoUTF16() * * FUNCTION: Convert character string to unicode string * */ int cifs_strtoUTF16(__le16 *to, const char *from, int len, const struct nls_table *codepage) { int charlen; int i; wchar_t wchar_to; /* needed to quiet sparse */ if (!strcmp(codepage->charset, "utf8")) { i = utf8s_to_utf16s(from, len, UTF16_LITTLE_ENDIAN, (wchar_t *) to, len); if (i >= 0) goto success; } for (i = 0; len && *from; i++, from += charlen, len -= charlen) { charlen = codepage->char2uni(from, len, &wchar_to); if (charlen < 1) { cERROR(1, "strtoUTF16: char2uni of 0x%x returned %d", *from, charlen); /* A question mark */ wchar_to = 0x003f; charlen = 1; } put_unaligned_le16(wchar_to, &to[i]); } success: put_unaligned_le16(0, &to[i]); return i; }
static void kvp_respond_to_host(struct hv_kvp_msg *msg_to_host, int error) { struct hv_kvp_msg *kvp_msg; struct hv_kvp_exchg_msg_value *kvp_data; char *key_name; char *value; struct icmsg_hdr *icmsghdrp; int keylen = 0; int valuelen = 0; u32 buf_len; struct vmbus_channel *channel; u64 req_id; int ret; /* * If a transaction is not active; log and return. */ if (!kvp_transaction.active) { /* * This is a spurious call! */ pr_warn("KVP: Transaction not active\n"); return; } /* * Copy the global state for completing the transaction. Note that * only one transaction can be active at a time. */ buf_len = kvp_transaction.recv_len; channel = kvp_transaction.recv_channel; req_id = kvp_transaction.recv_req_id; kvp_transaction.active = false; icmsghdrp = (struct icmsg_hdr *) &recv_buffer[sizeof(struct vmbuspipe_hdr)]; if (channel->onchannel_callback == NULL) /* * We have raced with util driver being unloaded; * silently return. */ return; icmsghdrp->status = error; /* * If the error parameter is set, terminate the host's enumeration * on this pool. */ if (error) { /* * Something failed or we have timedout; * terminate the current host-side iteration. */ goto response_done; } kvp_msg = (struct hv_kvp_msg *) &recv_buffer[sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; switch (kvp_transaction.kvp_msg->kvp_hdr.operation) { case KVP_OP_GET_IP_INFO: ret = process_ob_ipinfo(msg_to_host, (struct hv_kvp_ip_msg *)kvp_msg, KVP_OP_GET_IP_INFO); if (ret < 0) icmsghdrp->status = HV_E_FAIL; goto response_done; case KVP_OP_SET_IP_INFO: goto response_done; case KVP_OP_GET: kvp_data = &kvp_msg->body.kvp_get.data; goto copy_value; case KVP_OP_SET: case KVP_OP_DELETE: goto response_done; default: break; } kvp_data = &kvp_msg->body.kvp_enum_data.data; key_name = msg_to_host->body.kvp_enum_data.data.key; /* * The windows host expects the key/value pair to be encoded * in utf16. Ensure that the key/value size reported to the host * will be less than or equal to the MAX size (including the * terminating character). */ keylen = utf8s_to_utf16s(key_name, strlen(key_name), UTF16_HOST_ENDIAN, (wchar_t *) kvp_data->key, (HV_KVP_EXCHANGE_MAX_KEY_SIZE / 2) - 2); kvp_data->key_size = 2*(keylen + 1); /* utf16 encoding */ copy_value: value = msg_to_host->body.kvp_enum_data.data.value; valuelen = utf8s_to_utf16s(value, strlen(value), UTF16_HOST_ENDIAN, (wchar_t *) kvp_data->value, (HV_KVP_EXCHANGE_MAX_VALUE_SIZE / 2) - 2); kvp_data->value_size = 2*(valuelen + 1); /* utf16 encoding */ /* * If the utf8s to utf16s conversion failed; notify host * of the error. */ if ((keylen < 0) || (valuelen < 0)) icmsghdrp->status = HV_E_FAIL; kvp_data->value_type = REG_SZ; /* all our values are strings */ response_done: icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, VM_PKT_DATA_INBAND, 0); poll_channel(channel); }
/* * Convert 16 bit Unicode pathname to wire format from string in current code * page. Conversion may involve remapping up the six characters that are * only legal in POSIX-like OS (if they are present in the string). Path * names are little endian 16 bit Unicode on the wire */ int cifsConvertToUTF16(__le16 *target, const char *source, int srclen, const struct nls_table *cp, int map_chars) { int i, charlen; int j = 0; char src_char; __le16 dst_char; wchar_t tmp; wchar_t *wchar_to; /* UTF-16 */ int ret; unicode_t u; if (map_chars == NO_MAP_UNI_RSVD) return cifs_strtoUTF16(target, source, PATH_MAX, cp); wchar_to = kzalloc(6, GFP_KERNEL); for (i = 0; i < srclen; j++) { src_char = source[i]; charlen = 1; /* check if end of string */ if (src_char == 0) goto ctoUTF16_out; /* see if we must remap this char */ if (map_chars == SFU_MAP_UNI_RSVD) dst_char = convert_to_sfu_char(src_char); else if (map_chars == SFM_MAP_UNI_RSVD) { bool end_of_string; if (i == srclen - 1) end_of_string = true; else end_of_string = false; dst_char = convert_to_sfm_char(src_char, end_of_string); } else dst_char = 0; /* * FIXME: We can not handle remapping backslash (UNI_SLASH) * until all the calls to build_path_from_dentry are modified, * as they use backslash as separator. */ if (dst_char == 0) { charlen = cp->char2uni(source + i, srclen - i, &tmp); dst_char = cpu_to_le16(tmp); /* * if no match, use question mark, which at least in * some cases serves as wild card */ if (charlen > 0) goto ctoUTF16; /* convert SURROGATE_PAIR */ if (strcmp(cp->charset, "utf8") || !wchar_to) goto unknown; if (*(source + i) & 0x80) { charlen = utf8_to_utf32(source + i, 6, &u); if (charlen < 0) goto unknown; } else goto unknown; ret = utf8s_to_utf16s(source + i, charlen, UTF16_LITTLE_ENDIAN, wchar_to, 6); if (ret < 0) goto unknown; i += charlen; dst_char = cpu_to_le16(*wchar_to); if (charlen <= 3) /* 1-3bytes UTF-8 to 2bytes UTF-16 */ put_unaligned(dst_char, &target[j]); else if (charlen == 4) { /* 4bytes UTF-8(surrogate pair) to 4bytes UTF-16 * 7-8bytes UTF-8(IVS) divided to 2 UTF-16 * (charlen=3+4 or 4+4) */ put_unaligned(dst_char, &target[j]); dst_char = cpu_to_le16(*(wchar_to + 1)); j++; put_unaligned(dst_char, &target[j]); } else if (charlen >= 5) { /* 5-6bytes UTF-8 to 6bytes UTF-16 */ put_unaligned(dst_char, &target[j]); dst_char = cpu_to_le16(*(wchar_to + 1)); j++; put_unaligned(dst_char, &target[j]); dst_char = cpu_to_le16(*(wchar_to + 2)); j++; put_unaligned(dst_char, &target[j]); } continue; unknown: dst_char = cpu_to_le16(0x003f); charlen = 1; } ctoUTF16: /* * character may take more than one byte in the source string, * but will take exactly two bytes in the target string */ i += charlen; put_unaligned(dst_char, &target[j]); } ctoUTF16_out: put_unaligned(0, &target[j]); /* Null terminate target unicode string */ kfree(wchar_to); return j; }
static void kvp_respond_to_host(char *key, char *value, int error) { struct hv_kvp_msg *kvp_msg; struct hv_kvp_msg_enumerate *kvp_data; char *key_name; struct icmsg_hdr *icmsghdrp; int keylen, valuelen; u32 buf_len; struct vmbus_channel *channel; u64 req_id; /* * If a transaction is not active; log and return. */ if (!kvp_transaction.active) { /* * This is a spurious call! */ pr_warn("KVP: Transaction not active\n"); return; } /* * Copy the global state for completing the transaction. Note that * only one transaction can be active at a time. */ buf_len = kvp_transaction.recv_len; channel = kvp_transaction.recv_channel; req_id = kvp_transaction.recv_req_id; kvp_transaction.active = false; if (channel->onchannel_callback == NULL) /* * We have raced with util driver being unloaded; * silently return. */ return; icmsghdrp = (struct icmsg_hdr *) &recv_buffer[sizeof(struct vmbuspipe_hdr)]; kvp_msg = (struct hv_kvp_msg *) &recv_buffer[sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; kvp_data = &kvp_msg->kvp_data; key_name = key; /* * If the error parameter is set, terminate the host's enumeration. */ if (error) { /* * We don't support this index or the we have timedout; * terminate the host-side iteration by returning an error. */ icmsghdrp->status = HV_E_FAIL; goto response_done; } /* * The windows host expects the key/value pair to be encoded * in utf16. */ keylen = utf8s_to_utf16s(key_name, strlen(key_name), (wchar_t *)kvp_data->data.key); kvp_data->data.key_size = 2*(keylen + 1); /* utf16 encoding */ valuelen = utf8s_to_utf16s(value, strlen(value), (wchar_t *)kvp_data->data.value); kvp_data->data.value_size = 2*(valuelen + 1); /* utf16 encoding */ kvp_data->data.value_type = REG_SZ; /* all our values are strings */ icmsghdrp->status = HV_S_OK; response_done: icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; vmbus_sendpacket(channel, recv_buffer, buf_len, req_id, VM_PKT_DATA_INBAND, 0); }
void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, u8 *p_cstring, s32 *p_lossy) { int i, j, lossy = FALSE; u8 *end_of_name; u8 upname[MAX_NAME_LENGTH * 2]; u16 *uniname = p_uniname->name; struct nls_table *nls = EXFAT_SB(sb)->nls_io; /* strip all trailing spaces */ end_of_name = p_cstring + strlen((char *) p_cstring); while (*(--end_of_name) == ' ') { if (end_of_name < p_cstring) break; } *(++end_of_name) = '\0'; if (strcmp((char *) p_cstring, ".") && strcmp((char *) p_cstring, "..")) { /* strip all trailing periods */ while (*(--end_of_name) == '.') { if (end_of_name < p_cstring) break; } *(++end_of_name) = '\0'; } if (*p_cstring == '\0') lossy = TRUE; if (nls == NULL) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0) i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH, uniname); #else i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH, UTF16_HOST_ENDIAN, uniname, MAX_NAME_LENGTH); #endif for (j = 0; j < i; j++) SET16_A(upname + j * 2, nls_upper(sb, uniname[j])); uniname[i] = '\0'; } else { i = j = 0; while (j < (MAX_NAME_LENGTH-1)) { if (*(p_cstring+i) == '\0') break; i += convert_ch_to_uni(nls, uniname, (u8 *)(p_cstring+i), &lossy); if ((*uniname < 0x0020) || nls_wstrchr(bad_uni_chars, *uniname)) lossy = TRUE; SET16_A(upname + j * 2, nls_upper(sb, *uniname)); uniname++; j++; } if (*(p_cstring+i) != '\0') lossy = TRUE; *uniname = (u16) '\0'; } p_uniname->name_len = j; p_uniname->name_hash = calc_checksum_2byte((void *) upname, j<<1, 0, CS_DEFAULT); if (p_lossy != NULL) *p_lossy = lossy; } /* end of nls_cstring_to_uniname */
static int process_ob_ipinfo(void *in_msg, void *out_msg, int op) { struct hv_kvp_msg *in = in_msg; struct hv_kvp_ip_msg *out = out_msg; int len; switch (op) { case KVP_OP_GET_IP_INFO: /* * Transform all parameters into utf16 encoding. */ #if defined(RHEL_RELEASE_UPDATE_CODE) && \ (RHEL_RELEASE_UPDATE_CODE < RHEL_RELEASE_UPDATE_VERSION(6, 4, 358, 18)) len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr, strlen((char *)in->body.kvp_ip_val.ip_addr), (wchar_t *)out->kvp_ip_val.ip_addr); #else len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.ip_addr, strlen((char *)in->body.kvp_ip_val.ip_addr), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.ip_addr, MAX_IP_ADDR_SIZE); #endif if (len < 0) return len; #if defined(RHEL_RELEASE_UPDATE_CODE) && \ (RHEL_RELEASE_UPDATE_CODE < RHEL_RELEASE_UPDATE_VERSION(6, 4, 358, 18)) len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net, strlen((char *)in->body.kvp_ip_val.sub_net), (wchar_t *)out->kvp_ip_val.sub_net); #else len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.sub_net, strlen((char *)in->body.kvp_ip_val.sub_net), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.sub_net, MAX_IP_ADDR_SIZE); #endif if (len < 0) return len; #if defined(RHEL_RELEASE_UPDATE_CODE) && \ (RHEL_RELEASE_UPDATE_CODE < RHEL_RELEASE_UPDATE_VERSION(6, 4, 358, 18)) len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way, strlen((char *)in->body.kvp_ip_val.gate_way), (wchar_t *)out->kvp_ip_val.gate_way); #else len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.gate_way, strlen((char *)in->body.kvp_ip_val.gate_way), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.gate_way, MAX_GATEWAY_SIZE); #endif if (len < 0) return len; #if defined(RHEL_RELEASE_UPDATE_CODE) && \ (RHEL_RELEASE_UPDATE_CODE < RHEL_RELEASE_UPDATE_VERSION(6, 4, 358, 18)) len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr, strlen((char *)in->body.kvp_ip_val.dns_addr), (wchar_t *)out->kvp_ip_val.dns_addr); #else len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.dns_addr, strlen((char *)in->body.kvp_ip_val.dns_addr), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.dns_addr, MAX_IP_ADDR_SIZE); #endif if (len < 0) return len; #if defined(RHEL_RELEASE_UPDATE_CODE) && \ (RHEL_RELEASE_UPDATE_CODE < RHEL_RELEASE_UPDATE_VERSION(6, 4, 358, 18)) len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id, strlen((char *)in->body.kvp_ip_val.adapter_id), (wchar_t *)out->kvp_ip_val.adapter_id); #else len = utf8s_to_utf16s((char *)in->body.kvp_ip_val.adapter_id, strlen((char *)in->body.kvp_ip_val.adapter_id), UTF16_HOST_ENDIAN, (wchar_t *)out->kvp_ip_val.adapter_id, MAX_IP_ADDR_SIZE); #endif if (len < 0) return len; out->kvp_ip_val.dhcp_enabled = in->body.kvp_ip_val.dhcp_enabled; out->kvp_ip_val.addr_family = in->body.kvp_ip_val.addr_family; } return 0; }