#include <iostream>
#include <windows.h>
#include <jni.h>

//#pragma comment(lib, "jvm.lib")
#define PATH_MAX 1024

using namespace std;




void main(){

	

//	/////////////////////////////////////////////////////////////////////////////
//
//	DWORD retval;
//	// fetch jvm.dll path from registry
//	HKEY jKey;
//	if (retval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\JavaSoft\\Java Runtime Environment"), 0, KEY_READ, &jKey))
//	{
//		RegCloseKey(jKey);
//		// assuming you're using C++/CLI
//		
//	}
//
//	
//
//	TCHAR versionString[16]; // version numbers shouldn't be longer than 16 chars
//	DWORD bufsize = 16 * sizeof(TCHAR);
//
//	if (retval = RegQueryValueEx(jKey, TEXT("CurrentVersion"), NULL, NULL, (LPBYTE)versionString, &bufsize))
//	{
//		RegCloseKey(jKey);
//		// assuming you're using C++/CLI
//		
//	}
//
//	//if (retval = RegGetValue(jKey, NULL, TEXT("CurrentVersion"), RRF_RT_REG_SZ, NULL, versionString, &bufsize))
//	//{
//	//	RegCloseKey(jKey);
//	//	// assuming you're using C++/CLI
//	//	
//	//}
//
//	TCHAR* dllpath = new TCHAR[512];
//	bufsize = 512 * sizeof(TCHAR);
//
//	ULONG strLen = 256;
//	char strB[256] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
//
////	retval = RegGetValue(jKey, versionString, TEXT("RuntimeLib"), RRF_RT_REG_SZ, NULL, dllpath, &bufsize);
////		RegCloseKey(jKey);
//
//	/*retval = RegQueryValueEx(jKey, TEXT("RuntimeLib"), NULL, NULL, (LPBYTE)dllpath, &bufsize);
//		RegCloseKey(jKey);*/
//
//	if (retval)
//	{
//		delete[] dllpath;
//		// assuming you're using C++/CLI
//		
//	}
//
//	/////////////////////////////////////////////////////////////////////////////
//
//	/////////////////////////////////////////////////////////////////////////////
//
//	HMODULE jniModule = LoadLibrary(dllpath);
//	delete[] dllpath;
//	if (jniModule == NULL)
//		return;
//	typedef int (JNICALL * JNI_CreateJavaVM)(JavaVM** jvm, JNIEnv** env, JavaVMInitArgs* initargs);
//	JNI_CreateJavaVM createJavaVM = (JNI_CreateJavaVM)GetProcAddress(jniModule, "JNI_CreateJavaVM");

	/////////////////////////////////////////////////////////////////////////////

	cout<<"JVM Create Start!!"<<endl;

	char strA[256];
	char strB[256] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
	ULONG strLen;
	HKEY hk;
	LONG hkType = REG_SZ;
	
	LONG rv = RegOpenKeyEx(
		HKEY_LOCAL_MACHINE,
		strB, 0,
		KEY_QUERY_VALUE,
		&hk
		);

	if( rv != ERROR_SUCCESS ) return; // Windows Humour
	
	strLen = 256;
	rv = RegQueryValueEx(
	    hk, 
	    (LPTSTR)"CurrentVersion", (LPDWORD)0, 
	    (LPDWORD)&hkType,
	    (LPBYTE)&strA, 
	    (LPDWORD)&strLen 
	    );
	if( rv != ERROR_SUCCESS ) return;	
	rv = RegCloseKey( hk );

   	sprintf( strB, "%s\\%s", strB, strA );
   	
    strLen = 256;
   	rv = RegOpenKeyEx(
		HKEY_LOCAL_MACHINE,
		strB, 0,
		KEY_QUERY_VALUE,
		&hk
		);
	if( rv != ERROR_SUCCESS ) return;
   	
	rv = RegQueryValueEx(
	    hk,
	    (LPTSTR)"RuntimeLib", (LPDWORD)0, 
	    (LPDWORD)&hkType,
	    (LPBYTE)&strA, 
	    (LPDWORD)&strLen 
	    );
	if( rv != ERROR_SUCCESS ) return;
	
	rv = RegCloseKey( hk );
	
	HINSTANCE dllInstance = LoadLibrary( strA );	
	if( dllInstance == NULL )
		return;	

	//(PCreateVM) GetProcAddress( dllInstance,  "JNI_CreateJavaVM" );	

	typedef int (JNICALL * JNI_CreateJavaVM)(JavaVM** jvm, JNIEnv** env, JavaVMInitArgs* initargs);
	JNI_CreateJavaVM createJavaVM = (JNI_CreateJavaVM)GetProcAddress(dllInstance, "JNI_CreateJavaVM");

	/////////////////////////////////////////////////////////////////////////////

	JavaVMInitArgs vm_args;
	JavaVMOption options[1];
	options[0].optionString = "-Djava.class.path=.";

	vm_args.version = JNI_VERSION_1_6;
	vm_args.nOptions = 1;
	vm_args.options = options;
	JavaVM* jvm;
	JNIEnv* env;
	long status;
	if ((status = createJavaVM(&jvm, &env, &vm_args)) != JNI_OK)
		return;
///		throw gcnew System::Exception(); // beyond the scope of this answer

	/////////////////////////////////////////////////////////////////////////////

	
	//// JavaVM create & JVM environment setting start
	//JavaVMOption options[1];
	//JavaVMInitArgs vm_args;
	//JNIEnv *env;
	//JavaVM *jvm;
	//long status;
	//
	//options[0].optionString = "-Djava.class.path=.";
	//memset(&vm_args, 0, sizeof(vm_args));
	//vm_args.version = JNI_VERSION_1_6;
	//vm_args.nOptions = 1;
	//vm_args.options = options;
	//status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

	
	// JavaVM create & JVM environment setting end
	
	cout<<"JVM Operating......."<<endl;

	jclass cls;
	jmethodID mid;
	jobject obj;
	int staticresult=0;
	int result=0;

	if(status != JNI_ERR)
	{
		cls = env->FindClass("PWNJava");
		
		if(cls != 0)
		{
			cout<<"class found!"<<endl;

			mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");

			env->CallStaticVoidMethod(cls, mid);
				
		}
		else 
		{
			printf("Can't find class\n");
			return;
		}
		
		jvm->DestroyJavaVM();
		cout<<"\nJVM Destroyed!!"<<endl;

		
	}

	//delete jvm;
	//delete env;

	cout<<"I need to REACH here But it closes before!"<<endl;
	
}
