I am defensive because you have in so many words called me a
thief.
If you want to email me and discuss this, I would be more then
happy. I did go look at your code and you are correct, they
do appear to be very simalar. But you have to understand that
an NT Service HAS to follow a very rigid structure.
Anyone who would right an NT Service would end up with code
very similar to yours and mine.
As far as variable names and such, I use, as well as many other
people, have a standard method of naming object which help make
it easier to read.
Examples:
Most global vars start with g.
Global are usually then followed with lng = Long
int = Integer
etc...
Given the above information, it would be almost impossible not
to end up with code which appears to be very similar.
I do not disagree with your absurvation.
What I do disagree with is your method of pointing it out.
You, in so many words, accused me of taking credit for your
code. If you truly believed that, I would have at least expected
you to responde with your email address and a request for a
conversation.
It could have very well been that I had a copy of your code
and didn't event know it. I see it happen all the time.
People post entries on this and many other forums stating
' Here is some code, I don't remember where I got it' etc....
I apologize if I over reacted, however, being accused of
theft tends to make me very angry.
I still would be very glad to discuss this further.
We can continue to use this forumn or you can email me
and I will gladly answer. I will even email you my phone
number.
If you truly believe that I copied your code, we can even ask
the forumn admin people to remove it from the forum.
Ben Clark
[email protected]
------------------
Announcement
Collapse
No announcement yet.
Anybody want an NT Service Template?
Collapse
X
-
I won't comment on the similarity/differences of the service
template above with other code samples. I just want to say
that by its very nature (limited area) most service template
code is likely to have *many* similarities with other code
even if that code has been written from scratch.
Cheers
Florent
------------------
Leave a comment:
-
Guest repliedBen,
Why are you so defensive? Where did I accuse you of stealing code?
I've had my code on my web site for at least 2 years. I made my template because I was writing some NT services in PB, and I wanted a framework in place that would make it easier for me. I didn't copy my code from anywhere - I made it all up from scratch (except for the disclaimer, which I copied from another piece of code that I saw). I have never seen the book that you mentioned.
The structure and flow of your code is very similar to what I have. Whether you "stole" it from me or not - I could care less. All I ask for is some kind of acknowledgement. I know of no one else who had such a framework in place before I wrote mine. Other people on this site have mentioned this code sample before and mentioned that they grabbed my code and made tweaks to it.
Jason
------------------
Leave a comment:
-
Now we're at the NT service topic:
Does somebody know a reliable way to show an icon in the windows taskbar system tray?
(this means showing an icon when a user logs on, removing it when he logs off,
and showing it again at next logon....)
------------------
Peter.
mailto[email protected][email protected]</A>
Leave a comment:
-
I hope you guys used the same book... Even a lot of the comments are identical.
Very weird. Given your reactions I have to assume you happened to start out with the same sample code.
Please compare books before you start arguing. It may be better to take the arguing to private email but since it's here now, we'd like to at least know the outcome.
Peter.
------------------
[email protected]
Leave a comment:
-
First, I would appreciate it if you would accuse me of
stealing in private.
Second, as far as I know, I don't have ANY of your code
in my pessesion.
Third, I converted most of it from a copy I had written
years ago in C++, which I believe I modeled after an
example in a book called 'System Services' or something
simalar.
I do not, have not and never will take the credit for
someones work.
I would appreciate it if you would pay a little closer
attention to the code before making accusations.
If by some chance it appears similar to yours, I assure
you it is by chance only.
------------------
Leave a comment:
-
Guest repliedBen,
How did you come up with this code?
http://www.execpc.com/~jrbock
Specifically,
http://www.execpc.com/~jrbock/pbntservice.html
I don't care if you use my code as a basis for yours and improve on it. But I'd appreciate an acknowledgement.
Jason
------------------
Leave a comment:
-
Anybody want an NT Service Template?
I used this serveral times.
Works greate
Code:'------------------------------------------------------------------------------ ' ' NT SERVICE Template for 32-bit PB/DLL ' Copyright (c) 2001 by ClarkSoft.Com Inc ' ' Let me know if you find any errors or have any suggestions ' [email protected] ' ' DISCLAIMER: ' This code may be distributed on the condition that no fee is charged for ' such distribution with the exception of reasonable shipping and media ' charged. In addition, the code in this program may be incorporated ' into your own programs and the resulting programs may be distributed ' without payment of royalties. The author of this code is not ' responsible for the success or failure of any resultant usage ' of the code giving within this file. You are free to modify any code ' found within this file, but the author is not responsible for any changes ' to the base code file. ' '------------------------------------------------------------------------------- $COMPILE EXE "EXENAME.EXE" $RESOURCE "RESOURCE.PBR" ' Embed the resources into the exe #DIM ALL ' Force ALL vars to have to be declared GLOBAL hWindow AS LONG ' You should set this in your WINMAINX to the handle ' of your main window. $INCLUDE "WIN32API.INC" ' My includes actually have the WinAPI includes in them. '$INCLUDE "MYINC.INC" ' This was the main Bas file for my executable ' --------------------- ' CONSTANT DECLARATIONS ' --------------------- %EVENTLOG_AUDIT_FAILURE = 16 %EVENTLOG_AUDIT_SUCCESS = 8 %EVENTLOG_ERROR_TYPE = 1 %EVENTLOG_INFORMATION_TYPE = 4 %EVENTLOG_SUCCESS = 0 %EVENTLOG_WARNING_TYPE = 2 ' This constant is used to set logging status. %EVENTLOG_LEVEL = %EVENTLOG_AUDIT_FAILURE + %EVENTLOG_AUDIT_SUCCESS + %EVENTLOG_ERROR_TYPE + _ %EVENTLOG_INFORMATION_TYPE + %EVENTLOG_SUCCESS + %EVENTLOG_WARNING_TYPE %SERVICE_WIN32_OWN_PROCESS = &H10& %SERVICE_WIN32_SHARE_PROCESS = &H20& %SERVICE_WIN32 = %SERVICE_WIN32_OWN_PROCESS + %SERVICE_WIN32_SHARE_PROCESS %SERVICE_DEMAND_START = &H3& %SERVICE_ERROR_NORMAL = &H1& %WAIT_OBJECT_0 = 0& ' ------------------------- ' FUNCTION/SUB DECLARATIONS ' ------------------------- DECLARE FUNCTION Install() AS LONG DECLARE FUNCTION InitService() AS LONG DECLARE FUNCTION Uninstall() AS LONG DECLARE FUNCTION WinErrorMessage(BYVAL ErrNumber AS LONG) AS STRING DECLARE FUNCTION SendStatus(BYVAL CurrentStatus AS DWORD, BYVAL ExitCode AS DWORD, ServiceSpecificExitCode AS LONG, BYVAL Checkpoint AS DWORD, BYVAL WaitHint AS DWORD) AS LONG DECLARE FUNCTION ServiceThread(ID AS LONG) AS LONG DECLARE SUB Handler(BYVAL ControlValue AS DWORD) DECLARE SUB LogNTEvent(Message AS STRING, LogCode AS LONG) DECLARE SUB ServiceMain(BYVAL dwArgs AS DWORD, BYVAL lpszArgv AS DWORD) DECLARE SUB Terminate(ErrCode AS DWORD) DECLARE SUB StopService() DECLARE SUB PauseService() DECLARE SUB ResumeService() ' ---------------- ' GLOBAL VARIABLES ' ---------------- GLOBAL gascServiceName AS ASCIIZ * 8 GLOBAL gascServiceDisplayName AS ASCIIZ * 256 GLOBAL gdwdhStatus AS DWORD GLOBAL gdwdServiceState AS DWORD GLOBAL gdwdServiceStatus AS DWORD GLOBAL glnghInstance AS LONG GLOBAL glnghPrvInst AS LONG GLOBAL glnghTerminateEvent AS LONG GLOBAL glnghServiceThread AS LONG GLOBAL glngThreadResult AS LONG GLOBAL glngRunningService AS LONG GLOBAL glngPauseService AS LONG GLOBAL glngCmdShow AS LONG GLOBAL ptrCmdLine AS ASCIIZ PTR ' FUNCTION: WinMain FUNCTION WINMAIN(BYVAL hCurInst AS LONG, BYVAL hPrvInst AS LONG, CmdLine AS ASCIIZ PTR, BYVAL CmdShow AS LONG) EXPORT AS LONG DIM Result AS LONG DIM CmdParm AS STRING DIM udtSTE AS SERVICE_TABLE_ENTRY ' Set the service name and display name here. gascServiceName = "SERVICE NAME HERE" gascServiceDisplayName = "DISPLAY NAME HERE" glngHInstance = hCurInst glnghPrvInst = hPrvInst glngCmdShow = CmdShow ptrCmdLine = CmdLine ' Get the Command Line parms CmdParm = UCASE$(EXTRACT$(@CmdLine, ANY " ,." + CHR$(9))) ' Get rid of any seperators CmdParm = REMOVE$(CmdParm, ANY "-\/") ' If the exe was executed with the Install parm then we just install and quit IF CmdParm = "INSTALL" THEN ' Install the service. Result = Install() IF ISFALSE Result THEN MSGBOX "An error occured while trying to install this service END IF ' If the exe was executed with the UnInstall parm then we just uninstall and quit ELSEIF CmdParm = "UNINSTALL" THEN ' Uninstall the service. Result = Uninstall() IF ISFALSE Result THEN MSGBOX "An error occured while trying to uninstall this service END IF ' No parms were given that we want so start up as service ' This should only happen when the service control manager starts us ELSE udtSTE.lpServiceName = VARPTR(gascServiceName) udtSTE.lpServiceProc = CODEPTR(ServiceMain) Result = StartServiceCtrlDispatcher(udtSTE) IF Result = 0 THEN ExitProcess GetLastError() END IF END IF FUNCTION = 0 END FUNCTION ' Install the service into windows FUNCTION Install() AS LONG DIM dwdRet AS DWORD DIM lngDQEnd AS LONG DIM lngDQStart AS LONG DIM lngHSCManager AS LONG DIM lngHService AS LONG DIM ascEXE AS ASCIIZ * %MAX_PATH ON ERROR GOTO Error_Install ' Assume a failure for now. FUNCTION = %FALSE lngHSCManager = OpenSCManager(BYVAL %NULL, BYVAL %NULL, %SC_MANAGER_CREATE_SERVICE) IF lngHSCManager <> %NULL THEN ' OK, we have a handle to the SCM. ' Get the full EXE file path. dwdRet = GetModuleFileName(glngHInstance, ascEXE, %MAX_PATH) IF dwdRet <> 0 THEN ' Install the service. lngHService = CreateService(lngHSCManager, gascServiceName, gascServiceDisplayName, _ %SERVICE_ALL_ACCESS, %SERVICE_WIN32_OWN_PROCESS, _ %SERVICE_AUTO_START, %SERVICE_ERROR_NORMAL, _ ascEXE, BYVAL %NULL, BYVAL %NULL, _ BYVAL %NULL, BYVAL %NULL, BYVAL %NULL) ' Close any service handles. IF lngHService <> %NULL THEN ' Success! FUNCTION = %TRUE CloseServiceHandle lngHService END IF CloseServiceHandle lngHSCManager END IF END IF FUNCTION = %TRUE EXIT FUNCTION Error_Install: FUNCTION = -1& * ERR ON ERROR RESUME NEXT ' Close any service handles. IF lngHService <> %NULL THEN CALL CloseServiceHandle(lngHService) END IF IF lngHSCManager <> %NULL THEN CALL CloseServiceHandle(lngHSCManager) END IF END FUNCTION ' Unistall the service FUNCTION Uninstall() AS LONG DIM lngHSCManager AS LONG DIM lngHService AS LONG ON ERROR GOTO Error_Uninstall ' Assume a failure for now. FUNCTION = %FALSE lngHSCManager = OpenSCManager(BYVAL %NULL, BYVAL %NULL, %SC_MANAGER_CREATE_SERVICE) IF lngHSCManager <> %NULL THEN ' OK, we have a handle to the SCM. ' Now open our service. lngHService = OpenService(lngHSCManager, gascServiceName, %SERVICE_ALL_ACCESS) IF lngHService <> %NULL THEN ' Delete the service. IF DeleteService(lngHService) <> %NULL THEN ' Success! FUNCTION = %TRUE END IF CloseServiceHandle lngHService END IF CloseServiceHandle lngHSCManager END IF EXIT FUNCTION Error_Uninstall: FUNCTION = -1& * ERR ON ERROR RESUME NEXT ' Close any service handles. IF lngHService <> %NULL THEN CloseServiceHandle lngHService END IF IF lngHSCManager <> %NULL THEN CloseServiceHandle lngHSCManager END IF END FUNCTION ' Start up the service FUNCTION InitService() AS LONG DIM lngRet AS LONG DIM ID AS LONG DIM udtSTE AS SERVICE_TABLE_ENTRY DIM lpThreadAttributes AS SECURITY_ATTRIBUTES ' Start the main thread for this service glnghServiceThread = CreateThread(lpThreadAttributes, 0, CODEPTR(ServiceThread), 0, 0, ID) ' Did the thread start OK IF glnghServiceThread = 0 THEN FUNCTION = %FALSE EXIT FUNCTION ELSE ' Set the global to running glngRunningService = %TRUE FUNCTION = %TRUE EXIT FUNCTION END IF END FUNCTION SUB PauseService() ' Set the global indicating that we are not paused glngPauseService = %TRUE ' Let er rip SuspendThread glnghServiceThread END SUB SUB ResumeService() ' Set the global indicating that we are not paused glngPauseService = %FALSE ' Let er rip ResumeThread glnghServiceThread END SUB SUB StopService() ' Set the global flag indicating that the service is not running glngRunningService = %FALSE ' Set the event so the service will stop SetEvent glnghTerminateEvent END SUB FUNCTION SendStatus(BYVAL CurrentStatus AS DWORD, BYVAL ExitCode AS DWORD, ServiceSpecificExitCode AS LONG, BYVAL Checkpoint AS DWORD, BYVAL WaitHint AS DWORD) AS LONG DIM udtSS AS SERVICE_STATUS ' Reset the global service status value. gdwdServiceStatus = CurrentStatus ' Setup the UDT. udtSS.dwServiceType = %SERVICE_WIN32_OWN_PROCESS udtSS.dwCurrentState = CurrentStatus ' If we are the process of starting, then don't accept control events IF CurrentStatus = %SERVICE_START_PENDING THEN udtSS.dwControlsAccepted = 0 ELSE ' Take what was given udtSS.dwControlsAccepted = %SERVICE_ACCEPT_STOP + %SERVICE_ACCEPT_PAUSE_CONTINUE + %SERVICE_ACCEPT_SHUTDOWN END IF ' If a specific ServiceSpecificExitCode is defined, setup the Win32 exit code properly IF ServiceSpecificExitCode = 0 THEN udtSS.dwWin32ExitCode = ExitCode ELSE udtSS.dwWin32ExitCode = %ERROR_SERVICE_SPECIFIC_ERROR END IF ' Specific Exit Code udtSS.dwServiceSpecificExitCode = ServiceSpecificExitCode udtSS.dwCheckPoint = Checkpoint udtSS.dwWaitHint = WaitHint IF SetServiceStatus(gdwdHStatus, udtSS) = 0 THEN ' Something went wrong so stop the service StopService FUNCTION = %FALSE ELSE FUNCTION = %TRUE END IF END FUNCTION SUB ServiceMain(BYVAL dwArgs AS DWORD, BYVAL lpszArgv AS DWORD) LOCAL Result AS LONG LOCAL lpEventAttributes AS SECURITY_ATTRIBUTES ' Register with the SCM gdwdHStatus = RegisterServiceCtrlHandler(gascServiceName, CODEPTR(Handler)) ' Did it work IF gdwdHStatus = 0 THEN ' No, so terminate Terminate GetLastError() EXIT SUB END IF ' Service has been registered and startup is pending IF ISFALSE SendStatus(%SERVICE_START_PENDING, %NO_ERROR, 0, 1, 5000) THEN Terminate GetLastError() EXIT SUB END IF ' Create the termination event glnghTerminateEvent = CreateEvent(lpEventAttributes, %TRUE, %FALSE, "") IF glnghTerminateEvent = 0 THEN Terminate GetLastError() EXIT SUB END IF ' Service startup is still pending IF ISFALSE SendStatus(%SERVICE_START_PENDING, %NO_ERROR, 0, 2, 1000) THEN Terminate GetLastError() EXIT SUB END IF ' Start the service Result = InitService() IF ISFALSE Result THEN ' Oops Terminate GetLastError() EXIT SUB END IF ' Service is now running IF ISFALSE SendStatus(%SERVICE_RUNNING, %NO_ERROR, 0, 0, 0) THEN Terminate GetLastError() EXIT SUB END IF ' Wait for the signal to end WaitForSingleObject glnghTerminateEvent, %INFINITE Terminate 0 EXIT SUB END SUB SUB Terminate(ErrCode AS DWORD) ' If the Terminate Event has already been created then destroy it IF glnghTerminateEvent <> 0 THEN CloseHandle glnghTerminateEvent END IF IF gdwdHStatus <> 0 THEN ' Send a message to the SCM and tell them that we are stopping SendStatus %SERVICE_STOPPED, ErrCode, 0&, 0&, 0& END IF ' If the thread has started, then kill it IF glnghServiceThread <> 0 THEN ' Not normally here in a service ' However, this program was written as an executable first and converted into a service ' There is a global hWindow that is set in the WINMAINX when we start ' We need to destroy the window so the WINMAINX will come back to us ' Is it a valid window IF IsWindow(hWindow) THEN ' Yes so destroy it DestroyWindow hWindow ' This will cause the Message Loop in your WINMAINX to exit and return END IF ' Close the thread CloseHandle glnghServiceThread END IF END SUB SUB Handler(BYVAL ControlValue AS DWORD) ' This procedure (by its' name) handles all service requests. LOCAL Result AS LONG ON ERROR RESUME NEXT ' There is no Start option because the ServiceMain takes care of starting the service SELECT CASE ControlValue CASE %SERVICE_CONTROL_STOP ' Set the global Status gdwdServiceState = %SERVICE_STOP_PENDING ' Tell the SCM that we are stopping SendStatus %SERVICE_STOP_PENDING, %NO_ERROR, 0&, 1, 5000 ' Stop the service StopService CASE %SERVICE_CONTROL_PAUSE ' Are we running and not paused IF (ISTRUE glngRunningService) AND (ISFALSE glngPauseService) THEN ' Tell the SCM that we are pausing SendStatus %SERVICE_PAUSE_PENDING, %NO_ERROR, 0, 1, 1000 ' Pause it PauseService ' Set the current state gdwdServiceState = %SERVICE_PAUSED END IF CASE %SERVICE_CONTROL_CONTINUE ' Are we running and paused IF (ISTRUE glngRunningService) AND (ISTRUE glngPauseService) THEN ' Tell the SCM that we are un pausing SendStatus %SERVICE_CONTINUE_PENDING, %NO_ERROR, 0, 1, 1000 ' Resume the service ResumeService ' Set the current state gdwdServiceState = %SERVICE_RUNNING END IF CASE %SERVICE_CONTROL_INTERROGATE ' Don't need to do anything ' We will send the current status below CASE %SERVICE_CONTROL_SHUTDOWN ' We don't do anything with a shutdown EXIT SUB END SELECT ' Tell the SCM the new status SendStatus gdwdServiceState, %NO_ERROR, 0, 0, 0 END SUB FUNCTION ServiceThread(ID AS LONG) EXPORT AS LONG LOCAL Result AS LONG LOCAL Msg AS tagMsg ' Run until we are killed 'Result = WINMAINX(BYVAL glngHInstance, BYVAL glnghPrvInst, BYVAL ptrCmdLine, BYVAL glngCmdShow) ' I had written a program and compiled it as an exe ' To make it a service, I just renamed the WINMAIN to WINMAINX and then ' call it like you see above END FUNCTION
------------------
Tags: None
Leave a comment: