OSDN Git Service

initial files
[iptd/iPTd_R3.git] / src / Raym / Service.cpp
1 /**\r
2  * @file Service.cpp\r
3  *\r
4  */\r
5 \r
6 #include <process.h>\r
7 \r
8 #define DBG_LEVEL 3\r
9 #include "Raym/Log.h"\r
10 #include "Raym/Raym.h"\r
11 \r
12 namespace Raym\r
13 {\r
14 \r
15 static Service *sharedService_  = NULL;\r
16 \r
17 DWORD WINAPI _HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)\r
18 {\r
19     DebugLog2("%s() start.", __FUNCTION__);\r
20 \r
21     DWORD result = ERROR_CALL_NOT_IMPLEMENTED;\r
22 \r
23     Service *service = (Service *)lpContext;\r
24     SERVICE_STATUS ss;\r
25 \r
26     switch (dwControl)\r
27     {\r
28     case SERVICE_CONTROL_STOP:\r
29     case SERVICE_CONTROL_PRESHUTDOWN:\r
30 \r
31         ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;\r
32         ss.dwWin32ExitCode = NO_ERROR;\r
33         ss.dwServiceSpecificExitCode = 0;\r
34         ss.dwCheckPoint = 1;\r
35         ss.dwWaitHint = 50000;\r
36         ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN;\r
37         ss.dwCurrentState = SERVICE_STOP_PENDING;\r
38 \r
39         if (service->setServiceStatus(&ss))\r
40         {\r
41             DebugLog2("call stop()");\r
42             service->stop();\r
43 \r
44             ss.dwCurrentState = SERVICE_STOPPED;\r
45             ss.dwCheckPoint = 0;\r
46             ss.dwWaitHint = 0;\r
47               \r
48             if (!service->setServiceStatus(&ss))\r
49             {\r
50                 DebugLog0("error: SetServiceStatus(): %u", GetLastError());\r
51             }\r
52         }\r
53         else\r
54         {\r
55             DebugLog0("error: SetServiceStatus(): %u", GetLastError());\r
56         }\r
57 \r
58         result = NO_ERROR;\r
59         break;\r
60     }\r
61 \r
62     DebugLog2("%s() end.", __FUNCTION__);\r
63 \r
64     return result;\r
65 }\r
66 \r
67 VOID WINAPI _ServiceMain(DWORD dwArgc, PTSTR* pszArgv)\r
68 {\r
69     if (sharedService_ != NULL)\r
70     {\r
71         sharedService_->serviceMain(dwArgc, pszArgv);\r
72     }\r
73 }\r
74 \r
75 void Service::serviceMain(DWORD dwArgc, PTSTR* pszArgv)\r
76 {\r
77     DebugLog2("%s() start.", __FUNCTION__);\r
78 \r
79     _serviceStatus = RegisterServiceCtrlHandlerEx(_serviceName, _HandlerEx, this);\r
80     if (_serviceStatus == NULL)\r
81     {\r
82         DebugLog0("error: RegisterServiceCtrlHandler(): %u", GetLastError());\r
83         return;\r
84     }\r
85 \r
86     SERVICE_STATUS ss;\r
87     ss.dwServiceType = SERVICE_WIN32_OWN_PROCESS;\r
88     ss.dwWin32ExitCode = NO_ERROR;\r
89     ss.dwServiceSpecificExitCode = 0;\r
90     ss.dwCheckPoint = 1;\r
91     ss.dwWaitHint = 15000;\r
92     ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PRESHUTDOWN;\r
93     ss.dwCurrentState = SERVICE_START_PENDING;\r
94 \r
95     if (!SetServiceStatus(_serviceStatus, &ss))\r
96     {\r
97         DebugLog0("error: SetServiceStatus(): %u", GetLastError());\r
98         return;\r
99     }\r
100 \r
101     //\r
102     start();\r
103 \r
104     DebugLog2("%s() end.", __FUNCTION__);\r
105 }\r
106 \r
107 Service::Service()\r
108 {\r
109     DebugLog2("%s", __FUNCTION__);\r
110 }\r
111 \r
112 Service::~Service()\r
113 {\r
114     DebugLog2("%s", __FUNCTION__);\r
115 }\r
116 \r
117 int Service::main(Service *(*allocator)(), LPWSTR serviceName, int argc, char *argv[])\r
118 {\r
119     int result = -1;\r
120 \r
121 #ifdef RAYM_MEMORY_CHECK\r
122     DebugLog0("");\r
123     DebugLog0("Service::main() global_raym_count_ = %d", Raym::global_raym_count_);\r
124 #endif\r
125 \r
126     // ARP生成\r
127     AutoreleasePool *pool = AutoreleasePool::alloc()->init();\r
128 \r
129     // winsockの初期化\r
130     WSADATA wsaData;\r
131     WSAStartup(MAKEWORD(2,2), &wsaData);\r
132 \r
133     SERVICE_TABLE_ENTRY ServiceTable[] =\r
134     {\r
135         {serviceName, _ServiceMain},\r
136         {NULL, NULL}\r
137     };\r
138 \r
139     sharedService_ = allocator();\r
140 \r
141     if (sharedService_ != NULL)\r
142     {\r
143         if (sharedService_->init(serviceName))\r
144         {\r
145             StartServiceCtrlDispatcher(ServiceTable);\r
146         }\r
147     }\r
148 \r
149     sharedService_->release();\r
150 \r
151     // winsockのリソース解放\r
152     WSACleanup();\r
153 \r
154     // ARP解放\r
155     pool->release();\r
156 \r
157 #ifdef RAYM_MEMORY_CHECK\r
158     DebugLog0("Service::main() global_raym_count_ = %d", Raym::global_raym_count_);\r
159 #endif\r
160 \r
161     return result;\r
162 }\r
163 \r
164 Service *Service::init(LPWSTR serviceName)\r
165 {\r
166     _serviceName = serviceName;\r
167     _serviceStatus = NULL;\r
168     return this;\r
169 }\r
170 \r
171 bool Service::setServiceStatus(SERVICE_STATUS *ss)\r
172 {\r
173     return SetServiceStatus(_serviceStatus, ss) ? true : false;\r
174 }\r
175 \r
176 void Service::start()\r
177 {\r
178     DebugLog2("%s", __FUNCTION__);\r
179 }\r
180 \r
181 void Service::stop()\r
182 {\r
183     DebugLog2("%s", __FUNCTION__);\r
184 }\r
185 \r
186 void Service::sleep()\r
187 {\r
188     DebugLog2("%s", __FUNCTION__);\r
189 }\r
190 \r
191 void Service::shutdown()\r
192 {\r
193     DebugLog2("%s", __FUNCTION__);\r
194     system("shutdown /s /t 180");\r
195 }\r
196 \r
197 void Service::cancelShutdown()\r
198 {\r
199     DebugLog2("%s", __FUNCTION__);\r
200     system("shutdown /a");\r
201 }\r
202 \r
203 bool Service::setWakeSchedule(int year, int month, int day, int hour, int min)\r
204 {\r
205     return false;\r
206 }\r
207 \r
208 void Service::resetWakeSchedule()\r
209 {\r
210 }\r
211 \r
212 //\r
213 // remark: This function is not thread safe.\r
214 //\r
215 const char *Service::GetHomeDirectory(void)\r
216 {\r
217     static char home_directory_[MAX_PATH + 1];\r
218 \r
219     memset(home_directory_, 0x00, sizeof(home_directory_));\r
220 \r
221     TCHAR strbuf[MAX_PATH + 1];\r
222     size_t len = GetEnvironmentVariable(L"USERPROFILE", strbuf, sizeof(strbuf));\r
223     if (len > 0)\r
224     {\r
225         errno_t e;\r
226         size_t returnValue;\r
227         e = wcstombs_s(&returnValue, home_directory_, sizeof(home_directory_), strbuf, _TRUNCATE);\r
228         if (e == 0)\r
229         {\r
230             return home_directory_;\r
231         }\r
232     }\r
233     return NULL;\r
234 }\r
235 \r
236 //\r
237 // remark: This function is not thread safe.\r
238 //\r
239 const char *Service::GetExecutePath(void)\r
240 {\r
241     static char execute_path_[MAX_PATH + 1];\r
242     memset(execute_path_, 0x00, sizeof(execute_path_));\r
243 \r
244     TCHAR strbuf[MAX_PATH + 1];\r
245     if (GetModuleFileName(NULL, strbuf, MAX_PATH) != 0)\r
246     {\r
247         errno_t e;\r
248         size_t returnValue;\r
249         e = wcstombs_s(&returnValue, execute_path_, sizeof(execute_path_), strbuf, _TRUNCATE);\r
250         if (e == 0)\r
251         {\r
252             return execute_path_;\r
253         }\r
254     }\r
255     return NULL;\r
256 }\r
257 \r
258 //\r
259 // remark: This function is not thread safe.\r
260 //\r
261 const char *Service::GetPublicDirectory(void)\r
262 {\r
263     static char public_directory_[MAX_PATH + 1];\r
264 \r
265     memset(public_directory_, 0x00, sizeof(public_directory_));\r
266 \r
267     TCHAR strbuf[MAX_PATH + 1];\r
268     size_t len = GetEnvironmentVariable(L"PUBLIC", strbuf, sizeof(strbuf));\r
269     if (len > 0)\r
270     {\r
271         errno_t e;\r
272         size_t returnValue;\r
273         e = wcstombs_s(&returnValue, public_directory_, sizeof(public_directory_), strbuf, _TRUNCATE);\r
274         if (e == 0)\r
275         {\r
276             return public_directory_;\r
277         }\r
278     }\r
279     return NULL;\r
280 }\r
281 \r
282 } // Raym\r