From f1a543772246f59b8b52a8857270b38ee38f3588 Mon Sep 17 00:00:00 2001 From: LYW <leeyeanwoo@diteam.co.kr> Date: 화, 31 5월 2022 09:07:13 +0900 Subject: [PATCH] AOI RawMessenger 동기화 --- ReviewHistory/ReveiwHistory/DitGlassRawStruct.h | 7 DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp | 13 DitGlassRawMessenger/DitGlassRawMessenger/GlassRawDemo.cpp | 1 DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj.filters | 6 DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.cpp | 168 +++++-- DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.cpp | 614 ++++++++++++++++++++++++++++++ DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.h | 121 ++++++ DitGlassRawMessenger/Extern/DitGlassRawStruct.h | 7 DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.h | 4 ReviewSystem/ReviewSystem/DitGlassRawStruct.h | 7 ReviewHistory/bin/ReviewHistroy.exe | 0 DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.cpp | 9 DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj | 4 DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp | 190 +++++++- 14 files changed, 1,055 insertions(+), 96 deletions(-) diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.cpp index 3a7646a..b25fbae 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.cpp @@ -5,7 +5,7 @@ #include "stdafx.h" #include "DitGlassRawMessenger.h" #include "DitGlassRawMessengerDlg.h" - +#include "SelfDump.h" /* < KMH 20220406 : #4053 ADD > */ #ifdef _DEBUG #define new DEBUG_NEW #endif @@ -71,6 +71,13 @@ // 적절한 내용으로 수정해야 합니다. SetRegistryKey(_T("로컬 응용 프로그램 마법사에서 생성된 응용 프로그램")); + /* < KMH 20220406 : #4053 ADD Start > */ + CSelfDump cDump; + cDump.RegisterExceptionFilter(); + + //CreateDirectory("D:\\AOIServer\\Temp", NULL); + /* < KMH 20220406 : #4053 ADD End > */ + CDitGlassRawMessengerDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj index f54cbca..3ad997a 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj +++ b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj @@ -150,6 +150,7 @@ <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <TargetMachine>MachineX64</TargetMachine> + <UACExecutionLevel>RequireAdministrator</UACExecutionLevel> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> @@ -215,6 +216,7 @@ <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <TargetMachine>MachineX64</TargetMachine> + <UACExecutionLevel>RequireAdministrator</UACExecutionLevel> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -235,6 +237,7 @@ <ClCompile Include="InterfaceFTP.cpp" /> <ClCompile Include="MacroResultFile.cpp" /> <ClCompile Include="RawResultReader.cpp" /> + <ClCompile Include="SelfDump.cpp" /> <ClCompile Include="StackResultCPJT.cpp" /> <ClCompile Include="StackResultCSOT.cpp" /> <ClCompile Include="stdafx.cpp"> @@ -264,6 +267,7 @@ <ClInclude Include="MacroResultFile.h" /> <ClInclude Include="RawResultReader.h" /> <ClInclude Include="Resource.h" /> + <ClInclude Include="SelfDump.h" /> <ClInclude Include="StackResultCPJT.h" /> <ClInclude Include="StackResultCSOT.h" /> <ClInclude Include="stdafx.h" /> diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj.filters b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj.filters index 81b1bc2..cf48882 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj.filters +++ b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessenger.vcxproj.filters @@ -96,6 +96,9 @@ <ClCompile Include="RawResultReader.cpp"> <Filter>RawInterface\Stack</Filter> </ClCompile> + <ClCompile Include="SelfDump.cpp"> + <Filter>�냼�뒪 �뙆�씪</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="akLoggerExt.h"> @@ -167,6 +170,9 @@ <ClInclude Include="RawResultReader.h"> <Filter>RawInterface\Stack</Filter> </ClInclude> + <ClInclude Include="SelfDump.h"> + <Filter>�뿤�뜑 �뙆�씪</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\DitGlassRawMessenger.ico"> diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp index 056f20b..1fdb749 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp @@ -131,7 +131,6 @@ m_vecStrGridDefectHeader.push_back("MergeState"); } - void CDitGlassRawMessengerDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); @@ -199,6 +198,12 @@ BOOL CDitGlassRawMessengerDlg::OnInitDialog() { + + /* <LJC 20220407 : #4053 MOD Start> */ + CString strTemp; + strTemp.Format(_T("Version : %s %s"), _T(__DATE__), _T(__TIME__)); + AKLOG("DITRawMessenger 프로그램 실행( : %s )", strTemp); + /* <LJC 20220407 : #4053 MOD End> */ CDialog::OnInitDialog(); DragAcceptFiles(TRUE); @@ -443,7 +448,7 @@ { HMENU hMenu = CreatePopupMenu(); AppendMenu(hMenu, MF_STRING, 0, "연구소2파트작품"); - AppendMenu(hMenu, MF_STRING, WM_DESTROY, "Exit"); + AppendMenu(hMenu, MF_STRING, WM_DESTROY, "Exit"); TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, 0, GetSafeHwnd(), NULL); } @@ -602,6 +607,9 @@ Sleep(10); } pThis->m_nThreadMainFlag = 0; + /* <KMH 20220407 : #4053 ADD Start> */ + AKLOG("Main Thread End"); + /* <KMH 20220407 : #4053 ADD End> */ } void CDitGlassRawMessengerDlg::MainProcess() @@ -771,7 +779,6 @@ WriteConfigFile(); } - BOOL CDitGlassRawMessengerDlg::DestroyWindow() { diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp index 93a3018..8a1aa61 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp @@ -21,10 +21,6 @@ #define LOCAL_AOIRAWDFS_PATH "D:\\DIT_ResultData\\Raw" #define LOCAL_AOIRAWBIN_PATH "D:\\DIT_ResultData\\RawBin" -//TEST -// #define NETWORK_AOIRAWDFS_PATH "D:\\DIT_ResultData\\Raw" -// #define NETWORK_AOIRAWBIN_PATH "D:\\DIT_ResultData\\RawBin" - #define NETWORK_AOIRAWDFS_PATH "\\\\126.100.100.1\\d\\DIT_ResultData\\Raw" #define NETWORK_AOIRAWBIN_PATH "\\\\126.100.100.1\\d\\DIT_ResultData\\RawBin" @@ -39,7 +35,9 @@ /* <LJC 20211122 : #3820 ADD Start> */ #define NETWORK_AOIRAWMERGELOCAL_PATH "D:\\DIT_ResultData\\RawMerge" /* <LJC 20211122 : #3820 ADD End> */ - +/* <KMH 20220407 : #4053 ADD Start> */ +#define LOCAL_LOGDATA_PATH "D:\\DIT_LogData" +/* <KMH 20220407 : #4053 ADD End> */ char* g_pCellCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; void _TimeDelay(int delay) @@ -67,6 +65,20 @@ CreateDirectory(LOCAL_AOIRAWDFS_PATH, NULL); CreateDirectory(LOCAL_AOIRAWBIN_PATH, NULL); CreateDirectory("D:\\Raw_im", NULL); + + /* <KMH 20220407 : #4053 ADD Start> */ + CFileFind FileFinder; + SYSTEMTIME st; + GetLocalTime(&st); + char strLogFolderPath [256]; + sprintf(strLogFolderPath, "%s\\%02d%02d%02d", LOCAL_LOGDATA_PATH,st.wYear, st.wMonth, st.wDay); + + BOOL bFind = FileFinder.FindFile(strLogFolderPath); + if (!bFind) + { + CreateDirectory(strLogFolderPath, NULL); + } + /* <KMH 20220407 : #4053 ADD End> */ m_MuraResultFile.readOptionFile("C:\\DIT_Review\\ReviewServerConfig\\MacroInfo.cfg"); m_GlassRawRTMS.SetMuraResult(&m_MuraResultFile); @@ -80,6 +92,8 @@ BOOL CGlassRawCPJT::SequenceGlassLoading( CgrmGlassRawData* pData ) { + + AKLOG("Sequence : Glass Loading Signal Start ");/* <KMH 20220407 : #4053 ADD > */ SetEnableFtpAck(FALSE); m_nRawMergeIdx = 0; if(m_StackResult.getStackUse()) @@ -94,14 +108,24 @@ { File.FindNextFile(); strStackFileLocalPath = File.GetFilePath(); - DeleteFile(strStackFileLocalPath); - Sleep(10); + /* <KMH 20220407 : #4053 MOD Start> */ + if (DeleteFile(strStackFileLocalPath)) + /*< SWK 20220413 - #4053 MOD Start >*/ +// { +// AKLOG(" Fucntion : Delete Stack File Sucess[%s] ", strStackFileLocalPath); +// } +// /* <KMH 20220407 : #4053 MOD End> */ +// Sleep(10); +// } +// else +// { +// AKLOG(" Function : Delete Stack File Fail [%s]", strStackFileLocalPath);/* <KMH 20220407 : #4053 MOD > */ +// } + AKLOG(" Function : Delete Stack File Sucess[%s] ", strStackFileLocalPath); + else + AKLOG(" Function : Delete Stack File Fail [%s]", strStackFileLocalPath); } - else - { - AKLOG("Delete Stack File Fail [%s]", strStackFileLocalPath); - } - + /*< SWK 20220413 - #4053 MOD End >*/ //201218 CJH - Stack Download �떆�룄 SendMessageFTPDownloadStack(pData->GetGlassData()); @@ -117,20 +141,38 @@ { File.FindNextFile(); strRawFileLocalPath = File.GetFilePath(); - DeleteFile(strRawFileLocalPath); - Sleep(10); + /* <KMH 20220407 : #4053 MOD Start> */ + if (DeleteFile(strRawFileLocalPath)) + /*< SWK 20220413 - #4053 MOD Start >*/ +// { +// AKLOG(" Fucntion : Delete RawMerge File Sucess[%s] ", strRawFileLocalPath); +// } +// /* <KMH 20220407 : #4053 MOD End> */ +// Sleep(10); +// } +// else +// { +// AKLOG(" Function : Delete RawMerge File Fail [%s]", strRawFileLocalPath); /* <KMH 20220407 : #4053 ADD > */ +// } + AKLOG(" Function : Delete RawMerge File Sucess[%s] ", strRawFileLocalPath); + else + AKLOG(" Function : Delete RawMerge File Fail [%s]", strRawFileLocalPath); } + /*< SWK 20220413 - #4053 MOD End >*/ SetEnableFtpAck(TRUE); DownLoadMergeFile(pData); } /* <LJC 20211122 : #3820 ADD End> */ /*< KJG 20211024 - #3487 ADD End >*/ + AKLOG("Sequence : Glass Loading Signal End "); return TRUE; } BOOL CGlassRawCPJT::SequenceInspectEnd( CgrmGlassRawData* pData ) { + AKLOG(" Sequence : InspectionEnd Signal Start"); /* <KMH 20220407 : #4053 ADD > */ + m_bReviewEndCheck = FALSE; //210128 m_tmReviewEnd = m_tmReviewStart = CTime::GetCurrentTime(); @@ -220,9 +262,15 @@ fclose(pf); } } + else + { + SendMessageFTPUploadImage(pData->GetGlassData(), FTPCMD_MURA_IMAGE);/* <KMH 20220407 : #4053 ADD > */ + } + /* <KYH 211129 : #3806 ADD End> */ - SendMessageFTPUploadImage(pData->GetGlassData(), FTPCMD_MURA_IMAGE);//0405nwh + + AKLOG(" Sequence : InspectionEnd Signal End"); /* <KMH 20220407 : #4053 ADD > */ return TRUE; } @@ -351,6 +399,7 @@ BOOL CGlassRawCPJT::SequenceFtpUpload(char* pRawFilePathName) { + AKLOG(" Sequence : FTP Upload Signal Start "); // Manual Upload 湲곕뒫 [21-02-05 KJG] CTime tmFileCreate; _grmGlassData GlassData; @@ -423,7 +472,7 @@ fclose(pf); - + AKLOG(" Sequence : FTP Upload Signal End "); return TRUE; } @@ -538,10 +587,14 @@ CString strValue; /*< KJG 20211229 - #3846 MOD Start >*/ //strValue = "ITEM PANEL MODULETYPE MODULEID PROCESSID PRODUCTID STEPID PROD_TYPE BATCHID H_PANELID E_PANELID P_PANELID OPERID COMP_COUNT PPID GRADE CODE R_GRADE MAP_IMAGE L_TIME U_TIME S_TIME E_TIME T_DEFECT TR PR NG TB TW RB RW T_STACK NO_DEFECT MAX_AVG_GRAY MAX_PORTION OK_CELL RJ_CELL RW_CELL NR_CELL CSTID SLOT_NO JOB_END TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT LN_DEFECT IMG_COUNT RECIPE SHRINK RAW_CUT CRACK_DEFECT"; - strValue = "ITEM PANEL MODULETYPE MODULEID PROCESSID PRODUCTID STEPID PROD_TYPE BATCHID H_PANELID E_PANELID P_PANELID OPERID COMP_COUNT PPID GRADE CODE R_GRADE MAP_IMAGE L_TIME U_TIME S_TIME E_TIME T_DEFECT TR PR NG TB TW RB RW T_STACK NO_DEFECT MAX_NG MAX_PORTION OK_CELL RJ_CELL RW_CELL NR_CELL CSTID SLOT_NO JOB_END TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT LN_DEFECT IMG_COUNT RECIPE SHRINK RAW_CUT CRACK_DEFECT"; //56ea + /* <LJC 20220425 : #3957 MOD Start> */ + strValue = "ITEM PANEL MODULETYPE MODULEID PROCESSID PRODUCTID STEPID PROD_TYPE BATCHID H_PANELID E_PANELID P_PANELID OPERID COMP_COUNT PPID GRADE CODE R_GRADE MAP_IMAGE L_TIME U_TIME S_TIME E_TIME T_DEFECT TR PR NG TB TW RB RW T_STACK NO_DEFECT MAX_NG MAX_PORTION OK_CELL RJ_CELL RW_CELL NR_CELL CSTID SLOT_NO JOB_END TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT LN_DEFECT IMG_COUNT RECIPE SHRINK RAW_CUT CRACK_DEFECT CODE_COUNT1 CODE_COUNT2 CODE_COUNT3 CODE_COUNT4 CODE_COUNT5 CODE_COUNT6 CODE_COUNT7 CODE_COUNT8 CODE_COUNT9 CODE_COUNT10"; //56ea + /* <LJC 20220425 : #3957 MOD End> */ /*< KJG 20211229 - #3846 MOD End >*/ strLine += strValue; strLine += "\n"; - strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT LN_DEFECT TR PR NG RB RW TB TW T_STACK NO_DEFECT"; //31ea /* <KYH 211129 : #3796 MOD Start> */ + /* <LJC 20220425 : #3957 MOD Start> */ + strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT LN_DEFECT TR PR NG RB RW TB TW T_STACK NO_DEFECT CODE_COUNT1 CODE_COUNT2 CODE_COUNT3 CODE_COUNT4 CODE_COUNT5 CODE_COUNT6 CODE_COUNT7 CODE_COUNT8 CODE_COUNT9 CODE_COUNT10"; //31ea /* <KYH 211129 : #3796 MOD Start> */ + /* <LJC 20220425 : #3957 MOD End> */ strLine += strValue; strLine += "\n"; strValue = "ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE LINE_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG R_HEIGHT G_HEIGHT B_HEIGHT INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK CLASS_CODE"; //50ea strLine += strValue; @@ -930,7 +983,19 @@ { SPRINTRAW(12, "UNUSE"); } - + /* <LJC 20220425 : #3957 ADD Start> */ + for (int i = 0; i < RAW_CODE_MAX; i++) + { + if (pGlassData->m_nDefectCode[i] >= 0) + { + SPRINTRAW(12, "%d", pGlassData->m_nDefectCode[i]); + } + else + { + SPRINTRAW(12, "*"); + } + } + /* <LJC 20220425 : #3957 ADD End> */ SPRINTRAWEND; //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23] } @@ -1056,7 +1121,19 @@ // 31 6 NO_DEFECT 異붽� SPRINTRAW(12, "%d", pCellData->m_nDefectNumJudgeND); //KYH ND �뜲�씠�꽣 異붽� /* <KYH 211129 : #3796 MOD End> */ - + /* <LJC 20220425 : #3957 ADD Start> */ + for (int i = 0; i < RAW_CODE_MAX; i++) + { + if (pCellData->m_nDefectCode[i] >= 0) + { + SPRINTRAW(12, "%d", pCellData->m_nDefectCode[i]); + } + else + { + SPRINTRAW(12, "*"); + } + } + /* <LJC 20220425 : #3957 ADD End> */ SPRINTRAWEND; //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23] } @@ -1584,10 +1661,10 @@ cds.lpData = &upParam; DWORD dwReturn = 0; - if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 30000, (PDWORD_PTR)(dwReturn)) == FALSE) - { - } - + if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 5000, (PDWORD_PTR)(dwReturn)) == FALSE) + AKLOG(" FunCtion FTP : RAW File Upload Signal Fail[%d]", FTPCMD_RAW);/* <KMH 20220407 : #4053 ADD > */ + else + AKLOG(" FunCtion FTP : RAW File Upload Signal Sucess[%d]", FTPCMD_RAW);/* <KMH 20220407 : #4053 ADD > */ } void CGlassRawCPJT::SendMessageFTPDownloadStack( _grmGlassData* pGlassData ) @@ -1626,9 +1703,19 @@ cds.lpData = &upParam; DWORD dwReturn = 0; - if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE) - { - } + if (SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 5000, (PDWORD_PTR)(dwReturn)) == FALSE) + /*< SWK 20220413 - #4053 MOD Start >*/ +// { +// AKLOG(" Fucntion FTP : Stack File Download Signal Fail[%d]", FTPCMD_STACK);/* <KMH 20220407 : #4053 ADD > */ +// } +// else +// { +// AKLOG(" Fucntion FTP : Stack File Download Signal Sucess[%d]", FTPCMD_STACK);/* <KMH 20220407 : #4053 ADD > */ +// } + AKLOG(" Function FTP : Stack File Download Signal Fail[%d]", FTPCMD_STACK); + else + AKLOG(" Function FTP : Stack File Download Signal Success[%d]", FTPCMD_STACK); + /*< SWK 20220413 - #4053 MOD End >*/ } void CGlassRawCPJT::SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData ) @@ -1666,9 +1753,19 @@ cds.lpData = &upParam; DWORD dwReturn = 0; - if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE) - { - } + if (SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 5000, (PDWORD_PTR)(dwReturn)) == FALSE) + /*< SWK 20220413 - #4053 MOD Start >*/ +// { +// AKLOG(" Fucntion FTP : RawMerge File Download Signal Sucess[%d]", FTPCMD_RAWMERGE);/* <KMH 20220407 : #4053 ADD > */ +// } +// else +// { +// AKLOG(" Fucntion FTP : RawMerge File Download Signal Fail[%d]", FTPCMD_RAWMERGE);/* <KMH 20220407 : #4053 ADD > */ +// } + AKLOG(" Function FTP : RawMerge File Download Signal Fail[%d]", FTPCMD_RAWMERGE); + else + AKLOG(" Function FTP : RawMerge File Download Signal Success[%d]", FTPCMD_RAWMERGE); + /*< SWK 20220413 - #4053 MOD End >*/ /*< KJG 20211024 - #3487 ADD End >*/ } @@ -1708,9 +1805,19 @@ cds.lpData = &upParam; DWORD dwReturn = 0; - if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE) - { - } + if (SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 5000, (PDWORD_PTR)(dwReturn)) == FALSE) + /*< SWK 20220413 - #4053 MOD Start >*/ +// { +// AKLOG(" Fucntion FTP : Image Upload Signla Sucess[%d]", sort);/* <KMH 20220407 : #4053 ADD > */ +// } +// else +// { +// AKLOG(" Fucntion FTP : Image Upload Signla Fail[%d]", sort);/* <KMH 20220407 : #4053 ADD > */ +// } + AKLOG(" Function FTP : Image Upload Signal Fail[%d]", sort); + else + AKLOG(" Function FTP : Image Upload Signal Success[%d]", sort); + /*< SWK 20220413 - #4053 MOD End >*/ } @@ -1764,9 +1871,20 @@ cds.lpData = &upParam; DWORD dwReturn = 0; - if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE) - { - } + if (SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 5000, (PDWORD_PTR)(dwReturn)) == FALSE) + /*< SWK 20220413 - #4053 MOD Start >*/ +// { +// AKLOG(" Fucntion FTP : Index File Upload Signla Sucess[%d]", FTPCMD_INDEX);/* <KMH 20220407 : #4053 ADD > */ +// } +// else +// { +// AKLOG(" Fucntion FTP : Index File Upload Signla Fail[%d]", FTPCMD_INDEX);/* <KMH 20220407 : #4053 ADD > */ +// } + AKLOG(" Function FTP : Index File Upload Signal Fail[%d]", FTPCMD_INDEX); + else + AKLOG(" Function FTP : Index File Upload Signal Success[%d]", FTPCMD_INDEX); + /*< SWK 20220413 - #4053 MOD End >*/ + return TRUE; } diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawDemo.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawDemo.cpp index 2171e11..46308eb 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawDemo.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawDemo.cpp @@ -16,7 +16,6 @@ #define LOCAL_AOIRAWDFS_PATH "D:\\DIT_ResultData\\Raw" #define LOCAL_AOIRAWBIN_PATH "D:\\DIT_ResultData\\RawBin" - #define NETWORK_AOIRAWDFS_PATH "\\\\126.100.100.1\\d\\DIT_ResultData\\Raw" #define NETWORK_AOIRAWBIN_PATH "\\\\126.100.100.1\\d\\DIT_ResultData\\RawBin" diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.cpp index d5d79d1..e9bd828 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.cpp +++ b/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.cpp @@ -59,11 +59,15 @@ strFileName.Format("%s\\%s", m_strLocalPath, pGlassID); + FILE* pf = fopen(strFileName.GetBuffer(0), "r"); if (pf == NULL) return FALSE; + /* <KMH 20220407 : #4053 ADD Start> */ + AKLOG("Function : Read File Path: %s" , strFileName); + /* <KMH 20220407 : #4053 ADD End> */ /*< KJG 20211208 : #3696 ADD Start >*/ CDitGlassRawClient GlassRawClient; GlassRawClient.ConnectServer(); @@ -368,7 +372,9 @@ akFileDB.getItem("RawMerge_Use", &m_bStackUse, 0); akFileDB.getItem("RawMerge_LocalPath", m_strLocalPath, "D:\\DIT_ResultData\\RawMerge"); - if (m_bStackUse && m_nThreadStackFileReadFlag == 0) + //< SWK 20220413 - #4053 MOD > +// if (/*m_bStackUse && */m_nThreadStackFileReadFlag == 0) + if (m_nThreadStackFileReadFlag == 0) { _beginthread(threadResultFileRead, NULL, this); } @@ -395,7 +401,8 @@ nReadFailCount = 0; AKLOG("RawMerge File Read Start : %s\\%s", pThis->m_strLocalPath, strGlassID); - Sleep(3000); + //< SWK 20220413 - #4053 DEL > +// Sleep(3000); while (pThis->m_nProcessState == RPS_StateFileRead && pThis->m_nThreadStackFileReadFlag == 1) { if ((nThreadCount++ % 20) != 0) //명령 수행을 빠르게 감지 위한 조치 @@ -411,15 +418,19 @@ } nReadFailCount++; - AKLOG("RawMerge File Read Try : %d", nReadFailCount); + //< SWK 20220413 - #4053 DEL > +// AKLOG("RawMerge File Read Try : %d", nReadFailCount); if (nReadFailCount > 10) { pThis->m_nProcessState = RPS_ResultReadFail; break; } + //< SWK 20220413 - #4053 ADD > + AKLOG("RawMerge File Read Try : %d", nReadFailCount); - Sleep(50); + //< SWK 20220413 - #4053 DEL > +// Sleep(50); } if (pThis->m_nProcessState != RPS_ResultReadOK) { @@ -433,57 +444,90 @@ pThis->m_nThreadStackFileReadFlag = 0; } /* <LJC 20211122 : #3820 ADD Start> */ -void CRawResultReader::ProcessResultFileRead(void * pArg) +/*< SWK 20220413 - #4053 MOD Start >*/ +//void CRawResultReader::ProcessResultFileRead(void * pArg) +void CRawResultReader::ProcessResultFileRead() +/*< SWK 20220413 - #4053 MOD End >*/ { - CRawResultReader* pThis = (CRawResultReader*)pArg; - - pThis->m_nThreadStackFileReadFlag = 1; + /*< SWK 20220413 - #4053 MOD Start >*/ +// CRawResultReader* pThis = (CRawResultReader*)pArg; +// +// pThis->m_nThreadStackFileReadFlag = 1; +// int nReadFailCount = 0; +// int nThreadCount = 0; +// CString strGlassID; +// +// while (pThis->m_nThreadStackFileReadFlag == 1) +// { +// if (pThis->m_nProcessState == RPS_CmdFileRead) //스택파일 읽기 수행 [김태현 2019/1/12] +// { +// strGlassID = pThis->m_strGlassID; +// +// pThis->m_nProcessState = RPS_StateFileRead; +// nThreadCount = 0; +// nReadFailCount = 0; +// AKLOG("RawMerge File Read Start : %s\\%s", pThis->m_strLocalPath, strGlassID); +// Sleep(3000); +// while (pThis->m_nProcessState == RPS_StateFileRead && pThis->m_nThreadStackFileReadFlag == 1) +// { +// if (pThis->openFile(strGlassID.GetBuffer(0)) == TRUE) +// { +// pThis->m_nProcessState = RPS_ResultReadOK; +// AKLOG("RawMerge File Read Complete "); +// break; +// } +// nReadFailCount++; +// AKLOG("RawMerge File Read Try : %d", nReadFailCount); +// if (nReadFailCount > 10) +// { +// pThis->m_nProcessState = RPS_ResultReadFail; +// break; +// } +// Sleep(50); +// } +// if (pThis->m_nProcessState != RPS_ResultReadOK) +// { +// pThis->m_nProcessState = RPS_ResultReadFail; +// } +// } +// if (nReadFailCount) +// Sleep(500); +// } +// pThis->m_nThreadStackFileReadFlag = 0; + m_nProcessState = RPS_StateFileRead; int nReadFailCount = 0; int nThreadCount = 0; - CString strGlassID; - - while (pThis->m_nThreadStackFileReadFlag == 1) + AKLOG("RawMerge File Read Start : %s\\%s", m_strLocalPath, m_strGlassID); + while (m_nProcessState == RPS_StateFileRead && m_nThreadStackFileReadFlag == 1) { - if (pThis->m_nProcessState == RPS_CmdFileRead) //스택파일 읽기 수행 [김태현 2019/1/12] + if (openFile(m_strGlassID.GetBuffer(0)) == TRUE) { - strGlassID = pThis->m_strGlassID; - - pThis->m_nProcessState = RPS_StateFileRead; - nThreadCount = 0; - nReadFailCount = 0; - - AKLOG("RawMerge File Read Start : %s\\%s", pThis->m_strLocalPath, strGlassID); - Sleep(3000); - while (pThis->m_nProcessState == RPS_StateFileRead && pThis->m_nThreadStackFileReadFlag == 1) - { - if (pThis->openFile(strGlassID.GetBuffer(0)) == TRUE) - { - pThis->m_nProcessState = RPS_ResultReadOK; - AKLOG("RawMerge File Read Complete "); - break; - } - nReadFailCount++; - AKLOG("RawMerge File Read Try : %d", nReadFailCount); - if (nReadFailCount > 10) - { - pThis->m_nProcessState = RPS_ResultReadFail; - break; - } - Sleep(50); - } - if (pThis->m_nProcessState != RPS_ResultReadOK) - { - pThis->m_nProcessState = RPS_ResultReadFail; - } + m_nProcessState = RPS_ResultReadOK; + AKLOG("RawMerge File Read Complete "); + break; } - if (nReadFailCount) - Sleep(500); + nReadFailCount++; + if (nReadFailCount > 10) + { + m_nProcessState = RPS_ResultReadFail; + break; + } + AKLOG("RawMerge File Read Try : %d", nReadFailCount); } - pThis->m_nThreadStackFileReadFlag = 0; + if (m_nProcessState != RPS_ResultReadOK) + { + m_nProcessState = RPS_ResultReadFail; + } + /*< SWK 20220413 - #4053 MOD End >*/ } /* <LJC 20211122 : #3820 ADD End> */ BOOL CRawResultReader::RawMergeFileReadStart(char* pGlassID) { + /*< SWK 20220413 - #4053 ADD Start >*/ + m_strGlassID = pGlassID; + m_nProcessState = RPS_CmdFileRead; + /*< SWK 20220413 - #4053 ADD End >*/ + if (m_nThreadStackFileReadFlag == 0) { _beginthread(threadResultFileRead, NULL, this); @@ -495,27 +539,43 @@ while (m_nProcessState == RPS_CmdFileStop) Sleep(0); } - m_strGlassID = pGlassID; - m_nProcessState = RPS_CmdFileRead; + /*< SWK 20220413 - #4053 DEL Start > +// m_strGlassID = pGlassID; +// m_nProcessState = RPS_CmdFileRead; + < SWK 20220413 - #4053 DEL End >*/ return TRUE; } /* <LJC 20211122 : #3820 ADD Start> */ BOOL CRawResultReader::ProcessRawMergeFileReadStart(char * pGlassID) { - if (m_nThreadStackFileReadFlag == 0) { - ProcessResultFileRead(this); + //< SWK 20220413 - #4053 MOD > +// ProcessResultFileRead(this); + ProcessResultFileRead(); } - if (m_nProcessState == RPS_StateFileRead) + /*< SWK 20220413 - #4053 MOD Start >*/ +// if (m_nProcessState == RPS_StateFileRead) +// { +// m_nProcessState = RPS_CmdFileStop; +// while (m_nProcessState == RPS_CmdFileStop) Sleep(0); +// } +// +// m_strGlassID = pGlassID; +// m_nProcessState = RPS_CmdFileRead; + else { - m_nProcessState = RPS_CmdFileStop; - while (m_nProcessState == RPS_CmdFileStop) Sleep(0); - } + if (m_nProcessState == RPS_StateFileRead) + { + m_nProcessState = RPS_CmdFileStop; + while (!(m_nProcessState == RPS_ResultReadOK || m_nProcessState == RPS_ResultReadFail)) Sleep(0); + } - m_strGlassID = pGlassID; - m_nProcessState = RPS_CmdFileRead; + m_strGlassID = pGlassID; + m_nProcessState = RPS_CmdFileRead; + } + /*< SWK 20220413 - #4053 MOD End >*/ return TRUE; } diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.h b/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.h index ccffbe9..c462e68 100644 --- a/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.h +++ b/DitGlassRawMessenger/DitGlassRawMessenger/RawResultReader.h @@ -46,7 +46,9 @@ BOOL openFile(char* pGlassID); static void threadResultFileRead(void* pArg); /* <LJC 20211122 : #3820 ADD Start> */ - static void ProcessResultFileRead(void* pArg); + //< SWK 20220413 - #4053 MOD > +// static void ProcessResultFileRead(void* pArg); + void ProcessResultFileRead(); /* <LJC 20211122 : #3820 ADD End> */ int m_nThreadStackFileReadFlag; diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.cpp new file mode 100644 index 0000000..69e6a7c --- /dev/null +++ b/DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.cpp @@ -0,0 +1,614 @@ +#include "stdafx.h" +#include "SelfDump.h" +#include <strsafe.h> + +// SelfDump를 위한 파라미터 +static TCHAR g_szDumpPreFixName [MAX_PATH] = {0,}; +static TCHAR g_szDumpPath [MAX_PATH_SELFDUMP] = {0,}; +static DWORD g_dwDumpCapacityBytes = DEFAULT_DUMP_CAPACITY; +static MINIDUMP_TYPE g_nMiniDumpType = MiniDumpNormal; +static pfnCbOnCrash g_pfnCallback = NULL; +static LPVOID g_pUserData = NULL; + +CSelfDump::~CSelfDump() +{ + +} + +CSelfDump::CSelfDump(IN LPCTSTR lpszDumpPreFixName/*=NULL*/, IN MINIDUMP_TYPE nMiniDumpType/*=MiniDumpNormal*/, IN DWORD dwDumpCapacityBytes/*=DEFAULT_DUMP_CAPACITY*/, IN LPCTSTR lpszDumpPath/*=NULL*/, IN pfnCbOnCrash pfnCallback/*=NULL*/, IN LPVOID lpUserData/*=NULL*/) +{ + RegisterExceptionFilter(lpszDumpPreFixName, nMiniDumpType, dwDumpCapacityBytes, lpszDumpPath, pfnCallback, lpUserData); +} + +LONG CSelfDump::CbTopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo) +{ + LONG lRtnValue = EXCEPTION_CONTINUE_SEARCH; + HANDLE hFile = INVALID_HANDLE_VALUE; + BOOL bRtnValue = FALSE; + TCHAR szPath[MAX_PATH_SELFDUMP] = {0,}; + HMODULE hDll = NULL; + LPFN_MinuDumpWriteDump pfn = NULL; + SYSTEMTIME stTime = {0,}; + _MINIDUMP_EXCEPTION_INFORMATION stExceptInfo = {0,}; + + // Dump Path가 존재하지 않는다면, Pass + if (INVALID_FILE_ATTRIBUTES == ::GetFileAttributes(g_szDumpPath)) + { + // 로그도 남기지 않도록 한다. + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // Callback 등록 되어 있으면 우선 호출한다. + if (NULL != g_pfnCallback) + { + if (FALSE == (*g_pfnCallback)(g_pUserData)) + { + WriteLogFile(g_szDumpPath, TEXT(""), &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + } + + // 만약, MiniDumpType이 -1 이라면,... 종료 + if ((MINIDUMP_TYPE)-1 == g_nMiniDumpType) + { + WriteLogFile(g_szDumpPath, TEXT(""), &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // DbgHelp.dll을 로드한다. + hDll = CSelfDump::LoadLibrary_DbgHelp(); + if (NULL == hDll) + { + WriteLogFile(g_szDumpPath, TEXT(""), &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // DbgHelp.dll::MinuDumpWriteDump(...)를 구한다. + pfn = (LPFN_MinuDumpWriteDump)::GetProcAddress(hDll, "MiniDumpWriteDump"); + if (NULL == pfn) + { + WriteLogFile(g_szDumpPath, TEXT(""), &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // Dump 파일 이름을 구한다. + if (FALSE == CSelfDump::GetDumpFileFullPathName(g_szDumpPath, + g_szDumpPreFixName, + szPath, + MAX_PATH_SELFDUMP, + &stTime)) + { + ::GetLocalTime(&stTime); + WriteLogFile(g_szDumpPath, TEXT(""), &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // Dump 파일을 Create 한다. + hFile = ::CreateFile(szPath, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + WriteLogFile(g_szDumpPath, szPath, &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // 덤프 생성을 위한 변수 초기화 + stExceptInfo.ThreadId = ::GetCurrentThreadId(); + stExceptInfo.ExceptionPointers = pExceptionInfo; + stExceptInfo.ClientPointers = NULL; + + // Dump File 들을 manage하여 파일등을 삭제한다. + if (FALSE == CSelfDump::ManageCapacity(g_szDumpPath, + g_szDumpPreFixName, + g_dwDumpCapacityBytes)) + { + WriteLogFile(g_szDumpPath, szPath, &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + goto FINAL; + } + + // Dump 생성 + bRtnValue = (*pfn)(::GetCurrentProcess(), + ::GetCurrentProcessId(), + hFile, + MiniDumpNormal, + &stExceptInfo, + NULL, + NULL); + if (TRUE == bRtnValue) + { + WriteLogFile(g_szDumpPath, szPath, &stTime, g_szDumpPreFixName, TRUE); + + // EXCEPTION_EXECUTE_HANDLER 으로 하면, + // drwtsn32.exe와 같은 디버거를 통한 덤프가 남지 않는다. + // lRtnValue = EXCEPTION_EXECUTE_HANDLER; + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + } + else + { + WriteLogFile(g_szDumpPath, szPath, &stTime, g_szDumpPreFixName, FALSE); + lRtnValue = EXCEPTION_CONTINUE_SEARCH; + } + +FINAL: + + if (INVALID_HANDLE_VALUE != hFile) + { + ::CloseHandle(hFile); + hFile = INVALID_HANDLE_VALUE; + pfn = NULL; + } + + if (NULL != hDll) + { + ::FreeLibrary(hDll); + hDll = NULL; + pfn = NULL; + } + + return lRtnValue; +} + +VOID CSelfDump::SetMiniDumpTypeWhenExist(IN LPCTSTR lpszRegKeyPath, IN LPCTSTR lpszValueName) +{ + HKEY hKey = NULL; + LONG lRtnValue = 0; + DWORD dwType = 0; + DWORD dwCbSize = 0; + DWORD dwValue = 0; + + if ((NULL == lpszRegKeyPath) || (NULL == lpszValueName)) + { + goto FINAL; + } + + lRtnValue = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, + lpszRegKeyPath, + 0, + KEY_READ, + &hKey); + if (ERROR_SUCCESS != lRtnValue) + { + goto FINAL; + } + + dwType = REG_DWORD; + dwCbSize = sizeof(dwValue); + lRtnValue = ::RegQueryValueEx(hKey, + lpszValueName, + NULL, + &dwType, + (LPBYTE)&dwValue, + &dwCbSize); + if (ERROR_SUCCESS != lRtnValue) + { + goto FINAL; + } + + g_nMiniDumpType = (MINIDUMP_TYPE)dwValue; + +FINAL: + if (NULL != hKey) + { + ::RegCloseKey(hKey); + hKey = NULL; + } +} + +VOID CSelfDump::WriteLogFile(IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpFileFullPathName, IN PSYSTEMTIME pstTimeOccur, IN LPCTSTR lpszDumpPrefixName, IN BOOL bWriteDumpSuccess) +{ + TCHAR szLogPath[MAX_PATH_SELFDUMP] = {0,}; + TCHAR szSection[MAX_PATH] = {0,}; + TCHAR szTmp [MAX_PATH] = {0,}; + + if ((NULL == lpszPath) || (NULL == lpszDumpFileFullPathName) || (NULL == pstTimeOccur) || (NULL == lpszDumpPrefixName)) + { + return; + } + + StringCchPrintf(szLogPath, MAX_PATH_SELFDUMP, TEXT("%s\\CrashDmp.log"), lpszPath); + StringCchPrintf(szSection, MAX_PATH, TEXT("%.4d%.2d%.2d_%.2d%.2d%.2d%.3d"), pstTimeOccur->wYear, pstTimeOccur->wMonth, pstTimeOccur->wDay, pstTimeOccur->wHour, pstTimeOccur->wMinute, pstTimeOccur->wSecond, pstTimeOccur->wMilliseconds); + + ::WritePrivateProfileString(szSection, TEXT("Prefix"), lpszDumpPrefixName, szLogPath); + ::WritePrivateProfileString(szSection, TEXT("DumpPath"), lpszDumpFileFullPathName, szLogPath); + + StringCchPrintf(szTmp, MAX_PATH, TEXT("%d"), ::GetCurrentProcessId()); + ::WritePrivateProfileString(szSection, TEXT("ProcessId"), szTmp, szLogPath); + + ::GetModuleFileName(NULL, szTmp, MAX_PATH); + ::WritePrivateProfileString(szSection, TEXT("CrashModulePath"), szTmp, szLogPath); + + if (TRUE == bWriteDumpSuccess) + { + ::WritePrivateProfileString(szSection, TEXT("SuccessWriteDump"), TEXT("yes"), szLogPath); + } + else + { + ::WritePrivateProfileString(szSection, TEXT("SuccessWriteDump"), TEXT("no"), szLogPath); + } +} + +BOOL CSelfDump::RegisterExceptionFilter(IN LPCTSTR lpszDumpPreFixName/*=NULL*/, IN MINIDUMP_TYPE nMiniDumpType/*=MiniDumpNormal*/, IN DWORD dwDumpCapacityBytes/*=DEFAULT_DUMP_CAPACITY*/, IN LPCTSTR lpszDumpPath/*=NULL*/, IN pfnCbOnCrash pfnCallback/*=NULL*/, IN LPVOID lpUserData/*=NULL*/) +{ + BOOL bRtnValue = TRUE; + DWORD dwRtnValue = 0; + + // 파라미터들를 복사한다. + if (NULL != lpszDumpPreFixName) + { + StringCchCopy(g_szDumpPreFixName, MAX_PATH, lpszDumpPreFixName); + } + else + { + GetDefaultDumpPreFixName(g_szDumpPreFixName, MAX_PATH); + } + + if (DEFAULT_DUMP_CAPACITY != dwDumpCapacityBytes) + { + g_dwDumpCapacityBytes = dwDumpCapacityBytes; + } + + if (NULL != lpszDumpPath) + { + StringCchCopy(g_szDumpPath, MAX_PATH_SELFDUMP, lpszDumpPath); + } + else + { + // NULL --> Default Path ( <.exe의 ModulePath>\Temp ) + dwRtnValue = CSelfDump::GetDefaultModuleTempPath(g_szDumpPath, MAX_PATH_SELFDUMP); + if (ERROR_SUCCESS != dwRtnValue) + { + bRtnValue = FALSE; + goto FINAL; + } + } + + g_nMiniDumpType = nMiniDumpType; + g_pfnCallback = pfnCallback; + g_pUserData = lpUserData; + + // Exception Filter를 등록한다. + ::SetUnhandledExceptionFilter(CSelfDump::CbTopLevelExceptionFilter); + + bRtnValue = TRUE; + +FINAL: + return bRtnValue; +} + +BOOL CSelfDump::GetDumpFileFullPathName(IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpPreFixName, OUT LPTSTR lpszDumpFileFullPathName, IN DWORD dwCchDumpFileFullPathName, OUT PSYSTEMTIME pstTime) +{ + BOOL bRtnValue = TRUE; + + if ((NULL == lpszPath) || + (NULL == lpszDumpPreFixName) || + (NULL == lpszDumpFileFullPathName) || + (NULL == pstTime)) + { + bRtnValue = FALSE; + goto FINAL; + } + + ::GetLocalTime(pstTime); + StringCchPrintf(lpszDumpFileFullPathName, + dwCchDumpFileFullPathName, + TEXT("%s\\%s_%.4d%.2d%.2d%.2d%.2d%.2d.dmp"), + lpszPath, + lpszDumpPreFixName, + pstTime->wYear, + pstTime->wMonth, + pstTime->wDay, + pstTime->wHour, + pstTime->wMinute, + pstTime->wSecond); + bRtnValue = TRUE; +FINAL: + return bRtnValue; +} + +DWORD CSelfDump::GetFilesSize(IN LPCTSTR lpszFindFileName, OUT LPTSTR lpszEarlyFileName, IN DWORD dwCchEarlyFileName) +{ + HANDLE hFind = INVALID_HANDLE_VALUE; + DWORD dwTotalBytes = 0; + WIN32_FIND_DATA FindFileData = {0,}; + + dwTotalBytes = 0; + + if ((NULL == lpszFindFileName) || (NULL == lpszEarlyFileName)) + { + goto FINAL; + } + + ZeroMemory(lpszEarlyFileName, sizeof(TCHAR) * dwCchEarlyFileName); + + // Enum File 한다. + hFind = ::FindFirstFile(lpszFindFileName, &FindFileData); + if (hFind == INVALID_HANDLE_VALUE) + { + dwTotalBytes = 0; + goto FINAL; + } + + if (TEXT('.') != FindFileData.cFileName[0]) + { + dwTotalBytes += FindFileData.nFileSizeLow; + StringCchCopy(lpszEarlyFileName, dwCchEarlyFileName, FindFileData.cFileName); + } + + while (FindNextFile(hFind, &FindFileData) != 0) + { + if (TEXT('.') == FindFileData.cFileName[0]) + { + continue; + } + + // 파일 크기를 계속 더해 나간다. + // (설마 nFileHighSize는 0이겠지?) + dwTotalBytes += FindFileData.nFileSizeLow; + + if (TEXT('\0') == lpszEarlyFileName[0]) + { + StringCchCopy(lpszEarlyFileName, dwCchEarlyFileName, FindFileData.cFileName); + continue; + } + + if (0 < _tcscmp(lpszEarlyFileName, FindFileData.cFileName)) + { + StringCchCopy(lpszEarlyFileName, dwCchEarlyFileName, FindFileData.cFileName); + } + } + +FINAL: + + if (INVALID_HANDLE_VALUE != hFind) + { + ::FindClose(hFind); + hFind = INVALID_HANDLE_VALUE; + } + + return dwTotalBytes; +} + +BOOL CSelfDump::ManageCapacity(IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpPreFixName, IN DWORD dwDumpCapacityBytes) +{ + INT i = 0; + BOOL bRtnValue = FALSE; + DWORD dwCbFileSize = 0; + TCHAR szFileName[MAX_PATH_SELFDUMP] = {0,}; + TCHAR szDelFileName[MAX_PATH_SELFDUMP] = {0,}; + TCHAR szEarlyFileName[MAX_PATH_SELFDUMP] = {0,}; + + if ((NULL == lpszPath) || (NULL == lpszDumpPreFixName)) + { + bRtnValue = FALSE; + goto FINAL; + } + + // Path를 결정한다. + StringCchPrintf(szFileName, + MAX_PATH_SELFDUMP, + TEXT("%s\\%s_*.dmp"), + lpszPath, + lpszDumpPreFixName); + + // 한꺼번에 32개의 덤프파일을 삭제할 수 있다. + for (i=0; i<MAX_DEL_TRY_MANAGE; i++) + { + dwCbFileSize = CSelfDump::GetFilesSize(szFileName, + szEarlyFileName, + MAX_PATH_SELFDUMP); + + if (dwCbFileSize < g_dwDumpCapacityBytes) + { + break; + } + + // 삭제한다. + StringCchPrintf(szDelFileName, MAX_PATH_SELFDUMP, TEXT("%s\\%s"), g_szDumpPath, szEarlyFileName); + ::DeleteFile(szDelFileName); + } + + bRtnValue = TRUE; + +FINAL: + + return bRtnValue; +} + +HMODULE CSelfDump::LoadLibrary_DbgHelp(VOID) +{ + HMODULE hDLL = NULL; + TCHAR szDbgHelp[MAX_PATH_SELFDUMP] = {0,}; + LPTSTR lpszFound = NULL; + + if (0 != ::GetModuleFileName(NULL, szDbgHelp, MAX_PATH_SELFDUMP)) + { + // .exe의 Path에 DbgHelp.dll이 있다면, 이것을 LoadLibrary 한다. + lpszFound = _tcsrchr(szDbgHelp, TEXT('\\')); + if ((NULL != lpszFound) && (szDbgHelp < lpszFound)) + { + *lpszFound = TEXT('\0'); + StringCchCat(szDbgHelp, MAX_PATH_SELFDUMP, TEXT("\\DbgHelp.dll")); + + hDLL = ::LoadLibrary(szDbgHelp); + if (NULL != hDLL) + { + // success! + goto FINAL; + } + } + } + + // System32 폴더로 부터 dbghelp.dll을 LoadLibrary 한다. + hDLL = CSelfDump::LoadLibraryFromSystem(TEXT("DbgHelp.dll")); + +FINAL: + return hDLL; +} + +HMODULE CSelfDump::LoadLibraryFromSystem(IN LPCTSTR lpFileName) +{ + if( NULL == lpFileName ) { + return NULL; + } + + if( 0 == lpFileName[0] ) { + return NULL; + } + + const int BUF_SIZ = 4096; + + LPTSTR lpszSysDir = NULL; + UINT nNeedSize = GetSystemDirectory( NULL, 0 ); + lpszSysDir = (LPTSTR)malloc( (nNeedSize + 1) * sizeof(TCHAR) ); + if( NULL == lpszSysDir ) { + return NULL; + } + + if( 0 == GetSystemDirectory( lpszSysDir, nNeedSize + 1 ) ) { + free( lpszSysDir ); + lpszSysDir = NULL; + return NULL; + } + + TCHAR szFullPath[BUF_SIZ] = {0,}; + _tcsncpy( szFullPath, lpszSysDir, BUF_SIZ ); + _tcsncat( szFullPath, _T("\\"), BUF_SIZ ); + _tcsncat( szFullPath, lpFileName, BUF_SIZ ); + + HMODULE hModule = LoadLibraryEx( szFullPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ); + + free( lpszSysDir ); + lpszSysDir = NULL; + + if( hModule ) { + return hModule; + } + + return NULL; +} + +DWORD CSelfDump::GetDefaultModuleTempPath(OUT LPTSTR lpszPath, IN DWORD dwCchPath) +{ + DWORD dwRtnValue = ERROR_SUCCESS; + LPTSTR lpszFound = NULL; + + if (NULL == lpszPath) + { + dwRtnValue = ERROR_INVALID_PARAMETER; + goto FINAL; + } + + // Clean Up + ZeroMemory(lpszPath, sizeof(TCHAR) * dwCchPath); + + if (0 == ::GetModuleFileName(NULL, lpszPath, dwCchPath)) + { + // Module Handle 구하는데 실패 + dwRtnValue = ::GetLastError(); + goto FINAL; + } + + lpszFound = _tcsrchr(lpszPath, TEXT('\\')); + if (NULL == lpszFound) + { + // Path 끝에 \가 없음? + dwRtnValue = ERROR_PATH_NOT_FOUND; + goto FINAL; + } + + if (lpszFound <= lpszPath) + { + // Path 끝에 \가 없음? + dwRtnValue = ERROR_PATH_NOT_FOUND; + goto FINAL; + } + + // Null 문자로 만들어줌 + *lpszFound = TEXT('\0'); + + // Temp 폴더를 추가해줌 + StringCchCat(lpszPath, dwCchPath, TEXT("\\Temp")); + + // 여기까지 왔다면, 성공 + dwRtnValue = ERROR_SUCCESS; + +FINAL: + return dwRtnValue; +} + +DWORD CSelfDump::GetDefaultDumpPreFixName(OUT LPTSTR lpszDefaultDumpPreFixName, IN DWORD dwCchDefaultDumpPreFixName) +{ + DWORD dwRtnValue = ERROR_SUCCESS; + TCHAR szModulePath[MAX_PATH_SELFDUMP] = {0,}; + LPTSTR lpszFound = NULL; + LPTSTR lpszIter = NULL; + BOOL bFound = FALSE; + INT i = 0; + + // 실행 .exe의 파일이름 (확장자 제외)를 dumpfile의 prefix로 결정한다. + if (NULL == lpszDefaultDumpPreFixName) + { + dwRtnValue = ERROR_INVALID_PARAMETER; + goto FINAL; + } + + ZeroMemory(lpszDefaultDumpPreFixName, sizeof(TCHAR)*dwCchDefaultDumpPreFixName); + + if (0 == ::GetModuleFileName(NULL, szModulePath, MAX_PATH_SELFDUMP)) + { + dwRtnValue = ::GetLastError(); + StringCchPrintf(lpszDefaultDumpPreFixName, dwCchDefaultDumpPreFixName, TEXT("UnKnown")); + goto FINAL; + } + + lpszFound = _tcsrchr(szModulePath, TEXT('\\')); + if ((NULL == lpszFound) || (lpszFound <= szModulePath) || (TEXT('\0') == *(lpszFound+1))) + { + dwRtnValue = ERROR_PATH_NOT_FOUND; + StringCchPrintf(lpszDefaultDumpPreFixName, dwCchDefaultDumpPreFixName, TEXT("UnKnown")); + goto FINAL; + } + + // 확장자를 절단한다. + bFound = FALSE; + for (i=0; i<MAX_PATH; i++) + { + if (TEXT('\0') == *(lpszFound+i)) + { + break; + } + + if (TEXT('.') == *(lpszFound+i)) + { + bFound = TRUE; + *(lpszFound+i) = TEXT('\0'); + break; + } + } + + if (FALSE == bFound) + { + dwRtnValue = ERROR_PATH_NOT_FOUND; + StringCchPrintf(lpszDefaultDumpPreFixName, dwCchDefaultDumpPreFixName, TEXT("UnKnown")); + goto FINAL; + } + + dwRtnValue = ERROR_SUCCESS; + StringCchCopy(lpszDefaultDumpPreFixName, dwCchDefaultDumpPreFixName, lpszFound + 1); + +FINAL: + return dwRtnValue; +} \ No newline at end of file diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.h b/DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.h new file mode 100644 index 0000000..772815d --- /dev/null +++ b/DitGlassRawMessenger/DitGlassRawMessenger/SelfDump.h @@ -0,0 +1,121 @@ +#include <dbghelp.h> + +////////////////////////////////////////////////////////////////////////// +// +// 사용예: +// +// #include "selfdump.h" +// +// winmain() +// { +// ... +// // 대략 초기에... +// CSelfDump::RegisterExectionFilter(); // <- 코드로 실행 +// .. +// } +// +// 혹은 +// +// CApp theApp; +// ... +// CSelfDump g_cSelfDump(); // <- 전역 변수로 실행 +// .. +// +// ==> 만약, TestApp.exe에서 Crash가 발생하면, +// (파라미터를 default 값으로 위 코드와 같이 지정했을때), +// +// * TestApp.exe Path에 Temp 폴더가 있는 경우, 미니 덤프인 TestApp_yyyymmddhhmmssmmm.dmp가 생성된다. +// * TestApp.exe Path에 Temp 폴더가 없는 경우, 덤프를 남기지 않는다. +// * TestApp_*.dmp의 Total 파일 크기가 1MB를 넘어가면, 가장 옛날껏을 지워서 덤프를 만들어 크기를 유지한다. +// * TestApp.exe Path의 Temp 폴더에 CrashDmp.log 파일에 오류 사항들을 기록한다. +// * XP/Vista인 경우, 기존의 디버거로도 연결이 된다. (drwtsn32, Problem Reports and Solutions 지원) +// +// (알림) minidump 생성이므로, !analyze -v 정도로 사용될 수 있다. +// (알림) TestApp.exe가 User계정에서 실행될 수 있으므로, Temp 폴더는 everyone 777 권한이 있는것이 좋을 것이다. +// (알림) CSelfDump 함수군은 Thread Safe 보장이 없다. 따라서, .exe 실행 초기화때 되도록 단 한번만 호출하도록 한다. +// (알림) dbghelp.dll을 사용하는데, 실행 .exe의 module path 다음 system32 path 순서로 LoadLibrary를 시도한다. +// +////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// +// +// Parameter : +// +// CSelfDump::CSelfDump(...) / CSelfDump::RegisterExectionFilter(...) +// 의 Argument를 설명한다. +// +// * lpszDumpPreFixName : 덤프파일의 이름을 지정한다. 지정되지 않는 경우, 실행 .exe의 파일명이 된다. +// ex) "abc"로 지정하는 경우, abc_yyyymmddhhmmssmmm.dmp 파일명으로 강제 지정된다. +// +// * nMiniDumpType : 덤프파일의 타입 지정. 기본값은 MiniDumpNormal이다. +// **) 타입은 http://msdn.microsoft.com/en-us/library/ms680519(VS.85).aspx 에서 참고하시오. +// +// * dwDumpCapacityBytes : PreFixName으로 만들어진 덤프파일들이 유지될 파일 크기. 기본값은 1048576(1MB)이다. +// **) 덤프를 만들기 전에 크기를 확인하여, 넘어가는 경우 가장 옛날것을 차례로 지워서 크기를 일정하게 유지한다. +// +// * lpszDumpPath : 덤프파일을 생성할 Path. 기본값은 .exe의 Path 하부의 Temp 폴더이다. +// ex) 기본값인 경우, C:\ttt\abc.exe는 C:\ttt\temp\abc_~~~~.dmp로 저장된다) +// +// * pfnCallback / pfnUserData : 덤프파일을 만들기 전에 호출받을 수 있는 callback을 등록. 기본값은 NULL +// **) callback 호출받아 UI를 띄워 줄 수 있다. FALSE를 리턴하면 덤프를 남기지 않는다. +// +////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// +// +// Tool : +// +// * CSelfDump::SetMiniDumpTypeWhenExist(...) +// **) nMiniDumpType을 레지스트리 값으로 세팅한다. (레지스트리 값이 있는경우만 해당) +// ex) CSelfDump::RegisterExectionFilter(..., MiniDumpScanMemory, ...); +// CSelfDump::SetMiniDumpTypeWhenExist(TEXT("Sofware\....\Tmp", TEXT("minidumptype")); +// 인 경우, 만약 레지스트리에 값이 있다면, MiniDumpScanMemory값에서 레지스트리 값으로 변경된다. +// 만약, 해당 값이 (DWORD)-1인 경우에는, 덤프를 남기지 않도록 예외 처리되었다. +// +////////////////////////////////////////////////////////////////////////// + +// dbghelp.dll::MinuDumpWriteDump(...)의 prototype +typedef BOOL (WINAPI *LPFN_MinuDumpWriteDump) (HANDLE hProcess, + DWORD dwPid, + HANDLE hFile, + MINIDUMP_TYPE DumpType, + PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + +// Crash 발생때 호출되는 Callback의 Prototype +// FALSE를 리턴하면, 덤프를 남기지 않는다. +typedef BOOL (*pfnCbOnCrash) (IN LPVOID lpUserData); + +// Capacity에 맞춰 파일을 삭제하고 write dump 하므로, Total 용량은 최대 (1MB + 마지막 Dump File 크기) 가 될수 있다. +#define DEFAULT_DUMP_CAPACITY 1048576 // 1MB + +// 덤프 파일 manage를 위해, 한꺼번에 삭제될 파일 개수 +#define MAX_DEL_TRY_MANAGE 32 + +#define MAX_PATH_SELFDUMP 1024 + +class CSelfDump +{ + public: + CSelfDump(IN LPCTSTR lpszDumpPreFixName = NULL, IN MINIDUMP_TYPE nMiniDumpType = MiniDumpNormal, IN DWORD dwDumpCapacityBytes = DEFAULT_DUMP_CAPACITY, IN LPCTSTR lpszDumpPath = NULL, IN pfnCbOnCrash pfnCallback = NULL, IN LPVOID lpUserData = NULL); + virtual ~CSelfDump(); + + public: + static BOOL RegisterExceptionFilter (IN LPCTSTR lpszDumpPreFixName = NULL, IN MINIDUMP_TYPE nMiniDumpType = MiniDumpNormal, IN DWORD dwDumpCapacityBytes = DEFAULT_DUMP_CAPACITY, IN LPCTSTR lpszDumpPath = NULL, IN pfnCbOnCrash pfnCallback = NULL, IN LPVOID lpUserData = NULL); + static VOID SetMiniDumpTypeWhenExist (IN LPCTSTR lpszRegKeyPath, IN LPCTSTR lpszValueName); + + private: + static LONG WINAPI CbTopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo); + static VOID WriteLogFile (IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpFileFullPathName, IN PSYSTEMTIME pstTimeOccur, IN LPCTSTR lpszDumpPrefixName, IN BOOL bWriteDumpSuccess); + + // Utility + private: + static DWORD GetDefaultDumpPreFixName(OUT LPTSTR lpszDefaultDumpPreFixName, IN DWORD dwCchDefaultDumpPreFixName); + static DWORD GetDefaultModuleTempPath(OUT LPTSTR lpszPath, IN DWORD dwCchPath); + static HMODULE LoadLibrary_DbgHelp (VOID); + static HMODULE LoadLibraryFromSystem (IN LPCTSTR lpFileName); + static BOOL ManageCapacity (IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpPreFixName, IN DWORD dwDumpCapacityBytes); + static BOOL GetDumpFileFullPathName (IN LPCTSTR lpszPath, IN LPCTSTR lpszDumpPreFixName, OUT LPTSTR lpszDumpFileFullPathName, IN DWORD dwCchDumpFileFullPathName, OUT PSYSTEMTIME pstTime); + static DWORD GetFilesSize (IN LPCTSTR lpszFindFileName, OUT LPTSTR lpszEarlyFileName, IN DWORD dwCchEarlyFileName); +}; \ No newline at end of file diff --git a/DitGlassRawMessenger/Extern/DitGlassRawStruct.h b/DitGlassRawMessenger/Extern/DitGlassRawStruct.h index 5a336e2..d7fc000 100644 --- a/DitGlassRawMessenger/Extern/DitGlassRawStruct.h +++ b/DitGlassRawMessenger/Extern/DitGlassRawStruct.h @@ -9,6 +9,7 @@ #define RAWMESSENGER_MAXCAMNUM 30 #define RAWMESSENGER_MAXSCANNUM 20 #define RAWMESSENGER_MAXHLINUM 8 +#define RAW_CODE_MAX 10 #define MAX_ZONE_NUM 16 @@ -116,6 +117,9 @@ int m_nDefectNumTypeMD; int m_nDefectNumTypeCD; int m_nDefectNumTypeMC; + /* <LJC 20220422 : #3957 ADD Start> */ + int m_nDefectCode[RAW_CODE_MAX]; + /* <LJC 20220422 : #3957 ADD End> */ int m_nDefectNumJudgeOKWhite; int m_nDefectNumJudgeOKBlack; @@ -274,6 +278,9 @@ /* <KYH 211129 : #3796 ADD Start> */ int m_nDefectNumJudgeND; /* <KYH 211129 : #3796 ADD End> */ + /* <LJC 20220422 : #3957 ADD Start> */ + int m_nDefectCode[RAW_CODE_MAX]; + /* <LJC 20220422 : #3957 ADD End> */ //DUMY DATA int Dumy_int[9]; diff --git a/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h b/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h index 5a336e2..d7fc000 100644 --- a/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h +++ b/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h @@ -9,6 +9,7 @@ #define RAWMESSENGER_MAXCAMNUM 30 #define RAWMESSENGER_MAXSCANNUM 20 #define RAWMESSENGER_MAXHLINUM 8 +#define RAW_CODE_MAX 10 #define MAX_ZONE_NUM 16 @@ -116,6 +117,9 @@ int m_nDefectNumTypeMD; int m_nDefectNumTypeCD; int m_nDefectNumTypeMC; + /* <LJC 20220422 : #3957 ADD Start> */ + int m_nDefectCode[RAW_CODE_MAX]; + /* <LJC 20220422 : #3957 ADD End> */ int m_nDefectNumJudgeOKWhite; int m_nDefectNumJudgeOKBlack; @@ -274,6 +278,9 @@ /* <KYH 211129 : #3796 ADD Start> */ int m_nDefectNumJudgeND; /* <KYH 211129 : #3796 ADD End> */ + /* <LJC 20220422 : #3957 ADD Start> */ + int m_nDefectCode[RAW_CODE_MAX]; + /* <LJC 20220422 : #3957 ADD End> */ //DUMY DATA int Dumy_int[9]; diff --git a/ReviewHistory/bin/ReviewHistroy.exe b/ReviewHistory/bin/ReviewHistroy.exe index daac937..a3f69b4 100644 --- a/ReviewHistory/bin/ReviewHistroy.exe +++ b/ReviewHistory/bin/ReviewHistroy.exe Binary files differ diff --git a/ReviewSystem/ReviewSystem/DitGlassRawStruct.h b/ReviewSystem/ReviewSystem/DitGlassRawStruct.h index 5a336e2..d7fc000 100644 --- a/ReviewSystem/ReviewSystem/DitGlassRawStruct.h +++ b/ReviewSystem/ReviewSystem/DitGlassRawStruct.h @@ -9,6 +9,7 @@ #define RAWMESSENGER_MAXCAMNUM 30 #define RAWMESSENGER_MAXSCANNUM 20 #define RAWMESSENGER_MAXHLINUM 8 +#define RAW_CODE_MAX 10 #define MAX_ZONE_NUM 16 @@ -116,6 +117,9 @@ int m_nDefectNumTypeMD; int m_nDefectNumTypeCD; int m_nDefectNumTypeMC; + /* <LJC 20220422 : #3957 ADD Start> */ + int m_nDefectCode[RAW_CODE_MAX]; + /* <LJC 20220422 : #3957 ADD End> */ int m_nDefectNumJudgeOKWhite; int m_nDefectNumJudgeOKBlack; @@ -274,6 +278,9 @@ /* <KYH 211129 : #3796 ADD Start> */ int m_nDefectNumJudgeND; /* <KYH 211129 : #3796 ADD End> */ + /* <LJC 20220422 : #3957 ADD Start> */ + int m_nDefectCode[RAW_CODE_MAX]; + /* <LJC 20220422 : #3957 ADD End> */ //DUMY DATA int Dumy_int[9]; -- Gitblit v1.9.3