• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            我生如山

            置頂隨筆 #

            [置頂]還是懷念一個人爬山的感覺

            還是懷念上上周末一個人走香巴拉的感覺,那天因為頭一日走了香山,腳上本已起了水泡,但是因為看著天氣自己還是忍不住想找點事情做,于是選擇了走這條自己并不怎么認路的香巴拉。
            其實喜歡的不是路,是路上的感覺。總覺得自己和世人走的很遠,總覺得很多時候即使在和人一起喝酒其實自己也是寂寞的,總覺得有時候也很享受這種寂寞的感覺,總覺得有時候自己很無聊很無恥喜歡這樣子一個人虐待自己,總覺得也許有一個港灣或許是最后的歸宿可以一睡不醒,總覺得現(xiàn)在我不過是塵世的一個過客也許明日又將上路,總覺得,總覺得,總覺得有很多東西是這輩子就跟定我了,比如這種殺死人般的淡淡傷感。

            聽歌,沒人知道你的感覺,你可以和很多人分享,但是一種心情卻只能是自己的。在路上聽歌,沒人知道你在聽歌,寂寞的人會說有風知道云知道,其實那不過是在自欺罷了,何處知道風云就了解你在聽歌呢?沒處只到。只是正因為無處知曉,所以我寂寞的覺得幸福。

            還記得上上周末走向巴拉時在岔路口想的事情,還記得在坡上看到一對情侶的舞蹈在我當時的眼里如何之一如天人,還記得如何的清風中享受那《Nightingale》帶來的空谷回響。

            沒事情是一如往常,我只是在享受這種感覺。享受這種一個人在路上,在路上尋覓,在路上踟躕。
            有時候想想,人生也許不要答案或者不要結果真的很好,我可以永遠只想現(xiàn)在的如何,永遠只需要知曉我現(xiàn)在的感覺,永遠只需要在一次舞蹈之后擦拭自己受傷的靈魂無需知道有否另外一個觀眾。

            可是人生偏偏的如此需要結果。

            posted @ 2009-05-14 15:21 悟山 閱讀(2043) | 評論 (10)編輯 收藏

            2010年9月15日 #

            *控制流圖(II)

            控制流圖對編譯優(yōu)化和程序靜態(tài)分析很有用處。編譯優(yōu)化根據(jù)待編譯程序的控制流減少其中不必要的跳轉,使得代碼結構更加緊湊。靜態(tài)分析工具根據(jù)程序的控制流來分析得到程序的復雜度等等一系列統(tǒng)計信息,Visual Studio自帶的代碼度量(Code Metrics)就是靜態(tài)分析中控制流圖應用的一個例子。

            posted @ 2010-09-15 12:14 悟山 閱讀(294) | 評論 (0)編輯 收藏

            *控制流圖

            控制流圖(Control Flow Graph)是在計算機科學中用圖的方式來表現(xiàn)程序執(zhí)行過程中所有的可能執(zhí)行路徑的一種方式。在控制流圖中,每一個節(jié)點表示表示一個基本的代碼塊,這些基本的代碼塊用箭頭連接起來用以描述這些代碼塊之間的執(zhí)行順序。
            在控制流圖中,有兩類特殊的代碼塊,入口代碼塊和出口代碼塊;所有的執(zhí)行路徑都從入口塊開始,并且結束于一個出口塊。
            一個控制流圖本身是一個圖(Graph),可以用計算機圖論中的術語來加以描述,諸如edge,vertex,back edge等等。
            下面的圖片可以作為一個基本的控制流圖的樣本:

            posted @ 2010-09-15 12:00 悟山 閱讀(1725) | 評論 (0)編輯 收藏

            2009年11月6日 #

            一個小型CRM系統(tǒng)的設計(未完成版本)

            Core-Man System Design Document Version 1.0 9/29/2009 Contents 簡介 4 系統(tǒng)總體架構介紹 4 系統(tǒng)具體設計 6 后記 6 簡介 本文檔用來描述Core-Man這個用來為汽配行業(yè)做貨物、訂單、客戶關系管理的系統(tǒng)功能和設計。本文檔基于該系統(tǒng)的需求分析和前期市場調研,關于需求分析和市場調研的結果,可以查看文檔XXXX. 1. 系統(tǒng)設計目標 為了使得系統(tǒng)能最大程度的滿足用戶的需求,盡可能的減少以后再定制維護過程中的代價,Core-Man系統(tǒng)應該達到以下幾個目標: ? 可定制性:雖然本系統(tǒng)是為了汽配行業(yè)的客戶管理而設計的,但是本系統(tǒng)需要達到在特定的需求下經過適當?shù)呐渲茫〝?shù)據(jù)庫配置,配置文件更改)而達到滿足其他行業(yè)需求的目的。 ? 可維護性:本系統(tǒng)的設計應該達到可維護的目的,因為用戶的需求可能會變化(企業(yè)規(guī)模擴大,經營業(yè)務增多)。在用戶變化需求的時候,我們的系統(tǒng)就需要升級,那么在升級的過程,至少需要滿足兩方面的可重用,一是數(shù)據(jù)上的可重用。客戶在一定的經營過程中積累了一定數(shù)目的用戶資源和經營經驗數(shù)據(jù),這部分數(shù)據(jù)對于客戶以后繼續(xù)經營,擴大業(yè)務規(guī)模都是有重要作用的。在我們的系統(tǒng)升級的過程,應該使得客戶可以重用這部分數(shù)據(jù),即使得升級后的系統(tǒng)能夠識別維護舊的數(shù)據(jù)。另一方面的可重用性是指代碼上的可重用性,系統(tǒng)的升級不能使推到系統(tǒng)重來。新系統(tǒng)應該基于舊系統(tǒng)已有的代碼,這樣可以最大程度上的節(jié)省成本。 ? 安全性:雖然在系統(tǒng)初期,客戶對于安全性上的要求不會很高,但是隨著企業(yè)業(yè)務規(guī)模的擴大,必然涉及到很多的商業(yè)保密信息。企業(yè)的客戶數(shù)據(jù),訂單數(shù)據(jù),管理模式都有很重要的商業(yè)價值,此時對于我們系統(tǒng)的安全性就提出了要求。Core-Man系統(tǒng)的安全性主要體現(xiàn)在一下幾個方面: ? 用戶認證:系統(tǒng)應該區(qū)分登錄的會話中用戶的身份,以此來判斷用戶可訪問哪些數(shù)據(jù),可更改哪些數(shù)據(jù),這個對于一個中大型企業(yè)里面,各個管理層面(老板,總經理,經理,員工)應用同一個系統(tǒng)式很重要的。 ? 權限管理:驗證用戶后,需要判斷已驗證用戶是否被允許訪問其所請求的數(shù)據(jù),在判斷通過的情況下,系統(tǒng)返回正確的響應;否則,系統(tǒng)告知客戶端無權訪問。 ? 數(shù)據(jù)加密:企業(yè)的客戶數(shù)據(jù),員工數(shù)據(jù),訂單數(shù)據(jù)都涉及到商業(yè)秘密。這些數(shù)據(jù)都需要經過加密后存儲在系統(tǒng)的文件系統(tǒng)或者數(shù)據(jù)庫中。 系統(tǒng)總體架構介紹 很明顯的Core-Man系統(tǒng)是一個以數(shù)據(jù)庫為中心,以多終端進行數(shù)據(jù)處理維護的分布式系統(tǒng),一個Core-Man系統(tǒng)的典型的應用場景可以用下圖來描述: 在上面的應用場景中,各個角色的分工如下: ? 中心數(shù)據(jù)庫:負責提供整個系統(tǒng)的數(shù)據(jù)的存貯,這里包含兩部分內容 ? 由數(shù)據(jù)庫管理系統(tǒng)托管的數(shù)據(jù)庫表,視圖,存儲過程,數(shù)據(jù)等信息。 ? 由文件系統(tǒng)托管的圖片,文件等信息。 ? 請求監(jiān)聽/代理服務器:負責作為終端用戶和數(shù)據(jù)庫之間通信的一個代理人的角色。所有客戶端的操作如果涉及到數(shù)據(jù)庫查詢/更改請求,由請求監(jiān)聽/代理服務器將其轉換為對相應數(shù)據(jù)庫項目的查詢/更新操作。這樣的設計能使得終端用戶和數(shù)據(jù)庫的耦合性降到最低,使得在需要更換數(shù)據(jù)庫的時候,我們只需要更新請求監(jiān)聽/代理服務器里面與數(shù)據(jù)庫交互的那部分代碼。同時,加進一層請求監(jiān)聽/代理服務器,可以讓我們的系統(tǒng)在這一層進行安全性上的檢查更改等操作,比如,在這一層做終端用戶身份的鑒別,只有終端用戶是授權用戶的時候,我們才允許客戶端進行后續(xù)操作。 ? 超級管理終端:這個終端有最大的管理權限,用于進行數(shù)據(jù)的備份,緊急模式下的更改等操作。 ? 分布式終端1:本系統(tǒng)眾多分布式終端的其中一個,用戶為普通用戶(經理,員工,客戶)提供訪問我們系統(tǒng)的功能。每一個分布式終端在發(fā)起連接請求監(jiān)聽/代理服務器的時候,都需要提供用戶身份的信息,請求監(jiān)聽/代理服務器用這些信息來判斷發(fā)起連接的用戶是否是一個經過授權的用戶。 下圖描述了我們的數(shù)據(jù)庫設計的基本輪廓: 下圖描述了我們的請求監(jiān)聽/代理服務器的設計模塊以及模塊之間的聯(lián)系: 自上至下,三個大的模塊分別是: ? 請求監(jiān)聽層:負責監(jiān)聽客戶端的操作請求,檢查客戶端的身份,以及客戶端的權限。如果客戶端是經授權的用戶并且其請求操作被策略允許,請求監(jiān)聽層會將該請求放進該層維護的請求隊列中。放進請求隊列中的請求包含請求的客戶端信息,請求的優(yōu)先級,請求所要進行的具體操作等等。請求監(jiān)聽層會有一個請求分發(fā)線程,從請求隊列中按照一定的策略找出一個請求,將該請求送往邏輯處理層。 ? 邏輯處理層:邏輯處理層的主要功能是維護抽象的數(shù)據(jù)模型,使得請求層不必與具體的數(shù)據(jù)庫訪問器接口方法做交互。邏輯處理層將請求監(jiān)聽層分發(fā)過來的請求轉換為對特定抽象數(shù)據(jù)的操作,這就使得在這一層能盡最大可能地應用面向對象設計的好處,為以后的升級,定制提供方便。邏輯處理層由請求監(jiān)聽模塊,邏輯處理模塊和邏輯對象管理器組成。請求監(jiān)聽模塊將請求監(jiān)聽層分發(fā)過來的請求轉換為對特定邏輯對象的操作。邏輯處理模塊是一個特定的線程,負責調用邏輯對象管理器的方法來進行邏輯多項生命周期的維護。邏輯對象管理器負責提供邏輯對象的管理接口,比如邏輯對象的創(chuàng)建,刪除等操作。 ? 數(shù)據(jù)庫訪問層:數(shù)據(jù)庫訪問層主要由數(shù)據(jù)庫訪問器接口和數(shù)據(jù)庫訪問器實現(xiàn)來組成。這一層提供具體的數(shù)據(jù)訪問操作給邏輯處理層使用。數(shù)據(jù)庫訪問器接口和數(shù)據(jù)庫訪問器實現(xiàn)分屬于不同的程序集,這樣就使得數(shù)據(jù)庫訪問器實現(xiàn)能很方便的被替換,使系統(tǒng)能遷移到使用新的數(shù)據(jù)庫系統(tǒng),只要我們提供新數(shù)據(jù)庫系統(tǒng)的數(shù)據(jù)庫訪問器實現(xiàn),并且更改數(shù)據(jù)庫訪問層的程序配置文件指向新的數(shù)據(jù)庫訪問器實現(xiàn)。 系統(tǒng)具體設計 本章節(jié)按照“系統(tǒng)總體架構介紹”里面描述的模塊順序逐個介紹這些模塊的具體實現(xiàn)策略。 請求監(jiān)聽層: 請求監(jiān)聽模塊: 設計請求監(jiān)聽模塊涉及到設計我們所使用的具體的網(wǎng)絡協(xié)議的格式,在初步的設計里面,我們使用 .Net對于 WinSocket的封裝來實現(xiàn)網(wǎng)絡數(shù)據(jù)的傳輸,使用TCP/IP協(xié)議。在TCP的payload里面?zhèn)鬏斘覀兊恼埱笙⒑晚憫ⅰO⒏袷饺缦拢? 其中各個字段的含義如下: Command Value: 用于指示操作碼,如果系統(tǒng)最高位是0,表明這是系統(tǒng)定義的操作碼;如果最高位是1,則表明是用戶定義的操作碼。對于每一個特定的操作碼,系統(tǒng)應該提供一個該操作碼下的Request Data的解析函數(shù);所以,如果用戶需要定義自己的操作碼,那么他也應該提供該操作碼下的Request Data的解析函數(shù)實現(xiàn)。解析函數(shù)有特定的格式如下: public Dictionary RequestDataParser(ushort commandValue, ushort flags, Guid sessionId, byte[] requestData); 其輸入為一個完整的包結構,輸出為解析出來的Request Data中包含的有意義的字段對應C#中的數(shù)據(jù)類型,以及這些數(shù)據(jù)的值。這樣子就是得我們能在我們的請求監(jiān)聽層初始化的時候根據(jù)配置文件中的解析函數(shù)配置注冊合適的解析函數(shù),在運行中能夠調用注冊好的配置函數(shù)解析對應的網(wǎng)絡數(shù)據(jù)將其轉換為有意義的邏輯數(shù)據(jù)。 在這種設計之下,用戶如果需要定義自己的Command Value,假設其值為0xF000,那么用戶提供一個叫做CustomeRequestDataParser.dll的程序集,其中包含了對于Command Value0xF0000下的Request Data的解析函數(shù)實現(xiàn),其實現(xiàn)如下: public class CustomeRequestDataParser { public Dictionary RequestDataParser(ushort commandValue, ushort flags, Guid sessionId, byte[] requestData) { Dictionary result = new Dictionary(); if (requestData.Length != 8) { throw new ArgumentException("Invalid network data received."); } byte[] field1 = new byte[4]; byte[] field2 = new byte[4]; Array.Copy(requestData, field1, 4); Array.Copy(requestData, field2, 4, 4); result.Add( typeof(uint), BitConverter.ToUInt32(field1, 0)); result.Add(typeof(uint), BitConverter.ToUInt32(field2, 0)); return result; } } 在我們的請求監(jiān)聽層的程序配置文件中存在這么一項: 在我們的請求監(jiān)聽層的初始化代碼中存在這么幾行代碼: public void RegisterRequestDataParsers() { System.Collections.Specialized.NameObjectCollectionBase.KeysCollection keysCOllection = ConfigurationSettings.AppSettings.Keys; List requestDataParserKeys = new List(); foreach (string keyValue in keysCOllection) { if (keyValue.Contains("CommandValueParser")) { requestDataParserKeys.Add(keyValue); } } foreach (string keyValue in requestDataParserKeys) { string assemblyPath = GetAssemblyPath(ConfigurationSettings.AppSettings[keyValue]); if (!IsAssemblyLoaded(assemblyPath)) { AppDomain.CurrentDomain.Load(assemblyPath); } string typeName = GetTypeName(ConfigurationSettings.AppSettings[keyValue]); ushort commandValue=GetCommandValue(ConfigurationSettings.AppSettings[keyValue]); if (!registeredRequestDataParsers.ContainsKey(commandValue)) { registeredRequestDataParsers.Add(commandValue, Type.GetType(GetTypeFullName(typeName))); } } } 當請求監(jiān)聽模塊收到一個請求之后,它會將其轉換為一個事件,將其放進事件隊列中,一個事件應該包含以下信息: public class Event { private DateTime timeStamp; private ushort commandValue; private ushort flags; private Guid sessionId; Dictionary requestData; } 一個時間隊列的可能定義如下: public class EventQueue { private List eventPool; private uint eventCount; private Event mostPrioritizedEvent; } 請求調度模塊不斷的查詢事件隊列中的時間,按照特定的調度策略找出一個合適的事件交給邏輯層處理: public abstract class EventSelectionPolicy { } public class EventQueueProcessor { private EventQueue eventQueue; private EventSelectionPolicy eventSelectionPolicy; public void RegisterEventQueue(EventQueue queue) { if (this.eventQueue != null) { throw new ArgumentException("Unable to register another event queue when a queue is still in processing."); } this.eventQueue = queue; } public EventQueue UnregisterEventQueue() { if (this.eventQueue == null) { throw new InvalidOperationException("Unable to unregister an event queue when the queue is not intialized."); } EventQueue queue = this.eventQueue; this.eventQueue = null; return queue; } public void RegisterEventSelectionPolicy(EventSelectionPolicy policy) { this.eventSelectionPolicy = policy; } public Event SelectEvent() { // //return ...; } } EventQueueProcessor調用SelectEvent方法按照注冊過的調度策略選擇一個event交給邏輯處理層處理。 后記

            posted @ 2009-11-06 13:26 悟山 閱讀(217) | 評論 (0)編輯 收藏

            2009年7月24日 #

            在.Net Framework中動態(tài)創(chuàng)建類型---System.Reflection.Emit命名空間小試

             string assemblyName = this.txtAssemblyName.Text;
                        
            string className = this.txtClassName.Text;

                        System.Diagnostics.Debug.Assert(assemblyName 
            != null && assemblyName != string.Empty);
                        System.Diagnostics.Debug.Assert(className 
            != null && className != string.Empty);

                        System.Reflection.AssemblyName asmName 
            = new System.Reflection.AssemblyName(assemblyName);
                        AssemblyBuilder asmBuilder 
            = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
                        ModuleBuilder modBuilder 
            = asmBuilder.DefineDynamicModule("MyModule"true);

                        TypeBuilder typeBuilder 
            = modBuilder.DefineType(className);
                        typeBuilder.DefineField(
            "myfield",typeof(string), System.Reflection.FieldAttributes.Public);
                        MethodBuilder methodBuilder 
            = typeBuilder.DefineMethod("CallMethod", System.Reflection.MethodAttributes.Public| System.Reflection.MethodAttributes.SpecialName | System.Reflection.MethodAttributes.HideBySig
                            
                            , 
            nullnew Type[] { typeof(string) });

                        methodBuilder.DefineParameter(
            0, System.Reflection.ParameterAttributes.Retval, null);
                        methodBuilder.DefineParameter(
            1, System.Reflection.ParameterAttributes.In, "name");
                        ILGenerator ilGenerator 
            = methodBuilder.GetILGenerator();

                        ilGenerator.Emit(OpCodes.Ldarg_1);
                        
            //System.Reflection.Assembly asmSystem = System.Reflection.Assembly.GetAssembly(typeof(MessageBox));
                        
            //Type typeMessageBox = asmSystem.GetType("MessageBox");
                        Type typeMessageBox = typeof(MessageBox);
                        System.Reflection.MethodInfo mInfoShow 
            = typeMessageBox.GetMethod("Show",new Type[]{typeof(string)}
                            
            //System.Reflection.BindingFlags.Public| System.Reflection.BindingFlags.Static,
                            );

                        ilGenerator.EmitCall(OpCodes.Call, mInfoShow, 
            null);

                        ilGenerator.Emit(OpCodes.Ret);

                        Type customType 
            = typeBuilder.CreateType();
                        
            object customeObj = Activator.CreateInstance(customType); ;

                        System.Reflection.MethodInfo methodInfo 
            = customType.GetMethod("CallMethod");
                        
            //customType.InvokeMember("CallMethod", System.Reflection.BindingFlags.Public, null, customeObj, new object[] { "123" });
                        
            //methodBuilder.Invoke(customeObj, new object[] { "123" });
                        methodInfo.Invoke(customeObj, new object[] { "11" });
                        Console.ReadLine();

            posted @ 2009-07-24 21:51 悟山 閱讀(896) | 評論 (1)編輯 收藏

            2009年6月22日 #

            [轉載]濾波和卷積的資料匯總

            原文地址:http://hi.baidu.com/niiuniu1127/blog/item/ba6e07fb28248e126d22eb8c.html

            什么叫濾波:用白話講就是,一個電信號中有若干種成分,把其中一部分交流信號過濾掉就叫濾波。

            卷積和濾波的區(qū)別:在數(shù)字信號處理的理論中,卷給可以說是一種數(shù)學運算,而濾波是一種信號處理的方法。卷積就像加權乘法一樣,你能說濾波和加權乘法是一樣的嗎,顯然不行;但是濾波最終是有乘法來實現(xiàn)的。

            自適應濾波就是濾波所用的模板系數(shù)會根據(jù)圖像不同位置自動調整。
            中值濾波(median filter)簡單的說就是:一個窗(window)中心的象素值就是這個窗包含的象素中處于中間位置的象素值。
            均值濾波(mean filter)就是一個窗中心的象素值就是這個窗包含的象素的平均值。
            空間頻率主要是指圖像的平滑或粗糙程度。一般可認為,高空間頻率區(qū)域稱“粗糙”,即圖像的亮度值在小范圍內變化很大,而“平滑”區(qū),圖像的亮度值變化相對較小,如平滑的水體表面等。低通濾波主要用于加強圖像中的低頻成分,減弱高頻成分,而高通濾波則正好相反,加強高頻細節(jié),減弱低頻細節(jié),簡單地講:高通濾波處理過的圖像更加“粗糙”。高通濾波顧名思義就是讓頻率高的通過,使圖像具有銳化效果;低通濾波則恰好相反了,它是使低頻通過,使圖像具有平滑的效果。


            •模板的定義 –所謂模板就是一個系數(shù)矩陣 –模板大小:經常是奇數(shù),如: 3x3   5x5   7x7 –模板系數(shù): 矩陣的元素 w1 w2 w3 w4 w5 w6 w7 w8 w9
            空域過濾及過濾器的定義:使用空域模板進行的圖像處理,被稱為空域過濾。

            w1 w2 w3
            w4 w5 w6
            w7 w8 w9

            模板本身被稱為空域過濾器
            空域過濾器的分類
            按效果分:鈍化過濾器,銳化過濾器
            按數(shù)學形態(tài)分類
            1,線性過濾器:使用乘積和的計算,例如:R = w1z1 + w2z2 + … + wnzn
            高通:邊緣增強、邊緣提取
            低通:鈍化圖像、去除噪音
            帶通:刪除特定頻率、增強中很少用
            2,非線性過濾器:結果值直接取決于像素鄰域的值
            最大值:尋找最亮點,亮化圖片
            最小值:尋找最暗點,暗化圖片
            中值:鈍化圖像、去除噪音


            鈍化過濾器的主要用途
            1,對大圖像處理前,刪去無用的細小細節(jié)
            2,連接中斷的線段和曲線
            3,降低噪音
            4,鈍化處理,恢復過分銳化的圖像
            5,圖像創(chuàng)藝(陰影、軟邊、朦朧效果)
            缺點:
            如果圖像處理的目的是去除噪音,那么,低通濾波在去除噪音的同時也鈍化了邊和尖銳的細節(jié),但是中值濾波算法的特點:在去除噪音的同時,可以比較好地保留邊的銳度和圖像的細節(jié)銳化過濾器的主要用途
            1,印刷中的細微層次強調。彌補掃描、掛網(wǎng)對圖像的鈍化
            2,超聲探測成象,分辨率低,邊緣模糊,通過銳化來改善
            3,圖像識別中,分割前的邊緣提取
            4,銳化處理恢復過度鈍化、暴光不足的圖像
            5,圖像創(chuàng)藝(只剩下邊界的特殊圖像)
            6,尖端武器的目標識別、定位

            過濾器效果的分析
            1,常數(shù)或變化平緩的區(qū)域,結果為0或很小,圖像很暗,亮度被降低了
            2,在暗的背景上邊緣被增強了
            3,圖像的整體對比度降低了
            4,計算時會出現(xiàn)負值,歸0處理為常見

            基本高通空域濾波的缺點和問題
            高通濾波在增強了邊的同時,丟失了圖像的層次和亮度

            posted @ 2009-06-22 15:28 悟山 閱讀(654) | 評論 (1)編輯 收藏

            2009年6月4日 #

            [轉載]WM_PAINT消息小結

            原文地址:http://dev.csdn.net/article/74/74935.shtm


            WM_PAINT是Windows窗口系統(tǒng)中一條重要的消息,應用程序通過處理該消息實現(xiàn)在窗口上的繪制工作。

            1. 系統(tǒng)何時發(fā)送WM_PAINT消息?

            系統(tǒng)會在多個不同的時機發(fā)送WM_PAINT消息:當?shù)谝淮蝿?chuàng)建一個窗口時,當改變窗口的大小時,當把窗口從另一個窗口背后移出時,當最大化或最小化窗口時,等等,這些動作都是由 系統(tǒng)管理的,應用只是被動地接收該消息,在消息處理函數(shù)中進行繪制操作;大多數(shù)的時候應用也需要能夠主動引發(fā)窗口中的繪制操作,比如當窗口顯示的數(shù)據(jù)改變的時候,這一般是通過InvalidateRect和 InvalidateRgn函數(shù)來完成的。InvalidateRect和InvalidateRgn把指定的區(qū)域加到窗口的Update Region中,當應用的消息隊列沒有其他消息時,如果窗口的Update Region不為空時,系統(tǒng)就會自動產生WM_PAINT消息。

            系統(tǒng)為什么不在調用Invalidate時發(fā)送WM_PAINT消息呢?又為什么非要等應用消息隊列為空時才發(fā)送WM_PAINT消息呢?這是因為系統(tǒng)把在窗口中的繪制操作當作一種低優(yōu)先級的操作,于是盡 可能地推后做。不過這樣也有利于提高繪制的效率:兩個WM_PAINT消息之間通過InvalidateRect和InvaliateRgn使之失效的區(qū)域就會被累加起來,然后在一個WM_PAINT消息中一次得到 更新,不僅能避免多次重復地更新同一區(qū)域,也優(yōu)化了應用的更新操作。像這種通過InvalidateRect和InvalidateRgn來使窗口區(qū)域無效,依賴于系統(tǒng)在合適的時機發(fā)送WM_PAINT消息的機 制實際上是一種異步工作方式,也就是說,在無效化窗口區(qū)域和發(fā)送WM_PAINT消息之間是有延遲的;有時候這種延遲并不是我們希望的,這時我們當然可以在無效化窗口區(qū)域后利用
            SendMessage 發(fā)送一條WM_PAINT消息來強制立即重畫
            【注解:SendMessage會block到被發(fā)送的消息被處理完才返回,但是WM_PAINT消息的處理時間又是用戶不可控制的:“GetMessage returns the WM_PAINT message when there are no other messages in the application's message queue, and DispatchMessage sends the message to the appropriate window procedure. ”(MSDN原文),那么也就是說,你調用SendMessage之后,這個方法需要等待多長時間才能返回是不可控制的。所以MSDN不推薦用戶直接發(fā)送WM_PAINT消息:“The WM_PAINT message is generated by the system and should not be sent by an application”】
            ,但不如使用Windows GDI為我們提供的更方便和強大的函數(shù):UpdateWindow和RedrawWindow。UpdateWindow會檢查窗口的Update Region,當其不為空時才發(fā)送WM_PAINT消息;RedrawWindow則給我們更多的控制:是否重畫非客戶區(qū)和背景,是否總是發(fā)送WM_PAINT消息而不管Update Region是否為空等。

            2. BeginPaint

            BeginPaint和WM_PAINT消息緊密相關。試一試在WM_PAINT處理函數(shù)中不寫B(tài)eginPaint會怎樣?程序會像進入了一個死循環(huán)一樣達到驚人的CPU占用率,你會發(fā)現(xiàn)程序總在處理一個接 一個的WM_PAINT消息。這是因為在通常情況下,當應用收到WM_PAINT消息時,窗口的Update Region都是非空的(如果為空就不需要發(fā)送WM_PAINT消息了),BeginPaint的一個作用就是把該Update Region置為空,這樣如果不調用BeginPaint,窗口的Update Region就一直不為空,如前所述,系統(tǒng)就會一直發(fā)送WM_PAINT消息。

            BeginPaint和WM_ERASEBKGND消息也有關系。當窗口的Update Region被標志為需要擦除背景時,BeginPaint會發(fā)送WM_ERASEBKGND消息來重畫背景,同時在其返回信息里有一個標志表明窗口背景是否被重畫過。當我們用InvalidateRect和InvalidateRgn來把指定區(qū)域加到Update Region中時,可以設置該區(qū)域是否需要被擦除背景,這樣下一個BeginPaint就知道是否需要發(fā)送WM_ERASEBKGND消息了。

            另外要注意的一點是,BeginPaint只能在WM_PAINT處理函數(shù)中使用。

            posted @ 2009-06-04 17:21 悟山 閱讀(447) | 評論 (0)編輯 收藏

            2009年5月28日 #

            [圖像處理]自適應局部圖像閾值處理(Adaptive Local Thresholding)

            將一副灰度圖像轉換為只包含為黑白兩色的二值圖像稱之為圖像的閾值處理;這種處理有多種方式,最簡單的就是設定一個靜態(tài)的閾值,色素值大于該閾值的為白,否則該值的為黑色。但是在很多時候,這種簡單的方法并不能得到很好的效果。在這篇文章里面我們介紹一種很簡單的局部自適應性圖像閾值化處理方法,該方法根據(jù)圖像局部特點動態(tài)的調整其閾值,能夠得到比較理想的閾值化處理效果。

            該方法的思想是首先將圖像分為一定大小的區(qū)塊,這個可以根據(jù)情況選用,比如你可以選擇3*3的矩陣,或者5*5的矩陣。選定好這些小塊之后,我們計算這個小塊中包圍了中心像素點的其他像素點(或者用戶也可以加其他的限定條件選擇像素點)的灰度值的某種統(tǒng)計信息,比如灰度均值,或者灰度中間值,或者最大灰度與最小灰度之間的均值作為中間像素點的閾值。如果中間像素點的灰度大于該閾值,則中間像素被轉換為白色點;反之,則轉換為黑色點。
            以ROUND(x)代表像素點x周圍的所有像素點,以函數(shù)Statistic(ROUND(x))表示對上述的這些像素點的灰度值做統(tǒng)計運算,那么我們的算法思想可以描述為:
                   1(x>Statistic(ROUND(x)))
            x={
                   0(x<=Statistic(ROUND(x)))

            在實際情況中,選用3*3的包圍矩陣和取均值的統(tǒng)計算法可以得到比較理想的處理效果(處理效果的圖片對比如下:
            原圖:


            處理后圖片:




            )。

            posted @ 2009-05-28 17:04 悟山 閱讀(1832) | 評論 (0)編輯 收藏

            2009年5月22日 #

            [轉載]淺析本機API

            原文地址:http://www.xfocus.net/articles/200503/782.html


            創(chuàng)建時間:2005-03-09
            文章屬性:轉載
            文章提交:cisocker (cisocker_at_163.com)

            by sunwear [E.S.T]  
            2004/10/02  
            shellcoder@163.com

            此文只能說是一篇筆記,是關于本機API的.本機API是除了Win32 API,NT平臺開放了另一個基本接口。本機API也被很多人所熟悉,因為內核模式模塊位于更低的系統(tǒng)級別,在那個級別上環(huán)境子系統(tǒng)是不可見的。盡管如此,并不需要驅動級別去訪問這個接口,普通的Win32程序可以在任何時候向下調用本機API。并沒有任何技術上的限制,只不過微軟不支持這種應用開發(fā)方法。  
                User32.dll,kernel32.dll,shell32.dll,gdi32.dll,rpcrt4.dll,comctl32.dll,advapi32.dll,version.dll等dll代表了Win32 API的基本提供者。Win32 API中的所有調用最終都轉向了ntdll.dll,再由它轉發(fā)至ntoskrnl.exe。ntdll.dll是本機 API用戶模式的終端。真正的接口在ntoskrnl.exe里完成。事實上,內核模式的驅動大部分時間調用這個模塊,如果它們請求系統(tǒng)服務。Ntdll.dll的主要作用就是讓內核函數(shù)的特定子集可以被用戶模式下運行的程序調用。Ntdll.dll通過軟件中斷int 2Eh進入ntoskrnl.exe,就是通過中斷門切換CPU特權級。比如kernel32.dll導出的函數(shù)DeviceIoControl()實際上調用ntdll.dll中導出的NtDeviceIoControlFile(),反匯編一下這個函數(shù)可以看到,EAX載入magic數(shù)0x38,實際上是系統(tǒng)調用號,然后EDX指向堆棧。目標地址是當前堆棧指針ESP+4,所以EDX指向返回地址后面一個,也就是指向在進入NtDeviceIoControlFile()之前存入堆棧的東西。事實上就是函數(shù)的參數(shù)。下一個指令是int 2Eh,轉到中斷描述符表IDT位置0x2E處的中斷處理程序。

            反編匯這個函數(shù)得到:

            mov eax, 38h

            lea edx, [esp+4]

            int 2Eh

            ret 28h

            當然int 2E接口不僅僅是簡單的API調用調度員,他是從用戶模式進入內核模式的main gate。

            W2k Native API由248個這么處理的函數(shù)組成,比NT 4.0多了37個。可以從ntdll.dll的導出列表中很容易認出來:前綴Nt。Ntdll.dll中導出了249個,原因在于NtCurrentTeb()為一個純用戶模式函數(shù),所以不需要傳給內核。令人驚奇的是,僅僅Native API的一個子集能夠從內核模式調用。而另一方面,ntoskrnl.exe導出了兩個Nt*符號,它們不存在于ntdll.dll中: NtBuildNumber, NtGlobalFlag。它們不指向函數(shù),事實上,是指向ntoskrnl.exe的變量,可以被使用C編譯器extern關鍵字的驅動模塊導入。Ntdll.dll和ntoskrnl.exe中都有兩種前綴Nt*,Zw*。事實上ntdll.dll中反匯編結果兩者是一樣的。而在ntoskrnl.exe中,nt前綴指向真正的代碼,而zw還是一個int 2Eh的stub。也就是說zw*函數(shù)集通過用戶模式到內核模式門傳遞的,而Nt*符號直接指向模式切換以后的代碼。Ntdll.dll中的NtCurrentTeb()沒有相對應的zw函數(shù)。Ntoskrnl并不導出配對的Nt/zw函數(shù)。有些函數(shù)只以一種方式出現(xiàn)。

            2Eh中斷處理程序把EAX里的值作為查找表中的索引,去找到最終的目標函數(shù)。這個表就是系統(tǒng)服務表SST,C的結構SYSTEM_SERVICE_TABLE的定義如下:清單也包含了結構SERVICE_DESCRIPTOR_TABLE中的定義,為SST數(shù)組第四個成員,前兩個有著特別的用途。

            typedef NTSTATUS (NTAPI *NTPROC) ( ) ;

            typedef NTPROC *PNTPROC;

            #define NTPROC_ sizeof (NTPROC)

            typedef struct _SYSTEM_SERVICE_TABLE

            { PNTPROC ServiceTable; // 這里是入口指針數(shù)組

            PDWORD CounterTable; // 此處是調用次數(shù)計數(shù)數(shù)組

            DWORD ServiceLimit ; // 服務入口的個數(shù)

            PBYTE ArgumentTable; // 服務參數(shù)字節(jié)數(shù)的數(shù)組

            ) SYSTEM_SERVICE_TABLE ,

            * PSYSTEM_SERVICE_TABLE ,

            * * PPSYSTEM_SERVICE_TABLE ;

            / / _ _ _ _ _ _ _ _ _ _ _ _

            typedef struct _SERVICE_DESCRIPTOR_TABLE

            { SYSTEM_SERVICE_TABLE ntoskrnl ; // ntoskrnl所實現(xiàn)的系統(tǒng)服務,本機的API}

            SYSTEM_SERVICE_TABLE win32k; // win32k所實現(xiàn)的系統(tǒng)服務

            SYSTEM_SERVICE_TABLE Table3; // 未使用

            SYSTEM_SERVICE_TABLE Table4; // 未使用

            } SERVICE_DESCRIPTOR_TABLE ,

            * PSERVICE_DESCRIPTOR_TABLE,

            * PPSERVICE_DESCRIPTOR_TABLE ;

            ntoskrnl通過KeServiceDescriptorTable符號,導出了主要SDT的一個指針。內核維護另外的一個SDT,就是KeServiceDescriptorTableShadow。但這個符號沒有導出。要想在內核模式組件中存取主要SDT很簡單,只需兩行C語言的代碼:

            extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;

            PSERVICE_DESCRIPTOR_TABLE psdt= KeServiceDescriptorTable;

            NTPROC為本機 API的方便的占位符,他類似于Win32編程中的PROC。Native API正常的返回應該是一個NTSTATUS代碼,他使用NTAPI調用約定,它和_stdcall一樣。ServiceLimit成員有在ServiceTable數(shù)組里找到的入口數(shù)目。在2000下,默認值是248。ArgumentTable為BYTEs的數(shù)組,每一個對應于ServiceTable的位置并顯示了在調用者堆棧里的參數(shù)比特數(shù)。這個信息與EDX結合,這是內核從調用者堆棧copy參數(shù)到自己的堆棧所需的。CounterTable成員在free buid的2000中并沒有使用到,在debug build中,這個成員指向代表所有函數(shù)使用計數(shù)的DWORDS數(shù)組,這個信息能用于性能分析。
                可以使用這個命令來顯示:dd KeServiceDescriptorTable,調試器把此符號解析為0x8046e0c0。只有前四行是最重要的,對應那四個SDT成員。
                運行這個命令:ln 8046e100,顯示符號是KeServiceDescriptorTableShadow,說明第五個開始確實為內核維護的第二個SDT。主要的區(qū)別在于后一個包含了win32k.sys的入口,前一個卻沒有。在這兩個表中,Table3與Table4都是空的。Ntoskrnl.exe提供了一個方便的API函數(shù)。這個函數(shù)的名字為:

                KeAddSystemServiceTable
            此函數(shù)去填充這些位置。

            2Eh的中斷處理標記是KisystemService()。這也是ntoskrnl.exe沒有導出的內部的符號,但包含在2k符號文件中。關于KisystemService的操作如下:

            1 從當前的線程控制塊檢索SDT指針

            2 決定使用SDT中4個SST的其中一個。通過測試EAX中遞送ID的第12和13位來決定。ID在0x0000-0x0fff的映射至ntoskrnl表格,ID在

            0x1000與0x1ffff的分配給win32k表格。剩下的0x2000-0x2ffff與

            0x3000-0x3ffff則是Table3和Table4保留。

            3 通過選定SST中的ServiceLimit成員檢查EAX的0-11位。如果ID超過了范圍,返回錯誤代碼為STATUS_INVALID_SYSTEM_SERVICE。

            4 檢查EAX中的參數(shù)堆棧指針與MmUserProbeAddress。這是一個ntoskrnl導出的全局變量。通常等于0x7FFF0000,如果參數(shù)指針不在這個地址之下,返回STATUS_ACCESS_VIOLATION。

            5 查找ArgumentTable中的參數(shù)堆棧的字節(jié)數(shù),從調用者的堆棧copy所有的參數(shù)至當前內核模式堆棧。

            6 搜索serviceTable中的服務函數(shù)指針,并調用這個函數(shù)。

            7 控制轉到內部的函數(shù)KiserviceExit,在此次服務調用返回之后。

            從對SDT的討論可以看到與本機API一起還有第二個內核模式接口。這個接口把Win32子系統(tǒng)的圖形設備接口和窗口管理器和內核模式組件Win32k連接起來。Win32k接口一樣是基于int 2eh。本機API的服務號是從0x0000到0x0fff,win32k的服務號是從0x1000到0x1fff。(ddW32pServiceTable認定win32k.sys的符號可用。)win32k總共包含639個系統(tǒng)服務。


            2Eh的處理過程沒有使用全局SDT KeServiceDescriptorTable。

            而是一個與線程相關的指針。顯然,線程可以有不同得SDT相關到自身。線程初試化的時候,KeInitializeThread()把KeServiceDescriptorTable寫到線程的控制塊。盡管這樣,這個默認設置之后可能被改變?yōu)槠渌担鏚eServiceDescriptorTableShadow。


            Windows 2000運行時庫

            Ntdll.dll至少導出了不少于1179個符號。其中的249/248是屬于Nt*/zw*集合。所以還有682個函數(shù)不是通過int 2eh門中轉。很顯然,這么多的函數(shù)不依靠2k的內核。

            其中一些是和c運行時庫幾乎一樣的函數(shù)。其實ntoskrnl也實現(xiàn)了一些類似C運行時庫的一些函數(shù)。可以通過ddk里的ntdll.lib來鏈接和使用這些函數(shù)。反匯編ntdll.dll與ntoskrnl.exe的C運行時函數(shù)能發(fā)現(xiàn),ntdll.dll并不是依賴ntoskrnl.exe。這兩個模塊各自實現(xiàn)了這些函數(shù)。

            除了C運行時庫外,2000還提供了一個擴展的運行時函數(shù)集合。再一次,ntdll.dll與ntoskrnl.exe各自實現(xiàn)了它們。同樣,實現(xiàn)集合有重復,但是并不完全匹配。這個集合的函數(shù)都是以Rtl開頭的。2000運行時庫包括一些輔助函數(shù)用于C運行時候無法完成的任務。例如有些處理安全事務,另外的操縱2000專用的數(shù)據(jù)結構,還有些支持內存管理。微軟僅僅在DDK中記錄了很有用的406個函數(shù)中的115個函數(shù)。

            Ntdll.dll還提供了另外一個函數(shù)集合,以__e前綴開頭。實際上它們用于浮點數(shù)模擬器。

            還有很多的函數(shù)集合,所有這些函數(shù)的前綴如下:

            __e(浮點模擬),Cc(Cache管理),Csr(c/s運行時庫),Dbg(調試支持),Ex(執(zhí)行支持),FsRtl(文件系統(tǒng)運行時),Hal(硬件抽象層),Inbv(系統(tǒng)初試化/vga啟動驅動程序bootvid.dll),Init(系統(tǒng)初試化),Interlocked(線程安全變量操作),Io(IO管理器),Kd(內核調試器支持),Ke(內核例程),Ki(內核中斷處理),Ldr(映象裝載器),Lpc(本地過程調用),Lsa(本地安全授權),Mm(內存管理),Nls(國際化語言支持),Nt(NT本機API),Ob(對象管理器),Pfx(前綴處理),Po(電源管理),Ps(進程支持),READ_REGISTER_(從寄存器地址讀),Rtl(2k運行時庫),Se(安全處理),WRITE_REGISTER_(寫寄存器地址),Zw(本機API的替換叫法),<其它>(輔助函數(shù)和C運行時庫)。

            當編寫從用戶模式通過ntdll.dll或內核模式通過ntoskrnl.exe和2000內核交互的軟件的時候,需要處理很多基本的數(shù)據(jù)結構,這些結構在Win32世界中很少見到。

            常用數(shù)據(jù)結構

            l     整數(shù)

            ANSI字符是有符號的,而Unicode WCHAR是無符號的

            MASM的TBYTE是80位的浮點數(shù),用于高精度浮點運算單元操作,注意它與Win32的TBYTE(text byte)完全不同。

            TABLE 2-3. Equivalent Integral Data Types

            BITS    MASM   FUNDAMENTAL    ALIAS #1    ALIAS #2  SIGNED

            8       BYTE    unsigned char  UCHAR                 CHAR
            16      WORD    unsigned short USHORT     WCHAR      SHORT

            32      DWORD   unsigned long  ULONG                 LONG

            32      DWORD   unsigned int    UINT                 INT

            64      QWORD   unsigned _int64 ULONGLONG DWORDLONG LONGLONG

            80      TBYTE    N/A

            typedef union _LARGE_INTEGER

            {  struct{

            ULONG LowPart;

            LONG HighPart;};

            LONGLONG QuadPart;

            }

            LARGE_INTEGER , * PULARGE_INTEGER ;

            typedef union _ULARGE_INTEGER{

            struct{

            ULONG LowPart;

            ULONG HighPart;}

            ULONGLONG QuadPart;

            }ULARGE_INTEGER, *PULARGE_INTEGER;

            l     字符

                Win32編程中PSTR用戶CHAR*,PWSTR用于WCHAR*。取決于是否定義了UNICODE,PTSTR解釋為PSTR或者PWSTR。在2k內核模式下,常用的數(shù)據(jù)類型是UNICODE_STRING,而STRING用來表示ANSI字符串:

            typedef struct _UNICODE_STRING{

            USHORT Length; //當前字節(jié)長度,不是字符!!!

            USHORT MaximumLength; //Buffer的最大字節(jié)長度

            PWSTR Buffer;}UNICODE_STRING , * PUNICODE_STRING ;

            typedef struct _STRING{

            USHORT Length;

            USHORT MaximumLength;

            PCHAR Buffer;}STRING, *PSTRING;

            typedef STRING ANSI_STRING, *PANSI_STRING;

            typedef STRING OEM_STRING, *POEM_STRING;

              操縱函數(shù):RtlCreatUnicodeString(),RtlInitUnicodeString(),

            RtlCopyUnicodeString()等等

            l     結構

            許多內核API函數(shù)需要一個固定大小的OBJECT_ATTRIBUTES結構,比如NtOpenFile()。對象的屬性是OBJ_*值的組合,可以從ntdef.h中查到。

            IO_STATUS_BLOCK結構提供了所請求操作結果的信息,很簡單,status成員包含一個NTSTATUS代碼, 如果操作成功 information成員提供特定請求的信息。

            還有一個結構是LIST_ENTRY,這是一個雙向環(huán)鏈表。

            typedef struct _OBJECT_ATTRIBUTES

            {

            ULONG Length;

            HANDLE RootDirectory;

            PUNICODE_STRING ObjectName;

            ULONG Attributes;

            PVOID SecurityDescriptor;

            PVOID SecurityQualityOfService;

            } OBJECT_ATTRIBDTES, *POBJECT_ ATTRIBUTES;

            typedef struct _IO_STATUS_BLOCK

            {

            NTSTATDS Status;

            ULONG Information;

            }IO_STATUS_BLOCK , * PIO_STATUS_BLOCK ;

            typedef struct _LIST_ENTRY

            {

            Struct _LIST_ENTRY *Flink;

            Struct _LIST_ENTRY *Blink;

            }LIST_ENTRY, *PLIST_ENTRY;

            雙向鏈表的典型例子就是進程和線程鏈。內部變量PsActiveProcessHead是一個LIST_ENTRY結構,在ntoskrnl.exe的數(shù)據(jù)段中,指定了系統(tǒng)進程列表的第一個成員。

            CLIENT_ID結構由進程和線程ID組成。

            typedef struct _CLIENT_ID

            { HANDLE UniqueProcess;

            HANDLE UniqueThread;

            )CLIENT_ID, *PCLIENT_ID;

            想要從用戶模式調用ntdll.dll中的API函數(shù),必須考慮到以下四點:

            1 SDK頭文件沒有包括這些函數(shù)的原型

            2 這些函數(shù)使用的若干基本數(shù)據(jù)類型沒有包括在SDK文件中

            3 SDK和DDK頭文件不兼容,不能在win32的c源文件包含ntddk.h中

            4 ntdll.lib沒有包括在VC的默認導入庫列表中。

            第4個很容易解決:#progma comment(linker,“/defaultlib:ntdll.lib”)

            缺失的定義比較難解決,最簡單的方法是寫一個自定義的頭文件,剛剛包含需要調用ntdll.dll中函數(shù)的定義。幸運的是,已經在光盤的w2k_def.h文件中做了這個工作。因為這個頭文件將用于用戶模式和內核模式程序,所以必須在用戶模式代碼中,#include<w2k_def.h>之前#define _USER_MODE_,使得DDK中出現(xiàn)而SDK中沒有的定義可用。


            本文部分翻譯于一篇電子書<win api about>.也感謝朋友GameHunter這位英語極好的朋友幫忙.與Free的指導

            posted @ 2009-05-22 18:43 悟山 閱讀(213) | 評論 (0)編輯 收藏

            [C#學習筆記]在Vista或者Server2008下以Admin模式啟動程序

            原文(參考文章)鏈接:http://www.codeproject.com/KB/vista-security/UAC_Shield_for_Elevation.aspx

            Vista和Windows Server 2008上面系統(tǒng)的UAC(User Account Control)默認是開啟的,用戶在一般情況下并通過雙擊啟動程序都不是以管理員模式運行。但是,在很多情況下,為了在程序里面訪問系統(tǒng)的某些特定資源,需要當前程序的identity具有admin的權限。那么這就需要涉及到檢測當前程序的執(zhí)行用戶是否處于管理員模式,在當前程序不處于admin模式的情況以admin模式下重啟程序。

            參考了http://www.codeproject.com/KB/vista-security/UAC_Shield_for_Elevation.aspx這篇文章,做如下學習筆記。

            為了檢測當前進程的之行用戶是否是管理員,需要用到CLR種System.Security.Principal名稱空間種的WindowsIdentity類和WindowsPrincipal類。下面是代碼,很好理解:

            static bool IsAdmin()
                    
            {
                        WindowsIdentity identity 
            = WindowsIdentity.GetCurrent();
                        WindowsPrincipal principle 
            = new WindowsPrincipal(identity);
                        
            return principle.IsInRole(WindowsBuiltInRole.Administrator);
                    }

            如果當前進程不是處于管理員模式,那么我們可以重啟這個程序。為了重啟程序使用了System.Diagnostics名稱空間下的Process類,Process類調用命令行下的"runas"命令,以管理員模式重新啟動當前程序。代碼如下,也很好理解:

             static void RestartProcessElevated()
                    
            {
                        ProcessStartInfo info 
            = new ProcessStartInfo();
                        info.UseShellExecute 
            = true;
                        info.WorkingDirectory 
            = Environment.CurrentDirectory;
                        info.FileName 
            = System.Windows.Forms.Application.ExecutablePath;
                        info.Verb 
            = "runas";
                        
            try
                        
            {
                            Process.Start(info);
                        }

                        
            catch (System.ComponentModel.Win32Exception ex)
                        
            {
                            Console.WriteLine(
            "Exception:{0}", ex.Message);
                            
            return;
                        }


                        System.Windows.Forms.Application.Exit();
                    }

            posted @ 2009-05-22 18:36 悟山 閱讀(362) | 評論 (0)編輯 收藏

            2009年5月21日 #

            [轉載]解剖XP最核心的dll——NTDLL.dll

            原文地址:2.利用GetProcAddress 獲取其函數(shù)入口地址
            3.利用得到的函數(shù)指針調用

            但是可以大致的分為幾類吧
            1 PropertyLengthAsVariant  它被排在了第一號,但是我就是不明白它是做什么的
            2  Csr(configuration status register? Command and Status Register?)系列  
            CsrAllocateCaptureBuffer CsrAllocateMessagePointer CsrCaptureMessageBuffer CsrCaptureMessageMultiUnicodeStringsInPlace 
            CsrCaptureMessageString CsrCaptureTimeout CsrClientCallServer CsrClientConnectToServer CsrFreeCaptureBuffer 
            CsrGetProcessId CsrIdentifyAlertableThread CsrNewThread CsrProbeForRead CsrProbeForWrite CsrSetPriorityClass

            3 Dbg系列 調試函數(shù)
            DbgBreakPoint DbgPrint DbgPrintEx DbgPrintReturnControlC DbgPrompt DbgQueryDebugFilterState DbgSetDebugFilterState 
            DbgUiConnectToDbg DbgUiContinue DbgUiConvertStateChangeStructure DbgUiDebugActiveProcess DbgUiGetThreadDebugObject 
            DbgUiIssueRemoteBreakin DbgUiRemoteBreakin DbgUiSetThreadDebugObject DbgUiStopDebugging DbgUiWaitStateChange DbgUserBreakPoint

            4 ki系列
            KiRaiseUserExceptionDispatcher
            KiUserApcDispatcher
            KiUserCallbackDispatcher
            KiUserExceptionDispatcher

            5 Ldr系列  Loader APIs,共34個

            API
            NTDLL APIs
            LoadResource
            LdrAccessResource
            LdrAlternateResourcesEnabled
            DisableThreadLibraryCalls
            LdrDisableThreadCalloutsForDll
            LdrEnumResources
            LdrFindAppCompatVariableInfo
            LdrFindEntryForAddress
            EnumResourceTypesW
            LdrFindResourceDirectory_U
            FindResourceExA
            LdrFindResource_U
            LdrFlushAlternateResourceModules
            LdrGetAlternateResourceModuleHandle
            GetModuleHandleForUnicodeString
            LdrGetDllHandle
            GetProcAddress
            LdrGetProcedureAddress
            LdrInitializeThunk
            LoadLibraryEx (LOAD_LIBRARY_AS_DATAFILE)
            LdrLoadAlternateResourceModule
            LoadLibrary
            LdrLoadDll
            LdrProcessRelocationBlock
            LdrQueryApplicationCompatibilityGoo
            LdrQueryImageFileExecutionOptions
            LdrQueryProcessModuleInformation
            LdrRelocateImage
            ExitProcess
            LdrShutdownProcess
            ExitThread
            LdrShutdownThread
            LdrUnloadAlternateResourceModule
            FreeLibrary
            LdrUnloadDll
            LdrVerifyImageMatchesChecksum
            LdrVerifyMappedImageMatchesChecksum


            6 Nls(National Language Support)系列  代碼頁管理 
            NlsAnsiCodePage
            NlsMbCodePageTag
            NlsMbOemCodePageTag

            7 Nt系列 共285個,大部分都是kernel32.dll,user32.dll等的核心實現(xiàn)

            NtCreateFile, NtOpenFile, NtClose, NtWaitForSingleObject 是kernel32.dll中許多用戶級代碼的核心實現(xiàn)。

            NTSTATUS NtClose( HANDLE  Handle);
            竟然是CloseHandle 的原身!唯一的缺點是該函數(shù)并沒有導出庫,如果要調用,就必須使用GetProcAddress 來獲得其函數(shù)指針然后調用。

            NtCreateFile  可以說是DDK的核心

            RtlUnwind initiates an unwind of procedure call frames 
            結構化異常(Structured Exception Handling, SEH )的 核心。

            NTSTATUS NtWaitForSingleObject(  HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout);
            Waits until the specified object attains a state of signaled
            我想,信號同步等,應該與之有莫大的聯(lián)系吧

            8 pfx 不明白
            PfxFindPrefix
            PfxInitialize
            PfxInsertPrefix
            PfxRemovePrefix

            9 RestoreEm87Context SaveEm87Context

            10 rtl系列 共506個。我想,rtl應該是runtime library的縮寫吧。一個很龐大的函數(shù)族,
            里面包含像 RtlCreateUserProcess 這樣的一些很基本的函數(shù),通常供內核模式的driver等調用
            下面是一部分示例
            APIs Forwarded to NTDLL

            API
            Destination
            DeleteCriticalSection
            Forwarded to NTDLL.RtlDeleteCriticalSection
            EnterCriticalSection
            Forwarded to NTDLL.RtlEnterCriticalSection
            HeapAlloc
            Forwarded to NTDLL.RtlAllocateHeap
            HeapFree
            Forwarded to NTDLL.RtlFreeHeap
            HeapReAlloc
            Forwarded to NTDLL.RtlReAllocateHeap
            HeapSize
            Forwarded to NTDLL.RtlSizeHeap
            LeaveCriticalSection
            Forwarded to NTDLL.RtlLeaveCriticalSection
            RtlFillMemory
            Forwarded to NTDLL.RtlFillMemory
            RtlMoveMemory
            Forwarded to NTDLL.RtlMoveMemory
            RtlUnwind
            Forwarded to NTDLL.RtlUnwind
            RtlZeroMemory
            Forwarded to NTDLL.RtlZeroMemory
            SetCriticalSectionSpinCount
            Forwarded to NTDLL.RtlSetCriticalSection- SpinCount
            TryEnterCriticalSection
            Forwarded to NTDLL.RtlTryEnterCriticalSection
            VerSetConditionMask
            Forwarded to NTDLL.VerSetConditionMask

            11 VerSetConditionMask 用于確認系統(tǒng)信息
            The VerSetConditionMask function sets the bits of a 64-bit value to indicate the comparison operator to use for a specified operating system version attribute. 
            This function is used to build the dwlConditionMask parameter of the VerifyVersionInfo function.

            12 Zw系列 共284個。前面已經說過,為可執(zhí)行性系統(tǒng)服務提供內核模式的入口, 為NTOSKRNL.EXE 提供實現(xiàn)。由于是內核模式,所以在執(zhí)行的時候并不檢查用戶是否有執(zhí)行權限
            13 內部函數(shù) 共116個。具體作用不明,很底層的東西。無法查到任何相關資料。無法得知與其相關的任何信息。
            _CIcos 
            _CIlog 
            _CIpow 
            _CIsin 
            _CIsqrt 
            __eCommonExceptions 
            __eEmulatorInit 
            __eF2XM1 
            __eFABS 
            __eFADD32 
            __eFADD64 
            __eFADDPreg 
            __eFADDreg 
            __eFADDtop 
            __eFCHS 
            __eFCOM 
            __eFCOM32 
            __eFCOM64 
            __eFCOMP 
            __eFCOMP32 
            __eFCOMP64 
            __eFCOMPP 
            __eFCOS 
            __eFDECSTP 
            __eFDIV32 
            __eFDIV64 
            __eFDIVPreg 
            __eFDIVR32 
            __eFDIVR64 
            __eFDIVRPreg 
            __eFDIVRreg 
            __eFDIVRtop 
            __eFDIVreg 
            __eFDIVtop 
            __eFFREE 
            __eFIADD16 
            __eFIADD32 
            __eFICOM16 
            __eFICOM32 
            __eFICOMP16 
            __eFICOMP32 
            __eFIDIV16 
            __eFIDIV32 
            __eFIDIVR16 
            __eFIDIVR32 
            __eFILD16 
            __eFILD32 
            __eFILD64 
            __eFIMUL16 
            __eFIMUL32 
            __eFINCSTP 
            __eFINIT 
            __eFIST16 
            __eFIST32 
            __eFISTP16 
            __eFISTP32 
            __eFISTP64 
            __eFISUB16 
            __eFISUB32 
            __eFISUBR16 
            __eFISUBR32 
            __eFLD1 
            __eFLD32 
            __eFLD64 
            __eFLD80 
            __eFLDCW 
            __eFLDENV 
            __eFLDL2E 
            __eFLDLN2 
            __eFLDPI 
            __eFLDZ 
            __eFMUL32 
            __eFMUL64 
            __eFMULPreg 
            __eFMULreg 
            __eFMULtop 
            __eFPATAN 
            __eFPREM 
            __eFPREM1 
            __eFPTAN 
            __eFRNDINT 
            __eFRSTOR 
            __eFSAVE __eFSCALE __eFSIN __eFSQRT __eFST __eFST32 __eFST64 __eFSTCW __eFSTENV __eFSTP __eFSTP32 __eFSTP64 __eFSTP80
             __eFSTSW __eFSUB32 __eFSUB64 __eFSUBPreg __eFSUBR32 __eFSUBR64 __eFSUBRPreg __eFSUBRreg __eFSUBRtop __eFSUBreg __eFSUBtop
             __eFTST __eFUCOM __eFUCOMP __eFUCOMPP __eFXAM __eFXCH __eFXTRACT __eFYL2X __eFYL2XP1 __eGetStatusWord 

            14 一些CRT的基本函數(shù) 共131個 主要是字符串管理,還有些基本的數(shù)學函數(shù)
            __isascii __iscsym __iscsymf __toascii _alldiv _alldvrm _allmul _alloca_probe _allrem _allshl _allshr _atoi64 _aulldiv _aulldvrm _aullrem _aullshr _chkstk _fltused 
            _ftol _i64toa _i64tow _itoa _itow _lfind _ltoa _ltow _memccpy _memicmp _snprintf _snwprintf _splitpath _strcmpi _stricmp _strlwr _strnicmp _strupr _tolower 
            _toupper _ui64toa _ui64tow _ultoa _ultow _vsnprintf _vsnwprintf _wcsicmp _wcslwr _wcsnicmp _wcsupr _wtoi _wtoi64 _wtol abs atan atoi atol bsearch ceil 
            cos fabs floor isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper iswalpha iswctype iswdigit iswlower iswspace iswxdigit isxdigit labs log 
            mbstowcs memchr memcmp memcpy memmove memset pow qsort sin sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk 
            strrchr strspn strstr strtol strtoul swprintf tan tolower toupper towlower towupper vDbgPrintEx vDbgPrintExWithPrefix vsprintf wcscat wcschr wcscmp wcscpy 
            wcscspn wcslen wcsncat wcsncmp wcsncpy wcspbrk wcsrchr wcsspn wcsstr wcstol wcstombs wcstoul

            posted @ 2009-05-21 15:23 悟山 閱讀(1165) | 評論 (0)編輯 收藏

            僅列出標題  下一頁
            国产精品中文久久久久久久| 久久久久久狠狠丁香| 久久国产精品久久| 日本久久久久亚洲中字幕| 亚洲国产另类久久久精品小说| 四虎亚洲国产成人久久精品| 国产午夜精品理论片久久| 久久国产精品一区| 色婷婷久久久SWAG精品| 欧美性猛交xxxx免费看久久久| 青青热久久国产久精品| 精品伊人久久久| 久久精品国产99国产精品导航| 狠狠色丁香久久婷婷综合| 亚洲va久久久噜噜噜久久天堂| 色诱久久久久综合网ywww| 久久精品aⅴ无码中文字字幕不卡| 99国产欧美久久久精品蜜芽| 国产亚洲精品美女久久久| 久久精品视频网| 性做久久久久久久久久久| 麻豆AV一区二区三区久久| 色综合久久中文色婷婷| 久久成人国产精品一区二区| 久久精品成人欧美大片| 狠狠色综合网站久久久久久久| 国产精品99久久久久久www| 久久最新免费视频| 亚洲中文字幕久久精品无码APP| 久久丫精品国产亚洲av| 久久99国产一区二区三区| 五月丁香综合激情六月久久| 情人伊人久久综合亚洲| 免费久久人人爽人人爽av| 久久久国产精品网站| 亚洲另类欧美综合久久图片区| 91精品国产综合久久久久久| 亚洲伊人久久成综合人影院| 久久久久无码精品国产| 久久久久九国产精品| 91精品国产综合久久久久久|