/*
 * Win32 device functions
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Ulrich Weigand
 * Copyright 1998 Patrik Stridvall
 *
 * 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
 */

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

#include <stdlib.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#include <string.h>
#include <stdarg.h>
#include <time.h>

#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winerror.h"
#include "winnls.h"
#include "file.h"
#include "winioctl.h"
#include "winnt.h"
#include "iphlpapi.h"
#include "kernel_private.h"
#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(file);


static BOOL DeviceIo_VTDAPI(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);
static BOOL DeviceIo_MONODEBG(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);
static BOOL DeviceIo_MMDEVLDR(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_IFSMgr(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_VCD(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_VWin32(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_DHCP(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_PCCARD (DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_HASP (DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_NetBIOS(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

static BOOL DeviceIo_VNB(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped);

/*
 * VxD names are taken from the Win95 DDK
 */

struct VxDInfo
{
    LPCSTR  name;
    WORD    id;
    BOOL  (*deviceio)(DWORD, LPVOID, DWORD,
                        LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
};

static const struct VxDInfo VxDList[] =
{
    /* Standard VxD IDs */
    { "VMM",      0x0001, NULL },
    { "DEBUG",    0x0002, NULL },
    { "VPICD",    0x0003, NULL },
    { "VDMAD",    0x0004, NULL },
    { "VTD",      0x0005, NULL },
    { "V86MMGR",  0x0006, NULL },
    { "PAGESWAP", 0x0007, NULL },
    { "PARITY",   0x0008, NULL },
    { "REBOOT",   0x0009, NULL },
    { "VDD",      0x000A, NULL },
    { "VSD",      0x000B, NULL },
    { "VMD",      0x000C, NULL },
    { "VKD",      0x000D, NULL },
    { "VCD",      0x000E, DeviceIo_VCD },
    { "VPD",      0x000F, NULL },
    { "BLOCKDEV", 0x0010, NULL },
    { "VMCPD",    0x0011, NULL },
    { "EBIOS",    0x0012, NULL },
    { "BIOSXLAT", 0x0013, NULL },
    { "VNETBIOS", 0x0014, DeviceIo_NetBIOS },
    { "DOSMGR",   0x0015, NULL },
    { "WINLOAD",  0x0016, NULL },
    { "SHELL",    0x0017, NULL },
    { "VMPOLL",   0x0018, NULL },
    { "VPROD",    0x0019, NULL },
    { "DOSNET",   0x001A, NULL },
    { "VFD",      0x001B, NULL },
    { "VDD2",     0x001C, NULL },
    { "WINDEBUG", 0x001D, NULL },
    { "TSRLOAD",  0x001E, NULL },
    { "BIOSHOOK", 0x001F, NULL },
    { "INT13",    0x0020, NULL },
    { "PAGEFILE", 0x0021, NULL },
    { "SCSI",     0x0022, NULL },
    { "MCA_POS",  0x0023, NULL },
    { "SCSIFD",   0x0024, NULL },
    { "VPEND",    0x0025, NULL },
    { "VPOWERD",  0x0026, NULL },
    { "VXDLDR",   0x0027, NULL },
    { "NDIS",     0x0028, NULL },
    { "BIOS_EXT", 0x0029, NULL },
    { "VWIN32",   0x002A, DeviceIo_VWin32 },
    { "VCOMM",    0x002B, NULL },
    { "SPOOLER",  0x002C, NULL },
    { "WIN32S",   0x002D, NULL },
    { "DEBUGCMD", 0x002E, NULL },

    { "VNB",      0x0031, DeviceIo_VNB },
    { "SERVER",   0x0032, NULL },
    { "CONFIGMG", 0x0033, NULL },
    { "DWCFGMG",  0x0034, NULL },
    { "SCSIPORT", 0x0035, NULL },
    { "VFBACKUP", 0x0036, NULL },
    { "ENABLE",   0x0037, NULL },
    { "VCOND",    0x0038, NULL },

    { "EFAX",     0x003A, NULL },
    { "DSVXD",    0x003B, NULL },
    { "ISAPNP",   0x003C, NULL },
    { "BIOS",     0x003D, NULL },
    { "WINSOCK",  0x003E, NULL },
    { "WSOCK",    0x003E, NULL },
    { "WSIPX",    0x003F, NULL },
    { "IFSMgr",   0x0040, DeviceIo_IFSMgr },
    { "VCDFSD",   0x0041, NULL },
    { "MRCI2",    0x0042, NULL },
    { "PCI",      0x0043, NULL },
    { "PELOADER", 0x0044, NULL },
    { "EISA",     0x0045, NULL },
    { "DRAGCLI",  0x0046, NULL },
    { "DRAGSRV",  0x0047, NULL },
    { "PERF",     0x0048, NULL },
    { "AWREDIR",  0x0049, NULL },

    /* Far East support */
    { "ETEN",     0x0060, NULL },
    { "CHBIOS",   0x0061, NULL },
    { "VMSGD",    0x0062, NULL },
    { "VPPID",    0x0063, NULL },
    { "VIME",     0x0064, NULL },
    { "VHBIOSD",  0x0065, NULL },

    /* Multimedia OEM IDs */
    { "VTDAPI",   0x0442, DeviceIo_VTDAPI },
    { "MMDEVLDR", 0x044A, DeviceIo_MMDEVLDR },

    /* Network Device IDs */
    { "VNetSup",  0x0480, NULL },
    { "VRedir",   0x0481, NULL },
    { "VBrowse",  0x0482, NULL },
    { "VSHARE",   0x0483, NULL },
    { "IFSMgr",   0x0484, NULL },
    { "MEMPROBE", 0x0485, NULL },
    { "VFAT",     0x0486, NULL },
    { "NWLINK",   0x0487, NULL },
    { "VNWLINK",  0x0487, NULL },
    { "NWSUP",    0x0487, NULL },
    { "VTDI",     0x0488, NULL },
    { "VIP",      0x0489, NULL },
    { "VTCP",     0x048A, NULL },
    { "VCache",   0x048B, NULL },
    { "VUDP",     0x048C, NULL },
    { "VAsync",   0x048D, NULL },
    { "NWREDIR",  0x048E, NULL },
    { "STAT80",   0x048F, NULL },
    { "SCSIPORT", 0x0490, NULL },
    { "FILESEC",  0x0491, NULL },
    { "NWSERVER", 0x0492, NULL },
    { "SECPROV",  0x0493, NULL },
    { "NSCL",     0x0494, NULL },
    { "WSTCP",    0x0495, NULL },
    { "NDIS2SUP", 0x0496, NULL },
    { "MSODISUP", 0x0497, NULL },
    { "Splitter", 0x0498, NULL },
    { "PPP",      0x0499, NULL },
    { "VDHCP",    0x049A, DeviceIo_DHCP },
    { "VNBT",     0x049B, NULL },
    { "LOGGER",   0x049D, NULL },
    { "EFILTER",  0x049E, NULL },
    { "FFILTER",  0x049F, NULL },
    { "TFILTER",  0x04A0, NULL },
    { "AFILTER",  0x04A1, NULL },
    { "IRLAMP",   0x04A2, NULL },

    { "PCCARD",   0x097C, DeviceIo_PCCARD },
    { "HASP95",   0x3721, DeviceIo_HASP },

    /* WINE additions, ids unknown */
    { "MONODEBG.VXD", 0x4242, DeviceIo_MONODEBG },

    { NULL,       0,      NULL }
};

HANDLE DEVICE_Open( LPCWSTR filenameW, DWORD access, LPSECURITY_ATTRIBUTES sa )
{
    const struct VxDInfo *info;
    char filename[MAX_PATH];

    if (!WideCharToMultiByte(CP_ACP, 0, filenameW, -1, filename, MAX_PATH, NULL, NULL))
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    for (info = VxDList; info->name; info++)
        if (!strncasecmp( info->name, filename, strlen(info->name) ))
            return FILE_CreateDevice( info->id | 0x10000, access, sa );

    FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n",
           filename);

    SetLastError( ERROR_FILE_NOT_FOUND );
    return 0;
}

static DWORD DEVICE_GetClientID( HANDLE handle )
{
    DWORD       ret = 0;
    SERVER_START_REQ( get_device_id )
    {
        req->handle = handle;
        if (!wine_server_call( req )) ret = reply->id;
    }
    SERVER_END_REQ;
    return ret;
}

static const struct VxDInfo *DEVICE_GetInfo( DWORD clientID )
{
    const struct VxDInfo *info = NULL;

    if (clientID & 0x10000)
    {
        for (info = VxDList; info->name; info++)
            if (info->id == LOWORD(clientID)) break;
    }
    return info;
}

/****************************************************************************
 *		DeviceIoControl (KERNEL32.@)
 * This is one of those big ugly nasty procedure which can do
 * a million and one things when it comes to devices. It can also be
 * used for VxD communication.
 *
 * A return value of FALSE indicates that something has gone wrong which
 * GetLastError can decipher.
 */
BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
        DWORD clientID;

        TRACE( "(%p,%ld,%p,%ld,%p,%ld,%p,%p)\n",
               hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer,
               lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped	);

	if (!(clientID = DEVICE_GetClientID( hDevice )))
	{
		SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
	}

	/* Check if this is a user defined control code for a VxD */
	if( HIWORD( dwIoControlCode ) == 0 )
	{
                const struct VxDInfo *info;
                if (!(info = DEVICE_GetInfo( clientID )))
                {
                        FIXME( "No device found for id %lx\n", clientID);
                }
                else if ( info->deviceio )
		{
			return info->deviceio( dwIoControlCode,
                                        lpvInBuffer, cbInBuffer,
                                        lpvOutBuffer, cbOutBuffer,
                                        lpcbBytesReturned, lpOverlapped );
		}
		else
		{
			FIXME( "Unimplemented control %ld for VxD device %s\n",
                               dwIoControlCode, info->name ? info->name : "???" );
			/* FIXME: this is for invalid calls on W98SE,
			 * but maybe we should use ERROR_CALL_NOT_IMPLEMENTED
			 * instead ? */
			SetLastError( ERROR_INVALID_FUNCTION );
		}
	}
	else
	{       
            NTSTATUS            status;

            if (lpOverlapped)
            {
                status = NtDeviceIoControlFile(hDevice, lpOverlapped->hEvent, 
                                               NULL, NULL, 
                                               (PIO_STATUS_BLOCK)lpOverlapped,
                                               dwIoControlCode, 
                                               lpvInBuffer, cbInBuffer,
                                               lpvOutBuffer, cbOutBuffer);
                if (status) SetLastError(RtlNtStatusToDosError(status));
                if (lpcbBytesReturned) *lpcbBytesReturned = lpOverlapped->InternalHigh;
                return !status;
            }
            else
            {
                IO_STATUS_BLOCK     iosb;

                status = NtDeviceIoControlFile(hDevice, NULL, NULL, NULL, &iosb,
                                               dwIoControlCode, 
                                               lpvInBuffer, cbInBuffer,
                                               lpvOutBuffer, cbOutBuffer);
                if (status) SetLastError(RtlNtStatusToDosError(status));
                if (lpcbBytesReturned) *lpcbBytesReturned = iosb.Information;
                return !status;
            }
	}
   	return FALSE;
}

/***********************************************************************
 *           DeviceIo_VTDAPI
 */
static BOOL DeviceIo_VTDAPI(DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
    BOOL retv = TRUE;

    switch (dwIoControlCode)
    {
    case 5:
        if (lpvOutBuffer && (cbOutBuffer>=4))
            *(DWORD*)lpvOutBuffer = GetTickCount();

        if (lpcbBytesReturned)
            *lpcbBytesReturned = 4;

        break;

    default:
        FIXME( "Control %ld not implemented\n", dwIoControlCode);
        retv = FALSE;
        break;
    }

    return retv;
}

/***********************************************************************
 *           DeviceIo_IFSMgr
 * NOTES
 *   These ioctls are used by 'MSNET32.DLL'.
 *
 *   I have been unable to uncover any documentation about the ioctls so
 *   the implementation of the cases IFS_IOCTL_21 and IFS_IOCTL_2F are
 *   based on reasonable guesses on information found in the Windows 95 DDK.
 *
 */

/*
 * IFSMgr DeviceIO service
 */

#define IFS_IOCTL_21                100
#define IFS_IOCTL_2F                101
#define	IFS_IOCTL_GET_RES           102
#define IFS_IOCTL_GET_NETPRO_NAME_A 103

struct win32apireq {
	unsigned long 	ar_proid;
	unsigned long  	ar_eax;
	unsigned long  	ar_ebx;
	unsigned long  	ar_ecx;
	unsigned long  	ar_edx;
	unsigned long  	ar_esi;
	unsigned long  	ar_edi;
	unsigned long  	ar_ebp;
	unsigned short 	ar_error;
	unsigned short  ar_pad;
};

static void win32apieq_2_CONTEXT(struct win32apireq *pIn,CONTEXT86 *pCxt)
{
	memset(pCxt,0,sizeof(*pCxt));

	pCxt->ContextFlags=CONTEXT86_INTEGER|CONTEXT86_CONTROL;
	pCxt->Eax = pIn->ar_eax;
	pCxt->Ebx = pIn->ar_ebx;
	pCxt->Ecx = pIn->ar_ecx;
	pCxt->Edx = pIn->ar_edx;
	pCxt->Esi = pIn->ar_esi;
	pCxt->Edi = pIn->ar_edi;

	/* FIXME: Only partial CONTEXT86_CONTROL */
	pCxt->Ebp = pIn->ar_ebp;

	/* FIXME: pIn->ar_proid ignored */
	/* FIXME: pIn->ar_error ignored */
	/* FIXME: pIn->ar_pad ignored */
}

static void CONTEXT_2_win32apieq(CONTEXT86 *pCxt,struct win32apireq *pOut)
{
	memset(pOut,0,sizeof(struct win32apireq));

	pOut->ar_eax = pCxt->Eax;
	pOut->ar_ebx = pCxt->Ebx;
	pOut->ar_ecx = pCxt->Ecx;
	pOut->ar_edx = pCxt->Edx;
	pOut->ar_esi = pCxt->Esi;
	pOut->ar_edi = pCxt->Edi;

	/* FIXME: Only partial CONTEXT86_CONTROL */
	pOut->ar_ebp = pCxt->Ebp;

	/* FIXME: pOut->ar_proid ignored */
	/* FIXME: pOut->ar_error ignored */
	/* FIXME: pOut->ar_pad ignored */
}

static BOOL DeviceIo_IFSMgr(DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
    BOOL retv = TRUE;
	TRACE("(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
			dwIoControlCode,
			lpvInBuffer,cbInBuffer,
			lpvOutBuffer,cbOutBuffer,
			lpcbBytesReturned,
			lpOverlapped);

    switch (dwIoControlCode)
    {
	case IFS_IOCTL_21:
	case IFS_IOCTL_2F:{
		CONTEXT86 cxt;
		struct win32apireq *pIn=(struct win32apireq *) lpvInBuffer;
		struct win32apireq *pOut=(struct win32apireq *) lpvOutBuffer;

		TRACE(
			"Control '%s': "
			"proid=0x%08lx, eax=0x%08lx, ebx=0x%08lx, ecx=0x%08lx, "
			"edx=0x%08lx, esi=0x%08lx, edi=0x%08lx, ebp=0x%08lx, "
			"error=0x%04x, pad=0x%04x\n",
			(dwIoControlCode==IFS_IOCTL_21)?"IFS_IOCTL_21":"IFS_IOCTL_2F",
			pIn->ar_proid, pIn->ar_eax, pIn->ar_ebx, pIn->ar_ecx,
			pIn->ar_edx, pIn->ar_esi, pIn->ar_edi, pIn->ar_ebp,
			pIn->ar_error, pIn->ar_pad
		);

		win32apieq_2_CONTEXT(pIn,&cxt);

		if(dwIoControlCode==IFS_IOCTL_21)
                    INSTR_CallBuiltinHandler( &cxt, 0x21 );
                else
                    INSTR_CallBuiltinHandler( &cxt, 0x2f );

		CONTEXT_2_win32apieq(&cxt,pOut);

        retv = TRUE;
	} break;
	case IFS_IOCTL_GET_RES:{
        FIXME( "Control 'IFS_IOCTL_GET_RES' not implemented\n");
        retv = FALSE;
	} break;
	case IFS_IOCTL_GET_NETPRO_NAME_A:{
        FIXME( "Control 'IFS_IOCTL_GET_NETPRO_NAME_A' not implemented\n");
        retv = FALSE;
	} break;
    default:
        FIXME( "Control %ld not implemented\n", dwIoControlCode);
        retv = FALSE;
    }

    return retv;
}

/***********************************************************************
 *           DeviceIo_VCD
 */
static BOOL DeviceIo_VCD(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
    BOOL retv = TRUE;

    switch (dwIoControlCode)
    {
    case IOCTL_SERIAL_LSRMST_INSERT:
    {
        FIXME( "IOCTL_SERIAL_LSRMST_INSERT NIY !\n");
        retv = FALSE;
    }
    break;

    default:
        FIXME( "Unknown Control %ld\n", dwIoControlCode);
        retv = FALSE;
        break;
    }

    return retv;
}


/***********************************************************************
 *           DeviceIo_VWin32
 */

static void DIOCRegs_2_CONTEXT( DIOC_REGISTERS *pIn, CONTEXT86 *pCxt )
{
    memset( pCxt, 0, sizeof(*pCxt) );
    /* Note: segment registers == 0 means that CTX_SEG_OFF_TO_LIN
             will interpret 32-bit register contents as linear pointers */

    pCxt->ContextFlags=CONTEXT86_INTEGER|CONTEXT86_CONTROL;
    pCxt->Eax = pIn->reg_EAX;
    pCxt->Ebx = pIn->reg_EBX;
    pCxt->Ecx = pIn->reg_ECX;
    pCxt->Edx = pIn->reg_EDX;
    pCxt->Esi = pIn->reg_ESI;
    pCxt->Edi = pIn->reg_EDI;

    /* FIXME: Only partial CONTEXT86_CONTROL */

    pCxt->EFlags = pIn->reg_Flags & ~0x00020000; /* clear vm86 mode */
}

static void CONTEXT_2_DIOCRegs( CONTEXT86 *pCxt, DIOC_REGISTERS *pOut )
{
    memset( pOut, 0, sizeof(DIOC_REGISTERS) );

    pOut->reg_EAX = pCxt->Eax;
    pOut->reg_EBX = pCxt->Ebx;
    pOut->reg_ECX = pCxt->Ecx;
    pOut->reg_EDX = pCxt->Edx;
    pOut->reg_ESI = pCxt->Esi;
    pOut->reg_EDI = pCxt->Edi;

    /* FIXME: Only partial CONTEXT86_CONTROL */
    pOut->reg_Flags = pCxt->EFlags;
}

#define DIOC_AH(regs) (((unsigned char*)&((regs)->reg_EAX))[1])
#define DIOC_AL(regs) (((unsigned char*)&((regs)->reg_EAX))[0])
#define DIOC_BH(regs) (((unsigned char*)&((regs)->reg_EBX))[1])
#define DIOC_BL(regs) (((unsigned char*)&((regs)->reg_EBX))[0])
#define DIOC_DH(regs) (((unsigned char*)&((regs)->reg_EDX))[1])
#define DIOC_DL(regs) (((unsigned char*)&((regs)->reg_EDX))[0])

#define DIOC_AX(regs) (((unsigned short*)&((regs)->reg_EAX))[0])
#define DIOC_BX(regs) (((unsigned short*)&((regs)->reg_EBX))[0])
#define DIOC_CX(regs) (((unsigned short*)&((regs)->reg_ECX))[0])
#define DIOC_DX(regs) (((unsigned short*)&((regs)->reg_EDX))[0])

#define DIOC_SET_CARRY(regs) (((regs)->reg_Flags)|=0x00000001)

static BOOL DeviceIo_VWin32(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
    BOOL retv = TRUE;

    switch (dwIoControlCode)
    {
    case VWIN32_DIOC_DOS_IOCTL:
    case 0x10: /* Int 0x21 call, call it VWIN_DIOC_INT21 ? */
    case VWIN32_DIOC_DOS_INT13:
    case VWIN32_DIOC_DOS_INT25:
    case VWIN32_DIOC_DOS_INT26:
    case 0x29: /* Int 0x31 call, call it VWIN_DIOC_INT31 ? */
    case VWIN32_DIOC_DOS_DRIVEINFO:
    {
        CONTEXT86 cxt;
        DIOC_REGISTERS *pIn  = (DIOC_REGISTERS *)lpvInBuffer;
        DIOC_REGISTERS *pOut = (DIOC_REGISTERS *)lpvOutBuffer;
        BYTE intnum = 0;

        TRACE( "Control '%s': "
               "eax=0x%08lx, ebx=0x%08lx, ecx=0x%08lx, "
               "edx=0x%08lx, esi=0x%08lx, edi=0x%08lx \n",
               (dwIoControlCode == VWIN32_DIOC_DOS_IOCTL)? "VWIN32_DIOC_DOS_IOCTL" :
               (dwIoControlCode == VWIN32_DIOC_DOS_INT25)? "VWIN32_DIOC_DOS_INT25" :
               (dwIoControlCode == VWIN32_DIOC_DOS_INT26)? "VWIN32_DIOC_DOS_INT26" :
               (dwIoControlCode == VWIN32_DIOC_DOS_DRIVEINFO)? "VWIN32_DIOC_DOS_DRIVEINFO" :  "???",
               pIn->reg_EAX, pIn->reg_EBX, pIn->reg_ECX,
               pIn->reg_EDX, pIn->reg_ESI, pIn->reg_EDI );

        DIOCRegs_2_CONTEXT( pIn, &cxt );

        switch (dwIoControlCode)
        {
        case VWIN32_DIOC_DOS_IOCTL: /* Call int 21h */
        case 0x10: /* Int 0x21 call, call it VWIN_DIOC_INT21 ? */
        case VWIN32_DIOC_DOS_DRIVEINFO:        /* Call int 21h 730x */
            intnum = 0x21;
            break;
        case VWIN32_DIOC_DOS_INT13:
            intnum = 0x13;
            break;
        case VWIN32_DIOC_DOS_INT25: 
            intnum = 0x25;
            break;
        case VWIN32_DIOC_DOS_INT26:
            intnum = 0x26;
            break;
        case 0x29: /* Int 0x31 call, call it VWIN_DIOC_INT31 ? */
            intnum = 0x31;
            break;
        }

        INSTR_CallBuiltinHandler( &cxt, intnum );
        CONTEXT_2_DIOCRegs( &cxt, pOut );
    }
    break;

    case VWIN32_DIOC_SIMCTRLC:
        FIXME( "Control VWIN32_DIOC_SIMCTRLC not implemented\n");
        retv = FALSE;
        break;

    default:
        FIXME( "Unknown Control %ld\n", dwIoControlCode);
        retv = FALSE;
        break;
    }

    return retv;
}

/* this is the main multimedia device loader */
static BOOL DeviceIo_MMDEVLDR(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
	FIXME("(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
	    dwIoControlCode,
	    lpvInBuffer,cbInBuffer,
	    lpvOutBuffer,cbOutBuffer,
	    lpcbBytesReturned,
	    lpOverlapped
	);
	switch (dwIoControlCode) {
	case 5:
		/* Hmm. */
		*(DWORD*)lpvOutBuffer=0;
		*lpcbBytesReturned=4;
		return TRUE;
	}
	return FALSE;
}
/* this is used by some Origin games */
static BOOL DeviceIo_MONODEBG(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
	switch (dwIoControlCode) {
	case 1:	/* version */
		*(LPDWORD)lpvOutBuffer = 0x20004; /* WC SecretOps */
		break;
	case 9: /* debug output */
		ERR("MONODEBG: %s\n",debugstr_a(lpvInBuffer));
		break;
	default:
		FIXME("(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
			dwIoControlCode,
			lpvInBuffer,cbInBuffer,
			lpvOutBuffer,cbOutBuffer,
			lpcbBytesReturned,
			lpOverlapped
		);
		break;
	}
	return TRUE;
}

/* pccard */
static BOOL DeviceIo_PCCARD (DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
	switch (dwIoControlCode) {
	case 0x0000: /* PCCARD_Get_Version */
	case 0x0001: /* PCCARD_Card_Services */
	default:
		FIXME( "(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
			dwIoControlCode,
			lpvInBuffer,cbInBuffer,
			lpvOutBuffer,cbOutBuffer,
			lpcbBytesReturned,
			lpOverlapped
		);
		break;
	}
	return FALSE;
}

static BOOL DeviceIo_HASP(DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
    BOOL retv = TRUE;
	FIXME("(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
			dwIoControlCode,
			lpvInBuffer,cbInBuffer,
			lpvOutBuffer,cbOutBuffer,
			lpcbBytesReturned,
			lpOverlapped);

    return retv;
}

typedef UCHAR (WINAPI *NetbiosFunc)(LPVOID);

static BOOL DeviceIo_NetBIOS(DWORD dwIoControlCode,
			      LPVOID lpvInBuffer, DWORD cbInBuffer,
			      LPVOID lpvOutBuffer, DWORD cbOutBuffer,
			      LPDWORD lpcbBytesReturned,
			      LPOVERLAPPED lpOverlapped)
{
    static HMODULE netapi;
    static NetbiosFunc pNetbios;

    if (dwIoControlCode != 256)
    {
        FIXME("(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
                dwIoControlCode,
                lpvInBuffer,cbInBuffer,
                lpvOutBuffer,cbOutBuffer,
                lpcbBytesReturned,
                lpOverlapped);
    }
    else
    {
        if (!pNetbios)
        {
            if (!netapi) netapi = LoadLibraryA("netapi32.dll");
            if (netapi) pNetbios = (NetbiosFunc)GetProcAddress(netapi, "Netbios");
        }
        if (pNetbios)
        {
            pNetbios(lpvInBuffer);
            return TRUE;
        }
    }
    return FALSE;
}

static BOOL DeviceIo_DHCP(DWORD dwIoControlCode, LPVOID lpvInBuffer,
                          DWORD cbInBuffer,
                          LPVOID lpvOutBuffer, DWORD cbOutBuffer,
                          LPDWORD lpcbBytesReturned,
                          LPOVERLAPPED lpOverlapped)
{
    DWORD error;

    switch (dwIoControlCode) {
    case 1:
    {
        /* since IpReleaseAddress/IpRenewAddress are not implemented, say there
         * are no DHCP adapters
         */
        error = ERROR_FILE_NOT_FOUND;
        break;
    }

    /* FIXME: don't know what this means */
    case 5:
        if (lpcbBytesReturned)
            *lpcbBytesReturned = sizeof(DWORD);
        if (lpvOutBuffer && cbOutBuffer >= 4)
        {
            *(LPDWORD)lpvOutBuffer = 0;
            error = NO_ERROR;
        }
        else
            error = ERROR_BUFFER_OVERFLOW;
        break;

    default:
        FIXME("(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
                dwIoControlCode,
                lpvInBuffer,cbInBuffer,
                lpvOutBuffer,cbOutBuffer,
                lpcbBytesReturned,
                lpOverlapped);
        error = ERROR_NOT_SUPPORTED;
        break;
    }
    if (error)
        SetLastError(error);
    return error == NO_ERROR;
}

typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO, PDWORD);
typedef DWORD (WINAPI *GetAdaptersInfoFunc)(PIP_ADAPTER_INFO, PDWORD);

typedef struct _nbtInfo
{
    DWORD ip;
    DWORD winsPrimary;
    DWORD winsSecondary;
    DWORD dnsPrimary;
    DWORD dnsSecondary;
    DWORD unk0;
} nbtInfo;

#define MAX_NBT_ENTRIES 7

typedef struct _nbtTable
{
    DWORD   numEntries;
    nbtInfo table[MAX_NBT_ENTRIES];
    UCHAR   pad[6];
    WORD    nodeType;
    WORD    scopeLen;
    char    scope[254];
} nbtTable;

static BOOL DeviceIo_VNB(DWORD dwIoControlCode,
                         LPVOID lpvInBuffer, DWORD cbInBuffer,
                         LPVOID lpvOutBuffer, DWORD cbOutBuffer,
                         LPDWORD lpcbBytesReturned,
                         LPOVERLAPPED lpOverlapped)
{
    static HMODULE iphlpapi;
    static GetNetworkParamsFunc pGetNetworkParams;
    static GetAdaptersInfoFunc pGetAdaptersInfo;
    DWORD error;

    switch (dwIoControlCode)
    {
        case 116:
            if (lpcbBytesReturned)
                *lpcbBytesReturned = sizeof(nbtTable);
            if (!lpvOutBuffer || cbOutBuffer < sizeof(nbtTable))
                error = ERROR_BUFFER_OVERFLOW;
            else
            {
                nbtTable *info = (nbtTable *)lpvOutBuffer;

                memset(info, 0, sizeof(nbtTable));
                if (!iphlpapi)
                {
                    iphlpapi = LoadLibraryA("iphlpapi.dll");
                    pGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(iphlpapi,"GetNetworkParams");
                    pGetAdaptersInfo = (GetAdaptersInfoFunc)GetProcAddress(iphlpapi, "GetAdaptersInfo");
                }
                if (iphlpapi)
                {
                    DWORD size = 0;

                    error = pGetNetworkParams(NULL, &size);
                    if (ERROR_BUFFER_OVERFLOW == error)
                    {
                        PFIXED_INFO fixedInfo = (PFIXED_INFO)HeapAlloc(
                         GetProcessHeap(), 0, size);

                        error = pGetNetworkParams(fixedInfo, &size);
                        if (NO_ERROR == error)
                        {
                            info->nodeType = (WORD)fixedInfo->NodeType;
                            info->scopeLen = max(strlen(fixedInfo->ScopeId) + 1,
                             sizeof(info->scope) - 1);
                            memcpy(info->scope, fixedInfo->ScopeId,
                             info->scopeLen);
                            info->scope[info->scopeLen] = '\0';
                            /* FIXME: gotta L2-encode the scope ID */
                            /* could set DNS servers here too, but since
                             * ipconfig.exe and winipcfg.exe read these from the
                             * registry, there's no point */
                        }
                        if (fixedInfo)
                            HeapFree(GetProcessHeap(), 0, fixedInfo);
                    }
                    size = 0;
                    error = pGetAdaptersInfo(NULL, &size);
                    if (ERROR_BUFFER_OVERFLOW == error)
                    {
                        PIP_ADAPTER_INFO adapterInfo = (PIP_ADAPTER_INFO)
                         HeapAlloc(GetProcessHeap(), 0, size);

                        error = pGetAdaptersInfo(adapterInfo, &size);
                        if (NO_ERROR == error)
                        {
                            PIP_ADAPTER_INFO ptr = adapterInfo;

                            for (ptr = adapterInfo; ptr && info->numEntries <
                             MAX_NBT_ENTRIES; ptr = ptr->Next)
                            {
                                unsigned long addr;

                                addr = inet_addr(
                                 ptr->IpAddressList.IpAddress.String);
                                if (addr != 0 && addr != INADDR_NONE)
                                    info->table[info->numEntries].ip =
                                     ntohl(addr);
                                addr = inet_addr(
                                 ptr->PrimaryWinsServer.IpAddress.String);
                                if (addr != 0 && addr != INADDR_NONE)
                                    info->table[info->numEntries].winsPrimary
                                     = ntohl(addr);
                                addr = inet_addr(
                                 ptr->SecondaryWinsServer.IpAddress.String);
                                if (addr != 0 && addr != INADDR_NONE)
                                    info->table[info->numEntries].winsSecondary
                                     = ntohl(addr);
                                info->numEntries++;
                            }
                        }
                        if (adapterInfo)
                            HeapFree(GetProcessHeap(), 0, adapterInfo);
                    }
                }
                else
                    error = GetLastError();
            }
            break;

        case 119:
            /* nbtstat.exe uses this, but the return seems to be a bunch of
             * pointers, so it's not so easy to reverse engineer.  Fall through
             * to unimplemented...
             */
        default:
            FIXME( "Unimplemented control %ld for VxD device VNB\n",
                               dwIoControlCode );
            error = ERROR_NOT_SUPPORTED;
            break;
    }
    if (error)
        SetLastError(error);
    return error == NO_ERROR;
}
