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