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

📄 cryptlib.c

📁 老外写的加密库cryptlib(版本3.1)
💻 C
📖 第 1 页 / 共 4 页
字号:
	SetServiceStatus( hServiceStatus, &serviceStatus );
	}

/* Service-specific and generic main functions */

void WINAPI ServiceMain( DWORD dwArgc, LPTSTR *lpszArgv )
	{
	static const SERVICE_STATUS serviceStatusTemplate = {
		SERVICE_WIN32_OWN_PROCESS, SERVICE_START_PENDING,
		SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, 0, 0, 0, 0
		};
	int status;

	/* Register the service control handler and tell the SCM what we're
	   doing */
	if( ( hServiceStatus = RegisterServiceCtrlHandler( SERVICE_NAME,
													   Handler ) ) == 0 )
		return;
	serviceStatus = serviceStatusTemplate;
	SetServiceStatus( hServiceStatus, &serviceStatus );

	/* Initialise cryptlib */
	status = cryptInit();
	if( cryptStatusError( status ) )
		{
		serviceStatus.dwCurrentState = SERVICE_STOPPED;
		serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
		serviceStatus.dwServiceSpecificExitCode = status;
		SetServiceStatus( hServiceStatus, &serviceStatus );
		return;
		}
	serviceStatus.dwCurrentState = SERVICE_RUNNING;
	SetServiceStatus( hServiceStatus, &serviceStatus );
	}

int main( int argc, char *argv[] )
	{
	static const SERVICE_TABLE_ENTRY serviceTable[] = {
		{ TEXT( SERVICE_NAME ), ServiceMain }, { NULL, NULL } };

	if( argc > 2 )
		{
		puts( "Usage: " SERVICE_NAME " <install> <remove>" );
		exit( EXIT_FAILURE );
		}
	if( argc == 2 )
		{
		/* Handle service installation */
		if( !stricmp( argv[ 1 ], "install" ) )
			{
			SC_HANDLE schSCM, schService;

			/* Try and install the service */
			schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE );
			if( schSCM == NULL )
				{
				perror( SERVICE_NAME );
				exit( EXIT_FAILURE );
				}
			schService = CreateService( schSCM, TEXT( SERVICE_NAME ),
							TEXT( SERVICE_DISPLAY_NAME ), SERVICE_ALL_ACCESS,
#if 0	/* For debugging we make it demand-start */
							SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
#else
							SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
#endif /* 0 */
							SERVICE_ERROR_NORMAL, SERVICE_PATH, NULL, NULL,
							NULL, NULL, NULL );
			if( schService == NULL )
				{
				CloseServiceHandle( schSCM );
				if( GetLastError() == ERROR_SERVICE_EXISTS )
					puts( "The service is already installed.  To reinstall, "
						  "stop the service with\n'net stop " SERVICE_NAME "', "
						  "remove the current service with\n'" SERVICE_NAME " "
						  "remove', and rerun the install." );
				else
					perror( SERVICE_NAME );
				exit( EXIT_FAILURE );
				}
			CloseServiceHandle( schService );
			CloseServiceHandle( schSCM );

			puts( SERVICE_NAME " service successfully installed." );
			exit( EXIT_SUCCESS );
			}

		/* Handle service removal */
		if( !stricmp( argv[ 1 ], "remove" ) )
			{
			SC_HANDLE schSCM, schService;
			SERVICE_STATUS removeServiceStatus;

			/* Open the service */
			schSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
			if( schSCM == NULL )
				{
				perror( SERVICE_NAME );
				exit( EXIT_FAILURE );
				}
			schService = OpenService( schSCM, SERVICE_NAME, DELETE );
			if( schService == NULL )
				{
				CloseServiceHandle( schSCM );
				perror( SERVICE_NAME );
				exit( EXIT_FAILURE );
				}

			/* If the service is currently running, stop it before we try to
			   remove it.  Note that we use ControlService() to determine its
			   status rather than QueryServiceStatus() since the former
			   returns the actual state while the latter only returns the
			   state last reported to the SCM, which means the service could
			   already be stopped without the SCM realising it (probably one
			   of the reasons why it seems to take ages to stop even the
			   simplest service) */
			ControlService( schService, SERVICE_CONTROL_INTERROGATE,
							&removeServiceStatus );
			if( removeServiceStatus.dwCurrentState != SERVICE_STOPPED )
				{
				int timeout = 30;

				printf( "Stopping " SERVICE_DISPLAY_NAME );
				ControlService( schService, SERVICE_CONTROL_STOP,
								&removeServiceStatus );
				do
					{
					putchar( '.' );
					Sleep( 1000 );
					ControlService( schService, SERVICE_CONTROL_INTERROGATE,
									&removeServiceStatus );
					}
				while( ( removeServiceStatus.dwCurrentState == \
												SERVICE_STOP_PENDING ) && \
					   timeout-- > 0 );
				}
			if( removeServiceStatus.dwCurrentState != SERVICE_STOPPED )
				{
				puts( "Couldn't stop " SERVICE_DISPLAY_NAME "." );
				CloseServiceHandle( schSCM );
				exit( EXIT_FAILURE );
				}

			/* The service is stopped, remove it */
			DeleteService( schService );
			CloseServiceHandle( schService );
			CloseServiceHandle( schSCM );

			puts( SERVICE_NAME " service successfully removed." );
			exit( EXIT_SUCCESS );
			}

		printf( "Unknown argument '%s'.\n", argv[ 1 ] );
		exit( EXIT_FAILURE );
		}

	/* Pass control on to the service's main().  Since this is a
	   SERVICE_WIN32_OWN_PROCESS, we don't have to specify a name for it or
	   worry about much else */
	StartServiceCtrlDispatcher( serviceTable );
	}

#elif defined( __IBM4758__ )

#include <scc_err.h>
#include <scc_int.h>

void main( void )	/* Because the docs say so, that's why */
	{
	const static sccAgentID_t agentID = { "\x06\x00", "cryptlib\x00\x00\x00", 0x21, 0x00, 0x00 };
	sccRequestHeader_t request;
	long status;
	int initStatus;

	/* Register ourselves with the SCC manager */
	status = sccSignOn( ( sccAgentID_t * ) &agentID, NULL );
	if( status != PPDGood )
		exit( status );

	/* If we're running in debug mode, we have to make sure that we don't 
	   start running before the debugger can attach to the process.  The 
	   following infinite loop just yields our timeslice back to the OS, to 
	   move past it set a breakpoint on the i++ and then use 'Jump to 
	   location' to break out of the loop */
#ifdef _DEBUG
	{
	long i = 0, j = 1;

	while( j )
		{
		CPYield();
		i++; if( !i ) j++;	/* Confound the optimiser */
		}
	}
#endif /* _DEBUG */

	/* Initialise cryptlib.  Normally this is done in response to a user
	   request, however we can do it when the device is started so that
	   everything's ready when the user needs it.  In the spirit of FIPS 140,
	   we call cryptInit() rather than plain cryptInit() (this isn't that bad 
	   since many capabilities aren't present, all the slow stuff is being 
	   done in hardware, and the device isn't restarted that often anyway) */
	cryptInit();

	while( TRUE )
		{
		/* Wait for a request from the host system */
		status = sccGetNextHeader( &request, 0, SVCWAITFOREVER );
		if( status != PPDGood )
			break;

		/* Dispatch the message.  This just calls the built-in command
		   dispatcher with the request type (i.e.the cryptlib function being
		   called) and a reference to the data source.  Once the request has
		   been handled, the status value is passed back to the caller */
		status = dispatchRequest( request.UserDefined, request.RequestID );
		sccEndRequest( request.RequestID, 0, NULL, 0, status );
		}

	/* Clean up */
	cryptEnd();
	exit( PPDGood );
	}
#endif /* Client-server server-side code */

#endif /* USE_CLIENT_SERVER */

/****************************************************************************
*																			*
*						OS-Specific Support Routines						*
*																			*
****************************************************************************/

#if defined( __WINDOWS__ ) && !( defined( NT_DRIVER ) || defined( STATIC_LIB ) )

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

#ifdef __WIN16__

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 );
	}

#else

BOOLEAN isWin95;

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
	{
	void preInit( void );
	void postShutdown( void );
	static DWORD dwPlatform = ( DWORD ) CRYPT_ERROR;

	UNUSED( hinstDLL );
	UNUSED( lpvReserved );

	switch( fdwReason )
		{
		case DLL_PROCESS_ATTACH:
			/* Figure out which OS 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 tries to load the
				   DLL 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 );
	}

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

#pragma comment( linker, "/export:DllRegisterServer=_DllRegisterServer@0,PRIVATE" )

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 /* Win16 */
#endif /* Windows DLL */

⌨️ 快捷键说明

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