Esempio n. 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);
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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);
}