Linux中Wine QQ上线 转变成离线问题的解决(什么时候才能自己修改?)(qq2012出了 那个没有这个BUG)

Linux中Wine QQ问题的解决

    
     因为周围朋友同事都使用QQ,联络上离不开QQ。WebQQ的聊天记录和文件传送功能有限,LinuxQQ经常显示备注出错,并且文件传送功能也很有限,无奈选用非常占资源的wine QQ, 最重要的就win版QQ传送文件文件功能很好用,且可以远程协助他人。.

关于怎么在wine中安装QQ,网上教程很多,不过能搜索到的不少都有点老了,以前用Debian5.0/6.0的时候就是按网上教程并自己实践的。用wine1.2系列安装QQ是非常折腾的,需要安装很多支撑库,而且容易崩溃。在wine1.3版本后,就相对容易许多了。

以现在Ubuntu11.10为例,使用的是wine1.3.28版本,安装QQ2010的步骤:
1、sudo apt-get  install cups-bsd gnome-exe-thumbnailer wine1.3 ttf-droid ttf-liberation ttf-unfonts-core wine1.3-gecko winetricks

2、winetricks ie6 vcrun6 riched20

3、wine QQ2010.exe

(更新:如果需要安装QQ2011,则需要使用ppa上面的wine1.3.35版本之后的wine,但本人未测试过。)

QQ(2010)在wine里面的两个问题:

    1、“在线”状态时候很快自动切换到”离开“状态,不论“状态切换”的设置如何。
    2、使用gnome的“显示桌面”功能后,QQ主界面无法显示出来。

问题分析及解决:

    1、状态切换问题:

    根据状态切换原理,首先想到的是GetLastInputInfo这个函数,写了个测试程序,发现这个函数在wine里面运行是正常的。不过在gnome-terminal下启动wine /path_to_qq/qq.exe,发现重复如下信息:

fixme:crypt:SystemFunction041 (0x3d0b728, e78, 1): stub [RtlDecryptMemory]

fixme:crypt:SystemFunction040 (0x5558fc8, e78, 1): stub [RtlEncryptMemory]

fixme:winstation:OpenInputDesktop (0,0,400001cf): stub

    这个 OpenInputDesktop很可疑,google之发现其常用作检测当前桌面是否处于可输入状态,如果不能输入,通常是桌面被锁或者处理用户切换状态。在QQ的Bin目录下面翻箱倒柜的找了一遍,发现是Common.dll引用了这个函数。下面要有请逆向神器IDA出场~为了表示对IDA的景仰之情,要先沐浴更衣,并斋戒九日,1,2,...,9好,时辰到,启动IDA,打开common.dll,泡茶稍等,查找OpenInputDesktop,看到那个粉红色的OpenInputDesktop了吗?是的,是OpenInputDesktop(激动ing...),它在Util::WinScreenStatus::IsComputerLocked()这个函数里面,看这个函数名字就可以猜测出来它是判断系统是否处于锁屏的状态,返回值应该是int(甚至是bool型),从下图的IDA逆向代码来看,如果OpenInputDesktop失败,则函数提前结束,返回0。
    解决办法:

使得这个函数返回true就可以解决问题了。本人采用把OpenInputDesktop之后的那个jnz换成jmp的方法来完成的。使用IDA的HexView,找到jnz对应的机器代码75 xx,把随后的十来个数字一起,作为特征码;用WinHex打开common.dll,使用上面“特征码“定位,并把75改成EB(即jnz->jmp),并把common.dll的头部checksum值清空,保存文件。再次启qq,状态切换问题解决。(缺点是:在Linux真的处于锁屏状态时,QQ仍显示在线。



    2、主界面不显示问题:

在Debian下,Ctrl+Alt+d(显示桌面)后,双击托盘的qq图标,qq主界面不显示。本人解决办法是使用ShowWindow,代码如下:

  1. // showQQ.cpp : Defines the entry point for the application.  
  2. #include <windows.h>  
  3. BOOL CALLBACK EnumWndProc(HWND hWnd,LPARAM lParam)  
  4. {  
  5.     TCHAR winTitle[MAX_PATH] = {0};  
  6.     ::GetWindowText(hWnd, winTitle, sizeof(winTitle));  
  7.     if( 0 == strcmp(winTitle, "QQ International")  
  8.         || 0 == strcmp(winTitle, "QQ2011")  
  9.         || 0 == strcmp(winTitle, "QQ2010")  
  10.         // 请自行添加其它需要的QQ主窗口名  
  11.         )  
  12.     {  
  13.         ::SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);  
  14.         ::ShowWindow(hWnd, SW_SHOWNORMAL);  
  15.         ::SendMessage(hWnd, WM_SHOWWINDOW, 1, 0);  
  16.     }  
  17.     return TRUE;  
  18. }  
  19.   
  20. int APIENTRY WinMain(HINSTANCE hInstance,  
  21.                      HINSTANCE hPrevInstance,  
  22.                      LPSTR     lpCmdLine,  
  23.                      int       nCmdShow)  
  24. {  
  25.     ::EnumWindows(EnumWndProc, (LPARAM)0);  
  26.     return 0;  
  27. }  


用vc6编译后备用,当qq不出现的时候,用wine运行这个showQQ.exe程序就可以了。

结语:

qq是身边人用得比较多的联系工具,但腾讯对Linux用户照顾不周,使用非常艰难。希望有更好的开放协议的通讯工具,让大家有更多的选择。


附:

测试 GetLastInputInfo代码

  1. #define _WIN32_WINNT 0x500  
  2. #include <windows.h>  
  3. #include <winuser.h>      
  4. #include "stdio.h"  
  5. #include "time.h"  
  6.   
  7. int main(int argc, char* argv[])  
  8. {  
  9.     LASTINPUTINFO info;  
  10.     info.cbSize = sizeof(info);  
  11.     while(1) {  
  12.         if(GetLastInputInfo(&info)) {  
  13.             printf ( "%ud\n", info.dwTime);  
  14.         }  
  15.         else {  
  16.             printf("get last input info fail.\n");  
  17.         }  
  18.         Sleep(1000);  
  19.     }  
  20.     return 0;  
  21. }     

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值