Recent

Author Topic: Unlocking Files  (Read 848 times)

Redenegue

  • New Member
  • *
  • Posts: 16
Unlocking Files
« on: April 22, 2024, 01:09:29 am »
In Windows there are functions to unlock files. They require knowledge of the region inside the file that is locked.
I have not been able to find any Lazarus, pascal or Windows resource to find this region or an implementation of file unlocking.
Can anyone tell me how to use the Windows UnLockFiles or UnLockFilesEx functions?
How to find the region of the file that is locked?

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2218
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Unlocking Files
« Reply #1 on: April 22, 2024, 01:57:51 am »
You specify the filehandle that has been created by CreateFile() to be used by the UnlockFileEx() method.
You can not unlock files that are locked by other processes/threads.
That method is meant to work hand-in-hand with LockFileEx() where, depends on switches, you give or deny permission for other processes to read/write inside a particular region (offset + count of byte) or full file.
So the process that access it first (CreateFile() + LockFileEx()) is in charge up to the moment where the process calls UnlockFileEx() and CloseHandle().
Your own process has read/write permissions all the time, when its multithread than the thread that was calling createfile/lockfileex is the owner.
Hard to give example if its not known what you actually want to do.
AFAIK there is no direct way over the api that tells if a file has a lock or not, the only way that I do know is to actual try read/write to find out if it succeed.

CreateFile() itself can also lock files for other processes (that work generic for whole file), so of course you are forbid to change that as a 3rd party process.
Imagine your app write to a file while another process does do the same because it think "hey i locked it, now i can save changes".

There is much info to read about this topic.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Redenegue

  • New Member
  • *
  • Posts: 16
Re: Unlocking Files
« Reply #2 on: April 22, 2024, 09:47:51 am »
Thank you for the information.
There are unlocker programs that do unlock files.
Also, Windows file explorer will rename and delete files that Lazarus routines will not touch.
That has been a big issue for me.
Using an unlocker, I have seen some that have no locks or restrictions, but can not be renamed with Lazarus.
Then I have to access the files with explorer before I can rename them with my Lazarus program.
Any ideas?

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2218
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Unlocking Files
« Reply #3 on: April 22, 2024, 12:39:53 pm »
I am not sure what actual happen on your machine, "unlock" programs that "free filehandle/terminate accessing thread" can be dangerous aswell, just ask yourself why is a file locked or in what scenario would you lock a file.
To do the same that unlock-apps are doing you will need to write a driver else you missing access to the thread that locked.

If I would be you I would investigate why are files locked, from what process, for what reason etc...
Sysinternals, a division from microsoft, is offering for free system tools that help you to "unlock" the riddle of the "locks" :D
ProcMon/FileMon/RegMon etc... all those "mons" are no pokémon they are monitors to aid you.
Via filters you can get pretty easy pretty fast some results.

Another idea, dont call me stupid but its a good idea, how about to actual show some code where you try to rename or delete files within your app.
I somehow have a feeling that you lock files on your own by open them and forget to close before your renaming/delete action happen.
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

Redenegue

  • New Member
  • *
  • Posts: 16
Re: Unlocking Files
« Reply #4 on: April 23, 2024, 05:35:46 pm »
I have used 2 methods of renaming.
Usually they work good.
However sometimes when I go down a list of files, one or more of them will not rename.
I open Windows explorer, make a little change in the filename, and then my program will rename them.
So, it is in a list of files.
This happens in a situation where I never opened them.
But if I did accidentally open them, only a rare file, in a list, is affected, none of the others.
I am also curious why my function at the bottom will not rename files with foreign characters.
I thought it might work better than FileRename.
If they seem a little "wordy", its to make them easier to debug.
Also, there is no problem with the new file names. I checked that out carefully.
My renamed files get rid of questionable and junk characters, simplifies the name and gives them some common structure.

BTW, You have been kind to me. I appreciate that. I am old now, sometimes things get past me.
I have a few things to finish up while I can. I miss the old days when a hacker was a good guy.
Thank the ignorant media for that one. It was Phreakers who did the bad "hacking".
They never said a word about them. They turned a whole generation of us into criminals.

// Rename 1
TShellTreeView OnChange:
ActiveDir := IncludeTrailingPathDelimiter(STV1.Path); 

OnClickEvent:
     For I := 0 to ActiveList.Items.Count - 1 do
     begin
          If ActiveList.Items.Item.Selected then
          begin
               FN := ActiveList.Items.Item.Caption;
               NFN := FN;

// File Name altered here

               RenameFile(ActiveDir + FN, ActiveDir + NFN);
          end;
     end;

// Rename2
     I := 0;
     While I < Selected.FileList.Items.Count do
     begin
          If Selected.FileList.Items.Item.Selected then
          begin
               C := Selected.FileList.Items.Item.Caption;
               If MoveAFile(FileIn, FileOut) then
               Selected.FileList.Items.Item.Caption := C;

// This function will not rename files with foreign characters
Function TWork.MoveAFile(StrFrom, StrTo: string): Boolean;
var
  F : TShFileOpStruct;
begin
  F.wFunc:=FO_MOVE;
  F.pFrom:=PChar(StrFrom+#0);
  F.pTo:=PChar(StrTo+#0);
  F.fFlags := FOF_RENAMEONCOLLISION or FOF_NOCONFIRMMKDIR or FOF_NOCONFIRMATION or FOF_SILENT;

  if ShFileOperation(F) <> 0 then
    result:=False
  else
    result:=True;
end;               




440bx

  • Hero Member
  • *****
  • Posts: 4188
Re: Unlocking Files
« Reply #5 on: April 23, 2024, 05:51:27 pm »
@Redenegue,

It would be nice of you to put your code between code tags so it looks like this:
Code: Pascal  [Select][+][-]
  1. program ProgramName;

To see how I did that, click the "quote" (to quote the message) and you'll see the necessary tags between [ and ].

HTH.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2218
  • Fifty shades of code.
    • Delphi & FreePascal
Re: Unlocking Files
« Reply #6 on: April 23, 2024, 06:03:08 pm »
To be honest, on a windows machine I would use the windows api.
I have not checked what RenameFile() does do but this is how I would do:
Code: Pascal  [Select][+][-]
  1. function MyRenameFile(const OldName, NewName: WideString): Boolean;
  2. var
  3.   OldNameW, NewNameW: PWideChar;
  4. begin
  5.   OldNameW := PWideChar(OldName);
  6.   NewNameW := PWideChar(NewName);
  7.   Result := MoveFileW(OldNameW, NewNameW);
  8. end;
  9.  
  10. begin
  11.   if MyRenameFile('OldFileName.txt', 'NewFileName.txt') then
  12.     WriteLn('File renamed successfully.')
  13.   else
  14.     WriteLn('Failed to rename file.');
  15. end.
Extend that snipped with error handling like the link is suggesting.
My example assume that OldFileName.txt does exists and NewFileName.txt not.
That the destination folder exists and your process got write permission.
« Last Edit: April 23, 2024, 06:06:24 pm by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 xm by KodeZwerg »

 

TinyPortal © 2005-2018