Example #1
0
/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    checkPermissions
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions
  (JNIEnv *env, jclass cls, jstring path)
{
    jboolean isCopy;
    const char* p = GetStringPlatformChars(env, path, &isCopy);
    if (p != NULL) {
        struct stat64 sb;
        uid_t uid, gid;
        int res;

        /*
         * Check that the path is owned by the effective uid/gid of this
         * process. Also check that group/other access is not allowed.
         */
        uid = geteuid();
        gid = getegid();

        res = stat64(p, &sb);
        if (res != 0) {
            /* save errno */
            res = errno;
        }

        if (res == 0) {
            char msg[100];
            jboolean isError = JNI_FALSE;
            if (sb.st_uid != uid) {
                jio_snprintf(msg, sizeof(msg)-1,
                    "file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid);
                isError = JNI_TRUE;
            } else if (sb.st_gid != gid) {
                jio_snprintf(msg, sizeof(msg)-1,
                    "file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid);
                isError = JNI_TRUE;
            } else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) {
                jio_snprintf(msg, sizeof(msg)-1,
                    "file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777);
                isError = JNI_TRUE;
            }
            if (isError) {
                char buf[256];
                jio_snprintf(buf, sizeof(buf)-1, "well-known file %s is not secure: %s", p, msg);
                JNU_ThrowIOException(env, buf);
            }
        } else {
            char* msg = strdup(strerror(res));
            JNU_ThrowIOException(env, msg);
            if (msg != NULL) {
                free(msg);
            }
        }

        if (isCopy) {
            JNU_ReleaseStringPlatformChars(env, path, p);
        }
    }
}
Example #2
0
JNIEXPORT jint JNICALL
Java_java_util_zip_ZipFile_read(JNIEnv *env, jclass cls, jlong zfile,
				jlong zentry, jint pos, jbyteArray bytes,
				jint off, jint len)
{
#define BUFSIZE 8192
    jzfile *zip = jlong_to_ptr(zfile);
    jbyte buf[BUFSIZE];
    char *msg;

    if (len > BUFSIZE) {
	len = BUFSIZE;
    }
    ZIP_Lock(zip);
    len = ZIP_Read(zip, jlong_to_ptr(zentry), pos, buf, len);
    msg = zip->msg;
    ZIP_Unlock(zip);
    if (len == -1) {
	if (msg != 0) {
	    ThrowZipException(env, msg);
	} else {
	    JNU_ThrowIOException(env, strerror(errno));
	}
    } else {
	(*env)->SetByteArrayRegion(env, bytes, off, len, buf);
    }
    return len;
}
Example #3
0
/*
 * Class:     sun_tools_attach_BSDVirtualMachine
 * Method:    createAttachFile
 * Signature: (Ljava.lang.String;)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_BsdVirtualMachine_createAttachFile(JNIEnv *env, jclass cls, jstring path)
{
    const char* _path;
    jboolean isCopy;
    int fd, rc;

    _path = GetStringPlatformChars(env, path, &isCopy);
    if (_path == NULL) {
        JNU_ThrowIOException(env, "Must specify a path");
        return;
    }

    RESTARTABLE(open(_path, O_CREAT | O_EXCL, S_IWUSR | S_IRUSR), fd);
    if (fd == -1) {
        /* release p here before we throw an I/O exception */
        if (isCopy) {
            JNU_ReleaseStringPlatformChars(env, path, _path);
        }
        JNU_ThrowIOExceptionWithLastError(env, "open");
        return;
    }

    RESTARTABLE(chown(_path, geteuid(), getegid()), rc);

    RESTARTABLE(close(fd), rc);

    /* release p here */
    if (isCopy) {
        JNU_ReleaseStringPlatformChars(env, path, _path);
    }
}
static void
win32Error(JNIEnv *env, const WCHAR *functionName)
{
    WCHAR utf16_OSErrorMsg[MESSAGE_LENGTH - 100];
    WCHAR utf16_javaMessage[MESSAGE_LENGTH];
    /*Good suggestion about 2-bytes-per-symbol in localized error reports*/
    char  utf8_javaMessage[MESSAGE_LENGTH*2];
    const int errnum = (int)GetLastError();
    int n = os_error_message(errnum, utf16_OSErrorMsg, ARRAY_SIZE(utf16_OSErrorMsg));
    n = (n > 0)
        ? swprintf(utf16_javaMessage, MESSAGE_LENGTH, L"%s error=%d, %s", functionName, errnum, utf16_OSErrorMsg)
        : swprintf(utf16_javaMessage, MESSAGE_LENGTH, L"%s failed, error=%d", functionName, errnum);

    if (n > 0) /*terminate '\0' is not a part of conversion procedure*/
        n = WideCharToMultiByte(
            CP_UTF8,
            0,
            utf16_javaMessage,
            n, /*by creation n <= MESSAGE_LENGTH*/
            utf8_javaMessage,
            MESSAGE_LENGTH*2,
            NULL,
            NULL);

    /*no way to die*/
    {
        const char *errorMessage = "Secondary error while OS message extraction";
        if (n > 0) {
            utf8_javaMessage[min(MESSAGE_LENGTH*2 - 1, n)] = '\0';
            errorMessage = utf8_javaMessage;
        }
        JNU_ThrowIOException(env, errorMessage);
    }
}
Example #5
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    parseDisplayName0
 * Signature: (JLjava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0
    (JNIEnv* env, jclass cls, jlong jpIShellFolder, jstring jname)
{

    // Get desktop IShellFolder interface
    IShellFolder* pIShellFolder = (IShellFolder*)jpIShellFolder;
    if (pIShellFolder == NULL) {
        JNU_ThrowInternalError(env, "Desktop shell folder missing");
        return 0;
    }
    // Get relative PIDL for name
    LPITEMIDLIST pIDL;
    int nLength = env->GetStringLength(jname);
    const jchar* strPath = env->GetStringChars(jname, NULL);
    JNU_CHECK_EXCEPTION_RETURN(env, 0);
    jchar* wszPath = new jchar[nLength + 1];
    wcsncpy(reinterpret_cast<LPWSTR>(wszPath), reinterpret_cast<LPCWSTR>(strPath), nLength);
    wszPath[nLength] = 0;
    HRESULT res = pIShellFolder->ParseDisplayName(NULL, NULL,
                        reinterpret_cast<LPWSTR>(wszPath), NULL, &pIDL, NULL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not parse name");
        pIDL = 0;
    }
    delete[] wszPath;
    env->ReleaseStringChars(jname, strPath);
    return (jlong)pIDL;
}
Example #6
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    initSpecial
 * Signature: (JI)V
 */
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initSpecial
    (JNIEnv* env, jobject folder, jlong desktopIShellFolder, jint folderType)
{
    // Get desktop IShellFolder interface
    IShellFolder* pDesktop = (IShellFolder*)desktopIShellFolder;
    if (pDesktop == NULL) {
        JNU_ThrowInternalError(env, "Desktop shell folder missing");
        return;
    }
    // Get special folder relative PIDL
    LPITEMIDLIST relPIDL;
    HRESULT res = fn_SHGetSpecialFolderLocation(NULL, folderType,
        &relPIDL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not get shell folder ID list");
        return;
    }
    // Set field ID for relative PIDL
    env->CallVoidMethod(folder, MID_relativePIDL, (jlong)relPIDL);
    // Get special folder IShellFolder interface
    IShellFolder* pFolder;
    res = pDesktop->BindToObject(relPIDL, NULL, IID_IShellFolder,
        (void**)&pFolder);
    if (res != S_OK) {
        JNU_ThrowInternalError(env,
            "Could not bind shell folder to interface");
        return;
    }
    // Set field ID for pIShellFolder
    env->CallVoidMethod(folder, MID_pIShellFolder, (jlong)pFolder);
}
/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    open
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_open
  (JNIEnv *env, jclass cls, jstring path)
{
    jboolean isCopy;
    const char* p = GetStringPlatformChars(env, path, &isCopy);
    if (p == NULL) {
        return 0;
    } else {
        int fd;
        int err = 0;

        fd = open(p, O_RDWR);
        if (fd == -1) {
            err = errno;
        }

        if (isCopy) {
            JNU_ReleaseStringPlatformChars(env, path, p);
        }

        if (fd == -1) {
            if (err == ENOENT) {
                JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL);
            } else {
                char* msg = strdup(strerror(err));
                JNU_ThrowIOException(env, msg);
                if (msg != NULL) {
                    free(msg);
                }
            }
        }
        return fd;
    }
}
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
  (JNIEnv *env, jclass thisClass, jstring jName)
{
    HINSTANCE hModule;
    LPVOID lpMsgBuf;

    const char *libName = (*env)->GetStringUTFChars(env, jName, NULL);
    dprintf1("-lib %s\n", libName);

    hModule = LoadLibrary(libName);
    (*env)->ReleaseStringUTFChars(env, jName, libName);

    if (hModule == NULL) {
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM |
            FORMAT_MESSAGE_IGNORE_INSERTS,
            NULL,
            GetLastError(),
            0, /* Default language */
            (LPTSTR) &lpMsgBuf,
            0,
            NULL
        );
        dprintf1("-error: %s\n", lpMsgBuf);
        JNU_ThrowIOException(env, (char*)lpMsgBuf);
        LocalFree(lpMsgBuf);
        return 0;
    }
    dprintf2("-handle: %d (0X%X)\n", hModule, hModule);
    return (jlong)hModule;
}
Example #9
0
/**
 * Creates a SDP socket.
 */
static int create(JNIEnv* env)
{
    int s;

#if defined(__solaris__)
  #ifdef AF_INET6
    int domain = ipv6_available() ? AF_INET6 : AF_INET;
  #else
    int domain = AF_INET;
  #endif
    s = socket(domain, SOCK_STREAM, PROTO_SDP);
#elif defined(__linux__)
    /**
     * IPv6 not supported by SDP on Linux
     */
    if (ipv6_available()) {
        JNU_ThrowIOException(env, "IPv6 not supported");
        return -1;
    }
    s = socket(AF_INET_SDP, SOCK_STREAM, 0);
#else
    /* not supported on other platforms at this time */
    s = -1;
    errno = EPROTONOSUPPORT;
#endif

    if (s < 0)
        JNU_ThrowIOExceptionWithLastError(env, "socket");
    return s;
}
static char *fullPath(JNIEnv *env, char *part, char *full) {
    char **tmp;
    struct stat b;
    int ret;
    /*
     * If the filename we want to exec has any slashes in it then
     * we shouldn't do a path search, as in /foo ./foo or foo/bar.
     */
    if ((strchr(part, '/') == NULL) && PATH) {
	for (tmp = PATH; *tmp; tmp++) {
	    strcpy(full, *tmp);
	    /*
	     * empty path elements are like '.' so we don't want to append
	     * a slash to them.  Otherwise foo becomes /foo.
	     */
	    if (full[0] != '\0') {
		strcat(full, "/");
	    }
	    strcat(full, part);
	    ret = statExecutable(full, &b);
	    if (ret == -1) { /* doesn't exist */
		continue;
	    } else if (ret == -2) { /* can't execute */
		continue;    /* bug 4199993 - got to keep searching. */
	    } else {
		return full;
	    }
	}
    } else if (!(ret = statExecutable(part, &b))) {
	/* always copy value to be returned so `part' may always be freed
	 * after call (if needed) */
	strcpy(full, part);
	return full;
    } else if (ret == -2) { /* cannot execute */
	jio_snprintf(full, MAXPATHLEN, "%s: cannot execute", part);
	JNU_ThrowIOException(env, full);
	return 0;
    }

    /* not found if we got here */
    jio_snprintf(full, MAXPATHLEN, "%s: not found", part);
    JNU_ThrowIOException(env, full);
    return 0;
}
Example #11
0
/*
 * Class:     sun_tools_attach_LinuxVirtualMachine
 * Method:    checkPermissions
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_LinuxVirtualMachine_checkPermissions
  (JNIEnv *env, jclass cls, jstring path)
{
    jboolean isCopy;
    const char* p = GetStringPlatformChars(env, path, &isCopy);
    if (p != NULL) {
        struct stat64 sb;
        uid_t uid, gid;
        int res;

        /*
         * Check that the path is owned by the effective uid/gid of this
         * process. Also check that group/other access is not allowed.
         */
        uid = geteuid();
        gid = getegid();

        res = stat64(p, &sb);
        if (res != 0) {
            /* save errno */
            res = errno;
        }

        /* release p here before we throw an I/O exception */
        if (isCopy) {
            JNU_ReleaseStringPlatformChars(env, path, p);
        }

        if (res == 0) {
            if ( (sb.st_uid != uid) || (sb.st_gid != gid) ||
                 ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) ) {
                JNU_ThrowIOException(env, "well-known file is not secure");
            }
        } else {
            char* msg = strdup(strerror(res));
            JNU_ThrowIOException(env, msg);
            if (msg != NULL) {
                free(msg);
            }
        }
    }
}
    /*
     * Class:     sun_awt_shell_Win32ShellFolder
     * Method:    initFile
     * Signature: (JLjava/lang/String;Z)J
     */
    JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder_initFile
    (JNIEnv* env, jobject folder, jlong desktopIShellFolder,
     jstring absolutePath, jboolean initAttributes)
    {
        // Get desktop IShellFolder interface
        IShellFolder* pDesktop = (IShellFolder*)desktopIShellFolder;
        if (pDesktop == NULL) {
            JNU_ThrowInternalError(env, "Desktop shell folder missing");
            return 0;
        }
        // Get PIDL for file from desktop
        LPITEMIDLIST pIDL;
        int nLength = env->GetStringLength(absolutePath);
        jchar* wszPath = new jchar[nLength + 1];
        const jchar* strPath = env->GetStringChars(absolutePath, NULL);
        wcsncpy(wszPath, strPath, nLength);
        wszPath[nLength] = 0;
        HRESULT res = pDesktop->ParseDisplayName(NULL, NULL,
                      const_cast<jchar*>(wszPath), NULL, &pIDL, NULL);
        if (res != S_OK) {
            JNU_ThrowIOException(env, "Could not parse file path");
            delete[] wszPath;
            env->ReleaseStringChars(absolutePath, strPath);
            return 0;
        }
        delete[] wszPath;
        env->ReleaseStringChars(absolutePath, strPath);

        // Get display name, folder type, and possibly attributes
        SHFILEINFO fileInfo;
        UINT flags;

        if (initAttributes) {
            flags = SHGFI_ATTRIBUTES | SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_PIDL;
        } else {
            flags = SHGFI_DISPLAYNAME | SHGFI_TYPENAME | SHGFI_PIDL;
        }

        if (fn_SHGetFileInfo((char *)pIDL, 0L, &fileInfo, sizeof(fileInfo), flags) != 0) {

            if (initAttributes) {
                env->SetLongField(folder, FID_attributes, (jlong)fileInfo.dwAttributes);
            }

            env->SetObjectField(folder, FID_displayName,
                                JNU_NewStringPlatform(env, fileInfo.szDisplayName));

            env->SetObjectField(folder, FID_folderType,
                                JNU_NewStringPlatform(env, fileInfo.szTypeName));
        }
        return (jlong)pIDL;
    }
Example #13
0
static void
win32Error(JNIEnv *env, const char *functionName)
{
    static const char * const format = "%s error=%d, %s";
    static const char * const fallbackFormat = "%s failed, error=%d";
    char buf[256];
    char errmsg[sizeof(buf) + 100];
    const int errnum = GetLastError();
    const int n = JVM_GetLastErrorString(buf, sizeof(buf));
    if (n > 0)
        sprintf(errmsg, format, functionName, errnum, buf);
    else
        sprintf(errmsg, fallbackFormat, functionName, errnum);
    JNU_ThrowIOException(env, errmsg);
}
Example #14
0
/*
 * Class:     sun_awt_shell_Win32ShellFolder2
 * Method:    getFileSystemPath0
 * Signature: (I)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileSystemPath0
    (JNIEnv* env, jclass cls, jint csidl)
{
    LPITEMIDLIST relPIDL;
    TCHAR szBuf[MAX_PATH];
    HRESULT res = fn_SHGetSpecialFolderLocation(NULL, csidl, &relPIDL);
    if (res != S_OK) {
        JNU_ThrowIOException(env, "Could not get shell folder ID list");
        return NULL;
    }
    if (fn_SHGetPathFromIDList(relPIDL, szBuf)) {
        return JNU_NewStringPlatform(env, szBuf);
    } else {
        return NULL;
    }
}
/*
 * Class:     sun_tools_attach_WindowsVirtualMachine
 * Method:    openProcess
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_sun_tools_attach_WindowsVirtualMachine_openProcess
  (JNIEnv *env, jclass cls, jint pid)
{
    HANDLE hProcess;

    /*
     * Attempt to open process. If it fails then we try to enable the
     * SE_DEBUG_NAME privilege and retry.
     */
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
    if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
        hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
    }

    if (hProcess == NULL) {
        if (GetLastError() == ERROR_INVALID_PARAMETER) {
            JNU_ThrowIOException(env, "no such process");
        } else {
            JNU_ThrowIOExceptionWithLastError(env, "OpenProcess failed");
        }
        return (jlong)0;
    }

    /*
     * On Windows 64-bit we need to handle 32-bit tools trying to attach to 64-bit
     * processes (and visa versa). X-architecture attaching is currently not supported
     * by this implementation.
     */
    if (_IsWow64Process != NULL) {
        BOOL isCurrent32bit, isTarget32bit;
        (*_IsWow64Process)(GetCurrentProcess(), &isCurrent32bit);
        (*_IsWow64Process)(hProcess, &isTarget32bit);

        if (isCurrent32bit != isTarget32bit) {
            CloseHandle(hProcess);
            #ifdef _WIN64
              JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
                  "Unable to attach to 32-bit process running under WOW64");
            #else
              JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
                  "Unable to attach to 64-bit process");
            #endif
        }
    }

    return (jlong)hProcess;
}
Example #16
0
JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_Secmod_nssLoadLibrary
  (JNIEnv *env, jclass thisClass, jstring jLibName)
{
    void *hModule;
    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);

    dprintf1("-lib %s\n", libName);
    hModule = dlopen(libName, RTLD_LAZY);
    (*env)->ReleaseStringUTFChars(env, jLibName, libName);
    dprintf2("-handle: %u (0X%X)\n", hModule, hModule);

    if (hModule == NULL) {
        JNU_ThrowIOException(env, dlerror());
        return 0;
    }

    return (jlong)hModule;
}
Example #17
0
JNIEXPORT void JNICALL Java_sun_security_smartcardio_PlatformPCSC_initialize
        (JNIEnv *env, jclass thisClass, jstring jLibName) {
    const char *libName = (*env)->GetStringUTFChars(env, jLibName, NULL);
    hModule = dlopen(libName, RTLD_LAZY);
    (*env)->ReleaseStringUTFChars(env, jLibName, libName);

    if (hModule == NULL) {
        JNU_ThrowIOException(env, dlerror());
        return;
    }
    scardEstablishContext = (FPTR_SCardEstablishContext)findFunction(env, hModule, "SCardEstablishContext");
    scardConnect          = (FPTR_SCardConnect)         findFunction(env, hModule, "SCardConnect");
    scardDisconnect       = (FPTR_SCardDisconnect)      findFunction(env, hModule, "SCardDisconnect");
    scardStatus           = (FPTR_SCardStatus)          findFunction(env, hModule, "SCardStatus");
    scardGetStatusChange  = (FPTR_SCardGetStatusChange) findFunction(env, hModule, "SCardGetStatusChange");
    scardTransmit         = (FPTR_SCardTransmit)        findFunction(env, hModule, "SCardTransmit");
    scardListReaders      = (FPTR_SCardListReaders)     findFunction(env, hModule, "SCardListReaders");
    scardBeginTransaction = (FPTR_SCardBeginTransaction)findFunction(env, hModule, "SCardBeginTransaction");
    scardEndTransaction   = (FPTR_SCardEndTransaction)  findFunction(env, hModule, "SCardEndTransaction");
    scardControl          = (FPTR_SCardControl)         findFunction(env, hModule, "SCardControl");
}
Example #18
0
/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    connect
 * Signature: (ILjava/lang/String;)I
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_connect
  (JNIEnv *env, jclass cls, jint fd, jstring path)
{
    jboolean isCopy;
    const char* p = GetStringPlatformChars(env, path, &isCopy);
    if (p != NULL) {
        struct sockaddr_un addr;
        int err = 0;

        memset(&addr, 0, sizeof(addr));
        addr.sun_family = AF_UNIX;
        /* strncpy is safe because addr.sun_path was zero-initialized before. */
        strncpy(addr.sun_path, p, sizeof(addr.sun_path) - 1);

        if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
            err = errno;
        }

        if (isCopy) {
            JNU_ReleaseStringPlatformChars(env, path, p);
        }

        /*
         * If the connect failed then we throw the appropriate exception
         * here (can't throw it before releasing the string as can't call
         * JNI with pending exception)
         */
        if (err != 0) {
            if (err == ENOENT) {
                JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL);
            } else {
                char* msg = strdup(strerror(err));
                JNU_ThrowIOException(env, msg);
                if (msg != NULL) {
                    free(msg);
                }
            }
        }
    }
}
Example #19
0
/*
 * Class:     sun_tools_attach_LinuxVirtualMachine
 * Method:    getLinuxThreadsManager
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_sun_tools_attach_LinuxVirtualMachine_getLinuxThreadsManager
  (JNIEnv *env, jclass cls, jint pid)
{
    ChildCountContext context;

    /*
     * Iterate over all processes to find how many children 'pid' has
     */
    context.ppid = pid;
    context.count = 0;
    context.mpid = (pid_t)0;
    forEachProcess(ChildCountCallback, (void*)&context);

    /*
     * If there's no children then this is likely the pid of the primordial
     * created by the launcher - in that case the LinuxThreads manager is the
     * parent of this process.
     */
    if (context.count == 0) {
        pid_t parent = getParent(pid);
        if ((int)parent > 0) {
            return (jint)parent;
        }
    }

    /*
     * There's one child so this is likely the embedded VM case where the
     * the primordial thread == LinuxThreads initial thread. The LinuxThreads
     * manager in that case is the child.
     */
    if (context.count == 1) {
        return (jint)context.mpid;
    }

    /*
     * If we get here it's most likely we were given the wrong pid
     */
    JNU_ThrowIOException(env, "Unable to get pid of LinuxThreads manager thread");
    return -1;
}
Example #20
0
/*
 * Returns JNI_TRUE if the specified file is on a file system that supports
 * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
 * returns false).
 */
static jboolean isSecuritySupported(JNIEnv* env, const char* path) {
    char* root;
    char* p;
    BOOL res;
    DWORD dwMaxComponentLength;
    DWORD dwFlags;
    char fsName[128];
    DWORD fsNameLength;

    /*
     * Get root directory. Assume that files are absolute paths. For UNCs
     * the slash after the share name is required.
     */
    root = strdup(path);
    if (*root == '\\') {
        /*
         * \\server\share\file ==> \\server\share\
         */
        int slashskip = 3;
        p = root;
        while ((*p == '\\') && (slashskip > 0)) {
            char* p2;
            p++;
            p2 = strchr(p, '\\');
            if ((p2 == NULL) || (*p2 != '\\')) {
                free(root);
                JNU_ThrowIOException(env, "Malformed UNC");
                return JNI_FALSE;
            }
            p = p2;
            slashskip--;
        }
        if (slashskip != 0) {
            free(root);
            JNU_ThrowIOException(env, "Malformed UNC");
            return JNI_FALSE;
        }
        p++;
        *p = '\0';

    } else {
        p = strchr(root, '\\');
        if (p == NULL) {
            free(root);
            JNU_ThrowIOException(env, "Absolute filename not specified");
            return JNI_FALSE;
        }
        p++;
        *p = '\0';
    }


    /*
     * Get the volume information - this gives us the file system file and
     * also tells us if the file system supports persistent ACLs.
     */
    fsNameLength = sizeof(fsName)-1;
    res = GetVolumeInformation(root,
                               NULL,        // address of name of the volume, can be NULL
                               0,           // length of volume name
                               NULL,        // address of volume serial number, can be NULL
                               &dwMaxComponentLength,
                               &dwFlags,
                               fsName,
                               fsNameLength);
    if (res == 0) {
        free(root);
        JNU_ThrowIOExceptionWithLastError(env, "GetVolumeInformation failed");
        return JNI_FALSE;
    }

    free(root);
    return (dwFlags & FS_PERSISTENT_ACLS) ? JNI_TRUE : JNI_FALSE;
}
Example #21
0
/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    openProcess
 * Signature: (I)J
 */
JNIEXPORT jlong JNICALL Java_sun_tools_attach_VirtualMachineImpl_openProcess
  (JNIEnv *env, jclass cls, jint pid)
{
    HANDLE hProcess = NULL;

    if (pid == (jint) GetCurrentProcessId()) {
        /* process is attaching to itself; get a pseudo handle instead */
        hProcess = GetCurrentProcess();
        /* duplicate the pseudo handle so it can be used in more contexts */
        if (DuplicateHandle(hProcess, hProcess, hProcess, &hProcess,
                PROCESS_ALL_ACCESS, FALSE, 0) == 0) {
            /*
             * Could not duplicate the handle which isn't a good sign,
             * but we'll try again with OpenProcess() below.
             */
            hProcess = NULL;
        }
    }

    if (hProcess == NULL) {
        /*
         * Attempt to open process. If it fails then we try to enable the
         * SE_DEBUG_NAME privilege and retry.
         */
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
        if (hProcess == NULL && GetLastError() == ERROR_ACCESS_DENIED) {
            hProcess = doPrivilegedOpenProcess(PROCESS_ALL_ACCESS, FALSE,
                           (DWORD)pid);
        }

        if (hProcess == NULL) {
            if (GetLastError() == ERROR_INVALID_PARAMETER) {
                JNU_ThrowIOException(env, "no such process");
            } else {
                char err_mesg[255];
                /* include the last error in the default detail message */
                sprintf(err_mesg, "OpenProcess(pid=%d) failed; LastError=0x%x",
                    (int)pid, (int)GetLastError());
                JNU_ThrowIOExceptionWithLastError(env, err_mesg);
            }
            return (jlong)0;
        }
    }

    /*
     * On Windows 64-bit we need to handle 32-bit tools trying to attach to 64-bit
     * processes (and visa versa). X-architecture attaching is currently not supported
     * by this implementation.
     */
    if (_IsWow64Process != NULL) {
        BOOL isCurrent32bit, isTarget32bit;
        (*_IsWow64Process)(GetCurrentProcess(), &isCurrent32bit);
        (*_IsWow64Process)(hProcess, &isTarget32bit);

        if (isCurrent32bit != isTarget32bit) {
            CloseHandle(hProcess);
            #ifdef _WIN64
              JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
                  "Unable to attach to 32-bit process running under WOW64");
            #else
              JNU_ThrowByName(env, "com/sun/tools/attach/AttachNotSupportedException",
                  "Unable to attach to 64-bit process");
            #endif
        }
    }

    return (jlong)hProcess;
}
Example #22
0
/*
 * Class:     sun_tools_attach_VirtualMachineImpl
 * Method:    enqueue
 * Signature: (JILjava/lang/String;[Ljava/lang/Object;)V
 */
JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue
  (JNIEnv *env, jclass cls, jint fd, jstring cmd, jobjectArray args)
{
    jint arg_count, i;
    size_t size;
    jboolean isCopy;
    door_arg_t door_args;
    char res_buffer[128];
    jint result = -1;
    int rc;
    const char* cstr;
    char* buf;

    /*
     * First we get the command string and create the start of the
     * argument string to send to the target VM:
     * <ver>\0<cmd>\0
     */
    cstr = JNU_GetStringPlatformChars(env, cmd, &isCopy);
    if (cstr == NULL) {
        return -1;              /* pending exception */
    }
    size = strlen(PROTOCOL_VERSION) + strlen(cstr) + 2;
    buf = (char*)malloc(size);
    if (buf != NULL) {
        char* pos = buf;
        strcpy(buf, PROTOCOL_VERSION);
        pos += strlen(PROTOCOL_VERSION)+1;
        strcpy(pos, cstr);
    }
    if (isCopy) {
        JNU_ReleaseStringPlatformChars(env, cmd, cstr);
    }
    if (buf == NULL) {
        JNU_ThrowOutOfMemoryError(env, "malloc failed");
        return -1;
    }

    /*
     * Next we iterate over the arguments and extend the buffer
     * to include them.
     */
    arg_count = (*env)->GetArrayLength(env, args);

    for (i=0; i<arg_count; i++) {
        jobject obj = (*env)->GetObjectArrayElement(env, args, i);
        if (obj != NULL) {
            cstr = JNU_GetStringPlatformChars(env, obj, &isCopy);
            if (cstr != NULL) {
                size_t len = strlen(cstr);
                char* newbuf = (char*)realloc(buf, size+len+1);
                if (newbuf != NULL) {
                    buf = newbuf;
                    strcpy(buf+size, cstr);
                    size += len+1;
                }
                if (isCopy) {
                    JNU_ReleaseStringPlatformChars(env, obj, cstr);
                }
                if (newbuf == NULL) {
                    free(buf);
                    JNU_ThrowOutOfMemoryError(env, "realloc failed");
                    return -1;
                }
            }
        }
        if ((*env)->ExceptionOccurred(env)) {
            free(buf);
            return -1;
        }
    }

    /*
     * The arguments to the door function are in 'buf' so we now
     * do the door call
     */
    door_args.data_ptr = buf;
    door_args.data_size = size;
    door_args.desc_ptr = NULL;
    door_args.desc_num = 0;
    door_args.rbuf = (char*)&res_buffer;
    door_args.rsize = sizeof(res_buffer);

    RESTARTABLE(door_call(fd, &door_args), rc);

    /*
     * door_call failed
     */
    if (rc == -1) {
        JNU_ThrowIOExceptionWithLastError(env, "door_call");
    } else {
        /*
         * door_call succeeded but the call didn't return the expected jint.
         */
        if (door_args.data_size < sizeof(jint)) {
            JNU_ThrowIOException(env, "Enqueue error - reason unknown as result is truncated!");
        } else {
            jint* res = (jint*)(door_args.data_ptr);
            if (*res != JNI_OK) {
                const char* msg = translate_error(*res);
                char buf[255];
                if (msg == NULL) {
                    sprintf(buf, "Unable to enqueue command to target VM: %d", *res);
                } else {
                    sprintf(buf, "Unable to enqueue command to target VM: %s", msg);
                }
                JNU_ThrowIOException(env, buf);
            } else {
                /*
                 * The door call should return a file descriptor to one end of
                 * a socket pair
                 */
                if ((door_args.desc_ptr != NULL) &&
                    (door_args.desc_num == 1) &&
                    (door_args.desc_ptr->d_attributes & DOOR_DESCRIPTOR)) {
                    result = door_args.desc_ptr->d_data.d_desc.d_descriptor;
                } else {
                    JNU_ThrowIOException(env, "Reply from enqueue missing descriptor!");
                }
            }
        }
    }

    free(buf);
    return result;
}
/*
 * Class:     sun_awt_windows_WDataTransferer
 * Method:    platformImageBytesToImageData
 * Signature: ([BI)[I
 */
JNIEXPORT jintArray JNICALL
Java_sun_awt_windows_WDataTransferer_platformImageBytesToImageData(
    JNIEnv *env, jobject self, jbyteArray bytes, jlong format) {

    TRY;

    HDC hdc = NULL;

    LOGPALETTE* pLogPalette = NULL;
    WORD uPaletteEntries = 0;
    SIZE_T uOffset = 0;
    HPALETTE hPalette = NULL;
    HPALETTE hOldPalette = NULL;

    BITMAPINFO* pSrcBmi = NULL;
    BITMAPINFOHEADER* pSrcBmih = NULL;
    LPVOID pSrcBits = NULL;
    BITMAPINFO* pDstBmi = NULL;
    BITMAPINFOHEADER* pDstBmih = NULL;
    LPVOID pDstBits = NULL;

    LPBYTE lpEnhMetaFileBits = NULL;
    HENHMETAFILE hEnhMetaFile = NULL;

    HBITMAP hDibSection = NULL;
    HBITMAP hOldBitmap = NULL;
    jintArray buffer = NULL;
    LONG width = 0;
    LONG height = 0;
    int numPixels = 0;

    if (JNU_IsNull(env, bytes)) {
        return NULL;
    }

    jsize size = env->GetArrayLength(bytes);
    if (size == 0) {
        return NULL;
    }

    jbyte* bBytes = (jbyte*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, size, sizeof(jbyte));

    try {

        env->GetByteArrayRegion(bytes, 0, size, bBytes);

        pLogPalette = (LOGPALETTE*)bBytes;
        uPaletteEntries = pLogPalette->palNumEntries;
        uOffset = sizeof(LOGPALETTE) + uPaletteEntries * sizeof(PALETTEENTRY);
        DASSERT(uOffset < (SIZE_T)size);

        if (uPaletteEntries == 0) {
            pLogPalette = NULL;
        }

        hdc = ::CreateCompatibleDC(NULL);
        if (hdc == NULL) {
            free(bBytes);
            return NULL;
        }

        switch (format) {
        case CF_DIB:

            pSrcBmi = (BITMAPINFO*)((LPSTR)bBytes + uOffset);
            pSrcBmih = &pSrcBmi->bmiHeader;

            width = pSrcBmih->biWidth;
            height = abs(pSrcBmih->biHeight);

            {
                DWORD nColorEntries = 0;

                switch (pSrcBmih->biBitCount) {
                case  0: nColorEntries = 0; break;
                case  1: nColorEntries = 2; break;
                case  4:
                case  8:
                    nColorEntries = (pSrcBmih->biClrUsed != 0) ?
                        pSrcBmih->biClrUsed : (1 << pSrcBmih->biBitCount);
                    break;
                case 16:
                case 24:
                case 32:
                    nColorEntries = pSrcBmih->biClrUsed;
                    // If biBitCount is 16 or 32 and biCompression is
                    // BI_BITFIELDS the color table will be prefixed with
                    // three DWORD color masks.
                    if (pSrcBmih->biCompression == BI_BITFIELDS &&
                        (pSrcBmih->biBitCount == 16 ||
                         pSrcBmih->biBitCount == 32)) {
                        nColorEntries += 3;
                    }
                    break;
                default:
                    // The header is probably corrupted.
                    // Fail immediatelly to avoid memory access violation.
                    free(bBytes);
                    ::DeleteDC(hdc);
                    return NULL;
                }

                pSrcBits = (LPSTR)pSrcBmi + pSrcBmih->biSize
                    + nColorEntries * sizeof(RGBQUAD);
            }
            break;
        case CF_ENHMETAFILE:
        case CF_METAFILEPICT:
            lpEnhMetaFileBits = (BYTE*)bBytes + uOffset;
            // Warning C4244. size is jsize, uOffset is SIZE_T.
            // We assert that size > uOffset, so it is safe to cast to jsize.
            hEnhMetaFile = ::SetEnhMetaFileBits(size - (jsize)uOffset,
                                                lpEnhMetaFileBits);
            DASSERT(hEnhMetaFile != NULL);

            {
                UINT uHeaderSize =
                    ::GetEnhMetaFileHeader(hEnhMetaFile, 0, NULL);
                DASSERT(uHeaderSize != 0);
                ENHMETAHEADER* lpemh = (ENHMETAHEADER*)safe_Malloc(uHeaderSize);
                VERIFY(::GetEnhMetaFileHeader(hEnhMetaFile, uHeaderSize,
                                              lpemh) == uHeaderSize);
                LPRECTL lpFrame = &lpemh->rclFrame;
                POINT p = { abs(lpFrame->right - lpFrame->left),
                            abs(lpFrame->bottom - lpFrame->top) };
                VERIFY(::SaveDC(hdc));
                VERIFY(::SetMapMode(hdc, MM_HIMETRIC));
                VERIFY(::LPtoDP(hdc, &p, 1));
                VERIFY(::RestoreDC(hdc, -1));
                width = p.x;
                height = -p.y;

                free(lpemh);
            }
            break;
        default:
            DASSERT(FALSE); // Other formats are not supported yet.
            free(bBytes);
            ::DeleteDC(hdc);
            return NULL;
        }

        // JNI doesn't allow to store more than INT_MAX in a single array.
        // We report conversion failure in this case.
        if (width * height > INT_MAX) {
            free(bBytes);
            ::DeleteDC(hdc);
            return NULL;
        }

        numPixels = width * height;

        if (pLogPalette != NULL) {
            hPalette = ::CreatePalette(pLogPalette);
            if (hPalette == NULL) {
                free(bBytes);
                ::DeleteDC(hdc);
                return NULL;
            }
            hOldPalette = ::SelectPalette(hdc, hPalette, FALSE);
            ::RealizePalette(hdc);
        }

        // allocate memory for BITMAPINFO
        pDstBmi = (BITMAPINFO *)safe_Calloc(1, sizeof(BITMAPINFO));
        pDstBmih = &pDstBmi->bmiHeader;

        static const int BITS_PER_PIXEL = 32;

        // prepare BITMAPINFO for a 32-bit RGB bitmap
        pDstBmih->biSize = sizeof(BITMAPINFOHEADER);
        pDstBmih->biWidth = width;
        pDstBmih->biHeight = -height; // negative height means a top-down DIB
        pDstBmih->biPlanes = 1;
        pDstBmih->biBitCount = BITS_PER_PIXEL;
        pDstBmih->biCompression = BI_RGB;
        // NOTE: MSDN says that biSizeImage may be set to 0 for BI_RGB bitmaps,
        // but this causes CreateDIBSection to allocate zero-size memory block
        // for DIB data. It works okay when biSizeImage is explicitly specified.
        pDstBmih->biSizeImage = width * height * (BITS_PER_PIXEL >> 3);

        hDibSection = ::CreateDIBSection(hdc, (BITMAPINFO*)pDstBmi,
                                         DIB_RGB_COLORS, &pDstBits,
                                         NULL, 0);

        if (hDibSection == NULL) {
            free(pDstBmi); pDstBmi = NULL;
            if (hPalette != NULL) {
                VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
                hOldPalette = NULL;
                VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
            }
            VERIFY(::DeleteDC(hdc)); hdc = NULL;
            free(bBytes); bBytes = NULL;

            JNU_ThrowIOException(env, "failed to get drop data");
            return NULL;
        }

        hOldBitmap = (HBITMAP)::SelectObject(hdc, hDibSection);
        DASSERT(hOldBitmap != NULL);

        switch (format) {
        case CF_DIB:
            VERIFY(::StretchDIBits(hdc,
                                   0, 0, width, height,
                                   0, 0, width, height,
                                   pSrcBits, pSrcBmi,
                                   DIB_RGB_COLORS, SRCCOPY) != GDI_ERROR);
            break;
        case CF_ENHMETAFILE:
        case CF_METAFILEPICT: {
            RECT rect = { 0, 0, width, height };

            VERIFY(::PlayEnhMetaFile(hdc, hEnhMetaFile, &rect));
            VERIFY(::DeleteEnhMetaFile(hEnhMetaFile)); hEnhMetaFile = NULL;
            break;
        }
        default:
            // Other formats are not supported yet.
            DASSERT(FALSE);
            break;
        }

        // convert Win32 pixel format (BGRX) to Java format (ARGB)
        DASSERT(sizeof(jint) == sizeof(RGBQUAD));
        RGBQUAD* prgbq = (RGBQUAD*)pDstBits;
        for(int nPixel = 0; nPixel < numPixels; nPixel++, prgbq++) {
            jint jpixel = WIN_TO_JAVA_PIXEL(prgbq->rgbRed,
                                            prgbq->rgbGreen,
                                            prgbq->rgbBlue);
            // stuff the 32-bit pixel back into the 32-bit RGBQUAD
            *prgbq = *((RGBQUAD*)(&jpixel));
        }

        buffer = env->NewIntArray(numPixels + 2);
        if (buffer == NULL) {
            throw std::bad_alloc();
        }

        // copy pixels into Java array
        env->SetIntArrayRegion(buffer, 0, numPixels, (jint*)pDstBits);

        // copy dimensions into Java array
        env->SetIntArrayRegion(buffer, numPixels, 1, (jint*)&width);
        env->SetIntArrayRegion(buffer, numPixels + 1, 1, (jint*)&height);

        VERIFY(::SelectObject(hdc, hOldBitmap) != NULL); hOldBitmap = NULL;
        VERIFY(::DeleteObject(hDibSection)); hDibSection = NULL;
        free(pDstBmi); pDstBmi = NULL;
        if (hPalette != NULL) {
            VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
            hOldPalette = NULL;
            VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
        }
        VERIFY(::DeleteDC(hdc)); hdc = NULL;
        free(bBytes); bBytes = NULL;
    } catch (...) {
        if (hdc != NULL && hOldBitmap != NULL) {
            VERIFY(::SelectObject(hdc, hOldBitmap) != NULL); hOldBitmap = NULL;
        }
        if (hDibSection != NULL) {
            VERIFY(::DeleteObject(hDibSection)); hDibSection = NULL;
        }
        if (pDstBmi != NULL) {
            free(pDstBmi); pDstBmi = NULL;
        }
        if (hPalette != NULL) {
            if (hdc != NULL) {
                VERIFY(::SelectPalette(hdc, hOldPalette, FALSE) != NULL);
                hOldPalette = NULL;
            }
            VERIFY(::DeleteObject(hPalette)); hPalette = NULL;
        }
        if (hdc != NULL) {
            VERIFY(::DeleteDC(hdc)); hdc = NULL;
        }
        if (hEnhMetaFile != NULL) {
            VERIFY(::DeleteEnhMetaFile(hEnhMetaFile)); hEnhMetaFile = NULL;
        }
        if (bBytes != NULL) {
            free(bBytes); bBytes = NULL;
        }
        throw;
    }

    return buffer;

    CATCH_BAD_ALLOC_RET(NULL);
}
Example #24
0
/*
 * Class:     sun_awt_windows_WClipboard
 * Method:    getClipboardData
 * Signature: (J)[B
 */
JNIEXPORT jbyteArray JNICALL
Java_sun_awt_windows_WClipboard_getClipboardData
    (JNIEnv *env, jobject self, jlong format)
{
    TRY;

    DASSERT(::GetOpenClipboardWindow() == AwtToolkit::GetInstance().GetHWnd());

    HANDLE handle = ::GetClipboardData((UINT)format);
    if (handle == NULL) {
        JNU_ThrowIOException(env, "system clipboard data unavailable");
        return NULL;
    }

    jbyteArray bytes = NULL;
    jbyteArray paletteData = NULL;

    switch (format) {
    case CF_ENHMETAFILE:
    case CF_METAFILEPICT: {
        HENHMETAFILE hemf = NULL;

        if (format == CF_METAFILEPICT) {
            HMETAFILEPICT hMetaFilePict = (HMETAFILEPICT)handle;
            LPMETAFILEPICT lpMetaFilePict =
                (LPMETAFILEPICT)::GlobalLock(hMetaFilePict);
            UINT uSize = ::GetMetaFileBitsEx(lpMetaFilePict->hMF, 0, NULL);
            DASSERT(uSize != 0);

            try {
                LPBYTE lpMfBits = (LPBYTE)safe_Malloc(uSize);
                VERIFY(::GetMetaFileBitsEx(lpMetaFilePict->hMF, uSize,
                                           lpMfBits) == uSize);
                hemf = ::SetWinMetaFileBits(uSize, lpMfBits, NULL,
                                            lpMetaFilePict);
                free(lpMfBits);
                if (hemf == NULL) {
                    ::GlobalUnlock(hMetaFilePict);
                    JNU_ThrowIOException(env, "failed to get system clipboard data");
                    return NULL;
                }
            } catch (...) {
                ::GlobalUnlock(hMetaFilePict);
                throw;
            }
            ::GlobalUnlock(hMetaFilePict);
        } else {
            hemf = (HENHMETAFILE)handle;
        }

        UINT uEmfSize = ::GetEnhMetaFileBits(hemf, 0, NULL);
        if (uEmfSize == 0) {
            JNU_ThrowIOException(env, "cannot retrieve metafile bits");
            return NULL;
        }

        bytes = env->NewByteArray(uEmfSize);
        if (bytes == NULL) {
            throw std::bad_alloc();
        }

        LPBYTE lpbEmfBuffer =
            (LPBYTE)env->GetPrimitiveArrayCritical(bytes, NULL);
        if (lpbEmfBuffer == NULL) {
            env->DeleteLocalRef(bytes);
            throw std::bad_alloc();
        }
        VERIFY(::GetEnhMetaFileBits(hemf, uEmfSize, lpbEmfBuffer) == uEmfSize);
        env->ReleasePrimitiveArrayCritical(bytes, lpbEmfBuffer, 0);

        paletteData =
            AwtDataTransferer::GetPaletteBytes(hemf, OBJ_ENHMETAFILE, FALSE);
        break;
    }
    case CF_LOCALE: {
        LCID *lcid = (LCID *)::GlobalLock(handle);
        if (lcid == NULL) {
            JNU_ThrowIOException(env, "invalid LCID");
            return NULL;
        }
        try {
            bytes = AwtDataTransferer::LCIDToTextEncoding(env, *lcid);
        } catch (...) {
            ::GlobalUnlock(handle);
            throw;
        }
        ::GlobalUnlock(handle);
        break;
    }
    default: {
        ::SetLastError(0); // clear error
        // Warning C4244.
        // Cast SIZE_T (__int64 on 64-bit/unsigned int on 32-bit)
        // to jsize (long).
        SIZE_T globalSize = ::GlobalSize(handle);
        jsize size = (globalSize <= INT_MAX) ? (jsize)globalSize : INT_MAX;
        if (::GetLastError() != 0) {
            JNU_ThrowIOException(env, "invalid global memory block handle");
            return NULL;
        }

        bytes = env->NewByteArray(size);
        if (bytes == NULL) {
            throw std::bad_alloc();
        }

        if (size != 0) {
            LPVOID data = ::GlobalLock(handle);
            env->SetByteArrayRegion(bytes, 0, size, (jbyte *)data);
            ::GlobalUnlock(handle);
        }
        break;
    }
    }

    switch (format) {
    case CF_ENHMETAFILE:
    case CF_METAFILEPICT:
    case CF_DIB: {
        if (JNU_IsNull(env, paletteData)) {
            HPALETTE hPalette = (HPALETTE)::GetClipboardData(CF_PALETTE);
            paletteData =
                AwtDataTransferer::GetPaletteBytes(hPalette, OBJ_PAL, TRUE);
        }
        DASSERT(!JNU_IsNull(env, paletteData) &&
                !JNU_IsNull(env, bytes));

        jbyteArray concat =
            (jbyteArray)AwtDataTransferer::ConcatData(env, paletteData, bytes);

        if (!JNU_IsNull(env, safe_ExceptionOccurred(env))) {
            env->ExceptionDescribe();
            env->ExceptionClear();
            env->DeleteLocalRef(bytes);
            env->DeleteLocalRef(paletteData);
            return NULL;
        }

        env->DeleteLocalRef(bytes);
        env->DeleteLocalRef(paletteData);
        bytes = concat;
        break;
    }
    }

    return bytes;

    CATCH_BAD_ALLOC_RET(NULL);
}
/*
 * Class:     sun_tools_attach_WindowsVirtualMachine
 * Method:    enqueue
 * Signature: (JZLjava/lang/String;[Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_sun_tools_attach_WindowsVirtualMachine_enqueue
  (JNIEnv *env, jclass cls, jlong handle, jbyteArray stub, jstring cmd,
   jstring pipename, jobjectArray args)
{
    DataBlock data;
    DataBlock* pData;
    DWORD* pCode;
    DWORD numBytes;
    DWORD stubLen;
    HANDLE hProcess, hThread;
    jint argsLen, i;
    jbyte* stubCode;
    jboolean isCopy;

    /*
     * Setup data to copy to target process
     */
    data._LoadLibrary = _LoadLibrary;
    data._GetProcAddress = _GetProcAddress;

    strcpy(data.jvmLib, "jvm");
    strcpy(data.func1, "JVM_EnqueueOperation");
    strcpy(data.func2, "_JVM_EnqueueOperation@20");

    /*
     * Command and arguments
     */
    jstring_to_cstring(env, cmd, data.cmd, MAX_CMD_LENGTH);
    argsLen = (*env)->GetArrayLength(env, args);

    if (argsLen > 0) {
        if (argsLen > MAX_ARGS) {
            JNU_ThrowInternalError(env, "Too many arguments");
        }
        for (i=0; i<argsLen; i++) {
            jobject obj = (*env)->GetObjectArrayElement(env, args, i);
            if (obj == NULL) {
                data.arg[i][0] = '\0';
            } else {
                jstring_to_cstring(env, obj, data.arg[i], MAX_ARG_LENGTH);
            }
            if ((*env)->ExceptionOccurred(env)) return;
        }
    }
    for (i=argsLen; i<MAX_ARGS; i++) {
        data.arg[i][0] = '\0';
    }

    /* pipe name */
    jstring_to_cstring(env, pipename, data.pipename, MAX_PIPE_NAME_LENGTH);

    /*
     * Allocate memory in target process for data and code stub
     * (assumed aligned and matches architecture of target process)
     */
    hProcess = (HANDLE)handle;

    pData = (DataBlock*) VirtualAllocEx( hProcess, 0, sizeof(DataBlock), MEM_COMMIT, PAGE_READWRITE );
    if (pData == NULL) {
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
        return;
    }
    WriteProcessMemory( hProcess, (LPVOID)pData, (LPVOID)&data, (DWORD)sizeof(DataBlock), &numBytes );


    stubLen = (DWORD)(*env)->GetArrayLength(env, stub);
    stubCode = (*env)->GetByteArrayElements(env, stub, &isCopy);

    pCode = (PDWORD) VirtualAllocEx( hProcess, 0, stubLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
    if (pCode == NULL) {
        JNU_ThrowIOExceptionWithLastError(env, "VirtualAllocEx failed");
        VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
        return;
    }
    WriteProcessMemory( hProcess, (LPVOID)pCode, (LPVOID)stubCode, (DWORD)stubLen, &numBytes );
    if (isCopy) {
        (*env)->ReleaseByteArrayElements(env, stub, stubCode, JNI_ABORT);
    }

    /*
     * Create thread in target process to execute code
     */
    hThread = CreateRemoteThread( hProcess,
                                  NULL,
                                  0,
                                  (LPTHREAD_START_ROUTINE) pCode,
                                  pData,
                                  0,
                                  NULL );
    if (hThread != NULL) {
        if (WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0) {
            JNU_ThrowIOExceptionWithLastError(env, "WaitForSingleObject failed");
        } else {
            DWORD exitCode;
            GetExitCodeThread(hThread, &exitCode);
            if (exitCode) {
                switch (exitCode) {
                    case ERR_OPEN_JVM_FAIL :
                        JNU_ThrowIOException(env,
                            "jvm.dll not loaded by target process");
                        break;
                    case ERR_GET_ENQUEUE_FUNC_FAIL :
                        JNU_ThrowIOException(env,
                            "Unable to enqueue operation: the target VM does not support attach mechanism");
                        break;
                    default :
                        JNU_ThrowInternalError(env,
                            "Remote thread failed for unknown reason");
                }
            }
        }
        CloseHandle(hThread);
    } else {
        JNU_ThrowIOExceptionWithLastError(env, "CreateRemoteThread failed");
    }

    VirtualFreeEx(hProcess, pCode, 0, MEM_RELEASE);
    VirtualFreeEx(hProcess, pData, 0, MEM_RELEASE);
}