// MemoryStatus.c : servei que mira cuanta memoria queda lliure. // To install this service on your operating system, // you'll need to use the SC.EXE executable, // which comes with the Win32 Platform SDK tools. // // Here is the command-line to install your MemoryStatus service: // // sc create MemoryStatus binpath= c:\MyServices\MemoryStatus.exe // // To remove the service from the system, execute the following command: // // sc delete MemoryStatus // // Autor : jeka_books@hotmail.com. // // URL : http://www.devx.com/cplus/Article/9857/0/page/1 // // **************************************************************************** // calen funcions Win32 : #include // per escriure a disc. #include // periode entre 2 queries : #define SLEEP_TIME 5000 // path to log file : #define LOGFILE "C:\\MyServices\\memstatus.txt" // **************************************************************************** // Global vars : SERVICE_STATUS ServiceStatus ; SERVICE_STATUS_HANDLE hStatus ; // Forward declarations : void ServiceMain ( int argc, char ** argv ) ; void ControlHandler ( DWORD request ) ; int InitService ( ) ; // **************************************************************************** // Define the main function, which is the entry point to the program. // In case of services, the code for main will be surprisingly short, // since it just creates the dispatch table and starts the control dispatcher void main () { SERVICE_TABLE_ENTRY ServiceTable [ 2 ] ; ServiceTable [0].lpServiceName = "MemoryStatus" ; ServiceTable [0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION) ServiceMain ; ServiceTable [1].lpServiceName = NULL ; ServiceTable [1].lpServiceProc = NULL ; // Start the control dispatcher thread for our service StartServiceCtrlDispatcher ( ServiceTable ) ; } ; // **************************************************************************** int WriteToLog ( char * str ) { FILE * log ; log = fopen ( LOGFILE, "a+" ) ; if ( log == NULL ) return -1 ; fprintf ( log, "%s\n", str ) ; fclose ( log ) ; return 0 ; } ; // WriteToLog // **************************************************************************** // Service initialization int InitService ( ) { int result; result = WriteToLog ( "Monitoring started." ) ; return ( result ) ; } ; // InitService // **************************************************************************** void ControlHandler ( DWORD request ) { switch ( request ) { case SERVICE_CONTROL_STOP: WriteToLog ("Monitoring stopped." ) ; ServiceStatus.dwWin32ExitCode = 0 ; ServiceStatus.dwCurrentState = SERVICE_STOPPED ; SetServiceStatus ( hStatus, & ServiceStatus ) ; return; case SERVICE_CONTROL_SHUTDOWN: WriteToLog ("Monitoring stopped." ) ; ServiceStatus.dwWin32ExitCode = 0 ; ServiceStatus.dwCurrentState = SERVICE_STOPPED ; SetServiceStatus ( hStatus, & ServiceStatus) ; return; default: break ; } ; // switch // Report current status SetServiceStatus ( hStatus, & ServiceStatus ) ; return ; } ; // ControlHandler // **************************************************************************** // Initialize the ServiceStatus structure // specifying the service characteristics and its current state. // Each ServiceStatus structure fields has a purpose: // // * dwServiceType: indicates the type of service. // Author Win32 service; assign the SERVICE_WIN32 value. // // * dwCurrentState: specifies the current state of the service. // Since initialization of a service has not been finished at this point, // set the SERVICE_START_PENDING status. // // * dwControlsAccepted: this field will inform the SCM // which fields the service accepts. // In this case, allow STOP and SHUTDOWN requests. // Handling control requests is discussed in Step 3. // // * dwWin32ExitCode and dwServiceSpecificExitCode: these fields // are useful when you are terminating the service // and want to report the detailed exit code. // Since, you will initialize the service and will not exit, assign 0 values. // // * dwCheckPoint and dwWaitHint: these fields indicate the progress // of a service when it performs an initialization longer than 30 seconds . // This service has a very short initialization procedure, // so assign 0 values to both fields. void ServiceMain ( int argc, char ** argv ) { int error ; MEMORYSTATUS memory ; int result ; ServiceStatus.dwServiceType = SERVICE_WIN32 ; ServiceStatus.dwCurrentState = SERVICE_START_PENDING ; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ; ServiceStatus.dwWin32ExitCode = 0 ; ServiceStatus.dwServiceSpecificExitCode = 0 ; ServiceStatus.dwCheckPoint = 0 ; ServiceStatus.dwWaitHint = 0 ; hStatus = RegisterServiceCtrlHandler ( "MemoryStatus", (LPHANDLER_FUNCTION) ControlHandler ) ; if ( hStatus == (SERVICE_STATUS_HANDLE) 0 ) { // Registering Control Handler failed return ; } // Initialize Service error = InitService () ; if ( error ) { // Initialization failed ServiceStatus.dwCurrentState = SERVICE_STOPPED ; ServiceStatus.dwWin32ExitCode = -1 ; SetServiceStatus ( hStatus, & ServiceStatus ) ; return ; } // We report the running status to SCM. ServiceStatus.dwCurrentState = SERVICE_RUNNING ; SetServiceStatus ( hStatus, & ServiceStatus ) ; // The worker loop of a service while ( ServiceStatus.dwCurrentState == SERVICE_RUNNING ) { char buffer [ 16 ] ; GlobalMemoryStatus ( & memory ) ; sprintf ( buffer, "%d", memory.dwAvailPhys ) ; result = WriteToLog ( buffer ) ; if ( result ) { ServiceStatus.dwCurrentState = SERVICE_STOPPED ; ServiceStatus.dwWin32ExitCode = -1 ; SetServiceStatus ( hStatus, & ServiceStatus ) ; return; } Sleep ( SLEEP_TIME ) ; } return ; } ; // ServiceMain // ****************************************************************************