5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: #include "stdafx.h" 5128eecc9f 2011-02-23 kinaba: #include "CabTool.h" 5128eecc9f 2011-02-23 kinaba: #include "kiutil.h" 5128eecc9f 2011-02-23 kinaba: #include "fdi/fdi.h" 5128eecc9f 2011-02-23 kinaba: #include "kilib/kilib.h" 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // 無理矢理SFXも解凍 5128eecc9f 2011-02-23 kinaba: static int seeker=0; 5128eecc9f 2011-02-23 kinaba: static int offhan=-1; 5128eecc9f 2011-02-23 kinaba: static int offhan2=-1; 5128eecc9f 2011-02-23 kinaba: static const char* sdll; 5128eecc9f 2011-02-23 kinaba: static kiPath* sdllr; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // CallBack 定義 5128eecc9f 2011-02-23 kinaba: static FNALLOC(mymalloc) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: return (void*)new BYTE[cb]; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNFREE(mymfree) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: delete [] (BYTE*)pv; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNOPEN(myfopen) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: int han=_open( pszFile, oflag, pmode ); 5128eecc9f 2011-02-23 kinaba: if( han!=-1 && seeker!=0 && !(oflag&_O_WRONLY) ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: _lseek( han,seeker,SEEK_SET ); 5128eecc9f 2011-02-23 kinaba: if( offhan==-1 )offhan=han; 5128eecc9f 2011-02-23 kinaba: else if( offhan2==-1 )offhan2=han; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return han; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNREAD(myfread) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: return _read( hf, pv, cb ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNWRITE(myfwrite) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: return _write( hf, pv, cb ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNCLOSE(myfclose) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( hf==offhan )offhan=-1; 5128eecc9f 2011-02-23 kinaba: else if( hf==offhan2 )offhan2=-1; 5128eecc9f 2011-02-23 kinaba: return _close(hf); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNSEEK(myfseek) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( hf==offhan || hf==offhan2 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( seektype==SEEK_SET ) 5128eecc9f 2011-02-23 kinaba: return _lseek( hf, dist+seeker, SEEK_SET ) - seeker; 5128eecc9f 2011-02-23 kinaba: return _lseek( hf, dist, seektype ) - seeker; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return _lseek( hf, dist, seektype ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: static FNFDINOTIFY(mynotif) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: switch( fdint ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: case fdintCOPY_FILE: 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: char* name = kiutil::pathMake(pfdin->psz1); 5128eecc9f 2011-02-23 kinaba: if( 0==strcmpi( kiPath::name(name), sdll ) ) // DLLの位置を記憶 5128eecc9f 2011-02-23 kinaba: *sdllr = name; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: return myfopen( name, 5128eecc9f 2011-02-23 kinaba: _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY|_O_SEQUENTIAL, 5128eecc9f 2011-02-23 kinaba: _S_IREAD|_S_IWRITE ); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: case fdintCLOSE_FILE_INFO: 5128eecc9f 2011-02-23 kinaba: myfclose( pfdin->hf ); 5128eecc9f 2011-02-23 kinaba: kiutil::timeSet( pfdin->psz1, pfdin->date, pfdin->time ); 5128eecc9f 2011-02-23 kinaba: SetFileAttributes( pfdin->psz1, 5128eecc9f 2011-02-23 kinaba: pfdin->attribs&(_A_RDONLY| _A_HIDDEN|_A_SYSTEM|_A_ARCH) ); 5128eecc9f 2011-02-23 kinaba: return TRUE; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: return 0; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: int CCabTool::FindHeader( const char* fname, const BYTE* hdr, DWORD siz ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: // FDI初期化 5128eecc9f 2011-02-23 kinaba: FDICABINETINFO info; 5128eecc9f 2011-02-23 kinaba: ERF erf; 5128eecc9f 2011-02-23 kinaba: HFDI fdi=FDICreate( mymalloc,mymfree,myfopen,myfread, 5128eecc9f 2011-02-23 kinaba: myfwrite,myfclose,myfseek,cpuUNKNOWN,&erf ); 5128eecc9f 2011-02-23 kinaba: if( fdi==NULL ) 5128eecc9f 2011-02-23 kinaba: return false; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // 開く 5128eecc9f 2011-02-23 kinaba: int ans=-1, han=myfopen( const_cast<char*>(fname), 5128eecc9f 2011-02-23 kinaba: _O_BINARY|_O_RDONLY|_O_SEQUENTIAL,0 ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // ヘッダ検索 5128eecc9f 2011-02-23 kinaba: if( -1!=han ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( siz>10 && hdr[0]=='M' && hdr[1]=='Z' ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: for( DWORD i=2; i<siz; i++ ) 5128eecc9f 2011-02-23 kinaba: if( hdr[i+0]=='M' && hdr[i+1]=='S' && hdr[i+2]=='C' && 5128eecc9f 2011-02-23 kinaba: hdr[i+3]=='F' && hdr[i+4]== 0 && hdr[i+5]== 0 && 5128eecc9f 2011-02-23 kinaba: hdr[i+6]== 0 && hdr[i+7]==0 ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: myfseek( han,i,SEEK_SET ); 5128eecc9f 2011-02-23 kinaba: if( FDIIsCabinet(fdi,han,&info) ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: ans=i; 5128eecc9f 2011-02-23 kinaba: break; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: else 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: if( FDIIsCabinet( fdi,han,&info ) ) 5128eecc9f 2011-02-23 kinaba: ans = 0; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: myfclose(han); 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: FDIDestroy( fdi ); 5128eecc9f 2011-02-23 kinaba: return ans; 5128eecc9f 2011-02-23 kinaba: } 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: bool CCabTool::Extract( const char* aname, const char* dll, kiPath& dll_rel_path ) 5128eecc9f 2011-02-23 kinaba: { 5128eecc9f 2011-02-23 kinaba: sdll = dll, sdllr = &dll_rel_path; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // ヘッダを探す 5128eecc9f 2011-02-23 kinaba: FILE* fp = fopen( aname,"rb" ); 5128eecc9f 2011-02-23 kinaba: if( !fp ) 5128eecc9f 2011-02-23 kinaba: return false; 5128eecc9f 2011-02-23 kinaba: unsigned char* buff = new unsigned char[128<<10]; 5128eecc9f 2011-02-23 kinaba: DWORD siz = fread( buff, 1, 128<<10, fp ); 5128eecc9f 2011-02-23 kinaba: fclose( fp ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: seeker = 0; 5128eecc9f 2011-02-23 kinaba: seeker = FindHeader( aname,buff,siz ); 5128eecc9f 2011-02-23 kinaba: delete [] buff; 5128eecc9f 2011-02-23 kinaba: if( seeker==-1 ) 5128eecc9f 2011-02-23 kinaba: return false; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // FDI初期化 5128eecc9f 2011-02-23 kinaba: ERF erf; 5128eecc9f 2011-02-23 kinaba: HFDI fdi=FDICreate( mymalloc,mymfree,myfopen,myfread, 5128eecc9f 2011-02-23 kinaba: myfwrite,myfclose,myfseek,cpuUNKNOWN,&erf ); 5128eecc9f 2011-02-23 kinaba: if( fdi==NULL ) 5128eecc9f 2011-02-23 kinaba: return false; 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // FDIに渡すためにファイル名分割 5128eecc9f 2011-02-23 kinaba: int y,d; 5128eecc9f 2011-02-23 kinaba: kiutil::pathSplit( aname,&y,&d ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: char fbody[MAX_PATH], fdir[MAX_PATH]={0}; 5128eecc9f 2011-02-23 kinaba: strcpy( fbody,&aname[y+1] ); 5128eecc9f 2011-02-23 kinaba: if( y!=-1 ) 5128eecc9f 2011-02-23 kinaba: strncpy( fdir,aname,y+1 ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // 展開 5128eecc9f 2011-02-23 kinaba: BOOL ans=FDICopy( fdi,fbody,fdir,0,mynotif,NULL,NULL ); 5128eecc9f 2011-02-23 kinaba: 5128eecc9f 2011-02-23 kinaba: // 終了 5128eecc9f 2011-02-23 kinaba: FDIDestroy(fdi); 5128eecc9f 2011-02-23 kinaba: return ans!=FALSE; 5128eecc9f 2011-02-23 kinaba: }