示例#1
0
VOID PkUpdateArchiveExtractCallback::Run()
{
    HRESULT result;
    IInArchive *currentArchive;

    PhAcquireQueuedLockExclusive(&Lock);

    while (!ThreadStopping)
    {
        if (!InArchive)
        {
            PhWaitForCondition(&Condition, &Lock, NULL);
            continue;
        }

        currentArchive = InArchive;

        currentArchive->AddRef();
        result = currentArchive->Extract(NULL, -1, FALSE, this);
        currentArchive->Release();

        if (result != E_ABORT && !SUCCEEDED(result))
            Result = result;
    }

    PhReleaseQueuedLockExclusive(&Lock);
}
HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *realIndices)
{
  _hardLinks.Clear();

  if (!_arc->Ask_INode)
    return S_OK;
  
  IInArchive *archive = _arc->Archive;
  CRecordVector<CHardLinkNode> &hardIDs = _hardLinks.IDs;

  {
    UInt32 numItems;
    if (realIndices)
      numItems = realIndices->Size();
    else
    {
      RINOK(archive->GetNumberOfItems(&numItems));
    }

    for (UInt32 i = 0; i < numItems; i++)
    {
      CHardLinkNode h;
      bool defined;
      UInt32 realIndex = realIndices ? (*realIndices)[i] : i;

      RINOK(Archive_Get_HardLinkNode(archive, realIndex, h, defined));
      if (defined)
      {
        bool isAltStream = false;
        RINOK(Archive_IsItem_AltStream(archive, realIndex, isAltStream));
        if (!isAltStream)
          hardIDs.Add(h);
      }
    }
  }
  
  hardIDs.Sort2();
  
  {
    // wee keep only items that have 2 or more items
    unsigned k = 0;
    unsigned numSame = 1;
    for (unsigned i = 1; i < hardIDs.Size(); i++)
    {
      if (hardIDs[i].Compare(hardIDs[i - 1]) != 0)
        numSame = 1;
      else if (++numSame == 2)
      {
        if (i - 1 != k)
          hardIDs[k] = hardIDs[i - 1];
        k++;
      }
    }
    hardIDs.DeleteFrom(k);
  }
  
  _hardLinks.PrepareLinks();
  return S_OK;
}
示例#3
0
int ArchiveFile::ExtractItem(int index, const char* outFilename) const
{
	assert(!s_formatInfos.empty());
	//assert(index >= 0 && index < m_numItems);
	if(!(index >= 0 && index < m_numItems)) return 0;

	ArchiveItem& item = m_items[index];
	int rv = item.size;

#ifndef ANDROID
	DWORD outAttributes = GetFileAttributes(outFilename);
	if(outAttributes & FILE_ATTRIBUTE_READONLY)
		SetFileAttributes(outFilename, outAttributes & ~FILE_ATTRIBUTE_READONLY); // temporarily remove read-only attribute so we can decompress to there
#endif

	if(m_typeIndex < 0)
	{
#ifndef ANDROID //I don't *think* we care about this
		// uncompressed
		if(!CopyFile(m_filename, outFilename, false))
#endif
			rv = 0;
	}
	else
	{
		IInArchive* object = NULL;
		HRESULT hr = E_FAIL;
		if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object)))
		{
			InFileStream* ifs = new InFileStream(m_filename);
			if(SUCCEEDED(object->Open(ifs,0,0)))
			{
				gameInfo.resize(rv);
				OutStream* os = new OutStream(index, outFilename);
				const UInt32 indices [1] = {index};
				hr = object->Extract(indices, 1, 0, os);
				object->Close();
			}
			object->Release();
		}
		if(FAILED(hr))
			rv = 0;
	}

#ifndef ANDROID
	if(outAttributes & FILE_ATTRIBUTE_READONLY)
		SetFileAttributes(outFilename, outAttributes); // restore read-only attribute
#endif

	return rv;
}
示例#4
0
HRESULT PkUpdatePackage(
    __in PPK_FILE_STREAM FileStream,
    __in PPK_PACKAGE Package,
    __in PPK_ACTION_LIST ActionList,
    __in PPK_PACKAGE_CALLBACK Callback,
    __in_opt PVOID Context
    )
{
    HRESULT result;
    IInArchive *inArchive;
    PkFileStream *fileStream;
    IOutArchive *outArchive;
    PkArchiveUpdateCallback *updateCallback;

    inArchive = (IInArchive *)Package;
    fileStream = (PkFileStream *)FileStream;
    result = inArchive->QueryInterface(IID_IOutArchive_I, (void **)&outArchive);

    if (!SUCCEEDED(result))
        return result;

    updateCallback = new PkArchiveUpdateCallback;
    updateCallback->ReferenceCount = 1;
    updateCallback->ActionList = ActionList;
    updateCallback->Callback = Callback;
    updateCallback->Context = Context;
    updateCallback->InArchive = inArchive;
    updateCallback->CreateActionMap();

    result = outArchive->UpdateItems(&fileStream->OutStream, ActionList->NumberOfActions, updateCallback);

    if (SUCCEEDED(result))
        result = PkpCloseExtractCallback(updateCallback);
    else
        PkpCloseExtractCallback(updateCallback);

    updateCallback->Release();
    outArchive->Release();

    return result;
}
示例#5
0
int ArchiveFile::ExtractItem(int index, unsigned char* outBuffer, int bufSize) const
{
	assert(!s_formatInfos.empty());
	//assert(index >= 0 && index < m_numItems);
	if(!(index >= 0 && index < m_numItems)) return 0;

	ArchiveItem& item = m_items[index];

	if(bufSize < item.size)
		return 0;

	if(m_typeIndex < 0)
	{
		// uncompressed
		FILE* file = fopen(m_filename, "rb");
		fread(outBuffer, 1, item.size, file);
		fclose(file);
	}
	else
	{
		IInArchive* object = NULL;
		HRESULT hr = E_FAIL;
		if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object)))
		{
			InFileStream* ifs = new InFileStream(m_filename);
			if(SUCCEEDED(object->Open(ifs,0,0)))
			{
				OutStream* os = new OutStream(index, outBuffer, item.size);
				const UInt32 indices [1] = {index};
				hr = object->Extract(indices, 1, 0, os);
				object->Close();
			}
			object->Release();
		}
		if(FAILED(hr))
			return 0;
	}

	return item.size;
}
示例#6
0
HRESULT CProxyArc::Load(const CArc &arc, IProgress *progress)
{
  // DWORD tickCount = GetTickCount(); for (int ttt = 0; ttt < 1; ttt++) {

  Files.Free();
  Dirs.Clear();

  Dirs.AddNew();
  IInArchive *archive = arc.Archive;

  UInt32 numItems;
  RINOK(archive->GetNumberOfItems(&numItems));
  
  if (progress)
    RINOK(progress->SetTotal(numItems));
  
  Files.Alloc(numItems);

  UString path;
  UString name;
  NCOM::CPropVariant prop;
  
  for (UInt32 i = 0; i < numItems; i++)
  {
    if (progress && (i & 0xFFFF) == 0)
    {
      UInt64 currentItemIndex = i;
      RINOK(progress->SetCompleted(&currentItemIndex));
    }
    
    const wchar_t *s = NULL;
    unsigned len = 0;
    bool isPtrName = false;

    #ifdef MY_CPU_LE
    if (arc.GetRawProps)
    {
      const void *p;
      UInt32 size;
      UInt32 propType;
      if (arc.GetRawProps->GetRawProp(i, kpidPath, &p, &size, &propType) == S_OK
          && propType == NPropDataType::kUtf16z
          && size > 2)
      {
        // is (size <= 2), it's empty name, and we call default arc.GetItemPath();
        len = size / 2 - 1;
        s = (const wchar_t *)p;
        isPtrName = true;
      }
    }
    if (!s)
    #endif
    {
      prop.Clear();
      RINOK(arc.Archive->GetProperty(i, kpidPath, &prop));
      if (prop.vt == VT_BSTR)
      {
        s = prop.bstrVal;
        len = ::SysStringLen(prop.bstrVal);
      }
      else if (prop.vt != VT_EMPTY)
        return E_FAIL;
      if (len == 0)
      {
        RINOK(arc.GetDefaultItemPath(i, path));
        len = path.Len();
        s = path;
      }
      
      /*
      RINOK(arc.GetItemPath(i, path));
      len = path.Len();
      s = path;
      */
    }

    unsigned curItem = 0;

    /*
    if (arc.Ask_Deleted)
    {
      bool isDeleted = false;
      RINOK(Archive_IsItem_Deleted(archive, i, isDeleted));
      if (isDeleted)
        curItem = AddDirSubItem(curItem, (UInt32)(Int32)-1, false, L"[DELETED]");
    }
    */

    unsigned namePos = 0;
    for (unsigned j = 0; j < len; j++)
    {
      wchar_t c = s[j];
      if (c == WCHAR_PATH_SEPARATOR || c == L'/')
      {
        name.SetFrom(s + namePos, j - namePos);
        curItem = AddDir(curItem, -1, name);
        namePos = j + 1;
      }
    }

    /*
    that code must be implemeted to hide alt streams in list.
    if (arc.Ask_AltStreams)
    {
      bool isAltStream;
      RINOK(Archive_IsItem_AltStream(archive, i, isAltStream));
      if (isAltStream)
      {

      }
    }
    */

    bool isDir;
    RINOK(Archive_IsItem_Dir(archive, i, isDir));

    CProxyFile &f = Files[i];

    f.NameLen = len - namePos;
    s += namePos;

    if (isPtrName)
      f.Name = s;
    else
    {
      f.Name = new wchar_t[f.NameLen + 1];
      f.NeedDeleteName = true;
      MyStringCopy((wchar_t *)f.Name, s);
    }

    if (isDir)
    {
      name = s;
      AddDir(curItem, (int)i, name);
    }
    else
      Dirs[curItem].SubFiles.Add(i);
  }
  
  CalculateSizes(0, archive);

  // } char s[128]; sprintf(s, "Load archive: %7d ms", GetTickCount() - tickCount); OutputDebugStringA(s);

  return S_OK;
}
示例#7
0
HRESULT ListArchives(CCodecs *codecs, const CIntVector &formatIndices,
    bool stdInMode,
    UStringVector &arcPaths, UStringVector &arcPathsFull,
    const NWildcard::CCensorNode &wildcardCensor,
    bool enableHeaders, bool techMode,
    #ifndef _NO_CRYPTO
    bool &passwordEnabled, UString &password,
    #endif
    UInt64 &numErrors)
{
  numErrors = 0;
  CFieldPrinter fieldPrinter;
  if (!techMode)
    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));

  UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
  int numArcs = /* stdInMode ? 1 : */ arcPaths.Size();
  for (int i = 0; i < numArcs; i++)
  {
    const UString &archiveName = arcPaths[i];
    UInt64 arcPackSize = 0;
    if (!stdInMode)
    {
      NFile::NFind::CFileInfoW fi;
      if (!fi.Find(archiveName) || fi.IsDir())
      {
        g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
        numErrors++;
        continue;
      }
      arcPackSize = fi.Size;
    }

    CArchiveLink archiveLink;

    COpenCallbackConsole openCallback;
    openCallback.OutStream = &g_StdOut;

    #ifndef _NO_CRYPTO

    openCallback.PasswordIsDefined = passwordEnabled;
    openCallback.Password = password;

    #endif

    HRESULT result = archiveLink.Open2(codecs, formatIndices, stdInMode, NULL, archiveName, &openCallback);
    if (result != S_OK)
    {
      if (result == E_ABORT)
        return result;
      g_StdOut << endl << "Error: " << archiveName << ": ";
      if (result == S_FALSE)
      {
        #ifndef _NO_CRYPTO
        if (openCallback.Open_WasPasswordAsked())
          g_StdOut << "Can not open encrypted archive. Wrong password?";
        else
        #endif
          g_StdOut << "Can not open file as archive";
      }
      else if (result == E_OUTOFMEMORY)
        g_StdOut << "Can't allocate required memory";
      else
        g_StdOut << NError::MyFormatMessage(result);
      g_StdOut << endl;
      numErrors++;
      continue;
    }

    if (!stdInMode)
    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = arcPathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        arcPaths.Delete(index);
        arcPathsFull.Delete(index);
        numArcs = arcPaths.Size();
      }
    }

    if (enableHeaders)
    {
      g_StdOut << endl << kListing << archiveName << endl << endl;

      for (int i = 0; i < archiveLink.Arcs.Size(); i++)
      {
        const CArc &arc = archiveLink.Arcs[i];
        
        g_StdOut << "--\n";
        PrintPropPair(L"Path", arc.Path);
        PrintPropPair(L"Type", codecs->Formats[arc.FormatIndex].Name);
        if (!arc.ErrorMessage.IsEmpty())
          PrintPropPair(L"Error", arc.ErrorMessage);
        UInt32 numProps;
        IInArchive *archive = arc.Archive;
        if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
        {
          for (UInt32 j = 0; j < numProps; j++)
          {
            CMyComBSTR name;
            PROPID propID;
            VARTYPE vt;
            RINOK(archive->GetArchivePropertyInfo(j, &name, &propID, &vt));
            NCOM::CPropVariant prop;
            RINOK(archive->GetArchiveProperty(propID, &prop));
            UString s = ConvertPropertyToString(prop, propID);
            if (!s.IsEmpty())
              PrintPropPair(GetPropName(propID, name), s);
          }
        }
        if (i != archiveLink.Arcs.Size() - 1)
        {
          UInt32 numProps;
          g_StdOut << "----\n";
          if (archive->GetNumberOfProperties(&numProps) == S_OK)
          {
            UInt32 mainIndex = archiveLink.Arcs[i + 1].SubfileIndex;
            for (UInt32 j = 0; j < numProps; j++)
            {
              CMyComBSTR name;
              PROPID propID;
              VARTYPE vt;
              RINOK(archive->GetPropertyInfo(j, &name, &propID, &vt));
              NCOM::CPropVariant prop;
              RINOK(archive->GetProperty(mainIndex, propID, &prop));
              UString s = ConvertPropertyToString(prop, propID);
              if (!s.IsEmpty())
                PrintPropPair(GetPropName(propID, name), s);
            }
          }
        }
        
      }
      g_StdOut << endl;
      if (techMode)
        g_StdOut << "----------\n";
    }

    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitle();
      g_StdOut << endl;
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
    }

    const CArc &arc = archiveLink.Arcs.Back();
    IInArchive *archive = arc.Archive;
    if (techMode)
    {
      RINOK(fieldPrinter.Init(archive));
    }
    UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
    UInt32 numItems;
    RINOK(archive->GetNumberOfItems(&numItems));
    for (UInt32 i = 0; i < numItems; i++)
    {
      if (NConsoleClose::TestBreakSignal())
        return E_ABORT;

      UString filePath;
      HRESULT res = arc.GetItemPath(i, filePath);
      if (stdInMode && res == E_INVALIDARG)
        break;
      RINOK(res);

      bool isFolder;
      RINOK(IsArchiveItemFolder(archive, i, isFolder));
      if (!wildcardCensor.CheckPath(filePath, !isFolder))
        continue;
      
      fieldPrinter.PrintItemInfo(arc, i, techMode);
      
      UInt64 packSize, unpackSize;
      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
        unpackSize = 0;
      else
        totalUnPackSizePointer = &totalUnPackSize;
      if (!GetUInt64Value(archive, i, kpidPackSize, packSize))
        packSize = 0;
      else
        totalPackSizePointer = &totalPackSize;
      
      g_StdOut << endl;

      if (isFolder)
        numDirs++;
      else
        numFiles++;
      totalPackSize += packSize;
      totalUnPackSize += unpackSize;
    }

    if (!stdInMode && totalPackSizePointer == 0)
    {
      if (archiveLink.VolumePaths.Size() != 0)
        arcPackSize += archiveLink.VolumesSize;
      totalPackSize = (numFiles == 0) ? 0 : arcPackSize;
      totalPackSizePointer = &totalPackSize;
    }
    if (totalUnPackSizePointer == 0 && numFiles == 0)
    {
      totalUnPackSize = 0;
      totalUnPackSizePointer = &totalUnPackSize;
    }
    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
      fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
      g_StdOut << endl;
    }
    if (totalPackSizePointer != 0)
    {
      totalPackSizePointer2 = &totalPackSize2;
      totalPackSize2 += totalPackSize;
    }
    if (totalUnPackSizePointer != 0)
    {
      totalUnPackSizePointer2 = &totalUnPackSize2;
      totalUnPackSize2 += totalUnPackSize;
    }
    numFiles2 += numFiles;
    numDirs2 += numDirs;
  }
  if (enableHeaders && !techMode && numArcs > 1)
  {
    g_StdOut << endl;
    fieldPrinter.PrintTitleLines();
    g_StdOut << endl;
    fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
    g_StdOut << endl;
    g_StdOut << "Archives: " << numArcs << endl;
  }
  return S_OK;
}
示例#8
0
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;
}
示例#9
0
ArchiveFile::ArchiveFile(const char* filename)
{
	assert(!s_formatInfos.empty());

	m_typeIndex = -1;
	m_numItems = 0;
	m_items = NULL;
	m_filename = NULL;

	FILE* file = fopen(filename, "rb");
	if(!file)
		return;

	m_filename = new char[strlen(filename)+1];
	strcpy(m_filename, filename);

	// detect archive type using format signature in file
	for(size_t i = 0; i < s_formatInfos.size() && m_typeIndex < 0; i++)
	{
		fseek(file, 0, SEEK_SET);
		
		std::string& formatSig = s_formatInfos[i].signature;
		int len = formatSig.size();

		if(len == 0)
			continue; // because some formats have no signature

		char* fileSig = (char*)_alloca(len);
		fread(fileSig, 1, len, file);

		if(!memcmp(formatSig.c_str(), fileSig, len))
			m_typeIndex = i;
	}

	// if no signature match has been found, detect archive type using filename.
	// this is only for signature-less formats
	const char* fileExt = strrchr(filename, '.');
	if(fileExt++)
	{
		for(size_t i = 0; i < s_formatInfos.size() && m_typeIndex < 0; i++)
		{
			if(s_formatInfos[i].signature.empty())
			{
				std::vector<std::string>& formatExts = s_formatInfos[i].extensions;
				for(size_t j = 0; j < formatExts.size(); j++)
				{
					if(!_stricmp(formatExts[j].c_str(), fileExt))
					{
						m_typeIndex = i;
						break;
					}
				}
			}
		}
	}

	if(m_typeIndex < 0)
	{
		// uncompressed

		m_numItems = 1;
		m_items = new ArchiveItem[m_numItems];

		fseek(file, 0, SEEK_END);
		m_items[0].size = ftell(file);

		m_items[0].name = new char[strlen(filename)+1];
		strcpy(m_items[0].name, filename);
	}
	else
	{
		IInArchive* object = NULL;
		if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object)))
		{
			InFileStream* ifs = new InFileStream(filename);
			if(SUCCEEDED(object->Open(ifs,0,0)))
			{
				UInt32 numItems = 0;
				object->GetNumberOfItems(&numItems);
				m_numItems = numItems;
				m_items = new ArchiveItem[m_numItems];

				for(int i = 0; i < m_numItems; i++)
				{
					PROPVARIANT var = {VT_EMPTY};
					ArchiveItem& item = m_items[i];

					object->GetProperty(i, kpidSize, &var);
					item.size = var.uhVal.LowPart;

					object->GetProperty(i, kpidPath, &var);
					std::string& path = wstrToStr(var.bstrVal);
					item.name = new char[path.size()+1];
					strcpy(item.name, path.c_str());

					//object->GetProperty(i, kpidMethod, &var);
					//std::string& method = wstrToStr(var.bstrVal);
					//item.method = new char[method.size()+1];
					//strcpy(item.method, method.c_str());

					object->GetProperty(i, kpidEncrypted, &var);
#ifdef _NO_CRYPTO
					if(var.boolVal)
						item.size = 0; // don't support decompressing it, pretend size zero
#else
					#error password support NYI... see client7z.cpp
					item.encrypted = !!var.boolVal;
#endif

					VariantClear((VARIANTARG*)&var);
				}

				object->Close();
			}

			object->Release();
		}
	}

	fclose(file);
}
示例#10
0
HRESULT CProxyArchive::Load(const CArc &arc, IProgress *progress)
{
  RootFolder.Clear();
  IInArchive *archive = arc.Archive;
  {
    ThereIsPathProp = false;
    UInt32 numProps;
    archive->GetNumberOfProperties(&numProps);
    for (UInt32 i = 0; i < numProps; i++)
    {
      CMyComBSTR name;
      PROPID propID;
      VARTYPE varType;
      RINOK(archive->GetPropertyInfo(i, &name, &propID, &varType));
      if (propID == kpidPath)
      {
        ThereIsPathProp = true;
        break;
      }
    }
  }

  UInt32 numItems;
  RINOK(archive->GetNumberOfItems(&numItems));
  if (progress != NULL)
  {
    UInt64 totalItems = numItems;
    RINOK(progress->SetTotal(totalItems));
  }
  UString fileName;
  for (UInt32 i = 0; i < numItems; i++)
  {
    if (progress != NULL && (i & 0xFFFFF) == 0)
    {
      UInt64 currentItemIndex = i;
      RINOK(progress->SetCompleted(&currentItemIndex));
    }
    UString filePath;
    RINOK(arc.GetItemPath(i, filePath));
    CProxyFolder *curItem = &RootFolder;
    int len = filePath.Length();
    fileName.Empty();
    for (int j = 0; j < len; j++)
    {
      wchar_t c = filePath[j];
      if (c == WCHAR_PATH_SEPARATOR || c == L'/')
      {
        curItem = curItem->AddDirSubItem((UInt32)(Int32)-1, false, fileName);
        fileName.Empty();
      }
      else
        fileName += c;
    }

    bool isFolder;
    RINOK(IsArchiveItemFolder(archive, i, isFolder));
    if (isFolder)
      curItem->AddDirSubItem(i, true, fileName);
    else
      curItem->AddFileSubItem(i, fileName);
  }
  RootFolder.CalculateSizes(archive);
  return S_OK;
}
示例#11
0
HRESULT ListArchives(
    CCodecs *codecs,
    UStringVector &archivePaths, UStringVector &archivePathsFull,
    const NWildcard::CCensorNode &wildcardCensor,
    bool enableHeaders, bool techMode, bool &passwordEnabled, UString &password, UInt64 &numErrors)
{
  numErrors = 0;
  CFieldPrinter fieldPrinter;
  if (!techMode)
    fieldPrinter.Init(kStandardFieldTable, sizeof(kStandardFieldTable) / sizeof(kStandardFieldTable[0]));

  UInt64 numFiles2 = 0, numDirs2 = 0, totalPackSize2 = 0, totalUnPackSize2 = 0;
  UInt64 *totalPackSizePointer2 = 0, *totalUnPackSizePointer2 = 0;
  for (int i = 0; i < archivePaths.Size(); i++)
  {
    const UString &archiveName = archivePaths[i];
    NFile::NFind::CFileInfoW archiveFileInfo;
    if (!NFile::NFind::FindFile(archiveName, archiveFileInfo) || archiveFileInfo.IsDirectory())
    {
      g_StdOut << endl << "Error: " << archiveName << " is not archive" << endl;
      numErrors++;
      continue;
    }
    if (archiveFileInfo.IsDirectory())
    {
      g_StdOut << endl << "Error: " << archiveName << " is not file" << endl;
      numErrors++;
      continue;
    }

    CArchiveLink archiveLink;

    COpenCallbackConsole openCallback;
    openCallback.OutStream = &g_StdOut;
    openCallback.PasswordIsDefined = passwordEnabled;
    openCallback.Password = password;

    HRESULT result = MyOpenArchive(codecs, archiveName, archiveLink, &openCallback);
    if (result != S_OK)
    {
      g_StdOut << endl << "Error: " << archiveName << " is not supported archive" << endl;
      numErrors++;
      continue;
    }

    for (int v = 0; v < archiveLink.VolumePaths.Size(); v++)
    {
      int index = archivePathsFull.FindInSorted(archiveLink.VolumePaths[v]);
      if (index >= 0 && index > i)
      {
        archivePaths.Delete(index);
        archivePathsFull.Delete(index);
      }
    }

    IInArchive *archive = archiveLink.GetArchive();
    const UString defaultItemName = archiveLink.GetDefaultItemName();

    if (enableHeaders)
    {
      g_StdOut << endl << kListing << archiveName << endl << endl;

      UInt32 numProps;
      if (archive->GetNumberOfArchiveProperties(&numProps) == S_OK)
      {
        for (UInt32 i = 0; i < numProps; i++)
        {
          CMyComBSTR name;
          PROPID propID;
          VARTYPE vt;
          if (archive->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK)
            continue;
          NCOM::CPropVariant prop;
          if (archive->GetArchiveProperty(propID, &prop) != S_OK)
            continue;
          UString s = ConvertPropertyToString(prop, propID);
          if (!s.IsEmpty())
            g_StdOut << GetPropName(propID, name) << " = " << s << endl;
        }
      }
      if (techMode)
        g_StdOut << "----------\n";
      if (numProps > 0)
        g_StdOut << endl;
    }

    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitle();
      g_StdOut << endl;
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
    }

    if (techMode)
    {
      RINOK(fieldPrinter.Init(archive));
    }
    UInt64 numFiles = 0, numDirs = 0, totalPackSize = 0, totalUnPackSize = 0;
    UInt64 *totalPackSizePointer = 0, *totalUnPackSizePointer = 0;
    UInt32 numItems;
    RINOK(archive->GetNumberOfItems(&numItems));
    for(UInt32 i = 0; i < numItems; i++)
    {
      if (NConsoleClose::TestBreakSignal())
        return E_ABORT;

      UString filePath;
      RINOK(GetArchiveItemPath(archive, i, defaultItemName, filePath));

      bool isFolder;
      RINOK(IsArchiveItemFolder(archive, i, isFolder));
      if (!wildcardCensor.CheckPath(filePath, !isFolder))
        continue;
      
      fieldPrinter.PrintItemInfo(archive, defaultItemName, archiveFileInfo, i, techMode);
      
      UInt64 packSize, unpackSize;
      if (!GetUInt64Value(archive, i, kpidSize, unpackSize))
        unpackSize = 0;
      else
        totalUnPackSizePointer = &totalUnPackSize;
      if (!GetUInt64Value(archive, i, kpidPackedSize, packSize))
        packSize = 0;
      else
        totalPackSizePointer = &totalPackSize;
      
      g_StdOut << endl;

      if (isFolder)
        numDirs++;
      else
        numFiles++;
      totalPackSize += packSize;
      totalUnPackSize += unpackSize;
    }
    if (enableHeaders && !techMode)
    {
      fieldPrinter.PrintTitleLines();
      g_StdOut << endl;
      fieldPrinter.PrintSummaryInfo(numFiles, numDirs, totalUnPackSizePointer, totalPackSizePointer);
      g_StdOut << endl;
    }
    if (totalPackSizePointer != 0)
    {
      totalPackSizePointer2 = &totalPackSize2;
      totalPackSize2 += totalPackSize;
    }
    if (totalUnPackSizePointer != 0)
    {
      totalUnPackSizePointer2 = &totalUnPackSize2;
      totalUnPackSize2 += totalUnPackSize;
    }
    numFiles2 += numFiles;
    numDirs2 += numDirs;
  }
  if (enableHeaders && !techMode && archivePaths.Size() > 1)
  {
    g_StdOut << endl;
    fieldPrinter.PrintTitleLines();
    g_StdOut << endl;
    fieldPrinter.PrintSummaryInfo(numFiles2, numDirs2, totalUnPackSizePointer2, totalPackSizePointer2);
    g_StdOut << endl;
    g_StdOut << "Archives: " << archivePaths.Size() << endl;
  }
  return S_OK;
}
示例#12
0
HRESULT PkArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
    HRESULT result;
    PPK_ACTION action;
    PK_PARAMETER_GET_STREAM getStream;
    PkFileStream *fileStream;

    action = GetAction(index);

    if (!action)
        return E_ABORT;

    if (action->Type == PkAddFromPackageType)
    {
        IInArchive *package;
        PROPVARIANT sizeValue;
        PkFileStream *pipe;
        IOutStream *writer;
        IInStream *reader;

        package = (IInArchive *)action->u.AddFromPackage.Package;

        PropVariantInit(&sizeValue);
        result = package->GetProperty(action->u.AddFromPackage.IndexInPackage, kpidSize, &sizeValue);

        if (!SUCCEEDED(result))
            return result;

        pipe = new PkFileStream(PkPipeFileStream, NULL, sizeValue.hVal.QuadPart);
        pipe->InitializePipe(&writer, &reader);
        pipe->Release();

        if (pipe->Buffer)
        {
            if (!ExtractCallback)
            {
                ExtractCallback = new PkUpdateArchiveExtractCallback();
                ExtractCallback->Owner = this;
                ExtractCallback->StartThread();
            }

            ExtractCallback->SetNewJob(package, action->u.AddFromPackage.IndexInPackage, writer);
            writer->Release();
            *inStream = reader;
        }
        else
        {
            writer->Release();
            reader->Release();

            return E_OUTOFMEMORY;
        }

        return S_OK;
    }
    else if (action->Type == PkUpdateType)
    {
        return E_INVALIDARG;
    }

    memset(&getStream, 0, sizeof(PK_PARAMETER_GET_STREAM));

    if (!SUCCEEDED(result = Callback(PkGetStreamMessage, action, &getStream, Context)))
    {
        *inStream = NULL;
        return result;
    }

    if (!getStream.FileStream)
    {
        *inStream = NULL;
        return E_FAIL;
    }

    fileStream = (PkFileStream *)getStream.FileStream;
    *inStream = &fileStream->InStream;

    return S_OK;
}
示例#13
0
HRESULT PkArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
    PPK_ACTION action;
    FILE_NETWORK_OPEN_INFORMATION networkOpenInfo;

    action = GetAction(index);

    if (!action)
        return E_ABORT;

    if (action->Type == PkAddFromPackageType)
    {
        HRESULT result;
        IInArchive *package;

        package = (IInArchive *)action->u.AddFromPackage.Package;

        result = package->GetProperty(action->u.AddFromPackage.IndexInPackage, propID, value);

        if (!SUCCEEDED(result))
            return result;

        return S_OK;
    }
    else if (action->Type == PkUpdateType)
    {
        return InArchive->GetProperty(action->u.Update.Index, propID, value);
    }

    switch (propID)
    {
    case kpidPath:
        value->vt = VT_BSTR;
        value->bstrVal = SysAllocString(action->u.Add.Destination->Buffer);
        break;
    case kpidIsDir:
        value->vt = VT_BOOL;
        value->boolVal = !!(action->u.Add.Flags & PK_ACTION_DIRECTORY);
        break;
    case kpidSize:
        networkOpenInfo.EndOfFile.QuadPart = 0;
        Callback(PkGetSizeMessage, action, &networkOpenInfo, Context);
        value->vt = VT_UI8;
        value->uhVal.QuadPart = networkOpenInfo.EndOfFile.QuadPart;
        break;
    case kpidAttrib:
        networkOpenInfo.FileAttributes = 0;
        Callback(PkGetAttributesMessage, action, &networkOpenInfo, Context);
        value->vt = VT_UI4;
        value->uintVal = networkOpenInfo.FileAttributes;
        break;
    case kpidCTime:
        networkOpenInfo.CreationTime.QuadPart = 0;
        Callback(PkGetCreationTimeMessage, action, &networkOpenInfo, Context);
        value->vt = VT_FILETIME;
        value->filetime.dwLowDateTime = networkOpenInfo.CreationTime.LowPart;
        value->filetime.dwHighDateTime = networkOpenInfo.CreationTime.HighPart;
        break;
    case kpidATime:
        networkOpenInfo.LastAccessTime.QuadPart = 0;
        Callback(PkGetAccessTimeMessage, action, &networkOpenInfo, Context);
        value->vt = VT_FILETIME;
        value->filetime.dwLowDateTime = networkOpenInfo.LastAccessTime.LowPart;
        value->filetime.dwHighDateTime = networkOpenInfo.LastAccessTime.HighPart;
        break;
    case kpidMTime:
        networkOpenInfo.LastWriteTime.QuadPart = 0;
        Callback(PkGetModifiedTimeMessage, action, &networkOpenInfo, Context);
        value->vt = VT_FILETIME;
        value->filetime.dwLowDateTime = networkOpenInfo.LastWriteTime.LowPart;
        value->filetime.dwHighDateTime = networkOpenInfo.LastWriteTime.HighPart;
        break;
    case kpidIsAnti:
        value->vt = VT_BOOL;
        value->boolVal = FALSE;
        break;
    }

    return S_OK;
}
示例#14
0
HRESULT PkExtractPackage(
    __in PPK_PACKAGE Package,
    __in_opt PPK_ACTION_LIST ActionList,
    __in PPK_PACKAGE_CALLBACK Callback,
    __in_opt PVOID Context
    )
{
    HRESULT result;
    IInArchive *inArchive;
    PkArchiveExtractCallback *extractCallback;
    PULONG items;
    ULONG numberOfItems;
    PPK_ACTION_SEGMENT segment;
    ULONG i;

    result = S_OK;
    inArchive = (IInArchive *)Package;

    extractCallback = new PkArchiveExtractCallback;
    extractCallback->ReferenceCount = 1;
    extractCallback->ActionList = ActionList;
    extractCallback->Callback = Callback;
    extractCallback->Context = Context;
    extractCallback->InArchive = inArchive;

    if (ActionList)
    {
        items = (PULONG)PhAllocate(sizeof(ULONG) * ActionList->NumberOfActions);
        segment = ActionList->FirstSegment;
        numberOfItems = 0;

        while (segment)
        {
            for (i = 0; i < segment->Count; i++)
            {
                if (numberOfItems >= ActionList->NumberOfActions)
                {
                    result = E_INVALIDARG;
                    break;
                }

                if (segment->Actions[i].Type == PkUpdateType)
                {
                    items[numberOfItems] = segment->Actions[i].u.Update.Index;
                    numberOfItems++;
                }
            }

            segment = segment->Next;
        }

        extractCallback->CreateActionMap();
    }
    else
    {
        items = NULL;
        numberOfItems = -1;
    }

    if (!SUCCEEDED(result))
        return result;

    result = inArchive->Extract((UInt32 *)items, numberOfItems, FALSE, extractCallback);

    if (items)
        PhFree(items);

    extractCallback->Release();

    return result;
}
示例#15
0
HRESULT PkOpenPackageWithFilter(
    __in PPK_FILE_STREAM FileStream,
    __inout_opt PPK_ACTION_LIST ActionList,
    __in_opt PPK_PACKAGE_CALLBACK Callback,
    __in_opt PVOID Context,
    __out PPK_PACKAGE *Package
    )
{
    HRESULT result;
    PkFileStream *fileStream;
    IInArchive *inArchive;
    ULONG numberOfItems;
    ULONG i;

    fileStream = (PkFileStream *)FileStream;
    result = PkpCreateSevenZipObject(&SevenZipHandlerGuid, &IID_IInArchive_I, (void **)&inArchive);

    if (!SUCCEEDED(result))
        return result;

    result = inArchive->Open(&fileStream->InStream, NULL, NULL);

    if (!SUCCEEDED(result))
    {
        inArchive->Release();
        return result;
    }

    if (ActionList)
    {
        result = inArchive->GetNumberOfItems((UInt32 *)&numberOfItems);

        if (SUCCEEDED(result))
        {
            if (Callback)
            {
                for (i = 0; i < numberOfItems; i++)
                {
                    PK_PARAMETER_FILTER_ITEM filterItem;
                    PROPVARIANT pathValue;
                    PROPVARIANT attributesValue;
                    PROPVARIANT isDirValue;

                    PropVariantInit(&pathValue);
                    PropVariantInit(&attributesValue);
                    PropVariantInit(&isDirValue);

                    if (SUCCEEDED(inArchive->GetProperty(i, kpidPath, &pathValue)) &&
                        pathValue.vt == VT_BSTR &&
                        SUCCEEDED(inArchive->GetProperty(i, kpidAttrib, &attributesValue)) &&
                        SUCCEEDED(inArchive->GetProperty(i, kpidIsDir, &isDirValue)))
                    {
                        filterItem.Reject = FALSE;
                        filterItem.Path.Length = wcslen(pathValue.bstrVal) * sizeof(WCHAR);
                        filterItem.Path.Buffer = pathValue.bstrVal;
                        filterItem.FileAttributes = attributesValue.uintVal;
                        filterItem.NewContext = NULL;

                        if (isDirValue.boolVal)
                            filterItem.FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;

                        Callback(PkFilterItemMessage, NULL, &filterItem, Context);

                        if (!filterItem.Reject)
                        {
                            PkAppendUpdateToActionList(ActionList, i, filterItem.NewContext);
                        }

                        PropVariantClear(&pathValue);
                        PropVariantClear(&attributesValue);
                        PropVariantClear(&isDirValue);
                    }
                    else
                    {
                        result = E_FAIL;
                        PropVariantClear(&pathValue);
                        PropVariantClear(&attributesValue);
                        PropVariantClear(&isDirValue);
                        break;
                    }
                }
            }
            else
            {
                for (i = 0; i < numberOfItems; i++)
                {
                    PkAppendUpdateToActionList(ActionList, i, NULL);
                }
            }
        }
    }

    if (SUCCEEDED(result))
        *Package = (PPK_PACKAGE)inArchive;
    else
        inArchive->Release();

    return result;
}
示例#16
0
static HRESULT DecompressArchive(
    const CArc &arc,
    UInt64 packSize,
    const NWildcard::CCensorNode &wildcardCensor,
    const CExtractOptions &options,
    IExtractCallbackUI *callback,
    CArchiveExtractCallback *extractCallbackSpec,
    UString &errorMessage,
    UInt64 &stdInProcessed)
{
  stdInProcessed = 0;
  IInArchive *archive = arc.Archive;
  CRecordVector<UInt32> realIndices;
  if (!options.StdInMode)
  {
    UInt32 numItems;
    RINOK(archive->GetNumberOfItems(&numItems));

    for (UInt32 i = 0; i < numItems; i++)
    {
      UString filePath;
      RINOK(arc.GetItemPath(i, filePath));
      bool isFolder;
      RINOK(IsArchiveItemFolder(archive, i, isFolder));
      if (!wildcardCensor.CheckPath(filePath, !isFolder))
        continue;
      realIndices.Add(i);
    }
    if (realIndices.Size() == 0)
    {
      callback->ThereAreNoFiles();
      return S_OK;
    }
  }

  UStringVector removePathParts;

  UString outDir = options.OutputDir;
  outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName));
  #ifdef _WIN32
  // GetCorrectFullFsPath doesn't like "..".
  // outDir.TrimRight();
  // outDir = GetCorrectFullFsPath(outDir);
  #endif

  if (!outDir.IsEmpty())
    if (!NFile::NDirectory::CreateComplexDirectory(outDir))
    {
      HRESULT res = ::GetLastError();
      if (res == S_OK)
        res = E_FAIL;
      errorMessage = ((UString)L"Can not create output directory ") + outDir;
      return res;
    }

  extractCallbackSpec->Init(
      options.StdInMode ? &wildcardCensor : NULL,
      &arc,
      callback,
      options.StdOutMode, options.TestMode, options.CalcCrc,
      outDir,
      removePathParts,
      packSize);

  #if !defined(_7ZIP_ST) && !defined(_SFX)
  RINOK(SetProperties(archive, options.Properties));
  #endif

  HRESULT result;
  Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0;
  if (options.StdInMode)
  {
    result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec);
    NCOM::CPropVariant prop;
    if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK)
      if (prop.vt == VT_UI8 || prop.vt == VT_UI4)
        stdInProcessed = ConvertPropVariantToUInt64(prop);
  }
  else
    result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec);

  return callback->ExtractResult(result);
}