⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_spec.c

📁 cryptlib安全工具包
💻 C
📖 第 1 页 / 共 4 页
字号:
									   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 );
	}

STDC_NONNULL_ARG( ( 1 ) ) \
void freeACLInfo( INOUT TYPECAST( SECURITY_INFO * ) void *securityInfoPtr )
	{
	SECURITY_INFO *securityInfo = ( SECURITY_INFO * ) securityInfoPtr;

	assert( securityInfoPtr == NULL || \
			isWritePtr( securityInfoPtr, sizeof( SECURITY_INFO ) ) );

	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 */

STDC_NONNULL_ARG( ( 1 ) ) \
void *getACLInfo( INOUT TYPECAST( SECURITY_INFO * ) void *securityInfoPtr )
	{
	SECURITY_INFO *securityInfo = ( SECURITY_INFO * ) securityInfoPtr;

	assert( securityInfo == NULL || \
			isWritePtr( securityInfo, sizeof( SECURITY_INFO ) ) );

	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_ARG( hinstDLL );
	UNUSED_ARG( lpvReserved );

	switch( fdwReason )
		{
		case DLL_PROCESS_ATTACH:
			/* 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 );
	}

/* Idiot-proofing.  Yes, there really are people who'll try and register a
   straight DLL */

#define MB_OK				0x00000000L
#define MB_ICONQUESTION		0x00000020L

int WINAPI MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption,
						UINT uType );

#ifndef _WIN64
  #pragma comment( linker, "/export:DllRegisterServer=_DllRegisterServer@0,PRIVATE" )
#endif /* Win64 */

STDAPI DllRegisterServer( void )
	{
	MessageBoxA( NULL, "Why are you trying to register the cryptlib DLL?\n"
				 "It's just a standard Windows DLL, there's nothing\nto be "
				 "registered.", "ESO Error",
				 MB_ICONQUESTION | MB_OK );
	return( E_NOINTERFACE );
	}
#endif /* !( NT_DRIVER || STATIC_LIB ) */

/* Borland's archaic compilers don't recognise DllMain() but still use the
   OS/2-era DllEntryPoint(), so we have to alias it to DllMain() in order
   for things to be initialised properly */

#if defined( __BORLANDC__ ) && ( __BORLANDC__ < 0x550 )

BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL, DWORD fdwReason, \
						   LPVOID lpvReserved )
	{
	return( DllMain( hinstDLL, fdwReason, lpvReserved ) );
	}
#endif /* BC++ */

#elif defined( __WIN16__ )

/* WinMain() and WEP() under Win16 are intended for DLL initialisation,
   however it isn't possible to reliably do anything terribly useful in these
   routines.  The reason for this is that the WinMain/WEP functions are
   called by the windows module loader, which has a very limited workspace
   and can cause peculiar behaviour for some functions (allocating/freeing
   memory and loading other modules from these routines is unreliable), the
   order in which WinMain() and WEP() will be called for a set of DLL's is
   unpredictable (sometimes WEP doesn't seem to be called at all), and they
   can't be tracked by a standard debugger.  This is why MS have
   xxxRegisterxxx() and xxxUnregisterxxx() functions in their DLL's.

   Under Win16 on a Win32 system this isn't a problem because the module
   loader has been rewritten to work properly, but it isn't possible to get
   reliable performance under pure Win16, so the DLL entry/exit routines here
   do almost nothing, with the real work being done in cryptInit()/
   cryptEnd() */

HWND hInst;

int CALLBACK LibMain( HINSTANCE hInstance, WORD wDataSeg, WORD wHeapSize, \
					  LPSTR lpszCmdLine )
	{
	/* Remember the proc instance for later */
	hInst = hInstance;

	return( TRUE );
	}

int CALLBACK WEP( int nSystemExit )
	{
	switch( nSystemExit )
		{
		case WEP_SYSTEM_EXIT:
			/* System is shutting down */
			break;

		case WEP_FREE_DLL:
			/* DLL reference count = 0, DLL-only shutdown */
			break;
		}

	return( TRUE );
	}

/* Check whether we're running inside a VM, which is a potential risk for
   cryptovariables.  It gets quite tricky to detect the various VMs so for
   now the only one that we detect is the most widespread one, VMware */

#if defined( __WIN32__ )  && !defined( NO_ASM )

BOOLEAN isRunningInVM( void )
	{
	unsigned int magicValue, version;

	__try {
	__asm {
		push eax
		push ebx
		push ecx
		push edx

		/* Check for VMware via the VMware guest-to-host communications 
		   channel */
		mov eax, 'VMXh'		/* VMware magic value 0x564D5868 */
		xor ebx, ebx		/* Clear parameters register */
		mov ecx, 0Ah		/* Get-version command */
		mov dx, 'VX'		/* VMware I/O port 0x5658 */
		in eax, dx			/* Perform VMware call */
		mov magicValue, ebx	/* VMware magic value */
		mov version, ecx	/* VMware version */

		pop edx
		pop ecx
		pop ebx
		pop eax
		}
	} __except (EXCEPTION_EXECUTE_HANDLER) {}

	return( magicValue == 'VMXh' ) ? TRUE : FALSE );
	}
#else

BOOLEAN isRunningInVM( void )
	{
	return( FALSE );
	}
#endif /* __WIN32__ && !NO_ASM */

/****************************************************************************
*																			*
*									Windows CE								*
*																			*
****************************************************************************/

#elif defined( __WINCE__ )

/* Windows CE doesn't provide ANSI standard time functions (although it'd be
   relatively easy to do so, and they are in fact provided in MFC), so we
   have to provide our own */

CHECK_RETVAL \
static LARGE_INTEGER *getTimeOffset( void )
	{
	static LARGE_INTEGER timeOffset = { 0 };

	/* Get the difference between the ANSI/ISO C time epoch and the Windows
	   time epoch if we haven't already done so (we could also hardcode this
	   in as 116444736000000000LL) */
	if( timeOffset.QuadPart == 0 )
		{
		SYSTEMTIME ofsSystemTime;
		FILETIME ofsFileTime;

		memset( &ofsSystemTime, 0, sizeof( SYSTEMTIME ) );
		ofsSystemTime.wYear = 1970;
		ofsSystemTime.wMonth = 1;
		ofsSystemTime.wDay = 1;
		SystemTimeToFileTime( &ofsSystemTime, &ofsFileTime );
		timeOffset.HighPart = ofsFileTime.dwHighDateTime;
		timeOffset.LowPart = ofsFileTime.dwLowDateTime;
		}

	return( &timeOffset );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static time_t fileTimeToTimeT( const FILETIME *fileTime )
	{
	const LARGE_INTEGER *timeOffset = getTimeOffset();
	LARGE_INTEGER largeInteger;

	/* Convert a Windows FILETIME to a time_t by dividing by
	   10,000,000 (to go from 100ns ticks to 1s ticks) */
	largeInteger.HighPart = fileTime->dwHighDateTime;
	largeInteger.LowPart = fileTime->dwLowDateTime;
	largeInteger.QuadPart = ( largeInteger.QuadPart - \
							  timeOffset->QuadPart ) / 10000000L;
	if( sizeof( time_t ) == 4 && \
		largeInteger.QuadPart > 0x80000000UL )
		{
		/* time_t is 32 bits but the converted time is larger than a 32-bit
		   signed value, indicate that we couldn't convert it.  In theory
		   we could check for largeInteger.HighPart == 0 and perform a
		   second check to see if time_t is unsigned, but it's unlikely that
		   this change would be made to the VC++ runtime time_t since it'd
		   break too many existing apps */
		return( -1 );
		}
	return( ( time_t ) largeInteger.QuadPart );
	}

CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
static void timeTToFileTime( FILETIME *fileTime, const time_t timeT )
	{
	const LARGE_INTEGER *timeOffset = getTimeOffset();
	LARGE_INTEGER largeInteger = { timeT };

	/* Convert a time_t to a Windows FILETIME by multiplying by
	   10,000,000 (to go from 1s ticks to 100ns ticks) */
	largeInteger.QuadPart = ( largeInteger.QuadPart * 10000000L ) + \
							timeOffset->QuadPart;
	fileTime->dwHighDateTime = largeInteger.HighPart;
	fileTime->dwLowDateTime = largeInteger.LowPart;
	}

time_t time( time_t *timePtr )
	{
	FILETIME fileTime;
#ifdef __WINCE__
	SYSTEMTIME systemTime;
#endif /* __WINCE__ */

	assert( timePtr == NULL );

	/* Get the time via GetSystemTimeAsFileTime().  Windows CE doesn't have
	   the unified call so we have to assemble it from discrete calls */
#ifdef __WINCE__
	GetSystemTime( &systemTime );
	SystemTimeToFileTime( &systemTime, &fileTime );
#else
	GetSystemTimeAsFileTime( &fileTime );
#endif /* Win32 vs. WinCE */

	return( fileTimeToTimeT( &fileTime ) );
	}

time_t mktime( struct tm *tmStruct )
	{
	SYSTEMTIME systemTime;
	FILETIME fileTime;

	assert( isWritePtr( tmStruct, sizeof( struct tm ) ) );

	/* Use SystemTimeToFileTime() as a mktime() substitute.  The input time
	   seems to be treated as local time, so we have to convert it to GMT
	   before we return it */
	memset( &systemTime, 0, sizeof( SYSTEMTIME ) );
	systemTime.wYear = tmStruct->tm_year + 1900;
	systemTime.wMonth = tmStruct->tm_mon + 1;
	systemTime.wDay = tmStruct->tm_mday;
	systemTime.wHour = tmStruct->tm_hour;
	systemTime.wMinute = tmStruct->tm_min;
	systemTime.wSecond = tmStruct->tm_sec;
	SystemTimeToFileTime( &systemTime, &fileTime );
	LocalFileTimeToFileTime( &fileTime, &fileTime );

	return( fileTimeToTimeT( &fileTime ) );
	}

struct tm *gmtime( const time_t *timePtr )
	{
	static struct tm tmStruct;
	SYSTEMTIME systemTime;
	FILETIME fileTime;

	assert( isReadPtr( timePtr, sizeof( time_t ) ) );

	/* Use FileTimeToSystemTime() as a gmtime() substitute.  Note that this
	   function, like its original ANSI/ISO C counterpart, is not thread-
	   safe */
	timeTToFileTime( &fileTime, *timePtr );
	FileTimeToSystemTime( &fileTime, &systemTime );
	memset( &tmStruct, 0, sizeof( struct tm ) );
	tmStruct.tm_year = systemTime.wYear - 1900;
	tmStruct.tm_mon = systemTime.wMonth - 1;
	tmStruct.tm_mday = systemTime.wDay;
	tmStruct.tm_hour = systemTime.wHour;
	tmStruct.tm_min = systemTime.wMinute;
	tmStruct.tm_sec = systemTime.wSecond;

	return( &tmStruct );
	}

/* Windows CE systems need to convert characters from ASCII <-> Unicode
   before/after they're read/written to external formats, the following
   functions perform the necessary conversion.

   winnls.h was already included via the global include of windows.h, however
   it isn't needed for any other part of cryptlib so it was disabled via
   NONLS.  Since winnls.h is now locked out, we have to un-define the guards
   used earlier to get it included */

#undef _WINNLS_
#undef NONLS
#include <winnls.h>

int asciiToUnicode( wchar_t *dest, const int destMaxLen, 
					const char *src, const int length )
	{
	int status;

	assert( isReadPtr( src, length ) );
	assert( isWritePtr( dest, destMaxLen ) );

	status = MultiByteToWideChar( GetACP(), 0, src, destMaxLen, dest, 
								  length );
	return( status <= 0 ? CRYPT_ERROR_BADDATA : status * sizeof( wchar_t ) );
	}

int unicodeToAscii( char *dest, const int destMaxLen, 
					const wchar_t *src, const int length )
	{
	size_t destLen;
	int status;

	assert( isReadPtr( src, length ) );
	assert( isWritePtr( dest, destMaxLen ) );

	/* Convert the string, overriding the system default char '?', which
	   causes problems if the output is used as a filename.  This function
	   has stupid semantics in that instead of returning the number of bytes
	   written to the output it returns the number of bytes specified as
	   available in the output buffer, zero-filling the rest.  Because
	   there's no way to tell how long the resulting string actually is we
	   have to use wcstombs() instead, which is unfortunate because there's
	   nothing that we can do with the maxLength parameter */
#if 0
	status = WideCharToMultiByte( GetACP(), 0, src, length, dest,
								  length * sizeof( wchar_t ), "_", NULL );
	return( ( status <= 0 ) ? CRYPT_ERROR_BADDATA : wcslen( dest ) );
#else
	status = wcstombs_s( &destLen, dest, destMaxLen, src, 
						 length * sizeof( wchar_t ) );
	return( ( status <= 0 ) ? CRYPT_ERROR_BADDATA : status );
#endif
	}

BOOL WINAPI DllMain( HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved )
	{
	UNUSED_ARG( hinstDLL );
	UNUSED_ARG( lpvReserved );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -