// If there is Reprase data already, it still writes new Reparse data bool SetReparseData(CFSTR path, bool isDir, const void *data, DWORD size) { NFile::NFind::CFileInfo fi; if (fi.Find(path)) { if (fi.IsDir() != isDir) { ::SetLastError(ERROR_DIRECTORY); return false; } } else { if (isDir) { if (!NDir::CreateComplexDir(path)) return false; } else { CreatePrefixDirOfFile(path); COutFile file; if (!file.Create(path, CREATE_NEW)) return false; } } COutFile file; if (!file.Open(path, FILE_SHARE_WRITE, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS)) return false; DWORD returnedSize; if (!file.DeviceIoControl(my_FSCTL_SET_REPARSE_POINT, (void *)data, size, NULL, 0, &returnedSize)) return false; return true; }
HRESULT __stdcall CArchiveExtractCallback::GetStream ( unsigned int index, ISequentialOutStream **outStream, int askExtractMode ) { CPropVariant value; IInArchive *archive = m_pArchive->m_pArchive; if ( askExtractMode == 0 ) //extract { if ( archive->GetProperty (index, kpidPath, &value) != S_OK ) return S_OK; //!!! to return error char szArcFileName[MAX_PATH]; char szFullName[MAX_PATH]; if ( value.vt == VT_BSTR ) WideCharToMultiByte (CP_OEMCP, 0, value.bstrVal, -1, szArcFileName, MAX_PATH, NULL, NULL); else { //strcpy (szArcFileName, FSF.PointToName (m_pArchive->m_lpFileName)); //CutTo (szArcFileName, '.', true); ATLASSERT(FALSE); } strcpy (szFullName, m_lpDestPath.c_str()); PathAppendA(szFullName, szArcFileName); if ( (int)m_nLastProcessed == -1 ) m_nLastProcessed = 0; FILETIME ftCreationTime, ftLastAccessTime, ftLastWriteTime; DWORD dwFileAttributes = 0; memset (&ftCreationTime, 0, sizeof (FILETIME)); memset (&ftLastAccessTime, 0, sizeof (FILETIME)); memset (&ftLastWriteTime, 0, sizeof (FILETIME)); if ( archive->GetProperty (index, kpidAttrib, &value) == S_OK ) { if ( value.vt == VT_UI4 ) dwFileAttributes = value.ulVal; } if ( archive->GetProperty (index, kpidCTime, &value) == S_OK ) { if ( value.vt == VT_FILETIME ) memcpy (&ftCreationTime, &value.filetime, sizeof (FILETIME)); } if ( archive->GetProperty (index, kpidATime, &value) == S_OK ) { if ( value.vt == VT_FILETIME ) memcpy (&ftLastAccessTime, &value.filetime, sizeof (FILETIME)); } if ( archive->GetProperty (index, kpidMTime, &value) == S_OK ) { if ( value.vt == VT_FILETIME ) memcpy (&ftLastWriteTime, &value.filetime, sizeof (FILETIME)); } bool bIsFolder = false; if ( archive->GetProperty (index, kpidIsDir, &value) == S_OK ) { if (value.vt == VT_BOOL) bIsFolder = (value.boolVal == VARIANT_TRUE); } if ( bIsFolder || dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY ) { *outStream = NULL; CreateDirEx (szFullName, dwFileAttributes); } else { CreateDirs (szFullName); COutFile *file = new COutFile (szFullName); if ( file->Open () ) { file->SetAttributes (dwFileAttributes); file->SetTime (&ftCreationTime, &ftLastAccessTime, &ftLastWriteTime); *outStream = file; m_files.push_back( szFullName ); } else delete file; } } else *outStream = NULL; return S_OK; }
HRESULT __stdcall CArchiveExtractCallback::GetStream( unsigned int index, ISequentialOutStream** outStream, int askExtractMode ) { *outStream = nullptr; ArchiveItem item; memset(&item, 0, sizeof(ArchiveItem)); if ( !m_pArchive->GetArchiveItem(index, &item) ) return S_OK; string strFileName = item.lpFileName; string strFullName = m_strDestDiskPath; if ( !FSF.LStrnicmp (strFileName, m_strPathInArchive, m_strPathInArchive.GetLength()) ) strFullName += (const TCHAR*)strFileName+m_strPathInArchive.GetLength(); //FIX ASAP!!! else strFullName += strFileName; m_uTotalBytesFile = item.nFileSize; m_uProcessedBytesFile = 0; if ( askExtractMode == NArchive::NExtract::NAskMode::kSkip ) { m_pArchive->OnEnterStage(STAGE_SKIPPING); m_pArchive->OnProcessFile(&item, nullptr); } if ( askExtractMode == NArchive::NExtract::NAskMode::kExtract ) { m_pArchive->OnEnterStage(STAGE_EXTRACTING); int nOverwrite = m_pArchive->OnProcessFile(&item, strFullName); if ( nOverwrite == PROCESS_CANCEL ) { m_bUserAbort = true; *outStream = NULL; } else { if ( nOverwrite == PROCESS_SKIP ) { m_uSuccessCount++; *outStream = NULL; return S_OK; } else { if ( OptionIsOn(item.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY) ) apiCreateDirectoryEx(strFullName); //, dwFileAttributes); else { apiCreateDirectoryForFile(strFullName); COutFile *file = new COutFile(strFullName); if ( file->Open() ) { file->SetAttributes(item.dwFileAttributes); file->SetTime(&item.ftCreationTime, &item.ftLastAccessTime, &item.ftLastWriteTime); *outStream = file; } else delete file; } } } } m_pArchive->FreeArchiveItem(&item); return S_OK; }
int CSeedFile::ExportHeaderInfo( const WCHAR* lpPath ) { int iLeft, iLen, iCopy; int nRet; char* lpBegin; WCHAR headerFile[MAX_PATH]; COutFile OutHeader; if( !seed->IsMapFileValid() ) return FALSE; if(lpPath == NULL) lpPath = path; GetExportFileName(lpPath, headerFile, EXPORT_HEADER, NULL); char szheaderFile[MAX_PATH]; WcharNameToCharName(szheaderFile, sizeof(szheaderFile), headerFile, wcslen(headerFile)); //因为提取信息时的格式字符的存在, //使得buffer安全的border要比record大小要大一点 //这里使用了2倍 if(FALSE == OutHeader.CreateFile(headerFile, CREATE_ALWAYS, NORMAL_BUFFER_SIZE_CO, m_step*2)) { //日志,添加日志 if(log != NULL) { sprintf_s(log->logString, sizeof(log->logString), "the header file name:%s", szheaderFile); log->FormatAndAppendLog(error_seed, erro_header_create_failed, log->logString); } nRet = FALSE; } else{ //提取头信息 lpBegin = (char*)seed->m_lpBase; iLeft = seed->m_iSize; iCopy = 0; iLen = 0; while (iLeft >= m_step) { //提取信息 if( IS_CONTROL_HEADER_CHAR(lpBegin[6]) ) { nRet= ExtractOneCtrlHeader(lpBegin, m_step, iCopy, &iCopy, OutHeader.m_lpCurrent); OutHeader.Adjust(nRet); } iLen += nRet; iLeft -= m_step;//剩下的字符数 lpBegin += m_step;//下一个块 } //保存并关闭文件 OutHeader.Save(); OutHeader.Free(); //添加日志 if(log != NULL) { sprintf_s(log->logString, sizeof(log->logString), "the header file name:%s. header file size: %d", szheaderFile, iLen); log->FormatAndAppendLog(info_seed, info_header_export, log->logString); } nRet = iLen; } //一个系列操作后,就保存下log if(log != NULL) log->SaveLog(); return nRet; }