[KERNEL32]
[reactos.git] / reactos / dll / win32 / kernel32 / client / file / lock.c
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
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
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
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
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 */