Alexandre Julliard : ntdll: Implemented NtReadFileScatter.

Alexandre Julliard julliard at winehq.org
Sat Mar 15 05:53:46 CDT 2008


Module: wine
Branch: master
Commit: 81e4a0f6f30a6196de4a36496461be257b6d9885
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=81e4a0f6f30a6196de4a36496461be257b6d9885

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Mar 14 20:29:00 2008 +0100

ntdll: Implemented NtReadFileScatter.

---

 dlls/ntdll/file.c     |   85 +++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/ntdll/ntdll.spec |    8 ++--
 include/winternl.h    |    2 +-
 3 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index c7b944b..3b67832 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -715,6 +715,91 @@ err:
     return status;
 }
 
+
+/******************************************************************************
+ *  NtReadFileScatter   [NTDLL.@]
+ *  ZwReadFileScatter   [NTDLL.@]
+ */
+NTSTATUS WINAPI NtReadFileScatter( HANDLE file, HANDLE event, PIO_APC_ROUTINE apc, void *apc_user,
+                                   PIO_STATUS_BLOCK io_status, FILE_SEGMENT_ELEMENT *segments,
+                                   ULONG length, PLARGE_INTEGER offset, PULONG key )
+{
+    size_t page_size = getpagesize();
+    int result, unix_handle, needs_close;
+    unsigned int options;
+    NTSTATUS status;
+    ULONG pos = 0, total = 0;
+    enum server_fd_type type;
+    ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
+
+    TRACE( "(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!\n",
+           file, event, apc, apc_user, io_status, segments, length, offset, key);
+
+    if (length % page_size) return STATUS_INVALID_PARAMETER;
+    if (!io_status) return STATUS_ACCESS_VIOLATION;
+
+    status = server_get_unix_fd( file, FILE_READ_DATA, &unix_handle,
+                                 &needs_close, &type, &options );
+    if (status) return status;
+
+    if ((type != FD_TYPE_FILE) ||
+        (options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) ||
+        !(options & FILE_NO_INTERMEDIATE_BUFFERING))
+    {
+        status = STATUS_INVALID_PARAMETER;
+        goto error;
+    }
+
+    while (length)
+    {
+        if (offset && offset->QuadPart != (LONGLONG)-2 /* FILE_USE_FILE_POINTER_POSITION */)
+            result = pread( unix_handle, (char *)segments->Buffer + pos,
+                            page_size - pos, offset->QuadPart + total );
+        else
+            result = read( unix_handle, (char *)segments->Buffer + pos, page_size - pos );
+
+        if (result == -1)
+        {
+            if (errno == EINTR) continue;
+            status = FILE_GetNtStatus();
+            break;
+        }
+        if (!result)
+        {
+            status = STATUS_END_OF_FILE;
+            break;
+        }
+        total += result;
+        length -= result;
+        if ((pos += result) == page_size)
+        {
+            pos = 0;
+            segments++;
+        }
+    }
+
+    if (cvalue) NTDLL_AddCompletion( file, cvalue, status, total );
+
+ error:
+    if (needs_close) close( unix_handle );
+    if (status == STATUS_SUCCESS)
+    {
+        io_status->u.Status = status;
+        io_status->Information = total;
+        TRACE("= SUCCESS (%u)\n", total);
+        if (event) NtSetEvent( event, NULL );
+        if (apc) NtQueueApcThread( GetCurrentThread(), (PNTAPCFUNC)apc,
+                                   (ULONG_PTR)apc_user, (ULONG_PTR)io_status, 0 );
+    }
+    else
+    {
+        TRACE("= 0x%08x\n", status);
+        if (status != STATUS_PENDING && event) NtResetEvent( event, NULL );
+    }
+    return status;
+}
+
+
 /***********************************************************************
  *             FILE_AsyncWriteService      (INTERNAL)
  */
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 9385153..ebb65f4 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -275,8 +275,8 @@
 @ stdcall NtQueueApcThread(long ptr long long long)
 @ stdcall NtRaiseException(ptr ptr long)
 @ stub NtRaiseHardError
-@ stdcall NtReadFile(long long long long long long long long long)
-@ stub NtReadFileScatter
+@ stdcall NtReadFile(long long ptr ptr ptr ptr long ptr ptr)
+@ stdcall NtReadFileScatter(long long ptr ptr ptr ptr long ptr ptr)
 @ stub NtReadRequestData
 @ stdcall NtReadVirtualMemory(long ptr ptr long ptr)
 @ stub NtRegisterNewDevice
@@ -1118,8 +1118,8 @@
 @ stdcall ZwQueueApcThread(long ptr long long long) NtQueueApcThread
 @ stdcall ZwRaiseException(ptr ptr long) NtRaiseException
 @ stub ZwRaiseHardError
-@ stdcall ZwReadFile(long long long long long long long long long) NtReadFile
-# @ stub ZwReadFileScatter
+@ stdcall ZwReadFile(long long ptr ptr ptr ptr long ptr ptr) NtReadFile
+@ stdcall ZwReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) NtReadFileScatter
 @ stub ZwReadRequestData
 @ stdcall ZwReadVirtualMemory(long ptr ptr long ptr) NtReadVirtualMemory
 @ stub ZwRegisterNewDevice
diff --git a/include/winternl.h b/include/winternl.h
index d8d6469..5b54295 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1987,7 +1987,7 @@ NTSYSAPI NTSTATUS  WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,P
 NTSYSAPI NTSTATUS  WINAPI NtRaiseException(PEXCEPTION_RECORD,PCONTEXT,BOOL);
 NTSYSAPI NTSTATUS  WINAPI NtRaiseHardError(NTSTATUS,ULONG,PUNICODE_STRING,PVOID*,HARDERROR_RESPONSE_OPTION,PHARDERROR_RESPONSE);
 NTSYSAPI NTSTATUS  WINAPI NtReadFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,PLARGE_INTEGER,PULONG);
-NTSYSAPI NTSTATUS  WINAPI NtReadFileScatter(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,FILE_SEGMENT_ELEMENT,ULONG,PLARGE_INTEGER,PULONG);
+NTSYSAPI NTSTATUS  WINAPI NtReadFileScatter(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,FILE_SEGMENT_ELEMENT*,ULONG,PLARGE_INTEGER,PULONG);
 NTSYSAPI NTSTATUS  WINAPI NtReadRequestData(HANDLE,PLPC_MESSAGE,ULONG,PVOID,ULONG,PULONG);
 NTSYSAPI NTSTATUS  WINAPI NtReadVirtualMemory(HANDLE,const void*,void*,SIZE_T,SIZE_T*);
 NTSYSAPI NTSTATUS  WINAPI NtRegisterThreadTerminatePort(HANDLE);




More information about the wine-cvs mailing list