diff -urN ../mywork/wine-1.1.24/configure wine-1.1.24-merge-clean/configure
--- ../mywork/wine-1.1.24/configure	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/configure	2009-11-09 13:54:53.000000000 +0900
@@ -692,6 +692,7 @@
 X_PRE_LIBS
 X_CFLAGS
 XMKMF
+LIBAIO
 LIBPTHREAD
 CROSSTARGETFLAGS
 CROSSTEST
@@ -5773,7 +5774,9 @@
 	lcms.h \
 	lcms/lcms.h \
 	ldap.h \
+	libaio.h	\
 	libaudioio.h \
+	libiocp.h	\
 	link.h \
 	linux/cdrom.h \
 	linux/compiler.h \
@@ -8460,6 +8463,94 @@
 
 
 
+if test "$ac_cv_header_libaio_h" = "yes"
+then
+    { $as_echo "$as_me:$LINENO: checking for io_setup in -laio" >&5
+$as_echo_n "checking for io_setup in -laio... " >&6; }
+if test "${ac_cv_lib_aio_io_setup+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-laio  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char io_setup ();
+int
+main ()
+{
+return io_setup ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  ac_cv_lib_aio_io_setup=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_aio_io_setup=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_aio_io_setup" >&5
+$as_echo "$ac_cv_lib_aio_io_setup" >&6; }
+if test "x$ac_cv_lib_aio_io_setup" = x""yes; then
+  LIBAIO="-laio"
+
+fi
+
+fi
+if test "x$LIBAIO" = "x"; then
+  case "x$with_aio" in
+  xno) ;;
+  *)   { { $as_echo "$as_me:$LINENO: error: aio ${notice_platform}development files not found.
+Wine cannot support network aio without libaio.
+Use the --without-aio option if you really want this." >&5
+$as_echo "$as_me: error: aio ${notice_platform}development files not found.
+Wine cannot support network aio without libaio.
+Use the --without-aio option if you really want this." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+fi
+
+
+
 { $as_echo "$as_me:$LINENO: checking for X" >&5
 $as_echo_n "checking for X... " >&6; }
 
diff -urN ../mywork/wine-1.1.24/configure.ac wine-1.1.24-merge-clean/configure.ac
--- ../mywork/wine-1.1.24/configure.ac	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/configure.ac	2009-11-09 13:54:53.000000000 +0900
@@ -296,7 +296,9 @@
 	lcms.h \
 	lcms/lcms.h \
 	ldap.h \
+	libaio.h	\
 	libaudioio.h \
+	libiocp.h	\
 	link.h \
 	linux/cdrom.h \
 	linux/compiler.h \
@@ -712,6 +714,15 @@
 WINE_ERROR_WITH(pthread,[test "x$LIBPTHREAD" = "x"],[pthread ${notice_platform}development files not found.
 Wine cannot support threads without libpthread.])
 
+dnl **** Check for libaio ****
+
+if test "$ac_cv_header_libaio_h" = "yes"
+then
+    AC_CHECK_LIB(aio,io_setup,[AC_SUBST(LIBAIO,"-laio")])
+fi
+WINE_ERROR_WITH(aio,[test "x$LIBAIO" = "x"],[aio ${notice_platform}development files not found.
+Wine cannot support network aio without libaio.])
+
 dnl **** Check for X11 ****
 
 AC_PATH_XTRA
diff -urN ../mywork/wine-1.1.24/dlls/kernel32/process.c wine-1.1.24-merge-clean/dlls/kernel32/process.c
--- ../mywork/wine-1.1.24/dlls/kernel32/process.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/kernel32/process.c	2009-11-09 13:56:18.000000000 +0900
@@ -1330,6 +1330,7 @@
             hstdin = wine_server_ptr_handle( console_handle_unmap( hstdin ));
         if (is_console_handle( hstdout ))
             hstdout = wine_server_ptr_handle( console_handle_unmap( hstdout ));
+//FIXME("hstdin : %ld, hstdout : %ld \n", hstdin, hstdout);
         wine_server_handle_to_fd( hstdin, FILE_READ_DATA, &stdin_fd, NULL );
         wine_server_handle_to_fd( hstdout, FILE_WRITE_DATA, &stdout_fd, NULL );
     }
@@ -1591,7 +1592,7 @@
         HeapFree( GetProcessHeap(), 0, winedebug );
         return FALSE;
     }
-
+//FIXME("hstdin : %ld , hstdout : %ld \n", hstdin, hstdout);
     if (hstdin) wine_server_handle_to_fd( hstdin, FILE_READ_DATA, &stdin_fd, NULL );
     if (hstdout) wine_server_handle_to_fd( hstdout, FILE_WRITE_DATA, &stdout_fd, NULL );
 
diff -urN ../mywork/wine-1.1.24/dlls/kernel32/sync.c wine-1.1.24-merge-clean/dlls/kernel32/sync.c
--- ../mywork/wine-1.1.24/dlls/kernel32/sync.c	2009-07-20 15:05:54.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/kernel32/sync.c	2009-11-09 13:54:53.000000000 +0900
@@ -2222,12 +2222,17 @@
 
     *lpOverlapped = NULL;
 
-    status = NtRemoveIoCompletion( CompletionPort, pCompletionKey, (PULONG_PTR)lpOverlapped,
+	status = NtRemoveIoCompletion( CompletionPort, pCompletionKey, (PULONG_PTR)lpOverlapped,
                                    &iosb, get_nt_timeout( &wait_time, dwMilliseconds ) );
+	TRACE("(status=%lu, iosb.Info=%ld)\n", (unsigned long)status, iosb.Information);
+
     if (status == STATUS_SUCCESS)
     {
         *lpNumberOfBytesTransferred = iosb.Information;
-        return TRUE;
+		if (iosb.u.Status == STATUS_SUCCESS)
+        	return TRUE;
+		else
+			return FALSE;
     }
 
     if (status == STATUS_TIMEOUT) SetLastError( WAIT_TIMEOUT );
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/directory.c wine-1.1.24-merge-clean/dlls/ntdll/directory.c
--- ../mywork/wine-1.1.24/dlls/ntdll/directory.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/directory.c	2009-11-09 13:56:18.000000000 +0900
@@ -1619,7 +1619,7 @@
         FIXME( "Unsupported file info class %d\n", info_class );
         return io->u.Status = STATUS_NOT_IMPLEMENTED;
     }
-
+//FIXME("handle : %ld \n", handle);
     if ((io->u.Status = server_get_unix_fd( handle, FILE_LIST_DIRECTORY, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS)
         return io->u.Status;
 
@@ -2164,7 +2164,7 @@
 {
     NTSTATUS status;
     int unix_fd, needs_close;
-
+//FIXME("handle : %ld \n", handle);
     if (!(status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL, NULL )))
     {
         struct stat st;
@@ -2247,6 +2247,7 @@
         if (status != STATUS_SUCCESS) goto done;
     }
 
+//FIXME("handle : %ld \n", handle);
     if ((status = server_get_unix_fd( handle, 0, &unix_fd, &needs_close, NULL, NULL )) == STATUS_SUCCESS)
     {
         RtlEnterCriticalSection( &dir_section );
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/file.c wine-1.1.24-merge-clean/dlls/ntdll/file.c
--- ../mywork/wine-1.1.24/dlls/ntdll/file.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/file.c	2009-11-09 14:09:21.000000000 +0900
@@ -90,6 +90,11 @@
 #define SECSPERDAY         86400
 #define SECS_1601_TO_1970  ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
 
+typedef struct _ASYNCBUF
+{
+	ULONG len;
+	CHAR* buf;
+} ASYNCBUF, *LPASYNCBUF;
 
 /**************************************************************************
  *                 FILE_CreateFile                    (internal)
@@ -104,7 +109,9 @@
 {
     ANSI_STRING unix_name;
     int created = FALSE;
-
+    int fd;
+    char * name;
+//FIXME( "thread id : %04x \n", GetCurrentThreadId());
     TRACE("handle=%p access=%08x name=%s objattr=%08x root=%p sec=%p io=%p alloc_size=%p\n"
           "attr=%08x sharing=%08x disp=%d options=%08x ea=%p.0x%08x\n",
           handle, access, debugstr_us(attr->ObjectName), attr->Attributes,
@@ -160,6 +167,10 @@
             }
         }
 
+	if (!(name = RtlAllocateHeap( GetProcessHeap(), 0, unix_name.Length )))
+        	return STATUS_NO_MEMORY;
+//FIXME("name : %s unix_name.Buffer : %s unix_name.Length : %d \n", name, unix_name.Buffer, unix_name.Length);
+//	server_enter_critical_section();
         SERVER_START_REQ( create_file )
         {
             req->access     = access;
@@ -173,8 +184,23 @@
             wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
             io->u.Status = wine_server_call( req );
             *handle = wine_server_ptr_handle( reply->handle );
+	    if(*handle)
+	    {
+	    	if ((fd = get_fd_file( name, unix_name.Length )) != -1)
+            	{
+		    if( strncmp (name, unix_name.Buffer, unix_name.Length) == 0 )
+	            	add_fd_to_cache_at_file( *handle, fd, reply->type, reply->access, reply->options );
+		    
+//FIXME("not equal : name : %s, unix_name.Buffer : %s \n", name, unix_name.Buffer);
+//FIXME( "handle:%ld, unix_fd: %d, type:%d, removable:%d, access:%d, options:%d \n", *handle, fd, reply->type, reply->removable, reply->access, reply->options );
+		}
+	    }
+
         }
         SERVER_END_REQ;
+//	server_leave_critical_section();
+		if(name)
+			RtlFreeHeap( GetProcessHeap(), 0, name );
         NTDLL_free_struct_sd( sd );
         RtlFreeAnsiString( &unix_name );
     }
@@ -205,6 +231,7 @@
     return io->u.Status;
 }
 
+
 /**************************************************************************
  *                 NtOpenFile				[NTDLL.@]
  *                 ZwOpenFile				[NTDLL.@]
@@ -227,6 +254,7 @@
                             POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
                             ULONG sharing, ULONG options )
 {
+	//FIXME( " \n" );
     return FILE_CreateFile( handle, access, attr, io, NULL, 0,
                             sharing, FILE_OPEN, options, NULL, 0 );
 }
@@ -260,6 +288,7 @@
                               ULONG attributes, ULONG sharing, ULONG disposition,
                               ULONG options, PVOID ea_buffer, ULONG ea_length )
 {
+	//FIXME( " \n" );
     return FILE_CreateFile( handle, access, attr, io, alloc_size, attributes,
                             sharing, disposition, options, ea_buffer, ea_length );
 }
@@ -358,6 +387,8 @@
     switch (status)
     {
     case STATUS_ALERTED: /* got some new data */
+//FIXME("handle : %ld \n", fileio->io.handle);
+
         /* check to see if the data is ready (non-blocking) */
         if ((status = server_get_unix_fd( fileio->io.handle, FILE_READ_DATA, &fd,
                                           &needs_close, NULL, NULL )))
@@ -539,6 +570,119 @@
     return status;
 }
 
+/* only in case file=socket && overlapped!=NULL && hEvent==0 */
+NTSTATUS WINAPI	AsyncSockRead(int fd, void* overlapped, void* bufs, DWORD dwBufferCount)
+{
+	int i, ret;
+	struct iocb *iocb;
+	LPASYNCBUF buffers = (LPASYNCBUF) bufs;
+
+	TRACE("%d, %p, %p, %d\n", fd, overlapped, bufs, dwBufferCount);
+
+	if (!buffers) {
+		return STATUS_INVALID_PARAMETER;
+	}
+
+	if ((iocb = (struct iocb *)malloc(sizeof(struct iocb) * dwBufferCount)) == NULL)
+	{
+		return FILE_GetNtStatus();
+	}
+	memset(iocb, 0, sizeof(struct iocb)*dwBufferCount);
+	for (i=0; i < dwBufferCount; i++)
+	{
+		iocb[i].aio_fildes = fd;
+		iocb[i].aio_lio_opcode = IO_CMD_PREAD;
+		iocb[i].aio_reqprio = 0;
+		iocb[i].u.c.buf = (void *)buffers[i].buf;
+		iocb[i].u.c.nbytes = (size_t)buffers[i].len;
+		iocb[i].u.c.offset = (long long)0;
+		iocb[i].data = overlapped;
+	}
+
+	if (!async_ctx.ioctx) {
+		TRACE("ioctx==0\n");
+		pthread_mutex_lock(&async_ctx.mutex);
+		if (async_ctx.ioctx) {
+			pthread_mutex_unlock(&async_ctx.mutex);
+		}
+		else {
+			if ((ret = io_setup(IOCTX_MAXEVENTS, &async_ctx.ioctx)) < 0) {
+				perror("io_setup FAIL");
+				fprintf(stderr, "pid=%d,ret=%d\n", getpid(), ret);
+				pthread_mutex_unlock(&async_ctx.mutex);
+				return FILE_GetNtStatus();
+			}
+			else
+				TRACE("after io_setup,ioctx=%lu,ret=%d\n", (unsigned long)async_ctx.ioctx, ret);
+			pthread_mutex_unlock(&async_ctx.mutex);
+		}
+	}
+	TRACE("calling io_submit(ioctx=%lu)\n", (unsigned long)async_ctx.ioctx);
+	if (dwBufferCount != io_submit(async_ctx.ioctx, (long)dwBufferCount, &iocb)) {
+		perror("io_submit FAIL\n");
+		free(iocb);
+		return FILE_GetNtStatus();
+	}
+
+	return STATUS_PENDING;
+}
+
+/* only in case file=socket && overlapped!=NULL && hEvent==0 */
+NTSTATUS WINAPI	AsyncSockWrite(int fd, void* overlapped, void* bufs, DWORD dwBufferCount)
+{
+	int i, ret;
+	struct iocb *iocb;
+	LPASYNCBUF buffers = (LPASYNCBUF) bufs;
+
+	TRACE("%d, %p, %p, %d\n", fd, overlapped, bufs, dwBufferCount);
+
+	if (!buffers) {
+		return STATUS_INVALID_PARAMETER;
+	}
+
+	if ((iocb = (struct iocb *)malloc(sizeof(struct iocb) * dwBufferCount)) == NULL)
+	{
+		return FILE_GetNtStatus();
+	}
+	memset(iocb, 0, sizeof(struct iocb)*dwBufferCount);
+	for (i=0; i < dwBufferCount; i++)
+	{
+		iocb[i].aio_fildes = fd;
+		iocb[i].aio_lio_opcode = IO_CMD_PWRITE;
+		iocb[i].aio_reqprio = 0;
+		iocb[i].u.c.buf = (void *)buffers[i].buf;
+		iocb[i].u.c.nbytes = (size_t)buffers[i].len;
+		iocb[i].u.c.offset = (long long)0;
+		iocb[i].data = overlapped;
+	}
+
+	if (!async_ctx.ioctx) {
+		TRACE("ioctx==0\n");
+		pthread_mutex_lock(&async_ctx.mutex);
+		if (async_ctx.ioctx) {
+			pthread_mutex_unlock(&async_ctx.mutex);
+		}
+		else {
+			if ((ret = io_setup(IOCTX_MAXEVENTS, &async_ctx.ioctx)) < 0) {
+				perror("io_setup FAIL");
+				fprintf(stderr, "pid=%d,ret=%d\n", getpid(), ret);
+				pthread_mutex_unlock(&async_ctx.mutex);
+				return FILE_GetNtStatus();
+			}
+			else
+				TRACE("after io_setup,ioctx=%lu,ret=%d\n", (unsigned long)async_ctx.ioctx, ret);
+			pthread_mutex_unlock(&async_ctx.mutex);
+		}
+	}
+	TRACE("calling io_submit(ioctx=%lu)\n", (unsigned long)async_ctx.ioctx);
+	if (dwBufferCount != io_submit(async_ctx.ioctx, (long)dwBufferCount, &iocb)) {
+		perror("io_submit FAIL\n");
+		free(iocb);
+		return FILE_GetNtStatus();
+	}
+
+	return STATUS_PENDING;
+}
 
 /******************************************************************************
  *  NtReadFile					[NTDLL.@]
@@ -574,16 +718,30 @@
     ULONG total = 0;
     enum server_fd_type type;
     ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
+	ASYNCBUF buf;
 
     TRACE("(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p),partial stub!\n",
           hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
 
     if (!io_status) return STATUS_ACCESS_VIOLATION;
 
+//FIXME("handle : %ld \n", hFile);
     status = server_get_unix_fd( hFile, FILE_READ_DATA, &unix_handle,
                                  &needs_close, &type, &options );
     if (status) return status;
 
+	/* FD_TYPE_SOCKET && (hEvent&1 == 0) && overlapped && WSA_FLAG_OVERLAPPED */
+	if (type == FD_TYPE_SOCKET && apc_user && 
+		!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) {
+		TRACE("(Calling AsyncSockRead)\n");
+		buf.buf = buffer;
+		buf.len = length;
+		status = AsyncSockRead(unix_handle, apc_user, (void *)&buf, 1);
+		goto err;
+	}
+	else
+		TRACE("Not Calling AsyncSockRead\n");
+
     if (!virtual_check_buffer_for_write( buffer, length ))
     {
         status = STATUS_ACCESS_VIOLATION;
@@ -765,7 +923,7 @@
 
     if (length % page_size) return STATUS_INVALID_PARAMETER;
     if (!io_status) return STATUS_ACCESS_VIOLATION;
-
+//FIXME("handle : %ld \n", file);
     status = server_get_unix_fd( file, FILE_READ_DATA, &unix_handle,
                                  &needs_close, &type, &options );
     if (status) return status;
@@ -841,6 +999,7 @@
     {
     case STATUS_ALERTED:
         /* write some data (non-blocking) */
+//FIXME("handle : %ld \n", fileio->io.handle);
         if ((status = server_get_unix_fd( fileio->io.handle, FILE_WRITE_DATA, &fd,
                                           &needs_close, &type, NULL )))
             break;
@@ -913,16 +1072,30 @@
     ULONG total = 0;
     enum server_fd_type type;
     ULONG_PTR cvalue = apc ? 0 : (ULONG_PTR)apc_user;
+	ASYNCBUF buf;
 
     TRACE("(%p,%p,%p,%p,%p,%p,0x%08x,%p,%p)!\n",
           hFile,hEvent,apc,apc_user,io_status,buffer,length,offset,key);
 
     if (!io_status) return STATUS_ACCESS_VIOLATION;
 
+//FIXME("handle : %ld \n", hFile);
     status = server_get_unix_fd( hFile, FILE_WRITE_DATA, &unix_handle,
                                  &needs_close, &type, &options );
     if (status) return status;
 
+	/* FD_TYPE_SOCKET && (hEvent&1 == 0) && overlapped && WSA_FLAG_OVERLAPPED */
+    if (type == FD_TYPE_SOCKET && apc_user &&
+        !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))) {
+        TRACE("(Calling AsyncSockWrite)\n");
+        buf.buf = buffer;
+        buf.len = length;
+        status = AsyncSockWrite(unix_handle, apc_user, (void *)&buf, 1);
+        goto err;
+    }
+    else
+        TRACE("Not Calling AsyncSockWrite\n");
+
     if (!virtual_check_buffer_for_read( buffer, length ))
     {
         status = STATUS_INVALID_USER_BUFFER;
@@ -1090,6 +1263,7 @@
     if (length % page_size) return STATUS_INVALID_PARAMETER;
     if (!io_status) return STATUS_ACCESS_VIOLATION;
 
+//FIXME("handle : %ld \n", file);
     status = server_get_unix_fd( file, FILE_WRITE_DATA, &unix_handle,
                                  &needs_close, &type, &options );
     if (status) return status;
@@ -1375,6 +1549,7 @@
                 status = STATUS_INFO_LENGTH_MISMATCH;
                 break;
             }
+//FIXME("handle : %ld \n", handle);
 
             if ((status = server_get_unix_fd( handle, FILE_READ_DATA, &fd, &needs_close, NULL, NULL )))
                 break;
@@ -1566,6 +1741,7 @@
 
     if (class != FilePipeLocalInformation)
     {
+//FIXME("handle : %ld \n", hFile);
         if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, NULL )))
             return io->u.Status;
     }
@@ -1736,6 +1912,7 @@
                 if ((tmpbuf = RtlAllocateHeap( GetProcessHeap(), 0, size )))
                 {
                     int fd, needs_close;
+//FIXME("handle : %ld \n", hFile);
                     if (!server_get_unix_fd( hFile, FILE_READ_DATA, &fd, &needs_close, NULL, NULL ))
                     {
                         int res = recv( fd, tmpbuf, size, MSG_PEEK );
@@ -1816,7 +1993,7 @@
         {
             struct stat st;
             const FILE_BASIC_INFORMATION *info = ptr;
-
+//FIXME("handle : %ld \n", handle);
             if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
                 return io->u.Status;
 
@@ -1881,7 +2058,7 @@
         if (len >= sizeof(FILE_POSITION_INFORMATION))
         {
             const FILE_POSITION_INFORMATION *info = ptr;
-
+//FIXME("handle : %ld \n", handle);
             if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
                 return io->u.Status;
 
@@ -1898,7 +2075,7 @@
         {
             struct stat st;
             const FILE_END_OF_FILE_INFORMATION *info = ptr;
-
+//FIXME("handle : %ld \n", handle);
             if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
                 return io->u.Status;
 
@@ -1941,15 +2118,45 @@
         if (len >= sizeof(FILE_COMPLETION_INFORMATION))
         {
             FILE_COMPLETION_INFORMATION *info = ptr;
+			io_port_t iocp;
+			int fd;
 
             SERVER_START_REQ( set_completion_info )
             {
-                req->handle   = wine_server_obj_handle( handle );
-                req->chandle  = wine_server_obj_handle( info->CompletionPort );
-                req->ckey     = info->CompletionKey;
+                req->handle  = wine_server_obj_handle( info->CompletionPort );
                 io->u.Status  = wine_server_call( req );
+
+				iocp = reply->iocp;
             }
             SERVER_END_REQ;
+			if (io->u.Status || !iocp)
+				return STATUS_INVALID_PARAMETER;
+
+            if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
+                return io->u.Status;
+
+    		TRACE("(iocp=0x%08x,fd=%d)\n", (unsigned int)iocp, fd);
+			if (cp_add_file_to_port(iocp, fd, info->CompletionKey)) {
+				perror("cp_add_file_to_port fail");
+				switch(errno) {
+				case ENOMEM:
+					io->u.Status = STATUS_NO_MEMORY;
+					break;
+				case EINVAL:
+				case EBADF:
+					io->u.Status = STATUS_INVALID_PARAMETER;
+					break;
+				default:
+					io->u.Status = STATUS_UNSUCCESSFUL;
+					break;
+				}
+			}
+			else {
+				TRACE("(cp_add_file_to_port success)");
+			}
+
+			if (needs_close) close(fd);
+
         } else
             io->u.Status = STATUS_INVALID_PARAMETER_3;
         break;
@@ -2093,7 +2300,7 @@
 static NTSTATUS get_device_info( int fd, FILE_FS_DEVICE_INFORMATION *info )
 {
     struct stat st;
-
+//FIXME ("fd: %d, info : %p \n", fd, info);
     info->Characteristics = 0;
     if (fstat( fd, &st ) < 0) return FILE_GetNtStatus();
     if (S_ISCHR( st.st_mode ))
@@ -2215,6 +2422,7 @@
 #endif
         info->Characteristics |= FILE_DEVICE_IS_MOUNTED;
     }
+//FIXME ("fd: %d, info : %p \n", fd, info);
     return STATUS_SUCCESS;
 }
 
@@ -2242,13 +2450,14 @@
 {
     int fd, needs_close;
     struct stat st;
-
+//FIXME("handle : %ld \n", handle);
     if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS)
         return io->u.Status;
 
     io->u.Status = STATUS_NOT_IMPLEMENTED;
     io->Information = 0;
 
+//FIXME("handle : %ld, fd : %d \n", handle, fd);
     switch( info_class )
     {
     case FileFsVolumeInformation:
@@ -2258,6 +2467,7 @@
         FIXME( "%p: label info not supported\n", handle );
         break;
     case FileFsSizeInformation:
+//FIXME("fs size handle : %ld, fd : %d \n", handle, fd);
         if (length < sizeof(FILE_FS_SIZE_INFORMATION))
             io->u.Status = STATUS_BUFFER_TOO_SMALL;
         else
@@ -2313,6 +2523,7 @@
         }
         break;
     case FileFsDeviceInformation:
+//FIXME("fs device  handle : %ld, fd : %d \n", handle, fd);
         if (length < sizeof(FILE_FS_DEVICE_INFORMATION))
             io->u.Status = STATUS_BUFFER_TOO_SMALL;
         else
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/Makefile.in wine-1.1.24-merge-clean/dlls/ntdll/Makefile.in
--- ../mywork/wine-1.1.24/dlls/ntdll/Makefile.in	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/Makefile.in	2009-11-09 13:54:53.000000000 +0900
@@ -5,7 +5,7 @@
 VPATH     = @srcdir@
 MODULE    = ntdll.dll
 IMPORTLIB = ntdll
-EXTRALIBS = @IOKITLIB@ @LIBPTHREAD@
+EXTRALIBS = @IOKITLIB@ @LIBPTHREAD@ @LIBAIO@
 EXTRADLLFLAGS = -Wl,--image-base,0x7bc00000
 
 C_SRCS = \
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/ntdll_misc.h wine-1.1.24-merge-clean/dlls/ntdll/ntdll_misc.h
--- ../mywork/wine-1.1.24/dlls/ntdll/ntdll_misc.h	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/ntdll_misc.h	2009-11-09 13:56:18.000000000 +0900
@@ -86,6 +86,18 @@
 extern int server_get_unix_fd( HANDLE handle, unsigned int access, int *unix_fd,
                                int *needs_close, enum server_fd_type *type, unsigned int *options );
 
+//modified by tm 09.09
+extern int get_fd_file( char * name, int len );
+extern int add_fd_to_cache_at_file( HANDLE handle, int fd, enum server_fd_type type, unsigned int access, unsigned int options );
+//modified by tm 09.09
+//modified by tm 09.09
+//extern int get_fd_sock( obj_handle_t *handle);
+//extern int add_sock_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type, unsigned int access, unsigned int options );
+
+//extern void server_enter_critical_section();
+//extern void server_leave_critical_section();
+//modified by tm 09.09
+
 /* security descriptors */
 NTSTATUS NTDLL_create_struct_sd(PSECURITY_DESCRIPTOR nt_sd, struct security_descriptor **server_sd,
                                 data_size_t *server_sd_len);
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/ntdll.spec wine-1.1.24-merge-clean/dlls/ntdll/ntdll.spec
--- ../mywork/wine-1.1.24/dlls/ntdll/ntdll.spec	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/ntdll.spec	2009-11-09 13:56:18.000000000 +0900
@@ -275,6 +275,8 @@
 @ stdcall NtQueueApcThread(long ptr long long long)
 @ stdcall NtRaiseException(ptr ptr long)
 @ stub NtRaiseHardError
+@ stdcall AsyncSockRead(long ptr ptr long)
+@ stdcall AsyncSockWrite(long ptr ptr long)
 @ stdcall NtReadFile(long long ptr ptr ptr ptr long ptr ptr)
 @ stdcall NtReadFileScatter(long long ptr ptr ptr ptr long ptr ptr)
 @ stub NtReadRequestData
@@ -1381,6 +1383,10 @@
 @ cdecl wine_server_release_fd(long long)
 @ cdecl wine_server_send_fd(long)
 @ cdecl __wine_make_process_system()
+@ cdecl get_fd_sock(ptr)
+@ cdecl add_sock_fd_to_cache(long long long long long)
+@ cdecl server_enter_critical_section()
+@ cdecl server_leave_critical_section()
 
 # Version
 @ cdecl wine_get_version() NTDLL_wine_get_version
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/om.c wine-1.1.24-merge-clean/dlls/ntdll/om.c
--- ../mywork/wine-1.1.24/dlls/ntdll/om.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/om.c	2009-11-09 13:56:18.000000000 +0900
@@ -299,9 +299,11 @@
     NTSTATUS ret;
     int fd = server_remove_fd_from_cache( Handle );
 
+//FIXME( "fd : %d, handle: %ld \n", fd, Handle );
     SERVER_START_REQ( close_handle )
     {
         req->handle = wine_server_obj_handle( Handle );
+//FIXME( "handle : %ld \n", req->handle );
         ret = wine_server_call( req );
     }
     SERVER_END_REQ;
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/process.c wine-1.1.24-merge-clean/dlls/ntdll/process.c
--- ../mywork/wine-1.1.24/dlls/ntdll/process.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/process.c	2009-11-09 13:54:53.000000000 +0900
@@ -27,6 +27,10 @@
 #include <string.h>
 #include <time.h>
 
+#ifdef HAVE_LIBAIO_H
+#include <libaio.h>
+#endif
+
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "wine/debug.h"
@@ -58,6 +62,10 @@
         self = !ret && reply->self;
     }
     SERVER_END_REQ;
+
+	if (async_ctx.ioctx) {
+		io_destroy(async_ctx.ioctx);
+	}
     if (self) exit( exit_code );
     return ret;
 }
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/server.c wine-1.1.24-merge-clean/dlls/ntdll/server.c
--- ../mywork/wine-1.1.24/dlls/ntdll/server.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/server.c	2009-11-10 14:25:34.000000000 +0900
@@ -33,6 +33,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #ifdef HAVE_SYS_SOCKET_H
 # include <sys/socket.h>
 #endif
@@ -58,6 +59,9 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
+#ifdef HAVE_LIBAIO_H
+#include <libaio.h>
+#endif
 
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
@@ -120,6 +124,7 @@
 };
 static RTL_CRITICAL_SECTION fd_cache_section = { &critsect_debug, -1, 0, 0, 0, 0 };
 
+ASYNCCTX async_ctx = {0, PTHREAD_MUTEX_INITIALIZER};
 
 #ifdef __GNUC__
 static void fatal_error( const char *err, ... ) __attribute__((noreturn, format(printf,1,2)));
@@ -284,7 +289,7 @@
 {
     struct __server_request_info * const req = req_ptr;
     sigset_t old_set;
-    unsigned int ret;
+    register unsigned int ret;
 
     pthread_sigmask( SIG_BLOCK, &server_block_set, &old_set );
     ret = send_request( req );
@@ -313,6 +318,27 @@
     pthread_sigmask( SIG_SETMASK, sigset, NULL );
 }
 
+/***********************************************************************
+ *           call server_enter_uninterrupted_section
+ */
+void CDECL server_enter_critical_section( )
+{
+    sigset_t sigset;
+    server_enter_uninterrupted_section( &fd_cache_section, &sigset );    
+//server_enter_uninterrupted_section(&fd_cache_section, &sigset);
+}
+
+
+/***********************************************************************
+ *         call server_leave_uninterrupted_section
+ */
+void CDECL server_leave_critical_section( )
+{
+    sigset_t sigset;
+    server_leave_uninterrupted_section(&fd_cache_section, &sigset);
+}
+
+
 
 /***********************************************************************
  *           wine_server_send_fd   (NTDLL.@)
@@ -369,6 +395,74 @@
     }
 }
 
+// modified by tm 09.09
+
+/***********************************************************************
+ *           receive_fd_file
+ *
+ * Receive a file descriptor passed from the server.
+ * 	api => create_file, open_file_object
+ */
+static int receive_fd_file( char * name, int len )
+{
+    struct iovec vec;
+    int ret, fd;
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
+    struct msghdr msghdr;
+
+    fd = -1;
+    msghdr.msg_accrights    = (void *)&fd;
+    msghdr.msg_accrightslen = sizeof(fd);
+#else  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+    struct msghdr msghdr;
+    struct cmsg_fd cmsg;
+
+    cmsg.header.len   = sizeof(cmsg.header) + sizeof(fd);
+    cmsg.header.level = SOL_SOCKET;
+    cmsg.header.type  = SCM_RIGHTS;
+    cmsg.fd           = -1;
+    msghdr.msg_control    = &cmsg;
+    msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
+    msghdr.msg_flags      = 0;
+#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+
+    msghdr.msg_name    = NULL;
+    msghdr.msg_namelen = 0;
+    msghdr.msg_iov     = &vec;
+    msghdr.msg_iovlen  = 1;
+    vec.iov_base = (void *)name;
+    vec.iov_len  = len;
+
+    for (;;)
+    {
+        if ((ret = recvmsg( fd_socket, &msghdr, 0 )) > 0)
+        {
+#ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
+            fd = cmsg.fd;
+#endif
+            if (fd != -1) fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
+//FIXME( "server.c : receive_fd => fd : %d, len : %d \n", fd, len );
+            return fd;
+        }
+//FIXME( "server.c : receive_fd_file => ret : %d \n", ret );
+        if (!ret) break;
+        if (errno == EINTR) continue;
+        if (errno == EPIPE) break;
+//FIXME( "server.c : receive_fd_file \n" );
+        server_protocol_perror("recvmsg");
+    }
+    /* the server closed the connection; time to die... */
+    abort_thread(0);
+}
+
+
+int get_fd_file( char * name, int len )
+{
+	return receive_fd_file( name, len );
+}
+// modified by tm 09.09
+
 
 /***********************************************************************
  *           receive_fd
@@ -398,6 +492,7 @@
     msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
     msghdr.msg_flags      = 0;
 #endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+//FIXME( "server.c : receive_fd => fd : %p \n", &fd );
 
     msghdr.msg_name    = NULL;
     msghdr.msg_namelen = 0;
@@ -412,10 +507,13 @@
         {
 #ifndef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
             fd = cmsg.fd;
+//FIXME( "server.c : receive_fd1 => fd : %d, handle : %ld \n", fd, *handle );
 #endif
             if (fd != -1) fcntl( fd, F_SETFD, 1 ); /* set close on exec flag */
+//FIXME( "server.c : receive_fd => fd : %d, handle : %ld \n", fd, *handle );
             return fd;
         }
+//FIXME( "server.c : receive_fd => ret : %d \n", ret );
         if (!ret) break;
         if (errno == EINTR) continue;
         if (errno == EPIPE) break;
@@ -425,6 +523,12 @@
     abort_thread(0);
 }
 
+// modified by tm 09.09
+int CDECL get_fd_sock( obj_handle_t *handle)
+{
+	return receive_fd( handle );
+}
+// modified by tm 09.09
 
 /***********************************************************************/
 /* fd cache support */
@@ -461,7 +565,8 @@
 {
     unsigned int entry, idx = handle_to_index( handle, &entry );
     int prev_fd;
-
+//FIXME("fd cache index : %d, thread id : %04x  \n", entry, GetCurrentThreadId()); 
+//FIXME("handle : %ld, fd : %d  \n", handle, fd); 
     if (entry >= FD_CACHE_ENTRIES)
     {
         FIXME( "too many allocated handles, not caching %p\n", handle );
@@ -488,6 +593,27 @@
     return 1;
 }
 
+// modified by tm 09.09
+int add_fd_to_cache_at_file( HANDLE handle, int fd, enum server_fd_type type,
+                            unsigned int access, unsigned int options )
+{	
+    	int ret;
+	sigset_t sigset;
+    	server_enter_uninterrupted_section( &fd_cache_section, &sigset );
+	ret = add_fd_to_cache( handle, fd, type, access, options );
+    	server_leave_uninterrupted_section( &fd_cache_section, &sigset );
+	return ret;
+}
+// modified by tm 09.09
+// modified by tm 09.09
+int CDECL add_sock_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type,
+                            unsigned int access, unsigned int options )
+{
+	int ret;
+	ret = add_fd_to_cache( handle, fd, type, access, options );
+	return ret;
+}
+// modified by tm 09.09
 
 /***********************************************************************
  *           get_cached_fd
@@ -529,7 +655,7 @@
 /***********************************************************************
  *           server_get_unix_fd
  *
- * The returned unix_fd should be closed iff needs_close is non-zero.
+ * The returned unix_fd should be closed if needs_close is non-zero.
  */
 int server_get_unix_fd( HANDLE handle, unsigned int wanted_access, int *unix_fd,
                         int *needs_close, enum server_fd_type *type, unsigned int *options )
@@ -543,14 +669,19 @@
     *needs_close = 0;
     wanted_access &= FILE_READ_DATA | FILE_WRITE_DATA;
 
+
+    struct timeval start, end, result;
+	gettimeofday(&start, NULL);
     server_enter_uninterrupted_section( &fd_cache_section, &sigset );
 
     fd = get_cached_fd( handle, type, &access, options );
+//FIXME( "========================>cached handle :%ld, fd : %d, thread id : %04x \n", handle, fd, GetCurrentThreadId());
     if (fd != -1) goto done;
 
     SERVER_START_REQ( get_handle_fd )
     {
         req->handle = wine_server_obj_handle( handle );
+//FIXME( "========================>handle :%ld, req->handle : %ld \n", handle, req->handle);
         if (!(ret = wine_server_call( req )))
         {
             if (type) *type = reply->type;
@@ -558,10 +689,13 @@
             access = reply->access;
             if ((fd = receive_fd( &fd_handle )) != -1)
             {
+//FIXME( "handle:%ld, unix_fd: %d \n", fd_handle, fd );
                 assert( wine_server_ptr_handle(fd_handle) == handle );
                 *needs_close = (reply->removable ||
                                 !add_fd_to_cache( handle, fd, reply->type,
                                                   reply->access, reply->options ));
+//FIXME( "========================>cached handle2 :%ld, fd : %d, thread id : %04x \n", handle, fd, GetCurrentThreadId());
+//FIXME( "handle:%ld, unix_fd: %d, type:%d, removable:%d, access:%d, options:%d \n", handle, fd, reply->type, reply->removable, reply->access, reply->options );
             }
             else ret = STATUS_TOO_MANY_OPENED_FILES;
         }
@@ -570,6 +704,11 @@
 
 done:
     server_leave_uninterrupted_section( &fd_cache_section, &sigset );
+	gettimeofday(&end, NULL);
+	timersub(&end, &start, &result);
+	double time = result.tv_sec + (double)result.tv_usec/1000000;
+//FIXME( "get fd time : %f \n", time );
+
     if (!ret && ((access & wanted_access) != wanted_access))
     {
         ret = STATUS_ACCESS_DENIED;
@@ -630,7 +769,9 @@
 int CDECL wine_server_handle_to_fd( HANDLE handle, unsigned int access, int *unix_fd,
                               unsigned int *options )
 {
+//FIXME("handle : %ld \n", handle);
     int needs_close, ret = server_get_unix_fd( handle, access, unix_fd, &needs_close, NULL, options );
+//FIXME("handle : %ld, unix_fd : %d \n", handle, *unix_fd);
 
     if (!ret && !needs_close)
     {
@@ -929,6 +1070,7 @@
 {
     obj_handle_t version;
     const char *env_socket = getenv( "WINESERVERSOCKET" );
+	int ret;
 
     if (env_socket)
     {
@@ -963,6 +1105,14 @@
 #ifdef __APPLE__
     send_server_task_port();
 #endif
+
+/*	if (!ioctx) {
+		if ((ret = io_setup(IOCTX_MAXEVENTS, &ioctx)) < 0) {
+			perror("io_setup fail");
+		}
+		TRACE("after io_setup,ioctx=%lu,ret=%d\n", (unsigned long)ioctx, ret);
+	}
+*/
 }
 
 
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/sync.c wine-1.1.24-merge-clean/dlls/ntdll/sync.c
--- ../mywork/wine-1.1.24/dlls/ntdll/sync.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/sync.c	2009-11-09 13:54:53.000000000 +0900
@@ -58,6 +58,10 @@
 #include "wine/debug.h"
 #include "ntdll_misc.h"
 
+#ifdef HAVE_LIBIOCP_H
+#include <libiocp.h>
+#endif
+
 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
 
 /* creates a struct security_descriptor and contained information in one contiguous piece of memory */
@@ -1264,6 +1268,7 @@
                                       POBJECT_ATTRIBUTES ObjectAttributes, ULONG NumberOfConcurrentThreads )
 {
     NTSTATUS status;
+	io_port_t iocp = 0;
 
     TRACE("(%p, %x, %p, %d)\n", CompletionPort, DesiredAccess,
           ObjectAttributes, NumberOfConcurrentThreads);
@@ -1271,12 +1276,17 @@
     if (!CompletionPort)
         return STATUS_INVALID_PARAMETER;
 
+	if (cp_create_port((unsigned int)NumberOfConcurrentThreads, &iocp))
+		return errno;
+
+	TRACE("(iocp=%lx)\n", iocp);
     SERVER_START_REQ( create_completion )
     {
         req->access     = DesiredAccess;
         req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
         req->rootdir    = wine_server_obj_handle( ObjectAttributes ? ObjectAttributes->RootDirectory : 0 );
         req->concurrent = NumberOfConcurrentThreads;
+		req->iocp = iocp;
         if (ObjectAttributes && ObjectAttributes->ObjectName)
             wine_server_add_data( req, ObjectAttributes->ObjectName->Buffer,
                                        ObjectAttributes->ObjectName->Length );
@@ -1300,7 +1310,7 @@
  *      Status                   [I] operation status
  *      NumberOfBytesTransferred [I] number of bytes transferred
  */
-NTSTATUS WINAPI NtSetIoCompletion( HANDLE CompletionPort, ULONG_PTR CompletionKey,
+/*NTSTATUS WINAPI NtSetIoCompletion( HANDLE CompletionPort, ULONG_PTR CompletionKey,
                                    ULONG_PTR CompletionValue, NTSTATUS Status,
                                    ULONG NumberOfBytesTransferred )
 {
@@ -1321,6 +1331,59 @@
     SERVER_END_REQ;
     return status;
 }
+*/
+NTSTATUS WINAPI NtSetIoCompletion( HANDLE CompletionPort, ULONG_PTR CompletionKey,
+                                   ULONG_PTR CompletionValue, NTSTATUS Status,
+                                   ULONG NumberOfBytesTransferred )
+{
+    NTSTATUS status;
+	io_port_t iocp;
+	struct iocb *iocb;
+	struct cp_event event;
+
+    TRACE("(%p, %lx, %lx, %x, %d)\n", CompletionPort, CompletionKey,
+          CompletionValue, Status, NumberOfBytesTransferred);
+
+    SERVER_START_REQ( set_completion_info )
+    {
+        req->handle      = wine_server_obj_handle( CompletionPort );
+        status = wine_server_call( req );
+		iocp = reply->iocp;
+    }
+    SERVER_END_REQ;
+	if (status != STATUS_SUCCESS)
+		return status;
+	
+	iocb = (struct iocb *)malloc(sizeof(struct iocb));
+	if (!iocb)
+		return STATUS_NO_MEMORY;
+
+	iocb->data = (void *)CompletionValue;		/* overlapped */
+	event.result = NumberOfBytesTransferred;
+	event.completion_key = (void *)CompletionKey;
+	event.user = iocb;
+
+	if (!cp_post_completion_status(iocp, &event))
+		status = STATUS_SUCCESS;
+	else {
+		switch(errno) {
+		case EINVAL: 
+		case EFAULT:
+			status = STATUS_INVALID_PARAMETER; 
+			break;
+		case ENOMEM:
+			status = STATUS_NO_MEMORY; 
+			break;
+		default:
+			status = STATUS_UNSUCCESSFUL;
+			break;
+		}
+
+		free(iocb);
+	}
+
+    return status;
+}
 
 /******************************************************************
  *              NtRemoveIoCompletion (NTDLL.@)
@@ -1336,7 +1399,7 @@
  *      WaitTime        [I] optional wait time in NTDLL format
  *
  */
-NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE CompletionPort, PULONG_PTR CompletionKey,
+NTSTATUS WINAPI NtRemoveIoCompletion_org( HANDLE CompletionPort, PULONG_PTR CompletionKey,
                                       PULONG_PTR CompletionValue, PIO_STATUS_BLOCK iosb,
                                       PLARGE_INTEGER WaitTime )
 {
@@ -1367,6 +1430,99 @@
     return status;
 }
 
+NTSTATUS WINAPI NtRemoveIoCompletion( HANDLE CompletionPort, PULONG_PTR CompletionKey,
+                                      PULONG_PTR CompletionValue, PIO_STATUS_BLOCK iosb,
+                                      PLARGE_INTEGER WaitTime )
+{
+    NTSTATUS status;
+	io_port_t iocp;
+	struct cp_event event;
+	int ret;
+	struct timespec timeout;
+
+    TRACE("(%p, %p, %p, %p, %p)\n", CompletionPort, CompletionKey,
+          CompletionValue, iosb, WaitTime);
+
+	SERVER_START_REQ( set_completion_info )
+	{
+		req->handle	= wine_server_obj_handle( CompletionPort );
+		status 		= wine_server_call( req );
+		iocp		= reply->iocp;
+	}
+	SERVER_END_REQ;
+    TRACE("(iocp=%lx)\n", iocp);
+
+	if (status || !iocp) {
+		return STATUS_INVALID_HANDLE;
+	}
+
+	if (WaitTime == NULL) {		/* infinite */
+    	TRACE("(calling cp_get_completion_status)\n");
+		ret = cp_get_completion_status(iocp, &event, NULL);
+    	TRACE("(cp_get_completion_status, ret=%d, errno=%d)\n", ret, errno);
+	}
+	else {
+		timeout.tv_sec = (WaitTime->QuadPart/-10000)/1000;
+		timeout.tv_nsec = (WaitTime->QuadPart/-10)%1000000;
+
+    	TRACE("(calling cp_get_completion_status)\n");
+		ret = cp_get_completion_status(iocp, &event, &timeout);
+    	TRACE("(cp_get_completion_status, ret=%d, errno=%d)\n", ret, errno);
+	}
+	if (ret == 1) {
+		TRACE("(event.result=%lu,event.completion_key=%ld)\n",event.result, (unsigned long)event.completion_key);
+		iosb->Information	= event.result;
+		*CompletionKey		= (unsigned long)event.completion_key;
+		if (event.user) {
+			*CompletionValue	= (ULONG_PTR)(event.user)->data;
+			free(event.user);
+		}
+		else {
+			*CompletionValue	= 0;
+		}
+		
+		status = STATUS_SUCCESS;
+
+		if (event.result >= 0) {
+			iosb->u.Status = STATUS_SUCCESS;
+		}
+		else {
+			switch(event.result*(-1)) {
+			case EINVAL:
+				iosb->u.Status = STATUS_INVALID_PARAMETER;
+				break;
+			case EFAULT:
+				iosb->u.Status = STATUS_ACCESS_VIOLATION;
+				break;
+			case EINTR:
+			default:
+				iosb->u.Status = STATUS_UNSUCCESSFUL;
+				break;
+			}
+		}
+	}
+
+	else if (!ret) {	/* timeout */
+		status = STATUS_TIMEOUT;
+	}
+	else {
+		switch(errno) {
+			case EINVAL:
+				status = STATUS_INVALID_PARAMETER;
+				break;
+			case EFAULT:
+				status = STATUS_ACCESS_VIOLATION;
+				break;
+			case EINTR:
+			default:
+				status = STATUS_UNSUCCESSFUL;
+				break;
+		}
+	}
+
+    return status;
+}
+
 /******************************************************************
  *              NtOpenIoCompletion (NTDLL.@)
  *              ZwOpenIoCompletion (NTDLL.@)
@@ -1457,8 +1613,16 @@
                               NTSTATUS CompletionStatus, ULONG Information )
 {
     NTSTATUS status;
+	struct iocb *iocb;
+	int ret, result;
 
-    SERVER_START_REQ( add_fd_completion )
+	/*
+	hFile : file
+	CompletionVaule : overlapped
+	CompletionStatus : status(success or other)
+	Information : bytes sent(received)
+	*/
+   /* SERVER_START_REQ( add_fd_completion )
     {
         req->handle      = wine_server_obj_handle( hFile );
         req->cvalue      = CompletionValue;
@@ -1467,5 +1631,37 @@
         status = wine_server_call( req );
     }
     SERVER_END_REQ;
+	*/
+
+	if ((iocb = (struct iocb *)malloc(sizeof(struct iocb))) == NULL)
+	{
+		return STATUS_NO_MEMORY;
+	}
+	iocb->data = (void *)CompletionValue;
+
+	if (!Information && CompletionStatus)
+		result = errno*-1;
+	else
+		result = Information;
+	ret = aio_post_io_completion(wine_server_obj_handle(hFile), result, iocb);
+	if (!ret)
+		status = STATUS_SUCCESS;
+	else {
+		switch(errno) {
+		case EINVAL: 
+		case EFAULT:
+			status = STATUS_INVALID_PARAMETER; 
+			break;
+		case ENOMEM:
+			status = STATUS_NO_MEMORY; 
+			break;
+		default:
+			status = STATUS_UNSUCCESSFUL;
+			break;
+		}
+
+		free(iocb); 
+	}
+		
     return status;
 }
diff -urN ../mywork/wine-1.1.24/dlls/ntdll/tests/file.c wine-1.1.24-merge-clean/dlls/ntdll/tests/file.c
--- ../mywork/wine-1.1.24/dlls/ntdll/tests/file.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ntdll/tests/file.c	2009-11-09 13:56:18.000000000 +0900
@@ -721,7 +721,7 @@
     pNtSetInformationFile   = (void *)GetProcAddress(hntdll, "NtSetInformationFile");
 
     delete_file_test();
-    read_file_test();
+   /* read_file_test();
     nt_mailslot_test();
-    test_iocompletion();
+    test_iocompletion();*/
 }
diff -urN ../mywork/wine-1.1.24/dlls/ws2_32/Makefile.in wine-1.1.24-merge-clean/dlls/ws2_32/Makefile.in
--- ../mywork/wine-1.1.24/dlls/ws2_32/Makefile.in	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ws2_32/Makefile.in	2009-11-09 13:54:53.000000000 +0900
@@ -7,7 +7,7 @@
 IMPORTLIB = ws2_32
 IMPORTS   = kernel32 ntdll
 DELAYIMPORTS = iphlpapi user32
-EXTRALIBS = @LIBPOLL@
+EXTRALIBS = @LIBPOLL@ @LIBAIO@
 
 C_SRCS = \
 	async.c \
diff -urN ../mywork/wine-1.1.24/dlls/ws2_32/socket.c wine-1.1.24-merge-clean/dlls/ws2_32/socket.c
--- ../mywork/wine-1.1.24/dlls/ws2_32/socket.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ws2_32/socket.c	2009-11-10 14:26:26.000000000 +0900
@@ -1,3 +1,4 @@
+
 /*
  * based on Windows Sockets 1.1 specs
  *
@@ -31,6 +32,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
+#include <assert.h>
 #ifdef HAVE_SYS_IPC_H
 # include <sys/ipc.h>
 #endif
@@ -119,6 +121,9 @@
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
+#ifdef HAVE_LIBAIO_H
+# include <libaio.h>
+#endif
 
 #define NONAMELESSUNION
 #define NONAMELESSSTRUCT
@@ -141,6 +146,7 @@
 #include "wine/server.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
+#include "winternl.h"
 
 #ifdef HAVE_IPX
 # include "wsnwlink.h"
@@ -1358,32 +1364,69 @@
 {
     SOCKET as;
     BOOL is_blocking;
+    obj_handle_t handle;
+    obj_handle_t shandle;
+    int sock_fd;
 
+//FIXME( "socket : %04lx \n", s );
+//FIXME( "socket : %04ld \n", s );
     TRACE("socket %04lx\n", s );
     is_blocking = _is_blocking(s);
-
+//FIXME( "thread id : %04x \n", GetCurrentThreadId() );
+//FIXME( "blocking1 : %04d \n", is_blocking );
     do {
         if (is_blocking)
         {
+//FIXME( "blocking2 : %04d \n", is_blocking );
             int fd = get_sock_fd( s, FILE_READ_DATA, NULL );
             if (fd == -1) return INVALID_SOCKET;
             /* block here */
             do_block(fd, POLLIN, -1);
             _sync_sock_state(s); /* let wineserver notice connection */
             release_sock_fd( s, fd );
+//FIXME( "blocking3 : %04d \n", is_blocking );
             /* retrieve any error codes from it */
             SetLastError(_get_sock_error(s, FD_ACCEPT_BIT));
             /* FIXME: care about the error? */
+//FIXME( "blocking4 : %04d \n", is_blocking );
         }
+//FIXME( "blocking5 : %04d \n", is_blocking );
+	struct timeval start, end, result;
+	gettimeofday(&start, NULL);
+	server_enter_critical_section();
         SERVER_START_REQ( accept_socket )
         {
+//FIXME( "socket 1 :%04ld \n", s );
+//FIXME( "handle 1 :%04ld \n", SOCKET2HANDLE(s) );
             req->lhandle    = wine_server_obj_handle( SOCKET2HANDLE(s) );
+//FIXME( "req->handle:%ld \n", req->lhandle );
+	    shandle = req->lhandle;
             req->access     = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE;
             req->attributes = OBJ_INHERIT;
             set_error( wine_server_call( req ) );
             as = HANDLE2SOCKET( wine_server_ptr_handle( reply->handle ));
+//FIXME( "shandle:%ld \n", shandle );
+	    if(as)
+            {
+		if ((sock_fd = get_fd_sock( &handle )) != -1)
+        	{
+                    assert( handle == shandle );
+                    add_sock_fd_to_cache( wine_server_ptr_handle(reply->handle), sock_fd, reply->type, reply->access, reply->options );
+//FIXME( "handle:%ld, unix_fd: %d, type:%d, removable:%d, access:%d, options:%d \n", reply->handle, sock_fd, reply->type, reply->removable, reply->access, reply->options );
+
+		}
+	    }
+
         }
         SERVER_END_REQ;
+
+	server_leave_critical_section();
+	gettimeofday(&end, NULL);
+	timersub(&end, &start, &result);
+	double time;
+	time = result.tv_sec + (double)result.tv_usec/1000000;
+//FIXME( "time : %lf \n", time );
+
         if (as)
         {
             if (addr) WS_getpeername(as, addr, addrlen32);
@@ -2656,7 +2699,10 @@
                               ULONG Information )
 {
     NTSTATUS status;
+	struct iocb *iocb;
+	long result;
 
+/*
     SERVER_START_REQ( add_fd_completion )
     {
         req->handle      = wine_server_obj_handle( SOCKET2HANDLE(sock) );
@@ -2666,6 +2712,19 @@
         status = wine_server_call( req );
     }
     SERVER_END_REQ;
+	*/
+	if ((iocb = (struct iocb *)malloc(sizeof(struct iocb))) == NULL)
+    {
+        return;
+    }
+    iocb->data = (void *)CompletionValue;
+
+	if (!Information && CompletionStatus)
+		result = errno*-1;	
+	else
+		result = Information;
+    aio_post_io_completion(wine_server_obj_handle(SOCKET2HANDLE(sock)), result, iocb);
+
 }
 
 
@@ -2731,6 +2790,18 @@
 
     if ( fd == -1 ) return SOCKET_ERROR;
 
+	/* for linux async I/O */
+    if (cvalue && !lpCompletionRoutine &&
+		!(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
+	{
+		if(lpNumberOfBytesSent)
+			*lpNumberOfBytesSent = 0;
+		err = AsyncSockWrite(fd, (void*)lpOverlapped, (void*)lpBuffers, dwBufferCount);
+		release_sock_fd( s, fd );
+		WSASetLastError( NtStatusToWSAError(err) );
+		return SOCKET_ERROR;
+	}
+
     if (!(wsa = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET(struct ws2_async, iovec[dwBufferCount]) )))
     {
         err = WSAEFAULT;
@@ -2750,7 +2821,7 @@
         totalLength += lpBuffers[i].len;
     }
 
-    if (!lpNumberOfBytesSent)
+    if (!lpOverlapped && !lpNumberOfBytesSent)
     {
         err = WSAEFAULT;
         goto error;
@@ -2779,6 +2850,7 @@
 
         if (n == -1)
         {
+			/* errno == EAGAIN */
             iosb->u.Status = STATUS_PENDING;
             iosb->Information = 0;
 
@@ -2800,9 +2872,11 @@
             return SOCKET_ERROR;
         }
 
+		/* n != -1 */
         iosb->u.Status = STATUS_SUCCESS;
         iosb->Information = n;
-        *lpNumberOfBytesSent = n;
+		if(lpNumberOfBytesSent)
+     	   *lpNumberOfBytesSent = n;
         if (!wsa->completion_func)
         {
             if (cvalue) WS_AddCompletion( s, cvalue, STATUS_SUCCESS, n );
@@ -2821,7 +2895,8 @@
          * sending blocks until the entire buffer is sent. */
         DWORD timeout_start = GetTickCount();
 
-        *lpNumberOfBytesSent = 0;
+		if(lpNumberOfBytesSent)
+        	*lpNumberOfBytesSent = 0;
 
         while (wsa->first_iovec < dwBufferCount)
         {
@@ -2830,7 +2905,8 @@
 
             if (n >= 0)
             {
-                *lpNumberOfBytesSent += n;
+				if(lpNumberOfBytesSent)
+               		*lpNumberOfBytesSent += n;
                 while (wsa->first_iovec < dwBufferCount && wsa->iovec[wsa->first_iovec].iov_len <= n)
                     n -= wsa->iovec[wsa->first_iovec++].iov_len;
                 if (wsa->first_iovec >= dwBufferCount) break;
@@ -2870,10 +2946,12 @@
             err = WSAEWOULDBLOCK;
             goto error;
         }
-        *lpNumberOfBytesSent = n;
+		if (lpNumberOfBytesSent)
+        	*lpNumberOfBytesSent = n;
     }
 
-    TRACE(" -> %i bytes\n", *lpNumberOfBytesSent);
+	if (lpNumberOfBytesSent)
+    	TRACE(" -> %i bytes\n", *lpNumberOfBytesSent);
 
     HeapFree( GetProcessHeap(), 0, wsa );
     release_sock_fd( s, fd );
@@ -3979,7 +4057,9 @@
                          GROUP g, DWORD dwFlags)
 {
     SOCKET ret;
-
+    
+    int sfamily;
+    int sock_fd;
    /*
       FIXME: The "advanced" parameters of WSASocketW (lpProtocolInfo,
       g, dwFlags except WSA_FLAG_OVERLAPPED) are ignored.
@@ -4019,6 +4099,7 @@
           default: SetLastError(WSAEPROTOTYPE); return INVALID_SOCKET;
         }
 
+    server_enter_critical_section();
     SERVER_START_REQ( create_socket )
     {
         req->family     = af;
@@ -4029,8 +4110,22 @@
         req->flags      = dwFlags;
         set_error( wine_server_call( req ) );
         ret = HANDLE2SOCKET( wine_server_ptr_handle( reply->handle ));
+	if(ret)
+        {
+		if ((sock_fd = get_fd_sock( &sfamily )) != -1)
+        	{
+//FIXME( "handle:%ld, shandle : %ld \n", sfamily, af );
+                    assert( sfamily == af );
+                    add_sock_fd_to_cache( wine_server_ptr_handle(reply->handle), sock_fd, reply->type, reply->access, reply->options );
+//FIXME( "handle:%ld, unix_fd: %d, type:%d, removable:%d, access:%d, options:%d \n", reply->handle, sock_fd, reply->type, reply->removable, reply->access, reply->options );
+
+//FIXME( "accept->handle:%ld, unix_fd: %d \n", reply->handle, sock_fd );
+		}
+	 }
     }
     SERVER_END_REQ;
+	
+    server_leave_critical_section();
     if (ret)
     {
         TRACE("\tcreated %04lx\n", ret );
@@ -4357,6 +4452,44 @@
     }
 }
 
+/*
+UINT async_sock_recv(int fd, LPWSAOVERLAPPED lpOverlapped, LPWSABUF lpBuffers, DWORD dwBufferCount)
+{
+	int i;
+	struct iocb *iocb;
+
+	if (!lpBuffers) {
+		return WSAEINVAL;
+	}
+
+	if ((iocb = (struct iocb *)malloc(sizeof(struct iocb) * dwBufferCount)) == NULL)
+	{
+		return WSAEFAULT;	
+	}
+	
+	memset (iocb, 0, sizeof(struct iocb) * dwBufferCount);
+	for (i=0; i < dwBufferCount; i++)
+	{
+		iocb[i].aio_fildes = fd;
+		iocb[i].aio_lio_opcode = IO_CMD_PREAD;
+		iocb[i].aio_reqprio = 0;
+		iocb[i].u.c.buf = (void*)lpBuffers[i].buf;
+		iocb[i].u.c.nbytes = (size_t)lpBuffers[i].len;
+		iocb[i].u.c.offset = (long long)0;
+		iocb[i].data = (void*)lpOverlapped;
+	}
+
+	if (dwBufferCount != io_submit(ioctx, (long)dwBufferCount, &iocb))
+	{
+#ifdef DEBUG
+		printf("io_submit FAIL\n");
+#endif
+		free(iocb);
+		return wsaErrno();
+	}
+
+	return WSA_IO_PENDING;
+} */
 
 /***********************************************************************
  *		WSARecv			(WS2_32.67)
@@ -4391,10 +4524,22 @@
           lpOverlapped, lpCompletionRoutine);
 
     fd = get_sock_fd( s, FILE_READ_DATA, &options );
-    TRACE( "fd=%d, options=%x\n", fd, options );
+    TRACE( "(fd=%d, options=%x)\n", fd, options );
 
     if (fd == -1) return SOCKET_ERROR;
 
+	/* for linux async I/O */
+	if (cvalue && !lpCompletionRoutine &&
+             !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
+	{
+		if (lpNumberOfBytesRecvd)
+			*lpNumberOfBytesRecvd = 0;
+		err = AsyncSockRead(fd, (void*)lpOverlapped, (void*)lpBuffers, dwBufferCount);
+		release_sock_fd( s, fd );
+		WSASetLastError( NtStatusToWSAError(err) );
+		return SOCKET_ERROR;
+	}
+
     if (!(wsa = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET(struct ws2_async, iovec[dwBufferCount]) )))
     {
         err = WSAEFAULT;
@@ -4426,8 +4571,10 @@
                 goto error;
             }
         }
-        else
-            *lpNumberOfBytesRecvd = n;
+        else {
+			if (lpNumberOfBytesRecvd)
+        		*lpNumberOfBytesRecvd = n;
+		}
 
         if ((lpOverlapped || lpCompletionRoutine) &&
              !(options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
diff -urN ../mywork/wine-1.1.24/dlls/ws2_32/tests/sock.c wine-1.1.24-merge-clean/dlls/ws2_32/tests/sock.c
--- ../mywork/wine-1.1.24/dlls/ws2_32/tests/sock.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ws2_32/tests/sock.c	2009-11-09 13:56:18.000000000 +0900
@@ -2581,7 +2581,7 @@
     test_addr_to_print();
     test_ioctlsocket();
     test_dns();
-    test_gethostbyname_hack();
+//    test_gethostbyname_hack();
 
     test_send();
     test_write_events();
diff -urN ../mywork/wine-1.1.24/dlls/ws2_32/tests/test.sh wine-1.1.24-merge-clean/dlls/ws2_32/tests/test.sh
--- ../mywork/wine-1.1.24/dlls/ws2_32/tests/test.sh	1970-01-01 09:00:00.000000000 +0900
+++ wine-1.1.24-merge-clean/dlls/ws2_32/tests/test.sh	2009-11-09 13:56:18.000000000 +0900
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+WINEDEBUG+=relay ../../../tools/runtest -q -P wine -M ws2_32.dll -T ../../.. -p ws2_32_test.exe.so sock.c && touch sock.ok 
+
diff -urN ../mywork/wine-1.1.24/include/wine/server.h wine-1.1.24-merge-clean/include/wine/server.h
--- ../mywork/wine-1.1.24/include/wine/server.h	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/include/wine/server.h	2009-11-09 13:56:18.000000000 +0900
@@ -49,11 +49,28 @@
     struct __server_iovec data[__SERVER_MAX_DATA];  /* request variable size data */
 };
 
+//#define IOCTX_MAXEVENTS		65535
+//#define IOCTX_MAXEVENTS		10240
+#define IOCTX_MAXEVENTS		7100
+
+typedef struct _AYNCCTX {
+	io_context_t	ioctx;
+	pthread_mutex_t	mutex;
+} ASYNCCTX;
+
+extern ASYNCCTX async_ctx;
+
+
 extern unsigned int wine_server_call( void *req_ptr );
 extern void CDECL wine_server_send_fd( int fd );
 extern int CDECL wine_server_fd_to_handle( int fd, unsigned int access, unsigned int attributes, HANDLE *handle );
 extern int CDECL wine_server_handle_to_fd( HANDLE handle, unsigned int access, int *unix_fd, unsigned int *options );
 extern void CDECL wine_server_release_fd( HANDLE handle, int unix_fd );
+extern int get_fd_sock( obj_handle_t *handle);
+extern int add_sock_fd_to_cache( HANDLE handle, int fd, enum server_fd_type type, unsigned int access, unsigned int options);
+extern void server_enter_critical_section();
+extern void server_leave_critical_section();
+
 
 /* do a server call and set the last error code */
 static inline unsigned int wine_server_call_err( void *req_ptr )
diff -urN ../mywork/wine-1.1.24/include/wine/server_protocol.h wine-1.1.24-merge-clean/include/wine/server_protocol.h
--- ../mywork/wine-1.1.24/include/wine/server_protocol.h	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/include/wine/server_protocol.h	2009-11-09 13:56:18.000000000 +0900
@@ -15,6 +15,8 @@
 #include <windef.h>
 #include <winbase.h>
 
+#include <libiocp.h>
+
 typedef unsigned int obj_handle_t;
 typedef unsigned int user_handle_t;
 typedef unsigned int atom_t;
@@ -1134,7 +1136,14 @@
 {
     struct reply_header __header;
     obj_handle_t handle;
-    char __pad_12[4];
+    // modified by tm 09.09
+    //char __pad_12[4];
+//	int	 unix_fd;
+	int          type;
+    int          removable;
+    unsigned int access;
+    unsigned int options;
+	// modified by tm 09.09
 };
 
 
@@ -1153,7 +1162,15 @@
 {
     struct reply_header __header;
     obj_handle_t handle;
+	// modified by tm 09.09
     char __pad_12[4];
+//	int			 unix_fd;
+/*	int          type;
+    int          removable;
+    unsigned int access;
+    unsigned int options;
+*/
+	// modified by tm 09.09
 };
 
 
@@ -1263,7 +1280,11 @@
 {
     struct reply_header __header;
     obj_handle_t handle;
-    char __pad_12[4];
+    //char __pad_12[4];
+    int type;
+    int	removable;
+    unsigned int access;
+    unsigned int options;
 };
 
 
@@ -1279,7 +1300,11 @@
 {
     struct reply_header __header;
     obj_handle_t handle;
-    char __pad_12[4];
+    //char __pad_12[4];
+    int type;
+    int	removable;
+    unsigned int access;
+    unsigned int options;
 };
 
 
@@ -4445,6 +4470,7 @@
     unsigned int attributes;
     unsigned int concurrent;
     obj_handle_t rootdir;
+	io_port_t iocp;
     /* VARARG(filename,string); */
 };
 struct create_completion_reply
@@ -4530,6 +4556,8 @@
 struct set_completion_info_reply
 {
     struct reply_header __header;
+	io_port_t iocp;
+	char __pad_12[4];
 };
 
 
diff -urN ../mywork/wine-1.1.24/include/winternl.h wine-1.1.24-merge-clean/include/winternl.h
--- ../mywork/wine-1.1.24/include/winternl.h	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/include/winternl.h	2009-11-09 13:54:53.000000000 +0900
@@ -2143,6 +2143,8 @@
 NTSYSAPI NTSTATUS  WINAPI NtQueryVolumeInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,FS_INFORMATION_CLASS);
 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 AsyncSockRead(int,void*,void*,DWORD);
+NTSYSAPI NTSTATUS WINAPI AsyncSockWrite(int,void*,void*,DWORD);
 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 NtReadRequestData(HANDLE,PLPC_MESSAGE,ULONG,PVOID,ULONG,PULONG);
diff -urN ../mywork/wine-1.1.24/server/completion.c wine-1.1.24-merge-clean/server/completion.c
--- ../mywork/wine-1.1.24/server/completion.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/completion.c	2009-11-09 13:54:53.000000000 +0900
@@ -42,6 +42,10 @@
 #include "file.h"
 #include "handle.h"
 #include "request.h"
+#ifdef HAVE_LIBIOCP_H
+#include <libiocp.h>
+#endif
+#include <sys/errno.h>
 
 
 struct completion
@@ -49,6 +53,7 @@
     struct object  obj;
     struct list    queue;
     unsigned int   depth;
+    io_port_t	   iocp;
 };
 
 static void completion_dump( struct object*, int );
@@ -120,7 +125,7 @@
     return !list_empty( &completion->queue );
 }
 
-static struct completion *create_completion( struct directory *root, const struct unicode_str *name, unsigned int attr, unsigned int concurrent )
+static struct completion *create_completion( struct directory *root, const struct unicode_str *name, unsigned int attr, unsigned int concurrent, io_port_t iocp )
 {
     struct completion *completion;
 
@@ -130,6 +135,7 @@
         {
             list_init( &completion->queue );
             completion->depth = 0;
+			completion->iocp = iocp;    
         }
     }
 
@@ -172,7 +178,7 @@
     if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
         return;
 
-    if ( (completion = create_completion( root, &name, req->attributes, req->concurrent )) != NULL )
+    if ( (completion = create_completion( root, &name, req->attributes, req->concurrent, req->iocp )) != NULL )
     {
         reply->handle = alloc_handle( current->process, completion, req->access, req->attributes );
         release_object( completion );
@@ -254,3 +260,18 @@
 
     release_object( completion );
 }
+
+DECL_HANDLER(set_completion_info)
+{
+	struct completion *completion;
+
+	completion = get_completion_obj( current->process, req->handle, IO_COMPLETION_MODIFY_STATE ); 
+	if (!completion) {
+		set_error( STATUS_INVALID_PARAMETER);
+		reply->iocp = 0;
+	}
+	else
+		reply->iocp = completion->iocp;
+}
+
+
diff -urN ../mywork/wine-1.1.24/server/fd.c wine-1.1.24-merge-clean/server/fd.c
--- ../mywork/wine-1.1.24/server/fd.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/fd.c	2009-11-09 13:56:18.000000000 +0900
@@ -1540,13 +1540,16 @@
     const char *unlink_name = "";
     int rw_mode;
 
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd1 \n" );
     if ((options & FILE_DELETE_ON_CLOSE) && !(access & DELETE))
     {
         set_error( STATUS_INVALID_PARAMETER );
         return NULL;
     }
 
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd2 \n" );
     if (!(fd = alloc_fd_object())) return NULL;
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd fd : %p \n", fd );
 
     fd->options = options;
     if (options & FILE_DELETE_ON_CLOSE) unlink_name = name;
@@ -1556,6 +1559,7 @@
         return NULL;
     }
 
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd3 \n" );
     /* create the directory if needed */
     if ((options & FILE_DIRECTORY_FILE) && (flags & O_CREAT))
     {
@@ -1570,6 +1574,7 @@
         flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
     }
 
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd4 \n" );
     if ((access & FILE_UNIX_WRITE_ACCESS) && !(options & FILE_DIRECTORY_FILE))
     {
         if (access & FILE_UNIX_READ_ACCESS) rw_mode = O_RDWR;
@@ -1579,6 +1584,7 @@
 
     if ((fd->unix_fd = open( name, rw_mode | (flags & ~O_TRUNC), *mode )) == -1)
     {
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd => fd->unix_fd :%d \n", fd->unix_fd );
         /* if we tried to open a directory for write access, retry read-only */
         if (errno != EISDIR ||
             !(access & FILE_UNIX_WRITE_ACCESS) ||
@@ -1588,7 +1594,9 @@
             goto error;
         }
     }
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd => fd->unix_fd :%d \n", fd->unix_fd );
 
+//fprintf( stderr, "WINE SERVER : fd.c : open_fd5 \n" );
     closed_fd->unix_fd = fd->unix_fd;
     closed_fd->unlink[0] = 0;
     fstat( fd->unix_fd, &st );
@@ -1937,10 +1945,11 @@
 {
     struct fd *fd = NULL;
     struct object *obj;
-
+//fprintf( stderr, "WINE SERVER : fd.c : get_handle_fd_obj => handle:%ld \n", handle );
     if ((obj = get_handle_obj( process, handle, access, NULL )))
     {
         fd = get_obj_fd( obj );
+//fprintf( stderr, "WINE SERVER : fd.c : get_handle_fd_obj => fd : %p, obj : %p \n", fd, obj);
         release_object( obj );
     }
     return fd;
@@ -1985,12 +1994,34 @@
     get_req_unicode_str( &name );
     if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
         return;
+//fprintf( stderr, "WINE SERVER : fd.c : name : %s, len : %d \n", name.str, name.len );
 
     if ((obj = open_object_dir( root, &name, req->attributes, NULL )))
     {
         if ((result = obj->ops->open_file( obj, req->access, req->sharing, req->options )))
         {
             reply->handle = alloc_handle( current->process, result, req->access, req->attributes );
+			// modified by tm 09.09
+//			fprintf( stderr, "alloc_handle ==> handle:%ld \n", reply->handle );
+	/*		struct fd *fd;
+			if ((fd = get_handle_fd_obj( current->process, reply->handle, 0 )))
+			{
+				if(fd)
+				{
+					int unix_fd = get_unix_fd( fd );
+					if (unix_fd != -1)
+					{
+						reply->type = fd->fd_ops->get_fd_type( fd );
+						reply->removable = is_fd_removable(fd);
+						reply->options = fd->options;
+						reply->access = get_handle_access( current->process, reply->handle );
+fprintf( stderr, "WINE SERVER : fd.c : open_file_object => name : %s, len : %d \n", name.str, name.len );
+	fprintf( stderr, "handle:%ld, unix_fd: %d, type:%d, removable:%d, access:%d, options:%d \n", reply->handle, unix_fd, reply->type, reply->removable, reply->access, reply->options );
+					send_client_fd_file( current->process, unix_fd, name.str, name.len );
+					}
+				}
+			}
+	*/		// modified by tm 09.09
             release_object( result );
         }
         release_object( obj );
@@ -2003,10 +2034,12 @@
 DECL_HANDLER(get_handle_fd)
 {
     struct fd *fd;
-
+//fprintf( stderr, "WINE SERVER : fd.c : get_handle_fd => handle : %ld \n", req->handle );
     if ((fd = get_handle_fd_obj( current->process, req->handle, 0 )))
     {
+
         int unix_fd = get_unix_fd( fd );
+//fprintf( stderr, "WINE SERVER : fd.c : get_handle_fd => handle : %ld unix_fd : %d \n", req->handle, unix_fd );
         if (unix_fd != -1)
         {
             reply->type = fd->fd_ops->get_fd_type( fd );
@@ -2014,6 +2047,7 @@
             reply->options = fd->options;
             reply->access = get_handle_access( current->process, req->handle );
             send_client_fd( current->process, unix_fd, req->handle );
+//fprintf( stderr, "WINE SERVER : fd.c : get_handle_fd => handle : %ld unix_fd : %d \n", req->handle, unix_fd );
         }
         release_object( fd );
     }
@@ -2073,6 +2107,7 @@
 }
 
 /* attach completion object to a fd */
+/*
 DECL_HANDLER(set_completion_info)
 {
     struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
@@ -2087,7 +2122,21 @@
         else set_error( STATUS_INVALID_PARAMETER );
         release_object( fd );
     }
-}
+} */
+/* attach completion object to a fd */
+/*DECL_HANDLER(set_completion_info)
+{
+	struct completion *completion;
+	io_port_t iocp;
+	
+	completion = get_completion_obj( current->process, req->chandle, IO_COMPLETION_MODIFY_STATE );
+	if (!completion) {
+		set_error( STATUS_INVALID_PARAMETER);
+		reply->iocp = 0;
+	}
+	else
+		iocp = completion->iocp;
+}*/
 
 /* push new completion msg into a completion queue attached to the fd */
 DECL_HANDLER(add_fd_completion)
diff -urN ../mywork/wine-1.1.24/server/file.c wine-1.1.24-merge-clean/server/file.c
--- ../mywork/wine-1.1.24/server/file.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/file.c	2009-11-09 13:56:18.000000000 +0900
@@ -64,6 +64,31 @@
     uid_t               uid;        /* file stat.st_uid */
 };
 
+// modified by tm 09.09
+struct fd
+{
+    struct object        obj;         /* object header */
+    const struct fd_ops *fd_ops;      /* file descriptor operations */
+    struct inode        *inode;       /* inode that this fd belongs to */
+    struct list          inode_entry; /* entry in inode fd list */
+    struct closed_fd    *closed;      /* structure to store the unix fd at destroy time */
+    struct object       *user;        /* object using this file descriptor */
+    struct list          locks;       /* list of locks on this fd */
+    unsigned int         access;      /* file access (FILE_READ_DATA etc.) */
+    unsigned int         options;     /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
+    unsigned int         sharing;     /* file sharing mode */
+    int                  unix_fd;     /* unix file descriptor */
+    unsigned int         no_fd_status;/* status to return when unix_fd is -1 */
+    int                  signaled :1; /* is the fd signaled? */
+    int                  fs_locks :1; /* can we use filesystem locks for this fd? */
+    int                  poll_index;  /* index of fd in poll array */
+    struct async_queue  *read_q;      /* async readers of this fd */
+    struct async_queue  *write_q;     /* async writers of this fd */
+    struct async_queue  *wait_q;      /* other async waiters of this fd */
+    struct completion   *completion;  /* completion object attached to this fd */
+    apc_param_t          comp_key;    /* completion key to set in completion events */
+};
+// modified by tm 09.09
 static unsigned int generic_file_map_access( unsigned int access );
 
 static void file_dump( struct object *obj, int verbose );
@@ -201,8 +226,11 @@
 
     access = generic_file_map_access( access );
 
+
     /* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
+//fprintf( stderr, "WINE SERVER : file.c : create_file\n" );
     fd = open_fd( name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
+//fprintf( stderr, "WINE SERVER : file.c : create_file file fd : %d\n", fd->unix_fd );
     if (!fd) goto done;
 
     if (S_ISDIR(mode))
@@ -246,7 +274,7 @@
 {
     struct file *file = (struct file *)obj;
     assert( obj->ops == &file_ops );
-    fprintf( stderr, "File fd=%p\n", file->fd );
+   // fprintf( stderr, "File fd=%p\n", file->fd );
 }
 
 static int file_get_poll_events( struct fd *fd )
@@ -278,6 +306,8 @@
 {
     struct file *file = (struct file *)obj;
     assert( obj->ops == &file_ops );
+//fprintf( stderr, "WINE SERVER : file.c : file_get_fd => obj : %p \n", obj );
+//fprintf( stderr, "WINE SERVER : file.c : file_get_fd => unix_fd: %d \n", file->fd->unix_fd );
     return (struct fd *)grab_object( file->fd );
 }
 
@@ -717,6 +747,23 @@
                              req->attrs, sd )))
     {
         reply->handle = alloc_handle( current->process, file, req->access, req->attributes );
+	// modified by tm 09.09
+	struct fd *fd = get_obj_fd(file);
+	if(fd)
+	{
+		int unix_fd = get_unix_fd( fd );
+		if (unix_fd != -1)
+		{
+			reply->type = fd->fd_ops->get_fd_type( fd );
+			reply->removable = is_fd_removable(fd);
+			reply->options = fd->options;
+			reply->access = get_handle_access( current->process, reply->handle );
+			send_client_fd_file( current->process, unix_fd, name, name_len );
+//fprintf( stderr, "WINE SERVER : file.c : create_file => name : %s, handle : %ld, fd : %d \n", name, reply->handle, unix_fd );
+		}
+		release_object( fd );
+	}
+	// modified by tm 09.09
         release_object( file );
     }
 }
diff -urN ../mywork/wine-1.1.24/server/handle.c wine-1.1.24-merge-clean/server/handle.c
--- ../mywork/wine-1.1.24/server/handle.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/handle.c	2009-11-09 13:56:18.000000000 +0900
@@ -357,7 +357,6 @@
     struct handle_table *table;
     struct handle_entry *entry;
     struct object *obj;
-
     if (!(entry = get_handle( process, handle ))) return 0;
     if (entry->access & RESERVED_CLOSE_PROTECT)
     {
@@ -399,7 +398,7 @@
 {
     struct handle_entry *entry;
     struct object *obj;
-
+//fprintf( stderr, "WINE SERVER : handle.c : get_handle_obj => handle:%ld handle : %x\n", handle, handle );
     if (!(obj = get_magic_handle( handle )))
     {
         if (!(entry = get_handle( process, handle ))) return NULL;
@@ -410,11 +409,13 @@
         }
         obj = entry->ptr;
     }
+//fprintf( stderr, "WINE SERVER : handle.c : get_handle_obj ops : %p, obj->ops : %p \n", ops, obj->ops );
     if (ops && (obj->ops != ops))
     {
         set_error( STATUS_OBJECT_TYPE_MISMATCH );  /* not the right type */
         return NULL;
     }
+//fprintf( stderr, "WINE SERVER : handle.c : get_handle_obj : obj => %p \n", obj );
     return grab_object( obj );
 }
 
diff -urN ../mywork/wine-1.1.24/server/request.c wine-1.1.24-merge-clean/server/request.c
--- ../mywork/wine-1.1.24/server/request.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/request.c	2009-11-09 13:56:18.000000000 +0900
@@ -426,6 +426,53 @@
     return -1;
 }
 
+// modified by tm 09.09
+int send_client_fd_file( struct process *process, int fd, char * name, int len )
+{
+    int ret;
+
+    if (debug_level)
+        fprintf( stderr, "%04x: *fd* %s--> %d\n",
+                 current ? current->id : process->id, name, fd );
+//fprintf( stderr, "%04x: *fd* %s -> %d\n", current ? current->id : process->id, name, fd );
+
+#ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
+    msghdr.msg_accrightslen = sizeof(fd);
+    msghdr.msg_accrights = (void *)&fd;
+#else  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+    msghdr.msg_control    = &cmsg;
+    msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
+    cmsg.fd = fd;
+//fprintf( stderr, "WINE SERVER : request.c : send_client_fd_file => fd : %d\n", cmsg.fd );
+
+#endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
+
+    myiovec.iov_base = (void *)name;
+    myiovec.iov_len  = len;
+
+    ret = sendmsg( get_unix_fd( process->msg_fd ), &msghdr, 0 );
+
+    if (ret == len ) return 0;
+
+    if (ret >= 0)
+    {
+        fprintf( stderr, "Protocol error: process %04x: partial sendmsg %d\n", process->id, ret );
+        kill_process( process, 1 );
+    }
+    else if (errno == EPIPE)
+    {
+        kill_process( process, 0 );
+    }
+    else
+    {
+        fprintf( stderr, "Protocol error: process %04x: ", process->id );
+        perror( "sendmsg" );
+        kill_process( process, 1 );
+    }
+    return -1;
+}
+// modified by tm 09.09
+
 /* send an fd to a client */
 int send_client_fd( struct process *process, int fd, obj_handle_t handle )
 {
@@ -434,6 +481,7 @@
     if (debug_level)
         fprintf( stderr, "%04x: *fd* %04x -> %d\n",
                  current ? current->id : process->id, handle, fd );
+//fprintf( stderr, "%04x: *fd* %04x -> %d\n", current ? current->id : process->id, handle, fd );
 
 #ifdef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS
     msghdr.msg_accrightslen = sizeof(fd);
@@ -442,6 +490,8 @@
     msghdr.msg_control    = &cmsg;
     msghdr.msg_controllen = sizeof(cmsg.header) + sizeof(fd);
     cmsg.fd = fd;
+//fprintf( stderr, "WINE SERVER : request.c : send_client_fd => fd : %d, handle : %ld \n", cmsg.fd, handle );
+
 #endif  /* HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS */
 
     myiovec.iov_base = (void *)&handle;
diff -urN ../mywork/wine-1.1.24/server/request.h wine-1.1.24-merge-clean/server/request.h
--- ../mywork/wine-1.1.24/server/request.h	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/request.h	2009-11-09 13:56:18.000000000 +0900
@@ -831,15 +831,31 @@
 C_ASSERT( FIELD_OFFSET(struct create_file_request, create) == 24 );
 C_ASSERT( FIELD_OFFSET(struct create_file_request, options) == 28 );
 C_ASSERT( FIELD_OFFSET(struct create_file_request, attrs) == 32 );
+/* modified by tm 09.09 */
+/*C_ASSERT( FIELD_OFFSET(struct create_file_reply, handle) == 8 );
+C_ASSERT( sizeof(struct create_file_reply) == 16 );*/
 C_ASSERT( FIELD_OFFSET(struct create_file_reply, handle) == 8 );
-C_ASSERT( sizeof(struct create_file_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct create_file_reply, type) == 12 );
+C_ASSERT( FIELD_OFFSET(struct create_file_reply, removable) == 16 );
+C_ASSERT( FIELD_OFFSET(struct create_file_reply, access) == 20 );
+C_ASSERT( FIELD_OFFSET(struct create_file_reply, options) == 24 );
+C_ASSERT( sizeof(struct create_file_reply) == 28 );
+/* modified by tm 09.09 */
 C_ASSERT( FIELD_OFFSET(struct open_file_object_request, access) == 12 );
 C_ASSERT( FIELD_OFFSET(struct open_file_object_request, attributes) == 16 );
 C_ASSERT( FIELD_OFFSET(struct open_file_object_request, rootdir) == 20 );
 C_ASSERT( FIELD_OFFSET(struct open_file_object_request, sharing) == 24 );
 C_ASSERT( FIELD_OFFSET(struct open_file_object_request, options) == 28 );
+/* modified by tm 09.09 */
 C_ASSERT( FIELD_OFFSET(struct open_file_object_reply, handle) == 8 );
+/*C_ASSERT( FIELD_OFFSET(struct open_file_object_reply, handle) == 8 );
+C_ASSERT( FIELD_OFFSET(struct open_file_object_reply, type) == 12 );
+C_ASSERT( FIELD_OFFSET(struct open_file_object_reply, removable) == 16 );
+C_ASSERT( FIELD_OFFSET(struct open_file_object_reply, access) == 20 );
+C_ASSERT( FIELD_OFFSET(struct open_file_object_reply, options) == 24 );
+C_ASSERT( sizeof(struct open_file_object_reply) == 28 );*/
 C_ASSERT( sizeof(struct open_file_object_reply) == 16 );
+/* modified by tm 09.09 */
 C_ASSERT( FIELD_OFFSET(struct alloc_file_handle_request, access) == 12 );
 C_ASSERT( FIELD_OFFSET(struct alloc_file_handle_request, attributes) == 16 );
 C_ASSERT( FIELD_OFFSET(struct alloc_file_handle_request, fd) == 20 );
@@ -872,13 +888,24 @@
 C_ASSERT( FIELD_OFFSET(struct create_socket_request, type) == 24 );
 C_ASSERT( FIELD_OFFSET(struct create_socket_request, protocol) == 28 );
 C_ASSERT( FIELD_OFFSET(struct create_socket_request, flags) == 32 );
+/*C_ASSERT( FIELD_OFFSET(struct create_socket_reply, handle) == 8 );
+C_ASSERT( sizeof(struct create_socket_reply) == 16 );*/
 C_ASSERT( FIELD_OFFSET(struct create_socket_reply, handle) == 8 );
-C_ASSERT( sizeof(struct create_socket_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct create_socket_reply, type) == 12 );
+C_ASSERT( FIELD_OFFSET(struct create_socket_reply, removable) == 16 );
+C_ASSERT( FIELD_OFFSET(struct create_socket_reply, access) == 20 );
+C_ASSERT( FIELD_OFFSET(struct create_socket_reply, options) == 24 );
+C_ASSERT( sizeof(struct create_socket_reply) == 28 );
 C_ASSERT( FIELD_OFFSET(struct accept_socket_request, lhandle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct accept_socket_request, access) == 16 );
 C_ASSERT( FIELD_OFFSET(struct accept_socket_request, attributes) == 20 );
 C_ASSERT( FIELD_OFFSET(struct accept_socket_reply, handle) == 8 );
-C_ASSERT( sizeof(struct accept_socket_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_reply, type) == 12 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_reply, removable) == 16 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_reply, access) == 20 );
+C_ASSERT( FIELD_OFFSET(struct accept_socket_reply, options) == 24 );
+C_ASSERT( sizeof(struct accept_socket_reply) == 28 );
+/*C_ASSERT( sizeof(struct accept_socket_reply) == 16 );*/
 C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, handle) == 12 );
 C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, mask) == 16 );
 C_ASSERT( FIELD_OFFSET(struct set_socket_event_request, event) == 20 );
diff -urN ../mywork/wine-1.1.24/server/sock.c wine-1.1.24-merge-clean/server/sock.c
--- ../mywork/wine-1.1.24/server/sock.c	2009-06-20 00:49:15.000000000 +0900
+++ wine-1.1.24-merge-clean/server/sock.c	2009-11-09 13:56:18.000000000 +0900
@@ -47,6 +47,10 @@
 #include <time.h>
 #include <unistd.h>
 
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "windef.h"
@@ -87,6 +91,32 @@
     struct async_queue *write_q;     /* queue for asynchronous writes */
 };
 
+// modified by tm 09.09
+struct fd
+{
+    struct object        obj;         /* object header */
+    const struct fd_ops *fd_ops;      /* file descriptor operations */
+    struct inode        *inode;       /* inode that this fd belongs to */
+    struct list          inode_entry; /* entry in inode fd list */
+    struct closed_fd    *closed;      /* structure to store the unix fd at destroy time */
+    struct object       *user;        /* object using this file descriptor */
+    struct list          locks;       /* list of locks on this fd */
+    unsigned int         access;      /* file access (FILE_READ_DATA etc.) */
+    unsigned int         options;     /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
+    unsigned int         sharing;     /* file sharing mode */
+    int                  unix_fd;     /* unix file descriptor */
+    unsigned int         no_fd_status;/* status to return when unix_fd is -1 */
+    int                  signaled :1; /* is the fd signaled? */
+    int                  fs_locks :1; /* can we use filesystem locks for this fd? */
+    int                  poll_index;  /* index of fd in poll array */
+    struct async_queue  *read_q;      /* async readers of this fd */
+    struct async_queue  *write_q;     /* async writers of this fd */
+    struct async_queue  *wait_q;      /* other async waiters of this fd */
+    struct completion   *completion;  /* completion object attached to this fd */
+    apc_param_t          comp_key;    /* completion key to set in completion events */
+};
+// modified by tm 09.09
+
 static void sock_dump( struct object *obj, int verbose );
 static int sock_signaled( struct object *obj, struct thread *thread );
 static struct fd *sock_get_fd( struct object *obj );
@@ -627,13 +657,16 @@
     struct sock *sock;
     int	acceptfd;
     struct sockaddr	saddr;
+//fprintf( stderr, "WINE SERVER : sock.c(656) : accept_socket ==> handle : %ld \n", handle );
 
     sock = (struct sock *)get_handle_obj( current->process, handle, FILE_READ_DATA, &sock_ops );
+//fprintf( stderr, "WINE SERVER : sock.c(659) : accept_socket ==> struct sock : %04x \n", sock );
     if (!sock)
     	return NULL;
 
     if ( sock->deferred )
     {
+//fprintf( stderr, "WINE SERVER : sock.c(665) : accept_socket ==> struct sock : %04x \n", sock );
         acceptsock = sock->deferred;
         sock->deferred = NULL;
     }
@@ -646,6 +679,7 @@
          */
         unsigned int slen = sizeof(saddr);
         acceptfd = accept( get_unix_fd(sock->fd), &saddr, &slen);
+//fprintf( stderr, "WINE SERVER : sock.c(678) : accept_socket ==> acceptfd : %d \n", acceptfd );
         if (acceptfd==-1)
         {
             sock_set_error();
@@ -776,7 +810,22 @@
     reply->handle = 0;
     if ((obj = create_socket( req->family, req->type, req->protocol, req->flags )) != NULL)
     {
+	struct sock *sock = (struct sock*)obj;
         reply->handle = alloc_handle( current->process, obj, req->access, req->attributes );
+	struct fd *fd = sock->fd;
+	if(fd)
+	{
+		int unix_fd = get_unix_fd( fd );
+		if (unix_fd != -1)
+		{
+			reply->type = fd->fd_ops->get_fd_type( fd );
+			reply->removable = is_fd_removable(fd);
+			reply->options = fd->options;
+			reply->access = get_handle_access( current->process, reply->handle );
+			send_client_fd( current->process, unix_fd, req->family );
+//fprintf( stderr, "WINE SERVER : create_socket => handle:%ld, unix_fd: %d, type:%d, removable:%d, access:%d, options:%d \n", reply->handle, unix_fd, reply->type, reply->removable, reply->access, reply->options );
+		}
+	}
         release_object( obj );
     }
 }
@@ -792,8 +841,22 @@
         reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes );
         sock->wparam = reply->handle;  /* wparam for message is the socket handle */
         sock_reselect( sock );
+	struct fd *fd = sock->fd;
+	if(fd)
+	{
+		int unix_fd = get_unix_fd( fd );
+		if (unix_fd != -1)
+		{
+			reply->type = fd->fd_ops->get_fd_type( fd );
+			reply->removable = is_fd_removable(fd);
+			reply->options = fd->options;
+			reply->access = get_handle_access( current->process, reply->handle );
+			send_client_fd( current->process, unix_fd, req->lhandle );
+		}
+	}
         release_object( &sock->obj );
     }
+
 }
 
 /* set socket event parameters */
