/*
 * MPR WNet functions
 *
 * Copyright 1999 Ulrich Weigand
 * Copyright 2004 Juan Lang
 * Copyright 2007 Maarten Lankhorst
 *
 * 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 <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winioctl.h"
#include "winnetwk.h"
#include "npapi.h"
#include "winreg.h"
#include "winuser.h"
#define WINE_MOUNTMGR_EXTENSIONS
#include "ddk/mountmgr.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "mprres.h"
#include "wnetpriv.h"

WINE_DEFAULT_DEBUG_CHANNEL(mpr);

/* Data structures representing network service providers.  Assumes only one
 * thread creates them, and that they are constant for the life of the process
 * (and therefore doesn't synchronize access).
 * FIXME: only basic provider data and enumeration-related data are implemented
 * so far, need to implement the rest too.
 */
typedef struct _WNetProvider
{
    HMODULE           hLib;
    PWSTR             name;
    PF_NPGetCaps      getCaps;
    DWORD             dwSpecVersion;
    DWORD             dwNetType;
    DWORD             dwEnumScopes;
    PF_NPOpenEnum     openEnum;
    PF_NPEnumResource enumResource;
    PF_NPCloseEnum    closeEnum;
    PF_NPGetResourceInformation getResourceInformation;
} WNetProvider, *PWNetProvider;

typedef struct _WNetProviderTable
{
    LPWSTR           entireNetwork;
    DWORD            numAllocated;
    DWORD            numProviders;
    WNetProvider     table[1];
} WNetProviderTable, *PWNetProviderTable;

#define WNET_ENUMERATOR_TYPE_NULL     0
#define WNET_ENUMERATOR_TYPE_GLOBAL   1
#define WNET_ENUMERATOR_TYPE_PROVIDER 2
#define WNET_ENUMERATOR_TYPE_CONTEXT  3

/* An WNet enumerator.  Note that the type doesn't correspond to the scope of
 * the enumeration; it represents one of the following types:
 * - a 'null' enumeration, one that contains no members
 * - a global enumeration, one that's executed across all providers
 * - a provider-specific enumeration, one that's only executed by a single
 *   provider
 * - a context enumeration.  I know this contradicts what I just said about
 *   there being no correspondence between the scope and the type, but it's
 *   necessary for the special case that a "Entire Network" entry needs to
 *   be enumerated in an enumeration of the context scope.  Thus an enumeration
 *   of the context scope results in a context type enumerator, which morphs
 *   into a global enumeration (so the enumeration continues across all
 *   providers).
 */
typedef struct _WNetEnumerator
{
    DWORD          enumType;
    DWORD          providerIndex;
    HANDLE         handle;
    BOOL           providerDone;
    DWORD          dwScope;
    DWORD          dwType;
    DWORD          dwUsage;
    LPNETRESOURCEW lpNet;
} WNetEnumerator, *PWNetEnumerator;

#define BAD_PROVIDER_INDEX (DWORD)0xffffffff

/* Returns an index (into the global WNetProviderTable) of the provider with
 * the given name, or BAD_PROVIDER_INDEX if not found.
 */
static DWORD _findProviderIndexW(LPCWSTR lpProvider);

static PWNetProviderTable providerTable;

/*
 * Global provider table functions
 */

static void _tryLoadProvider(PCWSTR provider)
{
    static const WCHAR servicePrefix[] = { 'S','y','s','t','e','m','\\',
     'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
     'S','e','r','v','i','c','e','s','\\',0 };
    static const WCHAR serviceFmt[] = { '%','s','%','s','\\',
     'N','e','t','w','o','r','k','P','r','o','v','i','d','e','r',0 };
    WCHAR serviceName[MAX_PATH];
    HKEY hKey;

    TRACE("%s\n", debugstr_w(provider));
    snprintfW(serviceName, sizeof(serviceName) / sizeof(WCHAR), serviceFmt,
     servicePrefix, provider);
    serviceName[sizeof(serviceName) / sizeof(WCHAR) - 1] = '\0';
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, serviceName, 0, KEY_READ, &hKey) ==
     ERROR_SUCCESS)
    {
        static const WCHAR szProviderPath[] = { 'P','r','o','v','i','d','e','r',
         'P','a','t','h',0 };
        WCHAR providerPath[MAX_PATH];
        DWORD type, size = sizeof(providerPath);

        if (RegQueryValueExW(hKey, szProviderPath, NULL, &type,
         (LPBYTE)providerPath, &size) == ERROR_SUCCESS && type == REG_SZ)
        {
            static const WCHAR szProviderName[] = { 'N','a','m','e',0 };
            PWSTR name = NULL;
           
            size = 0;
            RegQueryValueExW(hKey, szProviderName, NULL, NULL, NULL, &size);
            if (size)
            {
                name = HeapAlloc(GetProcessHeap(), 0, size);
                if (RegQueryValueExW(hKey, szProviderName, NULL, &type,
                 (LPBYTE)name, &size) != ERROR_SUCCESS || type != REG_SZ)
                {
                    HeapFree(GetProcessHeap(), 0, name);
                    name = NULL;
                }
            }
            if (name)
            {
                HMODULE hLib = LoadLibraryW(providerPath);

                if (hLib)
                {
                    PF_NPGetCaps getCaps = (PF_NPGetCaps)GetProcAddress(hLib,
                     "NPGetCaps");

                    TRACE("loaded lib %p\n", hLib);
                    if (getCaps)
                    {
                        PWNetProvider provider =
                         &providerTable->table[providerTable->numProviders];

                        provider->hLib = hLib;
                        provider->name = name;
                        TRACE("name is %s\n", debugstr_w(name));
                        provider->getCaps = getCaps;
                        provider->dwSpecVersion = getCaps(WNNC_SPEC_VERSION);
                        provider->dwNetType = getCaps(WNNC_NET_TYPE);
                        TRACE("net type is 0x%08x\n", provider->dwNetType);
                        provider->dwEnumScopes = getCaps(WNNC_ENUMERATION);
                        if (provider->dwEnumScopes)
                        {
                            TRACE("supports enumeration\n");
                            provider->openEnum = (PF_NPOpenEnum)
                             GetProcAddress(hLib, "NPOpenEnum");
                            TRACE("openEnum is %p\n", provider->openEnum);
                            provider->enumResource = (PF_NPEnumResource)
                             GetProcAddress(hLib, "NPEnumResource");
                            TRACE("enumResource is %p\n",
                             provider->enumResource);
                            provider->closeEnum = (PF_NPCloseEnum)
                             GetProcAddress(hLib, "NPCloseEnum");
                            TRACE("closeEnum is %p\n", provider->closeEnum);
                            provider->getResourceInformation = (PF_NPGetResourceInformation)
                                    GetProcAddress(hLib, "NPGetResourceInformation");
                            TRACE("getResourceInformation is %p\n",
                                  provider->getResourceInformation);
                            if (!provider->openEnum || !provider->enumResource
                             || !provider->closeEnum)
                            {
                                provider->openEnum = NULL;
                                provider->enumResource = NULL;
                                provider->closeEnum = NULL;
                                provider->dwEnumScopes = 0;
                                WARN("Couldn't load enumeration functions\n");
                            }
                        }
                        providerTable->numProviders++;
                    }
                    else
                    {
                        WARN("Provider %s didn't export NPGetCaps\n",
                         debugstr_w(provider));
                        HeapFree(GetProcessHeap(), 0, name);
                        FreeLibrary(hLib);
                    }
                }
                else
                {
                    WARN("Couldn't load library %s for provider %s\n",
                     debugstr_w(providerPath), debugstr_w(provider));
                    HeapFree(GetProcessHeap(), 0, name);
                }
            }
            else
            {
                WARN("Couldn't get provider name for provider %s\n",
                 debugstr_w(provider));
            }
        }
        else
            WARN("Couldn't open value %s\n", debugstr_w(szProviderPath));
        RegCloseKey(hKey);
    }
    else
        WARN("Couldn't open service key for provider %s\n",
         debugstr_w(provider));
}

void wnetInit(HINSTANCE hInstDll)
{
    static const WCHAR providerOrderKey[] = { 'S','y','s','t','e','m','\\',
     'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
     'C','o','n','t','r','o','l','\\',
     'N','e','t','w','o','r','k','P','r','o','v','i','d','e','r','\\',
     'O','r','d','e','r',0 };
     static const WCHAR providerOrder[] = { 'P','r','o','v','i','d','e','r',
      'O','r','d','e','r',0 };
    HKEY hKey;

    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, providerOrderKey, 0, KEY_READ, &hKey)
     == ERROR_SUCCESS)
    {
        DWORD size = 0;

        RegQueryValueExW(hKey, providerOrder, NULL, NULL, NULL, &size);
        if (size)
        {
            PWSTR providers = HeapAlloc(GetProcessHeap(), 0, size);

            if (providers)
            {
                DWORD type;

                if (RegQueryValueExW(hKey, providerOrder, NULL, &type,
                 (LPBYTE)providers, &size) == ERROR_SUCCESS && type == REG_SZ)
                {
                    PWSTR ptr;
                    DWORD numToAllocate;

                    TRACE("provider order is %s\n", debugstr_w(providers));
                    /* first count commas as a heuristic for how many to
                     * allocate space for */
                    for (ptr = providers, numToAllocate = 1; ptr; )
                    {
                        ptr = strchrW(ptr, ',');
                        if (ptr) {
                            numToAllocate++;
                            ptr++;
                        }
                    }
                    providerTable =
                     HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                     sizeof(WNetProviderTable)
                     + (numToAllocate - 1) * sizeof(WNetProvider));
                    if (providerTable)
                    {
                        PWSTR ptrPrev;
                        int entireNetworkLen;
                        LPCWSTR stringresource;

                        entireNetworkLen = LoadStringW(hInstDll,
                         IDS_ENTIRENETWORK, (LPWSTR)&stringresource, 0);
                        providerTable->entireNetwork = HeapAlloc(
                         GetProcessHeap(), 0, (entireNetworkLen + 1) *
                         sizeof(WCHAR));
                        if (providerTable->entireNetwork)
                        {
                            memcpy(providerTable->entireNetwork, stringresource, entireNetworkLen*sizeof(WCHAR));
                            providerTable->entireNetwork[entireNetworkLen] = 0;
                        }
                        providerTable->numAllocated = numToAllocate;
                        for (ptr = providers; ptr; )
                        {
                            ptrPrev = ptr;
                            ptr = strchrW(ptr, ',');
                            if (ptr)
                                *ptr++ = '\0';
                            _tryLoadProvider(ptrPrev);
                        }
                    }
                }
                HeapFree(GetProcessHeap(), 0, providers);
            }
        }
        RegCloseKey(hKey);
    }
}

void wnetFree(void)
{
    if (providerTable)
    {
        DWORD i;

        for (i = 0; i < providerTable->numProviders; i++)
        {
            HeapFree(GetProcessHeap(), 0, providerTable->table[i].name);
            FreeModule(providerTable->table[i].hLib);
        }
        HeapFree(GetProcessHeap(), 0, providerTable->entireNetwork);
        HeapFree(GetProcessHeap(), 0, providerTable);
        providerTable = NULL;
    }
}

static DWORD _findProviderIndexW(LPCWSTR lpProvider)
{
    DWORD ret = BAD_PROVIDER_INDEX;

    if (providerTable && providerTable->numProviders)
    {
        DWORD i;

        for (i = 0; i < providerTable->numProviders &&
         ret == BAD_PROVIDER_INDEX; i++)
            if (!strcmpW(lpProvider, providerTable->table[i].name))
                ret = i;
    }
    return ret;
}

/*
 * Browsing Functions
 */

static LPNETRESOURCEW _copyNetResourceForEnumW(LPNETRESOURCEW lpNet)
{
    LPNETRESOURCEW ret;

    if (lpNet)
    {
        ret = HeapAlloc(GetProcessHeap(), 0, sizeof(NETRESOURCEW));
        if (ret)
        {
            size_t len;

            *ret = *lpNet;
            ret->lpLocalName = ret->lpComment = ret->lpProvider = NULL;
            if (lpNet->lpRemoteName)
            {
                len = strlenW(lpNet->lpRemoteName) + 1;
                ret->lpRemoteName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
                if (ret->lpRemoteName)
                    strcpyW(ret->lpRemoteName, lpNet->lpRemoteName);
            }
        }
    }
    else
        ret = NULL;
    return ret;
}

static void _freeEnumNetResource(LPNETRESOURCEW lpNet)
{
    if (lpNet)
    {
        HeapFree(GetProcessHeap(), 0, lpNet->lpRemoteName);
        HeapFree(GetProcessHeap(), 0, lpNet);
    }
}

static PWNetEnumerator _createNullEnumerator(void)
{
    PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
     HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));

    if (ret)
        ret->enumType = WNET_ENUMERATOR_TYPE_NULL;
    return ret;
}

static PWNetEnumerator _createGlobalEnumeratorW(DWORD dwScope, DWORD dwType,
 DWORD dwUsage, LPNETRESOURCEW lpNet)
{
    PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
     HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));

    if (ret)
    {
        ret->enumType = WNET_ENUMERATOR_TYPE_GLOBAL;
        ret->dwScope = dwScope;
        ret->dwType  = dwType;
        ret->dwUsage = dwUsage;
        ret->lpNet   = _copyNetResourceForEnumW(lpNet);
    }
    return ret;
}

static PWNetEnumerator _createProviderEnumerator(DWORD dwScope, DWORD dwType,
 DWORD dwUsage, DWORD index, HANDLE handle)
{
    PWNetEnumerator ret;

    if (!providerTable || index >= providerTable->numProviders)
        ret = NULL;
    else
    {
        ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));
        if (ret)
        {
            ret->enumType      = WNET_ENUMERATOR_TYPE_PROVIDER;
            ret->providerIndex = index;
            ret->dwScope       = dwScope;
            ret->dwType        = dwType;
            ret->dwUsage       = dwUsage;
            ret->handle        = handle;
        }
    }
    return ret;
}

static PWNetEnumerator _createContextEnumerator(DWORD dwScope, DWORD dwType,
 DWORD dwUsage)
{
    PWNetEnumerator ret = HeapAlloc(GetProcessHeap(),
     HEAP_ZERO_MEMORY, sizeof(WNetEnumerator));

    if (ret)
    {
        ret->enumType = WNET_ENUMERATOR_TYPE_CONTEXT;
        ret->dwScope = dwScope;
        ret->dwType  = dwType;
        ret->dwUsage = dwUsage;
    }
    return ret;
}

/* Thunks the array of wide-string LPNETRESOURCEs lpNetArrayIn into buffer
 * lpBuffer, with size *lpBufferSize.  lpNetArrayIn contains *lpcCount entries
 * to start.  On return, *lpcCount reflects the number thunked into lpBuffer.
 * Returns WN_SUCCESS on success (all of lpNetArrayIn thunked), WN_MORE_DATA
 * if not all members of the array could be thunked, and something else on
 * failure.
 */
static DWORD _thunkNetResourceArrayWToA(const NETRESOURCEW *lpNetArrayIn,
 const DWORD *lpcCount, LPVOID lpBuffer, const DWORD *lpBufferSize)
{
    DWORD i, numToThunk, totalBytes, ret;
    LPSTR strNext;

    if (!lpNetArrayIn)
        return WN_BAD_POINTER;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (*lpcCount == -1)
        return WN_BAD_VALUE;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;

    for (i = 0, numToThunk = 0, totalBytes = 0; i < *lpcCount; i++)
    {
        const NETRESOURCEW *lpNet = lpNetArrayIn + i;

        totalBytes += sizeof(NETRESOURCEA);
        if (lpNet->lpLocalName)
            totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpLocalName,
             -1, NULL, 0, NULL, NULL);
        if (lpNet->lpRemoteName)
            totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpRemoteName,
             -1, NULL, 0, NULL, NULL);
        if (lpNet->lpComment)
            totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpComment,
             -1, NULL, 0, NULL, NULL);
        if (lpNet->lpProvider)
            totalBytes += WideCharToMultiByte(CP_ACP, 0, lpNet->lpProvider,
             -1, NULL, 0, NULL, NULL);
        if (totalBytes < *lpBufferSize)
            numToThunk = i + 1;
    }
    strNext = (LPSTR)((LPBYTE)lpBuffer + numToThunk * sizeof(NETRESOURCEA));
    for (i = 0; i < numToThunk; i++)
    {
        LPNETRESOURCEA lpNetOut = (LPNETRESOURCEA)lpBuffer + i;
        const NETRESOURCEW *lpNetIn = lpNetArrayIn + i;

        memcpy(lpNetOut, lpNetIn, sizeof(NETRESOURCEA));
        /* lie about string lengths, we already verified how many
         * we have space for above
         */
        if (lpNetIn->lpLocalName)
        {
            lpNetOut->lpLocalName = strNext;
            strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpLocalName, -1,
             lpNetOut->lpLocalName, *lpBufferSize, NULL, NULL);
        }
        if (lpNetIn->lpRemoteName)
        {
            lpNetOut->lpRemoteName = strNext;
            strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpRemoteName, -1,
             lpNetOut->lpRemoteName, *lpBufferSize, NULL, NULL);
        }
        if (lpNetIn->lpComment)
        {
            lpNetOut->lpComment = strNext;
            strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpComment, -1,
             lpNetOut->lpComment, *lpBufferSize, NULL, NULL);
        }
        if (lpNetIn->lpProvider)
        {
            lpNetOut->lpProvider = strNext;
            strNext += WideCharToMultiByte(CP_ACP, 0, lpNetIn->lpProvider, -1,
             lpNetOut->lpProvider, *lpBufferSize, NULL, NULL);
        }
    }
    ret = numToThunk < *lpcCount ? WN_MORE_DATA : WN_SUCCESS;
    TRACE("numToThunk is %d, *lpcCount is %d, returning %d\n", numToThunk,
     *lpcCount, ret);
    return ret;
}

/* Thunks the array of multibyte-string LPNETRESOURCEs lpNetArrayIn into buffer
 * lpBuffer, with size *lpBufferSize.  lpNetArrayIn contains *lpcCount entries
 * to start.  On return, *lpcCount reflects the number thunked into lpBuffer.
 * Returns WN_SUCCESS on success (all of lpNetArrayIn thunked), WN_MORE_DATA
 * if not all members of the array could be thunked, and something else on
 * failure.
 */
static DWORD _thunkNetResourceArrayAToW(const NETRESOURCEA *lpNetArrayIn,
 const DWORD *lpcCount, LPVOID lpBuffer, const DWORD *lpBufferSize)
{
    DWORD i, numToThunk, totalBytes, ret;
    LPWSTR strNext;

    if (!lpNetArrayIn)
        return WN_BAD_POINTER;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (*lpcCount == -1)
        return WN_BAD_VALUE;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;

    for (i = 0, numToThunk = 0, totalBytes = 0; i < *lpcCount; i++)
    {
        const NETRESOURCEA *lpNet = lpNetArrayIn + i;

        totalBytes += sizeof(NETRESOURCEW);
        if (lpNet->lpLocalName)
            totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpLocalName,
             -1, NULL, 0) * sizeof(WCHAR);
        if (lpNet->lpRemoteName)
            totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpRemoteName,
             -1, NULL, 0) * sizeof(WCHAR);
        if (lpNet->lpComment)
            totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpComment,
             -1, NULL, 0) * sizeof(WCHAR);
        if (lpNet->lpProvider)
            totalBytes += MultiByteToWideChar(CP_ACP, 0, lpNet->lpProvider,
             -1, NULL, 0) * sizeof(WCHAR);
        if (totalBytes < *lpBufferSize)
            numToThunk = i + 1;
    }
    strNext = (LPWSTR)((LPBYTE)lpBuffer + numToThunk * sizeof(NETRESOURCEW));
    for (i = 0; i < numToThunk; i++)
    {
        LPNETRESOURCEW lpNetOut = (LPNETRESOURCEW)lpBuffer + i;
        const NETRESOURCEA *lpNetIn = lpNetArrayIn + i;

        memcpy(lpNetOut, lpNetIn, sizeof(NETRESOURCEW));
        /* lie about string lengths, we already verified how many
         * we have space for above
         */
        if (lpNetIn->lpLocalName)
        {
            lpNetOut->lpLocalName = strNext;
            strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpLocalName,
             -1, lpNetOut->lpLocalName, *lpBufferSize);
        }
        if (lpNetIn->lpRemoteName)
        {
            lpNetOut->lpRemoteName = strNext;
            strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpRemoteName,
             -1, lpNetOut->lpRemoteName, *lpBufferSize);
        }
        if (lpNetIn->lpComment)
        {
            lpNetOut->lpComment = strNext;
            strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpComment,
             -1, lpNetOut->lpComment, *lpBufferSize);
        }
        if (lpNetIn->lpProvider)
        {
            lpNetOut->lpProvider = strNext;
            strNext += MultiByteToWideChar(CP_ACP, 0, lpNetIn->lpProvider,
             -1, lpNetOut->lpProvider, *lpBufferSize);
        }
    }
    ret = numToThunk < *lpcCount ? WN_MORE_DATA : WN_SUCCESS;
    TRACE("numToThunk is %d, *lpcCount is %d, returning %d\n", numToThunk,
     *lpcCount, ret);
    return ret;
}

/*********************************************************************
 * WNetOpenEnumA [MPR.@]
 *
 * See comments for WNetOpenEnumW.
 */
DWORD WINAPI WNetOpenEnumA( DWORD dwScope, DWORD dwType, DWORD dwUsage,
                            LPNETRESOURCEA lpNet, LPHANDLE lphEnum )
{
    DWORD ret;

    TRACE( "(%08X, %08X, %08X, %p, %p)\n",
	    dwScope, dwType, dwUsage, lpNet, lphEnum );

    if (!lphEnum)
        ret = WN_BAD_POINTER;
    else if (!providerTable || providerTable->numProviders == 0)
    {
        *lphEnum = NULL;
        ret = WN_NO_NETWORK;
    }
    else
    {
        if (lpNet)
        {
            LPNETRESOURCEW lpNetWide = NULL;
            BYTE buf[1024];
            DWORD size = sizeof(buf), count = 1;
            BOOL allocated = FALSE;

            ret = _thunkNetResourceArrayAToW(lpNet, &count, buf, &size);
            if (ret == WN_MORE_DATA)
            {
                lpNetWide = HeapAlloc(GetProcessHeap(), 0,
                 size);
                if (lpNetWide)
                {
                    ret = _thunkNetResourceArrayAToW(lpNet, &count, lpNetWide,
                     &size);
                    allocated = TRUE;
                }
                else
                    ret = WN_OUT_OF_MEMORY;
            }
            else if (ret == WN_SUCCESS)
                lpNetWide = (LPNETRESOURCEW)buf;
            if (ret == WN_SUCCESS)
                ret = WNetOpenEnumW(dwScope, dwType, dwUsage, lpNetWide,
                 lphEnum);
            if (allocated)
                HeapFree(GetProcessHeap(), 0, lpNetWide);
        }
        else
            ret = WNetOpenEnumW(dwScope, dwType, dwUsage, NULL, lphEnum);
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetOpenEnumW [MPR.@]
 *
 * Network enumeration has way too many parameters, so I'm not positive I got
 * them right.  What I've got so far:
 *
 * - If the scope is RESOURCE_GLOBALNET, and no LPNETRESOURCE is passed,
 *   all the network providers should be enumerated.
 *
 * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and
 *   and neither the LPNETRESOURCE's lpRemoteName nor the LPNETRESOURCE's
 *   lpProvider is set, all the network providers should be enumerated.
 *   (This means the enumeration is a list of network providers, not that the
 *   enumeration is passed on to the providers.)
 *
 * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and the
 *   resource matches the "Entire Network" resource (no remote name, no
 *   provider, comment is the "Entire Network" string), a RESOURCE_GLOBALNET
 *   enumeration is done on every network provider.
 *
 * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and
 *   the LPNETRESOURCE's lpProvider is set, enumeration will be passed through
 *   only to the given network provider.
 *
 * - If the scope is RESOURCE_GLOBALNET, and LPNETRESOURCE is passed, and
 *   no lpProvider is set, enumeration will be tried on every network provider,
 *   in the order in which they're loaded.
 *
 * - The LPNETRESOURCE should be disregarded for scopes besides
 *   RESOURCE_GLOBALNET.  MSDN states that lpNet must be NULL if dwScope is not
 *   RESOURCE_GLOBALNET, but Windows doesn't return an error if it isn't NULL.
 *
 * - If the scope is RESOURCE_CONTEXT, MS includes an "Entire Network" net
 *   resource in the enumerated list, as well as any machines in your
 *   workgroup.  The machines in your workgroup come from doing a
 *   RESOURCE_CONTEXT enumeration of every Network Provider.
 */
DWORD WINAPI WNetOpenEnumW( DWORD dwScope, DWORD dwType, DWORD dwUsage,
                            LPNETRESOURCEW lpNet, LPHANDLE lphEnum )
{
    DWORD ret;

    TRACE( "(%08X, %08X, %08X, %p, %p)\n",
          dwScope, dwType, dwUsage, lpNet, lphEnum );

    if (!lphEnum)
        ret = WN_BAD_POINTER;
    else if (!providerTable || providerTable->numProviders == 0)
    {
        *lphEnum = NULL;
        ret = WN_NO_NETWORK;
    }
    else
    {
        switch (dwScope)
        {
            case RESOURCE_GLOBALNET:
                if (lpNet)
                {
                    if (lpNet->lpProvider)
                    {
                        DWORD index = _findProviderIndexW(lpNet->lpProvider);

                        if (index != BAD_PROVIDER_INDEX)
                        {
                            if (providerTable->table[index].openEnum &&
                             providerTable->table[index].dwEnumScopes & WNNC_ENUM_GLOBAL)
                            {
                                HANDLE handle;

                                ret = providerTable->table[index].openEnum(
                                 dwScope, dwType, dwUsage, lpNet, &handle);
                                if (ret == WN_SUCCESS)
                                {
                                    *lphEnum = _createProviderEnumerator(
                                     dwScope, dwType, dwUsage, index, handle);
                                    ret = *lphEnum ? WN_SUCCESS :
                                     WN_OUT_OF_MEMORY;
                                }
                            }
                            else
                                ret = WN_NOT_SUPPORTED;
                        }
                        else
                            ret = WN_BAD_PROVIDER;
                    }
                    else if (lpNet->lpRemoteName)
                    {
                        *lphEnum = _createGlobalEnumeratorW(dwScope,
                         dwType, dwUsage, lpNet);
                        ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
                    }
                    else
                    {
                        if (lpNet->lpComment && !strcmpW(lpNet->lpComment,
                         providerTable->entireNetwork))
                        {
                            /* comment matches the "Entire Network", enumerate
                             * global scope of every provider
                             */
                            *lphEnum = _createGlobalEnumeratorW(dwScope,
                             dwType, dwUsage, lpNet);
                        }
                        else
                        {
                            /* this is the same as not having passed lpNet */
                            *lphEnum = _createGlobalEnumeratorW(dwScope,
                             dwType, dwUsage, NULL);
                        }
                        ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
                    }
                }
                else
                {
                    *lphEnum = _createGlobalEnumeratorW(dwScope, dwType,
                     dwUsage, lpNet);
                    ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
                }
                break;
            case RESOURCE_CONTEXT:
                *lphEnum = _createContextEnumerator(dwScope, dwType, dwUsage);
                ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
                break;
            case RESOURCE_REMEMBERED:
            case RESOURCE_CONNECTED:
                *lphEnum = _createNullEnumerator();
                ret = *lphEnum ? WN_SUCCESS : WN_OUT_OF_MEMORY;
                break;
            default:
                WARN("unknown scope 0x%08x\n", dwScope);
                ret = WN_BAD_VALUE;
        }
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetEnumResourceA [MPR.@]
 */
DWORD WINAPI WNetEnumResourceA( HANDLE hEnum, LPDWORD lpcCount,
                                LPVOID lpBuffer, LPDWORD lpBufferSize )
{
    DWORD ret;

    TRACE( "(%p, %p, %p, %p)\n", hEnum, lpcCount, lpBuffer, lpBufferSize );

    if (!hEnum)
        ret = WN_BAD_POINTER;
    else if (!lpcCount)
        ret = WN_BAD_POINTER;
    else if (!lpBuffer)
        ret = WN_BAD_POINTER;
    else if (!lpBufferSize)
        ret = WN_BAD_POINTER;
    else if (*lpBufferSize < sizeof(NETRESOURCEA))
    {
        *lpBufferSize = sizeof(NETRESOURCEA);
        ret = WN_MORE_DATA;
    }
    else
    {
        DWORD localCount = *lpcCount, localSize = *lpBufferSize;
        LPVOID localBuffer = HeapAlloc(GetProcessHeap(), 0, localSize);

        if (localBuffer)
        {
            ret = WNetEnumResourceW(hEnum, &localCount, localBuffer,
             &localSize);
            if (ret == WN_SUCCESS || (ret == WN_MORE_DATA && localCount != -1))
            {
                /* FIXME: this isn't necessarily going to work in the case of
                 * WN_MORE_DATA, because our enumerator may have moved on to
                 * the next provider.  MSDN states that a large (16KB) buffer
                 * size is the appropriate usage of this function, so
                 * hopefully it won't be an issue.
                 */
                ret = _thunkNetResourceArrayWToA(localBuffer, &localCount,
                 lpBuffer, lpBufferSize);
                *lpcCount = localCount;
            }
            HeapFree(GetProcessHeap(), 0, localBuffer);
        }
        else
            ret = WN_OUT_OF_MEMORY;
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

static DWORD _countProviderBytesW(PWNetProvider provider)
{
    DWORD ret;

    if (provider)
    {
        ret = sizeof(NETRESOURCEW);
        ret += 2 * (strlenW(provider->name) + 1) * sizeof(WCHAR);
    }
    else
        ret = 0;
    return ret;
}

static DWORD _enumerateProvidersW(PWNetEnumerator enumerator, LPDWORD lpcCount,
 LPVOID lpBuffer, const DWORD *lpBufferSize)
{
    DWORD ret;

    if (!enumerator)
        return WN_BAD_POINTER;
    if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL)
        return WN_BAD_VALUE;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;
    if (*lpBufferSize < sizeof(NETRESOURCEA))
        return WN_MORE_DATA;

    if (!providerTable || enumerator->providerIndex >= 
     providerTable->numProviders)
        ret = WN_NO_MORE_ENTRIES;
    else
    {
        DWORD bytes = 0, count = 0, countLimit, i;
        LPNETRESOURCEW resource;
        LPWSTR strNext;

        countLimit = *lpcCount == -1 ?
         providerTable->numProviders - enumerator->providerIndex : *lpcCount;
        while (count < countLimit && bytes < *lpBufferSize)
        {
            DWORD bytesNext = _countProviderBytesW(
             &providerTable->table[count + enumerator->providerIndex]);

            if (bytes + bytesNext < *lpBufferSize)
            {
                bytes += bytesNext;
                count++;
            }
        }
        strNext = (LPWSTR)((LPBYTE)lpBuffer + count * sizeof(NETRESOURCEW));
        for (i = 0, resource = lpBuffer; i < count; i++, resource++)
        {
            resource->dwScope = RESOURCE_GLOBALNET;
            resource->dwType = RESOURCETYPE_ANY;
            resource->dwDisplayType = RESOURCEDISPLAYTYPE_NETWORK;
            resource->dwUsage = RESOURCEUSAGE_CONTAINER |
             RESOURCEUSAGE_RESERVED;
            resource->lpLocalName = NULL;
            resource->lpRemoteName = strNext;
            strcpyW(resource->lpRemoteName,
             providerTable->table[i + enumerator->providerIndex].name);
            strNext += strlenW(resource->lpRemoteName) + 1;
            resource->lpComment = NULL;
            resource->lpProvider = strNext;
            strcpyW(resource->lpProvider,
             providerTable->table[i + enumerator->providerIndex].name);
            strNext += strlenW(resource->lpProvider) + 1;
        }
        enumerator->providerIndex += count;
        *lpcCount = count;
        ret = count > 0 ? WN_SUCCESS : WN_MORE_DATA;
    }
    TRACE("Returning %d\n", ret);
    return ret;
}

/* Advances the enumerator (assumed to be a global enumerator) to the next
 * provider that supports the enumeration scope passed to WNetOpenEnum.  Does
 * not open a handle with the next provider.
 * If the existing handle is NULL, may leave the enumerator unchanged, since
 * the current provider may support the desired scope.
 * If the existing handle is not NULL, closes it before moving on.
 * Returns WN_SUCCESS on success, WN_NO_MORE_ENTRIES if there is no available
 * provider, and another error on failure.
 */
static DWORD _globalEnumeratorAdvance(PWNetEnumerator enumerator)
{
    if (!enumerator)
        return WN_BAD_POINTER;
    if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL)
        return WN_BAD_VALUE;
    if (!providerTable || enumerator->providerIndex >=
     providerTable->numProviders)
        return WN_NO_MORE_ENTRIES;

    if (enumerator->providerDone)
    {
        DWORD dwEnum = 0;
        enumerator->providerDone = FALSE;
        if (enumerator->handle)
        {
            providerTable->table[enumerator->providerIndex].closeEnum(
             enumerator->handle);
            enumerator->handle = NULL;
            enumerator->providerIndex++;
        }
        if (enumerator->dwScope == RESOURCE_CONNECTED)
            dwEnum = WNNC_ENUM_LOCAL;
        else if (enumerator->dwScope == RESOURCE_GLOBALNET)
            dwEnum = WNNC_ENUM_GLOBAL;
        else if (enumerator->dwScope == RESOURCE_CONTEXT)
            dwEnum = WNNC_ENUM_CONTEXT;
        for (; enumerator->providerIndex < providerTable->numProviders &&
         !(providerTable->table[enumerator->providerIndex].dwEnumScopes
         & dwEnum); enumerator->providerIndex++)
            ;
    }
    return enumerator->providerIndex < providerTable->numProviders ?
     WN_SUCCESS : WN_NO_MORE_ENTRIES;
}

/* "Passes through" call to the next provider that supports the enumeration
 * type.
 * FIXME: if one call to a provider's enumerator succeeds while there's still
 * space in lpBuffer, I don't call to the next provider.  The caller may not
 * expect that it should call EnumResourceW again with a return value of
 * WN_SUCCESS (depending what *lpcCount was to begin with).  That means strings
 * may have to be moved around a bit, ick.
 */
static DWORD _enumerateGlobalPassthroughW(PWNetEnumerator enumerator,
 LPDWORD lpcCount, LPVOID lpBuffer, LPDWORD lpBufferSize)
{
    DWORD ret;

    if (!enumerator)
        return WN_BAD_POINTER;
    if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL)
        return WN_BAD_VALUE;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;
    if (*lpBufferSize < sizeof(NETRESOURCEW))
        return WN_MORE_DATA;

    ret = _globalEnumeratorAdvance(enumerator);
    if (ret == WN_SUCCESS)
    {
        ret = providerTable->table[enumerator->providerIndex].
         openEnum(enumerator->dwScope, enumerator->dwType,
         enumerator->dwUsage, enumerator->lpNet,
         &enumerator->handle);
        if (ret == WN_SUCCESS)
        {
            ret = providerTable->table[enumerator->providerIndex].
             enumResource(enumerator->handle, lpcCount, lpBuffer,
             lpBufferSize);
            if (ret != WN_MORE_DATA)
                enumerator->providerDone = TRUE;
        }
    }
    TRACE("Returning %d\n", ret);
    return ret;
}

static DWORD _enumerateGlobalW(PWNetEnumerator enumerator, LPDWORD lpcCount,
 LPVOID lpBuffer, LPDWORD lpBufferSize)
{
    DWORD ret;

    if (!enumerator)
        return WN_BAD_POINTER;
    if (enumerator->enumType != WNET_ENUMERATOR_TYPE_GLOBAL)
        return WN_BAD_VALUE;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;
    if (*lpBufferSize < sizeof(NETRESOURCEW))
        return WN_MORE_DATA;
    if (!providerTable)
        return WN_NO_NETWORK;

    switch (enumerator->dwScope)
    {
        case RESOURCE_GLOBALNET:
            if (enumerator->lpNet)
                ret = _enumerateGlobalPassthroughW(enumerator, lpcCount,
                 lpBuffer, lpBufferSize);
            else
                ret = _enumerateProvidersW(enumerator, lpcCount, lpBuffer,
                 lpBufferSize);
            break;
        case RESOURCE_CONTEXT:
            ret = _enumerateGlobalPassthroughW(enumerator, lpcCount, lpBuffer,
             lpBufferSize);
            break;
        default:
            WARN("unexpected scope 0x%08x\n", enumerator->dwScope);
            ret = WN_NO_MORE_ENTRIES;
    }
    TRACE("Returning %d\n", ret);
    return ret;
}

static DWORD _enumerateProviderW(PWNetEnumerator enumerator, LPDWORD lpcCount,
 LPVOID lpBuffer, LPDWORD lpBufferSize)
{
    if (!enumerator)
        return WN_BAD_POINTER;
    if (enumerator->enumType != WNET_ENUMERATOR_TYPE_PROVIDER)
        return WN_BAD_VALUE;
    if (!enumerator->handle)
        return WN_BAD_VALUE;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;
    if (!providerTable)
        return WN_NO_NETWORK;
    if (enumerator->providerIndex >= providerTable->numProviders)
        return WN_NO_MORE_ENTRIES;
    if (!providerTable->table[enumerator->providerIndex].enumResource)
        return WN_BAD_VALUE;
    return providerTable->table[enumerator->providerIndex].enumResource(
     enumerator->handle, lpcCount, lpBuffer, lpBufferSize);
}

static DWORD _enumerateContextW(PWNetEnumerator enumerator, LPDWORD lpcCount,
 LPVOID lpBuffer, LPDWORD lpBufferSize)
{
    DWORD ret;
    size_t cchEntireNetworkLen, bytesNeeded;

    if (!enumerator)
        return WN_BAD_POINTER;
    if (enumerator->enumType != WNET_ENUMERATOR_TYPE_CONTEXT)
        return WN_BAD_VALUE;
    if (!lpcCount)
        return WN_BAD_POINTER;
    if (!lpBuffer)
        return WN_BAD_POINTER;
    if (!lpBufferSize)
        return WN_BAD_POINTER;
    if (!providerTable)
        return WN_NO_NETWORK;

    cchEntireNetworkLen = strlenW(providerTable->entireNetwork) + 1;
    bytesNeeded = sizeof(NETRESOURCEW) + cchEntireNetworkLen * sizeof(WCHAR);
    if (*lpBufferSize < bytesNeeded)
    {
        *lpBufferSize = bytesNeeded;
        ret = WN_MORE_DATA;
    }
    else
    {
        LPNETRESOURCEW lpNet = lpBuffer;

        lpNet->dwScope = RESOURCE_GLOBALNET;
        lpNet->dwType = enumerator->dwType;
        lpNet->dwDisplayType = RESOURCEDISPLAYTYPE_ROOT;
        lpNet->dwUsage = RESOURCEUSAGE_CONTAINER;
        lpNet->lpLocalName = NULL;
        lpNet->lpRemoteName = NULL;
        lpNet->lpProvider = NULL;
        /* odd, but correct: put comment at end of buffer, so it won't get
         * overwritten by subsequent calls to a provider's enumResource
         */
        lpNet->lpComment = (LPWSTR)((LPBYTE)lpBuffer + *lpBufferSize -
         (cchEntireNetworkLen * sizeof(WCHAR)));
        strcpyW(lpNet->lpComment, providerTable->entireNetwork);
        ret = WN_SUCCESS;
    }
    if (ret == WN_SUCCESS)
    {
        DWORD bufferSize = *lpBufferSize - bytesNeeded;

        /* "Entire Network" entry enumerated--morph this into a global
         * enumerator.  enumerator->lpNet continues to be NULL, since it has
         * no meaning when the scope isn't RESOURCE_GLOBALNET.
         */
        enumerator->enumType = WNET_ENUMERATOR_TYPE_GLOBAL;
        ret = _enumerateGlobalW(enumerator, lpcCount,
         (LPBYTE)lpBuffer + bytesNeeded, &bufferSize);
        if (ret == WN_SUCCESS)
        {
            /* reflect the fact that we already enumerated "Entire Network" */
            (*lpcCount)++;
            *lpBufferSize = bufferSize + bytesNeeded;
        }
        else
        {
            /* the provider enumeration failed, but we already succeeded in
             * enumerating "Entire Network"--leave type as global to allow a
             * retry, but indicate success with a count of one.
             */
            ret = WN_SUCCESS;
            *lpcCount = 1;
            *lpBufferSize = bytesNeeded;
        }
    }
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetEnumResourceW [MPR.@]
 */
DWORD WINAPI WNetEnumResourceW( HANDLE hEnum, LPDWORD lpcCount,
                                LPVOID lpBuffer, LPDWORD lpBufferSize )
{
    DWORD ret;

    TRACE( "(%p, %p, %p, %p)\n", hEnum, lpcCount, lpBuffer, lpBufferSize );

    if (!hEnum)
        ret = WN_BAD_POINTER;
    else if (!lpcCount)
        ret = WN_BAD_POINTER;
    else if (!lpBuffer)
        ret = WN_BAD_POINTER;
    else if (!lpBufferSize)
        ret = WN_BAD_POINTER;
    else if (*lpBufferSize < sizeof(NETRESOURCEW))
    {
        *lpBufferSize = sizeof(NETRESOURCEW);
        ret = WN_MORE_DATA;
    }
    else
    {
        PWNetEnumerator enumerator = (PWNetEnumerator)hEnum;

        switch (enumerator->enumType)
        {
            case WNET_ENUMERATOR_TYPE_NULL:
                ret = WN_NO_MORE_ENTRIES;
                break;
            case WNET_ENUMERATOR_TYPE_GLOBAL:
                ret = _enumerateGlobalW(enumerator, lpcCount, lpBuffer,
                 lpBufferSize);
                break;
            case WNET_ENUMERATOR_TYPE_PROVIDER:
                ret = _enumerateProviderW(enumerator, lpcCount, lpBuffer,
                 lpBufferSize);
                break;
            case WNET_ENUMERATOR_TYPE_CONTEXT:
                ret = _enumerateContextW(enumerator, lpcCount, lpBuffer,
                 lpBufferSize);
                break;
            default:
                WARN("bogus enumerator type!\n");
                ret = WN_NO_NETWORK;
        }
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetCloseEnum [MPR.@]
 */
DWORD WINAPI WNetCloseEnum( HANDLE hEnum )
{
    DWORD ret;

    TRACE( "(%p)\n", hEnum );

    if (hEnum)
    {
        PWNetEnumerator enumerator = (PWNetEnumerator)hEnum;

        switch (enumerator->enumType)
        {
            case WNET_ENUMERATOR_TYPE_NULL:
                ret = WN_SUCCESS;
                break;
            case WNET_ENUMERATOR_TYPE_GLOBAL:
                if (enumerator->lpNet)
                    _freeEnumNetResource(enumerator->lpNet);
                if (enumerator->handle)
                    providerTable->table[enumerator->providerIndex].
                     closeEnum(enumerator->handle);
                ret = WN_SUCCESS;
                break;
            case WNET_ENUMERATOR_TYPE_PROVIDER:
                if (enumerator->handle)
                    providerTable->table[enumerator->providerIndex].
                     closeEnum(enumerator->handle);
                ret = WN_SUCCESS;
                break;
            default:
                WARN("bogus enumerator type!\n");
                ret = WN_BAD_HANDLE;
        }
        HeapFree(GetProcessHeap(), 0, hEnum);
    }
    else
        ret = WN_BAD_HANDLE;
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetGetResourceInformationA [MPR.@]
 *
 * See WNetGetResourceInformationW
 */
DWORD WINAPI WNetGetResourceInformationA( LPNETRESOURCEA lpNetResource,
                                          LPVOID lpBuffer, LPDWORD cbBuffer,
                                          LPSTR *lplpSystem )
{
    DWORD ret;

    TRACE( "(%p, %p, %p, %p)\n",
           lpNetResource, lpBuffer, cbBuffer, lplpSystem );

    if (!providerTable || providerTable->numProviders == 0)
        ret = WN_NO_NETWORK;
    else if (lpNetResource)
    {
        LPNETRESOURCEW lpNetResourceW = NULL;
        DWORD size = 1024, count = 1;
        DWORD len;

        lpNetResourceW = HeapAlloc(GetProcessHeap(), 0, size);
        ret = _thunkNetResourceArrayAToW(lpNetResource, &count, lpNetResourceW, &size);
        if (ret == WN_MORE_DATA)
        {
            HeapFree(GetProcessHeap(), 0, lpNetResourceW);
            lpNetResourceW = HeapAlloc(GetProcessHeap(), 0, size);
            if (lpNetResourceW)
                ret = _thunkNetResourceArrayAToW(lpNetResource,
                        &count, lpNetResourceW, &size);
            else
                ret = WN_OUT_OF_MEMORY;
        }
        if (ret == WN_SUCCESS)
        {
            LPWSTR lpSystemW = NULL;
            LPVOID lpBufferW;
            size = 1024;
            lpBufferW = HeapAlloc(GetProcessHeap(), 0, size);
            if (lpBufferW)
            {
                ret = WNetGetResourceInformationW(lpNetResourceW,
                        lpBufferW, &size, &lpSystemW);
                if (ret == WN_MORE_DATA)
                {
                    HeapFree(GetProcessHeap(), 0, lpBufferW);
                    lpBufferW = HeapAlloc(GetProcessHeap(), 0, size);
                    if (lpBufferW)
                        ret = WNetGetResourceInformationW(lpNetResourceW,
                            lpBufferW, &size, &lpSystemW);
                    else
                        ret = WN_OUT_OF_MEMORY;
                }
                if (ret == WN_SUCCESS)
                {
                    ret = _thunkNetResourceArrayWToA(lpBufferW,
                            &count, lpBuffer, cbBuffer);
                    HeapFree(GetProcessHeap(), 0, lpNetResourceW);
                    lpNetResourceW = lpBufferW;
                    size = sizeof(NETRESOURCEA);
                    size += WideCharToMultiByte(CP_ACP, 0, lpNetResourceW->lpRemoteName,
                            -1, NULL, 0, NULL, NULL);
                    size += WideCharToMultiByte(CP_ACP, 0, lpNetResourceW->lpProvider,
                            -1, NULL, 0, NULL, NULL);

                    len = WideCharToMultiByte(CP_ACP, 0, lpSystemW,
                                      -1, NULL, 0, NULL, NULL);
                    if ((len) && ( size + len < *cbBuffer))
                    {
                        *lplpSystem = (char*)lpBuffer + *cbBuffer - len;
                        WideCharToMultiByte(CP_ACP, 0, lpSystemW, -1,
                             *lplpSystem, len, NULL, NULL);
                         ret = WN_SUCCESS;
                    }
                    else
                        ret = WN_MORE_DATA;
                }
                else
                    ret = WN_OUT_OF_MEMORY;
                HeapFree(GetProcessHeap(), 0, lpBufferW);
            }
            else
                ret = WN_OUT_OF_MEMORY;
            HeapFree(GetProcessHeap(), 0, lpSystemW);
        }
        HeapFree(GetProcessHeap(), 0, lpNetResourceW);
    }
    else
        ret = WN_NO_NETWORK;

    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetGetResourceInformationW [MPR.@]
 *
 * WNetGetResourceInformationW function identifies the network provider
 * that owns the resource and gets information about the type of the resource.
 *
 * PARAMS:
 *  lpNetResource    [ I]    the pointer to NETRESOURCEW structure, that
 *                          defines a network resource.
 *  lpBuffer         [ O]   the pointer to buffer, containing result. It
 *                          contains NETRESOURCEW structure and strings to
 *                          which the members of the NETRESOURCEW structure
 *                          point.
 *  cbBuffer         [I/O] the pointer to DWORD number - size of buffer
 *                          in bytes.
 *  lplpSystem       [ O]   the pointer to string in the output buffer,
 *                          containing the part of the resource name without
 *                          names of the server and share.
 *
 * RETURNS:
 *  NO_ERROR if the function succeeds. System error code if the function fails.
 */

DWORD WINAPI WNetGetResourceInformationW( LPNETRESOURCEW lpNetResource,
                                          LPVOID lpBuffer, LPDWORD cbBuffer,
                                          LPWSTR *lplpSystem )
{
    DWORD ret = WN_NO_NETWORK;
    DWORD index;

    TRACE( "(%p, %p, %p, %p)\n",
           lpNetResource, lpBuffer, cbBuffer, lplpSystem);

    if (!(lpBuffer))
        ret = WN_OUT_OF_MEMORY;
    else if (providerTable != NULL)
    {
        /* FIXME: For function value of a variable is indifferent, it does
         * search of all providers in a network.
         */
        for (index = 0; index < providerTable->numProviders; index++)
        {
            if(providerTable->table[index].getCaps(WNNC_DIALOG) &
                WNNC_DLG_GETRESOURCEINFORMATION)
            {
                if (providerTable->table[index].getResourceInformation)
                    ret = providerTable->table[index].getResourceInformation(
                        lpNetResource, lpBuffer, cbBuffer, lplpSystem);
                else
                    ret = WN_NO_NETWORK;
                if (ret == WN_SUCCESS)
                    break;
            }
        }
    }
    if (ret)
        SetLastError(ret);
    return ret;
}

/*********************************************************************
 * WNetGetResourceParentA [MPR.@]
 */
DWORD WINAPI WNetGetResourceParentA( LPNETRESOURCEA lpNetResource,
                                     LPVOID lpBuffer, LPDWORD lpBufferSize )
{
    FIXME( "(%p, %p, %p): stub\n",
           lpNetResource, lpBuffer, lpBufferSize );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetGetResourceParentW [MPR.@]
 */
DWORD WINAPI WNetGetResourceParentW( LPNETRESOURCEW lpNetResource,
                                     LPVOID lpBuffer, LPDWORD lpBufferSize )
{
    FIXME( "(%p, %p, %p): stub\n",
           lpNetResource, lpBuffer, lpBufferSize );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}



/*
 * Connection Functions
 */

/*********************************************************************
 *  WNetAddConnectionA [MPR.@]
 */
DWORD WINAPI WNetAddConnectionA( LPCSTR lpRemoteName, LPCSTR lpPassword,
                                 LPCSTR lpLocalName )
{
    FIXME( "(%s, %p, %s): stub\n",
           debugstr_a(lpRemoteName), lpPassword, debugstr_a(lpLocalName) );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 *  WNetAddConnectionW [MPR.@]
 */
DWORD WINAPI WNetAddConnectionW( LPCWSTR lpRemoteName, LPCWSTR lpPassword,
                                 LPCWSTR lpLocalName )
{
    FIXME( "(%s, %p, %s): stub\n",
           debugstr_w(lpRemoteName), lpPassword, debugstr_w(lpLocalName) );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 *  WNetAddConnection2A [MPR.@]
 */
DWORD WINAPI WNetAddConnection2A( LPNETRESOURCEA lpNetResource,
                                  LPCSTR lpPassword, LPCSTR lpUserID,
                                  DWORD dwFlags )
{
    FIXME( "(%p, %p, %s, 0x%08X): stub\n",
           lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetAddConnection2W [MPR.@]
 */
DWORD WINAPI WNetAddConnection2W( LPNETRESOURCEW lpNetResource,
                                  LPCWSTR lpPassword, LPCWSTR lpUserID,
                                  DWORD dwFlags )
{
    FIXME( "(%p, %p, %s, 0x%08X): stub\n",
           lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetAddConnection3A [MPR.@]
 */
DWORD WINAPI WNetAddConnection3A( HWND hwndOwner, LPNETRESOURCEA lpNetResource,
                                  LPCSTR lpPassword, LPCSTR lpUserID,
                                  DWORD dwFlags )
{
    FIXME( "(%p, %p, %p, %s, 0x%08X), stub\n",
           hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetAddConnection3W [MPR.@]
 */
DWORD WINAPI WNetAddConnection3W( HWND hwndOwner, LPNETRESOURCEW lpNetResource,
                                  LPCWSTR lpPassword, LPCWSTR lpUserID,
                                  DWORD dwFlags )
{
    FIXME( "(%p, %p, %p, %s, 0x%08X), stub\n",
           hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*****************************************************************
 *  WNetUseConnectionA [MPR.@]
 */
DWORD WINAPI WNetUseConnectionA( HWND hwndOwner, LPNETRESOURCEA lpNetResource,
                                 LPCSTR lpPassword, LPCSTR lpUserID, DWORD dwFlags,
                                 LPSTR lpAccessName, LPDWORD lpBufferSize,
                                 LPDWORD lpResult )
{
    FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",
           hwndOwner, lpNetResource, lpPassword, debugstr_a(lpUserID), dwFlags,
           debugstr_a(lpAccessName), lpBufferSize, lpResult );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*****************************************************************
 *  WNetUseConnectionW [MPR.@]
 */
DWORD WINAPI WNetUseConnectionW( HWND hwndOwner, LPNETRESOURCEW lpNetResource,
                                 LPCWSTR lpPassword, LPCWSTR lpUserID, DWORD dwFlags,
                                 LPWSTR lpAccessName, LPDWORD lpBufferSize,
                                 LPDWORD lpResult )
{
    FIXME( "(%p, %p, %p, %s, 0x%08X, %s, %p, %p), stub\n",
           hwndOwner, lpNetResource, lpPassword, debugstr_w(lpUserID), dwFlags,
           debugstr_w(lpAccessName), lpBufferSize, lpResult );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 *  WNetCancelConnectionA [MPR.@]
 */
DWORD WINAPI WNetCancelConnectionA( LPCSTR lpName, BOOL fForce )
{
    FIXME( "(%s, %d), stub\n", debugstr_a(lpName), fForce );

    return WN_SUCCESS;
}

/*********************************************************************
 *  WNetCancelConnectionW [MPR.@]
 */
DWORD WINAPI WNetCancelConnectionW( LPCWSTR lpName, BOOL fForce )
{
    FIXME( "(%s, %d), stub\n", debugstr_w(lpName), fForce );

    return WN_SUCCESS;
}

/*********************************************************************
 *  WNetCancelConnection2A [MPR.@]
 */
DWORD WINAPI WNetCancelConnection2A( LPCSTR lpName, DWORD dwFlags, BOOL fForce )
{
    FIXME( "(%s, %08X, %d), stub\n", debugstr_a(lpName), dwFlags, fForce );

    return WN_SUCCESS;
}

/*********************************************************************
 *  WNetCancelConnection2W [MPR.@]
 */
DWORD WINAPI WNetCancelConnection2W( LPCWSTR lpName, DWORD dwFlags, BOOL fForce )
{
    FIXME( "(%s, %08X, %d), stub\n", debugstr_w(lpName), dwFlags, fForce );

    return WN_SUCCESS;
}

/*****************************************************************
 *  WNetRestoreConnectionA [MPR.@]
 */
DWORD WINAPI WNetRestoreConnectionA( HWND hwndOwner, LPCSTR lpszDevice )
{
    FIXME( "(%p, %s), stub\n", hwndOwner, debugstr_a(lpszDevice) );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*****************************************************************
 *  WNetRestoreConnectionW [MPR.@]
 */
DWORD WINAPI WNetRestoreConnectionW( HWND hwndOwner, LPCWSTR lpszDevice )
{
    FIXME( "(%p, %s), stub\n", hwndOwner, debugstr_w(lpszDevice) );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/**************************************************************************
 * WNetGetConnectionA [MPR.@]
 *
 * RETURNS
 * - WN_BAD_LOCALNAME     lpLocalName makes no sense
 * - WN_NOT_CONNECTED     drive is a local drive
 * - WN_MORE_DATA         buffer isn't big enough
 * - WN_SUCCESS           success (net path in buffer)
 *
 * FIXME: need to test return values under different errors
 */
DWORD WINAPI WNetGetConnectionA( LPCSTR lpLocalName,
                                 LPSTR lpRemoteName, LPDWORD lpBufferSize )
{
    DWORD ret;

    if (!lpLocalName)
        ret = WN_BAD_POINTER;
    else if (!lpBufferSize)
        ret = WN_BAD_POINTER;
    else if (!lpRemoteName && *lpBufferSize)
        ret = WN_BAD_POINTER;
    else
    {
        int len = MultiByteToWideChar(CP_ACP, 0, lpLocalName, -1, NULL, 0);

        if (len)
        {
            PWSTR wideLocalName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

            if (wideLocalName)
            {
                WCHAR wideRemoteStatic[MAX_PATH];
                DWORD wideRemoteSize = sizeof(wideRemoteStatic) / sizeof(WCHAR);

                MultiByteToWideChar(CP_ACP, 0, lpLocalName, -1, wideLocalName, len);

                /* try once without memory allocation */
                ret = WNetGetConnectionW(wideLocalName, wideRemoteStatic,
                 &wideRemoteSize);
                if (ret == WN_SUCCESS)
                {
                    int len = WideCharToMultiByte(CP_ACP, 0, wideRemoteStatic,
                     -1, NULL, 0, NULL, NULL);

                    if (len <= *lpBufferSize)
                    {
                        WideCharToMultiByte(CP_ACP, 0, wideRemoteStatic, -1,
                         lpRemoteName, *lpBufferSize, NULL, NULL);
                        ret = WN_SUCCESS;
                    }
                    else
                    {
                        *lpBufferSize = len;
                        ret = WN_MORE_DATA;
                    }
                }
                else if (ret == WN_MORE_DATA)
                {
                    PWSTR wideRemote = HeapAlloc(GetProcessHeap(), 0,
                     wideRemoteSize * sizeof(WCHAR));

                    if (wideRemote)
                    {
                        ret = WNetGetConnectionW(wideLocalName, wideRemote,
                         &wideRemoteSize);
                        if (ret == WN_SUCCESS)
                        {
                            if (len <= *lpBufferSize)
                            {
                                WideCharToMultiByte(CP_ACP, 0, wideRemoteStatic,
                                 -1, lpRemoteName, *lpBufferSize, NULL, NULL);
                                ret = WN_SUCCESS;
                            }
                            else
                            {
                                *lpBufferSize = len;
                                ret = WN_MORE_DATA;
                            }
                        }
                        HeapFree(GetProcessHeap(), 0, wideRemote);
                    }
                    else
                        ret = WN_OUT_OF_MEMORY;
                }
                HeapFree(GetProcessHeap(), 0, wideLocalName);
            }
            else
                ret = WN_OUT_OF_MEMORY;
        }
        else
            ret = WN_BAD_LOCALNAME;
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/* find the network connection for a given drive; helper for WNetGetConnection */
static DWORD get_drive_connection( WCHAR letter, LPWSTR remote, LPDWORD size )
{
    char buffer[1024];
    struct mountmgr_unix_drive *data = (struct mountmgr_unix_drive *)buffer;
    HANDLE mgr;
    DWORD ret = WN_NOT_CONNECTED;

    if ((mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, GENERIC_READ|GENERIC_WRITE,
                            FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                            0, 0 )) == INVALID_HANDLE_VALUE)
    {
        ERR( "failed to open mount manager err %u\n", GetLastError() );
        return ret;
    }
    memset( data, 0, sizeof(*data) );
    data->letter = letter;
    if (DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, data, sizeof(*data),
                         data, sizeof(buffer), NULL, NULL ))
    {
        char *p, *mount_point = buffer + data->mount_point_offset;
        DWORD len;

        if (data->mount_point_offset && !strncmp( mount_point, "unc/", 4 ))
        {
            mount_point += 2;
            mount_point[0] = '\\';
            for (p = mount_point; *p; p++) if (*p == '/') *p = '\\';

            len = MultiByteToWideChar( CP_UNIXCP, 0, mount_point, -1, NULL, 0 );
            if (len > *size)
            {
                *size = len;
                ret = WN_MORE_DATA;
            }
            else
            {
                *size = MultiByteToWideChar( CP_UNIXCP, 0, mount_point, -1, remote, *size);
                ret = WN_SUCCESS;
            }
        }
    }
    CloseHandle( mgr );
    return ret;
}

/**************************************************************************
 * WNetGetConnectionW [MPR.@]
 *
 * FIXME: need to test return values under different errors
 */
DWORD WINAPI WNetGetConnectionW( LPCWSTR lpLocalName,
                                 LPWSTR lpRemoteName, LPDWORD lpBufferSize )
{
    DWORD ret;

    TRACE("(%s, %p, %p)\n", debugstr_w(lpLocalName), lpRemoteName,
     lpBufferSize);

    if (!lpLocalName)
        ret = WN_BAD_POINTER;
    else if (!lpBufferSize)
        ret = WN_BAD_POINTER;
    else if (!lpRemoteName && *lpBufferSize)
        ret = WN_BAD_POINTER;
    else if (!lpLocalName[0])
        ret = WN_BAD_LOCALNAME;
    else
    {
        if (lpLocalName[1] == ':')
        {
            switch(GetDriveTypeW(lpLocalName))
            {
            case DRIVE_REMOTE:
                ret = get_drive_connection( lpLocalName[0], lpRemoteName, lpBufferSize );
                break;
            case DRIVE_REMOVABLE:
            case DRIVE_FIXED:
            case DRIVE_CDROM:
                TRACE("file is local\n");
                ret = WN_NOT_CONNECTED;
                break;
            default:
                ret = WN_BAD_LOCALNAME;
            }
        }
        else
            ret = WN_BAD_LOCALNAME;
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/**************************************************************************
 * WNetSetConnectionA [MPR.@]
 */
DWORD WINAPI WNetSetConnectionA( LPCSTR lpName, DWORD dwProperty,
                                 LPVOID pvValue )
{
    FIXME( "(%s, %08X, %p): stub\n", debugstr_a(lpName), dwProperty, pvValue );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/**************************************************************************
 * WNetSetConnectionW [MPR.@]
 */
DWORD WINAPI WNetSetConnectionW( LPCWSTR lpName, DWORD dwProperty,
                                 LPVOID pvValue )
{
    FIXME( "(%s, %08X, %p): stub\n", debugstr_w(lpName), dwProperty, pvValue );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*****************************************************************
 * WNetGetUniversalNameA [MPR.@]
 */
DWORD WINAPI WNetGetUniversalNameA ( LPCSTR lpLocalPath, DWORD dwInfoLevel,
                                     LPVOID lpBuffer, LPDWORD lpBufferSize )
{
    DWORD err, size;

    FIXME( "(%s, 0x%08X, %p, %p): stub\n",
           debugstr_a(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize);

    switch (dwInfoLevel)
    {
    case UNIVERSAL_NAME_INFO_LEVEL:
    {
        LPUNIVERSAL_NAME_INFOA info = lpBuffer;

        if (GetDriveTypeA(lpLocalPath) != DRIVE_REMOTE)
        {
            err = ERROR_NOT_CONNECTED;
            break;
        }

        size = sizeof(*info) + lstrlenA(lpLocalPath) + 1;
        if (*lpBufferSize < size)
        {
            err = WN_MORE_DATA;
            break;
        }
        info->lpUniversalName = (char *)info + sizeof(*info);
        lstrcpyA(info->lpUniversalName, lpLocalPath);
        err = WN_NO_ERROR;
        break;
    }
    case REMOTE_NAME_INFO_LEVEL:
        err = WN_NO_NETWORK;
        break;

    default:
        err = WN_BAD_VALUE;
        break;
    }

    SetLastError(err);
    return err;
}

/*****************************************************************
 * WNetGetUniversalNameW [MPR.@]
 */
DWORD WINAPI WNetGetUniversalNameW ( LPCWSTR lpLocalPath, DWORD dwInfoLevel,
                                     LPVOID lpBuffer, LPDWORD lpBufferSize )
{
    DWORD err, size;

    FIXME( "(%s, 0x%08X, %p, %p): stub\n",
           debugstr_w(lpLocalPath), dwInfoLevel, lpBuffer, lpBufferSize);

    switch (dwInfoLevel)
    {
    case UNIVERSAL_NAME_INFO_LEVEL:
    {
        LPUNIVERSAL_NAME_INFOW info = lpBuffer;

        if (GetDriveTypeW(lpLocalPath) != DRIVE_REMOTE)
        {
            err = ERROR_NOT_CONNECTED;
            break;
        }

        size = sizeof(*info) + (lstrlenW(lpLocalPath) + 1) * sizeof(WCHAR);
        if (*lpBufferSize < size)
        {
            err = WN_MORE_DATA;
            break;
        }
        info->lpUniversalName = (LPWSTR)((char *)info + sizeof(*info));
        lstrcpyW(info->lpUniversalName, lpLocalPath);
        err = WN_NO_ERROR;
        break;
    }
    case REMOTE_NAME_INFO_LEVEL:
        err = WN_NO_NETWORK;
        break;

    default:
        err = WN_BAD_VALUE;
        break;
    }

    if (err != WN_NO_ERROR) SetLastError(err);
    return err;
}



/*
 * Other Functions
 */

/**************************************************************************
 * WNetGetUserA [MPR.@]
 *
 * FIXME: we should not return ourselves, but the owner of the drive lpName
 */
DWORD WINAPI WNetGetUserA( LPCSTR lpName, LPSTR lpUserID, LPDWORD lpBufferSize )
{
    if (GetUserNameA( lpUserID, lpBufferSize )) return WN_SUCCESS;
    return GetLastError();
}

/*****************************************************************
 * WNetGetUserW [MPR.@]
 *
 * FIXME: we should not return ourselves, but the owner of the drive lpName
 */
DWORD WINAPI WNetGetUserW( LPCWSTR lpName, LPWSTR lpUserID, LPDWORD lpBufferSize )
{
    if (GetUserNameW( lpUserID, lpBufferSize )) return WN_SUCCESS;
    return GetLastError();
}

/*********************************************************************
 * WNetConnectionDialog [MPR.@]
 */
DWORD WINAPI WNetConnectionDialog( HWND hwnd, DWORD dwType )
{
    FIXME( "(%p, %08X): stub\n", hwnd, dwType );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetConnectionDialog1A [MPR.@]
 */
DWORD WINAPI WNetConnectionDialog1A( LPCONNECTDLGSTRUCTA lpConnDlgStruct )
{
    FIXME( "(%p): stub\n", lpConnDlgStruct );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetConnectionDialog1W [MPR.@]
 */
DWORD WINAPI WNetConnectionDialog1W( LPCONNECTDLGSTRUCTW lpConnDlgStruct )
{
    FIXME( "(%p): stub\n", lpConnDlgStruct );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetDisconnectDialog [MPR.@]
 */
DWORD WINAPI WNetDisconnectDialog( HWND hwnd, DWORD dwType )
{
    FIXME( "(%p, %08X): stub\n", hwnd, dwType );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetDisconnectDialog1A [MPR.@]
 */
DWORD WINAPI WNetDisconnectDialog1A( LPDISCDLGSTRUCTA lpConnDlgStruct )
{
    FIXME( "(%p): stub\n", lpConnDlgStruct );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetDisconnectDialog1W [MPR.@]
 */
DWORD WINAPI WNetDisconnectDialog1W( LPDISCDLGSTRUCTW lpConnDlgStruct )
{
    FIXME( "(%p): stub\n", lpConnDlgStruct );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetGetLastErrorA [MPR.@]
 */
DWORD WINAPI WNetGetLastErrorA( LPDWORD lpError,
                                LPSTR lpErrorBuf, DWORD nErrorBufSize,
                                LPSTR lpNameBuf, DWORD nNameBufSize )
{
    FIXME( "(%p, %p, %d, %p, %d): stub\n",
           lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetGetLastErrorW [MPR.@]
 */
DWORD WINAPI WNetGetLastErrorW( LPDWORD lpError,
                                LPWSTR lpErrorBuf, DWORD nErrorBufSize,
                         LPWSTR lpNameBuf, DWORD nNameBufSize )
{
    FIXME( "(%p, %p, %d, %p, %d): stub\n",
           lpError, lpErrorBuf, nErrorBufSize, lpNameBuf, nNameBufSize );

    SetLastError(WN_NO_NETWORK);
    return WN_NO_NETWORK;
}

/*********************************************************************
 * WNetGetNetworkInformationA [MPR.@]
 */
DWORD WINAPI WNetGetNetworkInformationA( LPCSTR lpProvider,
                                         LPNETINFOSTRUCT lpNetInfoStruct )
{
    DWORD ret;

    TRACE( "(%s, %p)\n", debugstr_a(lpProvider), lpNetInfoStruct );

    if (!lpProvider)
        ret = WN_BAD_POINTER;
    else
    {
        int len;

        len = MultiByteToWideChar(CP_ACP, 0, lpProvider, -1, NULL, 0);
        if (len)
        {
            LPWSTR wideProvider = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));

            if (wideProvider)
            {
                MultiByteToWideChar(CP_ACP, 0, lpProvider, -1, wideProvider,
                 len);
                ret = WNetGetNetworkInformationW(wideProvider, lpNetInfoStruct);
                HeapFree(GetProcessHeap(), 0, wideProvider);
            }
            else
                ret = WN_OUT_OF_MEMORY;
        }
        else
            ret = GetLastError();
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*********************************************************************
 * WNetGetNetworkInformationW [MPR.@]
 */
DWORD WINAPI WNetGetNetworkInformationW( LPCWSTR lpProvider,
                                         LPNETINFOSTRUCT lpNetInfoStruct )
{
    DWORD ret;

    TRACE( "(%s, %p)\n", debugstr_w(lpProvider), lpNetInfoStruct );

    if (!lpProvider)
        ret = WN_BAD_POINTER;
    else if (!lpNetInfoStruct)
        ret = WN_BAD_POINTER;
    else if (lpNetInfoStruct->cbStructure < sizeof(NETINFOSTRUCT))
        ret = WN_BAD_VALUE;
    else
    {
        if (providerTable && providerTable->numProviders)
        {
            DWORD providerIndex = _findProviderIndexW(lpProvider);

            if (providerIndex != BAD_PROVIDER_INDEX)
            {
                lpNetInfoStruct->cbStructure = sizeof(NETINFOSTRUCT);
                lpNetInfoStruct->dwProviderVersion =
                 providerTable->table[providerIndex].dwSpecVersion;
                lpNetInfoStruct->dwStatus = NO_ERROR;
                lpNetInfoStruct->dwCharacteristics = 0;
                lpNetInfoStruct->dwHandle = 0;
                lpNetInfoStruct->wNetType =
                 HIWORD(providerTable->table[providerIndex].dwNetType);
                lpNetInfoStruct->dwPrinters = -1;
                lpNetInfoStruct->dwDrives = -1;
                ret = WN_SUCCESS;
            }
            else
                ret = WN_BAD_PROVIDER;
        }
        else
            ret = WN_NO_NETWORK;
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*****************************************************************
 *  WNetGetProviderNameA [MPR.@]
 */
DWORD WINAPI WNetGetProviderNameA( DWORD dwNetType,
                                   LPSTR lpProvider, LPDWORD lpBufferSize )
{
    DWORD ret;

    TRACE("(0x%08x, %s, %p)\n", dwNetType, debugstr_a(lpProvider),
     lpBufferSize);

    if (!lpProvider)
        ret = WN_BAD_POINTER;
    else if (!lpBufferSize)
        ret = WN_BAD_POINTER;
    else
    {
        if (providerTable)
        {
            DWORD i;

            ret = WN_NO_NETWORK;
            for (i = 0; i < providerTable->numProviders &&
             HIWORD(providerTable->table[i].dwNetType) != HIWORD(dwNetType);
             i++)
                ;
            if (i < providerTable->numProviders)
            {
                DWORD sizeNeeded = WideCharToMultiByte(CP_ACP, 0,
                 providerTable->table[i].name, -1, NULL, 0, NULL, NULL);

                if (*lpBufferSize < sizeNeeded)
                {
                    *lpBufferSize = sizeNeeded;
                    ret = WN_MORE_DATA;
                }
                else
                {
                    WideCharToMultiByte(CP_ACP, 0, providerTable->table[i].name,
                     -1, lpProvider, *lpBufferSize, NULL, NULL);
                    ret = WN_SUCCESS;
                    /* FIXME: is *lpBufferSize set to the number of characters
                     * copied? */
                }
            }
        }
        else
            ret = WN_NO_NETWORK;
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}

/*****************************************************************
 *  WNetGetProviderNameW [MPR.@]
 */
DWORD WINAPI WNetGetProviderNameW( DWORD dwNetType,
                                   LPWSTR lpProvider, LPDWORD lpBufferSize )
{
    DWORD ret;

    TRACE("(0x%08x, %s, %p)\n", dwNetType, debugstr_w(lpProvider),
     lpBufferSize);

    if (!lpProvider)
        ret = WN_BAD_POINTER;
    else if (!lpBufferSize)
        ret = WN_BAD_POINTER;
    else
    {
        if (providerTable)
        {
            DWORD i;

            ret = WN_NO_NETWORK;
            for (i = 0; i < providerTable->numProviders &&
             HIWORD(providerTable->table[i].dwNetType) != HIWORD(dwNetType);
             i++)
                ;
            if (i < providerTable->numProviders)
            {
                DWORD sizeNeeded = strlenW(providerTable->table[i].name) + 1;

                if (*lpBufferSize < sizeNeeded)
                {
                    *lpBufferSize = sizeNeeded;
                    ret = WN_MORE_DATA;
                }
                else
                {
                    strcpyW(lpProvider, providerTable->table[i].name);
                    ret = WN_SUCCESS;
                    /* FIXME: is *lpBufferSize set to the number of characters
                     * copied? */
                }
            }
        }
        else
            ret = WN_NO_NETWORK;
    }
    if (ret)
        SetLastError(ret);
    TRACE("Returning %d\n", ret);
    return ret;
}
