Пример #1
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;
}
Пример #2
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;
}
Пример #3
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);
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}