Recent

Author Topic: Rewrite(xxx) causes "Access denied"  (Read 17520 times)

RuudBaltissen

  • New Member
  • *
  • Posts: 14
    • Ruud's Homepage
Rewrite(xxx) causes "Access denied"
« on: June 13, 2017, 10:57:06 am »
Hallo,

I wrote a small program in FreePascal and decided to convert it into a GUI. The resulting program checks in FormCreate if a needed binary file exists. If not, the program creates one with some standard values using rewrite. Then the values are read from the file into an array. When closing the program (FormDestroy), whether the values in this array have been changed or not, the array is written back to the disk again using rewrite again.

And now the weird thing:
In DEBUG mode: If no files are present, the program runs fine. When stopping the program immediately after starting it: "Access denied" error.
When executing the EXE: no error.

Then I decided to update the file after every change. In both cases I get this "Access denied" error when the updated array is written to disk.

You can be assured that I closed the file after every operation. I also tried with setting FileMode to fOpenReadWrite (IIRC).
 
What could be going on and, more probably, what could I be doing wrong?

Thank you for any input!

Kind regards, Ruud Baltissen
 



Thaddy

  • Hero Member
  • *****
  • Posts: 19283
  • Glad to be alive.
Re: Rewrite(xxx) causes "Access denied"
« Reply #1 on: June 13, 2017, 11:00:57 am »
Code: Pascal  [Select][+][-]
  1. fmOpenReadWrite or fmShareDenyNone
Otherwise...

Unless you are under a modern (7+) windows and try to write to the install root disk of the OS (C:\   mostly ). That will only work with admin rights.
objects are fine constructs. You can even initialize them with constructors.

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: Rewrite(xxx) causes "Access denied"
« Reply #2 on: June 13, 2017, 11:04:48 am »
It's better to see the actual code then (not all the program, but the read-write related procedures).
Try using not "FormDestroy" (which shouldn't but might cause problems) but "FormClose" (which actually happens before the destruction process started). However, this shouldn't be the case.
When you execute EXE - you won't get an error, because it is "hidden" by program termination.
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

rvk

  • Hero Member
  • *****
  • Posts: 7045
Re: Rewrite(xxx) causes "Access denied"
« Reply #3 on: June 13, 2017, 11:13:26 am »
I wrote a small program in FreePascal and decided to convert it into a GUI. The resulting program checks in FormCreate if a needed binary file exists. If not, the program creates one with some standard values using rewrite. Then the values are read from the file into an array. When closing the program (FormDestroy), whether the values in this array have been changed or not, the array is written back to the disk again using rewrite again.
First of all, but that's personal opinion, I wouldn't create the file on startup if it doesn't exists. You are going to (re)write it anyway when closing your program so when te file doesn't exist on startup you can just fill the array and go on. No need to create the file in that case.

Then for the error. Like Thaddy already mentioned, location is important. But since you say the error occurs in the IDE and not in the standalone exe that seems unlikely.

It's best you create a small test-project where you demonstrate your actions.

For instance... Rewrite needs {$I-} to detect an IOResult. But if you misplace the corresponding {$I+} your IOResult is 0 and only becomes <> 0 when you do {$I+}. So you always need to match your {$I-} with the {$I+} and after that {$I+} you need to read out IOResult.

Code: Pascal  [Select][+][-]
  1. AssignFile(F,file.txt);  
  2. {$I-}  
  3. Rewrite(F);  
  4. {$I+}  
  5. if IOResult <> 0 then
(just misplacing one of those {$I} will wreak havoc on your program.)

RuudBaltissen

  • New Member
  • *
  • Posts: 14
    • Ruud's Homepage
Re: Rewrite(xxx) causes "Access denied"
« Reply #4 on: June 13, 2017, 11:20:48 am »
Unless you are under a modern (7+) windows and try to write to the install root disk of the OS (C:\   mostly ). That will only work with admin rights.
It goes wrong on two different PCs, both W7 and both on drive D, another partition. 
Regarding the admin rights: I can imagine that I have no rights to write to a disk or directory. But then why goes the first run fine? The FreePascal program has no problems at all.
« Last Edit: June 13, 2017, 03:41:32 pm by RuudBaltissen »

RuudBaltissen

  • New Member
  • *
  • Posts: 14
    • Ruud's Homepage
Re: Rewrite(xxx) causes "Access denied"
« Reply #5 on: June 13, 2017, 11:27:55 am »
Try using not "FormDestroy" (which shouldn't but might cause problems) but "FormClose" ...
Ah, I learned something again! Now I get the error on the EXE as well.


The used code:

- If the file doesn't exist:
    assignfile(fDB, sDatabaseBin);
    rewrite(fDB);
    aDatabase[0]._wDatabase := 0;
    aDatabase[0]._sDbName   := '<Dummy>';
    aDatabase[1]._wDatabase := 1;
    aDatabase[1]._sDbName   := '<Enter a name>';
    write(fDB, aDatabase[0]);
    write(fDB, aDatabase[1]);
    closefile(fDB);

- After an update and at the end of the program:
      assignfile(fDB, sDatabaseBin);
      rewrite(fDB);
      for w1 := 0 to wNumDB do write(fDB, aDatabase[w1]);
      closefile(fDB);

I hope this helps!

wp

  • Hero Member
  • *****
  • Posts: 13585
Re: Rewrite(xxx) causes "Access denied"
« Reply #6 on: June 13, 2017, 11:36:24 am »
Since you are writing something to a file there's probably also a routine which reads this file. Do you close the file in the READING code?

Eugene Loza

  • Hero Member
  • *****
  • Posts: 729
    • My games in Pascal
Re: Rewrite(xxx) causes "Access denied"
« Reply #7 on: June 13, 2017, 11:41:43 am »
for w1 := 0 to wNumDB do write(fDB, aDatabase[w1])
Try also turning on range-checking {$R+}. E.g. in this place you might get a range check error if wNumDB is larger equal to length(aDatabase). Such exception (hidden unless you have the range-checking on) may lead to file not being closed properly.
My FOSS games in FreePascal&CastleGameEngine: https://decoherence.itch.io/ (Sources: https://gitlab.com/EugeneLoza)

Thaddy

  • Hero Member
  • *****
  • Posts: 19283
  • Glad to be alive.
Re: Rewrite(xxx) causes "Access denied"
« Reply #8 on: June 13, 2017, 12:12:23 pm »
And furthermore:
Check IOResult if IO checks! (and range checks, but I think IO Checks were meant here) are off. That is even more useful, because that will give you a meaningful error code that, just like structured exceptions... you can handle in code...
« Last Edit: June 13, 2017, 12:14:02 pm by Thaddy »
objects are fine constructs. You can even initialize them with constructors.

RuudBaltissen

  • New Member
  • *
  • Posts: 14
    • Ruud's Homepage
Re: Rewrite(xxx) causes "Access denied"
« Reply #9 on: June 13, 2017, 03:30:41 pm »
Since you are writing something to a file there's probably also a routine which reads this file. Do you close the file in the READING code?
The only code used for reading this file in FormCreate:
  assignfile(fDB, sDatabaseBin);
  reset(fDB);
  cbDatabase.Clear;
  cbDatabase.Text := '';
  wNumDB := 0;

  repeat
   read(fDB, aDatabase[wNumDB]);
   inc(wNumDB);
  until EOF(fDB);

  dec(wNumDB);
  closefile(fDB);

RuudBaltissen

  • New Member
  • *
  • Posts: 14
    • Ruud's Homepage
Re: Rewrite(xxx) causes "Access denied"
« Reply #10 on: June 13, 2017, 03:40:43 pm »
for w1 := 0 to wNumDB do write(fDB, aDatabase[w1])
Try also turning on range-checking {$R+}. E.g. in this place you might get a range check error if wNumDB is larger equal to length(aDatabase). Such exception (hidden unless you have the range-checking on) may lead to file not being closed properly.
Thank you for the advice but in this case I'm 100% sure that that is not the case. If it really was a range check error, the very first run should have gone bad as well. When doing nothing at all, except starting and stopping the program, just the two records given in the code are written to the file. First run: no problem, second run: access denied.

rvk

  • Hero Member
  • *****
  • Posts: 7045
Re: Rewrite(xxx) causes "Access denied"
« Reply #11 on: June 13, 2017, 04:03:05 pm »
Can you provide the structure of aDatabase array and record?

(I take it you didn't define string there? Otherwise you have a big memory overwrite problem.)

Otherwise you need to strip down your program to just the reading and writing and see if your problem persists. If it does you can place your code here (which was already suggested).

wp

  • Hero Member
  • *****
  • Posts: 13585
Re: Rewrite(xxx) causes "Access denied"
« Reply #12 on: June 13, 2017, 04:07:06 pm »
Since you are writing something to a file there's probably also a routine which reads this file. Do you close the file in the READING code?
The only code used for reading this file in FormCreate:
  assignfile(fDB, sDatabaseBin);
  reset(fDB);
  cbDatabase.Clear;
  cbDatabase.Text := '';
  wNumDB := 0;

  repeat
   read(fDB, aDatabase[wNumDB]);
   inc(wNumDB);
  until EOF(fDB);

  dec(wNumDB);
  closefile(fDB);
This looks wrong. What is aDatabase? An array of records? Is it statically dimensioned, or dynamically? In any case, you do not check that you run over the array limits. Try something like this:
Code: Pascal  [Select][+][-]
  1. type
  2.   TDatabase = record
  3.     ID: Integer;
  4.     DBName: String;
  5.   end;
  6.  
  7. var
  8.   aDatabase: array of TDatabase;
  9.  
  10. procedure TForm1.FormCreate(Sender. TSender);
  11. begin
  12.   ...
  13.   SetLength(aDatabase, 0);
  14.   wNumDB := 0;
  15.   while not Eof(fDB) do begin
  16.     SetLength(aDatabase, wNumDB+1);   // <--- IMPORTANT!
  17.     Read(fDB, aDatabase[wNumDB])
  18.     inc(wNumDB);
  19.   end;
  20.   ..
  21.  

rvk

  • Hero Member
  • *****
  • Posts: 7045
Re: Rewrite(xxx) causes "Access denied"
« Reply #13 on: June 13, 2017, 04:09:37 pm »
Code: [Select]
type
  TDatabase = record
    ID: Integer;
    DBName: String; // <----- IEKS !!!
  end;
Would that work in a record saved on disk?
I thought this would give major problems because when reading the record the string is actually a pointer and memory will get overwritten.

I think it needs to be:
Code: [Select]
type
  TDatabase = record
    ID: Integer;
    DBName: String[120]; // or a maximum string-size
  end;


wp

  • Hero Member
  • *****
  • Posts: 13585
Re: Rewrite(xxx) causes "Access denied"
« Reply #14 on: June 13, 2017, 04:12:10 pm »
Right. I knew I had forgotten to write something...
« Last Edit: June 13, 2017, 04:33:17 pm by wp »

 

TinyPortal © 2005-2018