source: anotherchoice/tags/jsp-1.4.4-full-UTF8/windev/devicemanager/devicemanager.cpp@ 26

Last change on this file since 26 was 26, checked in by ykominami, 12 years ago

initial

File size: 12.5 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 *
9 * 上記著作権者
10は,以下の (1)〜(4) の条件か,Free Software Foundation
11 * によってå…
12¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
13 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
16 * 利用と呼ぶ)することを無償で許諾する.
17 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
18 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
19 * スコード中に含まれていること.
20 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
21 * 用できる形で再é…
22å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
23å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
24 * 者
25マニュアルなど)に,上記の著作権表示,この利用条件および下記
26 * の無保証規定を掲載すること.
27 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
28 * 用できない形で再é…
29å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
30 * と.
31 * (a) 再é…
32å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
33マニュアルなど)に,上記の著
34 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
35 * (b) 再é…
36å¸ƒã®å½¢æ…
37‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
38 * 報告すること.
39 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
40 * 害からも,上記著作権者
41およびTOPPERSプロジェクトをå…
42è²¬ã™ã‚‹ã“と.
43 *
44 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
45お
46 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
47 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
48 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
49 *
50 * @(#) $Id: devicemanager.cpp,v 1.11 2003/12/24 07:40:42 takayuki Exp $
51 */
52
53#include "stdafx.h"
54#include "resource.h"
55#include <initguid.h>
56#include <shellapi.h>
57#include "devicemanager.h"
58#include <commctrl.h>
59
60#include "devicemanager_i.c"
61#include "device.h"
62#include "information.h"
63#include "kernel.h"
64#include "kernellog.h"
65
66#define WM_NOTIFYICONCALLBACK (WM_APP+1) //NotifyIconから受け取るメッセージに使う番号
67
68const DWORD dwTimeOut = 5000; // EXEがシャットダウンするまでのアイドル時間です
69const DWORD dwPause = 1000; // スレッドが終わるのを待
70つ時間です
71
72HINSTANCE ProcessInstance = NULL; //プロセスのインスタンスハンドル
73
74
75// シャットダウン イベント監視用の CreateThread に渡されます
76static DWORD WINAPI MonitorProc(void* pv)
77{
78 CExeModule* p = (CExeModule*)pv;
79 p->MonitorShutdown();
80 return 0;
81}
82
83LONG CExeModule::Unlock()
84{
85 LONG l = CComModule::Unlock();
86 if (l == 0)
87 {
88 bActivity = true;
89 SetEvent(hEventShutdown); // モニターにゼロに変移したことをしらせます
90 }
91 return l;
92}
93
94//シャットダウンイベントを監視します
95void CExeModule::MonitorShutdown()
96{
97 while (1)
98 {
99 WaitForSingleObject(hEventShutdown, INFINITE);
100 DWORD dwWait=0;
101 do
102 {
103 bActivity = false;
104 dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut);
105 } while (dwWait == WAIT_OBJECT_0);
106 // timed out
107 if (!bActivity && m_nLockCnt == 0) // 何も動作しているものがなければ抜け出します
108 {
109#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
110 CoSuspendClassObjects();
111 if (!bActivity && m_nLockCnt == 0)
112#endif
113 break;
114 }
115 }
116 CloseHandle(hEventShutdown);
117 PostThreadMessage(dwThreadID, WM_QUIT, 0, 0);
118}
119
120bool CExeModule::StartMonitor()
121{
122 hEventShutdown = CreateEvent(NULL, false, false, NULL);
123 if (hEventShutdown == NULL)
124 return false;
125 DWORD dwThreadID;
126 HANDLE h = CreateThread(NULL, 0, MonitorProc, this, 0, &dwThreadID);
127 return (h != NULL);
128}
129
130CExeModule _Module;
131
132BEGIN_OBJECT_MAP(ObjectMap)
133OBJECT_ENTRY(CLSID_Device, CDevice)
134OBJECT_ENTRY(CLSID_Information, CInformation)
135OBJECT_ENTRY(CLSID_Kernel, CKernel)
136OBJECT_ENTRY(CLSID_KernelLog, CKernelLog)
137END_OBJECT_MAP()
138
139
140LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
141{
142 while (p1 != NULL && *p1 != NULL)
143 {
144 LPCTSTR p = p2;
145 while (p != NULL && *p != NULL)
146 {
147 if (*p1 == *p)
148 return CharNext(p1);
149 p = CharNext(p);
150 }
151 p1 = CharNext(p1);
152 }
153 return NULL;
154}
155
156static void InsertAllDeviceMapList(HWND hList)
157{
158 _TCHAR buffer[64];
159 std::map<Range, class CDevice *>::iterator scope;
160 LVITEM item;
161 int index;
162 int length = 0;
163
164 ListView_DeleteAllItems(hList);
165 item.iItem = -1;
166
167 EnterCriticalSection(&_Module.cs);
168
169 scope = _Module.DeviceMap.begin();
170 while(scope != _Module.DeviceMap.end()) {
171 _TCHAR * strbuf = (_TCHAR *)(BSTR)scope->second->DeviceName;
172
173#ifndef _UNICODE
174 length = WideCharToMultiByte(CP_ACP, 0, (BSTR)scope->second->DeviceName, -1, 0, 0, NULL, NULL);
175 if(length != 0) {
176 strbuf = new _TCHAR [length + 1];
177 WideCharToMultiByte(CP_ACP, 0, (BSTR)scope->second->DeviceName, length, (char *)strbuf, length, NULL, NULL);
178 }
179 else
180 strbuf = _T("<unknown>");
181#endif
182
183 item.mask = LVIF_TEXT;
184 ++ item.iItem;
185 item.iSubItem = 0;
186 item.pszText = strbuf;
187 index = ListView_InsertItem(hList, &item);
188
189 if(length != 0)
190 delete [] strbuf;
191
192 wsprintf(buffer, _T("0x%08X -- 0x%08X"), scope->first.GetBase(), scope->first.GetBase() + scope->first.GetLength() - 1);
193 ListView_SetItemText(hList, index, 1, buffer);
194
195 ++ scope;
196 }
197
198 LeaveCriticalSection(&_Module.cs);
199}
200
201
202
203INT CALLBACK MemoryMapDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
204{
205 switch(msg) {
206 case WM_INITDIALOG:
207 {
208 LVCOLUMN col;
209
210 HWND hList = GetDlgItem(hDlg, IDC_MAPLIST);
211
212 col.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_FMT;
213 col.fmt = LVCFMT_LEFT;
214 col.pszText = _T("デバイス名");
215 col.cx = 200;
216 ListView_InsertColumn(hList, 0, &col);
217
218 col.mask = LVCF_TEXT|LVCF_SUBITEM|LVCF_WIDTH|LVCF_FMT;
219 col.pszText = _T("アドレス範囲");
220 col.iSubItem = 1;
221 col.cx = 230;
222 ListView_InsertColumn(hList, 1, &col);
223
224 InsertAllDeviceMapList(hList);
225
226 break;
227 }
228
229 case WM_COMMAND:
230 switch(wParam) {
231 case IDOK:
232 DestroyWindow(hDlg);
233 break;
234 default:
235 FALSE;
236 }
237 break;
238
239 case WM_CLOSE:
240 DestroyWindow(hDlg);
241 break;
242
243 default:
244 return FALSE;
245 }
246
247 return TRUE;
248}
249
250void ShowMemoryMapDialog(HWND hParent)
251{
252 HWND hDlg = CreateDialog(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDD_MAPLISTDIALOG), hParent, MemoryMapDialogProc);
253 ShowWindow(hDlg, SW_SHOW);
254}
255
256
257//---------------------------------------------------------------------
258// NotifyIcon コンテキストメニュー
259INT DummyDialogContextMenu(HWND hDlg)
260{
261 enum tagMenuID {
262 IDM_EXIT = 1,
263 IDM_MAPLIST = 2
264 };
265
266 _TCHAR buffer[128];
267
268 HMENU hMenu = CreatePopupMenu();
269 if(hMenu == NULL)
270 return 0;
271
272 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, 0, _Module.Kernel != 0 ? _T("カーネル起動中") : _T("カーネル未接続"));
273 wsprintf(buffer, _T("接続デバイス数 : %d"), _Module.DeviceList.size());
274 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, 0, buffer);
275 wsprintf(buffer, _T("割付済み空間数 : %d"), _Module.DeviceMap.size());
276 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, 0, buffer);
277 wsprintf(buffer, _T("接続ウォッチャ数 : %d"), _Module.WatcherList.size());
278 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, 0, buffer);
279 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL);
280 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, IDM_MAPLIST, _T("メモリマップ表示"));
281 InsertMenu(hMenu, -1, MF_BYPOSITION|MF_STRING, IDM_EXIT, _T("強制終了"));
282
283 POINT curpos = {0,0};
284 GetCursorPos(&curpos);
285
286 int cmd = TrackPopupMenu(hMenu, TPM_RIGHTALIGN|TPM_BOTTOMALIGN|TPM_RETURNCMD|TPM_RIGHTBUTTON, curpos.x, curpos.y, 0, hDlg, NULL);
287
288 switch(cmd) {
289 case IDM_EXIT:
290 PostQuitMessage(0);
291 break;
292 case IDM_MAPLIST:
293 ShowMemoryMapDialog(hDlg);
294 break;
295 default:
296 break;
297 }
298
299 return cmd;
300}
301
302
303//---------------------------------------------------------------------
304// NotifyIcon用のダミーダイアログ メッセージハンドラ
305INT CALLBACK DummyDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
306{
307 switch(msg) {
308
309 case WM_NOTIFYICONCALLBACK:
310 switch(lParam) {
311 case WM_RBUTTONUP:
312 DummyDialogContextMenu(hDlg);
313 break;
314 default:
315 return FALSE;
316 }
317 break;
318
319 case WM_INITDIALOG:
320 {
321 /* タスクトレイにアイコンを登録 */
322 NOTIFYICONDATA nd;
323 HICON hIcon = LoadIcon(ProcessInstance, MAKEINTRESOURCE(IDI_ICON1));
324 nd.cbSize = sizeof(nd);
325 nd.hWnd = hDlg;
326 nd.uID = 100;
327 nd.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
328 nd.hIcon = hIcon;
329 nd.uCallbackMessage = WM_NOTIFYICONCALLBACK;
330 ::lstrcpy(nd.szTip, _T("TOPPERS/JSP DeviceManager"));
331 Shell_NotifyIcon(NIM_ADD, &nd);
332
333 break;
334 }
335
336 case WM_DESTROY:
337 {
338 NOTIFYICONDATA nd;
339 nd.cbSize = sizeof(nd);
340 nd.hWnd = hDlg;
341 nd.uID = 100;
342 nd.uFlags = 0;
343 Shell_NotifyIcon(NIM_DELETE, &nd);
344 break;
345 }
346
347 default:
348 return FALSE;
349 }
350
351 return TRUE;
352}
353
354
355/////////////////////////////////////////////////////////////////////////////
356//
357extern "C" int WINAPI _tWinMain(HINSTANCE hInstance,
358 HINSTANCE /*hPrevInstance*/, LPTSTR lpCmdLine, int /*nShowCmd*/)
359{
360 lpCmdLine = GetCommandLine(); // この行は _ATL_MIN_CRT のために必
361要です
362
363#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
364 HRESULT hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
365#else
366 HRESULT hRes = CoInitialize(NULL);
367#endif
368 _ASSERTE(SUCCEEDED(hRes));
369 _Module.Init(ObjectMap, hInstance, &LIBID_ATLDEVICEMANAGERLib);
370 _Module.dwThreadID = GetCurrentThreadId();
371 TCHAR szTokens[] = _T("-/");
372
373 int nRet = 0;
374 BOOL bRun = TRUE;
375 LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
376 while (lpszToken != NULL)
377 {
378 if (lstrcmpi(lpszToken, _T("UnregServer"))==0)
379 {
380 _Module.UpdateRegistryFromResource(IDR_ATLDeviceManager, FALSE);
381 nRet = _Module.UnregisterServer(TRUE);
382 bRun = FALSE;
383 break;
384 }
385 if (lstrcmpi(lpszToken, _T("RegServer"))==0)
386 {
387 _Module.UpdateRegistryFromResource(IDR_ATLDeviceManager, TRUE);
388 nRet = _Module.RegisterServer(TRUE);
389 bRun = FALSE;
390 break;
391 }
392 lpszToken = FindOneOf(lpszToken, szTokens);
393 }
394
395 if (bRun)
396 {
397 HWND dummy_dialog_handle = NULL;
398
399 //::AllocConsole();
400
401 ProcessInstance = hInstance;
402 dummy_dialog_handle = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DUMMYDIALOG), NULL, DummyDialogProc);
403 ShowWindow(dummy_dialog_handle, SW_HIDE);
404
405 _Module.StartMonitor();
406#if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED)
407 hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
408 REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED);
409 _ASSERTE(SUCCEEDED(hRes));
410 hRes = CoResumeClassObjects();
411#else
412 hRes = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
413 REGCLS_MULTIPLEUSE);
414#endif
415 _ASSERTE(SUCCEEDED(hRes));
416
417 MSG msg;
418 while (GetMessage(&msg, 0, 0, 0))
419 DispatchMessage(&msg);
420
421 _Module.RevokeClassObjects();
422 Sleep(dwPause); //スレッドが終了するまで待
423ちます
424
425 if(dummy_dialog_handle != NULL)
426 ::DestroyWindow(dummy_dialog_handle);
427
428 ::FreeConsole();
429 }
430
431 _Module.Term();
432 CoUninitialize();
433 return nRet;
434}
Note: See TracBrowser for help on using the repository browser.