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