JNI - WMI 连接错误
JNI - WMI connection error
我有一个 java Web 应用程序可以从本地和远程 windows 机器收集一些数据。我正在使用 wmi 连接来连接到机器。
我使用 tomcat 作为 Web 服务器。对于 wmi 连接,我编写了 C++ 代码并使用 JNI 连接 java 和 C++。当我启动服务器并输入登录详细信息时,tomcat 崩溃。
日志文件中的错误是..
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd1e6e2931, pid=3940, tid=0x0000000000000a6c
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [Verify_.dll+0x2931]
#
我正在使用 tomcat 8.5.28 和 jdk1.8。0_162
这是我的 java 代码:Verify_.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Verify_ extends HttpServlet{
public native int connect();
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.loadLibrary("Verify_");
Verify_ verify = new Verify_();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String ServerName = request.getParameter("servername");
String UserName = request.getParameter("username");
String Password = request.getParameter("password");
int status = verify.connect();
if(status == 0)
out.println("Connected to " + ServerName);
else if(status == 1)
out.println("failed to initialize CoInitializeEx");
else if(status == 2)
out.println("failed to initialize CoInitializeSecurity");
else if(status == 3)
out.println("failed to initialize CoCreateInstance");
else if(status == 4)
out.println("failed to connect to Server");
else
out.println(status);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request,response);
}}
这里是JNI接口代码:Verify_.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Verify_ */
#ifndef _Included_Verify_
#define _Included_Verify_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Verify_
* Method: connect
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Verify_1_connect
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
这是 C++ 代码:Verify_.cpp
#include <iostream>
#include <wbemidl.h>
#include <conio.h>
#include <windows.h>
#include <comdef.h>
#include <wincred.h>
#include <string.h>
#include "Verify_.h"
#pragma comment(lib, "credui.lib")
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Ole32.lib")
#define _WIN32_DCOM
JNIEXPORT jint JNICALL Java_Verify_1_connect (JNIEnv *, jobject){
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\172.21.111.250\ROOT\cimv2"));
wcscpy(pszUserName, BSTR(L"Administrator"));
wcscpy(pszPassword, BSTR(L"qwerty1233"));
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr)) {
return 1;
}
hr = CoInitializeSecurity(
NULL, // Security descriptor
-1, // COM negotiates authentication service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
NULL, // Authentication info
EOAC_NONE, // Additional capabilities of the client or server
NULL); // Reserved
if (FAILED(hr)) {
CoUninitialize();
return 2;
}
IWbemLocator *pLoc = 0;
hr = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hr)){
CoUninitialize();
return 3;
}
IWbemServices *pSvc = NULL;
// Connect to the root\default namespace with the current user.
hr = pLoc->ConnectServer(
pszRoot, //namespace
pszUserName, // User name
pszPassword, // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc); // IWbemServices proxy
if (FAILED(hr)){
pLoc->Release();
CoUninitialize();
return 4;
}
// pSvc->Release();
// pLoc->Release();
CoUninitialize();
return 0;
}
过去 5 天我一直在努力。请帮助我。如果有其他方法告诉我..
提前致谢
0xc0000005
-> 访问冲突,主要是因为使用了 NULL 指针。
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\172.21.111.250\ROOT\cimv2"));
使用wcscpy时必须分配内存。因此,使用无效(随机)地址调用 wcscopy(在调试模式下:使用 NULL)。
我不确定您是否正确处理了 BSTR(我不知道 BSTR)。见 BSTR 的定义:
typedef OLECHAR *BSTR;
为什么不直接赋值?
pszRoot = BSTR(L"\\172.21.111.250\ROOT\cimv2");
感谢拉尔夫·厄特
我改了这部分
BSTR pszRoot,pszUserName,pszPassword;
pszRoot = ::SysAllocString(L"\\172.21.111.250\ROOT\cimv2");
pszUserName = ::SysAllocString(L"Administrator");
pszPassword = ::SysAllocString(L"qwerty1233");
我有一个 java Web 应用程序可以从本地和远程 windows 机器收集一些数据。我正在使用 wmi 连接来连接到机器。 我使用 tomcat 作为 Web 服务器。对于 wmi 连接,我编写了 C++ 代码并使用 JNI 连接 java 和 C++。当我启动服务器并输入登录详细信息时,tomcat 崩溃。
日志文件中的错误是..
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd1e6e2931, pid=3940, tid=0x0000000000000a6c
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [Verify_.dll+0x2931]
#
我正在使用 tomcat 8.5.28 和 jdk1.8。0_162
这是我的 java 代码:Verify_.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Verify_ extends HttpServlet{
public native int connect();
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.loadLibrary("Verify_");
Verify_ verify = new Verify_();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String ServerName = request.getParameter("servername");
String UserName = request.getParameter("username");
String Password = request.getParameter("password");
int status = verify.connect();
if(status == 0)
out.println("Connected to " + ServerName);
else if(status == 1)
out.println("failed to initialize CoInitializeEx");
else if(status == 2)
out.println("failed to initialize CoInitializeSecurity");
else if(status == 3)
out.println("failed to initialize CoCreateInstance");
else if(status == 4)
out.println("failed to connect to Server");
else
out.println(status);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request,response);
}}
这里是JNI接口代码:Verify_.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Verify_ */
#ifndef _Included_Verify_
#define _Included_Verify_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Verify_
* Method: connect
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Verify_1_connect
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
这是 C++ 代码:Verify_.cpp
#include <iostream>
#include <wbemidl.h>
#include <conio.h>
#include <windows.h>
#include <comdef.h>
#include <wincred.h>
#include <string.h>
#include "Verify_.h"
#pragma comment(lib, "credui.lib")
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Ole32.lib")
#define _WIN32_DCOM
JNIEXPORT jint JNICALL Java_Verify_1_connect (JNIEnv *, jobject){
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\172.21.111.250\ROOT\cimv2"));
wcscpy(pszUserName, BSTR(L"Administrator"));
wcscpy(pszPassword, BSTR(L"qwerty1233"));
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr)) {
return 1;
}
hr = CoInitializeSecurity(
NULL, // Security descriptor
-1, // COM negotiates authentication service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
NULL, // Authentication info
EOAC_NONE, // Additional capabilities of the client or server
NULL); // Reserved
if (FAILED(hr)) {
CoUninitialize();
return 2;
}
IWbemLocator *pLoc = 0;
hr = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hr)){
CoUninitialize();
return 3;
}
IWbemServices *pSvc = NULL;
// Connect to the root\default namespace with the current user.
hr = pLoc->ConnectServer(
pszRoot, //namespace
pszUserName, // User name
pszPassword, // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc); // IWbemServices proxy
if (FAILED(hr)){
pLoc->Release();
CoUninitialize();
return 4;
}
// pSvc->Release();
// pLoc->Release();
CoUninitialize();
return 0;
}
过去 5 天我一直在努力。请帮助我。如果有其他方法告诉我..
提前致谢
0xc0000005
-> 访问冲突,主要是因为使用了 NULL 指针。
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\172.21.111.250\ROOT\cimv2"));
使用wcscpy时必须分配内存。因此,使用无效(随机)地址调用 wcscopy(在调试模式下:使用 NULL)。
我不确定您是否正确处理了 BSTR(我不知道 BSTR)。见 BSTR 的定义:
typedef OLECHAR *BSTR;
为什么不直接赋值?
pszRoot = BSTR(L"\\172.21.111.250\ROOT\cimv2");
感谢拉尔夫·厄特
我改了这部分
BSTR pszRoot,pszUserName,pszPassword;
pszRoot = ::SysAllocString(L"\\172.21.111.250\ROOT\cimv2");
pszUserName = ::SysAllocString(L"Administrator");
pszPassword = ::SysAllocString(L"qwerty1233");