debugging - why my app doesn't run under Wine

Questions about Wine on Linux
Locked
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

debugging - why my app doesn't run under Wine

Post by pnswdv »

I am running Linux Mint with Wine installed, and am testing a suite of Windows applications which I wrote & have control over, and am trying to determine why one of them doesn't run under Wine and see if there are any modifications I can make to it to make it work. The symptoms are a follows:

My application is a server/router written in C++/MFC which implements a proprietary protocol on top of TCP/IP. When I first tried running it, I received a WMI error, so I used Winetricks to install WMI. The WMI installation reported success, I rebooted my machine and attempted running it again. This time there is no error message, but I just get a spinning cursor for about 10 seconds and then the cursor returns to the pointer. Checking a logfile that my app creates indicates that it merely exits without ever performing it's initialization.

I am quite unfamiliar with linux so I do not know where to look for hints as to what may be going wrong. Several of my other applications run fine, so Wine seems to be working properly on my machine. Suggestions, please!
lahmbi5678
Level 7
Level 7
Posts: 823
Joined: Thu Aug 27, 2009 6:23 am

Post by lahmbi5678 »

Hi,

if your app needs access to TCP/IP ports < 1024 and you are running as regular user (running wine as root is not recommended), you will need to do something like described in http://unix.stackexchange.com/questions ... below-1024

The simpler alternative would be to choose ports above 1024, if you can.

Furthermore you might need to do "winetricks vcrun6", as wine doesn't implement mfc.

If it still doesn't work, upgrade to latest wine version, run from command line and post terminal output.
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

thanks, but still no success

Post by pnswdv »

Thanks for your suggestions! However, I have already loaded the MFC package you suggested, and I do not use ports below 1024.

I attempted to run from the command line and received the following information:

fixme:ole:CoInitializeSecurity ((nil),-1,(nil),(nil),0,3,(nil),0,(nil)) - stub!
err:ole:ProxyCliSec_SetBlanket (0x138b64,10,0,(null),3,3,(nil),0x0): stub
err:ole:CoSetProxyBlanket -- failed with 0x800004001
Could not set proxy blanket. Error code = 0x800004001

So that looks like a pretty good clue, if only I understood it! I went to winetricks to see if I could find anything related to OLE but didn't.
User avatar
DanKegel
Moderator
Moderator
Posts: 1164
Joined: Wed May 14, 2008 11:44 am

Post by DanKegel »

What version of Wine are you using? (What does wine --version output?)

What WMI functions do you call?

Can you look from your app's side (possibly using a debugger)
to see what's failing?
Alternately, a +relay,+seh log might be illuminating.

What app is this, and is a demo version downloadable somewhere?
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

Post by pnswdv »

Wine version is 1.4

I am a linux novice so I don't know how to create the "+relay,+seh" log you refer to. I tried including them as command line arguments to Wine but that didn't work.

The application can be downloaded from http://xxtinc.com/software-downloads.html The download you would want is the first one (xxMWD-PCSuite V02.10 Setup.zip) This will install a number of applications, but the one in question is the "xxNETserver" application. This is all special-purpose code to support our company's hardware products, and when you install it, it will ask you several questions that will likely make you say "huh?". You can just accept the default values for everything, but when you get to the one asking if you are going to use an RS232 port to connect to our hardware you should just say no. It might be simpler for you if I were to just send you the EXE in question.

In the meantime, following is the source for the code which contains the failing call to "CoSetProxyBlanket". Thanks for your help!

Code: Select all

BOOL CxxNETserverApp::InitializeWMI()
{
   HRESULT hres;
	CString strError;

    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------

    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))
    {
		strError.Format("Failed to initialize COM library. Error code = %X",hres);
		OutputDebugString (strError+"\n");
		g_EventFile.WriteEventFile(strError);
		AfxMessageBox (strError,MB_OK);
        return FALSE;                  // Program has failed.
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------
    // Note: If you are using Windows 2000, you need to specify -
    // the default authentication credentials for a user by using
    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
    // parameter of CoInitializeSecurity ------------------------

    hres =  CoInitializeSecurity(
        NULL, 
        -1,                          // COM negotiates service
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
        );

                      
    if (FAILED(hres))
    {
		strError.Format("Failed to initialize COM security. Error code = %X",hres);
		OutputDebugString (strError+"\n");
		g_EventFile.WriteEventFile(strError);
		AfxMessageBox (strError,MB_OK);
        CoUninitialize();
        return FALSE;                      // Program has failed.
    }
    
    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    m_pLoc = NULL;

    hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &m_pLoc);
 
    if (FAILED(hres))
    {
		strError.Format("Failed to create IWbemLocator object. Error code = %X",hres);
		OutputDebugString (strError+"\n");
		g_EventFile.WriteEventFile(strError);
		AfxMessageBox (strError,MB_OK);
        CoUninitialize();
        return FALSE;                 // Program has failed.
    }

    // Step 4: ---------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    m_pSvc = NULL;

   hres = m_pLoc->ConnectServer(
        _bstr_t(L"ROOT\\WMI"), 
        NULL,
        NULL, 
        0, 
        NULL, 
        0, 
        0, 
        &m_pSvc
    );
	    
    if (FAILED(hres))
    {
		strError.Format("Could not connect to ROOT\\WMI namespace. Error code = %X",hres);
		OutputDebugString (strError+"\n");
		g_EventFile.WriteEventFile(strError);
		AfxMessageBox (strError,MB_OK);
        m_pLoc->Release();     
        CoUninitialize();
        return FALSE;                // Program has failed.
    }

    cout << "Connected to ROOT\\WMI namespace" << endl;


    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
        m_pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx 
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx 
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
    );

    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x" 
             << hex << hres << endl;
        m_pSvc->Release();
        m_pLoc->Release();     
        CoUninitialize();
        return FALSE;               // Program has failed.
    }

    // Step 6: -------------------------------------------------
    // Receive event notifications -----------------------------

    // Use an unsecured apartment for security
    m_pUnsecApp = NULL;

    hres = CoCreateInstance(CLSID_UnsecuredApartment, NULL, 
        CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, 
        (void**)&m_pUnsecApp);
 
    m_pSink = new EventSink;
    m_pSink->AddRef();
	m_pSink->m_pProcessingThread = this;

    m_pStubUnk = NULL; 
    m_pUnsecApp->CreateObjectStub(m_pSink, &m_pStubUnk);

    m_pStubSink = NULL;
    m_pStubUnk->QueryInterface(IID_IWbemObjectSink,
        (void **) &m_pStubSink);

    // The ExecNotificationQueryAsync method will call
    // The EventQuery::Indicate method when an event occurs

	// the queries are taken from MS sample code

    hres = m_pSvc->ExecNotificationQueryAsync(
        _bstr_t("WQL"), 
         _bstr_t("SELECT * FROM MSNdis_StatusMediaDisconnect"), 
        WBEM_FLAG_SEND_STATUS, 
        NULL, 
        m_pStubSink);

	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_StatusMediaConnect"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

 	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_NotifyAdapterRemoval"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_NotifyAdapterArrival"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

 	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_StatusResetStart"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_StatusResetEnd"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_NotifyVcArrival"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_StatusLinkSpeedChange"), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

	// added 26 Sept 2011
	if (SUCCEEDED(hres))
	{
		hres = m_pSvc->ExecNotificationQueryAsync(
			_bstr_t("WQL"), 
			 _bstr_t("SELECT * FROM MSNdis_StatusProtocolBind "), 
			WBEM_FLAG_SEND_STATUS, 
			NULL, 
			m_pStubSink);
	}

  // Check for errors.
    if (FAILED(hres))
    {
		strError.Format("ExecNotificationQueryAsync failed. Error code = %X",hres);
		OutputDebugString (strError+"\n");
		g_EventFile.WriteEventFile(strError);
		AfxMessageBox (strError,MB_OK);
        m_pSvc->Release();
        m_pLoc->Release();
        m_pUnsecApp->Release();
        m_pStubUnk->Release();
        m_pSink->Release();
        m_pStubSink->Release();
        CoUninitialize();    
        return FALSE;
    }

    return TRUE;
}
User avatar
DanKegel
Moderator
Moderator
Posts: 1164
Joined: Wed May 14, 2008 11:44 am

Post by DanKegel »

Thanks for the info.

See
http://wiki.winehq.org/FAQ#get_log
and the one right below it
http://wiki.winehq.org/FAQ#head-16da35b ... 16862d0f5e
for how to get the log.
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

Post by pnswdv »

I created the log file you requested and zipped it up. However, I don't see a way to attach it to this message. Am I supposed to be creating some sort of bug report somewhere else for this issue?

Thanks!
John Drescher

debugging - why my app doesn't run under Wine

Post by John Drescher »

On Mon, Jun 4, 2012 at 10:15 AM, pnswdv <[email protected]> wrote:
I created the log file you requested and zipped it up.  However, I don't see a way to attach it to this message.  Am I supposed to be creating some sort of bug report somewhere else for this issue?
Put it on pastebin.com and link here.

John
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

Post by pnswdv »

Log file is too large for pastebin. The zip file is a reasonable size but I don't appear to be able to put a zip on pastebin.
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

Post by pnswdv »

Posted the log file on a web server at http://tinyurl.com/6ochbkk
User avatar
DanKegel
Moderator
Moderator
Posts: 1164
Joined: Wed May 14, 2008 11:44 am

Post by DanKegel »

The key bit of that log is

003b:Call ole32.CoSetProxyBlanket(00149b34,0000000a,00000000,00000000,00000003,00000003,00000000,00000000) ret=0043da13
003b:Call rpcrt4.IUnknown_QueryInterface_Proxy(00149b34,687ee7d8,0032fc5c) ret=687375a2
003b:Ret rpcrt4.IUnknown_QueryInterface_Proxy() retval=00000000 ret=687375a2
fixme:ole:ProxyCliSec_SetBlanket (0x149b34, 10, 0, (null), 3, 3, (nil), 0x0): stub
err:ole:CoSetProxyBlanket -- failed with 0x80004001
003b:Ret ole32.CoSetProxyBlanket() retval=80004001 ret=0043da13

SetBlanket is a stub that always returns failure:
http://source.winehq.org/source/dlls/ol ... hal.c#L579

You might hack the stub to pretend to succeed, and see if your app
gets further.
pnswdv
Level 1
Level 1
Posts: 7
Joined: Fri Jun 01, 2012 4:42 pm

Post by pnswdv »

Thanks for the info! I will try modifying my source to ignore the error return from CoSetProxyBlanket() and see what happens...
Locked