/********************************************************************* * 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; }
/* * 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; }
BOOL IsUnicodeFullWidth( IN WCHAR wch ) { if (0x20 <= wch && wch <= 0x7e) /* ASCII */ return FALSE; else if (0x3041 <= wch && wch <= 0x3094) /* Hiragana */ return TRUE; else if (0x30a1 <= wch && wch <= 0x30f6) /* Katakana */ return TRUE; else if (0x3105 <= wch && wch <= 0x312c) /* Bopomofo */ return TRUE; else if (0x3131 <= wch && wch <= 0x318e) /* Hangul Elements */ return TRUE; else if (0xac00 <= wch && wch <= 0xd7a3) /* Korean Hangul Syllables */ return TRUE; else if (0xff01 <= wch && wch <= 0xff5e) /* Fullwidth ASCII variants */ return TRUE; else if (0xff61 <= wch && wch <= 0xff9f) /* Halfwidth Katakana variants */ return FALSE; else if ( (0xffa0 <= wch && wch <= 0xffbe) || (0xffc2 <= wch && wch <= 0xffc7) || (0xffca <= wch && wch <= 0xffcf) || (0xffd2 <= wch && wch <= 0xffd7) || (0xffda <= wch && wch <= 0xffdc) ) /* Halfwidth Hangule variants */ return FALSE; else if (0xffe0 <= wch && wch <= 0xffe6) /* Fullwidth symbol variants */ return TRUE; else if (0x4e00 <= wch && wch <= 0x9fa5) /* Han Ideographic */ return TRUE; else if (0xf900 <= wch && wch <= 0xfa2d) /* Han Ideographic Compatibility */ return TRUE; else { #if 0 /* * Hack this block for I don't know FONT of Console Window. * * If you would like perfect result from IsUnicodeFullWidth routine, * then you should enable this block and * you should know FONT of Console Window. */ INT Width; TEXTMETRIC tmi; /* Unknown character */ GetTextMetricsW(hDC, &tmi); if (IS_ANY_DBCS_CHARSET(tmi.tmCharSet)) tmi.tmMaxCharWidth /= 2; GetCharWidth32(hDC, wch, wch, &Width); if (Width == tmi.tmMaxCharWidth) return FALSE; else if (Width == tmi.tmMaxCharWidth*2) return TRUE; #else ULONG MultiByteSize; RtlUnicodeToMultiByteSize(&MultiByteSize, &wch, sizeof(WCHAR)); if (MultiByteSize == 2) return TRUE ; else return FALSE ; #endif } ASSERT(FALSE); return FALSE; #if 0 ULONG MultiByteSize; RtlUnicodeToMultiByteSize(&MultiByteSize, &wch, sizeof(WCHAR)); if (MultiByteSize == 2) return TRUE ; else return FALSE ; #endif }
/****************************************************************** * 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; }
LRESULT WINAPI RealDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT Result = 0; PWND Wnd; Wnd = ValidateHwnd(hWnd); if ( !Wnd && Msg != WM_CTLCOLORMSGBOX && Msg != WM_CTLCOLORBTN && Msg != WM_CTLCOLORDLG && Msg != WM_CTLCOLORSTATIC ) return 0; SPY_EnterMessage(SPY_DEFWNDPROC, hWnd, Msg, wParam, lParam); switch (Msg) { case WM_NCCREATE: { if ( Wnd && Wnd->style & (WS_HSCROLL | WS_VSCROLL) ) { if (!Wnd->pSBInfo) { SCROLLINFO si = {sizeof si, SIF_ALL, 0, 100, 0, 0, 0}; SetScrollInfo( hWnd, SB_HORZ, &si, FALSE ); SetScrollInfo( hWnd, SB_VERT, &si, FALSE ); } } if (lParam) { LPCREATESTRUCTW cs = (LPCREATESTRUCTW)lParam; /* check for string, as static icons, bitmaps (SS_ICON, SS_BITMAP) * may have child window IDs instead of window name */ if (HIWORD(cs->lpszName)) { DefSetText(hWnd, cs->lpszName, FALSE); } Result = 1; } break; } case WM_GETTEXTLENGTH: { PWSTR buf; ULONG len; if (Wnd != NULL && Wnd->strName.Length != 0) { buf = DesktopPtrToUser(Wnd->strName.Buffer); if (buf != NULL && NT_SUCCESS(RtlUnicodeToMultiByteSize(&len, buf, Wnd->strName.Length))) { Result = (LRESULT) (Wnd->strName.Length / sizeof(WCHAR)); } } else Result = 0L; break; } case WM_GETTEXT: { PWSTR buf = NULL; PWSTR outbuf = (PWSTR)lParam; if (Wnd != NULL && wParam != 0) { if (Wnd->strName.Buffer != NULL) buf = DesktopPtrToUser(Wnd->strName.Buffer); else outbuf[0] = L'\0'; if (buf != NULL) { if (Wnd->strName.Length != 0) { Result = min(Wnd->strName.Length / sizeof(WCHAR), wParam - 1); RtlCopyMemory(outbuf, buf, Result * sizeof(WCHAR)); outbuf[Result] = L'\0'; } else outbuf[0] = L'\0'; } } break; } case WM_SETTEXT: { DefSetText(hWnd, (PCWSTR)lParam, FALSE); if ((GetWindowLongPtrW(hWnd, GWL_STYLE) & WS_CAPTION) == WS_CAPTION) UserPaintCaption(hWnd); Result = 1; break; } case WM_IME_CHAR: { PostMessageW(hWnd, WM_CHAR, wParam, lParam); Result = 0; break; } case WM_IME_KEYDOWN: { Result = PostMessageW(hWnd, WM_KEYDOWN, wParam, lParam); break; } case WM_IME_KEYUP: { Result = PostMessageW(hWnd, WM_KEYUP, wParam, lParam); break; } case WM_IME_STARTCOMPOSITION: case WM_IME_COMPOSITION: case WM_IME_ENDCOMPOSITION: case WM_IME_SELECT: case WM_IME_NOTIFY: { HWND hwndIME; hwndIME = DefWndImmGetDefaultIMEWnd(hWnd); if (hwndIME) Result = SendMessageW(hwndIME, Msg, wParam, lParam); break; } case WM_IME_SETCONTEXT: { HWND hwndIME; hwndIME = DefWndImmGetDefaultIMEWnd(hWnd); if (hwndIME) Result = DefWndImmIsUIMessageW(hwndIME, Msg, wParam, lParam); break; } default: Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE); } SPY_ExitMessage(SPY_RESULT_DEFWND, hWnd, Msg, Result, wParam, lParam); return Result; }
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 */ }