代码之家  ›  专栏  ›  技术社区  ›  Eddy

JNI-WMI连接错误

  •  -2
  • Eddy  · 技术社区  · 7 年前

    我有一个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\u 162

    下面是我的java代码:Verify\uu0。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\uu0。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\uu0。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天了。请帮帮我。如果还有别的办法,告诉我。。

    提前感谢

    2 回复  |  直到 7 年前
        1
  •  0
  •   Ralph Erdt    7 年前
    0xc0000005
    

    -&燃气轮机;访问冲突,主要是因为使用空指针。

    BSTR pszRoot,pszUserName,pszPassword;
    wcscpy(pszRoot, BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2"));
    

    使用wcscpy时,必须分配内存。因此,使用无效(随机)地址调用wcoscopy(在Debugmode中:NULL)。

    我不确定您是否正确处理BSTR(我不知道BSTR)。见BSTR的定义:

    typedef OLECHAR *BSTR;
    

    为什么不直接分配?

    pszRoot = BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2");
    
        2
  •  0
  •   Eddy    7 年前

    谢谢Ralph Erdt

    我改变了这个部分

    BSTR pszRoot,pszUserName,pszPassword;
    pszRoot = ::SysAllocString(L"\\\\172.21.111.250\\ROOT\\cimv2");
    pszUserName = ::SysAllocString(L"Administrator");
    pszPassword = ::SysAllocString(L"qwerty1233");