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 */ 230