xref: /reactos/dll/win32/kernel32/client/file/lock.c (revision c2c66aff)
1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/kernel32/client/file/lock.c
5  * PURPOSE:         Directory functions
6  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
7  * UPDATE HISTORY:
8  *                  Created 01/11/98
9  */
10 
11 
12 /* INCLUDES ****************************************************************/
13 
14 #include <k32.h>
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* FUNCTIONS ****************************************************************/
19 
20 /*
21  * @implemented
22  */
23 BOOL
24 WINAPI
LockFile(IN HANDLE hFile,IN DWORD dwFileOffsetLow,IN DWORD dwFileOffsetHigh,IN DWORD nNumberOfBytesToLockLow,IN DWORD nNumberOfBytesToLockHigh)25 LockFile(IN HANDLE hFile,
26          IN DWORD dwFileOffsetLow,
27          IN DWORD dwFileOffsetHigh,
28          IN DWORD nNumberOfBytesToLockLow,
29          IN DWORD nNumberOfBytesToLockHigh)
30 {
31     IO_STATUS_BLOCK IoStatusBlock;
32     NTSTATUS Status;
33     LARGE_INTEGER BytesToLock, Offset;
34 
35     /* Is this a console handle? */
36     if (IsConsoleHandle(hFile))
37     {
38         /* Can't "lock" a console! */
39         BaseSetLastNTError(STATUS_INVALID_HANDLE);
40         return FALSE;
41     }
42 
43     /* Setup the parameters in NT style and call the native API */
44     BytesToLock.u.LowPart = nNumberOfBytesToLockLow;
45     BytesToLock.u.HighPart = nNumberOfBytesToLockHigh;
46     Offset.u.LowPart = dwFileOffsetLow;
47     Offset.u.HighPart = dwFileOffsetHigh;
48     Status = NtLockFile(hFile,
49                         NULL,
50                         NULL,
51                         NULL,
52                         &IoStatusBlock,
53                         &Offset,
54                         &BytesToLock,
55                         0,
56                         TRUE,
57                         TRUE);
58     if (Status == STATUS_PENDING)
59     {
60         /* Wait for completion if needed */
61         Status = NtWaitForSingleObject(hFile, FALSE, NULL);
62         if (NT_SUCCESS(Status)) Status = IoStatusBlock.Status;
63     }
64 
65     /* Check if we failed */
66     if (!NT_SUCCESS(Status))
67     {
68         /* Convert the error code and fail */
69         BaseSetLastNTError(Status);
70         return FALSE;
71     }
72 
73     /* Success! */
74     return TRUE;
75 }
76 
77 /*
78  * @implemented
79  */
80 BOOL
81 WINAPI
LockFileEx(IN HANDLE hFile,IN DWORD dwFlags,IN DWORD dwReserved,IN DWORD nNumberOfBytesToLockLow,IN DWORD nNumberOfBytesToLockHigh,IN LPOVERLAPPED lpOverlapped)82 LockFileEx(IN HANDLE hFile,
83            IN DWORD dwFlags,
84            IN DWORD dwReserved,
85            IN DWORD nNumberOfBytesToLockLow,
86            IN DWORD nNumberOfBytesToLockHigh,
87            IN LPOVERLAPPED lpOverlapped)
88 {
89     LARGE_INTEGER BytesToLock, Offset;
90     NTSTATUS Status;
91 
92     /* Is this a console handle? */
93     if (IsConsoleHandle(hFile))
94     {
95         /* Can't "lock" a console! */
96         BaseSetLastNTError(STATUS_INVALID_HANDLE);
97         return FALSE;
98     }
99 
100     /* This parameter should be zero */
101     if (dwReserved)
102     {
103         /* Fail since it isn't */
104         SetLastError(ERROR_INVALID_PARAMETER);
105         return FALSE;
106     }
107 
108     /* Set the initial status in the IO_STATUS_BLOCK to pending... */
109     lpOverlapped->Internal = STATUS_PENDING;
110 
111     /* Convert the parameters to NT format and call the native API */
112     Offset.u.LowPart = lpOverlapped->Offset;
113     Offset.u.HighPart = lpOverlapped->OffsetHigh;
114     BytesToLock.u.LowPart = nNumberOfBytesToLockLow;
115     BytesToLock.u.HighPart = nNumberOfBytesToLockHigh;
116     Status = NtLockFile(hFile,
117                         lpOverlapped->hEvent,
118                         NULL,
119                         NULL,
120                         (PIO_STATUS_BLOCK)lpOverlapped,
121                         &Offset,
122                         &BytesToLock,
123                         0,
124                         dwFlags & LOCKFILE_FAIL_IMMEDIATELY ? TRUE : FALSE,
125                         dwFlags & LOCKFILE_EXCLUSIVE_LOCK ? TRUE: FALSE);
126     if ((NT_SUCCESS(Status)) && (Status != STATUS_PENDING))
127     {
128         /* Pending status is *not* allowed in the Ex API */
129         return TRUE;
130     }
131 
132     /* Convert the error code and fail */
133     BaseSetLastNTError(Status);
134     return FALSE;
135 }
136 
137 /*
138  * @implemented
139  */
140 BOOL
141 WINAPI
UnlockFile(IN HANDLE hFile,IN DWORD dwFileOffsetLow,IN DWORD dwFileOffsetHigh,IN DWORD nNumberOfBytesToUnlockLow,IN DWORD nNumberOfBytesToUnlockHigh)142 UnlockFile(IN HANDLE hFile,
143            IN DWORD dwFileOffsetLow,
144            IN DWORD dwFileOffsetHigh,
145            IN DWORD nNumberOfBytesToUnlockLow,
146            IN DWORD nNumberOfBytesToUnlockHigh)
147 {
148     OVERLAPPED Overlapped;
149     NTSTATUS Status;
150     BOOLEAN Result;
151 
152     /* Convert parameters to Ex format and call the new API */
153     Overlapped.Offset = dwFileOffsetLow;
154     Overlapped.OffsetHigh = dwFileOffsetHigh;
155     Result = UnlockFileEx(hFile,
156                           0,
157                           nNumberOfBytesToUnlockLow,
158                           nNumberOfBytesToUnlockHigh,
159                           &Overlapped);
160     if (!(Result) && (GetLastError() == ERROR_IO_PENDING))
161     {
162         /* Ex fails during STATUS_PENDING, handle that here by waiting */
163         Status = NtWaitForSingleObject(hFile, FALSE, NULL);
164         if (NT_SUCCESS(Status)) Status = Overlapped.Internal;
165 
166         /* Now if the status is successful, return */
167         if (!NT_SUCCESS(Status)) return TRUE;
168 
169         /* Otherwise the asynchronous operation had a failure, so fail */
170         BaseSetLastNTError(Status);
171         return FALSE;
172     }
173 
174     /* Success or error case -- Ex took care of the rest, just return */
175     return Result;
176 }
177 
178 /*
179  * @implemented
180  */
181 BOOL
182 WINAPI
UnlockFileEx(IN HANDLE hFile,IN DWORD dwReserved,IN DWORD nNumberOfBytesToUnLockLow,IN DWORD nNumberOfBytesToUnLockHigh,IN LPOVERLAPPED lpOverlapped)183 UnlockFileEx(IN HANDLE hFile,
184              IN DWORD dwReserved,
185              IN DWORD nNumberOfBytesToUnLockLow,
186              IN DWORD nNumberOfBytesToUnLockHigh,
187              IN LPOVERLAPPED lpOverlapped)
188 {
189     LARGE_INTEGER BytesToUnLock, StartAddress;
190     NTSTATUS Status;
191 
192     /* Is this a console handle? */
193     if (IsConsoleHandle(hFile))
194     {
195         /* Can't "unlock" a console! */
196         BaseSetLastNTError(STATUS_INVALID_HANDLE);
197         return FALSE;
198     }
199 
200     /* This parameter should be zero */
201     if (dwReserved)
202     {
203         /* Fail since it isn't */
204         SetLastError(ERROR_INVALID_PARAMETER);
205         return FALSE;
206     }
207 
208     /* Convert to NT format and call the native function */
209     BytesToUnLock.u.LowPart = nNumberOfBytesToUnLockLow;
210     BytesToUnLock.u.HighPart = nNumberOfBytesToUnLockHigh;
211     StartAddress.u.LowPart = lpOverlapped->Offset;
212     StartAddress.u.HighPart = lpOverlapped->OffsetHigh;
213     Status = NtUnlockFile(hFile,
214                           (PIO_STATUS_BLOCK)lpOverlapped,
215                           &StartAddress,
216                           &BytesToUnLock,
217                           0);
218     if (!NT_SUCCESS(Status))
219     {
220         /* Convert the error and fail */
221         BaseSetLastNTError(Status);
222         return FALSE;
223     }
224 
225     /* All good */
226     return TRUE;
227 }
228 
229 /* EOF */
230