From bb2d95953cf02afcabbeafb21e8ecc0980f5e1ba Mon Sep 17 00:00:00 2001 From: Rom Walton Date: Sat, 25 Jul 2009 03:51:18 +0000 Subject: [PATCH] - lib: revert previous commit, things in lib end up being linked into project applications, projects may want to continue supporting Win9x. lib/ win_util.cpp, .h svn path=/trunk/boinc/; revision=18718 --- checkin_notes | 8 +++ lib/win_util.cpp | 128 +++++++++++++++++++++++++++++++++++++++++------ lib/win_util.h | 3 +- 3 files changed, 121 insertions(+), 18 deletions(-) diff --git a/checkin_notes b/checkin_notes index 703987b32d..f2374a59ac 100644 --- a/checkin_notes +++ b/checkin_notes @@ -6480,3 +6480,11 @@ Rom 24 July 2009 lib/ win_util.cpp, .h + +Rom 24 July 2009 + - lib: revert previous commit, things in lib end up being linked + into project applications, projects may want to continue + supporting Win9x. + + lib/ + win_util.cpp, .h diff --git a/lib/win_util.cpp b/lib/win_util.cpp index 46ee5fe6c5..126c035d5c 100644 --- a/lib/win_util.cpp +++ b/lib/win_util.cpp @@ -22,6 +22,8 @@ #include "boinc_win.h" #endif +//#include // not present on academic version of VS2005! + #include "win_util.h" @@ -43,7 +45,6 @@ BOOL IsWindows2000Compatible() { * Define these if they aren't defined. They are normally found in * winnt.h, but some compilers don't have them. **/ - #ifndef VER_AND #define VER_AND 6 #endif @@ -70,6 +71,12 @@ BOOL IsTerminalServicesEnabled() { DWORD dwVersion; OSVERSIONINFOEXA osVersionInfo; DWORDLONG dwlConditionMask = 0; + HMODULE hmodK32 = NULL; + HMODULE hmodNtDll = NULL; + typedef ULONGLONG (WINAPI *PFnVerSetConditionMask)(ULONGLONG,ULONG,UCHAR); + typedef BOOL (WINAPI *PFnVerifyVersionInfoA)(POSVERSIONINFOEXA, DWORD, DWORDLONG); + PFnVerSetConditionMask pfnVerSetConditionMask; + PFnVerifyVersionInfoA pfnVerifyVersionInfoA; dwVersion = GetVersion(); @@ -79,16 +86,37 @@ BOOL IsTerminalServicesEnabled() { // Is it Windows 2000 (NT 5.0) or greater ? if (LOBYTE(LOWORD(dwVersion)) > 4) { - // In Windows 2000 or better we need to use the Product Suite APIs - dwlConditionMask = VerSetConditionMask( dwlConditionMask, VER_SUITENAME, VER_AND ); - - ZeroMemory(&osVersionInfo, sizeof(osVersionInfo)); - osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo); - osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL | VER_SUITE_SINGLEUSERTS; - bResult = VerifyVersionInfoA( - &osVersionInfo, - VER_SUITENAME, - dwlConditionMask); + // In Windows 2000 we need to use the Product Suite APIs + // Don't static link because it won't load on non-Win2000 systems + hmodNtDll = GetModuleHandleA( "NTDLL.DLL" ); + if (hmodNtDll != NULL) + { + pfnVerSetConditionMask = (PFnVerSetConditionMask )GetProcAddress( hmodNtDll, "VerSetConditionMask"); + if (pfnVerSetConditionMask != NULL) + { + dwlConditionMask = (*pfnVerSetConditionMask)( dwlConditionMask, VER_SUITENAME, VER_AND ); + hmodK32 = GetModuleHandleA( "KERNEL32.DLL" ); + if (hmodK32 != NULL) + { + pfnVerifyVersionInfoA = (PFnVerifyVersionInfoA)GetProcAddress( hmodK32, "VerifyVersionInfoA") ; + if (pfnVerifyVersionInfoA != NULL) + { + ZeroMemory(&osVersionInfo, sizeof(osVersionInfo)); + osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo); + osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL | VER_SUITE_SINGLEUSERTS; + bResult = (*pfnVerifyVersionInfoA)( + &osVersionInfo, + VER_SUITENAME, + dwlConditionMask); + } + } + } + } + } + else + { + // This is NT 4.0 or older + bResult = ValidateProductSuite( "Terminal Server" ); } } @@ -96,6 +124,64 @@ BOOL IsTerminalServicesEnabled() { } +/** + * This function compares the passed in "suite name" string + * to the product suite information stored in the registry. + * This only works on the Terminal Server 4.0 platform. + **/ +BOOL ValidateProductSuite (LPSTR SuiteName) { + BOOL rVal = FALSE; + LONG Rslt; + HKEY hKey = NULL; + DWORD Type = 0; + DWORD Size = 0; + LPSTR ProductSuite = NULL; + LPSTR p; + + Rslt = RegOpenKeyA( + HKEY_LOCAL_MACHINE, + "System\\CurrentControlSet\\Control\\ProductOptions", + &hKey + ); + + if (Rslt != ERROR_SUCCESS) + goto exit; + + Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type, NULL, &Size ); + if (Rslt != ERROR_SUCCESS || !Size) + goto exit; + + ProductSuite = (LPSTR) LocalAlloc( LPTR, Size ); + if (!ProductSuite) + goto exit; + + Rslt = RegQueryValueExA( hKey, "ProductSuite", NULL, &Type, + (LPBYTE) ProductSuite, &Size ); + if (Rslt != ERROR_SUCCESS || Type != REG_MULTI_SZ) + goto exit; + + p = ProductSuite; + while (*p) + { + if (lstrcmpA( p, SuiteName ) == 0) + { + rVal = TRUE; + break; + } + p += (lstrlenA( p ) + 1); + } + +exit: + if (ProductSuite) + LocalFree( ProductSuite ); + + if (hKey) + RegCloseKey( hKey ); + + return rVal; +} + + /** * This function terminates a process by process id instead of a handle. **/ @@ -655,16 +741,29 @@ GetAccountSid( return bSuccess; } - // Suspend or resume the threads in a given process. // The only way to do this on Windows is to enumerate // all the threads in the entire system, // and find those belonging to the process (ugh!!) // + +// OpenThread +typedef HANDLE (WINAPI *tOT)(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId); + int suspend_or_resume_threads(DWORD pid, bool resume) { HANDLE threads, thread; + HMODULE hKernel32Lib = NULL; THREADENTRY32 te = {0}; + tOT pOT = NULL; + // Dynamically link to the proper function pointers. + hKernel32Lib = GetModuleHandleA("kernel32.dll"); + pOT = (tOT) GetProcAddress( hKernel32Lib, "OpenThread" ); + + if (!pOT) { + return -1; + } + threads = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); if (threads == INVALID_HANDLE_VALUE) return -1; @@ -676,7 +775,7 @@ int suspend_or_resume_threads(DWORD pid, bool resume) { do { if (te.th32OwnerProcessID == pid) { - thread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID); + thread = pOT(THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID); resume ? ResumeThread(thread) : SuspendThread(thread); CloseHandle(thread); } @@ -687,9 +786,6 @@ int suspend_or_resume_threads(DWORD pid, bool resume) { return 0; } - -// Change the current working directory to the data directory -// void chdir_to_data_dir() { LONG lReturnValue; HKEY hkSetupHive; diff --git a/lib/win_util.h b/lib/win_util.h index ed8317eb15..bf1e0f96cd 100644 --- a/lib/win_util.h +++ b/lib/win_util.h @@ -19,6 +19,7 @@ extern BOOL IsWindows2000Compatible(); extern BOOL IsTerminalServicesEnabled(); +extern BOOL ValidateProductSuite(LPSTR SuiteName); extern BOOL TerminateProcessById(DWORD dwProcessId); extern BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid); extern BOOL AddAceToDesktop(HDESK hdesk, PSID psid); @@ -27,7 +28,5 @@ extern BOOL GetAccountSid( LPCSTR AccountName, // account of interest PSID *Sid // resultant buffer containing SID ); - extern int suspend_or_resume_threads(DWORD pid, bool resume); extern void chdir_to_data_dir(); -extern bool is_remote_desktop();