Example #1
0
File: Net.cpp Project: BIAINC/7Zip
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;
}
Example #3
0
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;
}
Example #4
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;
}
Example #5
0
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());
}
Example #6
0
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;
}
Example #7
0
	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());
	}
Example #8
0
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;
}
Example #9
0
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);
}
Example #10
0
File: Net.cpp Project: BIAINC/7Zip
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;
}
Example #11
0
File: Net.cpp Project: BIAINC/7Zip
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;
}
Example #12
0
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;
}
Example #13
0
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);
}
Example #14
0
File: Net.cpp Project: BIAINC/7Zip
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;
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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());
   }
}
Example #18
0
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;
}
Example #19
0
File: Net.cpp Project: BIAINC/7Zip
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;
}
Example #20
0
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();
}
Example #21
0
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();
}
Example #22
0
	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);
	}
Example #23
0
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);
}
Example #24
0
static inline void SetBuffer(CByteBuffer &bb, const Byte *data, int size)
{
  bb.SetCapacity(size);
  memmove((Byte *)bb, data, size);
}
Example #25
0
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
{
  Set(archive, byteBuffer, byteBuffer.GetCapacity());
}
Example #26
0
void CStreamSwitch::Set(CInArchive *archive, const CByteBuffer &byteBuffer)
{
  Set(archive, byteBuffer, byteBuffer.Size(), false);
}
Example #27
0
void CDynBufSeqOutStream::CopyToBuffer(CByteBuffer &dest) const
{
  dest.SetCapacity(_size);
  memcpy(dest, (const Byte *)_buffer, _size);
}
Example #28
0
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;
}
Example #29
0
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);
}
Example #30
0
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;
}