1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-21 21:52:10 +02:00

Bug 521515 - List running tasks using JNA on win32

As Eclipse only support 64-bit JRE on Windows, some legacy support has
been dropped.
* Dropped support for listing 16-bit applications using NTVDM.EXE
  process (was only supported on 32-bit WinNT based systems).
* Dropped support for listing processes on non-WinNT based systems
  (Windows 9x/ME is 32-bit only).

Signed-off-by: Torbjörn Svensson <azoff@svenskalinuxforeningen.se>
Change-Id: Ib827de6510a342c0de5c6eaca68a944b2f1d641e
This commit is contained in:
Torbjörn Svensson 2020-06-29 20:59:38 +02:00 committed by Jonah Graham
parent 803d6cd8ad
commit 36ec703c2f
10 changed files with 81 additions and 654 deletions

View file

@ -9,3 +9,5 @@ Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Eclipse-PlatformFilter: (osgi.os=win32) Eclipse-PlatformFilter: (osgi.os=win32)
Automatic-Module-Name: org.eclipse.cdt.core.win32 Automatic-Module-Name: org.eclipse.cdt.core.win32
Require-Bundle: com.sun.jna;bundle-version="4.5.1",
com.sun.jna.platform;bundle-version="4.5.1"

View file

@ -36,19 +36,12 @@ OBJS_WINREG=winreg/winreg.obj
EXE_STARTER = starter.exe EXE_STARTER = starter.exe
OBJS_STARTER=starter/starter.obj OBJS_STARTER=starter/starter.obj
EXE_LISTTASKS = listtasks.exe
OBJS_LISTTASKS=listtasks/listtasks.obj listtasks/StdAfx.obj
.c.obj: .c.obj:
cl /c $(CFLAGS_UNICODE) $*.c /Fo$@ cl /c $(CFLAGS_UNICODE) $*.c /Fo$@
.cpp.obj: .cpp.obj:
cl /c $(CFLAGS_UNICODE) $*.cpp /Fo$@ cl /c $(CFLAGS_UNICODE) $*.cpp /Fo$@
#TODO: Use unicode for listtasks, see bug 353460
listtasks/listtasks.obj:
cl /c $(CFLAGS) $*.cpp /Fo$@
spawner: $(OBJS_SPAWNER) spawner: $(OBJS_SPAWNER)
link /dll /nologo /out:$(DLL_SPAWNER) $(OBJS_SPAWNER) User32.lib link /dll /nologo /out:$(DLL_SPAWNER) $(OBJS_SPAWNER) User32.lib
@ -58,13 +51,10 @@ winreg: $(OBJS_WINREG)
starter: $(OBJS_STARTER) starter: $(OBJS_STARTER)
link /nologo /out:$(EXE_STARTER) $(OBJS_STARTER) Psapi.Lib Shell32.lib link /nologo /out:$(EXE_STARTER) $(OBJS_STARTER) Psapi.Lib Shell32.lib
listtasks: $(OBJS_LISTTASKS) all: spawner winreg starter
link /nologo /out:$(EXE_LISTTASKS) $(OBJS_LISTTASKS) Psapi.Lib
all: spawner winreg starter listtasks
clean: clean:
del *.obj *.lib *.exp *.exe *.dll winreg\*.obj starter\*.obj listtasks\*.obj del *.obj *.lib *.exp *.exe *.dll winreg\*.obj starter\*.obj
rebuild: clean all rebuild: clean all

View file

@ -1,21 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002 - 2005 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* QNX Software Systems - initial API and implementation
*******************************************************************************/
// stdafx.cpp : source file that includes just the standard includes
// ProcList.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View file

@ -1,32 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002 - 2005 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* QNX Software Systems - initial API and implementation
*******************************************************************************/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__CB3B970F_AA1A_4B59_9F98_DDBEA28470AF__INCLUDED_)
#define AFX_STDAFX_H__CB3B970F_AA1A_4B59_9F98_DDBEA28470AF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__CB3B970F_AA1A_4B59_9F98_DDBEA28470AF__INCLUDED_)

View file

@ -1,349 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002, 2011 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* QNX Software Systems - initial API and implementation
*******************************************************************************/
// ProcList.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "listtasks.h"
#include <tlhelp32.h>
#include <vdmdbg.h>
#include <iostream>
#include <iomanip>
using namespace std;
typedef struct
{
DWORD dwPID ;
PROCENUMPROC lpProc ;
DWORD lParam ;
BOOL bEnd ;
} EnumInfoStruct ;
BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;
BOOL CALLBACK OutProcInfo( DWORD pid, WORD, LPSTR procName, LPARAM ) ;
int main(int argc, char* argv[])
{
EnumProcs(OutProcInfo, 0);
return 0;
}
/*********************
EnumProc.cpp
*********************/
// The EnumProcs function takes a pointer to a callback function
// that will be called once per process in the system providing
// process EXE filename and process ID.
// Callback function definition:
// BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
//
// lpProc -- Address of callback routine.
//
// lParam -- A user-defined LPARAM value to be passed to
// the callback routine.
BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
{
OSVERSIONINFO osver ;
HINSTANCE hInstLib ;
HINSTANCE hInstLib2 ;
HANDLE hSnapShot ;
PROCESSENTRY32 procentry ;
BOOL bFlag ;
LPDWORD lpdwPIDs ;
DWORD dwSize, dwSize2, dwIndex ;
HMODULE hMod ;
HANDLE hProcess ;
char szFileName[ MAX_PATH ] ;
EnumInfoStruct sInfo ;
// ToolHelp Function Pointers.
HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
// PSAPI Function Pointers.
BOOL (WINAPI *lpfEnumProcesses)( DWORD *, DWORD cb, DWORD * );
BOOL (WINAPI *lpfEnumProcessModules)( HANDLE, HMODULE *,
DWORD, LPDWORD );
DWORD (WINAPI *lpfGetModuleFileNameEx)( HANDLE, HMODULE,
LPTSTR, DWORD );
// VDMDBG Function Pointers.
INT (WINAPI *lpfVDMEnumTaskWOWEx)( DWORD,
TASKENUMPROCEX fp, LPARAM );
// Check to see if were running under Windows95 or
// Windows NT.
osver.dwOSVersionInfoSize = sizeof( osver ) ;
if( !GetVersionEx( &osver ) )
{
return FALSE ;
}
// If Windows NT:
if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
// Load library and get the procedures explicitly. We do
// this so that we don't have to worry about modules using
// this code failing to load under Windows 95, because
// it can't resolve references to the PSAPI.DLL.
hInstLib = LoadLibraryA( "PSAPI.DLL" ) ;
if( hInstLib == NULL )
return FALSE ;
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
bool isWin64 = systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64;
if(!isWin64)
{
hInstLib2 = LoadLibraryA( "VDMDBG.DLL" ) ;
if( hInstLib2 == NULL )
return FALSE ;
}
// Get procedure addresses.
lpfEnumProcesses = (BOOL(WINAPI *)(DWORD *,DWORD,DWORD*))
GetProcAddress( hInstLib, "EnumProcesses" ) ;
lpfEnumProcessModules = (BOOL(WINAPI *)(HANDLE, HMODULE *,
DWORD, LPDWORD)) GetProcAddress( hInstLib,
"EnumProcessModules" ) ;
lpfGetModuleFileNameEx =(DWORD (WINAPI *)(HANDLE, HMODULE,
LPTSTR, DWORD )) GetProcAddress( hInstLib,
"GetModuleFileNameExA" ) ;
if(!isWin64)
{
lpfVDMEnumTaskWOWEx =(INT(WINAPI *)( DWORD, TASKENUMPROCEX,
LPARAM))GetProcAddress( hInstLib2, "VDMEnumTaskWOWEx" );
}
if( lpfEnumProcesses == NULL ||
lpfEnumProcessModules == NULL ||
lpfGetModuleFileNameEx == NULL ||
(!isWin64 && lpfVDMEnumTaskWOWEx == NULL))
{
FreeLibrary( hInstLib ) ;
if(!isWin64)
{
FreeLibrary( hInstLib2 ) ;
}
return FALSE ;
}
// Call the PSAPI function EnumProcesses to get all of the
// ProcID's currently in the system.
// NOTE: In the documentation, the third parameter of
// EnumProcesses is named cbNeeded, which implies that you
// can call the function once to find out how much space to
// allocate for a buffer and again to fill the buffer.
// This is not the case. The cbNeeded parameter returns
// the number of PIDs returned, so if your buffer size is
// zero cbNeeded returns zero.
// NOTE: The "HeapAlloc" loop here ensures that we
// actually allocate a buffer large enough for all the
// PIDs in the system.
dwSize2 = 256 * sizeof( DWORD ) ;
lpdwPIDs = NULL ;
do
{
if( lpdwPIDs )
{
HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
dwSize2 *= 2 ;
}
lpdwPIDs = (LPDWORD)HeapAlloc( GetProcessHeap(), 0, dwSize2 );
if( lpdwPIDs == NULL )
{
FreeLibrary( hInstLib ) ;
if(!isWin64)
{
FreeLibrary( hInstLib2 ) ;
}
return FALSE ;
}
if( !lpfEnumProcesses( lpdwPIDs, dwSize2, &dwSize ) )
{
HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
FreeLibrary( hInstLib ) ;
if(!isWin64)
{
FreeLibrary( hInstLib2 ) ;
}
return FALSE ;
}
}while( dwSize == dwSize2 ) ;
// How many ProcID's did we get?
dwSize /= sizeof( DWORD ) ;
// Loop through each ProcID.
for( dwIndex = 0 ; dwIndex < dwSize ; dwIndex++ )
{
szFileName[0] = 0 ;
// Open the process (if we can... security does not
// permit every process in the system).
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, lpdwPIDs[ dwIndex ] ) ;
if( hProcess != NULL )
{
// Here we call EnumProcessModules to get only the
// first module in the process this is important,
// because this will be the .EXE module for which we
// will retrieve the full path name in a second.
if( lpfEnumProcessModules( hProcess, &hMod,
sizeof( hMod ), &dwSize2 ) )
{
// Get Full pathname:
if( !lpfGetModuleFileNameEx( hProcess, hMod,
szFileName, sizeof( szFileName ) ) )
{
szFileName[0] = 0 ;
}
}
CloseHandle( hProcess ) ;
}
// Regardless of OpenProcess success or failure, we
// still call the enum func with the ProcID.
if(!lpProc( lpdwPIDs[dwIndex], 0, szFileName, lParam))
break ;
// Did we just bump into an NTVDM?
if(!isWin64 && _stricmp( szFileName+(strlen(szFileName)-9),
"NTVDM.EXE")==0)
{
// Fill in some info for the 16-bit enum proc.
sInfo.dwPID = lpdwPIDs[dwIndex] ;
sInfo.lpProc = lpProc ;
sInfo.lParam = lParam ;
sInfo.bEnd = FALSE ;
// Enum the 16-bit stuff.
lpfVDMEnumTaskWOWEx( lpdwPIDs[dwIndex],
(TASKENUMPROCEX) Enum16,
(LPARAM) &sInfo);
// Did our main enum func say quit?
if(sInfo.bEnd)
break ;
}
}
HeapFree( GetProcessHeap(), 0, lpdwPIDs ) ;
if(!isWin64)
{
FreeLibrary( hInstLib2 ) ;
}
// If Windows 95:
}else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
{
hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
if( hInstLib == NULL )
return FALSE ;
// Get procedure addresses.
// We are linking to these functions of Kernel32
// explicitly, because otherwise a module using
// this code would fail to load under Windows NT,
// which does not have the Toolhelp32
// functions in the Kernel 32.
lpfCreateToolhelp32Snapshot=
(HANDLE(WINAPI *)(DWORD,DWORD))
GetProcAddress( hInstLib,
"CreateToolhelp32Snapshot" ) ;
lpfProcess32First=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32First" ) ;
lpfProcess32Next=
(BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
GetProcAddress( hInstLib, "Process32Next" ) ;
if( lpfProcess32Next == NULL ||
lpfProcess32First == NULL ||
lpfCreateToolhelp32Snapshot == NULL )
{
FreeLibrary( hInstLib ) ;
return FALSE ;
}
// Get a handle to a Toolhelp snapshot of the systems
// processes.
hSnapShot = lpfCreateToolhelp32Snapshot(
TH32CS_SNAPPROCESS, 0 ) ;
if( hSnapShot == INVALID_HANDLE_VALUE )
{
FreeLibrary( hInstLib ) ;
return FALSE ;
}
// Get the first process' information.
procentry.dwSize = sizeof(PROCESSENTRY32) ;
bFlag = lpfProcess32First( hSnapShot, &procentry ) ;
// While there are processes, keep looping.
while( bFlag )
{
// Call the enum func with the filename and ProcID.
if(lpProc( procentry.th32ProcessID, 0,
procentry.szExeFile, lParam ))
{
procentry.dwSize = sizeof(PROCESSENTRY32) ;
bFlag = lpfProcess32Next( hSnapShot, &procentry );
}else
bFlag = FALSE ;
}
}else
return FALSE ;
// Free the library.
FreeLibrary( hInstLib ) ;
return TRUE ;
}
BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined )
{
BOOL bRet ;
EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined ;
bRet = psInfo->lpProc( psInfo->dwPID, hTask16, pszFileName,
psInfo->lParam ) ;
if(!bRet)
{
psInfo->bEnd = TRUE ;
}
return !bRet;
}
BOOL CALLBACK OutProcInfo( DWORD pid, WORD, LPSTR procName, LPARAM )
{
cout << setw(10) << pid << '\t' << procName << '\n';
return TRUE;
}

View file

@ -1,117 +0,0 @@
# Microsoft Developer Studio Project File - Name="listtasks" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=listtasks - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "listtasks.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "listtasks.mak" CFG="listtasks - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "listtasks - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "listtasks - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "listtasks - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "listtasks - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "listtasks - Win32 Release"
# Name "listtasks - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\listtasks.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\listtasks.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# Begin Source File
SOURCE=.\ReadMe.txt
# End Source File
# End Target
# End Project

View file

@ -1,29 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "listtasks"=.\listtasks.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View file

@ -1,25 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002 - 2005 QNX Software Systems and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* QNX Software Systems - initial API and implementation
*******************************************************************************/
#include <windows.h>
#ifndef __LISTTASKS_H
#define __LISTTASKS_H
typedef BOOL (CALLBACK *PROCENUMPROC)( DWORD, WORD, LPSTR,
LPARAM ) ;
BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam ) ;
#endif

View file

@ -14,91 +14,99 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.win32; package org.eclipse.cdt.internal.core.win32;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.cdt.core.IProcessInfo; import org.eclipse.cdt.core.IProcessInfo;
import org.eclipse.cdt.core.IProcessList; import org.eclipse.cdt.core.IProcessList;
import org.eclipse.cdt.internal.core.natives.CNativePlugin;
import org.eclipse.cdt.utils.spawner.ProcessFactory;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;
/* import com.sun.jna.Native;
* Currently this will only work for Windows XP since tasklist import com.sun.jna.platform.win32.Kernel32;
* is only shipped on XP. This could change to some JNI import com.sun.jna.platform.win32.Win32Exception;
* call out to get the list since the source to 'tlist' is import com.sun.jna.platform.win32.WinDef.DWORD;
* on the msdn web site but that can be done later. import com.sun.jna.platform.win32.WinNT;
*/ import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APIOptions;
public class ProcessList implements IProcessList { public class ProcessList implements IProcessList {
// TODO: Remove this inner class when JNA 5.6 is available
private static abstract class PsapiUtil {
public interface Psapi extends com.sun.jna.platform.win32.Psapi {
Psapi INSTANCE = Native.loadLibrary("psapi", Psapi.class, W32APIOptions.DEFAULT_OPTIONS); //$NON-NLS-1$
boolean EnumProcesses(int[] lpidProcess, int cb, IntByReference lpcbNeeded);
}
public static int[] enumProcesses() {
int size = 0;
int[] lpidProcess = null;
IntByReference lpcbNeeded = new IntByReference();
do {
size += 1024;
lpidProcess = new int[size];
if (!Psapi.INSTANCE.EnumProcesses(lpidProcess, size * DWORD.SIZE, lpcbNeeded)) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
} while (size == lpcbNeeded.getValue() / DWORD.SIZE);
return Arrays.copyOf(lpidProcess, lpcbNeeded.getValue() / DWORD.SIZE);
}
}
// TODO: Remove this inner class when JNA 5.6 is available
private static abstract class Kernel32Util extends com.sun.jna.platform.win32.Kernel32Util {
public static final String QueryFullProcessImageName(int pid, int dwFlags) {
HANDLE hProcess = null;
Win32Exception we = null;
try {
hProcess = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ, false,
pid);
if (hProcess == null) {
throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
}
return QueryFullProcessImageName(hProcess, dwFlags);
} catch (Win32Exception e) {
we = e;
throw we; // re-throw to invoke finally block
} finally {
try {
closeHandle(hProcess);
} catch (Win32Exception e) {
if (we == null) {
we = e;
} else {
we.addSuppressed(e);
}
}
if (we != null) {
throw we;
}
}
}
}
private IProcessInfo[] NOPROCESS = new IProcessInfo[0]; private IProcessInfo[] NOPROCESS = new IProcessInfo[0];
@Override @Override
public IProcessInfo[] getProcessList() { public IProcessInfo[] getProcessList() {
Process p = null;
String command = null;
InputStream in = null;
Bundle bundle = Platform.getBundle(CNativePlugin.PLUGIN_ID);
IProcessInfo[] procInfos = NOPROCESS;
try { try {
URL url = FileLocator.find(bundle, new Path("$os$/listtasks.exe"), null); //$NON-NLS-1$ List<IProcessInfo> processList = new ArrayList<>();
if (url != null) {
url = FileLocator.resolve(url); for (int pid : PsapiUtil.enumProcesses()) {
String path = url.getFile(); try {
File file = new File(path); String name = Kernel32Util.QueryFullProcessImageName(pid, 0);
if (file.exists()) { processList.add(new ProcessInfo(pid, name));
command = file.getCanonicalPath(); } catch (Win32Exception e) {
if (command != null) { // Intentionally ignored exception. Probable cause is access denied.
try {
p = ProcessFactory.getFactory().exec(command);
in = p.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
procInfos = parseListTasks(reader);
} finally {
if (in != null)
in.close();
if (p != null)
p.destroy();
}
}
} }
} }
} catch (IOException e) {
}
return procInfos;
}
public IProcessInfo[] parseListTasks(InputStreamReader reader) { return processList.toArray(new IProcessInfo[processList.size()]);
BufferedReader br = new BufferedReader(reader); } catch (Win32Exception e) {
ArrayList processList = new ArrayList(); return NOPROCESS;
try {
String line;
while ((line = br.readLine()) != null) {
int tab = line.indexOf('\t');
if (tab != -1) {
String proc = line.substring(0, tab).trim();
String name = line.substring(tab).trim();
if (proc.length() > 0 && name.length() > 0) {
try {
int pid = Integer.parseInt(proc);
processList.add(new ProcessInfo(pid, name));
} catch (NumberFormatException e) {
}
}
}
}
} catch (IOException e) {
} }
return (IProcessInfo[]) processList.toArray(new IProcessInfo[processList.size()]);
} }
} }