1/*
2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25#include <windows.h>
26#include <stdlib.h>
27#include <string.h>
28#include <Psapi.h>
29
30#include "jni.h"
31#include "jni_util.h"
32
33#include "sun_tools_attach_AttachProviderImpl.h"
34
35/*
36 * Class:     sun_tools_attach_AttachProviderImpl
37 * Method:    tempPath
38 * Signature: ()Ljava/lang/String;
39 */
40JNIEXPORT jstring JNICALL
41Java_sun_tools_attach_AttachProviderImpl_tempPath(JNIEnv *env, jclass cls)
42{
43    char buf[256];
44    DWORD bufLen, actualLen;
45    jstring result = NULL;
46
47    bufLen = sizeof(buf) / sizeof(char);
48    actualLen = GetTempPath(bufLen, buf);
49    if (actualLen > 0) {
50        char* bufP = buf;
51        if (actualLen > bufLen) {
52            actualLen += sizeof(char);
53            bufP = (char*)malloc(actualLen * sizeof(char));
54            actualLen = GetTempPath(actualLen, bufP);
55        }
56        if (actualLen > 0) {
57            result = JNU_NewStringPlatform(env, bufP);
58        }
59        if (bufP != buf) {
60            free((void*)bufP);
61        }
62    }
63    return result;
64}
65
66/*
67 * Class:     sun_tools_attach_AttachProviderImpl
68 * Method:    volumeFlags
69 * Signature: ()J
70 */
71JNIEXPORT jlong JNICALL
72Java_sun_tools_attach_AttachProviderImpl_volumeFlags(JNIEnv *env, jclass cls, jstring str)
73{
74    jboolean isCopy;
75    const char* volume;
76    DWORD result = 0;
77
78    volume = JNU_GetStringPlatformChars(env, str, &isCopy);
79    if (volume != NULL) {
80        DWORD componentLen, flags;
81        BOOL res = GetVolumeInformation(volume,
82                                        NULL,
83                                        0,
84                                        NULL,
85                                        &componentLen,
86                                        &flags,
87                                        NULL,
88                                        0);
89       if (res != 0) {
90           result = flags;
91       }
92       if (isCopy) {
93            JNU_ReleaseStringPlatformChars(env, str, volume);
94       }
95    }
96    return result;
97}
98
99
100/*
101 * Class:     sun_tools_attach_AttachProviderImpl
102 * Method:    enumProcesses
103 * Signature: ([JI)I
104 */
105JNIEXPORT jint JNICALL
106Java_sun_tools_attach_AttachProviderImpl_enumProcesses(JNIEnv *env, jclass cls,
107                                                       jintArray arr, jint max)
108{
109    DWORD size, bytesReturned;
110    DWORD* ptr;
111    jint result = 0;
112
113    size = max * sizeof(DWORD);
114    ptr = (DWORD*)malloc(size);
115    if (ptr != NULL) {
116        BOOL res = EnumProcesses(ptr, size, &bytesReturned);
117        if (res != 0) {
118            result = (jint)(bytesReturned / sizeof(DWORD));
119            (*env)->SetIntArrayRegion(env, arr, 0, (jsize)result, (jint*)ptr);
120        }
121        free((void*)ptr);
122    }
123    return result;
124}
125
126/*
127 * Class:     sun_tools_attach_AttachProviderImpl
128 * Method:    isLibraryLoadedByProcess
129 * Signature: (I[Ljava/lang/String;)Z
130 */
131JNIEXPORT jboolean JNICALL
132Java_sun_tools_attach_AttachProviderImpl_isLibraryLoadedByProcess(JNIEnv *env, jclass cls,
133                                                                  jstring str, jint processId)
134{
135    HANDLE hProcess;
136    jboolean isCopy;
137    const char* lib;
138    DWORD size, bytesReturned;
139    HMODULE* ptr;
140    jboolean result = JNI_FALSE;
141
142    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
143                           PROCESS_VM_READ,
144                           FALSE, (DWORD)processId);
145    if (hProcess == NULL) {
146        return JNI_FALSE;
147    }
148    lib = JNU_GetStringPlatformChars(env, str, &isCopy);
149    if (lib == NULL) {
150        CloseHandle(hProcess);
151        return JNI_FALSE;
152    }
153
154    /*
155     * Enumerate the modules that the process has opened and see if we have a
156     * match.
157     */
158    size = 1024 * sizeof(HMODULE);
159    ptr = (HMODULE*)malloc(size);
160    if (ptr != NULL) {
161        BOOL res = EnumProcessModules(hProcess, ptr, size, &bytesReturned);
162        if (res != 0) {
163            int count = bytesReturned / sizeof(HMODULE);
164            int i = 0;
165            while (i < count) {
166                char base[256];
167                BOOL res = GetModuleBaseName(hProcess, ptr[i], base, sizeof(base));
168                if (res != 0) {
169                    if (strcmp(base, lib) == 0) {
170                      result = JNI_TRUE;
171                      break;
172                    }
173                }
174                i++;
175            }
176        }
177        free((void*)ptr);
178    }
179    if (isCopy) {
180        JNU_ReleaseStringPlatformChars(env, str, lib);
181    }
182    CloseHandle(hProcess);
183
184    return result;
185}
186