/*
 * Copyright (C) 2002 Mike McCormack
 *
 * CIFS implementation for WINE
 *
 * This is a WINE's implementation of the Common Internet File System
 *
 * for specification see:
 *
 * http://www.codefx.com/CIFS_Explained.htm
 * http://www.ubiqx.org/cifs/rfc-draft/rfc1002.html
 * http://www.ubiqx.org/cifs/rfc-draft/draft-leach-cifs-v1-spec-02.html
 * http://ubiqx.org/cifs/
 * http://www.samba.org
 *
 * 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:
 *
 *   - There is a race condition when two threads try to read from the same
 *     SMB handle. Either we need to lock the SMB handle for the time we
 *     use it in the client, or do all reading and writing to the socket
 *     fd in the server.
 *
 *   - Each new handle opens up a new connection to the SMB server. This
 *     is not ideal, since operations can be multiplexed on one socket. For
 *     this to work properly we would need to have some way of discovering
 *     connections that are already open.
 *
 *   - All access is currently anonymous. Password protected shares cannot
 *     be accessed.  We need some way of organising passwords, storing them
 *     in the config file, or putting up a dialog box for the user.
 *
 *   - We don't deal with SMB dialects at all.
 *
 *   - SMB supports passing unicode over the wire, should use this if possible.
 *
 *   - Implement ability to read named pipes over the network. Would require
 *     integrate this code with the named pipes code in the server, and
 *     possibly implementing some support for security tokens.
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <sys/time.h>
#include <sys/poll.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif

#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "file.h"
#include "heap.h"

#include "smb.h"

#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(file);

#define MAX_HOST_NAME 15
#define NB_TIMEOUT 10000

USHORT SMB_MultiplexId = 0;

struct NB_Buffer
{
    unsigned char *buffer;
    int len;
};

static int netbios_name(const char *p, unsigned char *buffer)
{
    char ch;
    int i,len=0;

    buffer[len++]=' ';
    for(i=0; i<=MAX_HOST_NAME; i++)
    {
        if(i<MAX_HOST_NAME)
        {
            if(*p)
                ch = *p++&0xdf; /* add character from hostname */
            else
                ch = ' ';  /* add padding */
        }
        else
            ch = 0;        /* add terminator */
        buffer[len++] = ((ch&0xf0) >> 4) + 'A';
        buffer[len++] =  (ch&0x0f) + 'A';
    }
    buffer[len++] = 0;     /* add second terminator */
    return len;
}

static DWORD NB_NameReq(LPCSTR host, unsigned char *buffer, int len)
{
    int trn = 1234,i=0;

    NBR_ADDWORD(&buffer[i],trn);    i+=2;
    NBR_ADDWORD(&buffer[i],0x0110); i+=2;
    NBR_ADDWORD(&buffer[i],0x0001); i+=2;
    NBR_ADDWORD(&buffer[i],0x0000); i+=2;
    NBR_ADDWORD(&buffer[i],0x0000); i+=2;
    NBR_ADDWORD(&buffer[i],0x0000); i+=2;

    i += netbios_name(host,&buffer[i]);

    NBR_ADDWORD(&buffer[i],0x0020); i+=2;
    NBR_ADDWORD(&buffer[i],0x0001); i+=2;

    TRACE("packet is %d bytes in length\n",i);

    {
        int j;
        for(j=0; j<i; j++)
            printf("%02x%c",buffer[j],(((j+1)%16)&&((j+1)!=j))?' ':'\n');
    }

    return i;
}

/* unc = \\hostname\share\file... */
static BOOL UNC_SplitName(LPSTR unc, LPSTR *hostname, LPSTR *share, LPSTR *file)
{
    char *p;

    TRACE("%s\n",unc);

    p = strchr(unc,'\\');
    if(!p)
        return FALSE;
    p = strchr(p+1,'\\');
    if(!p)
        return FALSE;
    *hostname=++p;

    p = strchr(p,'\\');
    if(!p)
        return FALSE;
    *p=0;
    *share = ++p;

    p = strchr(p,'\\');
    if(!p)
        return FALSE;
    *p=0;
    *file = ++p;

    return TRUE;
}

static BOOL NB_Lookup(LPCSTR host, struct sockaddr_in *addr)
{
    int fd,on=1,r,len,i,fromsize;
    struct pollfd fds;
    struct sockaddr_in sin,fromaddr;
    unsigned char buffer[256];

    fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(fd<0)
        return FALSE;

    r = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof on);
    if(r<0)
        goto err;

    if(0==inet_aton("255.255.255.255", (struct in_addr *)&sin.sin_addr.s_addr))
    {
        FIXME("Error getting bcast address\n");
        goto err;
    }
    sin.sin_family = AF_INET;
    sin.sin_port    = htons(137);

    len = NB_NameReq(host,buffer,sizeof buffer);
    if(len<=0)
        goto err;

    r = sendto(fd, buffer, len, 0, &sin, sizeof sin);
    if(r<0)
    {
        FIXME("Error sending packet\n");
        goto err;
    }

    fds.fd = fd;
    fds.events = POLLIN;
    fds.revents = 0;

    /* FIXME: this is simple and easily fooled logic
     *  we should loop until we receive the correct packet or timeout
     */
    r = poll(&fds,1,NB_TIMEOUT);
    if(r!=1)
        goto err;

    TRACE("Got response!\n");

    fromsize = sizeof (fromaddr);
    r = recvfrom(fd, buffer, sizeof buffer, 0, &fromaddr, &fromsize);
    if(r<0)
        goto err;

    TRACE("%d bytes received\n",r);

    if(r!=62)
        goto err;

    for(i=0; i<r; i++)
        DPRINTF("%02X%c",buffer[i],(((i+1)!=r)&&((i+1)%16))?' ':'\n');
    DPRINTF("\n");

    if(0x0f & buffer[3])
        goto err;

    TRACE("packet is OK\n");

    memcpy(&addr->sin_addr, &buffer[58], sizeof addr->sin_addr);

    close(fd);
    return TRUE;

err:
    close(fd);
    return FALSE;
}

#define NB_FIRST 0x40

#define NB_HDRSIZE 4

#define NB_SESSION_MSG 0x00
#define NB_SESSION_REQ 0x81

/* RFC 1002, section 4.3.2 */
static BOOL NB_SessionReq(int fd, char *called, char *calling)
{
    unsigned char buffer[0x100];
    int len = 0,r;
    struct pollfd fds;

    TRACE("called %s, calling %s\n",called,calling);

    buffer[0] = NB_SESSION_REQ;
    buffer[1] = NB_FIRST;

    netbios_name(called, &buffer[NB_HDRSIZE]);
    len += 34;
    netbios_name(calling, &buffer[NB_HDRSIZE+len]);
    len += 34;

    NBR_ADDWORD(&buffer[2],len);

    /* for(i=0; i<(len+NB_HDRSIZE); i++)
        DPRINTF("%02X%c",buffer[i],(((i+1)!=(len+4))&&((i+1)%16))?' ':'\n'); */

    r = write(fd,buffer,len+4);
    if(r<0)
    {
        ERR("Write failed\n");
        return FALSE;
    }

    fds.fd = fd;
    fds.events = POLLIN;
    fds.revents = 0;

    r = poll(&fds,1,NB_TIMEOUT);
    if(r!=1)
    {
        ERR("Poll failed\n");
        return FALSE;
    }

    r = read(fd, buffer, NB_HDRSIZE);
    if((r!=NB_HDRSIZE) || (buffer[0]!=0x82))
    {
        TRACE("Received %d bytes\n",r);
        TRACE("%02x %02x %02x %02x\n", buffer[0],buffer[1],buffer[2],buffer[3]);
        return FALSE;
    }

    return TRUE;
}

static BOOL NB_SendData(int fd, struct NB_Buffer *out)
{
    unsigned char buffer[NB_HDRSIZE];
    int r;

    /* CHECK: is it always OK to do this in two writes?   */
    /*        perhaps use scatter gather sendmsg instead? */

    buffer[0] = NB_SESSION_MSG;
    buffer[1] = NB_FIRST;
    NBR_ADDWORD(&buffer[2],out->len);

    r = write(fd, buffer, NB_HDRSIZE);
    if(r!=NB_HDRSIZE)
        return FALSE;

    r = write(fd, out->buffer, out->len);
    if(r!=out->len)
    {
        ERR("write failed\n");
        return FALSE;
    }

    return TRUE;
}

static BOOL NB_RecvData(int fd, struct NB_Buffer *rx)
{
    int r;
    unsigned char buffer[NB_HDRSIZE];

    r = read(fd, buffer, NB_HDRSIZE);
    if((r!=NB_HDRSIZE) || (buffer[0]!=NB_SESSION_MSG))
    {
        ERR("Received %d bytes\n",r);
        return FALSE;
    }

    rx->len = NBR_GETWORD(&buffer[2]);

    rx->buffer = HeapAlloc(GetProcessHeap(), 0, rx->len);
    if(!rx->buffer)
        return FALSE;

    r = read(fd, rx->buffer, rx->len);
    if(rx->len!=r)
    {
        TRACE("Received %d bytes\n",r);
        HeapFree(GetProcessHeap(), 0, rx->buffer);
        rx->buffer = 0;
        rx->len = 0;
        return FALSE;
    }

    return TRUE;
}

static BOOL NB_Transaction(int fd, struct NB_Buffer *in, struct NB_Buffer *out)
{
    int r;
    struct pollfd fds;

    if(TRACE_ON(file))
    {
        int i;
    DPRINTF("Sending request:\n");
        for(i=0; i<in->len; i++)
            DPRINTF("%02X%c",in->buffer[i],(((i+1)!=in->len)&&((i+1)%16))?' ':'\n');
    }

    if(!NB_SendData(fd,in))
        return FALSE;

    fds.fd = fd;
    fds.events = POLLIN;
    fds.revents = 0;

    r = poll(&fds,1,NB_TIMEOUT);
    if(r!=1)
    {
        ERR("Poll failed\n");
        return FALSE;
    }

    if(!NB_RecvData(fd, out))
        return FALSE;

    if(TRACE_ON(file))
    {
        int i;
    DPRINTF("Got response:\n");
        for(i=0; i<out->len; i++)
            DPRINTF("%02X%c",out->buffer[i],(((i+1)!=out->len)&&((i+1)%16))?' ':'\n');
    }

    return TRUE;
}

#define SMB_ADDHEADER(b,l) { b[(l)++]=0xff; b[(l)++]='S'; b[(l)++]='M'; b[(l)++]='B'; }
#define SMB_ADDERRINFO(b,l) { b[(l)++]=0; b[(l)++]=0; b[(l)++]=0; b[(l)++]=0; }
#define SMB_ADDPADSIG(b,l) { memset(&b[l],0,12); l+=12; }

#define SMB_ERRCLASS 5
#define SMB_ERRCODE  7
#define SMB_TREEID  24
#define SMB_PROCID  26
#define SMB_USERID  28
#define SMB_PLEXID  30
#define SMB_PCOUNT  32
#define SMB_HDRSIZE 33

static DWORD SMB_GetError(unsigned char *buffer)
{
    char *err_class;

    switch(buffer[SMB_ERRCLASS])
    {
    case 0:
        return STATUS_SUCCESS;
    case 1:
        err_class = "DOS";
        break;
    case 2:
        err_class = "net server";
        break;
    case 3:
        err_class = "hardware";
        break;
    case 0xff:
        err_class = "smb";
        break;
    default:
        err_class = "unknown";
        break;
    }

    ERR("%s error %d \n",err_class, buffer[SMB_ERRCODE]);

    /* FIXME: return propper error codes */
    return STATUS_INVALID_PARAMETER;
}

static int SMB_Header(unsigned char *buffer, unsigned char command, USHORT tree_id, USHORT user_id)
{
    int len = 0;
    DWORD id;

    /* 0 */
    SMB_ADDHEADER(buffer,len);

    /* 4 */
    buffer[len++] = command;

    /* 5 */
    SMB_ADDERRINFO(buffer,len)

    /* 9 */
    buffer[len++] = 0x00; /* flags */
    SMB_ADDWORD(&buffer[len],1); len += 2; /* flags2 */

    /* 12 */
    SMB_ADDPADSIG(buffer,len)

    /* 24 */
    SMB_ADDWORD(&buffer[len],tree_id); len += 2; /* treeid */
    id = GetCurrentThreadId();
    SMB_ADDWORD(&buffer[len],id); len += 2; /* process id */
    SMB_ADDWORD(&buffer[len],user_id); len += 2; /* user id */
    SMB_ADDWORD(&buffer[len],SMB_MultiplexId); len += 2; /* multiplex id */
    SMB_MultiplexId++;

    return len;
}

static const char *SMB_ProtocolDialect = "NT LM 0.12";
/* = "Windows for Workgroups 3.1a"; */

/* FIXME: support multiple SMB dialects */
static BOOL SMB_NegotiateProtocol(int fd, USHORT *dialect)
{
    unsigned char buf[0x100];
    int buflen = 0;
    struct NB_Buffer tx, rx;

    TRACE("\n");

    memset(buf,0,sizeof buf);

    tx.buffer = buf;
    tx.len = SMB_Header(tx.buffer, SMB_COM_NEGOTIATE, 0, 0);

    /* parameters */
    tx.buffer[tx.len++] = 0; /* no parameters */

    /* command buffer */
    buflen = strlen(SMB_ProtocolDialect)+2;  /* include type and nul byte */
    SMB_ADDWORD(&tx.buffer[tx.len],buflen); tx.len += 2;

    tx.buffer[tx.len] = 0x02;
    strcpy(&tx.buffer[tx.len+1],SMB_ProtocolDialect);
    tx.len += buflen;

    rx.buffer = NULL;
    rx.len = 0;
    if(!NB_Transaction(fd, &tx, &rx))
    {
        ERR("Failed\n");
        return FALSE;
    }

    if(!rx.buffer)
        return FALSE;

    /* FIXME: check response */
    if(SMB_GetError(rx.buffer))
    {
        ERR("returned error\n");
        HeapFree(GetProcessHeap(),0,rx.buffer);
        return FALSE;
    }

    HeapFree(GetProcessHeap(),0,rx.buffer);

    *dialect = 0;

    return TRUE;
}

#define SMB_PARAM_COUNT(buffer) ((buffer)[SMB_PCOUNT])
#define SMB_PARAM(buffer,n) SMB_GETWORD(&(buffer)[SMB_HDRSIZE+2*(n)])
#define SMB_BUFFER_COUNT(buffer)  SMB_GETWORD(buffer+SMB_HDRSIZE+2*SMB_PARAM_COUNT(buffer))
#define SMB_BUFFER(buffer,n) ((buffer)[SMB_HDRSIZE + 2*SMB_PARAM_COUNT(buffer) + 2 + (n) ])

static BOOL SMB_SessionSetup(int fd, USHORT *userid)
{
    unsigned char buf[0x100];
    int pcount,bcount;
    struct NB_Buffer rx, tx;

    memset(buf,0,sizeof buf);
    tx.buffer = buf;

    tx.len = SMB_Header(tx.buffer, SMB_COM_SESSION_SETUP_ANDX, 0, 0);

    tx.buffer[tx.len++] = 0;    /* no parameters? */

    tx.buffer[tx.len++] = 0xff; /* AndXCommand: secondary request */
    tx.buffer[tx.len++] = 0x00; /* AndXReserved */
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* AndXOffset */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0x400); /* MaxBufferSize */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],1);     /* MaxMpxCount */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* VcNumber */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* SessionKey */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* SessionKey */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* Password length */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* Reserved */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0);     /* Reserved */
    tx.len += 2;

    /* FIXME: add name and password here */
    tx.buffer[tx.len++] = 0; /* number of bytes in password */

    rx.buffer = NULL;
    rx.len = 0;
    if(!NB_Transaction(fd, &tx, &rx))
        return FALSE;

    if(!rx.buffer)
        return FALSE;

    if(SMB_GetError(rx.buffer))
        goto done;

    pcount = SMB_PARAM_COUNT(rx.buffer);

    if( (SMB_HDRSIZE+pcount*2) > rx.len )
    {
        ERR("Bad parameter count %d\n",pcount);
        goto done;
    }

    if(TRACE_ON(file))
    {
        int i;
    DPRINTF("SMB_COM_SESSION_SETUP response, %d args: ",pcount);
    for(i=0; i<pcount; i++)
            DPRINTF("%04x ",SMB_PARAM(rx.buffer,i));
    DPRINTF("\n");
    }

    bcount = SMB_BUFFER_COUNT(rx.buffer);
    if( (SMB_HDRSIZE+pcount*2+2+bcount) > rx.len )
    {
        ERR("parameter count %x, buffer count %x, len %x\n",pcount,bcount,rx.len);
        goto done;
    }

    if(TRACE_ON(file))
    {
        int i;
    DPRINTF("response buffer %d bytes: ",bcount);
    for(i=0; i<bcount; i++)
    {
            unsigned char ch = SMB_BUFFER(rx.buffer,i);
        DPRINTF("%c", isprint(ch)?ch:' ');
    }
    DPRINTF("\n");
    }

    *userid = SMB_GETWORD(&rx.buffer[SMB_USERID]);

    HeapFree(GetProcessHeap(),0,rx.buffer);
    return TRUE;

done:
    HeapFree(GetProcessHeap(),0,rx.buffer);
    return FALSE;
}


static BOOL SMB_TreeConnect(int fd, USHORT user_id, LPCSTR share_name, USHORT *treeid)
{
    unsigned char buf[0x100];
    int slen;
    struct NB_Buffer rx,tx;

    TRACE("%s\n",share_name);

    memset(buf,0,sizeof buf);
    tx.buffer = buf;

    tx.len = SMB_Header(tx.buffer, SMB_COM_TREE_CONNECT, 0, user_id);

    tx.buffer[tx.len++] = 4; /* parameters */

    tx.buffer[tx.len++] = 0xff; /* AndXCommand: secondary request */
    tx.buffer[tx.len++] = 0x00; /* AndXReserved */
    SMB_ADDWORD(&tx.buffer[tx.len],0); /* AndXOffset */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],0); /* Flags */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],1); /* Password length */
    tx.len += 2;

    /* SMB command buffer */
    SMB_ADDWORD(&tx.buffer[tx.len],3); /* command buffer len */
    tx.len += 2;
    tx.buffer[tx.len++] = 0; /* null terminated password */

    slen = strlen(share_name);
    if(slen<(sizeof buf-tx.len))
        strcpy(&tx.buffer[tx.len], share_name);
    else
        return FALSE;
    tx.len += slen+1;

    /* name of the service */
    tx.buffer[tx.len++] = 0;

    rx.buffer = NULL;
    rx.len = 0;
    if(!NB_Transaction(fd, &tx, &rx))
        return FALSE;

    if(!rx.buffer)
        return FALSE;

    if(SMB_GetError(rx.buffer))
    {
        HeapFree(GetProcessHeap(),0,rx.buffer);
        return FALSE;
    }

    *treeid = SMB_GETWORD(&rx.buffer[SMB_TREEID]);

    HeapFree(GetProcessHeap(),0,rx.buffer);
    TRACE("OK, treeid = %04x\n", *treeid);

    return TRUE;
}

#if 0  /* not yet */
static BOOL SMB_NtCreateOpen(int fd, USHORT tree_id, USHORT user_id, USHORT dialect,
                              LPCSTR filename, DWORD access, DWORD sharing,
                              LPSECURITY_ATTRIBUTES sa, DWORD creation,
                              DWORD attributes, HANDLE template, USHORT *file_id )
{
    unsigned char buffer[0x100];
    int len = 0,slen;

    TRACE("%s\n",filename);

    memset(buffer,0,sizeof buffer);

    len = SMB_Header(buffer, SMB_COM_NT_CREATE_ANDX, tree_id, user_id);

    /* 0 */
    buffer[len++] = 24; /* parameters */

    buffer[len++] = 0xff; /* AndXCommand: secondary request */
    buffer[len++] = 0x00; /* AndXReserved */
    SMB_ADDWORD(&buffer[len],0); len += 2; /* AndXOffset */

    buffer[len++] = 0;                     /* reserved */
    slen = strlen(filename);
    SMB_ADDWORD(&buffer[len],slen);    len += 2; /* name length */

    /* 0x08 */
    SMB_ADDDWORD(&buffer[len],0);      len += 4; /* flags */
    SMB_ADDDWORD(&buffer[len],0);      len += 4; /* root directory fid */
    /* 0x10 */
    SMB_ADDDWORD(&buffer[len],access); len += 4; /* access */
    SMB_ADDDWORD(&buffer[len],0);      len += 4; /* allocation size */
    /* 0x18 */
    SMB_ADDDWORD(&buffer[len],0);      len += 4; /* root directory fid */

    /* 0x1c */
    SMB_ADDDWORD(&buffer[len],0);      len += 4; /* initial allocation */
    SMB_ADDDWORD(&buffer[len],0);      len += 4;

    /* 0x24 */
    SMB_ADDDWORD(&buffer[len],attributes);      len += 4; /* ExtFileAttributes*/

    /* 0x28 */
    SMB_ADDDWORD(&buffer[len],sharing);      len += 4; /* ShareAccess */

    /* 0x2c */
    TRACE("creation = %08lx\n",creation);
    SMB_ADDDWORD(&buffer[len],creation);      len += 4; /* CreateDisposition */

    /* 0x30 */
    SMB_ADDDWORD(&buffer[len],creation);      len += 4; /* CreateOptions */

    /* 0x34 */
    SMB_ADDDWORD(&buffer[len],0);      len += 4; /* Impersonation */

    /* 0x38 */
    buffer[len++] = 0;                     /* security flags */

    /* 0x39 */
    SMB_ADDWORD(&buffer[len],slen); len += 2; /* size of buffer */

    if(slen<(sizeof buffer-len))
        strcpy(&buffer[len], filename);
    else
        return FALSE;
    len += slen+1;

    /* name of the file */
    buffer[len++] = 0;

    if(!NB_Transaction(fd, buffer, len, &len))
        return FALSE;

    if(SMB_GetError(buffer))
        return FALSE;

    TRACE("OK\n");

    /* FIXME */
    /* *file_id = SMB_GETWORD(&buffer[xxx]); */
    *file_id = 0;
    return FALSE;

    return TRUE;
}
#endif

static USHORT SMB_GetMode(DWORD access, DWORD sharing)
{
    USHORT mode=0;

    switch(access&(GENERIC_READ|GENERIC_WRITE))
    {
    case GENERIC_READ:
        mode |= OF_READ;
        break;
    case GENERIC_WRITE:
        mode |= OF_WRITE;
        break;
    case (GENERIC_READ|GENERIC_WRITE):
        mode |= OF_READWRITE;
        break;
    }

    switch(sharing&(FILE_SHARE_READ|FILE_SHARE_WRITE))
    {
    case (FILE_SHARE_READ|FILE_SHARE_WRITE):
        mode |= OF_SHARE_DENY_NONE;
        break;
    case FILE_SHARE_READ:
        mode |= OF_SHARE_DENY_WRITE;
        break;
    case FILE_SHARE_WRITE:
        mode |= OF_SHARE_DENY_READ;
        break;
    default:
        mode |= OF_SHARE_EXCLUSIVE;
        break;
    }

    return mode;
}

#if 0  /* not yet */
/* inverse of FILE_ConvertOFMode */
static BOOL SMB_OpenAndX(int fd, USHORT tree_id, USHORT user_id, USHORT dialect,
                              LPCSTR filename, DWORD access, DWORD sharing,
                              DWORD creation, DWORD attributes, USHORT *file_id )
{
    unsigned char buffer[0x100];
    int len = 0;
    USHORT mode;

    TRACE("%s\n",filename);

    mode = SMB_GetMode(access,sharing);

    memset(buffer,0,sizeof buffer);

    len = SMB_Header(buffer, SMB_COM_OPEN_ANDX, tree_id, user_id);

    /* 0 */
    buffer[len++] = 15; /* parameters */
    buffer[len++] = 0xff; /* AndXCommand: secondary request */
    buffer[len++] = 0x00; /* AndXReserved */
    SMB_ADDWORD(buffer+len,0); len+=2; /* AndXOffset */
    SMB_ADDWORD(buffer+len,0); len+=2; /* Flags */
    SMB_ADDWORD(buffer+len,mode); len+=2; /* desired access */
    SMB_ADDWORD(buffer+len,0); len+=2; /* search attributes */
    SMB_ADDWORD(buffer+len,0); len+=2;

    /*FIXME: complete */
    return FALSE;
}
#endif


static BOOL SMB_Open(int fd, USHORT tree_id, USHORT user_id, USHORT dialect,
                              LPCSTR filename, DWORD access, DWORD sharing,
                              DWORD creation, DWORD attributes, USHORT *file_id )
{
    unsigned char buf[0x100];
    int slen,pcount,i;
    USHORT mode = SMB_GetMode(access,sharing);
    struct NB_Buffer rx,tx;

    TRACE("%s\n",filename);

    memset(buf,0,sizeof buf);

    tx.buffer = buf;
    tx.len = SMB_Header(tx.buffer, SMB_COM_OPEN, tree_id, user_id);

    /* 0 */
    tx.buffer[tx.len++] = 2; /* parameters */
    SMB_ADDWORD(tx.buffer+tx.len,mode); tx.len+=2;
    SMB_ADDWORD(tx.buffer+tx.len,0);    tx.len+=2; /* search attributes */

    slen = strlen(filename)+2;   /* inc. nul and BufferFormat */
    SMB_ADDWORD(tx.buffer+tx.len,slen); tx.len+=2;

    tx.buffer[tx.len] = 0x04;  /* BufferFormat */
    strcpy(&tx.buffer[tx.len+1],filename);
    tx.len += slen;

    rx.buffer = NULL;
    rx.len = 0;
    if(!NB_Transaction(fd, &tx, &rx))
        return FALSE;

    if(!rx.buffer)
        return FALSE;

    if(SMB_GetError(rx.buffer))
        return FALSE;

    pcount = SMB_PARAM_COUNT(rx.buffer);

    if( (SMB_HDRSIZE+pcount*2) > rx.len )
    {
        ERR("Bad parameter count %d\n",pcount);
        return FALSE;
    }

    TRACE("response, %d args: ",pcount);
    for(i=0; i<pcount; i++)
        DPRINTF("%04x ",SMB_PARAM(rx.buffer,i));
    DPRINTF("\n");

    *file_id = SMB_PARAM(rx.buffer,0);

    TRACE("file_id = %04x\n",*file_id);

    return TRUE;
}


static BOOL SMB_Read(int fd, USHORT tree_id, USHORT user_id, USHORT dialect,
       USHORT file_id, DWORD offset, LPVOID out, USHORT count, LPUSHORT read)
{
    int buf_size,n,i;
    struct NB_Buffer rx,tx;

    TRACE("user %04x tree %04x file %04x count %04x offset %08lx\n",
        user_id, tree_id, file_id, count, offset);

    buf_size = count+0x100;
    tx.buffer = (unsigned char *) HeapAlloc(GetProcessHeap(),0,buf_size);

    memset(tx.buffer,0,buf_size);

    tx.len = SMB_Header(tx.buffer, SMB_COM_READ, tree_id, user_id);

    tx.buffer[tx.len++] = 5;
    SMB_ADDWORD(&tx.buffer[tx.len],file_id); tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],count);   tx.len += 2;
    SMB_ADDDWORD(&tx.buffer[tx.len],offset); tx.len += 4;
    SMB_ADDWORD(&tx.buffer[tx.len],0);       tx.len += 2; /* how many more bytes will be read */

    tx.buffer[tx.len++] = 0;

    rx.buffer = NULL;
    rx.len = 0;
    if(!NB_Transaction(fd, &tx, &rx))
    {
        HeapFree(GetProcessHeap(),0,tx.buffer);
        return FALSE;
    }

    if(SMB_GetError(rx.buffer))
    {
        HeapFree(GetProcessHeap(),0,rx.buffer);
        HeapFree(GetProcessHeap(),0,tx.buffer);
        return FALSE;
    }

    n = SMB_PARAM_COUNT(rx.buffer);

    if( (SMB_HDRSIZE+n*2) > rx.len )
    {
        HeapFree(GetProcessHeap(),0,rx.buffer);
        HeapFree(GetProcessHeap(),0,tx.buffer);
        ERR("Bad parameter count %d\n",n);
        return FALSE;
    }

    TRACE("response, %d args: ",n);
    for(i=0; i<n; i++)
        DPRINTF("%04x ",SMB_PARAM(rx.buffer,i));
    DPRINTF("\n");

    n = SMB_PARAM(rx.buffer,5) - 3;
    if(n>count)
        n=count;

    memcpy( out, &SMB_BUFFER(rx.buffer,3), n);

    TRACE("Read %d bytes\n",n);
    *read = n;

    HeapFree(GetProcessHeap(),0,tx.buffer);
    HeapFree(GetProcessHeap(),0,rx.buffer);

    return TRUE;
}


/*
 * setup_count : number of USHORTs in the setup string
 */
struct SMB_Trans2Info
{
    struct NB_Buffer buf;
    unsigned char *setup;
    int setup_count;
    unsigned char *params;
    int param_count;
    unsigned char *data;
    int data_count;
};

/*
 * Do an SMB transaction
 *
 * This function allocates memory in the recv structure. It is
 * the caller's responsibility to free the memory if it finds
 * that recv->buf.buffer is nonzero.
 */
static BOOL SMB_Transaction2(int fd, int tree_id, int user_id,
                 struct SMB_Trans2Info *send,
                 struct SMB_Trans2Info *recv)
{
    int buf_size;
    const int retmaxparams = 0xf000;
    const int retmaxdata = 1024;
    const int retmaxsetup = 0; /* FIXME */
    const int flags = 0;
    const int timeout = 0;
    int param_ofs, data_ofs;
    struct NB_Buffer tx;
    BOOL ret = FALSE;

    buf_size = 0x100 + send->setup_count*2 + send->param_count + send->data_count ;
    tx.buffer = (unsigned char *) HeapAlloc(GetProcessHeap(),0,buf_size);

    tx.len = SMB_Header(tx.buffer, SMB_COM_TRANSACTION2, tree_id, user_id);

    tx.buffer[tx.len++] = 14 + send->setup_count;
    SMB_ADDWORD(&tx.buffer[tx.len],send->param_count); /* total param bytes sent */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],send->data_count);  /* total data bytes sent */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],retmaxparams); /*max parameter bytes to return */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],retmaxdata);  /* max data bytes to return */
    tx.len += 2;
    tx.buffer[tx.len++] = retmaxsetup;
    tx.buffer[tx.len++] = 0;                     /* reserved1 */

    SMB_ADDWORD(&tx.buffer[tx.len],flags);       /* flags */
    tx.len += 2;
    SMB_ADDDWORD(&tx.buffer[tx.len],timeout);    /* timeout */
    tx.len += 4;
    SMB_ADDWORD(&tx.buffer[tx.len],0);           /* reserved2 */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],send->param_count); /* parameter count - this buffer */
    tx.len += 2;

    param_ofs = tx.len;                          /* parameter offset */
    tx.len += 2;
    SMB_ADDWORD(&tx.buffer[tx.len],send->data_count);  /* data count */
    tx.len += 2;

    data_ofs = tx.len;                           /* data offset */
    tx.len += 2;
    tx.buffer[tx.len++] = send->setup_count;     /* setup count */
    tx.buffer[tx.len++] = 0;                     /* reserved3 */

    memcpy(&tx.buffer[tx.len], send->setup, send->setup_count*2); /* setup */
    tx.len += send->setup_count*2;

    /* add string here when implementing SMB_COM_TRANS */

    SMB_ADDWORD(&tx.buffer[param_ofs], tx.len);
    memcpy(&tx.buffer[tx.len], send->params, send->param_count); /* parameters */
    tx.len += send->param_count;
    if(tx.len%2)
        tx.len ++;                                      /* pad2 */

    SMB_ADDWORD(&tx.buffer[data_ofs], tx.len);
    if(send->data_count && send->data)
    {
        memcpy(&tx.buffer[tx.len], send->data, send->data_count); /* data */
        tx.len += send->data_count;
    }

    recv->buf.buffer = NULL;
    recv->buf.len = 0;
    if(!NB_Transaction(fd, &tx, &recv->buf))
        goto done;

    if(!recv->buf.buffer)
        goto done;

    if(SMB_GetError(recv->buf.buffer))
        goto done;

    /* reuse these two offsets to check the received message */
    param_ofs = SMB_PARAM(recv->buf.buffer,4);
    data_ofs = SMB_PARAM(recv->buf.buffer,7);

    if( (recv->param_count + param_ofs) > recv->buf.len )
        goto done;

    if( (recv->data_count + data_ofs) > recv->buf.len )
        goto done;

    TRACE("Success\n");

    recv->setup = NULL;
    recv->setup_count = 0;

    recv->param_count = SMB_PARAM(recv->buf.buffer,0);
    recv->params = &recv->buf.buffer[param_ofs];

    recv->data_count = SMB_PARAM(recv->buf.buffer,6);
    recv->data = &recv->buf.buffer[data_ofs];

   /*
    TRACE("%d words\n",SMB_PARAM_COUNT(recv->buf.buffer));
    TRACE("total parameters = %d\n",SMB_PARAM(recv->buf.buffer,0));
    TRACE("total data       = %d\n",SMB_PARAM(recv->buf.buffer,1));
    TRACE("parameters       = %d\n",SMB_PARAM(recv->buf.buffer,3));
    TRACE("parameter offset = %d\n",SMB_PARAM(recv->buf.buffer,4));
    TRACE("param displace   = %d\n",SMB_PARAM(recv->buf.buffer,5));

    TRACE("data count       = %d\n",SMB_PARAM(recv->buf.buffer,6));
    TRACE("data offset      = %d\n",SMB_PARAM(recv->buf.buffer,7));
    TRACE("data displace    = %d\n",SMB_PARAM(recv->buf.buffer,8));
   */

    ret = TRUE;

done:
    if(tx.buffer)
        HeapFree(GetProcessHeap(),0,tx.buffer);

    return ret;
}

static BOOL SMB_SetupFindFirst(struct SMB_Trans2Info *send, LPSTR filename)
{
    int search_attribs = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
    int search_count = 10;
    int flags = 0;
    int infolevel = 0x104; /* SMB_FILE_BOTH_DIRECTORY_INFO */
    int storagetype = 0;
    int len, buf_size;

    memset(send,0,sizeof send);

    send->setup_count = 1;
    send->setup = HeapAlloc(GetProcessHeap(),0,send->setup_count*2);
    if(!send->setup)
        return FALSE;

    buf_size = 0x10 + lstrlenA(filename);
    send->params = HeapAlloc(GetProcessHeap(),0,buf_size);
    if(!send->params)
    {
        HeapFree(GetProcessHeap(),0,send->setup);
        return FALSE;
    }

    SMB_ADDWORD(send->setup,TRANS2_FIND_FIRST2);

    len = 0;
    memset(send->params,0,buf_size);
    SMB_ADDWORD(&send->params[len],search_attribs); len += 2;
    SMB_ADDWORD(&send->params[len],search_count); len += 2;
    SMB_ADDWORD(&send->params[len],flags); len += 2;
    SMB_ADDWORD(&send->params[len],infolevel); len += 2;
    SMB_ADDDWORD(&send->params[len],storagetype); len += 4;

    strcpy(&send->params[len],filename);
    len += lstrlenA(filename)+1;

    send->param_count = len;
    send->data = NULL;
    send->data_count = 0;

    return TRUE;
}

static SMB_DIR *SMB_Trans2FindFirst(int fd, USHORT tree_id,
                    USHORT user_id, USHORT dialect, LPSTR filename )
{
    int num;
    BOOL ret;
    /* char *filename = "\\*"; */
    struct SMB_Trans2Info send, recv;
    SMB_DIR *smbdir = NULL;

    TRACE("patern = %s\n",filename);

    if(!SMB_SetupFindFirst(&send, filename))
        return FALSE;

    memset(&recv,0,sizeof recv);

    ret = SMB_Transaction2(fd, tree_id, user_id, &send, &recv);
    HeapFree(GetProcessHeap(),0,send.params);
    HeapFree(GetProcessHeap(),0,send.setup);

    if(!ret)
        goto done;

    if(recv.setup_count)
        goto done;

    if(recv.param_count != 10)
        goto done;

    num = SMB_GETWORD(&recv.params[2]);
    TRACE("Success, search id: %d\n",num);

    if(SMB_GETWORD(&recv.params[4]))
        FIXME("need to read more!\n");

    smbdir = HeapAlloc(GetProcessHeap(),0,sizeof(*smbdir));
    if(smbdir)
    {
        int i, ofs=0;

        smbdir->current = 0;
        smbdir->num_entries = num;
        smbdir->entries = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned char*)*num);
        if(!smbdir->entries)
            goto done;
        smbdir->buffer = recv.buf.buffer; /* save to free later */

        for(i=0; i<num; i++)
        {
            int size = SMB_GETDWORD(&recv.data[ofs]);

            smbdir->entries[i] = &recv.data[ofs];

            if(TRACE_ON(file))
            {
                int j;
                for(j=0; j<size; j++)
                    DPRINTF("%02x%c",recv.data[ofs+j],((j+1)%16)?' ':'\n');
            }
            TRACE("file %d : %s\n", i, &recv.data[ofs+0x5e]);
            ofs += size;
            if(ofs>recv.data_count)
                goto done;
        }

        ret = TRUE;
    }

done:
    if(!ret)
    {
        if( recv.buf.buffer )
            HeapFree(GetProcessHeap(),0,recv.buf.buffer);
        if( smbdir )
        {
            if( smbdir->entries )
                HeapFree(GetProcessHeap(),0,smbdir->entries);
            HeapFree(GetProcessHeap(),0,smbdir);
        }
        smbdir = NULL;
    }

    return smbdir;
}

static int SMB_GetSocket(LPCSTR host)
{
    int fd=-1,r;
    struct sockaddr_in sin;
    struct hostent *he;

    TRACE("host %s\n",host);

    he = gethostbyname(host);
    if(he)
    {
        memcpy(&sin.sin_addr,he->h_addr, sizeof (sin.sin_addr));
        goto connect;
    }

    if(NB_Lookup(host,&sin))
        goto connect;

    /* FIXME: resolve by WINS too */

    ERR("couldn't resolve SMB host %s\n", host);

    return -1;

connect:
    sin.sin_family = AF_INET;
    sin.sin_port   = htons(139);  /* netbios session */

    fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(fd<0)
        return fd;

    {
        unsigned char *x = (unsigned char *)&sin.sin_addr;
        TRACE("Connecting to %d.%d.%d.%d ...\n", x[0],x[1],x[2],x[3]);
    }
    r = connect(fd, &sin, sizeof sin);

    if(!NB_SessionReq(fd, "*SMBSERVER", "WINE"))
    {
        close(fd);
        return -1;
    }

    return fd;
}

static BOOL SMB_LoginAndConnect(int fd, LPCSTR host, LPCSTR share, USHORT *tree_id, USHORT *user_id, USHORT *dialect)
{
    LPSTR name=NULL;

    TRACE("host %s share %s\n",host,share);

    if(!SMB_NegotiateProtocol(fd, dialect))
        return FALSE;

    if(!SMB_SessionSetup(fd, user_id))
        return FALSE;

    name = HeapAlloc(GetProcessHeap(),0,strlen(host)+strlen(share)+5);
    if(!name)
        return FALSE;

    sprintf(name,"\\\\%s\\%s",host,share);
    if(!SMB_TreeConnect(fd,*user_id,name,tree_id))
    {
        HeapFree(GetProcessHeap(),0,name);
        return FALSE;
    }

    return TRUE;
}

static HANDLE SMB_RegisterFile( int fd, USHORT tree_id, USHORT user_id, USHORT dialect, USHORT file_id)
{
    int r;
    HANDLE ret;

    wine_server_send_fd( fd );

    SERVER_START_REQ( create_smb )
    {
        req->tree_id = tree_id;
        req->user_id = user_id;
        req->file_id = file_id;
        req->dialect = 0;
        req->fd      = fd;
        SetLastError(0);
        r = wine_server_call_err( req );
        ret = reply->handle;
    }
    SERVER_END_REQ;

    if(!r)
        TRACE("created wineserver smb object, handle = %04x\n",ret);
    else
        SetLastError( ERROR_PATH_NOT_FOUND );

    return ret;
}

HANDLE WINAPI SMB_CreateFileA( LPCSTR uncname, DWORD access, DWORD sharing,
                              LPSECURITY_ATTRIBUTES sa, DWORD creation,
                              DWORD attributes, HANDLE template )
{
    int fd;
    USHORT tree_id=0, user_id=0, dialect=0, file_id=0;
    LPSTR name,host,share,file;
    HANDLE handle = INVALID_HANDLE_VALUE;

    name = HeapAlloc(GetProcessHeap(),0,lstrlenA(uncname));
    if(!name)
        return handle;

    lstrcpyA(name,uncname);

    if( !UNC_SplitName(name, &host, &share, &file) )
    {
        HeapFree(GetProcessHeap(),0,name);
        return handle;
    }

    TRACE("server is %s, share is %s, file is %s\n", host, share, file);

    fd = SMB_GetSocket(host);
    if(fd < 0)
        goto done;

    if(!SMB_LoginAndConnect(fd, host, share, &tree_id, &user_id, &dialect))
        goto done;

#if 0
    if(!SMB_NtCreateOpen(fd, tree_id, user_id, dialect, file,
                    access, sharing, sa, creation, attributes, template, &file_id ))
    {
        close(fd);
        ERR("CreateOpen failed\n");
        goto done;
    }
#endif
    if(!SMB_Open(fd, tree_id, user_id, dialect, file,
                    access, sharing, creation, attributes, &file_id ))
    {
        close(fd);
        ERR("CreateOpen failed\n");
        goto done;
    }

    handle = SMB_RegisterFile(fd, tree_id, user_id, dialect, file_id);
    if(!handle)
    {
        ERR("register failed\n");
        close(fd);
    }

done:
    HeapFree(GetProcessHeap(),0,name);
    return handle;
}

static BOOL SMB_GetSmbInfo(HANDLE hFile, USHORT *tree_id, USHORT *user_id, USHORT *dialect, USHORT *file_id, LPDWORD offset)
{
    int r;

    SERVER_START_REQ( get_smb_info )
    {
        req->handle  = hFile;
        req->flags   = 0;
        SetLastError(0);
        r = wine_server_call_err( req );
        if(tree_id)
            *tree_id = reply->tree_id;
        if(user_id)
            *user_id = reply->user_id;
        if(file_id)
            *file_id = reply->file_id;
        if(dialect)
            *dialect = reply->dialect;
        if(offset)
            *offset = reply->offset;
    }
    SERVER_END_REQ;

    return !r;
}

static BOOL SMB_SetOffset(HANDLE hFile, DWORD offset)
{
    int r;

    TRACE("offset = %08lx\n",offset);

    SERVER_START_REQ( get_smb_info )
    {
        req->handle  = hFile;
        req->flags   = SMBINFO_SET_OFFSET;
        req->offset  = offset;
        SetLastError(0);
        r = wine_server_call_err( req );
        /* if(offset)
            *offset = reply->offset; */
    }
    SERVER_END_REQ;

    return !r;
}

BOOL WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED lpOverlapped)
{
    int fd;
    DWORD total, count, offset;
    USHORT user_id, tree_id, dialect, file_id, read;
    BOOL r=TRUE;

    TRACE("%04x %p %ld %p\n", hFile, buffer, bytesToRead, bytesRead);

    if(!SMB_GetSmbInfo(hFile, &tree_id, &user_id, &dialect, &file_id, &offset))
        return FALSE;

    fd = FILE_GetUnixHandle(hFile, GENERIC_READ);
    if(fd<0)
        return FALSE;

    total = 0;
    while(1)
    {
        count = bytesToRead - total;
        if(count>0x400)
            count = 0x400;
        if(count==0)
            break;
        read = 0;
        r = SMB_Read(fd, tree_id, user_id, dialect, file_id, offset, buffer, count, &read);
        if(!r)
            break;
        if(!read)
            break;
        total += read;
        buffer = (char*)buffer + read;
        offset += read;
        if(total>=bytesToRead)
            break;
    }
    close(fd);

    if(bytesRead)
        *bytesRead = total;

    if(!SMB_SetOffset(hFile, offset))
        return FALSE;

    return r;
}

SMB_DIR* WINAPI SMB_FindFirst(LPCSTR name)
{
    int fd = -1;
    LPSTR host,share,file;
    USHORT tree_id=0, user_id=0, dialect=0;
    SMB_DIR *ret = NULL;
    LPSTR filename;

    TRACE("Find %s\n",debugstr_a(name));

    filename = HeapAlloc(GetProcessHeap(),0,lstrlenA(name)+1);
    if(!filename)
        return ret;

    lstrcpyA(filename,name);

    if( !UNC_SplitName(filename, &host, &share, &file) )
        goto done;

    fd = SMB_GetSocket(host);
    if(fd < 0)
        goto done;

    if(!SMB_LoginAndConnect(fd, host, share, &tree_id, &user_id, &dialect))
        goto done;

    TRACE("server is %s, share is %s, file is %s\n", host, share, file);

    ret = SMB_Trans2FindFirst(fd, tree_id, user_id, dialect, file);

done:
    /* disconnect */
    if(fd != -1)
        close(fd);

    if(filename)
        HeapFree(GetProcessHeap(),0,filename);

    return ret;
}


BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAA *data )
{
    unsigned char *ent;
    int len, fnlen;

    TRACE("%d of %d\n",dir->current,dir->num_entries);

    if(dir->current >= dir->num_entries)
        return FALSE;

    memset(data, 0, sizeof *data);

    ent = dir->entries[dir->current];
    len = SMB_GETDWORD(&ent[0]);
    if(len<0x5e)
        return FALSE;

    memcpy(&data->ftCreationTime, &ent[8], 8);
    memcpy(&data->ftLastAccessTime, &ent[0x10], 8);
    memcpy(&data->ftLastWriteTime, &ent[0x18], 8);
    data->nFileSizeHigh = SMB_GETDWORD(&ent[0x30]);
    data->nFileSizeLow = SMB_GETDWORD(&ent[0x34]);
    data->dwFileAttributes = SMB_GETDWORD(&ent[0x38]);

    /* copy the long filename */
    fnlen = SMB_GETDWORD(&ent[0x3c]);
    if ( fnlen > (sizeof data->cFileName/sizeof(CHAR)) )
        return FALSE;
    memcpy(data->cFileName, &ent[0x5e], fnlen);

    /* copy the short filename */
    if ( ent[0x44] > (sizeof data->cAlternateFileName/sizeof(CHAR)) )
        return FALSE;
    memcpy(data->cAlternateFileName, &ent[0x5e + len], ent[0x44]);

    dir->current++;

    return TRUE;
}

BOOL WINAPI SMB_CloseDir(SMB_DIR *dir)
{
    HeapFree(GetProcessHeap(),0,dir->buffer);
    HeapFree(GetProcessHeap(),0,dir->entries);
    memset(dir,0,sizeof *dir);
    HeapFree(GetProcessHeap(),0,dir);
    return TRUE;
}
