{"id":280,"date":"2011-09-16T20:57:44","date_gmt":"2011-09-16T18:57:44","guid":{"rendered":"http:\/\/dev.flauschig.ch\/wordpress\/?p=280"},"modified":"2011-09-16T20:57:44","modified_gmt":"2011-09-16T18:57:44","slug":"skype-home-closer-part-2","status":"publish","type":"post","link":"http:\/\/dev.flauschig.ch\/wordpress\/?p=280","title":{"rendered":"Skype Home Closer Part 2"},"content":{"rendered":"<p>I spent some more Time improving the App.<br \/>\nIt now injects a DLL which listens for the Window Activated Event and then closes it. It also listens for Skype Started Event and tries to close the Window and injects the DLL.<\/p>\n<p>Since DLLs which should be injected can&#8217;t be in Managed Code, I had to go back to my C++ knowledge.<\/p>\n<p>Here are the most important parts described:<\/p>\n<p><strong>The DLL<\/strong><br \/>\nWell, instead of writing too much I&#8217;ll just post the complete code for the DLL:<\/p>\n<pre class=\"brush: cpp; title: ; wrap-lines: false; notranslate\" title=\"\">\r\n#define WIN32_LEAN_AND_MEAN\r\n#include &lt;windows.h&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;stdio.h&gt;\r\n\r\nHINSTANCE dllInstance;\r\nHHOOK hookHandle;\r\n\r\n\/\/ Search for the Window and Close it\r\nvoid CloseWindow() {\r\n\tHWND hWnd = FindWindow(&quot;THomeForm&quot;, &quot;Skype Home&quot;);\r\n\tif (hWnd != NULL) {\r\n\t\tSendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);\r\n\t}\r\n}\r\n\r\n\/\/ Callback for the Timer\r\nVOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {\r\n\tCloseWindow();\r\n\tKillTimer(NULL, 1);\r\n}\r\n\r\n\/\/ Callback for the Hook\r\nLRESULT CALLBACK WindowHookProc(int code, WPARAM wParam, LPARAM lParam)\r\n{\r\n\tif (code &gt;= 0) {\r\n\t\tswitch(code) {\r\n\t\t\t\/\/case HCBT_ACTIVATE:\r\n\t\t\t\/\/case HCBT_CREATEWND:\r\n\t\t\t\/\/case HSHELL_WINDOWCREATED:\r\n\t\t\tcase HSHELL_WINDOWACTIVATED:\r\n\t\t\t\t\/\/ Get the Class and the Title\r\n\t\t\t\tTCHAR className&#x5B;255];\r\n\t\t\t\tTCHAR title&#x5B;255];\r\n\t\t\t\tmemset(className, 0, sizeof(className));\r\n\t\t\t\tmemset(title, 0, sizeof(title));\r\n\t\t\t\tHWND window = (HWND)wParam;\r\n\t\t\t\tint ret = GetClassName(window, className, sizeof(className));\r\n\t\t\t\tret = GetWindowText(window, title, sizeof(title));\r\n\t\t\t\t\/\/ Compare the Class and the Title\r\n\t\t\t\tif (strcmp(className, &quot;THomeForm&quot;) == 0 &amp;&amp; strcmp(title, &quot;Skype Home&quot;) == 0) {\r\n\t\t\t\t\t\/\/ Success, Create a Timer to close the Window\r\n\t\t\t\t\tint m_LoadTimesTimerID = SetTimer(NULL, 1, 1000, TimerProc);\r\n\t\t\t\t}\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\treturn CallNextHookEx(hookHandle, code, wParam, lParam);\r\n}\r\n\r\nextern &quot;C&quot; __declspec(dllexport) void InstallHook(int threadID) {\r\n\tint hookID = WH_CBT;\r\n\thookID = WH_SHELL;\r\n\tif (threadID &gt; 0) {\r\n\t\thookHandle = SetWindowsHookEx(hookID, WindowHookProc, dllInstance, threadID);\r\n\t} else {\r\n\t\thookHandle = SetWindowsHookEx(hookID, WindowHookProc, dllInstance, NULL);\r\n\t}\r\n}\r\n\r\nextern &quot;C&quot; __declspec(dllexport) void UninstallHook() {\r\n\tUnhookWindowsHookEx(hookHandle); \r\n}\r\n\r\nBOOL WINAPI DllMain(__in  HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {\r\n\tdllInstance = hinstDLL;\r\n\treturn TRUE;\r\n}\r\n<\/pre>\n<p><strong>Calling the unmanaged Code in the Managed C# App<\/strong><br \/>\nAs you see, there are two exported Functions in the DLL:<br \/>\nInstallHook and UninstallHook<br \/>\nTo be able to call them, there are some Win32 Stuff and some delegates needed:<\/p>\n<pre class=\"brush: csharp; title: ; wrap-lines: false; notranslate\" title=\"\">\r\n&#x5B;DllImport(&quot;kernel32.dll&quot;)]\r\npublic static extern IntPtr LoadLibrary(string dllToLoad);\r\n&#x5B;DllImport(&quot;kernel32.dll&quot;)]\r\npublic static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);\r\n&#x5B;DllImport(&quot;kernel32.dll&quot;)]\r\npublic static extern bool FreeLibrary(IntPtr hModule);\r\n\r\n&#x5B;UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r\npublic delegate void InstallHook(int threadID);\r\n&#x5B;UnmanagedFunctionPointer(CallingConvention.Cdecl)]\r\npublic delegate void UninstallHook();\r\n<\/pre>\n<p>Here&#8217;s the Code to call the InstallHook:<\/p>\n<pre class=\"brush: csharp; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic static void Install()\r\n{\r\n\tIntPtr pDll = LoadLibrary(@&quot;SkypeHomeCloserNativeHelper.dll&quot;);\r\n\tif (pDll == IntPtr.Zero)\r\n\t{\r\n\t\tMessageBox.Show(&quot;DLL not found&quot;);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tIntPtr procAddress = GetProcAddress(pDll, &quot;InstallHook&quot;);\r\n\t\tif (procAddress == IntPtr.Zero)\r\n\t\t{\r\n\t\t\tMessageBox.Show(&quot;Proc not found&quot;);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tInstallHook install = (InstallHook)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(InstallHook));\r\n\t\t\tProcess&#x5B;] procList = Process.GetProcessesByName(&quot;Skype&quot;);\r\n\t\t\tif (procList.Length &gt; 0)\r\n\t\t\t{\r\n\t\t\t\tint threadID = procList&#x5B;0].Threads&#x5B;0].Id;\r\n\t\t\t\tinstall(threadID);\r\n\t\t\t}\r\n\t\t\tbool result = FreeLibrary(pDll);\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>Here&#8217;s the Code to uninstall it:<\/p>\n<pre class=\"brush: csharp; title: ; wrap-lines: false; notranslate\" title=\"\">\r\npublic static void Remove()\r\n{\r\n\tIntPtr pDll = LoadLibrary(@&quot;SkypeHomeCloserNativeHelper.dll&quot;);\r\n\tif (pDll == IntPtr.Zero)\r\n\t{\r\n\t\tMessageBox.Show(&quot;DLL not found&quot;);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tIntPtr procAddress = GetProcAddress(pDll, &quot;UninstallHook&quot;);\r\n\t\tif (procAddress == IntPtr.Zero)\r\n\t\t{\r\n\t\t\tMessageBox.Show(&quot;Proc not found&quot;);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tUninstallHook uninstall = (UninstallHook)Marshal.GetDelegateForFunctionPointer(procAddress, typeof(UninstallHook));\r\n\t\t\tuninstall();\r\n\t\t\tbool result = FreeLibrary(pDll);\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>And here&#8217;s the compiled Tool:<br \/>\n<a href='http:\/\/dev.flauschig.ch\/wordpress\/wp-content\/uploads\/2011\/09\/SkypeHomeCloser_2.0.zip'>SkypeHomeCloser_2.0<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I spent some more Time improving the App. It now injects a DLL which listens for the Window Activated Event and then closes it. It also listens for Skype Started Event and tries to close the Window and injects the DLL. Since DLLs which should be injected can&#8217;t be in Managed Code, I had to &hellip; <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[4,3],"tags":[],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-roemer","4":"post-280","6":"format-standard","7":"category-csharp","8":"category-programming"},"acf":[],"views":1774,"_links":{"self":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/280"}],"collection":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=280"}],"version-history":[{"count":0,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/280\/revisions"}],"wp:attachment":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=280"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}