Example #1
0
extern "C" JNIEXPORT jint JNICALL 
Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
  DWORD exitCode;
  WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
  BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
  if(not success){
    throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
  }

  CloseHandle(reinterpret_cast<HANDLE>(pid));
  CloseHandle(reinterpret_cast<HANDLE>(tid));

  return exitCode;
}
Example #2
0
extern "C" JNIEXPORT jint JNICALL
    Java_java_lang_Runtime_waitFor(JNIEnv* e, jclass, jlong pid, jlong tid)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  DWORD exitCode;
  WaitForSingleObject(reinterpret_cast<HANDLE>(pid), INFINITE);
  BOOL success = GetExitCodeProcess(reinterpret_cast<HANDLE>(pid), &exitCode);
  if (not success) {
    throwNew(e, "java/lang/Exception", getErrorStr(GetLastError()));
  }

  CloseHandle(reinterpret_cast<HANDLE>(pid));
  CloseHandle(reinterpret_cast<HANDLE>(tid));

  return exitCode;
#else
  throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
  return -1;
#endif
}
Example #3
0
extern "C" JNIEXPORT void JNICALL
    Java_java_lang_Runtime_exec(JNIEnv* e,
                                jclass,
                                jobjectArray command,
                                jlongArray process)
{
#if !defined(WINAPI_FAMILY) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
  int size = 0;
  for (int i = 0; i < e->GetArrayLength(command); ++i) {
    jstring element = (jstring)e->GetObjectArrayElement(command, i);
    if (element) {
      // worst case, assuming every character is '"', and we escape all of them
      size += 2 * e->GetStringUTFLength(element) + 3;
    } else {
      throwNew(e,
               "java/lang/NullPointerException",
               strdup("null string array element"));
    }
  }

  RUNTIME_ARRAY(char, line, size);
  char* linep = RUNTIME_ARRAY_BODY(line);
  for (int i = 0; i < e->GetArrayLength(command); ++i) {
    if (i)
      *(linep++) = _T(' ');
    jstring element = (jstring)e->GetObjectArrayElement(command, i);
    const char* s = e->GetStringUTFChars(element, 0);

    copyAndEscape(&linep, s, e->GetStringUTFLength(element));

    e->ReleaseStringUTFChars(element, s);
  }
  *(linep++) = _T('\0');

  HANDLE in[] = {0, 0};
  HANDLE out[] = {0, 0};
  HANDLE err[] = {0, 0};

  makePipe(e, in);
  SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
  jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
  if (e->ExceptionCheck())
    return;
  e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
  makePipe(e, out);
  SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
  jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
  if (e->ExceptionCheck())
    return;
  e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
  makePipe(e, err);
  SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
  jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
  if (e->ExceptionCheck())
    return;
  e->SetLongArrayRegion(process, 4, 1, &errDescriptor);

  PROCESS_INFORMATION pi;
  ZeroMemory(&pi, sizeof(pi));

  STARTUPINFO si;
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdOutput = in[1];
  si.hStdInput = out[0];
  si.hStdError = err[1];

  BOOL success = CreateProcess(0,
                               (LPSTR)RUNTIME_ARRAY_BODY(line),
                               0,
                               0,
                               1,
                               CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                               0,
                               0,
                               &si,
                               &pi);

  CloseHandle(in[1]);
  CloseHandle(out[0]);
  CloseHandle(err[1]);

  if (not success) {
    throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    return;
  }

  jlong pid = reinterpret_cast<jlong>(pi.hProcess);
  e->SetLongArrayRegion(process, 0, 1, &pid);
  jlong tid = reinterpret_cast<jlong>(pi.hThread);
  e->SetLongArrayRegion(process, 1, 1, &tid);
#else
  throwNew(e, "java/io/Exception", strdup("Not supported on WinRT/WinPhone8"));
#endif
}
Example #4
0
extern "C" JNIEXPORT void JNICALL 
Java_java_lang_Runtime_exec(JNIEnv* e, jclass, 
                            jobjectArray command, jlongArray process)
{
  
  int size = 0;
  for (int i = 0; i < e->GetArrayLength(command); ++i){
    jstring element = (jstring) e->GetObjectArrayElement(command, i);
    size += e->GetStringUTFLength(element) + 1;
  } 
   
  RUNTIME_ARRAY(char, line, size);
  char* linep = RUNTIME_ARRAY_BODY(line);
  for (int i = 0; i < e->GetArrayLength(command); ++i) {
    if (i) *(linep++) = _T(' ');
    jstring element = (jstring) e->GetObjectArrayElement(command, i);
    const char* s =  e->GetStringUTFChars(element, 0);
#ifdef _MSC_VER
    _tcscpy_s(linep, size - (linep - RUNTIME_ARRAY_BODY(line)), s);
#else
    _tcscpy(linep, s);
#endif
    e->ReleaseStringUTFChars(element, s);
    linep += e->GetStringUTFLength(element);
  }
  *(linep++) = _T('\0');
 
  HANDLE in[] = { 0, 0 };
  HANDLE out[] = { 0, 0 };
  HANDLE err[] = { 0, 0 };
  
  makePipe(e, in);
  SetHandleInformation(in[0], HANDLE_FLAG_INHERIT, 0);
  jlong inDescriptor = static_cast<jlong>(descriptor(e, in[0]));
  if(e->ExceptionCheck()) return;
  e->SetLongArrayRegion(process, 2, 1, &inDescriptor);
  makePipe(e, out);
  SetHandleInformation(out[1], HANDLE_FLAG_INHERIT, 0);
  jlong outDescriptor = static_cast<jlong>(descriptor(e, out[1]));
  if(e->ExceptionCheck()) return;
  e->SetLongArrayRegion(process, 3, 1, &outDescriptor);
  makePipe(e, err);
  SetHandleInformation(err[0], HANDLE_FLAG_INHERIT, 0);
  jlong errDescriptor = static_cast<jlong>(descriptor(e, err[0]));
  if(e->ExceptionCheck()) return;
  e->SetLongArrayRegion(process, 4, 1, &errDescriptor);
  
  PROCESS_INFORMATION pi;
  ZeroMemory(&pi, sizeof(pi));
 
  STARTUPINFO si;
  ZeroMemory(&si, sizeof(si));
  si.cb = sizeof(si);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdOutput = in[1];
  si.hStdInput = out[0];
  si.hStdError = err[1];
 
  BOOL success = CreateProcess(0, (LPSTR) RUNTIME_ARRAY_BODY(line), 0, 0, 1,
                               CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
                               0, 0, &si, &pi);

  CloseHandle(in[1]);
  CloseHandle(out[0]);
  CloseHandle(err[1]);
  
  if (not success) {
    throwNew(e, "java/io/IOException", getErrorStr(GetLastError()));
    return;
  }
  
  jlong pid = reinterpret_cast<jlong>(pi.hProcess);
  e->SetLongArrayRegion(process, 0, 1, &pid);
  jlong tid = reinterpret_cast<jlong>(pi.hThread);  
  e->SetLongArrayRegion(process, 1, 1, &tid);
}
Example #5
0
int DirectoryMonitor::Server::read() {
	DWORD		dwBytesXFered = 0;
	ULONG_PTR	ulKey = 0;
	OVERLAPPED*	pOl;

	auto ret = GetQueuedCompletionStatus(m_hIOCP, &dwBytesXFered, &ulKey, &pOl, INFINITE);
	auto dwError = GetLastError();
	if (!ret) {
		if (!m_hIOCP) {
			// shutting down
			return 0;
		}

		if (dwError == WAIT_TIMEOUT) {
			//harmless
			return 1;
		}
	}

	{
		WLock l(cs);
		auto mon = find_if(monitors | map_values, [ulKey](const Monitor* m) { return (ULONG_PTR)m->key == ulKey; });
		if (mon.base() != monitors.end()) {
			if (!(*mon)->m_hDirectory) {
				//this is going to be deleted
				deleteDirectory(mon.base());
				return 1;
			}

			try {
				if ((dwError != 0 && dwError != ERROR_INVALID_PARAMETER) || !ret) {
					// Too many changes to track, http://blogs.msdn.com/b/oldnewthing/archive/2011/08/12/10195186.aspx
					// The documentation only states the code ERROR_NOTIFY_ENUM_DIR for this, but according to the testing ERROR_NOT_ENOUGH_QUOTA and ERROR_ALREADY_EXISTS seem to be used instead....
					// (and ERROR_TOO_MANY_CMDS with network drives)
					if (dwError == ERROR_NOTIFY_ENUM_DIR || dwError == ERROR_NOT_ENOUGH_QUOTA || dwError == ERROR_ALREADY_EXISTS || dwError == ERROR_TOO_MANY_CMDS) {
						(*mon)->beginRead();
						auto monBase = (*mon)->server->base;
						monBase->callAsync([=] { monBase->fire(DirectoryMonitorListener::Overflow(), (*mon)->path); });
					} else {
						throw MonitorException(getErrorStr(dwError));
					}
				} else {
					if ((*mon)->errorCount > 0) {
						(*mon)->errorCount = 0;
					}

					if (dwBytesXFered > 0) {
						(*mon)->changes++;
						(*mon)->queueNotificationTask(dwBytesXFered);
					} /*else {
						LogManager::getInstance()->message("An empty notification was received when monitoring " + Text::fromT((*mon)->path) + " (report this)", LogMessage::SEV_WARNING);
					}*/

					(*mon)->beginRead();
				}
			} catch (const MonitorException& e) {
				(*mon)->errorCount++;
				if ((*mon)->errorCount < 60) {
					//we'll most likely get the error instantly again...
					Thread::sleep(1000);

					try {
						(*mon)->openDirectory(m_hIOCP);
						(*mon)->beginRead();
						return 1;
					} catch (const MonitorException& /*e*/) {
						//go to removal
					}
				}

				failDirectory((*mon)->path, e.getError());
			}
		}
	}

	return 1;
}
Example #6
0
Exception::Exception(EnErrors err, const char* func, const char* file, int line)
	: m_err(err) {
#ifdef LOG_EXCEPTIONS
	CLog::getInstance().Log(ERROR, file, func, line, "Exception: %s", getErrorStr().c_str());
#endif
}