BOOL RtlMBMessageWParamCharToWCS(DWORD msg, WPARAM *pWParam) { DWORD dwUni; NTSTATUS Status; // FE_SB (RtlMBMessageWParamCharToWCS) BOOL bWmCrIrDbcsChar = FALSE; WORD wAnsi = LOWORD(*pWParam); // end FE_SB (RtlMBMessageWParamCharToWCS) WORD CodePage = THREAD_CODEPAGE(); /* * Only these messages have CHARs: others are passed through */ switch(msg) { // FE_SB (RtlMBMessageWParamCharToWCS) case WM_CHAR: // // WM_CHAR's wParam format for WM_IME_REPORT:IR_DBCSCHAR // if (IS_DBCS_ENABLED() && (*pWParam & WMCR_IR_DBCSCHAR)) { // // Mark this message is sent as IR_DBCSCHAR format. // bWmCrIrDbcsChar = TRUE; } // // Fall through.... // #ifdef FE_IME case WM_IME_CHAR: case WM_IME_COMPOSITION: // // We need to re-align for Unicode convertsion.. // WM_CHAR/WM_IME_CHAR/WM_IME_COMPOSITION's wParam format : // // ReAlign IR_DBCS char format to regular sequence. // // From: // // HIWORD(wParam) = 0; // HIBYTE(LOWORD(wParam)) = DBCS LeadingByte. // LOBYTE(LOWORD(wParan)) = DBCS TrailingByte or SBCS character. // // To: // HIWORD(wParam) = 0; // HIBYTE(LOWORD(wParam)) = DBCS TrailingByte. // LOBYTE(LOWORD(wParam)) = DBCS LeadingByte or SBCS character. // if (IS_DBCS_ENABLED()) { *pWParam = MAKE_WPARAM_DBCSCHAR(wAnsi); } #endif // // Fall through... // // end FE_SB (RtlMBMessageWParamCharToWCS) case WM_CHARTOITEM: case EM_SETPASSWORDCHAR: case WM_DEADCHAR: case WM_SYSCHAR: case WM_SYSDEADCHAR: case WM_MENUCHAR: dwUni = 0; if (IS_ACP(CodePage)) { Status = RtlMultiByteToUnicodeN((LPWSTR)&dwUni, sizeof(dwUni), NULL, (LPSTR)pWParam, 2 * sizeof(CHAR)); if (!NT_SUCCESS(Status)) return FALSE; } else { int cwch; #ifdef _USERK_ cwch = EngMultiByteToWideChar(CodePage, (LPWSTR)&dwUni, sizeof(dwUni), (LPSTR)pWParam, 2); #else cwch = MultiByteToWideChar(CodePage, 0, (LPSTR)pWParam, 2, (LPWSTR)&dwUni, sizeof(dwUni) / sizeof(WCHAR)); #endif // _USERK_ // KdPrint(("0x%02x -> 0x%04x (%d)\n", *pWParam, dwUni, CodePage)); if (cwch == 0) { return FALSE; } } // FE_SB (RtlMBMessageWParamCharToWCS) // // if this character is sent for WM_IME_REPORT:IR_DBCSCHAR, we mark it. // if (bWmCrIrDbcsChar) dwUni |= WMCR_IR_DBCSCHAR; // else FE_SB (RtlMBMessageWParamCharToWCS) #if DBG if ((dwUni == 0) || (dwUni > 0xFF)) { RIPMSG1(RIP_VERBOSE, "msgA -> msgW: wchar = 0x%lX\n", dwUni); } #endif // end FE_SB *pWParam = dwUni; break; } return TRUE; }
HFF TestFdLoadFontFileTE ( ULONG cFiles, ULONG *piFile, PVOID *ppvView, ULONG *pcjView, ULONG ulLangId ) { FONTFILE *pff = NULL; ULONG cjIFI; BYTE *pjView0 = (BYTE *)ppvView[0]; BYTE *pjView1 = (BYTE *)ppvView[1]; ULONG cjView0 = pcjView[0]; ULONG cjView1 = pcjView[1]; ulLangId; if (cFiles != 2) return 0; // first file contains facename only cjIFI = ALIGN4(sizeof(IFIMETRICS) + (cjView0 + 1) * sizeof(WCHAR)); pff = (FONTFILE*)EngAllocMem(0, sizeof(FONTFILE) + cjIFI, EXFDTAG); if (pff) { WCHAR *pwszFace; ULONG cwc = cjView0; // wcslen(pwszFace); IFIMETRICS * pifi; pff->id = 0Xff; // remember these so that we can open files later pff->iFilePFM = piFile[0]; pff->iFilePFB = piFile[1]; pff->ulGlyph = *pjView1; // just touch it to be sure it is mapped pifi = pff->pifi = (IFIMETRICS *)(pff+1); memset((PVOID)pifi, 0, cjIFI); pifi->cjThis = cjIFI; pifi->dpwszFaceName = sizeof(IFIMETRICS); pifi->dpwszFamilyName = pifi->dpwszFaceName; // point to terminating zero pifi->dpwszStyleName = pifi->dpwszFaceName +sizeof(WCHAR) * cwc; pifi->dpwszUniqueName = pifi->dpwszStyleName; pwszFace = (WCHAR *)((BYTE*)pifi + pifi->dpwszFaceName); EngMultiByteToWideChar( 1252, // CodePage, pwszFace, // LPWSTR WideCharString, cwc * sizeof(WCHAR) , // BytesInWideCharString, (LPSTR)pjView0, // MultiByteString (INT)cjView0 // BytesInMultiByteString ); if (cwc > 2) cwc-=2; // hack to get rid of \r\n at the end of the line pwszFace[cwc] = L'\0'; // zero terminate pifi->fwdWinAscender = 4; pifi->fwdWinDescender = 3; pifi->fwdUnitsPerEm = pifi->fwdWinDescender + pifi->fwdWinAscender; pifi->usWinWeight = 400; pifi->flInfo = ( FM_INFO_TECH_BITMAP | FM_INFO_RETURNS_BITMAPS | FM_INFO_1BPP | FM_INFO_INTEGER_WIDTH | FM_INFO_RIGHT_HANDED | FM_INFO_NONNEGATIVE_AC ); pifi->fwdMacAscender = pifi->fwdWinAscender; pifi->fwdMacDescender = -pifi->fwdWinDescender; pifi->fwdMacLineGap = 0; pifi->fwdTypoAscender = pifi->fwdMacAscender; pifi->fwdTypoDescender = pifi->fwdMacDescender; pifi->fwdTypoLineGap = pifi->fwdMacLineGap; pifi->fwdMaxCharInc = pifi->fwdAveCharWidth = 5; pifi->fwdUnderscoreSize = 1; pifi->fwdUnderscorePosition = -(FWORD)(pifi->fwdUnderscoreSize / 2 + 1); pifi->fwdStrikeoutSize = pifi->fwdUnderscoreSize; pifi->fwdStrikeoutPosition = pifi->fwdWinAscender / 2; pifi->wcFirstChar = pifi->chFirstChar = THEGLYPH; pifi->wcLastChar = pifi->chLastChar = THEGLYPH; pifi->wcBreakChar = pifi->chBreakChar = THEGLYPH; pifi->wcDefaultChar = pifi->chDefaultChar = THEGLYPH; pifi->fwdCapHeight = pifi->fwdUnitsPerEm/2; pifi->fwdXHeight = pifi->fwdUnitsPerEm/4; pifi->dpCharSets = 0; // no multiple charsets in bm fonts // All the fonts that this font driver will see are to be rendered left // to right pifi->ptlBaseline.x = 1; pifi->ptlBaseline.y = 0; pifi->ptlAspect.y = 1; pifi->ptlAspect.x = 1; pifi->rclFontBox.left = 0; pifi->rclFontBox.top = (LONG) pifi->fwdTypoAscender; pifi->rclFontBox.right = (LONG) pifi->fwdMaxCharInc; pifi->rclFontBox.bottom = (LONG) pifi->fwdTypoDescender; // achVendorId, unknown, don't bother figure it out from copyright msg pifi->achVendId[0] = 'U'; pifi->achVendId[1] = 'n'; pifi->achVendId[2] = 'k'; pifi->achVendId[3] = 'n'; } return (HFF)pff; }
int MBToWCSEx( WORD wCodePage, LPCSTR pAnsiString, int nAnsiChar, LPWSTR *ppUnicodeString, int cchUnicodeString, BOOL bAllocateMem) { ULONG nBytesInUnicodeString; if (nAnsiChar == 0 || cchUnicodeString == 0 || pAnsiString == NULL) { return 0; // nothing to translate or nowhere to put it } /* * Adjust the nAnsiChar value. If nAnsiChar == -1 then the * string pointed to by pAnsiString is NUL terminated so we * count the number of bytes. If nAnsiChar < -1 this is an * illegal value so we return FALSE. Otherwise, nAnsiChar is * set and requires no adjustment. */ #ifdef _USERK_ UserAssert(nAnsiChar >= USER_AWCONV_COUNTSTRINGSZ); #endif if (nAnsiChar < 0) { /* * Bug 268035 - joejo * Need to fail if the count is a negative number less than -2! */ if (nAnsiChar < USER_AWCONV_COUNTSTRINGSZ) { return 0; } #if (USER_AWCONV_COUNTSTRING != -1 || USER_AWCONV_COUNTSTRINGSZ != -2) #error USER_AWCONV_COUNTSTRING or USER_AWCONV_COUNTSTRINGSZ has unexpected value. #endif /* HACK HACK HACK * If nAnsiChar is -1 (USER_AWCONV_COUNTSTRING), nAnsiChar length will be strlen() + 1, * to allocate the memory including trailing \0: this is compatible to the original code. * If nAnsiCahr is -2 (USER_AWCONV_COUNTSTRINGSZ), memory for trailing \0 will not be needed, * so memory allocation is optimized and the return value would be same as strlen(). */ nAnsiChar = strlen(pAnsiString) + 2 + nAnsiChar; // don't forget the NUL if nAnsiChar == -1 if (nAnsiChar == 0) { return 0; } } /* * Adjust the cchUnicodeString value. If cchUnicodeString == -1 then we * pick a value based on nAnsiChar to hold the converted string. If * cchUnicodeString < -1 this is an illegal value so we return FALSE. * Otherwise, cchUnicodeString is set and requires no adjustment. */ if (cchUnicodeString == -1) { if (bAllocateMem == FALSE) { return 0; // no destination } cchUnicodeString = nAnsiChar; } else if (cchUnicodeString < -1) { return 0; // illegal value } if (bAllocateMem) { *ppUnicodeString = (LPWSTR)UserRtlAllocMem(cchUnicodeString*sizeof(WCHAR)); if (*ppUnicodeString == NULL) { return 0; // allocation failed } } /* * if codepage is CP_ACP, We will call faster RtlXXX function. */ if (IS_ACP(wCodePage)) { /* * translate ANSI string pointed to by pAnsiString into Unicode * and store in location pointed to by pUnicodeString. We * stop translating when we fill up the Unicode buffer or reach * the end of the ANSI string. */ if (!NT_SUCCESS(RtlMultiByteToUnicodeN( (PWCH)*ppUnicodeString, cchUnicodeString * sizeof(WCHAR), &nBytesInUnicodeString, (PCH)pAnsiString, nAnsiChar ))) { if (bAllocateMem) { UserRtlFreeMem(*ppUnicodeString); } return 0; // translation failed } return (int)(nBytesInUnicodeString / sizeof(WCHAR)); } else { /* * if wCodePage is not ACP, Call NLS API. */ ULONG nCharsInUnicodeString; #ifdef _USERK_ /* * I believe we will never hit this code which is why I am * adding this assert. [gerritv] 5-21-96 */ #define SHOULD_NOT_REACH_HERE 0 UserAssert(SHOULD_NOT_REACH_HERE); #undef SHOULD_NOT_REACH_HERE return 0; #if 0 // FYI: old code INT iCharsInUnicodeString; /* * Call GRE to convert string to Unicode. (Kernel mode) * I believe we will never hit this code which is why I am * adding this assert. [gerritv] 5-21-96 */ UserAssert(0); iCharsInUnicodeString = EngMultiByteToWideChar( (UINT)wCodePage, (LPWSTR)*ppUnicodeString, (int)cchUnicodeString * sizeof(WCHAR), (LPSTR)pAnsiString, (int)nAnsiChar); nCharsInUnicodeString = (iCharsInUnicodeString == -1) ? 0 : (ULONG) iCharsInUnicodeString; #endif #else /* * Call NLS API (Kernel32) to convert string to Unicode. (User mode) */ nCharsInUnicodeString = MultiByteToWideChar( (UINT)wCodePage, 0, (LPCSTR)pAnsiString, (int)nAnsiChar, (LPWSTR)*ppUnicodeString, (int)cchUnicodeString); #endif // _USERK_ if (nCharsInUnicodeString == 0) { if (bAllocateMem) { UserRtlFreeMem(*ppUnicodeString); } } return (int)nCharsInUnicodeString; } }