DWORD GetResourceInformation(const CResourceW &resource, CResourceW &destResource, UString &systemPathPart) { if (g_IsNT) { CByteBuffer byteBuffer; const DWORD kBufferSize = 16384; byteBuffer.SetCapacity(kBufferSize); LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer); ZeroMemory(lpnrLocal, kBufferSize); DWORD bufferSize = kBufferSize; NETRESOURCEW netResource; ConvertCResourceToNETRESOURCE(resource, netResource); LPWSTR lplpSystem; DWORD result = ::WNetGetResourceInformationW(&netResource, lpnrLocal, &bufferSize, &lplpSystem); if (result != NO_ERROR) return result; if (lplpSystem != 0) systemPathPart = lplpSystem; ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource); return result; } CResource resourceA, destResourceA; ConvertResourceWToResource(resource, resourceA); AString systemPathPartA; DWORD result = GetResourceInformation(resourceA, destResourceA, systemPathPartA); ConvertResourceToResourceW(destResourceA, destResource); systemPathPart = GetUnicodeString(systemPathPartA); return result; }
HRESULT CHandler::Open2(ISequentialInStream *stream) { const UInt32 kBufSize = 1 << 18; const UInt32 kSigSize = 4; CByteBuffer buffer; buffer.SetCapacity(kBufSize); Byte *buf = buffer; size_t processed = kSigSize; RINOK(ReadStream_FALSE(stream, buf, processed)); UInt32 sig = GetUi32(buf); bool be, mode64; switch(sig) { case 0xCEFAEDFE: be = true; mode64 = false; break; case 0xCFFAEDFE: be = true; mode64 = true; break; case 0xFEEDFACE: be = false; mode64 = false; break; case 0xFEEDFACF: be = false; mode64 = true; break; default: return S_FALSE; } processed = kBufSize - kSigSize; RINOK(ReadStream(stream, buf + kSigSize, &processed)); _mode64 = mode64; _be = be; return Parse(buf, (UInt32)processed + kSigSize) ? S_OK : S_FALSE; }
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2) { size_t c1 = a1.GetCapacity(); size_t c2 = a2.GetCapacity(); RINOZ_COMP(c1, c2); for (size_t i = 0; i < c1; i++) RINOZ_COMP(a1[i], a2[i]); return 0; }
static int CreateInArchive(pU7ZipFunctions pFunctions, const C7ZipObjectPtrArray & formatInfos, CMyComPtr<IInStream> & inStream, wstring ext, CMyComPtr<IInArchive> & archive, bool fCheckFileTypeBySignature) { for (C7ZipObjectPtrArray::const_iterator it = formatInfos.begin(); it != formatInfos.end();it++) { const C7ZipFormatInfo * pInfo = dynamic_cast<const C7ZipFormatInfo *>(*it); if (!fCheckFileTypeBySignature) { for(WStringArray::const_iterator extIt = pInfo->Exts.begin(); extIt != pInfo->Exts.end(); extIt++) { if (MyStringCompareNoCase((*extIt).c_str(), ext.c_str()) == 0) { return pFunctions->v.CreateObject(&pInfo->m_ClassID, &IID_IInArchive, (void **)&archive); } } } else { #if MY_VER_MAJOR >= 15 if (pInfo->Signatures.Size() == 0 /*&& pInfo->m_FinishSignature.length() == 0*/) #else if (pInfo->m_StartSignature.GetCapacity() == 0 /*&& pInfo->m_FinishSignature.length() == 0*/) #endif continue; //no signature #if MY_VER_MAJOR >= 15 for(unsigned i = 0; i < pInfo->Signatures.Size(); i++) { CByteBuffer signature(pInfo->Signatures[i].Size()); if (!ReadStream(inStream, pInfo->SignatureOffset, FILE_BEGIN, signature)) continue; //unable to read signature if (signature == pInfo->Signatures[i]) { return pFunctions->v.CreateObject(&pInfo->m_ClassID, &IID_IInArchive, (void **)&archive); } } #else CByteBuffer signature; signature.SetCapacity(pInfo->m_StartSignature.GetCapacity()); if (!ReadStream(inStream, 0, FILE_BEGIN, signature)) continue; //unable to read signature if (signature == pInfo->m_StartSignature) { return pFunctions->v.CreateObject(&pInfo->m_ClassID, &IID_IInArchive, (void **)&archive); } #endif } //check file type by signature } return CLASS_E_CLASSNOTAVAILABLE; }
static void TestTCPClientKeepAlive_SendData(CTcpClient& tcpClient, const CStringBuffer& buffer) { CStringBuffer sBuffer; CByteBuffer bBuffer; dword numBytesSend; sBuffer.FormatString(__FILE__LINE__ _T("##%05d## %s"), buffer.GetLength(), buffer.GetString()); sBuffer.convertToByteBuffer(bBuffer); tcpClient.SendData(bBuffer.get_Buffer(), bBuffer.get_BufferSize(), &numBytesSend); assert(numBytesSend == bBuffer.get_BufferSize()); }
HRESULT ReadStreams(IInStream *inStream, const CHeader &h, CDatabase &db) { CByteBuffer offsetBuf; RINOK(UnpackData(inStream, h.OffsetResource, h.IsLzxMode(), offsetBuf, NULL)); for (size_t i = 0; i + kStreamInfoSize <= offsetBuf.GetCapacity(); i += kStreamInfoSize) { CStreamInfo s; GetStream((const Byte *)offsetBuf + i, s); if (s.PartNumber == h.PartNumber) db.Streams.Add(s); } return S_OK; }
void SendData(CTcpClient* tcpClient, const CStringBuffer& buffer) { CScopedLock _lock; CStringBuffer sBuffer; CByteBuffer bBuffer; dword numBytesSend; sBuffer.FormatString(__FILE__LINE__ _T("##%05d## %s"), buffer.GetLength(), buffer.GetString()); sBuffer.convertToByteBuffer(bBuffer); _lock.unlock(); tcpClient->SendData(bBuffer.get_Buffer(), bBuffer.get_BufferSize(), &numBytesSend); assert(numBytesSend == bBuffer.get_BufferSize()); }
HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit) { RINOK(ReadStream_FALSE(stream, _header, kHeaderSize)); if (TestSignature2(_header)) return S_OK; CByteBuffer byteBuffer; const UInt32 kBufferSize = (1 << 16); byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; UInt32 numPrevBytes = kHeaderSize; memcpy(buffer, _header, kHeaderSize); UInt64 curTestPos = _arhiveBeginStreamPosition; for (;;) { if (searchHeaderSizeLimit != NULL) if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit) break; do { UInt32 numReadBytes = kBufferSize - numPrevBytes; UInt32 processedSize; RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize)); numPrevBytes += processedSize; if (processedSize == 0) return S_FALSE; } while (numPrevBytes <= kHeaderSize); UInt32 numTests = numPrevBytes - kHeaderSize; for (UInt32 pos = 0; pos < numTests; pos++) { for (; buffer[pos] != '7' && pos < numTests; pos++); if (pos == numTests) break; if (TestSignature(buffer + pos)) { memcpy(_header, buffer + pos, kHeaderSize); curTestPos += pos; _arhiveBeginStreamPosition = curTestPos; return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL); } } curTestPos += numTests; numPrevBytes -= numTests; memmove(buffer, buffer + numTests, numPrevBytes); } return S_FALSE; }
static HRESULT UnpackData(IInStream *inStream, const CResource &resource, bool lzxMode, CByteBuffer &buf, Byte *digest) { size_t size = (size_t)resource.UnpackSize; if (size != resource.UnpackSize) return E_OUTOFMEMORY; buf.Free(); buf.SetCapacity(size); CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2(); CMyComPtr<ISequentialOutStream> outStream = outStreamSpec; outStreamSpec->Init((Byte *)buf, size); CUnpacker unpacker; return unpacker.Unpack(inStream, resource, lzxMode, outStream, NULL, digest); }
DWORD GetResourceParent(const CResource &resource, CResource &parentResource) { CByteBuffer byteBuffer; const DWORD kBufferSize = 16384; byteBuffer.SetCapacity(kBufferSize); LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer); ZeroMemory(lpnrLocal, kBufferSize); DWORD bufferSize = kBufferSize; NETRESOURCE netResource; ConvertCResourceToNETRESOURCE(resource, netResource); DWORD result = ::WNetGetResourceParent(&netResource, lpnrLocal, &bufferSize); if (result != NO_ERROR) return result; ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource); return result; }
DWORD CEnum::Next(CResource &resource) { CByteBuffer byteBuffer; const DWORD kBufferSize = 16384; byteBuffer.SetCapacity(kBufferSize); LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer); ZeroMemory(lpnrLocal, kBufferSize); DWORD bufferSize = kBufferSize; DWORD numEntries = 1; DWORD result = Next(&numEntries, lpnrLocal, &bufferSize); if (result != NO_ERROR) return result; if (numEntries != 1) return (DWORD)E_FAIL; ConvertNETRESOURCEToCResource(lpnrLocal[0], resource); return result; }
bool GetReparseData(CFSTR path, CByteBuffer &reparseData, BY_HANDLE_FILE_INFORMATION *fileInfo) { reparseData.Free(); CInFile file; if (!file.OpenReparse(path)) return false; if (fileInfo) file.GetFileInformation(fileInfo); const unsigned kBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE; CByteArr buf(kBufSize); DWORD returnedSize; if (!file.DeviceIoControlOut(my_FSCTL_GET_REPARSE_POINT, buf, kBufSize, &returnedSize)) return false; reparseData.CopyFrom(buf, returnedSize); return true; }
LONG CKey::QueryValue(LPCTSTR name, CByteBuffer &value, UInt32 &dataSize) { DWORD type = 0; dataSize = 0; LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&dataSize); if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) return res; value.Alloc(dataSize); return QueryValue(name, (BYTE *)value, dataSize); }
DWORD GetResourceInformation(const CResource &resource, CResource &destResource, CSysString &systemPathPart) { CByteBuffer byteBuffer; const DWORD kBufferSize = 16384; byteBuffer.SetCapacity(kBufferSize); LPNETRESOURCE lpnrLocal = (LPNETRESOURCE) (BYTE *)(byteBuffer); ZeroMemory(lpnrLocal, kBufferSize); DWORD bufferSize = kBufferSize; NETRESOURCE netResource; ConvertCResourceToNETRESOURCE(resource, netResource); LPTSTR lplpSystem; DWORD result = ::WNetGetResourceInformation(&netResource, lpnrLocal, &bufferSize, &lplpSystem); if (result != NO_ERROR) return result; if (lplpSystem != 0) systemPathPart = lplpSystem; ConvertNETRESOURCEToCResource(lpnrLocal[0], destResource); return result; }
HRESULT OpenArchive(IInStream *inStream, const CHeader &h, CByteBuffer &xml, CDatabase &db) { RINOK(UnpackData(inStream, h.XmlResource, h.IsLzxMode(), xml, NULL)); RINOK(ReadStreams(inStream, h, db)); bool needBootMetadata = !h.MetadataResource.IsEmpty(); if (h.PartNumber == 1) { int imageIndex = 1; for (int j = 0; j < db.Streams.Size(); j++) { // if (imageIndex > 1) break; const CStreamInfo &si = db.Streams[j]; if (!si.Resource.IsMetadata() || si.PartNumber != h.PartNumber) continue; Byte hash[kHashSize]; CByteBuffer metadata; RINOK(UnpackData(inStream, si.Resource, h.IsLzxMode(), metadata, hash)); if (memcmp(hash, si.Hash, kHashSize) != 0) return S_FALSE; wchar_t sz[32]; ConvertUInt64ToString(imageIndex++, sz); UString s = sz; s += WCHAR_PATH_SEPARATOR; RINOK(ParseDir(metadata, metadata.GetCapacity(), s, db.Items)); if (needBootMetadata) if (h.MetadataResource.Offset == si.Resource.Offset) needBootMetadata = false; } } if (needBootMetadata) { CByteBuffer metadata; RINOK(UnpackData(inStream, h.MetadataResource, h.IsLzxMode(), metadata, NULL)); RINOK(ParseDir(metadata, metadata.GetCapacity(), L"0" WSTRING_PATH_SEPARATOR, db.Items)); } return S_OK; }
HRESULT CHandler::Open2(IInStream *stream) { const UInt32 kBufSize = 1 << 18; const UInt32 kSigSize = 4; CByteBuffer buffer; buffer.SetCapacity(kBufSize); Byte *buf = buffer; size_t processed = kSigSize; RINOK(ReadStream_FALSE(stream, buf, processed)); if (buf[0] != 0x7F || buf[1] != 'E' || buf[2] != 'L' || buf[3] != 'F') return S_FALSE; processed = kBufSize - kSigSize; RINOK(ReadStream(stream, buf + kSigSize, &processed)); processed += kSigSize; if (!Parse(buf, (UInt32)processed)) return S_FALSE; UInt64 fileSize; RINOK(stream->Seek(0, STREAM_SEEK_END, &fileSize)); return (fileSize == _totalSize) ? S_OK : S_FALSE; }
void CAsyncSerialPort::send(const CByteBuffer& buffer) { try { m_boostSerialPort.write_some(boost::asio::const_buffers_1(buffer.begin(), buffer.size())); } catch (boost::system::system_error& e) { // boost::asio::error::eof is the normal stop if (e.code() != boost::asio::error::eof) { YADOMS_LOG(error) << "Serial port write error : " << e.what(); disconnect(); } notifyEventHandler(false); throw CPortException( (e.code() == boost::asio::error::eof) ? CPortException::kConnectionClosed : CPortException::kConnectionError, e.what()); } }
static bool ReadStream(CMyComPtr<IInStream> & inStream, Int64 offset, UINT32 seekOrigin, CByteBuffer & signature) { UInt64 savedPosition = 0; UInt64 newPosition = 0; #if MY_VER_MAJOR >= 15 UInt32 readCount = signature.Size(); #else UInt32 readCount = signature.GetCapacity(); #endif unsigned char * buf = signature; if (S_OK != inStream->Seek(0, FILE_CURRENT, &savedPosition)) return false; if (S_OK != inStream->Seek(offset, seekOrigin, &newPosition)) { inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos return false; } while (readCount > 0) { UInt32 processedCount = 0; if (S_OK != inStream->Read(buf, readCount, &processedCount)) { inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos return false; } if (processedCount == 0) break; readCount -= processedCount; buf += processedCount; } inStream->Seek(savedPosition, FILE_BEGIN, &newPosition); //restore pos return readCount == 0; }
DWORD GetResourceParent(const CResourceW &resource, CResourceW &parentResource) { if (g_IsNT) { CByteBuffer byteBuffer; const DWORD kBufferSize = 16384; byteBuffer.SetCapacity(kBufferSize); LPNETRESOURCEW lpnrLocal = (LPNETRESOURCEW) (BYTE *)(byteBuffer); ZeroMemory(lpnrLocal, kBufferSize); DWORD bufferSize = kBufferSize; NETRESOURCEW netResource; ConvertCResourceToNETRESOURCE(resource, netResource); DWORD result = ::WNetGetResourceParentW(&netResource, lpnrLocal, &bufferSize); if (result != NO_ERROR) return result; ConvertNETRESOURCEToCResource(lpnrLocal[0], parentResource); return result; } CResource resourceA, parentResourceA; ConvertResourceWToResource(resource, resourceA); DWORD result = GetResourceParent(resourceA, parentResourceA); ConvertResourceToResourceW(parentResourceA, parentResource); return result; }
std::string CAsciiBufferLogger::msgToString(const CByteBuffer& data) const { std::ostringstream ss; for (size_t idx = 0 ; idx < data.size() ; ++ idx) { char c = data[idx]; switch(c) { case 0x00 : ss << "<nul>"; break; case 0x01 : ss << "<soh>"; break; case 0x02 : ss << "<stx>"; break; case 0x03 : ss << "<etx>"; break; case 0x04 : ss << "<eot>"; break; case 0x05 : ss << "<enq>"; break; case 0x06 : ss << "<ack>"; break; case 0x07 : ss << "<bel>"; break; case 0x08 : ss << "<bs>"; break; case 0x09 : ss << "<tab>"; break; case 0x0A : ss << "<lf>"; break; case 0x0B : ss << "<vt>"; break; case 0x0C : ss << "<ff>"; break; case 0x0D : ss << "<cr>"; break; case 0x0E : ss << "<so>"; break; case 0x0F : ss << "<si>"; break; case 0x10 : ss << "<dle>"; break; case 0x11 : ss << "<dc1>"; break; case 0x12 : ss << "<dc2>"; break; case 0x13 : ss << "<dc3>"; break; case 0x14 : ss << "<dc4>"; break; case 0x15 : ss << "<nak>"; break; case 0x16 : ss << "<syn>"; break; case 0x17 : ss << "<etb>"; break; case 0x18 : ss << "<can>"; break; case 0x19 : ss << "<em>"; break; case 0x1A : ss << "<sub>"; break; case 0x1B : ss << "<esc>"; break; case 0x1C : ss << "<fs>"; break; case 0x1D : ss << "<gs>"; break; case 0x1E : ss << "<rs>"; break; case 0x1F : ss << "<us>"; break; case 0x7F : ss << "<del>"; break; default: ss << c; break; } } return ss.str(); }
void COutArchive::WriteCentralDir(const CObjectVector<CItem> &items, const CByteBuffer &comment) { SeekTo(m_BasePosition); UInt64 cdOffset = GetCurrentPosition(); for(int i = 0; i < items.Size(); i++) WriteCentralHeader(items[i]); UInt64 cd64EndOffset = GetCurrentPosition(); UInt64 cdSize = cd64EndOffset - cdOffset; bool cdOffset64 = cdOffset >= 0xFFFFFFFF; bool cdSize64 = cdSize >= 0xFFFFFFFF; bool items64 = items.Size() >= 0xFFFF; bool isZip64 = (cdOffset64 || cdSize64 || items64); if (isZip64) { WriteUInt32(NSignature::kZip64EndOfCentralDir); WriteUInt64(kZip64EcdSize); // ThisDiskNumber = 0; WriteUInt16(45); // version WriteUInt16(45); // version WriteUInt32(0); // ThisDiskNumber = 0; WriteUInt32(0); // StartCentralDirectoryDiskNumber;; WriteUInt64((UInt64)items.Size()); WriteUInt64((UInt64)items.Size()); WriteUInt64((UInt64)cdSize); WriteUInt64((UInt64)cdOffset); WriteUInt32(NSignature::kZip64EndOfCentralDirLocator); WriteUInt32(0); // number of the disk with the start of the zip64 end of central directory WriteUInt64(cd64EndOffset); WriteUInt32(1); // total number of disks } WriteUInt32(NSignature::kEndOfCentralDir); WriteUInt16(0); // ThisDiskNumber = 0; WriteUInt16(0); // StartCentralDirectoryDiskNumber; WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); WriteUInt16((UInt16)(items64 ? 0xFFFF: items.Size())); WriteUInt32(cdSize64 ? 0xFFFFFFFF: (UInt32)cdSize); WriteUInt32(cdOffset64 ? 0xFFFFFFFF: (UInt32)cdOffset); UInt16 commentSize = (UInt16)comment.GetCapacity(); WriteUInt16(commentSize); if (commentSize > 0) WriteBytes((const Byte *)comment, commentSize); m_OutBuffer.FlushWithCheck(); }
void ReceiveData(CTcpClient* tcpClient, CStringBuffer& buffer) { CScopedLock _lock; CStringBuffer responseString; CByteBuffer responseBuffer; dword numDataReceived = 0; dword totalDataReceived = 0; CStringConstIterator itB; CStringBuffer sBuffer; dword numData; for ( ; totalDataReceived < 10; ) { responseBuffer.set_BufferSize(__FILE__LINE__ totalDataReceived + MAX_BUFFER); _lock.unlock(); tcpClient->ReceiveData(responseBuffer.get_Buffer() + totalDataReceived, MAX_BUFFER, &numDataReceived); totalDataReceived += numDataReceived; _lock.lock(); responseBuffer.set_BufferSize(__FILE__LINE__ totalDataReceived); } responseString.convertFromByteBuffer(responseBuffer); itB = responseString.GetString(); buffer = responseString; if ( (itB[0] == _T('#')) && (itB[1] == _T('#')) && (itB[7] == _T('#')) && (itB[8] == _T('#')) ) { responseString.SubString(2, 5, sBuffer); if ( sBuffer.ScanString(_T("%u"), &numData) <= 0 ) return; } else return; for ( ; totalDataReceived < (10 + numData); ) { responseBuffer.set_BufferSize(__FILE__LINE__ totalDataReceived + MAX_BUFFER); _lock.unlock(); tcpClient->ReceiveData(responseBuffer.get_Buffer() + totalDataReceived, MAX_BUFFER, &numDataReceived); totalDataReceived += numDataReceived; _lock.lock(); responseBuffer.set_BufferSize(__FILE__LINE__ totalDataReceived); } responseString.convertFromByteBuffer(responseBuffer); responseString.SubString(10, numData, buffer); }
void CLinkDialog::OnButton_Link() { UString from, to; _pathFromCombo.GetText(from); _pathToCombo.GetText(to); if (from.IsEmpty()) return; if (!NName::IsAbsolutePath(from)) from.Insert(0, CurDirPrefix); int idb = -1; for (unsigned i = 0;; i++) { if (i >= ARRAY_SIZE(k_LinkType_Buttons)) return; idb = k_LinkType_Buttons[i]; if (IsButtonCheckedBool(idb)) break; } NFind::CFileInfo info1, info2; bool finded1 = info1.Find(us2fs(from)); bool finded2 = info2.Find(us2fs(to)); bool isDirLink = ( idb == IDR_LINK_TYPE_SYM_DIR || idb == IDR_LINK_TYPE_JUNCTION); if (finded1 && info1.IsDir() != isDirLink || finded2 && info2.IsDir() != isDirLink) { ShowError(L"Incorrect link type"); return; } if (idb == IDR_LINK_TYPE_HARD) { if (!NDir::MyCreateHardLink(us2fs(from), us2fs(to))) { ShowLastErrorMessage(); return; } } else { bool isSymLink = (idb != IDR_LINK_TYPE_JUNCTION); CByteBuffer data; if (!FillLinkData(data, to, isSymLink)) { ShowError(L"Incorrect link"); return; } CReparseAttr attr; if (!attr.Parse(data, data.Size())) { ShowError(L"Internal conversion error"); return; } if (!NIO::SetReparseData(us2fs(from), isDirLink, data, (DWORD)data.Size())) { ShowLastErrorMessage(); return; } } End(IDOK); }
static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size) { bb.SetCapacity(size); memmove((Byte *)bb, data, size); }
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) { Set(archive, byteBuffer, byteBuffer.GetCapacity()); }
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer) { Set(archive, byteBuffer, byteBuffer.Size(), false); }
void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const { dest.SetCapacity(_size); memcpy(dest, (const Byte *)_buffer, _size); }
HRESULT CArc::OpenStream( CCodecs *codecs, int formatIndex, IInStream *stream, ISequentialInStream *seqStream, IArchiveOpenCallback *callback) { Archive.Release(); ErrorMessage.Empty(); const UString fileName = ExtractFileNameFromPath(Path); UString extension; { int dotPos = fileName.ReverseFind(L'.'); if (dotPos >= 0) extension = fileName.Mid(dotPos + 1); } CIntVector orderIndices; if (formatIndex >= 0) orderIndices.Add(formatIndex); else { int i; int numFinded = 0; for (i = 0; i < codecs->Formats.Size(); i++) if (codecs->Formats[i].FindExtension(extension) >= 0) orderIndices.Insert(numFinded++, i); else orderIndices.Add(i); if (!stream) { if (numFinded != 1) return E_NOTIMPL; orderIndices.DeleteFrom(1); } #ifndef _SFX if (orderIndices.Size() >= 2 && (numFinded == 0 || extension.CompareNoCase(L"exe") == 0)) { CIntVector orderIndices2; CByteBuffer byteBuffer; const size_t kBufferSize = (1 << 21); byteBuffer.SetCapacity(kBufferSize); RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); size_t processedSize = kBufferSize; RINOK(ReadStream(stream, byteBuffer, &processedSize)); if (processedSize == 0) return S_FALSE; const Byte *buf = byteBuffer; CByteBuffer hashBuffer; const UInt32 kNumVals = 1 << (kNumHashBytes * 8); hashBuffer.SetCapacity(kNumVals); Byte *hash = hashBuffer; memset(hash, 0xFF, kNumVals); Byte prevs[256]; if (orderIndices.Size() >= 256) return S_FALSE; int i; for (i = 0; i < orderIndices.Size(); i++) { const CArcInfoEx &ai = codecs->Formats[orderIndices[i]]; const CByteBuffer &sig = ai.StartSignature; if (sig.GetCapacity() < kNumHashBytes) continue; UInt32 v = HASH_VAL(sig, 0); prevs[i] = hash[v]; hash[v] = (Byte)i; } processedSize -= (kNumHashBytes - 1); for (UInt32 pos = 0; pos < processedSize; pos++) { for (; pos < processedSize && hash[HASH_VAL(buf, pos)] == 0xFF; pos++); if (pos == processedSize) break; UInt32 v = HASH_VAL(buf, pos); Byte *ptr = &hash[v]; int i = *ptr; do { int index = orderIndices[i]; const CArcInfoEx &ai = codecs->Formats[index]; const CByteBuffer &sig = ai.StartSignature; if (sig.GetCapacity() != 0 && pos + sig.GetCapacity() <= processedSize + (kNumHashBytes - 1) && TestSignature(buf + pos, sig, sig.GetCapacity())) { orderIndices2.Add(index); orderIndices[i] = 0xFF; *ptr = prevs[i]; } else ptr = &prevs[i]; i = *ptr; } while (i != 0xFF); } for (i = 0; i < orderIndices.Size(); i++) { int val = orderIndices[i]; if (val != 0xFF) orderIndices2.Add(val); } orderIndices = orderIndices2; } else if (extension == L"000" || extension == L"001") { CByteBuffer byteBuffer; const size_t kBufferSize = (1 << 10); byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); size_t processedSize = kBufferSize; RINOK(ReadStream(stream, buffer, &processedSize)); if (processedSize >= 16) { Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] & 1) != 0) { for (int i = 0; i < orderIndices.Size(); i++) { int index = orderIndices[i]; const CArcInfoEx &ai = codecs->Formats[index]; if (ai.Name.CompareNoCase(L"rar") != 0) continue; orderIndices.Delete(i--); orderIndices.Insert(0, index); break; } } } } if (orderIndices.Size() >= 2) { int isoIndex = codecs->FindFormatForArchiveType(L"iso"); int udfIndex = codecs->FindFormatForArchiveType(L"udf"); int iIso = -1; int iUdf = -1; for (int i = 0; i < orderIndices.Size(); i++) { if (orderIndices[i] == isoIndex) iIso = i; if (orderIndices[i] == udfIndex) iUdf = i; } if (iUdf > iIso && iIso >= 0) { orderIndices[iUdf] = isoIndex; orderIndices[iIso] = udfIndex; } } #endif } for (int i = 0; i < orderIndices.Size(); i++) { if (stream) { RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } CMyComPtr<IInArchive> archive; FormatIndex = orderIndices[i]; RINOK(codecs->CreateInArchive(FormatIndex, archive)); if (!archive) continue; #ifdef EXTERNAL_CODECS { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); } } #endif // OutputDebugStringW(codecs->Formats[FormatIndex].Name); HRESULT result; if (stream) result = archive->Open(stream, &kMaxCheckStartPosition, callback); else { CMyComPtr<IArchiveOpenSeq> openSeq; archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq); if (!openSeq) return E_NOTIMPL; result = openSeq->OpenSeq(seqStream); } if (result == S_FALSE) continue; RINOK(result); { NCOM::CPropVariant prop; archive->GetArchiveProperty(kpidError, &prop); if (prop.vt != VT_EMPTY) ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error"; } Archive = archive; const CArcInfoEx &format = codecs->Formats[FormatIndex]; if (format.Exts.Size() == 0) DefaultName = GetDefaultName2(fileName, L"", L""); else { int subExtIndex = format.FindExtension(extension); if (subExtIndex < 0) subExtIndex = 0; const CArcExtInfo &extInfo = format.Exts[subExtIndex]; DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); } return S_OK; } return S_FALSE; }
HRESULT CDecoder::Decode( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, UInt64 startPos, const UInt64 *packSizes, const CFolder &folderInfo, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress #ifndef _NO_CRYPTO , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined #endif #ifdef COMPRESS_MT , bool mtMode, UInt32 numThreads #endif ) { if (!folderInfo.CheckStructure()) return E_NOTIMPL; #ifndef _NO_CRYPTO passwordIsDefined = false; #endif CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; CLockedInStream lockedInStream; lockedInStream.Init(inStream); for (int j = 0; j < folderInfo.PackStreams.Size(); j++) { CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp; CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; lockedStreamImpSpec->Init(&lockedInStream, startPos); startPos += packSizes[j]; CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream = streamSpec; streamSpec->SetStream(lockedStreamImp); streamSpec->Init(packSizes[j]); inStreams.Add(inStream); } int numCoders = folderInfo.Coders.Size(); CBindInfoEx bindInfo; ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); bool createNewCoders; if (!_bindInfoExPrevIsDefined) createNewCoders = true; else createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); if (createNewCoders) { int i; _decoders.Clear(); // _decoders2.Clear(); _mixerCoder.Release(); if (_multiThread) { _mixerCoderMTSpec = new NCoderMixer::CCoderMixer2MT; _mixerCoder = _mixerCoderMTSpec; _mixerCoderCommon = _mixerCoderMTSpec; } else { #ifdef _ST_MODE _mixerCoderSTSpec = new NCoderMixer::CCoderMixer2ST; _mixerCoder = _mixerCoderSTSpec; _mixerCoderCommon = _mixerCoderSTSpec; #endif } RINOK(_mixerCoderCommon->SetBindInfo(bindInfo)); for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; CMyComPtr<ICompressCoder> decoder; CMyComPtr<ICompressCoder2> decoder2; RINOK(CreateCoder( EXTERNAL_CODECS_LOC_VARS coderInfo.MethodID, decoder, decoder2, false)); CMyComPtr<IUnknown> decoderUnknown; if (coderInfo.IsSimpleCoder()) { if (decoder == 0) return E_NOTIMPL; decoderUnknown = (IUnknown *)decoder; if (_multiThread) _mixerCoderMTSpec->AddCoder(decoder); #ifdef _ST_MODE else _mixerCoderSTSpec->AddCoder(decoder, false); #endif } else { if (decoder2 == 0) return E_NOTIMPL; decoderUnknown = (IUnknown *)decoder2; if (_multiThread) _mixerCoderMTSpec->AddCoder2(decoder2); #ifdef _ST_MODE else _mixerCoderSTSpec->AddCoder2(decoder2, false); #endif } _decoders.Add(decoderUnknown); #ifdef EXTERNAL_CODECS CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo)); } #endif } _bindInfoExPrev = bindInfo; _bindInfoExPrevIsDefined = true; } int i; _mixerCoderCommon->ReInit(); UInt32 packStreamIndex = 0, unpackStreamIndex = 0; UInt32 coderIndex = 0; // UInt32 coder2Index = 0; for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; CMyComPtr<IUnknown> &decoder = _decoders[coderIndex]; { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); if (setDecoderProperties) { const CByteBuffer &props = coderInfo.Props; size_t size = props.GetCapacity(); if (size > 0xFFFFFFFF) return E_NOTIMPL; if (size > 0) { RINOK(setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size)); } } } #ifdef COMPRESS_MT if (mtMode) { CMyComPtr<ICompressSetCoderMt> setCoderMt; decoder.QueryInterface(IID_ICompressSetCoderMt, &setCoderMt); if (setCoderMt) { RINOK(setCoderMt->SetNumberOfThreads(numThreads)); } } #endif #ifndef _NO_CRYPTO { CMyComPtr<ICryptoSetPassword> cryptoSetPassword; decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); if (cryptoSetPassword) { if (getTextPassword == 0) return E_FAIL; CMyComBSTR passwordBSTR; RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); CByteBuffer buffer; passwordIsDefined = true; const UString password(passwordBSTR); const UInt32 sizeInBytes = password.Length() * 2; buffer.SetCapacity(sizeInBytes); for (int i = 0; i < password.Length(); i++) { wchar_t c = password[i]; ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); } } #endif coderIndex++; UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; CRecordVector<const UInt64 *> packSizesPointers; CRecordVector<const UInt64 *> unpackSizesPointers; packSizesPointers.Reserve(numInStreams); unpackSizesPointers.Reserve(numOutStreams); UInt32 j; for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]); for (j = 0; j < numInStreams; j++, packStreamIndex++) { int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); if (bindPairIndex >= 0) packSizesPointers.Add( &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); else { int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); if (index < 0) return E_FAIL; packSizesPointers.Add(&packSizes[index]); } } _mixerCoderCommon->SetCoderInfo(i, &packSizesPointers.Front(), &unpackSizesPointers.Front()); } UInt32 mainCoder, temp; bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); if (_multiThread) _mixerCoderMTSpec->SetProgressCoderIndex(mainCoder); /* else _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; */ if (numCoders == 0) return 0; CRecordVector<ISequentialInStream *> inStreamPointers; inStreamPointers.Reserve(inStreams.Size()); for (i = 0; i < inStreams.Size(); i++) inStreamPointers.Add(inStreams[i]); ISequentialOutStream *outStreamPointer = outStream; return _mixerCoder->Code(&inStreamPointers.Front(), NULL, inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); }
HRESULT OpenArchive( CCodecs *codecs, IInStream *inStream, const UString &fileName, IInArchive **archiveResult, int &formatIndex, UString &defaultItemName, IArchiveOpenCallback *openArchiveCallback) { *archiveResult = NULL; UString extension; { int dotPos = fileName.ReverseFind(L'.'); if (dotPos >= 0) extension = fileName.Mid(dotPos + 1); } CIntVector orderIndices; int i; int numFinded = 0; for (i = 0; i < codecs->Formats.Size(); i++) if (codecs->Formats[i].FindExtension(extension) >= 0) orderIndices.Insert(numFinded++, i); else orderIndices.Add(i); #ifndef _SFX if (numFinded != 1) { CIntVector orderIndices2; CByteBuffer byteBuffer; const UInt32 kBufferSize = (200 << 10); byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); UInt32 processedSize; RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize)); for (UInt32 pos = 0; pos < processedSize; pos++) { for (int i = 0; i < orderIndices.Size(); i++) { int index = orderIndices[i]; const CArcInfoEx &ai = codecs->Formats[index]; const CByteBuffer &sig = ai.StartSignature; if (sig.GetCapacity() == 0) continue; if (pos + sig.GetCapacity() > processedSize) continue; if (TestSignature(buffer + pos, sig, sig.GetCapacity())) { orderIndices2.Add(index); orderIndices.Delete(i--); } } } orderIndices2 += orderIndices; orderIndices = orderIndices2; /* begin: extracted from 4.65 */ if (orderIndices.Size() >= 2) { int isoIndex = codecs->FindFormatForArchiveType(L"iso"); int udfIndex = codecs->FindFormatForArchiveType(L"udf"); int iIso = -1; int iUdf = -1; for (int i = 0; i < orderIndices.Size(); i++) { if (orderIndices[i] == isoIndex) iIso = i; if (orderIndices[i] == udfIndex) iUdf = i; } if (iUdf == iIso + 1) { orderIndices[iUdf] = isoIndex; orderIndices[iIso] = udfIndex; } } /* end: extracted from 4.65 */ } else if (extension == L"000" || extension == L"001") { CByteBuffer byteBuffer; const UInt32 kBufferSize = (1 << 10); byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL)); UInt32 processedSize; RINOK(ReadStream(inStream, buffer, kBufferSize, &processedSize)); if (processedSize >= 16) { Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] && 1) != 0) { for (int i = 0; i < orderIndices.Size(); i++) { int index = orderIndices[i]; const CArcInfoEx &ai = codecs->Formats[index]; if (ai.Name.CompareNoCase(L"rar") != 0) continue; orderIndices.Delete(i--); orderIndices.Insert(0, index); break; } } } } #endif HRESULT badResult = S_OK; for(i = 0; i < orderIndices.Size(); i++) { inStream->Seek(0, STREAM_SEEK_SET, NULL); CMyComPtr<IInArchive> archive; formatIndex = orderIndices[i]; RINOK(codecs->CreateInArchive(formatIndex, archive)); if (!archive) continue; #ifdef EXTERNAL_CODECS { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); } } #endif HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback); if (result == S_FALSE) continue; if(result != S_OK) { badResult = result; if(result == E_ABORT) break; continue; } *archiveResult = archive.Detach(); const CArcInfoEx &format = codecs->Formats[formatIndex]; if (format.Exts.Size() == 0) { defaultItemName = GetDefaultName2(fileName, L"", L""); } else { int subExtIndex = format.FindExtension(extension); if (subExtIndex < 0) subExtIndex = 0; defaultItemName = GetDefaultName2(fileName, format.Exts[subExtIndex].Ext, format.Exts[subExtIndex].AddExt); } return S_OK; } if (badResult != S_OK) return badResult; return S_FALSE; }