- got rid of include/async.h
- fixed some overlapped issues in socket handling
- moved kernel32.CancelIo implementation to ntdll

diff --git a/server/file.c b/server/file.c
index 352932f..2b7fb2e 100644
--- a/server/file.c
+++ b/server/file.c
@@ -50,7 +50,6 @@
 #include "handle.h"
 #include "thread.h"
 #include "request.h"
-#include "async.h"
 
 struct file
 {
@@ -58,8 +57,8 @@
     struct fd          *fd;         /* file descriptor for this file */
     unsigned int        access;     /* file access (GENERIC_READ/WRITE) */
     unsigned int        options;    /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
-    struct async_queue  read_q;
-    struct async_queue  write_q;
+    struct async       *read_q;
+    struct async       *write_q;
 };
 
 static void file_dump( struct object *obj, int verbose );
@@ -70,7 +69,8 @@
 static void file_poll_event( struct fd *fd, int event );
 static int file_flush( struct fd *fd, struct event **event );
 static int file_get_info( struct fd *fd );
-static void file_queue_async( struct fd *fd, void *ptr, unsigned int status, int type, int count );
+static void file_queue_async( struct fd *fd, void *apc, void *user, void* iosb, int type, int count );
+static void file_cancel_async( struct fd *fd );
 
 static const struct object_ops file_ops =
 {
@@ -90,7 +90,8 @@
     file_poll_event,              /* poll_event */
     file_flush,                   /* flush */
     file_get_info,                /* get_file_info */
-    file_queue_async              /* queue_async */
+    file_queue_async,             /* queue_async */
+    file_cancel_async             /* cancel_async */
 };
 
 static inline int is_overlapped( const struct file *file )
@@ -141,6 +142,7 @@
     case FILE_OVERWRITE:    flags = O_TRUNC; break;
     default:                set_error( STATUS_INVALID_PARAMETER ); goto error;
     }
+
     switch(access & (GENERIC_READ | GENERIC_WRITE))
     {
     case 0: break;
@@ -160,8 +162,7 @@
     file->options    = options;
     if (is_overlapped( file ))
     {
-        init_async_queue (&file->read_q);
-        init_async_queue (&file->write_q);
+        file->read_q = file->write_q = NULL;
     }
 
     /* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
@@ -236,14 +237,14 @@
     assert( file->obj.ops == &file_ops );
     if (is_overlapped( file ))
     {
-        if( IS_READY(file->read_q) && (POLLIN & event) )
+        if ( file->read_q && (POLLIN & event) )
         {
-            async_notify(file->read_q.head, STATUS_ALERTED);
+            async_terminate( file->read_q, STATUS_ALERTED );
             return;
         }
-        if( IS_READY(file->write_q) && (POLLOUT & event) )
+        if ( file->write_q && (POLLOUT & event) )
         {
-            async_notify(file->write_q.head, STATUS_ALERTED);
+            async_terminate( file->write_q, STATUS_ALERTED );
             return;
         }
     }
@@ -266,58 +267,53 @@
     else return 0;
 }
 
-static void file_queue_async(struct fd *fd, void *ptr, unsigned int status, int type, int count)
+static void file_queue_async( struct fd *fd, void *apc, void *user, void *iosb,
+                              int type, int count )
 {
     struct file *file = get_fd_user( fd );
-    struct async *async;
-    struct async_queue *q;
+    struct async **head;
+    int events;
 
     assert( file->obj.ops == &file_ops );
 
     if (!is_overlapped( file ))
     {
-        set_error ( STATUS_INVALID_HANDLE );
+        set_error( STATUS_INVALID_HANDLE );
         return;
     }
 
-    switch(type)
+    switch (type)
     {
     case ASYNC_TYPE_READ:
-        q = &file->read_q;
+        head = &file->read_q;
         break;
     case ASYNC_TYPE_WRITE:
-        q = &file->write_q;
+        head = &file->write_q;
         break;
     default:
         set_error( STATUS_INVALID_PARAMETER );
         return;
     }
 
-    async = find_async ( q, current, ptr );
+    if (!create_async( fd, current, 0, head, apc, user, iosb ))
+        return;
 
-    if ( status == STATUS_PENDING )
-    {
-        int events;
-
-        if ( !async )
-            async = create_async ( &file->obj, current, ptr );
-        if ( !async )
-            return;
-
-        async->status = STATUS_PENDING;
-        if ( !async->q )
-            async_insert( q, async );
-
-        /* Check if the new pending request can be served immediately */
-        events = check_fd_events( fd, file_get_poll_events( fd ) );
-        if (events) file_poll_event ( fd, events );
-    }
-    else if ( async ) destroy_async ( async );
-    else set_error ( STATUS_INVALID_PARAMETER );
+    /* Check if the new pending request can be served immediately */
+    events = check_fd_events( fd, file_get_poll_events( fd ) );
+    if (events) file_poll_event( fd, events );
 
     set_fd_events( fd, file_get_poll_events( fd ));
 }
 
+static void file_cancel_async( struct fd *fd )
+{
+    struct file *file = get_fd_user( fd );
+    assert( file->obj.ops == &file_ops );
+
+    async_terminate_queue( &file->read_q, STATUS_CANCELLED );
+    async_terminate_queue( &file->write_q, STATUS_CANCELLED );
+}
+
 static struct fd *file_get_fd( struct object *obj )
 {
     struct file *file = (struct file *)obj;
@@ -332,8 +328,8 @@
 
     if (is_overlapped( file ))
     {
-        destroy_async_queue (&file->read_q);
-        destroy_async_queue (&file->write_q);
+        async_terminate_queue( &file->read_q, STATUS_CANCELLED );
+        async_terminate_queue( &file->write_q, STATUS_CANCELLED );
     }
     if (file->fd) release_object( file->fd );
 }