<commit_before>#include "stdafx.h"
#include "winp.h"
#include "java-interface.h"


// http://msdn.microsoft.com/en-us/library/aa813741(VS.85).aspx
struct RTL_USER_PROCESS_PARAMETERS {
	BYTE dwFiller[16];
	PVOID	dwFiller2[10];
	WORD wLength;
	WORD wMaxLength;
	union {
		LPCWSTR dwCmdLineAddress;
		DWORD _dwCmdLineAddress;
	};
#ifdef _WIN64
	// just found them by trial and error
	PVOID _filler[2];
#endif
	LPCWSTR env;
};

struct PEB  {
#ifdef _WIN64
	BYTE dwFiller[24];
	PVOID dwFiltter2;
#else
	DWORD dwFiller[4];
#endif
	RTL_USER_PROCESS_PARAMETERS* dwInfoBlockAddress;
};

struct PROCESS_BASIC_INFORMATION {
	NTSTATUS ExitStatus;
	PEB* PebBaseAddress;
	PULONG AffinityMask;
	LONG BasePriority;
	PULONG UniqueProcessId;
	PULONG InheritedFromUniqueProcessId;
};

JNIEXPORT jstring JNICALL Java_org_jvnet_winp_Native_getCmdLineAndEnvVars(
	JNIEnv* pEnv, jclass clazz, jint pid) {
	
	// see http://msdn2.microsoft.com/en-us/library/ms674678%28VS.85%29.aspx
	// for kernel string functions

	HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pid);
	if(hProcess==NULL) {
		reportError(pEnv,"Failed to open process");
		return NULL;
	}

	// obtain PROCESS_BASIC_INFORMATION
	PROCESS_BASIC_INFORMATION ProcInfo;
	SIZE_T _;
	if(!NT_SUCCESS(ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo), &_))) {
		reportError(pEnv,"Failed to ZWQueryInformationProcess");
		return NULL;
	}

	// from there to PEB
	PEB ProcPEB;
	if(!ReadProcessMemory(hProcess, ProcInfo.PebBaseAddress, &ProcPEB, sizeof(ProcPEB), &_)) {
		reportError(pEnv,"Failed to read PEB");
		return NULL;
	}

	// then to INFOBLOCK
	RTL_USER_PROCESS_PARAMETERS ProcBlock;
	if(!ReadProcessMemory(hProcess, ProcPEB.dwInfoBlockAddress, &ProcBlock, sizeof(ProcBlock), &_)) {
		reportError(pEnv,"Failed to read RT_USER_PROCESS_PARAMETERS");
		return NULL;
	}

	// now read command line aguments
	LPWSTR pszCmdLine = (LPWSTR)::LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,ProcBlock.wLength+2);
	if(pszCmdLine==NULL) {
		reportError(pEnv,"Failed to allocate memory for reading command line");
		return NULL;
	}

	if(!ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress, pszCmdLine, ProcBlock.wLength, &_)) {
		// on some processes, I noticed that the value of dwCmdLineAddress doesn't have 0x20000 bias
		// that seem to be there for any other processes. This results in err=299.
		// so retry with this address.
		ProcBlock._dwCmdLineAddress |= 0x20000;
		if(!ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress, pszCmdLine, ProcBlock.wLength, &_)) {
			reportError(pEnv,"Failed to read command line arguments");
			return NULL;
		}
	}

	// figure out the size of the env var block
	MEMORY_BASIC_INFORMATION info;
	if(::VirtualQueryEx(hProcess, ProcBlock.env, &info, sizeof(info))==0) {
		reportError(pEnv,"VirtualQueryEx failed");
		return NULL;
	}

	int cmdLineLen = lstrlen(pszCmdLine);
	int envSize = min(0x2000,info.RegionSize); // just to be on the safe side, don't read too big a memory
	LPWSTR buf = (LPWSTR)LocalAlloc(LMEM_FIXED,(cmdLineLen+1/*for \0*/)*2+envSize);
	if(buf==NULL) {
		reportError(pEnv,"Buffer allocation failed");
		return NULL;
	}
	lstrcpy(buf,pszCmdLine);

	if(!ReadProcessMemory(hProcess, ProcBlock.env, buf+cmdLineLen+1, envSize, &_)) {
		reportError(pEnv,"Failed to read environment variable table");
		return NULL;
	}

	CloseHandle(hProcess);

	jstring packedStr = pEnv->NewString((jchar*)buf,cmdLineLen+1+jsize(envSize)/2);

	LocalFree(pszCmdLine);
	LocalFree(buf);

	return packedStr;
}

JNIEXPORT jint JNICALL Java_org_jvnet_winp_Native_getProcessId(JNIEnv* pEnv, jclass clazz, jint handle) {
	HANDLE hProcess = (HANDLE)handle;
	PROCESS_BASIC_INFORMATION ProcInfo;
	SIZE_T _;
	if(!NT_SUCCESS(ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo), &_))) {
		reportError(pEnv,"Failed to ZWQueryInformationProcess");
		return -1;
	}<commit_msg>x86 bug fix. This is getting really messy<commit_after>#include "stdafx.h"
#include "winp.h"
#include "java-interface.h"


// http://msdn.microsoft.com/en-us/library/aa813741(VS.85).aspx
struct RTL_USER_PROCESS_PARAMETERS {
#ifdef _WIN64
	BYTE dwFiller[16];
	PVOID	dwFiller2[10];
#else
	DWORD	dwFiller[16];
#endif
	WORD wLength;
	WORD wMaxLength;
	union {
		LPCWSTR dwCmdLineAddress;
		DWORD _dwCmdLineAddress;
	};
#ifdef _WIN64
	// just found them by trial and error
	PVOID _filler[2];
#endif
	LPCWSTR env;
};

struct PEB  {
#ifdef _WIN64
	BYTE dwFiller[24];
	PVOID dwFiltter2;
#else
	DWORD dwFiller[4];
#endif
	RTL_USER_PROCESS_PARAMETERS* dwInfoBlockAddress;
};

struct PROCESS_BASIC_INFORMATION {
	NTSTATUS ExitStatus;
	PEB* PebBaseAddress;
	PULONG AffinityMask;
	LONG BasePriority;
	PULONG UniqueProcessId;
	PULONG InheritedFromUniqueProcessId;
};

JNIEXPORT jstring JNICALL Java_org_jvnet_winp_Native_getCmdLineAndEnvVars(
	JNIEnv* pEnv, jclass clazz, jint pid) {
	
	// see http://msdn2.microsoft.com/en-us/library/ms674678%28VS.85%29.aspx
	// for kernel string functions

	HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,FALSE,pid);
	if(hProcess==NULL) {
		reportError(pEnv,"Failed to open process");
		return NULL;
	}

	// obtain PROCESS_BASIC_INFORMATION
	PROCESS_BASIC_INFORMATION ProcInfo;
	SIZE_T _;
	if(!NT_SUCCESS(ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo), &_))) {
		reportError(pEnv,"Failed to ZWQueryInformationProcess");
		return NULL;
	}

	// from there to PEB
	PEB ProcPEB;
	if(!ReadProcessMemory(hProcess, ProcInfo.PebBaseAddress, &ProcPEB, sizeof(ProcPEB), &_)) {
		reportError(pEnv,"Failed to read PEB");
		return NULL;
	}

	// then to INFOBLOCK
	RTL_USER_PROCESS_PARAMETERS ProcBlock;
	if(!ReadProcessMemory(hProcess, ProcPEB.dwInfoBlockAddress, &ProcBlock, sizeof(ProcBlock), &_)) {
		reportError(pEnv,"Failed to read RT_USER_PROCESS_PARAMETERS");
		return NULL;
	}

	// now read command line aguments
	LPWSTR pszCmdLine = (LPWSTR)::LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT,ProcBlock.wLength+2);
	if(pszCmdLine==NULL) {
		reportError(pEnv,"Failed to allocate memory for reading command line");
		return NULL;
	}

	if(!ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress, pszCmdLine, ProcBlock.wLength, &_)) {
		// on some processes, I noticed that the value of dwCmdLineAddress doesn't have 0x20000 bias
		// that seem to be there for any other processes. This results in err=299.
		// so retry with this address.
		ProcBlock._dwCmdLineAddress |= 0x20000;
		if(!ReadProcessMemory(hProcess, ProcBlock.dwCmdLineAddress, pszCmdLine, ProcBlock.wLength, &_)) {
			reportError(pEnv,"Failed to read command line arguments");
			return NULL;
		}
	}

	// figure out the size of the env var block
	MEMORY_BASIC_INFORMATION info;
	if(::VirtualQueryEx(hProcess, ProcBlock.env, &info, sizeof(info))==0) {
		reportError(pEnv,"VirtualQueryEx failed");
		return NULL;
	}

	int cmdLineLen = lstrlen(pszCmdLine);
	int envSize = info.RegionSize; // min(0x2000,info.RegionSize); // just to be on the safe side, don't read too big a memory
	LPWSTR buf = (LPWSTR)LocalAlloc(LMEM_FIXED,(cmdLineLen+1/*for \0*/)*2+envSize);
	if(buf==NULL) {
		reportError(pEnv,"Buffer allocation failed");
		return NULL;
	}
	lstrcpy(buf,pszCmdLine);

	if(!ReadProcessMemory(hProcess, ProcBlock.env, buf+cmdLineLen+1, envSize, &_)) {
		reportError(pEnv,"Failed to read environment variable table");
		return NULL;
	}

	CloseHandle(hProcess);

	jstring packedStr = pEnv->NewString((jchar*)buf,cmdLineLen+1+jsize(envSize)/2);

	LocalFree(pszCmdLine);
	LocalFree(buf);

	return packedStr;
}

JNIEXPORT jint JNICALL Java_org_jvnet_winp_Native_getProcessId(JNIEnv* pEnv, jclass clazz, jint handle) {
	HANDLE hProcess = (HANDLE)handle;
	PROCESS_BASIC_INFORMATION ProcInfo;
	SIZE_T _;
	if(!NT_SUCCESS(ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &ProcInfo, sizeof(ProcInfo), &_))) {
		reportError(pEnv,"Failed to ZWQueryInformationProcess");
		return -1;
	}
{'fraction_non_alphanumeric': 0.11294384286074037, 'fraction_numerical': 0.01687232435154873, 'mean_word_length': 5.783091374893254, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5856380', 'n_tokens_mistral': 3081, 'n_tokens_neox': 2875, 'n_words': 608}