/*
 * Win32 VxD 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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_STAT_H
# include <sys/stat.h>
#endif
#include <string.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"
#include "winioctl.h"
#include "kernel_private.h"
#include "kernel16_private.h"
#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(vxd);

typedef DWORD (WINAPI *VxDCallProc)(DWORD, CONTEXT86 *);

struct vxd_module
{
    LARGE_INTEGER index;
    HANDLE        handle;
    HMODULE       module;
    DeviceIoProc  proc;
};

struct vxdcall_service
{
    WCHAR       name[12];
    DWORD       service;
    HMODULE     module;
    VxDCallProc proc;
};

#define MAX_VXD_MODULES 32

static struct vxd_module vxd_modules[MAX_VXD_MODULES];

static struct vxdcall_service vxd_services[] =
{
    { {'v','m','m','.','v','x','d',0},             0x0001, NULL, NULL },
    { {'v','w','i','n','3','2','.','v','x','d',0}, 0x002a, NULL, NULL }
};

#define NB_VXD_SERVICES  (sizeof(vxd_services)/sizeof(vxd_services[0]))

static CRITICAL_SECTION vxd_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &vxd_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": vxd_section") }
};
static CRITICAL_SECTION vxd_section = { &critsect_debug, -1, 0, 0, 0, 0 };


/* create a file handle to represent a VxD, by opening a dummy file in the wineserver directory */
static HANDLE open_vxd_handle( LPCWSTR name )
{
    static const WCHAR prefixW[] = {'\\','?','?','\\','u','n','i','x'};
    const char *dir = wine_get_server_dir();
    int len;
    HANDLE ret;
    NTSTATUS status;
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING nameW;
    IO_STATUS_BLOCK io;

    len = MultiByteToWideChar( CP_UNIXCP, 0, dir, -1, NULL, 0 );
    nameW.Length = sizeof(prefixW) + (len + strlenW( name )) * sizeof(WCHAR);
    nameW.MaximumLength = nameW.Length + sizeof(WCHAR);
    if (!(nameW.Buffer = HeapAlloc( GetProcessHeap(), 0, nameW.MaximumLength )))
    {
        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
        return 0;
    }
    memcpy( nameW.Buffer, prefixW, sizeof(prefixW) );
    MultiByteToWideChar( CP_UNIXCP, 0, dir, -1, nameW.Buffer + sizeof(prefixW)/sizeof(WCHAR), len );
    len += sizeof(prefixW) / sizeof(WCHAR);
    nameW.Buffer[len-1] = '/';
    strcpyW( nameW.Buffer + len, name );

    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.Attributes = 0;
    attr.ObjectName = &nameW;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;

    status = NtCreateFile( &ret, 0, &attr, &io, NULL, 0,
                           FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF,
                           FILE_SYNCHRONOUS_IO_ALERT, NULL, 0 );
    if (status)
    {
        ret = 0;
        SetLastError( RtlNtStatusToDosError(status) );
    }
    RtlFreeUnicodeString( &nameW );
    return ret;
}

/* retrieve the DeviceIoControl function for a Vxd given a file handle */
DeviceIoProc VXD_get_proc( HANDLE handle )
{
    DeviceIoProc ret = NULL;
    int status, i;
    IO_STATUS_BLOCK io;
    FILE_INTERNAL_INFORMATION info;

    status = NtQueryInformationFile( handle, &io, &info, sizeof(info), FileInternalInformation );
    if (status)
    {
        SetLastError( RtlNtStatusToDosError(status) );
        return NULL;
    }

    RtlEnterCriticalSection( &vxd_section );

    for (i = 0; i < MAX_VXD_MODULES; i++)
    {
        if (!vxd_modules[i].module) break;
        if (vxd_modules[i].index.QuadPart == info.IndexNumber.QuadPart)
        {
            if (!(ret = vxd_modules[i].proc)) SetLastError( ERROR_INVALID_FUNCTION );
            goto done;
        }
    }
    /* FIXME: Here we could go through the directory to find the VxD name and load it. */
    /* Let's wait to find out if there are actually apps out there that try to share   */
    /* VxD handles between processes, before we go to the trouble of implementing it.  */
    ERR( "handle %p not found in module list, inherited from another process?\n", handle );

done:
    RtlLeaveCriticalSection( &vxd_section );
    return ret;
}


/* load a VxD and return a file handle to it */
HANDLE VXD_Open( LPCWSTR filenameW, DWORD access, SECURITY_ATTRIBUTES *sa )
{
    static const WCHAR dotVxDW[] = {'.','v','x','d',0};
    int i;
    HANDLE handle;
    HMODULE module;
    WCHAR *p, name[16];

    if (!(GetVersion() & 0x80000000))  /* there are no VxDs on NT */
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    /* normalize the filename */

    if (strlenW( filenameW ) >= sizeof(name)/sizeof(WCHAR) - 4 ||
        strchrW( filenameW, '/' ) || strchrW( filenameW, '\\' ))
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }
    strcpyW( name, filenameW );
    strlwrW( name );
    p = strchrW( name, '.' );
    if (!p) strcatW( name, dotVxDW );
    else if (strcmpiW( p, dotVxDW ))  /* existing extension has to be .vxd */
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    /* try to load the module first */

    if (!(module = LoadLibraryW( name )))
    {
        FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n",
               debugstr_w(name) );
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    /* register the module in the global list if necessary */

    RtlEnterCriticalSection( &vxd_section );

    for (i = 0; i < MAX_VXD_MODULES; i++)
    {
        if (vxd_modules[i].module == module)
        {
            handle = vxd_modules[i].handle;
            goto done;  /* already registered */
        }
        if (!vxd_modules[i].module)  /* new one, register it */
        {
            IO_STATUS_BLOCK io;
            FILE_INTERNAL_INFORMATION info;

            /* get a file handle to the dummy file */
            if (!(handle = open_vxd_handle( name )))
            {
                FreeLibrary( module );
                goto done;
            }
            if (!NtQueryInformationFile( handle, &io, &info, sizeof(info), FileInternalInformation ))
                vxd_modules[i].index = info.IndexNumber;

            vxd_modules[i].module = module;
            vxd_modules[i].handle = handle;
            vxd_modules[i].proc = (DeviceIoProc)GetProcAddress( module, "DeviceIoControl" );
            goto done;
        }
    }

    ERR("too many open VxD modules, please report\n" );
    FreeLibrary( module );
    handle = 0;

done:
    RtlLeaveCriticalSection( &vxd_section );
    if (!DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle, 0,
                          (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle),
                          DUP_HANDLE_SAME_ACCESS ))
        handle = 0;
    return handle;
}


/***********************************************************************
 *		VxDCall0 (KERNEL32.1)
 *		VxDCall1 (KERNEL32.2)
 *		VxDCall2 (KERNEL32.3)
 *		VxDCall3 (KERNEL32.4)
 *		VxDCall4 (KERNEL32.5)
 *		VxDCall5 (KERNEL32.6)
 *		VxDCall6 (KERNEL32.7)
 *		VxDCall7 (KERNEL32.8)
 *		VxDCall8 (KERNEL32.9)
 */
void WINAPI __regs_VxDCall( DWORD service, CONTEXT86 *context )
{
    unsigned int i;
    VxDCallProc proc = NULL;

    RtlEnterCriticalSection( &vxd_section );
    for (i = 0; i < NB_VXD_SERVICES; i++)
    {
        if (HIWORD(service) != vxd_services[i].service) continue;
        if (!vxd_services[i].module)  /* need to load it */
        {
            if ((vxd_services[i].module = LoadLibraryW( vxd_services[i].name )))
                vxd_services[i].proc = (VxDCallProc)GetProcAddress( vxd_services[i].module, "VxDCall" );
        }
        proc = vxd_services[i].proc;
        break;
    }
    RtlLeaveCriticalSection( &vxd_section );

    if (proc) context->Eax = proc( service, context );
    else
    {
        FIXME( "Unknown/unimplemented VxD (%08x)\n", service);
        context->Eax = 0xffffffff; /* FIXME */
    }
}
#ifdef DEFINE_REGS_ENTRYPOINT
DEFINE_REGS_ENTRYPOINT( VxDCall, 1 )
#endif
