提交 | 用户 | age
418cb3 1 
Q 2 // ConfigTool.cpp: 定义应用程序的类行为。
3 //
4
5 #include "pch.h"
6 #include "framework.h"
7 #include "afxwinappex.h"
8 #include "afxdialogex.h"
9 #include "ConfigTool.h"
10 #include "MainFrm.h"
11
12 #include "ConfigToolDoc.h"
13 #include "ConfigToolView.h"
14
15 #ifdef _DEBUG
16 #define new DEBUG_NEW
17 #endif
18
19 #include <devguid.h>
20 #include <SetupAPI.h>
21
22 #include <eh.h>
23 #include <dbghelp.h>
24 #pragma comment(lib,"dbghelp.lib")
25 #pragma comment(lib,"SetupAPI.lib")
26
27 MHash MyCfg1;
28 Logger myLogger1;
29
30 MHash DeviceList;
31
32 // CConfigToolApp
33
34 BEGIN_MESSAGE_MAP(CConfigToolApp, CWinApp)
35     ON_COMMAND(ID_APP_ABOUT, &CConfigToolApp::OnAppAbout)
36     // 基于文件的标准文档命令
37     ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
38     ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
39     // 标准打印设置命令
40     ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
41 END_MESSAGE_MAP()
42
43
44 // CConfigToolApp 构造
45
46 CConfigToolApp::CConfigToolApp() noexcept
47 {
48     // 支持重新启动管理器
49     m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;
50 #ifdef _MANAGED
51     // 如果应用程序是利用公共语言运行时支持(/clr)构建的,则: 
52     //     1) 必须有此附加设置,“重新启动管理器”支持才能正常工作。
53     //     2) 在您的项目中,您必须按照生成顺序向 System.Windows.Forms 添加引用。
54     System::Windows::Forms::Application::SetUnhandledExceptionMode(System::Windows::Forms::UnhandledExceptionMode::ThrowException);
55 #endif
56
57     // TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式
58     //为 CompanyName.ProductName.SubProduct.VersionInformation
59     SetAppID(_T("ConfigTool.AppID.NoVersion"));
60
61     // TODO: 在此处添加构造代码,
62     // 将所有重要的初始化放置在 InitInstance 中
63 }
64
65 // 唯一的 CConfigToolApp 对象
66
67 CConfigToolApp theApp;
68
69
70 // CConfigToolApp 初始化
71
72 BOOL CConfigToolApp::InitInstance()
73 {
74     // 如果一个运行在 Windows XP 上的应用程序清单指定要
75     // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
76     //则需要 InitCommonControlsEx()。  否则,将无法创建窗口。
77     INITCOMMONCONTROLSEX InitCtrls;
78     InitCtrls.dwSize = sizeof(InitCtrls);
79     // 将它设置为包括所有要在应用程序中使用的
80     // 公共控件类。
81     InitCtrls.dwICC = ICC_WIN95_CLASSES;
82     InitCommonControlsEx(&InitCtrls);
83
84     CWinApp::InitInstance();
85
86
87     // 初始化 OLE 库
88     if (!AfxOleInit())
89     {
90         AfxMessageBox(IDP_OLE_INIT_FAILED);
91         return FALSE;
92     }
93
94     AfxEnableControlContainer();
95
96     EnableTaskbarInteraction(FALSE);
97
98     // 使用 RichEdit 控件需要 AfxInitRichEdit2()
99     // AfxInitRichEdit2();
100
101     // 标准初始化
102     // 如果未使用这些功能并希望减小
103     // 最终可执行文件的大小,则应移除下列
104     // 不需要的特定初始化例程
105     // 更改用于存储设置的注册表项
106     // TODO: 应适当修改该字符串,
107     // 例如修改为公司或组织名
108     SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
109     LoadStdProfileSettings(4);  // 加载标准 INI 文件选项(包括 MRU)
110
111     DeviceList.LoadFromFile(_T("./DeviceList.Ini"));
112
113     // 注册应用程序的文档模板。  文档模板
114     // 将用作文档、框架窗口和视图之间的连接
115     CSingleDocTemplate* pDocTemplate;
116     pDocTemplate = new CSingleDocTemplate(
117         IDR_MAINFRAME,
118         RUNTIME_CLASS(CConfigToolDoc),
119         RUNTIME_CLASS(CMainFrame),       // 主 SDI 框架窗口
120         RUNTIME_CLASS(CConfigToolView));
121     if (!pDocTemplate)
122         return FALSE;
123     AddDocTemplate(pDocTemplate);
124
125
126     // 分析标准 shell 命令、DDE、打开文件操作的命令行
127     CCommandLineInfo cmdInfo;
128     ParseCommandLine(cmdInfo);
129
130 //    if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
131 //        cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
132
133     // 调度在命令行中指定的命令。  如果
134     // 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
135     if (!ProcessShellCommand(cmdInfo))
136         return FALSE;
137
138     // 唯一的一个窗口已初始化,因此显示它并对其进行更新
139     m_pMainWnd->ShowWindow(m_nCmdShow);
140     m_pMainWnd->UpdateWindow();
141     return TRUE;
142 }
143
144 int CConfigToolApp::ExitInstance()
145 {
146     //TODO: 处理可能已添加的附加资源
147     AfxOleTerm(FALSE);
148
149     return CWinApp::ExitInstance();
150 }
151
152 // CConfigToolApp 消息处理程序
153
154
155 // 用于应用程序“关于”菜单项的 CAboutDlg 对话框
156
157 class CAboutDlg : public CDialogEx
158 {
159 public:
160     CAboutDlg() noexcept;
161
162 // 对话框数据
163 #ifdef AFX_DESIGN_TIME
164     enum { IDD = IDD_ABOUTBOX };
165 #endif
166
167 protected:
168     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持
169
170 // 实现
171 protected:
172     DECLARE_MESSAGE_MAP()
173 };
174
175 CAboutDlg::CAboutDlg() noexcept : CDialogEx(IDD_ABOUTBOX)
176 {
177 }
178
179 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
180 {
181     CDialogEx::DoDataExchange(pDX);
182 }
183
184 BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
185 END_MESSAGE_MAP()
186
187 // 用于运行对话框的应用程序命令
188 void CConfigToolApp::OnAppAbout()
189 {
190     CAboutDlg aboutDlg;
191     aboutDlg.DoModal();
192 }
193
194 // CConfigToolApp 消息处理程序
195
196
197
198
199
200 int SysLog(CString s, int channel)
201 {
202     myLogger1.LogTxt(s, channel);
203     return 1;
204 }
205
206 int DbgLog(CString s, int channel)
207 {
208     myLogger1.LogTxt(s, channel);
209     return 1;
210 }
211
212 int PopupMessage(CString Msg, int channel)
213 {
214     Msg.Trim(_T("\r\n"));
215     SysLog(_T("报警信息: ") + Msg + _T("\r\n"), channel);
216     return 0;
217 }
218
219 void DoEvents()
220 {
221     MSG msg;
222     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
223     {
224         DispatchMessage(&msg);
225         TranslateMessage(&msg);
226     }
227 }
228
229 void dump_callstack(PCONTEXT pcontext, CString & infostr)
230 {
231 #ifdef _WIN64
232
233     STACKFRAME64 sf;
234     memset(&sf, 0, sizeof(STACKFRAME64));
235
236     sf.AddrPC.Offset = pcontext->Rip;
237     //context->
238     sf.AddrPC.Mode = AddrModeFlat;
239     sf.AddrStack.Offset = pcontext->Rsp;
240     sf.AddrStack.Mode = AddrModeFlat;
241     sf.AddrFrame.Offset = pcontext->Rbp;
242     sf.AddrFrame.Mode = AddrModeFlat;
243
244     DWORD machineType = //IMAGE_FILE_MACHINE_I386;
245         IMAGE_FILE_MACHINE_AMD64;
246 #elif defined _WIN32
247     STACKFRAME sf;
248     memset(&sf, 0, sizeof(STACKFRAME));
249
250     sf.AddrPC.Offset = pcontext->Eip;
251     //context->
252     sf.AddrPC.Mode = AddrModeFlat;
253     sf.AddrStack.Offset = pcontext->Esp;
254     sf.AddrStack.Mode = AddrModeFlat;
255     sf.AddrFrame.Offset = pcontext->Ebp;
256     sf.AddrFrame.Mode = AddrModeFlat;
257
258     DWORD machineType = //IMAGE_FILE_MACHINE_I386;
259         IMAGE_FILE_MACHINE_AMD64;
260 #endif
261     HANDLE hProcess = GetCurrentProcess();
262     HANDLE hThread = GetCurrentThread();
263
264     for (;;)
265     {
266         if (!StackWalk(machineType, hProcess, hThread, &sf, pcontext, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
267         {
268             break;
269         }
270
271         if (sf.AddrFrame.Offset == 0)
272         {
273             break;
274         }
275         BYTE symbolBuffer[sizeof(SYMBOL_INFO) + 1024];
276         PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
277
278         pSymbol->SizeOfStruct = sizeof(symbolBuffer);
279         pSymbol->MaxNameLen = 1024;
280
281         DWORD64 symDisplacement = 0;
282         if (SymFromAddr(hProcess, sf.AddrPC.Offset, 0, pSymbol))
283         {
284             printf("Function : %s\n", pSymbol->Name);
285             infostr.AppendFormat(_T("Function : %S \r\n"), pSymbol->Name);
286         }
287         else
288         {
289             printf("SymFromAdd failed!\n");
290             //    infostr.AppendFormat(_T("SymFromAdd failed \r\n"),pSymbol->Name);
291         }
292
293         DWORD dwLineDisplacement;
294 #ifdef _WIN64
295         IMAGEHLP_LINEW64 lineInfoW = { sizeof(IMAGEHLP_LINEW64) };
296         if (SymGetLineFromAddrW(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfoW))
297         {
298             //        printf( "[Source File : %s]\n", lineInfo.FileName ); 
299             //        printf( "[Source Line : %u]\n", lineInfo.LineNumber ); 
300             CString s1(lineInfoW.FileName);
301             infostr.AppendFormat(_T("File %s Line %d\r\n"), s1.Mid(s1.ReverseFind(_T('\\')) + 1, 99), lineInfoW.LineNumber);
302         }
303         else
304         {
305             printf("SymGetLineFromAddr failed!\n");
306             //    infostr.Append(_T("SymGetLineFromAddr failed!\r\n"));
307         }
308 #elif defined _WIN32
309         IMAGEHLP_LINE lineInfo = { sizeof(IMAGEHLP_LINE) };
310         if (SymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &dwLineDisplacement, &lineInfo))
311         {
312             //        printf( "[Source File : %s]\n", lineInfo.FileName ); 
313             //        printf( "[Source Line : %u]\n", lineInfo.LineNumber ); 
314             CString s1(lineInfo.FileName);
315             infostr.AppendFormat(_T("File %s Line %d\r\n"), s1.Mid(s1.ReverseFind(_T('\\')) + 1, 99), lineInfo.LineNumber);
316         }
317         else
318         {
319             printf("SymGetLineFromAddr failed!\n");
320             //    infostr.Append(_T("SymGetLineFromAddr failed!\r\n"));
321         }
322 #endif
323
324     }
325 }
326 DWORD excep_filter(LPEXCEPTION_POINTERS lpEP)
327 {
328     /**//// init dbghelp.dll
329     CString s1;
330     if (SymInitialize(GetCurrentProcess(), NULL, TRUE))
331     {
332         printf("Init dbghelp ok.\n");
333     }
334
335     dump_callstack(lpEP->ContextRecord, s1);
336
337     if (SymCleanup(GetCurrentProcess()))
338     {
339         printf("Cleanup dbghelp ok.\n");
340     }
341
342     return EXCEPTION_EXECUTE_HANDLER;
343 }
344
345 void Trans_Tunc(unsigned int n, EXCEPTION_POINTERS* pExp)
346 {
347     //    pExp->ExceptionRecord.
348     //    throw SE_Exception(n);
349     CString s1;
350     if (SymInitialize(GetCurrentProcess(), NULL, TRUE))
351     {
352         printf("Init dbghelp ok.\n");
353         //        s1=_T("Init dbghelp ok.\r\n");
354     }
355
356     dump_callstack(pExp->ContextRecord, s1);
357
358     if (SymCleanup(GetCurrentProcess()))
359     {
360         printf("Cleanup dbghelp ok.\n");
361         //        s1.Append(_T("Cleanup dbghelp ok.\n"));
362     }
363     throw SE_Exception(n, pExp->ExceptionRecord->ExceptionAddress, s1);
364 }
365
366 int DisplayException(CString File, int Line, CString Func, CString Sentence, SE_Exception &e)
367 {
368     CString Serror;
369     CString s1;
370     s1.Format(_T("程序发生SE异常 代码 %08X 地址 %p \r\nFile: %s \r\nLine: %d \r\nFunc %s \r\n语句 %s \r\n 信息\r\n %s \r\n"), e.getSeNumber(), e.getAddress(), File, Line, Func, Sentence, e.getInfoStr());;
371     PopupMessage(s1);
372     return 0;
373 }
374 int DisplayException(CString File, int Line, CString Func, CString Sentence, CException *e)
375 {
376     CString Serror;
377     CString s1;
378     e->GetErrorMessage(Serror.GetBuffer(256), 256);
379     Serror.ReleaseBuffer();
380     s1.Format(_T("程序发生C++异常 %s 在File: %s Line: %d Func %s Sentence %s \r\n"), Serror, File, Line, Func, Sentence);
381     PopupMessage(s1);
382     return 0;
383 }
384 int DisplayException(CString File, int Line, CString Func, CString Sentence)
385 {
386     CString s1;
387     s1.Format(_T("程序发生未知错误 File: %s Line: %d Func %s Sentence %s \r\n"), File, Line, Func, Sentence);
388     PopupMessage(s1);
389     return 0;
390 }
391
392
393 int LoadMyConfig()
394 {
395     CString ConfigFilePathName;
396     ConfigFilePathName = _T("./Settings.ini");
397     int j = MyCfg1.LoadFromFile(ConfigFilePathName);
398     return j;
399 }
400
401 int SaveMyConfig()
402 {
403     CString ConfigFilePathName;
404     ConfigFilePathName = _T("./Settings.ini");
405     int j = MyCfg1.SaveToFile(ConfigFilePathName);
406     return j;
407 }
408
409 CString& FormatHex(void * databuf, int nSize)
410 {
411     static CString str1;
412     unsigned char * ptr1 = (unsigned char *)databuf;
413     str1.Empty();
414
415     for (int i = 0; i < nSize && i<256; i++)
416     {
417 //        if ((i & 0xf) == 0) str1.AppendFormat(_T("%02X  "), i);
418         str1.AppendFormat(_T("%02X "), ptr1[i]);
419         if (((i + 1) & 0xf) == 0) str1.Append(_T("\r\n"));
420     }
421     return str1;
422 }