634 lines
15 KiB
C++
634 lines
15 KiB
C++
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1996-1998
|
||
|
//
|
||
|
// File: utils.cpp
|
||
|
//
|
||
|
// Contents: Hydra License Server Service Control Manager Interface
|
||
|
//
|
||
|
// History: 12-09-97 HueiWang Modified from MSDN RPC Service Sample
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
#include "pch.cpp"
|
||
|
#include <lm.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#include "utils.h"
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
FileExists(
|
||
|
IN PCTSTR FileName,
|
||
|
OUT PWIN32_FIND_DATA FindData OPTIONAL
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Determine if a file exists and is accessible.
|
||
|
Errormode is set (and then restored) so the user will not see
|
||
|
any pop-ups.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
FileName - supplies full path of file to check for existance.
|
||
|
|
||
|
FindData - if specified, receives find data for the file.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE if the file exists and is accessible.
|
||
|
FALSE if not. GetLastError() returns extended error info.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
WIN32_FIND_DATA findData;
|
||
|
HANDLE FindHandle;
|
||
|
DWORD Error;
|
||
|
|
||
|
FindHandle = FindFirstFile(FileName,&findData);
|
||
|
if(FindHandle == INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
Error = GetLastError();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
FindClose(FindHandle);
|
||
|
if(FindData)
|
||
|
{
|
||
|
*FindData = findData;
|
||
|
}
|
||
|
Error = NO_ERROR;
|
||
|
}
|
||
|
|
||
|
SetLastError(Error);
|
||
|
return (Error == NO_ERROR);
|
||
|
}
|
||
|
|
||
|
/*----------------------------------------------------------------------------
|
||
|
Routine Description:
|
||
|
|
||
|
This function checks to see whether the specified sid is enabled in
|
||
|
the specified token.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
TokenHandle - If present, this token is checked for the sid. If not
|
||
|
present then the current effective token will be used. This must
|
||
|
be an impersonation token.
|
||
|
|
||
|
SidToCheck - The sid to check for presence in the token
|
||
|
|
||
|
IsMember - If the sid is enabled in the token, contains TRUE otherwise
|
||
|
false.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
TRUE - The API completed successfully. It does not indicate that the
|
||
|
sid is a member of the token.
|
||
|
|
||
|
FALSE - The API failed. A more detailed status code can be retrieved
|
||
|
via GetLastError()
|
||
|
|
||
|
|
||
|
Note : Code modified from 5.0 \\rastaman\ntwin\src\base\advapi\security.c
|
||
|
----------------------------------------------------------------------------*/
|
||
|
BOOL
|
||
|
TLSCheckTokenMembership(
|
||
|
IN HANDLE TokenHandle OPTIONAL,
|
||
|
IN PSID SidToCheck,
|
||
|
OUT PBOOL IsMember
|
||
|
)
|
||
|
{
|
||
|
HANDLE ProcessToken = NULL;
|
||
|
HANDLE EffectiveToken = NULL;
|
||
|
DWORD Status = ERROR_SUCCESS;
|
||
|
PISECURITY_DESCRIPTOR SecDesc = NULL;
|
||
|
ULONG SecurityDescriptorSize;
|
||
|
GENERIC_MAPPING GenericMapping = { STANDARD_RIGHTS_READ,
|
||
|
STANDARD_RIGHTS_EXECUTE,
|
||
|
STANDARD_RIGHTS_WRITE,
|
||
|
STANDARD_RIGHTS_ALL };
|
||
|
//
|
||
|
// The size of the privilege set needs to contain the set itself plus
|
||
|
// any privileges that may be used. The privileges that are used
|
||
|
// are SeTakeOwnership and SeSecurity, plus one for good measure
|
||
|
//
|
||
|
BYTE PrivilegeSetBuffer[sizeof(PRIVILEGE_SET) + 3*sizeof(LUID_AND_ATTRIBUTES)];
|
||
|
PPRIVILEGE_SET PrivilegeSet = (PPRIVILEGE_SET) PrivilegeSetBuffer;
|
||
|
ULONG PrivilegeSetLength = sizeof(PrivilegeSetBuffer);
|
||
|
ACCESS_MASK AccessGranted = 0;
|
||
|
BOOL AccessStatus = FALSE;
|
||
|
PACL Dacl = NULL;
|
||
|
|
||
|
#define MEMBER_ACCESS 1
|
||
|
|
||
|
*IsMember = FALSE;
|
||
|
|
||
|
//
|
||
|
// Get a handle to the token
|
||
|
//
|
||
|
if (TokenHandle != NULL)
|
||
|
{
|
||
|
EffectiveToken = TokenHandle;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(!OpenThreadToken(GetCurrentThread(),
|
||
|
TOKEN_QUERY,
|
||
|
FALSE, // don't open as self
|
||
|
&EffectiveToken))
|
||
|
{
|
||
|
//
|
||
|
// if there is no thread token, try the process token
|
||
|
//
|
||
|
if((Status=GetLastError()) == ERROR_NO_TOKEN)
|
||
|
{
|
||
|
if(!OpenProcessToken(GetCurrentProcess(),
|
||
|
TOKEN_QUERY | TOKEN_DUPLICATE,
|
||
|
&ProcessToken))
|
||
|
{
|
||
|
Status = GetLastError();
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// If we have a process token, we need to convert it to an
|
||
|
// impersonation token
|
||
|
//
|
||
|
if (Status == ERROR_SUCCESS)
|
||
|
{
|
||
|
BOOL Result;
|
||
|
Result = DuplicateToken(ProcessToken,
|
||
|
SecurityImpersonation,
|
||
|
&EffectiveToken);
|
||
|
CloseHandle(ProcessToken);
|
||
|
if (!Result)
|
||
|
{
|
||
|
return(FALSE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Status != ERROR_SUCCESS)
|
||
|
{
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Construct a security descriptor to pass to access check
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// The size is equal to the size of an SD + twice the length of the SID
|
||
|
// (for owner and group) + size of the DACL = sizeof ACL + size of the
|
||
|
// ACE, which is an ACE + length of
|
||
|
// ths SID.
|
||
|
//
|
||
|
|
||
|
SecurityDescriptorSize = sizeof(SECURITY_DESCRIPTOR) +
|
||
|
sizeof(ACCESS_ALLOWED_ACE) +
|
||
|
sizeof(ACL) +
|
||
|
3 * GetLengthSid(SidToCheck);
|
||
|
|
||
|
SecDesc = (PISECURITY_DESCRIPTOR) LocalAlloc(LMEM_ZEROINIT, SecurityDescriptorSize );
|
||
|
if (SecDesc == NULL)
|
||
|
{
|
||
|
Status = ERROR_OUTOFMEMORY;
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
Dacl = (PACL) (SecDesc + 1);
|
||
|
|
||
|
InitializeSecurityDescriptor(SecDesc, SECURITY_DESCRIPTOR_REVISION);
|
||
|
|
||
|
//
|
||
|
// Fill in fields of security descriptor
|
||
|
//
|
||
|
SetSecurityDescriptorOwner(SecDesc, SidToCheck, FALSE);
|
||
|
SetSecurityDescriptorGroup(SecDesc, SidToCheck, FALSE);
|
||
|
|
||
|
if(!InitializeAcl( Dacl,
|
||
|
SecurityDescriptorSize - sizeof(SECURITY_DESCRIPTOR),
|
||
|
ACL_REVISION))
|
||
|
{
|
||
|
Status=GetLastError();
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if(!AddAccessAllowedAce(Dacl, ACL_REVISION, MEMBER_ACCESS, SidToCheck))
|
||
|
{
|
||
|
Status=GetLastError();
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if(!SetSecurityDescriptorDacl(SecDesc, TRUE, Dacl, FALSE))
|
||
|
{
|
||
|
Status=GetLastError();
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
if(!AccessCheck(SecDesc,
|
||
|
EffectiveToken,
|
||
|
MEMBER_ACCESS,
|
||
|
&GenericMapping,
|
||
|
PrivilegeSet,
|
||
|
&PrivilegeSetLength,
|
||
|
&AccessGranted,
|
||
|
&AccessStatus))
|
||
|
{
|
||
|
Status=GetLastError();
|
||
|
goto Cleanup;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// if the access check failed, then the sid is not a member of the
|
||
|
// token
|
||
|
//
|
||
|
if ((AccessStatus == TRUE) && (AccessGranted == MEMBER_ACCESS))
|
||
|
{
|
||
|
*IsMember = TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
Cleanup:
|
||
|
if (TokenHandle == NULL && EffectiveToken != NULL)
|
||
|
{
|
||
|
CloseHandle(EffectiveToken);
|
||
|
}
|
||
|
|
||
|
if (SecDesc != NULL)
|
||
|
{
|
||
|
LocalFree(SecDesc);
|
||
|
}
|
||
|
|
||
|
return (Status == ERROR_SUCCESS) ? TRUE : FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*------------------------------------------------------------------------
|
||
|
|
||
|
BOOL IsAdmin(void)
|
||
|
|
||
|
returns TRUE if user is an admin
|
||
|
FALSE if user is not an admin
|
||
|
------------------------------------------------------------------------*/
|
||
|
DWORD
|
||
|
IsAdmin(
|
||
|
BOOL* bMember
|
||
|
)
|
||
|
{
|
||
|
PSID psidAdministrators;
|
||
|
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
|
||
|
DWORD dwStatus=ERROR_SUCCESS;
|
||
|
|
||
|
do {
|
||
|
if(!AllocateAndInitializeSid(&siaNtAuthority,
|
||
|
2,
|
||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
||
|
DOMAIN_ALIAS_RID_ADMINS,
|
||
|
0, 0, 0, 0, 0, 0,
|
||
|
&psidAdministrators))
|
||
|
{
|
||
|
dwStatus=GetLastError();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// assume that we don't find the admin SID.
|
||
|
if(!TLSCheckTokenMembership(NULL,
|
||
|
psidAdministrators,
|
||
|
bMember))
|
||
|
{
|
||
|
dwStatus=GetLastError();
|
||
|
}
|
||
|
|
||
|
FreeSid(psidAdministrators);
|
||
|
|
||
|
} while(FALSE);
|
||
|
|
||
|
return dwStatus;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL
|
||
|
LoadResourceString(
|
||
|
DWORD dwId,
|
||
|
LPTSTR szBuf,
|
||
|
DWORD dwBufSize
|
||
|
)
|
||
|
{
|
||
|
int dwRet;
|
||
|
|
||
|
dwRet=LoadString(GetModuleHandle(NULL), dwId, szBuf, dwBufSize);
|
||
|
|
||
|
return (dwRet != 0);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
HRESULT
|
||
|
LogEvent(
|
||
|
LPTSTR lpszSource,
|
||
|
DWORD dwEventType,
|
||
|
DWORD dwIdEvent,
|
||
|
WORD cStrings,
|
||
|
TCHAR **apwszStrings
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HANDLE hAppLog=NULL;
|
||
|
BOOL bSuccess=FALSE;
|
||
|
WORD wElogType;
|
||
|
|
||
|
wElogType = (WORD) dwEventType;
|
||
|
if(hAppLog=RegisterEventSource(NULL, lpszSource))
|
||
|
{
|
||
|
bSuccess = ReportEvent(
|
||
|
hAppLog,
|
||
|
wElogType,
|
||
|
0,
|
||
|
dwIdEvent,
|
||
|
NULL,
|
||
|
cStrings,
|
||
|
0,
|
||
|
(const TCHAR **) apwszStrings,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
DeregisterEventSource(hAppLog);
|
||
|
}
|
||
|
|
||
|
return((bSuccess) ? ERROR_SUCCESS : GetLastError());
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void
|
||
|
TLSLogInfoEvent(
|
||
|
IN DWORD code
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
LogEvent(
|
||
|
_TEXT(SZSERVICENAME),
|
||
|
EVENTLOG_INFORMATION_TYPE,
|
||
|
code,
|
||
|
0,
|
||
|
NULL
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void
|
||
|
TLSLogWarningEvent(
|
||
|
IN DWORD code
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
LogEvent(
|
||
|
_TEXT(SZSERVICENAME),
|
||
|
EVENTLOG_WARNING_TYPE,
|
||
|
code,
|
||
|
0,
|
||
|
NULL
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void
|
||
|
TLSLogErrorEvent(
|
||
|
IN DWORD errCode
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
LogEvent(
|
||
|
_TEXT(SZSERVICENAME),
|
||
|
EVENTLOG_ERROR_TYPE,
|
||
|
errCode,
|
||
|
0,
|
||
|
NULL
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void
|
||
|
TLSLogEventString(
|
||
|
IN DWORD dwEventType,
|
||
|
IN DWORD dwEventId,
|
||
|
IN WORD wNumString,
|
||
|
IN LPCTSTR* lpStrings
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
HANDLE hAppLog=NULL;
|
||
|
BOOL bSuccess=FALSE;
|
||
|
WORD wElogType = (WORD) dwEventType;
|
||
|
|
||
|
__try {
|
||
|
if(hAppLog=RegisterEventSource(NULL, _TEXT(SZSERVICENAME)))
|
||
|
{
|
||
|
bSuccess = ReportEvent(
|
||
|
hAppLog,
|
||
|
wElogType,
|
||
|
0,
|
||
|
dwEventId,
|
||
|
NULL,
|
||
|
wNumString,
|
||
|
0,
|
||
|
(const TCHAR **) lpStrings,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
DeregisterEventSource(hAppLog);
|
||
|
}
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void
|
||
|
TLSLogEvent(
|
||
|
IN DWORD type,
|
||
|
IN DWORD EventId,
|
||
|
IN DWORD code, ...
|
||
|
)
|
||
|
/*
|
||
|
*/
|
||
|
{
|
||
|
va_list marker;
|
||
|
va_start( marker, code );
|
||
|
DWORD dwRet;
|
||
|
LPTSTR lpszTemp = NULL;
|
||
|
|
||
|
__try {
|
||
|
dwRet=FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE |
|
||
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
||
|
NULL,
|
||
|
code,
|
||
|
LANG_NEUTRAL,
|
||
|
(LPTSTR)&lpszTemp,
|
||
|
0,
|
||
|
&marker);
|
||
|
|
||
|
if(dwRet != 0)
|
||
|
{
|
||
|
LogEvent(_TEXT(SZSERVICENAME), type, EventId, 1, &lpszTemp);
|
||
|
if(lpszTemp)
|
||
|
{
|
||
|
LocalFree((HLOCAL)lpszTemp);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
// this is only for putting a break point here
|
||
|
SetLastError(GetLastError());
|
||
|
}
|
||
|
|
||
|
va_end( marker );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
BOOL
|
||
|
TLSSystemTimeToFileTime(
|
||
|
SYSTEMTIME* pSysTime,
|
||
|
LPFILETIME pfTime
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DoConvert:
|
||
|
|
||
|
if(SystemTimeToFileTime(pSysTime, pfTime) == FALSE)
|
||
|
{
|
||
|
if(GetLastError() != ERROR_INVALID_PARAMETER)
|
||
|
{
|
||
|
TLSASSERT(FALSE);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if(pSysTime->wMonth == 2)
|
||
|
{
|
||
|
if(pSysTime->wDay > 29)
|
||
|
{
|
||
|
pSysTime->wDay = 29;
|
||
|
goto DoConvert;
|
||
|
}
|
||
|
else if(pSysTime->wDay == 29)
|
||
|
{
|
||
|
pSysTime->wDay = 28;
|
||
|
goto DoConvert;
|
||
|
}
|
||
|
}
|
||
|
else if ((pSysTime->wMonth == 9) ||
|
||
|
(pSysTime->wMonth == 4) ||
|
||
|
(pSysTime->wMonth == 6) ||
|
||
|
(pSysTime->wMonth == 11))
|
||
|
{
|
||
|
if (pSysTime->wDay > 30)
|
||
|
{
|
||
|
pSysTime->wDay = 30;
|
||
|
goto DoConvert;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
BOOL
|
||
|
FileTimeToLicenseDate(
|
||
|
LPFILETIME pft,
|
||
|
DWORD* t
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
++*/
|
||
|
{
|
||
|
SYSTEMTIME sysTime;
|
||
|
struct tm gmTime;
|
||
|
FILETIME localFt;
|
||
|
time_t licenseTime;
|
||
|
|
||
|
if(FileTimeToLocalFileTime(pft, &localFt) == FALSE)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if(FileTimeToSystemTime(&localFt, &sysTime) == FALSE)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if(sysTime.wYear >= 2038)
|
||
|
{
|
||
|
licenseTime = INT_MAX;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Unix time support up to 2038/1/18
|
||
|
// restrict any expiration data
|
||
|
memset(&gmTime, 0, sizeof(gmTime));
|
||
|
gmTime.tm_sec = sysTime.wSecond;
|
||
|
gmTime.tm_min = sysTime.wMinute;
|
||
|
gmTime.tm_hour = sysTime.wHour;
|
||
|
gmTime.tm_year = sysTime.wYear - 1900;
|
||
|
gmTime.tm_mon = sysTime.wMonth - 1;
|
||
|
gmTime.tm_mday = sysTime.wDay;
|
||
|
gmTime.tm_isdst = -1;
|
||
|
|
||
|
if((licenseTime = mktime(&gmTime)) == (time_t)-1)
|
||
|
{
|
||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*t = (DWORD)licenseTime;
|
||
|
|
||
|
return licenseTime != (time_t)-1;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
void
|
||
|
UnixTimeToFileTime(
|
||
|
time_t t,
|
||
|
LPFILETIME pft
|
||
|
)
|
||
|
{
|
||
|
LARGE_INTEGER li;
|
||
|
|
||
|
li.QuadPart = Int32x32To64(t, 10000000) + 116444736000000000;
|
||
|
|
||
|
pft->dwHighDateTime = li.HighPart;
|
||
|
pft->dwLowDateTime = li.LowPart;
|
||
|
}
|
||
|
|