/***************************************************************************************************

  2006 ? ÀÛ¾÷½ÃÀÛ
  2006/10/31  ¼Õ»óµÈ RAR ÆÄÀÏÀÎ °æ¿ì Áß°£¿¡ ¹«½ÃÇÏ°í ´ÙÀ½ÆÄÀÏÀº °è¼Ó ¾ÐÃà Ç®µµ·Ï ¼öÁ¤




***************************************************************************************************/



#include "stdafx.h"
#include "resource.h"
#include "unzip.h"
#include "./unrar/unrar.h"
#include "./unlzh/unlzh.h"


HINSTANCE			hInst;
LRESULT CALLBACK	MainDlgProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK	PassDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

LPTSTR	g_szCmdLine = NULL;
CHAR	g_szPass[256];

HICON	g_hIconBig;
HICON	g_hIconSmall;
BOOL	g_bHalt;				// ¸ØÃâ±î?

int		g_nCodePage=936;		// 932=japan

struct SCodePage
{
	LPCTSTR szDesc;
	int		nCodepage;
};

SCodePage g_supportedCodePages[]=
{
	{ _T("ÀÏº»¾î"), 932 },
	{ _T("Áß±¹¾î(°£Ã¼)"), 936 },
	{ _T("Áß±¹¾î(¹øÃ¼)"), 950 },
	{ _T("ÇÑ±Û(CP949)"), 949 },
};

CUnLzh	g_unlzh;



//CP_ACP

#define APP _T("ZIPJ")


LPCTSTR TXT_ABOUT = 
	_T("ÀÌ ÇÁ·Î±×·¥Àº ¿Ü±¹¾î(ÀÏº»¾î/Áß±¹¾î)·Î µÈ .ZIP/.RAR./.LZH ÆÄÀÏÀÇ ¾ÐÃàÀ» ÇØÁ¦ÇÏ´Â ÇÁ·Î±×·¥ ÀÔ´Ï´Ù.\r\n\r\n")
	_T("È¨ÆäÀÌÁö : www.kippler.com");

#ifndef _MAX_PATH
#   define _MAX_PATH   260 /* max. length of full pathname */
#endif

BOOL IsFolder(LPCTSTR szPathName)
{
	UINT32 dwRet;
	dwRet = GetFileAttributes(szPathName);
	if(dwRet==0xffffffff) return FALSE;
	if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return TRUE;
	return FALSE;
}

// È®ÀåÀÚ ºñ±³ÇÏ±â.
BOOL CheckExt(LPCTSTR szPathName, LPCTSTR szExt)
{
	if(szPathName==NULL || szExt==NULL){ASSERT(0); return FALSE;}

	LPCTSTR szTail = ::_tcsrchr(szPathName, '.');
	if(szTail==NULL){ASSERT(0); return FALSE;}

	if(::_tcsicmp(szTail, szExt)==0) return TRUE;
	return FALSE;
}



#define PATHSEP _T("\\")

BOOL DigPath(LPCTSTR szPathName)
{
	TCHAR*	dup = _tcsdup(szPathName);
	TCHAR	seps[]   = _T("/\\");
	TCHAR*	token;
	TCHAR	path[MAX_PATH] = {0};
	TCHAR*	last;

	// °æ·Î¸¸ »Ì±â.
	last = dup + lstrlen(dup);
	while(last!=dup)
	{
		if(*last=='/' || *last=='\\') 
		{
			*last = (char)NULL;
			break;
		}
		last --;
	}

	
	token = _tcstok( dup, seps );
	while( token != NULL )
	{
		if(lstrlen(path)==0)
		{
			if(szPathName[0]=='/')			// is absolute path ?
				lstrcpy(path,_T("/"));
			else if(szPathName[0]=='\\' && szPathName[1]=='\\')	// network drive ?
				lstrcpy(path,_T("\\\\"));
			lstrcat(path, token);
		}
		else
		{
			lstrcat(path, PATHSEP);
			lstrcat(path, token);
		}

		if(IsFolder(path)==FALSE)
			_tmkdir(path);
		token = _tcstok( NULL, seps );
	}

	free(dup);
	if(IsFolder(szPathName)) return TRUE;
	return FALSE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
///          control enable/disable ÇÏ±â
/// @date    2004-03-01 ¿ÀÀü 6:34:40
////////////////////////////////////////////////////////////////////////////////////////////////////
static void EnableControl(HWND hDlg, BOOL bExtracting)
{
	BOOL bEnable;
	BOOL bDisable;

	if(bExtracting)
	{
		bEnable = FALSE;
		bDisable = TRUE;
	}
	else
	{
		bEnable = TRUE;
		bDisable = FALSE;
	}
	
	// Æò¼Ò¿¡ enable
	EnableWindow(GetDlgItem(hDlg, IDC_EDIT_ZIPPATH),	bEnable);
	EnableWindow(GetDlgItem(hDlg, IDC_EDIT_OUTPATH),	bEnable);
	EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_FINDZIP),	bEnable);
	EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_FINDPATH), bEnable);
	EnableWindow(GetDlgItem(hDlg, IDCANCEL),			bEnable);
	EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_EXTRACT),	bEnable);

	// ¾ÐÃàÇ®¶§¸¸ enable
	EnableWindow(GetDlgItem(hDlg, IDC_BUTTON_STOP),		bDisable);
}

////////////////////////////////////////////////////////////////////////////////////////////////////
///          list control ¿¡ ¸Þ½ÃÁö »Ñ¸®±â
/// @date    2004-03-01 ¿ÀÀü 6:12:51
////////////////////////////////////////////////////////////////////////////////////////////////////
#define LEN_MSG	2048
void Message(HWND hList, LPCTSTR str, ...)
{
	TCHAR	msg[LEN_MSG];
	BOOL	bPartialOK = FALSE;
	va_list args;
	va_start(args, str);
	_vstprintf(msg, str, args);
	va_end(args);

	int	nCount = ::SendMessage(hList, LVM_GETITEMCOUNT, 0, 0L);

	LVITEM item;
	item.mask = LVIF_TEXT;
	item.iItem = nCount;
	item.iSubItem = 0;
	item.pszText = (LPTSTR)msg;
	item.state = 0;
	item.stateMask = 0;
	item.iImage = 0;
	item.lParam = 0;

	::SendMessage(hList, LVM_INSERTITEM, 0, (LPARAM)&item);
	::SendMessage(hList, LVM_ENSUREVISIBLE, (LPARAM)nCount,MAKELPARAM(bPartialOK, 0));
	::SendMessage(hList, LVM_SETCOLUMNWIDTH, 0, (LPARAM)LVSCW_AUTOSIZE_USEHEADER);
}

void PumpUntilEmpty(HWND hWnd)
{
	MSG msg;
	while(::PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
	{
		::TranslateMessage(&msg);
		::DispatchMessage(&msg);
	}
}



BOOL	ExtractZipFile(HWND hDlg, HWND hList, LPTSTR szSrc, LPTSTR szDst, BOOL& bOpenFailed)
{
	unzFile		uf;
	int			ret;
	unz_file_info	file_info;
	CHAR szFileName[MAX_PATH];
	WCHAR szFileNameW[MAX_PATH];

	#ifdef _UNICODE
	uf = unzOpenW(szSrc);
	#else
	uf = unzOpen(szSrc);
	#endif
	if (uf==NULL) 
	{
		bOpenFailed = TRUE;
		return FALSE;
	}

	EnableControl(hDlg, TRUE);

	ret = unzGoToFirstFile(uf);
	if(ret!=UNZ_OK) goto END;

	for(;;)
	{
		ret = unzGetCurrentFileInfo(uf, &file_info, szFileName, MAX_PATH, NULL,0, NULL, 0);

		//MultiByteToWideChar(CP_ACP, 0, szFileName, -1, szFileNameW, MAX_PATH);
		MultiByteToWideChar(g_nCodePage, 0, szFileName, -1, szFileNameW, MAX_PATH);	   // 932==japan

		if(ret!=UNZ_OK) goto END;

		ret = unzOpenCurrentFile(uf);
		if (ret!=UNZ_OK)
		{
			Message(hList, _T("ÆÄÀÏ ¿­±â ½ÇÆÐ:%s"), szFileName);
			break;
		}

		TCHAR szResult[MAX_PATH];
		
		lstrcpy(szResult, szDst);
		if( szResult[lstrlen(szResult)-1] != _T('\\'))
			lstrcat(szResult, _T("\\"));
		lstrcat(szResult, szFileNameW);

		#define BUF_LEN 4096
		BYTE buf[BUF_LEN];
		int len;

		// Æú´õ ¸¸µé±â.
		DigPath(szResult);

		if(::IsFolder(szResult)==FALSE)
		{
			// ÆÄÀÏ·Î ¾²±â.
			FILE* fp;
			fp = _tfopen(szResult, _T("wb"));
			if(fp==NULL)
			{
				Message(hList, _T("ÆÄÀÏ ¿­±â ½ÇÆÐ:%s"), szResult);
				break;
			}
			Message(hList,_T("%s,%dbytes"), szFileNameW,file_info.uncompressed_size);

			for(;;)
			{
				len = unzReadCurrentFile(uf,buf, BUF_LEN);
				if (len<0)	
				{
					goto END;
				}
				if(len==0) break;
				fwrite(buf, 1, len, fp);
				PumpUntilEmpty(hDlg);
				if(g_bHalt) 
				{
					Message(hList, _T("ÁßÁö"));
					goto END;
				}
			}

			fclose(fp);
		}

		unzCloseCurrentFile(uf);


		ret = unzGoToNextFile(uf);
		if(ret==UNZ_END_OF_LIST_OF_FILE)
		{
			break;
		}
	}

	END:
	EnableControl(hDlg, FALSE);
	if(uf) unzCloseCurrentFile(uf);
	if(uf) unzClose(uf);

	return TRUE;
}

BOOL	ExtractRarFile(HWND hDlg, HWND hList, LPTSTR szSrc, LPTSTR szDst, BOOL& bOpenFailed)
{
	HANDLE hArcData;
	int RHCode,PFCode;
	char CmtBuf[16384];
	struct RAROpenArchiveDataEx OpenArchiveData;
	struct RARHeaderDataEx HeaderData;
	
	memset(&OpenArchiveData,0,sizeof(OpenArchiveData));
#ifdef _UNICODE
	OpenArchiveData.ArcNameW=szSrc;
#else
	OpenArchiveData.ArcName=sRarPath;
#endif
	OpenArchiveData.CmtBuf=CmtBuf;
	OpenArchiveData.CmtBufSize=sizeof(CmtBuf);
	OpenArchiveData.OpenMode=RAR_OM_EXTRACT;
	hArcData=RAROpenArchiveEx(&OpenArchiveData);
	
	if (OpenArchiveData.OpenResult!=0)
	{
		bOpenFailed = TRUE;
		return FALSE;
	}

	// ÄÝ¹é..
	//RARSetCallback(hArcData,CallbackProc,(LONG)&Mode);

	EnableControl(hDlg, TRUE);

	HeaderData.CmtBuf=NULL;

	while ((RHCode=RARReadHeaderEx(hArcData,&HeaderData))==0)
	{
		Message(hList,_T("%s,%dbytes"), HeaderData.FileNameW,HeaderData.UnpSize);
		::PumpUntilEmpty(NULL);
		if(g_bHalt) 
		{
			Message(hList, _T("ÁßÁö"));
			break;
		}

#ifdef _UNICODE
		PFCode=RARProcessFileW(hArcData,RAR_EXTRACT,szDst, NULL);//sDestFileName.GetBuffer(0));//W2A(sDestFileName));
#else
		PFCode=RARProcessFile(hArcData,RAR_EXTRACT,szDst, NULL);//sDestFileName.GetBuffer(0));
#endif
		if (PFCode!=0)
		{
			TCHAR szErr[1024];

			if(PFCode==ERAR_BAD_DATA)
				wsprintf(szErr, _T(" ¿¡·¯ : ÆÄÀÏÀÌ ¼Õ»óµÊ"));
			else if(PFCode==ERAR_ECREATE)
				wsprintf(szErr, _T(" ¿¡·¯ : ÆÄÀÏ »ý¼º ½ÇÆÐ"));
			else
				wsprintf(szErr, _T(" ¿¡·¯ : ¿¡·¯ÄÚµå(%d)"), PFCode);

			Message(hList, szErr);
			//RARCloseArchive(hArcData);
			//EnableControl(hDlg, FALSE);
			//return FALSE;
		}
	}

	RARCloseArchive(hArcData);
	EnableControl(hDlg, FALSE);

	return TRUE;
}




BOOL	ExtractLzhFile(HWND hDlg, HWND hList, LPTSTR szSrc, LPTSTR szDst, BOOL& bOpenFailed)
{
	// ¿­±â..
	if(g_unlzh.Open(hDlg, szSrc, g_nCodePage)==FALSE)
	{
		Message(hList, _T("ÆÄÀÏ ¿­±â ½ÇÆÐ"));
		return FALSE;
	}

	EnableControl(hDlg, TRUE);

	int ret;

	DigPath(szDst);

	
	CUnLzh::FileList fileList = g_unlzh.GetFileList();
	CUnLzh::FileList::iterator i;
	WCHAR szMsg[4096];
	for(i=fileList.begin(); i<fileList.end(); i++)
	{
		WCHAR szCmdLine[MAX_PATH*10];
		WCHAR szResult[4096];

		wsprintf(szCmdLine, L"x -n \"%s\" \"%s\" \"%s\"", szSrc, szDst, i->szFileName);
		ret = g_unlzh.UnlhaW(hDlg, szCmdLine, szResult, 4096);

#ifdef _DEBUG
wprintf(L"%s", szResult);
#endif
		if(ret)
		{
			wsprintf(szMsg, L"¾ÐÃàÇ®±â ½ÇÆÐ:%s(0x%x)", i->szFileName,ret);
		}
		else
		{
			wsprintf(szMsg, L"%s(%dbytes)", i->szFileName, i->dwOriginalSize);
		}
		Message(hList, szMsg);
	}
	

	/*
	WCHAR szCmdLine[MAX_PATH*10];
	WCHAR szResult[4096];

	wsprintf(szCmdLine, L"x -n \"%s\" \"%s\" ", szSrc, szDst);
	ret = g_unlzh.UnlhaW(hDlg, szCmdLine, szResult, 4096);
	Message(hList, L"¿Ï·á");
	*/

	EnableControl(hDlg, FALSE);
	return TRUE;
}

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
	hInst = hInstance;

	g_hIconBig = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ZIPJ));
	g_hIconSmall = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMALL));

	//g_szCmdLine = lpCmdLine;
	g_szCmdLine = new TCHAR[_tcslen(lpCmdLine)+1];
	TCHAR* p;
	TCHAR* q;
	p = lpCmdLine;
	q = g_szCmdLine;
	while(*p)
	{
		if(*p!='"')						// µû¿ÈÇ¥ ¾ø¾Ö±â..
		{
			*q = *p;
			q++;
		}
		p++;
	}
	*q = 0;

/////////////////// ÄÜ¼Ö Ãâ·Â ///////////////////////////
#ifdef _DEBUG
	AllocConsole();
	freopen( "conin$", "r", stdin );
	freopen( "conout$", "w", stdout );
	freopen( "conout$", "w", stderr );
#endif

	DialogBox(hInstance, (LPCTSTR)IDD_MAIN, NULL, (DLGPROC)MainDlgProc);

	delete g_szCmdLine;

/////////////////// ÄÜ¼Ö ÇÁ¸® ///////////////////////////
#ifdef _DEBUG
	FreeConsole(); 
#endif

	return 0;
}


BOOL IsFile(LPCTSTR szPathName)
{
	DWORD dwRet;
	dwRet = GetFileAttributes(szPathName);
	if(dwRet==-1) return FALSE;
	if(dwRet & FILE_ATTRIBUTE_DIRECTORY) return FALSE;
	return TRUE;
}


void CenterWindow(HWND hWnd)
{
	RECT rcTemp1, rcTemp2 ;
	LONG iX, iY, iWidth, iHeight ;

	GetWindowRect(GetDesktopWindow(),&rcTemp1) ;
	GetWindowRect(hWnd,&rcTemp2) ;
	iWidth = rcTemp2.right - rcTemp2.left ;
	iHeight = rcTemp2.bottom - rcTemp2.top ;
	iX = LONG((rcTemp1.right - iWidth) / 2) ;
	iY = LONG((rcTemp1.bottom - iHeight) / 2) ;
	MoveWindow(hWnd,iX,iY,iWidth,iHeight,TRUE) ;
}

BOOL ExtractResource(LPCTSTR sResName, LPCTSTR szDst)
{
	HRSRC		hResInfo;
	HANDLE		hRes;
	int			nBufSize;
	FILE*		fp;
	
	TCHAR		szType[] = _T("BIN");
	TCHAR*		szRes;
	

	fp = _tfopen(szDst, _T("wb"));
	if(fp==NULL) return FALSE;

	
	hResInfo = FindResource(hInst, sResName, szType);
	if (hResInfo == NULL)  { fclose(fp); return FALSE; }
	
	// Load the resource
	hRes = LoadResource(hInst, hResInfo);
	
	// Lock the resource
	szRes = (TCHAR*)LockResource(hRes);

	if (szRes == NULL) { fclose(fp); FreeResource(hRes); return FALSE; }

	nBufSize = SizeofResource(hInst, hResInfo);
	fwrite(szRes, 1, nBufSize, fp);
	UnlockResource(hRes);  
	
	// Free the resource
	FreeResource(hRes);
	fclose(fp);

	return TRUE;
}

TCHAR g_sGetDirectoryDir[MAX_PATH];
static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT msg,LPARAM lp, LPARAM pData)
{
	TCHAR buf[MAX_PATH];
	switch(msg) 
	{
	case BFFM_INITIALIZED: 
		_tcscpy(buf,g_sGetDirectoryDir);
		::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)buf);
		break;
	case BFFM_SELCHANGED:
		if (::SHGetPathFromIDList((LPITEMIDLIST) lp ,buf)) 
			SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)buf);
		break;
	}
	return 0;
}

#ifndef BIF_NEWDIALOGSTYLE
  #define BIF_NEWDIALOGSTYLE     0x0040   // Use the new dialog layout with the ability to resize
  #define BIF_USENEWUI           (BIF_NEWDIALOGSTYLE | BIF_EDITBOX)
#endif
LPCTSTR GetDirectory(HWND hWndParent, LPCTSTR szRoot, LPCTSTR szTitle)
{
	static TCHAR str[MAX_PATH];
	BROWSEINFO bi;
    bi.hwndOwner=hWndParent;		//owner of created dialog box
    bi.pidlRoot=0;					//unused
    bi.pszDisplayName=0;			//buffer to receive name displayed by folder (not a valid path)
    bi.lpszTitle=szTitle;			//title is "Browse for Folder", this is an instruction
	bi.lpfn = BrowseCallbackProc;	//callback routine called when dialog has been initialized
    bi.lParam=0;					//passed to callback routine
    bi.ulFlags=
		BIF_RETURNONLYFSDIRS |		//only allow user to select a directory
		BIF_STATUSTEXT |			//create status text field we will be writing to in callback
		BIF_NEWDIALOGSTYLE |		// resizing °¡´ÉÇÑ »õ·Î¿î ½ºÅ¸ÀÏ..OleInitialize() °¡ È£Ãâ µÇ¾îÀÖ¾î¾ß ÇÔ..
//		BIF_BROWSEFORCOMPUTER|		//only allow user to select a computer
//		BIF_BROWSEFORPRINTER |		//only allow user to select a printer
//		BIF_BROWSEINCLUDEFILES|		//displays files too which user can pick
//		BIF_DONTGOBELOWDOMAIN|		//when user is exploring the "Entire Network" they
									// are not allowed into any domain
		0; 
	_tcscpy(g_sGetDirectoryDir, szRoot);

	LPITEMIDLIST lpItemId=::SHBrowseForFolder(&bi); 
	if (lpItemId)
	{
		::SHGetPathFromIDList(lpItemId, str);
		::GlobalFree(lpItemId);
	}

	return str;
}

void SetFileName(HWND hDlg, LPCTSTR szPathName)
{
	SetDlgItemText(hDlg, IDC_EDIT_ZIPPATH, szPathName);
	//TCHAR* temp = _tcsrchr(szPathName, '\\');
	TCHAR* temp = _tcsrchr(szPathName, '.');
	
	if(temp)
	{
		*(temp) = '\\';
		*(temp+1) = 0;
		SetDlgItemText(hDlg, IDC_EDIT_OUTPATH, szPathName);
	}
}


#ifndef LVM_SETEXTENDEDLISTVIEWSTYLE
#define LVM_SETEXTENDEDLISTVIEWSTYLE (LVM_FIRST + 54)   // optional wParam == mask
#endif

void SetListControl(HWND hList)
{
	LVCOLUMN	lvcolumn;
	lvcolumn.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
	lvcolumn.fmt = LVCFMT_LEFT;
	lvcolumn.iSubItem = 0;

	RECT r;
	::GetWindowRect(hList, &r);
	lvcolumn.cx = 100;
	lvcolumn.pszText = (LPTSTR)_T("¸Þ½ÃÁö");

	::SendMessage(hList, LVM_INSERTCOLUMN, 0, (LPARAM)&lvcolumn);
//	::SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM) LVS_EX_FULLROWSELECT);
	::SendMessage(hList, LVM_SETCOLUMNWIDTH, 0, (LPARAM)LVSCW_AUTOSIZE_USEHEADER);
}



LRESULT CALLBACK MainDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	HWND	hList = GetDlgItem(hDlg, IDC_LIST_MESSAGE);
	switch (message)
	{
	case WM_INITDIALOG:
		::SendMessage(hDlg, WM_SETICON, TRUE, (LPARAM)g_hIconBig);
		::SendMessage(hDlg, WM_SETICON, FALSE, (LPARAM)g_hIconSmall);
		CenterWindow(hDlg);
		DragAcceptFiles(hDlg, TRUE);

		if(g_szCmdLine && _tcslen(g_szCmdLine))
			SetFileName(hDlg, g_szCmdLine);

		SetListControl(hList);
		EnableControl(hDlg, FALSE);

		// codepage
		{
			int  i;
			HWND hCombo = ::GetDlgItem(hDlg, IDC_COMBO_CP);
			for(i=0;i<sizeof(g_supportedCodePages)/sizeof(g_supportedCodePages[0]);i++)
			{
				ComboBox_AddString(hCombo, g_supportedCodePages[i].szDesc);
				ComboBox_SetItemData(hCombo, i, g_supportedCodePages[i].nCodepage);		// codepage ¸¦ itemdata ·Î »ç¿ë.
			}
			ComboBox_SetCurSel(hCombo, 0);		// ±âº» - ÀÏº»¾î.
		}

		//ComboBox_SetCurSel
		//IDC_COMBO_CP

		return TRUE;
		
	case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
			case IDC_BUTTON_EXTRACT :
				{
					TCHAR szSrc[MAX_PATH];
					TCHAR szDst[MAX_PATH];
					BOOL		bRet=FALSE;
					HWND hCombo = ::GetDlgItem(hDlg, IDC_COMBO_CP);

					g_bHalt = FALSE;

					GetDlgItemText(hDlg, IDC_EDIT_ZIPPATH, szSrc, MAX_PATH);
					GetDlgItemText(hDlg, IDC_EDIT_OUTPATH, szDst, MAX_PATH);


					// codepgage
					g_nCodePage = ComboBox_GetItemData(hCombo, ComboBox_GetCurSel(hCombo));

					if(lstrlen(szSrc)==0)
					{
						MessageBox(hDlg, _T("¾ÐÃà(zip/rar) ÆÄÀÏÀ» ¸ÕÀú ¼±ÅÃÇØ ÁÖ»ï. µå·¡±×&µå·Óµµ °¡´ÉÇÔ."), APP, MB_OK);
						return 0;
					}

					if(::IsFile(szSrc)==FALSE)
					{
						MessageBox(hDlg, _T("¾ÐÃà ÆÄÀÏ °æ·Î°¡ ¹Ù¸£Áö ¾Ê³×.."), APP, MB_OK);
						return 0;
					}

					BOOL bOpenFailed=FALSE;
					if(ExtractZipFile(hDlg, hList, szSrc, szDst, bOpenFailed)==FALSE && bOpenFailed==TRUE)		// zip ÀÌ ½ÇÆÐ..
					{
						// rar ·Î ´Ù½Ã µµÀü.
						bOpenFailed=FALSE;
						if(::ExtractRarFile(hDlg, hList, szSrc, szDst, bOpenFailed)==FALSE &&bOpenFailed==TRUE)
						{
							// lzh ?
							if(CheckExt(szSrc, _T(".lzh")))
							{
								if(g_unlzh.LoadDll()==FALSE)
								{
									::MessageBox(hDlg, _T("LZH ÆÄÀÏÀ» Ç®·Á¸é UNLHA32.DLLÀÌ ÇÊ¿äÇÕ´Ï´Ù. È¨ÆäÀÌÁö°¡¸é ÀÖÀ¸´Ï±î È¨ÆäÀÌÁö °¡¼­ ´Ù¿î¹ÞÀ¸¼À"), APP, MB_OK);
								}
								else if(::ExtractLzhFile(hDlg, hList, szSrc, szDst, bOpenFailed)==FALSE &&bOpenFailed==TRUE)
								{
									MessageBox(hDlg, _T("Ç® ¼ö ÀÖ´Â ¾ÐÃà ÆÄÀÏÀÌ ¾Æ´Ï°Å³ª ÆÄÀÏÀÌ ¼Õ»óµÆ¾î."), APP, MB_OK);
								}
							}
							else
							{
								MessageBox(hDlg, _T("Ç® ¼ö ÀÖ´Â ¾ÐÃà ÆÄÀÏÀÌ ¾Æ´Ï°Å³ª ÆÄÀÏÀÌ ¼Õ»óµÆ¾î."), APP, MB_OK);
							}
						}
					}
					Message(hList, _T("Á¾·á"));

					return 0;
				}
				break;


			case IDC_BUTTON_FINDZIP :
				{
					TCHAR* szFile;
					OPENFILENAME ofn;       
					szFile = (TCHAR*)calloc(sizeof(TCHAR), MAX_PATH*2);

					// Initialize OPENFILENAME
					ZeroMemory(&ofn, sizeof(OPENFILENAME));
					ofn.lStructSize = sizeof(OPENFILENAME);
					ofn.hwndOwner = hDlg;
					ofn.lpstrFile = szFile;
					ofn.nMaxFile = MAX_PATH;
					ofn.lpstrFilter = 
									_T("Áö¿øÇÏ´Â ÆÄÀÏ\0*.ZIP;*.RAR;*.LZH\0")
									_T("ZIPÆÄÀÏ\0*.ZIP\0")
									_T("RARÆÄÀÏ\0*.RAR\0")
									_T("LZHÆÄÀÏ\0*.LZH\0")
									_T("¸ðµçÆÄÀÏ\0*.*\0\0");
					ofn.nFilterIndex = 1;
					ofn.lpstrFileTitle = NULL;
					ofn.nMaxFileTitle = 0;
					ofn.lpstrTitle = _T("ÆÄÀÏ ¼±ÅÃ");
					ofn.lpstrInitialDir = NULL;
					ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;

					if (!GetOpenFileName (&ofn)) { free(szFile); return 0; }


					SetFileName(hDlg, szFile);

					free(szFile);
				}
				return 0;

			case IDC_OPEN_FOLDER :
				{
					TCHAR szPath[MAX_PATH];
					GetDlgItemText(hDlg, IDC_EDIT_OUTPATH, szPath, MAX_PATH);
					ShellExecute(NULL, _T("open"), szPath, NULL, NULL, SW_SHOW);
				}
				return 0;

			case IDC_BUTTON_STOP :
				g_bHalt = TRUE;
				return 0;

			case IDC_BUTTON_FINDPATH :
				{
					TCHAR szPath[MAX_PATH];
					GetDlgItemText(hDlg, IDC_EDIT_OUTPATH, szPath, MAX_PATH);

					LPCTSTR szPath2 = GetDirectory(hDlg, szPath, _T("¾ÐÃàÇ® °æ·Î ¼±ÅÃ"));
					if(_tcslen(szPath2)==0) return 0;
					SetDlgItemText(hDlg, IDC_EDIT_OUTPATH, szPath2);
					return 0;
				}

			case IDC_BUTTON_ABOUT :
				MessageBox(hDlg, TXT_ABOUT, APP, MB_OK|MB_ICONEXCLAMATION);
				return 0;
			case IDC_BUTTON_HOMEPAGE :
				ShellExecute(hDlg, _T("open"), _T("http://www.kippler.com"), _T(""), _T(""), SW_SHOW);
				return 0;

			case IDOK :
			case IDCANCEL :
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
		}
		break;

	case WM_DROPFILES :
		{
			HDROP			hDropInfo = (HDROP) wParam; 
			TCHAR			szPathName[_MAX_PATH];
			int				nCount;

			nCount = ::DragQueryFile(hDropInfo, 0xffffffff, NULL, 0);

			::DragQueryFile(hDropInfo, 0, szPathName, _MAX_PATH);

			SetFileName(hDlg, szPathName);
			::DragFinish(hDropInfo);

		}
		break;

	}
    return FALSE;
}



