📄 cryptlib.c
字号:
{
switch( fdwControl )
{
case SERVICE_CONTROL_STOP:
serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
case SERVICE_CONTROL_INTERROGATE:
; /* Fall through */
}
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 = cryptInitEx();
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 )
{
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 );
}
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 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 cryptInitEx() 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) */
cryptInitEx();
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 (ie 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
which 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;
DEFINE_LOCKING_VARS( initialisation )
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 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 library initialisation lock */
initGlobalResourceLock( initialisation );
break;
case DLL_PROCESS_DETACH:
/* Delete the library initialisation lock */
deleteGlobalResourceLock( initialisation );
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return( TRUE );
}
#endif /* __WIN16__ */
#endif /* __WINDOWS__ && !( NT_DRIVER || STATIC_LIB ) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -