﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-桂湖山BLOG-随笔分类-windows OS</title><link>http://www.cnitblog.com/yggl1889/category/5789.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 15:03:37 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 15:03:37 GMT</pubDate><ttl>60</ttl><item><title>阻断弹出式广告的BHO 的学习</title><link>http://www.cnitblog.com/yggl1889/archive/2011/09/07/75378.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Wed, 07 Sep 2011 10:09:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2011/09/07/75378.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/75378.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2011/09/07/75378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/75378.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/75378.html</trackback:ping><description><![CDATA[<div><p><strong></strong></p><div><strong>注明<a href="http://delphi.sharpplus.com/">转自Delphi深度探索</a></strong></div><strong><br /></strong><p>&nbsp;</p><p><strong>介绍</strong></p>               <p style="text-indent:21.0pt">随着网络免费的大潮的 退去，网站变得越来越商业化。浏览一些常去的网站，每看一个页面都会弹出N多的广告窗口，而且都是花花绿绿的Flash和Gif小动画,浪费带宽（我在家 还是拨号上网），同时干扰了正常的阅读，非常讨厌。那么如何才能将这些广告屏蔽掉呢？答案就是Browser Helper  Object(简称BHO)。</p>               <p style="text-indent:21.0pt">BHO实际上也是一个简单的IE扩展COM组件，它和其它COM组件的区别就在于其它扩展需要一些用户的手工操作，如点击菜单，点击工具条按钮，在地址栏输入               网址等等触发动作才会被IE加载。而BHO则不同，每当IE启动时，都会自动去加载BHO而无须任何触发条件，另外BHO还可以监听IE的各类事件的通知消息，比如窗               口大小的变化，下载是否完成等事件。</p>               <p style="text-indent:21.0pt">由于BHO可以在一启动IE就被加载，并能监听各种事件，我们就可以使用BHO扩展实现限制用户浏览某些色情网站，或者搜集用户浏览喜好信息等功能。接下来，               我们就来实现一个能够阻断广告弹出的BHO扩展。</p>               <p style="text-align:left;text-autospace:none" align="left"><strong>创建</strong><strong>COM</strong><strong>组件</strong></p>               <p style="text-align:left;text-autospace:none" align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新建一个ActiveX Library，保存为IEBHO.dpr，然后新建一个名为TIEAdvBHO的COM Object，然后保存生成的文件为CIEBHO.pas，作为BHO扩展，需要实现两                 个接口IObjectWithSite和IDispatch，其中               IObjectWithSite接口同前面的工具条扩展一样可以用来获得浏览器的接口，而IDispatch接口，则被用来监听浏览器的事件。下面就是BHO扩展的类定义：</p>               <pre><code><strong>type</strong></code></pre>               <pre><code><strong>&nbsp; </strong>TTIEAdvBHO = <strong>class</strong>(TComObject, IObjectWithSite, IDispatch)</code></pre>               <pre><code>&nbsp; <strong>private</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>FIESite: IUnknown;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; FIE: IWebBrowser2;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; FCPC: IConnectionPointContainer;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; FCP: IConnectionPoint;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; FCookie: Integer;</code></pre>               <pre><code>&nbsp; <strong>protected</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong><em>//IObjectWithSite接口方法定义</em></code></pre>               <pre><code><em>&nbsp;&nbsp;&nbsp; </em><strong>function </strong>SetSite(<strong>const </strong>pUnkSite: IUnknown): HResult; <strong>stdcall</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>function </strong>GetSite(<strong>const </strong>riid: TIID; <strong>out </strong>site: IUnknown): HResult; <strong>stdcall</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <em>//IDispatch</em><em>接口方法定义</em></code></pre>               <pre><code><em>&nbsp;&nbsp;&nbsp; </em><strong>function </strong>GetTypeInfoCount(<strong>out </strong>Count: Integer): HResult; <strong>stdcall</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>function </strong>GetTypeInfo(Index, LocaleID: Integer; <strong>out </strong>TypeInfo): HResult;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>stdcall</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>function </strong>GetIDsOfNames(<strong>const </strong>IID: TGUID; Names: Pointer;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; <strong>stdcall</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>function </strong>Invoke(<strong>DispID</strong>: Integer; <strong>const </strong>IID: TGUID; LocaleID: Integer;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Flags: Word; <strong>var </strong>Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<strong>stdcall</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <em>//</em><em>阻断广告弹出事件处理过程</em></code></pre>               <pre style="text-indent:19.8pt"><code><strong>procedure </strong>DoNewWindow2(<strong>var </strong>ppDisp: IDispatch; <strong>var </strong>Cancel: WordBool);</code></pre>               <pre style="margin-left:40.0pt;text-indent:-40.0pt"><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>DoBeforeNavigate2(<strong>const </strong>pDisp: IDispatch; <strong>var </strong>URL: OleVariant; <strong>var </strong>Flags: OleVariant; <strong>var </strong>TargetFrameName: OleVariant; <br /><strong>var </strong>PostData: OleVariant;<strong>var </strong>Headers: OleVariant; <strong>var </strong>Cancel: WordBool);</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left">&nbsp;</p>               <p style="text-align:left;text-autospace:none" align="left"><strong>IObjectWithSite</strong><strong>的接口的实现</strong></p>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong></p>               <p style="text-align:left;text-autospace:none" align="left">先 看IObjectWithSite的接口的实现，当IE加载BHO扩展后，会调用BHO的扩展，把自身的IUnknown接口作为参数pUnkSite传 给扩展，BHO扩展应该从pUnkSite参数中获得浏览器接口IWebBrowser2,同时为了监听浏览器的事件，还需要获得事件链接点接口，IE的 支持的事件都定义在DWebBrowserEvents2的双接口中，使用链接点的Advise方法建立对IE事件的监听，注意Advise方法调用后               会返回一个Cookie，需要保存Cookie，后面在退出IE时，需要Cookie作为参数来断开对IE事件的监听。</p>               <pre><code><strong>function </strong>TTIEAdvBHO.SetSite(<strong>const </strong>pUnkSite: IInterface): HResult;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; </strong>Result := E_FAIL;</code></pre>               <pre><code>&nbsp; <em>//</em><em>保存接口</em></code></pre>               <pre><code><em>&nbsp; </em>FIESite := pUnkSite;</code></pre>               <pre><code>&nbsp; <strong>if not </strong>Supports(FIESite, IWebBrowser2, FIE) <strong>then</strong></code></pre>               <pre style="text-indent: 20.4pt"><code>Exit;</code></pre>               <pre><code>&nbsp; //获得事件连接点</code></pre>               <pre><code>&nbsp; <strong>if not </strong>Supports(FIE, IConnectionPointContainer, FCPC) <strong>then</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>Exit;</code></pre>               <pre><code><em>&nbsp; </em>FCPC.FindConnectionPoint(DWebBrowserEvents2, FCP);</code></pre>               <pre><code>&nbsp; <em>//</em><em>监听事件</em></code></pre>               <pre><code>&nbsp; FCP.Advise(Self, FCookie);</code></pre>               <pre><code>&nbsp; Result := S_OK;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left">后面IE有时会调用IObjectWithSite接口的GetSite方法获得需要的接口，这时可以将保存的接口返回。</p>               <pre><code><strong>function </strong>TTIEAdvBHO.GetSite(<strong>const </strong>riid: TIID;</code></pre>               <pre><code>&nbsp; <strong>out </strong>site: IInterface): HResult;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; if </strong>Supports(FIESite, riid,site) <strong>then</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>Result := S_OK</code></pre>               <pre><code>&nbsp; <strong>else</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>Result:= E_NOINTERFACE;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left">&nbsp;</p>               <p style="text-align:left;text-autospace:none" align="left"><strong>IDispatch</strong><strong>接口的实现</strong></p>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong></p>               <p style="text-align:left;text-autospace:none" align="left">前 面我们在SetSite中建立了对IE事件的监听，建立事件监听后每当IE产生了新的事件，它就会调用扩展的IDispatch接口的Invoke方法通 知扩展发生的事件类型以及事件参数，并请求扩展对事件进行处理。因此对于BHO扩展来说，IDispatch接口的Invoke方法是必须实现的，而其它 的GetTypeInfoCount，GetTypeInfo和GetIDsOfNames方法都无须实现，只要返回结果为E_NOTIMPL，表示未实 现该方法就可以了。</p>               <p style="text-align:left;text-autospace:none" align="left">&nbsp;</p>               <pre><code><strong>function </strong>TTIEAdvBHO.GetIDsOfNames(<strong>const </strong>IID: TGUID; Names: Pointer;</code></pre>               <pre><code>&nbsp; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; </strong>Result := E_NOTIMPL;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <pre><code>&nbsp;</code></pre>               <pre><code><strong>function </strong>TTIEAdvBHO.GetTypeInfo(Index, LocaleID: Integer;</code></pre>               <pre><code>&nbsp; <strong>out </strong>TypeInfo): HResult;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; </strong>Result := E_NOTIMPL;</code></pre>               <pre><code>&nbsp; pointer(TypeInfo) := <strong>nil</strong>;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <pre><code>&nbsp;</code></pre>               <pre><code><strong>function </strong>TTIEAdvBHO.GetTypeInfoCount(<strong>out </strong>Count: Integer): HResult;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; </strong>Result := E_NOTIMPL;</code></pre>               <pre><code>&nbsp; Count := 0;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left">&nbsp;</p>               <p style="text-align:left;text-autospace:none" align="left"><strong>事件的监听</strong></p>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong></p>               <p style="text-align:left;text-autospace:none" align="left">IE支持的事件都定义在DWebEvents2接口中，如下：</p>               <pre><code>&nbsp; DWebBrowserEvents2 = <strong>dispinterface</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>[<em>'{34A715A0-6587-11D0-924A-0020AFC7AC4D}'</em>]</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>StatusTextChange(<strong>const </strong>Text: WideString); <strong>dispid </strong>102;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>ProgressChange(Progress: Integer; ProgressMax: Integer); <strong>dispid </strong>108;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>CommandStateChange(Command: Integer; Enable: WordBool); <strong>dispid </strong>105;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>DownloadBegin; <strong>dispid </strong>106;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>DownloadComplete; <strong>dispid </strong>104;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>TitleChange(<strong>const </strong>Text: WideString); <strong>dispid </strong>113;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>PropertyChange(<strong>const </strong>szProperty: WideString); <strong>dispid </strong>112;</code></pre>               <pre style="text-indent:19.8pt"><code><strong>procedure </strong>BeforeNavigate2(<strong>const </strong>pDisp: IDispatch; <strong>var </strong>URL: OleVariant; <strong>var </strong>Flags:</code></pre>               <pre style="text-indent:69.8pt"><code> OleVariant; <strong>var </strong>TargetFrameName: OleVariant; <strong>var </strong>PostData: OleVariant;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </code></pre>               <pre style="text-indent:79.2pt"><code><strong>var </strong>Headers: OleVariant; <strong>var </strong>Cancel: WordBool); <strong>dispid </strong>250;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>NewWindow2(<strong>var </strong>ppDisp: IDispatch; <strong>var </strong>Cancel: WordBool); <strong>dispid </strong>251;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>NavigateComplete2(<strong>const </strong>pDisp: IDispatch; <strong>var </strong>URL: OleVariant); <strong>dispid </strong>252;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>DocumentComplete(<strong>const </strong>pDisp: IDispatch; <strong>var </strong>URL: OleVariant); <strong>dispid </strong>259;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnQuit; <strong>dispid </strong>253;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnVisible(Visible: WordBool); <strong>dispid </strong>254;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnToolBar(ToolBar: WordBool); <strong>dispid </strong>255;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnMenuBar(MenuBar: WordBool); <strong>dispid </strong>256;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnStatusBar(StatusBar: WordBool); <strong>dispid </strong>257;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnFullScreen(FullScreen: WordBool); <strong>dispid </strong>258;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>procedure </strong>OnTheaterMode(TheaterMode: WordBool); <strong>dispid </strong>260;</code></pre>               <pre><code>&nbsp; <strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong></p>               <pre>可以看到每个事件中的后面都有一个dispid关键加上数字如 258 ,260等等。Dispid的数字就是事件类型的标识符号。<br />IDispatch的Invoke方法定义如下：</pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>function </strong>Invoke(<strong>DispID</strong>: Integer; <strong>const </strong>IID: TGUID; LocaleID: Integer;</code></pre>               <p style="text-align:left;text-indent:30.0pt; text-autospace:none" align="left"><code>Flags: Word; <strong>var </strong>Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult;</code></p>               <p style="text-align:left;text-autospace:none" align="left"><code>当</code><code>IE</code><code>调用</code><code>Invoke</code><code>方法时，会设定</code><code>DispId</code><code>参数为事件的标识符号，这样我们就可以知道</code><code>IE</code><code>发生了什么事件。对于要实现               的阻断广告窗口弹出来说，我们只需关心</code><code>BeforeNavigate2</code><code>和</code><code>OnQuit</code><code>事件就可以了，因为当广告窗口弹出前，会激发               </code><code>IE</code><code>的</code><code>BeforeNavigate2</code><code>事件，而弹出式窗口一般没有工具条，所以只要</code><code>BeforeNavigate2</code><code>事件中判断当前页面是否有               工具条就可以判断是否是弹出窗口，并予以禁止。而当</code><code>IE</code><code>退出时，会激发</code><code>OnQuit</code><code>事件，在</code><code>OnQuit</code><code>事件中应该断开事件              监听，同时清理分配的资源。下面就是截获</code><code>BeforeNavigate2</code><code>和</code><code>OnQuit</code><code>事件的</code><code>Invoke</code><code>方法的实现</code><code>:</code></p>               <pre><code><strong>procedure </strong>BuildPositionalDispIds(pDispIds: PDispIdList; <strong>const </strong>dps: TDispParams);</code></pre>               <pre><code><strong>var</strong></code></pre>               <pre><code><strong>&nbsp; </strong>i: integer;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; </strong>Assert(pDispIds &lt;&gt; <strong>nil</strong>);</code></pre>               <pre><code>&nbsp; <strong>for </strong>i := 0 <strong>to </strong>dps.cArgs - 1 <strong>do</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>pDispIds^[i] := dps.cArgs - 1 - i;</code></pre>               <pre><code>&nbsp; <strong>if </strong>(dps.cNamedArgs &lt;= 0) <strong>then</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>Exit;</code></pre>               <pre><code>&nbsp; <strong>for </strong>i := 0 <strong>to </strong>dps.cNamedArgs - 1 <strong>do</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>pDispIds^[dps.rgdispidNamedArgs^[i]] := i;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left"><code>&nbsp;</code></p>               <pre><code><strong>function </strong>TTIEAdvBHO.Invoke(<strong>DispID</strong>: Integer; <strong>const </strong>IID: TGUID;</code></pre>               <pre><code>&nbsp; LocaleID: Integer; Flags: Word; <strong>var </strong>Params; VarResult, ExcepInfo,</code></pre>               <pre><code>&nbsp; ArgErr: Pointer): HResult;</code></pre>               <pre><code><strong>var</strong></code></pre>               <pre><code><strong>&nbsp; </strong>dps: TDispParams <strong>absolute </strong>Params;</code></pre>               <pre><code>&nbsp; bHasParams: boolean;</code></pre>               <pre><code>&nbsp; pDispIds: PDispIdList;</code></pre>               <pre><code>&nbsp; iDispIdsSize: integer;</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; </strong>pDispIds := <strong>nil</strong>;</code></pre>               <pre><code>&nbsp; iDispIdsSize := 0;</code></pre>               <pre><code>&nbsp; bHasParams := (dps.cArgs &gt; 0);</code></pre>               <pre><code>&nbsp; <strong>if </strong>(bHasParams) <strong>then</strong></code></pre>               <pre><code><strong>&nbsp; begin</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>iDispIdsSize := dps.cArgs * SizeOf(TDispId);</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; GetMem(pDispIds, iDispIdsSize);</code></pre>               <pre><code>&nbsp; <strong>end</strong>;</code></pre>               <pre><code>&nbsp; <strong>try</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; if </strong>(bHasParams) <strong>then</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>BuildPositionalDispIds(pDispIds, dps);</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; Result := S_OK;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>case DispId of</strong></code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 250:<em>//BeforeNaviage2</em><em>事件id</em></code></pre>               <pre><code><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </em><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>DoBeforeNavigate2(IDispatch(dps.rgvarg^[pDispIds^[0]].dispval),</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;POleVariant(dps.rgvarg^[pDispIds^[1]].pvarval)^,</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; POleVariant(dps.rgvarg^[pDispIds^[2]].pvarval)^,</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; POleVariant(dps.rgvarg^[pDispIds^[3]].pvarval)^,</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; POleVariant(dps.rgvarg^[pDispIds^[4]].pvarval)^,</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; POleVariant(dps.rgvarg^[pDispIds^[5]].pvarval)^,</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dps.rgvarg^[pDispIds^[6]].pbool^);</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>end</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 253:<em>//OnQuit</em><em>事件ID</em></code></pre>               <pre><code><em>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </em><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>FCP.Unadvise(FCookie);</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>end</strong>;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>else</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>Result := DISP_E_MEMBERNOTFOUND;</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <strong>end</strong>;</code></pre>               <pre><code>&nbsp; <strong>finally</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; if </strong>(bHasParams) <strong>then</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </strong>FreeMem(pDispIds, iDispIdsSize);</code></pre>               <pre><code>&nbsp; <strong>end</strong>;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left"><code>&nbsp;</code></p>               <p style="text-align:left;text-autospace:none" align="left">在Invoke方法中，<code>Params</code><code>参数包含了被激发的事件包含的参数的数目以及参数的值，而</code><code>BuildPositionalDispIds</code><code>              则从</code><code>Params</code><code>参数中提取参数值，并放到数组中，然后在</code><code>BeforeNavigate2</code><code>事件中，调用</code><code>Do</code><code>BeforeNavigate2</code><code>过程对               事件进行处理，事件参数作为过程参数被传递过去，下面是具体禁止弹出网页的</code><code>Do</code><code>BeforeNavigate2</code><code>的处理过程：</code></p>               <pre><code><strong>procedure </strong>TTIEAdvBHO.DoBeforeNavigate2(<strong>const </strong>pDisp: IDispatch; <strong>var </strong>URL,</code></pre>               <pre><code>&nbsp; Flags, TargetFrameName, PostData, Headers: OleVariant;</code></pre>               <pre><code>&nbsp; <strong>var </strong>Cancel: WordBool);</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; if </strong>FIE.ToolBar=0 <strong>then </strong>FIE.Quit;</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong></p>               <p style="text-align:left;text-autospace:none" align="left">在过程中，首先，调用IWebBrowser2接口的Toolbar属性判断页面是否有工具条，如果没有，则调用IE的退出方法关闭弹出窗口。另外在Invoke中还在OnQuit事件激发时，调用事件连接点的UnAdvise方法，断开事件监听。</p>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong><strong>注册扩展</strong></p>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong><code>注册扩展非常简单，只要在注册表中关键字</code><code>HKEY_LOCAL_MACHINE</code><code>\</code><code>Software\Microsoft\Windows\CurrentVersion<br />               \explorer\Browser Helper Objects\</code><code>下添加值为扩展的</code><code>Guid</code><code>的字符串形式的下级关键字就可以了。</code></p>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong><code><strong>type</strong></code></p>                              <pre><code><strong>&nbsp; </strong>TIEAdvBHOFactory = <strong>class</strong>(TComObjectFactory)</code></pre>               <pre><code>&nbsp; <strong>public</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; procedure </strong>UpdateRegistry(<strong>Register</strong>: Boolean); <strong>override</strong>;</code></pre>               <pre><code>&nbsp; <strong>end</strong>;</code></pre>               <pre><code>&nbsp;</code></pre>               <pre><code><em>{ TIEAdvBHOFactory }</em></code></pre>               <pre><code><em>&nbsp;</em></code></pre>               <pre><code><strong>procedure </strong>TIEAdvBHOFactory.UpdateRegistry(<strong>Register</strong>: Boolean);</code></pre>               <pre><code><strong>begin</strong></code></pre>               <pre><code><strong>&nbsp; inherited</strong>;</code></pre>               <pre><code>&nbsp; <strong>if Register then</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>CreateRegKeyValue(HKEY_LOCAL_MACHINE, <em>'Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\' <br />                      </em>+ GuidToString(ClassID), <em>''</em>, <em>''</em>)</code></pre>               <pre><code>&nbsp; <strong>else</strong></code></pre>               <pre><code><strong>&nbsp;&nbsp;&nbsp; </strong>DeleteRegKeyValue(HKEY_LOCAL_MACHINE, <em>'Software\Microsoft\Windows\CurrentVersion\explorer\Browser Helper Objects\' <br />                      </em>+ GuidToString(ClassID), <em>''</em>);</code></pre>               <pre><code><strong>end</strong>;</code></pre>               <pre><code>&nbsp;</code></pre>               <pre><code><strong>initialization</strong></code></pre>               <pre><code><strong>&nbsp; </strong>TIEAdvBHOFactory.Create(ComServer, TTIEAdvBHO, Class_TIEAdvBHO,</code></pre>               <pre><code>&nbsp;&nbsp;&nbsp; <em>'TIEAdvBHO'</em>, <em>''</em>, ciMultiInstance, tmApartment);</code></pre>               <pre><code><strong>end</strong>.</code></pre>               <p style="text-align:left;text-autospace:none" align="left"><strong>&nbsp;</strong></p>               <p style="text-align:left;text-autospace:none" align="left">注册扩展后，打开浏览器浏览新浪网站(http://www.sina.com.cn)，你会发现平时讨厌的弹出广告窗口都消失了。</p></div><img src ="http://www.cnitblog.com/yggl1889/aggbug/75378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2011-09-07 18:09 <a href="http://www.cnitblog.com/yggl1889/archive/2011/09/07/75378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>获得windowxp desktop hwnd</title><link>http://www.cnitblog.com/yggl1889/archive/2011/01/21/72698.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Fri, 21 Jan 2011 08:54:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2011/01/21/72698.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/72698.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2011/01/21/72698.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/72698.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/72698.html</trackback:ping><description><![CDATA[确切地讲，Desktop&nbsp;&nbsp; Window包含一个无标题的、类名为&#8220;SHELLDLL_DefView&#8221;的子窗口，这个字窗口又包含一个无标题的、类名为&#8220;SysListView32&#8221;的子窗口——这才是那个真正包含桌面图标的窗口。<img src ="http://www.cnitblog.com/yggl1889/aggbug/72698.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2011-01-21 16:54 <a href="http://www.cnitblog.com/yggl1889/archive/2011/01/21/72698.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CAsyncSocket，CSocket内幕及其用法</title><link>http://www.cnitblog.com/yggl1889/archive/2008/07/19/46929.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Sat, 19 Jul 2008 09:35:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2008/07/19/46929.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/46929.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2008/07/19/46929.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/46929.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/46929.html</trackback:ping><description><![CDATA[<h2 class="diaryTitle">CAsyncSocket，CSocket内幕及其用法 </h2>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<table border="0" cellpadding="0" cellspacing="3" width="600">
    <tbody>
        <tr>
            <td width="600">〖文章转载或出处〗&#8801;中国电子技术信息网&#8801; 网址：www.CETINet.com</td>
        </tr>
        <tr>
            <td width="600">Socket&nbsp;API，CAsyncSocket，CSocket内幕及其用法<br>jmcooler（原作）&nbsp;&nbsp;<br>&nbsp;&nbsp;<br>关键字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Socket&nbsp;CAsyncSocket&nbsp;CSocket&nbsp;CSocketFile&nbsp;同步(阻塞)&nbsp;异步(非阻塞)&nbsp;<br>&nbsp;&nbsp;<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;Socket有同步阻塞方式和异步非阻塞方式两种使用，事实上同步和异步在我们编程的生涯中可能遇到了很多，而Socket也没什么特别。虽然同步好用，不费劲，但不能满足一些应用场合，其效率也很低。<br>&nbsp;&nbsp;&nbsp;&nbsp;
            也许初涉编程的人不能理解&#8220;同步(或阻塞)&#8221;和&#8220;异步(或非阻塞)&#8221;，其实简单两句话就能讲清楚，同步和异步往往都是针对一个函数来说的，&#8220;同步&#8221;就是函
            数直到其要执行的功能全部完成时才返回，而&#8220;异步&#8221;则是，函数仅仅做一些简单的工作，然后马上返回，而它所要实现的功能留给别的线程或者函数去完成。例
            如，SendMessage就是&#8220;同步&#8221;函数，它不但发送消息到消息队列，还需要等待消息被执行完才返回；相反PostMessage就是个异步函数，它
            只管发送一个消息，而不管这个消息是否被处理，就马上返回。<br><br><strong>一、Socket&nbsp;API</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;
            首先应该知道，有Socket1.1提供的原始API函数，和Socket2.0提供的一组扩展函数，两套函数。这两套函数有重复，但是2.0提供的函数
            功能更强大，函数数量也更多。这两套函数可以灵活混用，分别包含在头文件Winsock.h，Winsock2.h，分别需要引入库
            wsock32.lib、Ws2_32.lib。<br><br>1、默认用作同步阻塞方式，那就是当你从不调用WSAIoctl()和
            ioctlsocket()来改变Socket&nbsp;IO模式，也从不调用WSAAsyncSelect()和WSAEventSelect()来选择需要处
            理的Socket事件。正是由于函数accept()，WSAAccept()，connect()，WSAConnect()，send()，
            WSASend()，recv()，WSARecv()等函数被用作阻塞方式，所以可能你需要放在专门的线程里，这样以不影响主程序的运行和主窗口的刷
            新。<br>2、如果作为异步用，那么程序主要就是要处理事件。它有两种处理事件的办法：<br>&nbsp;&nbsp;&nbsp;&nbsp;第一种，它常关联一个窗口，也就是异步Socket的事件将作为消息发往该窗口，这是由WinSock扩展规范里的一个函数WSAAsyncSelect()来实现和窗口关联。最终你只需要处理窗口消息，来收发数据。<br>&nbsp;&nbsp;
            第二种，用到了扩展规范里另一个关于事件的函数WSAEventSelect()，它是用事件对象的方式来处理Socket事件，也就是，你必须首先用
            WSACreateEvent()来创建一个事件对象，然后调用WSAEventSelect()来使得Socket的事件和这个事件对象关联。最终你将
            要在一个线程里用WSAWaitForMultipleEvents()来等待这个事件对象被触发。这个过程也稍显复杂。<br><strong>二、CAsyncSocket<br></strong>&nbsp;&nbsp;&nbsp;&nbsp;
            看类名就知道，它是一个异步非阻塞Socket封装类，CAsyncSocket::Create()有一个参数指明了你想要处理哪些Socket事件，
            你关心的事件被指定以后，这个Socket默认就被用作了异步方式。那么CAsyncSocket内部到底是如何将事件交给你的呢？<br>&nbsp;&nbsp;&nbsp;&nbsp;CAsyncSocket
            的Create()函数，除了创建了一个SOCKET以外，还创建了个CSocketWnd窗口对象，并使用WSAAsyncSelect()将这个
            SOCKET与该窗口对象关联，以让该窗口对象处理来自Socket的事件(消息)，然而CSocketWnd收到Socket事件之后，只是简单地回调
            CAsyncSocket::OnReceive()，CAsyncSocket::OnSend()，CAsyncSocket::OnAccept
            ()，CAsyncSocket::OnConnect()等虚函数。所以CAsyncSocket的派生类，只需要在这些虚函数里添加发送和接收的代
            码。<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;简化后，大致的代码为：<br>&nbsp;&nbsp;bool&nbsp;CAsyncSocket::Create(&nbsp;long&nbsp;lEvent&nbsp;)&nbsp;file://参/数lEvent是指定你所关心的Socket事件<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;m_hSocket&nbsp;=&nbsp;socket(&nbsp;PF_INET,&nbsp;SOCK_STREAM,&nbsp;0&nbsp;);&nbsp;file://创/建Socket本身<br><br>&nbsp;&nbsp;&nbsp;CSocketWnd*&nbsp;pSockWnd&nbsp;=&nbsp;new&nbsp;CSocketWnd;&nbsp;file://创/建响应事件的窗口，实际的这个窗口在AfxSockInit()调用时就被创建了。<br>&nbsp;&nbsp;&nbsp;pSockWnd-&gt;Create(...);<br><br>&nbsp;&nbsp;&nbsp;WSAAsyncSelect(&nbsp;m_hSocket,&nbsp;pSockWnd-&gt;m_hWnd,&nbsp;WM_SOCKET_NOTIFY,&nbsp;lEvent&nbsp;);&nbsp;file://Socket/事件和窗口关联<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;static&nbsp;void&nbsp;PASCAL&nbsp;CAsyncSocket::DoCallBack(WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;CAsyncSocket&nbsp;Socket;<br>&nbsp;&nbsp;&nbsp;Socket.Attach(&nbsp;(SOCKET)wParam&nbsp;);&nbsp;file://wParam/就是触发这个事件的Socket的句柄<br>&nbsp;&nbsp;&nbsp;int&nbsp;nErrorCode&nbsp;=&nbsp;WSAGETSELECTERROR(lParam);&nbsp;file://lParam/是错误码与事件码的合成<br>&nbsp;&nbsp;&nbsp;switch&nbsp;(WSAGETSELECTEVENT(lParam))<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;case&nbsp;FD_READ:<br>&nbsp;&nbsp;&nbsp;&nbsp;pSocket-&gt;OnReceive(nErrorCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;case&nbsp;FD_WRITE:<br>&nbsp;&nbsp;&nbsp;&nbsp;pSocket-&gt;OnSend(nErrorCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;case&nbsp;FD_OOB:<br>&nbsp;&nbsp;&nbsp;&nbsp;pSocket-&gt;OnOutOfBandData(nErrorCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;case&nbsp;FD_ACCEPT:<br>&nbsp;&nbsp;&nbsp;&nbsp;pSocket-&gt;OnAccept(nErrorCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;case&nbsp;FD_CONNECT:<br>&nbsp;&nbsp;&nbsp;&nbsp;pSocket-&gt;OnConnect(nErrorCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;case&nbsp;FD_CLOSE:<br>&nbsp;&nbsp;&nbsp;&nbsp;pSocket-&gt;OnClose(nErrorCode);<br>&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;CSocketWnd类大致为：<br><br>&nbsp;&nbsp;BEGIN_MESSAGE_MAP(CSocketWnd,&nbsp;CWnd)<br>&nbsp;&nbsp;&nbsp;ON_MESSAGE(WM_SOCKET_NOTIFY,&nbsp;OnSocketNotify)<br>&nbsp;&nbsp;END_MESSAGE_MAP()<br><br>&nbsp;&nbsp;LRESULT&nbsp;CSocketWnd::OnSocketNotify(WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;CAsyncSocket::DoCallBack(&nbsp;wParam,&nbsp;lParam&nbsp;);&nbsp;file://收/到Socket事件消息，回调CAsyncSocket的DoCallBack()函数<br>&nbsp;&nbsp;&nbsp;return&nbsp;0L;<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;
            然而，最不容易被初学Socket编程的人理解的，也是本文最要提醒的一点是，客户方在使用CAsyncSocket::Connect()时，往往返回
            一个WSAEWOULDBLOCK的错误(其它的某些函数调用也如此)，实际上这不应该算作一个错误，它是Socket提醒我们，由于你使用了非阻塞
            Socket方式，所以(连接)操作需要时间，不能瞬间建立。既然如此，我们可以等待呀，等它连接成功为止，于是许多程序员就在调用Connect()之
            后，Sleep(0)，然后不停地用WSAGetLastError()或者CAsyncSocket::GetLastError()查看Socket
            返回的错误，直到返回成功为止。这是一种错误的做法，断言，你不能达到预期目的。事实上，我们可以在Connect()调用之后等待
            CAsyncSocket::OnConnect()事件被触发，CAsyncSocket::OnConnect()是要表明Socket要么连接成功
            了，要么连接彻底失败了。至此，我们在CAsyncSocket::OnConnect()被调用之后就知道是否Socket连接成功了，还是失败了。<br>&nbsp;&nbsp;类似的，Send()如果返回WSAEWOULDBLOCK错误，我们在OnSend()处等待，Receive()如果返回WSAEWOULDBLOCK错误，我们在OnReceive()处等待，以此类推。<br>&nbsp;&nbsp;还有一点，也许是个难点，那就是在客户方调用Connect()连接服务方，那么服务方如何Accept()，以建立连接的问题。简单的做法就是在监听的Socket收到OnAccept()时，用一个新的CAsyncSocket对象去建立连接，例如：<br><br>&nbsp;void&nbsp;CMySocket::OnAccept(&nbsp;int&nbsp;ErrCode&nbsp;)<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CMySocket*&nbsp;pSocket&nbsp;=&nbsp;new&nbsp;CMySocket;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Accept(&nbsp;*pSocket&nbsp;);<br>&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;
            于是，上面的pSocket和客户方建立了连接，以后的通信就是这个pSocket对象去和客户方进行，而监听的Socket仍然继续在监听，一旦又有一
            个客户方要连接服务方，则上面的OnAccept()又会被调用一次。当然pSocket是和客户方通信的服务方，它不会触发OnAccept()事件，
            因为它不是监听Socket。<br><br><strong>三、CSocket</strong><br>&nbsp;&nbsp;&nbsp;CSocket是MFC在CAsyncSocket基础上派生的一个同步阻塞Socket的封装类。它是如何又把CAsyncSocket变成同步的，而且还能响应同样的Socket事件呢？<br>&nbsp;&nbsp;
            其实很简单，CSocket在Connect()返回WSAEWOULDBLOCK错误时，不是在OnConnect()，OnReceive()这些事
            件终端函数里去等待。你先必须明白Socket事件是如何到达这些事件函数里的。这些事件处理函数是靠CSocketWnd窗口对象回调的，而窗口对象收
            到来自Socket的事件，又是靠线程消息队列分发过来的。总之，Socket事件首先是作为一个消息发给CSocketWnd窗口对象，这个消息肯定需
            要经过线程消息队列的分发，最终CSocketWnd窗口对象收到这些消息就调用相应的回调函数(OnConnect()等)。<br>&nbsp;&nbsp;&nbsp;所以，
            CSocket在调用Connect()之后，如果返回一个WSAEWOULDBLOCK错误时，它马上进入一个消息循环，就是从当前线程的消息队列里取
            关心的消息，如果取到了WM_PAINT消息，则刷新窗口，如果取到的是Socket发来的消息，则根据Socket是否有操作错误码，调用相应的回调函
            数(OnConnect()等)。<br>&nbsp;&nbsp;大致的简化代码为：<br><br>&nbsp;&nbsp;BOOL&nbsp;CSocket::Connect(&nbsp;...&nbsp;)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;if(&nbsp;!CAsyncSocket::Connect(&nbsp;...&nbsp;)&nbsp;)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;WSAGetLastError()&nbsp;==&nbsp;WSAEWOULDBLOCK&nbsp;)&nbsp;file://由/于异步操作需要时间，不能立即完成，所以Socket返回这个错误<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file://进/入消息循环，以从线程消息队列里查看FD_CONNECT消息，直到收到FD_CONNECT消息，认为连接成功。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(&nbsp;PumpMessages(&nbsp;FD_CONNECT&nbsp;)&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;BOOL&nbsp;CSocket::PumpMessages(&nbsp;UINT&nbsp;uEvent&nbsp;)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CWinThread*&nbsp;pThread&nbsp;=&nbsp;AfxGetThread();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(&nbsp;bBlocking&nbsp;)&nbsp;file://bBlocking/仅仅是一个标志，看用户是否取消对Connect()的调用<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSG&nbsp;msg;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;PeekMessage(&nbsp;&amp;msg,&nbsp;WM_SOCKET_NOTIFY&nbsp;)&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;msg.message&nbsp;==&nbsp;WM_SOCKET_NOTIFY&nbsp;&amp;&amp;&nbsp;WSAGETSELECTEVENT(msg.lParam)&nbsp;==&nbsp;uStopFlag&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CAsyncSocket::DoCallBack(&nbsp;msg.wParam,&nbsp;msg.lParam&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;TRUE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OnMessagePending();&nbsp;file://处/理消息队列里的其它消息<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pThread-&gt;OnIdle(-1);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;}<br>&nbsp;&nbsp;BOOL&nbsp;CSocket::OnMessagePending()<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSG&nbsp;msg;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;PeekMessage(&nbsp;&amp;msg,&nbsp;NULL,&nbsp;WM_PAINT,&nbsp;WM_PAINT,&nbsp;PM_REMOVE&nbsp;)&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;file://这/里仅关心WM_PAINT消息，以处理阻塞期间的主窗口重画<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;::DispatchMessage(&nbsp;&amp;msg&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;FALSE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;FALSE;<br>&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;
            其它的CSocket函数，诸如Send()，Receive()，Accept()都在收到WSAEWOULDBLOCK错误时，进入
            PumpMessages()消息循环，这样一个原本异步的CAsyncSocket，到了派生类CSocket，就变成同步的了。<br>&nbsp;&nbsp;明白之后，我们可以对CSocket应用自如了。比如有些程序员将CSocket的操作放入一个线程，以实现多线程的异步Socket(通常，同步+多线程&nbsp;相似于&nbsp;异步&nbsp;)。<br><br><strong>四、CSocketFile</strong><br>&nbsp;&nbsp;
            另外，进行Socket编程，不能不提到CSocketFile类，其实它并不是用来在Socket双方发送文件的，而是将需要序列化的数据，比如一些结
            构体数据，传给对方，这样，程序的CDocument()的序列化函数就完全可以和CSocketFile联系起来。例如你有一个CMyDocument
            实现了Serialize()，你可以这样来将你的文档数据传给Socket的另一方：<br><br>&nbsp;CSocketFile&nbsp;file(&nbsp;pSocket&nbsp;);<br>&nbsp;CArchive&nbsp;ar(&nbsp;&amp;file,&nbsp;CArchive::store&nbsp;);<br>&nbsp;pDocument-&gt;Serialize(&nbsp;ar&nbsp;);<br>&nbsp;ar.Close();<br><br>&nbsp;&nbsp;同样，接收一方可以只改变上面的代码为CArchive&nbsp;ar(&nbsp;&amp;file,&nbsp;CArchive::load&nbsp;);即可。<br>&nbsp;&nbsp;&nbsp;
            注意到，CSocketFile类虽然从CFile派生，但它屏蔽掉了CFile::Open()等函数，而函数里仅扔出一个例外。那么也就是说，你不能
            调用CSocketFile的Open函数来打开一个实实在在的文件，否则会导致例外，如果你需要利用CSocketFile来传送文件，你必须提供
            CSocketFile类的这些函数的实现。<br>&nbsp;&nbsp;再一点，CArchive不支持在datagram的Socket连接上序列化数据</td>
        </tr>
    </tbody>
</table><img src ="http://www.cnitblog.com/yggl1889/aggbug/46929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2008-07-19 17:35 <a href="http://www.cnitblog.com/yggl1889/archive/2008/07/19/46929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用远程线程来进行DLL注入 </title><link>http://www.cnitblog.com/yggl1889/archive/2008/01/16/38944.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Wed, 16 Jan 2008 14:54:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2008/01/16/38944.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/38944.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2008/01/16/38944.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/38944.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/38944.html</trackback:ping><description><![CDATA[这种方法同前一种方法相比，要显得复杂一些，并且这种方法只能在WIN2000中使用（XP，和最新的2003不知道）。具体步骤如下： <br>
<br>
１）、取得远程进程的进程ID； <br>
<br>
２）、在远程进程空间中分配一段内存用来存放要注入的DLL完整路径； <br>
<br>
３）、将要注入的DLL的路径写到刚才分配的远程进程空间； <br>
<br>
４）、从Kernel32.dll中取得LoadLibray的地址； <br>
<br>
５）、调用CreateRemoteThread函数以从Kernel32.dll中取得的LoadLibrary函数的地址为线程函数的地址，以我们要注入的DLL文件名为参数，创建远程线程； <br>
<br>
在第二三步中，为什么要把我们要注入的DLL的文件名写到远程进程的地址空间进行操作，《WINDOWS核心编程》中是这样描述的： <br>
<br>
&#8220;（要注入的DLL文件名）字符串是在调用进程的地址空间中。该字符串的地址已经被赋予新创建的远程线程，该线程将它传递给L o a d L i b
r a r y A。但是，当L o a d L i b r a r y A取消对内存地址的引用时， D L
L路径名字符串将不再存在，远程进程的线程就可能引发访问违规&#8221;； <br>
<br>
<br>
<br>
至于第四步中为什么不直接对LoadLibrary进行调用，《WINDOWS核心编程》中是这样描述的： <br>
<br>
&#8220;如果在对C r e a t e R e m o t e T h r e a d的调用中使用一个对L o a d L i b r a r y
A的直接引用，这将在你的模块的输入节中转换成L o a d L i b r a r y
A的形实替换程序的地址。将形实替换程序的地址作为远程线程的起始地址来传递，会导致远程线程开始执行一些令人莫名其妙的东西。其结果很可能造成访问违
规。&#8221; <br><br>另：<br>
<p>DLL注入的步骤</p>
<p>1。在受害进程中为DLL代码分配要占据的空间。<br>用到的函数：VirtualAllocEx</p>
<p>2。在受害进程中为要注入的DLL所需的参数分配空间。<br>用到的函数：VirtualAllocEx</p>
<p>3。把DLL的名字和代码写入受害进程的存储空间。<br>用到的函数：WriteProcessMemory</p>
<p>4。在受害进程中创建线程，运行新注入的DLL。<br>用到的函数：CreateRemoteThread</p>
<p>5。释放受害进程中的资源。<br>用到的函数：VirtualFreeEx</p>
<br>//sample<br><span class="content">#include &lt;windows.h&gt;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> Dzm?锷w?</font></span>&nbsp;<br>#include &lt;winsvc.h&gt;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?鵾 :.禔 </font></span>&nbsp;<br>#include &lt;tlhelp32.h&gt; <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">lY篼rc柲v?</font></span>&nbsp;<br>// DLL注入函数 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?W黲?銷 </font></span>&nbsp;<br>bool LoadLib(DWORD dwProcessId, LPWSTR lpszLibName)<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> =孔觧f镏J </font></span>&nbsp;<br>{ <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">焿t瞵醞 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;HANDLE hProcess = NULL; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?7?箨W? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;HANDLE hThread = NULL; <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">/?G#q腱Y </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;LPWSTR lpszRemoteFile = NULL; <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">i缘?碫9?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 諥?堃櫛 </font></span>&nbsp;<br><span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">t~,?叮 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 打开远程进程 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">`2?q駉f&lt;?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;hProcess = OpenProcess(PROCESS_CREATE_THREAD &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> eO`;*?=?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| PROCESS_VM_OPERATION &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 綂?咧v??</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| PROCESS_VM_WRITE, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?{瘐?高 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;FALSE, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 陾?柺&amp;荗w </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;dwProcessId); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">浙?(v  </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> w??S甗J?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;if (hProcess == NULL) &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 鑉?&gt;Y祽?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 垺|}=Z肬_ </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(NULL, "OpenProcess failed with error " , "Error", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?珚綛: </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_ICONINFORMATION + MB_OK); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> )b禸齲;u </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return FALSE; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ]嘢W?缣 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">户喯?椱m?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?睟諗倝?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 訬E)￥梥?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 在远程进程中分配存贮DLL文件名的空间 &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 庿}忸丁! </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;lpszRemoteFile = (LPWSTR)VirtualAllocEx(hProcess, NULL, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 1闎u;P?茒 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;sizeof(WCHAR) * lstrlenW(lpszLibName) + 1, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> _tH硎娾] </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MEM_COMMIT, PAGE_READWRITE); &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> &lt;?J?痲v </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;if (lpszRemoteFile == NULL) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 徇??笯l* </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;{ &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> (SNX~[70 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(NULL, "VirtualAllocEx failed with error " , "Error", <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">囖沒何M??</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_ICONINFORMATION + MB_OK); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?眖ir? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return FALSE; <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">龝H﹢湷? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">巙碋&#954;m7巇 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 幚w薦?H </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 复制DLL文件名到远程刚分配的进程空间 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">QH洐迦?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;if (!WriteProcessMemory(hProcess, lpszRemoteFile, <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?鈷坘侄煝 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(PVOID)lpszLibName, sizeof(WCHAR) * lstrlenW(lpszLibName) + 1, <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?钍禵绚? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NULL)) <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">P+??滁 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;{ <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">E耦??C'?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(NULL, "WriteProcessMemory failed with error " , "Error", <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">p`j$潀1 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_ICONINFORMATION + MB_OK); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?鮑征?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return FALSE; <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?etXF?%M </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">01?熜?鑴 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 取得LoadLibrary函数在Kennel32.dll中的地址 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">_雨B芰? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;PTHREAD_START_ROUTINE pfnThreadRtn = <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">'k1汕 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(PTHREAD_START_ROUTINE)GetProcAddress( <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">j澇x竳俘?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;GetModuleHandle("Kernel32.dll"),"LoadLibraryW"); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">E?涽gm埳?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;if (pfnThreadRtn == NULL) <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">伓ZC騷远? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;{ <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">&gt;痥T ◣g?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(NULL, "GetProcAddress failed with error " , "Error", <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">y 广篋狤? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_ICONINFORMATION + MB_OK); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">MqQ?? } </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return FALSE; <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">A?`|9欛 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">e?&amp;嘄 ^? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 创建远程线程 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">c,0髛jgeJ </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;hThread = CreateRemoteThread(hProcess, <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">`剎^D鯩??</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NULL, <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">Ar鹼DH貂 ?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">#W?枊R柑 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pfnThreadRtn, // LoadLibrary地址 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">胭mG榍?? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;lpszRemoteFile, // 要加载的DLL名 <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">楖8資啱 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?I挷?腺?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NULL); &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 熿騒I&lt;簀?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;if (hThread == NULL) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 撪?殥?v?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> }教z &gt;? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MessageBox(NULL, "CreateRemoteThread failed with error " , "Error", &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 靁嘽g授G </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;MB_ICONINFORMATION + MB_OK); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ? 4復? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return FALSE; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> .k钄z5.S </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">m袁鹯?Z?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 躎?b|钍 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 等待线程返回 &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 媣l\\厝I0 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;WaitForSingleObject(hThread, INFINITE); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">屰騉-7@e?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 検蓮~R灔 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 释放进程空间中的内存 &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?跑+e脌 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;VirtualFreeEx(hProcess, lpszRemoteFile, 0, MEM_RELEASE); &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 摶"汊驄&amp;?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 关闭句柄 &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 钡領?荴 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;CloseHandle(hThread); &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?蚊ˉ? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;CloseHandle(hProcess); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?G.矽庉N </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;return TRUE; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ZCu尢5賆 </font></span>&nbsp;<br>} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">90??嫫蟄 </font></span>&nbsp;<br><span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">螨^rn`+v膼 </font></span>&nbsp;<br>void main()<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> J癋赖澝? </font></span>&nbsp;<br>{ <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">嫟g賜jG??</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;LPWSTR m_szDllFile = L"D:\\FileHook\\APIHook_Dll\\Debug\\APIHook_Dll.dll";<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> ?k2R脽忮 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;DWORD m_dwProcessId = 0;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> }&#933;ofe介?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;PROCESSENTRY32 pe;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 蝷?掆 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 创建快照句柄<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> pT唓虌赦⊿ </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 葺?M櫍M </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 先搜索系统中第一个进程的信息<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> cG嫕l詻翘?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;Process32First(hSnapshot, &amp;pe);<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> q杴5?Y?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 下面对系统中的所有进程进行枚举，并保存其信息<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> _m?]5椃t </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;do{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> FMJ? </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(strcmp(pe.szExeFile,"explorer.exe") == 0 &nbsp; &nbsp; &nbsp;)<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> h? |VH?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> F塠昷籛^ </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 彞€?T胉eF </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;m_dwProcessId =pe.th32ProcessID;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> m災滑磁A?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> /?漌2n?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> O??拻懠?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">5謣軇旽j </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;while (Process32Next(hSnapshot, &amp;pe));<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> M_:娌_樆?</font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;// 关闭快照句柄<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> w?E眳 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;CloseHandle(hSnapshot);<span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff"> 鐭ㄘ碲ш潰 </font></span>&nbsp;<br>&nbsp; &nbsp; &nbsp;LoadLib(m_dwProcessId, m_szDllFile); <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?8Y旡X苽{ </font></span>&nbsp;<br>} <span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">唜#B鮘 </font></span>&nbsp;<br><span class="copyctrl" style="font-size: 0pt;"><font color="#ffffff">?i淪渧"f?</font></span> </span><br>   <img src ="http://www.cnitblog.com/yggl1889/aggbug/38944.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2008-01-16 22:54 <a href="http://www.cnitblog.com/yggl1889/archive/2008/01/16/38944.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ogre3d manual</title><link>http://www.cnitblog.com/yggl1889/archive/2007/07/26/30751.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Thu, 26 Jul 2007 14:54:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2007/07/26/30751.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/30751.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2007/07/26/30751.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/30751.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/30751.html</trackback:ping><description><![CDATA[http://www.ogre3d.org/docs/manual/manual_toc.html#SEC_Contents<br><img src ="http://www.cnitblog.com/yggl1889/aggbug/30751.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2007-07-26 22:54 <a href="http://www.cnitblog.com/yggl1889/archive/2007/07/26/30751.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows 2000 中的有用进程</title><link>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30328.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Fri, 20 Jul 2007 10:08:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30328.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/30328.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30328.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/30328.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/30328.html</trackback:ping><description><![CDATA[<div class="cnt">
<p style="margin: 0px;">Windows 2000/XP
的任务管理器是一个非常有用的工具，它能提供我们很多信息，比如现在系统中运行的程序（进程），但是面对那些文件可执行文件名我们可能有点茫然，不知道它
们是做什么的，会不会有可疑进程（病毒，木马等）。本文的目的就是提供一些常用的Windows 2000 中的进程名，并简单说明它们的用处。 </p>
<p style="margin: 0px;">在 WINDOWS 2000 中,系统包含以下缺省进程： <br>
Csrss.exe <br>
Explorer.exe <br>
Internat.exe <br>
Lsass.exe <br>
Mstask.exe <br>
Smss.exe <br>
Spoolsv.exe <br>
Svchost.exe <br>
Services.exe <br>
System <br>
System Idle Process <br>
Taskmgr.exe <br>
Winlogon.exe <br>
Winmgmt.exe </p>
<p style="margin: 0px;">下面列出更多的进程和它们的简要说明 <br>
进程名 描述 <br>
smss.exe Session Manager <br>
csrss.exe 子系统服务器进程 <br>
winlogon.exe 管理用户登录 <br>
services.exe 包含很多系统服务 <br>
lsass.exe 管理IP安全策略以及启动ISAKMP/Oakley(IKE)和IP安全驱动程序 <br>
svchost.exe Windows 2000/XP 的文件保护系统 <br>
SPOOLSV.EXE 将文件加载到内存中以便迟后打印 <br>
explorer.exe 资源管理器 <br>
internat.exe 托盘区的拼音图标 <br>
mstask.exe 允许程序在指定时间运行。 <br>
regsvc.exe 允许远程注册表操作。(系统服务)-&gt;remoteregister <br>
winmgmt.exe 提供系统管理信息(系统服务) <br>
inetinfo.exe msftpsvc,w3svc,iisadmn <br>
tlntsvr.exe tlnrsvr <br>
tftpd.exe&nbsp;&nbsp;&nbsp;&nbsp; 实现 TFTP Internet 标准。该标准不要求用户名和密码 <br>
termsrv.exe&nbsp;&nbsp;&nbsp;&nbsp; termservice <br>
dns.exe&nbsp;&nbsp;&nbsp;&nbsp; 应答对域名系统(DNS)名称的查询和更新请求 <br>
tcpsvcs.exe&nbsp;&nbsp;&nbsp;&nbsp; 提供在PXE可远程启动客户计算机上远程安装2000 Professional的能力 <br>
ismserv.exe&nbsp;&nbsp;&nbsp;&nbsp; 允许在 Windows Advanced Server 站点间发送和接收消息 <br>
ups.exe&nbsp;&nbsp;&nbsp;&nbsp; 管理连接到计算机的不间断电源(UPS) <br>
wins.exe&nbsp;&nbsp;&nbsp;&nbsp; 为注册和解析 NetBIOS 型名称的TCP/IP客户提供NetBIOS名称服务 <br>
llssrv.exe&nbsp;&nbsp;&nbsp;&nbsp; 证****录服务 <br>
ntfrs.exe&nbsp;&nbsp;&nbsp;&nbsp; 在多个服务器间维护文件目录内容的文件同步 <br>
RsSub.exe&nbsp;&nbsp;&nbsp;&nbsp; 控制用来远程储存数据的媒体 <br>
locator.exe&nbsp;&nbsp;&nbsp;&nbsp; 管理 RPC 名称服务数据库 <br>
lserver.exe&nbsp;&nbsp;&nbsp;&nbsp; 注册客户端许可证 <br>
dfssvc.exe&nbsp;&nbsp;&nbsp;&nbsp; 管理分布于局域网或广域网的逻辑卷 <br>
clipsrv.exe&nbsp;&nbsp;&nbsp;&nbsp; 支持&#8220;剪贴簿查看器&#8221;，以便可以从远程剪贴簿查阅剪贴页面 <br>
msdtc.exe&nbsp;&nbsp;&nbsp;&nbsp; 并列事务，是分布于两个以上的数据库，消息队列，文件系统或其它事务保护护资源管理器。 <br>
faxsvc.exe&nbsp;&nbsp;&nbsp;&nbsp; 帮助您发送和接收传真。 <br>
cisvc.exe&nbsp;&nbsp;&nbsp;&nbsp; 索引服务 <br>
madmin.exe&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 磁盘管理请求的系统管理服务。 <br>
mnmsrvc.exe&nbsp;&nbsp;&nbsp;&nbsp; 允许有权限的用户使用 NetMeeting 远程访问 Windows 桌面。 <br>
netdde.exe&nbsp;&nbsp;&nbsp;&nbsp; 提供动态数据交换 (DDE) 的网络传输和安全特性。 <br>
smlogsvc.exe&nbsp;&nbsp;&nbsp; 配置性能日志和警报。 <br>
rsvp.exe&nbsp;&nbsp;&nbsp;&nbsp; 为依赖质量服务(QoS)的程序和控制应用程序提供网络信号和本地通信控制安装功功能。 <br>
RsEng.exe&nbsp;&nbsp;&nbsp;&nbsp; 协调用来储存不常用数据的服务和管理工具。 <br>
RsFsa.exe&nbsp;&nbsp;&nbsp;&nbsp; 管理远程储存的文件的操作。 <br>
grovel.exe&nbsp;&nbsp;&nbsp;&nbsp; 扫描零备份存储(SIS)卷上的重复文件，并且将重复文件指向一个数据存储点，以节省磁盘空间(只对NTFS文件系统有用) <br>
SCardSvr.ex&nbsp;&nbsp;&nbsp;&nbsp; 对插入在计算机智能卡阅读器中的智能卡进行管理和访问控制。 <br>
snmp.exe&nbsp;&nbsp;&nbsp;&nbsp; 包含代理程序可以监视网络设备的活动并且向网络控制台工作站汇报。 <br>
snmptrap.exe&nbsp;&nbsp;&nbsp; 接收由本地或远程SNMP代理程序产生的陷阱(trap)消息，然后将消息传递到运行在这台计算机上 SNMP 管理程序。 <br>
UtilMan.exe&nbsp;&nbsp;&nbsp;&nbsp; 从一个窗口中启动和配置辅助工具。 <br>
msiexec.exe&nbsp;&nbsp;&nbsp;&nbsp; 依据.MSI文件中包含的命令来安装、修复以及删除软件。 </p>
<p style="margin: 0px;">总结： 发现可疑进程的秘诀就是要多看任务管理器中的进程列表，看多了以后，一眼就可以发现可可疑进程，就象找一群熟悉人中的陌生人一样</p>
</div><img src ="http://www.cnitblog.com/yggl1889/aggbug/30328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2007-07-20 18:08 <a href="http://www.cnitblog.com/yggl1889/archive/2007/07/20/30328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>windows 中的无用的服务</title><link>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30324.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Fri, 20 Jul 2007 09:05:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30324.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/30324.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30324.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/30324.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/30324.html</trackback:ping><description><![CDATA[<div class="cnt">
<p>　　我们使用电脑时经常会碰到各种各样的问题，比如在网上邻居中看不到其他的&#8220;网友&#8221;、无法正常上网、电脑关机速度变慢等等，在尝试了各种方法还没有解决时，不妨到&#8220;控制面板&#8594;管理工具&#8594;服务&#8221;中&#8220;打探&#8221;一番，没准就能找到故障的根源。 </p>
<p>　　1. Computer Browser </p>
<p>　　这个服务主要用于维护网上邻居中计算机的最新列表，其中包括基于Windows的域、工作组的计算机，还有其他使用NetBIOS协议的网络设
备。&#8220;网上邻居&#8221;显示的内容正是来源于此，Computer
Browser服务会将这个列表通知给请求的程序。如果你在&#8220;网上邻居&#8221;看不到其他电脑，很可能是这个服务没有开启。笔者建议个人用户将其设置为&#8220;已禁
用&#8221;，局域网用户应设置为&#8220;自动&#8221;。 </p>
<p>　　2. Event Log </p>
<p>　　这个服务会将程序和系统发送的出错消息记录到日志中，其中会包含对诊断问题有所帮助的信息。一般情况下，禁用这个服务并不会有什么问题，但有时
很可能会导致几个与网络有关的服务无法启动，并出现无法拨号上网的现象。如果需要上网或是处于局域网中的用户，笔者建议将其设置为&#8220;自动&#8221;。 </p>
<p>　　3. IMAPI CD-Burning COM Service </p>
<p>　　Windows XP刻录服务，可以让你通过拖放文件进行光盘刻录。同时，一些与刻录相关的软件也会用到这个服务，比如:Windows
Media
Player等。不过，如果你使用Nero作为默认的刻录软件，在开启这个服务后，Nero的运行速度会受影响。如果使用Nero，笔者建议将其设置为
&#8220;已禁用&#8221;，这样会提高Nero的运行速度。 </p>
<p>　　4. Shell Hardware Detection </p>
<p>　　用于支持闪存、各种记忆卡、光驱等设备的自动播放，如果你的笔记本电脑在使用这个服务后，出现一些问题，或者在&#8220;我的电脑&#8221;中看不到DVD光驱、光驱自动运行出现问题等，笔者建议将其设置为&#8220;自动&#8221;。 </p>
<p>　　5. ATi HotKey Poller </p>
<p>　　这是ATi显卡驱动程序的服务，用来管理ATi驱动程序所附带的热键功能，不过大部分用户并不需要。同时，这个服务不仅会占用相当多的CPU资源，同时还导致关机速度变慢，笔者建议将其设置为&#8220;已禁用&#8221;。 </p>
<p>　　6. Nvidia Driver Helper Service </p>
<p>　　这个服务是安装NVIDIA显卡驱动程序后生成的服务，尽管我们并不太清楚它的作用到底是什么，但起码知道，一些关机慢的故障是由它引起的，同时它还占用了不少内存资源。笔者建议将其设置为&#8220;已禁用&#8221;。 </p>
<p>　　7. O&amp;O Defrag </p>
<p>　　这是磁盘整理软件O&amp;O
Defrag的即时检测服务，它能自动监视磁盘使用情况，并在需要整理磁盘，而且系统处于空闲状态时自动启动。不少朋友可能会遇到启动O&amp;O
Defrag时，出现错误提示，无法运行软件。其实，只要先进入&#8220;服务&#8221;窗口，选中&#8220;O&amp;O
Defrag&#8221;服务，接着单击工具栏中的启动服务按钮将其启动起来，然后再运行软件即可。因此，如果遇到某个软件无法运行，除检查软件本身外，最好到&#8220;服
务&#8221;中查一查。笔者建议将其设置为&#8220;自动&#8221;。</p>
</div><img src ="http://www.cnitblog.com/yggl1889/aggbug/30324.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2007-07-20 17:05 <a href="http://www.cnitblog.com/yggl1889/archive/2007/07/20/30324.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>了解svchost</title><link>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30320.html</link><dc:creator>桂湖山</dc:creator><author>桂湖山</author><pubDate>Fri, 20 Jul 2007 07:54:00 GMT</pubDate><guid>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30320.html</guid><wfw:comment>http://www.cnitblog.com/yggl1889/comments/30320.html</wfw:comment><comments>http://www.cnitblog.com/yggl1889/archive/2007/07/20/30320.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/yggl1889/comments/commentRss/30320.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/yggl1889/services/trackbacks/30320.html</trackback:ping><description><![CDATA[svchost.exe是NT核心系统非常重要的文件，对于Win2000/XP来说，不可或缺。这些svchost进程提供很多系统服务，如：
rpcss服务（remote procedure call）、dmserver服务（logical disk
manager）、dhcp服务（dhcp client）等等。
<br>
<br>如果要了解每个svchost进程到底提供了多少系统服务，可以在WinXP的命令提示符窗口中输入&#8220;tasklist /svc&#8221;命令来查看。
<br>一般来说，Win2000有两个SVCHOST进程，WinXP中则有四个或四个以上的SVCHOST进程（以后看到系统中有多个这种进程，千万别立即判
定系统有病毒了哟），而Win2003 server中则更多。这些SVCHOST进程提供很多系统服务，如：RpcSs服务（Remote
Procedure Call）、dmserver服务（Logical Disk Manager）、Dhcp服务（DHCP Client）等。<br><br>HKEY_LOCAL_MACHINE\System\currentcontrolset\services\Remote Registry&#8221; <img src ="http://www.cnitblog.com/yggl1889/aggbug/30320.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/yggl1889/" target="_blank">桂湖山</a> 2007-07-20 15:54 <a href="http://www.cnitblog.com/yggl1889/archive/2007/07/20/30320.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>