/* Unit test suite for Ntdll directory functions
 *
 * Copyright 2007 Jeff Latimer
 * Copyright 2007 Andrey Turkin
 * Copyright 2008 Jeff Zaroyko
 * Copyright 2009 Dan Kegel
 *
 * 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
 *
 * NOTES
 * We use function pointers here as there is no import library for NTDLL on
 * windows.
 */

#include <stdio.h>
#include <stdarg.h>

#include "ntstatus.h"
/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
 * definition errors when we get to winnt.h
 */
#define WIN32_NO_STATUS

#include "wine/test.h"
#include "winternl.h"

static NTSTATUS (WINAPI *pNtClose)( PHANDLE );
static NTSTATUS (WINAPI *pNtOpenFile)    ( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, ULONG, ULONG );
static NTSTATUS (WINAPI *pNtQueryDirectoryFile)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,
                                                PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
static BOOLEAN  (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR);
static BOOL     (WINAPI *pRtlDosPathNameToNtPathName_U)( LPCWSTR, PUNICODE_STRING, PWSTR*, CURDIR* );
static VOID     (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
static VOID     (WINAPI *pRtlFreeUnicodeString)( PUNICODE_STRING );
static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
                                                   LPCSTR src, DWORD srclen );
static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirection)( BOOLEAN enable );
static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG *old_value );

/* The attribute sets to test */
static struct testfile_s {
    BOOL todo;                /* set if it doesn't work on wine yet */
    BOOL attr_done;           /* set if attributes were tested for this file already */
    const DWORD attr;         /* desired attribute */
    const char *name;         /* filename to use */
    const char *target;       /* what to point to (only for reparse pts) */
    const char *description;  /* for error messages */
    int nfound;               /* How many were found (expect 1) */
    WCHAR nameW[20];          /* unicode version of name (filled in later) */
} testfiles[] = {
    { 0, 0, FILE_ATTRIBUTE_NORMAL,    "longfilename.tmp", NULL, "normal" },
    { 0, 0, FILE_ATTRIBUTE_NORMAL,    "n.tmp", NULL, "normal" },
    { 1, 0, FILE_ATTRIBUTE_HIDDEN,    "h.tmp", NULL, "hidden" },
    { 1, 0, FILE_ATTRIBUTE_SYSTEM,    "s.tmp", NULL, "system" },
    { 0, 0, FILE_ATTRIBUTE_DIRECTORY, "d.tmp", NULL, "directory" },
    { 0, 0, FILE_ATTRIBUTE_DIRECTORY, ".",     NULL, ". directory" },
    { 0, 0, FILE_ATTRIBUTE_DIRECTORY, "..",    NULL, ".. directory" },
    { 0, 0, 0, NULL }
};
static const int max_test_dir_size = 20;  /* size of above plus some for .. etc */

/* Create a test directory full of attribute test files, clear counts */
static void set_up_attribute_test(const char *testdirA)
{
    int i;
    BOOL ret;

    ret = CreateDirectoryA(testdirA, NULL);
    ok(ret, "couldn't create dir '%s', error %d\n", testdirA, GetLastError());

    for (i=0; testfiles[i].name; i++) {
        char buf[MAX_PATH];
        pRtlMultiByteToUnicodeN(testfiles[i].nameW, sizeof(testfiles[i].nameW), NULL, testfiles[i].name, strlen(testfiles[i].name)+1);

        if (strcmp(testfiles[i].name, ".") == 0 || strcmp(testfiles[i].name, "..") == 0)
            continue;
        sprintf(buf, "%s\\%s", testdirA, testfiles[i].name);
        if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
            ret = CreateDirectoryA(buf, NULL);
            ok(ret, "couldn't create dir '%s', error %d\n", buf, GetLastError());
        } else {
            HANDLE h = CreateFileA(buf,
                                   GENERIC_READ|GENERIC_WRITE,
                                   0, NULL, CREATE_ALWAYS,
                                   testfiles[i].attr, 0);
            ok( h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf );
            CloseHandle(h);
        }
    }
}

static void reset_found_files(void)
{
    int i;

    for (i = 0; testfiles[i].name; i++)
        testfiles[i].nfound = 0;
}

/* Remove the given test directory and the attribute test files, if any */
static void tear_down_attribute_test(const char *testdirA)
{
    int i;

    for (i=0; testfiles[i].name; i++) {
        int ret;
        char buf[MAX_PATH];
        if (strcmp(testfiles[i].name, ".") == 0 || strcmp(testfiles[i].name, "..") == 0)
            continue;
        sprintf(buf, "%s\\%s", testdirA, testfiles[i].name);
        if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
            ret = RemoveDirectoryA(buf);
            ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
               "Failed to rmdir %s, error %d\n", buf, GetLastError());
        } else {
            ret = DeleteFileA(buf);
            ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
               "Failed to rm %s, error %d\n", buf, GetLastError());
        }
    }
    RemoveDirectoryA(testdirA);
}

/* Match one found file against testfiles[], increment count if found */
static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
{
    int i;
    DWORD attribmask =
      (FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_REPARSE_POINT);
    DWORD attrib = dir_info->FileAttributes & attribmask;
    WCHAR *nameW = dir_info->FileName;
    int namelen = dir_info->FileNameLength / sizeof(WCHAR);

    for (i=0; testfiles[i].name; i++) {
        int len = strlen(testfiles[i].name);
        if (namelen != len || memcmp(nameW, testfiles[i].nameW, len*sizeof(WCHAR)))
            continue;
        if (!testfiles[i].attr_done) {
            if (testfiles[i].todo) {
                todo_wine
                ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", testfiles[i].name, testfiles[i].description, testfiles[i].attr, attrib);
            } else {
                ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", testfiles[i].name, testfiles[i].description, testfiles[i].attr, attrib);
            }
            testfiles[i].attr_done = TRUE;
        }
        testfiles[i].nfound++;
        break;
    }
    ok(testfiles[i].name != NULL, "unexpected file found\n");
}

static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA,
                                            UNICODE_STRING *mask,
                                            BOOLEAN single_entry, BOOLEAN restart_flag)
{
    HANDLE dirh;
    IO_STATUS_BLOCK io;
    UINT data_pos, data_size;
    UINT data_len;    /* length of dir data */
    BYTE data[8192];  /* directory data */
    FILE_BOTH_DIRECTORY_INFORMATION *dir_info;
    DWORD status;
    int numfiles;
    int i;

    reset_found_files();

    data_size = mask ? offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] ) : sizeof(data);

    /* Read the directory and note which files are found */
    status = pNtOpenFile( &dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, attr, &io, FILE_SHARE_READ,
                         FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DIRECTORY_FILE);
    ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdirA, status, GetLastError());
    if (status != STATUS_SUCCESS) {
       skip("can't test if we can't open the directory\n");
       return;
    }

    pNtQueryDirectoryFile( dirh, NULL, NULL, NULL, &io, data, data_size,
                       FileBothDirectoryInformation, single_entry, mask, restart_flag );
    ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
    data_len = io.Information;
    ok (data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n");

    data_pos = 0;
    numfiles = 0;
    while ((data_pos < data_len) && (numfiles < max_test_dir_size)) {
        dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + data_pos);

        tally_test_file(dir_info);

        if (dir_info->NextEntryOffset == 0) {
            pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
                               FileBothDirectoryInformation, single_entry, mask, FALSE );
            if (U(io).Status == STATUS_NO_MORE_FILES)
                break;
            ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
            data_len = io.Information;
            if (data_len < sizeof(FILE_BOTH_DIRECTORY_INFORMATION))
                break;
            data_pos = 0;
        } else {
            data_pos += dir_info->NextEntryOffset;
        }
        numfiles++;
    }
    ok(numfiles < max_test_dir_size, "too many loops\n");

    if (mask)
        for (i=0; testfiles[i].name; i++)
            ok(testfiles[i].nfound == (testfiles[i].nameW == mask->Buffer),
               "Wrong number %d of %s files found (single_entry=%d,mask=%s)\n",
               testfiles[i].nfound, testfiles[i].description, single_entry,
               wine_dbgstr_wn(mask->Buffer, mask->Length/sizeof(WCHAR) ));
    else
        for (i=0; testfiles[i].name; i++)
            ok(testfiles[i].nfound == 1, "Wrong number %d of %s files found (single_entry=%d,restart=%d)\n",
               testfiles[i].nfound, testfiles[i].description, single_entry, restart_flag);
    pNtClose(dirh);
}

static void test_NtQueryDirectoryFile(void)
{
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING ntdirname, mask;
    char testdirA[MAX_PATH];
    WCHAR testdirW[MAX_PATH];
    int i;
    IO_STATUS_BLOCK io;
    WCHAR short_name[12];
    UINT data_size;
    BYTE data[8192];
    FILE_BOTH_DIRECTORY_INFORMATION *fbdi = (FILE_BOTH_DIRECTORY_INFORMATION*)data;
    DWORD status;
    HANDLE dirh;

    /* Clean up from prior aborted run, if any, then set up test files */
    ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n");
    strcat(testdirA, "NtQueryDirectoryFile.tmp");
    tear_down_attribute_test(testdirA);
    set_up_attribute_test(testdirA);

    pRtlMultiByteToUnicodeN(testdirW, sizeof(testdirW), NULL, testdirA, strlen(testdirA)+1);
    if (!pRtlDosPathNameToNtPathName_U(testdirW, &ntdirname, NULL, NULL))
    {
        ok(0, "RtlDosPathNametoNtPathName_U failed\n");
        goto done;
    }
    InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL);

    test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, TRUE);
    test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, FALSE);
    test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, TRUE);
    test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, FALSE);

    for (i = 0; testfiles[i].name; i++)
    {
        if (testfiles[i].nameW[0] == '.') continue;  /* . and .. as masks are broken on Windows */
        mask.Buffer = testfiles[i].nameW;
        mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].nameW) * sizeof(WCHAR);
        test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE);
        test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, FALSE);
        test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, TRUE);
        test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE);
    }

    /* short path passed as mask */
    status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
            FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
    ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA);
    if (status != STATUS_SUCCESS) {
        skip("can't test if we can't open the directory\n");
        return;
    }
    mask.Buffer = testfiles[0].nameW;
    mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].nameW) * sizeof(WCHAR);
    data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]);
    pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
            FileBothDirectoryInformation, TRUE, &mask, FALSE);
    ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
    ok(fbdi->ShortName[0], "ShortName is empty\n");

    mask.Length = mask.MaximumLength = fbdi->ShortNameLength;
    memcpy(short_name, fbdi->ShortName, mask.Length);
    mask.Buffer = short_name;
    pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
            FileBothDirectoryInformation, TRUE, &mask, TRUE);
    ok(U(io).Status == STATUS_SUCCESS, "failed to query directory status %x\n", U(io).Status);
    ok(fbdi->FileNameLength == strlen(testfiles[0].name)*sizeof(WCHAR) &&
            !memcmp(fbdi->FileName, testfiles[0].nameW, fbdi->FileNameLength),
            "incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName,
                fbdi->FileNameLength/sizeof(WCHAR)));

    pNtClose(dirh);

done:
    tear_down_attribute_test(testdirA);
    pRtlFreeUnicodeString(&ntdirname);
}

static void set_up_case_test(const char *testdir)
{
    BOOL ret;
    char buf[MAX_PATH];
    HANDLE h;

    ret = CreateDirectoryA(testdir, NULL);
    ok(ret, "couldn't create dir '%s', error %d\n", testdir, GetLastError());

    sprintf(buf, "%s\\%s", testdir, "TesT");
    h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                    FILE_ATTRIBUTE_NORMAL, 0);
    ok(h != INVALID_HANDLE_VALUE, "failed to create temp file '%s'\n", buf);
    CloseHandle(h);
}

static void tear_down_case_test(const char *testdir)
{
    int ret;
    char buf[MAX_PATH];

    sprintf(buf, "%s\\%s", testdir, "TesT");
    ret = DeleteFileA(buf);
    ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
       "Failed to rm %s, error %d\n", buf, GetLastError());
    RemoveDirectoryA(testdir);
}

static void test_NtQueryDirectoryFile_case(void)
{
    static const char testfile[] = "TesT";
    static const WCHAR testfile_w[] = {'T','e','s','T'};
    static int testfile_len = sizeof(testfile) - 1;
    static WCHAR testmask[] = {'t','e','s','t'};
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING ntdirname;
    char testdir[MAX_PATH];
    WCHAR testdir_w[MAX_PATH];
    HANDLE dirh;
    UNICODE_STRING mask;
    IO_STATUS_BLOCK io;
    UINT data_size, data_len;
    BYTE data[8192];
    FILE_BOTH_DIRECTORY_INFORMATION *dir_info = (FILE_BOTH_DIRECTORY_INFORMATION *)data;
    DWORD status;
    WCHAR *name;
    ULONG name_len;

    /* Clean up from prior aborted run, if any, then set up test files */
    ok(GetTempPathA(MAX_PATH, testdir), "couldn't get temp dir\n");
    strcat(testdir, "case.tmp");
    tear_down_case_test(testdir);
    set_up_case_test(testdir);

    pRtlMultiByteToUnicodeN(testdir_w, sizeof(testdir_w), NULL, testdir, strlen(testdir) + 1);
    if (!pRtlDosPathNameToNtPathName_U(testdir_w, &ntdirname, NULL, NULL))
    {
        ok(0, "RtlDosPathNametoNtPathName_U failed\n");
        goto done;
    }
    InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL);

    data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]);

    status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
                         FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
    ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdir, status, GetLastError());
    if (status != STATUS_SUCCESS)
    {
       skip("can't test if we can't open the directory\n");
       return;
    }

    mask.Buffer = testmask;
    mask.Length = mask.MaximumLength = sizeof(testmask);
    pNtQueryDirectoryFile(dirh, NULL, NULL, NULL, &io, data, data_size,
                          FileBothDirectoryInformation, TRUE, &mask, FALSE);
    ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
    data_len = io.Information;
    ok(data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n");

    name = dir_info->FileName;
    name_len = dir_info->FileNameLength / sizeof(WCHAR);

    ok(name_len == testfile_len, "unexpected filename length %u\n", name_len);
    ok(!memcmp(name, testfile_w, testfile_len * sizeof(WCHAR)), "unexpected filename %s\n",
       wine_dbgstr_wn(name, name_len));

    pNtClose(dirh);

done:
    tear_down_case_test(testdir);
    pRtlFreeUnicodeString(&ntdirname);
}

static void test_redirection(void)
{
    ULONG old, cur;
    NTSTATUS status;

    if (!pRtlWow64EnableFsRedirection || !pRtlWow64EnableFsRedirectionEx)
    {
        skip( "Wow64 redirection not supported\n" );
        return;
    }
    status = pRtlWow64EnableFsRedirectionEx( FALSE, &old );
    if (status == STATUS_NOT_IMPLEMENTED)
    {
        skip( "Wow64 redirection not supported\n" );
        return;
    }
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );

    status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur );

    status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur );

    status = pRtlWow64EnableFsRedirection( TRUE );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur );

    status = pRtlWow64EnableFsRedirectionEx( TRUE, NULL );
    ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status );
    status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)1 );
    ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status );

    status = pRtlWow64EnableFsRedirection( FALSE );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
    ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
    ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur );

    pRtlWow64EnableFsRedirectionEx( old, &cur );
}

START_TEST(directory)
{
    HMODULE hntdll = GetModuleHandleA("ntdll.dll");
    if (!hntdll)
    {
        skip("not running on NT, skipping test\n");
        return;
    }

    pNtClose                = (void *)GetProcAddress(hntdll, "NtClose");
    pNtOpenFile             = (void *)GetProcAddress(hntdll, "NtOpenFile");
    pNtQueryDirectoryFile   = (void *)GetProcAddress(hntdll, "NtQueryDirectoryFile");
    pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz");
    pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(hntdll, "RtlDosPathNameToNtPathName_U");
    pRtlInitUnicodeString   = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
    pRtlFreeUnicodeString   = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString");
    pRtlMultiByteToUnicodeN = (void *)GetProcAddress(hntdll,"RtlMultiByteToUnicodeN");
    pRtlWow64EnableFsRedirection = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirection");
    pRtlWow64EnableFsRedirectionEx = (void *)GetProcAddress(hntdll,"RtlWow64EnableFsRedirectionEx");

    test_NtQueryDirectoryFile();
    test_NtQueryDirectoryFile_case();
    test_redirection();
}
