JNIEXPORT jint JNICALL JNI_OnLoad()

in src/main/c/Windows/SerialPort_Windows.c [611:709]


JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
{
	// Retrieve the JNI environment and class
	JNIEnv *env;
	jint jniVersion = JNI_VERSION_1_2;
	if ((*jvm)->GetEnv(jvm, (void**)&env, jniVersion))
		return JNI_ERR;
	jclass localSerialCommClass = (*env)->FindClass(env, "com/fazecast/jSerialComm/SerialPort");
	if (!localSerialCommClass) return JNI_ERR;
	serialCommClass = (*env)->NewGlobalRef(env, localSerialCommClass);
	if (!serialCommClass) return JNI_ERR;
	jclass localJniErrorClass = (*env)->FindClass(env, "java/lang/Exception");
	if (!localJniErrorClass) return JNI_ERR;
	jniErrorClass = (*env)->NewGlobalRef(env, localJniErrorClass);
	if (!jniErrorClass) return JNI_ERR;

	// Cache Java fields as global references
	serialCommConstructor = (*env)->GetMethodID(env, serialCommClass, "<init>", "()V");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	serialPortHandleField = (*env)->GetFieldID(env, serialCommClass, "portHandle", "J");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	vendorIdField = (*env)->GetFieldID(env, serialCommClass, "vendorID", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	productIdField = (*env)->GetFieldID(env, serialCommClass, "productID", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	serialNumberField = (*env)->GetFieldID(env, serialCommClass, "serialNumber", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	manufacturerField = (*env)->GetFieldID(env, serialCommClass, "manufacturer", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	deviceDriverField = (*env)->GetFieldID(env, serialCommClass, "deviceDriver", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	portLocationField = (*env)->GetFieldID(env, serialCommClass, "portLocation", "Ljava/lang/String;");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	allowOpenForEnumerationField = (*env)->GetStaticFieldID(env, serialCommClass, "allowOpenForEnumeration", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	autoFlushIOBuffersField = (*env)->GetFieldID(env, serialCommClass, "autoFlushIOBuffers", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	parityField = (*env)->GetFieldID(env, serialCommClass, "parity", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	flowControlField = (*env)->GetFieldID(env, serialCommClass, "flowControl", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	requestElevatedPermissionsField = (*env)->GetFieldID(env, serialCommClass, "requestElevatedPermissions", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	xonStartCharField = (*env)->GetFieldID(env, serialCommClass, "xonStartChar", "B");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	xoffStopCharField = (*env)->GetFieldID(env, serialCommClass, "xoffStopChar", "B");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	readTimeoutField = (*env)->GetFieldID(env, serialCommClass, "readTimeout", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	writeTimeoutField = (*env)->GetFieldID(env, serialCommClass, "writeTimeout", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;
	eventFlagsField = (*env)->GetFieldID(env, serialCommClass, "eventFlags", "I");
	if (checkJniError(env, __LINE__ - 1)) return JNI_ERR;

	// Attempt to load Windows functions that may or may not be present on every PC
	HINSTANCE setupApiInstance = LoadLibrary(TEXT("SetupAPI.dll"));
	HINSTANCE kernelInstance = LoadLibrary(TEXT("Kernel32.dll"));
	if (setupApiInstance != NULL)
		SetupDiGetDevicePropertyW = (SetupDiGetDevicePropertyWFunction)GetProcAddress(setupApiInstance, "SetupDiGetDevicePropertyW");
	if (kernelInstance != NULL)
		CancelIoEx = (CancelIoExFunction)GetProcAddress(kernelInstance, "CancelIoEx");

	// Initialize the critical section lock
	InitializeCriticalSection(&criticalSection);
	classInitialized = 1;
	return jniVersion;
}