RegisterServiceCtrlHandler reports error
BlitzMax Forums/BlitzMax Programming/RegisterServiceCtrlHandler reports error
| ||
I don't like to give up about the BM Service ... But I'm not able to register the Ctrl Handler. Maybe somebody have an idea - or is there something wrong pointing to the functions? SuperStrict Import "-ladvapi32" 'API Constants Const SERVICES_ACTIVE_DATABASE:String = "ServicesActive" ' Service Control Const SERVICE_CONTROL_STOP:Int = $1 Const SERVICE_CONTROL_PAUSE:Int = $2 ' Service State - for CurrentState Const SERVICE_STOPPED:Int = $1 Const SERVICE_START_PENDING:Int = $2 Const SERVICE_STOP_PENDING:Int = $3 Const SERVICE_RUNNING:Int = $4 Const SERVICE_CONTINUE_PENDING:Int = $5 Const SERVICE_PAUSE_PENDING:Int = $6 Const SERVICE_PAUSED:Int = $7 Const SERVICE_ACCEPT_STOP:Int = $1 Const SERVICE_ACCEPT_PAUSE_CONTINUE:Int = $2 Const SERVICE_ACCEPT_SHUTDOWN:Int = $4 'Service Control Manager object specific access types Const STANDARD_RIGHTS_REQUIRED:Int = $F0000 Const SC_MANAGER_CONNECT:Int = $1 Const SC_MANAGER_CREATE_SERVICE:Int = $2 Const SC_MANAGER_ENUMERATE_SERVICE:Int = $4 Const SC_MANAGER_LOCK:Int = $8 Const SC_MANAGER_QUERY_LOCK_STATUS:Int = $10 Const SC_MANAGER_MODIFY_BOOT_CONFIG:Int = $20 Const SC_MANAGER_ALL_ACCESS:Int = $F003F 'STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_LOCK or SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG 'Service object specific access types Const SERVICE_QUERY_CONFIG:Int = $1 Const SERVICE_CHANGE_CONFIG:Int = $2 Const SERVICE_QUERY_STATUS:Int = $4 Const SERVICE_ENUMERATE_DEPENDENTS:Int = $8 Const SERVICE_START:Int = $10 Const SERVICE_STOP:Int = $20 Const SERVICE_PAUSE_CONTINUE:Int = $40 Const SERVICE_INTERROGATE:Int = $80 Const SERVICE_USER_DEFINED_CONTROL:Int = $100 Const SERVICE_ALL_ACCESS:Int = $1FF 'STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL ' Service Install - Types Const SERVICE_WIN32_OWN_PROCESS:Int = $10 Const SERVICE_ERROR_NORMAL:Int = $1 Const SERVICE_AUTO_START:Int = $2 Const SERVICE_DEMAND_START:Int = $3 ' Service Types Const SERVICE_WIN32_SHARE_PROCESS:Int = $20 Const SERVICE_WIN32:Int = $30 Type SERVICE_STATUS Field dwServiceType:Int Field dwCurrentState:Int Field dwControlsAccepted:Int Field dwWin32ExitCode:Int Field dwServiceSpecificExitCode:Int Field dwCheckPoint:Int Field dwWaitHint:Int End Type Type SERVICE_TABLE_ENTRY Field lpServiceName:String Field lpServiceProc:Byte ptr End Type Extern "Win32" Function CloseServiceHandle:Int (hSCObject:Int) = "CloseServiceHandle@4" Function ControlService:Int (hService:Int, dwControl:Int, lpServiceStatus:Byte ptr) = "ControlService@12" Function OpenSCManager:Int (lpMachineName:Byte Ptr, lpDatabaseName:Byte Ptr, dwDesiredAccess:Int) = "OpenSCManagerA@12" Function OpenService:Int (hSCManager:Int, lpServiceName:Byte Ptr, dwDesiredAccess:Int) = "OpenServiceA@12" Function QueryServiceStatus (hService:Int, lpServiceStatus:Byte ptr) = "QueryServiceStatus@8" Function StartService:Int (hService:Int, dwNumServiceArgs:Int, lpServiceArgVectors:Int) = "StartServiceA@12" Function CreateService:Int (hSCManager:Int, lpServiceName:Byte ptr, lpDisplayName:Byte ptr, dwDesiredAccess:Int, dwServiceType:Int, dwStartType:Int, dwErrorControl:Int, lpBinaryPathName:Byte ptr, lpLoadOrderGroup:Byte ptr, lpdwTagID:Int, lpDependencies:Byte ptr, lp:Byte ptr, lpPassword:Byte ptr) = "CreateServiceA@52" Function StartServiceCtrlDispatcher:Int (lpServiceStartTable:Byte ptr) = "StartServiceCtrlDispatcherA@4" Function RegisterServiceCtrlHandler:Int(lpServiceName:Byte ptr, lpHandlerProc:Byte ptr) = "RegisterServiceCtrlHandlerA@8" Function SetServiceStatus:Int(hService:Int, lpHandlerProc:Byte ptr) = "SetServiceStatus@8" Function GetLastError() End Extern Function ServiceCreate:Int(ServiceName:String) Local hSManager:Int = OpenSCManager(Null, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS) Local res:Int If hSManager <> 0 Local schService:Int = CreateService(hSManager, ServiceName, ServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, AppFile, Null, Null, Null, Null, Null) If schService <> 0 CloseServiceHandle schService Endif CloseServiceHandle hSManager EndIf Return res End Function ServiceCreate "TestService" Local svc:SERVICE_TABLE_ENTRY = New SERVICE_TABLE_ENTRY svc.lpServiceName = "MyProc" svc.lpServiceProc = Byte ptr(SvcMain()) DebugLog("Register Handler") Local success:Int = StartServiceCtrlDispatcher(svc) DebugLog("Success: " + success) Function SvcMain (argc:Int = Null, argv:String = "") Local svchandle:Int = RegisterServiceCtrlHandler("TestService", Byte ptr(svcCtrlHandler())) DebugLog("svchandle: " + svchandle) If svchandle = 0 Then DebugLog("Ctrl Service Handle could not be registered. Error: " + GetLastError()) End If End Function Function svcCtrlHandler(dwOpcode:Int = Null) DebugLog("svcCtrl") End Function Thanks, Andre |
| ||
Maybe somebody could find a solution checking the C Source I like to translate to BM. Please have a look: /* A skeleton for writing an NT/2K service */ /* Author :- Nishant S */ /* EMail :- nish@... */ #include <windows.h> #include <winsvc.h> void ServiceMain(DWORD argc, LPTSTR *argv); void ServiceCtrlHandler(DWORD nControlCode); BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint); BOOL StartServiceThread(); DWORD ServiceExecutionThread(LPDWORD param); HANDLE hServiceThread; void KillService(); char *strServiceName = "NishFirstService"; SERVICE_STATUS_HANDLE nServiceStatusHandle; HANDLE killServiceEvent; BOOL nServiceRunning; DWORD nServiceCurrentStatus; void main(int argc, char* argv[]) { SERVICE_TABLE_ENTRY servicetable[]= { {strServiceName,(LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL,NULL} }; BOOL success; success=StartServiceCtrlDispatcher(servicetable); if(!success) { //error occured } } void ServiceMain(DWORD argc, LPTSTR *argv) { BOOL success; nServiceStatusHandle=RegisterServiceCtrlHandler(strServiceName, (LPHANDLER_FUNCTION)ServiceCtrlHandler); if(!nServiceStatusHandle) { return; } success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000); if(!success) { return; } killServiceEvent=CreateEvent(0,TRUE,FALSE,0); if(killServiceEvent==NULL) { return; } success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000); if(!success) { return; } success=StartServiceThread(); if(!success) { return; } nServiceCurrentStatus=SERVICE_RUNNING; success=UpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0); if(!success) { return; } WaitForSingleObject(killServiceEvent,INFINITE); CloseHandle(killServiceEvent); } BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) { BOOL success; SERVICE_STATUS nServiceStatus; nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS; nServiceStatus.dwCurrentState=dwCurrentState; if(dwCurrentState==SERVICE_START_PENDING) { nServiceStatus.dwControlsAccepted=0; } else { nServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP |SERVICE_ACCEPT_SHUTDOWN; } if(dwServiceSpecificExitCode==0) { nServiceStatus.dwWin32ExitCode=dwWin32ExitCode; } else { nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR; } nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode; nServiceStatus.dwCheckPoint=dwCheckPoint; nServiceStatus.dwWaitHint=dwWaitHint; success=SetServiceStatus(nServiceStatusHandle,&nServiceStatus); if(!success) { KillService(); return success; } else return success; } BOOL StartServiceThread() { DWORD id; hServiceThread=CreateThread(0,0, (LPTHREAD_START_ROUTINE)ServiceExecutionThread, 0,0,&id); if(hServiceThread==0) { return false; } else { nServiceRunning=true; return true; } } DWORD ServiceExecutionThread(LPDWORD param) { while(nServiceRunning) { Beep(450,150); Sleep(4000); } return 0; } void KillService() { nServiceRunning=false; SetEvent(killServiceEvent); UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0); } void ServiceCtrlHandler(DWORD nControlCode) { BOOL success; switch(nControlCode) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: nServiceCurrentStatus=SERVICE_STOP_PENDING; success=UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000); KillService(); return; default: break; } UpdateServiceStatus(nServiceCurrentStatus,NO_ERROR,0,0,0); } |