diff options
Diffstat (limited to 'vcl/win/source/app')
-rw-r--r-- | vcl/win/source/app/MAKEFILE.MK | 40 | ||||
-rw-r--r-- | vcl/win/source/app/saldata.cxx | 267 | ||||
-rw-r--r-- | vcl/win/source/app/salinfo.cxx | 884 | ||||
-rw-r--r-- | vcl/win/source/app/salinst.cxx | 897 | ||||
-rw-r--r-- | vcl/win/source/app/salshl.cxx | 198 | ||||
-rw-r--r-- | vcl/win/source/app/saltimer.cxx | 152 |
6 files changed, 2438 insertions, 0 deletions
diff --git a/vcl/win/source/app/MAKEFILE.MK b/vcl/win/source/app/MAKEFILE.MK new file mode 100644 index 000000000000..f53f534b69a1 --- /dev/null +++ b/vcl/win/source/app/MAKEFILE.MK @@ -0,0 +1,40 @@ +#************************************************************************* +#* +#* $Workfile: makefile. $ +#* +#* Ersterstellung TH 01.04.97 +#* Letzte Aenderung $Author: hr $ $Date: 2000-09-18 17:05:49 $ +#* $Revision: 1.1.1.1 $ +#* +#* $Logfile: T:/sv2/win/source/app/makefile.__v $ +#* +#* Copyright (c) 1990 - 2000, STAR DIVISION +#* +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=vcl +TARGET=salapp + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +OBJFILES= $(OBJ)$/salmain.obj + +SLOFILES= $(SLO)$/salshl.obj \ + $(SLO)$/saldata.obj \ + $(SLO)$/salinst.obj \ + $(SLO)$/saltimer.obj \ + $(SLO)$/salsound.obj \ + $(SLO)$/salinfo.obj \ + $(SLO)$/salsys.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/vcl/win/source/app/saldata.cxx b/vcl/win/source/app/saldata.cxx new file mode 100644 index 000000000000..7142badf3a20 --- /dev/null +++ b/vcl/win/source/app/saldata.cxx @@ -0,0 +1,267 @@ +/************************************************************************* + * + * $RCSfile: saldata.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVWIN_H +#include <tools/svwin.h> +#endif + +#define _SV_SALDATA_CXX + +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif + +// ======================================================================= + +rtl_TextEncoding ImplSalGetSystemEncoding() +{ + static UINT nOldAnsiCodePage = 0; + static rtl_TextEncoding eEncoding = RTL_TEXTENCODING_MS_1252; + + UINT nAnsiCodePage = GetACP(); + if ( nAnsiCodePage != nOldAnsiCodePage ) + { + switch ( nAnsiCodePage ) + { + case 1252: + eEncoding = RTL_TEXTENCODING_MS_1252; + break; + case 1250: + eEncoding = RTL_TEXTENCODING_MS_1250; + break; + case 1251: + eEncoding = RTL_TEXTENCODING_MS_1251; + break; + case 1253: + eEncoding = RTL_TEXTENCODING_MS_1253; + break; + case 1254: + eEncoding = RTL_TEXTENCODING_MS_1254; + break; + case 1255: + eEncoding = RTL_TEXTENCODING_MS_1255; + break; + case 1256: + eEncoding = RTL_TEXTENCODING_MS_1256; + break; + case 1257: + eEncoding = RTL_TEXTENCODING_MS_1257; + break; + case 1258: + eEncoding = RTL_TEXTENCODING_MS_1258; + break; + case 874: + eEncoding = RTL_TEXTENCODING_MS_874; + break; + case 932: + eEncoding = RTL_TEXTENCODING_MS_932; + break; + case 936: + eEncoding = RTL_TEXTENCODING_MS_936; + break; + case 949: + eEncoding = RTL_TEXTENCODING_MS_949; + break; + case 950: + eEncoding = RTL_TEXTENCODING_MS_950; + break; +// case 1381: +// eEncoding = RTL_TEXTENCODING_MS_1381; +// break; + } + } + + return eEncoding; +} + +// ----------------------------------------------------------------------- + +ByteString ImplSalGetWinAnsiString( const UniString& rStr, BOOL bFileName ) +{ + rtl_TextEncoding eEncoding = ImplSalGetSystemEncoding(); + if ( bFileName ) + { + return ByteString( rStr, eEncoding, + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_UNDERLINE | + RTL_UNICODETOTEXT_FLAGS_INVALID_UNDERLINE | + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE | + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR | + RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 ); + } + else + { + return ByteString( rStr, eEncoding, + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_DEFAULT | + RTL_UNICODETOTEXT_FLAGS_INVALID_DEFAULT | + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE | + RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACESTR | + RTL_UNICODETOTEXT_FLAGS_PRIVATE_MAPTO0 ); + } +} + +// ----------------------------------------------------------------------- + +UniString ImplSalGetUniString( const sal_Char* pStr, xub_StrLen nLen ) +{ + return UniString( pStr, nLen, ImplSalGetSystemEncoding(), + RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_DEFAULT | + RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT | + RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT ); +} + +// ======================================================================= + +int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 ) +{ + int nRet; + wchar_t c1; + char c2; + do + { + // Ist das Zeichen zwischen 'A' und 'Z' dann umwandeln + c1 = *pStr1; + c2 = *pStr2; + if ( (c1 >= 65) && (c1 <= 90) ) + c1 += 32; + if ( (c2 >= 65) && (c2 <= 90) ) + c2 += 32; + nRet = ((sal_Int32)c1)-((sal_Int32)((unsigned char)c2)); + if ( nRet != 0 ) + break; + + pStr1++; + pStr2++; + } + while ( c2 ); + + return nRet; +} + +// ======================================================================= + +LONG ImplSetWindowLong( HWND hWnd, int nIndex, DWORD dwNewLong ) +{ + if ( aSalShlData.mbWNT ) + return SetWindowLongW( hWnd, nIndex, dwNewLong ); + else + return SetWindowLongA( hWnd, nIndex, dwNewLong ); +} + +// ----------------------------------------------------------------------- + +LONG ImplGetWindowLong( HWND hWnd, int nIndex ) +{ + if ( aSalShlData.mbWNT ) + return GetWindowLongW( hWnd, nIndex ); + else + return GetWindowLongA( hWnd, nIndex ); +} + +// ----------------------------------------------------------------------- + +WIN_BOOL ImplPostMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) +{ + if ( aSalShlData.mbWNT ) + return PostMessageW( hWnd, nMsg, wParam, lParam ); + else + return PostMessageA( hWnd, nMsg, wParam, lParam ); +} + +// ----------------------------------------------------------------------- + +WIN_BOOL ImplSendMessage( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) +{ + if ( aSalShlData.mbWNT ) + return SendMessageW( hWnd, nMsg, wParam, lParam ); + else + return SendMessageA( hWnd, nMsg, wParam, lParam ); +} + +// ----------------------------------------------------------------------- + +WIN_BOOL ImplGetMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax ) +{ + if ( aSalShlData.mbWNT ) + return GetMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax ); + else + return GetMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax ); +} + +// ----------------------------------------------------------------------- + +WIN_BOOL ImplPeekMessage( LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg ) +{ + if ( aSalShlData.mbWNT ) + return PeekMessageW( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg ); + else + return PeekMessageA( lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg ); +} + +// ----------------------------------------------------------------------- + +LONG ImplDispatchMessage( CONST MSG *lpMsg ) +{ + if ( aSalShlData.mbWNT ) + return DispatchMessageW( lpMsg ); + else + return DispatchMessageA( lpMsg ); +} + diff --git a/vcl/win/source/app/salinfo.cxx b/vcl/win/source/app/salinfo.cxx new file mode 100644 index 000000000000..97a3b0c97e35 --- /dev/null +++ b/vcl/win/source/app/salinfo.cxx @@ -0,0 +1,884 @@ +/************************************************************************* + * + * $RCSfile: salinfo.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifdef ENABLEUNICODE + +#define VCL_NEED_BASETSD + +#include <tools/presys.h> +#include <windows.h> +#include <imagehlp.h> +#include <tools/postsys.h> + +#include <salsys.hxx> + +/* !!! UNICODE !!! */ +XubString SalSystem::GetSummarySystemInfos( ULONG nFlags ) +{ + return XubString(); +} + +#else + +#define VCL_NEED_BASETSD + +#include <tools/presys.h> +#include <windows.h> +#include <imagehlp.h> +#include <tools/postsys.h> + +#include <stdio.h> +#include <tools/string.hxx> +#include <salsys.hxx> + +// Wegen Stacktrace-Generierung +#pragma optimize ("", off) + +// #include <tlhelp32.h> +// ToolHelp32 +#define MAX_MODULE_NAME32 255 +#define TH32CS_SNAPMODULE 0x00000008 + +typedef struct tagMODULEENTRY32 +{ + DWORD dwSize; + DWORD th32ModuleID; // This module + DWORD th32ProcessID; // owning process + DWORD GlblcntUsage; // Global usage count on the module + DWORD ProccntUsage; // Module usage count in th32ProcessID's context + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + HMODULE hModule; // The hModule of this module in th32ProcessID's context + char szModule[MAX_MODULE_NAME32 + 1]; + char szExePath[MAX_PATH]; +} MODULEENTRY32; +typedef MODULEENTRY32 * PMODULEENTRY32; +typedef MODULEENTRY32 * LPMODULEENTRY32; + +// PSAPI functions - Windows NT only +typedef struct _MODULEINFO { + LPVOID lpBaseOfDll; + DWORD SizeOfImage; + LPVOID EntryPoint; +} MODULEINFO, *LPMODULEINFO; + + + +// PSAPI +typedef BOOL (WINAPI *ENUMPROCESSMODULESPROC)( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded ); +typedef BOOL (WINAPI *GETMODULEINFORMATIONPROC)( HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb ); +typedef DWORD (WINAPI *GETMODULEBASENAMEAPROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize ); +typedef DWORD (WINAPI *GETMODULEFILENAMEEXAPROC)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); +typedef HANDLE (WINAPI *CREATESNAPSHOTPROC)(DWORD dwFlags, DWORD th32ProcessID); +typedef BOOL (WINAPI *MODULE32FIRSTPROC)( HANDLE hSnapshot, LPMODULEENTRY32 lpme ); +typedef BOOL (WINAPI *MODULE32NEXTPROC)( HANDLE hSnapshot, LPMODULEENTRY32 lpme ); + + +// ImageHlp +typedef int (__stdcall *STACKWALKPROC) ( DWORD, HANDLE, HANDLE, LPSTACKFRAME, PVOID, PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE ); +typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)( HANDLE, DWORD ); +typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)( HANDLE, DWORD ); +typedef DWORD (__stdcall *SYMSETOPTIONSPROC ) (DWORD dwSymOptions); +typedef int (__stdcall *SYMINITIALIZEPROC ) ( HANDLE, LPSTR, int ); +typedef int (__stdcall *SYMCLEANUPPROC)( HANDLE ); +typedef DWORD (__stdcall WINAPI *UNDECORATESYMBOLNAMEPROC)( PCSTR, PSTR, DWORD, DWORD ); +typedef DWORD (__stdcall *SYMLOADMODULEPROC) ( HANDLE, HANDLE, LPSTR, LPSTR, DWORD, DWORD ); +typedef int (__stdcall *SYMGETSYMFROMADDR)( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL ); + + +struct ModuleInfo +{ + struct ModuleInfo* pNext; + + char szModBaseName[MAX_PATH]; + char szModFileName[MAX_PATH]; + unsigned long nBaseAddress; + unsigned long nSize; +// unsigned long nEntryPoint; +// HANDLE nHandle; +// PIMAGE_DEBUG_INFORMATION pDebugInfos; +}; + +struct ModuleInfo* FindModuleContainingAddress( struct ModuleInfo* pStart, void* pAddr ); + + + +struct SystemInfos +{ + DWORD nCurrentProcessId; + HANDLE hCurrentProcess; + DWORD nCurrentThreadId; + HANDLE hCurrentThread; + + ModuleInfo* pModInfos; + + String aStack; + String aModules; + String aSystemVersion; + String aCPUType; + String aMemoryInfo; + String aLocalVolumes; + String aSystemDirs; + String aMouseInfo; + + SystemInfos() + { + nCurrentProcessId = 0; + hCurrentProcess = 0; + hCurrentThread = 0; + pModInfos = NULL; + } +}; + +void DebugThread( SystemInfos* pSysInfos ); + + +typedef struct _Thread +{ + DWORD dwThreadId; + HANDLE hThread; +} Thread; + + +struct ModuleInfo* WNT_CreateModuleInfos(); + +String ImplCreateToken( const String& rToken ) +{ + String aToken( '<' ); + aToken += rToken; + aToken += ' '; + while ( aToken.Len() < 25 ) + aToken += '-'; + aToken += '>'; + return aToken; +} + + + +String WNT_CreateModulePath( struct ModuleInfo* pModInfos ) +{ + String aPath; + struct ModuleInfo* pM = pModInfos; + while ( pM ) + { + String aTmpPath = pM->szModFileName; + USHORT n = aTmpPath.SearchBackward( '\\' ); + if ( n != STRING_NOTFOUND ) + aTmpPath.Erase( n ); + aTmpPath += ';'; + aTmpPath.ToLower(); + if ( aPath.Search( aTmpPath ) == STRING_NOTFOUND ) + aPath += aTmpPath; + + pM = pM->pNext; + } + return aPath; +} + + +struct ModuleInfo* WNT_CreateModuleInfos() +{ + struct ModuleInfo* pModInfos = NULL; + + OSVERSIONINFO aOSVersion; + aOSVersion.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + if ( GetVersionEx( &aOSVersion ) ) + { + if ( aOSVersion.dwPlatformId == VER_PLATFORM_WIN32_NT ) + { + HINSTANCE hPSAPILib = LoadLibrary( "PSAPI.DLL" ); + if( hPSAPILib ) + { + ENUMPROCESSMODULESPROC _fpEnumProcessModules = (ENUMPROCESSMODULESPROC) GetProcAddress( hPSAPILib, "EnumProcessModules" ); + GETMODULEINFORMATIONPROC _fpGetModuleInformation = (GETMODULEINFORMATIONPROC) GetProcAddress( hPSAPILib, "GetModuleInformation" ); + GETMODULEBASENAMEAPROC _fpGetModuleBaseNameA = (GETMODULEBASENAMEAPROC) GetProcAddress( hPSAPILib, "GetModuleBaseNameA" ); + GETMODULEFILENAMEEXAPROC _fpGetModuleFileNameExA = (GETMODULEFILENAMEEXAPROC) GetProcAddress( hPSAPILib, "GetModuleFileNameExA" ); + + HANDLE hProcess = GetCurrentProcess(); + HMODULE hMods[1024]; + DWORD cbNeeded; + if( _fpEnumProcessModules( hProcess, hMods, sizeof(hMods), &cbNeeded ) ) + { + int nMods = cbNeeded / sizeof( HMODULE ); + int nArrSz = nMods * sizeof( struct ModuleInfo ); + pModInfos = (struct ModuleInfo*) malloc( nArrSz ); + memset( pModInfos, 0, nArrSz ); + + for ( int i = 0; i < nMods; i++ ) + { + pModInfos[i].pNext = 0; + if ( i ) + pModInfos[i-1].pNext = &pModInfos[i]; + + _fpGetModuleBaseNameA( hProcess, hMods[i], pModInfos[i].szModBaseName, sizeof( pModInfos[i].szModBaseName ) ); + _fpGetModuleFileNameExA( hProcess, hMods[i], pModInfos[i].szModFileName, sizeof( pModInfos[i].szModFileName ) ); + + MODULEINFO aInf; + if ( _fpGetModuleInformation( hProcess, hMods[i], &aInf, sizeof( aInf ) ) ) + { + pModInfos[i].nBaseAddress = (unsigned long) aInf.lpBaseOfDll; + pModInfos[i].nSize = aInf.SizeOfImage; + // pModInfos[i].nEntryPoint = (unsigned long) aInf.EntryPoint; + } + } + } + FreeLibrary( hPSAPILib ); + } + } + else if ( aOSVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) + { + HINSTANCE hToolHelpLib = LoadLibrary( "KERNEL32.DLL" ); + if( hToolHelpLib ) + { + CREATESNAPSHOTPROC _fpCreateSnapshot = (CREATESNAPSHOTPROC) GetProcAddress( hToolHelpLib, "CreateToolhelp32Snapshot" ); + MODULE32FIRSTPROC _fpModule32First = (MODULE32FIRSTPROC) GetProcAddress( hToolHelpLib, "Module32First" ); + MODULE32NEXTPROC _fpModule32Next = (MODULE32NEXTPROC) GetProcAddress( hToolHelpLib, "Module32Next" ); + + HANDLE hSnap = _fpCreateSnapshot( TH32CS_SNAPMODULE, 0 ); + if ( hSnap ) + { + MODULEENTRY32 aMod32Entry; + ZeroMemory( &aMod32Entry, sizeof( MODULEENTRY32 ) ); + aMod32Entry.dwSize = sizeof( MODULEENTRY32 ); + int nMods = 0; + BOOL bMod = _fpModule32First( hSnap, &aMod32Entry ); + while ( bMod ) + { + nMods++; + bMod = _fpModule32Next( hSnap, &aMod32Entry ); + } + + int nArrSz = nMods * sizeof( struct ModuleInfo ); + pModInfos = (struct ModuleInfo*) malloc( nArrSz ); + memset( pModInfos, 0, nArrSz ); + + int nMod = 0; + bMod = _fpModule32First( hSnap, &aMod32Entry ); + while ( bMod ) + { + pModInfos[nMod].pNext = 0; + if ( nMod ) + pModInfos[nMod-1].pNext = &pModInfos[nMod]; + + strcpy( pModInfos[nMod].szModBaseName, aMod32Entry.szModule ); + strcpy( pModInfos[nMod].szModFileName, aMod32Entry.szExePath ); + pModInfos[nMod].nBaseAddress = (unsigned long) aMod32Entry.modBaseAddr; + pModInfos[nMod].nSize = aMod32Entry.modBaseSize; +// pModInfos[nMod].nEntryPoint = 0xFFFFFFFF; + + bMod = _fpModule32Next( hSnap, &aMod32Entry ); + nMod++; + } + + CloseHandle( hSnap ); + } + + FreeLibrary( hToolHelpLib ); + } + } + } + return pModInfos; +} + +BOOL WNT_GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset ) +{ + MEMORY_BASIC_INFORMATION mbi; + + if( VirtualQuery( addr, &mbi, sizeof(mbi) ) && mbi.AllocationBase ) + { + DWORD hMod = (DWORD)mbi.AllocationBase; + + if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) ) + return FALSE; + + // Point to the DOS header in memory + PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod; + + // From the DOS header, find the NT (PE) header + PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew); + + PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr ); + + DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address + + // Iterate through the section table, looking for the one that encompasses + // the linear address. + for ( unsigned i = 0; + i < pNtHdr->FileHeader.NumberOfSections; + i++, pSection++ ) + { + DWORD sectionStart = pSection->VirtualAddress; + DWORD sectionEnd = sectionStart + + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize); + + // Is the address in this section??? + if ( (rva >= sectionStart) && (rva <= sectionEnd) ) + { + // Yes, address is in the section. Calculate section and offset, + // and store in the "section" & "offset" params, which were + // passed by reference. + section = i+1; + offset = rva - sectionStart; + return TRUE; + } + } + } + return FALSE; +} + + +struct ModuleInfo* FindModuleContainingAddress( struct ModuleInfo* pStart, void* pAddr ) +{ + struct ModuleInfo* pRet = NULL; + struct ModuleInfo* pM = pStart; + unsigned long nAddr = (unsigned long) pAddr; + + while ( pM && !pRet ) + { + if ( ( nAddr >= pM->nBaseAddress ) && + ( nAddr < ( pM->nBaseAddress + pM->nSize ) ) ) + { + pRet = pM; + } + else + { + pM = pM->pNext; + } + } + return pRet; +} + +String _OLD_GetStackInfo() +{ + // Try an other way... + String aTmpStack; + ModuleInfo* pMods = WNT_CreateModuleInfos(); + + ULONG* pBP; + __asm mov pBP, ebp; + char buffer[1024]; + + for ( int i = 0; i < 15; i++ ) + { + ULONG nIP = pBP[1]; + sprintf( buffer, "[%.2u] IP=%.8lx", i, nIP ); + aTmpStack += buffer; + + ModuleInfo* pI = FindModuleContainingAddress( pMods, (void*)nIP ); + if ( pI ) + { + sprintf( buffer, " (Rel=%.8lx) [%s, Base=%.8lx, Path=%s]", nIP-pI->nBaseAddress-0x1000, pI->szModBaseName, pI->nBaseAddress, pI->szModFileName ); + aTmpStack += buffer; + } + + if ( !pI || (pBP[0] & 3) || (ULONG)pBP > pBP[0] ) + { + aTmpStack += "\nError!\n"; + break; + } + + aTmpStack += '\n'; + pBP = (ULONG*) pBP[0]; + } + + // Modul-Infos zerstoeren... + return aTmpStack; +} + +String SalSystem::GetSummarySystemInfos( ULONG nFlags) +{ + SystemInfos aSysInfos; + HANDLE nCurrentThreadPseudo = GetCurrentThread(); + HANDLE nCurrentProcessPseudo = GetCurrentProcess(); + aSysInfos.nCurrentThreadId = GetCurrentThreadId(); + DuplicateHandle( nCurrentProcessPseudo, nCurrentThreadPseudo, nCurrentProcessPseudo, + &aSysInfos.hCurrentThread, PROCESS_ALL_ACCESS, TRUE, 0 ); + aSysInfos.nCurrentProcessId = GetCurrentProcessId(); + DuplicateHandle( nCurrentProcessPseudo, nCurrentProcessPseudo, nCurrentProcessPseudo, + &aSysInfos.hCurrentProcess, PROCESS_ALL_ACCESS, TRUE, 0 ); + + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_STACK ) + { + DWORD nDebugThreadId; + HANDLE hDebugThread = CreateThread( + NULL, 16000, + (LPTHREAD_START_ROUTINE)DebugThread, &aSysInfos, + 0, &nDebugThreadId ); + + WaitForSingleObject( hDebugThread, INFINITE ); + CloseHandle( hDebugThread ); + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MODULES ) + { + aSysInfos.aModules = "<Modules>\n"; + char buffer[1024]; + if ( !aSysInfos.pModInfos ) + aSysInfos.pModInfos = WNT_CreateModuleInfos(); + struct ModuleInfo* pM = aSysInfos.pModInfos; + while ( pM ) + { + aSysInfos.aModules += " <Module name=\""; + aSysInfos.aModules += pM->szModBaseName; + aSysInfos.aModules += "\" path=\""; + aSysInfos.aModules += pM->szModFileName; + aSysInfos.aModules += "\" >\n"; + aSysInfos.aModules += " <ModuleInfo name=\"BASE\" value=\""; + sprintf( buffer, "%.8lx", pM->nBaseAddress ); + aSysInfos.aModules += buffer; + aSysInfos.aModules += "\" />\n"; + aSysInfos.aModules += " <ModuleInfo name=\"Size\" value=\""; + aSysInfos.aModules += pM->nSize; + aSysInfos.aModules += "\" />\n </Module>\n"; + pM = pM->pNext; + } + aSysInfos.aModules += "</Modules>"; + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMVERSION ) + { + aSysInfos.aSystemVersion = "<System name=\""; + OSVERSIONINFO aVersionInfos; + memset(&aVersionInfos, 0, sizeof( OSVERSIONINFO ) ); + aVersionInfos.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); + GetVersionEx( &aVersionInfos ); + if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32s ) + aSysInfos.aSystemVersion += "Microsoft Win32s"; + else if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32_NT ) + aSysInfos.aSystemVersion += "Microsoft Windows NT"; + else if ( aVersionInfos.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) + { + if ( !aVersionInfos.dwMinorVersion ) + aSysInfos.aSystemVersion += "Microsoft Windows 95"; + else + aSysInfos.aSystemVersion += "Microsoft Windows 98"; + } + else + aSysInfos.aSystemVersion += "Unknown Windows"; + aSysInfos.aSystemVersion += "\" version=\""; + aSysInfos.aSystemVersion += aVersionInfos.dwMajorVersion; + aSysInfos.aSystemVersion += '.'; + aSysInfos.aSystemVersion += aVersionInfos.dwMinorVersion; + aSysInfos.aSystemVersion += "\" build=\""; + aSysInfos.aSystemVersion += aVersionInfos.dwBuildNumber&0xFFFF; + aSysInfos.aSystemVersion += "\" />"; + + // aSysInfos.aSystemVersion += aVersionInfos.szCSDVersion; + /* + Under both Windows NT and Windows 95, you can get the + language information in the FileVersionInfo of User.exe by + calling GetFileVersionInfo, and then + VerQueryValue (on \\VarFileInfo\\Translation") on the + VersionInfo block of the operating system's User.exe. + NOTE: This method is the most reliable. It works well under + both Windows NT and Windows 95. This method also works for + Windows 3.1 + */ +// DWORD nDefInputLanguage; +// if ( SystemParametersInfo( SPI_GETDEFAULTINPUTLANG, 0, &nDefInputLanguage, 0 ) ) +// { +// aSysInfos.aSystemVersion += " default input language = "; +// aSysInfos.aSystemVersion += nDefInputLanguage; +// } + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_CPUTYPE ) + { + SYSTEM_INFO aSystemInfo; + memset( &aSystemInfo, 0, sizeof( SYSTEM_INFO ) ); + GetSystemInfo( &aSystemInfo ); + aSysInfos.aCPUType = "<CPU count=\""; + aSysInfos.aCPUType += aSystemInfo.dwNumberOfProcessors; + aSysInfos.aCPUType += "\" type=\""; + if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) + aSysInfos.aCPUType += "X86"; + else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) + aSysInfos.aCPUType += "MIPS"; + else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) + aSysInfos.aCPUType += "ALPHA"; + else if ( aSystemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ) + aSysInfos.aCPUType += "PPC"; + else + aSysInfos.aCPUType += "unknown"; + aSysInfos.aCPUType += "\"></CPU>"; + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MEMORYINFO ) + { + MEMORYSTATUS aMemStatus; + memset( &aMemStatus, 0, sizeof( MEMORYSTATUS ) ); + GlobalMemoryStatus( &aMemStatus ); + aSysInfos.aMemoryInfo = "<Memory>\n"; + aSysInfos.aMemoryInfo += " <MemoryType name=\"Physical\" total=\""; + aSysInfos.aMemoryInfo += (aMemStatus.dwTotalPhys+512)/1024/1024+1; + aSysInfos.aMemoryInfo += " MB\" free=\""; + aSysInfos.aMemoryInfo += (aMemStatus.dwAvailPhys+512)/1024/1024+1; + aSysInfos.aMemoryInfo += " MB\" />\n"; + aSysInfos.aMemoryInfo += " <MemoryType name=\"Swap\" total=\""; + aSysInfos.aMemoryInfo += (aMemStatus.dwTotalPageFile+512)/1024/1024+1; + aSysInfos.aMemoryInfo += " MB\" free=\""; + aSysInfos.aMemoryInfo += (aMemStatus.dwAvailPageFile+512)/1024/1024+1; + aSysInfos.aMemoryInfo += " MB\" />\n"; + aSysInfos.aMemoryInfo += " <MemoryType name=\"Virtual\" total=\""; + aSysInfos.aMemoryInfo += (aMemStatus.dwTotalVirtual+512)/1024/1024+1; + aSysInfos.aMemoryInfo += " MB\" free=\""; + aSysInfos.aMemoryInfo += (aMemStatus.dwAvailVirtual+512)/1024/1024+1; + aSysInfos.aMemoryInfo += " MB\" />\n"; + aSysInfos.aMemoryInfo += "</Memory>"; + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_LOCALVOLUMES ) + { + aSysInfos.aLocalVolumes = "<LocalVolumes>\n"; + char aDriveStrings[4096]; + GetLogicalDriveStrings( 4096, aDriveStrings ); + LPTSTR pDriveStr = aDriveStrings; + while ( *pDriveStr ) + { + UINT nType = GetDriveType( pDriveStr ); + if ( nType != DRIVE_REMOTE ) + { + aSysInfos.aLocalVolumes += " <LocalVolume type=\""; + + switch ( nType ) + { + case DRIVE_REMOVABLE: aSysInfos.aLocalVolumes += "Removable"; break; + case DRIVE_FIXED: aSysInfos.aLocalVolumes += "Fixed"; break; + case DRIVE_REMOTE: aSysInfos.aLocalVolumes += "Remote"; break; + case DRIVE_CDROM: aSysInfos.aLocalVolumes += "CD-ROM"; break; + case DRIVE_RAMDISK: aSysInfos.aLocalVolumes += "RAM disk"; break; + default: aSysInfos.aLocalVolumes += "Unkown"; + } + aSysInfos.aLocalVolumes += "\" path=\""; + aSysInfos.aLocalVolumes += pDriveStr; + aSysInfos.aLocalVolumes += "\""; + if( nType == DRIVE_FIXED ) + { + DWORD nSectorsPerCluster; + DWORD nBytesPerSector; + DWORD nNumberFreeClusters; + DWORD nNumberTotalClusters; + if( GetDiskFreeSpace( pDriveStr, &nSectorsPerCluster, &nBytesPerSector, &nNumberFreeClusters, &nNumberTotalClusters ) ) + { + DWORD nUnitsPerCluster = nSectorsPerCluster*nBytesPerSector; + DWORD nUnitDivi = 1; + String aUnit = "bytes"; + if( ( nUnitsPerCluster % 1024 ) == 0 ) + { + aUnit = "KB"; + nUnitsPerCluster /= 1024; + } + else if( ( nUnitsPerCluster % 512 ) == 0 ) + { + aUnit = "KB"; + nUnitDivi = 1024; + } + DWORD nFree = nNumberFreeClusters*nUnitsPerCluster/nUnitDivi; + aSysInfos.aLocalVolumes += " free=\""; + aSysInfos.aLocalVolumes += nFree; + aSysInfos.aLocalVolumes += ' '; + aSysInfos.aLocalVolumes += aUnit; + aSysInfos.aLocalVolumes += "\""; + } + } + aSysInfos.aLocalVolumes += " />\n"; + } + while ( *pDriveStr ) + pDriveStr++; + pDriveStr++; + } + aSysInfos.aLocalVolumes += "</LocalVolumes>"; + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_SYSTEMDIRS ) + { + aSysInfos.aSystemDirs = "<SystemDirs>\n"; + char buffer[ MAX_PATH ]; + aSysInfos.aSystemDirs += " <SystemDir envname=\"Windows\" path=\""; + if( GetWindowsDirectory( buffer, MAX_PATH ) ) + aSysInfos.aSystemDirs += buffer; + aSysInfos.aSystemDirs += "\" />\n"; + + aSysInfos.aSystemDirs += " <SystemDir envname=\"System\" path=\""; + if( GetSystemDirectory( buffer, MAX_PATH ) ) + aSysInfos.aSystemDirs += buffer; + aSysInfos.aSystemDirs += "\" />\n"; + + aSysInfos.aSystemDirs += " <SystemDir envname=\"Current\" path=\""; + if( GetCurrentDirectory( MAX_PATH, buffer ) ) + aSysInfos.aSystemDirs += buffer; + aSysInfos.aSystemDirs += "\" />\n"; + + aSysInfos.aSystemDirs += " <SystemDir envname=\"Temp\" path=\""; + if( GetTempPath( MAX_PATH, buffer ) ) + aSysInfos.aSystemDirs += buffer; + aSysInfos.aSystemDirs += "\" />\n"; + aSysInfos.aSystemDirs += "</SystemDirs>"; + + } + if ( nFlags & SALSYSTEM_GETSYSTEMINFO_MOUSEINFO ) + { + aSysInfos.aMouseInfo = "<Mouse "; + int nRet = GetSystemMetrics( SM_CMOUSEBUTTONS ); + if ( nRet ) + { + aSysInfos.aMouseInfo += "buttons=\""; + aSysInfos.aMouseInfo += nRet; + aSysInfos.aMouseInfo += "\" description=\""; + if( GetSystemMetrics( 75 /*SM_MOUSEWHEELPRESENT - missing in SDK from MSVC4.2 */ ) ) + aSysInfos.aMouseInfo += "wheel mouse"; + else + aSysInfos.aMouseInfo += "standard mouse"; + aSysInfos.aMouseInfo += "\""; + } + else + { + aSysInfos.aMouseInfo += "description=\"Not installed.\""; + } + aSysInfos.aMouseInfo += " />"; + } + + CloseHandle( aSysInfos.hCurrentThread ); + CloseHandle( aSysInfos.hCurrentProcess ); + + String aInfos; + + aInfos += aSysInfos.aSystemVersion; + aInfos += "\n\n"; + + aInfos += aSysInfos.aCPUType; + aInfos += "\n\n"; + + aInfos += aSysInfos.aMouseInfo; + aInfos += "\n\n"; + + aInfos += aSysInfos.aMemoryInfo; + aInfos += "\n\n"; + + aInfos += aSysInfos.aStack; + aInfos += "\n\n"; + + aInfos += aSysInfos.aModules; + aInfos += "\n\n"; + + aInfos += aSysInfos.aLocalVolumes; + aInfos += "\n\n"; + + aInfos += aSysInfos.aSystemDirs; + aInfos += "\n\n"; + + return aInfos; +} + + + + +void DebugThread( SystemInfos* pSysInfos ) +{ + HINSTANCE hImageHelpLib = LoadLibrary( "IMAGEHLP.DLL" ); + if( hImageHelpLib ) + { + if ( SuspendThread( pSysInfos->hCurrentThread ) != 0xFFFFFFFF ) + { + STACKFRAME aStackFrame; + memset( &aStackFrame, 0, sizeof( aStackFrame ) ); + + CONTEXT aContext; + memset( &aContext, 0, sizeof( aContext ) ); + aContext.ContextFlags = CONTEXT_FULL; + if ( GetThreadContext( pSysInfos->hCurrentThread, &aContext ) ) + { + STACKWALKPROC _fpStackWalk = (STACKWALKPROC) GetProcAddress( hImageHelpLib, "StackWalk" ); + SYMFUNCTIONTABLEACCESSPROC _fpSymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC) GetProcAddress( hImageHelpLib, "SymFunctionTableAccess" ); + SYMGETMODULEBASEPROC _fpSymGetModuleBase = (SYMGETMODULEBASEPROC) GetProcAddress( hImageHelpLib, "SymGetModuleBase" ); + SYMSETOPTIONSPROC _fpSymSetOptionsProc = (SYMSETOPTIONSPROC) GetProcAddress( hImageHelpLib, "SymGetOptions" ); + SYMINITIALIZEPROC _fpSymInitializeProc = (SYMINITIALIZEPROC) GetProcAddress( hImageHelpLib, "SymInitialize" ); + SYMCLEANUPPROC _fpSymCleanup = (SYMCLEANUPPROC) GetProcAddress( hImageHelpLib, "SymCleanup" ); + UNDECORATESYMBOLNAMEPROC _fpUndecorateSymbolName = (UNDECORATESYMBOLNAMEPROC) GetProcAddress( hImageHelpLib, "UnDecorateSymbolName" ); + SYMLOADMODULEPROC _fpSymLoadModule = ( SYMLOADMODULEPROC) GetProcAddress( hImageHelpLib, "SymLoadModule" ); + SYMGETSYMFROMADDR _fpSymGetSymFromAddr = ( SYMGETSYMFROMADDR ) GetProcAddress( hImageHelpLib, "SymGetSymFromAddr" ); + + if ( !pSysInfos->pModInfos ) + pSysInfos->pModInfos = WNT_CreateModuleInfos(); + + _fpSymSetOptionsProc( SYMOPT_DEFERRED_LOADS ); + + char buffer[1024]; + + // Initialize the imagehlp symbol handler + BOOL bAutoLoad = FALSE; +// String aPath = WNT_CreateModulePath( pSysInfos->pModInfos ); +// USHORT nLen = aPath.Len(); +// memcpy( buffer, aPath.GetStr(), nLen ); +// buffer[nLen] = 0; +// BOOL bSymbols = _fpSymInitializeProc( pSysInfos->hCurrentProcess, NULL, bAutoLoad ); + // Path funktioniert nicht, also lade ich unten alle von Hand! + BOOL bSymbols = _fpSymInitializeProc( pSysInfos->hCurrentProcess, NULL, bAutoLoad ); + + // Load symbol modules for the current process + if ( bSymbols && !bAutoLoad ) + { + // LoadModuleSymbols( pSysInfos->nCurrentProcessId, pSysInfos->hCurrentProcess ); + struct ModuleInfo* pM = pSysInfos->pModInfos; + char buffer1[1024]; + char buffer2[1024]; + + while ( pM ) + { + strcpy( buffer1, pM->szModFileName ); + strcpy( buffer2, pM->szModBaseName ); + + BOOL bDone = _fpSymLoadModule( pSysInfos->hCurrentProcess, 0, buffer1, buffer2, pM->nBaseAddress, pM->nSize ); + + pM = pM->pNext; + } + } + + // Initialize the STACKFRAME structure for the first call. This is only + // necessary for Intel CPUs, and isn't mentioned in the documentation. + aStackFrame.AddrPC.Offset = aContext.Eip; + aStackFrame.AddrPC.Mode = AddrModeFlat; + aStackFrame.AddrStack.Offset = aContext.Esp; + aStackFrame.AddrStack.Mode = AddrModeFlat; + aStackFrame.AddrFrame.Offset = aContext.Ebp; + aStackFrame.AddrFrame.Mode = AddrModeFlat; + + + pSysInfos->aStack = "<Stack type=\"WIN32\" >\n"; + + for ( int nS = 0; nS < 20; nS++ ) + { + SetLastError( 0 ); + BOOL bStack = _fpStackWalk( IMAGE_FILE_MACHINE_I386, + pSysInfos->hCurrentProcess, + pSysInfos->hCurrentThread, + &aStackFrame, + &aContext, + NULL, // ReadProcessMemory, + _fpSymFunctionTableAccess, + _fpSymGetModuleBase, + NULL ); + + if ( !bStack || !aStackFrame.AddrReturn.Offset || !aStackFrame.AddrFrame.Offset ) + break; + + pSysInfos->aStack += " <StackInfo pos=\""; + pSysInfos->aStack += (USHORT)nS; + pSysInfos->aStack += "\" ip=\""; + ULONG nIP = aStackFrame.AddrReturn.Offset; + sprintf( buffer, "%.8lx", nIP ); + pSysInfos->aStack += buffer; + pSysInfos->aStack += "\""; + + TCHAR aModuleFileName[MAX_PATH]; + DWORD section, offset; + if ( WNT_GetLogicalAddress( (void*)nIP, aModuleFileName, MAX_PATH, section, offset ) ) + { + pSysInfos->aStack += " rel=\""; + sprintf( buffer, "%.8lx", offset ); + pSysInfos->aStack += buffer; + pSysInfos->aStack += "\" file=\""; + char* pModName = strrchr( aModuleFileName, '\\' ); + pSysInfos->aStack += pModName ? (pModName+1) : aModuleFileName; + pSysInfos->aStack += "\""; + } + else + { + pSysInfos->aStack += " rel=\"ERROR\""; + break; + } + + if ( bSymbols ) + { + + BYTE symbolBuffer[ sizeof(IMAGEHLP_SYMBOL) + 512 ]; + PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer; + memset( symbolBuffer, 0, sizeof(symbolBuffer) ); + pSymbol->SizeOfStruct = sizeof(symbolBuffer); + pSymbol->MaxNameLength = sizeof(symbolBuffer) - sizeof(IMAGEHLP_SYMBOL) + 1; + + DWORD symDisplacement = 0; // Displacement of the input address, + // relative to the start of the symbol + + if ( _fpSymGetSymFromAddr( pSysInfos->hCurrentProcess, aStackFrame.AddrReturn.Offset, + &symDisplacement, pSymbol ) ) + { + pSysInfos->aStack += " ordinal=\""; + _fpUndecorateSymbolName( pSymbol->Name, buffer, 1024, UNDNAME_NAME_ONLY ); + pSysInfos->aStack += buffer; + pSysInfos->aStack += "\""; + // aStackLine += '<'; + // _fpUndecorateSymbolName( pSymbol->Name, buffer, 1024, UNDNAME_COMPLETE ); + // aStackLine += buffer; + // aStackLine += '>'; + } + else // No symbol found. Print out the logical address instead. + { + pSysInfos->aStack += " ordinal=\"???\""; + } + } + + pSysInfos->aStack += " />\n"; + } + pSysInfos->aStack += "</Stack>"; + _fpSymCleanup( pSysInfos->hCurrentProcess ); + } + ResumeThread( pSysInfos->hCurrentThread ); + } + FreeLibrary( hImageHelpLib ); + } +} + +#endif diff --git a/vcl/win/source/app/salinst.cxx b/vcl/win/source/app/salinst.cxx new file mode 100644 index 000000000000..bafb98e35bfa --- /dev/null +++ b/vcl/win/source/app/salinst.cxx @@ -0,0 +1,897 @@ +/************************************************************************* + * + * $RCSfile: salinst.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <string.h> +#include <tools/svwin.h> +#ifdef WNT +#include <process.h> +#endif + +#define _SV_SALINST_CXX + +#ifndef _VOS_MUTEX_HXX +#include <vos/mutex.hxx> +#endif + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _SV_WINCOMP_HXX +#include <wincomp.hxx> +#endif +#ifndef _SV_SALIDS_HRC +#include <salids.hrc> +#endif +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALINST_HXX +#include <salinst.hxx> +#endif +#ifndef _SV_SALFRAME_HXX +#include <salframe.hxx> +#endif +#ifndef _SV_SALOBJ_HXX +#include <salobj.hxx> +#endif +#ifndef _SV_SALSYS_HXX +#include <salsys.hxx> +#endif +#ifndef _SV_SALTIMER_HXX +#include <saltimer.hxx> +#endif +#ifndef _SV_SALSOUND_HXX +#include <salsound.hxx> +#endif +#ifndef _SV_SALATYPE_HXX +#include <salatype.hxx> +#endif +#ifndef _SV_SYSDATA_HXX +#include <sysdata.hxx> +#endif + +#ifndef _SV_TIMER_HXX +#include <timer.hxx> +#endif + +// ======================================================================= + +void SalAbort( const XubString& rErrorText ) +{ + ImplFreeSalGDI(); + + if ( !rErrorText.Len() ) + FatalAppExit( 0, "Application Error" ); + else + { + ByteString aErrorText( ImplSalGetWinAnsiString( rErrorText ) ); + FatalAppExit( 0, aErrorText.GetBuffer() ); + } +} + +// ======================================================================= + +LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); +LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ); + +// ======================================================================= + +class SalYieldMutex : public NAMESPACE_VOS(OMutex) +{ +public: // for ImplSalYield() + SalInstanceData* mpInstData; + ULONG mnCount; + DWORD mnThreadId; + +public: + SalYieldMutex( SalInstanceData* pInstData ); + + virtual void SAL_CALL acquire(); + virtual void SAL_CALL release(); + virtual sal_Bool SAL_CALL tryToAcquire(); + + ULONG GetAcquireCount( ULONG nThreadId ); +}; + +// ----------------------------------------------------------------------- + +SalYieldMutex::SalYieldMutex( SalInstanceData* pInstData ) +{ + mpInstData = pInstData; + mnCount = 0; + mnThreadId = 0; +} + +// ----------------------------------------------------------------------- + +void SAL_CALL SalYieldMutex::acquire() +{ + OMutex::acquire(); + mnCount++; + mnThreadId = GetCurrentThreadId(); +} + +// ----------------------------------------------------------------------- + +void SAL_CALL SalYieldMutex::release() +{ + DWORD nThreadId = GetCurrentThreadId(); + if ( mnThreadId != nThreadId ) + OMutex::release(); + else + { + // If we don't call these message, the Output from the + // Java clients doesn't come in the right order + GdiFlush(); + + SalData* pSalData = GetSalData(); + if ( pSalData->mnAppThreadId != nThreadId ) + { + if ( mnCount == 1 ) + { + mpInstData->mpSalWaitMutex->acquire(); + if ( mpInstData->mnYieldWaitCount ) + ImplPostMessage( mpInstData->mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 ); + mnThreadId = 0; + mnCount--; + OMutex::release(); + mpInstData->mpSalWaitMutex->release(); + } + else + { + mnCount--; + OMutex::release(); + } + } + else + { + if ( mnCount == 1 ) + mnThreadId = 0; + mnCount--; + OMutex::release(); + } + } +} + +// ----------------------------------------------------------------------- + +sal_Bool SAL_CALL SalYieldMutex::tryToAcquire() +{ + if( OMutex::tryToAcquire() ) + { + mnCount++; + mnThreadId = GetCurrentThreadId(); + return True; + } + else + return False; +} + +// ----------------------------------------------------------------------- + +ULONG SalYieldMutex::GetAcquireCount( ULONG nThreadId ) +{ + if ( nThreadId == mnThreadId ) + return mnCount; + else + return 0; +} + +// ----------------------------------------------------------------------- + +void ImplSalYieldMutexAcquireWithWait() +{ + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( !pInst ) + return; + + // If we are the main thread, then we must wait with wait, because + // in if we don't reschedule, then we create deadlocks if a Windows + // Function is called from another thread. If we arn't the main thread, + // than we call qcquire directly. + DWORD nThreadId = GetCurrentThreadId(); + SalData* pSalData = GetSalData(); + if ( pSalData->mnAppThreadId == nThreadId ) + { + // Wenn wir den Mutex nicht bekommen, muessen wir solange + // warten, bis wir Ihn bekommen + BOOL bAcquire = FALSE; + do + { + if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() ) + bAcquire = TRUE; + else + { + pInst->maInstData.mpSalWaitMutex->acquire(); + if ( pInst->maInstData.mpSalYieldMutex->tryToAcquire() ) + { + bAcquire = TRUE; + pInst->maInstData.mpSalWaitMutex->release(); + } + else + { + pInst->maInstData.mnYieldWaitCount++; + pInst->maInstData.mpSalWaitMutex->release(); + MSG aTmpMsg; + ImplGetMessage( &aTmpMsg, pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, SAL_MSG_RELEASEWAITYIELD ); + pInst->maInstData.mnYieldWaitCount--; + if ( pInst->maInstData.mnYieldWaitCount ) + ImplPostMessage( pInst->maInstData.mhComWnd, SAL_MSG_RELEASEWAITYIELD, 0, 0 ); + } + } + } + while ( !bAcquire ); + } + else + pInst->maInstData.mpSalYieldMutex->acquire(); +} + +// ----------------------------------------------------------------------- + +BOOL ImplSalYieldMutexTryToAcquire() +{ + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( pInst ) + return pInst->maInstData.mpSalYieldMutex->tryToAcquire(); + else + return FALSE; +} + +// ----------------------------------------------------------------------- + +void ImplSalYieldMutexAcquire() +{ + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( pInst ) + pInst->maInstData.mpSalYieldMutex->acquire(); +} + +// ----------------------------------------------------------------------- + +void ImplSalYieldMutexRelease() +{ + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( pInst ) + pInst->maInstData.mpSalYieldMutex->release(); +} + +// ----------------------------------------------------------------------- + +ULONG ImplSalReleaseYieldMutex() +{ + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( !pInst ) + return 0; + + SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex; + ULONG nCount = pYieldMutex->GetAcquireCount( GetCurrentThreadId() ); + ULONG n = nCount; + while ( n ) + { + pYieldMutex->release(); + n--; + } + + return nCount; +} + +// ----------------------------------------------------------------------- + +void ImplSalAcquireYieldMutex( ULONG nCount ) +{ + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( !pInst ) + return; + + SalYieldMutex* pYieldMutex = pInst->maInstData.mpSalYieldMutex; + while ( nCount ) + { + pYieldMutex->acquire(); + nCount--; + } +} + +// ----------------------------------------------------------------------- + +#ifdef DBG_UTIL + +void ImplDbgTestSolarMutex() +{ + SalData* pSalData = GetSalData(); + DWORD nCurThreadId = GetCurrentThreadId(); + if ( pSalData->mnAppThreadId != nCurThreadId ) + { + if ( pSalData->mpFirstInstance ) + { + SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex; + if ( pYieldMutex->mnThreadId != nCurThreadId ) + { + DBG_ERROR( "SolarMutex not locked, and not thread save code in VCL is called from outside of the main thread" ); + } + } + } + else + { + if ( pSalData->mpFirstInstance ) + { + SalYieldMutex* pYieldMutex = pSalData->mpFirstInstance->maInstData.mpSalYieldMutex; + if ( pYieldMutex->mnThreadId != nCurThreadId ) + { + DBG_ERROR( "SolarMutex not locked in the main thread" ); + } + } + } +} + +#endif + +// ======================================================================= + +static void InitSalShlData() +{ + aSalShlData.mnVKAdd = LOWORD( VkKeyScan( '+' ) ); + aSalShlData.mnVKSubtract = LOWORD( VkKeyScan( '-' ) ); + aSalShlData.mnVKMultiply = LOWORD( VkKeyScan( '*' ) ); + aSalShlData.mnVKDivide = LOWORD( VkKeyScan( '/' ) ); + aSalShlData.mnVKPoint = LOWORD( VkKeyScan( '.' ) ); + aSalShlData.mnVKComma = LOWORD( VkKeyScan( ',' ) ); + aSalShlData.mnVKLess = LOWORD( VkKeyScan( '<' ) ); + aSalShlData.mnVKGreater = LOWORD( VkKeyScan( '>' ) ); + aSalShlData.mnVKEqual = LOWORD( VkKeyScan( '=' ) ); +} + +// ======================================================================= + +void InitSalData() +{ + SalData* pSalData = new SalData; + memset( pSalData, 0, sizeof( SalData ) ); + SetSalData( pSalData ); + CoInitialize(0); +} + +// ----------------------------------------------------------------------- + +void DeInitSalData() +{ + CoUninitialize(); + SalData* pSalData = GetSalData(); + delete pSalData; + SetSalData( NULL ); +} + +// ----------------------------------------------------------------------- + +void SetFilterCallback( void* pCallback, void* pInst ) +{ + SalData* pSalData = GetSalData(); + + pSalData->mpFirstInstance->maInstData.mpFilterCallback = pCallback; + pSalData->mpFirstInstance->maInstData.mpFilterInst = pInst; +} + +// ----------------------------------------------------------------------- + +SalInstance* CreateSalInstance() +{ + SalData* pSalData = GetSalData(); + + // determine the windows version + WORD nVer = (WORD)GetVersion(); + aSalShlData.mnVersion = (((WORD)LOBYTE(nVer)) * 100) + HIBYTE(nVer); + if ( aSalShlData.mnVersion >= W95_VERSION ) + aSalShlData.mbW40 = 1; + OSVERSIONINFO aVerInfo; + aVerInfo.dwOSVersionInfoSize = sizeof( aVerInfo ); + if ( GetVersionEx( &aVerInfo ) ) + { + if ( aVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) + aSalShlData.mbWNT = 1; + } + + pSalData->mnAppThreadId = GetCurrentThreadId(); + + // register frame class + if ( !pSalData->mhPrevInst ) + { + if ( aSalShlData.mbWNT ) + { + WNDCLASSEXW aWndClassEx; + aWndClassEx.cbSize = sizeof( aWndClassEx ); + aWndClassEx.style = CS_OWNDC; + aWndClassEx.lpfnWndProc = SalFrameWndProcW; + aWndClassEx.cbClsExtra = 0; + aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA; + aWndClassEx.hInstance = pSalData->mhInst; + aWndClassEx.hCursor = 0; + aWndClassEx.hbrBackground = 0; + aWndClassEx.lpszMenuName = 0; + aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEW; + ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm ); + if ( !RegisterClassExW( &aWndClassEx ) ) + return NULL; + aWndClassEx.style |= CS_SAVEBITS; + aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBW; + if ( !RegisterClassExW( &aWndClassEx ) ) + return NULL; + + aWndClassEx.style = 0; + aWndClassEx.lpfnWndProc = SalComWndProcW; + aWndClassEx.cbWndExtra = 0; + aWndClassEx.hIcon = 0; + aWndClassEx.hIconSm = 0; + aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEW; + if ( !RegisterClassExW( &aWndClassEx ) ) + return NULL; + } + else + { + WNDCLASSEXA aWndClassEx; + aWndClassEx.cbSize = sizeof( aWndClassEx ); + aWndClassEx.style = CS_OWNDC; + aWndClassEx.lpfnWndProc = SalFrameWndProcA; + aWndClassEx.cbClsExtra = 0; + aWndClassEx.cbWndExtra = SAL_FRAME_WNDEXTRA; + aWndClassEx.hInstance = pSalData->mhInst; + aWndClassEx.hCursor = 0; + aWndClassEx.hbrBackground = 0; + aWndClassEx.lpszMenuName = 0; + aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAMEA; + ImplLoadSalIcon( SAL_RESID_ICON_DEFAULT, aWndClassEx.hIcon, aWndClassEx.hIconSm ); + if ( !RegisterClassExA( &aWndClassEx ) ) + return NULL; + aWndClassEx.style |= CS_SAVEBITS; + aWndClassEx.lpszClassName = SAL_FRAME_CLASSNAME_SBA; + if ( !RegisterClassExA( &aWndClassEx ) ) + return NULL; + + aWndClassEx.style = 0; + aWndClassEx.lpfnWndProc = SalComWndProcA; + aWndClassEx.cbWndExtra = 0; + aWndClassEx.hIcon = 0; + aWndClassEx.hIconSm = 0; + aWndClassEx.lpszClassName = SAL_COM_CLASSNAMEA; + if ( !RegisterClassExA( &aWndClassEx ) ) + return NULL; + } + } + + HWND hComWnd; + if ( aSalShlData.mbWNT ) + { + hComWnd = CreateWindowExW( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEW, + L"", WS_POPUP, 0, 0, 0, 0, 0, 0, + pSalData->mhInst, NULL ); + } + else + { + hComWnd = CreateWindowExA( WS_EX_TOOLWINDOW, SAL_COM_CLASSNAMEA, + "", WS_POPUP, 0, 0, 0, 0, 0, 0, + pSalData->mhInst, NULL ); + } + if ( !hComWnd ) + return NULL; + + SalInstance* pInst = new SalInstance; + + // init shl data + InitSalShlData(); + + // init instance (only one instance in this version !!!) + pSalData->mpFirstInstance = pInst; + pInst->maInstData.mhInst = pSalData->mhInst; + pInst->maInstData.mhComWnd = hComWnd; + + // init static GDI Data + ImplInitSalGDI(); + + return pInst; +} + +// ----------------------------------------------------------------------- + +void DestroySalInstance( SalInstance* pInst ) +{ + SalData* pSalData = GetSalData(); + + // (only one instance in this version !!!) + + ImplFreeSalGDI(); + + // reset instance + if ( pSalData->mpFirstInstance == pInst ) + pSalData->mpFirstInstance = NULL; + + delete pInst; +} + +// ----------------------------------------------------------------------- + +SalInstance::SalInstance() +{ + maInstData.mhComWnd = 0; + maInstData.mpFilterCallback = NULL; + maInstData.mpFilterInst = NULL; + maInstData.mpSalYieldMutex = new SalYieldMutex( &maInstData ); + maInstData.mpSalWaitMutex = new NAMESPACE_VOS(OMutex); + maInstData.mnYieldWaitCount = 0; + maInstData.mpSalYieldMutex->acquire(); +} + +// ----------------------------------------------------------------------- + +SalInstance::~SalInstance() +{ + maInstData.mpSalYieldMutex->release(); + delete maInstData.mpSalYieldMutex; + delete maInstData.mpSalWaitMutex; + DestroyWindow( maInstData.mhComWnd ); +} + +// ----------------------------------------------------------------------- + +#ifdef _VOS_NO_NAMESPACE +IMutex* SalInstance::GetYieldMutex() +#else +vos::IMutex* SalInstance::GetYieldMutex() +#endif +{ + return maInstData.mpSalYieldMutex; +} + +// ----------------------------------------------------------------------- + +ULONG SalInstance::ReleaseYieldMutex() +{ + return ImplSalReleaseYieldMutex(); +} + +// ----------------------------------------------------------------------- + +void SalInstance::AcquireYieldMutex( ULONG nCount ) +{ + ImplSalAcquireYieldMutex( nCount ); +} + +// ----------------------------------------------------------------------- + +static void ImplSalDispatchMessage( MSG* pMsg ) +{ + SalData* pSalData = GetSalData(); + if ( pSalData->mpFirstObject ) + { + if ( ImplSalPreDispatchMsg( pMsg ) ) + return; + } + LRESULT lResult = ImplDispatchMessage( pMsg ); + if ( pSalData->mpFirstObject ) + ImplSalPostDispatchMsg( pMsg, lResult ); +} + +// ----------------------------------------------------------------------- + +void ImplSalYield( BOOL bWait ) +{ + MSG aMsg; + + if ( bWait ) + { + if ( ImplGetMessage( &aMsg, 0, 0, 0 ) ) + { + TranslateMessage( &aMsg ); + ImplSalDispatchMessage( &aMsg ); + } + } + else + { + if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_REMOVE ) ) + { + TranslateMessage( &aMsg ); + ImplSalDispatchMessage( &aMsg ); + } + } +} + +// ----------------------------------------------------------------------- + +void SalInstance::Yield( BOOL bWait ) +{ + SalYieldMutex* pYieldMutex = maInstData.mpSalYieldMutex; + SalData* pSalData = GetSalData(); + DWORD nCurThreadId = GetCurrentThreadId(); + ULONG nCount = pYieldMutex->GetAcquireCount( nCurThreadId ); + ULONG n = nCount; + while ( n ) + { + pYieldMutex->release(); + n--; + } + if ( pSalData->mnAppThreadId != nCurThreadId ) + { + ImplSendMessage( maInstData.mhComWnd, SAL_MSG_THREADYIELD, (WPARAM)bWait, (LPARAM)0 ); + n = nCount; + while ( n ) + { + pYieldMutex->acquire(); + n--; + } + } + else + { + ImplSalYield( bWait ); + + n = nCount; + while ( n ) + { + ImplSalYieldMutexAcquireWithWait(); + n--; + } + } +} + +// ----------------------------------------------------------------------- + +LRESULT CALLBACK SalComWndProc( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam, int& rDef ) +{ + LRESULT nRet = 0; + + switch ( nMsg ) + { + case SAL_MSG_PRINTABORTJOB: + ImplSalPrinterAbortJobAsync( (HDC)wParam ); + rDef = FALSE; + break; + case SAL_MSG_THREADYIELD: + ImplSalYield( (BOOL)wParam ); + rDef = FALSE; + break; + // If we get this message, because another GetMessage() call + // has recieved this message, we must post this message to + // us again, because in the other case we wait forever. + case SAL_MSG_RELEASEWAITYIELD: + { + SalInstance* pInst = GetSalData()->mpFirstInstance; + if ( pInst && pInst->maInstData.mnYieldWaitCount ) + ImplPostMessage( hWnd, SAL_MSG_RELEASEWAITYIELD, wParam, lParam ); + } + rDef = FALSE; + break; + case SAL_MSG_STARTTIMER: + ImplSalStartTimer( (ULONG) lParam, FALSE ); + rDef = FALSE; + break; + case SAL_MSG_CREATEFRAME: + nRet = (LRESULT)ImplSalCreateFrame( GetSalData()->mpFirstInstance, (HWND)lParam, (ULONG)wParam ); + rDef = FALSE; + break; + case SAL_MSG_DESTROYFRAME: + delete (SalFrame*)lParam; + rDef = FALSE; + break; + case SAL_MSG_CREATEOBJECT: + nRet = (LRESULT)ImplSalCreateObject( GetSalData()->mpFirstInstance, (SalFrame*)lParam ); + rDef = FALSE; + break; + case SAL_MSG_DESTROYOBJECT: + delete (SalObject*)lParam; + rDef = FALSE; + break; + case SAL_MSG_CREATESOUND: + nRet = ((SalSound*)lParam)->ImplCreate(); + rDef = FALSE; + break; + case SAL_MSG_DESTROYSOUND: + ((SalSound*)lParam)->ImplDestroy(); + rDef = FALSE; + break; + } + + return nRet; +} + +LRESULT CALLBACK SalComWndProcA( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) +{ + int bDef = TRUE; + LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef ); + if ( bDef ) + { + if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) ) + nRet = DefWindowProcA( hWnd, nMsg, wParam, lParam ); + } + return nRet; +} + +LRESULT CALLBACK SalComWndProcW( HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam ) +{ + int bDef = TRUE; + LRESULT nRet = SalComWndProc( hWnd, nMsg, wParam, lParam, bDef ); + if ( bDef ) + { + if ( !ImplHandleGlobalMsg( hWnd, nMsg, wParam, lParam, nRet ) ) + nRet = DefWindowProcW( hWnd, nMsg, wParam, lParam ); + } + return nRet; +} + +// ----------------------------------------------------------------------- + +BOOL SalInstance::AnyInput( USHORT nType ) +{ + MSG aMsg; + + if ( (nType & (INPUT_ANY)) == (INPUT_ANY) ) + { + // Any Input + if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) ) + return TRUE; + } + else + { + if ( nType & INPUT_MOUSE ) + { + // Test auf Mouseinput + if ( ImplPeekMessage( &aMsg, 0, WM_MOUSEFIRST, WM_MOUSELAST, + PM_NOREMOVE | PM_NOYIELD ) ) + return TRUE; + } + + if ( nType & INPUT_KEYBOARD ) + { + // Test auf Keyinput + if ( ImplPeekMessage( &aMsg, 0, WM_KEYDOWN, WM_KEYDOWN, + PM_NOREMOVE | PM_NOYIELD ) ) + { + if ( (aMsg.wParam == VK_SHIFT) || + (aMsg.wParam == VK_CONTROL) || + (aMsg.wParam == VK_MENU) ) + return FALSE; + else + return TRUE; + } + } + + if ( nType & INPUT_PAINT ) + { + // Test auf Paintinput + if ( ImplPeekMessage( &aMsg, 0, WM_PAINT, WM_PAINT, + PM_NOREMOVE | PM_NOYIELD ) ) + return TRUE; + } + + if ( nType & INPUT_TIMER ) + { + // Test auf Timerinput + if ( ImplPeekMessage( &aMsg, 0, WM_TIMER, WM_TIMER, + PM_NOREMOVE | PM_NOYIELD ) ) + return TRUE; + } + + if ( nType & INPUT_OTHER ) + { + // Test auf sonstigen Input + if ( ImplPeekMessage( &aMsg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD ) ) + return TRUE; + } + } + + return FALSE; +} + +// ----------------------------------------------------------------------- + +void SalTimer::Start( ULONG nMS ) +{ + // Um auf Main-Thread umzuschalten + SalData* pSalData = GetSalData(); + if ( pSalData->mpFirstInstance ) + { + if ( pSalData->mnAppThreadId != GetCurrentThreadId() ) + ImplPostMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS ); + else + ImplSendMessage( pSalData->mpFirstInstance->maInstData.mhComWnd, SAL_MSG_STARTTIMER, 0, (LPARAM)nMS ); + } + else + ImplSalStartTimer( nMS, FALSE ); +} + +// ----------------------------------------------------------------------- + +SalFrame* SalInstance::CreateChildFrame( SystemParentData* pSystemParentData, ULONG nSalFrameStyle ) +{ + // Um auf Main-Thread umzuschalten + return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)pSystemParentData->hWnd ); +} + +// ----------------------------------------------------------------------- + +SalFrame* SalInstance::CreateFrame( SalFrame* pParent, ULONG nSalFrameStyle ) +{ + // Um auf Main-Thread umzuschalten + HWND hWndParent; + if ( pParent ) + hWndParent = pParent->maFrameData.mhWnd; + else + hWndParent = 0; + return (SalFrame*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEFRAME, nSalFrameStyle, (LPARAM)hWndParent ); +} + +// ----------------------------------------------------------------------- + +void SalInstance::DestroyFrame( SalFrame* pFrame ) +{ + ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYFRAME, 0, (LPARAM)pFrame ); +} + +// ----------------------------------------------------------------------- + +SalObject* SalInstance::CreateObject( SalFrame* pParent ) +{ + // Um auf Main-Thread umzuschalten + return (SalObject*)ImplSendMessage( maInstData.mhComWnd, SAL_MSG_CREATEOBJECT, 0, (LPARAM)pParent ); +} + +// ----------------------------------------------------------------------- + +void SalInstance::DestroyObject( SalObject* pObject ) +{ + ImplSendMessage( maInstData.mhComWnd, SAL_MSG_DESTROYOBJECT, 0, (LPARAM)pObject ); +} diff --git a/vcl/win/source/app/salshl.cxx b/vcl/win/source/app/salshl.cxx new file mode 100644 index 000000000000..3c026c053906 --- /dev/null +++ b/vcl/win/source/app/salshl.cxx @@ -0,0 +1,198 @@ +/************************************************************************* + * + * $RCSfile: salshl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVWIN_H +#include <tools/svwin.h> +#endif + +#define _SV_SALSHL_CXX + +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif + +#ifndef _DEBUG_HXX +#include <tools/debug.hxx> +#endif + +// ======================================================================= + +SalShlData aSalShlData; + +// ======================================================================= + +#ifdef WIN + +extern "C" +{ + +int CALLBACK LibMain( HINSTANCE hInst, WORD, WORD nHeap, LPSTR ) +{ + if ( nHeap ) + UnlockData( 0 ); + + aSalShlData.mhInst = hInst; + + return 1; +} + +// ----------------------------------------------------------------------- + +int CALLBACK WEP( int ) +{ + return 1; +} + +} + +#endif + +// ======================================================================= + +#ifdef WNT + +extern "C" +{ + +#ifdef ICC +int _CRT_init(void); +#else +WIN_BOOL WINAPI _CRT_INIT( HINSTANCE hInst, DWORD nReason, LPVOID pReserved ); +#endif + +WIN_BOOL WINAPI LibMain( HINSTANCE hInst, DWORD nReason, LPVOID pReserved ) +{ + // Unsere DLL-Initialisierung + if ( nReason == DLL_PROCESS_ATTACH ) + aSalShlData.mhInst = hInst; + +#if !defined ( __BORLANDC__ ) +#ifdef ICC + if ( _CRT_init() == -1 ) +#else + if ( !_CRT_INIT( hInst, nReason, pReserved ) ) +#endif + return 0; +#endif + + return 1; +} + +} + +#endif + +// ======================================================================= + +HCURSOR ImplLoadSalCursor( int nId ) +{ + DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" ); + + HCURSOR hCursor = LoadCursor( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) ); + + DBG_ASSERT( hCursor, "cursor not found in sal resource" ); + + return hCursor; +} + +// ----------------------------------------------------------------------- + +HBITMAP ImplLoadSalBitmap( int nId ) +{ + DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" ); + + HBITMAP hBitmap = LoadBitmap( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) ); + + DBG_ASSERT( hBitmap, "bitmap not found in sal resource" ); + + return hBitmap; +} + +// ----------------------------------------------------------------------- + +BOOL ImplLoadSalIcon( int nId, HICON& rIcon, HICON& rSmallIcon ) +{ + DBG_ASSERT( aSalShlData.mhInst, "no DLL instance handle" ); + + // Try at first to load the icons from the application exe file + SalData* pSalData = GetSalData(); + rIcon = LoadIcon( pSalData->mhInst, MAKEINTRESOURCE( nId ) ); + if ( !rIcon ) + { + // If the application don't provide these icons, then we try + // to load the icon from the VCL resource + rIcon = LoadIcon( aSalShlData.mhInst, MAKEINTRESOURCE( nId ) ); + if ( rIcon ) + { + rSmallIcon = (HICON)LoadImage( aSalShlData.mhInst, MAKEINTRESOURCE( nId ), + IMAGE_ICON, 16, 16, 0 ); + } + else + rSmallIcon = 0; + } + else + { + rSmallIcon = (HICON)LoadImage( pSalData->mhInst, MAKEINTRESOURCE( nId ), + IMAGE_ICON, 16, 16, 0 ); + } + + return (rSmallIcon != 0); +} diff --git a/vcl/win/source/app/saltimer.cxx b/vcl/win/source/app/saltimer.cxx new file mode 100644 index 000000000000..b051c72110bf --- /dev/null +++ b/vcl/win/source/app/saltimer.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * $RCSfile: saltimer.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 17:05:49 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _SVWIN_H +#include <tools/svwin.h> +#endif + +#define _SV_SALTIMER_CXX + +#ifndef _SV_SALDATA_HXX +#include <saldata.hxx> +#endif +#ifndef _SV_SALTIMER_HXX +#include <saltimer.hxx> +#endif + +// ======================================================================= + +// Maximale Periode +#define MAX_SYSPERIOD 65533 + +// ======================================================================= + +void ImplSalStartTimer( ULONG nMS, BOOL bMutex ) +{ + SalData* pSalData = GetSalData(); + + // Remenber the time of the timer + pSalData->mnTimerMS = nMS; + if ( !bMutex ) + pSalData->mnTimerOrgMS = nMS; + + // Periode darf nicht zu gross sein, da Windows mit USHORT arbeitet + if ( nMS > MAX_SYSPERIOD ) + nMS = MAX_SYSPERIOD; + + // Gibt es einen Timer, dann zerstoren + if ( pSalData->mnTimerId ) + KillTimer( 0, pSalData->mnTimerId ); + + // Make a new timer with new period + pSalData->mnTimerId = SetTimer( 0, 0, (UINT)nMS, SalTimerProc ); +} + +// ----------------------------------------------------------------------- + +void SalTimer::Stop() +{ + SalData* pSalData = GetSalData(); + + // If we have a timer, than + if ( pSalData->mnTimerId ) + { + KillTimer( 0, pSalData->mnTimerId ); + pSalData->mnTimerId = 0; + } +} + +// ----------------------------------------------------------------------- + +void SalTimer::SetCallback( SALTIMERPROC pProc ) +{ + SalData* pSalData = GetSalData(); + pSalData->mpTimerProc = pProc; +} + +// ----------------------------------------------------------------------- + +void CALLBACK SalTimerProc( HWND, UINT, UINT, DWORD ) +{ + SalData* pSalData = GetSalData(); + + // Test for MouseLeave + SalTestMouseLeave(); + + if ( pSalData->mpTimerProc ) + { + // Try to aquire the mutex. If we don't get the mutex then we + // try this a short time later again. + if ( ImplSalYieldMutexTryToAcquire() ) + { + pSalData->mpTimerProc(); + ImplSalYieldMutexRelease(); + + // Run the timer in the correct time, if we start this + // with a small timeout, because we don't get the mutex + if ( pSalData->mnTimerId && + (pSalData->mnTimerMS != pSalData->mnTimerOrgMS) ) + ImplSalStartTimer( pSalData->mnTimerOrgMS, FALSE ); + } + else + ImplSalStartTimer( 10, TRUE ); + } +} |