native/os/win32/system.c (118 lines of code) (raw):

/* 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. */ #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 "tcn.h" #include "ssl_private.h" #pragma warning(push) #pragma warning(disable : 4201) #include <psapi.h> #pragma warning(pop) static CRITICAL_SECTION dll_critical_section; /* dll's critical section */ static HINSTANCE dll_instance = NULL; 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; 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: DeleteCriticalSection(&dll_critical_section); break; default: break; } return TRUE; UNREFERENCED_PARAMETER(reserved); } 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); }