- 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
This commit is contained in:
Rom Walton 2009-07-25 03:51:18 +00:00
parent dca67408fd
commit bb2d95953c
3 changed files with 121 additions and 18 deletions

View File

@ -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

View File

@ -22,6 +22,8 @@
#include "boinc_win.h"
#endif
//#include <Wtsapi32.h> // 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;

View File

@ -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();