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