Artifact eeea8ebd808979ec2caa7dce299adb97aae75e4f
1
2 #include "stdafx.h"
3 #include "ArcAce.h"
4 #include "NoahApp.h"
5
6
7 int CArcAce::v_load()
8 {
9 if( hDLL = kiSUtil::loadLibrary("UnAceV2") )
10 {
11 if( (aceInit = (FI)::GetProcAddress( hDLL,"ACEInitDll" ))
12 && (aceHead = (FR)::GetProcAddress( hDLL,"ACEReadArchiveData" ))
13 && (aceList = (FL)::GetProcAddress( hDLL,"ACEList" ))
14 && (aceTest = (FT)::GetProcAddress( hDLL,"ACETest" ))
15 && (aceExtr = (FE)::GetProcAddress( hDLL,"ACEExtract" )) )
16 {
17 tACEInitDllStruc ini;
18 ki_memzero( &ini, sizeof(ini) );
19
20 ini.GlobalData.Obj = this;
21 ini.GlobalData.MaxArchiveTestBytes = 0x2ffFF;
22 ini.GlobalData.MaxFileBufSize = 0x2ffFF;
23 ini.GlobalData.InfoCallbackProc = callback_info;
24 ini.GlobalData.ErrorCallbackProc = callback_error;
25 ini.GlobalData.RequestCallbackProc = callback_request;
26 ini.GlobalData.StateCallbackProc = callback_state;
27 ini.GlobalData.DecryptPassword = pwdBuf;
28
29 if( 0 == aceInit( &ini ) )
30 return aCheck|aMelt|aList|aMeltEach;
31 }
32
33 ::FreeLibrary( hDLL );
34 hDLL = NULL;
35 }
36 return 0;
37 }
38
39 bool CArcAce::v_ver( kiStr& str )
40 {
41 str = "UnAceV2.dll ";
42
43 //-- 存在確認
44 char buf[40];
45 if( hDLL )
46 if( GetVersionInfoStr( "UnAceV2", buf, sizeof(buf) ) )
47 str += buf;
48 else
49 str += "OK!";
50 else
51 str += "----";
52
53 return true;
54 }
55
56 bool CArcAce::v_check( const kiPath& aname )
57 {
58 //-- 書庫情報を読み込んでみる
59 tACEReadArchiveDataStruc dt;
60 ki_memzero( &dt, sizeof(dt) );
61 return ( 0==aceHead( const_cast<char*>((const char*)aname), &dt )
62 && NULL!=dt.ArchiveData );
63 }
64
65 bool CArcAce::v_list( const arcname& aname, aflArray& files )
66 {
67 list = &files;
68
69 //-- リスティング開始!
70 tACEListStruc lst;
71 ki_memzero( &lst, sizeof(lst) );
72 lst.Files.SourceDir = "";
73 lst.Files.FileList = "*";
74 lst.Files.ExcludeList = "";
75 lst.Files.FullMatch = FALSE;
76
77 char anm[MAX_PATH];
78 ki_strcpy( anm, aname.basedir );
79 ki_strcat( anm, aname.lname );
80
81 return ( 0==aceList( anm, &lst ) );
82 }
83
84 int CArcAce::v_contents( const kiPath& aname, kiPath& dname )
85 {
86 list = NULL;
87 aCnt = aUnknown;
88 dName = &dname;
89
90 //-- リスティング開始!
91 tACEListStruc lst;
92 ki_memzero( &lst, sizeof(lst) );
93 lst.Files.SourceDir = "";
94 lst.Files.FileList = "*";
95 lst.Files.ExcludeList = "";
96 lst.Files.FullMatch = TRUE;
97 if( 0!=aceList( const_cast<char*>((const char*)aname), &lst ) )
98 return aMulti;
99 return aCnt;
100 }
101
102 int CArcAce::v_melt( const arcname& aname, const kiPath& ddir, const aflArray* files )
103 {
104 pathCheck = new CArcPathCheckDlg;
105
106 //-- 渡すファイルリスト作成
107 kiStr lst;
108 if( files )
109 {
110 dlg = NULL;
111 for( unsigned int i=0; i!=list->len(); i++ )
112 if( (*files)[i].selected )
113 lst += (*files)[i].inf.szFileName, lst += '\xd';
114 }
115 else
116 lst = "*", dlg = new CArcProgressDlg( 32768 );
117
118 //-- 展開開始!
119 ::SetCurrentDirectory( ddir );
120
121 m_aname = aname.lname;
122 pwdBuf[0] = -1;
123
124 tACEExtractStruc ex;
125 ki_memzero( &ex, sizeof(ex) );
126 ex.Files.SourceDir = "";
127 ex.Files.FileList = const_cast<char*>((const char*)lst);
128 ex.Files.ExcludeList = "";
129 ex.Files.FullMatch = files==NULL;
130 ex.DestinationDir = const_cast<char*>((const char*)ddir);
131 ex.ExcludePath = FALSE;
132 ex.DecryptPassword = "";
133
134 char anm[MAX_PATH];
135 ki_strcpy( anm, aname.basedir );
136 ki_strcat( anm, aname.lname );
137
138 m_bCanceled = false;
139 bool ans = ( 0==aceExtr( anm, &ex ) );
140 if( dlg && ans )
141 {
142 dlg->change(NULL,32768);
143 ::Sleep(100);
144 }
145 delete dlg;
146 delete pathCheck;
147 return ans ? 0 : (m_bCanceled?0x8020:0xffff);
148 }
149
150 int __stdcall CArcAce::callback_error( pACEErrorCallbackProcStruc Error )
151 {
152 return ACE_CALLBACK_RETURN_OK;
153 }
154
155 int __stdcall CArcAce::callback_info( pACEInfoCallbackProcStruc Info )
156 {
157 return ACE_CALLBACK_RETURN_OK;
158 }
159
160 int __stdcall CArcAce::callback_request( pACERequestCallbackProcStruc Request )
161 {
162 // パスワード要求@解凍 ... ArchivedFile
163 if( Request->Global.Code == ACE_CALLBACK_REQUEST_PASSWORD
164 && Request->Global.Operation == ACE_CALLBACK_OPERATION_EXTRACT )
165 {
166 CArcAce* ace = (CArcAce*)(Request->Global.GlobalData->Obj);
167 if( ace->pwdBuf[0] == -1 )
168 {
169 ace->pwdBuf[0]=0;
170
171 CArcPwdDlg pwd( ace->dlg ? ace->dlg->hwnd() : NULL, ace->pwdBuf, 60, ace->m_aname );
172 if( IDCANCEL == pwd.getEndCode() )
173 {
174 ace->m_bCanceled = true;
175 return ACE_CALLBACK_RETURN_CANCEL;
176 }
177
178 Request->Global.GlobalData->DecryptPassword = ace->pwdBuf;
179 }
180 }
181
182 if( Request->Global.Code == ACE_CALLBACK_REQUEST_CHANGEVOLUME )
183 if( !kiSUtil::exist(Request->Archive.ArchiveData->ArchiveName) )
184 return ACE_CALLBACK_RETURN_CANCEL;
185
186 return ACE_CALLBACK_RETURN_OK;
187 }
188
189 int __stdcall CArcAce::callback_state( pACEStateCallbackProcStruc State )
190 {
191 // ファイル処理開始@解凍orリスト
192 if( State->Progress.Code == ACE_CALLBACK_STATE_STARTFILE )
193 {
194 CArcAce* ptr = (CArcAce*)(State->ArchivedFile.GlobalData->Obj);
195
196 if( State->Progress.Operation == ACE_CALLBACK_OPERATION_LIST )
197 {
198 if( !ptr->listup( *(State->ArchivedFile.FileData) ) )
199 return ACE_CALLBACK_RETURN_CANCEL;
200 }
201 else if( State->Progress.Operation == ACE_CALLBACK_OPERATION_EXTRACT )
202 {
203 if( ptr->dlg )
204 ptr->dlg->change( State->ArchivedFile.FileData->SourceFileName );
205 if( ptr->pathCheck )
206 if( containsDangerPath( State->ArchivedFile.FileData->SourceFileName ) )
207 if( ! ptr->pathCheck->is_ok_to_extract( State->ArchivedFile.FileData->SourceFileName, ptr->dlg ) )
208 return ACE_CALLBACK_RETURN_CANCEL;
209 }
210 }
211 // 進展状況グラフ@解凍
212 else if( State->Progress.Code == ACE_CALLBACK_STATE_PROGRESS )
213 {
214 CArcAce* ptr = (CArcAce*)(State->ArchivedFile.GlobalData->Obj);
215
216 if( State->Progress.Operation == ACE_CALLBACK_OPERATION_EXTRACT && ptr->dlg )
217 {
218 unsigned long prs = (unsigned long)State->Progress.ProgressData->TotalProcessedSize;
219 unsigned long ttl = (unsigned long)State->Progress.ProgressData->TotalSize;
220 ptr->dlg->change( NULL, ttl ? (int)((((__int64)prs)<<15)/ttl) : 10000 );
221 if( !ptr->dlg->msgloop() )
222 {
223 ptr->m_bCanceled = true;
224 return ACE_CALLBACK_RETURN_CANCEL;
225 }
226 }
227 }
228 // CRCチェック@解凍
229 else if( State->Progress.Code == ACE_CALLBACK_STATE_ENDCRCCHECK )
230 {
231 if( !State->CRCCheck.CRCOk )
232 ::DeleteFile( State->CRCCheck.FileData->SourceFileName );
233 }
234
235 return ACE_CALLBACK_RETURN_OK;
236 }
237
238 bool CArcAce::listup( tACEFileDataStruc& f )
239 {
240 if( list ) // 全ファイルリスティングモード
241 {
242 arcfile x;
243
244 ki_strcpy( x.inf.szFileName, f.SourceFileName );
245 x.isfile = ( 0== (f.Attributes & 0x10) ); //_A_SUBDIR
246 x.inf.dwCompressedSize = (unsigned long)f.CompressedSize;
247 x.inf.dwOriginalSize = (unsigned long)f.Size;
248 x.inf.wDate = (unsigned short)(f.Time>>16);
249 x.inf.wTime = (unsigned short)(f.Time);
250
251 if( f.Method==0 ) ki_strcpy( x.inf.szMode, "store" );
252 else if( f.Method&2 ) ki_strcpy( x.inf.szMode, "ace2" );
253 else if( f.Method&1 ) ki_strcpy( x.inf.szMode, "ace1" );
254 else ki_strcpy( x.inf.szMode, "-ace-" );
255
256 list->add( x );
257 return true;
258 }
259
260 // 書庫内ファイル構成検索モード
261 for( const char* p=f.SourceFileName; *p; p=kiStr::next(p) )
262 if( *p=='\\' || *p=='/' )
263 return true; // ルートのファイルのみ処理対象…
264
265 if( aCnt != aUnknown )
266 return false;
267
268 aCnt = (f.Attributes & 0x10) ? aSingleDir : aSingleFile;
269 if( aCnt == aSingleDir )
270 *dName = f.SourceFileName;
271
272 return true;
273 }