ZipLocalFileHeader::ZipLocalFileHeader(std::istream& inp, bool assumeHeaderRead, ParseCallback& callback):
    _forceZip64(false),
    _rawHeader(),
    _startPos(inp.tellg()),
    _endPos(-1),
    _fileName(),
    _lastModifiedAt(),
    _extraField(),
    _crc32(0),
    _compressedSize(0),
    _uncompressedSize(0)
{
    poco_assert_dbg( (EXTRA_FIELD_POS+EXTRA_FIELD_LENGTH) == FULLHEADER_SIZE);

    if (assumeHeaderRead)
        _startPos -= ZipCommon::HEADER_SIZE;

    parse(inp, assumeHeaderRead);

    bool ok = callback.handleZipEntry(inp, *this);

    if (ok)
    {
        if (searchCRCAndSizesAfterData())
        {
            char header[ZipCommon::HEADER_SIZE]={'\x00', '\x00', '\x00', '\x00'};
            inp.read(header, ZipCommon::HEADER_SIZE);
            if (std::memcmp(header, ZipDataInfo64::HEADER, sizeof(header)) == 0) 
            {
                ZipDataInfo64 nfo(inp, true);
                setCRC(nfo.getCRC32());
                setCompressedSize(nfo.getCompressedSize());
                setUncompressedSize(nfo.getUncompressedSize());
            } 
            else 
            {
                ZipDataInfo nfo(inp, true);
                setCRC(nfo.getCRC32());
                setCompressedSize(nfo.getCompressedSize());
                setUncompressedSize(nfo.getUncompressedSize());
            }
        }
    }
    else
    {
        poco_assert_dbg(!searchCRCAndSizesAfterData());
        ZipUtil::sync(inp);
    }
    _endPos = _startPos + getHeaderSize() + _compressedSize; // exclude the data block!
}
Beispiel #2
0
int ZipStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
    if (!_ptrBuf) return 0; // directory entry
    _ptrBuf->read(buffer, length);
    int cnt = _ptrBuf->gcount();
    if (cnt > 0)
    {
        _crc32.update(buffer, cnt);
    }
    else
    {
        if (_crc32.checksum() != _expectedCrc32)
        {
            if (_checkCRC)
                throw ZipException("CRC failure");
            else
            {
                // the CRC value is written directly after the data block
                // parse it directly from the input stream
                ZipDataInfo nfo(*_pIstr, false);
                // now push back the header to the stream, so that the ZipLocalFileHeader can read it
                Poco::Int32 size = static_cast<Poco::Int32>(nfo.getFullHeaderSize());
                _expectedCrc32 = nfo.getCRC32();
                const char* rawHeader = nfo.getRawHeader();
                for (Poco::Int32 i = size-1; i >= 0; --i)
                    _pIstr->putback(rawHeader[i]);
                if (!crcValid())
                    throw ZipException("CRC failure");
            }
        }
    }
    return cnt;
}
Beispiel #3
0
void ZipArchive::parse(std::istream& in, ParseCallback& pc)
{
	// read 4 bytes
	while (in.good() && !in.eof())
	{
		char header[ZipCommon::HEADER_SIZE]={'\x00', '\x00', '\x00', '\x00'};
		in.read(header, ZipCommon::HEADER_SIZE);
		if (in.eof())
			return;
		if (std::memcmp(header, ZipLocalFileHeader::HEADER, ZipCommon::HEADER_SIZE) == 0)
		{
			ZipLocalFileHeader entry(in, true, pc);
			poco_assert (_entries.insert(std::make_pair(entry.getFileName(), entry)).second);
		}
		else if (std::memcmp(header, ZipFileInfo::HEADER, ZipCommon::HEADER_SIZE) == 0)
		{
			ZipFileInfo info(in, true);
			FileHeaders::iterator it = _entries.find(info.getFileName());
			if (it != _entries.end())
			{
				it->second.setStartPos(info.getRelativeOffsetOfLocalHeader());
			}
			poco_assert (_infos.insert(std::make_pair(info.getFileName(), info)).second);
		}
		else if (std::memcmp(header, ZipArchiveInfo::HEADER, ZipCommon::HEADER_SIZE) == 0)
		{
			ZipArchiveInfo nfo(in, true);
			poco_assert (_disks.insert(std::make_pair(nfo.getDiskNumber(), nfo)).second);
		}
		else
		{
			if (_disks.empty())
				throw Poco::IllegalStateException("Illegal header in zip file");
			else
				throw Poco::IllegalStateException("Garbage after directory header");
		}
	}
}
Beispiel #4
0
bool MakeJunction(const string& target, const string& junkpath, mgr_file::Attrs* attrs) {
	if (mgr_file::Exists(junkpath))
		return false;
	if (!mgr_file::Exists(target))
		return false;
	mgr_file::Info nfo(target);
	if (!nfo.IsDir())
		return false;
	mgr_file::MkDir(junkpath, attrs);
	str::u16string tgt(target);
	str::u16string junk(junkpath);
	ResHandle hLink(OpenLinkHandle(str::u16string(junkpath).c_str(), GENERIC_WRITE));
	if ((bool)hLink) {
		str::u16string SubstituteName("\\??\\" + target);
		REPARSE_BUF rdb;
		rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
		rdb.fill(tgt.c_str(), tgt.size(), SubstituteName.c_str(), SubstituteName.size());
		if (rdb.set(junk.c_str())) {
			return true;
		}
	}
	mgr_file::Remove(junkpath);
	return false;
}