Eneboo - Documentación para desarrolladores
|
00001 /**************************************************************************** 00002 ** $Id: qt_windows.h,v 1.2.2.16 2005/08/10 04:35:23 chehrlic Exp $ 00003 ** 00004 ** Windows Specific headers 00005 ** 00006 ** Copyright (C) 2002 Wolfpack Emu. All rights reserved. 00007 ** 00008 ** This file may be distributed under the terms of the Q Public License 00009 ** as defined by Trolltech AS of Norway and appearing in the file 00010 ** LICENSE.QPL included in the packaging of this file. 00011 ** 00012 ** This file may be distributed and/or modified under the terms of the 00013 ** GNU General Public License version 2 as published by the Free Software 00014 ** Foundation and appearing in the file LICENSE.GPL included in the 00015 ** packaging of this file. 00016 ** 00017 **********************************************************************/ 00018 00019 #ifndef QT_WINDOWS_H 00020 #define QT_WINDOWS_H 00021 00022 #if defined(Q_CC_BOR) 00023 // Borland's windows.h does not set these correctly, resulting in 00024 // unusable WinSDK standard dialogs 00025 #ifndef WINVER 00026 #define WINVER 0x400 00027 #endif 00028 #ifndef _WIN32_WINNT 00029 #define _WIN32_WINNT 0x400 00030 #endif 00031 #endif 00032 00033 #ifdef __MINGW32__ 00034 // mingw's windows.h does not set _WIN32_WINNT, resulting breaking compilation 00035 #ifndef WINVER 00036 #define WINVER 0x500 00037 #endif 00038 #endif 00039 00040 #include <windows.h> 00041 00042 #ifdef Q_CYGWIN_WIN 00043 #define WSAGETSELECTEVENT(l) LOWORD(l) 00044 #define FD_READ_BIT 0 00045 #define FD_READ (1 << FD_READ_BIT) 00046 #define FD_WRITE_BIT 1 00047 #define FD_WRITE (1 << FD_WRITE_BIT) 00048 #define FD_OOB_BIT 2 00049 #define FD_OOB (1 << FD_OOB_BIT) 00050 #define FD_ACCEPT_BIT 3 00051 #define FD_ACCEPT (1 << FD_ACCEPT_BIT) 00052 #define FD_CONNECT_BIT 4 00053 #define FD_CONNECT (1 << FD_CONNECT_BIT) 00054 #define FD_CLOSE_BIT 5 00055 #define FD_CLOSE (1 << FD_CLOSE_BIT) 00056 typedef unsigned int SOCKET; 00057 extern "C" int PASCAL WSAAsyncSelect(SOCKET,HWND,unsigned int,long); 00058 #endif 00059 00060 #include "qnamespace.h" 00061 00062 #ifndef QT_SOCKLEN_T 00063 #define QT_SOCKLEN_T int FAR 00064 #endif 00065 00066 void qlasterror( CHAR *msg, DWORD dwLastError, bool showWindow = false ); 00067 00068 #if !defined(SPI_GETKEYBOARDCUES) 00069 #define SPI_GETKEYBOARDCUES 0x100A 00070 #endif 00071 00072 // msvc 6.0 lacks some symbole 00073 #if defined(Q_CC_MSVC) || defined(Q_CC_BOR) 00074 #include <winuser.h> 00075 #endif 00076 00077 #ifndef WM_MOUSEWHEEL 00078 # define WM_MOUSEWHEEL 522 00079 #endif 00080 00081 #ifndef WS_EX_LAYERED 00082 #define WS_EX_LAYERED 0x00080000 00083 #define LWA_COLORKEY 0x00000001 00084 #define LWA_ALPHA 0x00000002 00085 #endif 00086 00087 #ifndef AC_SRC_OVER 00088 #define AC_SRC_OVER 0x00 00089 #endif 00090 #ifndef AC_SRC_ALPHA 00091 #define AC_SRC_ALPHA 0x01 00092 #endif 00093 00094 // already defined when compiled with WINVER >= 0x0500 00095 // and we only use them in Qt::WV_2000 and Qt::WV_98 00096 #ifndef SPI_SETMENUANIMATION 00097 #define SPI_SETMENUANIMATION 0x1003 00098 #endif 00099 #ifndef SPI_SETMENUFADE 00100 #define SPI_SETMENUFADE 0x1013 00101 #endif 00102 #ifndef SPI_SETCOMBOBOXANIMATION 00103 #define SPI_SETCOMBOBOXANIMATION 0x1005 00104 #endif 00105 #ifndef SPI_SETTOOLTIPANIMATION 00106 #define SPI_SETTOOLTIPANIMATION 0x1017 00107 #endif 00108 #ifndef SPI_SETTOOLTIPFADE 00109 #define SPI_SETTOOLTIPFADE 0x1019 00110 #endif 00111 #ifndef SPI_SETUIEFFECTS 00112 #define SPI_SETUIEFFECTS 0x103F 00113 #endif 00114 #ifndef SPI_GETMENUANIMATION 00115 #define SPI_GETMENUANIMATION 0x1002 00116 #endif 00117 #ifndef SPI_GETMENUFADE 00118 #define SPI_GETMENUFADE 0x1012 00119 #endif 00120 #ifndef SPI_GETCOMBOBOXANIMATION 00121 #define SPI_GETCOMBOBOXANIMATION 0x1004 00122 #endif 00123 #ifndef SPI_GETTOOLTIPANIMATION 00124 #define SPI_GETTOOLTIPANIMATION 0x1016 00125 #endif 00126 #ifndef SPI_GETTOOLTIPFADE 00127 #define SPI_GETTOOLTIPFADE 0x1018 00128 #endif 00129 #ifndef SPI_GETUIEFFECTS 00130 #define SPI_GETUIEFFECTS 0x103E 00131 #endif 00132 #ifndef SPI_GETKEYBOARDCUES 00133 #define SPI_GETKEYBOARDCUES 0x100A 00134 #endif 00135 #ifndef IDC_HAND 00136 #define IDC_HAND MAKEINTRESOURCE(32649) 00137 #endif 00138 #ifndef WM_MOUSEWHEEL 00139 #define WM_MOUSEWHEEL 0x020A 00140 #endif 00141 00142 #ifndef WM_MOUSEHOVER 00143 # define WM_MOUSEHOVER 0x2A1 00144 #endif 00145 #ifndef WM_MOUSELEAVE 00146 # define WM_MOUSELEAVE 0x2A3 00147 #endif 00148 00149 #ifndef VK_OEM_PLUS 00150 #define VK_OEM_PLUS 0xBB 00151 #endif 00152 #ifndef VK_OEM_COMMA 00153 #define VK_OEM_COMMA 0xBC 00154 #endif 00155 #ifndef VK_OEM_MINUS 00156 #define VK_OEM_MINUS 0xBD 00157 #endif 00158 #ifndef VK_OEM_PERIOD 00159 #define VK_OEM_PERIOD 0xBE 00160 #endif 00161 00162 #if _MSC_VER < 1300 || defined(Q_CC_BOR) 00163 // missing function 00164 # define __FUNCTION__ "" 00165 # define SetWindowLongPtrA SetWindowLongA 00166 # define SetWindowLongPtrW SetWindowLongW 00167 00168 #endif 00169 00170 00171 #if defined(UNICODE) 00172 #define qt_strncpy wcsncpy 00173 #else 00174 #define qt_strncpy strncpy 00175 #endif 00176 00177 // CCJ - remove for beta release! 00178 // CCJ - uncomment this define to enable backtrace generation on MSVC++. 00179 //#define BACKTRACES 00180 00181 #ifdef BACKTRACES 00182 /* 00183 * Backtrace Generator 00184 * 00185 * Copyright 2004 Eric Poech 00186 * Copyright 2004 Robert Shearman 00187 * 00188 * This library is free software; you can redistribute it and/or 00189 * modify it under the terms of the GNU Lesser General Public 00190 * License as published by the Free Software Foundation; either 00191 * version 2.1 of the License, or (at your option) any later version. 00192 * 00193 * This library is distributed in the hope that it will be useful, 00194 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00195 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00196 * Lesser General Public License for more details. 00197 * 00198 * You should have received a copy of the GNU Lesser General Public 00199 * License along with this library; if not, write to the Free Software 00200 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00201 */ 00202 00203 #include <winver.h> 00204 #include <dbghelp.h> 00205 #include <stdio.h> 00206 00207 void DPRINTF( const char *msg, ... ) 00208 { 00209 char buf[256]; 00210 va_list ap; 00211 va_start( ap, msg ); // use variable arg list 00212 #if defined(QT_VSNPRINTF) 00213 QT_VSNPRINTF( buf, 256, msg, ap ); 00214 #else 00215 vsprintf( buf, msg, ap ); 00216 #endif 00217 va_end( ap ); 00218 // QString fstr( buf ); 00219 // OutputDebugString( fstr.ucs2() ); 00220 OutputDebugStringA (buf); 00221 } 00222 00223 00224 //#define MAKE_FUNCPTR(f) static typeof(f) * p##f 00225 00226 //MAKE_FUNCPTR(StackWalk); 00227 //MAKE_FUNCPTR(SymGetModuleBase); 00228 //MAKE_FUNCPTR(SymFunctionTableAccess); 00229 //MAKE_FUNCPTR(SymInitialize); 00230 //MAKE_FUNCPTR(SymGetSymFromAddr); 00231 //MAKE_FUNCPTR(SymGetModuleInfo); 00232 static BOOL WINAPI (*pStackWalk)( 00233 DWORD MachineType, 00234 HANDLE hProcess, 00235 HANDLE hThread, 00236 LPSTACKFRAME StackFrame, 00237 PVOID ContextRecord, 00238 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, 00239 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, 00240 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, 00241 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress 00242 ); 00243 static DWORD WINAPI (*pSymGetModuleBase)( 00244 HANDLE hProcess, 00245 DWORD dwAddr 00246 ); 00247 static PVOID WINAPI (*pSymFunctionTableAccess)( 00248 HANDLE hProcess, 00249 DWORD AddrBase 00250 ); 00251 static BOOL WINAPI (*pSymInitialize)( 00252 HANDLE hProcess, 00253 PSTR UserSearchPath, 00254 BOOL fInvadeProcess 00255 ); 00256 static BOOL WINAPI (*pSymGetSymFromAddr)( 00257 HANDLE hProcess, 00258 DWORD Address, 00259 PDWORD Displacement, 00260 PIMAGEHLP_SYMBOL Symbol 00261 ); 00262 static BOOL WINAPI (*pSymGetModuleInfo)( 00263 HANDLE hProcess, 00264 DWORD dwAddr, 00265 PIMAGEHLP_MODULE ModuleInfo 00266 ); 00267 static DWORD WINAPI (*pSymSetOptions)( 00268 DWORD SymOptions 00269 ); 00270 00271 00272 static BOOL init_backtrace() 00273 { 00274 HMODULE hmodDbgHelp = LoadLibraryA("dbghelp"); 00275 /* 00276 #define GETFUNC(x) \ 00277 p##x = (typeof(x)*)GetProcAddress(hmodDbgHelp, #x); \ 00278 if (!p##x) \ 00279 { \ 00280 return FALSE; \ 00281 } 00282 */ 00283 00284 00285 // GETFUNC(StackWalk); 00286 // GETFUNC(SymGetModuleBase); 00287 // GETFUNC(SymFunctionTableAccess); 00288 // GETFUNC(SymInitialize); 00289 // GETFUNC(SymGetSymFromAddr); 00290 // GETFUNC(SymGetModuleInfo); 00291 00292 #define FUNC(x) #x 00293 00294 pStackWalk = (BOOL WINAPI (*)( 00295 DWORD MachineType, 00296 HANDLE hProcess, 00297 HANDLE hThread, 00298 LPSTACKFRAME StackFrame, 00299 PVOID ContextRecord, 00300 PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, 00301 PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, 00302 PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, 00303 PTRANSLATE_ADDRESS_ROUTINE TranslateAddress 00304 ))GetProcAddress (hmodDbgHelp, FUNC(StackWalk)); 00305 pSymGetModuleBase=(DWORD WINAPI (*)( 00306 HANDLE hProcess, 00307 DWORD dwAddr 00308 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleBase)); 00309 pSymFunctionTableAccess=(PVOID WINAPI (*)( 00310 HANDLE hProcess, 00311 DWORD AddrBase 00312 ))GetProcAddress (hmodDbgHelp, FUNC(SymFunctionTableAccess)); 00313 pSymInitialize = (BOOL WINAPI (*)( 00314 HANDLE hProcess, 00315 PSTR UserSearchPath, 00316 BOOL fInvadeProcess 00317 ))GetProcAddress (hmodDbgHelp, FUNC(SymInitialize)); 00318 pSymGetSymFromAddr = (BOOL WINAPI (*)( 00319 HANDLE hProcess, 00320 DWORD Address, 00321 PDWORD Displacement, 00322 PIMAGEHLP_SYMBOL Symbol 00323 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetSymFromAddr)); 00324 pSymGetModuleInfo = (BOOL WINAPI (*)( 00325 HANDLE hProcess, 00326 DWORD dwAddr, 00327 PIMAGEHLP_MODULE ModuleInfo 00328 ))GetProcAddress (hmodDbgHelp, FUNC(SymGetModuleInfo)); 00329 pSymSetOptions = (DWORD WINAPI (*)( 00330 DWORD SymOptions 00331 ))GetProcAddress (hmodDbgHelp, FUNC(SymSetOptions)); 00332 00333 00334 pSymSetOptions(SYMOPT_UNDNAME); 00335 00336 pSymInitialize(GetCurrentProcess(), NULL, TRUE); 00337 00338 return TRUE; 00339 } 00340 00341 static void dump_backtrace_for_thread(HANDLE hThread) 00342 { 00343 STACKFRAME sf; 00344 CONTEXT context; 00345 DWORD dwImageType; 00346 00347 if (!pStackWalk) 00348 if (!init_backtrace()) 00349 return; 00350 00351 /* can't use this function for current thread as GetThreadContext 00352 * doesn't support getting context from current thread */ 00353 if (hThread == GetCurrentThread()) 00354 return; 00355 00356 DPRINTF("Backtrace:\n"); 00357 00358 memset(&context, 0, sizeof(context)); 00359 context.ContextFlags = CONTEXT_FULL; 00360 00361 SuspendThread(hThread); 00362 00363 if (!GetThreadContext(hThread, &context)) 00364 { 00365 DPRINTF("Couldn't get thread context (error %ld)\n", GetLastError()); 00366 ResumeThread(hThread); 00367 return; 00368 } 00369 00370 memset(&sf, 0, sizeof(sf)); 00371 00372 #ifdef __i386__ 00373 sf.AddrFrame.Offset = context.Ebp; 00374 sf.AddrFrame.Mode = AddrModeFlat; 00375 sf.AddrPC.Offset = context.Eip; 00376 sf.AddrPC.Mode = AddrModeFlat; 00377 dwImageType = IMAGE_FILE_MACHINE_I386; 00378 #else 00379 # error You need to fill in the STACKFRAME structure for your architecture 00380 #endif 00381 00382 while (pStackWalk(dwImageType, GetCurrentProcess(), 00383 hThread, &sf, &context, NULL, pSymFunctionTableAccess, 00384 pSymGetModuleBase, NULL)) 00385 { 00386 BYTE buffer[256]; 00387 IMAGEHLP_SYMBOL * pSymbol = (IMAGEHLP_SYMBOL *)buffer; 00388 DWORD dwDisplacement; 00389 00390 pSymbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL); 00391 pSymbol->MaxNameLength = sizeof(buffer) - sizeof(IMAGEHLP_SYMBOL) + 1; 00392 00393 if (!pSymGetSymFromAddr(GetCurrentProcess(), sf.AddrPC.Offset, 00394 &dwDisplacement, pSymbol)) 00395 { 00396 IMAGEHLP_MODULE ModuleInfo; 00397 ModuleInfo.SizeOfStruct = sizeof(ModuleInfo); 00398 00399 if (!pSymGetModuleInfo(GetCurrentProcess(), sf.AddrPC.Offset, 00400 &ModuleInfo)) 00401 DPRINTF("1\t%p\n", (void*)sf.AddrPC.Offset); 00402 else 00403 DPRINTF("2\t%s+0x%lx\n", ModuleInfo.ImageName, 00404 sf.AddrPC.Offset - ModuleInfo.BaseOfImage); 00405 } 00406 else if (dwDisplacement) 00407 DPRINTF("3\t%s+0x%lx\n", pSymbol->Name, dwDisplacement); 00408 else 00409 DPRINTF("4\t%s\n", pSymbol->Name); 00410 } 00411 00412 ResumeThread(hThread); 00413 } 00414 00415 static DWORD WINAPI dump_thread_proc(LPVOID lpParameter) 00416 { 00417 dump_backtrace_for_thread((HANDLE)lpParameter); 00418 return 0; 00419 } 00420 00421 /* cannot get valid context from current thread, so we have to execute 00422 * backtrace from another thread */ 00423 static void dump_backtrace() 00424 { 00425 HANDLE hCurrentThread; 00426 HANDLE hThread; 00427 DWORD dwThreadId; 00428 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), 00429 GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS); 00430 hThread = CreateThread(NULL, 0, dump_thread_proc, (LPVOID)hCurrentThread, 00431 0, &dwThreadId); 00432 WaitForSingleObject(hThread, INFINITE); 00433 CloseHandle(hThread); 00434 CloseHandle(hCurrentThread); 00435 } 00436 #endif 00437 00438 #endif