Beispiel #1
0
bool FScanner::CheckValue(bool allowfloat) 
{ 
	auto savedstate = SavePos();
	bool res = ScanValue(allowfloat);
	if (!res) RestorePos(savedstate);
	return res;
}
Beispiel #2
0
int64 File::FileLength()
{
  
  SaveFilePos SavePos(*this);
  Seek(0,SEEK_END);
  return Tell();
}
Beispiel #3
0
double qPBReaderEpub::GetPos()
{
   double pos = _pSettings->GetPagePos();

   if (pos < 0.)
   {
      pos = 0.;
      SavePos(pos);
   }

   else if (pos > 1.0)
   {
      pos = 1.;
      SavePos(pos);
   }

   return pos;
}
Beispiel #4
0
int Archive::GetRecoverySize(bool Required)
{
  if (!Protected)
    return(0);
  if (RecoverySectors!=-1 || !Required)
    return(RecoverySectors);
  SaveFilePos SavePos(*this);
  Seek(SFXSize,SEEK_SET);
  SearchSubBlock(SUBHEAD_TYPE_RR);
  return(RecoverySectors);
}
Beispiel #5
0
uint CalcFileCRC(File *SrcFile,int64 Size,CALCCRC_SHOWMODE ShowMode)
{
  SaveFilePos SavePos(*SrcFile);
  const size_t BufSize=0x10000;
  Array<byte> Data(BufSize);
  int64 BlockCount=0;
  uint DataCRC=0xffffffff;

#if !defined(SILENT) && !defined(_WIN_CE)
  int64 FileLength=SrcFile->FileLength();
  if (ShowMode!=CALCCRC_SHOWNONE)
  {
    mprintf(St(MCalcCRC));
    mprintf("     ");
  }

#endif

  SrcFile->Seek(0,SEEK_SET);
  while (true)
  {
    size_t SizeToRead;
    if (Size==INT64NDF)   // If we process the entire file.
      SizeToRead=BufSize; // Then always attempt to read the entire buffer.
    else
      SizeToRead=(size_t)Min((int64)BufSize,Size);
    int ReadSize=SrcFile->Read(&Data[0],SizeToRead);
    if (ReadSize==0)
      break;

    ++BlockCount;
    if ((BlockCount & 15)==0)
    {
#if !defined(SILENT) && !defined(_WIN_CE)
      if (ShowMode==CALCCRC_SHOWALL)
        mprintf("\b\b\b\b%3d%%",ToPercent(BlockCount*int64(BufSize),FileLength));
#endif
      Wait();
    }
    DataCRC=CRC(DataCRC,&Data[0],ReadSize);
    if (Size!=INT64NDF)
      Size-=ReadSize;
  }
#if !defined(SILENT) && !defined(_WIN_CE)
  if (ShowMode==CALCCRC_SHOWALL)
    mprintf("\b\b\b\b    ");
#endif
  return(DataCRC^0xffffffff);
}
Beispiel #6
0
// Used for archives created by old RAR versions up to and including RAR 2.9.
// New RAR versions store file comments in separate headers and such comments
// are displayed in ListNewSubHeader function.
void Archive::ViewFileComment()
{
    if (!(NewLhd.Flags & LHD_COMMENT) || Cmd->DisableComment || OldFormat)
        return;

#ifndef GUI
    mprintf(St(MFileComment));
#endif
    const int MaxSize = 0x8000;
    Array<char> CmtBuf(MaxSize);
    SaveFilePos SavePos(*this);
    Seek(CurBlockPos + SIZEOF_NEWLHD + NewLhd.NameSize, SEEK_SET);
    int64 SaveCurBlockPos = CurBlockPos;
    int64 SaveNextBlockPos = NextBlockPos;
    size_t Size = ReadHeader();
    CurBlockPos = SaveCurBlockPos;
    NextBlockPos = SaveNextBlockPos;

    if (Size < 7 || CommHead.HeadType != COMM_HEAD)
        return;

    if (CommHead.HeadCRC != HeaderCRC)
    {
#ifndef GUI
        Log(FileName, St(MLogCommHead));
#endif
        return;
    }

    if (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER ||
            CommHead.Method > 0x30 || CommHead.UnpSize > MaxSize)
        return;

    Read(&CmtBuf[0], CommHead.UnpSize);

    if (CommHead.CommCRC != ((~CRC(0xffffffff, &CmtBuf[0], CommHead.UnpSize) & 0xffff)))
    {
        Log(FileName, St(MLogBrokFCmt));
    }

    else
    {
        OutComment(&CmtBuf[0], CommHead.UnpSize);
#ifndef GUI
        mprintf("\n");
#endif
    }
}
Beispiel #7
0
orthoMap::orthoMap(Vect &_pos,Vect &rot)
{
	pos=_pos;
	look=Vect(0,0,1);
	up=Vect(0,1,0);
	right=Vect(1,0,0);
	oldpos=oldlook=oldup=oldright=NULL;
	LRot(rot);
	resettracebacks();
	oldpos=new Vect[VIEW_TRACEBACKS];
	oldlook=new Vect[VIEW_TRACEBACKS];
	oldup=new Vect[VIEW_TRACEBACKS];
	oldright=new Vect[VIEW_TRACEBACKS];
	oldscale=new fptype[VIEW_TRACEBACKS];
	SavePos();
}
Beispiel #8
0
void orthoMap::LRot(Vect &rot)
{
	//x-as
	look=up*(-sin(rot.x))+look*cos(rot.x);
	up=up*cos(rot.x)+look*sin(rot.x);

	//y-as
	//right=look*sin(rot.y)+right*cos(rot.y);
	look=look*cos(rot.y)+right*-(sin(rot.y));

	//z-as
	up=right*(-sin(rot.z))+up*cos(rot.z);
	//right=right*cos(rot.z)+up*sin(rot.z);

	look.setLength(FL1);
	up.setLength(FL1);
	right=up^look;
	up=look^right;
	SavePos();
}
Beispiel #9
0
uint CalcFileCRC(File *SrcFile,Int64 Size)
{
  SaveFilePos SavePos(*SrcFile);
  const int BufSize=0x10000;
  Array<byte> Data(BufSize);
  int ReadSize,BlockCount=0;
  uint DataCRC=0xffffffff;


  SrcFile->Seek(0,SEEK_SET);
  while ((ReadSize=SrcFile->Read(&Data[0],int64to32(Size==INT64ERR ? Int64(BufSize):Min(Int64(BufSize),Size))))!=0)
  {
    if ((++BlockCount & 15)==0)
    {
      Wait();
    }
    DataCRC=CRC(DataCRC,&Data[0],ReadSize);
    if (Size!=INT64ERR)
      Size-=ReadSize;
  }
  return(DataCRC^0xffffffff);
}
Beispiel #10
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
#ifndef SFX_MODULE
  if (IsDevice())
  {
#ifndef SHELL_EXT
    Log(FileName,St(MInvalidName),FileName);
#endif
    return(false);
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
    return(false);
  SFXSize=0;
  if (IsSignature(MarkHead.Mark))
  {
    if (OldFormat)
      Seek(0,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(MAXSFXSIZE);
    long CurPos=(long)Tell();
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
      {
        if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
        {
          char *D=&Buffer[28-CurPos];
          if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
            continue;
        }
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (!OldFormat)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD);
        break;
      }
    if (SFXSize==0)
      return(false);
  }
  ReadHeader();
  SeekToNext();
#ifndef SFX_MODULE
  if (OldFormat)
  {
    NewMhd.Flags=OldMhd.Flags & 0x3f;
    NewMhd.HeadSize=OldMhd.HeadSize;
  }
  else
#endif
  {
    if (HeaderCRC!=NewMhd.HeadCRC)
    {
#ifndef SHELL_EXT
      Log(FileName,St(MLogMainHead));
#endif
      Alarm();
      if (!EnableBroken)
        return(false);
    }
  }
  Volume=(NewMhd.Flags & MHD_VOLUME);
  Solid=(NewMhd.Flags & MHD_SOLID)!=0;
  MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
  Locked=(NewMhd.Flags & MHD_LOCK)!=0;
  Signed=(NewMhd.PosAV!=0);
  Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
  Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;

  if (NewMhd.EncryptVer>UNP_VER)
  {
#ifdef RARDLL
    Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#else
    ErrHandler.SetErrorCode(RARX_WARNING);
  #if !defined(SILENT) && !defined(SFX_MODULE)
      Log(FileName,St(MUnknownMeth),FileName);
      Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
  #endif
#endif
    return(false);
  }
#ifdef RARDLL
  // If callback function is not set, we cannot get the password,
  // so we skip the initial header processing for encrypted header archive.
  // It leads to skipped archive comment, but the rest of archive data
  // is processed correctly.
  if (Cmd->Callback==NULL)
    SilentOpen=true;
#endif

  // If not encrypted, we'll check it below.
  NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;

  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;

    NotFirstVolume=false;
    while (ReadHeader()!=0)
    {
      int HeaderType=GetHeaderType();
      if (HeaderType==NEWSUB_HEAD)
      {
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
          MainComment=true;
        if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
            Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
          NotFirstVolume=true;
      }
      else
      {
        if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
            Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
          NotFirstVolume=true;
        break;
      }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
  }
  if (!Volume || !NotFirstVolume)
  {
    strcpy(FirstVolumeName,FileName);
    wcscpy(FirstVolumeNameW,FileNameW);
  }

  return(true);
}
Beispiel #11
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
#ifndef SFX_MODULE
  if (IsDevice())
  {
#ifndef SHELL_EXT
    Log(FileName,St(MInvalidName),FileName);
#endif
    return(false);
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
    return(false);
  SFXSize=0;
  if (IsSignature(MarkHead.Mark))
  {
    if (OldFormat)
      Seek(0,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(0x40000);
    long CurPos=int64to32(Tell());
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
      {
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (!OldFormat)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD);
        break;
      }
    if (SFXSize==0)
      return(false);
  }
  ReadHeader();
  SeekToNext();
#ifndef SFX_MODULE
  if (OldFormat)
  {
    NewMhd.Flags=OldMhd.Flags & 0x3f;
    NewMhd.HeadSize=OldMhd.HeadSize;
  }
  else
#endif
  {
    if (HeaderCRC!=NewMhd.HeadCRC)
    {
#ifndef SHELL_EXT
      Log(FileName,St(MLogMainHead));
#endif
      Alarm();
      if (!EnableBroken)
        return(false);
    }
  }
  Volume=(NewMhd.Flags & MHD_VOLUME);
  Solid=(NewMhd.Flags & MHD_SOLID)!=0;
  MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
  Locked=(NewMhd.Flags & MHD_LOCK)!=0;
  Signed=(NewMhd.PosAV!=0);
  Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
  Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;

#ifdef RARDLL
  SilentOpen=true;
#endif
  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    Int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;

    NotFirstVolume=false;
    while (ReadHeader())
    {
      int HeaderType=GetHeaderType();
      if (HeaderType==NEWSUB_HEAD)
      {
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
          MainComment=true;
        if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
            Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
          NotFirstVolume=true;
      }
      else
      {
        if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
            Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
          NotFirstVolume=true;
        break;
      }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
  }
  return(true);
}
Beispiel #12
0
void orthoMap::SetPos(Vect &WCor)
{
	pos=WCor;
	SavePos();
}
Beispiel #13
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
  BrokenHeader=false; // Might be left from previous volume.
  
#ifndef SFX_MODULE
  if (IsDevice())
  {
    uiMsg(UIERROR_INVALIDNAME,FileName,FileName);
    return false;
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3)
    return false;
  SFXSize=0;
  
  RARFORMAT Type;
  if ((Type=IsSignature(MarkHead.Mark,SIZEOF_MARKHEAD3))!=RARFMT_NONE)
  {
    Format=Type;
    if (Format==RARFMT14)
      Seek(Tell()-SIZEOF_MARKHEAD3,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(MAXSFXSIZE);
    long CurPos=(long)Tell();
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
      {
        Format=Type;
        if (Format==RARFMT14 && I>0 && CurPos<28 && ReadSize>31)
        {
          char *D=&Buffer[28-CurPos];
          if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
            continue;
        }
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (Format==RARFMT15 || Format==RARFMT50)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD3);
        break;
      }
    if (SFXSize==0)
      return false;
  }
  if (Format==RARFMT_FUTURE)
  {
    uiMsg(UIERROR_NEWRARFORMAT,FileName);
    return false;
  }
  if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
  {
    Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1);
    if (MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
      return false;
    MarkHead.HeadSize=SIZEOF_MARKHEAD5;
  }
  else
    MarkHead.HeadSize=SIZEOF_MARKHEAD3;

#ifdef RARDLL
  // If callback function is not set, we cannot get the password,
  // so we skip the initial header processing for encrypted header archive.
  // It leads to skipped archive comment, but the rest of archive data
  // is processed correctly.
  if (Cmd->Callback==NULL)
    SilentOpen=true;
#endif

  // Skip the archive encryption header if any and read the main header.
  while (ReadHeader()!=0)
  {
    HEADER_TYPE Type=GetHeaderType();
    // In RAR 5.0 we need to quit after reading HEAD_CRYPT if we wish to
    // avoid the password prompt.
    if (Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT)
      break;
    SeekToNext();
  }

  // This check allows to make RS based recovery even if password is incorrect.
  // But we should not do it for EnableBroken or we'll get 'not RAR archive'
  // messages when extracting encrypted archives with wrong password.
  if (FailedHeaderDecryption && !EnableBroken)
    return false;

  SeekToNext();
  if (BrokenHeader) // Main archive header is corrupt.
  {
    uiMsg(UIERROR_MHEADERBROKEN,FileName);
    if (!EnableBroken)
      return false;
  }

  MainComment=MainHead.CommentInHeader;

  // If we process non-encrypted archive or can request a password,
  // we set 'first volume' flag based on file attributes below.
  // It is necessary for RAR 2.x archives, which did not have 'first volume'
  // flag in main header. Also for all RAR formats we need to scan until
  // first file header to set "comment" flag when reading service header.
  // Unless we are in silent mode, we need to know about presence of comment
  // immediately after IsArchive call.
  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
    HEADER_TYPE SaveCurHeaderType=CurHeaderType;

    while (ReadHeader()!=0)
    {
      HEADER_TYPE HeaderType=GetHeaderType();
      if (HeaderType==HEAD_SERVICE)
        FirstVolume=Volume && !SubHead.SplitBefore;
      else
        if (HeaderType==HEAD_FILE)
        {
          FirstVolume=Volume && !FileHead.SplitBefore;
          break;
        }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
    CurHeaderType=SaveCurHeaderType;
  }
  if (!Volume || FirstVolume)
    wcscpy(FirstVolumeName,FileName);

  return true;
}
short LIBFUNC L_Config_Filetypes(
	REG(a0, struct Screen *screen),
	REG(a1, IPCData *ipc),
	REG(a2, IPCData *owner_ipc),
	REG(d0, ULONG command_list),
	REG(a3, char *name))
{
	config_filetypes_data *data;
	IPCMessage *quit_msg=0;
	short undo_flag=0,pending_quit=0;
	short ret=0,fontsize;
	struct IBox pos;
	ConfigWindow dims;

	// Allocate data and memory handle
	if (!(data=AllocVec(sizeof(config_filetypes_data),MEMF_CLEAR)) ||
		!(data->memory=NewMemHandle(4096,256,MEMF_CLEAR)))
		return 0;

	// Save pointers
	data->ipc=ipc;
	data->owner_ipc=owner_ipc;
	data->command_list=command_list;

	// Initialise data
	NewList(&data->list_list);
	InitListLock(&data->proc_list,0);

	// Fill in new window
	data->newwin.parent=screen;
	data->newwin.dims=&dims;
	data->newwin.title=GetString(locale,MSG_FILETYPES_TITLE);
	data->newwin.locale=locale;
	data->newwin.flags=WINDOW_SCREEN_PARENT|WINDOW_VISITOR|WINDOW_REQ_FILL|WINDOW_AUTO_KEYS|WINDOW_SIZE_BOTTOM;

	// Get default size
	dims=_config_filetypes_window;

	// Get saved position
	if (LoadPos("dopus/windows/filetypes",&pos,&fontsize))
	{
		dims.char_dim.Width=0;
		dims.char_dim.Height=0;
		dims.fine_dim.Width=pos.Width;
		dims.fine_dim.Height=pos.Height;
	}
		
	// Open window and add objects
	if (!(data->window=OpenConfigWindow(&data->newwin)) ||
		!(data->objlist=AddObjectList(data->window,_config_filetypes_objects)))
	{
		CloseConfigWindow(data->window);
		FreeMemHandle(data->memory);
		FreeVec(data);
		return 0;
	}

	// Set minimum size
	SetConfigWindowLimits(data->window,&_config_filetypes_window,0);

	// Read filetype list
	SetWindowBusy(data->window);
	filetype_read_list(data->memory,&data->list_list);

	// Build display list
	filetype_build_list(data);
	ClearWindowBusy(data->window);

	// Name to edit?
	if (name) filetype_edit_name(data,name);

	// Event loop
	FOREVER
	{
		struct IntuiMessage *msg;
		IPCMessage *imsg;
		int quit_flag=0;

		// Any IPC messages?
		while ((imsg=(IPCMessage *)GetMsg(ipc->command_port)))
		{
			// Look at command
			switch (imsg->command)
			{
				// Quit
				case IPC_QUIT:
					quit_flag=1;
					quit_msg=imsg;
					imsg=0;
					data->change=0;
					break;


				// Activate
				case IPC_ACTIVATE:
					if (data->window)
					{
						// Bring window to front
						WindowToFront(data->window);
						ActivateWindow(data->window);

						// Edit name supplied?
						if (imsg->data) filetype_edit_name(data,(char *)imsg->data);
					}
					break;


				// Process saying goodbye
				case IPC_GOODBYE:
					{
						FiletypeNode *node;

						// Handle goodbye
						if ((node=(FiletypeNode *)IPC_GetGoodbye(imsg)))
						{
							// Node no longer has an editor
							node->editor=0;
						}

						// All process gone and pending quit?
						if (pending_quit && (IsListEmpty(&data->proc_list.list)))
						{
							quit_flag=1;
							pending_quit=2;
						}
					}
					break;


				// Got a filetype back from the editor
				case FILETYPEEDIT_RETURN:
					if (filetype_receive_edit(
						data,
						(Cfg_Filetype *)imsg->flags,
						(FiletypeNode *)imsg->data))
					{
						data->change=1;
						imsg->command=1;
					}
					else imsg->command=0;
					break;
			}

			// Reply message
			IPC_Reply(imsg);

			// Check quit flag
			if (quit_flag) break;
		}

		// Intuimessages
		if (data->window)
		{
			while ((msg=GetWindowMsg(data->window->UserPort)))
			{
				struct IntuiMessage msg_copy;
				UWORD id;

				// Copy message and reply
				msg_copy=*msg;
				ReplyWindowMsg(msg);

				if (pending_quit) continue;

				// Look at message
				switch (msg_copy.Class)
				{
					// Close window
					case IDCMP_CLOSEWINDOW:
						quit_flag=1;
						undo_flag=1;
						break;


					// Gadget
					case IDCMP_GADGETUP:

						id=((struct Gadget *)msg_copy.IAddress)->GadgetID;
						switch (id)
						{
							// Cancel
							case GAD_FILETYPES_CANCEL:
								undo_flag=1;

							// Use
							case GAD_FILETYPES_USE:
								quit_flag=1;
								break;


							// Filetype selected
							case GAD_FILETYPES_LIST:
								{
									Att_Node *node;

									// Enable buttons
									filetype_able_buttons(data,FALSE);

									// Get selection
									if (!(node=Att_FindNode(data->filetype_list,msg_copy.Code)))
										break;

									// Double-click?
									if (node==data->sel_filetype &&
										DoubleClick(
											data->seconds,data->micros,
											msg_copy.Seconds,msg_copy.Micros))
									{
										// Launch editor for this filetype
										filetype_edit(data,(FiletypeNode *)data->sel_filetype->data,0);
									}

									// New selection
									else
									{
										data->sel_filetype=node;
										data->seconds=msg_copy.Seconds;
										data->micros=msg_copy.Micros;
									}
								}
								break;


							// Add a new filetype
							case GAD_FILETYPES_DUPLICATE:
								if (!data->sel_filetype) break;
							case GAD_FILETYPES_ADD:
								{
									Cfg_FiletypeList *list;
									Cfg_Filetype *type=0;

									// Allocate a new filetype list
									if ((list=AllocMemH(data->memory,sizeof(Cfg_FiletypeList))))
									{
										// Initialise list
										NewList(&list->filetype_list);

										// Copy existing filetype?
										if ((((struct Gadget *)msg_copy.IAddress)->GadgetID==
											GAD_FILETYPES_DUPLICATE))
										{
											// Copy filetype
											type=CopyFiletype(
												((FiletypeNode *)data->sel_filetype->data)->type,
												data->memory);
										}

										// Allocate a new filetype
										else if ((type=NewFiletype(data->memory)))
										{
											// Initialise name
											strcpy(type->type.name,GetString(locale,MSG_UNTITLED));
										}

										// Get a filetype?
										if (type)
										{
											// Add filetype list to main list
											AddTail(&data->list_list,&list->node);

											// Add filetype to list
											AddTail(&list->filetype_list,&type->node);

											// Set list pointer
											type->list=list;
											list->flags=FTLISTF_CHANGED;
										}

										// Failed
										else FreeMemH(list);
									}

									// Got new filetype?
									if (type)
									{
										Att_Node *node;

										// Remove existing list
										SetGadgetChoices(
											data->objlist,
											GAD_FILETYPES_LIST,
											(APTR)~0);

										// Add entry for this filetype
										node=filetype_add_entry(data,type);

										// Handle new nodes
										filetype_new_node(data,node);
									}
								}
								break;


							// Edit filetype
							case GAD_FILETYPES_EDIT:

								// Valid selection?
								if (data->sel_filetype)
								{
									// Launch editor for this filetype
									filetype_edit(data,(FiletypeNode *)data->sel_filetype->data,0);
								}
								break;


							// Remove/Store
							case GAD_FILETYPES_REMOVE:
							case GAD_FILETYPES_STORE:

								// Valid selection?
								if (data->sel_filetype)
								{
									short ret;

									// Remove filetype
									if ((ret=
										filetype_remove(
											data,
											data->sel_filetype,
											(id==GAD_FILETYPES_STORE)))==1)
									{
										data->change=1;
										data->sel_filetype=0;
									}

									// Quit?
									else if (ret==-1)
									{
										quit_flag=1;
									}
								}
								break;
						}
						break;


					// Key press
					case IDCMP_RAWKEY:

						// Help?
						if (msg_copy.Code==0x5f &&
							!(msg_copy.Qualifier&VALID_QUALIFIERS))
						{
							// Set busy pointer
							SetWindowBusy(data->window);

							// Send help command
							IPC_Command(data->owner_ipc,IPC_HELP,(1<<31),"File Types",0,REPLY_NO_PORT);

							// Clear busy pointer
							ClearWindowBusy(data->window);
						}
						break;
				}

				// Check quit flag
				if (quit_flag) break;
			}
		}

		// Check quit flag
		if (quit_flag)
		{
			if (!pending_quit)
			{
				SetWindowBusy(data->window);
				if (!(IPC_ListQuit(&data->proc_list,0,!undo_flag,FALSE)))
					pending_quit=2;
				else
					pending_quit=1;
			}
		}

		// Set to break?
		if (pending_quit==2)
		{
			// Save filetypes?
			if (data->change && !undo_flag)
			{
				if (!(ret=filetype_save(data)))
				{
					// Abort save/quit
					ClearWindowBusy(data->window);
					pending_quit=0;
					continue;
				}
			}
			break;
		}

		// Wait for an event
		Wait(1<<ipc->command_port->mp_SigBit|
			((data->window)?1<<data->window->UserPort->mp_SigBit:0));
	}

	// Save window position
	if (data->window)
	{
		struct IBox pos;
		pos.Left=data->window->LeftEdge;
		pos.Top=data->window->TopEdge;
		pos.Width=data->window->Width-data->window->BorderLeft-data->window->BorderRight;
		pos.Height=data->window->Height-data->window->BorderTop-data->window->BorderBottom;
		SavePos("dopus/windows/filetypes",(struct IBox *)&pos,data->window->RPort->TxHeight);
	}

	// Close up
	CloseConfigWindow(data->window);

	// Free data
	Att_RemList(data->filetype_list,REMLIST_FREEDATA);
	FreeMemHandle(data->memory);
	FreeVec(data);

	// Reply quit message
	IPC_Reply(quit_msg);
	return ret;
}
Beispiel #15
0
bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
{
  if (!MainComment)
    return(false);
  SaveFilePos SavePos(*this);

#ifndef SFX_MODULE
  ushort CmtLength;
  if (OldFormat)
  {
    Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
    CmtLength=GetByte();
    CmtLength+=(GetByte()<<8);
  }
  else
#endif
  {
    if (NewMhd.Flags & MHD_COMMENT)
    {
      // Old style (RAR 2.9) archive comment embedded into the main 
      // archive header.
      Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
      ReadHeader();
    }
    else
    {
      // Current (RAR 3.0+) version of archive comment.
      Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
      return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0);
    }
#ifndef SFX_MODULE
    // Old style (RAR 2.9) comment header embedded into the main 
    // archive header.
    if (CommHead.HeadCRC!=HeaderCRC)
    {
      Log(FileName,St(MLogCommHead));
      Alarm();
      return(false);
    }
    CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
  }
#ifndef SFX_MODULE
  if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT) || !OldFormat && CommHead.Method!=0x30)
  {
    if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
      return(false);
    ComprDataIO DataIO;
    Unpack Unpack(&DataIO);
    Unpack.Init();
    DataIO.SetTestMode(true);
    uint UnpCmtLength;
    if (OldFormat)
    {
#ifdef RAR_NOCRYPT
      return(false);
#else
      UnpCmtLength=GetByte();
      UnpCmtLength+=(GetByte()<<8);
      CmtLength-=2;
      DataIO.SetCmt13Encryption();
#endif
    }
    else
      UnpCmtLength=CommHead.UnpSize;
    DataIO.SetFiles(this,NULL);
    DataIO.EnableShowProgress(false);
    DataIO.SetPackedSizeToRead(CmtLength);
    Unpack.SetDestSize(UnpCmtLength);
    Unpack.DoUnpack(CommHead.UnpVer,false);

    if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      return(false);
    }
    else
    {
      byte *UnpData;
      size_t UnpDataSize;
      DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
      CmtData->Alloc(UnpDataSize);
      memcpy(&((*CmtData)[0]),UnpData,UnpDataSize);
    }
  }
  else
  {
    CmtData->Alloc(CmtLength);
    
    Read(&((*CmtData)[0]),CmtLength);
    if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff))
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      CmtData->Reset();
      return(false);
    }
  }
#endif
#if defined(_WIN_ALL) && !defined(_WIN_CE)
  if (CmtData->Size()>0)
  {
    size_t CmtSize=CmtData->Size();
    char *DataA=(char *)CmtData->Addr();
    OemToCharBuffA(DataA,DataA,(DWORD)CmtSize);

    if (CmtDataW!=NULL)
    {
      CmtDataW->Alloc(CmtSize+1);
      CmtData->Push(0);
      CharToWide(DataA,CmtDataW->Addr(),CmtSize+1);
      CmtData->Alloc(CmtSize);
      CmtDataW->Alloc(wcslen(CmtDataW->Addr()));
    }
  }
#endif
  return(CmtData->Size()>0);
}
Beispiel #16
0
bool Archive::GetComment(Array<byte> &CmtData)
{
  if (!MainComment)
    return(false);
  SaveFilePos SavePos(*this);

  ushort CmtLength;
#ifndef SFX_MODULE
  if (OldFormat)
  {
    Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
    CmtLength=GetByte()+(GetByte()<<8);
  }
  else
#endif
  {
    if (NewMhd.Flags & MHD_COMMENT)
    {
      Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
      ReadHeader();
    }
    else
    {
      Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
      return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData)!=0);
    }
#ifndef SFX_MODULE
    if (CommHead.HeadCRC!=HeaderCRC)
    {
      Log(FileName,St(MLogCommHead));
      Alarm();
      return(false);
    }
    CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
  }
#ifndef SFX_MODULE
  if ((OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT)) || (!OldFormat && CommHead.Method!=0x30))
  {
    if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
      return(false);
    ComprDataIO DataIO;
    Unpack Unpack(&DataIO);
    Unpack.Init();
    DataIO.SetTestMode(true);
    uint UnpCmtLength;
    if (OldFormat)
    {
      UnpCmtLength=GetByte()+(GetByte()<<8);
      CmtLength-=2;
      DataIO.SetCmt13Encryption();
    }
    else
      UnpCmtLength=CommHead.UnpSize;
    DataIO.SetFiles(this,NULL);
    DataIO.EnableShowProgress(false);
    DataIO.SetPackedSizeToRead(CmtLength);
    Unpack.SetDestSize(UnpCmtLength);
    Unpack.DoUnpack(CommHead.UnpVer,false);

    if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      return(false);
    }
    else
    {
      unsigned char *UnpData;
      uint UnpDataSize;
      DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
      CmtData.Alloc(UnpDataSize);
      memcpy(&CmtData[0],UnpData,UnpDataSize);
    }
  }
  else
  {
    CmtData.Alloc(CmtLength);
    
    Read(&CmtData[0],CmtLength);
    if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&CmtData[0],CmtLength)&0xffff))
    {
      Log(FileName,St(MLogCommBrk));
      Alarm();
      CmtData.Reset();
      return(false);
    }
  }
#endif
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(_XBOX) && !defined(_LINUX)
  //if (CmtData.Size()>0)
  //  OemToCharBuff((char*)&CmtData[0],(char*)&CmtData[0],CmtData.Size());
#endif
  return(CmtData.Size()>0);
}
Beispiel #17
0
bool Archive::IsArchive(bool EnableBroken)
{
  Encrypted=false;
#ifdef USE_QOPEN
  QOpen.Unload();
#endif

  // Important if we reuse Archive object and it has virtual QOpen
  // file position not matching real. For example, for 'l -v volname'.
  Seek(0,SEEK_SET);
  
#ifndef SFX_MODULE
  if (IsDevice())
  {
#ifndef SHELL_EXT
    Log(FileName,St(MInvalidName),FileName);
#endif
    return false;
  }
#endif
  if (Read(MarkHead.Mark,SIZEOF_MARKHEAD3)!=SIZEOF_MARKHEAD3)
    return(false);
  SFXSize=0;
  
  RARFORMAT Type;
  if ((Type=IsSignature(MarkHead.Mark,SIZEOF_MARKHEAD3))!=RARFMT_NONE)
  {
    Format=Type;
    if (Format==RARFMT14)
      Seek(0,SEEK_SET);
  }
  else
  {
    Array<char> Buffer(MAXSFXSIZE);
    long CurPos=(long)Tell();
    int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
    for (int I=0;I<ReadSize;I++)
      if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
      {
        Format=Type;
        if (Format==RARFMT14 && I>0 && CurPos<28 && ReadSize>31)
        {
          char *D=&Buffer[28-CurPos];
          if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
            continue;
        }
        SFXSize=CurPos+I;
        Seek(SFXSize,SEEK_SET);
        if (Format==RARFMT15 || Format==RARFMT50)
          Read(MarkHead.Mark,SIZEOF_MARKHEAD3);
        break;
      }
    if (SFXSize==0)
      return false;
  }
  if (Format==RARFMT_FUTURE)
  {
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
    Log(FileName,St(MNewRarFormat));
#endif
    return false;
  }
  if (Format==RARFMT50) // RAR 5.0 signature is by one byte longer.
  {
    Read(MarkHead.Mark+SIZEOF_MARKHEAD3,1);
    if (MarkHead.Mark[SIZEOF_MARKHEAD3]!=0)
      return false;
    MarkHead.HeadSize=SIZEOF_MARKHEAD5;
  }
  else
    MarkHead.HeadSize=SIZEOF_MARKHEAD3;

  // Skip the archive encryption header if any and read the main header.
  while (ReadHeader()!=0 && GetHeaderType()!=HEAD_MAIN)
    SeekToNext();

  // This check allows to make RS based recovery even if password is incorrect.
  // But we should not do it for EnableBroken or we'll get 'not RAR archive'
  // messages when extracting encrypted archives with wrong password.
  if (FailedHeaderDecryption && !EnableBroken)
    return false;

  SeekToNext();
  if (BrokenHeader)
  {
#ifndef SHELL_EXT
    Log(FileName,St(MMainHeaderBroken));
#endif
    if (!EnableBroken)
      return false;
  }

/*
  if (MainHead.EncryptVer>VER_UNPACK)
  {
#ifdef RARDLL
    Cmd->DllError=ERAR_UNKNOWN_FORMAT;
#else
    ErrHandler.SetErrorCode(RARX_WARNING);
  #if !defined(SILENT) && !defined(SFX_MODULE)
      Log(FileName,St(MUnknownMeth),FileName);
      Log(FileName,St(MVerRequired),MainHead.EncryptVer/10,MainHead.EncryptVer%10);
  #endif
#endif
    return(false);
  }
*/

#ifdef RARDLL
  // If callback function is not set, we cannot get the password,
  // so we skip the initial header processing for encrypted header archive.
  // It leads to skipped archive comment, but the rest of archive data
  // is processed correctly.
  if (Cmd->Callback==NULL)
    SilentOpen=true;
#endif

  MainComment=MainHead.CommentInHeader;

#ifdef USE_QOPEN
  if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
  {
    QOpen.Init(this,false);
    QOpen.Load(MainHead.QOpenOffset);
  }
#endif

  // If we process non-encrypted archive or can request a password,
  // we set 'first volume' flag based on file attributes below.
  // It is necessary for RAR 2.x archives, which did not have 'first volume'
  // flag in main header.
  if (!SilentOpen || !Encrypted)
  {
    SaveFilePos SavePos(*this);
    int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;

    while (ReadHeader()!=0)
    {
      HEADER_TYPE HeaderType=GetHeaderType();
      if (HeaderType==HEAD_SERVICE)
      {
        if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
          MainComment=true;
        FirstVolume=!SubHead.SplitBefore;
      }
      else
      {
        FirstVolume=HeaderType==HEAD_FILE && !FileHead.SplitBefore;
        break;
      }
      SeekToNext();
    }
    CurBlockPos=SaveCurBlockPos;
    NextBlockPos=SaveNextBlockPos;
  }
  if (!Volume || FirstVolume)
    wcscpy(FirstVolumeName,FileName);

  return true;
}
BOOL CBasicCPU1EDXCaptions::OnInitDialog()
    {
     CScrollableCaptions::OnInitDialog();

     ColorSet colors(TRUE);
     POSITION p = colors.GetFirstColorPosition();

     SETCOLORI(FPU, 0);    // 0
     SETALIGN(FPU);        // 0
     c_FPU.SetWindowText(_T("")); // 0
     
     SETCOLORI(VME, 1);    // 1
     SETALIGN(VME);        // 1
     c_VME.SetWindowText(_T("")); // 1
     
     SETCOLORI(DE, 2);     // 2
     SETALIGN(DE);         // 2
     c_DE.SetWindowText(_T("")); // 2
     
     SETCOLORI(PSE, 3);    // 3
     SETALIGN(PSE);        // 3
     c_PSE.SetWindowText(_T("")); // 3

     SETCOLORI(TSC, 4);    // 4
     SETALIGN(TSC);        // 4
     c_TSC.SetWindowText(_T("")); // 4

     SETCOLORI(MSR, 5);    // 5
     SETALIGN(MSR);        // 5
     c_MSR.SetWindowText(_T("")); // 5

     SETCOLORI(PAE, 6);    // 6
     SETALIGN(PAE);        // 6
     c_PAE.SetWindowText(_T("")); // 6

     SETCOLORI(MCE, 7);    // 7
     SETALIGN(MCE);        // 7
     c_MCE.SetWindowText(_T("")); // 7

     SETCOLORI(CX8, 8);    // 8
     SETALIGN(CX8);        // 8
     c_CX8.SetWindowText(_T("")); // 8

     SETCOLORI(APIC, 9);   // 9
     SETALIGN(APIC);       // 9
     c_APIC.SetWindowText(_T("")); // 9

     SETRESERVEDCOLOR(Reserved1); // 10
     SETALIGN(RESERVED1);  // 10
     c_Reserved1.SetWindowText(_T("")); // 10

     SETCOLORI(SEP, 11);   // 11
     SETALIGN(SEP);        // 11
     c_SEP.SetWindowText(_T("")); // 11
     
     SETCOLORI(MTRR, 12);  // 12
     SETALIGN(MTRR);       // 12
     c_MTRR.SetWindowText(_T("")); // 12

     SETCOLORI(PGE, 13);   // 13
     SETALIGN(PGE);        // 13
     c_PGE.SetWindowText(_T("")); // 13

     SETCOLORI(MCA, 14);   // 14
     SETALIGN(MCA);        // 14
     c_MCA.SetWindowText(_T("")); // 14

     SETCOLORI(CMOV, 15);  // 15
     SETALIGN(CMOV);       // 15
     c_CMOV.SetWindowText(_T("")); // 15

     SETCOLORI(PAT, 16);   // 16
     SETALIGN(PAT);        // 16
     c_PAT.SetWindowText(_T("")); // 16

     SETCOLORI(PSE36, 17); // 17
     SETALIGN(PSE36);      // 17
     c_PSE36.SetWindowText(_T("")); // 17
                           // 18: subclass
     
     SETCOLORI(CFLSH, 19); // 19
     SETALIGN(CFLSH);      // 19
     c_CFLSH.SetWindowText(_T("")); // 19

     SETRESERVEDCOLOR(Reserved2); // 20
     SETALIGN(RESERVED2);  // 20
     c_Reserved2.SetWindowText(_T("")); // 20

                           // 21: subclass
                           // 22: subclass
     
     SETCOLORI(MMX, 23);   // 23
     SETALIGN(MMX);        // 23
     c_MMX.SetWindowText(_T("")); // 23 

     SETCOLORI(FXSR, 24);  // 24
     SETALIGN(FXSR);       // 24
     c_FXSR.SetWindowText(_T("")); // 24

     SETCOLORI(SSE, 25);   // 25
     SETALIGN(SSE);        // 25
     c_SSE.SetWindowText(_T("")); // 25

     SETCOLORI(SSE2, 26);  // 26
     SETALIGN(SSE2);       // 26
     c_SSE2.SetWindowText(_T("")); // 26
                           // 27: subclass
     
     SETCOLORI(HTT, 28);   // 28
     SETALIGN(HTT);        // 28
     c_HTT.SetWindowText(_T("")); // 28

                           // 29: subclass
     
     SETRESERVEDCOLOR(Reserved3); // 30
     SETALIGN(RESERVED3);  // 30
     c_Reserved3.SetWindowText(_T("")); // 30

                           // 31: subclass
     
     SavePos();  // save the newly-computed positions
     
     return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
    }
Beispiel #19
0
void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size,uint Flags)
{
  SaveFilePos SavePos(*SrcFile);
#ifndef SILENT
  int64 FileLength=SrcFile->FileLength();
  if ((Flags & (CALCFSUM_SHOWTEXT|CALCFSUM_SHOWALL))!=0)
  {
    mprintf(St(MCalcCRC));
    mprintf(L"     ");
  }

#endif

  if ((Flags & CALCFSUM_CURPOS)==0)
    SrcFile->Seek(0,SEEK_SET);

  const size_t BufSize=0x100000;
  Array<byte> Data(BufSize);


  DataHash HashCRC,HashBlake2;
  HashCRC.Init(HASH_CRC32,Threads);
  HashBlake2.Init(HASH_BLAKE2,Threads);

  int64 BlockCount=0;
  while (true)
  {
    size_t SizeToRead;
    if (Size==INT64NDF)   // If we process the entire file.
      SizeToRead=BufSize; // Then always attempt to read the entire buffer.
    else
      SizeToRead=(size_t)Min((int64)BufSize,Size);
    int ReadSize=SrcFile->Read(&Data[0],SizeToRead);
    if (ReadSize==0)
      break;

    if ((++BlockCount & 0xf)==0)
    {
#ifndef SILENT
      if ((Flags & CALCFSUM_SHOWALL)!=0)
        mprintf(L"\b\b\b\b%3d%%",ToPercent(BlockCount*int64(BufSize),FileLength));
#endif
      Wait();
    }

    if (CRC32!=NULL)
      HashCRC.Update(&Data[0],ReadSize);
    if (Blake2!=NULL)
      HashBlake2.Update(&Data[0],ReadSize);

    if (Size!=INT64NDF)
      Size-=ReadSize;
  }
#ifndef SILENT
  if ((Flags & CALCFSUM_SHOWALL)!=0)
    mprintf(L"\b\b\b\b    ");
#endif

  if (CRC32!=NULL)
    *CRC32=HashCRC.GetCRC32();
  if (Blake2!=NULL)
  {
    HashValue Result;
    HashBlake2.Result(&Result);
    memcpy(Blake2,Result.Digest,sizeof(Result.Digest));
  }
}
Beispiel #20
0
bool Archive::GetComment(Array<wchar> *CmtData)
{
  if (!MainComment)
    return false;
  SaveFilePos SavePos(*this);

#ifndef SFX_MODULE
  ushort CmtLength;
  if (Format==RARFMT14)
  {
    Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
    CmtLength=GetByte();
    CmtLength+=(GetByte()<<8);
  }
  else
#endif
  {
    if (MainHead.CommentInHeader)
    {
      // Old style (RAR 2.9) archive comment embedded into the main 
      // archive header.
      Seek(SFXSize+SIZEOF_MARKHEAD3+SIZEOF_MAINHEAD3,SEEK_SET);
      ReadHeader();
    }
    else
    {
      // Current (RAR 3.0+) version of archive comment.
      Seek(GetStartPos(),SEEK_SET);
      return SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData);
    }
#ifndef SFX_MODULE
    // Old style (RAR 2.9) comment header embedded into the main 
    // archive header.
    if (BrokenHeader)
    {
      uiMsg(UIERROR_CMTBROKEN,FileName);
      return false;
    }
    CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
#endif
  }
#ifndef SFX_MODULE
  if (Format==RARFMT14 && MainHead.PackComment || Format!=RARFMT14 && CommHead.Method!=0x30)
  {
    if (Format!=RARFMT14 && (CommHead.UnpVer < 15 || CommHead.UnpVer > VER_UNPACK || CommHead.Method > 0x35))
      return(false);
    ComprDataIO DataIO;
    DataIO.SetTestMode(true);
    uint UnpCmtLength;
    if (Format==RARFMT14)
    {
#ifdef RAR_NOCRYPT
      return(false);
#else
      UnpCmtLength=GetByte();
      UnpCmtLength+=(GetByte()<<8);
      CmtLength-=2;
      DataIO.SetCmt13Encryption();
      CommHead.UnpVer=15;
#endif
    }
    else
      UnpCmtLength=CommHead.UnpSize;
    DataIO.SetFiles(this,NULL);
    DataIO.EnableShowProgress(false);
    DataIO.SetPackedSizeToRead(CmtLength);
    DataIO.UnpHash.Init(HASH_CRC32,1);

    Unpack CmtUnpack(&DataIO);
    CmtUnpack.Init(0x10000,false);
    CmtUnpack.SetDestSize(UnpCmtLength);
    CmtUnpack.DoUnpack(CommHead.UnpVer,false);

    if (Format!=RARFMT14 && (DataIO.UnpHash.GetCRC32()&0xffff)!=CommHead.CommCRC)
    {
      uiMsg(UIERROR_CMTBROKEN,FileName);
      return false;
    }
    else
    {
      byte *UnpData;
      size_t UnpDataSize;
      DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
#ifdef _WIN_ALL
      OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
#endif
      CmtData->Alloc(UnpDataSize+1);
      memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
      CharToWide((char *)UnpData,CmtData->Addr(0),UnpDataSize);
      CmtData->Alloc(wcslen(CmtData->Addr(0)));
    }
  }
  else
  {
    Array<byte> CmtRaw(CmtLength);
    Read(&CmtRaw[0],CmtLength);

    if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
    {
      uiMsg(UIERROR_CMTBROKEN,FileName);
      return false;
    }
    CmtData->Alloc(CmtLength+1);
    CmtRaw.Push(0);
#ifdef _WIN_ALL
    OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
#endif
    CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtLength);
    CmtData->Alloc(wcslen(CmtData->Addr(0)));
  }
#endif
  return CmtData->Size() > 0;
}