📄 cryptlib.c
字号:
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 + -