|
 |
|
|
What is the point of this ?
char m_strName[182];
I mean, how did you come up with 182 as a buffer size ?
Was it just a random number, or did you discover some hidden limit to the size of a service name ?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I am confused by your use of SERVICE_WIN32 as the default ServiceType.
The help for SERVICE_STATUS states that the dwServiceType should be one of the values listed, yet SERVCIE_WIN32 is a bitwise or of two of the possible values - and seems to be use primarily for enumeration of services.
Members dwServiceType Type of service. This member can be one of the following values. Value Meaning SERVICE_FILE_SYSTEM_DRIVER The service is a file system driver. SERVICE_KERNEL_DRIVER The service is a device driver. SERVICE_WIN32_OWN_PROCESS The service runs in its own process. SERVICE_WIN32_SHARE_PROCESS The service shares a process with other services.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
File: cservice_base_src.zip : I_ServiceBase.cpp
void CI_ServiceBase::set_CanHandlePowerEvent(bool b) { //SET_BIT(this->m_CanHandle, P_CAN_HANDLE_POWER_EVENT, b); if(b) { m_Status.dwControlsAccepted |= SERVICE_ACCEPT_POWEREVENT; } else { m_Status.dwControlsAccepted ^= SERVICE_ACCEPT_POWEREVENT; } }
Please tell me you're kidding. Do you know what ^ means? It means XOR, it means toggle. set_CanHandlePowerEvent(true) will always turn on the flag, but set_CanHandlePowerEvent(false) will not always turn it off.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Ok, I was not long time here. But here is the answer just for the archive.
if SERVICE_ACCEPT_POWEREVENT bits are set already, this operation: m_Status.dwControlsAccepted ^= SERVICE_ACCEPT_POWEREVENT; will do turn off, that's for shure.
Thank You
Faruk Kasumovic. Student of Electrical Enginering (Information Technologies) in Tuzla, Bosnia and Herzegovina.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Just so I understand, is this what you want to achieve in this code?
set_CanHandlePowerEvent(true) = turn "on" SERVICE_ACCEPT_POWEREVENT
set_CanHandlePowerEvent(false) *and* SERVICE_ACCEPT_POWEREVENT is currently "on" = turn "off" SERVICE_ACCEPT_POWEREVENT set_CanHandlePowerEvent(false) *and* SERVICE_ACCEPT_POWEREVENT is currently "off" = turn "on" SERVICE_ACCEPT_POWEREVENT
This is what your code currently does. Just making sure I understand. Thanks.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Clearly what is really desired is this:
void CI_ServiceBase::set_CanHandlePowerEvent(bool b) { if(b) { m_Status.dwControlsAccepted |= SERVICE_ACCEPT_POWEREVENT; } else { m_Status.dwControlsAccepted &= ~SERVICE_ACCEPT_POWEREVENT; } }
which has the expected results of:
set_CanHandlePowerEvent(true) = turn "on" SERVICE_ACCEPT_POWEREVENT set_CanHandlePowerEvent(false) = turn "off" SERVICE_ACCEPT_POWEREVENT
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Cute article. However, your class seems to be missing some pieces...
1. When a service starts up, a standard initialisation function is called which, as the name implies, initialises the service and any resources that may be needed. What if a programmer using your class wanted to do more in the initialisation?
2. How does one send hints to the SCUM during a lengthy initialisation process?
Cheers, Peter
www.kinkycode.com [Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs, Fix 1 bug, recompile.... 101 little bugs in the code...
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks, I will add it in next article update.
Faruk Kasumovic. Student of Electrical Enginering (Information Technologies) in Tuzla, Bosnia and Herzegovina.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
 |
|
|
dog_spawn wrote: Strange! What is this all about?
The drunken cat is calling the base class destructor, to make sure things get cleaned up. Strange indeed. 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
In case when base class destructor is not declared as virtual, he will not be called in derived class destructor, you have to call it explicit to release any resources used by base class. It's C++.
When I wrote the sample code I just do it for habit, but it should not produce the problem even if base class destructor is virtual.
Faruk Kasumovic. Student of Electrical Enginering (Information Technologies) in Tuzla, Bosnia and Herzegovina.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
>>In case when base class destructor is not declared as virtual, he will not be called in derived class destructor, you have to call it explicit to release any resources used by base class. It's C++.
NO IT'S NOT C++ !!!
#include
using std::cout; using std::endl;
class b_virt { public: b_virt(){} virtual ~b_virt(){ cout << "b_virt virtual destructor" << endl; } };
class b_std { public: b_std(){} ~b_std(){ cout << "b_std destructor" << endl; } };
class d_virt : public b_virt { public: d_virt(){} ~d_virt(){ cout << "d_virt derived destructor" << endl; } };
class d_std : public b_std { public: d_std(){} ~d_std(){ cout << "d_std derived destructor" << endl; } };
int main(int argc, char* argv[]) { d_virt dv; d_std ds;
return 0; }
produces this:
d_std derived destructor b_std destructor d_virt derived destructor b_virt virtual destructor
Notice there is no explicit call to either destructor, yet *somehow*, this code magically calls the virtual destructor in class b_virt. That is C++ !
It is not necessary to call the base clas destructor from within the derived class, the compiler will generate code to do this, just as it generates code to call destructors on class members.
>>When I wrote the sample code I just do it for habit, but it should not produce the problem even if base class destructor is virtual.
It is very dangerous to assume it is safe to call a destructor twice. Your habit is dangerous, and you should stop it. Your code is otherwise quite good.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Maybe it worth to clarify this virtual destructor thing a bit. The problem occurs, when you have derived classes which allocates system resources in overridden virtual methods. If your destructor is not virtual, it can happen that these resources will not be released at all. A small - stupid - example:
class base { public: ~base() { /* nothing to do */ } virtual const char * getString() { return "a string"; } }
class derived : public base { public: derived() : m_str(0) {}
~derived() { if ( m_str != 0 ) { free(m_str); } }
const char * getString() { if ( m_str == 0 ) { m_str = strdup("another string"); } return m_str; }
private: char * m_str; }
...
base * a = new base(); derived * b = new derived(); base * c = new derived();
// virtual method works well: cout << a.getString(); // call of base::getString() - 'a string' cout << b.getString(); // call of derived::getString() - 'another string' cout << c.getString(); // call of derived::getString() - 'another string'
// as the destructor is NOT virtual, it will NOT work similar: delete a; // call of ~base() delete b; // call of ~derived() delete c; // oops! call of ~base() - derived::m_str is not cleaned up!!!
Solution of such problems is clear: use virtual destructor. As a rule of thumb, use virtual destructor if you has virtual method. I hope this helps to clarify virtual destructor a bit.
Gy
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |