Index: oup/rewrite/DataAccess/Access_OUP_ADB.pas
===================================================================
--- oup/rewrite/DataAccess/Access_OUP_ADB.pas	(revision 97)
+++ oup/rewrite/DataAccess/Access_OUP_ADB.pas	(revision 101)
@@ -2,46 +2,46 @@
 interface
 
-uses DataAccess;
+uses DataAccess, ABSMain, TypeDefs, Classes;
 
 type
   TAccess_OUP_ADB = class(TDataAccess)
   private
-{    FDatabase: TABSDatabase;
-    FQuery:    TABSQuery;
-    Fdat_files:    TFiles;
+    FDatabase:          TABSDatabase;
+    FQuery:             TABSQuery;
+    Fdat_files:         TFiles;
     Fdat_extensionsmap: TExtensionsMap;
   protected
   public
-    constructor Create(OLDBFilename: String; var Result: Boolean); override;
+    constructor Create(DBFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
     procedure Close; override;
 
     procedure UpdateListCache;
-    //      function GetDatLinks(srcid:LongWord):TDatLinks;
-    function GetFileInfo(fileid: Integer): TFileInfo; override;
-    function GetFilesList(ext: String; pattern: String;
-      NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
-    function GetFilesCount: LongWord; override;
-    function GetExtensionsList: TStringArray; override;
-    function GetExtendedExtensionsList: TExtensionsMap; override;
-    function GetNamedFilesMap: TNamedFilesMap;
-
-    function LoadDatFile(fileid: LongWord): Tdata; override;
-    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
-    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-
-    function GetRawList(fileid: LongWord): TRawList; override;
-    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
-    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
-      target: Pointer); override;
-    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
+
+    function GetFileInfo(FileID: Integer): TFileInfo; override;
+    function GetFilesList(Ext: String; Pattern: String;
+      NoEmptyFiles: Boolean; SortType: TSortType): TStrings; override;
+    function GetFileCount: Integer; override;
+    function GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings; override;
+
+    procedure LoadDatFile(FileID: Integer; var Target: TStream); overload; override;
+    procedure UpdateDatFile(FileID: Integer; Src: TStream); overload; override;
+    procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; override;
+    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; override;
+
+    function GetRawList(FileID: Integer): TRawDataList; override;
+    function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override;
+
+    procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; override;
+    procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; override;
+    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; override;
+    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; override;
   published
-}  end;
+  end;
 
 
 implementation
+
+uses
+  SysUtils, Data, Functions, ABSDecUtil, DB;
 
 
@@ -51,23 +51,23 @@
 *)
 
-{
-constructor TOniDataADB.Create(OLDBFilename: String; var Result: Boolean);
-var
-  i, j:  Byte;
-  temps: String;
-begin
-  if not FileExists(OLDBFilename) then
-  begin
-    ShowMessage('File doesn''t exist!!!');
-    Result := False;
+
+constructor TAccess_OUP_ADB.Create(DBFilename: String; ConnectionID: Integer; var Msg: TStatusMessages);
+var
+  i: Integer;
+begin
+  Msg := SM_UnknownError;
+  if not FileExists(DBFilename) then
+  begin
+    Msg := SM_FileNotFound;
     Exit;
   end;
-  FFileName := OLDBFilename;
+  FFileName := DBFilename;
+
   FDatabase := TABSDatabase.Create(nil);
-  FDatabase.DatabaseName := 'OLDBcon';
-  FDatabase.DatabaseFileName := OLDBFilename;
+  FDatabase.DatabaseName := 'OLDBcon' + IntToStr(ConnectionID);
+  FDatabase.DatabaseFileName := DBFilename;
   FDatabase.Open;
   FQuery := TABSQuery.Create(FDatabase);
-  FQuery.DatabaseName := 'OLDBcon';
+  FQuery.DatabaseName := 'OLDBcon' + IntToStr(ConnectionID);
   FQuery.SQL.Text := 'SELECT [name],[value] FROM globals ORDER BY [name] ASC';
   FQuery.Open;
@@ -78,42 +78,21 @@
       if FQuery.FieldByName('value').AsString <> DBversion then
       begin
-        ShowMessage('Database-file ' + #13 + #10 +
-          '"' + OLDBFilename + '"' + #13 + #10 +
-          'has wrong version. (Required: ' + DBversion + '; found: ' +
-          FQuery.FieldByName('value').AsString + ')');
+        Msg := SM_IncompatibleDBVersion;
         FQuery.Close;
-        Result := False;
         Exit;
       end;
     end;
     if FQuery.FieldByName('name').AsString = 'lvl' then
-    begin
-      FLevelInfo.LevelNumber := StrToInt(FQuery.FieldByName('value').AsString);
-    end;
-    if FQuery.FieldByName('name').AsString = 'ident' then
-    begin
-      temps := FQuery.FieldByName('value').AsString;
-      for i := 0 to High(FLevelInfo.Ident) do
-      begin
-        j := i * 2 + 1;
-        case temps[j] of
-          '0'..'9':
-            FLevelInfo.Ident[i] := Ord(temps[j]) - 48;
-          'A'..'F':
-            FLevelInfo.Ident[i] := Ord(temps[j]) - 55;
-        end;
-        FLevelInfo.Ident[i] := FLevelInfo.Ident[i] * 16;
-        case temps[j + 1] of
-          '0'..'9':
-            FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 48;
-          'A'..'F':
-            FLevelInfo.Ident[i] := FLevelInfo.Ident[i] + Ord(temps[j + 1]) - 55;
-        end;
-      end;
-    end;
-    if FQuery.FieldByName('name').AsString = 'ident' then
-    begin
-      temps   := FQuery.FieldByName('value').AsString;
-      Fos_mac := temps = 'MAC';
+      FLevelNumber := StrToInt(FQuery.FieldByName('value').AsString);
+    if FQuery.FieldByName('name').AsString = 'DataOS' then
+    begin
+      if FQuery.FieldByName('value').AsString = 'WIN' then
+        FDataOS := DOS_WIN
+      else if FQuery.FieldByName('value').AsString = 'WINDEMO' then
+        FDataOS := DOS_WINDEMO
+      else if FQuery.FieldByName('value').AsString = 'MAC' then
+        FDataOS := DOS_MAC
+      else if FQuery.FieldByName('value').AsString = 'MACBETA' then
+        FDataOS := DOS_MACBETA;
     end;
     FQuery.Next;
@@ -121,15 +100,18 @@
   FQuery.Close;
 
+  Msg := SM_OK;
+  FBackend := DB_ADB;
+
+  FChangeRights := [CR_EditDat, CR_EditRaw, CR_ResizeDat, CR_ResizeRaw];
+
   UpdateListCache;
-
-  Result   := True;
-  FBackend := ODB_ADB;
-end;
-
-
-
-
-procedure TOniDataADB.Close;
-begin
+end;
+
+
+
+
+procedure TAccess_OUP_ADB.Close;
+begin
+  FQuery.Free;
   FDatabase.Close;
   FDatabase.Free;
@@ -139,15 +121,15 @@
 
 
-procedure TOniDataADB.UpdateListCache;
-var
-  i:     LongWord;
+procedure TAccess_OUP_ADB.UpdateListCache;
+var
+  i:     Integer;
   temps: String;
 begin
   FQuery.SQL.Text := 'SELECT id,name,extension,[size],contenttype FROM datfiles ORDER BY id ASC;';
   FQuery.Open;
+  SetLength(Fdat_files, FQuery.RecordCount);
   if FQuery.RecordCount > 0 then
   begin
     FQuery.First;
-    SetLength(Fdat_files, FQuery.RecordCount);
     i := 0;
     repeat
@@ -155,12 +137,7 @@
       Fdat_files[i].Name := FQuery.FieldByName('name').AsString;
       Fdat_files[i].Extension := FQuery.FieldByName('extension').AsString;
-      Fdat_files[i].FileName := FormatNumber(Fdat_files[i].ID, 5, '0') + '-' +
-          Fdat_files[i].Name + '.' + Fdat_files[0].Extension;
-      Fdat_files[i].FileNameHex := IntToHex(Fdat_files[i].ID, 4) + '-' +
-          Fdat_files[i].Name + '.' + Fdat_files[0].Extension;
       Fdat_files[i].Size := FQuery.FieldByName('size').AsInteger;
       Fdat_files[i].FileType := HexToLong(FQuery.FieldByName('contenttype').AsString);
       Fdat_files[i].DatAddr := 0;
-      Fdat_files[i].opened := False;
       Inc(i);
       FQuery.Next;
@@ -169,14 +146,13 @@
   FQuery.Close;
 
-  SetLength(Fdat_extensionsmap, 0);
   FQuery.SQL.Text :=
     'SELECT extension,count(extension) AS x FROM datfiles GROUP BY extension ORDER BY extension ASC;';
   FQuery.Open;
+  SetLength(Fdat_extensionsmap, FQuery.RecordCount);
   if FQuery.RecordCount > 0 then
   begin
-    SetLength(Fdat_extensionsmap, FQuery.RecordCount);
     i := 0;
     repeat
-      temps := FQuery.FieldByName('extension').AsString[1];
+      temps := FQuery.FieldByName('extension').AsString;
       Fdat_extensionsmap[i].Extension[3] := temps[1];
       Fdat_extensionsmap[i].Extension[2] := temps[2];
@@ -192,7 +168,5 @@
 
 
-function TOniDataADB.GetFileInfo(fileid: Integer): TFileInfo;
-var
-  i: Integer;
+function TAccess_OUP_ADB.GetFileInfo(fileid: Integer): TFileInfo;
 begin
   if fileid = -1 then
@@ -201,28 +175,18 @@
     Exit;
   end;
-  if fileid < Self.GetFilesCount then
-  begin
-    for i := 0 to High(Fdat_files) do
-      if Fdat_files[i].ID = fileid then
-        Break;
-    if i < Length(Fdat_files) then
-      Result := Fdat_files[i]
-    else
-      Result.ID := -1;
-  end
+  if fileid < Self.GetFileCount then
+    Result    := Fdat_files[fileid]
   else
-  begin
     Result.ID := -1;
-  end;
-end;
-
-
-
-
-function TOniDataADB.GetFilesList(ext: String; pattern: String;
-  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
-var
-  i: LongWord;
-  list: TStringList;
+end;
+
+
+
+
+function TAccess_OUP_ADB.GetFilesList(ext: String; pattern: String;
+  NoEmptyFiles: Boolean; SortType: TSortType): TStrings;
+var
+  i:      Integer;
+  list:   TStringList;
   id, name, extension: String;
   fields: TStrings;
@@ -230,6 +194,6 @@
   procedure getfields;
   begin
-     fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
-    if sort in [stIDAsc, stIDDesc] then
+    fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
+    if SortType in [ST_IDAsc, ST_IDDesc] then
     begin
       id := fields.Strings[0];
@@ -237,5 +201,5 @@
       extension := fields.Strings[2];
     end;
-    if sort in [stNameAsc, stNameDesc] then
+    if SortType in [ST_NameAsc, ST_NameDesc] then
     begin
       id := fields.Strings[1];
@@ -243,5 +207,5 @@
       extension := fields.Strings[2];
     end;
-    if sort in [stExtAsc, stExtDesc] then
+    if SortType in [ST_ExtAsc, ST_ExtDesc] then
     begin
       id := fields.Strings[1];
@@ -254,5 +218,5 @@
   list := TStringList.Create;
   list.Sorted := True;
-  for i := 0 to High(Fdat_files) do
+  for i := 0 to GetFileCount - 1 do
   begin
     if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
@@ -269,34 +233,37 @@
         extension := Fdat_files[i].Extension;
 
-        case sort of
-          stIDAsc, stIDDesc:     list.Add(id + ';' + name + ';' + extension);
-          stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
-          stExtAsc, stExtDesc:   list.Add(extension + ';' + id + ';' + name);
+        case SortType of
+          ST_IDAsc, ST_IDDesc:     list.Add(id + ';' + name + ';' + extension);
+          ST_NameAsc, ST_NameDesc: list.Add(name + ';' + id + ';' + extension);
+          ST_ExtAsc, ST_ExtDesc:   list.Add(extension + ';' + id + ';' + name);
         end;
       end;
     end;
   end;
-  SetLength(Result, list.Count);
-  fields := TStringList.Create;
-  if sort in [stIDAsc, stNameAsc, stExtAsc] then
-    for i := 0 to list.Count - 1 do
-    begin
-      getfields;
-      Result[i] := id + '-' + name + '.' + extension;
-    end
-  else
-    for i := list.Count - 1 downto 0 do
-    begin
-      getfields;
-      Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
-    end;
+  Result := TStringList.Create;
+  if list.Count > 0 then
+  begin
+    fields := TStringList.Create;
+    if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc] then
+      for i := 0 to list.Count - 1 do
+      begin
+        getfields;
+        Result.Add(id + '-' + name + '.' + extension);
+      end
+    else
+      for i := list.Count - 1 downto 0 do
+      begin
+        getfields;
+        Result.Add(id + '-' + name + '.' + extension);
+      end;
+    fields.Free;
+  end;
   list.Free;
-  fields.Free;
-end;
-
-
-
-
-function TOniDataADB.GetFilesCount: LongWord;
+end;
+
+
+
+
+function TAccess_OUP_ADB.GetFileCount: Integer;
 begin
   Result := Length(Fdat_files);
@@ -304,122 +271,37 @@
 
 
-
-
-function TOniDataADB.GetExtensionsList: TStringArray;
-var
-  i: LongWord;
-begin
-  SetLength(Result, Length(Fdat_extensionsmap));
-  for i := 0 to High(Result) do
+function TAccess_OUP_ADB.GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings;
+var
+  i: Integer;
+begin
+  Result := TStringList.Create;
+  for i := 0 to Length(Fdat_extensionsmap) - 1 do
   begin
     with Fdat_extensionsmap[i] do
     begin
-      Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
-        ' (' + IntToStr(ExtCount) + ')';
-    end;
-  end;
-end;
-
-
-
-
-function TOniDataADB.GetExtendedExtensionsList: TExtensionsMap;
-var
-  i, j:  LongWord;
-  temps: String;
-  Data:  Tdata;
-begin
-  SetLength(Result, 0);
-  FQuery.SQL.Text := 'SELECT ext,ident FROM extlist ORDER BY ext ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    SetLength(Result, FQuery.RecordCount);
-    i := 0;
-    repeat
-      temps := FQuery.FieldByName('ext').AsString;
-      for j := 0 to 3 do
-        Result[i].Extension[j] := temps[4 - j];
-      Data := DecodeHexString(FQuery.FieldByName('ident').AsString);
-      for j := 0 to 7 do
-        Result[i].Ident[j] := Data[j];
-      Inc(i);
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-end;
-
-
-
-
-function TOniDataADB.GetNamedFilesMap: TNamedFilesMap;
-var
-  i:     LongWord;
-  temp:  Integer;
-  temps: String;
-  temparray: array of record
-    id: Integer;
-    fullname: String[50];
-  end;
-begin
-  SetLength(temparray, 0);
-  FQuery.SQL.Text :=
-    'SELECT id,(extension+name) AS xname FROM datfiles WHERE Length(name)>0 ORDER BY extension,name ASC;';
-  FQuery.Open;
-  if FQuery.RecordCount > 0 then
-  begin
-    repeat
-      temp  := FQuery.FieldByName('id').AsInteger;
-      temps := FQuery.FieldByName('xname').AsString;
-
-      SetLength(temparray, Length(temparray) + 1);
-      if Length(temparray) > 1 then
-      begin
-        for i := High(temparray) - 1 downto 0 do
-        begin
-          if StringSmaller(temps, temparray[i].fullname) then
-          begin
-            temparray[i + 1] := temparray[i];
-            if i = 0 then
-            begin
-              temparray[i].id := temp;
-              temparray[i].fullname := temps;
-            end;
-          end
-          else
-          begin
-            temparray[i + 1].id := temp;
-            temparray[i + 1].fullname := temps;
-            Break;
-          end;
-        end;
-      end
-      else
-      begin
-        temparray[0].id := temp;
-        temparray[0].fullname := temps;
+      case ExtListFormat of
+        EF_ExtOnly:
+          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0]);
+        EF_ExtCount:
+          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0] +
+                ' (' + IntToStr(ExtCount) + ')');
       end;
-      FQuery.Next;
-    until FQuery.EOF;
-  end;
-  FQuery.Close;
-  SetLength(Result, Length(temparray));
-  for i := 0 to High(temparray) do
-  begin
-    Result[i].FileNumber := temparray[i].id;
-    Result[i].blubb      := 0;
-  end;
-end;
-
-
-
-
-function TOniDataADB.LoadDatFile(fileid: LongWord): Tdata;
+    end;
+  end;
+end;
+
+
+procedure TAccess_OUP_ADB.LoadDatFile(FileID: Integer; var Target: TStream);
 var
   mem: TStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
+  streampos: Integer;
+begin
+  if fileid < GetFileCount then
+  begin
+    if not Assigned(Target) then
+      Target := TMemoryStream.Create;
+
+    streampos := Target.Position;
+
     FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
     FQuery.Open;
@@ -427,27 +309,24 @@
     begin
       mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
-      SetLength(Result, mem.Size);
       mem.Seek(0, soFromBeginning);
-      mem.Read(Result[0], mem.Size);
+      Target.CopyFrom(mem, mem.Size);
       mem.Free;
     end;
     FQuery.Close;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateDatFile(fileid: LongWord; Data: Tdata);
+
+    Target.Seek(streampos, soFromBeginning);
+  end;
+end;
+
+procedure TAccess_OUP_ADB.UpdateDatFile(FileID: Integer; Src: TStream);
 var
   MimeCoder: TStringFormat_MIME64;
   mem: TMemoryStream;
 begin
-  if fileid < Self.GetFilesCount then
+  if fileid < GetFileCount then
   begin
     mimecoder := TStringFormat_MIME64.Create;
     mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(0, soFromBeginning);
+    mem.CopyFrom(Src, Src.Size); 
     FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
       MimeCoder.StrTo(mem.Memory, mem.Size) + '"), size=' + IntToStr(mem.Size) +
@@ -457,16 +336,19 @@
     mimecoder.Free;
   end;
-  UpdateListCache;
-end;
-
-
-
-
-procedure TOniDataADB.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-var
+end;
+
+
+
+procedure TAccess_OUP_ADB.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream);
+var
+  streampos: Integer;
   mem: TStream;
 begin
-  if fileid < Self.GetFilesCount then
-  begin
+  if fileid < GetFileCount then
+  begin
+    if not Assigned(Target) then
+      Target := TMemoryStream.Create;
+    streampos := Target.Position;
+
     FQuery.SQL.Text := 'SELECT data FROM datfiles WHERE id=' + IntToStr(fileid) + ';';
     FQuery.Open;
@@ -475,29 +357,27 @@
       mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
       mem.Seek(offset, soFromBeginning);
-      mem.Read(target^, size);
+      Target.CopyFrom(mem, size);
       mem.Free;
     end;
     FQuery.Close;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
+    Target.Seek(streampos, soFromBeginning);
+  end;
+end;
+
+
+
+procedure TAccess_OUP_ADB.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream);
 var
   MimeCoder: TStringFormat_MIME64;
   mem:  TMemoryStream;
-  Data: Tdata;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    Data := Self.LoadDatFile(fileid);
+begin
+  if fileid < GetFileCount then
+  begin
+    mem := nil;
+    LoadDatFile(fileid, TStream(mem));
+    mem.Seek(Offset, soFromBeginning);
+    mem.CopyFrom(Src, Size);
+    mem.Seek(0, soFromBeginning);
     mimecoder := TStringFormat_MIME64.Create;
-    mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(offset, soFromBeginning);
-    mem.Write(target^, size);
-    mem.Seek(0, soFromBeginning);
     FQuery.SQL.Text := 'UPDATE datfiles SET data=MimeToBin("' +
       MimeCoder.StrTo(mem.Memory, mem.Size) + '") WHERE id=' + IntToStr(fileid) + ';';
@@ -509,9 +389,7 @@
 
 
-
-
-function TOniDataADB.GetRawList(fileid: LongWord): TRawList;
-var
-  i: LongWord;
+function TAccess_OUP_ADB.GetRawList(FileID: Integer): TRawDataList;
+var
+  i: Integer;
 begin
   SetLength(Result, 0);
@@ -525,9 +403,9 @@
     i := 0;
     repeat
-      Result[i].src_id     := fileid;
-      Result[i].src_offset := FQuery.FieldByName('src_link_offset').AsInteger;
-      Result[i].raw_addr   := 0;
-      Result[i].raw_size   := FQuery.FieldByName('size').AsInteger;
-      Result[i].loc_sep    := FQuery.FieldByName('sep').AsBoolean;
+      Result[i].SrcID     := fileid;
+      Result[i].SrcOffset := FQuery.FieldByName('src_link_offset').AsInteger;
+      Result[i].RawAddr   := 0;
+      Result[i].RawSize   := FQuery.FieldByName('size').AsInteger;
+      Result[i].LocSep    := FQuery.FieldByName('sep').AsBoolean;
       Inc(i);
       FQuery.Next;
@@ -538,14 +416,40 @@
 
 
-
-
-procedure TOniDataADB.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
+function TAccess_OUP_ADB.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
+var
+  i: Integer;
+  rawlist: TRawDataList;
+begin
+  rawlist := GetRawList(FileID);
+  if Length(rawlist) > 0 then
+  begin
+    for i := 0 to High(rawlist) do
+      if rawlist[i].SrcOffset = DatOffset then
+        Break;
+    if i < Length(rawlist) then
+      Result := rawlist[i]
+    else begin
+      Result.SrcID     := -1;
+      Result.SrcOffset := -1;
+      Result.RawAddr   := -1;
+      Result.RawSize   := -1;
+    end;
+  end;
+end;
+
+
+
+procedure TAccess_OUP_ADB.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
 var
   mem: TStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
+  streampos: Integer;
+begin
+  if fileid < GetFileCount then
+  begin
+    if not Assigned(Target) then
+      Target := TMemoryStream.Create;
+    streampos := Target.Position;
     FQuery.SQL.Text := 'SELECT data FROM rawmap WHERE (src_id=' +
-      IntToStr(fileid) + ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
+      IntToStr(FileID) + ') AND (src_link_offset=' + IntToStr(DatOffset) + ');';
     FQuery.Open;
     if FQuery.RecordCount > 0 then
@@ -553,29 +457,27 @@
       mem := FQuery.CreateBlobStream(FQuery.FieldByName('data'), bmRead);
       mem.Seek(0, soFromBeginning);
-      mem.Read(target^, mem.size);
+      Target.CopyFrom(mem, mem.Size);
       mem.Free;
     end;
     FQuery.Close;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateRawFile(fileid, dat_offset: LongWord;
-  size: LongWord; target: Pointer);
+    Target.Seek(streampos, soFromBeginning);
+  end;
+end;
+
+
+procedure TAccess_OUP_ADB.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
 var
   MimeCoder: TStringFormat_MIME64;
   mem: TMemoryStream;
 begin
-  if fileid < Self.GetFilesCount then
+  if fileid < GetFileCount then
   begin
     mimecoder := TStringFormat_MIME64.Create;
     mem := TMemoryStream.Create;
-    mem.Write(target^, size);
+    mem.CopyFrom(Src, Src.Size);
     mem.Seek(0, soFromBeginning);
     FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
-      mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
-      ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
+      mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(FileID) +
+      ') AND (src_link_offset=' + IntToStr(DatOffset) + ');';
     FQuery.ExecSQL;
     mem.Free;
@@ -587,44 +489,42 @@
 
 
-procedure TOniDataADB.LoadRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  Data: Tdata;
+procedure TAccess_OUP_ADB.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
+var
   mem:  TMemoryStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    SetLength(Data, Self.GetRawInfo(fileid, dat_offset).raw_size);
-    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
-    mem := TMemoryStream.Create;
-    mem.Write(Data[offset], size);
-    mem.Read(target^, size);
+  streampos: Integer;
+begin
+  if fileid < GetFileCount then
+  begin
+    if not Assigned(Target) then
+      Target := TMemoryStream.Create;
+    streampos := Target.Position;
+    mem := nil;
+    LoadRawFile(FileID, DatOffset, TStream(mem));
+    mem.Seek(Offset, soFromBeginning);
+    Target.CopyFrom(mem, Size);
     mem.Free;
-  end;
-end;
-
-
-
-
-procedure TOniDataADB.UpdateRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
+    Target.Seek(streampos, soFromBeginning);
+  end;
+end;
+
+
+
+
+procedure TAccess_OUP_ADB.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
 var
   MimeCoder: TStringFormat_MIME64;
   mem:  TMemoryStream;
-  Data: Tdata;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    SetLength(Data, Self.GetRawInfo(fileid, offset).raw_size);
-    Self.LoadRawFile(fileid, offset, @Data[0]);
+begin
+  if fileid < GetFileCount then
+  begin
+    mem := nil;
+    LoadRawFile(fileid, offset, TStream(mem));
+    mem.Seek(offset, soFromBeginning);
+    mem.CopyFrom(Src, Size);
+    mem.Seek(0, soFromBeginning);
     mimecoder := TStringFormat_MIME64.Create;
-    mem := TMemoryStream.Create;
-    mem.Write(Data[0], Length(Data));
-    mem.Seek(offset, soFromBeginning);
-    mem.Write(target^, size);
-    mem.Seek(0, soFromBeginning);
     FQuery.SQL.Text := 'UPDATE rawmap SET data=MimeToBin("' + MimeCoder.StrTo(
       mem.Memory, mem.Size) + '") WHERE (src_id=' + IntToStr(fileid) +
-      ') AND (src_link_offset=' + IntToStr(dat_offset) + ');';
+      ') AND (src_link_offset=' + IntToStr(DatOffset) + ');';
     FQuery.ExecSQL;
     mem.Free;
@@ -633,5 +533,5 @@
 end;
 
-}
+
 
 
Index: oup/rewrite/DataAccess/Access_OniArchive.pas
===================================================================
--- oup/rewrite/DataAccess/Access_OniArchive.pas	(revision 97)
+++ oup/rewrite/DataAccess/Access_OniArchive.pas	(revision 101)
@@ -2,99 +2,53 @@
 interface
 
-uses DataAccess, Classes;
+uses DataAccess, Classes, TypeDefs;
 
 type
-{
-  THeader = packed record
-    Ident:      array[0..$13] of Byte;
-    Files:      LongWord;
-    NamedFiles: LongWord;
-    Extensions: LongWord;
-    DataAddr:   LongWord;
-    DataSize:   LongWord;
-    NamesAddr:  LongWord;
-    NamesSize:  LongWord;
-    Ident2:     array[0..$F] of Byte;
-  end;
-  TFilesMap = array of packed record
-    Extension: array[0..$3] of Char;
-    DataAddr:  LongWord;
-    NameAddr:  LongWord;
-    FileSize:  LongWord;
-    FileType:  LongWord;
-  end;
-
-  TFileInfo = packed record
-    ID:      Integer;
-    FileName: String;
-    FileNameHex: String;
-    Extension: String[4];
-    Name:    String;
-    Size:    LongWord;
-    FileType: LongWord;
-    DatAddr: LongWord;
-    opened:  Boolean;
-  end;
-  TFiles = array of TFileInfo;
-
-  TNamedFilesMap = array of packed record
-    FileNumber: LongWord;
-    blubb:      LongWord;
-  end;
-  TExtensionsMap = array of packed record
-    Ident:     array[0..$7] of Byte;
-    Extension: array[0..$3] of Char;
-    ExtCount:  LongWord;
-  end;
-}
-
   TAccess_OniArchive = class(TDataAccess)
   private
-{    Fdat_file:     TFileStream;
-    Fraw_file:     TFileStream;
-    Fsep_file:     TFileStream;
-    Fdat_header:   THeader;
-    Fdat_filesmap: TFilesMap;
-    Fdat_files:    TFiles;
-    Fdat_namedfilesmap: TNamedFilesMap;
-    Fdat_extensionsmap: TExtensionsMap;
-    FUnloadWhenUnused: Boolean;
-    FDatOpened:    Boolean;
-    FRawOpened:    Boolean;
-    FSepOpened:    Boolean;
+    Fdat_file:           TFileStream;
+    Fraw_file:           TFileStream;
+    Fsep_file:           TFileStream;
+    Fdat_files:          TFiles;
+    Fdat_extensionsmap:  TExtensionsMap;
+    FUnloadWhenUnused:   Boolean;
+    FDatOpened:          Boolean;
+    FRawOpened:          Boolean;
+    FSepOpened:          Boolean;
   protected
   public
     property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write FUnloadWhenUnused;
 
-    constructor Create(DatFilename: String; var Result: Boolean); override;
+    constructor Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
     procedure Close; override;
 
-    function GetFileInfo(fileid: Integer): TFileInfo; override;
-    function GetFilesList(ext: String; pattern: String;
-      NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
-    function GetFilesCount: LongWord; override;
-    function GetExtensionsList: TStringArray; override;
-    function GetExtendedExtensionsList: TExtensionsMap; override;
-
-    function LoadDatFile(fileid: LongWord): Tdata; override;
-    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
-    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
-
-    procedure LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord; target: Pointer);
-    function GetRawList(fileid: LongWord): TRawList; override;
-    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
-    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
-      target: Pointer); override;
-    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
-      offset, size: LongWord; target: Pointer); override;
-    function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
-      override;//Returns new Address
+    function GetFileInfo(FileID: Integer): TFileInfo; override;
+    function GetFilesList(Ext: String; Pattern: String;
+      NoEmptyFiles: Boolean; SortType: TSortType): TStrings; override;
+    function GetFileCount: Integer; override;
+    function GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings; override;
+
+    procedure LoadDatFile(FileID: Integer; var Target: TStream); overload; override;
+    procedure UpdateDatFile(FileID: Integer; Src: TStream); overload; override;
+    procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; override;
+    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; override;
+
+    function GetRawList(FileID: Integer): TRawDataList; override;
+    function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override;
+
+    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
+    procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; override;
+    procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; override;
+    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; override;
+    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; override;
+
+    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer; overload; override;
   published
-}  end;
+  end;
 
 implementation
+
+uses
+  SysUtils, StrUtils, Data, Functions, RawList;
 
 
@@ -104,6 +58,29 @@
 *)
 
-{
-constructor TOniDataDat.Create(DatFilename: String; var Result: Boolean);
+
+constructor TAccess_OniArchive.Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages);
+type
+  THeader = packed record
+    Ident:      array[0..$13] of Byte;
+    Files:      Integer;
+    NamedFiles: Integer;
+    Extensions: Integer;
+    DataAddr:   Integer;
+    DataSize:   Integer;
+    NamesAddr:  Integer;
+    NamesSize:  Integer;
+    Ident2:     array[0..$F] of Byte;
+  end;
+  TFilesMap = array of packed record
+    Extension: array[0..$3] of Char;
+    DataAddr:  Integer;
+    NameAddr:  Integer;
+    FileSize:  Integer;
+    FileType:  LongWord;
+  end;
+  TNamedFilesMap = array of packed record
+    FileNumber: Integer;
+    blubb:      Integer;
+  end;
 const
   header_ident1_pc: array[0..$13] of Byte =
@@ -119,14 +96,17 @@
     ($99, $CF, $40, $00, $90, $4F, $63, $00, $F4, $55, $5F, $00, $90, $4F, $63, $00);
 var
-  i: LongWord;
-  header_pc, header_mac: Boolean;
+  i: Integer;
+  header_pc, header_mac, header_macbeta: Boolean;
+  Fdat_header:   THeader;
+  Fdat_filesmap: TFilesMap;
+  Fdat_namedfilesmap: TNamedFilesMap;
 begin
   FUnloadWhenUnused := True;
   FDatOpened := False;
   FRawOpened := False;
+  Msg := SM_UnknownError;
   if not FileExists(DatFilename) then
   begin
-    ShowMessage('File doesn''t exist!!!');
-    Result := False;
+    Msg := SM_FileNotFound;
     Exit;
   end;
@@ -136,23 +116,28 @@
   header_pc  := True;
   header_mac := True;
+  header_macbeta := True;
   for i := 0 to High(Fdat_header.Ident) do
   begin
-    FLevelInfo.Ident[i] := Fdat_header.Ident[i];
+//    FLevelInfo.Ident[i] := Fdat_header.Ident[i];
     if Fdat_header.Ident[i] <> header_ident1_pc[i] then
       header_pc := False;
     if Fdat_header.Ident[i] <> header_ident1_mac[i] then
       header_mac := False;
-  end;
-  if not (header_pc xor header_mac) then
-  begin
-    Result := False;
+    if Fdat_header.Ident[i] <> header_ident1_macbeta[i] then
+      header_macbeta := False;
+  end;
+  if not (header_pc xor header_mac xor header_macbeta) then
+  begin
+    Msg := SM_IncompatibleFile;
     Exit;
   end
   else
   begin
-    if (header_pc and not header_mac) then
-      Fos_mac := False
-    else
-      Fos_mac := True;
+    if (header_pc and not header_mac and not header_macbeta) then
+      FDataOS := DOS_WIN
+    else if (not header_pc and header_mac and not header_macbeta) then
+      FDataOS := DOS_MAC
+    else if (not header_pc and not header_mac and header_macbeta) then
+      FDataOS := DOS_MACBETA;
   end;
   SetLength(Fdat_filesmap, Fdat_header.Files);
@@ -180,8 +165,4 @@
       Fdat_files[i].Name := '';
     end;
-    Fdat_files[i].FileName    :=
-      FormatNumber(i, 5, '0') + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
-    Fdat_files[i].FileNameHex :=
-      IntToHex(i, 4) + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
   end;
   Fdat_file.Seek($40 + Fdat_header.Files * $14, soFromBeginning);
@@ -196,23 +177,24 @@
 
   Fdat_file.Seek(Fdat_files[0].DatAddr + 7, soFromBeginning);
-  Fdat_file.Read(FLevelInfo.LevelNumber, 1);
-  FLevelInfo.LevelNumber := FLevelInfo.LevelNumber div 2;
+  Fdat_file.Read(FLevelNumber, 1);
+  FLevelNumber := FLevelNumber div 2;
 
   Fdat_file.Free;
 
-  Result   := True;
-  FBackend := ODB_Dat;
-end;
-
-
-
-
-procedure TOniDataDat.Close;
-begin
-  if not FUnloadWhenUnused and FDatOpened then
+  Msg := SM_OK;
+  FBackend := DB_ONI;
+  FChangeRights := [CR_EditDat, CR_EditRaw, CR_AppendRaw];
+end;
+
+
+
+
+procedure TAccess_OniArchive.Close;
+begin
+  if FDatOpened then
     Fdat_file.Free;
-  if not FUnloadWhenUnused and FRawOpened then
+  if FRawOpened then
     Fraw_file.Free;
-  if not FUnloadWhenUnused and FSepOpened then
+  if FSepOpened then
     Fsep_file.Free;
   Self.Free;
@@ -222,5 +204,5 @@
 
 
-function TOniDataDat.GetFileInfo(fileid: Integer): TFileInfo;
+function TAccess_OniArchive.GetFileInfo(fileid: Integer): TFileInfo;
 begin
   if fileid = -1 then
@@ -229,5 +211,5 @@
     Exit;
   end;
-  if fileid < Self.GetFilesCount then
+  if fileid < Self.GetFileCount then
     Result    := Fdat_files[fileid]
   else
@@ -238,9 +220,9 @@
 
 
-function TOniDataDat.GetFilesList(ext: String; pattern: String;
-  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
-var
-  i: LongWord;
-  list: TStringList;
+function TAccess_OniArchive.GetFilesList(ext: String; pattern: String;
+  NoEmptyFiles: Boolean; SortType: TSortType): TStrings;
+var
+  i:      Integer;
+  list:   TStringList;
   id, name, extension: String;
   fields: TStrings;
@@ -248,6 +230,6 @@
   procedure getfields;
   begin
-     fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
-    if sort in [stIDAsc, stIDDesc] then
+    fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
+    if SortType in [ST_IDAsc, ST_IDDesc] then
     begin
       id := fields.Strings[0];
@@ -255,5 +237,5 @@
       extension := fields.Strings[2];
     end;
-    if sort in [stNameAsc, stNameDesc] then
+    if SortType in [ST_NameAsc, ST_NameDesc] then
     begin
       id := fields.Strings[1];
@@ -261,5 +243,5 @@
       extension := fields.Strings[2];
     end;
-    if sort in [stExtAsc, stExtDesc] then
+    if SortType in [ST_ExtAsc, ST_ExtDesc] then
     begin
       id := fields.Strings[1];
@@ -272,5 +254,5 @@
   list := TStringList.Create;
   list.Sorted := True;
-  for i := 0 to Fdat_header.Files - 1 do
+  for i := 0 to GetFileCount - 1 do
   begin
     if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
@@ -287,21 +269,21 @@
         extension := Fdat_files[i].Extension;
 
-        case sort of
-          stIDAsc, stIDDesc:     list.Add(id + ';' + name + ';' + extension);
-          stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
-          stExtAsc, stExtDesc:   list.Add(extension + ';' + id + ';' + name);
+        case SortType of
+          ST_IDAsc, ST_IDDesc:     list.Add(id + ';' + name + ';' + extension);
+          ST_NameAsc, ST_NameDesc: list.Add(name + ';' + id + ';' + extension);
+          ST_ExtAsc, ST_ExtDesc:   list.Add(extension + ';' + id + ';' + name);
         end;
       end;
     end;
   end;
-  SetLength(Result, list.Count);
-  if Length(Result) > 0 then
+  Result := TStringList.Create;
+  if list.Count > 0 then
   begin
     fields := TStringList.Create;
-    if sort in [stIDAsc, stNameAsc, stExtAsc] then
+    if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc] then
       for i := 0 to list.Count - 1 do
       begin
         getfields;
-        Result[i] := id + '-' + name + '.' + extension;
+        Result.Add(id + '-' + name + '.' + extension);
       end
     else
@@ -309,5 +291,5 @@
       begin
         getfields;
-        Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
+        Result.Add(id + '-' + name + '.' + extension);
       end;
     fields.Free;
@@ -319,55 +301,53 @@
 
 
-function TOniDataDat.GetFilesCount: LongWord;
-begin
-  Result := Fdat_header.Files;
-end;
-
-
-
-
-function TOniDataDat.GetExtensionsList: TStringArray;
-var
-  i: LongWord;
-begin
-  SetLength(Result, Fdat_header.Extensions);
-  for i := 0 to Fdat_header.Extensions - 1 do
+function TAccess_OniArchive.GetFileCount: Integer;
+begin
+  Result := Length(Fdat_files);
+end;
+
+
+
+
+function TAccess_OniArchive.GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings;
+var
+  i: Integer;
+begin
+  Result := TStringList.Create;
+  for i := 0 to Length(Fdat_extensionsmap) - 1 do
   begin
     with Fdat_extensionsmap[i] do
     begin
-      Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
-        ' (' + IntToStr(ExtCount) + ')';
-    end;
-  end;
-end;
-
-
-
-
-function TOniDataDat.GetExtendedExtensionsList: TExtensionsMap;
-var
-  i: LongWord;
-begin
-  SetLength(Result, Fdat_header.Extensions);
-  for i := 0 to Fdat_header.Extensions - 1 do
-  begin
-    Result[i] := Fdat_extensionsmap[i];
-  end;
-end;
-
-
-
-
-function TOniDataDat.LoadDatFile(fileid: LongWord): Tdata;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
+      case ExtListFormat of
+        EF_ExtOnly:
+          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0]);
+        EF_ExtCount:
+          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0] +
+                ' (' + IntToStr(ExtCount) + ')');
+      end;
+    end;
+  end;
+end;
+
+
+
+procedure TAccess_OniArchive.LoadDatFile(FileID: Integer; var Target: TStream);
+var
+  streampos: Integer;
+begin
+  if fileid < GetFileCount then
+  begin
+    if not Assigned(Target) then
+      Target := TMemoryStream.Create;
+    if not FDatOpened then
       Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
-    SetLength(Result, Fdat_files[fileid].Size);
-    Fdat_file.Read(Result[0], Fdat_files[fileid].Size);
-    if UnloadWhenUnused then
-      Fdat_file.Free
+    streampos := Target.Position;
+    Target.CopyFrom(Fdat_file, Fdat_files[fileid].Size);
+    Target.Seek(streampos, soFromBeginning);
+    if UnloadWhenUnused then
+    begin
+      Fdat_file.Free;
+      FDatOpened := False;
+    end
     else
       FDatOpened := True;
@@ -375,17 +355,17 @@
 end;
 
-
-
-
-procedure TOniDataDat.UpdateDatFile(fileid: LongWord; Data: Tdata);
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
+procedure TAccess_OniArchive.UpdateDatFile(FileID: Integer; Src: TStream);
+begin
+  if fileid < GetFileCount then
+  begin
+    if not FDatOpened then
       Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
-    Fdat_file.Write(Data[0], Length(Data));
-    if UnloadWhenUnused then
-      Fdat_file.Free
+    Fdat_file.CopyFrom(Src, Fdat_files[fileid].Size);
+    if UnloadWhenUnused then
+    begin
+      Fdat_file.Free;
+      FDatOpened := False;
+    end
     else
       FDatOpened := True;
@@ -393,17 +373,23 @@
 end;
 
-
-
-
-procedure TOniDataDat.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
+procedure TAccess_OniArchive.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream);
+var
+  streampos: Integer;
+begin
+  if fileid < GetFileCount then
+  begin
+    if not Assigned(Target) then
+      Target := TMemoryStream.Create;
+    if not FDatOpened then
       Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
-    Fdat_file.Read(target^, size);
-    if UnloadWhenUnused then
-      Fdat_file.Free
+    streampos := Target.Position;
+    Target.CopyFrom(Fdat_file, size);
+    Target.Seek(streampos, soFromBeginning);
+    if UnloadWhenUnused then
+    begin
+      FDatOpened := False;
+      Fdat_file.Free;
+    end
     else
       FDatOpened := True;
@@ -411,17 +397,17 @@
 end;
 
-
-
-
-procedure TOniDataDat.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    if FUnloadWhenUnused or not FDatOpened then
+procedure TAccess_OniArchive.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream);
+begin
+  if fileid < GetFileCount then
+  begin
+    if not FDatOpened then
       Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
-    Fdat_file.Write(target^, size);
-    if UnloadWhenUnused then
-      Fdat_file.Free
+    Fdat_file.CopyFrom(Src, Size);
+    if UnloadWhenUnused then
+    begin
+      Fdat_file.Free;
+      FDatOpened := False;
+    end
     else
       FDatOpened := True;
@@ -431,39 +417,35 @@
 
 
-
-function TOniDataDat.GetRawList(fileid: LongWord): TRawList;
-var
-  i: LongWord;
-begin
-  SetLength(Result, 0);
-  for i := 0 to High(RawListHandlers) do
-    if UpperCase(RawListHandlers[i].Ext) = UpperCase(Fdat_files[fileid].extension) then
-      if RawListHandlers[i].needed then
-      begin
-        Result := RawListHandlers[i].Handler(Self, fileid);
-        Break;
-      end
-      else
-        Break;
-end;
-
-
-
-
-procedure TOniDataDat.LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord;
-  target: Pointer);
-begin
-  if not loc_sep then
-  begin
-    if FUnloadWhenUnused or not FRawOpened then
+function TAccess_OniArchive.GetRawList(FileID: Integer): TRawDataList;
+begin
+  Result := RawLists.GetRawList(FConnectionID, FileID);
+end;
+
+
+function TAccess_OniArchive.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
+begin
+  Result := RawLists.GetRawInfo(FConnectionID, FileID, DatOffset);
+end;
+
+
+
+
+procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
+begin
+  if not LocSep then
+  begin
+    if not FRawOpened then
       Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
         fmOpenReadWrite);
-    if raw_addr <= Fraw_file.Size then
-    begin
-      Fraw_file.Seek(raw_addr, soFromBeginning);
+    if RawAddr <= Fraw_file.Size then
+    begin
+      Fraw_file.Seek(RawAddr, soFromBeginning);
       Fraw_file.Read(target^, size);
     end;
     if UnloadWhenUnused then
-      Fraw_file.Free
+    begin
+      FRawOpened := False;
+      Fraw_file.Free;
+    end
     else
       FRawOpened := True;
@@ -471,14 +453,17 @@
   else
   begin
-    if FUnloadWhenUnused or not FSepOpened then
+    if not FSepOpened then
       Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
         fmOpenReadWrite);
-    if raw_addr <= Fsep_file.Size then
-    begin
-      Fsep_file.Seek(raw_addr, soFromBeginning);
+    if RawAddr <= Fsep_file.Size then
+    begin
+      Fsep_file.Seek(RawAddr, soFromBeginning);
       Fsep_file.Read(target^, size);
     end;
     if UnloadWhenUnused then
-      Fsep_file.Free
+    begin
+      FSepOpened := False;
+      Fsep_file.Free;
+    end
     else
       FSepOpened := True;
@@ -486,23 +471,28 @@
 end;
 
-
-
-
-procedure TOniDataDat.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    if not raw_info.loc_sep then
-    begin
-      if FUnloadWhenUnused or not FRawOpened then
+procedure TAccess_OniArchive.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
+var
+  raw_info: TRawDataInfo;
+  streampos: Integer;
+begin
+  if not Assigned(Target) then
+    Target := TMemoryStream.Create;
+  if fileid < GetFileCount then
+  begin
+    raw_info := Self.GetRawInfo(FileID, DatOffset);
+    if not raw_info.LocSep then
+    begin
+      if not FRawOpened then
         Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
           fmOpenReadWrite);
-      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fraw_file.Read(target^, raw_info.raw_size);
+      Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
+      streampos := Target.Position;
+      Target.CopyFrom(Fraw_file, raw_info.RawSize);
+      Target.Seek(streampos, soFromBeginning);
       if UnloadWhenUnused then
-        Fraw_file.Free
+      begin
+        FRawOpened := False;
+        Fraw_file.Free;
+      end
       else
         FRawOpened := True;
@@ -513,8 +503,13 @@
         Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
           fmOpenReadWrite);
-      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fsep_file.Read(target^, raw_info.raw_size);
+      Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
+      streampos := Target.Position;
+      Target.CopyFrom(Fsep_file, raw_info.RawSize);
+      Target.Seek(streampos, soFromBeginning);
       if UnloadWhenUnused then
-        Fsep_file.Free
+      begin
+        FSepOpened := False;
+        Fsep_file.Free;
+      end
       else
         FSepOpened := True;
@@ -523,24 +518,23 @@
 end;
 
-
-
-
-procedure TOniDataDat.UpdateRawFile(fileid, dat_offset: LongWord;
-  size: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    if not raw_info.loc_sep then
-    begin
-      if FUnloadWhenUnused or not FRawOpened then
+procedure TAccess_OniArchive.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
+var
+  raw_info: TRawDataInfo;
+begin
+  if fileid < GetFileCount then
+  begin
+    raw_info := GetRawInfo(FileID, DatOffset);
+    if not raw_info.LocSep then
+    begin
+      if not FRawOpened then
         Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
           fmOpenReadWrite);
-      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fraw_file.Write(target^, raw_info.raw_size);
+      Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
+      Fraw_file.CopyFrom(Src, raw_info.RawSize);
       if UnloadWhenUnused then
-        Fraw_file.Free
+      begin
+        FRawOpened := False;
+        Fraw_file.Free;
+      end
       else
         FRawOpened := True;
@@ -548,11 +542,14 @@
     else
     begin
-      if FUnloadWhenUnused or not FSepOpened then
+      if not FSepOpened then
         Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
           fmOpenReadWrite);
-      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
-      Fsep_file.Write(target^, raw_info.raw_size);
+      Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
+      Fsep_file.CopyFrom(Src, raw_info.RawSize);
       if UnloadWhenUnused then
-        Fsep_file.Free
+      begin
+        FSepOpened := False;
+        Fsep_file.Free;
+      end
       else
         FSepOpened := True;
@@ -561,46 +558,41 @@
 end;
 
-
-
-
-procedure TOniDataDat.LoadRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-  Data:     Tdata;
-  mem:      TMemoryStream;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    SetLength(Data, raw_info.raw_size);
-    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
-    mem := TMemoryStream.Create;
-    mem.Write(Data[offset], size);
-    mem.Read(target^, size);
-    mem.Free;
-  end;
-end;
-
-
-
-
-procedure TOniDataDat.UpdateRawFilePart(fileid, dat_offset: LongWord;
-  offset, size: LongWord; target: Pointer);
-var
-  raw_info: TRawInfo;
-begin
-  if fileid < Self.GetFilesCount then
-  begin
-    raw_info := Self.GetRawInfo(fileid, dat_offset);
-    if not raw_info.loc_sep then
-    begin
-      if FUnloadWhenUnused or not FRawOpened then
+procedure TAccess_OniArchive.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
+var
+  Data: TStream;
+  streampos: Integer;
+begin
+  if not Assigned(Target) then
+    Target := TMemoryStream.Create;
+  if fileid < Self.GetFileCount then
+  begin
+    data := nil;
+    LoadRawFile(FileID, DatOffset, Data);
+    Data.Seek(Offset, soFromBeginning);
+    streampos := Target.Position;
+    Target.CopyFrom(Data, Size);
+    Target.Seek(streampos, soFromBeginning);
+  end;
+end;
+
+procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
+var
+  raw_info: TRawDataInfo;
+begin
+  if fileid < GetFileCount then
+  begin
+    raw_info := GetRawInfo(FileID, DatOffset);
+    if not raw_info.LocSep then
+    begin
+      if not FRawOpened then
         Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
           fmOpenReadWrite);
-      Fraw_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
-      Fraw_file.Write(target^, raw_info.raw_size);
+      Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
+      Fraw_file.CopyFrom(Src, Size);
       if UnloadWhenUnused then
-        Fraw_file.Free
+      begin
+        FRawOpened := False;
+        Fraw_file.Free;
+      end
       else
         FRawOpened := True;
@@ -608,11 +600,14 @@
     else
     begin
-      if FUnloadWhenUnused or not FSepOpened then
+      if not FSepOpened then
         Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
           fmOpenReadWrite);
-      Fsep_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
-      Fsep_file.Write(target^, raw_info.raw_size);
+      Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
+      Fsep_file.CopyFrom(Src, Size);
       if UnloadWhenUnused then
-        Fsep_file.Free
+      begin
+        FSepOpened := False;
+        Fsep_file.Free;
+      end
       else
         FSepOpened := True;
@@ -621,20 +616,19 @@
 end;
 
-
-
-
-function TOniDataDat.AppendRawFile(loc_sep: Boolean; size: LongWord;
-  target: Pointer): LongWord; //Returns new Address
-begin
-  if not loc_sep then
-  begin
-    if FUnloadWhenUnused or not FRawOpened then
+function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer;
+begin
+  if not LocSep then
+  begin
+    if not FRawOpened then
       Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
         fmOpenReadWrite);
     Result := Fraw_file.Size;
     Fraw_file.Seek(0, soFromEnd);
-    Fraw_file.Write(target^, size);
-    if UnloadWhenUnused then
-      Fraw_file.Free
+    Fraw_file.CopyFrom(Src, Size);
+    if UnloadWhenUnused then
+    begin
+      FRawOpened := False;
+      Fraw_file.Free;
+    end
     else
       FRawOpened := True;
@@ -642,12 +636,15 @@
   else
   begin
-    if FUnloadWhenUnused or not FSepOpened then
+    if not FSepOpened then
       Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
         fmOpenReadWrite);
     Result := Fsep_file.Size;
     Fsep_file.Seek(0, soFromEnd);
-    Fsep_file.Write(target^, size);
-    if UnloadWhenUnused then
-      Fsep_file.Free
+    Fsep_file.CopyFrom(Src, Size);
+    if UnloadWhenUnused then
+    begin
+      FSepOpened := False;
+      Fsep_file.Free;
+    end
     else
       FSepOpened := True;
@@ -655,9 +652,3 @@
 end;
 
-
-}
-
-
-
-
 end.
Index: oup/rewrite/DataAccess/ConnectionManager.pas
===================================================================
--- oup/rewrite/DataAccess/ConnectionManager.pas	(revision 97)
+++ oup/rewrite/DataAccess/ConnectionManager.pas	(revision 101)
@@ -150,7 +150,7 @@
   ext := UpperCase(ExtractFileExt(FileName));
 
-  if ext = 'ODB' then
+  if ext = '.OLDB' then
     backend := DB_ADB
-  else if ext = 'DAT' then
+  else if ext = '.DAT' then
     backend := DB_ONI
   else
@@ -173,4 +173,5 @@
     FLastID := FConnections[i].ConnectionID;
     Result := FLastID;
+    Msg := SM_OK;
   end
   else
@@ -180,5 +181,5 @@
     FConnections[i] := nil;
     SetLength(FConnections, Length(FConnections) - 1);
-    Msg := SM_UnknownError;
+    Msg := CreateMsg;
   end;
 end;
Index: oup/rewrite/DataAccess/DataAccess.pas
===================================================================
--- oup/rewrite/DataAccess/DataAccess.pas	(revision 97)
+++ oup/rewrite/DataAccess/DataAccess.pas	(revision 101)
@@ -3,11 +3,9 @@
 
 uses TypeDefs, Classes, StrUtils, SysUtils;
-//uses Data, Classes, SysUtils, StrUtils,
-//  Dialogs, ABSDecUtil, ABSMain, DB, Windows;
-
 
 type
   TDataAccess = class
   private
+  protected
     FConnectionID:  Integer;
     FFileName:      String;
@@ -17,5 +15,4 @@
     FChangeRights:  TChangeRights;
     procedure SetDataOS(DataOS: TDataOS);
-  protected
   public
     property ConnectionID: Integer      read FConnectionID;
@@ -24,4 +21,5 @@
     property DataOS:       TDataOS      read FDataOS write SetDataOS;
     property LevelNumber:  Integer      read FLevelNumber;
+    property ChangeRights: TChangeRights read FChangeRights;
 
     constructor Create(FileName: String; ConnectionID: Integer; var Msg: TStatusMessages); virtual; abstract;
@@ -37,31 +35,31 @@
 
     procedure LoadDatFile(FileID: Integer; var Target: TStream); overload; virtual; abstract;
-    procedure LoadDatFile(FileID: Integer; var Target: TByteData); overload; virtual; abstract;
+    procedure LoadDatFile(FileID: Integer; var Target: TByteData); overload;
     procedure UpdateDatFile(FileID: Integer; Src: TStream); overload; virtual; abstract;
-    procedure UpdateDatFile(FileID: Integer; Src: TByteData); overload; virtual; abstract;
+    procedure UpdateDatFile(FileID: Integer; Src: TByteData); overload;
     procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; virtual; abstract;
-    procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TByteData); overload; virtual; abstract;
-    procedure LoadDatFilePart(FileID, Offset, Size: Integer; Target: Pointer); overload; virtual; abstract;
+    procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TByteData); overload;
+    procedure LoadDatFilePart(FileID, Offset, Size: Integer; Target: Pointer); overload;
     procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; virtual; abstract;
-    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TByteData); overload; virtual; abstract;
-    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: Pointer); overload; virtual; abstract;
+    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TByteData); overload;
+    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: Pointer); overload;
 
     function GetRawList(FileID: Integer): TRawDataList; virtual; abstract;
-    function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
+    function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; virtual; abstract;
 
     procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; virtual; abstract;
-    procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TByteData); overload; virtual; abstract;
-    procedure UpdateRawFile(FileID, DatOffset, Size: Integer; Src: TStream); overload; virtual; abstract;
-    procedure UpdateRawFile(FileID, DatOffset, Size: Integer; Src: TByteData); overload; virtual; abstract;
+    procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TByteData); overload;
+    procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; virtual; abstract;
+    procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TByteData); overload;
     procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; virtual; abstract;
-    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TByteData); overload; virtual; abstract;
-    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; Target: Pointer); overload; virtual; abstract;
+    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TByteData); overload;
+    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; Target: Pointer); overload;
     procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; virtual; abstract;
-    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TByteData); overload; virtual; abstract;
-    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: Pointer); overload; virtual; abstract;
-
-    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer; overload; virtual; abstract;
-    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: TByteData): Integer; overload; virtual; abstract;
-    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: Pointer): Integer; overload; virtual; abstract;
+    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TByteData); overload;
+    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: Pointer); overload;
+
+    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer; overload; virtual;
+    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: TByteData): Integer; overload;
+    function AppendRawFile(LocSep: Boolean; Size: Integer; Src: Pointer): Integer; overload;
   published
   end;
@@ -120,30 +118,201 @@
 
 
-function TDataAccess.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
-var
-  i: LongWord;
-  RawList: TRawDataList;
-begin
-  RawList          := GetRawList(FileID);
-  Result.SrcID     := -1;
-  Result.SrcOffset := -1;
-  Result.RawAddr   := -1;
-  Result.RawSize   := -1;
-  if Length(RawList) > 0 then
-  begin
-    for i := 0 to High(RawList) do
-    begin
-      if RawList[i].SrcOffset = DatOffset then
-      begin
-        Result.SrcID     := FileID;
-        Result.SrcOffset := RawList[i].SrcOffset;
-        Result.RawAddr   := RawList[i].RawAddr;
-        Result.RawSize   := RawList[i].RawSize;
-        Result.LocSep    := RawList[i].LocSep;
-        Break;
-      end;
-    end;
-  end;
-end;
+procedure TDataAccess.LoadDatFile(FileID: Integer; var Target: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := nil;
+    LoadDatFile(FileID, data);
+    SetLength(Target, data.Size);
+    data.Read(Target[0], data.Size);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.UpdateDatFile(FileID: Integer; Src: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := TMemoryStream.Create;
+    data.Write(Src[0], Length(Src));
+    data.Seek(0, soFromBeginning);
+    UpdateDatFile(FileID, data);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := nil;
+    LoadDatFilePart(FileID, offset, size, data);
+    SetLength(Target, data.Size);
+    data.Read(Target[0], data.Size);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.LoadDatFilePart(FileID, Offset, Size: Integer; Target: Pointer);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := nil;
+    LoadDatFilePart(FileID, offset, size, data);
+    data.Read(Target^, data.Size);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := TMemoryStream.Create;
+    data.Write(Src[0], Size);
+    data.Seek(0, soFromBeginning);
+    UpdateDatFilePart(FileID, offset, size, data);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: Pointer);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := TMemoryStream.Create;
+    data.Write(Src^, Size);
+    data.Seek(0, soFromBeginning);
+    UpdateDatFilePart(FileID, offset, size, data);
+    data.Free;
+  end;
+end;
+
+
+
+procedure TDataAccess.LoadRawFile(FileID, DatOffset: Integer; var Target: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := nil;
+    LoadRawFile(FileID, DatOffset, data);
+    SetLength(Target, data.Size);
+    data.Read(Target[0], data.Size);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.UpdateRawFile(FileID, DatOffset: Integer; Src: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := TMemoryStream.Create;
+    data.Write(Src[0], Length(Src));
+    data.Seek(0, soFromBeginning);
+    UpdateRawFile(FileID, DatOffset, data);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := nil;
+    SetLength(Target, Size);
+    LoadRawFile(FileID, DatOffset, Data);
+    Data.Seek(Offset, soFromBeginning);
+    Data.Read(Target[0], Size);
+    Data.Free;
+  end;
+end;
+
+procedure TDataAccess.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; Target: Pointer);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := nil;
+    LoadRawFile(FileID, DatOffset, Data);
+    Data.Seek(Offset, soFromBeginning);
+    Data.Read(Target^, Size);
+    Data.Free;
+  end;
+end;
+
+procedure TDataAccess.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TByteData);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := TMemoryStream.Create;
+    data.Write(Src[0], Size);
+    data.Seek(0, soFromBeginning);
+    UpdateRawFilePart(FileID, DatOffset, Offset, Size, data);
+    data.Free;
+  end;
+end;
+
+procedure TDataAccess.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: Pointer);
+var
+  data: TStream;
+begin
+  if fileid < GetFileCount then
+  begin
+    data := TMemoryStream.Create;
+    data.Write(Src^, Size);
+    data.Seek(0, soFromBeginning);
+    UpdateRawFilePart(FileID, DatOffset, Offset, Size, data);
+    data.Free;
+  end;
+end;
+
+
+function TDataAccess.AppendRawFile(LocSep: Boolean; Size: Integer; Src: TStream): Integer;
+begin
+  raise ENotImplemented.Create('ERROR: AppendRawFile not implemented here!!!');
+end;
+
+
+function TDataAccess.AppendRawFile(LocSep: Boolean; Size: Integer; Src: TByteData): Integer;
+var
+  data: TStream;
+begin
+  data := TMemoryStream.Create;
+  data.Write(Src[0], Size);
+  AppendRawFile(LocSep, Size, data);
+  data.Free;
+end;
+
+function TDataAccess.AppendRawFile(LocSep: Boolean; Size: Integer; Src: Pointer): Integer;
+var
+  data: TStream;
+begin
+  data := TMemoryStream.Create;
+  data.Write(Src^, Size);
+  AppendRawFile(LocSep, Size, data);
+  data.Free;
+end;
+
 
 
Index: oup/rewrite/Global/OniImgClass.pas
===================================================================
--- oup/rewrite/Global/OniImgClass.pas	(revision 97)
+++ oup/rewrite/Global/OniImgClass.pas	(revision 101)
@@ -700,7 +700,10 @@
 var
   data: TByteData;
+  streampos: Integer;
 begin
   GetAsBMP(data);
+  streampos := Target.Position;
   Target.Write(data[0], Length(data));
+  Target.Seek(streampos, soFromBeginning);
 end;
 
Index: oup/rewrite/Global/RawList.pas
===================================================================
--- oup/rewrite/Global/RawList.pas	(revision 97)
+++ oup/rewrite/Global/RawList.pas	(revision 101)
@@ -3,13 +3,14 @@
 interface
 
-uses TypeDefs, ConnectionManager;
+uses TypeDefs;
 
 type
   THandler = function(ConnectionID, FileID: Integer): TRawDataList;
-  TRawListHandlers = record
+  TRawListHandler = record
     Ext:     String[4];
     needed:  Boolean;
     Handler: THandler;
   end;
+  TRawListHandlers = array of TRawListHandler;
 
   TRawLists = class
@@ -25,10 +26,10 @@
 var
   RawLists: TRawLists;
-  
+
 
 implementation
 
 uses
-  Template;
+  Template, ConnectionManager, Access_OniArchive, Classes, SysUtils;
 
 
@@ -39,17 +40,14 @@
   i:     Integer;
 begin
-  if not connection.OSisMac then
-  begin
-    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links);
-    links := links * 2;
-    SetLength(Result, links);
-    for i := 0 to links - 1 do
-    begin
-      Result[i].src_offset := $20 + i * 4;
-      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * 4, 4, @link);
-      Result[i].raw_addr := link;
-      Result[i].raw_size := 32;
-      Result[i].loc_sep  := False;
-    end;
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links);
+  links := links * 2;
+  SetLength(Result, links);
+  for i := 0 to links - 1 do
+  begin
+    Result[i].SrcOffset := $20 + i * 4;
+    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * 4, 4, @link);
+    Result[i].RawAddr := link;
+    Result[i].RawSize := 32;
+    Result[i].LocSep  := False;
   end;
 end;
@@ -64,17 +62,14 @@
   i:     Integer;
 begin
-  if not connection.OSisMac then
-  begin
-    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links);
-    SetLength(Result, links);
-    for i := 0 to links - 1 do
-    begin
-      Result[i].src_offset := $20 + i * $74 + $24;
-      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * $74 + $24, 4, @link);
-      Result[i].raw_addr := link;
-      ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * $74 + $28, 4, @link);
-      Result[i].raw_size := link;
-      Result[i].loc_sep  := False;
-    end;
+  ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @links);
+  SetLength(Result, links);
+  for i := 0 to links - 1 do
+  begin
+    Result[i].SrcOffset := $20 + i * $74 + $24;
+    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * $74 + $24, 4, @link);
+    Result[i].RawAddr := link;
+    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + i * $74 + $28, 4, @link);
+    Result[i].RawSize := link;
+    Result[i].LocSep  := False;
   end;
 end;
@@ -91,8 +86,8 @@
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $08, 4, @datasize);
   SetLength(Result, 1);
-  Result[0].src_offset := $0C;
-  Result[0].raw_addr   := link;
-  Result[0].raw_size   := datasize;
-  Result[0].loc_sep    := connection.OSisMac;
+  Result[0].SrcOffset := $0C;
+  Result[0].RawAddr   := link;
+  Result[0].RawSize   := datasize;
+  Result[0].LocSep    := not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN);
 end;
 
@@ -108,8 +103,8 @@
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $0C, 4, @link);
   SetLength(Result, 1);
-  Result[0].src_offset := $0C;
-  Result[0].raw_addr   := link;
-  Result[0].raw_size   := datasize;
-  Result[0].loc_sep    := connection.OSisMac;
+  Result[0].SrcOffset := $0C;
+  Result[0].RawAddr   := link;
+  Result[0].RawSize   := datasize;
+  Result[0].LocSep     := not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN);
 end;
 
@@ -123,19 +118,19 @@
 begin
   SetLength(Result, 1);
-  if not connection.OSisMac then
+  if ConManager.Connection[ConnectionID].DataOS = DOS_MAC then
+  begin
+    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, 4, @datasize);
+    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $14, 4, @link);
+    Result[0].SrcOffset := $14;
+  end
+  else
   begin
     ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $40, 4, @datasize);
     ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $44, 4, @link);
-    Result[0].src_offset := $44;
-  end
-  else
-  begin
-    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, 4, @datasize);
-    ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $14, 4, @link);
-    Result[0].src_offset := $14;
-  end;
-  Result[0].raw_addr := link;
-  Result[0].raw_size := datasize;
-  Result[0].loc_sep  := False;
+    Result[0].SrcOffset := $44;
+  end;
+  Result[0].RawAddr := link;
+  Result[0].RawSize := datasize;
+  Result[0].LocSep  := False;
 end;
 
@@ -148,5 +143,6 @@
   links: Integer;
   j, k:  Integer;
-  Data:  TByteData;
+//  Data:  TByteData;
+  Data:  TStream;
 begin
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, 4, @baselink);
@@ -155,8 +151,13 @@
   begin
     ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20 + (links - 1) * 4, 4, @lastlink);
-    SetLength(Data, lastlink + 1024);
-    TOniDataDat(connection).LoadRawOffset(False,
-      baselink, lastlink + 1024, Data);
+//    SetLength(Data, lastlink + 1024);
+    Data := nil;
+    TAccess_OniArchive(ConManager.Connection[ConnectionID]).LoadRawOffset(
+          False, baselink, lastlink + 1024, Data);
+//    TOniDataDat(connection).LoadRawOffset(False, baselink, lastlink + 1024, Data);
     //      connection.LoadRawFile(fileid,$1C,baselink,lastlink+1024,False,@data[0]);
+    raise ENotImplemented.Create('RawList.SUBT');
+  end;
+{
     k := 0;
     for j := 0 to 1024 do
@@ -182,4 +183,5 @@
     end;
   end;
+}
 end;
 
@@ -203,73 +205,73 @@
   {y-pos}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $0C, 4, @link);
-  Result[0].src_offset := $0C;
-  Result[0].raw_addr   := link;
-  Result[0].raw_size   := frames * 4;
+  Result[0].SrcOffset := $0C;
+  Result[0].RawAddr   := link;
+  Result[0].RawSize   := frames * 4;
   {x-z-pos}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $10, 4, @link);
-  Result[1].src_offset := $10;
-  Result[1].raw_addr   := link;
-  Result[1].raw_size   := frames * 8;
+  Result[1].SrcOffset := $10;
+  Result[1].RawAddr   := link;
+  Result[1].RawSize   := frames * 8;
   {attacks}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $182, 1, @tempb);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $14, 4, @link);
-  Result[2].src_offset := $14;
-  Result[2].raw_addr   := link;
-  Result[2].raw_size   := tempb * 32;
+  Result[2].SrcOffset := $14;
+  Result[2].RawAddr   := link;
+  Result[2].RawSize   := tempb * 32;
   {damage}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $183, 1, @tempb);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $18, 4, @link);
-  Result[3].src_offset := $18;
-  Result[3].raw_addr   := link;
-  Result[3].raw_size   := tempb * 8;
+  Result[3].SrcOffset := $18;
+  Result[3].RawAddr   := link;
+  Result[3].RawSize   := tempb * 8;
   {motionblur}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $184, 1, @tempb);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $1C, 4, @link);
-  Result[4].src_offset := $1C;
-  Result[4].raw_addr   := link;
-  Result[4].raw_size   := tempb * 8;
+  Result[4].SrcOffset := $1C;
+  Result[4].RawAddr   := link;
+  Result[4].RawSize   := tempb * 8;
   {shortcut}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $185, 1, @tempb);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $20, 4, @link);
-  Result[5].src_offset := $20;
-  Result[5].raw_addr   := link;
-  Result[5].raw_size   := tempb * 8;
+  Result[5].SrcOffset := $20;
+  Result[5].RawAddr   := link;
+  Result[5].RawSize   := tempb * 8;
   {throw}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $24, 4, @link);
-  Result[6].src_offset := $24;
-  Result[6].raw_addr   := link;
+  Result[6].SrcOffset := $24;
+  Result[6].RawAddr   := link;
   if link > 0 then
-    Result[6].raw_size := 24
+    Result[6].RawSize := 24
   else
-    Result[6].raw_size := 0;
+    Result[6].RawSize := 0;
   {footstep}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $186, 1, @tempb);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $28, 4, @link);
-  Result[7].src_offset := $28;
-  Result[7].raw_addr   := link;
-  Result[7].raw_size   := tempb * 4;
+  Result[7].SrcOffset := $28;
+  Result[7].RawAddr   := link;
+  Result[7].RawSize   := tempb * 4;
   {particle}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $187, 1, @tempb);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $2C, 4, @link);
-  Result[8].src_offset := $2C;
-  Result[8].raw_addr   := link;
-  Result[8].raw_size   := tempb * 24;
+  Result[8].SrcOffset := $2C;
+  Result[8].RawAddr   := link;
+  Result[8].RawSize   := tempb * 24;
   {position}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $30, 4, @link);
-  Result[9].src_offset := $30;
-  Result[9].raw_addr   := link;
-  Result[9].raw_size   := frames * 8;
+  Result[9].SrcOffset := $30;
+  Result[9].RawAddr   := link;
+  Result[9].RawSize   := frames * 8;
   {particle}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $154, 2, @tempw);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $38, 4, @link);
-  Result[11].src_offset := $38;
-  Result[11].raw_addr   := link;
-  Result[11].raw_size   := tempw * 34;
+  Result[11].SrcOffset := $38;
+  Result[11].RawAddr   := link;
+  Result[11].RawSize   := tempw * 34;
   {extent}
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $138, 4, @templ);
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $13C, 4, @link);
-  Result[12].src_offset := $13C;
-  Result[12].raw_addr   := link;
-  Result[12].raw_size   := templ * 12;
+  Result[12].SrcOffset := $13C;
+  Result[12].RawAddr   := link;
+  Result[12].RawSize   := templ * 12;
 
   ConManager.Connection[ConnectionID].LoadDatFilePart(fileid, $34, 4, @link);
@@ -280,5 +282,6 @@
     i := 0;
     SetLength(Data, $FFFF);
-    TOniDataDat(connection).LoadRawOffset(False, link, $FFFF, Data);
+    TAccess_OniArchive(ConManager.Connection[ConnectionID]).LoadRawOffset(
+          False, link, $FFFF, Data);
     offset := Data[$24] + Data[$25] * 256;
     while (offset + i < Length(Data)) and (frame_count < frames - 1) do
@@ -291,13 +294,13 @@
     begin
       Inc(i, tempw);
-      Result[10].raw_size := offset + i;
+      Result[10].RawSize := offset + i;
     end
     else
     begin
-      Result[10].raw_size := 0;
+      Result[10].RawSize := 0;
     end;
   end;
-  Result[10].src_offset := $34;
-  Result[10].raw_addr   := link;
+  Result[10].SrcOffset := $34;
+  Result[10].RawAddr   := link;
 end;
 
@@ -327,16 +330,16 @@
   end;
   SetLength(Result, 1);
-  if not connection.OSisMac then
-  begin
-    Result[0].src_offset := $9C;
-    Result[0].raw_addr   := link_pc;
+  if ConManager.Connection[ConnectionID].DataOS = DOS_WIN then
+  begin
+    Result[0].SrcOffset := $9C;
+    Result[0].RawAddr   := link_pc;
   end
   else
   begin
-    Result[0].src_offset := $A0;
-    Result[0].raw_addr   := link_mac;
-  end;
-  Result[0].raw_size := datasize;
-  Result[0].loc_sep  := connection.OSisMac;
+    Result[0].SrcOffset := $A0;
+    Result[0].RawAddr   := link_mac;
+  end;
+  Result[0].RawSize := datasize;
+  Result[0].LocSep  := not (ConManager.Connection[ConnectionID].DataOS = DOS_WIN);
 end;
 
Index: oup/rewrite/Global/TypeDefs.pas
===================================================================
--- oup/rewrite/Global/TypeDefs.pas	(revision 97)
+++ oup/rewrite/Global/TypeDefs.pas	(revision 101)
@@ -9,7 +9,7 @@
 
   TDataBackend = (DB_ONI, DB_ADB);
-  TDataOS = (DOS_WIN, DOS_MAC);
+  TDataOS = (DOS_WIN, DOS_WINDEMO, DOS_MAC, DOS_MACBETA);
 
-  TChangeRights = set of (CR_EditDat, CR_EditRaw, CR_ResizeDat, CR_ResizeRaw);
+  TChangeRights = set of (CR_EditDat, CR_EditRaw, CR_ResizeDat, CR_ResizeRaw, CR_AppendRaw);
 
   TStatusMessages = (
@@ -19,6 +19,13 @@
       SM_UnknownExtension,
       SM_IncompatibleFile,
+      SM_IncompatibleDBVersion,
       SM_UnknownError
   ); 
+
+  TExtensionsMap = array of packed record
+      Ident:       array[0..$7] of Byte;
+      Extension:   array[0..$3] of Char;
+      ExtCount:    LongWord;
+  end;
 
   TFileInfo = packed record
@@ -30,4 +37,5 @@
       DatAddr:     Integer;
   end;
+  TFiles = array of TFileInfo;
 
   TRawDataInfo = record
Index: oup/rewrite/Helper/Helper_ValueEdit.pas
===================================================================
--- oup/rewrite/Helper/Helper_ValueEdit.pas	(revision 97)
+++ oup/rewrite/Helper/Helper_ValueEdit.pas	(revision 101)
@@ -35,5 +35,5 @@
 implementation
 
-uses BinEdit, RawEdit, DataStructures, Main;
+uses BinEdit, RawEdit, DatStructureLoader, Main;
 
 {$R *.dfm}
Index: oup/rewrite/OniUnPacker.dpr
===================================================================
--- oup/rewrite/OniUnPacker.dpr	(revision 97)
+++ oup/rewrite/OniUnPacker.dpr	(revision 101)
@@ -15,12 +15,7 @@
   Settings in 'Settings.pas' {Form_Settings},
   Template in 'Tools\Template.pas' {Form_ToolTemplate},
-  TxmpReplace in 'Tools\TxmpReplace.pas' {Form_TxmpReplace},
-  BinEdit in 'Tools\BinEdit.pas' {Form_BinEdit},
-  Extractor in 'Tools\Extractor.pas' {Form_Extractor},
   Preview in 'Tools\Preview.pas' {Form_Preview},
-  RawEdit in 'Tools\RawEdit.pas' {Form_RawEdit},
   OniImgClass in 'Global\OniImgClass.pas',
   Functions in 'Global\Functions.pas',
-  Helper_ValueEdit in 'Helper\Helper_ValueEdit.pas' {Form_ValueEdit},
   RawList in 'Global\RawList.pas',
   DatStructureLoader in 'Global\DatStructureLoader.pas',
@@ -35,5 +30,4 @@
   Application.CreateForm(TForm_Main, Form_Main);
   Application.CreateForm(TForm_Settings, Form_Settings);
-  Application.CreateForm(TForm_ValueEdit, Form_ValueEdit);
   Application.Run;
 end.
Index: oup/rewrite/Tools/Preview.dfm
===================================================================
--- oup/rewrite/Tools/Preview.dfm	(revision 97)
+++ oup/rewrite/Tools/Preview.dfm	(revision 101)
@@ -1,4 +1,7 @@
 inherited Form_Preview: TForm_Preview
   Caption = 'Preview'
+  OnCreate = FormCreate
+  ExplicitWidth = 500
+  ExplicitHeight = 450
   PixelsPerInch = 96
   TextHeight = 13
Index: oup/rewrite/Tools/Preview.pas
===================================================================
--- oup/rewrite/Tools/Preview.pas	(revision 97)
+++ oup/rewrite/Tools/Preview.pas	(revision 101)
@@ -84,17 +84,12 @@
 procedure TForm_Preview.LoadImage(fileid, index: Integer);
 var
-  Data:      TByteData;
   memstream: TMemoryStream;
   OniImage:  TOniImage;
-
 begin
   OniImage := TOniImage.Create;
   OniImage.Load(ConnectionID, fileid);
-  OniImage.GetAsBMP(Data);
+  memstream := TMemoryStream.Create;
+  OniImage.GetAsBMP(TStream(memstream));
   OniImage.Free;
-
-  memstream := TMemoryStream.Create;
-  memstream.Write(Data[0], Length(Data));
-  memstream.Seek(0, soFromBeginning);
   bitmaps[index].LoadFromStream(memstream);
   memstream.Free;
Index: oup/rewrite/Tools/Template.dfm
===================================================================
--- oup/rewrite/Tools/Template.dfm	(revision 97)
+++ oup/rewrite/Tools/Template.dfm	(revision 101)
@@ -19,5 +19,4 @@
   OnActivate = FormActivate
   OnClose = FormClose
-  OnResize = FormResize
   PixelsPerInch = 96
   TextHeight = 13
@@ -247,5 +246,5 @@
         Font.Color = clWindowText
         Font.Height = -11
-        Font.Name = 'Tahoma'
+        Font.Name = 'Courier'
         Font.Style = []
         ItemHeight = 13
Index: oup/rewrite/Tools/Template.pas
===================================================================
--- oup/rewrite/Tools/Template.pas	(revision 97)
+++ oup/rewrite/Tools/Template.pas	(revision 101)
@@ -54,5 +54,4 @@
       Shift: TShiftState; X, Y: Integer);
 
-    procedure FormResize(Sender: TObject);
     procedure FormClose(Sender: TObject; var Action: TCloseAction);
     procedure popup_importClick(Sender: TObject);
@@ -220,22 +219,40 @@
   fs: TFileStream;
 begin
-  id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
-  finfo := ConManager.Connection[FConnectionID].GetFileInfo(id);
-
-  importd.Filter := 'Files of matching extension (*.' + finfo.Extension + ')|*.' +
-        finfo.Extension + '|All files|*.*';
-  if importd.Execute then
-  begin
-    fs := TFileStream.Create(importd.FileName, fmOpenRead);
-    if fs.Size <> finfo.Size then
-      ShowMessage('Can''t import ' + ExtractFilename(importd.FileName) +
-        ', file has to have same size as file in .dat.' + CrLf +
-        'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
-        'Size of chosen file: ' + FormatFileSize(fs.Size))
-    else begin
+  if CR_EditDat in ConManager.Connection[FConnectionID].ChangeRights then
+  begin
+    id := ConManager.Connection[FConnectionID].ExtractFileIDOfName(filelist.Items.Strings[filelist.ItemIndex]);
+    finfo := ConManager.Connection[FConnectionID].GetFileInfo(id);
+
+    importd.Filter := 'Files of matching extension (*.' + finfo.Extension + ')|*.' +
+          finfo.Extension + '|All files|*.*';
+    if importd.Execute then
+    begin
+      fs := TFileStream.Create(importd.FileName, fmOpenRead);
+      if fs.Size <> finfo.Size then
+      begin
+        if not (CR_ResizeDat in ConManager.Connection[FConnectionID].ChangeRights) then
+        begin
+          ShowMessage('Can''t import ' + ExtractFilename(importd.FileName) +
+            ', file has to have same size as file in .dat with this backend.' + CrLf +
+            'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
+            'Size of chosen file: ' + FormatFileSize(fs.Size));
+          Exit;
+        end else begin
+          if MessageBox(Self.Handle,
+              PChar('File has different size from the file in the .dat.' + CrLf +
+                    'Size of file in .dat: ' + FormatFileSize(finfo.Size) + CrLf +
+                    'Size of chosen file: ' + FormatFileSize(fs.Size) + CrLf +
+                    'Replace anyway?'), PChar('Different size'), MB_YESNO + MB_ICONWARNING) = ID_NO then
+          begin
+            Exit;
+          end;
+        end;
+      end;
       ConManager.Connection[FConnectionID].UpdateDatFile(id, fs);
       Self.listClick(Self);
+      fs.Free;
     end;
-    fs.Free;
+  end else begin
+    ShowMessage('Editing .dat-contents not allowed with this backend.');
   end;
 end;
@@ -449,14 +466,4 @@
 
 
-procedure TForm_ToolTemplate.FormResize(Sender: TObject);
-begin
-  if Self.Width < 300 then
-    Self.Width := 300;
-  if Self.Height < 200 then
-    Self.Height := 200;
-end;
-
-
-
 function TForm_ToolTemplate.GetToolCloseable: Boolean;
 begin
