Page 1 of 1

Win_Services.pbi [Win only]

Posted: Thu Feb 14, 2013 8:06 pm
by HeX0R
This Include is based on Rings' PBOSL_NTService and will help you starting (and managing) your applications as service.
An example is on the second post.

Thanks to Danilo for opening my eyes with the Grant_Access-Procedure.

Remember not to use APPDATA, when storing your preferences, as this doesn't exist for a service.
Better use COMMON_APPDATA

Have fun!

Go here for the >=PB5.20 module-powered version.

Code: Select all

; ==============================================================
; COMPILER OPTIONS:
;  [ ] Enable inline ASM support
;  [ ] Create unicode executable
;  [ ] Create threadsafe executable
;  [ ] Enable OnError lines support
;  [x] Enable XP skin support
;  [ ] Request Administrator mode for Windows Vista
;  [x] Request User mode for Windows Vista (no virtualization)
; Library Subsystem:
; File Format:        UTF-8
; Executable Format:  Windows
;
; Created on:         28/01/2013 23:07
; App/Lib-Name:       Win_Services.pbi
; Author:             HeX0R
; Version:            1.00
; Compiler:           PureBasic 5.10 Beta 5 (Windows - x86)
; ==============================================================
;
; This little include is a rewrite of Rings' PBOSL_NTService
; You can give your app the possibility to work as service.
; You also can start/stop/pause/resume/install/uninstall services
;

CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
   Macro StructureAlign : EndMacro
CompilerElse
   Macro StructureAlign : Align 8 : EndMacro
CompilerEndIf

Prototype __Service_Notify_Procedure__(ServiceStateChanged.i)
Declare __Service_CtrlHandler(controlCode.l)

#DACL_SECURITY_INFORMATION = $04
#NO_INHERITANCE            = $00
#SE_SERVICE                = $02
#SET_ACCESS                = $02

Structure _TRUSTEE StructureAlign
	*pMultipleTrustee
	MultipleTrusteeOperation.l
	TrusteeForm.l
	TrusteeType.l
	*ptstrName
EndStructure

Structure EXPLICIT_ACCESS StructureAlign
	grfAccessPermissions.l
	grfAccessMode.l
	grfInheritance.l
	Trustee._TRUSTEE
EndStructure

Structure __Service_Main_Structure_
	VTable.i
EndStructure

Structure __Service_GlobalVars__
	ServiceName.s
	hStatus.i
	Semaphore.i
	ThreadID.i
	ThreadID2.i
	*MainProc
	NotifyProc.__Service_Notify_Procedure__
EndStructure

Global __ServiceGlobals__.__Service_GlobalVars__

;----- Interface

Interface __Service_Interface_
	;Procedures to interact with services
	StartService(ServiceName.s)
	StopService(ServiceName.s)
	PauseService(ServiceName.s)
	ResumeService(ServiceName.s)
	;Procedures to create/remove services
	InstallService(ServiceName.s, DisplayName.s, FileName.s, Description.s = "", StartParameter = #SERVICE_AUTO_START)
	RemoveService(ServiceName.s)
	StartRunning(ServiceName.s, *MainProcedure, *NotifyProcedure = #Null)
	;Procedure to quick-check state of services
	GetServiceState(ServiceName.s)
	;Procedure to sllow User to Start/Stop/Pause/Resume Service
	GrantAccess(ServiceName.s, UserName.s, Rights.i = #SERVICE_START | #SERVICE_STOP | #SERVICE_PAUSE_CONTINUE)
EndInterface

;----- Internal Procedures

Procedure __Service_Internal_DoService(*THIS.__Service_Main_Structure_, ServiceName.s, DoWhat.i)
	Protected sStatus.SERVICE_STATUS
	Protected Result, schSCManager, schService

	;Internal procedure to change the status of a service.

	schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CONNECT)
	If schSCManager
		schService = OpenService_(schSCManager, @ServiceName, #GENERIC_EXECUTE)
		If schService
			If DoWhat <> 0
				Result = ControlService_(schService, DoWhat, sStatus)
			Else
				Result = StartService_(schService, 0, 0)
			EndIf
			CloseServiceHandle_(schService)
		EndIf
		CloseServiceHandle_(schSCManager)
	EndIf
	ProcedureReturn Result
EndProcedure

Procedure __Service_Internal_SendStatus(dwCurrentState, dwWin32ExitCode, dwServiceSpecificExitCode, dwCheckPoint, dwWaitHint)
	Protected sStatus.SERVICE_STATUS

	;Internal procedure to set the SERVICE_STATUS-structure of a Service.

	sStatus\dwServiceType  = #SERVICE_WIN32_OWN_PROCESS
	sStatus\dwCurrentState = dwCurrentState
	If dwCurrentState = #SERVICE_START_PENDING
		sStatus\dwControlsAccepted = 0
	Else
		sStatus\dwControlsAccepted = #SERVICE_ACCEPT_STOP | #SERVICE_ACCEPT_PAUSE_CONTINUE | #SERVICE_ACCEPT_SHUTDOWN
	EndIf
	;
	If dwServiceSpecificExitCode = 0
		sStatus\dwWin32ExitCode = dwWin32ExitCode
	Else
		sStatus\dwWin32ExitCode = #ERROR_SERVICE_SPECIFIC_ERROR
	EndIf

	sStatus\dwServiceSpecificExitCode  = dwServiceSpecificExitCode
	sStatus\dwCheckPoint               = dwCheckPoint
	sStatus\dwWaitHint                 = dwWaitHint

	;Pass the status record to the SCM
	SetServiceStatus_(__ServiceGlobals__\hStatus, sStatus)
EndProcedure

Procedure __Service_Internal_Main(argc.l, *argv)
	Protected dwNull

	;Internal Procedure to start the service and initialize the main procedure.

	With __ServiceGlobals__
		;immediately call Registration function
		\hStatus = RegisterServiceCtrlHandler_(@\ServiceName, @__Service_CtrlHandler())
		If \hStatus
			;Notify SCM of progress
			__Service_Internal_SendStatus(#SERVICE_START_PENDING, #NO_ERROR, 0, 1, 5000)

			;create the termination semaphore
			\Semaphore = CreateSemaphore()
			If \Semaphore
				;Notify SCM of progress
				__Service_Internal_SendStatus(#SERVICE_START_PENDING, #NO_ERROR, 0, 2, 1000)
				;Notify SCM of progress
				__Service_Internal_SendStatus(#SERVICE_START_PENDING, #NO_ERROR, 0, 3, 5000)
				;Start the service itself
				\ThreadID = CreateThread(\MainProc, #True)
				;\ThreadID = CreateThread(@__Service_Internal_DummyThread(), #True)
				If \ThreadID
					;Notify SCM of progress
					__Service_Internal_SendStatus(#SERVICE_RUNNING, #NO_ERROR, 0, 0, 0)
					;Wait for stop signal, and then terminate
					WaitSemaphore(\Semaphore)
					If IsThread(\ThreadID) And WaitThread(\ThreadID, 1000) = 0
						KillThread(\ThreadID)
					EndIf
					\ThreadID = 0
				EndIf
				FreeSemaphore(\Semaphore)
				\Semaphore = 0
			EndIf
			__Service_Internal_SendStatus(#SERVICE_STOPPED, #NO_ERROR, 0, 0, 0)
			\hStatus = #Null
		EndIf
	EndWith

EndProcedure

;----- Public Procedures

Procedure __Service_Grant_Access(*THIS.__Service_Main_Structure_, ServiceName.s, UserName.s, Rights.i)
	Protected *psd.SECURITY_DESCRIPTOR, *pacl, *pNewAcl
	Protected ea.EXPLICIT_ACCESS, Result

	;Procedure to grant a user access to pause/resume/start/stop the service.
	;(normaly not needed for WinXP)

	If GetNamedSecurityInfo_(ServiceName, #SE_SERVICE, #DACL_SECURITY_INFORMATION, #Null, #Null, @*pacl, 0, @*psd) = #ERROR_SUCCESS
		BuildExplicitAccessWithName_(@ea, @UserName, Rights, #SET_ACCESS, #NO_INHERITANCE)
		If SetEntriesInAcl_(1, @ea, *pacl, @*pNewAcl) = #ERROR_SUCCESS
			If SetNamedSecurityInfo_(ServiceName, #SE_SERVICE, #DACL_SECURITY_INFORMATION, #Null, #Null, *pNewAcl, 0) = #ERROR_SUCCESS
				Result = #True
			EndIf
		EndIf
	EndIf

	If *psd
		LocalFree_(*psd)
	EndIf
	If *pNewAcl
		LocalFree_(*pNewAcl)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure __Service_StartService(*THIS.__Service_Main_Structure_, ServiceName.s) ;Start the service ServiceName

	ProcedureReturn __Service_Internal_DoService(*THIS, ServiceName.s, 0)
EndProcedure

Procedure __Service_StopService(*THIS.__Service_Main_Structure_, ServiceName.s) ;Stop the Service ServiceName

	ProcedureReturn __Service_Internal_DoService(*THIS, ServiceName.s, #SERVICE_CONTROL_STOP)
EndProcedure

Procedure __Service_ResumeService(*THIS.__Service_Main_Structure_, ServiceName.s) ;Resume the Service ServiceName

	ProcedureReturn __Service_Internal_DoService(*THIS, ServiceName.s, #SERVICE_CONTROL_CONTINUE)
EndProcedure

Procedure __Service_PauseService(*THIS.__Service_Main_Structure_, ServiceName.s) ;Pause the Service ServiceName

	ProcedureReturn __Service_Internal_DoService(*THIS, ServiceName.s, #SERVICE_CONTROL_PAUSE)
EndProcedure

Procedure __Service_RemoveService(*THIS.__Service_Main_Structure_, ServiceName.s) ;Remove the service ServiceName
	Protected sStatus.SERVICE_STATUS
	Protected Result, schSCManager, schService

	schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_ALL_ACCESS)
	If schSCManager
		schService = OpenService_(schSCManager, @ServiceName, #SERVICE_ALL_ACCESS)
		If schService
			If ControlService_(schService, #SERVICE_CONTROL_STOP, sStatus) = 0
				Result = DeleteService_(schService)
			Else
				;Loop until its stopped, then delete it. It only deletes the SCM entry, not the executable.
				Repeat
					If QueryServiceStatus_(schService, sStatus ) = 0
						Break
					EndIf

					If sStatus\dwCurrentState = #SERVICE_STOPPED
						Result = DeleteService_(schService)
						Break
					EndIf
				ForEver
			EndIf
			CloseServiceHandle_(schService)
		EndIf
		CloseServiceHandle_(schSCManager)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure __Service_CtrlHandler(controlCode.l)
	Protected currentState, success, nopThread

	;Controlhandler, which gets called, whenever a service state has been changed.
	;If an optional notify-procedure has been set, it will also be called

	With __ServiceGlobals__
		Select controlCode
			Case #SERVICE_CONTROL_STOP
				currentState  = #SERVICE_STOP_PENDING
				;Tell the SCM what's happening
				__Service_Internal_SendStatus(#SERVICE_STOP_PENDING, #NO_ERROR, 0, 1, 5000)
				; Changed on 27.09.2005 by Peter Tübben (aka Kiffi)

				;First notify, otherwise it will be to late...
				If \NotifyProc
					\NotifyProc(controlCode)
				EndIf
				SignalSemaphore(\Semaphore)
				ProcedureReturn
			Case #SERVICE_CONTROL_PAUSE
				__Service_Internal_SendStatus(#SERVICE_PAUSE_PENDING, #NO_ERROR, 0, 1, 1000)
				If \NotifyProc
					\NotifyProc(controlCode)
				EndIf
				PauseThread(\ThreadID)
				currentState  = #SERVICE_PAUSED
			Case #SERVICE_CONTROL_CONTINUE
				__Service_Internal_SendStatus(#SERVICE_CONTINUE_PENDING, #NO_ERROR, 0, 1, 1000)
				ResumeThread(\ThreadID)
				currentState  = #SERVICE_RUNNING
			Case #SERVICE_CONTROL_INTERROGATE
				; it will fall to bottom and send status
				;Could do cleanup here but it must be very quick.
			Case #SERVICE_CONTROL_SHUTDOWN
				;The service is notified when system
				;shutdown occurs.
				;Do nothing on shutdown.
		EndSelect

		__Service_Internal_SendStatus(currentState, #NO_ERROR, 0, 0, 0)
		If \NotifyProc And currentState  <> #SERVICE_PAUSED
			\NotifyProc(controlCode)
		EndIf
	EndWith

EndProcedure

Procedure __Service_StartRunning(*THIS.__Service_Main_Structure_, ServiceName.s, *MainProcedure, *NotifyProcedure)
	Protected Result

	;Call this procedure, do start the service (when it is trying to start with a state of #SERVICE_START_PENDING)
	;MainProcedure should look like this: MyMainProcedure(IsService.i)
	;NotifyProcedure (optional) should look like this: MyNotifyProcedure(NewServiceState.i)

	If __ServiceGlobals__\hStatus = #Null And *MainProcedure <> #Null
		;o.k. now lets go!
		__ServiceGlobals__\MainProc       = *MainProcedure
		__ServiceGlobals__\NotifyProc     = *NotifyProcedure
		__ServiceGlobals__\ServiceName    = ServiceName

		Dim sTable.SERVICE_TABLE_ENTRY(1)
		sTable(0)\lpServiceProc = @__Service_Internal_Main()
		sTable(0)\lpServiceName = @ServiceName
		Result                  = StartServiceCtrlDispatcher_(@sTable())
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure __Service_InstallService(*THIS.__Service_Main_Structure_, ServiceName.s, DisplayName.s, FileName.s, Description.s, StartParameter);Installs a service and starts it
	Protected sStatus.SERVICE_STATUS
	Protected dwDesiredAccess = #SERVICE_ALL_ACCESS
	Protected dwServiceType   = #SERVICE_WIN32_OWN_PROCESS; | #SERVICE_INTERACTIVE_PROCESS ;<- this flag won't work that perfect on Win7, so better don't use it
	Protected dwErrorControl  = #SERVICE_ERROR_NORMAL
	Protected schSCManager, schService
	Protected Result, hKey, sTopKey, sKeyName.s, GetHandle

	schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CREATE_SERVICE | #SC_MANAGER_CONNECT)
	If schSCManager
		schService = CreateService_(schSCManager, @ServiceName, @DisplayName, dwDesiredAccess, dwServiceType, StartParameter, dwErrorControl, @FileName, 0, 0, 0, 0, 0)
		If schService
			Result = #True
			If QueryServiceStatus_(schService, @sStatus)
				If sStatus\dwCurrentState = #SERVICE_STOPPED
					If StartParameter = #SERVICE_AUTO_START Or StartParameter = #SERVICE_DEMAND_START
						Result = StartService_(schService, 0, 0)
					EndIf
				EndIf
			EndIf
			CloseServiceHandle_(schService)
		EndIf
		CloseServiceHandle_(schSCManager)
	EndIf

	If schSCManager And schService And Result And Description
		sTopKey   = #HKEY_LOCAL_MACHINE
		sKeyName  = "SYSTEM\CurrentControlSet\Services\" + Servicename
		GetHandle = RegOpenKeyEx_(stopKey, sKeyName, 0, #KEY_WRITE, @hKey)
		If GetHandle = #ERROR_SUCCESS
			GetHandle = RegSetValueEx_(hkey, "Description", 0, #REG_SZ, @Description, StringByteLength(Description) + SizeOf(CHARACTER))
		EndIf
		RegCloseKey_(hkey)
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure __Service_GetServiceState(*THIS.__Service_Main_Structure_, ServiceName.s)
	Protected schSCManager, schService
	Protected sStatus.SERVICE_STATUS
	Protected Result

	;Get the State of the Service ServiceName

	schSCManager = OpenSCManager_(0, 0, #SC_MANAGER_CONNECT)
	If schSCManager
		schService = OpenService_(schSCManager, @ServiceName, #GENERIC_READ)
		If schService
			If QueryServiceStatus_(schService, @sStatus)
				Result = sStatus\dwCurrentState
			EndIf
			CloseServiceHandle_(schService)
		EndIf
		CloseServiceHandle_(schSCManager)
	EndIf

	ProcedureReturn Result
EndProcedure

;----- Create Interface

Procedure CreateServiceObject()
	Protected *THIS.__Service_Main_Structure_

	;Create the interface

	*THIS = AllocateMemory(SizeOf(__Service_Main_Structure_))
	If *THIS
		*THIS\VTable = ?__Service_Procedures_
		InitializeStructure(*THIS, __Service_Main_Structure_)
	EndIf

	ProcedureReturn *THIS
EndProcedure

;----- Data

DataSection
	__Service_Procedures_:
	Data.i @__Service_StartService()
	Data.i @__Service_StopService()
	Data.i @__Service_PauseService()
	Data.i @__Service_ResumeService()
	Data.i @__Service_InstallService()
	Data.i @__Service_RemoveService()
	Data.i @__Service_StartRunning()
	Data.i @__Service_GetServiceState()
	Data.i @__Service_Grant_Access()
EndDataSection

Re: Win_Services.pbi [Win only]

Posted: Thu Feb 14, 2013 8:06 pm
by HeX0R
Example:

Code: Select all

EnableExplicit

InitSound()

#SERVICE_NAME = "THIS_IS_A_TEST"

XIncludeFile "Win_Services.pbi"

Procedure.s GetErrorText(Error.l)
	Protected Buffer, Len, Result.s

	Len   = FormatMessage_(#FORMAT_MESSAGE_ALLOCATE_BUFFER | #FORMAT_MESSAGE_FROM_SYSTEM, 0, Error, 0, @Buffer, 0, 0)
	If Len
		Result = PeekS(Buffer, Len - 2)
		LocalFree_(Buffer)
	EndIf
	
	ProcedureReturn Result
EndProcedure

Procedure CheckButtons(State)
	Protected i
	
	Dim ButtonStates.i(4)
	For i = 0 To 3
		ButtonStates(i) = 1
	Next i
	Select State
		Case 1 ;Service Stopped, so enable Startbutton
			ButtonStates(2) = 0
		Case 4 ;Service Running, so enable Stop- and Pausebutton
			ButtonStates(0) = 0
			ButtonStates(3) = 0
		Case 7 ;Service Paused, enable Continuebutton
			ButtonStates(1) = 0
	EndSelect
	For i = 0 To 3
		DisableGadget(2 + i, ButtonStates(i))
	Next i

EndProcedure

Procedure main(IsService)
	Protected *SER.__Service_Interface_ = CreateServiceObject()
	Protected ServiceState, Err, i, k, Counter
	
	Dim Service_Message.s(7)
	Service_Message(0) = "No Service Installed"
	Service_Message(1) = "Service Stopped"
	Service_Message(2) = "Service Start Pending"
	Service_Message(3) = "Service Stop Pending"
	Service_Message(4) = "Service Running"
	Service_Message(5) = "Service Continue Pending"
	Service_Message(6) = "Service Pause Pending"
	Service_Message(7) = "Service Paused"
	
	;-Initial checking, what's going on

	ServiceState = *SER\GetServiceState(#SERVICE_NAME)   ;<- check, if service already exists and what state it is
	
	;If IsService = 1 we are definately called from the service, otherwise check what's up with the service-state
	If IsService = 0 And ServiceState = #SERVICE_START_PENDING ;<- Start_Pending means, we should now start with our service
		If *SER\StartRunning(#SERVICE_NAME, @main()) ;<- start the service mode. The procedure main() will get called again with IsService = #True
			;we will come here, when service has been stopped
			End
		EndIf
	EndIf
	
	If IsService
		OpenWindow(0, 5, 5, 305, 300, "Test", #PB_Window_SystemMenu | #PB_Window_Invisible)
		;#PB_Window_Invisible is not really necessary as long as we don't use the flag #SERVICE_INTERACTIVE_PROCESS when creating the service
		CatchSound(0, ?Sound) ;<- we only need the sound when running as service
	Else
		OpenWindow(0, 5, 5, 305, 300, "Test", #PB_Window_SystemMenu)
	EndIf
	EditorGadget(0, 5, 5, 295, 150, #PB_Editor_ReadOnly)
	ButtonGadget(1, 93, 165, 120, 24, "Install Service")
	ButtonGadget(2, 5, 195, 70, 22, "Pause")
	ButtonGadget(3, 80, 195, 70, 22, "Resume")
	ButtonGadget(4, 155, 195, 70, 22, "Start")
	ButtonGadget(5, 230, 195, 70, 22, "Stop")
	
	CreateStatusBar(0, WindowID(0))
	AddStatusBarField(#PB_Ignore)
	
	AddWindowTimer(0, 0, 500)

	If ServiceState <> 0
		SetGadgetText(1, "Remove Service")
	EndIf
	StatusBarText(0, 0, Service_Message(ServiceState))
	CheckButtons(ServiceState)

	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_CloseWindow
				Break
			Case #PB_Event_Timer
				Select EventTimer()
					Case 0
						;Check State of Service
						k = *SER\GetServiceState(#SERVICE_NAME)
						If k <> ServiceState
							StatusBarText(0, 0, Service_Message(k))
							ServiceState = k
							CheckButtons(ServiceState)
						EndIf
						If IsService
							Counter + 1
							If Counter > 9
								;Beep any 5 Seconds, so you know, the service is running
								;(Beep_ and MessageBeep_ won't work inside services! [well... at least not in Win7])
								PlaySound(0)
								Counter = 0
							EndIf
						EndIf
				EndSelect
			Case #PB_Event_Gadget
				Select EventGadget()
					Case 1 ;install/uninstall
						If GetGadgetText(1) = "Remove Service"
							If *SER\RemoveService(#SERVICE_NAME)
								SetGadgetText(1, "Install Service")
								AddGadgetItem(0, -1, "Service 'Test App' removed!")
							Else
								Err = GetLastError_()
								AddGadgetItem(0, -1, "Error, while trying to remove the service:")
								If Err = #ERROR_ACCESS_DENIED
									AddGadgetItem(0, -1, "You don't have enough rights, try to start as admin.")
								Else
									AddGadgetItem(0, -1, GetErrorText(Err))
								EndIf
							EndIf
						Else
							If *SER\InstallService(#SERVICE_NAME, "TestApp", ProgramFilename(), "Dies ist eine TestApp")
								If *SER\GrantAccess(#SERVICE_NAME, UserName()) = 0
									Err = GetLastError_()
									AddGadgetItem(0, -1, GetErrorText(Err))
								EndIf
								SetGadgetText(1, "Remove Service")
								AddGadgetItem(0, -1, "Service 'Test App' installed!")
							Else
								Err = GetLastError_()
								AddGadgetItem(0, -1, "Error, while trying to install the service:")
								If Err = #ERROR_ACCESS_DENIED
									AddGadgetItem(0, -1, "You don't have enough rights, try to start as admin.")
								Else
									AddGadgetItem(0, -1, GetErrorText(Err))
								EndIf
							EndIf
						EndIf
					Case 2 ;pause
						If *SER\PauseService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
					Case 3 ;resume
						If *SER\ResumeService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
					Case 4 ;start
						If *SER\StartService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
					Case 5 ;stop
						If *SER\StopService(#SERVICE_NAME) = 0
							Err = GetLastError_()
							AddGadgetItem(0, -1, GetErrorText(Err))
						EndIf
				EndSelect
		EndSelect
	ForEver
EndProcedure


main(0)
End

DataSection
	Sound:
	;a little beep sound
	Data.l $46464952, $00000D12, $45564157, $20746D66, $00000010, $00010001, $00002B11, $00002B11
	Data.l $00080001, $61746164, $00000CED, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F807F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F80, $7F7F8080, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F708281, $AF5F709E
	Data.l $C07F43A0, $88BD5F60, $60C08F45, $4B80B767, $6F60C097, $9F4F80B6, $C06F60C0, $A09F4F80
	Data.l $70C06F50, $50A09F4F, $4F70C077, $7F50A09F, $AB5770C0, $C07F4AA0, $90AF5770, $60C07F4A
	Data.l $4B90AF5F, $5F60C07F, $7F4B90AF, $B36760C0, $C08F4D88, $80B56760, $60C0974F, $4F80B56F
	Data.l $6F60A89F, $9F4F80B5, $C06F60A0, $A09F4F78, $70C07750, $50A09F57, $5770C07F, $7F50A0A7
	Data.l $AF5B70C0, $C07F4D90, $90AF5F68, $60C07F4D, $4F90AF5F, $6760C07F, $8F4F88AF, $B36760C0
	Data.l $A8974F80, $80B36F60, $60A89F4F, $5380B46F, $6F60A09F, $9F5780B4, $B27750A0, $A09F5780
	Data.l $70C07F50, $50A09F57, $5F70C07F, $7F5090AB, $AF5F68C0, $C07F5090, $90AF6760, $60A87F51
	Data.l $5180AF67, $6760A88F, $975380AF, $B26F60A8, $A0975380, $80B26F60, $60A09F57, $5780B16F
	Data.l $7760A09F, $9F5780B0, $B07F50A0, $A09F5B80, $70B07F50, $5190A75F, $5F68B07F, $7F5190AB
	Data.l $AF6760B0, $A87F5190, $88AF6760, $60A87F53, $5380AF6F, $6F60A88F, $975380AF, $B06F60A0
	Data.l $A09F5780, $80B06F60, $60A09F57, $5780B077, $7F52A09F, $9F5F80B0, $B07F5298, $90A75F70
	Data.l $68B07F51, $5290AB5F, $6760A87F, $7F5390AD, $AF6760A8, $A87F5388, $80AF6F60, $60A48F53
	Data.l $5780AF6F, $6F60A097, $9F5780AF, $AE6F60A0, $A09F5780, $80B07760, $54A09F5B, $5F80B07F
	Data.l $7F52909F, $9F5F70AC, $AC7F5290, $90A76368, $64A87F53, $5390AB67, $6760A87F, $7F5380AD
	Data.l $AF6F60A8, $A08F5580, $80AF6F60, $60A09757, $5780AF6F, $7760A09F, $9F5780AE, $AE7760A0
	Data.l $A09F5B80, $80AC7F60, $54909F5F, $5F70AC7F, $7F53909F, $A76368A8, $A87F5390, $90AB6768
	Data.l $60A87F53, $5580AD67, $6F60A87F, $8F5580AD, $AE6F60A0, $A0975780, $80AE6F60, $60A09F57
	Data.l $5780AC77, $7B60A09F, $9F5B80AC, $AC7F60A0, $909F5F80, $70AC7F54, $53909F5F, $6768A87F
	Data.l $7F5390A7, $AB6764A8, $A87F5388, $80AB6760, $60A07F55, $5780AB6F, $6F60A08F, $975780AD
	Data.l $AD6F60A0, $A09B5780, $80AC7760, $60A09F5B, $5F80AC7B, $7F60989F, $9F5F80AC, $AA7F5490
	Data.l $909F5F70, $68A87F54, $5490A763, $6768A87F, $7F5588A7, $AB6760A8, $A07F5580, $80AB6F60
	Data.l $60A08F57, $5780AB6F, $6F60A097, $975780AC, $967F60A0, $7C887778, $7F78847F, $877B7A88
	Data.l $80837C80, $7F7E817F, $827E7E82, $80817D80, $7F807F7E, $7F7F7F7F, $7F7F7F7F, $7F7F807F
	Data.l $7F7F807F, $7F7F7F80, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7E
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7F, $7F7F7F7F
	Data.l $7E7E7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7E, $7E7F7F7F, $7F7E7F7F, $7F7E7F7F, $7F7F7E7F
	Data.l $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7E7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F
	Data.l $7E7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7E7E7F, $7F7F7E7E, $7E7F7F7E, $7E7E7F7E
	Data.l $7F7E7F7F, $7F7E7E7F, $7F7E7E7F, $7F7F7E7E, $7E7F7F7E, $7E7F7F7E, $7E7E7F7E, $7F7E7F7F
	Data.l $7F7E7E7F, $7F7F7E7F, $7F7F7E7E, $7E7F7F7E, $7E7F7F7E, $7F7E7F7F, $7F7E7E7F, $7F7F7E7F
	Data.l $7F7F7E7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7E7F7F7E, $7E7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7E7F7F7E
	Data.l $7E7F7F7F, $7F7E7F7F, $7F7E7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7E, $7E7F7F7F, $7F7F7F7F
	Data.l $7F7E7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7F, $7F7F7F7F, $7F7E7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $74817F7F, $6380987F, $7F50909F, $AD5F68C0, $A87F5190, $80AB6760, $60A07F57
	Data.l $5780A76F, $6F60A07F, $8F5780AA, $AA6F60A0, $A0975780, $80AA6F60, $60A09B57, $5B80AA77
	Data.l $7F60989F, $9F5F80AA, $A87F6090, $909F5F70, $70A87F54, $55909F63, $6768A87F, $7F5588A7
	Data.l $A76760A4, $A07F5580, $80AB6F60, $60A08F57, $5780AB6F, $6F60A097, $975780AB, $AA6F60A0
	Data.l $A09F5780, $80AC7760, $60989F5B, $5F80AA7F, $7F54909F, $9F5F70A8, $A87F5490, $90A76368
	Data.l $68A87F54, $5588A767, $6760A47F, $7F5580AB, $AB6F60A0, $A08F5780, $80AB6F60, $60A09757
	Data.l $5780AB6F, $7760A09B, $9F5B80AC, $AA7760A0, $909F5B80, $80A87F60, $54909F5F, $5F70A87F
	Data.l $7F54909F, $A76768A8, $A87F5590, $88A76764, $60A47F55, $5580AB67, $6F60A07F, $8F5780AB
	Data.l $AB6F60A0, $A0975780, $80AB6F60, $60A09757, $5B80AC77, $7F60A09F, $9F5F80AA, $A87F6098
	Data.l $909F5F80, $70A87F54, $55909F63, $6768A87F, $7F5590A7, $A76768A8, $A47F5588, $80AB6760
	Data.l $60A07F57, $5780AB6F, $6F60A08F, $975780AB, $AB6F60A0, $A09B5780, $80AA7760, $60A09F5B
	Data.l $5F80AA7F, $7F60909F, $9F5F80A8, $A87F5490, $909F6370, $68A87F55, $5590A767, $6760A87F
	Data.l $7F5580A7, $AB6B60A4, $A08F5780, $80AB6F60, $60A08F57, $5780AB6F, $6F60A097, $9B5780AB
	Data.l $AA7760A0, $989F5B80, $80AA7F60, $60909F5F, $5F70A87F, $7F55909F, $9F6370A8, $A87F5590
	Data.l $88A76768, $60A47F55, $5588A767, $6F60A47F, $8F5780AB, $AB6F60A0, $A0975780, $80AB6F60
	Data.l $60A09757, $5780AA6F, $7760A09B, $9F5B80AA, $AA7F6098, $909F5F80, $70A87F60, $54909F5F
	Data.l $6370A87F, $7F55909F, $A76768A8, $A87F5588, $80A76760, $60A07F57, $5780AB6F, $6F60A08F
	Data.l $975780AB, $AB6F60A0, $A0975780, $80AA6F60, $60A09B5B, $5B80AA77, $7F60989F, $9F5F80AA
	Data.l $A87F6090, $909F5F70, $70A87F54, $55909F63, $6768A87F, $7F5588A7, $A76760A4, $A07F5580
	Data.l $80AB6B60, $60A08F57, $5780AB6F, $6F60A097, $975780AB, $AA7760A0, $A09F5B80, $80AA7760
	Data.l $60989F5B, $5F80AA7F, $7F60909F, $9F6370A8, $A87F5590, $909F6768, $68A87F55, $5588A767
	Data.l $6760A47F, $7F5780A7, $AB6F60A0, $A08F5780, $80AB6F60, $60A09757, $5780AB6F, $7F60A097
	Data.l $88777894, $78847F7C, $7B7A887F, $827C8086, $7E817E80, $7E7E827F, $817D8082, $807F7E80
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F807F7E, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7F, $7E7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F
	Data.l $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7E7E7F
	Data.l $7F7F7E7F, $7E7F7E7E, $7E7F7F7E, $7F7E7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7E
	Data.l $7F7F7F7F, $7E7F7F7F, $7F7E7F7F, $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7E
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7E7F7F
	Data.l $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7F7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F
	Data.l $7F7F7F7E, $7E7F7F7E, $7E7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7E7E7F, $7F7F7F7F, $7F7F7F7E
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7E7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7E7E7F
	Data.l $7F7F7E7F, $7F7F7F7E, $7E7F7F7E, $7F7F7F7F, $7F7E7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7E7F
	Data.l $7F7F7F7E, $7E7F7F7E, $7E7E7F7F, $7F7E7F7F, $7F7F7E7F, $7F7F7E7F, $7F7F7F7E, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7E, $7E7F7F7E, $7E7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7E7F, $7F7F7F7F, $7F7F7F7E, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.l $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F, $7F7F7F7F
	Data.b $7F, $00
EndDataSection

Re: Win_Services.pbi [Win only]

Posted: Thu Feb 14, 2013 8:25 pm
by rsts
Very nice.

Props to you.

Thanks for sharing.

Re: Win_Services.pbi [Win only]

Posted: Fri Jul 26, 2013 5:57 pm
by NoahPhense
Love it.

Re: Win_Services.pbi [Win only]

Posted: Wed Oct 29, 2014 12:01 pm
by SeregaZ
i am trying use CreateService win api at http://msdn.microsoft.com/en-us/library ... s.85).aspx and i cant understand what he want from me at this item:
lpServiceStartName [in, optional]
The name of the account under which the service should run. If the service type is SERVICE_WIN32_OWN_PROCESS, use an account name in the form DomainName\UserName. The service process will be logged on as this user. If the account belongs to the built-in domain, you can specify .\UserName.

where to get this DomainName\UserName and how to set it to function? if this parametr is null - service starts from LocalSystem account. but i need my account.

Re: Win_Services.pbi [Win only]

Posted: Thu Oct 30, 2014 11:21 am
by HeX0R
I didn't ever need it myself, but I think this should work (in case you don't need the domain):

Code: Select all

".\" + UserName()
So in the above code it should look like this:

Code: Select all

ServiceStartName.s = ".\" + UserName()
UserPassword.s = "yourloginpassword"
schService = CreateService_(schSCManager, @ServiceName, @DisplayName, dwDesiredAccess, dwServiceType, StartParameter, dwErrorControl, @FileName, 0, 0, 0, @ServiceStartName, @UserPassword)

Re: Win_Services.pbi [Win only]

Posted: Thu Oct 30, 2014 11:46 am
by SeregaZ
it says wrong parametres :(

i have no password. so i set it to UserPassword.s = "" - can system have some password anyway?
, @ServiceStartName, @UserPassword) - wrong parametres
, @ServiceStartName, 0) - wrong parametres
, 0, 0) - work, but local, not username.

username must be english letters or no matter?

just once i see another error message - that name not exists, or password wrong - when i try to set like this:
, 0, 0, @*ServiceStartName, @UserPassword)

Re: Win_Services.pbi [Win only]

Posted: Thu Oct 30, 2014 3:55 pm
by HeX0R
I tried it here on my company PC and also had no luck, but problem is I need a domain here.
So I tried it with:

Code: Select all

ServiceStartName.s = Space(128)
Size = 128
GetUserNameEx_(2, @ServiceStartName, @Size)
to get the Domainname\Username.

With this name it was possible to create the service, but no luck in starting it (my account doesn't have the right to start as service and I can't do anything against it here).

I will also try it at home, there shouldn't be a domainname needed.

Re: Win_Services.pbi [Win only]

Posted: Thu Oct 30, 2014 5:14 pm
by SeregaZ
i think i found problem :(((

lpServiceStartName [in, optional]
If the service type specifies SERVICE_INTERACTIVE_PROCESS, the service must run in the LocalSystem account.


i think it means dwServiceType.l=#SERVICE_WIN32_OWN_PROCESS | #SERVICE_INTERACTIVE_PROCESS can be apply only with null parameter, it will run as local without domain name. if i set only one param - dwServiceType.l=#SERVICE_WIN32_OWN_PROCESS - it create service fine, but cant launch exe. says problem with login to system. how to know sure - i have or no have password? when windows starts - no any passwords requiered.

Re: Win_Services.pbi [Win only]

Posted: Thu Oct 30, 2014 6:00 pm
by HeX0R
I tried it at home, and it is running flawlessly (even with ".\" + UserName())

BUT:
By default the users don't have the right to run as service, you need to add your user in the Local Security Policy (User Rights Assignment/Log on as a service).

Re: Win_Services.pbi [Win only]

Posted: Fri Oct 31, 2014 6:46 am
by SeregaZ
deamed billy g... with deamed uac...

i think i need to return to local starts. but make some change in main programm. now i read path to My Documents by use Droopy Global DocumFolder$ = GetSpecialFolderLocation(5) + "MNP\".
XP - 5 C:\Documents And Settings\Username\Mes Documents\
W7 - 5 C:\Users\UserName\Documents\

Code: Select all

ProcedureDLL.s GetSpecialFolderLocation(fid.l) ; Get Name / Folder of Windows Special Folders
  
  If SHGetSpecialFolderLocation_(0, fid, @Dossier_ID) = 0 
    SpecialFolderLocation.s = Space(#MAX_PATH) 
    SHGetPathFromIDList_(Dossier_ID, @SpecialFolderLocation) 
    If SpecialFolderLocation 
      If Right(SpecialFolderLocation, 1) <> "\" 
        SpecialFolderLocation + "\" 
      EndIf 
    EndIf 
  EndIf 
  ProcedureReturn SpecialFolderLocation.s 
EndProcedure
with this local this path is goin to wrong place. so how i can get path to My Documents folder of user, not local? and my programm reads certificates in windows - with this local starts he will read certificates of user, or local? and my programm is control internet exlorer - will explorer of user obey to programm of local?

Re: Win_Services.pbi [Win only]

Posted: Fri Oct 31, 2014 11:11 am
by HeX0R
I think you have two possibilities:
1.) Save your certificates in CSIDL_COMMON_DOCUMENTS
2.) Use an ini file stored in CSIDL_COMMON_APPDATA where you store the path to the documents of the wished user.
Read this ini file, when your service starts.
But could be that this service doesn't have the rights to read/write in this users document folder.