Begin to make wine an SMB client.

diff --git a/server/Makefile.in b/server/Makefile.in
index 1bcfaaa..d62c3d9 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -31,6 +31,7 @@
 	select.c \
 	semaphore.c \
 	serial.c \
+	smb.c \
 	snapshot.c \
 	sock.c \
 	thread.c \
diff --git a/server/protocol.def b/server/protocol.def
index ad8292e..6cc06b5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -563,7 +563,8 @@
 {
     FD_TYPE_INVALID,
     FD_TYPE_DEFAULT,
-    FD_TYPE_CONSOLE
+    FD_TYPE_CONSOLE,
+    FD_TYPE_SMB
 };
 #define FD_FLAG_OVERLAPPED 0x01
 #define FD_FLAG_TIMEOUT    0x02
@@ -1634,6 +1635,31 @@
 @END
 
 
+@REQ(create_smb)
+    int            fd;
+    unsigned int   tree_id;
+    unsigned int   user_id;
+    unsigned int   file_id;
+    unsigned int   dialect;
+@REPLY
+    handle_t       handle;
+@END
+
+
+@REQ(get_smb_info)
+    handle_t       handle;
+    unsigned int   flags;
+    unsigned int   offset;
+@REPLY
+    unsigned int   tree_id;
+    unsigned int   user_id;
+    unsigned int   dialect;
+    unsigned int   file_id;
+    unsigned int   offset;
+@END
+#define SMBINFO_SET_OFFSET    0x01
+
+
 /* Create a window */
 @REQ(create_window)
     user_handle_t  parent;      /* parent window */
diff --git a/server/request.h b/server/request.h
index 07aed40..9a1350e 100644
--- a/server/request.h
+++ b/server/request.h
@@ -232,6 +232,8 @@
 DECL_HANDLER(wait_named_pipe);
 DECL_HANDLER(disconnect_named_pipe);
 DECL_HANDLER(get_named_pipe_info);
+DECL_HANDLER(create_smb);
+DECL_HANDLER(get_smb_info);
 DECL_HANDLER(create_window);
 DECL_HANDLER(link_window);
 DECL_HANDLER(destroy_window);
@@ -388,6 +390,8 @@
     (req_handler)req_wait_named_pipe,
     (req_handler)req_disconnect_named_pipe,
     (req_handler)req_get_named_pipe_info,
+    (req_handler)req_create_smb,
+    (req_handler)req_get_smb_info,
     (req_handler)req_create_window,
     (req_handler)req_link_window,
     (req_handler)req_destroy_window,
diff --git a/server/smb.c b/server/smb.c
new file mode 100644
index 0000000..ab0e84d
--- /dev/null
+++ b/server/smb.c
@@ -0,0 +1,192 @@
+/*
+ * Server-side smb network file management
+ *
+ * Copyright (C) 1998 Alexandre Julliard
+ * Copyright (C) 2000, 2001, 2002 Mike McCormack
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * FIXME: if you can't find something to fix, 
+ *          you're not looking hard enough
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+#include <sys/errno.h>
+#endif
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <utime.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include "winerror.h"
+#include "winbase.h"
+
+#include "handle.h"
+#include "thread.h"
+#include "request.h"
+
+static void smb_dump( struct object *obj, int verbose );
+static int smb_get_fd( struct object *obj );
+static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags );
+static int smb_get_poll_events( struct object *obj );
+static void destroy_smb(struct object *obj);
+
+struct smb
+{
+    struct object       obj;
+    unsigned int        tree_id;
+    unsigned int        user_id;
+    unsigned int        dialect;
+    unsigned int        file_id;
+    unsigned int        offset;
+};
+
+static const struct object_ops smb_ops =
+{
+    sizeof(struct smb),        /* size */
+    smb_dump,                  /* dump */
+    default_poll_add_queue,    /* add_queue */
+    default_poll_remove_queue, /* remove_queue */
+    default_poll_signaled,     /* signaled */
+    no_satisfied,              /* satisfied */
+    smb_get_poll_events,       /* get_poll_events */
+    default_poll_event,        /* poll_event */
+    smb_get_fd,                /* get_fd */
+    no_flush,                  /* flush */
+    smb_get_info,              /* get_file_info */
+    NULL,                      /* queue_async */
+    destroy_smb                /* destroy */
+};
+
+static void destroy_smb( struct object *obj)
+{
+    /* struct smb *smb = (struct smb *)obj; */
+    assert( obj->ops == &smb_ops );
+}
+
+static void smb_dump( struct object *obj, int verbose )
+{
+    struct smb *smb = (struct smb *)obj;
+    assert( obj->ops == &smb_ops );
+    fprintf( stderr, "smb file with socket fd=%d \n", smb->obj.fd );
+}
+
+struct smb *get_smb_obj( struct process *process, handle_t handle, unsigned int access )
+{
+    return (struct smb *)get_handle_obj( process, handle, access, &smb_ops );
+}
+
+static int smb_get_poll_events( struct object *obj )
+{
+    /* struct smb *smb = (struct smb *)obj; */
+    int events = 0;
+    assert( obj->ops == &smb_ops );
+
+    events |= POLLIN;
+
+    /* fprintf(stderr,"poll events are %04x\n",events); */
+
+    return events;
+}
+
+static int smb_get_fd( struct object *obj )
+{
+    struct smb *smb = (struct smb *)obj;
+    assert( obj->ops == &smb_ops );
+    return smb->obj.fd;
+}
+
+static int smb_get_info( struct object *obj, struct get_file_info_reply *reply, int *flags )
+{
+    /* struct smb *smb = (struct smb *) obj; */
+    assert( obj->ops == &smb_ops );
+
+    if (reply)
+    {
+        reply->type        = FILE_TYPE_CHAR;
+        reply->attr        = 0;
+        reply->access_time = 0;
+        reply->write_time  = 0;
+        reply->size_high   = 0;
+        reply->size_low    = 0;
+        reply->links       = 0;
+        reply->index_high  = 0;
+        reply->index_low   = 0;
+        reply->serial      = 0;
+    }
+
+    *flags = 0;
+
+    return FD_TYPE_SMB;
+}
+
+/* create a smb */
+DECL_HANDLER(create_smb)
+{
+    struct smb *smb;
+    int fd;
+
+    reply->handle = 0;
+
+    fd = thread_get_inflight_fd( current, req->fd );
+    if (fd == -1)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+
+    smb = alloc_object( &smb_ops, fd );
+    if (smb)
+    {
+        smb->tree_id = req->tree_id;
+        smb->user_id = req->user_id;
+        smb->dialect = req->dialect;
+        smb->file_id = req->file_id;
+        smb->offset = 0;
+        reply->handle = alloc_handle( current->process, smb, GENERIC_READ, 0);
+        release_object( smb );
+    }
+}
+
+DECL_HANDLER(get_smb_info)
+{
+    struct smb *smb;
+
+    if ((smb = get_smb_obj( current->process, req->handle, 0 )))
+    {
+        if(req->flags & SMBINFO_SET_OFFSET)
+            smb->offset = req->offset;
+
+        reply->tree_id = smb->tree_id;
+        reply->user_id = smb->user_id;
+        reply->dialect = smb->dialect;
+        reply->file_id = smb->file_id;
+        reply->offset  = smb->offset;
+
+        release_object( smb );
+    }
+}
+
diff --git a/server/trace.c b/server/trace.c
index c4c2879..2e36fe4 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1843,6 +1843,36 @@
     fprintf( stderr, " insize=%08x", req->insize );
 }
 
+static void dump_create_smb_request( const struct create_smb_request *req )
+{
+    fprintf( stderr, " fd=%d,", req->fd );
+    fprintf( stderr, " tree_id=%08x,", req->tree_id );
+    fprintf( stderr, " user_id=%08x,", req->user_id );
+    fprintf( stderr, " file_id=%08x,", req->file_id );
+    fprintf( stderr, " dialect=%08x", req->dialect );
+}
+
+static void dump_create_smb_reply( const struct create_smb_reply *req )
+{
+    fprintf( stderr, " handle=%d", req->handle );
+}
+
+static void dump_get_smb_info_request( const struct get_smb_info_request *req )
+{
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " flags=%08x,", req->flags );
+    fprintf( stderr, " offset=%08x", req->offset );
+}
+
+static void dump_get_smb_info_reply( const struct get_smb_info_reply *req )
+{
+    fprintf( stderr, " tree_id=%08x,", req->tree_id );
+    fprintf( stderr, " user_id=%08x,", req->user_id );
+    fprintf( stderr, " dialect=%08x,", req->dialect );
+    fprintf( stderr, " file_id=%08x,", req->file_id );
+    fprintf( stderr, " offset=%08x", req->offset );
+}
+
 static void dump_create_window_request( const struct create_window_request *req )
 {
     fprintf( stderr, " parent=%08x,", req->parent );
@@ -2193,6 +2223,8 @@
     (dump_func)dump_wait_named_pipe_request,
     (dump_func)dump_disconnect_named_pipe_request,
     (dump_func)dump_get_named_pipe_info_request,
+    (dump_func)dump_create_smb_request,
+    (dump_func)dump_get_smb_info_request,
     (dump_func)dump_create_window_request,
     (dump_func)dump_link_window_request,
     (dump_func)dump_destroy_window_request,
@@ -2346,6 +2378,8 @@
     (dump_func)0,
     (dump_func)0,
     (dump_func)dump_get_named_pipe_info_reply,
+    (dump_func)dump_create_smb_reply,
+    (dump_func)dump_get_smb_info_reply,
     (dump_func)dump_create_window_reply,
     (dump_func)dump_link_window_reply,
     (dump_func)0,
@@ -2499,6 +2533,8 @@
     "wait_named_pipe",
     "disconnect_named_pipe",
     "get_named_pipe_info",
+    "create_smb",
+    "get_smb_info",
     "create_window",
     "link_window",
     "destroy_window",