개발자 블로그

ZipArchive 라이브러리 사용시 v3로 인한 압축해제 에러 해결 본문

프로그래밍/MFC

ZipArchive 라이브러리 사용시 v3로 인한 압축해제 에러 해결

로이드.Roid 2016. 4. 15. 02:07

비슷한 문제를 겪을 사람이 얼마나 될지는 모르겠지만,, 일단 기록해둔다.


우선 ZipArchive 라이브러리는 MFC에서 사용할 수 있는 zip 파일 압축 및 해제 라이브러리다. MFC에 내장된 클래스는 아니고, Code project에서 다운받은 라이브러리다. (여기를 클릭하면 해당 글로 이동함.)

요즘은 MFC를 사용하는 사람도 적을 것 같고, 또 컴파일 할 때 에러가 나기 때문에 최신버전의 visual studio에서는 사용이 불가능하다.

개발자의 사이트에서 최신버전의 라이브러리를 다운받을 수 있지만 소유권을 주장할 수 있는 프로그램에 사용하는것은 라이센스 위반이다. 이 경우에는 라이브러리를 별도로 구입해야 한다. 뭐 꼭 라이브러리 홍보하려고 쓰는 것 같네. 어쨌든 나는 더이상 사용 안한다. MFC를 버리고 윈폼으로 넘어왔다.


처음 개발했을 때는 문제가 없었는데 어느순간 문제가 생겼다. 기존에 빌드한 프로그램은 정상적으로 동작하는데, 새롭게 빌드한 프로그램은 에러가 난다. 


에러 메시지는 내가 그냥 찍은거라서 아무런 의미없고.. 

압축해제 로직은 전혀 건들지도 않았는데 갑자기 에러가 나니깐 정말 미칠지경이다. visual studio 사용 버전을 업그레이드 했었는데 그게 원인인가 싶어서 가상머신에 윈도우를 새로 설치하고 이전 버전의 visual studio를 다시 설치해서 테스트 해봤는데 결과가 마찬가지다. 

아직까지도 의문이다. 이런일이 가능한건지.. 일단 이 부분의 원인은 밝혀내지 못했지만, 에러가 발생하는 원인은 v3의 실시간 검사 기능 때문이었다.


에러가 발생하는 부분은 ZipArchive.cpp 파일의 아래 함수다.

int CZipArchive::CloseFile(LPCTSTR lpszFilePath, bool bAfterException)
{
	if (m_iFileOpened != extract)
	{
		TRACE(_T("No opened file.\n"));
		return false;
	}

	int iRet = 1;
	if (!bAfterException)
	{
		if (m_info.m_uUncomprLeft == 0)
		{
			if (m_info.m_uCrc32 != CurrentFile()->m_uCrc32)
				ThrowError(ZIP_BADCRC);
		}
		else
			iRet = -1;

				
		if (CurrentFile()->m_uMethod == Z_DEFLATED)
			inflateEnd(&m_info.m_stream);
		
		// 아래 블럭을 주석으로 막으면 에러는 발생하지 않는다.
		if (lpszFilePath)
		{
			try
			{
				CFileStatus fs;
				fs.m_ctime = fs.m_atime = CTime::GetCurrentTime();
				fs.m_attribute = 0;
				fs.m_mtime = CurrentFile()->GetTime();
				CFile::SetStatus(lpszFilePath, fs);
				if (SetFileAttributes(lpszFilePath, CurrentFile()->m_uExternalAttr) == 0)
					iRet = -2;
			}
			catch (CException* e)
			{
				e->Delete();
				return false;
			}
		}
	}
	m_centralDir.CloseFile();
	m_iFileOpened = nothing;
	m_info.m_pBuffer.Release();
	EmptyPtrList();
	return iRet;
}

try 블럭한 속한 부분은 파일의 속성을 설정하는 부분인데, 압축을 해제해서 새롭게 생성된 파일의 생성시간, 최종수정시간을 적용하기 위한 코드다. 

위 프로그램은 압축을 해제 한 다음 파일의 내용을 검색하고 검색이 끝난 파일은 삭제한다. 그렇기 때문에 생성시간과 수정시간은 필요가 없다. 

저 부분에서 에러가 나는건 파일의 속성을 변경하려는 시점에 v3가 실시간 검사를 위해서 파일을 동시에 접근하면서 공유위반 에러가 발생하는 듯 하다. 항상 발생하는건 아니고 운이 없으면 발생한다. (서로 동시에 접근하는 경우가 운이 없는 경우일 것이다.)

v3 실시간 검사를 끌 수는 없으니깐 주석으로 틀어막아서 해결했는데 지금 생각해보니깐 파일 공유접근을 위한 코드를 넣어서 해결이 가능할 것 같기도 하다.

Comments