/*
 * Copyright (c) 2008, 2022, 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.
 */

#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 <Sddl.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 diskSpace_bytesPerSector;

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 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;

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

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

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

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$DiskFreeSpace");
    CHECK_NULL(clazz);
    diskSpace_bytesAvailable = (*env)->GetFieldID(env, clazz, "freeBytesAvailable", "J");
    CHECK_NULL(diskSpace_bytesAvailable);
    diskSpace_totalBytes = (*env)->GetFieldID(env, clazz, "totalNumberOfBytes", "J");
    CHECK_NULL(diskSpace_totalBytes);
    diskSpace_totalFree = (*env)->GetFieldID(env, clazz, "totalNumberOfFreeBytes", "J");
    CHECK_NULL(diskSpace_totalFree);
    diskSpace_bytesPerSector = (*env)->GetFieldID(env, clazz, "bytesPerSector", "J");
    CHECK_NULL(diskSpace_bytesPerSector);

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

    clazz = (*env)->FindClass(env, "sun/nio/fs/WindowsNativeDispatcher$AclInformation");
    CHECK_NULL(clazz);
    aclInfo_aceCount = (*env)->GetFieldID(env, clazz, "aceCount", "I");
    CHECK_NULL(aclInfo_aceCount);

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

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateEvent(JNIEnv* env, jclass this,
    jboolean bManualReset, jboolean bInitialState)
{
    HANDLE hEvent = CreateEventW(NULL, bManualReset, bInitialState, NULL);
    if (hEvent == NULL) {
        throwWindowsException(env, GetLastError());
    }
    return ptr_to_jlong(hEvent);
}

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 {
        if (len > 3) {
            // Drop final '.', CR, LF
            if (message[len - 1] == L'\n') len--;
            if (message[len - 1] == L'\r') len--;
            if (message[len - 1] == L'.') len--;
            message[len] = L'\0';
        }

        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 jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetFileSizeEx(JNIEnv *env,
    jclass this, jlong handle)
{
    HANDLE h = (HANDLE)jlong_to_ptr(handle);
    LARGE_INTEGER size;
    if (GetFileSizeEx(h, &size) == 0) {
        throwWindowsException(env, GetLastError());
    }
    return long_to_jlong(size.QuadPart);
}

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, (jsize)wcslen(data.cFileName));
        if (name == NULL) {
            FindClose(handle);
            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_FindNextFile0(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, (jsize)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)
{
    WIN32_FIND_STREAM_DATA data;
    LPCWSTR lpFileName = jlong_to_ptr(address);
    HANDLE handle;

    handle = FindFirstStreamW(lpFileName, FindStreamInfoStandard, &data, 0);
    if (handle != INVALID_HANDLE_VALUE) {
        jstring name = (*env)->NewString(env, data.cStreamName, (jsize)wcslen(data.cStreamName));
        if (name == NULL) {
            FindClose(handle);
            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_FindNextStream0(JNIEnv* env, jclass this,
    jlong handle)
{
    WIN32_FIND_STREAM_DATA data;
    HANDLE h = (HANDLE)jlong_to_ptr(handle);

    if (FindNextStreamW(h, &data) != 0) {
        return (*env)->NewString(env, data.cStreamName, (jsize)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_GetFileInformationByHandle0(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_SetFileTime0(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 void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetDiskFreeSpace0(JNIEnv* env, jclass this,
    jlong address, jobject obj)
{
    DWORD sectorsPerCluster;
    DWORD bytesPerSector;
    DWORD numberOfFreeClusters;
    DWORD totalNumberOfClusters;
    LPCWSTR lpRootPathName = jlong_to_ptr(address);


    BOOL res = GetDiskFreeSpaceW(lpRootPathName,
                                 &sectorsPerCluster,
                                 &bytesPerSector,
                                 &numberOfFreeClusters,
                                 &totalNumberOfClusters);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
        return;
    }

    (*env)->SetLongField(env, obj, diskSpace_bytesPerSector,
        long_to_jlong(bytesPerSector));
}

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);

    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);
    return (jint)GetLengthSid(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 (ConvertSidToStringSidW(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 (ConvertStringSidToSidW(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 jboolean JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_AccessCheck(JNIEnv* env,
    jclass this, jlong token, jlong securityInfo, jint accessMask,
    jint genericRead, jint genericWrite, jint genericExecute, jint genericAll)
{
    HANDLE hImpersonatedToken = (HANDLE)jlong_to_ptr(token);
    PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)jlong_to_ptr(securityInfo);
    DWORD checkAccessRights = (DWORD)accessMask;
    GENERIC_MAPPING mapping = {
        genericRead,
        genericWrite,
        genericExecute,
        genericAll};
    PRIVILEGE_SET privileges = {0};
    DWORD privilegesLength = sizeof(privileges);
    DWORD grantedAccess = 0;
    BOOL result = FALSE;

    /* checkAccessRights is in-out parameter */
    MapGenericMask(&checkAccessRights, &mapping);
    if (AccessCheck(security, hImpersonatedToken, checkAccessRights,
            &mapping, &privileges, &privilegesLength, &grantedAccess, &result) == 0)
        throwWindowsException(env, GetLastError());

    return (result == FALSE) ? JNI_FALSE : JNI_TRUE;
}

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) {
            LocalFree(pLuid);
            throwWindowsException(env, GetLastError());
            return (jlong)0;
        }
    }
    return ptr_to_jlong(pLuid);
}

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 (CreateSymbolicLinkW(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 (CreateHardLinkW(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);
            } else {
                JNU_ThrowOutOfMemoryError(env, "native memory allocation failure");
            }
        }
    } else {
        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;

    len = GetFinalPathNameByHandleW(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 = GetFinalPathNameByHandleW(h, lpBuf, len, 0);
                if (len > 0)  {
                    rv = (*env)->NewString(env, (const jchar *)lpBuf, (jsize)len);
                } else {
                    JNU_ThrowInternalError(env, "GetFinalPathNameByHandleW failed");
                }
                free(lpBuf);
            } else {
                JNU_ThrowOutOfMemoryError(env, "native memory allocation failure");
            }
        }
    } else {
        throwWindowsException(env, GetLastError());
    }
    return rv;
}

JNIEXPORT jlong JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CreateIoCompletionPort(JNIEnv* env, jclass this,
    jlong fileHandle, jlong existingPort, jlong completionKey)
{
    HANDLE port = CreateIoCompletionPort((HANDLE)jlong_to_ptr(fileHandle),
                                         (HANDLE)jlong_to_ptr(existingPort),
                                         (ULONG_PTR)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;
    ULONG_PTR 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)->SetLongField(env, obj, completionStatus_completionKey,
            (jlong)completionKey);
    }
}

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

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

JNIEXPORT void JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_CancelIo(JNIEnv* env, jclass this, jlong hFile) {
    if (CancelIo((HANDLE)jlong_to_ptr(hFile)) == 0) {
        throwWindowsException(env, GetLastError());
    }
}

JNIEXPORT jint JNICALL
Java_sun_nio_fs_WindowsNativeDispatcher_GetOverlappedResult(JNIEnv *env, jclass this,
    jlong hFile, jlong lpOverlapped)
{
    BOOL res;
    DWORD bytesTransferred = -1;

    res = GetOverlappedResult((HANDLE)jlong_to_ptr(hFile),
                              (LPOVERLAPPED)jlong_to_ptr(lpOverlapped),
                              &bytesTransferred,
                              TRUE);
    if (res == 0) {
        throwWindowsException(env, GetLastError());
    }

    return (jint)bytesTransferred;
}

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;

    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());
    }
}
