/*
 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <direct.h>
#include <malloc.h>
#include <io.h>
#include <windows.h>
#include <aclapi.h>
#include <winioctl.h>

#include "jni.h"
#include "jni_util.h"
#include "jlong.h"

#include "sun_nio_fs_WindowsNativeDispatcher.h"

/**
 * jfieldIDs
 */
static jfieldID findFirst_handle;
static jfieldID findFirst_name;
static jfieldID findFirst_attributes;

static jfieldID findStream_handle;
static jfieldID findStream_name;

static jfieldID volumeInfo_fsName;
static jfieldID volumeInfo_volName;
static jfieldID volumeInfo_volSN;
static jfieldID volumeInfo_flags;

static jfieldID diskSpace_bytesAvailable;
static jfieldID diskSpace_totalBytes;
static jfieldID diskSpace_totalFree;

static jfieldID account_domain;
static jfieldID account_name;
static jfieldID account_use;

static jfieldID aclInfo_aceCount;

static jfieldID completionStatus_error;
static jfieldID completionStatus_bytesTransferred;
static jfieldID completionStatus_completionKey;

static jfieldID backupResult_bytesTransferred;
static jfieldID backupResult_context;


/**
 * Win32 APIs not defined in Visual Studio 2003 header files
 */

typedef enum {
  FindStreamInfoStandard
} MY_STREAM_INFO_LEVELS;

typedef struct _MY_WIN32_FIND_STREAM_DATA {
  LARGE_INTEGER StreamSize;
  WCHAR cStreamName[MAX_PATH + 36];
} MY_WIN32_FIND_STREAM_DATA;

typedef HANDLE (WINAPI* FindFirstStream_Proc)(LPCWSTR, MY_STREAM_INFO_LEVELS, LPVOID, DWORD);
typedef BOOL (WINAPI* FindNextStream_Proc)(HANDLE, LPVOID);

typedef BOOLEAN (WINAPI* CreateSymbolicLinkProc) (LPCWSTR, LPCWSTR, DWORD);
typedef BOOL (WINAPI* CreateHardLinkProc) (LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES);
typedef BOOL (WINAPI* GetFinalPathNameByHandleProc) (HANDLE, LPWSTR, DWORD, DWORD);

typedef BOOL (WINAPI* ConvertSidToStringSidProc) (PSID, LPWSTR*);
typedef BOOL (WINAPI* ConvertStringSidToSidProc) (LPWSTR, PSID*);
typedef DWORD (WINAPI* GetLengthSidProc) (PSID);

static FindFirstStream_Proc FindFirstStream_func;
static FindNextStream_Proc FindNextStream_func;

static CreateSymbolicLinkProc CreateSymbolicLink_func;
static CreateHardLinkProc CreateHardLink_func;
static GetFinalPathNameByHandleProc GetFinalPathNameByHandle_func;

static ConvertSidToStringSidProc ConvertSidToStringSid_func;
static ConvertStringSidToSidProc ConvertStringSidToSid_func;
static GetLengthSidProc GetLengthSid_func;

static void throwWindowsException(JNIEnv* env, DWORD lastError) {
    jobject x = JNU_NewObjectByName(env, "sun/nio/fs/WindowsException",
        "(I)V", lastError);
    if (x != NULL) {
        (*env)->Throw(env, x);
    }
}

/**
 * Initializes jfieldIDs and get address of Win32 calls that are located
 * at runtime.
 */
JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_initIDs(JNIEnv* env, jclass this)
{
    jclass clazz;
    HMODULE h;

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstFile");
    if (clazz == NULL) {
        return;
    }
    findFirst_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
    findFirst_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
    findFirst_attributes = (*env)->GetFieldID(env, clazz, "attributes", "I");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$FirstStream");
    if (clazz == NULL) {
        return;
    }
    findStream_handle = (*env)->GetFieldID(env, clazz, "handle", "J");
    findStream_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$VolumeInformation");
    if (clazz == NULL) {
        return;
    }
    volumeInfo_fsName = (*env)->GetFieldID(env, clazz, "fileSystemName", "Ljava/lang/String;");
    volumeInfo_volName = (*env)->GetFieldID(env, clazz, "volumeName", "Ljava/lang/String;");
    volumeInfo_volSN = (*env)->GetFieldID(env, clazz, "volumeSerialNumber", "I");
    volumeInfo_flags = (*env)->GetFieldID(env, clazz, "flags", "I");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace");
    if (clazz == NULL) {
        return;
    }
    diskSpace_bytesAvailable = (*env)->GetFieldID(env, clazz, "freeBytesAvailable", "J");
    diskSpace_totalBytes = (*env)->GetFieldID(env, clazz, "totalNumberOfBytes", "J");
    diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$Account");
    if (clazz == NULL) {
        return;
    }
    account_domain = (*env)->GetFieldID(env, clazz, "domain", "Ljava/lang/String;");
    account_name = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
    account_use = (*env)->GetFieldID(env, clazz, "use", "I");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$AclInformation");
    if (clazz == NULL) {
        return;
    }
    aclInfo_aceCount = (*env)->GetFieldID(env, clazz, "aceCount", "I");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$CompletionStatus");
    if (clazz == NULL) {
        return;
    }
    completionStatus_error = (*env)->GetFieldID(env, clazz, "error", "I");
    completionStatus_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
    completionStatus_completionKey = (*env)->GetFieldID(env, clazz, "completionKey", "I");

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$BackupResult");
    if (clazz == NULL) {
        return;
    }
    backupResult_bytesTransferred = (*env)->GetFieldID(env, clazz, "bytesTransferred", "I");
    backupResult_context = (*env)->GetFieldID(env, clazz, "context", "J");


    h = LoadLibrary("kernel32");
    if (h != INVALID_HANDLE_VALUE) {
        FindFirstStream_func =
            (FindFirstStream_Proc)GetProcAddress(h, "FindFirstStreamW");
        FindNextStream_func =
            (FindNextStream_Proc)GetProcAddress(h, "FindNextStreamW");
        CreateSymbolicLink_func =
            (CreateSymbolicLinkProc)GetProcAddress(h, "CreateSymbolicLinkW");
        CreateHardLink_func =
            (CreateHardLinkProc)GetProcAddress(h, "CreateHardLinkW");
        GetFinalPathNameByHandle_func =
            (GetFinalPathNameByHandleProc)GetProcAddress(h, "GetFinalPathNameByHandleW");
        FreeLibrary(h);
    }

    h = LoadLibrary("advapi32");
    if (h != INVALID_HANDLE_VALUE) {
        ConvertSidToStringSid_func =
            (ConvertSidToStringSidProc)GetProcAddress(h, "ConvertSidToStringSidW");
        ConvertStringSidToSid_func =
            (ConvertStringSidToSidProc)GetProcAddress(h, "ConvertStringSidToSidW");
        GetLengthSid_func =
            (GetLengthSidProc)GetProcAddress(h, "GetLengthSid");
        FreeLibrary(h);
    }

}

JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FormatMessage(JNIEnv* env, jclass this, jint errorCode) {
    WCHAR message[255];

    DWORD len = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
                               NULL,
                               (DWORD)errorCode,
                               0,
                               &message[0],
                               255,
                               NULL);


    if (len == 0) {
        return NULL;
    } else {
        return (*env)->NewString(env, (const jchar *)message, (jsize)wcslen(message));
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LocalFree(JNIEnv* env, jclass this, jlong address)
{
    HLOCAL hMem = (HLOCAL)jlong_to_ptr(address);
    LocalFree(hMem);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateFile0(JNIEnv* env, jclass this,
    jlong address, jint dwDesiredAccess, jint dwShareMode, jlong sdAddress,
    jint dwCreationDisposition, jint dwFlagsAndAttributes)
{
    HANDLE handle;
    LPCWSTR lpFileName = jlong_to_ptr(address);

    SECURITY_ATTRIBUTES securityAttributes;
    LPSECURITY_ATTRIBUTES lpSecurityAttributes;
    PSECURITY_DESCRIPTOR lpSecurityDescriptor = jlong_to_ptr(sdAddress);


    if (lpSecurityDescriptor == NULL) {
        lpSecurityAttributes = NULL;
    } else {
        securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
        securityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
        securityAttributes.bInheritHandle = FALSE;
        lpSecurityAttributes = &securityAttributes;
    }

    handle = CreateFileW(lpFileName,
                        (DWORD)dwDesiredAccess,
                        (DWORD)dwShareMode,
                        lpSecurityAttributes,
                        (DWORD)dwCreationDisposition,
                        (DWORD)dwFlagsAndAttributes,
                        NULL);
    if (handle == INVALID_HANDLE_VALUE) {
        throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(handle);
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlSetSparse(JNIEnv* env, jclass this,
    jlong handle)
{
    DWORD bytesReturned;
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    if (DeviceIoControl(h, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &bytesReturned, NULL) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DeviceIoControlGetReparsePoint(JNIEnv* env, jclass this,
    jlong handle, jlong bufferAddress, jint bufferSize)
{
    DWORD bytesReturned;
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    LPVOID outBuffer = (LPVOID)jlong_to_ptr(bufferAddress);

    if (DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, outBuffer, (DWORD)bufferSize,
                        &bytesReturned, NULL) == 0)
    {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DeleteFile0(JNIEnv* env, jclass this, jlong address)
{
    LPCWSTR lpFileName = jlong_to_ptr(address);
    if (DeleteFileW(lpFileName) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateDirectory0(JNIEnv* env, jclass this,
    jlong address, jlong sdAddress)
{
    LPCWSTR lpFileName = jlong_to_ptr(address);

    SECURITY_ATTRIBUTES securityAttributes;
    LPSECURITY_ATTRIBUTES lpSecurityAttributes;
    PSECURITY_DESCRIPTOR lpSecurityDescriptor = jlong_to_ptr(sdAddress);


    if (lpSecurityDescriptor == NULL) {
        lpSecurityAttributes = NULL;
    } else {
        securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
        securityAttributes.lpSecurityDescriptor = lpSecurityDescriptor;
        securityAttributes.bInheritHandle = FALSE;
        lpSecurityAttributes = &securityAttributes;
    }

    if (CreateDirectoryW(lpFileName, lpSecurityAttributes) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_RemoveDirectory0(JNIEnv* env, jclass this, jlong address)
{
    LPCWSTR lpFileName = jlong_to_ptr(address);
    if (RemoveDirectoryW(lpFileName) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CloseHandle(JNIEnv* env, jclass this,
    jlong handle)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    CloseHandle(h);
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile0(JNIEnv* env, jclass this,
    jlong address, jobject obj)
{
    WIN32_FIND_DATAW data;
    LPCWSTR lpFileName = jlong_to_ptr(address);

    HANDLE handle = FindFirstFileW(lpFileName, &data);
    if (handle != INVALID_HANDLE_VALUE) {
        jstring name = (*env)->NewString(env, data.cFileName, wcslen(data.cFileName));
        if (name == NULL)
            return;
        (*env)->SetLongField(env, obj, findFirst_handle, ptr_to_jlong(handle));
        (*env)->SetObjectField(env, obj, findFirst_name, name);
        (*env)->SetIntField(env, obj, findFirst_attributes, data.dwFileAttributes);
    } else {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstFile1(JNIEnv* env, jclass this,
    jlong pathAddress, jlong dataAddress)
{
    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
    WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);

    HANDLE handle = FindFirstFileW(lpFileName, data);
    if (handle == INVALID_HANDLE_VALUE) {
        throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(handle);
}

JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindNextFile(JNIEnv* env, jclass this,
    jlong handle, jlong dataAddress)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    WIN32_FIND_DATAW* data = (WIN32_FIND_DATAW*)jlong_to_ptr(dataAddress);

    if (FindNextFileW(h, data) != 0) {
        return (*env)->NewString(env, data->cFileName, wcslen(data->cFileName));
    } else {
    if (GetLastError() != ERROR_NO_MORE_FILES)
        throwWindowsException(env, GetLastError());
        return NULL;
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindFirstStream0(JNIEnv* env, jclass this,
    jlong address, jobject obj)
{
    MY_WIN32_FIND_STREAM_DATA data;
    LPCWSTR lpFileName = jlong_to_ptr(address);
    HANDLE handle;

    if (FindFirstStream_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return;
    }

    handle = (*FindFirstStream_func)(lpFileName, FindStreamInfoStandard, &data, 0);
    if (handle != INVALID_HANDLE_VALUE) {
        jstring name = (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
        if (name == NULL)
            return;
        (*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
        (*env)->SetObjectField(env, obj, findStream_name, name);
    } else {
        if (GetLastError() == ERROR_HANDLE_EOF) {
             (*env)->SetLongField(env, obj, findStream_handle, ptr_to_jlong(handle));
        } else {
            throwWindowsException(env, GetLastError());
        }
    }

}

JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindNextStream(JNIEnv* env, jclass this,
    jlong handle)
{
    MY_WIN32_FIND_STREAM_DATA data;
    HANDLE h = (HANDLE)jlong_to_ptr(handle);

    if (FindNextStream_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return NULL;
    }

    if ((*FindNextStream_func)(h, &data) != 0) {
        return (*env)->NewString(env, data.cStreamName, wcslen(data.cStreamName));
    } else {
        if (GetLastError() != ERROR_HANDLE_EOF)
            throwWindowsException(env, GetLastError());
        return NULL;
    }
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_FindClose(JNIEnv* env, jclass this,
    jlong handle)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    if (FindClose(h) == 0) {
        throwWindowsException(env, GetLastError());
    }
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileInformationByHandle(JNIEnv* env, jclass this,
    jlong handle, jlong address)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    BY_HANDLE_FILE_INFORMATION* info =
        (BY_HANDLE_FILE_INFORMATION*)jlong_to_ptr(address);
    if (GetFileInformationByHandle(h, info) == 0) {
        throwWindowsException(env, GetLastError());
    }
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CopyFileEx0(JNIEnv* env, jclass this,
    jlong existingAddress, jlong newAddress, jint flags, jlong cancelAddress)
{
    LPCWSTR lpExistingFileName = jlong_to_ptr(existingAddress);
    LPCWSTR lpNewFileName = jlong_to_ptr(newAddress);
    LPBOOL cancel = (LPBOOL)jlong_to_ptr(cancelAddress);
    if (CopyFileExW(lpExistingFileName, lpNewFileName, NULL, NULL, cancel,
                    (DWORD)flags) == 0)
    {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_MoveFileEx0(JNIEnv* env, jclass this,
    jlong existingAddress, jlong newAddress, jint flags)
{
    LPCWSTR lpExistingFileName = jlong_to_ptr(existingAddress);
    LPCWSTR lpNewFileName = jlong_to_ptr(newAddress);
    if (MoveFileExW(lpExistingFileName, lpNewFileName, (DWORD)flags) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetLogicalDrives(JNIEnv* env, jclass this)
{
    DWORD res = GetLogicalDrives();
    if (res == 0) {
        throwWindowsException(env, GetLastError());
    }
    return (jint)res;
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributes0(JNIEnv* env, jclass this,
    jlong address)
{
    LPCWSTR lpFileName = jlong_to_ptr(address);
    DWORD value = GetFileAttributesW(lpFileName);

    if (value == INVALID_FILE_ATTRIBUTES) {
        throwWindowsException(env, GetLastError());
    }
    return (jint)value;
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetFileAttributes0(JNIEnv* env, jclass this,
    jlong address, jint value)
{
    LPCWSTR lpFileName = jlong_to_ptr(address);
    if (SetFileAttributesW(lpFileName, (DWORD)value) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileAttributesEx0(JNIEnv* env, jclass this,
    jlong pathAddress, jlong dataAddress)
{
    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
    WIN32_FILE_ATTRIBUTE_DATA* data = (WIN32_FILE_ATTRIBUTE_DATA*)jlong_to_ptr(dataAddress);

    BOOL res = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, (LPVOID)data);
    if (res == 0)
        throwWindowsException(env, GetLastError());
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetFileTime(JNIEnv* env, jclass this,
    jlong handle, jlong createTime, jlong lastAccessTime, jlong lastWriteTime)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);

    if (SetFileTime(h,
        (createTime == (jlong)-1) ? NULL : (CONST FILETIME *)&createTime,
        (lastAccessTime == (jlong)-1) ? NULL : (CONST FILETIME *)&lastAccessTime,
        (lastWriteTime == (jlong)-1) ? NULL : (CONST FILETIME *)&lastWriteTime) == 0)
    {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetEndOfFile(JNIEnv* env, jclass this,
    jlong handle)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);

    if (SetEndOfFile(h) == 0)
        throwWindowsException(env, GetLastError());
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumeInformation0(JNIEnv* env, jclass this,
    jlong address, jobject obj)
{
    WCHAR volumeName[MAX_PATH+1];
    DWORD volumeSerialNumber;
    DWORD maxComponentLength;
    DWORD flags;
    WCHAR fileSystemName[MAX_PATH+1];
    LPCWSTR lpFileName = jlong_to_ptr(address);
    jstring str;

    BOOL res = GetVolumeInformationW(lpFileName,
                                     &volumeName[0],
                                     MAX_PATH+1,
                                     &volumeSerialNumber,
                                     &maxComponentLength,
                                     &flags,
                                     &fileSystemName[0],
                                     MAX_PATH+1);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
        return;
    }

    str = (*env)->NewString(env, (const jchar *)fileSystemName, (jsize)wcslen(fileSystemName));
    if (str == NULL) return;
    (*env)->SetObjectField(env, obj, volumeInfo_fsName, str);

    str = (*env)->NewString(env, (const jchar *)volumeName, (jsize)wcslen(volumeName));
    if (str == NULL) return;
    (*env)->SetObjectField(env, obj, volumeInfo_volName, str);

    (*env)->SetIntField(env, obj, volumeInfo_volSN, (jint)volumeSerialNumber);
    (*env)->SetIntField(env, obj, volumeInfo_flags, (jint)flags);
}


JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDriveType0(JNIEnv* env, jclass this, jlong address) {
    LPCWSTR lpRootPathName = jlong_to_ptr(address);
    return (jint)GetDriveTypeW(lpRootPathName);
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpaceEx0(JNIEnv* env, jclass this,
    jlong address, jobject obj)
{
    ULARGE_INTEGER freeBytesAvailable;
    ULARGE_INTEGER totalNumberOfBytes;
    ULARGE_INTEGER totalNumberOfFreeBytes;
    LPCWSTR lpDirName = jlong_to_ptr(address);


    BOOL res = GetDiskFreeSpaceExW(lpDirName,
                                   &freeBytesAvailable,
                                   &totalNumberOfBytes,
                                   &totalNumberOfFreeBytes);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
        return;
    }

    (*env)->SetLongField(env, obj, diskSpace_bytesAvailable,
        long_to_jlong(freeBytesAvailable.QuadPart));
    (*env)->SetLongField(env, obj, diskSpace_totalBytes,
        long_to_jlong(totalNumberOfBytes.QuadPart));
    (*env)->SetLongField(env, obj, diskSpace_totalFree,
        long_to_jlong(totalNumberOfFreeBytes.QuadPart));
}


JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetVolumePathName0(JNIEnv* env, jclass this,
    jlong address)
{
    WCHAR volumeName[MAX_PATH+1];
    LPCWSTR lpFileName = jlong_to_ptr(address);


    BOOL res = GetVolumePathNameW(lpFileName,
                                  &volumeName[0],
                                  MAX_PATH+1);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
        return NULL;
    } else {
        return (*env)->NewString(env, (const jchar *)volumeName, (jsize)wcslen(volumeName));
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_InitializeSecurityDescriptor(JNIEnv* env, jclass this,
    jlong address)
{
    PSECURITY_DESCRIPTOR pSecurityDescriptor =
        (PSECURITY_DESCRIPTOR)jlong_to_ptr(address);

    if (InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_InitializeAcl(JNIEnv* env, jclass this,
    jlong address, jint size)
{
    PACL pAcl = (PACL)jlong_to_ptr(address);

    if (InitializeAcl(pAcl, (DWORD)size, ACL_REVISION) == 0) {
        throwWindowsException(env, GetLastError());
    }
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetFileSecurity0(JNIEnv* env, jclass this,
    jlong pathAddress, jint requestedInformation, jlong descAddress)
{
    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
    DWORD lengthNeeded = 0;

    BOOL res = SetFileSecurityW(lpFileName,
                                (SECURITY_INFORMATION)requestedInformation,
                                pSecurityDescriptor);

    if (res == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileSecurity0(JNIEnv* env, jclass this,
    jlong pathAddress, jint requestedInformation, jlong descAddress, jint nLength)
{
    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);
    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
    DWORD lengthNeeded = 0;

    BOOL res = GetFileSecurityW(lpFileName,
                                (SECURITY_INFORMATION)requestedInformation,
                                pSecurityDescriptor,
                                (DWORD)nLength,
                                &lengthNeeded);

    if (res == 0) {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            return (jint)lengthNeeded;
        } else {
            throwWindowsException(env, GetLastError());
            return 0;
        }
    } else {
        return (jint)nLength;
    }
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorOwner(JNIEnv* env,
    jclass this, jlong address)
{
    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(address);
    PSID pOwner;
    BOOL bOwnerDefaulted;


    if (GetSecurityDescriptorOwner(pSecurityDescriptor, &pOwner, &bOwnerDefaulted) == 0) {
        throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(pOwner);
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorOwner(JNIEnv* env,
    jclass this, jlong descAddress, jlong ownerAddress)
{
    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(descAddress);
    PSID pOwner = jlong_to_ptr(ownerAddress);

    if (SetSecurityDescriptorOwner(pSecurityDescriptor, pOwner, FALSE) == 0) {
        throwWindowsException(env, GetLastError());
    }
}


JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetSecurityDescriptorDacl(JNIEnv* env,
    jclass this, jlong address)
{
    PSECURITY_DESCRIPTOR pSecurityDescriptor = jlong_to_ptr(address);
    BOOL bDaclPresent;
    PACL pDacl;
    BOOL bDaclDefaulted;

    if (GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted) == 0) {
        throwWindowsException(env, GetLastError());
        return (jlong)0;
    } else {
        return (bDaclPresent) ? ptr_to_jlong(pDacl) : (jlong)0;
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetSecurityDescriptorDacl(JNIEnv* env,
    jclass this, jlong descAddress, jlong aclAddress)
{
    PSECURITY_DESCRIPTOR pSecurityDescriptor = (PSECURITY_DESCRIPTOR)jlong_to_ptr(descAddress);
    PACL pAcl = (PACL)jlong_to_ptr(aclAddress);

    if (SetSecurityDescriptorDacl(pSecurityDescriptor, TRUE, pAcl, FALSE) == 0) {
        throwWindowsException(env, GetLastError());
    }
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetAclInformation0(JNIEnv* env,
    jclass this, jlong address, jobject obj)
{
    PACL pAcl = (PACL)jlong_to_ptr(address);
    ACL_SIZE_INFORMATION acl_size_info;

    if (GetAclInformation(pAcl, (void *) &acl_size_info, sizeof(acl_size_info), AclSizeInformation) == 0) {
        throwWindowsException(env, GetLastError());
    } else {
        (*env)->SetIntField(env, obj, aclInfo_aceCount, (jint)acl_size_info.AceCount);
    }
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetAce(JNIEnv* env, jclass this, jlong address,
    jint aceIndex)
{
    PACL pAcl = (PACL)jlong_to_ptr(address);
    LPVOID pAce;

    if (GetAce(pAcl, (DWORD)aceIndex, &pAce) == 0) {
        throwWindowsException(env, GetLastError());
        return (jlong)0;
    } else {
        return ptr_to_jlong(pAce);
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessAllowedAceEx(JNIEnv* env,
    jclass this, jlong aclAddress, jint flags, jint mask, jlong sidAddress)
{
    PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
    PSID pSid = (PSID)jlong_to_ptr(sidAddress);

    if (AddAccessAllowedAceEx(pAcl, ACL_REVISION, (DWORD)flags, (DWORD)mask, pSid) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AddAccessDeniedAceEx(JNIEnv* env,
    jclass this, jlong aclAddress, jint flags, jint mask, jlong sidAddress)
{
    PACL pAcl = (PACL)jlong_to_ptr(aclAddress);
    PSID pSid = (PSID)jlong_to_ptr(sidAddress);

    if (AddAccessDeniedAceEx(pAcl, ACL_REVISION, (DWORD)flags, (DWORD)mask, pSid) == 0) {
        throwWindowsException(env, GetLastError());
    }
}


JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountSid0(JNIEnv* env,
    jclass this, jlong address, jobject obj)
{
    WCHAR domain[255];
    WCHAR name[255];
    DWORD domainLen = sizeof(domain);
    DWORD nameLen = sizeof(name);
    SID_NAME_USE use;
    PSID sid = jlong_to_ptr(address);
    jstring s;

    if (LookupAccountSidW(NULL, sid, &name[0], &nameLen, &domain[0], &domainLen, &use) == 0) {
        throwWindowsException(env, GetLastError());
        return;
    }

    s = (*env)->NewString(env, (const jchar *)domain, (jsize)wcslen(domain));
    if (s == NULL)
        return;
    (*env)->SetObjectField(env, obj, account_domain, s);

    s = (*env)->NewString(env, (const jchar *)name, (jsize)wcslen(name));
    if (s == NULL)
        return;
    (*env)->SetObjectField(env, obj, account_name, s);
    (*env)->SetIntField(env, obj, account_use, (jint)use);
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LookupAccountName0(JNIEnv* env,
    jclass this, jlong nameAddress, jlong sidAddress, jint cbSid)
{

    LPCWSTR accountName = jlong_to_ptr(nameAddress);
    PSID sid = jlong_to_ptr(sidAddress);
    WCHAR domain[255];
    DWORD domainLen = sizeof(domain);
    SID_NAME_USE use;

    if (LookupAccountNameW(NULL, accountName, sid, (LPDWORD)&cbSid,
                           &domain[0], &domainLen, &use) == 0)
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            throwWindowsException(env, GetLastError());
        }
    }

    return cbSid;
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetLengthSid(JNIEnv* env,
    jclass this, jlong address)
{
    PSID sid = jlong_to_ptr(address);

    if (GetLengthSid_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return 0;
    }
    return (jint)(*GetLengthSid_func)(sid);
}


JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_ConvertSidToStringSid(JNIEnv* env,
    jclass this, jlong address)
{
    PSID sid = jlong_to_ptr(address);
    LPWSTR string;

    if (ConvertSidToStringSid_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return NULL;
    }

    if ((*ConvertSidToStringSid_func)(sid, &string) == 0) {
        throwWindowsException(env, GetLastError());
        return NULL;
    } else {
        jstring s = (*env)->NewString(env, (const jchar *)string,
            (jsize)wcslen(string));
        LocalFree(string);
        return s;
    }
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_ConvertStringSidToSid0(JNIEnv* env,
    jclass this, jlong address)
{
    LPWSTR lpStringSid = jlong_to_ptr(address);
    PSID pSid;

    if (ConvertStringSidToSid_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return (jlong)0;
    }

    if ((*ConvertStringSidToSid_func)(lpStringSid, &pSid) == 0)
        throwWindowsException(env, GetLastError());

    return ptr_to_jlong(pSid);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentProcess(JNIEnv* env, jclass this) {
    HANDLE hProcess = GetCurrentProcess();
    return ptr_to_jlong(hProcess);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetCurrentThread(JNIEnv* env, jclass this) {
    HANDLE hThread = GetCurrentThread();
    return ptr_to_jlong(hThread);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_OpenProcessToken(JNIEnv* env,
    jclass this, jlong process, jint desiredAccess)
{
    HANDLE hProcess = (HANDLE)jlong_to_ptr(process);
    HANDLE hToken;

    if (OpenProcessToken(hProcess, (DWORD)desiredAccess, &hToken) == 0)
        throwWindowsException(env, GetLastError());
    return ptr_to_jlong(hToken);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_OpenThreadToken(JNIEnv* env,
    jclass this, jlong thread, jint desiredAccess, jboolean openAsSelf)
{
    HANDLE hThread = (HANDLE)jlong_to_ptr(thread);
    HANDLE hToken;
    BOOL bOpenAsSelf = (openAsSelf == JNI_TRUE) ? TRUE : FALSE;

    if (OpenThreadToken(hThread, (DWORD)desiredAccess, bOpenAsSelf, &hToken) == 0) {
        if (GetLastError() == ERROR_NO_TOKEN)
            return (jlong)0;
        throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(hToken);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_DuplicateTokenEx(JNIEnv* env,
    jclass this, jlong token, jint desiredAccess)
{
    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
    HANDLE resultToken;
    BOOL res;

    res = DuplicateTokenEx(hToken,
                           (DWORD)desiredAccess,
                           NULL,
                           SecurityImpersonation,
                           TokenImpersonation,
                           &resultToken);
    if (res == 0)
        throwWindowsException(env, GetLastError());
    return ptr_to_jlong(resultToken);
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_SetThreadToken(JNIEnv* env,
    jclass this, jlong thread, jlong token)
{
    HANDLE hThread = (HANDLE)jlong_to_ptr(thread);
    HANDLE hToken = (HANDLE)jlong_to_ptr(token);

    if (SetThreadToken(hThread, hToken) == 0)
        throwWindowsException(env, GetLastError());
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetTokenInformation(JNIEnv* env,
    jclass this, jlong token, jint tokenInfoClass, jlong tokenInfo, jint tokenInfoLength)
{
    BOOL res;
    DWORD lengthNeeded;
    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
    LPVOID result = (LPVOID)jlong_to_ptr(tokenInfo);

    res = GetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS)tokenInfoClass, (LPVOID)result,
                              tokenInfoLength, &lengthNeeded);
    if (res == 0) {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            return (jint)lengthNeeded;
        } else {
            throwWindowsException(env, GetLastError());
            return 0;
        }
    } else {
        return tokenInfoLength;
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AdjustTokenPrivileges(JNIEnv* env,
    jclass this, jlong token, jlong luid, jint attributes)
{
    TOKEN_PRIVILEGES privs[1];
    HANDLE hToken = (HANDLE)jlong_to_ptr(token);
    PLUID pLuid = (PLUID)jlong_to_ptr(luid);

    privs[0].PrivilegeCount = 1;
    privs[0].Privileges[0].Luid = *pLuid;
    privs[0].Privileges[0].Attributes = (DWORD)attributes;

    if (AdjustTokenPrivileges(hToken, FALSE, &privs[0], 1, NULL, NULL) == 0)
        throwWindowsException(env, GetLastError());
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_LookupPrivilegeValue0(JNIEnv* env,
    jclass this, jlong name)
{
    LPCWSTR lpName = (LPCWSTR)jlong_to_ptr(name);
    PLUID pLuid = LocalAlloc(0, sizeof(LUID));

    if (pLuid == NULL) {
        JNU_ThrowInternalError(env, "Unable to allocate LUID structure");
    } else {
        if (LookupPrivilegeValueW(NULL, lpName, pLuid) == 0)
            throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(pLuid);
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_BuildTrusteeWithSid(JNIEnv* env,
    jclass this, jlong sid)
{
    PSID pSid = (HANDLE)jlong_to_ptr(sid);
    PTRUSTEE_W pTrustee = LocalAlloc(0, sizeof(TRUSTEE_W));

    if (pTrustee == NULL) {
        JNU_ThrowInternalError(env, "Unable to allocate TRUSTEE_W structure");
    } else {
        BuildTrusteeWithSidW(pTrustee, pSid);
    }
    return ptr_to_jlong(pTrustee);
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetEffectiveRightsFromAcl(JNIEnv* env,
    jclass this, jlong acl, jlong trustee)
{
    ACCESS_MASK access;
    PACL pAcl = (PACL)jlong_to_ptr(acl);
    PTRUSTEE pTrustee = (PTRUSTEE)jlong_to_ptr(trustee);

    if (GetEffectiveRightsFromAcl(pAcl, pTrustee, &access) != ERROR_SUCCESS) {
        throwWindowsException(env, GetLastError());
    }
    return (jint)access;
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateSymbolicLink0(JNIEnv* env,
    jclass this, jlong linkAddress, jlong targetAddress, jint flags)
{
    LPCWSTR link = jlong_to_ptr(linkAddress);
    LPCWSTR target = jlong_to_ptr(targetAddress);

    if (CreateSymbolicLink_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return;
    }

    /* On Windows 64-bit this appears to succeed even when there is insufficient privileges */
    if ((*CreateSymbolicLink_func)(link, target, (DWORD)flags) == 0)
        throwWindowsException(env, GetLastError());
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateHardLink0(JNIEnv* env,
    jclass this, jlong newFileAddress, jlong existingFileAddress)
{
    LPCWSTR newFile = jlong_to_ptr(newFileAddress);
    LPCWSTR existingFile = jlong_to_ptr(existingFileAddress);

    if (CreateHardLink_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return;
    }
    if ((*CreateHardLink_func)(newFile, existingFile, NULL) == 0)
        throwWindowsException(env, GetLastError());
}

JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFullPathName0(JNIEnv *env,
                                                         jclass clz,
                                                         jlong pathAddress)
{
    jstring rv = NULL;
    WCHAR *lpBuf = NULL;
    WCHAR buf[MAX_PATH];
    DWORD len;
    LPCWSTR lpFileName = jlong_to_ptr(pathAddress);

    len = GetFullPathNameW(lpFileName, MAX_PATH, buf, NULL);
    if (len > 0) {
        if (len < MAX_PATH) {
            rv = (*env)->NewString(env, buf, len);
        } else {
            len += 1;  /* return length does not include terminator */
            lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
            if (lpBuf != NULL) {
                len = GetFullPathNameW(lpFileName, len, lpBuf, NULL);
                if (len > 0) {
                    rv = (*env)->NewString(env, lpBuf, len);
                } else {
                    JNU_ThrowInternalError(env, "GetFullPathNameW failed");
                }
                free(lpBuf);
            }
        }
    }
    if (len == 0)
        throwWindowsException(env, GetLastError());

    return rv;
}

JNIEXPORT jstring JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFinalPathNameByHandle(JNIEnv* env,
    jclass this, jlong handle)
{
    jstring rv = NULL;
    WCHAR *lpBuf = NULL;
    WCHAR path[MAX_PATH];
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    DWORD len;

    if (GetFinalPathNameByHandle_func == NULL) {
        JNU_ThrowInternalError(env, "Should not get here");
        return NULL;
    }

    len = (*GetFinalPathNameByHandle_func)(h, path, MAX_PATH, 0);
    if (len > 0) {
        if (len < MAX_PATH) {
            rv = (*env)->NewString(env, (const jchar *)path, (jsize)len);
        } else {
            len += 1;  /* return length does not include terminator */
            lpBuf = (WCHAR*)malloc(len * sizeof(WCHAR));
            if (lpBuf != NULL) {
                len = (*GetFinalPathNameByHandle_func)(h, lpBuf, len, 0);
                if (len > 0)  {
                    rv = (*env)->NewString(env, (const jchar *)lpBuf, (jsize)len);
                } else {
                    JNU_ThrowInternalError(env, "GetFinalPathNameByHandleW failed");
                }
                free(lpBuf);
            }
        }
    }

    if (len == 0)
        throwWindowsException(env, GetLastError());

    return rv;
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this,
    jlong fileHandle, jlong existingPort, jint completionKey)
{
    HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle),
                                         (HANDLE)jlong_to_ptr(existingPort),
                                         (DWORD)completionKey,
                                         0);
    if (port == NULL) {
        throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(port);
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetQueuedCompletionStatus0(JNIEnv* env, jclass this,
    jlong completionPort, jobject obj)
{
    DWORD bytesTransferred;
    DWORD completionKey;
    OVERLAPPED *lpOverlapped;
    BOOL res;

    res = GetQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
                                  &bytesTransferred,
                                  &completionKey,
                                  &lpOverlapped,
                                  INFINITE);
    if (res == 0 && lpOverlapped == NULL) {
        throwWindowsException(env, GetLastError());
    } else {
        DWORD ioResult = (res == 0) ? GetLastError() : 0;
        (*env)->SetIntField(env, obj, completionStatus_error, ioResult);
        (*env)->SetIntField(env, obj, completionStatus_bytesTransferred,
            (jint)bytesTransferred);
        (*env)->SetIntField(env, obj, completionStatus_completionKey,
            (jint)completionKey);

    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_PostQueuedCompletionStatus(JNIEnv* env, jclass this,
    jlong completionPort, jint completionKey)
{
    BOOL res;

    res = PostQueuedCompletionStatus((HANDLE)jlong_to_ptr(completionPort),
                                     (DWORD)0,  /* dwNumberOfBytesTransferred */
                                     (DWORD)completionKey,
                                     NULL);  /* lpOverlapped */
    if (res == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_ReadDirectoryChangesW(JNIEnv* env, jclass this,
    jlong hDirectory, jlong bufferAddress, jint bufferLength, jboolean watchSubTree, jint filter,
    jlong bytesReturnedAddress, jlong pOverlapped)
{
    BOOL res;
    BOOL subtree = (watchSubTree == JNI_TRUE) ? TRUE : FALSE;

    ((LPOVERLAPPED)jlong_to_ptr(pOverlapped))->hEvent = NULL;
    res = ReadDirectoryChangesW((HANDLE)jlong_to_ptr(hDirectory),
                                (LPVOID)jlong_to_ptr(bufferAddress),
                                (DWORD)bufferLength,
                                subtree,
                                (DWORD)filter,
                                (LPDWORD)jlong_to_ptr(bytesReturnedAddress),
                                (LPOVERLAPPED)jlong_to_ptr(pOverlapped),
                                NULL);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_BackupRead0(JNIEnv* env, jclass this,
    jlong hFile, jlong bufferAddress, jint bufferSize, jboolean abort,
    jlong context, jobject obj)
{
    BOOL res;
    DWORD bytesTransferred;
    BOOL a = (abort == JNI_TRUE) ? TRUE : FALSE;
    VOID* pContext = (VOID*)jlong_to_ptr(context);

    res = BackupRead((HANDLE)jlong_to_ptr(hFile),
                     (LPBYTE)jlong_to_ptr(bufferAddress),
                     (DWORD)bufferSize,
                     &bytesTransferred,
                     a,
                     FALSE,
                     &pContext);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
    } else {
        (*env)->SetIntField(env, obj, backupResult_bytesTransferred,
            bytesTransferred);
        (*env)->SetLongField(env, obj, backupResult_context,
            ptr_to_jlong(pContext));
    }
}

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_BackupSeek(JNIEnv* env, jclass this,
    jlong hFile, jlong bytesToSeek, jlong context)
{
    BOOL res;
    jint lowBytesToSeek = (jint)bytesToSeek;
    jint highBytesToSeek = (jint)(bytesToSeek >> 32);
    DWORD lowBytesSeeked;
    DWORD highBytesSeeked;
    VOID* pContext = jlong_to_ptr(context);

    res = BackupSeek((HANDLE)jlong_to_ptr(hFile),
                     (DWORD)lowBytesToSeek,
                     (DWORD)highBytesToSeek,
                     &lowBytesSeeked,
                     &highBytesSeeked,
                     &pContext);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
    }
}
