summaryrefslogtreecommitdiff
path: root/vcl/win/source/app
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/win/source/app')
-rw-r--r--vcl/win/source/app/MAKEFILE.MK40
-rw-r--r--vcl/win/source/app/saldata.cxx267
-rw-r--r--vcl/win/source/app/salinfo.cxx884
-rw-r--r--vcl/win/source/app/salinst.cxx897
-rw-r--r--vcl/win/source/app/salshl.cxx198
-rw-r--r--vcl/win/source/app/saltimer.cxx152
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 );
+ }
+}