The following is a possible native implementation of LockableFile on
Windows NT (the API of the "LockFileEx" and "UnlockFileEx" functions
is not supported on Windows 95).



#include "local_LockableFile.h"
#include <winbase.h>

void
local_LockableFile_lock(
    struct Hlocal_LockableFile *this_h,
    long mode)
{
    Classlocal_LockableFile *this = unhand(this_h);
    DWORD flags = 0;
    OVERLAPPED offset;

    switch (mode) {
      case local_LockableFile_READ:
        break;
      case local_LockableFile_WRITE:
        flags |= LOCKFILE_EXCLUSIVE_LOCK;
        break;
      default:
        SignalError(EE(), "java/lang/IllegalArgumentException", NULL);
        return;
    }

    if (this->fd == -1 && !open_fd(this))
        return;         /* must have been an error */

    offset.Offset = offset.OffsetHigh = 0;
    if (!LockFileEx((HANDLE)this->fd, flags, 0,
                    0xFFFFFFFF, 0x7FFFFFFF, &offset)) {
        char errMsg[256];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0L,
                      errMsg, sizeof(errMsg), NULL);
        SignalError(EE(), "java/io/IOException", errMsg);
    }
}

void
local_LockableFile_unlock(
    struct Hlocal_LockableFile *this_h)
{
    Classlocal_LockableFile *this = unhand(this_h);
    OVERLAPPED offset;

    offset.Offset = offset.OffsetHigh = 0;
    if (!UnlockFileEx((HANDLE)this->fd, 0,
                      0xFFFFFFFF, 0x7FFFFFFF, &offset)) {
        char errMsg[256];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0L,
                      errMsg, sizeof(errMsg), NULL);
        SignalError(EE(), "java/io/IOException", errMsg);
    }
}

static int
open_fd(Classlocal_LockableFile *this)
{
    char *path = makeCString(this->path);
    HANDLE handle;

    handle = CreateFile((LPCTSTR)path, GENERIC_READ /*| GENERIC_WRITE*/,
                        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (handle != INVALID_HANDLE_VALUE) {       /* which is -1 anyway */
        this->fd = (long) handle;
        return 1;
    } else {
        char errMsg[256];
        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0L,
                      errMsg, sizeof(errMsg), NULL);
        SignalError(EE(), "java/io/IOException", errMsg);
        return 0;
    }
}
