diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp	2016-05-20 16:20:03.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp	2017-01-30 14:51:29.000000000 +0800
@@ -2,6 +2,9 @@
 
 #include "StdAfx.h"
 
+#include <iconv.h>
+#include <natspec.h>
+
 // #include <stdio.h>
 
 #include "../../../Common/DynamicBuffer.h"
@@ -16,6 +19,8 @@
 
 #include "ZipIn.h"
 
+#include "myPrivate.h" // global_use_utf16_conversion
+
 #define Get16(p) GetUi16(p)
 #define Get32(p) GetUi32(p)
 #define Get64(p) GetUi64(p)
@@ -604,6 +609,19 @@
 }
 
 
+void CInArchive::RecodeFileName(CItem &item) {
+  if (item.IsUtf8()) return;
+
+  /* Convert filename from archive charset to current locale's charset */
+  char *p = natspec_convert(item.Name.Ptr(), NULL, archive_oem_charset, 0);
+  if (p) {
+    item.Name = p;
+    item.SetUtf8(true);
+    USING_UTF8 = true;
+    free(p);
+  }
+}
+
 bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extraBlock,
     UInt64 &unpackSize, UInt64 &packSize, UInt64 &localHeaderOffset, UInt32 &diskStartNumber)
 {
@@ -745,6 +763,7 @@
     HeadersWarning = true;
   }
   
+  RecodeFileName(item);
   return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
 }
 
@@ -1017,6 +1036,7 @@
   G32(34, item.ExternalAttrib);
   G32(38, item.LocalHeaderPos);
   ReadFileName(nameSize, item.Name);
+  RecodeFileName(item);
   
   if (extraSize > 0)
     ReadExtra(extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk);
@@ -2126,6 +2146,9 @@
   StartStream = stream;
   Callback = callback;
   
+    /* Guess archive filename charset */
+  archive_oem_charset = natspec_get_charset_by_locale(NATSPEC_DOSCS, "");
+
   bool volWasRequested = false;
 
   if (callback
diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
--- a/CPP/7zip/Archive/Zip/ZipIn.h	2016-05-19 01:30:59.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipIn.h	2017-01-30 14:50:14.000000000 +0800
@@ -349,6 +349,9 @@
 
     return true;
   }
+
+  const char *archive_oem_charset;
+  void RecodeFileName(CItem &item);
 };
   
 }}
diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp	2016-02-02 00:50:10.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp	2017-01-30 14:50:14.000000000 +0800
@@ -15,6 +15,8 @@
 namespace NArchive {
 namespace NZip {
 
+bool USING_UTF8 = true;
+
 using namespace NFileHeader;
 
 bool CExtraSubBlock::ExtractNtfsTime(unsigned index, FILETIME &ft) const
diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
--- a/CPP/7zip/Archive/Zip/ZipItem.h	2016-05-19 01:30:59.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipItem.h	2017-01-30 14:50:14.000000000 +0800
@@ -14,6 +14,8 @@
 namespace NArchive {
 namespace NZip {
 
+extern bool USING_UTF8;
+
 struct CVersion
 {
   Byte Version;
diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp
--- a/CPP/7zip/Archive/Zip/ZipOut.cpp	2014-12-21 20:44:02.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipOut.cpp	2017-01-30 14:50:14.000000000 +0800
@@ -2,10 +2,15 @@
 
 #include "StdAfx.h"
 
+#include <iconv.h>
+#include <natspec.h>
+
 #include "../../Common/OffsetStream.h"
 
 #include "ZipOut.h"
 
+#include "myPrivate.h" // global_use_utf16_conversion
+
 namespace NArchive {
 namespace NZip {
 
@@ -18,9 +23,24 @@
   m_OutBuffer.SetStream(outStream);
   m_OutBuffer.Init();
 
+  /* Guess archive filename charset */
+  archive_oem_charset = natspec_get_charset_by_locale(NATSPEC_DOSCS, "");
+
   return m_Stream->Seek(0, STREAM_SEEK_CUR, &m_Base);
 }
 
+void COutArchive::RecodeFileName(CItem &item) {
+  if (USING_UTF8) return;
+
+  /* Convert filename from current locale charset to archive charset. */
+  char *p = natspec_convert(item.Name.Ptr(), archive_oem_charset, NULL, 0);
+  if (p) {
+    item.Name = p;
+    item.SetUtf8(false);
+    free(p);
+  }
+}
+
 void COutArchive::MoveCurPos(UInt64 distanceToMove)
 {
   m_CurPos += distanceToMove; // test overflow
diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
--- a/CPP/7zip/Archive/Zip/ZipOut.h	2015-06-19 18:52:06.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipOut.h	2017-01-30 14:50:14.000000000 +0800
@@ -81,6 +81,9 @@
 
   void CreateStreamForCompressing(IOutStream **outStream);
   void CreateStreamForCopying(ISequentialOutStream **outStream);
+
+  const char *archive_oem_charset;
+  void RecodeFileName(CItem &item);
 };
 
 }}
diff -Naur -x '.*' a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp	2016-05-20 16:35:36.000000000 +0800
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp	2017-01-30 14:50:14.000000000 +0800
@@ -79,6 +79,8 @@
   else
     isDir = item.IsDir();
 
+  archive.RecodeFileName(item);
+
   item.LocalHeaderPos = archive.GetCurPos();
   item.MadeByVersion.HostOS = kMadeByHostOS;
   item.MadeByVersion.Version = NFileHeader::NCompressionMethod::kMadeByProgramVersion;
@@ -364,6 +366,7 @@
     item.Ntfs_ATime = ui.Ntfs_ATime;
     item.Ntfs_CTime = ui.Ntfs_CTime;
     item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
+    archive.RecodeFileName(item);
 
     item.CentralExtra.RemoveUnknownSubBlocks();
     item.LocalExtra.RemoveUnknownSubBlocks();
@@ -383,6 +386,8 @@
     if (!packStream)
       return E_NOTIMPL;
     
+    archive.RecodeFileName(item);
+
     // set new header position
     item.LocalHeaderPos = archive.GetCurPos();
     
diff -Naur -x '.*' a/makefile.linux_amd64_asm b/makefile.linux_amd64_asm
--- a/makefile.linux_amd64_asm	2015-09-19 17:49:28.000000000 +0800
+++ b/makefile.linux_amd64_asm	2017-01-30 14:50:14.000000000 +0800
@@ -19,7 +19,7 @@
 
 PRE_COMPILED_HEADER=StdAfx.h.gch
 
-LOCAL_LIBS=-lpthread
+LOCAL_LIBS=-lpthread -lnatspec
 LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl
 
 CPU=x64
diff -Naur -x '.*' a/makefile.linux_any_cpu_gcc_4.X b/makefile.linux_any_cpu_gcc_4.X
--- a/makefile.linux_any_cpu_gcc_4.X	2015-09-14 02:17:48.000000000 +0800
+++ b/makefile.linux_any_cpu_gcc_4.X	2017-01-30 14:50:14.000000000 +0800
@@ -19,7 +19,7 @@
 
 PRE_COMPILED_HEADER=StdAfx.h.gch
 
-LOCAL_LIBS=-lpthread
+LOCAL_LIBS=-lpthread -lnatspec
 LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl
 
 OBJ_CRC32=$(OBJ_CRC32_C)
diff -Naur -x '.*' a/makefile.linux_x86_asm_gcc_4.X b/makefile.linux_x86_asm_gcc_4.X
--- a/makefile.linux_x86_asm_gcc_4.X	2015-09-19 17:49:28.000000000 +0800
+++ b/makefile.linux_x86_asm_gcc_4.X	2017-01-30 14:50:14.000000000 +0800
@@ -22,7 +22,7 @@
 
 PRE_COMPILED_HEADER=StdAfx.h.gch
 
-LOCAL_LIBS=-lpthread
+LOCAL_LIBS=-lpthread -lnatspec
 LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl
 
 CPU=x86
diff -Naur -x '.*' a/makefile.macosx_gcc_64bits b/makefile.macosx_gcc_64bits
--- a/makefile.macosx_gcc_64bits	2015-01-12 00:34:26.000000000 +0800
+++ b/makefile.macosx_gcc_64bits	2017-01-30 14:54:27.000000000 +0800
@@ -13,7 +13,7 @@
 CC=cc
 LINK_SHARED=-bundle
 
-LOCAL_LIBS=-framework CoreFoundation
+LOCAL_LIBS=-framework CoreFoundation -lnatspec -liconv
 LOCAL_LIBS_DLL=$(LOCAL_LIBS)
 
 OBJ_CRC32=$(OBJ_CRC32_C)
diff -Naur -x '.*' a/makefile.macosx_llvm_64bits b/makefile.macosx_llvm_64bits
--- a/makefile.macosx_llvm_64bits	2015-06-13 22:40:46.000000000 +0800
+++ b/makefile.macosx_llvm_64bits	2017-01-30 14:54:29.000000000 +0800
@@ -19,7 +19,7 @@
 
 LINK_SHARED=-bundle
 
-LOCAL_LIBS=-framework CoreFoundation
+LOCAL_LIBS=-framework CoreFoundation -lnatspec -liconv
 LOCAL_LIBS_DLL=$(LOCAL_LIBS)
 
 OBJ_CRC32=$(OBJ_CRC32_C)