I. Overview
Locks are a security mechanism provided by the operating system for data sharing, which makes it possible to share and exchange data securely and efficiently between different applications and different computers. To ensure the safe and efficient operation of shared data, the type of lock must be judged before the appropriate operation to determine whether the data is readable or writable, thus providing a practical basis for developing robust programs.
Similarly, in Windows, files can be opened in shared mode, and it also involves the operation of locks. Locks can be divided into global and local locks based on the size of the lock range in Windows, and global locks are characterized by locking the contents of the file, while local locks are characterized by locking the local contents of the file, and the locked area of the file is not repeatable. Depending on the operation permissions of the lock in Windows file sharing, locks can be divided into: Read lock, write lock, read/write lock (readable writable, global lock).
We can try to add a global lock to the specified file by using the non-repeatable feature of the lock in the above file. If the lock succeeds, the specified file is not locked by another process, otherwise the file is locked by another process. Here, we use two Windows API file manipulation functions: OpenFile and CreateFile to determine the locking state.
Second, the realization method
1. OpenFile Function Usage Instructions
Functional prototype: function OpenFile (const LPFILENAME:LPCSTR; var lpreopenbuff:tofstruct;
Ustyle:uint): hfile; stdcall;
function function: The operation to open a file in different ways (for functions that are compatible with 16-bit Windows programs). Suggestions
Use the CreateFile function under Windows.
Parameter description: lpFileName: The name of the file to open
Lpreopenbuff: variable pointer used to store the information that was received when the file was first opened.
Ustyle: The constant type of the open file.
Constant name
Significance
Of_create
Create a file
Of_delete
Delete the specified file
Of_exist
Open the file to verify that it exists no? exists, returns an invalid handle; otherwise, a negative number is returned
Of_parse
Populate the Lpreopenbuff content without doing anything
Of_prompt
Displays a message box with retry and Cancel buttons if one does not exist
Of_read
Read-only mode open
Of_readwrite
Read/write mode open
Of_reopen
Opens the file specified in the Lpreopenbuff, not according to lpFileName
Of_search
Force windows to find files---even if a file path is specified
Of_share_compat
Files can be opened more than once by multiple programs
Of_share_deny_none
Shared Open
Of_share_deny_read
Prohibit other programs from reading the file
Of_share_deny_write
Prohibit other programs from writing the file
Of_share_exclusive
Exclusive way to open the file, other programs must not open the file
Of_write
Write-only mode open
Return value: Successful, the return value is a file handle (but may not be valid, such as: of_exist); error, return hfile_error.
2. CreateFile function Usage Instructions
Functional prototype: function CreateFile (Lpfilename:pchar;
dwDesiredAccess, Dwsharemode:dword;
Lpsecurityattributes:psecurityattributes;
dwCreationDisposition, Dwflagsandattributes:dword;
Htemplatefile:thandle): Thandle; stdcall;
Functions: Open files in different ways, but also operate pipelines, mail slots, communication services, equipment and control
System, and so on.
Parameter description: lpFileName: The name of the file to open
dwDesiredAccess: Desired access mode
Value 0: Only one device is allowed to get information about it.
Generic_read: Only read devices are allowed
Generic_write: Only write devices are allowed (they can be used in combination).
dwShareMode: Shared mode.
Value 0: not shared.
File_share_read and/or file_share_write: share read and/or write.
lpSecurityAttributes: A pointer to a file security attribute (provided that the operating system supports it).
dwCreationDisposition: How to open and create files.
Value create_new: Always create a new file, if the file already exists, there is an error.
Create_always: Always creates a new file (overwrites the old file).
Open_existing: Open an existing file and an error if the file does not exist.
Open_always: Always open file, if not present, create.
dwFlagsAndAttributes: To open the file's flags and attributes (such as: hidden, system, etc.).
Generally used File_attribute_normal, default properties.
hTemplateFile:: Template file handle.
Specify a file handle if not 0; otherwise, the new file will be copied from this file
Extended properties.
Return value: Success, return value is file handle; error, return Invalid_handle_value.
3. Program implementation
Using these two functions, we can write a program to determine whether a file is being locked by another process, the following is the detailed code.
Use the OpenFile API function to determine
function filelocked (fn:string): Boolean;
Var
I:integer;
Struct:tofstruct;
style:cardinal;
Hdl:hfile;
drive:string;
Begin
Style: = of_share_exclusive; The way it opens
Drive: = Uppercase (fn[1]);
Struct.ffixeddisk: = Ord (drive <> ' A '); Determine if it is a hard disk
Struct.cbytes: = SizeOf (Struct);
For I: = 1 to Length (Fn) does
Struct.szpathname[i-1]: = Fn[i];
Struct.szpathname[i]: = CHR (0); Fill file name
HDL: = OpenFile (Pchar (Fn), Struct, Style);
If Hdl = Hfile_error Then
Begin
Result: = True; File is locked
ShowMessage (Syserrormessage (GetLastError)); Show the cause of the error
End
Else
Result: = False;
End
Use the CreateFile API function to determine
function Lockedfile (fn:string): Boolean;
Var
Afile:thandle;
Secatrrs:tsecurityattributes;
Begin
Fillchar (Secatrrs, SizeOf (Secatrrs), #0);
Secatrrs.nlength: = SizeOf (Secatrrs); Length of structure body
Secatrrs.lpsecuritydescriptor: = nil; Security description
Secatrrs.binherithandle: = True; Inheritance Flags
Afile: = CreateFile (PChar (Fn), generic_read or Generic_write,
File_share_read, @SecAtrrs, open_existing,
File_attribute_normal, 0);
If Afile = Invalid_handle_value Then
Begin
Result: = True; File is locked
ShowMessage (Syserrormessage (GetLastError));
End
Else
Result: = False;
End
4. Test of the program
Create a new application in Delphi and write in the Form1 OnCreate event:
If not filelocked (' c:\windows\desktop\a.txt ') then ShowMessage (' cannot Open 1 ');
Or
If not lockedfile (' c:\windows\desktop\a.txt ') then ShowMessage (' cannot Open 2 ');
Then create a new batch file to save to the desktop with the content:
Dir c:\*.*/s> c:\windows\desktop\a.txt '
Run this batch file, and then run the above Delphi program. The message box appears "Other processes are using the file and are now inaccessible." ”。 This information does not appear when the batch command finishes running the program. At this point, double-click the A.txt document, and the Notepad program will not be able to open the document stating that locking succeeded.
Iii. concluding remarks
The above two methods are implemented to determine whether a file is being locked by another process. Among them, the method one realizes is simple, but the compatibility is not good, but the method two is the method which the Windows recommends, and the function is powerful.
By using the above implementation method, the problem of determining the file lock status in Windows is solved satisfactorily. It provides a good reference for avoiding sharing conflict and improving the robustness of the file operation program.
http://blog.csdn.net/yanjiaye520/article/details/7880967
Delphi Windows API determines file share lock status