8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 20:43:03 +01:00

Removed isc_win32.cpp.

This commit is contained in:
dimitr 2002-11-26 08:58:31 +00:00
parent 3f16945373
commit 593298110c

View File

@ -1,472 +0,0 @@
/*
* PROGRAM: JRD Access Method - Win32 specific functions.
* MODULE: isc_win32.c
* DESCRIPTION: General purpose but non-user routines.
*
* The contents of this file are subject to the Interbase Public
* License Version 1.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.Inprise.com/IPL.html
*
* Software distributed under the License is distributed on an
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
* or implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code was created by Inprise Corporation
* and its predecessors. Portions created by Inprise Corporation are
* Copyright (C) Inprise Corporation.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
* Added TCP_NO_DELAY option for superserver on Linux
* FSG 16.03.2001
* Solaris x86 changes - Konstantin Kuznetsov, Neil McCalden
*/
/*
$Id: isc_win32.cpp,v 1.9 2002-11-13 16:37:05 alexpeshkoff Exp $
*/
#include "firebird.h"
#include "../jrd/ib_stdio.h"
#include "../jrd/common.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <windows.h>
#include "gen/codes.h"
#include "../jrd/isc.h"
#include "../jrd/ibase.h"
#include "../jrd/jrd.h"
#include "../jrd/gds_proto.h"
#include "../jrd/isc_proto.h"
#include "../jrd/jrd_proto.h"
#include "../utilities/registry.h"
#include <windows.h>
#ifdef TEXT
#undef TEXT
#endif
#define TEXT SCHAR
#include <process.h>
#include <signal.h>
static USHORT os_type;
static SECURITY_ATTRIBUTES security_attr;
static TEXT interbase_directory[MAXPATHLEN];
void isc_internal_set_config_value(UCHAR, ULONG*, ULONG*);
static BOOLEAN check_user_privilege();
//____________________________________________________________
//
// Checks if the process indicated by the process id 'pid' exists.
// Returns TRUE if the indicated process exists, FALSE otherwise.
//
int DLL_EXPORT ISC_check_process_existence(SLONG pid,
SLONG xl_pid,
USHORT super_user)
{
HANDLE handle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, (DWORD) pid);
if (!handle && GetLastError() != ERROR_ACCESS_DENIED)
{
return FALSE;
}
CloseHandle(handle);
return TRUE;
}
//____________________________________________________________
//
// Get host name. Note that this is not the DNS (TCP/IP) hostname,
// it's the Win32 computer name.
//
TEXT* INTERNAL_API_ROUTINE ISC_get_host(TEXT * string, USHORT length)
{
DWORD host_len = length;
if (GetComputerName(string, &host_len))
{
string[host_len] = 0;
}
else
{
strcpy(string, "local");
}
return string;
}
//____________________________________________________________
//
// Returns the type of OS. TRUE for NT,
// FALSE for the 16-bit based ones (9x/ME, ...).
//
BOOLEAN ISC_is_WinNT()
{
OSVERSIONINFO OsVersionInfo;
if (!os_type)
{
os_type = 1; /* Default to NT */
/* The first time this routine is called we use the Windows API
call GetVersion to determine whether Windows/NT or Chicago
is running. */
OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx((LPOSVERSIONINFO) & OsVersionInfo))
{
os_type =
(OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 1 : 2;
}
}
return (os_type != 2) ? TRUE : FALSE;
}
//____________________________________________________________
//
// Lookup a registry entry.
// Returns TRUE if the lookup was successful, FALSE otherwise.
//
SSHORT ISC_get_registry_var(TEXT* variable,
TEXT* buffer,
SSHORT buffer_length,
void** user_hkey)
{
#pragma FB_COMPILER_MESSAGE("This routine no longer used.")
HKEY hkey;
DWORD len, type;
if (!user_hkey)
{
LPCTSTR szKey = REG_KEY_ROOT_CUR_VER;
const LONG ret =
RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKey, 0, KEY_QUERY_VALUE, &hkey);
if (ret != ERROR_SUCCESS)
{
return -1;
}
}
else
{
hkey = *((PHKEY) user_hkey);
}
len = buffer_length;
#pragma FB_COMPILER_MESSAGE("Can/should we fix this cast?")
const LONG ret =
RegQueryValueEx(hkey, variable, NULL, &type, (LPBYTE) buffer, &len);
if (ret != ERROR_SUCCESS)
{
len = 0;
}
if (!user_hkey)
{
RegCloseKey(hkey);
}
return (SSHORT) len;
}
//____________________________________________________________
//
//
LPSECURITY_ATTRIBUTES ISC_get_security_desc()
{
if (security_attr.lpSecurityDescriptor)
{
return &security_attr;
}
PSECURITY_DESCRIPTOR p_security_desc =
(PSECURITY_DESCRIPTOR) gds__alloc((SLONG)
SECURITY_DESCRIPTOR_MIN_LENGTH);
/* FREE: apparently never freed */
if (!p_security_desc) /* NOMEM: */
{
return NULL;
}
#ifdef DEBUG_GDS_ALLOC
gds_alloc_flag_unfreed((void *) p_security_desc);
#endif
if (!InitializeSecurityDescriptor( p_security_desc,
SECURITY_DESCRIPTOR_REVISION) ||
!SetSecurityDescriptorDacl(p_security_desc, TRUE, (PACL) NULL, FALSE))
{
gds__free(p_security_desc);
return NULL;
}
security_attr.nLength = sizeof(security_attr);
security_attr.lpSecurityDescriptor = p_security_desc;
security_attr.bInheritHandle = TRUE;
return &security_attr;
}
//____________________________________________________________
//
// Find out who the user is.
//
int INTERNAL_API_ROUTINE ISC_get_user(TEXT* name,
int* id,
int* group,
TEXT* project,
TEXT* organization,
int* node,
TEXT* user_string)
{
if (id)
*id = -1;
if (group)
*group = -1;
if (project)
*project = 0;
if (organization)
*organization = 0;
if (node)
*node = 0;
if (name)
{
name[0] = 0;
DWORD name_len = 128;
if (GetUserName(name, &name_len))
{
name[name_len] = 0;
/* NT user name is case insensitive */
for (DWORD i = 0; i < name_len; i++)
{
name[i] = UPPER7(name[i]);
}
/* This check is not internationalized, the security model needs to be
* reengineered, especially on SUPERSERVER where none of these local
* user (in process) assumptions are valid.
*/
if (!strcmp(name, "ADMINISTRATOR"))
{
if (id)
*id = 0;
if (group)
*group = 0;
}
}
}
return check_user_privilege();
}
//____________________________________________________________
//
// Check to see if the user belongs to the administrator group.
//
// This routine was adapted from code in routine RunningAsAdminstrator
// in \mstools\samples\regmpad\regdb.c.
//
static BOOLEAN check_user_privilege(void)
{
HANDLE tkhandle;
SID_IDENTIFIER_AUTHORITY system_sid_authority = SECURITY_NT_AUTHORITY;
// First we must open a handle to the access token for this thread.
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &tkhandle))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
// If the thread does not have an access token, we'll examine the
// access token associated with the process.
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &tkhandle))
{
CloseHandle(tkhandle);
return FALSE;
}
}
else
{
return FALSE;
}
}
TOKEN_GROUPS* ptg = NULL;
DWORD token_len = 0;
while (TRUE)
{
/* Then we must query the size of the group information associated with
the token. This is guarenteed to fail the first time through
because there is no buffer. */
if (GetTokenInformation(tkhandle,
TokenGroups,
ptg,
token_len,
&token_len))
{
break;
}
/* If there had been a buffer, it's either too small or something
else is wrong. Either way, we can dispose of it. */
if (ptg)
{
gds__free(ptg);
}
/* Here we verify that GetTokenInformation failed for lack of a large
enough buffer. */
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
CloseHandle(tkhandle);
return FALSE;
}
// Allocate a buffer for the group information.
ptg = (TOKEN_GROUPS *) gds__alloc((SLONG) token_len);
if (!ptg)
{
CloseHandle(tkhandle);
return FALSE; /* NOMEM: */
}
// FREE: earlier in this loop, and at procedure return
}
// Create a System Identifier for the Admin group.
PSID admin_sid;
if (!AllocateAndInitializeSid(&system_sid_authority, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0, &admin_sid))
{
gds__free(ptg);
CloseHandle(tkhandle);
return FALSE;
}
// Finally we'll iterate through the list of groups for this access
// token looking for a match against the SID we created above.
BOOLEAN admin_priv = FALSE;
for (DWORD i = 0; i < ptg->GroupCount; i++)
{
if (EqualSid(ptg->Groups[i].Sid, admin_sid))
{
admin_priv = TRUE;
break;
}
}
// Deallocate the SID we created.
FreeSid(admin_sid);
gds__free(ptg);
CloseHandle(tkhandle);
return admin_priv;
}
#ifdef SUPERSERVER
//____________________________________________________________
//
//
void isc_internal_set_config_value(UCHAR key,
ULONG* value1_ptr,
ULONG* value2_ptr)
{
switch (key)
{
case ISCCFG_DBCACHE_KEY:
JRD_set_cache_default(value1_ptr);
break;
case ISCCFG_PRIORITY_KEY:
{
ULONG priority;
if (*value1_ptr == 2)
priority = HIGH_PRIORITY_CLASS;
else
priority = NORMAL_PRIORITY_CLASS;
if (!SetPriorityClass(GetCurrentProcess(), priority))
{
gds__log("Unable to set process priority.");
}
}
break;
case ISCCFG_MEMMAX_KEY:
case ISCCFG_MEMMIN_KEY:
if (*value1_ptr && *value2_ptr && ISC_is_WinNT())
{
HANDLE hndl =
OpenProcess(PROCESS_SET_QUOTA, FALSE, GetCurrentProcessId());
if (hndl) {
ULONG value1 = *value1_ptr * 1024;
ULONG value2 = *value2_ptr * 1024;
if (!SetProcessWorkingSetSize(hndl, value1, value2))
{
switch (GetLastError())
{
case ERROR_ACCESS_DENIED:
case ERROR_PRIVILEGE_NOT_HELD:
gds__log("Error setting process working set size, access denied.");
break;
case ERROR_INVALID_PARAMETER:
gds__log("Error setting process working set size, improper range.");
break;
case ERROR_NO_SYSTEM_RESOURCES:
gds__log("Error setting process working set size, insufficient memory.");
break;
default:
gds__log("Error setting process working set size, unknown problem.");
}
*value1_ptr = 0;
*value2_ptr = 0;
}
CloseHandle(hndl);
}
}
}
}
#endif /* SUPERSERVER */