📄 os_spec.c
字号:
BYTE buffer[ 16 ];
/* The maximum length of a numeric string value that can be converted
to a 4-byte integer is considered as 10 characters (9,999,999,999) */
strncpy( buffer, str, 10 );
buffer[ 10 ] = '\0';
asciiToEbcdic( buffer, strlen( buffer ) );
return( atoi( buffer ) );
}
/****************************************************************************
* *
* PalmOS *
* *
****************************************************************************/
#elif defined( __PALMOS__ )
#include <CmnErrors.h>
#include <CmnLaunchCodes.h>
/* The cryptlib entry point, defined in cryptlib.sld */
uint32_t cryptlibMain( uint16_t cmd, void *cmdPBP, uint16_t launchFlags )
{
UNUSED( cmdPBP );
UNUSED( launchFlags );
switch( cmd )
{
case sysLaunchCmdInitialize:
/* Set up the initialisation lock in the kernel */
preInit();
break;
case sysLaunchCmdFinalize:
/* Delete the initialisation lock in the kernel */
postShutdown();
break;
}
return( errNone );
}
/****************************************************************************
* *
* RTEMS *
* *
****************************************************************************/
#elif defined( __RTEMS__ )
/* The RTEMS thread-self function returns the task ID via a reference
parameter, because of this we have to provide a wrapper that returns it
as a return value. We use RTEMS_SEARCH_ALL_NODES because there isn't
any other way to specify the local node, this option always searches the
local node first so it has the desired effect */
rtems_id threadSelf( void )
{
rtems_id taskID;
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &taskID );
return( taskID );
}
/****************************************************************************
* *
* Tandem *
* *
****************************************************************************/
/* The Tandem mktime() is broken and can't convert dates beyond 2023, if
mktime() fails and the year is between then and the epoch try again with
a time that it can convert */
#elif defined( __TANDEM_NSK__ ) || defined( __TANDEM_OSS__ )
#undef mktime /* Restore the standard mktime() */
time_t my_mktime( struct tm *timeptr )
{
time_t theTime;
theTime = mktime( timeptr );
if( theTime < 0 && timeptr->tm_year > 122 && timeptr->tm_year <= 138 )
{
timeptr->tm_year = 122; /* Try again with a safe year of 2022 */
theTime = mktime( timeptr );
}
return( theTime );
}
/****************************************************************************
* *
* Unix *
* *
****************************************************************************/
#elif defined( __UNIX__ ) && \
!( defined( __MVS__ ) || defined( __TANDEM_NSK__ ) || \
defined( __TANDEM_OSS__ ) )
#include <sys/time.h>
/* For performance evaluation purposes we provide the following function,
which returns ticks of the 1us timer */
long getTickCount( long startTime )
{
struct timeval tv;
long timeLSB, timeDifference;
/* Only accurate to about 1us */
gettimeofday( &tv, NULL );
timeLSB = tv.tv_usec;
/* If we're getting an initial time, return an absolute value */
if( !startTime )
return( timeLSB );
/* We're getting a time difference */
if( startTime < timeLSB )
timeDifference = timeLSB - startTime;
else
/* gettimeofday() rolls over at 1M us */
timeDifference = ( 1000000L - startTime ) + timeLSB;
if( timeDifference <= 0 )
{
printf( "Error: Time difference = %X, startTime = %X, endTime = %X.\n",
timeDifference, startTime, timeLSB );
return( 1 );
}
return( timeDifference );
}
/****************************************************************************
* *
* Windows *
* *
****************************************************************************/
#elif defined( __WIN32__ )
/* A flag to record whether we're running under the Win95 or WinNT code
base */
BOOLEAN isWin95;
/* For performance evaluation purposes we provide the following function,
which returns ticks of the 3.579545 MHz hardware timer (see the long
comment in rndwin32.c for more details on Win32 timing issues) */
long getTickCount( long startTime )
{
long timeLSB, timeDifference;
#if 1
LARGE_INTEGER performanceCount;
/* Sensitive to context switches */
QueryPerformanceCounter( &performanceCount );
timeLSB = performanceCount.LowPart;
#else
FILETIME dummyTime, kernelTime, userTime;
int status;
/* Only accurate to 10ms, returns constant values in VC++ debugger */
GetThreadTimes( GetCurrentThread(), &dummyTime, &dummyTime,
&kernelTime, &userTime );
timeLSB = userTime.dwLowDateTime;
#endif /* 0 */
/* If we're getting an initial time, return an absolute value */
if( !startTime )
return( timeLSB );
/* We're getting a time difference */
if( startTime < timeLSB )
timeDifference = timeLSB - startTime;
else
/* Windows rolls over at INT_MAX */
timeDifference = ( 0xFFFFFFFFUL - startTime ) + 1 + timeLSB;
if( timeDifference <= 0 )
{
printf( "Error: Time difference = %X, startTime = %X, endTime = %X.\n",
timeDifference, startTime, timeLSB );
return( 1 );
}
return( timeDifference );
}
/* Windows NT/2000/XP support ACL-based access control mechanisms for system
objects, so when we create objects such as files and threads we give them
an ACL that allows only the creator access. The following functions
return the security info needed when creating objects. The interface for
this has changed in every major OS release, although it never got any
better, just differently ugly. The following code uses the original NT
3.1 interface, which works for all OS versions */
/* The size of the buffer for ACLs and the user token */
#define ACL_BUFFER_SIZE 1024
#define TOKEN_BUFFER_SIZE 256
/* A composite structure to contain the various ACL structures. This is
required because ACL handling is a complex, multistage operation that
requires first creating an ACL and security descriptor to contain it,
adding an access control entry (ACE) to the ACL, adding the ACL as the
DACL of the security descriptor, and finally, wrapping the security
descriptor up in a security attributes structure that can be passed to
an object-creation function.
The handling of the TOKEN_INFO is extraordinarily ugly because although
the TOKEN_USER struct as defined is only 8 bytes long, Windoze allocates
an extra 24 bytes after the end of the struct into which it stuffs data
that the SID pointer in the TOKEN_USER struct points to. This means that
we can't statically allocate memory of the size of the TOKEN_USER struct
but have to make it a pointer into a larger buffer that can contain the
additional invisible data tacked onto the end */
typedef struct {
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR pSecurityDescriptor;
PACL pAcl;
PTOKEN_USER pTokenUser;
BYTE aclBuffer[ ACL_BUFFER_SIZE ];
BYTE tokenBuffer[ TOKEN_BUFFER_SIZE ];
} SECURITY_INFO;
/* Initialise an ACL allowing only the creator access and return it to the
caller as an opaque value */
void *initACLInfo( const int access )
{
SECURITY_INFO *securityInfo;
HANDLE hToken = INVALID_HANDLE_VALUE; /* See comment below */
BOOLEAN tokenOK = FALSE;
/* Win95/98/ME doesn't have any security, return null security info */
if( isWin95 )
return( NULL );
/* Allocate and initialise the composite security info structure */
if( ( securityInfo = \
clAlloc( "initACLInfo", sizeof( SECURITY_INFO ) ) ) == NULL )
return( NULL );
memset( securityInfo, 0, sizeof( SECURITY_INFO ) );
securityInfo->pAcl = ( PACL ) securityInfo->aclBuffer;
securityInfo->pTokenUser = ( PTOKEN_USER ) securityInfo->tokenBuffer;
/* Get the security token for this thread. First we try for the thread
token (which it typically only has when impersonating), if we don't
get that we use the token associated with the process. We also
initialise the hToken (above) even though it shouldn't be necessary
because Windows tries to read its contents, which indicates there
might be problems if it happens to start out with the wrong value */
if( OpenThreadToken( GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken ) || \
OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &hToken ) )
{
DWORD cbTokenUser;
tokenOK = GetTokenInformation( hToken, TokenUser,
securityInfo->pTokenUser,
TOKEN_BUFFER_SIZE, &cbTokenUser );
CloseHandle( hToken );
}
if( !tokenOK )
{
clFree( "initACLInfo", securityInfo );
return( NULL );
}
/* Set a security descriptor owned by the current user */
if( !InitializeSecurityDescriptor( &securityInfo->pSecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION ) || \
!SetSecurityDescriptorOwner( &securityInfo->pSecurityDescriptor,
securityInfo->pTokenUser->User.Sid,
FALSE ) )
{
clFree( "initACLInfo", securityInfo );
return( NULL );
}
/* Set up the discretionary access control list (DACL) with one access
control entry (ACE) for the current user */
if( !InitializeAcl( securityInfo->pAcl, ACL_BUFFER_SIZE,
ACL_REVISION ) || \
!AddAccessAllowedAce( securityInfo->pAcl, ACL_REVISION, access,
securityInfo->pTokenUser->User.Sid ) )
{
clFree( "initACLInfo", securityInfo );
return( NULL );
}
/* Bind the DACL to the security descriptor */
if( !SetSecurityDescriptorDacl( &securityInfo->pSecurityDescriptor, TRUE,
securityInfo->pAcl, FALSE ) )
{
clFree( "initACLInfo", securityInfo );
return( NULL );
}
assert( IsValidSecurityDescriptor( &securityInfo->pSecurityDescriptor ) );
/* Finally, set up the security attributes structure */
securityInfo->sa.nLength = sizeof( SECURITY_ATTRIBUTES );
securityInfo->sa.bInheritHandle = FALSE;
securityInfo->sa.lpSecurityDescriptor = &securityInfo->pSecurityDescriptor;
return( securityInfo );
}
void freeACLInfo( void *securityInfoPtr )
{
SECURITY_INFO *securityInfo = ( SECURITY_INFO * ) securityInfoPtr;
if( securityInfo == NULL )
return;
clFree( "freeACLInfo", securityInfo );
}
/* Extract the security info needed in Win32 API calls from the collection of
security data that we set up earlier */
void *getACLInfo( void *securityInfoPtr )
{
SECURITY_INFO *securityInfo = ( SECURITY_INFO * ) securityInfoPtr;
return( ( securityInfo == NULL ) ? NULL : &securityInfo->sa );
}
#if !( defined( NT_DRIVER ) || defined( STATIC_LIB ) )
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
static DWORD dwPlatform = ( DWORD ) CRYPT_ERROR;
UNUSED( hinstDLL );
UNUSED( lpvReserved );
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
/* Figure out which version of Windows we're running under */
if( dwPlatform == ( DWORD ) CRYPT_ERROR )
{
OSVERSIONINFO osvi = { sizeof( osvi ) };
GetVersionEx( &osvi );
dwPlatform = osvi.dwPlatformId;
isWin95 = ( dwPlatform == VER_PLATFORM_WIN32_WINDOWS ) ? \
TRUE : FALSE;
/* Check for Win32s just in case someone ever tries to load
cryptlib under it */
if( dwPlatform == VER_PLATFORM_WIN32s )
return( FALSE );
}
/* Disable thread-attach notifications, which we don't do
anything with and therefore don't need */
DisableThreadLibraryCalls( hinstDLL );
/* Set up the initialisation lock in the kernel */
preInit();
break;
case DLL_PROCESS_DETACH:
/* Delete the initialisation lock in the kernel */
postShutdown();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return( TRUE );
}
#endif /* !( NT_DRIVER || STATIC_LIB ) */
/* Idiot-proofing. Yes, there really are people who'll try and register a
straight DLL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -