/* * @implemented */ int WINAPI CopyAcceleratorTableA ( HACCEL hAccelSrc, LPACCEL lpAccelDst, /* can be NULL */ int cAccelEntries ) { int i; cAccelEntries = CopyAcceleratorTableW(hAccelSrc, lpAccelDst, cAccelEntries); if (lpAccelDst == NULL) return cAccelEntries; for(i = 0; i < cAccelEntries; ++ i) if(!(lpAccelDst[i].fVirt & FVIRTKEY)) { NTSTATUS nErrCode = RtlUnicodeToMultiByteN( (PCHAR)&lpAccelDst[i].key, sizeof(lpAccelDst[i].key), NULL, (PWCHAR)&lpAccelDst[i].key, sizeof(lpAccelDst[i].key) ); if(!NT_SUCCESS(nErrCode)) lpAccelDst[i].key = 0; } return cAccelEntries; }
/* * writes a string of characters to the output * returns -1 if the string doesn't fit in the output buffer * return the length of the string if all characters were written */ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len ) { int space = out->len - out->used; if( len < 0 ) len = strlenW( str ); if( out->unicode ) { LPWSTR p = out->buf.W + out->used; if( space >= len ) { memcpy( p, str, len*sizeof(WCHAR) ); out->used += len; return len; } if( space > 0 ) memcpy( p, str, space*sizeof(WCHAR) ); out->used += len; } else { LPSTR p = out->buf.A + out->used; ULONG n; RtlUnicodeToMultiByteSize( &n, str, len * sizeof(WCHAR) ); if( space >= n ) { RtlUnicodeToMultiByteN( p, n, NULL, str, len * sizeof(WCHAR) ); out->used += n; return len; } if (space > 0) RtlUnicodeToMultiByteN( p, space, NULL, str, len * sizeof(WCHAR) ); out->used += n; } return -1; }
/********************************************************************* * wcstombs (NTDLL.@) */ INT __cdecl NTDLL_wcstombs( LPSTR dst, LPCWSTR src, INT n ) { DWORD len; if (!dst) { RtlUnicodeToMultiByteSize( &len, src, strlenW(src)*sizeof(WCHAR) ); return len; } else { if (n <= 0) return 0; RtlUnicodeToMultiByteN( dst, n, &len, src, strlenW(src)*sizeof(WCHAR) ); if (len < n) dst[len] = 0; } return len; }
PSTR WCharToMByte(PCWSTR Unicode, ULONG_PTR Length) { PSTR AnsiString; if (Length == -1) Length = StrLengthW(Unicode); ++Length; Length *= sizeof(WCHAR); AnsiString = (PSTR)AllocateMemoryP(Length); if (AnsiString == NULL) return NULL; RtlUnicodeToMultiByteN(AnsiString, Length, NULL, Unicode, Length); return AnsiString; }
BOOL DebugConvertToAnsi( HANDLE hCurrentProcess, PWINDBG_EXTENSION_APIS lpExtensionApis, LPWSTR psrc, LPSTR pdst) { WCHAR awch[80]; ULONG cchText; move(awch, psrc); cchText = wcslen(awch) + 1; if (cchText == 0) { strcpy(pdst, "<null>"); } else { awch[sizeof(awch) / sizeof(WCHAR) - 1] = L'\0'; RtlUnicodeToMultiByteN(pdst, cchText, NULL, awch, cchText * sizeof(WCHAR)); } }
/* IO_pp_init * * Read the ppdev entries from wine.conf, open the device and check * for necessary IOCTRL * Report verbose about possible errors */ char IO_pp_init(void) { char name[80]; char buffer[256]; HANDLE root, hkey; int i,idx=0,fd,res,userbase,nports=0; char * timeout; char ret=1; int lasterror; OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; static const WCHAR configW[] = {'S','o','f','t','w','a','r','e','\\', 'W','i','n','e','\\','V','D','M','\\','p','p','d','e','v',0}; TRACE("\n"); RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); attr.Length = sizeof(attr); attr.RootDirectory = root; attr.ObjectName = &nameW; attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; RtlInitUnicodeString( &nameW, configW ); /* @@ Wine registry key: HKCU\Software\Wine\VDM\ppdev */ if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) hkey = 0; NtClose( root ); if (!hkey) return 1; for (;;) { DWORD total_size, len; char temp[256]; KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)temp; if (NtEnumerateValueKey( hkey, idx, KeyValueFullInformation, temp, sizeof(temp), &total_size )) break; if (info->Type != REG_SZ) break; RtlUnicodeToMultiByteN( name, sizeof(name)-1, &len, info->Name, info->NameLength ); name[len] = 0; RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len, (WCHAR *)(temp + info->DataOffset), total_size-info->DataOffset ); buffer[len] = 0; idx++; if(nports >4) { FIXME("Make the PPDeviceList larger than 5 elements\n"); break; } TRACE("Device '%s' at virtual userbase '%s'\n", buffer,name); timeout = strchr(buffer,','); if (timeout) *timeout++=0; fd=open(buffer,O_RDWR); lasterror=errno; if (fd == -1) { WARN("Configuration: No access to %s Cause: %s\n",buffer,strerror(lasterror)); WARN("Rejecting configuration item\n"); if (lasterror == ENODEV) ERR("Is the ppdev module loaded?\n"); continue; } userbase = strtol(name, NULL, 16); if ( errno == ERANGE) { WARN("Configuration: Invalid base %s for %s\n",name,buffer); WARN("Rejecting configuration item\n"); continue; } if (ioctl (fd,PPCLAIM,0)) { ERR("PPCLAIM rejected %s\n",buffer); ERR("Perhaps the device is already in use or nonexistent\n"); continue; } if (nports > 0) { for (i=0; i<= nports; i++) { if (PPDeviceList[i].userbase == userbase) { WARN("Configuration: %s uses the same virtual ports as %s\n", buffer,PPDeviceList[0].devicename); WARN("Configuration: Rejecting configuration item\n"); userbase = 0; break; } } if (!userbase) continue; } /* Check for the minimum required IOCTLS */ if ((ioctl(fd,PPRDATA,&res))|| (ioctl(fd,PPRSTATUS,&res))|| (ioctl(fd,PPRCONTROL,&res))) { ERR("PPUSER IOCTL not available for parport device %s\n",buffer); continue; } if (ioctl (fd,PPRELEASE,0)) { ERR("PPRELEASE rejected %s\n",buffer); ERR("Perhaps the device is already in use or nonexistent\n"); continue; } PPDeviceList[nports].devicename = malloc(sizeof(buffer)+1); if (!PPDeviceList[nports].devicename) { ERR("No (more) space for devicename\n"); break; } strcpy(PPDeviceList[nports].devicename,buffer); PPDeviceList[nports].fd = fd; PPDeviceList[nports].userbase = userbase; PPDeviceList[nports].lastaccess=GetTickCount(); if (timeout) { PPDeviceList[nports].timeout = strtol(timeout, NULL, 10); if (errno == ERANGE) { WARN("Configuration: Invalid timeout %s in configuration for %s, Setting to 0\n", timeout,buffer); PPDeviceList[nports].timeout = 0; } } else PPDeviceList[nports].timeout = 0; nports++; } TRACE("found %d ports\n",nports); NtClose( hkey ); PPDeviceNum= nports; if (nports > 1) /* sort in ascending order for userbase for faster access */ qsort (PPDeviceList,PPDeviceNum,sizeof(PPDeviceStruct),IO_pp_sort); if (nports) ret=0; for (idx= 0;idx<PPDeviceNum; idx++) TRACE("found device %s userbase %x fd %x timeout %d\n", PPDeviceList[idx].devicename, PPDeviceList[idx].userbase, PPDeviceList[idx].fd,PPDeviceList[idx].timeout); /* FIXME: register a timer callback perhaps every 30 seconds to release unused ports Set lastaccess = 0 as indicator when port was released */ return ret; }
LPCWSTR FASTCALL ClassNameToVersion( LPCTSTR lpszClass, LPCWSTR lpszMenuName, LPCWSTR *plpLibFileName, HANDLE *pContext, BOOL bAnsi) { NTSTATUS Status; UNICODE_STRING SectionName; WCHAR SeactionNameBuf[MAX_PATH] = {0}; ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) }; if (IS_ATOM(lpszClass)) { SectionName.Buffer = (LPWSTR)&SeactionNameBuf; SectionName.MaximumLength = sizeof(SeactionNameBuf); if(!NtUserGetAtomName(LOWORD((DWORD_PTR)lpszClass), &SectionName)) { return NULL; } } else { if (bAnsi) { RtlCreateUnicodeStringFromAsciiz(&SectionName, (LPSTR)lpszClass); } else { RtlInitUnicodeString(&SectionName, lpszClass); } } Status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, &SectionName, &KeyedData ); if (NT_SUCCESS(Status) && KeyedData.ulDataFormatVersion == 1) { struct dll_redirect *dll = KeyedData.lpSectionBase; if (plpLibFileName) *plpLibFileName = dll->name; if (lpszMenuName) { WCHAR * mnubuf; LPWSTR mnuNameW; LPSTR mnuNameA; int len = 0; struct entity *entity = KeyedData.lpData; FIXME("actctx: Needs to support menu name from redirected class!"); if (entity->clsid) { mnubuf = entity->clsid; if (bAnsi) { mnuNameA = (LPSTR)lpszMenuName; RtlUnicodeToMultiByteN( mnuNameA, 255, (PULONG)&len, mnubuf, strlenW(mnubuf) * sizeof(WCHAR) ); mnuNameA[len] = 0; } else { mnuNameW = (LPWSTR)lpszMenuName; len = strlenW(mnubuf) * sizeof(WCHAR); RtlCopyMemory((void *)mnuNameW, mnubuf, len); mnuNameW[len] = 0; } } } if (pContext) *pContext = KeyedData.hActCtx; } if (!IS_ATOM(lpszClass) && bAnsi) RtlFreeUnicodeString(&SectionName); if (KeyedData.hActCtx) RtlReleaseActivationContext(KeyedData.hActCtx); return lpszClass; }
int main( int argc, char *argv[] ) { ULONG j; ULONG cb; char *pch; printf("Start NlsXlatTest()\n"); // // First initialize the buffers // for (j = 0; j < sizeof(OEMBuff); j++) { OEMBuff[j] = (char)(j * 17); ABuff[j] = (char)(j * 19); } // // TEST 1 // RtlMultiByteToUnicodeN, RtlUnicodeToMultiByteN // printf("Test 1: MultiByteToUnicodeN & RtlUnicodeToMultiByteN\n"); // TEST 1.1 // printf(" Test 1.1: A->U U->A\n"); RtlMultiByteToUnicodeN(UBuff, sizeof(UBuff), &cb, ABuff, sizeof(ABuff)); printf(" %d bytes converted to Unicode\n", cb); RtlUnicodeToMultiByteN(ABuff, sizeof(ABuff), &cb, UBuff, sizeof(UBuff)); printf(" %d bytes converted back to ANSI\n", cb); for (j = 0; j < sizeof(ABuff); j++) { if (ABuff[j] != (char)(j * 19)) { printf("ABuff[%d] was 0x%02x, now 0x%02x\n", j, (char)(j * 19), ABuff[j]); return FALSE; } } printf(" Test 1.1 OK\n"); // TEST 1.2 // printf(" Test 1.2: A->U U->A (source & dest buffers the same)\n"); RtlCopyMemory(UBuff, ABuff, sizeof(ABuff)); RtlMultiByteToUnicodeN(UBuff, sizeof(UBuff), &cb, UBuff, sizeof(ABuff)); printf(" %d bytes converted to Unicode\n", cb); RtlUnicodeToMultiByteN(UBuff, sizeof(ABuff), &cb, UBuff, sizeof(UBuff)); printf(" %d bytes converted back to ANSI\n", cb); pch = (LPSTR)UBuff; for (j = 0; j < sizeof(ABuff); j++) { if (pch[j] != ABuff[j]) { printf(" ABuff[%d] was 0x%02x, was turned into 0x%02x\n", j, ABuff[j], pch[j]); printf(" Test 1.2 FAILED!\n"); return FALSE; } } printf(" Test 1.2 OK!\n"); return TRUE; }
/****************************************************************** * start_debugger * * Does the effective debugger startup according to 'format' */ static BOOL start_debugger(PEXCEPTION_POINTERS epointers, HANDLE hEvent) { OBJECT_ATTRIBUTES attr; UNICODE_STRING nameW; char *cmdline, *env, *p; HANDLE hDbgConf; DWORD bAuto = TRUE; PROCESS_INFORMATION info; STARTUPINFOA startup; char* format = NULL; BOOL ret = FALSE; char buffer[256]; static const WCHAR AeDebugW[] = {'M','a','c','h','i','n','e','\\', 'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'W','i','n','d','o','w','s',' ','N','T','\\', 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 'A','e','D','e','b','u','g',0}; static const WCHAR DebuggerW[] = {'D','e','b','u','g','g','e','r',0}; static const WCHAR AutoW[] = {'A','u','t','o',0}; format_exception_msg( epointers, buffer, sizeof(buffer) ); MESSAGE("wine: %s (thread %04x), starting debugger...\n", buffer, GetCurrentThreadId()); attr.Length = sizeof(attr); attr.RootDirectory = 0; attr.ObjectName = &nameW; attr.Attributes = 0; attr.SecurityDescriptor = NULL; attr.SecurityQualityOfService = NULL; RtlInitUnicodeString( &nameW, AeDebugW ); if (!NtOpenKey( &hDbgConf, KEY_ALL_ACCESS, &attr )) { char buffer[64]; KEY_VALUE_PARTIAL_INFORMATION *info; DWORD format_size = 0; RtlInitUnicodeString( &nameW, DebuggerW ); if (NtQueryValueKey( hDbgConf, &nameW, KeyValuePartialInformation, NULL, 0, &format_size ) == STATUS_BUFFER_OVERFLOW) { char *data = HeapAlloc(GetProcessHeap(), 0, format_size); NtQueryValueKey( hDbgConf, &nameW, KeyValuePartialInformation, data, format_size, &format_size ); info = (KEY_VALUE_PARTIAL_INFORMATION *)data; RtlUnicodeToMultiByteSize( &format_size, (WCHAR *)info->Data, info->DataLength ); format = HeapAlloc( GetProcessHeap(), 0, format_size+1 ); RtlUnicodeToMultiByteN( format, format_size, NULL, (WCHAR *)info->Data, info->DataLength ); format[format_size] = 0; if (info->Type == REG_EXPAND_SZ) { char* tmp; /* Expand environment variable references */ format_size=ExpandEnvironmentStringsA(format,NULL,0); tmp=HeapAlloc(GetProcessHeap(), 0, format_size); ExpandEnvironmentStringsA(format,tmp,format_size); HeapFree(GetProcessHeap(), 0, format); format=tmp; } HeapFree( GetProcessHeap(), 0, data ); } RtlInitUnicodeString( &nameW, AutoW ); if (!NtQueryValueKey( hDbgConf, &nameW, KeyValuePartialInformation, buffer, sizeof(buffer)-sizeof(WCHAR), &format_size )) { info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer; if (info->Type == REG_DWORD) memcpy( &bAuto, info->Data, sizeof(DWORD) ); else if (info->Type == REG_SZ) { WCHAR *str = (WCHAR *)info->Data; str[info->DataLength/sizeof(WCHAR)] = 0; bAuto = atoiW( str ); } } NtClose(hDbgConf); } if (format) { cmdline = HeapAlloc(GetProcessHeap(), 0, strlen(format) + 2*20); sprintf(cmdline, format, GetCurrentProcessId(), hEvent); HeapFree(GetProcessHeap(), 0, format); } else { cmdline = HeapAlloc(GetProcessHeap(), 0, 80); sprintf(cmdline, "winedbg --auto %d %ld", GetCurrentProcessId(), (ULONG_PTR)hEvent); } if (!bAuto) { HMODULE mod = GetModuleHandleA( "user32.dll" ); MessageBoxA_funcptr pMessageBoxA = NULL; if (mod) pMessageBoxA = (MessageBoxA_funcptr)GetProcAddress( mod, "MessageBoxA" ); if (pMessageBoxA) { static const char msg[] = ".\nDo you wish to debug it?"; char buffer[256]; format_exception_msg( epointers, buffer, sizeof(buffer)-sizeof(msg) ); strcat( buffer, msg ); if (pMessageBoxA( 0, buffer, "Exception raised", MB_YESNO | MB_ICONHAND ) == IDNO) { TRACE("Killing process\n"); goto EXIT; } } } /* make WINEDEBUG empty in the environment */ env = GetEnvironmentStringsA(); for (p = env; *p; p += strlen(p) + 1) { if (!memcmp( p, "WINEDEBUG=", sizeof("WINEDEBUG=")-1 )) { char *next = p + strlen(p); char *end = next + 1; while (*end) end += strlen(end) + 1; memmove( p + sizeof("WINEDEBUG=") - 1, next, end + 1 - next ); break; } } TRACE("Starting debugger %s\n", debugstr_a(cmdline)); memset(&startup, 0, sizeof(startup)); startup.cb = sizeof(startup); startup.dwFlags = STARTF_USESHOWWINDOW; startup.wShowWindow = SW_SHOWNORMAL; ret = CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, env, NULL, &startup, &info); FreeEnvironmentStringsA( env ); if (ret) { /* wait for debugger to come up... */ HANDLE handles[2]; CloseHandle(info.hThread); handles[0]=hEvent; handles[1]=info.hProcess; WaitForMultipleObjects(2, handles, FALSE, INFINITE); CloseHandle(info.hProcess); } else ERR("Couldn't start debugger (%s) (%d)\n" "Read the Wine Developers Guide on how to set up winedbg or another debugger\n", debugstr_a(cmdline), GetLastError()); EXIT: HeapFree(GetProcessHeap(), 0, cmdline); return ret; }
BOOL WINAPI SYSSETUP_LogItem(IN const LPSTR lpFileName, IN DWORD dwLineNumber, IN DWORD dwSeverity, IN LPWSTR lpMessageText) { LPCSTR lpSeverityString; LPSTR lpMessageString; DWORD dwMessageLength; DWORD dwMessageSize; DWORD dwWritten; CHAR Buffer[6]; CHAR TimeBuffer[30]; SYSTEMTIME stTime; /* Get the severity code string */ switch (dwSeverity) { case SYSSETUP_SEVERITY_INFORMATION: lpSeverityString = "Information : "; break; case SYSSETUP_SEVERITY_WARNING: lpSeverityString = "Warning : "; break; case SYSSETUP_SEVERITY_ERROR: lpSeverityString = "Error : "; break; case SYSSETUP_SEVERITY_FATAL_ERROR: lpSeverityString = "Fatal error : "; break; default: lpSeverityString = "Unknown : "; break; } /* Get length of the converted ansi string */ dwMessageLength = wcslen(lpMessageText) * sizeof(WCHAR); RtlUnicodeToMultiByteSize(&dwMessageSize, lpMessageText, dwMessageLength); /* Allocate message string buffer */ lpMessageString = (LPSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwMessageSize); if (!lpMessageString) return FALSE; /* Convert unicode to ansi */ RtlUnicodeToMultiByteN(lpMessageString, dwMessageSize, NULL, lpMessageText, dwMessageLength); /* Set file pointer to the end of the file */ SetFilePointer(hLogFile, 0, NULL, FILE_END); /* Write Time/Date */ GetLocalTime(&stTime); snprintf(TimeBuffer, sizeof(TimeBuffer), "%02d/%02d/%02d %02d:%02d:%02d.%03d", stTime.wMonth, stTime.wDay, stTime.wYear, stTime.wHour, stTime.wMinute, stTime.wSecond, stTime.wMilliseconds); WriteFile(hLogFile, TimeBuffer, strlen(TimeBuffer), &dwWritten, NULL); /* Write comma */ WriteFile(hLogFile, ",", 1, &dwWritten, NULL); /* Write file name */ WriteFile(hLogFile, lpFileName, strlen(lpFileName), &dwWritten, NULL); /* Write comma */ WriteFile(hLogFile, ",", 1, &dwWritten, NULL); /* Write line number */ snprintf(Buffer, sizeof(Buffer), "%lu", dwLineNumber); WriteFile(hLogFile, Buffer, strlen(Buffer), &dwWritten, NULL); /* Write comma */ WriteFile(hLogFile, ",", 1, &dwWritten, NULL); /* Write severity code */ WriteFile(hLogFile, lpSeverityString, strlen(lpSeverityString), &dwWritten, NULL); /* Write message string */ WriteFile(hLogFile, lpMessageString, dwMessageSize, &dwWritten, NULL); /* Write newline */ WriteFile(hLogFile, "\r\n", 2, &dwWritten, NULL); HeapFree(GetProcessHeap(), 0, lpMessageString); return TRUE; }
/***************************************************************************\ * _ClientEventCallback * * Description: * Called from the server side to perform event callbacks. * * History: * 11-12-91 sanfords Created. \***************************************************************************/ DWORD _ClientEventCallback( PCL_INSTANCE_INFO pcii, PEVENT_PACKET pep) { HDDEDATA hData; EnterDDECrit; switch (pep->EventType) { case 0: // MonitorFlags change event - everybody gets it pcii->MonitorFlags = pep->Data; break; case MF_CALLBACKS: { MONCBSTRUCT mcb; mcb = *((MONCBSTRUCT *)&pep->Data); mcb.hsz1 = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mcb.hsz1)); mcb.hsz2 = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mcb.hsz2)); if ( mcb.wType == XTYP_REGISTER || mcb.wType == XTYP_UNREGISTER) { mcb.hsz2 = INST_SPECIFIC_HSZ_FROM_LATOM((LATOM)mcb.hsz2); } hData = InternalCreateDataHandle(pcii, (LPSTR)&mcb, pep->cbEventData, 0, HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0); if (hData) { DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L, pep->EventType); InternalFreeDataHandle((HDDEDATA)hData, TRUE); DeleteAtom(LATOM_FROM_HSZ(mcb.hsz1)); DeleteAtom(LATOM_FROM_HSZ(mcb.hsz2)); } } break; case MF_LINKS: { MONLINKSTRUCT ml; ml = *((MONLINKSTRUCT *)&pep->Data); ml.hszSvc = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)ml.hszSvc)); ml.hszTopic = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)ml.hszTopic)); ml.hszItem = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)ml.hszItem)); hData = InternalCreateDataHandle(pcii, (LPSTR)&ml, pep->cbEventData, 0, HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0); if (hData) { DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L, pep->EventType); InternalFreeDataHandle((HDDEDATA)hData, TRUE); DeleteAtom(LATOM_FROM_HSZ(ml.hszSvc)); DeleteAtom(LATOM_FROM_HSZ(ml.hszTopic)); DeleteAtom(LATOM_FROM_HSZ(ml.hszItem)); } } break; case MF_CONV: { MONCONVSTRUCT mc; mc = *((MONCONVSTRUCT *)&pep->Data); mc.hszSvc = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mc.hszSvc)); mc.hszTopic = NORMAL_HSZ_FROM_LATOM(GlobalToLocalAtom((GATOM)mc.hszTopic)); hData = InternalCreateDataHandle(pcii, (LPSTR)&mc, pep->cbEventData, 0, HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0); if (hData) { DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L, pep->EventType); InternalFreeDataHandle((HDDEDATA)hData, TRUE); DeleteAtom(LATOM_FROM_HSZ(mc.hszSvc)); DeleteAtom(LATOM_FROM_HSZ(mc.hszTopic)); } } break; case MF_HSZ_INFO: if (!(pcii->flags & IIF_UNICODE)) { LPSTR pszAnsi; /* * Translate HSZ string back into ANSI */ if (WCSToMB(((PMONHSZSTRUCT)&pep->Data)->str, ((int)pep->cbEventData - (int)((PMONHSZSTRUCT)&pep->Data)->cb) / sizeof(WCHAR), &pszAnsi, (int)pep->cbEventData - (int)((PMONHSZSTRUCT)&pep->Data)->cb, TRUE)) { strcpy(((PMONHSZSTRUCTA)&pep->Data)->str, pszAnsi); UserLocalFree(pszAnsi); } ((PMONHSZSTRUCT)&pep->Data)->cb = sizeof(MONHSZSTRUCTA); } // fall through case MF_SENDMSGS: case MF_POSTMSGS: if (pep->EventType == MF_POSTMSGS) { PMONMSGSTRUCT pmms = (PMONMSGSTRUCT)&pep->Data; BYTE buf[32]; /* * We may need to translate the Execute string to/from * UNICODE depending on what type of monitor this is * going to. */ if (pmms->wMsg == WM_DDE_EXECUTE) { BOOL fUnicodeText; int flags; flags = (IS_TEXT_UNICODE_UNICODE_MASK | IS_TEXT_UNICODE_REVERSE_MASK | (IS_TEXT_UNICODE_NOT_UNICODE_MASK & (~IS_TEXT_UNICODE_ILLEGAL_CHARS)) | IS_TEXT_UNICODE_NOT_ASCII_MASK); #ifdef ISTEXTUNICODE_WORKS fUnicodeText = RtlIsTextUnicode(pmms->dmhd.Data, min(32, pmms->dmhd.cbData), &flags); #else fUnicodeText = (*(LPSTR)pmms->dmhd.Data == '\0'); #endif if (pcii->flags & IIF_UNICODE && !fUnicodeText) { /* Ascii->UNICODE */ RtlMultiByteToUnicodeN((LPWSTR)buf, 32, NULL, (LPSTR)&pmms->dmhd.Data, min(32, pmms->dmhd.cbData)); RtlCopyMemory(&pmms->dmhd.Data, buf, 32); } else if (!(pcii->flags & IIF_UNICODE) && fUnicodeText) { /* UNICODE->Ascii */ RtlUnicodeToMultiByteN((LPSTR)buf, 32, NULL, (LPWSTR)&pmms->dmhd.Data, min(32, pmms->dmhd.cbData)); RtlCopyMemory(&pmms->dmhd.Data, buf, 32); } } } case MF_ERRORS: hData = InternalCreateDataHandle(pcii, (LPSTR)&pep->Data, pep->cbEventData, 0, HDATA_NOAPPFREE | HDATA_READONLY | HDATA_EXECUTE, 0, 0); if (hData) { DoCallback(pcii, (WORD)XTYP_MONITOR, 0, 0, 0, 0, hData, 0L, pep->EventType); InternalFreeDataHandle((HDDEDATA)hData, TRUE); } break; } LeaveDDECrit; return (0); }
int WCSToMBEx( WORD wCodePage, LPCWSTR pUnicodeString, int cchUnicodeString, LPSTR *ppAnsiString, int nAnsiChar, BOOL bAllocateMem) { ULONG nCharsInAnsiString; #ifdef _USERK_ INT iCharsInAnsiString; #endif // _USERK_ if (nAnsiChar == 0 || cchUnicodeString == 0 || pUnicodeString == NULL) { return 0; // nothing to translate or nowhere to put it } /* * Adjust the cchUnicodeString value. If cchUnicodeString == -1 then the * string pointed to by pUnicodeString is NUL terminated so we * count the number of bytes. If cchUnicodeString < -1 this is an * illegal value so we return FALSE. Otherwise, cchUnicodeString is * set and requires no adjustment. */ if (cchUnicodeString == -1) { cchUnicodeString = (wcslen(pUnicodeString) + 1); } else if (cchUnicodeString < -1) { return 0; // illegal value } /* * Adjust the nAnsiChar value. If nAnsiChar == -1 then we pick a * value based on cchUnicodeString to hold the converted string. If * nAnsiChar < -1 this is an illegal value so we return FALSE. * Otherwise, nAnsiChar is set and requires no adjustment. */ if (nAnsiChar == -1) { if (bAllocateMem == FALSE) { return 0; // no destination } nAnsiChar = cchUnicodeString * DBCS_CHARSIZE; } else if (nAnsiChar < -1) { return 0; // illegal value } if (bAllocateMem) { /* * We need to allocate memory to hold the translated string. */ *ppAnsiString = (LPSTR)UserRtlAllocMem(nAnsiChar); if (*ppAnsiString == NULL) { return 0; } } /* * translate Unicode string pointed to by pUnicodeString into * ANSI and store in location pointed to by pAnsiString. We * stop translating when we fill up the ANSI buffer or reach * the end of the Unicode string. */ /* * if the target multibyte codepage is eqaul to ACP, Call faster Rtl function. */ if (IS_ACP(wCodePage)) { NTSTATUS Status; Status = RtlUnicodeToMultiByteN( (PCH)*ppAnsiString, nAnsiChar, &nCharsInAnsiString, (PWCH)pUnicodeString, cchUnicodeString * sizeof(WCHAR)); /* * If the ansi buffer is too small, RtlUnicodeToMultiByteN() * returns STATUS_BUFFER_OVERFLOW. In this case, the function * put as many ansi characters as specified in the buffer and * returns the number by chacacters(in bytes) written. We would * like to return the actual byte count written in the ansi * buffer rather than returnning 0 since callers of this function * don't expect to be returned 0 in most case. */ if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) { if (bAllocateMem) { UserRtlFreeMem(*ppAnsiString); } return 0; // translation failed } return (int)nCharsInAnsiString; } else { #ifdef _USERK_ /* * Call GRE to convert string to Unicode. (Kernel mode) */ iCharsInAnsiString = EngWideCharToMultiByte( (UINT)wCodePage, (LPWSTR)pUnicodeString, cchUnicodeString * sizeof(WCHAR), (LPSTR)*ppAnsiString, nAnsiChar); nCharsInAnsiString = (iCharsInAnsiString == -1) ? 0 : (ULONG) iCharsInAnsiString; #else /* * Call NLS API (Kernel32) to convert string to Unicode. (User mode) */ nCharsInAnsiString = WideCharToMultiByte( (UINT)wCodePage, 0, (LPCWSTR)pUnicodeString, cchUnicodeString, (LPSTR)*ppAnsiString, nAnsiChar, NULL, NULL); #endif // _USERK_ if (nCharsInAnsiString == 0) { if (bAllocateMem) { UserRtlFreeMem(*ppAnsiString); } } return (int)nCharsInAnsiString; } }
BOOL RtlWCSMessageWParamCharToMB(DWORD msg, WPARAM *pWParam) { DWORD dwAnsi; NTSTATUS Status; WORD CodePage; int nbWch; #ifdef FE_SB // RtlWCSMessageWParamCharToMB() // // Format of *pWParam here... // // LOWORD(*pWParam) = Unicode CodePoint... // HIWORD(*pWParam) = Has some information for DBCS messaging // (ex. WPARAM_IR_DBCSCHAR) // // Then we need to convert ONLY loword of wParam to Unicode... // #endif // FE_SB #ifndef FE_SB // NtBug #3135 (Closed 02/04/93) // Publisher Posts WM_CHAR messages with wParam > 0xFF (not a valid ANSI char)! // // It does this to disable TranslateAccelerator for that char. // MSPub's winproc must get the non-ANSI 'character' value, so PostMessage must // translate *two* characters of wParam for character messages, and PeekMessage // must translate *two* Unicode chars of wParam for ANSI app. #endif /* * Only these messages have CHARs: others are passed through */ switch(msg) { #ifdef FE_IME // RtlWCSMessageWParamCharToMB() case WM_IME_CHAR: case WM_IME_COMPOSITION: #endif // FE_IME case WM_CHAR: case WM_CHARTOITEM: case EM_SETPASSWORDCHAR: case WM_DEADCHAR: case WM_SYSCHAR: case WM_SYSDEADCHAR: case WM_MENUCHAR: CodePage = THREAD_CODEPAGE(); dwAnsi = 0; nbWch = IS_DBCS_ENABLED() ? 1 * sizeof(WCHAR) : 2 * sizeof(WCHAR); if (IS_ACP(CodePage)) { // HACK HACK HACK HACK (for NtBug #3135) // to allow applications that store data in high word of wParam // Jan/06/96 hiroyama Status = RtlUnicodeToMultiByteN((LPSTR)&dwAnsi, sizeof(dwAnsi), NULL, (LPWSTR)pWParam, nbWch); if (!NT_SUCCESS(Status)) { // LATER IanJa: returning FALSE makes GetMessage fail, which // terminates the app. We should use some default 'bad character' // I use 0x00 for now. *pWParam = 0x00; return TRUE; } } else { int cwch; // assuming little endian #ifdef _USERK_ cwch = EngWideCharToMultiByte(CodePage, (LPWSTR)pWParam, nbWch, (LPSTR)&dwAnsi, sizeof(dwAnsi)); #else cwch = WideCharToMultiByte(CodePage, 0, (LPCWSTR)pWParam, nbWch / sizeof(WCHAR), (LPSTR)&dwAnsi, sizeof(dwAnsi), NULL, NULL); #endif // _USERK_ // KdPrint(("0x%04x -> 0x%02x (%d)\n", *pWParam, dwAnsi, CodePage)); if (cwch == 0) { *pWParam = 0x00; return TRUE; } } if (IS_DBCS_ENABLED()) { WORD wAnsi = LOWORD(dwAnsi); // // From: // HIBYTE(wAnsi) = Dbcs TrailingByte. // LOBYTE(wAnsi) = Dbcs LeadingByte or Sbcs character. // // To: // HIWORD(*pWParam) = Original Data (information for DBCS messgaing). // HIBYTE(LOWORD(*pWParam)) = Dbcs LeadingByte Byte. // LOBYTE(LOWORD(*pWParam)) = Dbcs TrailingByte or Sbcs character. // if (IS_DBCS_MESSAGE(wAnsi)) { // // It's a DBCS character. // *pWParam = MAKEWPARAM(MAKEWORD(HIBYTE(wAnsi),LOBYTE(wAnsi)),HIWORD(*pWParam)); } else { // // It's a SBCS character. // *pWParam = MAKEWPARAM(MAKEWORD(LOBYTE(wAnsi),0),0); } } else { #if DBG if ((dwAnsi == 0) || (dwAnsi > 0xFF)) { RIPMSG1(RIP_VERBOSE, "msgW -> msgA: char = 0x%.4lX\n", dwAnsi); } #endif *pWParam = dwAnsi; } break; } return TRUE; }
NTSTATUS FalseUnicodeToRealUnicode( IN OUT LPWSTR Source, IN int SourceLength, // in chars IN UINT Codepage ) /* this routine converts a unicode string from the internally stored unicode characters into the real unicode characters. */ { NTSTATUS Status; LPSTR Temp; ULONG TempLength; ULONG Length; CHAR StackBuffer[STACK_BUFFER_SIZE]; BOOL NormalChars; int i; DBGCHARS(("UnicodeAnsiToUnicodeAnsi U->ACP:%d->U %.*ls\n", Codepage, SourceLength > 10 ? 10 : SourceLength, Source)); NormalChars = TRUE; /* * Test for characters < 0x20 or >= 0x7F. If none are found, we don't have * any conversion to do! */ for (i=0;i<SourceLength;i++) { if ((USHORT)(Source[i] - 0x20) > 0x5e) { NormalChars = FALSE; break; } } if (NormalChars) { return STATUS_SUCCESS; } TempLength = SourceLength; if (TempLength > STACK_BUFFER_SIZE) { Temp = (LPSTR)HeapAlloc(pConHeap,MAKE_TAG( TMP_TAG ),TempLength); if (Temp == NULL) { return STATUS_NO_MEMORY; } } else { Temp = StackBuffer; } Status = RtlUnicodeToMultiByteN(Temp, TempLength, &Length, Source, SourceLength * sizeof(WCHAR) ); if (!NT_SUCCESS(Status)) { if (TempLength > STACK_BUFFER_SIZE) { HeapFree(pConHeap,0,Temp); } return Status; } if (Codepage == OEMCP) { Status = RtlCustomCPToUnicodeN(&GlyphCP, Source, SourceLength * sizeof(WCHAR), &Length, Temp, TempLength ); } else { Status = MultiByteToWideChar(Codepage, MB_USEGLYPHCHARS, Temp, TempLength*sizeof(WCHAR), Source, SourceLength); } if (TempLength > STACK_BUFFER_SIZE) { HeapFree(pConHeap,0,Temp); } if (!NT_SUCCESS(Status)) { return Status; } else { return STATUS_SUCCESS; } }
size_t __cdecl _wcstombs_lk #else size_t __cdecl wcstombs #endif ( char * s, const wchar_t * pwcs, size_t n ) { size_t count = 0; #ifdef _WIN32 int i, retval; char buffer[MB_LEN_MAX]; BOOL defused = 0; #endif if (s && n == 0) /* dest string exists, but 0 bytes converted */ return (size_t) 0; _ASSERTE(pwcs != NULL); #ifdef _WIN32 #if !defined( _NTSUBSET_ ) && !defined(_POSIX_) /* if destination string exists, fill it in */ if (s) { if (__lc_handle[LC_CTYPE] == _CLOCALEHANDLE) { /* C locale: easy and fast */ while(count < n) { if (*pwcs > 255) /* validate high byte */ { errno = EILSEQ; return (size_t)-1; /* error */ } s[count] = (char) *pwcs; if (*pwcs++ == L'\0') return count; count++; } return count; } else { if (1 == MB_CUR_MAX) { /* If SBCS, one wchar_t maps to one char */ /* WideCharToMultiByte will compare past NULL - reset n */ if (n > 0) n = wcsncnt(pwcs, n); if (((count=WideCharToMultiByte(__lc_codepage, WC_COMPOSITECHECK | WC_SEPCHARS, pwcs, n, s, n, NULL, &defused)) != 0) && (!defused)) { if (*(s+count-1) == '\0') count--; /* don't count NUL */ return count; } errno = EILSEQ; return (size_t)-1; } else { /* If MBCS, wchar_t to char mapping unknown */ /* Assume that usually the buffer is large enough */ if (((count=WideCharToMultiByte(__lc_codepage, WC_COMPOSITECHECK | WC_SEPCHARS, pwcs, -1, s, n, NULL, &defused)) != 0) && (!defused)) { return count - 1; /* don't count NUL */ } if (defused || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { errno = EILSEQ; return (size_t)-1; } /* buffer not large enough, must do char by char */ while (count < n) { if (((retval = WideCharToMultiByte (__lc_codepage, 0, pwcs, 1, buffer, MB_CUR_MAX, NULL, &defused)) == 0) || defused) { errno = EILSEQ; return (size_t)-1; } if (count + retval > n) return count; for (i = 0; i < retval; i++, count++) /* store character */ if((s[count] = buffer[i])=='\0') return count; pwcs++; } return count; } } } else { /* s == NULL, get size only, pwcs must be NUL-terminated */ if (__lc_handle[LC_CTYPE] == _CLOCALEHANDLE) return wcslen(pwcs); else { if (((count=WideCharToMultiByte(__lc_codepage, WC_COMPOSITECHECK | WC_SEPCHARS, pwcs, -1, NULL, 0, NULL, &defused)) == 0) || (defused)) { errno = EILSEQ; return (size_t)-1; } return count - 1; } } #else /* _NTSUBSET_/_POSIX_ */ /* if destination string exists, fill it in */ if (s) { NTSTATUS Status; Status = RtlUnicodeToMultiByteN(s, n, (PULONG)&count, (wchar_t *)pwcs, (wcslen(pwcs)+1)*sizeof(WCHAR)); if (NT_SUCCESS(Status)) { return count - 1; /* don't count NUL */ } else { errno = EILSEQ; count = (size_t)-1; } } else { /* s == NULL, get size only, pwcs must be NUL-terminated */ NTSTATUS Status; Status = RtlUnicodeToMultiByteSize((PULONG)&count, (wchar_t *)pwcs, (wcslen(pwcs)+1)*sizeof(WCHAR)); if (NT_SUCCESS(Status)) { return count - 1; /* don't count NUL */ } else { errno = EILSEQ; count = (size_t)-1; } } #endif /* _NTSUBSET_/_POSIX_ */ #else /* _WIN32 */ /* if destination string exists, fill it in */ if (s) { /* C locale: easy and fast */ while(count < n) { if (*pwcs > 255) /* validate high byte */ { errno = EILSEQ; return (size_t)-1; /* error */ } s[count] = (char) *pwcs; if (*pwcs++ == L'\0') return count; count++; } return count; } else { /* s == NULL, get size only, pwcs must be NUL-terminated */ const wchar_t *eos = pwcs; while( *eos++ ) ; return( (size_t)(eos - pwcs - 1) ); } #endif /* _WIN32 */ }
NTSTATUS StreamEditLoadConfig( const WDFKEY key ) { NTSTATUS status = STATUS_SUCCESS; DECLARE_CONST_UNICODE_STRING(stringToFindKey, L"StringToFind"); DECLARE_CONST_UNICODE_STRING(stringToReplaceKey, L"StringToReplace"); DECLARE_CONST_UNICODE_STRING(inspectionPortKey, L"InspectionPort"); DECLARE_CONST_UNICODE_STRING(editInlineKey, L"EditInline"); DECLARE_CONST_UNICODE_STRING(inspectOutboundKey, L"InspectOutbound"); UNICODE_STRING stringValue; WCHAR buffer[128]; USHORT requiredSize; ULONG valueSize; ULONG ulongValue; stringValue.Buffer = buffer; stringValue.Length = 0; stringValue.MaximumLength = sizeof(buffer) - sizeof(buffer[0]); if (NT_SUCCESS( WdfRegistryQueryUnicodeString( key, &stringToFindKey, &requiredSize, &stringValue ))) { stringValue.Buffer[stringValue.Length/sizeof(stringValue.Buffer[0])] = UNICODE_NULL; status = RtlUnicodeToMultiByteN( configStringToFind, sizeof(configStringToFind) - 1, &valueSize, stringValue.Buffer, (ULONG)requiredSize ); if (!NT_SUCCESS(status)) { goto Exit; } configStringToFind[valueSize] = '\0'; } if (NT_SUCCESS( WdfRegistryQueryUnicodeString( key, &stringToReplaceKey, &requiredSize, &stringValue ))) { status = RtlUnicodeToMultiByteN( configStringToReplace, sizeof(configStringToReplace) - 1, &valueSize, stringValue.Buffer, (ULONG)requiredSize ); if (!NT_SUCCESS(status)) { goto Exit; } configStringToReplace[valueSize] = '\0'; } if (NT_SUCCESS( WdfRegistryQueryULong( key, &inspectionPortKey, &ulongValue ))) { configInspectionPort = (USHORT) ulongValue; } if (NT_SUCCESS( WdfRegistryQueryULong( key, &editInlineKey, &ulongValue ))) { configEditInline = (ulongValue != 0); } if (NT_SUCCESS( WdfRegistryQueryULong( key, &inspectOutboundKey, &ulongValue ))) { configInspectionOutbound = (ulongValue != 0); } Exit: return status; }