- started implementing ntdll.NtDeviceIoControlFile and made
[wine/multimedia.git] / dlls / ntdll / file.c
blobd57bc1d13b1ef58a31eaefdf7dd7b61195ecd68e
1 /*
2 * Copyright 1999, 2000 Juergen Schmied
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "config.h"
20 #include "wine/port.h"
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #ifdef HAVE_SYS_ERRNO_H
30 #include <sys/errno.h>
31 #endif
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35 #include "wine/unicode.h"
36 #include "wine/debug.h"
37 #include "wine/server.h"
38 #include "ntdll_misc.h"
39 #include "file.h" /* FIXME */
41 #include "winternl.h"
42 #include "winioctl.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
47 /**************************************************************************
48 * NtOpenFile [NTDLL.@]
49 * ZwOpenFile [NTDLL.@]
50 * FUNCTION: Opens a file
51 * ARGUMENTS:
52 * FileHandle Variable that receives the file handle on return
53 * DesiredAccess Access desired by the caller to the file
54 * ObjectAttributes Structue describing the file to be opened
55 * IoStatusBlock Receives details about the result of the operation
56 * ShareAccess Type of shared access the caller requires
57 * OpenOptions Options for the file open
59 NTSTATUS WINAPI NtOpenFile(
60 OUT PHANDLE FileHandle,
61 ACCESS_MASK DesiredAccess,
62 POBJECT_ATTRIBUTES ObjectAttributes,
63 OUT PIO_STATUS_BLOCK IoStatusBlock,
64 ULONG ShareAccess,
65 ULONG OpenOptions)
67 LPWSTR filename;
68 static const WCHAR szDosDevices[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
69 DOS_FULL_NAME full_name;
70 NTSTATUS r;
72 FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx) partial stub\n",
73 FileHandle, DesiredAccess, ObjectAttributes,
74 IoStatusBlock, ShareAccess, OpenOptions);
76 dump_ObjectAttributes (ObjectAttributes);
78 if(ObjectAttributes->RootDirectory)
80 FIXME("Object root directory unknown %p\n",
81 ObjectAttributes->RootDirectory);
82 return STATUS_OBJECT_NAME_NOT_FOUND;
85 filename = ObjectAttributes->ObjectName->Buffer;
87 /* FIXME: DOSFS stuff should call here, not vice-versa */
88 if(strncmpW(filename, szDosDevices, strlenW(szDosDevices)))
89 return STATUS_OBJECT_NAME_NOT_FOUND;
91 /* FIXME: this calls SetLastError() -> bad */
92 if(!DOSFS_GetFullName(&filename[strlenW(szDosDevices)], TRUE,
93 &full_name))
94 return STATUS_OBJECT_NAME_NOT_FOUND;
96 /* FIXME: modify server protocol so
97 create file takes an OBJECT_ATTRIBUTES structure */
98 SERVER_START_REQ( create_file )
100 req->access = DesiredAccess;
101 req->inherit = 0;
102 req->sharing = ShareAccess;
103 req->create = OPEN_EXISTING;
104 req->attrs = 0;
105 req->drive_type = GetDriveTypeW( full_name.short_name );
106 wine_server_add_data( req, full_name.long_name, strlen(full_name.long_name) );
107 SetLastError(0);
108 r = wine_server_call( req );
109 *FileHandle = reply->handle;
111 SERVER_END_REQ;
113 return r;
116 /**************************************************************************
117 * NtCreateFile [NTDLL.@]
118 * ZwCreateFile [NTDLL.@]
119 * FUNCTION: Either causes a new file or directory to be created, or it opens
120 * an existing file, device, directory or volume, giving the caller a handle
121 * for the file object. This handle can be used by subsequent calls to
122 * manipulate data within the file or the file object's state of attributes.
123 * ARGUMENTS:
124 * FileHandle Points to a variable which receives the file handle on return
125 * DesiredAccess Desired access to the file
126 * ObjectAttributes Structure describing the file
127 * IoStatusBlock Receives information about the operation on return
128 * AllocationSize Initial size of the file in bytes
129 * FileAttributes Attributes to create the file with
130 * ShareAccess Type of shared access the caller would like to the file
131 * CreateDisposition Specifies what to do, depending on whether the file already exists
132 * CreateOptions Options for creating a new file
133 * EaBuffer Undocumented
134 * EaLength Undocumented
136 NTSTATUS WINAPI NtCreateFile(
137 OUT PHANDLE FileHandle,
138 ACCESS_MASK DesiredAccess,
139 POBJECT_ATTRIBUTES ObjectAttributes,
140 OUT PIO_STATUS_BLOCK IoStatusBlock,
141 PLARGE_INTEGER AllocateSize,
142 ULONG FileAttributes,
143 ULONG ShareAccess,
144 ULONG CreateDisposition,
145 ULONG CreateOptions,
146 PVOID EaBuffer,
147 ULONG EaLength)
149 FIXME("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n",
150 FileHandle,DesiredAccess,ObjectAttributes,
151 IoStatusBlock,AllocateSize,FileAttributes,
152 ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
153 dump_ObjectAttributes (ObjectAttributes);
154 return 0;
157 /* set the last error depending on errno */
158 NTSTATUS NTFILE_errno_to_status(int val)
160 switch (val)
162 case EAGAIN: return ( STATUS_SHARING_VIOLATION );
163 case ESPIPE:
164 case EBADF: return ( STATUS_INVALID_HANDLE );
165 case ENOSPC: return ( STATUS_DISK_FULL );
166 case EACCES:
167 case ESRCH:
168 case EPERM: return ( STATUS_ACCESS_DENIED );
169 case EROFS: return ( STATUS_MEDIA_WRITE_PROTECTED );
170 case EBUSY: return ( STATUS_FILE_LOCK_CONFLICT );
171 case ENOENT: return ( STATUS_NO_SUCH_FILE );
172 case EISDIR: return ( STATUS_FILE_IS_A_DIRECTORY );
173 case ENFILE:
174 case EMFILE: return ( STATUS_NO_MORE_FILES );
175 case EEXIST: return ( STATUS_OBJECT_NAME_COLLISION );
176 case EINVAL: return ( STATUS_INVALID_PARAMETER );
177 case ENOTEMPTY: return ( STATUS_DIRECTORY_NOT_EMPTY );
178 case EIO: return ( STATUS_ACCESS_VIOLATION );
180 perror("file_set_error");
181 return ( STATUS_INVALID_PARAMETER );
185 /******************************************************************************
186 * NtReadFile [NTDLL.@]
187 * ZwReadFile [NTDLL.@]
189 * Parameters
190 * HANDLE32 FileHandle
191 * HANDLE32 Event OPTIONAL
192 * PIO_APC_ROUTINE ApcRoutine OPTIONAL
193 * PVOID ApcContext OPTIONAL
194 * PIO_STATUS_BLOCK IoStatusBlock
195 * PVOID Buffer
196 * ULONG Length
197 * PLARGE_INTEGER ByteOffset OPTIONAL
198 * PULONG Key OPTIONAL
200 * IoStatusBlock->Information contains the number of bytes read on return.
202 NTSTATUS WINAPI NtReadFile (
203 HANDLE FileHandle,
204 HANDLE EventHandle,
205 PIO_APC_ROUTINE ApcRoutine,
206 PVOID ApcContext,
207 PIO_STATUS_BLOCK IoStatusBlock,
208 PVOID Buffer,
209 ULONG Length,
210 PLARGE_INTEGER ByteOffset,
211 PULONG Key)
213 int fd, result, flags, ret;
214 enum fd_type type;
216 FIXME("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p),partial stub!\n",
217 FileHandle,EventHandle,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
219 if (IsBadWritePtr( Buffer, Length ) ||
220 IsBadWritePtr( IoStatusBlock, sizeof(*IoStatusBlock)) ||
221 IsBadWritePtr( ByteOffset, sizeof(*ByteOffset)) )
222 return STATUS_ACCESS_VIOLATION;
224 IoStatusBlock->Information = 0;
226 ret = wine_server_handle_to_fd( FileHandle, GENERIC_READ, &fd, &type, &flags );
227 if(ret)
228 return ret;
230 /* FIXME: this code only does synchronous reads so far */
232 /* FIXME: depending on how libc implements this, between two processes
233 there could be a race condition between the seek and read here */
236 result = pread( fd, Buffer, Length, ByteOffset->QuadPart);
238 while ( (result == -1) && ((errno == EAGAIN) || (errno == EINTR)) );
240 close( fd );
242 if (result == -1)
244 return IoStatusBlock->u.Status = NTFILE_errno_to_status(errno);
247 IoStatusBlock->Information = result;
248 IoStatusBlock->u.Status = 0;
250 return STATUS_SUCCESS;
253 /******************************************************************************
254 * NtWriteFile [NTDLL.@]
255 * ZwWriteFile [NTDLL.@]
257 * Parameters
258 * HANDLE32 FileHandle
259 * HANDLE32 Event OPTIONAL
260 * PIO_APC_ROUTINE ApcRoutine OPTIONAL
261 * PVOID ApcContext OPTIONAL
262 * PIO_STATUS_BLOCK IoStatusBlock
263 * PVOID Buffer
264 * ULONG Length
265 * PLARGE_INTEGER ByteOffset OPTIONAL
266 * PULONG Key OPTIONAL
268 NTSTATUS WINAPI NtWriteFile (
269 HANDLE FileHandle,
270 HANDLE EventHandle,
271 PIO_APC_ROUTINE ApcRoutine,
272 PVOID ApcContext,
273 PIO_STATUS_BLOCK IoStatusBlock,
274 PVOID Buffer,
275 ULONG Length,
276 PLARGE_INTEGER ByteOffset,
277 PULONG Key)
279 FIXME("(%p,%p,%p,%p,%p,%p,0x%08lx,%p,%p),stub!\n",
280 FileHandle,EventHandle,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
281 return 0;
284 /**************************************************************************
285 * NtDeviceIoControlFile [NTDLL.@]
286 * ZwDeviceIoControlFile [NTDLL.@]
288 NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE DeviceHandle, HANDLE hEvent,
289 PIO_APC_ROUTINE UserApcRoutine,
290 PVOID UserApcContext,
291 PIO_STATUS_BLOCK IoStatusBlock,
292 ULONG IoControlCode,
293 PVOID InputBuffer,
294 ULONG InputBufferSize,
295 PVOID OutputBuffer,
296 ULONG OutputBufferSize)
298 DWORD clientID = 0;
299 char str[3];
301 TRACE("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx)\n",
302 DeviceHandle, hEvent, UserApcRoutine, UserApcContext,
303 IoStatusBlock, IoControlCode,
304 InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize);
306 /* FIXME: clientID hack should disappear */
307 SERVER_START_REQ( get_device_id )
309 req->handle = DeviceHandle;
310 if (!wine_server_call( req )) clientID = reply->id;
312 SERVER_END_REQ;
314 if (!clientID) return STATUS_INVALID_PARAMETER;
315 strcpy(str, "A:");
316 str[0] += LOBYTE(clientID);
318 /* FIXME: should use the NTDLL equivalent */
319 if (GetDriveTypeA(str) == DRIVE_CDROM)
321 return CDROM_DeviceIoControl(clientID, DeviceHandle, hEvent,
322 UserApcRoutine, UserApcContext,
323 IoStatusBlock, IoControlCode,
324 InputBuffer, InputBufferSize,
325 OutputBuffer, OutputBufferSize);
328 FIXME("Unimplemented dwIoControlCode=%08lx\n", IoControlCode);
329 IoStatusBlock->u.Status = STATUS_NOT_IMPLEMENTED;
330 IoStatusBlock->Information = 0;
331 if (hEvent) NtSetEvent(hEvent, NULL);
332 return STATUS_NOT_IMPLEMENTED;
335 /******************************************************************************
336 * NtFsControlFile [NTDLL.@]
337 * ZwFsControlFile [NTDLL.@]
339 NTSTATUS WINAPI NtFsControlFile(
340 IN HANDLE DeviceHandle,
341 IN HANDLE Event OPTIONAL,
342 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
343 IN PVOID ApcContext OPTIONAL,
344 OUT PIO_STATUS_BLOCK IoStatusBlock,
345 IN ULONG IoControlCode,
346 IN PVOID InputBuffer,
347 IN ULONG InputBufferSize,
348 OUT PVOID OutputBuffer,
349 IN ULONG OutputBufferSize)
351 FIXME("(%p,%p,%p,%p,%p,0x%08lx,%p,0x%08lx,%p,0x%08lx): stub\n",
352 DeviceHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,IoControlCode,
353 InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize);
354 return 0;
357 /******************************************************************************
358 * NtSetVolumeInformationFile [NTDLL.@]
359 * ZwSetVolumeInformationFile [NTDLL.@]
361 NTSTATUS WINAPI NtSetVolumeInformationFile(
362 IN HANDLE FileHandle,
363 PIO_STATUS_BLOCK IoStatusBlock,
364 PVOID FsInformation,
365 ULONG Length,
366 FS_INFORMATION_CLASS FsInformationClass)
368 FIXME("(%p,%p,%p,0x%08lx,0x%08x) stub\n",
369 FileHandle,IoStatusBlock,FsInformation,Length,FsInformationClass);
370 return 0;
373 /******************************************************************************
374 * NtQueryInformationFile [NTDLL.@]
375 * ZwQueryInformationFile [NTDLL.@]
377 NTSTATUS WINAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
378 PVOID ptr, LONG len,
379 FILE_INFORMATION_CLASS class)
381 NTSTATUS status;
382 LONG used = 0;
383 BYTE answer[256];
384 time_t ct = 0, wt = 0, at = 0;
386 TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
388 switch (class)
390 case FileBasicInformation:
392 FILE_BASIC_INFORMATION* fbi = (FILE_BASIC_INFORMATION*)answer;
393 if (sizeof(answer) < sizeof(*fbi)) goto too_small;
395 SERVER_START_REQ( get_file_info )
397 req->handle = hFile;
398 if (!(status = wine_server_call( req )))
400 /* FIXME: which file types are supported ?
401 * Serial ports (FILE_TYPE_CHAR) are not,
402 * and MSDN also says that pipes are not supported.
403 * FILE_TYPE_REMOTE seems to be supported according to
404 * MSDN q234741.txt */
405 if ((reply->type == FILE_TYPE_DISK) ||
406 (reply->type == FILE_TYPE_REMOTE))
408 at = reply->access_time;
409 wt = reply->write_time;
410 ct = reply->change_time;
411 fbi->FileAttributes = reply->attr;
412 used = sizeof(*fbi);
414 else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
417 SERVER_END_REQ;
418 if (used)
420 RtlSecondsSince1970ToTime(wt, &fbi->CreationTime);
421 RtlSecondsSince1970ToTime(wt, &fbi->LastWriteTime);
422 RtlSecondsSince1970ToTime(ct, &fbi->ChangeTime);
423 RtlSecondsSince1970ToTime(at, &fbi->LastAccessTime);
426 break;
427 case FileStandardInformation:
429 FILE_STANDARD_INFORMATION* fsi = (FILE_STANDARD_INFORMATION*)answer;
430 if (sizeof(answer) < sizeof(*fsi)) goto too_small;
432 SERVER_START_REQ( get_file_info )
434 req->handle = hFile;
435 if (!(status = wine_server_call( req )))
437 /* FIXME: which file types are supported ?
438 * Serial ports (FILE_TYPE_CHAR) are not,
439 * and MSDN also says that pipes are not supported.
440 * FILE_TYPE_REMOTE seems to be supported according to
441 * MSDN q234741.txt */
442 if ((reply->type == FILE_TYPE_DISK) ||
443 (reply->type == FILE_TYPE_REMOTE))
445 fsi->AllocationSize.s.HighPart = reply->alloc_high;
446 fsi->AllocationSize.s.LowPart = reply->alloc_low;
447 fsi->EndOfFile.s.HighPart = reply->size_high;
448 fsi->EndOfFile.s.LowPart = reply->size_low;
449 fsi->NumberOfLinks = reply->links;
450 fsi->DeletePending = FALSE; /* FIXME */
451 fsi->Directory = (reply->attr & FILE_ATTRIBUTE_DIRECTORY);
452 used = sizeof(*fsi);
454 else status = STATUS_INVALID_HANDLE; /* FIXME ??? */
457 SERVER_END_REQ;
459 break;
460 case FilePositionInformation:
462 FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)answer;
463 if (sizeof(answer) < sizeof(*fpi)) goto too_small;
465 SERVER_START_REQ( set_file_pointer )
467 req->handle = hFile;
468 req->low = 0;
469 req->high = 0;
470 req->whence = SEEK_CUR;
471 if (!(status = wine_server_call( req )))
473 fpi->CurrentByteOffset.s.HighPart = reply->new_high;
474 fpi->CurrentByteOffset.s.LowPart = reply->new_low;
475 used = sizeof(*fpi);
478 SERVER_END_REQ;
480 break;
481 default:
482 FIXME("Unsupported class (%d)\n", class);
483 return io_status->u.Status = STATUS_NOT_IMPLEMENTED;
485 if (used) memcpy(ptr, answer, min(used, len));
486 io_status->u.Status = status;
487 io_status->Information = len;
488 return status;
489 too_small:
490 io_status->Information = 0;
491 return io_status->u.Status = STATUS_BUFFER_TOO_SMALL;
494 /******************************************************************************
495 * NtSetInformationFile [NTDLL.@]
496 * ZwSetInformationFile [NTDLL.@]
498 NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
499 PVOID ptr, ULONG len,
500 FILE_INFORMATION_CLASS class)
502 NTSTATUS status = STATUS_INVALID_PARAMETER_3;
504 TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
506 switch (class)
508 case FilePositionInformation:
509 if (len >= sizeof(FILE_POSITION_INFORMATION))
511 FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr;
513 SERVER_START_REQ( set_file_pointer )
515 req->handle = hFile;
516 req->low = fpi->CurrentByteOffset.s.LowPart;
517 req->high = fpi->CurrentByteOffset.s.HighPart;
518 req->whence = SEEK_SET;
519 status = wine_server_call( req );
521 SERVER_END_REQ;
522 status = STATUS_SUCCESS;
524 break;
525 default:
526 FIXME("Unsupported class (%d)\n", class);
527 return STATUS_NOT_IMPLEMENTED;
529 io_status->u.Status = status;
530 io_status->Information = 0;
531 return status;
534 /******************************************************************************
535 * NtQueryDirectoryFile [NTDLL.@]
536 * ZwQueryDirectoryFile [NTDLL.@]
537 * ZwQueryDirectoryFile
539 NTSTATUS WINAPI NtQueryDirectoryFile(
540 IN HANDLE FileHandle,
541 IN HANDLE Event OPTIONAL,
542 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
543 IN PVOID ApcContext OPTIONAL,
544 OUT PIO_STATUS_BLOCK IoStatusBlock,
545 OUT PVOID FileInformation,
546 IN ULONG Length,
547 IN FILE_INFORMATION_CLASS FileInformationClass,
548 IN BOOLEAN ReturnSingleEntry,
549 IN PUNICODE_STRING FileName OPTIONAL,
550 IN BOOLEAN RestartScan)
552 FIXME("(%p %p %p %p %p %p 0x%08lx 0x%08x 0x%08x %p 0x%08x\n",
553 FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation,
554 Length, FileInformationClass, ReturnSingleEntry,
555 debugstr_us(FileName),RestartScan);
556 return 0;
559 /******************************************************************************
560 * NtQueryVolumeInformationFile [NTDLL.@]
561 * ZwQueryVolumeInformationFile [NTDLL.@]
563 NTSTATUS WINAPI NtQueryVolumeInformationFile (
564 IN HANDLE FileHandle,
565 OUT PIO_STATUS_BLOCK IoStatusBlock,
566 OUT PVOID FSInformation,
567 IN ULONG Length,
568 IN FS_INFORMATION_CLASS FSInformationClass)
570 ULONG len = 0;
572 FIXME("(%p %p %p 0x%08lx 0x%08x) stub!\n",
573 FileHandle, IoStatusBlock, FSInformation, Length, FSInformationClass);
575 switch ( FSInformationClass )
577 case FileFsVolumeInformation:
578 len = sizeof( FILE_FS_VOLUME_INFORMATION );
579 break;
580 case FileFsLabelInformation:
581 len = 0;
582 break;
584 case FileFsSizeInformation:
585 len = sizeof( FILE_FS_SIZE_INFORMATION );
586 break;
588 case FileFsDeviceInformation:
589 len = sizeof( FILE_FS_DEVICE_INFORMATION );
590 break;
591 case FileFsAttributeInformation:
592 len = sizeof( FILE_FS_ATTRIBUTE_INFORMATION );
593 break;
595 case FileFsControlInformation:
596 len = 0;
597 break;
599 case FileFsFullSizeInformation:
600 len = 0;
601 break;
603 case FileFsObjectIdInformation:
604 len = 0;
605 break;
607 case FileFsMaximumInformation:
608 len = 0;
609 break;
612 if (Length < len)
613 return STATUS_BUFFER_TOO_SMALL;
615 switch ( FSInformationClass )
617 case FileFsVolumeInformation:
618 break;
619 case FileFsLabelInformation:
620 break;
622 case FileFsSizeInformation:
623 break;
625 case FileFsDeviceInformation:
626 if (FSInformation)
628 FILE_FS_DEVICE_INFORMATION * DeviceInfo = FSInformation;
629 DeviceInfo->DeviceType = FILE_DEVICE_DISK;
630 DeviceInfo->Characteristics = 0;
631 break;
633 case FileFsAttributeInformation:
634 break;
636 case FileFsControlInformation:
637 break;
639 case FileFsFullSizeInformation:
640 break;
642 case FileFsObjectIdInformation:
643 break;
645 case FileFsMaximumInformation:
646 break;
648 IoStatusBlock->u.Status = STATUS_SUCCESS;
649 IoStatusBlock->Information = len;
650 return STATUS_SUCCESS;
653 /******************************************************************
654 * NtFlushBuffersFile (NTDLL.@)
656 NTSTATUS WINAPI NtFlushBuffersFile( HANDLE hFile, IO_STATUS_BLOCK* IoStatusBlock )
658 NTSTATUS ret;
659 HANDLE hEvent = NULL;
661 SERVER_START_REQ( flush_file )
663 req->handle = hFile;
664 ret = wine_server_call( req );
665 hEvent = reply->event;
667 SERVER_END_REQ;
668 if( !ret && hEvent )
670 ret = NtWaitForSingleObject( hEvent, FALSE, NULL );
671 NtClose( hEvent );
673 return ret;
676 /******************************************************************
677 * NtLockFile (NTDLL.@)
681 NTSTATUS WINAPI NtLockFile( HANDLE hFile, HANDLE lock_granted_event,
682 PIO_APC_ROUTINE apc, void* apc_user,
683 PIO_STATUS_BLOCK io_status, PLARGE_INTEGER offset,
684 PLARGE_INTEGER count, ULONG* key, BOOLEAN dont_wait,
685 BOOLEAN exclusive )
687 NTSTATUS ret;
688 HANDLE handle;
689 BOOLEAN async;
691 if (apc || io_status || key)
693 FIXME("Unimplemented yet parameter\n");
694 return STATUS_NOT_IMPLEMENTED;
697 for (;;)
699 SERVER_START_REQ( lock_file )
701 req->handle = hFile;
702 req->offset_low = offset->s.LowPart;
703 req->offset_high = offset->s.HighPart;
704 req->count_low = count->s.LowPart;
705 req->count_high = count->s.HighPart;
706 req->shared = !exclusive;
707 req->wait = !dont_wait;
708 ret = wine_server_call( req );
709 handle = reply->handle;
710 async = reply->overlapped;
712 SERVER_END_REQ;
713 if (ret != STATUS_PENDING)
715 if (!ret && lock_granted_event) NtSetEvent(lock_granted_event, NULL);
716 return ret;
719 if (async)
721 FIXME( "Async I/O lock wait not implemented, might deadlock\n" );
722 if (handle) NtClose( handle );
723 return STATUS_PENDING;
725 if (handle)
727 NtWaitForSingleObject( handle, FALSE, NULL );
728 NtClose( handle );
730 else
732 LARGE_INTEGER time;
734 /* Unix lock conflict, sleep a bit and retry */
735 time.QuadPart = 100 * (ULONGLONG)10000;
736 time.QuadPart = -time.QuadPart;
737 NtWaitForMultipleObjects( 0, NULL, FALSE, FALSE, &time );
743 /******************************************************************
744 * NtUnlockFile (NTDLL.@)
748 NTSTATUS WINAPI NtUnlockFile( HANDLE hFile, PIO_STATUS_BLOCK io_status,
749 PLARGE_INTEGER offset, PLARGE_INTEGER count,
750 PULONG key )
752 NTSTATUS status;
754 TRACE( "%p %lx%08lx %lx%08lx\n",
755 hFile, offset->s.HighPart, offset->s.LowPart, count->s.HighPart, count->s.LowPart );
757 if (io_status || key)
759 FIXME("Unimplemented yet parameter\n");
760 return STATUS_NOT_IMPLEMENTED;
763 SERVER_START_REQ( unlock_file )
765 req->handle = hFile;
766 req->offset_low = offset->s.LowPart;
767 req->offset_high = offset->s.HighPart;
768 req->count_low = count->s.LowPart;
769 req->count_high = count->s.HighPart;
770 status = wine_server_call( req );
772 SERVER_END_REQ;
773 return status;