示例#1
0
/*
 * Class:     jcuda_jcufft_JCufft
 * Method:    cufftGetVersionNative
 * Signature: ([I)I
 */
JNIEXPORT jint JNICALL Java_jcuda_jcufft_JCufft_cufftGetVersionNative
  (JNIEnv *env, jclass cls, jintArray version)
{
    if (version == NULL)
    {
        ThrowByName(env, "java/lang/NullPointerException", "Parameter 'version' is null for cufftGetVersion");
        return JCUFFT_INTERNAL_ERROR;
    }

    Logger::log(LOG_TRACE, "Executing cufftGetVersion\n");

    int nativeVersion = 0;
    int result = cufftGetVersion(&nativeVersion);
    set(env, version, 0, nativeVersion);
    return result;
}
示例#2
0
/*
 * Class:     jcuda_jcufft_JCufft
 * Method:    cufftPlan3dNative
 * Signature: (Ljcuda/jcufft/JCufftHandle;IIII)I
 */
JNIEXPORT jint JNICALL Java_jcuda_jcufft_JCufft_cufftPlan3dNative
  (JNIEnv *env, jclass cla, jobject handle, jint nx, jint ny, jint nz, jint type)
{
    if (handle == NULL)
    {
        ThrowByName(env, "java/lang/NullPointerException", "Parameter 'handle' is null for cufftPlan3d");
        return JCUFFT_INTERNAL_ERROR;
    }

    Logger::log(LOG_TRACE, "Creating 3D plan for (%d, %d, %d) elements of type %d\n", nx, ny, nz, type);

    cufftHandle plan = env->GetIntField(handle, cufftHandle_plan);
    cufftResult result = cufftPlan3d(&plan, nx, ny, nz, getCufftType(type));
    env->SetIntField(handle, cufftHandle_plan, plan);
    return result;
}
示例#3
0
bool releaseNative(JNIEnv *env, cl_double2& values_native, jdoubleArray values, bool writeBack)
{
    if (writeBack)
    {
        jsize length = env->GetArrayLength(values);
        if (length < 2)
        {
            ThrowByName(env, "java/lang/ArrayIndexOutOfBoundsException",
                "Array length must be at least 2");
        }
        jdouble localValues[2];
        localValues[0] = (jdouble)values_native.x;
        localValues[1] = (jdouble)values_native.y;
        env->SetDoubleArrayRegion(values, 0, 2, localValues);
    }
    return true;
}
示例#4
0
bool initNative(JNIEnv *env, jdoubleArray values, cl_double2& values_native, bool fillTarget)
{
    if (fillTarget)
    {
        jsize length = env->GetArrayLength(values);
        if (length < 2)
        {
            ThrowByName(env, "java/lang/ArrayIndexOutOfBoundsException",
                "Array length must be at least 2");
        }
        jdouble localValues[2];
        env->GetDoubleArrayRegion(values, 0, 2, localValues);
        values_native.x = (cl_double)localValues[0];
        values_native.y = (cl_double)localValues[1];
    }
    return true;
}
示例#5
0
文件: JCufft.cpp 项目: caomw/jcufft
/*
 * Class:     jcuda_jcufft_JCufft
 * Method:    cufftEstimate3dNative
 * Signature: (IIII[J)I
 */
JNIEXPORT jint JNICALL Java_jcuda_jcufft_JCufft_cufftEstimate3dNative
  (JNIEnv *env, jclass cls, jint nx, jint ny, jint nz, jint type, jlongArray workSize)
{
    if (workSize == NULL)
    {
        ThrowByName(env, "java/lang/NullPointerException", "Parameter 'workSize' is null for cufftEstimate3d");
        return JCUFFT_INTERNAL_ERROR;
    }

    Logger::log(LOG_TRACE, "Executing cufftEstimate3d\n");

    size_t nativeWorkSize = 0;
    cufftResult result = cufftEstimate3d((int)nx, (int)ny, (int)nz, getCufftType(type), &nativeWorkSize);

    set(env, workSize, 0, (jlong)nativeWorkSize);
    return result;
}
示例#6
0
文件: JCufft.cpp 项目: caomw/jcufft
/*
 * Class:     jcuda_jcufft_JCufft
 * Method:    cufftSetCompatibilityModeNative
 * Signature: (Ljcuda/jcufft/cufftHandle;I)I
 */
JNIEXPORT jint JNICALL Java_jcuda_jcufft_JCufft_cufftSetCompatibilityModeNative
  (JNIEnv *env, jclass cla, jobject plan, jint mode)
{
    if (plan == NULL)
    {
        ThrowByName(env, "java/lang/NullPointerException", "Parameter 'plan' is null for cufftSetCompatibilityMode");
        return JCUFFT_INTERNAL_ERROR;
    }

    Logger::log(LOG_TRACE, "Executing cufftSetCompatibilityMode\n");

    cufftHandle nativePlan = env->GetIntField(plan, cufftHandle_plan);
    cufftCompatibility nativeMode = (cufftCompatibility)mode;

    cufftResult result = cufftSetCompatibilityMode(nativePlan, nativeMode);
    return result;
}
示例#7
0
文件: JCufft.cpp 项目: caomw/jcufft
/*
 * Class:     jcuda_jcufft_JCufft
 * Method:    cufftCreateNative
 * Signature: (Ljcuda/jcufft/cufftHandle;)I
 */
JNIEXPORT jint JNICALL Java_jcuda_jcufft_JCufft_cufftCreateNative
  (JNIEnv *env, jclass cls, jobject handle)
{
    if (handle == NULL)
    {
        ThrowByName(env, "java/lang/NullPointerException", "Parameter 'handle' is null for cufftCreate");
        return JCUFFT_INTERNAL_ERROR;
    }
    Logger::log(LOG_TRACE, "Executing cufftCreate\n");

    cufftHandle nativeHandle = env->GetIntField(handle, cufftHandle_plan);

    cufftResult result = cufftCreate(&nativeHandle);

    env->SetIntField(handle, cufftHandle_plan, nativeHandle);
    return result;

}
示例#8
0
        bool init(JNIEnv *env, jobject object)
        {
            // Obtain the direct buffer address from the given buffer
            jobject buffer = env->GetObjectField(object, Pointer_buffer);
            startPointer = env->GetDirectBufferAddress(buffer);
            if (startPointer == 0)
            {
                ThrowByName(env, "java/lang/IllegalArgumentException",
                    "Failed to obtain direct buffer address");
                return false;
            }

            // Obtain the byteOffset
            byteOffset = env->GetLongField(object, Pointer_byteOffset);
            if (env->ExceptionCheck())
            {
                return false;
            }

            Logger::log(LOG_DEBUGTRACE, "Initialized  DirectBufferPointerData        %p\n", startPointer);
            return true;
        }
示例#9
0
/**
 * Converts the given jlongArray into a size_t* and returns it.
 * To delete the size_t* is left to the caller. Returns
 * NULL if an error occurs.
 */
size_t* convertArray(JNIEnv *env, jlongArray array)
{
    jsize arrayLength = env->GetArrayLength(array);
    size_t *result = new size_t[(size_t)arrayLength];
    if (result == NULL)
    {
        ThrowByName(env, "java/lang/OutOfMemoryError",
            "Out of memory during array creation");
        return NULL;
    }
    jlong *jArray = (jlong*)env->GetPrimitiveArrayCritical(array, NULL);
    if (jArray == NULL)
    {
        return NULL;
    }
    for (int i=0; i<arrayLength; i++)
    {
        result[i] = (size_t)jArray[i];
    }
    env->ReleasePrimitiveArrayCritical(array, jArray, JNI_ABORT);
    return result;
}
示例#10
0
        bool init(JNIEnv *env, jobject object)
        {
            if (object != NULL)
            {
                // Create a global reference to the given object
                nativePointerObject = env->NewGlobalRef(object);
                if (nativePointerObject == NULL)
                {
                    ThrowByName(env, "java/lang/OutOfMemoryError",
                        "Out of memory while creating global reference for pointer data");
                    return false;
                }

                // Obtain the nativePointer value
                nativePointer = env->GetLongField(object, NativePointerObject_nativePointer);
                if (env->ExceptionCheck())
                {
                    return false;
                }
            }
            Logger::log(LOG_DEBUGTRACE, "Initialized  NativePointerObjectPointerData %p\n", nativePointer);
            return true;
        }
示例#11
0
 bool setNewNativePointerValue(JNIEnv *env, jlong nativePointerValue)
 {
     ThrowByName(env, "java/lang/IllegalArgumentException",
         "Pointer to an array may not be overwritten");
     return false;
 }
示例#12
0
        bool release(JNIEnv *env, jint mode=0)
        {
            Logger::log(LOG_DEBUGTRACE, "Releasing    PointersArrayPointerData       %p\n", startPointer);

            jobjectArray pointersArray = (jobjectArray)env->GetObjectField(
                nativePointerObject, Pointer_pointers);
            long size = (long)env->GetArrayLength(pointersArray);

            void **localPointer = (void**)startPointer;
            if (mode != JNI_ABORT)
            {
                // Write back the values from the native pointers array
                // into the Java objects
                for (int i=0; i<size; i++)
                {
                    jobject p = env->GetObjectArrayElement(pointersArray, i);
                    if (env->ExceptionCheck())
                    {
                        return false;
                    }
                    if (p != NULL)
                    {
                        // Check whether the value inside the pointer array has changed.
                        void *oldLocalPointer = arrayPointerDatas[i]->getPointer(env);

                        Logger::log(LOG_DEBUGTRACE, "About to write back pointer %d in PointersArrayPointerData\n", i);
                        Logger::log(LOG_DEBUGTRACE, "Old local pointer was %p\n", oldLocalPointer);
                        Logger::log(LOG_DEBUGTRACE, "New local pointer is  %p\n", localPointer[i]);

                        if (localPointer[i] != oldLocalPointer)
                        {
                            Logger::log(LOG_DEBUGTRACE, "In pointer %d setting value %p\n", i, localPointer[i]);
                            bool pointerUpdated = arrayPointerDatas[i]->setNewNativePointerValue(env, (jlong)localPointer[i]);
                            if (!pointerUpdated)
                            {
                                // If the pointer value could not be updated,
                                // (see setNewNativePointerValue documentation)
                                // then there is a pending IllegalArgumentException
                                return false;
                            }
                        }
                    }
                    else if (localPointer[i] != NULL)
                    {
                        // TODO: In future versions, it might be necessary to instantiate
                        // a pointer object here
                        ThrowByName(env, "java/lang/NullPointerException",
                            "Pointer points to an array containing a 'null' entry");
                        return false;
                    }
                }
            }

            // Release the PointerDatas for the pointer objects that
            // the pointer points to
            if (arrayPointerDatas != NULL)
            {
                for (int i=0; i<size; i++)
                {
                    if (arrayPointerDatas[i] != NULL)
                    {
                        if (!releasePointerData(env, arrayPointerDatas[i], mode)) return false;
                    }
                }
                delete[] arrayPointerDatas;
            }
            delete[] localPointer;

            env->DeleteGlobalRef(nativePointerObject);
            return true;
        }
示例#13
0
        bool init(JNIEnv *env, jobject object)
        {
            // Create a global reference to the given object
            nativePointerObject = env->NewGlobalRef(object);
            if (nativePointerObject == NULL)
            {
                ThrowByName(env, "java/lang/OutOfMemoryError",
                    "Out of memory while creating global reference for pointer data");
                return false;
            }

            jobjectArray pointersArray = (jobjectArray)env->GetObjectField(
                object, Pointer_pointers);
            long size = (long)env->GetArrayLength(pointersArray);

            // Prepare the pointer that points to the pointer
            // values of the NativePointerObjects
            void **localPointer = new void*[size];
            if (localPointer == NULL)
            {
                ThrowByName(env, "java/lang/OutOfMemoryError",
                    "Out of memory while initializing pointer array");
                return false;
            }
            startPointer = (void*)localPointer;

            // Prepare the PointerData objects for the Java NativePointerObjects
            arrayPointerDatas = new PointerData*[size];
            if (arrayPointerDatas == NULL)
            {
                ThrowByName(env, "java/lang/OutOfMemoryError",
                    "Out of memory while initializing pointer data array");
                return false;
            }

            // Initialize the PointerDatas and the pointer values
            // from the NativePointerObjects in the Java Pointer.
            for (int i=0; i<size; i++)
            {
                jobject p = env->GetObjectArrayElement(pointersArray, i);
                if (env->ExceptionCheck())
                {
                    return false;
                }
                if (p != NULL)
                {
                    // Initialize a PointerData for the pointer object that
                    // the pointer points to
                    PointerData *arrayPointerData = initPointerData(env, p);
                    if (arrayPointerData == NULL)
                    {
                        return false;
                    }
                    arrayPointerDatas[i] = arrayPointerData;
                    localPointer[i] = arrayPointerData->getPointer(env);
                }
                else
                {
                    arrayPointerDatas[i] = NULL;
                    localPointer[i] = NULL;
                }
            }

            // Obtain the byteOffset
            byteOffset = env->GetLongField(object, Pointer_byteOffset);
            if (env->ExceptionCheck())
            {
                return false;
            }

            Logger::log(LOG_DEBUGTRACE, "Initialized  PointersArrayPointerData       %p\n", startPointer);
            return true;
        }
示例#14
0
/**
 * Initializes a PointerData with the data from the given Java NativePointerObject.
 *
 * If the given pointerObject is NULL, the method simply sets the startPointer
 * and pointer of the pointerData to NULL and returns it.
 *
 * Otherwise, this method will initialize the startPointer of the PointerData,
 * and the pointer of the PointerData will be set to
 *     startPointer+byteOffset
 * where byteOffset is the byteOffset that is obtained from the Java Pointer
 * object.
 *
 * By default, the startPointer of the PointerData will be initialized with
 * the native pointer value from the given Java Pointer object. If this
 * startPointer is non-NULL, the method sets memoryType to NATIVE and
 * returns it.
 *
 * If the array of Java Pointers that the Pointer points to is non-NULL, then
 * the startPointer of the PointerData be set to point to an array of
 * void* pointers that correspond to the values of the Java Pointers
 * from the array. If this array can be created, the method sets the
 * memoryType to POINTERS and returns the PointerData.
 *
 * If the Buffer of the Pointer is non-null, then the startPointer will be
 * obtained from the buffer:
 * - If the Buffer is direct, this method sets the startPointer to the
 *   direct buffer address, sets memoryType to DIRECT and returns the
 *   PointerData
 * - If the buffer has an array, the method sets the startPointer to the
 *   array, sets memoryType to ARRAY or ARRAY_COPY, indicating whether
 *   the array was pinned or copied, and returns the PointerData.
 *
 * If none of these attempts of obtaining the startPointer was
 * successful, then the method returns the empty PointerData.
 *
 * If an Exception occurs, NULL is returned.
 */
PointerData* initPointerData(JNIEnv *env, jobject pointerObject)
{
    Logger::log(LOG_DEBUGTRACE, "Initializing pointer data for Java Pointer object %p\n", pointerObject);

    PointerData *pointerData = new PointerData();
    if (pointerData == NULL)
    {
        ThrowByName(env, "java/lang/OutOfMemoryError",
            "Out of memory while initializing pointer data");
        return NULL;
    }

    pointerData->startPointer = (jlong)NULL;
    pointerData->pointer = (jlong)NULL;
    pointerData->memoryType = NATIVE;

    if (pointerObject == NULL)
    {
        return pointerData;
    }
    else
    {
        pointerData->pointerObject = env->NewGlobalRef(pointerObject);
        if (pointerData->pointerObject == NULL)
        {
            ThrowByName(env, "java/lang/OutOfMemoryError",
                "Out of memory while creating reference to pointer object");
            return NULL;
        }
    }


    pointerData->startPointer = env->GetLongField(pointerData->pointerObject, NativePointerObject_nativePointer);

    // Set the actual pointer to be the startPointer + the byte offset
    long byteOffset = (long)env->GetLongField(pointerObject, NativePointerObject_byteOffset);
    pointerData->pointer = (jlong)(((char*)pointerData->startPointer)+byteOffset);

    if (pointerData->startPointer != (jlong)NULL)
    {
        Logger::log(LOG_DEBUGTRACE, "Obtaining native pointer %p\n", (void*)pointerData->startPointer);

        pointerData->memoryType = NATIVE;
        return pointerData;
    }

    // Obtain the array of pointers the pointer points to
    jobjectArray pointersArray = (jobjectArray)env->GetObjectField(pointerObject, NativePointerObject_pointers);
    if (pointersArray != NULL)
    {
        Logger::log(LOG_DEBUGTRACE, "Obtaining pointers in host memory\n");

        // Create an array containing the native representations of the
        // pointers, and store them as the data of the pointerData
        jsize size = env->GetArrayLength(pointersArray);
        void **localPointer = new void*[(size_t)size];
        PointerData **localPointerDatas = new PointerData*[(size_t)size];

        if (localPointer == NULL)
        {
            ThrowByName(env, "java/lang/OutOfMemoryError",
                "Out of memory while obtaining native pointers");
            return NULL;
        }
        for (int i=0; i<size; i++)
        {
            jobject p = env->GetObjectArrayElement(pointersArray, i);
            if (env->ExceptionCheck())
            {
                return NULL;
            }
            if (p != NULL)
            {
                // Initialize a PointerData for the pointer object that
                // the pointer points to
                PointerData *localPointerData = initPointerData(env, p);
                if (localPointerData == NULL)
                {
                    return NULL;
                }
                localPointerDatas[i] = localPointerData;
                localPointer[i] = (void*)localPointerData->startPointer;
            }
            else
            {
                localPointerDatas[i] = NULL;
                localPointer[i] = NULL;
            }
        }
        pointerData->pointers = localPointerDatas;
        pointerData->startPointer = (jlong)localPointer;

        // Set the actual pointer to be the startPointer + the byte offset
        long byteOffset = (long)env->GetLongField(pointerObject, NativePointerObject_byteOffset);
        pointerData->pointer = (jlong)(((char*)pointerData->startPointer)+byteOffset);

        pointerData->memoryType = POINTERS;
        return pointerData;
    }

    jobject buffer = env->GetObjectField(pointerObject, NativePointerObject_buffer);
    if (buffer != NULL)
    {
        // Check if the buffer is direct
        jboolean isDirect = env->CallBooleanMethod(buffer, Buffer_isDirect);
        if (env->ExceptionCheck())
        {
            return NULL;
        }

        if (isDirect==JNI_TRUE)
        {
            Logger::log(LOG_DEBUGTRACE, "Obtaining host memory from direct java buffer\n");

            // Obtain the direct buffer address from the given buffer
            pointerData->startPointer = (jlong)env->GetDirectBufferAddress(buffer);
            if (pointerData->startPointer == 0)
            {
                ThrowByName(env, "java/lang/IllegalArgumentException",
                    "Failed to obtain direct buffer address");
                return NULL;
            }
            pointerData->memoryType = DIRECT;

            // Set the actual pointer to be the startPointer + the byte offset
            long byteOffset = (long)env->GetLongField(pointerObject, NativePointerObject_byteOffset);
            pointerData->pointer = (jlong)(((char*)pointerData->startPointer)+byteOffset);

            return pointerData;
        }

        // Check if the buffer has an array
        jboolean hasArray = env->CallBooleanMethod(buffer, Buffer_hasArray);
        if (env->ExceptionCheck())
        {
            return NULL;
        }

        if (hasArray==JNI_TRUE)
        {
            Logger::log(LOG_DEBUGTRACE, "Obtaining host memory from array in java buffer\n");

            long byteOffset = (long)env->GetLongField(pointerObject, NativePointerObject_byteOffset);

            jarray localArray = (jarray)env->CallObjectMethod(buffer, Buffer_array);
            if (env->ExceptionCheck())
            {
                return NULL;
            }
            jarray globalArray = (jarray)env->NewGlobalRef(localArray);
            if (globalArray == NULL)
            {
                return NULL;
            }
            pointerData->array = globalArray;

            jboolean isCopy = JNI_FALSE;
            pointerData->startPointer = (jlong)env->GetPrimitiveArrayCritical(globalArray, &isCopy); 
            if (pointerData->startPointer == 0)
            {
                return NULL;
            }

            if (isCopy==JNI_TRUE)
            {
                pointerData->memoryType = ARRAY_COPY;
            }
            else
            {
                pointerData->memoryType = ARRAY;
            }

            // Set the actual pointer to be the startPointer + the byte offset
            pointerData->pointer = (jlong)(((char*)pointerData->startPointer)+byteOffset);

            return pointerData;
        }

        // The buffer is neither direct nor has an array - should have
        // been checked on Java side
        Logger::log(LOG_ERROR, "Buffer is neither direct nor has an array\n");
        ThrowByName(env, "java/lang/IllegalArgumentException",
            "Buffer is neither direct nor has an array");
        return NULL;
    }

    return pointerData;
}
示例#15
0
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec1
  (JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir) 
{

    SECURITY_ATTRIBUTES sa;
    PROCESS_INFORMATION pi = {0};
    STARTUPINFOW si;
	DWORD flags = 0;
    wchar_t * cwd = NULL;
	wchar_t * envBlk = NULL;
    int ret = 0;
	jsize nCmdTokens = 0;
	jsize nEnvVars = 0;
	int i;
	int nPos;
    int nCmdLineLength= 0;
	wchar_t * szCmdLine= 0;
	int nBlkSize = MAX_ENV_SIZE; 
	wchar_t * szEnvBlock = NULL;

    nCmdLineLength= MAX_CMD_SIZE;
	szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t));
    szCmdLine[0]= 0;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = 0;
    sa.bInheritHandle = TRUE;


	nCmdTokens = env->GetArrayLength(cmdarray);
    nEnvVars   = env->GetArrayLength(envp);

	nPos = 0;

	// Prepare command line
	for(i = 0; i < nCmdTokens; ++i) 
		{
		jstring item = (jstring)env->GetObjectArrayElement(cmdarray, i);
		jsize    len = env->GetStringLength(item);
		int nCpyLen;
		const wchar_t *  str = (const wchar_t *)env->GetStringChars(item, 0);	
		if(NULL != str)
			{
			int requiredSize= nPos+len+2;
			if (requiredSize > 32*1024) {
				ThrowByName(env, "java/io/IOException", "Command line too long");
				return 0;
			}				
			ensureSize(&szCmdLine, &nCmdLineLength, requiredSize);
			if (NULL == szCmdLine) {
				ThrowByName(env, "java/io/IOException", "Not enough memory");
				return 0;
			}
			    
			if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, nCmdLineLength - nPos)))
				{
				ThrowByName(env, "java/io/Exception", "Command line too long");
				return 0;
				}
			nPos += nCpyLen;
			szCmdLine[nPos] = _T(' ');
			++nPos;
			env->ReleaseStringChars(item, (const jchar *)str);
			}
		}

	szCmdLine[nPos] = _T('\0');

	// Prepare environment block
    if (nEnvVars > 0) 
		{
		szEnvBlock = (wchar_t *)malloc(nBlkSize * sizeof(wchar_t));
		nPos = 0;
		for(i = 0; i < nEnvVars; ++i) 
			{
			jstring item = (jstring)env->GetObjectArrayElement(envp, i);
			jsize    len = env->GetStringLength(item);
			const wchar_t *  str = (const wchar_t *)env->GetStringChars(item, 0);	
			if(NULL != str)
				{
				while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0'
					{
					nBlkSize += MAX_ENV_SIZE;
					szEnvBlock = (wchar_t *)realloc(szEnvBlock, nBlkSize * sizeof(wchar_t));
					if(NULL == szEnvBlock) 
						{
						ThrowByName(env, "java/io/Exception", "Not enough memory");
						return 0;
						}
					}
				wcsncpy(szEnvBlock + nPos, str, len);
				nPos += len;
				szEnvBlock[nPos] = _T('\0');
				++nPos;
				env->ReleaseStringChars(item, (const jchar *)str);
				}
			}
    	szEnvBlock[nPos] = _T('\0');
		envBlk = szEnvBlock;
		}



    if (dir != 0) 
		{ 
		const wchar_t * str = (const wchar_t *)env->GetStringChars(dir, 0);
		if(NULL != str) 
			{
			cwd = wcsdup(str);
			env->ReleaseStringChars(dir, (const jchar *)str);
			}
		}


    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);





	flags = CREATE_NEW_CONSOLE;
	flags |= CREATE_UNICODE_ENVIRONMENT;
    ret = CreateProcessW(0,                /* executable name */
                        szCmdLine,              /* command line */
                        0,                /* process security attribute */
                        0,                /* thread security attribute */
                        TRUE,             /* inherits system handles */
                        flags,            /* normal attached process */
                        envBlk,       /* environment block */
                        cwd,              /* change to the new current directory */
                        &si,              /* (in)  startup information */
                        &pi);             /* (out) process information */

    

	if(NULL != cwd)
		free(cwd);
	if(NULL != szEnvBlock)
		free(szEnvBlock);
	if(NULL != szCmdLine)
		free(szCmdLine);

    if (!ret)  // error
		{
		char * lpMsgBuf;

		FormatMessage( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
				(wchar_t *)&lpMsgBuf,
				0,
				NULL 
		);
		ThrowByName(env, "java/io/IOException", lpMsgBuf);
		// Free the buffer.
		LocalFree( lpMsgBuf );		
		ret = -1;
		}
    else
		{
		// Clean-up
		CloseHandle(pi.hThread);
		CloseHandle(pi.hProcess);
		ret = (long)pi.dwProcessId; //hProcess;
		}


    return ret;

}
示例#16
0
JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_spawner_Spawner_exec0
  (JNIEnv * env, jobject process, jobjectArray cmdarray, jobjectArray envp, jstring dir, jintArray channels) 
{
	HANDLE stdHandles[3];
    PROCESS_INFORMATION pi = {0}, *piCopy;
    STARTUPINFOW si;
	DWORD flags = 0;
    const wchar_t  * cwd = NULL;
	LPVOID envBlk = NULL;
    int ret = 0;
    int nCmdLineLength= 0;
	wchar_t * szCmdLine= 0;
	int nBlkSize = MAX_ENV_SIZE; 
	wchar_t * szEnvBlock = NULL;
	jsize nCmdTokens = 0;
	jsize nEnvVars = 0;
	int i;
	DWORD pid = GetCurrentProcessId();
	int nPos;
	pProcInfo_t pCurProcInfo;

	// This needs to be big enough to contain the name of the event used when calling CreateEventW bellow. 
	// It is made of a prefix (7 characters max) plus the value of a pointer that gets output in characters.
	// This will be bigger in the case of 64 bit.
	static const int MAX_EVENT_NAME_LENGTH = 50;
	wchar_t eventBreakName[MAX_EVENT_NAME_LENGTH];
	wchar_t eventWaitName[MAX_EVENT_NAME_LENGTH];
	wchar_t eventTerminateName[MAX_EVENT_NAME_LENGTH];
	wchar_t eventKillName[MAX_EVENT_NAME_LENGTH];
	wchar_t eventCtrlcName[MAX_EVENT_NAME_LENGTH];
#ifdef DEBUG_MONITOR
	wchar_t buffer[4000];
#endif
	int nLocalCounter;
	wchar_t inPipeName[PIPE_NAME_LENGTH];
	wchar_t outPipeName[PIPE_NAME_LENGTH];
	wchar_t errPipeName[PIPE_NAME_LENGTH];

    nCmdLineLength= MAX_CMD_SIZE;
    szCmdLine= (wchar_t *)malloc(nCmdLineLength * sizeof(wchar_t));
    szCmdLine[0]= _T('\0');
	if((HIBYTE(LOWORD(GetVersion()))) & 0x80)
		{
		ThrowByName(env, "java/io/IOException", "Does not support Windows 3.1/95/98/Me");
		return 0;
		}

    if (cmdarray == 0) 
		{
		ThrowByName(env, "java/lang/NullPointerException", "No command line specified");
		return 0;
		}

   ZeroMemory(stdHandles, sizeof(stdHandles));

	// Create pipe names
   EnterCriticalSection(&cs);
   swprintf(inPipeName,  L"\\\\.\\pipe\\stdin%08i%010i",  pid, nCounter); 
   swprintf(outPipeName, L"\\\\.\\pipe\\stdout%08i%010i", pid, nCounter); 
   swprintf(errPipeName, L"\\\\.\\pipe\\stderr%08i%010i", pid, nCounter); 
   nLocalCounter = nCounter;
   ++nCounter;
   LeaveCriticalSection(&cs);

   if ((INVALID_HANDLE_VALUE == (stdHandles[0] = CreateNamedPipeW(inPipeName, PIPE_ACCESS_OUTBOUND,
									  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
									  PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) ||
	   (INVALID_HANDLE_VALUE == (stdHandles[1] = CreateNamedPipeW(outPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
									  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
									  PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))) ||
	   (INVALID_HANDLE_VALUE == (stdHandles[2] = CreateNamedPipeW(errPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
									  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
									  PIPE_UNLIMITED_INSTANCES, PIPE_SIZE, PIPE_SIZE, PIPE_TIMEOUT, NULL))))		{
		CloseHandle(stdHandles[0]);
        CloseHandle(stdHandles[1]);
        CloseHandle(stdHandles[2]);
		ThrowByName(env, "java/io/IOException", "CreatePipe");
		return 0;
   } 

#ifdef DEBUG_MONITOR
	swprintf(buffer, _T("Opened pipes: %s, %s, %s\n"), inPipeName, outPipeName, errPipeName);
	OutputDebugStringW(buffer);
#endif
	

	nCmdTokens = env->GetArrayLength(cmdarray);
    nEnvVars   = env->GetArrayLength(envp);

	pCurProcInfo = createProcInfo();

	if(NULL == pCurProcInfo)
		{
		ThrowByName(env, "java/io/IOException", "Too many processes");
		return 0;
		}

	// Construct starter's command line
	swprintf(eventBreakName, L"SABreak%04x%08x", pid, nLocalCounter);
	swprintf(eventWaitName, L"SAWait%004x%08x", pid, nLocalCounter);
	swprintf(eventTerminateName, L"SATerm%004x%08x", pid, nLocalCounter);
	swprintf(eventKillName, L"SAKill%04x%08x", pid, nLocalCounter);
	swprintf(eventCtrlcName, L"SACtrlc%04x%08x", pid, nLocalCounter);

	pCurProcInfo->eventBreak     = CreateEventW(NULL, FALSE, FALSE, eventBreakName);
    if(NULL == pCurProcInfo->eventBreak || GetLastError() == ERROR_ALREADY_EXISTS)
        {
        ThrowByName(env, "java/io/IOException", "Cannot create event");
        return 0;
        }
	pCurProcInfo->eventWait      = CreateEventW(NULL, TRUE,  FALSE, eventWaitName);
	pCurProcInfo->eventTerminate = CreateEventW(NULL, FALSE, FALSE, eventTerminateName);
	pCurProcInfo->eventKill      = CreateEventW(NULL, FALSE, FALSE, eventKillName);
	pCurProcInfo->eventCtrlc     = CreateEventW(NULL, FALSE, FALSE, eventCtrlcName);

	swprintf(szCmdLine, L"\"%sstarter.exe\" %i %i %s %s %s %s %s ", path, pid, nLocalCounter, eventBreakName, eventWaitName, eventTerminateName, eventKillName, eventCtrlcName);
	nPos = wcslen(szCmdLine);

	// Prepare command line
	for(i = 0; i < nCmdTokens; ++i) 
    	{
		jstring item = (jstring)env->GetObjectArrayElement(cmdarray, i);
		jsize    len = env->GetStringLength(item);
		int nCpyLen;
		const wchar_t *  str = (const wchar_t *)env->GetStringChars(item, 0);	
		if(NULL != str) 
			{
			int requiredSize= nPos+len+2;
			if (requiredSize > 32*1024) {
				ThrowByName(env, "java/io/IOException", "Command line too long");
				return 0;
			}				
			ensureSize(&szCmdLine, &nCmdLineLength, requiredSize);
			if (NULL == szCmdLine) {
				ThrowByName(env, "java/io/IOException", "Not enough memory");
				return 0;
			}
			    
			if(0 > (nCpyLen = copyTo(szCmdLine + nPos, str, len, nCmdLineLength - nPos)))
                {
				ThrowByName(env, "java/io/IOException", "Command line too long");
				return 0;
			}
			nPos += nCpyLen;
			szCmdLine[nPos] = _T(' ');
			++nPos;
			env->ReleaseStringChars(item, (const jchar *)str);
		}
	}
	szCmdLine[nPos] = _T('\0');

#ifdef DEBUG_MONITOR
	swprintf(buffer, _T("There are %i environment variables \n"), nEnvVars);
	OutputDebugStringW(buffer);
#endif
	// Prepare environment block
    if (nEnvVars > 0) 
		{
		nPos = 0;
		szEnvBlock = (wchar_t *)malloc(nBlkSize * sizeof(wchar_t));
		for(i = 0; i < nEnvVars; ++i) 
			{
			jstring item = (jstring)env->GetObjectArrayElement(envp, i);
			jsize    len = env->GetStringLength(item);
			const wchar_t *  str = (const wchar_t *)env->GetStringChars(item, 0);	
			if(NULL != str)
				{
				while((nBlkSize - nPos) <= (len + 2)) // +2 for two '\0'
					{
					nBlkSize += MAX_ENV_SIZE;
					szEnvBlock = (wchar_t *)realloc(szEnvBlock, nBlkSize * sizeof(wchar_t));
					if(NULL == szEnvBlock) 
						{
						ThrowByName(env, "java/io/IOException", "Not enough memory");
						return 0;
						}
#ifdef DEBUG_MONITOR
					swprintf(buffer, _T("Realloc environment block; new length is  %i \n"), nBlkSize);
					OutputDebugStringW(buffer);
#endif

					}
#ifdef DEBUG_MONITOR
				swprintf(buffer, _T("%s\n"), str);
				OutputDebugStringW(buffer);
#endif
				wcsncpy(szEnvBlock + nPos, str, len);
				nPos += len;
				szEnvBlock[nPos] = _T('\0');
				++nPos;
				env->ReleaseStringChars(item, (const jchar *)str);
				}
			}
			szEnvBlock[nPos] = _T('\0');
		}



    if (dir != 0) 
		{ 
		const wchar_t * str = (const wchar_t *)env->GetStringChars(dir, 0);
		if(NULL != str)
			{
			cwd = wcsdup(str);
			env->ReleaseStringChars(dir, (const jchar *)str);
			}
		}


    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags |= STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;  // Processes in the Process Group are hidden



    SetHandleInformation(stdHandles[0], HANDLE_FLAG_INHERIT, FALSE);
    SetHandleInformation(stdHandles[1],  HANDLE_FLAG_INHERIT, FALSE);
    SetHandleInformation(stdHandles[2],  HANDLE_FLAG_INHERIT, FALSE);

	flags = CREATE_NEW_CONSOLE;
	flags |= CREATE_NO_WINDOW;
	flags |= CREATE_UNICODE_ENVIRONMENT;

#ifdef DEBUG_MONITOR
	OutputDebugStringW(szCmdLine);
#endif
	// launches starter; we need it to create another console group to correctly process 
	// emulation of SYSint signal (Ctrl-C)
    ret = CreateProcessW(0,                /* executable name */
                        szCmdLine,        /* command line */
                        0,                /* process security attribute */
                        0,                /* thread security attribute */
                        FALSE,            /* inherits system handles */
                        flags,            /* normal attached process */
                        szEnvBlock,		  /* environment block */
                        cwd,              /* change to the new current directory */
                        &si,              /* (in)  startup information */
                        &pi);             /* (out) process information */

	if(NULL != cwd)
		free((void *)cwd);

	if(NULL != szEnvBlock)
		free(szEnvBlock);

    if(NULL != szCmdLine) 
        free(szCmdLine);
      
    if (!ret) // Launching error
		{
		char * lpMsgBuf;	    
		CloseHandle(stdHandles[0]);
		CloseHandle(stdHandles[1]);
		CloseHandle(stdHandles[2]); 
		FormatMessageA( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS,
			NULL,
			GetLastError(),
			MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
			(char *)&lpMsgBuf,
			0,
			NULL 
		);
		ThrowByName(env, "java/io/IOException", lpMsgBuf);
		// Free the buffer.
		LocalFree( lpMsgBuf );
		cleanUpProcBlock(pCurProcInfo);
		ret = -1;
		}
    else
		{
    	int file_handles[3];
		HANDLE h[2];
		int what;

		EnterCriticalSection(&cs);

		pCurProcInfo -> pid = pi.dwProcessId;
        h[0] = pCurProcInfo -> eventWait;
		h[1] = pi.hProcess;
		
		what = WaitForMultipleObjects(2, h, FALSE, INFINITE); 
		if(what != WAIT_OBJECT_0) // CreateProcess failed
			{
#ifdef DEBUG_MONITOR
			swprintf(buffer, _T("Process %i failed\n"), pi.dwProcessId);
			OutputDebugStringW(buffer);
#endif
			cleanUpProcBlock(pCurProcInfo);
			ThrowByName(env, "java/io/IOException", "Launching failed");
#ifdef DEBUG_MONITOR
			OutputDebugStringW(_T("Process failed\n"));
#endif
			}
		else 
			{
			ret = (long)(pCurProcInfo -> uid);
			
			// Prepare stream handlers to return to java program
			file_handles[0] = (int)stdHandles[0];
			file_handles[1] = (int)stdHandles[1];
			file_handles[2] = (int)stdHandles[2];
			env->SetIntArrayRegion(channels, 0, 3, (jint *)file_handles);

			// do the cleanup so launch the according thread
			// create a copy of the PROCESS_INFORMATION as this might get destroyed
			piCopy = (PROCESS_INFORMATION *)malloc(sizeof(PROCESS_INFORMATION));
			memcpy(piCopy, &pi, sizeof(PROCESS_INFORMATION));
			_beginthread(waitProcTermination, 0, (void *)piCopy);

#ifdef DEBUG_MONITOR
			OutputDebugStringW(_T("Process started\n"));
#endif
			}				
		LeaveCriticalSection(&cs);

		}

	CloseHandle(pi.hThread);

    return ret;

}