i'm trying to write a service for NT which will start explorer.exe but i can't get the service to start
i've read through several sources from services, but i still can't figure out what i'm doing wrong .....
any ideas?:
.686
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib
ServiceControlHandler PROTO :DWORD
MyFunction PROTO
ServiceMain PROTO
.DATA
explorer db "explorer",0
backslash db "\",0
AppName db "Test",0
.DATA?
startinfo STARTUPINFO <>
secat SECURITY_ATTRIBUTES <>
procinfo PROCESS_INFORMATION <>
ServStat SERVICE_STATUS <>
ServTable SERVICE_TABLE_ENTRY <>
hServStat DWORD ?
stopServiceEvent DWORD ?
explorerbuf db 512 dup (?)
.CODE
start:
mov ServTable.lpServiceName,offset AppName
mov ServTable.lpServiceProc,offset ServiceMain
invoke StartServiceCtrlDispatcher,addr ServTable
.IF eax==NULL
invoke GetLastError
.IF eax==ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
invoke MyFunction
.ENDIF
.ELSE
invoke ServiceMain
.ENDIF
invoke ExitProcess,0
ServiceMain PROC
mov ServStat.dwServiceType,SERVICE_WIN32
mov ServStat.dwCurrentState,SERVICE_STOPPED
mov ServStat.dwControlsAccepted,0
mov ServStat.dwWin32ExitCode,NO_ERROR
mov ServStat.dwServiceSpecificExitCode,NO_ERROR
mov ServStat.dwCheckPoint,0
mov ServStat.dwWaitHint,0
invoke RegisterServiceCtrlHandler,addr AppName,addr ServiceControlHandler
mov hServStat,eax
.IF eax!=NULL
mov ServStat.dwCurrentState,SERVICE_START_PENDING
invoke SetServiceStatus,hServStat,addr ServStat
invoke CreateEvent,0,FALSE,FALSE,0
mov stopServiceEvent,eax
mov ServStat.dwControlsAccepted,SERVICE_ACCEPT_STOP+SERVICE_ACCEPT_SHUTDOWN
mov ServStat.dwCurrentState,SERVICE_RUNNING
invoke SetServiceStatus,hServStat,addr ServStat
invoke MyFunction
mov ServStat.dwCurrentState,SERVICE_STOP_PENDING
invoke SetServiceStatus,hServStat,addr ServStat
invoke CloseHandle,stopServiceEvent
mov stopServiceEvent,0
mov ServStat.dwControlsAccepted,SERVICE_ACCEPT_STOP+SERVICE_ACCEPT_SHUTDOWN
mov ServStat.dwCurrentState,SERVICE_STOPPED
invoke SetServiceStatus,hServStat,addr ServStat
.ENDIF
ret
ServiceMain ENDP
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;The procedure to handle the service controls
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ServiceControlHandler PROC controlcode:DWORD
.IF controlcode==SERVICE_CONTROL_INTERROGATE
jmp next
.ELSEIF controlcode==SERVICE_CONTROL_SHUTDOWN || controlcode==SERVICE_CONTROL_STOP
mov ServStat.dwCurrentState,SERVICE_STOP_PENDING
invoke SetServiceStatus,addr hServStat,addr ServStat
invoke SetEvent,addr stopServiceEvent
ret
.ELSEIF controlcode==SERVICE_CONTROL_PAUSE
jmp next
.ELSEIF controlcode==SERVICE_CONTROL_CONTINUE
jmp next
.ENDIF
next:
invoke SetServiceStatus,hServStat,addr ServStat
ret
ServiceControlHandler ENDP
;-----------------------------------------------------
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;My function
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MyFunction PROC
invoke GetWindowsDirectory,addr explorerbuf,sizeof explorerbuf
invoke lstrcat,addr explorerbuf,addr backslash
invoke lstrcat,addr explorerbuf,addr explorer
mov secat.nLength,sizeof SECURITY_ATTRIBUTES
mov secat.bInheritHandle,TRUE
invoke GetStartupInfo,addr startinfo
mov startinfo.dwFlags,STARTF_USESHOWWINDOW
invoke CreateProcess,NULL,addr explorerbuf,NULL,NULL,TRUE,\
CREATE_NEW_CONSOLE,NULL,NULL,addr startinfo,addr procinfo
invoke Sleep,500
ret
MyFunction ENDP
;-----------------------------------------------------
end start
