/*
 * Copyright 2012 Andrew Eikum for CodeWeavers
 *
 * 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
 */

#define COBJMACROS

#include <stdio.h>

#include "windows.h"
#include "winnetwk.h"
#include "wine/test.h"

static void test_WNetGetUniversalName(void)
{
    DWORD ret;
    char buffer[1024];
    DWORD drive_type, info_size, fail_size;
    char driveA[] = "A:\\";
    char driveandpathA[] = "A:\\file.txt";
    WCHAR driveW[] = {'A',':','\\',0};

    for(; *driveA <= 'Z'; ++*driveA,  ++*driveandpathA, ++*driveW){
        drive_type = GetDriveTypeW(driveW);

        info_size = sizeof(buffer);
        ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL,
                buffer, &info_size);

        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret);
        else
            /* WN_NO_NET_OR_BAD_PATH (DRIVE_FIXED) returned from the virtual drive (usual Q:)
               created by the microsoft application virtualization client */
            ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH),
                "WNetGetUniversalNameA(%s, ...) returned %u (drive_type: %u)\n",
                driveA, ret, drive_type);

        ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size);

        fail_size = 0;
        ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL,
                buffer, &fail_size);
        if(drive_type == DRIVE_REMOTE)
            todo_wine ok(ret == WN_BAD_VALUE, "WNetGetUniversalNameA failed: %08x\n", ret);
        else
            ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH,
                "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret);

        fail_size = sizeof(driveA) / sizeof(char) - 1;
        ret = WNetGetUniversalNameA(driveA, UNIVERSAL_NAME_INFO_LEVEL,
                buffer, &fail_size);
        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret);

        ret = WNetGetUniversalNameA(driveandpathA, UNIVERSAL_NAME_INFO_LEVEL,
                buffer, &info_size);
        if(drive_type == DRIVE_REMOTE)
            todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret);

        info_size = sizeof(buffer);
        ret = WNetGetUniversalNameW(driveW, UNIVERSAL_NAME_INFO_LEVEL,
                buffer, &info_size);

        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret);
        else
            ok((ret == WN_NOT_CONNECTED) || (ret == WN_NO_NET_OR_BAD_PATH),
                "WNetGetUniversalNameW(%s, ...) returned %u (drive_type: %u)\n",
                wine_dbgstr_w(driveW), ret, drive_type);
        if(drive_type != DRIVE_REMOTE)
            ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size);
    }
}

static void test_WNetGetRemoteName(void)
{
    DWORD ret;
    char buffer[1024];
    DWORD drive_type, info_size, fail_size;
    char driveA[] = "A:\\";
    char driveandpathA[] = "A:\\file.txt";
    WCHAR driveW[] = {'A',':','\\',0};

    for(; *driveA <= 'Z'; ++*driveA,  ++*driveandpathA, ++*driveW){
        drive_type = GetDriveTypeW(driveW);

        info_size = sizeof(buffer);
        ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL,
                buffer, &info_size);
        todo_wine{
        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret);
        else
            ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH,
                "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret);
        }
        ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size);

        fail_size = 0;
        ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL,
                buffer, &fail_size);
        todo_wine{
        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_BAD_VALUE, "WNetGetUniversalNameA failed: %08x\n", ret);
        else
            ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH,
                "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret);
        }
        ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL,
                buffer, NULL);
        todo_wine ok(ret == WN_BAD_POINTER, "WNetGetUniversalNameA failed: %08x\n", ret);

        ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL,
                NULL, &info_size);

        todo_wine {
        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_BAD_POINTER, "WNetGetUniversalNameA failed: %08x\n", ret);
        else
            ok(ret == WN_NOT_CONNECTED || ret == WN_BAD_VALUE,
                "(%s) WNetGetUniversalNameA gave wrong error: %u\n", driveA, ret);
        }

        fail_size = sizeof(driveA) / sizeof(char) - 1;
        ret = WNetGetUniversalNameA(driveA, REMOTE_NAME_INFO_LEVEL,
                buffer, &fail_size);
        if(drive_type == DRIVE_REMOTE)
            todo_wine ok(ret == WN_MORE_DATA, "WNetGetUniversalNameA failed: %08x\n", ret);

        ret = WNetGetUniversalNameA(driveandpathA, REMOTE_NAME_INFO_LEVEL,
                buffer, &info_size);
        if(drive_type == DRIVE_REMOTE)
          todo_wine ok(ret == WN_NO_ERROR, "WNetGetUniversalNameA failed: %08x\n", ret);

        info_size = sizeof(buffer);
        ret = WNetGetUniversalNameW(driveW, REMOTE_NAME_INFO_LEVEL,
                buffer, &info_size);
        todo_wine{
        if(drive_type == DRIVE_REMOTE)
            ok(ret == WN_NO_ERROR, "WNetGetUniversalNameW failed: %08x\n", ret);
        else
            ok(ret == WN_NOT_CONNECTED || ret == WN_NO_NET_OR_BAD_PATH,
                "(%s) WNetGetUniversalNameW gave wrong error: %u\n", driveA, ret);
        }
        ok(info_size == sizeof(buffer), "Got wrong size: %u\n", info_size);
    }
}

static DWORD (WINAPI *pWNetCachePassword)( LPSTR, WORD, LPSTR, WORD, BYTE, WORD );
static DWORD (WINAPI *pWNetGetCachedPassword)( LPSTR, WORD, LPSTR, LPWORD, BYTE );
static UINT (WINAPI *pWNetEnumCachedPasswords)( LPSTR, WORD, BYTE, ENUMPASSWORDPROC, DWORD);
static UINT (WINAPI *pWNetRemoveCachedPassword)( LPSTR, WORD, BYTE );
static DWORD (WINAPI *pWNetUseConnectionA)( HWND, LPNETRESOURCEA, LPCSTR, LPCSTR, DWORD, LPSTR, LPDWORD, LPDWORD );

#define MPR_GET_PROC(func) \
    p ## func = (void*)GetProcAddress(hmpr, #func)

static void InitFunctionPtrs(void)
{
    HMODULE hmpr = GetModuleHandleA("mpr.dll");

    MPR_GET_PROC(WNetCachePassword);
    MPR_GET_PROC(WNetGetCachedPassword);
    MPR_GET_PROC(WNetEnumCachedPasswords);
    MPR_GET_PROC(WNetRemoveCachedPassword);
    MPR_GET_PROC(WNetUseConnectionA);
}

static const char* m_resource = "wine-test-resource";
static const char* m_password = "wine-test-password";
static const BYTE m_type = 1;
static const DWORD m_param = 8;
static BOOL m_callback_reached;

static BOOL CALLBACK enum_password_proc(PASSWORD_CACHE_ENTRY* pce, DWORD param)
{
    WORD size = 0;
    char* buf;

    ok(param == m_param, "param, got %d, got %d\n", param, m_param);

    size = offsetof( PASSWORD_CACHE_ENTRY, abResource[pce->cbResource + pce->cbPassword] );
    ok(pce->cbEntry == size, "cbEntry, got %d, expected %d\n", pce->cbEntry, size);
    ok(pce->cbResource == strlen(m_resource), "cbResource, got %d\n", pce->cbResource);
    ok(pce->cbPassword == strlen(m_password), "cbPassword, got %d\n", pce->cbPassword);
    ok(pce->iEntry == 0, "iEntry, got %d, got %d\n", pce->iEntry, 0);
    ok(pce->nType == m_type, "nType, got %d, got %d\n", pce->nType, m_type);

    buf = (char*)pce->abResource;
    ok(strncmp(buf, m_resource, pce->cbResource)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbResource, buf, m_resource);

    buf += pce->cbResource;
    ok(strncmp(buf, m_password, pce->cbPassword)==0, "enumerated resource differs, got %.*s, expected %s\n", pce->cbPassword, buf, m_password);

    m_callback_reached = 1;
    return TRUE;
}

static void test_WNetCachePassword(void)
{
    char resource_buf[32];
    char password_buf[32];
    char prefix_buf[32];
    WORD resource_len;
    WORD password_len;
    WORD prefix_len;
    DWORD ret;

    InitFunctionPtrs();

    if (pWNetCachePassword &&
        pWNetGetCachedPassword &&
        pWNetEnumCachedPasswords &&
        pWNetRemoveCachedPassword)
    {
        strcpy(resource_buf, m_resource);
        resource_len = strlen(m_resource);
        strcpy(password_buf, m_password);
        password_len = strlen(m_password);
        ret = pWNetCachePassword(resource_buf, resource_len, password_buf, password_len, m_type, 0);
        ok(ret == WN_SUCCESS, "WNetCachePassword failed: got %d, expected %d\n", ret, WN_SUCCESS);

        strcpy(resource_buf, m_resource);
        resource_len = strlen(m_resource);
        strcpy(password_buf, "------");
        password_len = sizeof(password_buf);
        ret = pWNetGetCachedPassword(resource_buf, resource_len, password_buf, &password_len, m_type);
        ok(ret == WN_SUCCESS, "WNetGetCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS);
        ok(password_len == strlen(m_password), "password length different, got %d\n", password_len);
        ok(strncmp(password_buf, m_password, password_len)==0, "passwords different, got %.*s, expected %s\n", password_len, password_buf, m_password);

        prefix_len = 9;
        strcpy(prefix_buf, m_resource);
        prefix_buf[prefix_len] = '0';
        ret = pWNetEnumCachedPasswords(prefix_buf, prefix_len, m_type, enum_password_proc, m_param);
        ok(ret == WN_SUCCESS, "WNetEnumCachedPasswords failed: got %d, expected %d\n", ret, WN_SUCCESS);
        ok(m_callback_reached == 1, "callback was not reached\n");

        strcpy(resource_buf, m_resource);
        resource_len = strlen(m_resource);
        ret = pWNetRemoveCachedPassword(resource_buf, resource_len, m_type);
        ok(ret == WN_SUCCESS, "WNetRemoveCachedPassword failed: got %d, expected %d\n", ret, WN_SUCCESS);
    } else {
        win_skip("WNetCachePassword() is not supported.\n");
    }
}

static void test_WNetUseConnection(void)
{
    DWORD ret, bufSize, outRes;
    LPNETRESOURCEA netRes;
    char outBuf[4], drive[] = "J:", letter;

    if (!pWNetUseConnectionA)
    {
        win_skip("WNetUseConnection() is not supported.\n");
        return;
    }
    netRes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NETRESOURCEA) + sizeof("\\\\127.0.0.1\\c$") + sizeof("J:"));
    netRes->dwType        = RESOURCETYPE_DISK;
    netRes->dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
    netRes->dwUsage       = RESOURCEUSAGE_CONNECTABLE;
    netRes->lpLocalName   = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA));
    netRes->lpRemoteName  = (LPSTR)((LPBYTE)netRes + sizeof(NETRESOURCEA) + sizeof("J:"));

    for (letter = 'J'; letter <= 'Z'; letter++)
    {
        drive[0] = letter;
        strcpy(netRes->lpLocalName, drive);
        strcpy(netRes->lpRemoteName, "\\\\127.0.0.1\\c$");
        bufSize = 0;
        ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, NULL, &bufSize, &outRes);
        if (ret == ERROR_ALREADY_ASSIGNED) continue;
    }
    todo_wine ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret);
    ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize);
    if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE);

    bufSize = 0;
    ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes);
    todo_wine ok(ret == ERROR_INVALID_PARAMETER, "Unexpected return: %u\n", ret);
    ok(bufSize == 0, "Unexpected buffer size: %u\n", bufSize);
    if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE);

    todo_wine {
    bufSize = 1;
    ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes);
    ok(ret == ERROR_MORE_DATA, "Unexpected return: %u\n", ret);
    ok(bufSize == 3, "Unexpected buffer size: %u\n", bufSize);
    if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE);

    bufSize = 4;
    ret = pWNetUseConnectionA(NULL, netRes, NULL, NULL, 0, outBuf, &bufSize, &outRes);
    ok(ret == WN_SUCCESS, "Unexpected return: %u\n", ret);
    }
    ok(bufSize == 4, "Unexpected buffer size: %u\n", bufSize);
    if (ret == WN_SUCCESS) WNetCancelConnectionA(drive, TRUE);

    HeapFree(GetProcessHeap(), 0, netRes);
}

START_TEST(mpr)
{
    test_WNetGetUniversalName();
    test_WNetGetRemoteName();
    test_WNetCachePassword();
    test_WNetUseConnection();
}
