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

/*
 * A class to track key JVM instance info from the AT WinAccessBridge
 */

#include "AccessBridgeDebug.h"
#include "AccessBridgeJavaVMInstance.h"
#include "AccessBridgeMessages.h"
#include "AccessBridgePackages.h"
#include "accessBridgeResource.h"       // for debugging messages

#include <winbase.h>
#include <jni.h>

// The initialization must only be done one time and to provide for that the initialization
// is now done in WinAccessBridge and the CRITICAL_SECTION memory has been moved to there.
// send memory lock
//CRITICAL_SECTION sendMemoryIPCLock;
extern CRITICAL_SECTION sendMemoryIPCLock;

// protects the javaVMs chain while in use
extern bool isVMInstanceChainInUse;

DEBUG_CODE(extern HWND theDialogWindow);
extern "C" {
    DEBUG_CODE(void AppendToCallInfo(const char *s));
}


/**
 *
 *
 */
AccessBridgeJavaVMInstance::AccessBridgeJavaVMInstance(HWND ourABWindow,
                                                       HWND javaABWindow,
                                                       long javaVMID,
                                                       AccessBridgeJavaVMInstance *next) {
    goingAway = FALSE;
    // This should be called once.  Moved to WinAccessBridge c'tor
    //InitializeCriticalSection(&sendMemoryIPCLock);
    ourAccessBridgeWindow = ourABWindow;
    javaAccessBridgeWindow = javaABWindow;
    vmID = javaVMID;
    nextJVMInstance = next;
    memoryMappedFileMapHandle = (HANDLE) 0;
    memoryMappedView = (char *) 0;
    snprintf(memoryMappedFileName, sizeof(memoryMappedFileName), "AccessBridge-%p-%p.mmf",
            ourAccessBridgeWindow, javaAccessBridgeWindow);
}

/**
 *
 *
 */
AccessBridgeJavaVMInstance::~AccessBridgeJavaVMInstance() {
    DEBUG_CODE(char buffer[256]);

    DEBUG_CODE(AppendToCallInfo("***** in AccessBridgeJavaVMInstance::~AccessBridgeJavaVMInstance\r\n"));
    EnterCriticalSection(&sendMemoryIPCLock);

    // if IPC memory mapped file view is valid, unmap it
    goingAway = TRUE;
    if (memoryMappedView != (char *) 0) {
        DEBUG_CODE(snprintf(buffer, sizeof(buffer), "  unmapping memoryMappedView; view = %p\r\n", memoryMappedView));
        DEBUG_CODE(AppendToCallInfo(buffer));
        UnmapViewOfFile(memoryMappedView);
        memoryMappedView = (char *) 0;
    }
    // if IPC memory mapped file handle map is open, close it
    if (memoryMappedFileMapHandle != (HANDLE) 0) {
        DEBUG_CODE(snprintf(buffer, sizeof(buffer), "  closing memoryMappedFileMapHandle; handle = %p\r\n", memoryMappedFileMapHandle));
        DEBUG_CODE(AppendToCallInfo(buffer));
        CloseHandle(memoryMappedFileMapHandle);
        memoryMappedFileMapHandle = (HANDLE) 0;
    }
    LeaveCriticalSection(&sendMemoryIPCLock);

}

/**
 * initiateIPC - sets up the memory-mapped file to do IPC messaging
 *               1 file is created: to handle requests for information
 *               initiated from Windows AT.  The package is placed into
 *               the memory-mapped file (char *memoryMappedView),
 *               and then a special SendMessage() is sent.  When the
 *               JavaDLL returns from SendMessage() processing, the
 *               data will be in memoryMappedView.  The SendMessage()
 *               return value tells us if all is right with the world.
 *
 *               The set-up proces involves creating the memory-mapped
 *               file, and handshaking with the JavaDLL so it knows
 *               about it as well.
 *
 */
LRESULT
AccessBridgeJavaVMInstance::initiateIPC() {
    DEBUG_CODE(char debugBuf[256]);
    DWORD errorCode;

    DEBUG_CODE(AppendToCallInfo(" in AccessBridgeJavaVMInstance::initiateIPC()\r\n"));

    // create Windows-initiated IPC file & map it to a ptr
    memoryMappedFileMapHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
                                                  PAGE_READWRITE, 0,
                                                  // 8 bytes for return code
                                                  sizeof(WindowsInitiatedPackages) + 8,
                                                  memoryMappedFileName);
    if (memoryMappedFileMapHandle == NULL) {
        errorCode = GetLastError();
        DEBUG_CODE(snprintf(debugBuf, sizeof(debugBuf), "  Failed to CreateFileMapping for %s, error: %X", memoryMappedFileName, errorCode));
        DEBUG_CODE(AppendToCallInfo(debugBuf));
        return errorCode;
    } else {
        DEBUG_CODE(snprintf(debugBuf, sizeof(debugBuf), "  CreateFileMapping worked - filename: %s\r\n", memoryMappedFileName));
        DEBUG_CODE(AppendToCallInfo(debugBuf));
    }

    memoryMappedView = (char *) MapViewOfFile(memoryMappedFileMapHandle,
                                              FILE_MAP_READ | FILE_MAP_WRITE,
                                              0, 0, 0);
    if (memoryMappedView == NULL) {
        errorCode = GetLastError();
        DEBUG_CODE(snprintf(debugBuf, sizeof(debugBuf), "  Failed to MapViewOfFile for %s, error: %X", memoryMappedFileName, errorCode));
        DEBUG_CODE(AppendToCallInfo(debugBuf));
        return errorCode;
    } else {
        DEBUG_CODE(snprintf(debugBuf, sizeof(debugBuf), "  MapViewOfFile worked - view: %p\r\n", memoryMappedView));
        DEBUG_CODE(AppendToCallInfo(debugBuf));
    }


    // write some data to the memory mapped file
    strcpy(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_QUERY);


    // inform the JavaDLL that we've a memory mapped file ready for it
    char buffer[sizeof(PackageType) + sizeof(MemoryMappedFileCreatedPackage)];
    PackageType *type = (PackageType *) buffer;
    MemoryMappedFileCreatedPackage *pkg = (MemoryMappedFileCreatedPackage *) (buffer + sizeof(PackageType));
    *type = cMemoryMappedFileCreatedPackage;
    pkg->bridgeWindow = ABHandleToLong(ourAccessBridgeWindow);
    strncpy(pkg->filename, memoryMappedFileName, cMemoryMappedNameSize);
    sendPackage(buffer, sizeof(buffer));


    // look for the JavaDLL's answer to see if it could read the file
    if (strcmp(memoryMappedView, AB_MEMORY_MAPPED_FILE_OK_ANSWER) != 0) {
        DEBUG_CODE(snprintf(debugBuf, sizeof(debugBuf), "  JavaVM failed to deal with memory mapped file %s\r\n",
                      memoryMappedFileName));
        DEBUG_CODE(AppendToCallInfo(debugBuf));
        return -1;
    } else {
        DEBUG_CODE(snprintf(debugBuf, sizeof(debugBuf), "  Success!  JavaVM accpeted our file\r\n"));
        DEBUG_CODE(AppendToCallInfo(debugBuf));
    }

    return 0;
}

// -----------------------

/**
 * sendPackage - uses SendMessage(WM_COPYDATA) to do IPC messaging
 *               with the Java AccessBridge DLL
 *
 *               NOTE: WM_COPYDATA is only for one-way IPC; there
 *               is no way to return parameters (especially big ones)
 *               Use sendMemoryPackage() to do that!
 */
LRESULT
AccessBridgeJavaVMInstance::sendPackage(char *buffer, long bufsize) {
    COPYDATASTRUCT toCopy;
    toCopy.dwData = 0;          // 32-bits we could use for something...
    toCopy.cbData = bufsize;
    toCopy.lpData = buffer;

    PrintDebugString("[INFO]: In AccessBridgeVMInstance::sendPackage");
    PrintDebugString("[INFO]:     javaAccessBridgeWindow: %p", javaAccessBridgeWindow);
    /* This was SendMessage.  Normally that is a blocking call.  However, if
     * SendMessage is sent to another process, e.g. another JVM and an incoming
     * SendMessage is pending, control will be passed to the DialogProc to handle
     * the incoming message.  A bug occurred where this allowed an AB_DLL_GOING_AWAY
     * message to be processed deleting an AccessBridgeJavaVMInstance object in
     * the javaVMs chain.  SendMessageTimeout with SMTO_BLOCK set will prevent the
     * calling thread from processing other requests while waiting, i.e control
     * will not be passed to the DialogProc.  Also note that PostMessage or
     * SendNotifyMessage can't be used.  Although they don't allow transfer to
     * the DialogProc they can't be used in cases where pointers are passed.  This
     * is because the referenced memory needs to be available when the other thread
     * gets control.
     */
    UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG;
    DWORD_PTR out; // not used
    LRESULT lr = SendMessageTimeout( javaAccessBridgeWindow, WM_COPYDATA,
                                     (WPARAM)ourAccessBridgeWindow, (LPARAM)&toCopy,
                                     flags, 4000, &out );
    return lr;
}


/**
 * sendMemoryPackage - uses Memory-Mapped files to do IPC messaging
 *                     with the Java AccessBridge DLL, informing the
 *                     Java AccessBridge DLL via SendMessage that something
 *                     is waiting for it in the shared file...
 *
 *                     In the SendMessage call, the third param (WPARAM) is
 *                     the source HWND (ourAccessBridgeWindow in this case),
 *                     and the fourth param (LPARAM) is the size in bytes of
 *                     the package put into shared memory.
 *
 */
BOOL
AccessBridgeJavaVMInstance::sendMemoryPackage(char *buffer, long bufsize) {

    // Protect against race condition where the memory mapped file is
    // deallocated before the memory package is being sent
    if (goingAway) {
        return FALSE;
    }
    BOOL retval = FALSE;

    DEBUG_CODE(char outputBuf[256]);
    DEBUG_CODE(snprintf(outputBuf, sizeof(outputBuf), "AccessBridgeJavaVMInstance::sendMemoryPackage(, %d)", bufsize));
    DEBUG_CODE(AppendToCallInfo(outputBuf));

    DEBUG_CODE(PackageType *type = (PackageType *) buffer);
    DEBUG_CODE(if (*type == cGetAccessibleTextRangePackage) {)
        DEBUG_CODE(AppendToCallInfo("  'buffer' contains:"));
        DEBUG_CODE(GetAccessibleTextRangePackage *pkg = (GetAccessibleTextRangePackage *) (buffer + sizeof(PackageType)));
        DEBUG_CODE(snprintf(outputBuf, sizeof(outputBuf), "    PackageType = %X", *type));
        DEBUG_CODE(AppendToCallInfo(outputBuf));
        DEBUG_CODE(snprintf(outputBuf, sizeof(outputBuf), "    GetAccessibleTextRange: start = %d, end = %d, rText = %ls",
            pkg->start, pkg->end, pkg->rText));
        DEBUG_CODE(AppendToCallInfo(outputBuf));
    DEBUG_CODE(})

    EnterCriticalSection(&sendMemoryIPCLock);
    {
        // copy the package into shared memory
        if (!goingAway) {
            memcpy(memoryMappedView, buffer, bufsize);

            DEBUG_CODE(PackageType *type = (PackageType *) memoryMappedView);
            DEBUG_CODE(if (*type == cGetAccessibleTextItemsPackage) {)
                DEBUG_CODE(AppendToCallInfo("  'memoryMappedView' now contains:"));
                DEBUG_CODE(GetAccessibleTextItemsPackage *pkg = (GetAccessibleTextItemsPackage *) (buffer + sizeof(PackageType)));
                DEBUG_CODE(snprintf(outputBuf, sizeof(outputBuf), "    PackageType = %X", *type));
                DEBUG_CODE(AppendToCallInfo(outputBuf));
            DEBUG_CODE(})
        }

        if (!goingAway) {
            // Let the recipient know there is a package waiting for them. The unset byte
            // at end of buffer which will only be set if message is properly received
            char *done = &memoryMappedView[bufsize];
            *done = 0;

            PrintDebugString("[INFO]:     javaAccessBridgeWindow: %p", javaAccessBridgeWindow);
            // See the comment above the call to SendMessageTimeout in SendPackage method above.
            UINT flags = SMTO_BLOCK | SMTO_NOTIMEOUTIFNOTHUNG;
            DWORD_PTR out; // not used
            SendMessageTimeout( javaAccessBridgeWindow, AB_MESSAGE_WAITING, (WPARAM)ourAccessBridgeWindow, (LPARAM)bufsize,
                                flags, 4000, &out );

            // only succeed if message has been properly received
            if(!goingAway) retval = (*done == 1);
        }

        // copy the package back from shared memory
        if (!goingAway) {
            memcpy(buffer, memoryMappedView, bufsize);
        }
    }
    LeaveCriticalSection(&sendMemoryIPCLock);
    return retval;
}


/**
 * findAccessBridgeWindow - walk through linked list from where we are,
 *                          return the HWND of the ABJavaVMInstance that
 *                          matches the passed in vmID; no match: return 0
 *
 */
HWND
AccessBridgeJavaVMInstance::findAccessBridgeWindow(long javaVMID) {
    PrintDebugString("[INFO]: In findAccessBridgeWindow");
    // no need to recurse really
    if (vmID == javaVMID) {
        return javaAccessBridgeWindow;
    } else {
        isVMInstanceChainInUse = true;
        AccessBridgeJavaVMInstance *current = nextJVMInstance;
        while (current != (AccessBridgeJavaVMInstance *) 0) {
            if (current->vmID == javaVMID) {
                isVMInstanceChainInUse = false;
                return current->javaAccessBridgeWindow;
            }
            current = current->nextJVMInstance;
        }
        isVMInstanceChainInUse = false;
    }
    return 0;
}

/**
 * findABJavaVMInstanceFromJavaHWND - walk through linked list from
 *                                    where we are.  Return the
 *                                    AccessBridgeJavaVMInstance
 *                                    of the ABJavaVMInstance that
 *                                    matches the passed in vmID;
 *                                    no match: return 0
 */
AccessBridgeJavaVMInstance *
AccessBridgeJavaVMInstance::findABJavaVMInstanceFromJavaHWND(HWND window) {
    PrintDebugString("[INFO]: In findABJavaInstanceFromJavaHWND");
    // no need to recurse really
    if (javaAccessBridgeWindow == window) {
        return this;
    } else {
        isVMInstanceChainInUse = true;
        AccessBridgeJavaVMInstance *current = nextJVMInstance;
        while (current != (AccessBridgeJavaVMInstance *) 0) {
            if (current->javaAccessBridgeWindow == window) {
                isVMInstanceChainInUse = false;
                return current;
            }
            current = current->nextJVMInstance;
        }
    }
    isVMInstanceChainInUse = false;
    return (AccessBridgeJavaVMInstance *) 0;
}
