static inline LRESULT HexEdit_Char (HEXEDIT_INFO *infoPtr, TCHAR ch) { INT nCaretBytePos = infoPtr->nCaretPos/2; assert(nCaretBytePos >= 0); /* backspace is special */ if (ch == '\b') { if (infoPtr->nCaretPos == 0) return 0; /* if at end of byte then delete the whole byte */ if (infoPtr->bFocusHex && (infoPtr->nCaretPos % 2 == 0)) { memmove(infoPtr->pData + nCaretBytePos - 1, infoPtr->pData + nCaretBytePos, infoPtr->cbData - nCaretBytePos); infoPtr->cbData--; infoPtr->nCaretPos -= 2; /* backtrack two nibble */ } else /* blank upper nibble */ { infoPtr->pData[nCaretBytePos] &= 0x0f; infoPtr->nCaretPos--; /* backtrack one nibble */ } } else { if (infoPtr->bFocusHex && hexchar_to_byte(ch) == (BYTE)-1) { MessageBeep(MB_ICONWARNING); return 0; } if ((infoPtr->bInsert && (infoPtr->nCaretPos % 2 == 0)) || (nCaretBytePos >= infoPtr->cbData)) { /* make room for another byte */ infoPtr->cbData++; infoPtr->pData = HeapReAlloc(GetProcessHeap(), 0, infoPtr->pData, infoPtr->cbData + 1); if (!infoPtr->pData) return 0; /* move everything after caret up one byte */ memmove(infoPtr->pData + nCaretBytePos + 1, infoPtr->pData + nCaretBytePos, infoPtr->cbData - nCaretBytePos); /* zero new byte */ infoPtr->pData[nCaretBytePos] = 0x0; } /* overwrite a byte */ assert(nCaretBytePos < infoPtr->cbData); if (infoPtr->bFocusHex) { BYTE orig_byte = infoPtr->pData[nCaretBytePos]; BYTE digit = hexchar_to_byte(ch); if (infoPtr->nCaretPos % 2) /* set low nibble */ infoPtr->pData[nCaretBytePos] = (orig_byte & 0xf0) | digit; else /* set high nibble */ infoPtr->pData[nCaretBytePos] = (orig_byte & 0x0f) | digit << 4; infoPtr->nCaretPos++; /* advance one nibble */ } else { infoPtr->pData[nCaretBytePos] = (BYTE)ch; infoPtr->nCaretPos += 2; /* advance two nibbles */ } } HexEdit_UpdateScrollbars(infoPtr); InvalidateRect(infoPtr->hwndSelf, NULL, TRUE); HexEdit_UpdateCaret(infoPtr); HexEdit_EnsureVisible(infoPtr, infoPtr->nCaretPos); return 0; }
/** * Take two hex characters and merge them into a single byte. * * @param[in] high high order byte. * @param[in] low low order byte. * @returns high and low mixed into a single byte. */ static inline char hex_to_int(char high, char low) { return hexchar_to_byte(high) << 4 | hexchar_to_byte(low); }
static LPBYTE get_regdata(LPWSTR data, DWORD reg_type, WCHAR separator, DWORD *reg_count) { LPBYTE out_data = NULL; *reg_count = 0; switch (reg_type) { case REG_NONE: case REG_SZ: case REG_EXPAND_SZ: { *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); lstrcpyW((LPWSTR)out_data,data); break; } case REG_DWORD: /* case REG_DWORD_LITTLE_ENDIAN: */ case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */ { LPWSTR rest; DWORD val; val = strtoulW(data, &rest, (data[1] == 'x') ? 16 : 10); if (*rest || data[0] == '-') { output_message(STRING_MISSING_INTEGER); break; } *reg_count = sizeof(DWORD); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); ((LPDWORD)out_data)[0] = val; break; } case REG_BINARY: { BYTE hex0, hex1; int i = 0, destByteIndex = 0, datalen = lstrlenW(data); *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE); out_data = HeapAlloc(GetProcessHeap(), 0, *reg_count); if(datalen % 2) { hex1 = hexchar_to_byte(data[i++]); if(hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = hex1; } for(;i + 1 < datalen;i += 2) { hex0 = hexchar_to_byte(data[i]); hex1 = hexchar_to_byte(data[i + 1]); if(hex0 == 0xFF || hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = (hex0 << 4) | hex1; } break; no_hex_data: /* cleanup, print error */ HeapFree(GetProcessHeap(), 0, out_data); output_message(STRING_MISSING_HEXDATA); out_data = NULL; break; } case REG_MULTI_SZ: /* FIXME: Needs handling */ default: output_message(STRING_UNHANDLED_TYPE, reg_type, data); } return out_data; }
static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DWORD *reg_count) { static const WCHAR empty; LPBYTE out_data = NULL; *reg_count = 0; if (!data) data = ∅ switch (reg_type) { case REG_NONE: case REG_SZ: case REG_EXPAND_SZ: { *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); lstrcpyW((LPWSTR)out_data,data); break; } case REG_DWORD: /* case REG_DWORD_LITTLE_ENDIAN: */ case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */ { LPWSTR rest; DWORD val; val = strtoulW(data, &rest, (tolowerW(data[1]) == 'x') ? 16 : 10); if (*rest || data[0] == '-' || (val == ~0u && errno == ERANGE)) { output_message(STRING_MISSING_INTEGER); break; } *reg_count = sizeof(DWORD); out_data = HeapAlloc(GetProcessHeap(),0,*reg_count); ((LPDWORD)out_data)[0] = val; break; } case REG_BINARY: { BYTE hex0, hex1; int i = 0, destByteIndex = 0, datalen = lstrlenW(data); *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE); out_data = HeapAlloc(GetProcessHeap(), 0, *reg_count); if(datalen % 2) { hex1 = hexchar_to_byte(data[i++]); if(hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = hex1; } for(;i + 1 < datalen;i += 2) { hex0 = hexchar_to_byte(data[i]); hex1 = hexchar_to_byte(data[i + 1]); if(hex0 == 0xFF || hex1 == 0xFF) goto no_hex_data; out_data[destByteIndex++] = (hex0 << 4) | hex1; } break; no_hex_data: /* cleanup, print error */ HeapFree(GetProcessHeap(), 0, out_data); output_message(STRING_MISSING_HEXDATA); out_data = NULL; break; } case REG_MULTI_SZ: { int i, destindex, len = strlenW(data); WCHAR *buffer = HeapAlloc(GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR)); for (i = 0, destindex = 0; i < len; i++, destindex++) { if (!separator && data[i] == '\\' && data[i + 1] == '0') { buffer[destindex] = 0; i++; } else if (data[i] == separator) buffer[destindex] = 0; else buffer[destindex] = data[i]; if (destindex && !buffer[destindex - 1] && (!buffer[destindex] || destindex == 1)) { HeapFree(GetProcessHeap(), 0, buffer); output_message(STRING_INVALID_STRING); return NULL; } } buffer[destindex] = 0; if (destindex && buffer[destindex - 1]) buffer[++destindex] = 0; *reg_count = (destindex + 1) * sizeof(WCHAR); return (BYTE *)buffer; } default: output_message(STRING_UNHANDLED_TYPE, reg_type, data); } return out_data; }