This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat-native.git

commit 1d727eaad90eb87e2a34f29c7cee045f193d60dd
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Jun 22 12:44:08 2022 +0100

    Restore Windows specific system.c as it contains password prompt methods
---
 native/NMAKEmakefile     |   1 +
 native/libtcnative.dsp   |   4 +
 native/os/win32/system.c | 458 +++++++++++++++++++++++++++++++++++++++++++++++
 native/tcnative.dsp      |   4 +
 4 files changed, 467 insertions(+)

diff --git a/native/NMAKEmakefile b/native/NMAKEmakefile
index 530e6a339..224d1352a 100644
--- a/native/NMAKEmakefile
+++ b/native/NMAKEmakefile
@@ -96,6 +96,7 @@ OBJECTS = \
        $(WORKDIR)\sslcontext.obj \
        $(WORKDIR)\sslconf.obj \
        $(WORKDIR)\sslutils.obj \
+        $(WORKDIR)\system.obj
 !IF DEFINED(WITH_FIPS)
 OBJECTS = $(OBJECTS) srclib\openssl\tmp32\fips_premain.obj
 !ENDIF
diff --git a/native/libtcnative.dsp b/native/libtcnative.dsp
index 214370f70..1e88b7c57 100644
--- a/native/libtcnative.dsp
+++ b/native/libtcnative.dsp
@@ -150,6 +150,10 @@ SOURCE=.\include\tcn_version.h
 # Begin Group "Platform Files"
 
 # PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\os\win32\system.c
+# End Source File
 # End Group
 # Begin Source File
 
diff --git a/native/os/win32/system.c b/native/os/win32/system.c
new file mode 100644
index 000000000..42adf611f
--- /dev/null
+++ b/native/os/win32/system.c
@@ -0,0 +1,458 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x0500
+#endif
+#include <winsock2.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <tlhelp32.h>
+
+#include "apr.h"
+#include "apr_pools.h"
+#include "apr_poll.h"
+#include "apr_network_io.h"
+#include "apr_arch_misc.h" /* for apr_os_level */
+#include "apr_arch_atime.h"  /* for FileTimeToAprTime */
+
+#include "tcn.h"
+#include "ssl_private.h"
+
+#pragma warning(push)
+#pragma warning(disable : 4201)
+#if (_WIN32_WINNT < 0x0501)
+#include <winternl.h>
+#endif
+#include <psapi.h>
+#pragma warning(pop)
+
+
+static CRITICAL_SECTION dll_critical_section;   /* dll's critical section */
+static HINSTANCE        dll_instance = NULL;
+static SYSTEM_INFO      dll_system_info;
+static HANDLE           h_kernel = NULL;
+static HANDLE           h_ntdll  = NULL;
+static char             dll_file_name[MAX_PATH];
+
+typedef BOOL (WINAPI *pfnGetSystemTimes)(LPFILETIME, LPFILETIME, LPFILETIME);
+static pfnGetSystemTimes fnGetSystemTimes = NULL;
+#if (_WIN32_WINNT < 0x0501)
+typedef NTSTATUS (WINAPI 
*pfnNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
+static pfnNtQuerySystemInformation fnNtQuerySystemInformation = NULL;
+#endif
+
+BOOL
+WINAPI
+DllMain(
+    HINSTANCE instance,
+    DWORD reason,
+    LPVOID reserved)
+{
+
+    switch (reason) {
+        /** The DLL is loading due to process
+         *  initialization or a call to LoadLibrary.
+         */
+        case DLL_PROCESS_ATTACH:
+            InitializeCriticalSection(&dll_critical_section);
+            dll_instance = instance;
+            GetSystemInfo(&dll_system_info);
+            if ((h_kernel = LoadLibrary("kernel32.dll")) != NULL)
+                fnGetSystemTimes = (pfnGetSystemTimes)GetProcAddress(h_kernel,
+                                                            "GetSystemTimes");
+            if (fnGetSystemTimes == NULL) {
+                FreeLibrary(h_kernel);
+                h_kernel = NULL;
+#if (_WIN32_WINNT < 0x0501)
+                if ((h_ntdll = LoadLibrary("ntdll.dll")) != NULL)
+                    fnNtQuerySystemInformation =
+                        (pfnNtQuerySystemInformation)GetProcAddress(h_ntdll,
+                                                "NtQuerySystemInformation");
+
+                if (fnNtQuerySystemInformation == NULL) {
+                    FreeLibrary(h_ntdll);
+                    h_ntdll = NULL;
+                }
+#endif
+            }
+            GetModuleFileName(instance, dll_file_name, sizeof(dll_file_name));
+            break;
+        /** The attached process creates a new thread.
+         */
+        case DLL_THREAD_ATTACH:
+            break;
+
+        /** The thread of the attached process terminates.
+         */
+        case DLL_THREAD_DETACH:
+            ERR_remove_thread_state(NULL);
+            break;
+
+        /** DLL unload due to process termination
+         *  or FreeLibrary.
+         */
+        case DLL_PROCESS_DETACH:
+            if (h_kernel)
+                FreeLibrary(h_kernel);
+            if (h_ntdll)
+                FreeLibrary(h_ntdll);
+            DeleteCriticalSection(&dll_critical_section);
+            break;
+
+        default:
+            break;
+    }
+
+    return TRUE;
+    UNREFERENCED_PARAMETER(reserved);
+}
+
+
+TCN_IMPLEMENT_CALL(jstring, OS, syserror)(TCN_STDARGS, jint err)
+{
+    jstring str;
+    void *buf;
+
+    UNREFERENCED(o);
+    if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                       FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS,
+                       NULL,
+                       err,
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                       (LPTSTR)&buf,
+                       0,
+                       NULL)) {
+        str = AJP_TO_JSTRING("Unknown Error");
+    }
+    else {
+        str = AJP_TO_JSTRING((const char *)buf);
+        LocalFree(buf);
+    }
+    return str;
+}
+
+TCN_IMPLEMENT_CALL(jstring, OS, expand)(TCN_STDARGS, jstring val)
+{
+    jstring str;
+    jchar buf[TCN_BUFFER_SZ] = L"";
+    DWORD len;
+    TCN_ALLOC_WSTRING(val);
+
+    UNREFERENCED(o);
+    TCN_INIT_WSTRING(val);
+
+    len = ExpandEnvironmentStringsW(J2W(val), buf, TCN_BUFFER_SZ - 1);
+    if (len > (TCN_BUFFER_SZ - 1)) {
+        jchar *dbuf = malloc((len + 1) * 2);
+        ExpandEnvironmentStringsW(J2W(val), dbuf, len);
+        str = (*e)->NewString(e, dbuf, lstrlenW(dbuf));
+        free(dbuf);
+    }
+    else
+        str = (*e)->NewString(e, buf, lstrlenW(buf));
+
+    TCN_FREE_WSTRING(val);
+    return str;
+}
+
+#define LOG_MSG_EMERG                    0xC0000001L
+#define LOG_MSG_ERROR                    0xC0000002L
+#define LOG_MSG_NOTICE                   0x80000003L
+#define LOG_MSG_WARN                     0x80000004L
+#define LOG_MSG_INFO                     0x40000005L
+#define LOG_MSG_DEBUG                    0x00000006L
+#define LOG_MSG_DOMAIN                   "Native"
+
+static char log_domain[MAX_PATH] = "Native";
+
+static void init_log_source(const char *domain)
+{
+    HKEY  key;
+    DWORD ts;
+    char event_key[MAX_PATH];
+
+    strcpy(event_key, 
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
+    strcat(event_key, domain);
+    if (!RegCreateKey(HKEY_LOCAL_MACHINE, event_key, &key)) {
+        RegSetValueEx(key, "EventMessageFile", 0, REG_SZ, 
(LPBYTE)&dll_file_name[0],
+                      lstrlenA(dll_file_name) + 1);
+        ts = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | 
EVENTLOG_INFORMATION_TYPE;
+
+        RegSetValueEx(key, "TypesSupported", 0, REG_DWORD, (LPBYTE) &ts, 
sizeof(DWORD));
+        RegCloseKey(key);
+    }
+    strcpy(log_domain, domain);
+}
+
+TCN_IMPLEMENT_CALL(void, OS, sysloginit)(TCN_STDARGS, jstring domain)
+{
+    const char *d;
+    TCN_ALLOC_CSTRING(domain);
+
+    UNREFERENCED(o);
+
+    if ((d = J2S(domain)) == NULL)
+        d = LOG_MSG_DOMAIN;
+    init_log_source(d);
+
+    TCN_FREE_CSTRING(domain);
+}
+
+TCN_IMPLEMENT_CALL(void, OS, syslog)(TCN_STDARGS, jint level,
+                                     jstring msg)
+{
+    TCN_ALLOC_CSTRING(msg);
+    DWORD id = LOG_MSG_DEBUG;
+    WORD  il = EVENTLOG_SUCCESS;
+    HANDLE  source;
+    const char *messages[1];
+    UNREFERENCED(o);
+
+    switch (level) {
+        case TCN_LOG_EMERG:
+            id = LOG_MSG_EMERG;
+            il = EVENTLOG_ERROR_TYPE;
+        break;
+        case TCN_LOG_ERROR:
+            id = LOG_MSG_ERROR;
+            il = EVENTLOG_ERROR_TYPE;
+        break;
+        case TCN_LOG_NOTICE:
+            id = LOG_MSG_NOTICE;
+            il = EVENTLOG_WARNING_TYPE;
+        break;
+        case TCN_LOG_WARN:
+            id = LOG_MSG_WARN;
+            il = EVENTLOG_WARNING_TYPE;
+        break;
+        case TCN_LOG_INFO:
+            id = LOG_MSG_INFO;
+            il = EVENTLOG_INFORMATION_TYPE;
+        break;
+    }
+
+    messages[0] = J2S(msg);
+    source = RegisterEventSource(NULL, log_domain);
+
+    if (source != NULL) {
+        ReportEvent(source, il,
+                    0,
+                    id,
+                    NULL,
+                    1, 0,
+                    messages, NULL);
+        DeregisterEventSource(source);
+    }
+
+    TCN_FREE_CSTRING(msg);
+}
+
+TCN_IMPLEMENT_CALL(jboolean, OS, is)(TCN_STDARGS, jint type)
+{
+    UNREFERENCED_STDARGS;
+#ifdef _WIN64
+    if (type == 4)
+        return JNI_TRUE;
+    else
+#endif
+    if (type == 3)
+        return JNI_TRUE;
+    else
+        return JNI_FALSE;
+}
+
+TCN_IMPLEMENT_CALL(jint, OS, info)(TCN_STDARGS,
+                                   jlongArray inf)
+{
+    MEMORYSTATUSEX ms;
+    ULONGLONG st[4];
+    FILETIME ft[4];
+    PROCESS_MEMORY_COUNTERS pmc;
+    jint rv;
+    int i;
+    jsize ilen = (*e)->GetArrayLength(e, inf);
+    jlong *pvals = (*e)->GetLongArrayElements(e, inf, NULL);
+
+    if (ilen < 16) {
+        return APR_EINVAL;
+    }
+    for (i = 0; i < 16; i++)
+        pvals[i] = 0;
+
+    ms.dwLength = sizeof(MEMORYSTATUSEX);
+
+    UNREFERENCED(o);
+    if (GlobalMemoryStatusEx(&ms)) {
+        pvals[0] = (jlong)ms.ullTotalPhys;
+        pvals[1] = (jlong)ms.ullAvailPhys;
+        pvals[2] = (jlong)ms.ullTotalPageFile;
+        pvals[3] = (jlong)ms.ullAvailPageFile;
+        /* Slots 4 and 5 are for shared memory */
+        pvals[6] = (jlong)ms.dwMemoryLoad;
+    }
+    else
+        goto cleanup;
+
+    memset(st, 0, sizeof(st));
+
+    if (fnGetSystemTimes) {
+        if ((*fnGetSystemTimes)(&ft[0], &ft[1], &ft[2])) {
+            st[0] = (((ULONGLONG)ft[0].dwHighDateTime << 32) | 
ft[0].dwLowDateTime) / 10;
+            st[1] = (((ULONGLONG)ft[1].dwHighDateTime << 32) | 
ft[1].dwLowDateTime) / 10;
+            st[2] = (((ULONGLONG)ft[2].dwHighDateTime << 32) | 
ft[2].dwLowDateTime) / 10;
+        }
+        else
+            goto cleanup;
+    }
+#if (_WIN32_WINNT < 0x0501)
+    else if (fnNtQuerySystemInformation) {
+        BYTE buf[2048]; /* This should ne enough for 32 processors */
+        NTSTATUS rs = 
(*fnNtQuerySystemInformation)(SystemProcessorPerformanceInformation,
+                                           (LPVOID)buf, 2048, NULL);
+        if (rs == 0) {
+            PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION pspi = 
(PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)&buf[0];
+            DWORD i;
+            /* Calculate all processors */
+            for (i = 0; i < dll_system_info.dwNumberOfProcessors; i++) {
+                st[0] += pspi[i].IdleTime.QuadPart / 10;
+                st[1] += pspi[i].KernelTime.QuadPart / 10;
+                st[2] += pspi[i].UserTime.QuadPart / 10;
+            }
+        }
+        else
+            goto cleanup;
+    }
+#endif
+    pvals[7] = st[0];
+    pvals[8] = st[1];
+    pvals[9] = st[2];
+
+    memset(st, 0, sizeof(st));
+    if (GetProcessTimes(GetCurrentProcess(), &ft[0], &ft[1], &ft[2], &ft[3])) {
+        FileTimeToAprTime((apr_time_t *)&st[0], &ft[0]);
+        st[1] = (((ULONGLONG)ft[2].dwHighDateTime << 32) | 
ft[2].dwLowDateTime) / 10;
+        st[2] = (((ULONGLONG)ft[3].dwHighDateTime << 32) | 
ft[3].dwLowDateTime) / 10;
+    }
+    pvals[10] = st[0];
+    pvals[11] = st[1];
+    pvals[12] = st[2];
+
+    if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
+        pvals[13] = pmc.WorkingSetSize;
+        pvals[14] = pmc.PeakWorkingSetSize;
+        pvals[15] = pmc.PageFaultCount;
+    }
+
+    (*e)->ReleaseLongArrayElements(e, inf, pvals, 0);
+    return APR_SUCCESS;
+cleanup:
+    rv = apr_get_os_error();
+    (*e)->ReleaseLongArrayElements(e, inf, pvals, 0);
+    return rv;
+}
+
+
+static DWORD WINAPI password_thread(void *data)
+{
+    tcn_pass_cb_t *cb = (tcn_pass_cb_t *)data;
+    MSG     msg;
+    HWINSTA hwss;
+    HWINSTA hwsu;
+    HDESK   hwds;
+    HDESK   hwdu;
+    HWND    hwnd;
+
+    /* Ensure connection to service window station and desktop, and
+     * save their handles.
+     */
+    GetDesktopWindow();
+    hwss = GetProcessWindowStation();
+    hwds = GetThreadDesktop(GetCurrentThreadId());
+
+    /* Impersonate the client and connect to the User's
+     * window station and desktop.
+     */
+    hwsu = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
+    if (hwsu == NULL) {
+        ExitThread(1);
+        return 1;
+    }
+    SetProcessWindowStation(hwsu);
+    hwdu = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
+    if (hwdu == NULL) {
+        SetProcessWindowStation(hwss);
+        CloseWindowStation(hwsu);
+        ExitThread(1);
+        return 1;
+    }
+    SetThreadDesktop(hwdu);
+
+    hwnd = CreateDialog(dll_instance, MAKEINTRESOURCE(1001), NULL, NULL);
+    if (hwnd != NULL)
+        ShowWindow(hwnd, SW_SHOW);
+    else  {
+        ExitThread(1);
+        return 1;
+    }
+    while (1) {
+        if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE)) {
+            if (msg.message == WM_KEYUP) {
+                int nVirtKey = (int)msg.wParam;
+                if (nVirtKey == VK_ESCAPE) {
+                    DestroyWindow(hwnd);
+                    break;
+                }
+                else if (nVirtKey == VK_RETURN) {
+                    HWND he = GetDlgItem(hwnd, 1002);
+                    if (he) {
+                        int n = GetWindowText(he, cb->password, 
SSL_MAX_PASSWORD_LEN - 1);
+                        cb->password[n] = '\0';
+                    }
+                    DestroyWindow(hwnd);
+                    break;
+                }
+            }
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+        else
+            Sleep(100);
+    }
+    /* Restore window station and desktop.
+     */
+    SetThreadDesktop(hwds);
+    SetProcessWindowStation(hwss);
+    CloseDesktop(hwdu);
+    CloseWindowStation(hwsu);
+
+    ExitThread(0);
+    return 0;
+}
+
+int WIN32_SSL_password_prompt(tcn_pass_cb_t *data)
+{
+    DWORD id;
+    HANDLE thread;
+    /* TODO: See how to display this from service mode */
+    thread = CreateThread(NULL, 0,
+                password_thread, data,
+                0, &id);
+    WaitForSingleObject(thread, INFINITE);
+    CloseHandle(thread);
+    return (int)strlen(data->password);
+}
diff --git a/native/tcnative.dsp b/native/tcnative.dsp
index 9b9e45609..56c9db8c7 100644
--- a/native/tcnative.dsp
+++ b/native/tcnative.dsp
@@ -150,6 +150,10 @@ SOURCE=.\include\tcn_version.h
 # Begin Group "Platform Files"
 
 # PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\os\win32\system.c
+# End Source File
 # End Group
 # Begin Source File
 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to