BOOL apxAddToPathW(APXHANDLE hPool, LPCWSTR szAdd) { LPWSTR wsAdd; DWORD rc; DWORD al; rc = GetEnvironmentVariableW(L"PATH", NULL, 0); if (rc == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) return FALSE; al = lstrlenW(szAdd) + 6; if (!(wsAdd = apxPoolAlloc(hPool, (al + rc + 1) * sizeof(WCHAR)))) return FALSE; lstrcpyW(wsAdd, L"PATH="); lstrcatW(wsAdd, szAdd); lstrcatW(wsAdd, L";"); if (!GetEnvironmentVariableW(L"PATH", wsAdd + al, rc - al)) { apxLogWrite(APXLOG_MARK_SYSERR); apxFree(wsAdd); return FALSE; } SetEnvironmentVariableW(L"PATH", wsAdd + 5); _wputenv(wsAdd); apxFree(wsAdd); return TRUE; }
/** * Call glob on each PATH like string path. * Glob is called only if the part ends with asterisk in which * case asterisk is replaced by *.jar when searching */ static LPSTR __apxEvalClasspath(APXHANDLE hPool, LPCSTR szCp) { LPSTR pCpy = __apxStrnCatA(hPool, NULL, JAVA_CLASSPATH, szCp); LPSTR pGcp = NULL; LPSTR pPos; LPSTR pPtr; if (!pCpy) return NULL; pPtr = pCpy + sizeof(JAVA_CLASSPATH) - 1; while ((pPos = __apxStrIndexA(pPtr, ';'))) { *pPos = '\0'; if (pGcp) pGcp = __apxStrnCatA(hPool, pGcp, ";", NULL); else pGcp = __apxStrnCatA(hPool, NULL, JAVA_CLASSPATH, NULL); if ((pPos > pPtr) && (*(pPos - 1) == '*')) { if (!(pGcp = __apxEvalPathPart(hPool, pGcp, pPtr))) { /* Error. * Return the original string processed so far. */ return pCpy; } } else { /* Standard path element */ if (!(pGcp = __apxStrnCatA(hPool, pGcp, pPtr, NULL))) { /* Error. * Return the original string processed so far. */ return pCpy; } } pPtr = pPos + 1; } if (*pPtr) { int end = lstrlenA(pPtr); if (pGcp) pGcp = __apxStrnCatA(hPool, pGcp, ";", NULL); else pGcp = __apxStrnCatA(hPool, NULL, JAVA_CLASSPATH, NULL); if (end > 0 && pPtr[end - 1] == '*') { /* Last path elemet ends with star * Do a globbing. */ pGcp = __apxEvalPathPart(hPool, pGcp, pPtr); } else { /* Just add the part */ pGcp = __apxStrnCatA(hPool, pGcp, pPtr, NULL); } } /* Free the allocated copy */ if (pGcp) { apxFree(pCpy); return pGcp; } else return pCpy; }
LPWSTR apxExpandStrW(APXHANDLE hPool, LPCWSTR szString) { LPCWSTR p = szString; while (*p) { if (*p == L'%') { p = szString; break; } ++p; } if (p != szString) return apxPoolStrdupW(hPool, szString); else { DWORD l = ExpandEnvironmentStringsW(szString, NULL, 0); if (l) { LPWSTR rv = apxPoolAlloc(hPool, l * sizeof(WCHAR)); l = ExpandEnvironmentStringsW(szString, rv, l); if (l) return rv; else { apxFree(rv); return NULL; } } else return NULL; } }
LPWSTR ANSIToWide(LPCSTR cs) { LPWSTR s; int cch = MultiByteToWideChar(CP_ACP, 0, cs, -1, NULL, 0); s = (LPWSTR)apxAlloc(cch * sizeof(WCHAR)); if (!MultiByteToWideChar(CP_ACP, 0, cs, -1, s, cch)) { apxFree(s); return NULL; } return s; }
LPSTR WideToANSI(LPCWSTR ws) { LPSTR s; int cch = WideCharToMultiByte(CP_ACP, 0, ws, -1, NULL, 0, NULL, NULL); s = (LPSTR)apxAlloc(cch); if (!WideCharToMultiByte(CP_ACP, 0, ws, -1, s, cch, NULL, NULL)) { apxFree(s); return NULL; } return s; }
void apxLogClose( HANDLE hFile) { apx_logfile_st *lf = (apx_logfile_st *)hFile; if (IS_INVALID_HANDLE(lf)) lf = _st_sys_loghandle; if (IS_INVALID_HANDLE(lf)) return; FlushFileBuffers(lf->hFile); CloseHandle(lf->hFile); if (lf == _st_sys_loghandle) _st_sys_loghandle = NULL; apxFree(lf); }
LPSTR __apxGetEnvironmentVariableA(APXHANDLE hPool, LPCSTR szName) { LPSTR szRet; DWORD rc; rc = GetEnvironmentVariableA(szName, NULL, 0); if (rc == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) return NULL; if (!(szRet = apxPoolAlloc(hPool, rc + 1))) return NULL; if (!GetEnvironmentVariableA(szName, szRet, rc)) { apxLogWrite(APXLOG_MARK_SYSERR); apxFree(szRet); return NULL; } return szRet; }
LPWSTR __apxGetEnvironmentVariableW(APXHANDLE hPool, LPCWSTR wsName) { LPWSTR wsRet; DWORD rc; rc = GetEnvironmentVariableW(wsName, NULL, 0); if (rc == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND) return NULL; if (!(wsRet = apxPoolAlloc(hPool, (rc + 1) * sizeof(WCHAR)))) return NULL; if (!GetEnvironmentVariableW(wsName, wsRet, rc)) { apxLogWrite(APXLOG_MARK_SYSERR); apxFree(wsRet); return NULL; } return wsRet; }
BOOL apxSetEnvironmentVariable(APXHANDLE hPool, LPCTSTR szName, LPCTSTR szValue, BOOL bAppend) { LPTSTR szNew = (LPTSTR)szValue; if (bAppend) { DWORD l = GetEnvironmentVariable(szName, NULL, 0); if (l > 0) { BOOL rv; if (IS_INVALID_HANDLE(hPool)) szNew = apxAlloc(l + lstrlen(szValue) + 3); else szNew = apxPoolAlloc(hPool, l + lstrlen(szValue) + 3); GetEnvironmentVariable(szName, szNew, l + 1); lstrcat(szNew, TEXT(";")); lstrcat(szNew, szValue); rv = SetEnvironmentVariable(szName, szNew); apxFree(szNew); return rv; } } return SetEnvironmentVariable(szName, szNew); }
/* * argv parsing. * Parse the argv[0] and split to ExePath and * Executable name. Strip the extension ('.exe'). * Check for command in argv[1] //CMD//Application * Parse the options --option value or --option==value * break on first argument that doesn't start with '--' */ LPAPXCMDLINE apxCmdlineParse( APXHANDLE hPool, APXCMDLINEOPT *lpOptions, LPCWSTR *lpszCommands, LPCWSTR *lpszAltcmds) { LPAPXCMDLINE lpCmdline = NULL; DWORD l, i, s = 1; LPWSTR p; DWORD match; WCHAR mh[SIZ_HUGLEN]; if (_st_sys_argc < 1) return NULL; if (!(lpCmdline = (LPAPXCMDLINE)apxPoolCalloc(hPool, sizeof(APXCMDLINE)))) return NULL; lpCmdline->hPool = hPool; lpCmdline->lpOptions = lpOptions; if (GetModuleFileNameW(GetModuleHandle(NULL), mh, SIZ_HUGLEN)) { GetLongPathNameW(mh, mh, SIZ_HUGLEN); lpCmdline->szExePath = apxPoolStrdupW(hPool, mh); lpCmdline->szArgv0 = apxPoolStrdupW(hPool, mh); if (lpCmdline->szExePath == NULL || lpCmdline->szArgv0 == NULL) return NULL; if ((p = wcsrchr(lpCmdline->szExePath, L'\\'))) *p++ = L'\0'; else return NULL; } else return NULL; lpCmdline->szExecutable = p; p = wcsrchr(lpCmdline->szExecutable, L'.'); if (p && lstrcmpiW(p, EXE_SUFFIX) == 0) *p = L'\0'; if ((p = wcsrchr(lpCmdline->szExecutable, L'.'))) { if (lstrcmpiW(p, X86_SUFFIX) == 0) { *p = L'\0'; } else if (lstrcmpiW(p, X64_SUFFIX) == 0) { *p = L'\0'; } else if (lstrcmpiW(p, A64_SUFFIX) == 0) { *p = L'\0'; } } if (_st_sys_argc > 1 && lstrlenW(_st_sys_argvw[1]) > 2) { LPWSTR cp = _st_sys_argvw[1]; LPWSTR cn = _st_sys_argc > 2 ? _st_sys_argvw[2] : NULL; LPWSTR ca = cp; i = 0; if (ca[0] == L'/' && ca[1] == L'/') { ca += 2; if ((cn = wcschr(ca, L'/'))) { *cn++ = L'\0'; while (*cn == L'/') cn++; if (*cn == L'\0') cn = NULL; } if (cn == NULL) cn = lpCmdline->szExecutable; while (lpszCommands[i]) { if (lstrcmpW(lpszCommands[i++], ca) == 0) { lpCmdline->dwCmdIndex = i; break; } } if (lpCmdline->dwCmdIndex) { lpCmdline->szApplication = cn; s = 2; } else { apxLogWrite(APXLOG_MARK_ERROR "Unrecognized cmd option %S", cp); return NULL; } } else { while (lpszAltcmds[i]) { if (lstrcmpW(lpszAltcmds[i++], ca) == 0) { lpCmdline->dwCmdIndex = i; break; } } if (lpCmdline->dwCmdIndex) { s = 2; if (cn && iswalnum(*cn)) { s++; lpCmdline->szApplication = cn; } else lpCmdline->szApplication = lpCmdline->szExecutable; } else { apxLogWrite(APXLOG_MARK_ERROR "Unrecognized cmd option %S", cp); return NULL; } } } else { lpCmdline->szApplication = lpCmdline->szExecutable; lpCmdline->dwCmdIndex = 1; return lpCmdline; } for (i = s; i < (DWORD)_st_sys_argc; i++) { LPWSTR e = NULL; LPWSTR a = _st_sys_argvw[i]; BOOL add = FALSE; if (a[0] == L'+' && a[1] == L'+') add = TRUE; else if (a[0] != L'-' || a[1] != L'-') break; p = a + 2; /* Find if the option has '=' char * for --option==value or --option value cases. */ while (*p) { if (*p == L'=') { *p = L'\0'; e = p + 1; break; } else p++; } match = 0; for (l = 0; lpOptions[l].szName; l++) { if (lstrcmpW(lpOptions[l].szName, a + 2) == 0) { LPWSTR val; /* check if arg is needed */ if (e) val = e; else if ((i + 1) < (DWORD)_st_sys_argc) val = _st_sys_argvw[++i]; else { lpOptions[l].dwValue = 0; lpOptions[l].szValue = NULL; lpOptions[l].dwType |= APXCMDOPT_FOUND; break; } if (add) { if (!(lpOptions[l].dwType & APXCMDOPT_FOUND)) { /* Only set add flag in case there was no --option */ lpOptions[l].dwType |= APXCMDOPT_ADD; } } else if (lpOptions[l].dwType & APXCMDOPT_ADD) { /* We have ++option --option ... * Discard earlier values and go over. */ lpOptions[l].dwType &= ~APXCMDOPT_ADD; lpOptions[l].dwValue = 0; lpOptions[l].szValue = 0; } if (lpOptions[l].dwType & APXCMDOPT_STR) lpOptions[l].szValue = val; else if (lpOptions[l].dwType & APXCMDOPT_INT) lpOptions[l].dwValue = (DWORD)apxAtoulW(val); else if (lpOptions[l].dwType & APXCMDOPT_MSZ) { LPWSTR pp; BOOL insquote = FALSE, indquote=FALSE; DWORD sp = 0; LPWSTR ov = lpOptions[l].szValue; if (lpOptions[l].dwValue > 2) { sp = (lpOptions[l].dwValue - sizeof(WCHAR)) / sizeof(WCHAR); } lpOptions[l].dwValue = (sp + lstrlenW(val) + 2) * sizeof(WCHAR); lpOptions[l].szValue = (LPWSTR)apxPoolCalloc(hPool, lpOptions[l].dwValue); if (sp) { AplMoveMemory(lpOptions[l].szValue, ov, sp * sizeof(WCHAR)); apxFree(ov); } pp = val; while(*pp) { if (*pp == L'\'') insquote = !insquote; else if (*pp == L'"') { indquote = !indquote; lpOptions[l].szValue[sp++] = L'"'; } else if ((*pp == L'#' || *pp == L';') && !insquote && !indquote) lpOptions[l].szValue[sp++] = L'\0'; else lpOptions[l].szValue[sp++] = *pp; pp++; } } lpOptions[l].dwType |= APXCMDOPT_FOUND; match = l + 1; break; } } if (match == 0) { /* --unknown option * */ apxLogWrite(APXLOG_MARK_ERROR "Unrecognized program option %S", _st_sys_argvw[i]); return NULL; } } if (i < (DWORD)_st_sys_argc) { lpCmdline->dwArgc = _st_sys_argc - i; lpCmdline->lpArgvw = &_st_sys_argvw[i]; } return lpCmdline; }
/* Used for future expansion */ void apxCmdlineFree( LPAPXCMDLINE lpCmdline) { apxFree(lpCmdline); }
BOOL apxJavaLoadMainClass(APXHANDLE hJava, LPCSTR szClassName, LPCSTR szMethodName, LPCVOID lpArguments) { LPWSTR *lpArgs = NULL; DWORD nArgs; LPAPXJAVAVM lpJava; jclass jClazz; LPCSTR szSignature = "([Ljava/lang/String;)V"; if (hJava->dwType != APXHANDLE_TYPE_JVM) return FALSE; lpJava = APXHANDLE_DATA(hJava); if (!lpJava) return FALSE; if (IS_EMPTY_STRING(szMethodName)) szMethodName = "main"; if (lstrcmpA(szClassName, "java/lang/System") == 0) { /* Usable only for exit method, so force */ szSignature = "(I)V"; szMethodName = "exit"; } lstrlcpyA(lpJava->clWorker.sClazz, 1024, szClassName); lstrlcpyA(lpJava->clWorker.sMethod, 512, szMethodName); jClazz = JNICALL_1(FindClass, JAVA_CLASSSTRING); if (!jClazz) { JVM_EXCEPTION_CLEAR(lpJava); apxLogWrite(APXLOG_MARK_ERROR "FindClass " JAVA_CLASSSTRING " failed"); return FALSE; } lpJava->clString.jClazz = JNICALL_1(NewGlobalRef, jClazz); JNI_LOCAL_UNREF(jClazz); /* Find the class */ jClazz = JNICALL_1(FindClass, szClassName); if (!jClazz) { JVM_EXCEPTION_CLEAR(lpJava); apxLogWrite(APXLOG_MARK_ERROR "FindClass %s failed", szClassName); return FALSE; } /* Make the class global so that worker thread can attach */ lpJava->clWorker.jClazz = JNICALL_1(NewGlobalRef, jClazz); JNI_LOCAL_UNREF(jClazz); lpJava->clWorker.jMethod = JNICALL_3(GetStaticMethodID, lpJava->clWorker.jClazz, szMethodName, szSignature); if (!lpJava->clWorker.jMethod) { JVM_EXCEPTION_CLEAR(lpJava); apxLogWrite(APXLOG_MARK_ERROR "Method 'static void %s(String[])' not found in Class %s", szMethodName, szClassName); return FALSE; } if (lstrcmpA(szClassName, "java/lang/System")) { nArgs = apxMultiSzToArrayW(hJava->hPool, lpArguments, &lpArgs); lpJava->clWorker.jArgs = JNICALL_3(NewObjectArray, nArgs, lpJava->clString.jClazz, NULL); if (nArgs) { DWORD i; for (i = 0; i < nArgs; i++) { jstring arg = JNICALL_2(NewString, lpArgs[i], lstrlenW(lpArgs[i])); JNICALL_3(SetObjectArrayElement, lpJava->clWorker.jArgs, i, arg); apxLogWrite(APXLOG_MARK_DEBUG "argv[%d] = %S", i, lpArgs[i]); } } apxFree(lpArgs); } return TRUE; }
/* ANSI version only */ BOOL apxJavaInitialize(APXHANDLE hJava, LPCSTR szClassPath, LPCVOID lpOptions, DWORD dwMs, DWORD dwMx, DWORD dwSs, DWORD bJniVfprintf) { LPAPXJAVAVM lpJava; JavaVMInitArgs vmArgs; JavaVMOption *lpJvmOptions; DWORD i, nOptions, sOptions = 0; BOOL rv = FALSE; if (hJava->dwType != APXHANDLE_TYPE_JVM) return FALSE; lpJava = APXHANDLE_DATA(hJava); if (lpJava->iVmCount) { if (!lpJava->lpEnv && !__apxJvmAttach(lpJava)) { if (lpJava->iVersion == JNI_VERSION_1_2) { apxLogWrite(APXLOG_MARK_ERROR "Unable To Attach the JVM"); return FALSE; } else lpJava->iVersion = JNI_VERSION_1_2; if (!__apxJvmAttach(lpJava)) { apxLogWrite(APXLOG_MARK_ERROR "Unable To Attach the JVM"); return FALSE; } } lpJava->iVersion = JNICALL_0(GetVersion); if (lpJava->iVersion < JNI_VERSION_1_2) { apxLogWrite(APXLOG_MARK_ERROR "Unsupported JNI version %#08x", lpJava->iVersion); return FALSE; } rv = TRUE; } else { CHAR iB[3][64]; LPSTR szCp = NULL; lpJava->iVersion = JNI_VERSION_DEFAULT; if (dwMs) ++sOptions; if (dwMx) ++sOptions; if (dwSs) ++sOptions; if (bJniVfprintf) ++sOptions; if (szClassPath && *szClassPath) ++sOptions; sOptions++; /* unconditionally set for extraInfo exit */ nOptions = __apxMultiSzToJvmOptions(hJava->hPool, lpOptions, &lpJvmOptions, sOptions); if (szClassPath && *szClassPath) { szCp = __apxEvalClasspath(hJava->hPool, szClassPath); if (szCp == NULL) { apxLogWrite(APXLOG_MARK_ERROR "Invalid classpath %s", szClassPath); return FALSE; } lpJvmOptions[nOptions - sOptions].optionString = szCp; --sOptions; } if (bJniVfprintf) { /* default JNI error printer */ lpJvmOptions[nOptions - sOptions].optionString = "vfprintf"; lpJvmOptions[nOptions - sOptions].extraInfo = __apxJniVfprintf; --sOptions; } /* unconditionally add hook for System.exit() in order to store exit code */ lpJvmOptions[nOptions - sOptions].optionString = "exit"; lpJvmOptions[nOptions - sOptions].extraInfo = __apxJniExit; --sOptions; if (dwMs) { wsprintfA(iB[0], "-Xms%dm", dwMs); lpJvmOptions[nOptions - sOptions].optionString = iB[0]; --sOptions; } if (dwMx) { wsprintfA(iB[1], "-Xmx%dm", dwMx); lpJvmOptions[nOptions - sOptions].optionString = iB[1]; --sOptions; } if (dwSs) { wsprintfA(iB[2], "-Xss%dk", dwSs); lpJvmOptions[nOptions - sOptions].optionString = iB[2]; --sOptions; } for (i = 0; i < nOptions; i++) { apxLogWrite(APXLOG_MARK_DEBUG "Jvm Option[%d] %s", i, lpJvmOptions[i].optionString); } vmArgs.options = lpJvmOptions; vmArgs.nOptions = nOptions; vmArgs.version = lpJava->iVersion; vmArgs.ignoreUnrecognized = JNI_FALSE; if (DYNLOAD_FPTR(JNI_CreateJavaVM)(&(lpJava->lpJvm), (void **)&(lpJava->lpEnv), &vmArgs) != JNI_OK) { apxLogWrite(APXLOG_MARK_ERROR "CreateJavaVM Failed"); rv = FALSE; } else { rv = TRUE; if (!_st_sys_jvm) _st_sys_jvm = lpJava->lpJvm; } apxFree(szCp); apxFree(lpJvmOptions); } if (rv) return TRUE; else return FALSE; }