473,399 Members | 2,146 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Writing a service...

Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.
The service will then restore the original time zone upon stopping and
force another resync. I have two versions that does the same thing, the
older one works perfectly but I did not like its structure. Thus I
followed another template, which formed the new version. However, the
new version works, but on shutdown, it finishes changing the time zone
and resyncing and then crashes. If I were to remove the time zone and
resyncing commands, the service terminates successfully.

The following is the old code that works fine:
<noscript><code>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define SLEEP_TIME 1800000
#define RESET_ON_MANUAL_STOP 1
#define LOCAL_TIME_ZONE "Singapore Standard Time"
#define FOREIGN_TIME_ZONE "GMT Standard Time"

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();

void ChangeTimeZone(char zone[])
{
char command[150];
command[0]='\0';
strcat(command,"RunDLL32 shell32.dll,Control_RunDLL
%SystemRoot%\\system32\\TIMEDATE.cpl,,/Z ");
strcat(command,zone);
system(command);
return;
}

void UpdateTime()
{
system("w32tm /resync /nowait");
return;
}

void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "TimeHandler";
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);
}
void ServiceMain(int argc, char** argv)
{
int error;

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(
"TimeHandler",
(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)
{
Sleep(SLEEP_TIME);
UpdateTime();

return;
}

// Service initialization
int InitService()
{
ChangeTimeZone(LOCAL_TIME_ZONE);
UpdateTime();
return 0;
}

// Control handler function
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:

if(RESET_ON_MANUAL_STOP)
{
ChangeTimeZone(FOREIGN_TIME_ZONE);
UpdateTime();
}

ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;

case SERVICE_CONTROL_SHUTDOWN:

ChangeTimeZone(FOREIGN_TIME_ZONE);
UpdateTime();

ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;

default:
break;
}

// Report current status
SetServiceStatus (hStatus, &ServiceStatus);

return;
}
</code></noscript>

The following is the newer code based on another template, which
crashes on termination:
<noscript><code>
#include <stdio.h>
#include <windows.h>

#define SLEEP_TIME 1800000
#define RESET_ON_MANUAL_STOP 1
#define LOCAL_TIME_ZONE "Singapore Standard Time"
#define FOREIGN_TIME_ZONE "GMT Standard Time"

SERVICE_STATUS_HANDLE serviceStatusHandle;
void ServiceMain(DWORD argc, LPSTR *argv);
BOOL StartServiceThread();
void ServiceCtrlHandler (DWORD controlCode);
int UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint);
void KillService(void);
void terminateService(int);
LPTSTR GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize );
void ChangeTimeZone(char zone[]);
void UpdateTime(void);

HANDLE killServiceEvent;
DWORD serviceCurrentStatus;
DWORD serviceRunning;
HANDLE threadHandle;
DWORD servicePaused;
TCHAR szErr[256];
char *szServiceName = "TimeHandler";

void main(void)
{
SERVICE_TABLE_ENTRY serviceTable[] =
{
{szServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain},
{ NULL, NULL }
};
// Register the service with the Service Control Manager
StartServiceCtrlDispatcher(serviceTable);
}

void ServiceMain(DWORD argc, LPSTR *argv)
{
int bSuccess;

serviceStatusHandle = RegisterServiceCtrlHandler(szServiceName,
(LPHANDLER_FUNCTION) ServiceCtrlHandler);

if (!serviceStatusHandle)
{
terminateService(GetLastError());
return;
}
bSuccess = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1,
5000);

if (!bSuccess)
{
terminateService(GetLastError());
return;
}

killServiceEvent = CreateEvent(0, 1, 0, 0);
if (!killServiceEvent)
{
terminateService(GetLastError());
return;
}

bSuccess = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 2,
1000);
if (!bSuccess)
{
terminateService(GetLastError());
return;
}
ChangeTimeZone(LOCAL_TIME_ZONE);
UpdateTime();
//handle_args( argc, argv );

bSuccess = UpdateSCMStatus(SERVICE_START_PENDING, NO_ERROR, 0, 3,
5000);
if (!bSuccess)
{
terminateService(GetLastError());
return;
}
bSuccess = StartServiceThread();
if (!bSuccess)
{
terminateService(GetLastError());
return;
}
serviceCurrentStatus = SERVICE_RUNNING;
bSuccess = UpdateSCMStatus(SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
if (!bSuccess)
{
terminateService(GetLastError());
return;
}
WaitForSingleObject(killServiceEvent, INFINITE);
terminateService(0);
serviceCurrentStatus = SERVICE_STOPPED;
bSuccess = UpdateSCMStatus(SERVICE_STOPPED, NO_ERROR, 0, 0, 0);
return;
}
DWORD ServiceExecutionThread(LPDWORD param)
{
while (serviceRunning)
{
Sleep(SLEEP_TIME);
UpdateTime();
}

return 0;
}

BOOL StartServiceThread()
{
DWORD id;

threadHandle = CreateThread(0, 0,
(LPTHREAD_START_ROUTINE) ServiceExecutionThread, 0, 0, &id);
if (threadHandle != 0)
{
serviceRunning = 1;
return 1;
}
return 0;
// return(threadHandle == 0); //Somehow this line always returns a
non-zero
}

int UpdateSCMStatus (DWORD dwCurrentState, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
DWORD dwWaitHint)
{
int bSuccess;
SERVICE_STATUS serviceStatus;

serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = dwCurrentState;

if (dwCurrentState == SERVICE_START_PENDING)
serviceStatus.dwControlsAccepted = 0;
else
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;

if (dwServiceSpecificExitCode == 0)
serviceStatus.dwWin32ExitCode = dwWin32ExitCode;
else
serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;

serviceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint;
bSuccess = SetServiceStatus(serviceStatusHandle, &serviceStatus);

if (!bSuccess)
KillService();
return bSuccess;
}

void ServiceCtrlHandler (DWORD controlCode)
{
int bSuccess;

switch (controlCode)
{
case SERVICE_CONTROL_PAUSE:
if (serviceRunning && !servicePaused)
{
bSuccess = UpdateSCMStatus(SERVICE_PAUSE_PENDING, NO_ERROR, 0, 1,
1000);
servicePaused = 1;
SuspendThread(threadHandle);
serviceCurrentStatus = SERVICE_PAUSED;
}
break;
case SERVICE_CONTROL_CONTINUE:
if (serviceRunning && servicePaused)
{
bSuccess = UpdateSCMStatus(SERVICE_CONTINUE_PENDING, NO_ERROR, 0,
1, 1000);
servicePaused = 0;
ResumeThread(threadHandle);
serviceCurrentStatus = SERVICE_RUNNING;
}
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_STOP:
if(RESET_ON_MANUAL_STOP)
{
serviceCurrentStatus = SERVICE_STOP_PENDING;
bSuccess = UpdateSCMStatus(SERVICE_STOP_PENDING,
NO_ERROR, 0, 1, 5000);
KillService();
ChangeTimeZone(FOREIGN_TIME_ZONE); //Remove this and the
next line and the service does not crash
UpdateTime();
return;
}
break;
case SERVICE_CONTROL_SHUTDOWN:
serviceCurrentStatus = SERVICE_STOP_PENDING;
bSuccess = UpdateSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 1,
5000);
KillService();
ChangeTimeZone(FOREIGN_TIME_ZONE); //Remove this and the
next line and the service does not crash
UpdateTime();
return;
default:
break;
}

UpdateSCMStatus(serviceCurrentStatus, NO_ERROR, 0, 0, 0);
return;
}

void KillService(void)
{
serviceRunning = 0;
SetEvent(killServiceEvent);
}

void terminateService(int iErr)
{
printf("Killing service: Err(%d)\n", iErr);
KillService();
}

void ChangeTimeZone(char zone[])
{
char command[150];
command[0]='\0';
strcat(command,"RunDLL32 shell32.dll,Control_RunDLL
%SystemRoot%\\system32\\TIMEDATE.cpl,,/Z ");
strcat(command,zone);
system(command);
return;
}

void UpdateTime(void)
{
system("w32tm /resync /nowait");
return;
}
</code></noscript>

Oh, on another note, can anyone point out how to allow the time zone to
be specified via command line arguments? I have no experience in
dealing with arguments in C.

Also, how do I make this service self-installable?

Thank you all in advance!

Nov 8 '06 #1
9 3836
Oh, forgot to mention I'm using Dev-cpp 4.9.9.2, gcc 3.4.2
(mingw-special) and GNU ld 2.15.91 20040904.

Thanks again!

Nov 8 '06 #2
xi******@gmail.com wrote:
Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.
C knows nothing of services or time servers.

<snip highly system specific code>
void main()
The only return type the C standard defines is int, not void, and using
void provides no advantage that I can see.

int main(void)

<snip>

<OT>I'm not convinced using system() from a service is a good idea</OT>

Other than that, you code is highly system specific. Try on a Windows
programming group.
Oh, on another note, can anyone point out how to allow the time zone to
be specified via command line arguments? I have no experience in
dealing with arguments in C.
Look in a real C book (one that does not use void main()) at the allowed
definitions of main. Also play with this

#include <stdio.h>
int main(int argc, char **argv)
{
while (*argv)
puts(*argv++);
return 0;
}

Note that you might not get any arguments, not even a representation of
the program name.
Also, how do I make this service self-installable?
No idea, ask on a Windows group.
--
Flash Gordon
Nov 8 '06 #3
Flash Gordon a écrit :
xi******@gmail.com wrote:
>Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.


C knows nothing of services or time servers.
Translation:

"I think that comp.lang.c is only for discussing concepts that appear
explicitely in the published C standard. Since the C standard doesn't
mention anything about time servers I think you should not discuss it
here"
>
Nov 8 '06 #4
In article <45***********************@news.orange.fr>,
jacob navia <ja***@jacob.remcomp.frwrote:
>Flash Gordon a écrit :
>xi******@gmail.com wrote:
>>Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.
>C knows nothing of services or time servers.
>Translation:
>"I think that comp.lang.c is only for discussing concepts that appear
explicitely in the published C standard. Since the C standard doesn't
mention anything about time servers I think you should not discuss it
here"
If the original poster's code could compile and run on any standard
conforming hosted implementation, there might be *some* room for
the argument that particular algorithms should be discussable.

However, the original poster's code is inherently system specific.
There would be no way to even get it to compile on a non-Windows
system without hacking together extensive headers to define DWORD
and HANDLE and SERVICE_STATUS* and so on.

comp.lang.c is not the place to discuss any random program that happens
to have been written in a C-like language (such as gcc) and which
by choice or by necessity relies upon system-specific extensions.
--
Prototypes are supertypes of their clones. -- maplesoft
Nov 8 '06 #5
2006-11-08 <11**********************@h54g2000cwb.googlegroups .com>,
xi******@gmail.com wrote:
<off topic>
Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.
The service will then restore the original time zone upon stopping and
force another resync.
If you think you need to sync with the time server after changing time
zones, you don't understand how time zones work on windows
</offtopic>
Oh, on another note, can anyone point out how to allow the time zone to
be specified via command line arguments? I have no experience in
dealing with arguments in C.
argc and argv. google on those terms.
Nov 8 '06 #6
jacob navia wrote:
>
Flash Gordon a écrit :
xi******@gmail.com wrote:
Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.

C knows nothing of services or time servers.

Translation:

"I think that comp.lang.c is only for discussing concepts that appear
explicitely in the published C standard. Since the C standard doesn't
mention anything about time servers I think you should not discuss it
here"
I assume that you disagree with that "translation"? How so?

If the question had been related to the standard C part of the
program, rather than the extremely platform-specific concepts of
things like "Windows services", there wouldn't be any problem.
Witness the recent "question on structs" thread, which seemed at
first to be asking about sockets, sockaddr_in structs, and udp
communications, but in reality was a question about C structs
themselves, and was answered here as being on-topic.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Nov 8 '06 #7
jacob navia wrote:
Flash Gordon a écrit :
>xi******@gmail.com wrote:
>>Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.

C knows nothing of services or time servers.

Translation:

"I think that comp.lang.c is only for discussing concepts that appear
explicitely in the published C standard. Since the C standard doesn't
mention anything about time servers I think you should not discuss it
here"
Well, at last you understand. Now try to keep that thought in mind.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Nov 9 '06 #8
Thank you all for explaining to me that this is not the correct place
to post this. I have taken note of your reminders and will move on to a
more system specific group instead.

Thanks.

On Nov 9, 7:10 am, CBFalconer <cbfalco...@yahoo.comwrote:
jacob navia wrote:
Flash Gordon a écrit :
xieli...@gmail.com wrote:
>Hello, I'm attempting to write a WinNT service that basically changes
the time zone and forces a resync with a time server on initialisation.
C knows nothing of services or time servers.
Translation:
"I think that comp.lang.c is only for discussing concepts that appear
explicitely in the published C standard. Since the C standard doesn't
mention anything about time servers I think you should not discuss it
here"Well, at last you understand. Now try to keep that thought in mind.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
Nov 9 '06 #9
xi******@gmail.com wrote:
Thank you all for explaining to me that this is not the correct place
to post this. I have taken note of your reminders and will move on to a
more system specific group instead.

Thanks.

On Nov 9, 7:10 am, CBFalconer <cbfalco...@yahoo.comwrote:
<snip>

We (many of us, I believe) appreciate it when people politely accept
redirect. Thank you. However, you should learn that your reply belongs
under (bottom posting) or interspersed with (sometimes called middle
posting) the text you are replying to, not above it (top posting).
--
Flash Gordon
Nov 9 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Glenn Venzke | last post by:
I'd like to write a windows service. Unfortunately, my company would only spring for the standard edition of VB.NET which doesn't support the creation of windows services. Is it possible to write one...
3
by: Chris Dunaway | last post by:
I am writing a Windows Service that reads and processes files on a set schedule. I want to create a second app that can monitor the Windows service. The Windows service will write trace messages...
8
by: songstre | last post by:
I would like to write a service that handles certain tasks fro a third party back end. There is an API for the back end that I can use to accomplish this, but there are certain calls I have to make...
0
by: =?ISO-8859-1?Q?Mickel_Gr=F6nroos?= | last post by:
Hi fellow pythoneers, I'm thinking about writing a simple web service for use in the "Research Task Pane" in Microsoft Office. There is a lot of C# and VB code samples out there and tutorials on...
5
by: gnanapoongothai | last post by:
hi, i am doing socket programming , and once socket is connected getting data from client and wrting into the file. the file is created but nothing is in it? whats up ? code: WORD...
0
by: Sid Price | last post by:
I am writing a service using VB.NET 2005 and having some trouble getting started. I sued the wizard to create the service and I have added some code to the "OnStart" method. Using the technique...
2
by: Solomon_Man | last post by:
All, I have a Windows Service application that has database connectivity and needs the capability to let a user know that there has been a db failure. What is the proper way to notify a user that...
2
by: cj | last post by:
<System.Web.Services.WebService(Name:="CJ's Service", Description:="Testing 123", Namespace:="http://myco.com/cj/one")_...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.