Exemplo n.º 1
0
HRESULT CHeader::Parse(const Byte *p)
{
  UInt32 haderSize = Get32(p + 8);
  if (haderSize < 0x74)
    return S_FALSE;
  Version = Get32(p + 0x0C);
  Flags = Get32(p + 0x10);
  if (!IsSupported())
    return S_FALSE;
  UInt32 chunkSize = Get32(p + 0x14);
  if (chunkSize != kChunkSize && chunkSize != 0)
    return S_FALSE;
  memcpy(Guid, p + 0x18, 16);
  PartNumber = Get16(p + 0x28);
  NumParts = Get16(p + 0x2A);
  int offset = 0x2C;
  if (IsNewVersion())
  {
    NumImages = Get32(p + offset);
    offset += 4;
  }
  GetResource(p + offset, OffsetResource);
  GetResource(p + offset + 0x18, XmlResource);
  GetResource(p + offset + 0x30, MetadataResource);
  /*
  if (IsNewVersion())
  {
    if (haderSize < 0xD0)
      return S_FALSE;
    IntegrityResource.Parse(p + offset + 0x4C);
    BootIndex = Get32(p + 0x48);
  }
  */
  return S_OK;
}
Exemplo n.º 2
0
	void Assert16(const char *title, u16 x, u16 y) {
		u16 resx = Get16();
		u16 resy = Get16();
		if (resx != x || resy != y) {
			assertFailed_ = true;
			printf("%s: Failed %d, %d != expected %d, %d\n", title, resx, resy, x, y);
		}
	}
Exemplo n.º 3
0
/*
 * For use by other reformatters: find a specific resource.
 *
 * Returns "true" on success, "false" on failure.
 */
/*static*/ bool
ReformatResourceFork::GetResource(const uint8_t* srcBuf, long srcLen,
    uint16_t resourceType, uint32_t resourceID,
    const uint8_t** pResource, long* pResourceLen)
{
    /* read the file header */
    long rFileVersion, rFileToMap, rFileMapSize;
    bool littleEndian;
    bool result;

    result = ReadHeader(srcBuf, srcLen, &rFileVersion, &rFileToMap,
                &rFileMapSize, &littleEndian);
    if (!result)
        return false;

    /* move to start of resource map */
    const uint8_t* mapPtr;
    long mapToIndex, mapIndexSize, mapIndexUsed;

    mapPtr = srcBuf + rFileToMap;
    mapToIndex = Get16(mapPtr + 0x0e, littleEndian);
    mapIndexSize = Get32(mapPtr + 0x14, littleEndian);
    mapIndexUsed = Get32(mapPtr + 0x18, littleEndian);

    /* find the appropriate entry */
    const uint8_t* indexPtr = mapPtr + mapToIndex;
    int i;

    for (i = 0; i < mapIndexSize; i++) {
        uint16_t resType;
        uint32_t resID;
        
        resType = Get16(indexPtr + 0x00, littleEndian);
        if (resType == 0)
            break;      // should happen when i == mapIndexUsed
        resID = Get32(indexPtr + 0x02, littleEndian);

        if (resType == resourceType && resID == resourceID) {
            LOGI("Found resource with type=0x%04x id=0x%04x",
                resType, resID);
            *pResource = srcBuf + Get32(indexPtr + 0x06, littleEndian);
            *pResourceLen = Get32(indexPtr + 0x0c, littleEndian);
            if (*pResource + *pResourceLen > srcBuf+srcLen) {
                LOGI(" Bad bounds on resource");
                DebugBreak();
                return false;
            }
            return true;
        }

        indexPtr += kRsrcMapEntryLen;
    }

    LOGI("Resource not found (type=0x%04x id=0x%04x)",
        resourceType, resourceID);
    return false;
}
Exemplo n.º 4
0
static HRESULT ParseDirItem(const Byte *base, size_t pos, size_t size,
    const UString &prefix, CObjectVector<CItem> &items)
{
  for (;;)
  {
    if (pos + 8 > size)
      return S_FALSE;
    const Byte *p = base + pos;
    UInt64 length = Get64(p);
    if (length == 0)
      return S_OK;
    if (pos + 102 > size || pos + length + 8 > size || length > ((UInt64)1 << 62))
      return S_FALSE;
    CItem item;
    item.Attrib = Get32(p + 8);
    // item.SecurityId = Get32(p + 0xC);
    UInt64 subdirOffset = Get64(p + 0x10);
    GetFileTimeFromMem(p + 0x28, &item.CTime);
    GetFileTimeFromMem(p + 0x30, &item.ATime);
    GetFileTimeFromMem(p + 0x38, &item.MTime);
    memcpy(item.Hash, p + 0x40, kHashSize);

    // UInt16 shortNameLen = Get16(p + 98);
    UInt16 fileNameLen = Get16(p + 100);
    
    size_t tempPos = pos + 102;
    if (tempPos + fileNameLen > size)
      return S_FALSE;
    
    wchar_t *sz = item.Name.GetBuffer(prefix.Length() + fileNameLen / 2 + 1);
    MyStringCopy(sz, (const wchar_t *)prefix);
    sz += prefix.Length();
    for (UInt16 i = 0; i + 2 <= fileNameLen; i += 2)
      *sz++ = Get16(base + tempPos + i);
    *sz++ = '\0';
    item.Name.ReleaseBuffer();
    if (fileNameLen == 0 && item.isDir() && !item.HasStream())
    {
      item.Attrib = 0x10; // some swm archives have system/hidden attributes for root
      item.Name.Delete(item.Name.Length() - 1);
    }
    items.Add(item);
    pos += (size_t)length;
    if (item.isDir() && (subdirOffset != 0))
    {
      if (subdirOffset >= size)
        return S_FALSE;
      RINOK(ParseDirItem(base, (size_t)subdirOffset, size, item.Name + WCHAR_PATH_SEPARATOR, items));
    }
  }
}
Exemplo n.º 5
0
static void GetStream(const Byte *p, CStreamInfo &s)
{
  s.Resource.Parse(p);
  s.PartNumber = Get16(p + 24);
  s.RefCount = Get32(p + 26);
  memcpy(s.Hash, p + 30, kHashSize);
}
Exemplo n.º 6
0
bool CInArchive::ReadLocalItem(CItemEx &item)
{
  const unsigned kPureHeaderSize = kLocalHeaderSize - 4;
  Byte p[kPureHeaderSize];
  SafeReadBytes(p, kPureHeaderSize);
  {
    unsigned i;
    for (i = 0; i < kPureHeaderSize && p[i] == 0; i++);
    if (i == kPureHeaderSize)
      return false;
  }

  item.ExtractVersion.Version = p[0];
  item.ExtractVersion.HostOS = p[1];
  item.Flags = Get16(p + 2);
  item.Method = Get16(p + 4);
  item.Time = Get32(p + 6);
  item.Crc = Get32(p + 10);
  item.PackSize = Get32(p + 14);
  item.Size = Get32(p + 18);
  unsigned nameSize = Get16(p + 22);
  unsigned extraSize = Get16(p + 24);
  ReadFileName(nameSize, item.Name);
  item.LocalFullHeaderSize = kLocalHeaderSize + (UInt32)nameSize + extraSize;

  /*
  if (item.IsDir())
    item.Size = 0; // check It
  */

  if (extraSize > 0)
  {
    UInt64 localHeaderOffset = 0;
    UInt32 diskStartNumber = 0;
    if (!ReadExtra(extraSize, item.LocalExtra, item.Size, item.PackSize,
        localHeaderOffset, diskStartNumber))
      return false;
  }
  if (!CheckDosTime(item.Time))
  {
    HeadersWarning = true;
    // return false;
  }
  if (item.Name.Len() != nameSize)
    return false;
  return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
}
Exemplo n.º 7
0
HRESULT CHandler::Open2(IInStream *stream)
{
  UInt64 archiveStartPos;
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &archiveStartPos));

  const UInt32 kHeaderSize = 0x1C;
  Byte buf[kHeaderSize];
  RINOK(ReadStream_FALSE(stream, buf, kHeaderSize));

  UInt32 size = Get16(buf + 4);
  // UInt32 ver = Get16(buf + 6); // == 0
  if (Get32(buf) != 0x78617221 || size != kHeaderSize)
    return S_FALSE;

  UInt64 packSize = Get64(buf + 8);
  UInt64 unpackSize = Get64(buf + 0x10);
  // UInt32 checkSumAlogo = Get32(buf + 0x18);

  if (unpackSize >= kXmlSizeMax)
    return S_FALSE;

  _dataStartPos = archiveStartPos + kHeaderSize + packSize;

  char *ss = _xml.GetBuffer((int)unpackSize + 1);

  NCompress::NZlib::CDecoder *zlibCoderSpec = new NCompress::NZlib::CDecoder();
  CMyComPtr<ICompressCoder> zlibCoder = zlibCoderSpec;

  CLimitedSequentialInStream *inStreamLimSpec = new CLimitedSequentialInStream;
  CMyComPtr<ISequentialInStream> inStreamLim(inStreamLimSpec);
  inStreamLimSpec->SetStream(stream);
  inStreamLimSpec->Init(packSize);

  CBufPtrSeqOutStream *outStreamLimSpec = new CBufPtrSeqOutStream;
  CMyComPtr<ISequentialOutStream> outStreamLim(outStreamLimSpec);
  outStreamLimSpec->Init((Byte *)ss, (size_t)unpackSize);

  RINOK(zlibCoder->Code(inStreamLim, outStreamLim, NULL, NULL, NULL));

  if (outStreamLimSpec->GetPos() != (size_t)unpackSize)
    return S_FALSE;

  ss[(size_t)unpackSize] = 0;
  _xml.ReleaseBuffer();

  CXml xml;
  if (!xml.Parse(_xml))
    return S_FALSE;

  if (!xml.Root.IsTagged("xar") || xml.Root.SubItems.Size() != 1)
    return S_FALSE;
  const CXmlItem &toc = xml.Root.SubItems[0];
  if (!toc.IsTagged("toc"))
    return S_FALSE;
  if (!AddItem(toc, _files, -1))
    return S_FALSE;
  return S_OK;
}
Exemplo n.º 8
0
HRESULT CInArchive::Open2(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
  m_CryptoMode = false;
  RINOK(stream->Seek(0, STREAM_SEEK_SET, &m_StreamStartPosition));
  m_Position = m_StreamStartPosition;

  UInt64 arcStartPos;
  RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
      searchHeaderSizeLimit, arcStartPos));
  m_Position = arcStartPos + NHeader::kMarkerSize;
  RINOK(stream->Seek(m_Position, STREAM_SEEK_SET, NULL));
  Byte buf[NHeader::NArchive::kArchiveHeaderSize + 1];

  RINOK(ReadStream_FALSE(stream, buf, NHeader::NArchive::kArchiveHeaderSize));
  AddToSeekValue(NHeader::NArchive::kArchiveHeaderSize);


  UInt32 blockSize = Get16(buf + 5);

  _header.EncryptVersion = 0;
  _header.Flags = Get16(buf + 3);

  UInt32 headerSize = NHeader::NArchive::kArchiveHeaderSize;
  if (_header.IsThereEncryptVer())
  {
    if (blockSize <= headerSize)
      return S_FALSE;
    RINOK(ReadStream_FALSE(stream, buf + NHeader::NArchive::kArchiveHeaderSize, 1));
    AddToSeekValue(1);
    _header.EncryptVersion = buf[NHeader::NArchive::kArchiveHeaderSize];
    headerSize += 1;
  }
  if (blockSize < headerSize ||
      buf[2] != NHeader::NBlockType::kArchiveHeader ||
      (UInt32)Get16(buf) != (CrcCalc(buf + 2, headerSize - 2) & 0xFFFF))
    return S_FALSE;

  size_t commentSize = blockSize - headerSize; 
  _comment.SetCapacity(commentSize);
  RINOK(ReadStream_FALSE(stream, _comment, commentSize));
  AddToSeekValue(commentSize);
  m_Stream = stream;
  _header.StartPosition = arcStartPos;
  return S_OK;
}
Exemplo n.º 9
0
HRESULT CTag::Parse(const Byte *buf, size_t size)
{
  if (size < 16)
    return S_FALSE;
  Byte sum = 0;
  int i;
  for (i = 0; i <  4; i++) sum = (Byte)(sum + buf[i]);
  for (i = 5; i < 16; i++) sum = (Byte)(sum + buf[i]);
  if (sum != buf[4] || buf[5] != 0) return S_FALSE;

  Id = Get16(buf);
  Version = Get16(buf + 2);
  // SerialNumber = Get16(buf + 6);
  UInt16 crc = Get16(buf + 8);
  UInt16 crcLen = Get16(buf + 10);
  // TagLocation = Get32(buf + 12);

  if (size >= 16 + (size_t)crcLen)
    if (crc == Crc16Calc(buf + 16, crcLen))
      return S_OK;
  return S_FALSE;
}
Exemplo n.º 10
0
bool CReparseShortInfo::Parse(const Byte *p, size_t size)
{
  const Byte *start = p;
  Offset= 0;
  Size = 0;
  if (size < 8)
    return false;
  UInt32 Tag = Get32(p);
  UInt32 len = Get16(p + 4);
  if (len + 8 > size)
    return false;
  /*
  if ((type & kReparseFlags_Alias) == 0 ||
      (type & kReparseFlags_Microsoft) == 0 ||
      (type & 0xFFFF) != 3)
  */
  if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
      Tag != _my_IO_REPARSE_TAG_SYMLINK)
    // return true;
    return false;

  if (Get16(p + 6) != 0) // padding
    return false;
  
  p += 8;
  size -= 8;
  
  if (len != size) // do we need that check?
    return false;
  
  if (len < 8)
    return false;
  unsigned subOffs = Get16(p);
  unsigned subLen = Get16(p + 2);
  unsigned printOffs = Get16(p + 4);
  unsigned printLen = Get16(p + 6);
  len -= 8;
  p += 8;

  // UInt32 Flags = 0;
  if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
  {
    if (len < 4)
      return false;
    // Flags = Get32(p);
    len -= 4;
    p += 4;
  }

  if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
    return false;
  if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
    return false;

  Offset = (unsigned)(p - start) + subOffs;
  Size = subLen;
  return true;
}
Exemplo n.º 11
0
//--------------------------------------------------------------------------
// Evaluate number, be it int, rational, or float from directory.
//--------------------------------------------------------------------------
double CExifParse::ConvertAnyFormat(const void* const ValuePtr, int Format)
{
  double Value;
  Value = 0;

  switch(Format)
  {
    case FMT_SBYTE:     Value = *(const   signed char*)ValuePtr;          break;
    case FMT_BYTE:      Value = *(const unsigned char*)ValuePtr;          break;

    case FMT_USHORT:    Value = Get16(ValuePtr, m_MotorolaOrder);   break;
    case FMT_ULONG:     Value = (unsigned)Get32(ValuePtr, m_MotorolaOrder);   break;

    case FMT_URATIONAL:
    case FMT_SRATIONAL:
    {
      int Num,Den;
      Num = Get32(ValuePtr, m_MotorolaOrder);
      Den = Get32(4+(const char *)ValuePtr, m_MotorolaOrder);

      if (Den == 0)    Value = 0;
      else             Value = (double)Num/Den;
    }
    break;

    case FMT_SSHORT:    Value = (signed short)Get16(ValuePtr, m_MotorolaOrder);    break;
    case FMT_SLONG:     Value = Get32(ValuePtr, m_MotorolaOrder);                  break;

    // Not sure if this is correct (never seen float used in Exif format)
    case FMT_SINGLE:    Value = (double)*(const float*)ValuePtr;          break;
    case FMT_DOUBLE:    Value = *(const double*)ValuePtr;                 break;

    default:
      ErrNonfatal("Illegal format code %d",Format,0);
  }
  return Value;
}
Exemplo n.º 12
0
static bool ParseUtf16zString(const Byte *p, UInt32 size, UString &res)
{
  if ((size & 1) != 0)
    return false;
  res.Empty();
  UInt32 i;
  for (i = 0; i < size; i += 2)
  {
    wchar_t c = Get16(p + i);
    if (c == 0)
      break;
    res += c;
  }
  return (i == size - 2);
}
Exemplo n.º 13
0
bool CReparseAttr::Parse(const Byte *p, size_t size)
{
  if (size < 8)
    return false;
  Tag = Get32(p);
  UInt32 len = Get16(p + 4);
  if (len + 8 > size)
    return false;
  /*
  if ((type & kReparseFlags_Alias) == 0 ||
      (type & kReparseFlags_Microsoft) == 0 ||
      (type & 0xFFFF) != 3)
  */
  if (Tag != _my_IO_REPARSE_TAG_MOUNT_POINT &&
      Tag != _my_IO_REPARSE_TAG_SYMLINK)
    // return true;
    return false;

  if (Get16(p + 6) != 0) // padding
    return false;
  
  p += 8;
  size -= 8;
  
  if (len != size) // do we need that check?
    return false;
  
  if (len < 8)
    return false;
  unsigned subOffs = Get16(p);
  unsigned subLen = Get16(p + 2);
  unsigned printOffs = Get16(p + 4);
  unsigned printLen = Get16(p + 6);
  len -= 8;
  p += 8;

  Flags = 0;
  if (Tag == _my_IO_REPARSE_TAG_SYMLINK)
  {
    if (len < 4)
      return false;
    Flags = Get32(p);
    len -= 4;
    p += 4;
  }

  if ((subOffs & 1) != 0 || subOffs > len || len - subOffs < subLen)
    return false;
  if ((printOffs & 1) != 0 || printOffs > len || len - printOffs < printLen)
    return false;
  GetString(p + subOffs, subLen >> 1, SubsName);
  GetString(p + printOffs, printLen >> 1, PrintName);

  return true;
}
Exemplo n.º 14
0
HRESULT CInArchive::ReadCdItem(CItemEx &item)
{
  item.FromCentral = true;
  Byte p[kCentralHeaderSize - 4];
  SafeReadBytes(p, kCentralHeaderSize - 4);

  item.MadeByVersion.Version = p[0];
  item.MadeByVersion.HostOS = p[1];
  item.ExtractVersion.Version = p[2];
  item.ExtractVersion.HostOS = p[3];
  item.Flags = Get16(p + 4);
  item.Method = Get16(p + 6);
  item.Time = Get32(p + 8);
  item.Crc = Get32(p + 12);
  item.PackSize = Get32(p + 16);
  item.Size = Get32(p + 20);
  unsigned nameSize = Get16(p + 24);
  UInt16 extraSize = Get16(p + 26);
  UInt16 commentSize = Get16(p + 28);
  UInt32 diskNumberStart = Get16(p + 30);
  item.InternalAttrib = Get16(p + 32);
  item.ExternalAttrib = Get32(p + 34);
  item.LocalHeaderPos = Get32(p + 38);
  ReadFileName(nameSize, item.Name);

  if (extraSize > 0)
  {
    ReadExtra(extraSize, item.CentralExtra, item.Size, item.PackSize,
        item.LocalHeaderPos, diskNumberStart);
  }

  if (diskNumberStart != 0)
    return E_NOTIMPL;

  // May be these strings must be deleted
  /*
  if (item.IsDir())
    item.Size = 0;
  */

  ReadBuffer(item.Comment, commentSize);
  return S_OK;
}
Exemplo n.º 15
0
void CInByte2::ReadString(UString &s)
{
  const Byte *buf = _buffer + _pos;
  size_t rem = (_size - _pos) / 2 * 2;
  {
    size_t i;
    for (i = 0; i < rem; i += 2)
      if (buf[i] == 0 && buf[i + 1] == 0)
        break;
    if (i == rem)
      ThrowEndOfData();
    rem = i;
  }
  int len = (int)(rem / 2);
  if (len < 0 || (size_t)len * 2 != rem)
    ThrowUnsupported();
  wchar_t *p = s.GetBuffer(len);
  int i;
  for (i = 0; i < len; i++, buf += 2)
    p[i] = (wchar_t)Get16(buf);
  s.ReleaseBuffer(len);
  _pos += rem + 2;
}
Exemplo n.º 16
0
//--------------------------------------------------------------------------
// Process a EXIF marker
// Describes all the drivel that most digital cameras include...
//--------------------------------------------------------------------------
bool CExifParse::Process (const unsigned char* const ExifSection, const unsigned short length, ExifInfo_t *info)
{
  m_ExifInfo = info;
  // EXIF signature: "Exif\0\0"
  // Check EXIF signatures
  const char ExifHeader[]     = "Exif\0\0";
  const char ExifAlignment0[] = "II";
  const char ExifAlignment1[] = "MM";
  const char ExifExtra        = 0x2a;

  const char* pos = (const char*)(ExifSection + sizeof(short));   // position data pointer after length field

  if (memcmp(pos, ExifHeader,6))
  {
    printf("ExifParse: incorrect Exif header");
    return false;
  }
  pos += 6;

  if (memcmp(pos, ExifAlignment0, strlen(ExifAlignment0)) == 0)
  {
    m_MotorolaOrder = false;
  }
  else if (memcmp(pos, ExifAlignment1, strlen(ExifAlignment1)) == 0)
  {
    m_MotorolaOrder = true;
  }
  else
  {
    printf("ExifParse: invalid Exif alignment marker");
    return false;
  }
  pos += strlen(ExifAlignment0);

  // Check the next value for correctness.
  if (Get16((const void*)(pos), m_MotorolaOrder) != ExifExtra)
  {
    printf("ExifParse: invalid Exif start (1)");
    return false;
  }
  pos += sizeof(short);

  unsigned long FirstOffset = (unsigned)Get32((const void*)pos, m_MotorolaOrder);
  if (FirstOffset < 8 || FirstOffset > 16)
  {
    // Usually set to 8, but other values valid too.
//  CLog::Log(LOGERROR, "ExifParse: suspicious offset of first IFD value");
  }



  // First directory starts 16 bytes in.  All offset are relative to 8 bytes in.
  ProcessDir(ExifSection+8+FirstOffset, ExifSection+8, length-8, 0);

  m_ExifInfo->ThumbnailAtEnd = m_ExifInfo->ThumbnailOffset >= m_LargestExifOffset;

  // Compute the CCD width, in millimeters.
  if (m_FocalPlaneXRes != 0)
  {
    // Note: With some cameras, its not possible to compute this correctly because
    // they don't adjust the indicated focal plane resolution units when using less
    // than maximum resolution, so the CCDWidth value comes out too small.  Nothing
    // that Jhead can do about it - its a camera problem.
    m_ExifInfo->CCDWidth = (float)(m_ExifImageWidth * m_FocalPlaneUnits / m_FocalPlaneXRes);
  }

  if (m_ExifInfo->FocalLength)
  {
    if (m_ExifInfo->FocalLength35mmEquiv == 0)
    {
      // Compute 35 mm equivalent focal length based on sensor geometry if we haven't
      // already got it explicitly from a tag.
      if (m_ExifInfo->CCDWidth != 0.0)
      {
        m_ExifInfo->FocalLength35mmEquiv = (int)(m_ExifInfo->FocalLength/m_ExifInfo->CCDWidth*36 + 0.5);
      }
    }
  }
  return true;
}
Exemplo n.º 17
0
void CLogBlockAddr::Parse(const Byte *buf)
{
  Pos = Get32(buf);
  PartitionRef = Get16(buf + 4);
}
Exemplo n.º 18
0
/*
 * Split a resource fork into its individual resources, and display them.
 */
int
ReformatResourceFork::Process(const ReformatHolder* pHolder,
    ReformatHolder::ReformatID id, ReformatHolder::ReformatPart part,
    ReformatOutput* pOutput)
{
    const uint8_t* srcBuf = pHolder->GetSourceBuf(part);
    long srcLen = pHolder->GetSourceLen(part);
    fUseRTF = false;

    long rFileVersion, rFileToMap, rFileMapSize;
    bool littleEndian;
    bool result;

    result = ReadHeader(srcBuf, srcLen, &rFileVersion, &rFileToMap,
                &rFileMapSize, &littleEndian);

    BufPrintf("Resource fork header (%s):\r\n",
        littleEndian ? "Apple IIgs little-endian" : "Macintosh big-endian");
    BufPrintf("  rFileVersion = %d\r\n", rFileVersion);
    BufPrintf("  rFileToMap   = 0x%08lx\r\n", rFileToMap);
    BufPrintf("  rFileMapSize = %ld\r\n", rFileMapSize);
    BufPrintf("  rFileMemo:\r\n");
    BufHexDump(srcBuf+12, 128);
    BufPrintf("\r\n");

    if (rFileVersion != 0) {
        BufPrintf("Not an Apple IIgs resource fork (probably Macintosh).\r\n");
        goto done;
    }
    if (!result) {
        BufPrintf("Does not appear to be a valid resource fork.\r\n");
        goto done;
    }

    /* move to start of resource map */
    const uint8_t* mapPtr;
    long mapToIndex, mapIndexSize, mapIndexUsed;

    mapPtr = srcBuf + rFileToMap;
    mapToIndex = Get16(mapPtr + 0x0e, littleEndian);
    mapIndexSize = Get32(mapPtr + 0x14, littleEndian);
    mapIndexUsed = Get32(mapPtr + 0x18, littleEndian);

    BufPrintf("Resource map:\r\n");
    BufPrintf("  mapToIndex      = 0x%04x (file offset=0x%08lx)\n",
        mapToIndex, mapToIndex + rFileToMap);
    BufPrintf("  mapIndexSize    = %ld\r\n", mapIndexSize);
    BufPrintf("  mapIndexUsed    = %ld\r\n", mapIndexUsed);
    BufPrintf("  mapFreeListSize = %ld\r\n", Get16(mapPtr + 0x1c, littleEndian));
    BufPrintf("  mapFreeListUsed = %ld\r\n", Get16(mapPtr + 0x1e, littleEndian));

    /* dump contents of resource reference records */
    const uint8_t* indexPtr;

    BufPrintf("\r\nResources:");
    indexPtr = mapPtr + mapToIndex;
    int i;

    for (i = 0; i < mapIndexSize; i++) {
        uint16_t resType = Get16(indexPtr + 0x00, littleEndian);
        if (resType == 0)
            break;      // should happen when i == mapIndexUsed

        const char* typeDescr;
        if (resType >= 0x8000 && resType < 0x8000 + NELEM(kRsrc8000))
            typeDescr = kRsrc8000[resType - 0x8000];
        else if (resType >= 0xc000 && resType < 0xc000 + NELEM(kRsrcC000))
            typeDescr = kRsrcC000[resType - 0xc000];
        else if (resType >= 0x0001 && resType <= 0x7fff)
            typeDescr = "(application-defined resource)";
        else
            typeDescr = kUnknownSysRsrc;

        BufPrintf("\r\n  Entry #%d:\r\n", i);
        BufPrintf("    resType   = 0x%04x - %s\r\n", resType, typeDescr);
        BufPrintf("    resID     = 0x%04x\r\n",
            Get32(indexPtr + 0x02, littleEndian));
        BufPrintf("    resOffset = 0x%04x\r\n",
            Get32(indexPtr + 0x06, littleEndian));
        BufPrintf("    resAttr   = 0x%04x\r\n",
            Get16(indexPtr + 0x0a, littleEndian));
        BufPrintf("    resSize   = 0x%04x\r\n",
            Get32(indexPtr + 0x0c, littleEndian));
        //BufPrintf("    resHandle = 0x%04x\r\n",
        //  Get32(indexPtr + 0x10, littleEndian));

        BufHexDump(srcBuf + Get32(indexPtr + 0x06, littleEndian),
            Get32(indexPtr + 0x0c, littleEndian));

        indexPtr += kRsrcMapEntryLen;
    }

done:
    SetResultBuffer(pOutput);
    return 0;
}
Exemplo n.º 19
0
UInt16 CInArchive::ReadUInt16() { Byte buf[2]; SafeReadBytes(buf, 2); return Get16(buf); }
Exemplo n.º 20
0
void CCdInfo::ParseEcd(const Byte *p)
{
  NumEntries = Get16(p + 10);
  Size = Get32(p + 12);
  Offset = Get32(p + 16);
}
Exemplo n.º 21
0
//--------------------------------------------------------------------------
// Process one of the nested EXIF directories.
//--------------------------------------------------------------------------
void CExifParse::ProcessDir(const unsigned char* const DirStart,
                            const unsigned char* const OffsetBase,
                            const unsigned ExifLength,
                            int NestingLevel)
{
  if (NestingLevel > 4)
  {
    ErrNonfatal("Maximum directory nesting exceeded (corrupt exif header)", 0,0);
    return;
  }

  char IndentString[25];
  memset(IndentString, ' ', 25);
  IndentString[NestingLevel * 4] = '\0';


  int NumDirEntries = Get16((const void*)DirStart, m_MotorolaOrder);

  const unsigned char* const DirEnd = DIR_ENTRY_ADDR(DirStart, NumDirEntries);
  if (DirEnd+4 > (OffsetBase+ExifLength))
  {
    if (DirEnd+2 == OffsetBase+ExifLength || DirEnd == OffsetBase+ExifLength)
    {
      // Version 1.3 of jhead would truncate a bit too much.
      // This also caught later on as well.
    }
    else
    {
      ErrNonfatal("Illegally sized directory", 0,0);
      return;
    }
  }

  for (int de=0;de<NumDirEntries;de++)
  {
    int Tag, Format, Components;
    unsigned char* ValuePtr;
    int ByteCount;
    const unsigned char* const DirEntry = DIR_ENTRY_ADDR(DirStart, de);

    Tag = Get16(DirEntry, m_MotorolaOrder);
    Format = Get16(DirEntry+2, m_MotorolaOrder);
    Components = Get32(DirEntry+4, m_MotorolaOrder);

    if (Format <= 0 || Format > NUM_FORMATS)
    {
      ErrNonfatal("Illegal number format %d for tag %04x", Format, Tag);
      continue;
    }

    if ((unsigned)Components > 0x10000)
    {
      ErrNonfatal("Illegal number of components %d for tag %04x", Components, Tag);
      continue;
    }

    ByteCount = Components * BytesPerFormat[Format - 1];

    if (ByteCount > 4)
    {
      unsigned OffsetVal;
      OffsetVal = (unsigned)Get32(DirEntry+8, m_MotorolaOrder);
      // If its bigger than 4 bytes, the dir entry contains an offset.
      if (OffsetVal+ByteCount > ExifLength)
      {
        // Bogus pointer offset and / or bytecount value
        ErrNonfatal("Illegal value pointer for tag %04x", Tag,0);
        continue;
      }
      ValuePtr = (unsigned char*)(const_cast<unsigned char*>(OffsetBase)+OffsetVal);

      if (OffsetVal > m_LargestExifOffset)
      {
        m_LargestExifOffset = OffsetVal;
      }

    }
    else {
      // 4 bytes or less and value is in the dir entry itself
      ValuePtr = (unsigned char*)(const_cast<unsigned char*>(DirEntry)+8);
    }


    // Extract useful components of tag
    switch(Tag)
    {
      case TAG_DESCRIPTION:
      {
        int length = max(ByteCount, 0);
        length = min(length, MAX_COMMENT);
        strncpy(m_ExifInfo->Description, (char *)ValuePtr, length);
        m_ExifInfo->Description[length] = '\0';
        break;
      }
      case TAG_MAKE:
      {
        int space = sizeof(m_ExifInfo->CameraMake);
        if (space > 0)
        {
          strncpy(m_ExifInfo->CameraMake, (char *)ValuePtr, space - 1);
          m_ExifInfo->CameraMake[space - 1] = '\0';
        }
        break;
      }
      case TAG_MODEL:
      {
        int space = sizeof(m_ExifInfo->CameraModel);
        if (space > 0)
        {
          strncpy(m_ExifInfo->CameraModel, (char *)ValuePtr, space - 1);
          m_ExifInfo->CameraModel[space - 1] = '\0';
        }
        break;
      }
//      case TAG_SOFTWARE:          strncpy(m_ExifInfo->Software, ValuePtr, 5);    break;
      case TAG_FOCALPLANEXRES:    m_FocalPlaneXRes  = ConvertAnyFormat(ValuePtr, Format);               break;
      case TAG_THUMBNAIL_OFFSET:  m_ExifInfo->ThumbnailOffset = (unsigned)ConvertAnyFormat(ValuePtr, Format);     break;
      case TAG_THUMBNAIL_LENGTH:  m_ExifInfo->ThumbnailSize   = (unsigned)ConvertAnyFormat(ValuePtr, Format);     break;

      case TAG_MAKER_NOTE:
        continue;
      break;

      case TAG_DATETIME_ORIGINAL:
      {

        int space = sizeof(m_ExifInfo->DateTime);
        if (space > 0)
        {
          strncpy(m_ExifInfo->DateTime, (char *)ValuePtr, space - 1);
          m_ExifInfo->DateTime[space - 1] = '\0';
          // If we get a DATETIME_ORIGINAL, we use that one.
          m_DateFound = true;
        }
        break;
      }
      case TAG_DATETIME_DIGITIZED:
      case TAG_DATETIME:
      {
        if (!m_DateFound)
        {
          // If we don't already have a DATETIME_ORIGINAL, use whatever
          // time fields we may have.
          int space = sizeof(m_ExifInfo->DateTime);
          if (space > 0)
          {
            strncpy(m_ExifInfo->DateTime, (char *)ValuePtr, space - 1);
            m_ExifInfo->DateTime[space - 1] = '\0';
          }
        }
        break;
      }
      case TAG_USERCOMMENT:
      {
        // The UserComment allows comments without the charset limitations of ImageDescription.
        // Therefore the UserComment field is prefixed by a CharacterCode field (8 Byte):
        //  - ASCII:         'ASCII\0\0\0'
        //  - Unicode:       'UNICODE\0'
        //  - JIS X208-1990: 'JIS\0\0\0\0\0'
        //  - Unknown:       '\0\0\0\0\0\0\0\0' (application specific)

        m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_UNKNOWN;

        const int EXIF_COMMENT_CHARSET_LENGTH = 8;
        if (ByteCount >= EXIF_COMMENT_CHARSET_LENGTH)
        {
          // As some implementations use spaces instead of \0 for the padding,
          // we're not so strict and check only the prefix.
          if (memcmp(ValuePtr, "ASCII", 5) == 0)
            m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_ASCII;
          else if (memcmp(ValuePtr, "UNICODE", 7) == 0)
            m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_UNICODE;
          else if (memcmp(ValuePtr, "JIS", 3) == 0)
            m_ExifInfo->CommentsCharset = EXIF_COMMENT_CHARSET_JIS;

          int length = ByteCount - EXIF_COMMENT_CHARSET_LENGTH;
          length = min(length, MAX_COMMENT);
          memcpy(m_ExifInfo->Comments, ValuePtr + EXIF_COMMENT_CHARSET_LENGTH, length);
          m_ExifInfo->Comments[length] = '\0';
//          FixComment(comment);                          // Ensure comment is printable
        }
      }
      break;

      case TAG_XP_COMMENT:
      {
        // The XP user comment field is always unicode (UCS-2) encoded
        m_ExifInfo->XPCommentsCharset = EXIF_COMMENT_CHARSET_UNICODE;
        size_t length = min(ByteCount, MAX_COMMENT);
        memcpy(m_ExifInfo->XPComment, ValuePtr, length);
        m_ExifInfo->XPComment[length] = '\0';
      }
      break;

      case TAG_FNUMBER:
        // Simplest way of expressing aperture, so I trust it the most.
        // (overwrite previously computd value if there is one)
        m_ExifInfo->ApertureFNumber = (float)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_APERTURE:
      case TAG_MAXAPERTURE:
        // More relevant info always comes earlier, so only use this field if we don't
        // have appropriate aperture information yet.
        if (m_ExifInfo->ApertureFNumber == 0)
        {
          m_ExifInfo->ApertureFNumber = (float)exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)*0.5);
        }
      break;

      case TAG_FOCALLENGTH:
        // Nice digital cameras actually save the focal length as a function
        // of how far they are zoomed in.
        m_ExifInfo->FocalLength = (float)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_SUBJECT_DISTANCE:
        // Inidcates the distacne the autofocus camera is focused to.
        // Tends to be less accurate as distance increases.
        {
          float distance = (float)ConvertAnyFormat(ValuePtr, Format);
          m_ExifInfo->Distance = distance;
        }
      break;

      case TAG_EXPOSURETIME:
        {
        // Simplest way of expressing exposure time, so I trust it most.
        // (overwrite previously computd value if there is one)
        float expTime = (float)ConvertAnyFormat(ValuePtr, Format);
        if (expTime)
          m_ExifInfo->ExposureTime = expTime;
        }
      break;

      case TAG_SHUTTERSPEED:
        // More complicated way of expressing exposure time, so only use
        // this value if we don't already have it from somewhere else.
        if (m_ExifInfo->ExposureTime == 0)
        {
          m_ExifInfo->ExposureTime = (float)(1/exp(ConvertAnyFormat(ValuePtr, Format)*log(2.0)));
        }
      break;

      case TAG_FLASH:
        m_ExifInfo->FlashUsed = (int)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_ORIENTATION:
        m_ExifInfo->Orientation = (int)ConvertAnyFormat(ValuePtr, Format);
        if (m_ExifInfo->Orientation < 0 || m_ExifInfo->Orientation > 8)
        {
          ErrNonfatal("Undefined rotation value %d", m_ExifInfo->Orientation, 0);
          m_ExifInfo->Orientation = 0;
        }
      break;

      case TAG_EXIF_IMAGELENGTH:
      case TAG_EXIF_IMAGEWIDTH:
        // Use largest of height and width to deal with images that have been
        // rotated to portrait format.
        {
          int a = (int)ConvertAnyFormat(ValuePtr, Format);
          if (m_ExifImageWidth < a) m_ExifImageWidth = a;
        }
      break;

      case TAG_FOCALPLANEUNITS:
        switch((int)ConvertAnyFormat(ValuePtr, Format))
        {
          // According to the information I was using, 2 means meters.
          // But looking at the Cannon powershot's files, inches is the only
          // sensible value.
          case 1: m_FocalPlaneUnits = 25.4; break;  // inch
          case 2: m_FocalPlaneUnits = 25.4; break;
          case 3: m_FocalPlaneUnits = 10;   break;  // centimeter
          case 4: m_FocalPlaneUnits = 1;    break;  // millimeter
          case 5: m_FocalPlaneUnits = .001; break;  // micrometer
        }
      break;

      case TAG_EXPOSURE_BIAS:
        m_ExifInfo->ExposureBias = (float)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_WHITEBALANCE:
        m_ExifInfo->Whitebalance = (int)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_LIGHT_SOURCE:
        //Quercus: 17-1-2004 Added LightSource, some cams return this, whitebalance or both
        m_ExifInfo->LightSource = (int)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_METERING_MODE:
        m_ExifInfo->MeteringMode = (int)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_EXPOSURE_PROGRAM:
        m_ExifInfo->ExposureProgram = (int)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_EXPOSURE_INDEX:
        if (m_ExifInfo->ISOequivalent == 0)
        {
          // Exposure index and ISO equivalent are often used interchangeably,
          // so we will do the same.
          // http://photography.about.com/library/glossary/bldef_ei.htm
          m_ExifInfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
        }
      break;

      case TAG_ISO_EQUIVALENT:
        m_ExifInfo->ISOequivalent = (int)ConvertAnyFormat(ValuePtr, Format);
        if (m_ExifInfo->ISOequivalent < 50)
          m_ExifInfo->ISOequivalent *= 200;          // Fixes strange encoding on some older digicams.
      break;

      case TAG_EXPOSURE_MODE:
        m_ExifInfo->ExposureMode = (int)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_DIGITALZOOMRATIO:
        m_ExifInfo->DigitalZoomRatio = (float)ConvertAnyFormat(ValuePtr, Format);
      break;

      case TAG_EXIF_OFFSET:
      case TAG_INTEROP_OFFSET:
      {
        const unsigned char* const SubdirStart = OffsetBase + (unsigned)Get32(ValuePtr, m_MotorolaOrder);
        if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength)
        {
          ErrNonfatal("Illegal exif or interop ofset directory link",0,0);
        }
        else
        {
          ProcessDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
        }
        continue;
      }
      break;

      case TAG_GPSINFO:
      {
        const unsigned char* const SubdirStart = OffsetBase + (unsigned)Get32(ValuePtr, m_MotorolaOrder);
        if (SubdirStart < OffsetBase || SubdirStart > OffsetBase+ExifLength)
        {
          ErrNonfatal("Illegal GPS directory link",0,0);
        }
        else
        {
          ProcessGpsInfo(SubdirStart, ByteCount, OffsetBase, ExifLength);
        }
        continue;
      }
      break;

      case TAG_FOCALLENGTH_35MM:
        // The focal length equivalent 35 mm is a 2.2 tag (defined as of April 2002)
        // if its present, use it to compute equivalent focal length instead of
        // computing it from sensor geometry and actual focal length.
        m_ExifInfo->FocalLength35mmEquiv = (unsigned)ConvertAnyFormat(ValuePtr, Format);
      break;
    }
  }


  // In addition to linking to subdirectories via exif tags,
  // there's also a potential link to another directory at the end of each
  // directory.  this has got to be the result of a committee!
  unsigned Offset;

  if (DIR_ENTRY_ADDR(DirStart, NumDirEntries) + 4 <= OffsetBase+ExifLength)
  {
    Offset = (unsigned)Get32(DirStart+2+12*NumDirEntries, m_MotorolaOrder);
    if (Offset)
    {
      const unsigned char* const SubdirStart = OffsetBase + Offset;
      if (SubdirStart > OffsetBase+ExifLength || SubdirStart < OffsetBase)
      {
        if (SubdirStart > OffsetBase && SubdirStart < OffsetBase+ExifLength+20)
        {
          // Jhead 1.3 or earlier would crop the whole directory!
          // As Jhead produces this form of format incorrectness,
          // I'll just let it pass silently
        }
        else
        {
          ErrNonfatal("Illegal subdirectory link",0,0);
        }
      }
      else
      {
        if (SubdirStart <= OffsetBase+ExifLength)
        {
          ProcessDir(SubdirStart, OffsetBase, ExifLength, NestingLevel+1);
        }
      }
      if (Offset > m_LargestExifOffset)
      {
        m_LargestExifOffset = Offset;
      }
    }
  }
  else
  {
    // The exif header ends before the last next directory pointer.
  }

  if (m_ExifInfo->ThumbnailOffset)
  {
    m_ExifInfo->ThumbnailAtEnd = false;

    if (m_ExifInfo->ThumbnailOffset <= ExifLength)
    {
      if (m_ExifInfo->ThumbnailSize > ExifLength - m_ExifInfo->ThumbnailOffset)
      {
        // If thumbnail extends past exif header, only save the part that
        // actually exists.  Canon's EOS viewer utility will do this - the
        // thumbnail extracts ok with this hack.
        m_ExifInfo->ThumbnailSize = ExifLength - m_ExifInfo->ThumbnailOffset;
      }
    }
  }
}
Exemplo n.º 22
0
API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
{
  if (size < 8)
    return k_IsArc_Res_NEED_MORE;
  if (p[0] != 'P')
    return k_IsArc_Res_NO;

  UInt32 value = Get32(p);

  if (value == NSignature::kNoSpan)
  {
    p += 4;
    size -= 4;
  }

  value = Get32(p);

  if (value == NSignature::kEcd)
  {
    if (size < kEcdSize)
      return k_IsArc_Res_NEED_MORE;
    CEcd ecd;
    ecd.Parse(p + 4);
    // if (ecd.cdSize != 0)
    if (!ecd.IsEmptyArc())
      return k_IsArc_Res_NO;
    return k_IsArc_Res_YES; // k_IsArc_Res_YES_2;
  }

  if (value != NSignature::kLocalFileHeader)
    return k_IsArc_Res_NO;

  if (size < kLocalHeaderSize)
    return k_IsArc_Res_NEED_MORE;

  p += 4;

  {
    const unsigned kPureHeaderSize = kLocalHeaderSize - 4;
    unsigned i;
    for (i = 0; i < kPureHeaderSize && p[i] == 0; i++);
    if (i == kPureHeaderSize)
      return k_IsArc_Res_NEED_MORE;
  }

  /*
  if (p[0] >= 128) // ExtractVersion.Version;
    return k_IsArc_Res_NO;
  */

  // ExtractVersion.Version = p[0];
  // ExtractVersion.HostOS = p[1];
  // Flags = Get16(p + 2);
  // Method = Get16(p + 4);
  /*
  // 9.33: some zip archives contain incorrect value in timestamp. So we don't check it now
  UInt32 dosTime = Get32(p + 6);
  if (!CheckDosTime(dosTime))
    return k_IsArc_Res_NO;
  */
  // Crc = Get32(p + 10);
  // PackSize = Get32(p + 14);
  // Size = Get32(p + 18);
  unsigned nameSize = Get16(p + 22);
  unsigned extraSize = Get16(p + 24);
  UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize;
  if (extraOffset + extraSize > (1 << 16))
    return k_IsArc_Res_NO;

  p -= 4;

  {
    size_t rem = size - kLocalHeaderSize;
    if (rem > nameSize)
      rem = nameSize;
    const Byte *p2 = p + kLocalHeaderSize;
    for (size_t i = 0; i < rem; i++)
      if (p2[i] == 0)
        return k_IsArc_Res_NO;
  }

  if (size < extraOffset)
    return k_IsArc_Res_NEED_MORE;

  if (extraSize > 0)
  {
    p += extraOffset;
    size -= extraOffset;
    while (extraSize != 0)
    {
      if (extraSize < 4)
      {
        // 7-Zip before 9.31 created incorrect WsAES Extra in folder's local headers.
        // so we return k_IsArc_Res_YES to support such archives.
        // return k_IsArc_Res_NO; // do we need to support such extra ?
        return k_IsArc_Res_YES;
      }
      if (size < 4)
        return k_IsArc_Res_NEED_MORE;
      unsigned dataSize = Get16(p + 2);
      size -= 4;
      extraSize -= 4;
      p += 4;
      if (dataSize > extraSize)
        return k_IsArc_Res_NO;
      if (dataSize > size)
        return k_IsArc_Res_NEED_MORE;
      size -= dataSize;
      extraSize -= dataSize;
      p += dataSize;
    }
  }

  return k_IsArc_Res_YES;
}
Exemplo n.º 23
0
//--------------------------------------------------------------------------
// Process GPS info directory
//--------------------------------------------------------------------------
void CExifParse::ProcessGpsInfo(
                    const unsigned char* const DirStart,
                    int ByteCountUnused,
                    const unsigned char* const OffsetBase,
                    unsigned ExifLength)
{
  int NumDirEntries = Get16(DirStart, m_MotorolaOrder);

  for (int de=0;de<NumDirEntries;de++)
  {
    const unsigned char* DirEntry = DIR_ENTRY_ADDR(DirStart, de);

    unsigned Tag        = Get16(DirEntry, m_MotorolaOrder);
    unsigned Format     = Get16(DirEntry+2, m_MotorolaOrder);
    unsigned Components = (unsigned)Get32(DirEntry+4, m_MotorolaOrder);
    if (Format == 0 || Format > NUM_FORMATS)
    {
      ErrNonfatal("Illegal number format %d for tag %04x", Format, Tag);
      continue;
    }

    unsigned ComponentSize = BytesPerFormat[Format - 1];
    unsigned ByteCount = Components * ComponentSize;

    const unsigned char* ValuePtr;

    if (ByteCount > 4)
    {
      unsigned OffsetVal = (unsigned)Get32(DirEntry+8, m_MotorolaOrder);
      // If its bigger than 4 bytes, the dir entry contains an offset.
      if (OffsetVal+ByteCount > ExifLength)
      {
        // Bogus pointer offset and / or bytecount value
        ErrNonfatal("Illegal value pointer for tag %04x", Tag,0);
        continue;
      }
      ValuePtr = OffsetBase+OffsetVal;
    }
    else
    {
      // 4 bytes or less and value is in the dir entry itself
      ValuePtr = DirEntry+8;
    }

    switch(Tag)
    {
      case TAG_GPS_LAT_REF:
        m_ExifInfo->GpsLat[0] = ValuePtr[0];
        m_ExifInfo->GpsLat[1] = 0;
      break;

      case TAG_GPS_LONG_REF:
        m_ExifInfo->GpsLong[0] = ValuePtr[0];
        m_ExifInfo->GpsLong[1] = 0;
      break;

      case TAG_GPS_LAT:
        GetLatLong(Format, ValuePtr, ComponentSize, m_ExifInfo->GpsLat);
      break;
      case TAG_GPS_LONG:
        GetLatLong(Format, ValuePtr, ComponentSize, m_ExifInfo->GpsLong);
      break;

      case TAG_GPS_ALT_REF:
        if (ValuePtr[0] != 0)
          m_ExifInfo->GpsAlt[0] = '-';
        m_ExifInfo->GpsAlt[1] = 0;
      break;

      case TAG_GPS_ALT:
        {
          char temp[18];
          sprintf(temp,"%dm", Get32(ValuePtr, m_MotorolaOrder));
          strcat(m_ExifInfo->GpsAlt, temp);
        }
      break;
    }
  }
}
Exemplo n.º 24
0
int8 KismetExecuteEvent(int16 _DeviceID,int8 _EventID)
{
	int8  a;//variable for the kismet blocks to use
	int8  read8;
	int16 read16;
	int16 eventaddr;
	int16 methodaddr;
	int16 BlockAddr;
	int16 timeout;

	if(!OperationEnabled)return 1;//return if no operating is allowed

	//ToSendDataBuffer[2]=((int8*)&_DeviceID)[0];
	//ToSendDataBuffer[3]=((int8*)&_DeviceID)[1];
	//ToSendDataBuffer[4]=_EventID;

	MemoryBeginRead(EEPROMHEADERSIZE);

	for(timeout=0;timeout<1024;timeout++)
	{
		read16=MemoryReadInt16();
		eventaddr =MemoryReadInt16();
		if(read16==_DeviceID)break;
		if(read16==0xffff) { MemoryEndRead(); return 2; }
	}
	MemoryEndRead(); 
	MemoryBeginRead(eventaddr);
	for(timeout=0;timeout<1024;timeout++)
	{
		read8=MemoryReadInt8();
		methodaddr=MemoryReadInt16();
		
		if(read8==_EventID)break;
		if(read8==0xff) { MemoryEndRead(); return 3; }
	}
	MemoryEndRead();
	//ToSendDataBuffer[12]=((int8*)&eventaddr)[0];
	//ToSendDataBuffer[13]=((int8*)&eventaddr)[1];
	//ToSendDataBuffer[14]=((int8*)&methodaddr)[0];
	//ToSendDataBuffer[15]=((int8*)&methodaddr)[1];
	
	BlockAddr=methodaddr;
	MemoryBeginRead(BlockAddr);
	while(1)
	{
		int8 blocktype=MemoryReadInt8();
		//#=EEPROM DATA $=REGISTER DATA
		switch(blocktype)
		{
			case 0x00://end of code
			default://or we dont understand it
			{
				MemoryEndRead();
				return 0;
			}
			case 0x01://load literal int16
			{
				int8 reg	=MemoryReadInt8();
				int16 value	=MemoryReadInt16();
				Set16(reg,value);
			}break;
			case 0x02://load literal int8
			{
				int8 reg	=MemoryReadInt8();
				int8 value	=MemoryReadInt8();
				Set8(reg,value);
			}break;
			case 0x0B://equal
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,(Get16(reg1)==Get16(reg2))?0xffff:0);
			}break;
			case 0x0C://differ
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,(Get16(reg1)!=Get16(reg2))?0xffff:0);
			}break;
			case 0x0D://and
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)&Get16(reg2));
			}break;
			case 0x0E://or
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)|Get16(reg2));
			}break;
			case 0x0F://xor
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)^Get16(reg2));
			}break;
			case 0x20://add
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)+Get16(reg2));
			}break;
			case 0x21://sub
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)-Get16(reg2));
			}break;
			case 0x22://mul
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)*Get16(reg2));
			}break;
			case 0x23://div
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 reg3	=MemoryReadInt8();
				Set16(reg3,Get16(reg1)/Get16(reg2));
			}break;
			case 0x30://hours
			{
				int8 reg1	=MemoryReadInt8();
				Set16(reg1,(int16)RTCHour);
			}break;
			case 0x31://minutes
			{
				int8 reg1	=MemoryReadInt8();
				Set16(reg1,(int16)RTCMinute);
			}break;
			case 0x32://seconds
			{
				int8 reg1	=MemoryReadInt8();
				Set16(reg1,(int16)RTCSecond);
			}break;
			case 0x33://days
			{
				int8 reg1	=MemoryReadInt8();
				Set16(reg1,(int16)RTCDay);
			}break;
			case 0x0A://Set LED
			{
				int8 reg	=MemoryReadInt8();
				//Set16(reg,1);
				SetLED(Get16(reg));
			}break;
			case 0x80:// $if goto $here?
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				if(Get16(reg1)==0)
				{
					BlockAddr=methodaddr+(int16)reg2;
					MemoryEndRead();MemoryBeginRead(BlockAddr);
				}
			}break;
			case 0x70://mov
			{
				int8 reg1	=MemoryReadInt8();
				int8 reg2	=MemoryReadInt8();
				int8 amnt	=MemoryReadInt8();
				for(a=0;a<amnt;a++)
					Set8(reg2+a,Get8(reg1+a));
			}break;
			case 0x71://EPSend
			{
				int16 dev	=MemoryReadInt16();
				EPBufferSize=MemoryReadInt8();
				//try three times
				if(EPSend(dev))break;
				if(EPSend(dev))break;
				if(EPSend(dev))break;
			}break;
			case 0x90://Set Delay
			{
				int8 timer	=MemoryReadInt8();
				int8 event	=MemoryReadInt8();
				int8 reg	=MemoryReadInt8();
				int16 time=Get16(reg);
				SetTimer(timer,event,time);
			}break;
		}
	}
	return 4;
}