• <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>
            幽幽
             
            posts - 51,  comments - 28,  trackbacks - 0
              daemon進程是后臺守護進程,有時候也叫精靈進程(agent).linux 下server都是daemon進程。相信大部分開發(fā)人員都知道如何去寫一個daemon進程。但是另一方面,大部分人不知道為什么要這么做,不少人是從某個地方copy一個函數(shù),拿來主義。但是具體為什么這么實現(xiàn),卻不是很透徹。
              見過一些面試官或被面試人。很多人解釋daemon進程存在的理由是因為僵死進程。或者輸入輸出。其實和這些東西一毛錢關系都沒有。daemon函數(shù)存在的原因是因為控制終端由于某些原因(如斷開終端鏈接)會發(fā)送一些信號的原因。而接收進城處理這些信號缺省動作會讓進程退出。這些信號會由于終端上敲一些特殊按鍵而產(chǎn)生。

              貼一個daemon函數(shù)常見的實現(xiàn):
             1 int daemon(void)
             2 {
             3     pid_t pid = fork();
             4 
             5     if( pid != 0 ) exit(0);//parent
             6 
             7     //first children
             8     if(setsid() == -1)
             9     {
            10        printf("setsid failed\n");
            11        assert(0);
            12        exit(-1);
            13     }
            14 
            15     umask(0);
            16 
            17 
            18     pid = fork();
            19 
            20     if( pid != 0) exit(0);
            21   
            22     //second children 
            23     chdir ("/");
            24 
            25     for (int i = 0; i < 3; i++)
            26     {
            27         close (i);
            28     }
            29 
            30 
            31     int stdfd = open ("/dev/null", O_RDWR);
            32     dup2(stdfd, STDOUT_FILENO);
            33     dup2(stdfd, STDERR_FILENO);
            34 
            35     return 0;
            36 }
            37 

                1 、第一次fork的作用是讓shell 認為本條命令 已經(jīng)終止,不用掛在終端輸入上。還有一個作用是為后面setsid服務。setsid的調(diào)用者不能是進程組組長(group leader). 此時父進程是進程組組長。
                
                2 、setsid() 是本函數(shù)最重要的一個調(diào)用。它完成了daemon函數(shù)想要做的大部分事情。調(diào)用完整個函數(shù)。子進程是會話組長(sid==pid),也是進程組組長(pgid == pid),并且脫離了原來控制終端。到了這一步,基本上不管控制終端如何怎么樣。新的進程都不會收到那些信號。
                3  、經(jīng)過前面2個步驟,基本想要做的都做了。第2次fork不是必須的。也看到很多開源服務沒有fork第二次。fork第二次主要目的是。防止進程再次打開一個控制終端。因為打開一個控制終端的前臺條件是該進程必須是會話組長。再fork一次,子進程ID != sid(sid是進程父進程的sid)。所以也無法打開新的控制終端。
                daemon目的就是防止終端產(chǎn)生的一些信號讓進程退出。上面函數(shù)并沒有直接調(diào)用signal函數(shù)去處理它。而是間接通過fork和setsid函數(shù)使用更少代碼優(yōu)雅處理。而被有些人誤以為是僵死進程的原因需要這樣處理。
                當然,也有很多程序不是像上面函數(shù)那樣去實現(xiàn)。而是直接通過忽略信號方式處理。這樣其實也不錯,因為這些信號很少會有用到的價值。直接忽略基本上不存在誤殺的情況。反正達到最終目的就可以。條條大路通羅馬。
               下面羅列一下控制終端會產(chǎn)生哪些信號。程序中只要處理好這些信號,同樣能達到上面函數(shù)實現(xiàn)的目的。
               //后臺進程讀取/寫入終端輸入產(chǎn)生下面兩個信號,或者控制終端不存在情況讀取和寫入會產(chǎn)生
               signal(SIGTTOU, SIG_IGN);
               signal(SIGTTIN, SIG_IGN);
               //按CTRL-C ,CTRL-\ CTRL-Z會向前臺進程組發(fā)送下面這些信號
               signal(SIGINT,  SIG_IGN );
               signal(SIGQUIT, SIG_IGN );
               signal(SIGTSTP, SIG_IGN );
               
               //終端斷開,會給會話組長或孤兒進程組所有成員發(fā)送下面信號
               signal(SIGHUP,  SIG_IGN );
               還有有些信號也可以由終端shell產(chǎn)生,需要關注
               signal(SIGCONT, SIG_IGN );
               signal(SIGSTOP, SIG_IGN );
              上面這些信號,應該有些程序缺省處理(SIG_DFL)本身動作就是忽略(SIG_IGN),不是退出進程。不過按照上面寫也不會造成什么問題。
            posted @ 2014-10-10 14:15 幽幽 閱讀(395) | 評論 (0)編輯 收藏
                 摘要:     11.在COM組件中調(diào)用JavaScript函數(shù)  2// 連接點方式頁面javascript腳本  3<object classid="CLSID:B568F111-DFE4-4944-B67F-0728AB2AB30F" id="testCom" VIEWASTEXT&...  閱讀全文
            posted @ 2010-10-09 03:21 幽幽 閱讀(3441) | 評論 (2)編輯 收藏
              
            轉自 http://www.shnenglu.com/Zezese/archive/2010/07/25/121247.html?opt=admin

            1 
              2 
              3 
              4 
              5 template <class R, class P1, class P2>
              6 class IDelegate
              7 {
              8 public:
              9     virtual R Invoke(P1, P2) = 0;
             10 };
             11 
             12 
             13 template <class T, class R, class P1, class P2>
             14 class CDelegate : public IDelegate<R, P1, P2>
             15 {
             16 protected:
             17 
             18     typedef R (T::*pfnHandle)(P1, P2);
             19 
             20     const pfnHandle m_pfn;
             21 
             22     T* const m_pThis;
             23 
             24 public:
             25 
             26     CDelegate(T* const pThis, const pfnHandle pfn)
             27         :m_pThis(pThis), m_pfn(pfn)
             28     {
             29         if (m_pThis == NULL || m_pfn == NULL)
             30         {
             31             throw;
             32         } 
             33     }
             34 
             35     virtual R Invoke(P1 p1, P2 p2)
             36     {
             37         return (m_pThis->*m_pfn)(p1, p2);
             38     }
             39 
             40 };
             41 
             42 class CDelegateSource
             43 {
             44 public:
             45     CDelegateSource()
             46         : m_lpCallBack(NULL)
             47     {
             48     }
             49 
             50     void SetCallBack(IDelegate<boolintint>* newVal) 
             51     { 
             52         m_lpCallBack = newVal; 
             53     }
             54 
             55     void DoSomething()
             56     {
             57         for (int i = 0; i < 10; i++)
             58         {   
             59             if (m_lpCallBack != NULL)
             60             {
             61                 m_lpCallBack->Invoke(i, i * i);
             62             }
             63         }
             64     }
             65 
             66 private:
             67 
             68     IDelegate<boolintint>* m_lpCallBack;
             69 
             70 };
             71 
             72 class CDelegateTester
             73 {
             74 private:
             75 
             76     bool OnCallBack(int nParam1, int nParam2)
             77     {
             78         printf("OnCallBack -> nParam1:%d, nParam2:%d\r\n", nParam1, nParam2);
             79 
             80         return true;
             81     }
             82 
             83     CDelegate<CDelegateTester, boolintint> m_OnCallBack;
             84 
             85 public:
             86 
             87     CDelegateTester()
             88         : m_OnCallBack(this, OnCallBack)
             89     {
             90     }
             91 
             92     void Execute()
             93     {
             94         CDelegateSource src;
             95         src.SetCallBack(&m_OnCallBack);
             96         src.DoSomething();
             97     }
             98 };
             99 
            100 void main()
            101 {
            102     CDelegateTester Tester;
            103     Tester.Execute();
            104 
            105     getchar();
            106 }
            107 
            posted @ 2010-10-04 09:10 幽幽 閱讀(810) | 評論 (0)編輯 收藏
            1SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST+SHCNF_FLUSH, 00);
            posted @ 2010-09-12 01:19 幽幽 閱讀(659) | 評論 (0)編輯 收藏
            轉一些從shell32.dll導出的函數(shù)

            外殼對話框

            外殼對話框的秘密

            常見的Windows的通用對話框被封裝在Comdlg32.dll,這給我們的編程提供了很大的便利。但它還不夠完整,我們在系統(tǒng)里經(jīng)常能看到大量的可重復使用的對話框,但在Windows的文檔里你卻找不到它們的調(diào)用方法。而如果我們自己去做這樣的界面是非常費時費力的而且也是沒有必要的,因為這些對話框?qū)嶋H上很容易得到。這里我要介紹一些已經(jīng)眾所周知或不為認知的對話框,它們可以應用在我們的程序中使程序顯得非常友好和專業(yè)。

            瀏覽文件夾對話框



            圖2.23

            大多數(shù)Delphi程序員都知道如何使用VCL的TOpenDialog控件來讓用戶瀏覽將要打開的文件。然而有時你可能只想讓用戶選擇文件夾而不是特定的文件,windows已經(jīng)提供了一個這樣的對話框如圖2.23所示。我們可以通過公開的函數(shù)SHBrowseForFolder來調(diào)用 (這個函數(shù)定義在ShlObj單元),函數(shù)定義如下:

            function SHBrowseForFolder(var BrowseInfo: TBrowseInfo): PItemIDList; stdcall;

            這個函數(shù)只有一個參數(shù),但這個參數(shù)是一個比較復雜的記錄類型

                TBrowseInfo = packed record

                  hwndOwner: HWND;

                  pidlRoot: PItemIDList;

                  pszDisplayName: PChar;

                  lpszTitle: PChar;

                  ulFlags: UINT;

                  lpfn: TFNBFFCallBack;

                  lParam: LPARAM;

                  iImage: Integer;

                end;


            hwndOwner數(shù)據(jù)成員包含對話框的父窗體的窗口句柄,可以把它設成0。PIdlRoot數(shù)據(jù)成員指向一個PIDL的指針對應于對話框初始化時的根目錄。指定了PIdlRoot后,就只有根目錄及它的子目錄會出現(xiàn)在對話框中。可以設定它為nil,這時缺省的根目錄是桌面,pszDisplayName 數(shù)據(jù)成員指向一個緩沖區(qū)可以用來儲存被用戶選中的文件名,緩沖區(qū)的大小至少為MAX_PATH 這個常數(shù)那么大,否則遇到特別長的文件名會溢出。lpszTitle 數(shù)據(jù)對象指向一個以null結尾的字符串,字符串作為對話框的標題來顯示。注意標題不要太長,否則顯示時會被截斷。ulFlags 標志數(shù)據(jù)對象用來限制在對話框中顯示的文件夾類型。可以設定它為0或下列值的組合:

                //在對話框中會包含一個狀態(tài)區(qū),回調(diào)函數(shù)可以通過向?qū)υ捒虬l(fā)送消息來設定狀態(tài)

            BIF_STATUSTEXT

                //只允許選擇標準文件系統(tǒng),若選了非標準的文件夾如打印機,確認按鈕會變灰

                BIF_RETURNONLYFSDIRS   = $0001;

                //不選擇網(wǎng)絡文件夾

                BIF_DONTGOBELOWDOMAIN  = $0002;

                // 給狀態(tài)條留出空白

                BIF_STATUSTEXT         = $0004;

                // 只選擇文件系統(tǒng)的上級目錄

                BIF_RETURNFSANCESTORS  = $0008;

                //只選擇計算機

                BIF_BROWSEFORCOMPUTER  = $1000;

                //只選擇打印機

                BIF_BROWSEFORPRINTER   = $2000;

                //包括文件也可以選

                BIF_BROWSEINCLUDEFILES = $4000;


            注意:如果你想對話框顯示lpszTitle里的用戶定制的狀態(tài)條信息,必須包括 BIF_STATUSTEXT標識。Lpfn數(shù)據(jù)對象是一個回調(diào)函數(shù)類型的指針,函數(shù)類型如下:

                TFNBFFCallBack = function(DialogHandle: HWND;

                  MessageID: UINT; PIDL: PItemIDList; Data: LPARAM):Integer; stdcall;


            這是一個回調(diào)函數(shù),可以用來在同用戶交互時控制和更新對話框的顯示。如果你不想控制對話框,可以把它設成nil,lParam 數(shù)據(jù)對象允許你在回調(diào)函數(shù)中以參數(shù)lpfn形式返回一個指針(通常我們用它來返回對象),當然也可以把它設成為0。IImage數(shù)據(jù)成員不需要設置,因為它是用來接收系統(tǒng)中同文件夾相關的圖標列表索引的,我們這里設它為0。

            SHBrowseForFolder函數(shù)返回一個唯一的指向被選擇的文件夾的PIDL。如果文件夾是一個傳統(tǒng)的文件對象的話,可以用函數(shù)SHGetPathFromIDList把PIDL轉換為真實的目錄。同時,作為調(diào)用者,必須負責釋放被返回的item identifier list,使用IMalloc COM 接口來釋放。

            注意:不要用FreeMem或其他方法來釋放 PIDL ,這是因為外殼的內(nèi)存管理是獨立的,只能用IMalloc來釋放。

            現(xiàn)在我們已經(jīng)可以顯示對話框了,那讓我們更深入一步看看如何能夠控制對用戶動作的反應,這就要用到了回調(diào)函數(shù) TFNBFFCallBack。 注意回調(diào)函數(shù)的意思就是,你只是實現(xiàn)了它,系統(tǒng)就知道什么時候去調(diào)用它,就好比一個守株待兔的例子。

            DialogHandle參數(shù)代表對話框窗口句柄。通常可以用這個句柄給對話框發(fā)消息,MessageID 參數(shù)并不是一個TMessage 結構的記錄,它是對話框通過回調(diào)函數(shù)發(fā)給用戶消息的,它可以是下面兩個值:

                BFFM_INITIALIZED = 1;   // 對話框?qū)⒁@示

                BFFM_SELCHANGED  = 2; // 用戶選中了某項


            PIDL參數(shù)包含其他的額外信息。如果MessageID 是 BFFM_INITIALIZED,PIDL將等于nil。如果MessageID是BFFM_SELCHANGED,PIDL的值將是一個PIDL 對應于用戶選擇的文件夾。Data 參數(shù)包含用戶付給TbrowseInfo記錄中的Lparam數(shù)據(jù)成員的值,通常可以傳遞一個對象指針。下面是一個簡單的回調(diào)函數(shù)的例子:

                function BrowseForFolderCallback(DialogHandle: HWND;

                  MessageID: UINT; PIDL: PItemIDList; Data: LPARAM):

                  Integer;

                begin

                  //響應對話框的通知消息

                  case (MessageID) of

                    BFFM_INITIALIZED:

                      DialogInitialized(DialogHandle, Data);

                    BFFM_SELCHANGED:

                      HandleNewSelection(DialogHandle, PIDL, Data);

                  end;

                  Result := 0; // 總返回0.

                end;


            在回調(diào)函數(shù)里,可以根據(jù)用戶的輸入發(fā)送三個用戶的消息給對話框,下面是消息ID:

                // 改變對話框的狀態(tài)信息

                BFFM_SETSTATUSTEXT = WM_USER + 100;

                //控制確定按鈕失效與否

                BFFM_ENABLEOK      = WM_USER + 101;

                //改變選擇的文件夾

                BFFM_SETSELECTION  = WM_USER + 102;


            通常,這些消息發(fā)送給對話框使之根據(jù)用戶的選擇更新顯示,當然你也可以發(fā)送其他的消息給對話框,比如可以發(fā)送WM_SETTEXT消息來改變對話框的標題。

            下面是一個發(fā)送消息的例子(見表2.11):

            PostMessage(DialogHandle, BFFM_SETSELECTION, True, LPARAM(PChar (NewPath)));

            表2.11

            Message ID WParam LParam
            BFFM_SETSTATUSTEXT 沒有使用 一個指向新的狀態(tài)信息的Pchar
            BFFM_ENABLEOK 沒有使用 True使得確認按鈕有效,F(xiàn)alse無效
            BFFM_SETSELECTION 如果Lparam是路徑則為True,若Lparam是PIDL則為False 指向被選擇的文件路徑或PIDL的Pchar



            另外要提到的是,Delphi也提供了對這個函數(shù)的封裝,那就是SelectDirectory函數(shù)。

            關于對話框

            通常我們都要在自己的程序里加上一個關于對話框來顯示一些版本信息等等,Windows為我們提供了一個標準的對話框如圖2.24所示,可以在一定范圍內(nèi)對它定制,不過它只適合顯示簡單的標識和文本(我覺得用處極小)。我們可以通過函數(shù)ShellAbout來調(diào)用它(聲明在ShellAPI單元里),函數(shù)定義如下:

                function ShellAbout(Owner: HWND; ApplicationName: PChar;

                  OtherText: PChar; IconHandle: HICON): Integer; stdcall;


            Owner參數(shù)標識了擁有對話框的父窗體句柄,通常設為0,表明沒有父窗體。ApplicationName 參數(shù)包含對話框的標題,字符串中可以包含“#”字符,它能起到分割符的作用。這種情況下,函數(shù)會把分割符前的字符串作為標題欄,分割符后的部分作為 "Microsoft"字符串后的第一行。OtherText參數(shù)包含了打算顯示在Microsoft 版本和版權信息后的字符串。IconHandle 參數(shù)標識了打算顯示在對話框上的圖標標識,如果設為0,函數(shù)會顯示W(wǎng)indows缺省的圖標。



            圖2.24




            圖2.25

            格式化對話框

            SHFormatDrive函數(shù)會顯示一個格式化對話框,如圖2.25所示,它是一個半公開的函數(shù)。但現(xiàn)在它不在微軟的SDK里。然而微軟承認它的存在并把它從Shell32.dll里用名字公開聲明,Delphi中的函數(shù)定義如下:

                function SHFormatDrive(Owner: HWND; Drive: UINT;

                  FormatID: UINT; OptionFlags: UINT): DWORD; stdcall;


            Owner參數(shù)標識擁有對話框的窗體句柄,文檔中推薦不要設為0,但實際上好像沒什么影響。Drive參數(shù)是用來標識打算格式化的驅(qū)動器的數(shù)值,它是以0為底的,從A開始 A:=0,B:=1依此類推。FormatID 參數(shù)允許我們指定一個格式化的模板,通常情況下,只要賦值為SHFMT_ID_DEFAULT就可以了。OptionFlags 參數(shù)是一個選項掩碼,來確定格式化的選項。當前有兩個選項:

                SHFMT_OPT_FULL    = $0001; // 快速格式化

                SHFMT_OPT_SYSONLY = $0002; // 復制系統(tǒng)文件


            如果函數(shù)調(diào)用失敗,會返回下列錯誤中的一種來表明錯誤原因,錯誤常數(shù)如下:

                SHFMT_NOFORMAT = $FFFFFFFD;   // 驅(qū)動器無法格式化

                SHFMT_CANCEL   = $FFFFFFFE;   //格式化被取消了

                SHFMT_ERROR    = $FFFFFFFF; //其他錯誤


            Windows NT 和 WideChar

            在進一步研究未公開的函數(shù)前, 我們必須清楚一點,對于未公開的函數(shù)來說以null結尾的字符串類型參數(shù)大多數(shù)被聲明為類型指針而不是PChar。這有點像陷阱,但必須承認這是事實。在Win 9X上所有的字符串類型參數(shù)聲明為PAnsiChar,而在Windows NT上被聲明為PWideChar。如果你想你的應用程序適應所有平臺,你必須考慮兩種情況,在運行時要判斷平臺類型,這是很討厭的,但這也是使用未公開的API的代價。

            選擇圖標對話框



            圖2.26

            我們要討論的第一個完全未公開的函數(shù)是PickIconDlg。如圖2.26所示這個函數(shù)會顯示一個對話框,用戶可以用來從文件中選擇一個圖標資源。它通常是用文件類型編輯器來關聯(lián)圖標和某一文件類型的,也會在快捷方式對話框中被調(diào)用來修改快捷方式的圖標。這個函數(shù)從Shell32.dll 用值62來公開出來,函數(shù)定義如下:

                function PickIconDlg(Owner: HWND; FileName: Pointer;

                  MaxFileNameChars: DWORD; var IconIndex: DWORD):LongBool; stdcall;


            Owner參數(shù)和上面的意義類似。FileName 參數(shù)指向一個緩沖區(qū),包含了被瀏覽圖標的文件名,緩沖區(qū)要不小于MAX_PATH+1。MaxFileNameChars 指定字符數(shù)量大小。IconIndex 常數(shù)是以0為底的圖標索引,當對話框打開時會把焦點定在IconIndex對應的圖標上,函數(shù)返回后,IconIndex指向最后被選的圖標索引。如果用戶點了取消按鈕,函數(shù)返回False。

            運行程序?qū)υ捒?/strong>




            圖2.27

            RunFileDlg函數(shù)是相當靈活的,如圖2.27所示就是調(diào)用開始菜單的運行子菜單后會顯示的對話框,我們通過值61把它從Shell32.dll暴露出來。下面是函數(shù)聲明:

                procedure RunFileDlg(Owner: HWND; IconHandle: HICON;

                  WorkPath: Pointer; Caption: Pointer; Description: Pointer; Flags: UINT); stdcall;


            Owner參數(shù)就不用再說了。IconHandle參數(shù)是顯示在對話框上的圖標句柄,如果為nil,缺省的icon將會使用。WorkPath 參數(shù)指向一個字符串來指定應用程序運行的工作路徑。 Title 參數(shù)指向作為對話框標題的字符串,如果為nil,就使用缺省的標題。Description 參數(shù)指向一個描述字符串,主要是告訴用戶如何去做,可以設為nil,這時使用缺省的描述。 Flags參數(shù)用一組位掩碼來設定對話框的屬性。下面是定義:

                RFF_NOBROWSE      = $01;   // 移去瀏覽按鈕

                RFF_NODEFAULT     = $02;   // 無缺省的選項

                RFF_CALCDIRECTORY = $04;   // 由文件名確定工作路徑

                RFF_NOLABEL       = $08;   // 去掉編輯框標簽

                RFF_NOSEPARATEMEM = $20; // 去掉在單獨的內(nèi)存空間運行的復選框 (只對NT有效)


            這個對話框一個很好的特性是允許你控制用戶可以運行的應用程序。當用戶選擇了確認按鈕,對話框的父窗體會發(fā)送一個通知消息來傳遞將要運行的程序信息。通知消息是一個 WM_NOTIFY消息,它的通知代碼設定為RFN_VALIDATE (-510),然后lParam指向一個 TNM_RunFileDlg記錄。定義如下:

                TNM_RunFileDlg = packed record

                  hdr: TNMHdr;

                  lpFile: Pointer;

                  lpDirectory: Pointer;

                  nShow: LongBool;

                end;


            hdr數(shù)據(jù)對象是TNMHdr類型,它是一種標準的Windows數(shù)據(jù)類型,每個WM_NOTIFY消息的lParam參數(shù)都會指向這個數(shù)據(jù)成分。同時根據(jù)不同的消息類型,可能一些額外的數(shù)據(jù)跟在記錄后面,標準的TNMHdr記錄定義如下:

                TNMHdr = packed record

                  hwndFrom: HWND;

                  idFrom: UINT;

                  code: UINT;

                end;


            記錄中的hwndFrom包含發(fā)送消息的窗口句柄,idFrom則包含發(fā)送消息的控件標示符,code 中包含標識被發(fā)送的消息的通知代碼。

            在TNMHdr記錄后被打包的額外數(shù)據(jù)包含三個數(shù)據(jù)成分:LpFile指向一個包含將要運行的文件的路徑字符串;LpDirectory指向正在運行程序的工作目錄字符串;最后,nShow 用來指定將要運行的應用程序是否可見。

            對于本文中特定的消息,只對TNMHdr記錄中的Code感興趣,通過檢驗Code可以確保我們收到一個運行文件校驗消息,同時使我們可以存取額外的TNM_RunFileDlg數(shù)據(jù)成員。當TNMHdr記錄中的code等于RFN_VALIDATE(-510)時,可以獲得一個TNM_RunFileDlg記錄。下面是校驗消息的代碼:

                var

                  FileToRun: String;

                  ...

                  if TheMessage.Msg = WM_NOTIFY then

                    if PNMHdr(TheMessage.LParam).code = RFN_VALIDATE then

                      WideCharToStrVar(PNM_RUNFILEDLG(

                      TheMessage.LParam).lpFile, FileToRun);

                ...


            注意只有當我們已經(jīng)檢驗TNMHdr的Code為RFN_VALIDATE后,才映射LParam 參數(shù)為PNM_RunFileDlg類型。

            通知消息的返回值決定了應用程序是否能夠運行,下面是可能的值:

                RF_OK     = $00; //允許程序運行

                RF_CANCEL = $01;   //取消操作,關閉對話框

                RF_RETRY  = $02; //取消操作,對話框仍然打開


            查找文件對話框




            圖2.28

            調(diào)用查找文件對話框的函數(shù)是SHFindFiles,對話框如圖2.28所示。它是從Shell32.dll按索引值90公開出來的:

                function SHFindFiles(SearchRoot: PItemIDList;

                  SavedSearchFile: PItemIDList): LongBool; stdcall;


            SearchRoot 參數(shù)允許從一個特定的文件夾開始查找,同在資源管理器中在文件夾上用右鍵點擊查找菜單的效果是一樣的。如果設為nil,那么查找是從桌面開始的。 SavedSearchFile 參數(shù)讓你指定一個以前查詢保存的查找策略文件(*.fnd文件),根據(jù)以前的設定來查找,若不需要的話可以設定為nil。如果你指定了一個非空值的SearchRoot PIDL,那么在調(diào)用完SHFindFiles后必須負責釋放掉。但是有點奇怪的是,如果你指定了一個非空的SavedSearchFile PIDL參數(shù),函數(shù)成功調(diào)用的話,你不能去釋放這個 PIDL,否則會出錯,但如果調(diào)用失敗了的話,你必須釋放它。

            同大多數(shù)對話框函數(shù)不一樣,這個函數(shù)是非模態(tài)的,也就是系統(tǒng)在另外一個獨立的線程中啟動對話框,然后立即返回,對話框會在你的程序結束后自動關閉。也就是說你沒有任何直接的方法來告訴用戶如何使用查找到的結果,所以要想知道用戶找到的文件的話,最好是讓你的程序支持文件拖放,以便讓用戶把找到的文件拖放給你。

            查找電腦對話框

            同SHFindFiles比較接近的一個函數(shù)是SHFindComputer,這個函數(shù)調(diào)用的結果同開始菜單上查找電腦菜單調(diào)用的結果是一樣的。它的參數(shù)同SHFindFiles完全一樣,不同之處在于它完全忽略傳遞給它的參數(shù),很顯然是保留起來為了將來擴展的需要。這里我們只要把參數(shù)都設成nil就可以了,另外注意這個對話框也是非模態(tài)的。 SHFindComputer 是從Shell32.dll 以索引號91公開出來的:

                function SHFindComputer(Reserved1: PItemIDList;

                  Reserved2: PItemIDList): LongBool; stdcall;



            查找文件對話框

            通過調(diào)用GetFileNameFromBrowse函數(shù)可以調(diào)出這個對話框,不過說實在的,它實際上只是GetOpenFileName 函數(shù)的簡單封裝。而我們常用的TOpenDialog控件也是對GetOpenFileName 函數(shù)封裝,這個函數(shù)我們很少會去直接用它。不過還是寫出來吧,它是從Shell32.dll里按索引值63公開出來的:

                function GetFileNameFromBrowse(Owner: HWND;

                  FileName: Pointer; MaxFileNameChars: DWORD;

                  InitialDirectory: Pointer; DefaultExtension: Pointer;

                  Filter: Pointer; Caption: Pointer): LongBool; stdcall;




            圖2.29

            大多數(shù)參數(shù)對應于OPENFILENAME 結構的成員。Owner參數(shù)我想就不用再重復了, FileName 參數(shù)指向一個初始化對話框編輯控制文件名的緩沖區(qū),函數(shù)返回后FileName包含被選擇的文件路徑,它的大小一般設成MAX_PATH+1那么大。MaxFileNameChars 參數(shù)用來指定FileName緩沖區(qū)的大小。 InitialDirectory參數(shù)指向?qū)υ捒虺跏蓟哪夸浢绻鸉ileName參數(shù)被指定了,InitialDirectory就會被忽略而使用FileName參數(shù)中的路徑。DefaultExtension參數(shù)指向一個包含要搜索的缺省擴展名的字符串。Filter參數(shù)指向一個以null結尾的可以用來在下拉列表中限定文件類型的過濾字符串。Caption參數(shù)指向?qū)υ捒驑祟}字符串。

            如果用戶選擇了一個要打開的文件,函數(shù)返回True,當有錯誤發(fā)生,用戶選擇取消按鈕或關閉對話框的話會返回False。

            外殼對象屬性對話框

            另一個未公開的對話框函數(shù)是SHObjectProperties,它可以用來顯示外殼對象的屬性,比如驅(qū)動器、文件夾或文件等,運行效果如圖2.29所示。函數(shù)可以從Shell32.dll中按索引值178公開出來,定義如下:

                function SHObjectProperties(Owner: HWND; Flags: UINT;

                  ObjectName: Pointer; InitialTabName: Pointer):LongBool; stdcall;


            Flags參數(shù)用來指定ObjectName參數(shù)對應對象的類型,它可以是下列標識:

                //打印機

                OPF_PRINTERNAME = $01;

                //路徑

                OPF_PATHNAME    = $02;


            ObjectName參數(shù)指向一個包含路徑名的字符串或是要顯示屬性的打印機名。如果打印機是本地的,可以使用實際的打印機名,如果是網(wǎng)絡打印機,就需要使用完整的UNC樣式名稱,比如\\COMPUTERNAME\PRINTERNAME。InitialTabName參數(shù)指向一個屬性對話框中頁面名稱字符串,用來指定要顯示的缺省頁面。如果InitialTabName參數(shù)為nil,或不匹配任何頁面的名稱,第一個屬性頁面將會被顯示。

            如果函數(shù)調(diào)用成功會返回True,如果失敗會返回False。要想獲得擴展的錯誤信息,可以調(diào)用API函數(shù)GetLastError。要注意的是這個對話框是非模態(tài)的,類似于查找文件對話框,所以函數(shù)一被調(diào)用,就肯定會顯示一個對話框,同時我們沒有辦法知道用戶什么時候關閉了對話框。

            映射網(wǎng)絡驅(qū)動對話框





            圖2.30

            圖2.30顯示了映射網(wǎng)絡驅(qū)動器的對話框,我們通過SHNetConnectionDialog函數(shù)調(diào)用它(win 9x和Win NT上都支持),它可以按索引值160從Shell32.dll暴露出來,函數(shù)定義如下:

                function SHNetConnectionDialog(Owner: HWND;

                  ResourceName: Pointer; ResourceType: DWORD): DWORD; stdcall;


            SHStartNetConnectionDialog函數(shù)也會顯示同樣的對話框,但它顯示的對話框是非模態(tài)的,同時只在NT上才支持。它可以按索引值215從Shell32.dll中公開出來,函數(shù)定義如下:

                function SHStartNetConnectionDialog(Owner: HWND;

                  ResourceName: PWideChar; ResourceType: DWORD):DWORD; stdcall;


            上面兩個函數(shù)的參數(shù)完全相同。其中ResourceName參數(shù)指向一個要連接的網(wǎng)絡資源UNC路徑名。指定了這個參數(shù)的話,顯示的對話框中被預設的連接資源就不可改變了。如果這個參數(shù)為nil,則在對話框中用戶可以指定要連接的資源。ResourceType參數(shù)可以是下面的值之一:RESOURCETYPE_DISK或RESOURCETYPE_PRINT。它的不同將會生成不同的對話框。參數(shù)為RESOURCETYPE_DISK允許我們?yōu)榫W(wǎng)絡驅(qū)動資源指定一個盤符,另一個參數(shù)允許我們映射一個并行口名比如LPT2為一個網(wǎng)絡打印機。然而,不知道為什么RESOURCETYPE_PRINT參數(shù)在NT上無效。




            圖2.31

            如果函數(shù)調(diào)用成功的話,返回值是NO_ERROR,如果用戶取消的對話框,則返回 -1($FFFFFFFF),如果調(diào)用失敗則返回其他的錯誤代碼,具體錯誤信息可以用GetLastError API調(diào)用獲得。

            關閉系統(tǒng)對話框

            ExitWindowsDialog和RestartDialog函數(shù)可以用來顯示關閉和重啟系統(tǒng)對話框(如圖2.31),它們同公開的ExitWindowsEx API函數(shù)沒有什么太大的不同,但在其過程中都會產(chǎn)生一個對話框。ExitWindowsDialog函數(shù)可以按索引值60從Shell32.dll中公開出來,RestartDialog函數(shù)的在Shell32.dll中的索引值則是59,兩個函數(shù)的定義如下:

                procedure ExitWindowsDialog(Owner: HWND); stdcall;

                function RestartDialog(Owner: HWND; Reason: Pointer; ExitType: UINT): DWORD; stdcall;


            對ExitWindowsDialog函數(shù)來說,對話框好像并不使用Owner參數(shù)作為父窗口,在Windows 95上,當操作成功的話owner窗口會收到一個WM_QUIT消息。在Windows NT上,owner 窗口根本不被使用。同時這個函數(shù)沒有返回值,所以沒有辦法知道用戶選擇了什么操作以及操作是否被取消了。

            RestartDialog函數(shù)更有用一些,當我們修改了系統(tǒng)的設置,并希望重新啟動系統(tǒng)使修改生效的時候可以使用這個函數(shù)。Reason參數(shù)指向一個要顯示在對話框中的字符串,用來解釋關閉系統(tǒng)的原因。ExitType參數(shù)指定關閉類型,可以使用ExitWindowsEX函數(shù)使用值的一個子集及額外的幾個新值,下面是它們的完全列表:

                EWX_LOGOFF        = $00;

                EWX_SHUTDOWN      = $01;

                EWX_REBOOT        = $02;

                EW_RESTARTWINDOWS = $42;

                EW_REBOOTSYSTEM   = $43;

                EW_EXITANDEXECAPP = $44;


            如果用戶選擇執(zhí)行關閉操作,函數(shù)返回IDYES,否則返回IDNO。

            要注意的是顯示在對話框中的原因字符串后總會跟著一個系統(tǒng)缺省提供的字符串用來顯示確認信息,所以應該在我們的Reason字符串后附上空格或回車換行字符。另外返回值不能用于確定操作的成功性,它只表明用戶的選擇,如果重啟操作由于某些原因失敗了,返回值仍然是IDYES。同時要注意的是要想調(diào)用成功,用戶還必須有SE_SHUTDOWN_NAME權限(在NT上)。

            缺少內(nèi)存對話框

            SHOutOfMemoryMessageBox是一個未公開的函數(shù),當系統(tǒng)內(nèi)存不足時可以用來顯示標準的外殼信息對話框,它在Shell32.dll中的索引值是126,函數(shù)定義如下:

                function SHOutOfMemoryMessageBox(Owner: HWND;

                  Caption: Pointer; Style: UINT): Integer; stdcall;


            它會調(diào)用MessageBox API,同時傳遞3個標準的參數(shù)和ERROR_OUTOFMEMORY錯誤消息。Caption參數(shù)指向?qū)υ捒驑祟}字符串。如果Caption為nil,父窗口的標題就會被使用。Style參數(shù)可以被設置為任意MessageBox函數(shù)使用的MB_XXX常數(shù)的組合,通常設置它為MB_OK或MB_ICONHAND。函數(shù)調(diào)用返回值參見SDK中MessageBox函數(shù)說明。

            當MessageBox函數(shù)被調(diào)用時,MB_SETFOREGROUND標識會被添加到Style參數(shù)中,但如果第一次調(diào)用失敗了的話,MessageBox函數(shù)會被再次調(diào)用,這次MB_SYSTEMMODAL 標識會被添加到Style參數(shù)中。MB_SYSTEMMODAL同MB_ICONHAND標識結合后會忽略內(nèi)存狀況來顯示消息對話框。當內(nèi)存確實不足時,函數(shù)不會顯示任何東西,然而它仍然會返回MessageBox函數(shù)調(diào)用結果。所以我們可以根據(jù)返回值判斷函數(shù)是否調(diào)用成功了。

            空間不足對話框




            圖2.32

            另一個資源相關的函數(shù)是SHHandleDiskFull,它會顯示磁盤不足的信息對話框(如圖2.32)。我們可以在由于沒有足夠磁盤空間時導致程序無法運行的條件下調(diào)用這個函數(shù),調(diào)用后,如果回收站中有什么東西沒有刪除的話,對話框允許用戶清空回收站來釋放磁盤空間。它在Shell32.dll中的索引值為185,函數(shù)的定義如下:

                procedure SHHandleDiskFull(Owner: HWND; Drive: UINT); stdcall;


            Drive參數(shù)用于指定以0為底的驅(qū)動器盤符。0代表A:\,1代表B:\,依此類推。這個函數(shù)的應用比較困難,因為當回收站中沒有任何東西時對話框不會顯示,同時也沒有任何返回值表示對話框是否顯示,還無法知道用戶的操作,比如它是否真的清空了。看起來比較可行的應用只能是程序自行監(jiān)視磁盤剩余空間,只是使用這個對話框作為一個快速修復的工具。

            一般外殼消息對話框

            ShellMessageBox函數(shù)僅僅是一個對MessageBox函數(shù)的簡單封裝函數(shù),它允許使用字符串資源標識符或標準的以null結尾的字符串,同時還允許加入支持格式化ForamtMessage函數(shù)的控制符。ShellMessageBox函數(shù)在Shell32.dll中的索引值為183:

                function ShellMessageBoxA(Module: THandle; Owner: HWND;

                  Text: PChar; Caption: PChar; Style: UINT;

                  Parameters: array of Pointer): Integer; cdecl;


            更確切地說這個函數(shù)應該叫ShellMessageBoxA因為它只支持ANSI字符串,還有一個UNICODE的版本的函數(shù)ShellMessageBoxW,它的索引值為182,但它只在Windows NT上才有,函數(shù)定義如下:

                function ShellMessageBoxW(Module: THandle; Owner: HWND;

                  Text: PWideChar; Caption: PWideChar; Style: UINT;

                  Parameters: array of Pointer): Integer; cdecl;


            Module參數(shù)是提供字符串資源的模塊句柄,句柄可以用GetModuleHandle函數(shù)獲得。顧名思義Text 參數(shù)指向一個要顯示在對話框中的文本,它也可以是資源字符串ID,文本中可以包括格式控制序列,它將會被在Parameters中提供的額外字符串替代。控制符格式為“%#”,其中“#”是額外字符串在參數(shù)中的位置,比如“%1”將被第一個Parameters數(shù)組中的字符串元素替代,“%3”將會被第三個元素替代,依此類推。Caption參數(shù)指向?qū)υ捒驑祟}文本,同樣它也可以是資源ID,如果參數(shù)為nil,Owner指定的窗口標題將被用于對話框標題。Style參數(shù)是由位掩碼標識組成的,可以設置成MessageBox函數(shù)支持的MB_XXX常數(shù)的組合。返回值同MessageBox完全一樣。

            對于這個函數(shù)很重要的一點是微軟公司使用cdecl來輸出這個函數(shù)而不是通常的 stdcall。此外,Parameters參數(shù)使用了C語言中的可變參數(shù)列表,這意味著這個函數(shù)不是語言無關的,這使得調(diào)用起來非常麻煩,因為Delphi并不直接支持cdecl和可變參數(shù)列表。為了解決這個問題,Parameters參數(shù)被映射為一個動態(tài)指針列表。同時我們還需要使用嵌入式匯編來建立cdecl樣式的堆棧。由于動態(tài)指針列表的性質(zhì),我們必須至少指定一個指針值。如果不想指定要替代的字符串,簡單設置為nil就可以了。
            posted @ 2009-12-18 09:20 幽幽 閱讀(822) | 評論 (0)編輯 收藏

            首先,先簡單介紹一下MD5

            MD5的全稱是message-digest algorithm 5(信息-摘要算法,在90年代初由mit laboratory for computer science和rsa data security inc的ronald l. rivest開發(fā)出來, 經(jīng)md2、md3和md4發(fā)展而來。

            MD5具有很好的安全性(因為它具有不可逆的特征,加過密的密文經(jīng)過解密后和加密前的東東相同的可能性極小)

            引用
            using System.Security.Cryptography;
            using System.Text;

            具體代碼如下(寫在按鈕的Click事件里):
            byte[] result = Encoding.Default.GetBytes(this.tbPass.Text.Trim());    //tbPass為輸入密碼的文本框
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] output = md5.ComputeHash(result);
            this.tbMd5pass.Text = BitConverter.ToString(output).Replace("-","");  //tbMd5pass為輸出加密文本的文本框

            本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/lykycs/archive/2006/06/16/802873.aspx


            posted @ 2009-12-07 08:29 幽幽 閱讀(450) | 評論 (0)編輯 收藏

            再談異常――談C++與Object Pascal中的構造函數(shù)與異常

            作者:Nicrosoft(nicrosoft@sunistudio.com) 2001.9.15
            個人主頁:http://www.sunistudio.com/nicrosoft/
            東日文檔:http://www.sunistudio.com/asp/sunidoc.asp

              我們知道,類的構造函數(shù)是沒有返回值的,如果構造函數(shù)構造對象失敗,不可能依靠返回錯誤代碼。那么,在程序中如何標識構造函數(shù)的失敗呢?最“標準”的方法就是:拋出一個異常。

              構造函數(shù)失敗,意味著對象的構造失敗,那么拋出異常之后,這個“半死不活”的對象會被如何處理呢?這就是本文的主題。

            在C++中,構造函數(shù)拋出異常后,析構函數(shù)不會被調(diào)用。這是合理的,因為此時對象并沒有被完整構造。也就是說,如果構造函數(shù)已經(jīng)做了一些諸如分配內(nèi)存、 打開文件等操作的話,那么類需要有自己的成員來記住做過哪些動作。在C++中,經(jīng)典的解決方案是使用STL的標準類auto_ptr,這在每一本經(jīng)典 C++著作中都有介紹,我在這里就不多說了。在這里,我想再介紹一種“非常規(guī)”的方式,其思想就是避免在構造函數(shù)中拋出異常。我們可以在類中增加一個 Init(); 以及 UnInit();成員函數(shù)用于進行容易產(chǎn)生錯誤的資源分配工作,而真正的構造函數(shù)中先將所有成員置為NULL,然后調(diào)用 Init(); 并判斷其返回值(或者捕捉 Init()拋出的異常),如果Init();失敗了,則在構造函數(shù)中調(diào)用 UnInit(); 并設置一個標志位表明構造失敗。UnInit()中按照成員是否為NULL進行資源的釋放工作。示例代碼如下:
            class A
            {
            private:
             char* str;
             int failed;

            public:
             A();
             ~A();
             int Init();
             int UnInit();
             int Failed();
            };

            A::A()
            {
             str = NULL;
             try
             {
              Init();
              failed = 0;
             }
             catch(...)
             {
              failed = 1;
              UnInit();
             }
            }

            A::~A()
            {
             UnInit();
            }

            int A::Init()
            {
             str = new char[10];
             strcpy(str, "ABCDEFGHI");
             throw 10;

             return 1;
            }

            int A::UnInit()
            {
             if (!str)
             {
              delete []str;
              str = NULL;
             }

             printf("Free Resource

            ");
             return 1;
            }

            int A::Failed()
            {
             return failed;
            }

            int main(int argc, char* argv[])
            {
             A* a = new A;
             if ( a->Failed() )
              printf("failed

            ");
             else
              printf("succeeded

            ");

             delete a;

             getchar();
             return 0;
            }

              你會發(fā)現(xiàn),在int A::Init()中包含了throw 10;的代碼(產(chǎn)生一個異常,模擬錯誤的發(fā)生),執(zhí)行結果是:
              Free Resource
              failed
              Free Resource
              雖然 UnInit();被調(diào)用了兩次,但是由于UnInit();中做了判斷(if (!str)),因此不會發(fā)生錯誤。而如果沒有發(fā)生異常(去掉 int A::Init()中的throw 10;代碼),執(zhí)行結果是:
              Succeeded
              Free Resource
              和正常的流程沒有任何區(qū)別。

            在Object Pascal(Delphi/VCL)中,這個問題就變得非常的簡單了,因為 OP 對構造函數(shù)的異常的處理與C++不同,在Create時拋出異常后,編譯器會自動調(diào)用析構函數(shù)Destroy,并且會判斷哪些資源被分配了,實行自動回 收。因此,其代碼也變得非常簡潔,如下:
            type
              A = class
              private
              str : PChar;
              public
              constructor Create();
              destructor Destroy(); override;
              end;

            constructor A.Create();
            begin
              str := StrAlloc(10);
              StrCopy(str, 'ABCDEFGHI');
              raise Exception.Create('error');
            end;

            destructor A.Destroy();
            begin
              StrDispose(str);
              WriteLn('Free Resource');
            end;

            var oa : A;
              i : integer;
            begin
              try
                  oa := A.Create();
                  WriteLn('Succeeded');
                  oa.Free();
              except
                  oa := nil;
                  WriteLn('Failed');
              end;

              Read(i);
            end.

              在這段代碼中,如果構造函數(shù)拋出異常(即Create中含有raise Exception.Create('error');),執(zhí)行的結果是:
              Free Resource
              Failed
              此時的“Free Resource”輸出是由編譯器自動調(diào)用析構函數(shù)所產(chǎn)生的。而如果構造函數(shù)正常返回(即不拋出異常),則執(zhí)行結果是:
              Succeeded
              Free Resource
              此時的“Free Resource”輸出是由 oa.Free()的調(diào)用產(chǎn)生的。

            綜上,C++與Object Pascal對于構造函數(shù)拋出異常后的不同處理方式,其實正是兩種語言的設計思想的體現(xiàn)。C++秉承C的風格,注重效率,一切交給程序員來掌握,編譯器不 作多余動作。Object Pascal繼承Pascal的風格,注重程序的美學意義(不可否認,Pascal代碼是全世界最優(yōu)美的代碼),編譯器幫助程序員完成復雜的工作。兩種語 言都有存在的理由,都有存在的必要!而掌握它們之間的差別,能讓你更好地控制它們,達到自由的理想王國。


            posted @ 2009-05-20 00:42 幽幽 閱讀(653) | 評論 (1)編輯 收藏

            串口通訊中的DCB結構

            typedef struct _DCB {// dcb

            DWORD DCBlength; // sizeof(DCB)

            DORD BaudRate; // current baud rate 指定當前的波特率

            DWORD fBinary: 1; // binary mode, no EOF check 指定是否允許二進制模式WIN95中須為TRUE
                   

            DWORD fParity: 1; // enable parity checking 指定奇偶校驗是否允許

            DWORD fOutxCtsFlow:1; // CTS output flow control 指定CTS是否用于檢測發(fā)送控制。當為TRUE是CTS為OFF,發(fā)送將被掛起。


            DWORD fOutxDsrFlow:1; // DSR output flow control   指定CTS是否用于檢測發(fā)送控制。當為TRUE是CTS為OFF,發(fā)送將被掛起。


            DWORD fDtrControl:2; // DTR flow control type

            DTR_CONTROL_DISABLE 值將DTR置為OFF,DTR_CONTROL_ENABLE值將DTR置為ON, 

            DTR_CONTROL_HANDSHAKE 允許DTR"握手",

             

            DWORD fDsrSensitivity:1;// DSR sensitivity 當該值為TRUE時DSR為OFF時接收的字節(jié)被忽略

             

            DWORD fTXContinueOnXoff:1; // XOFF continues Tx
                指定當接收緩沖區(qū)已滿,并且驅(qū)動程序已經(jīng)發(fā)送出XoffChar字符時發(fā)送是否停止。

                TRUE時,在接收緩沖區(qū)接收到緩沖區(qū)已滿的字節(jié)XoffLim且驅(qū)動程序已經(jīng)發(fā)送出XoffChar字      符中止接收字節(jié)之后,發(fā)送繼續(xù)進行。
                FALSE時,在接收緩沖區(qū)接收到代表緩沖區(qū)已空的字節(jié)XonChar且驅(qū)動程序已經(jīng)發(fā)送出恢復發(fā)送的XonChar之后,發(fā)送繼續(xù)進行。


            DWORD fOutX: 1; // XON/XOFF out flow control    TRUE時,接收到XoffChar之后便停止發(fā)送接收到XonChar之后將重新開始

             

            DWORD fInX: 1; // XON/XOFF in flow control
                         TRUE時,接收緩沖區(qū)接收到代表緩沖區(qū)滿的XoffLim之后,XoffChar發(fā)送出去接收緩沖區(qū)接收到代表緩沖區(qū)空的XonLim之后,XonChar發(fā)送出去


            DWORD fErrorChar: 1; // enable error replacement
                     該值為TRUE且fParity為TRUE時,用ErrorChar 成員指定的字符代替奇偶校驗錯誤的接收字符


            DWORD fNull: 1; // enable null stripping  TRUE時,接收時去掉空(0值)字節(jié)

             

            DWORD fRtsControl:2; // RTS flow control


            DWORD fAbortOnError:1; // abort reads/writes on error  TRUE時,有錯誤發(fā)生時中止讀和寫操作RTS_CONTROL_DISABLE時,RTS置為OFFRTS_CONTROL_ENABLE時, RTS置為ON

             

            RTS_CONTROL_HANDSHAKE時,當接收緩沖區(qū)小于半滿時RTS為ON當接收緩沖區(qū)超過四分之三滿時RTS為OFF


            RTS_CONTROL_TOGGLE時,當接收緩沖區(qū)仍有剩余字節(jié)時RTS為ON ,否則缺省為OFF


            DWORD fDummy2:17; // reserved  未使用

             

            WORD wReserved; // not currently used  未使用,必須為0

             

            WORD XonLim; // transmit XON threshold   指定在XON字符發(fā)送這前接收緩沖區(qū)中可允許的最小字節(jié)數(shù)


            WORD XoffLim; // transmit XOFF threshold  指定在XOFF字符發(fā)送這前接收緩沖區(qū)中可允許的最小字節(jié)數(shù)


            BYTE ByteSize; // number of bits/byte, 4-8  指定端口當前使用的數(shù)據(jù)位

             

            BYTE Parity; // 0-4=no,odd,even,mark,space 指定端口當前使用的奇偶校驗方法,可能為:
                                        EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY BYTE

             

            StopBits;      0,1,2 = 1, 1.5, 2   指定端口當前使用的停止位數(shù),可能為:
                                      ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS


            char XonChar; // Tx and Rx XON character  指定用于發(fā)送和接收字符XON的值

             

            char XoffChar; // Tx and Rx XOFF character  指定用于發(fā)送和接收字符XOFF值

             

            char ErrorChar; // error replacement character本字符用來代替接收到的奇偶校驗發(fā)生錯誤時的值

             

            char EofChar; // end of input character 當沒有使用二進制模式時,本字符可用來指示數(shù)據(jù)的結束

             

            char EvtChar; // received event character 當接收到此字符時,會產(chǎn)生一個事件

             

            WORD wReserved1; // reserved; do not use 未使用

            } DCB;

            posted @ 2009-05-05 02:35 幽幽 閱讀(1913) | 評論 (0)編輯 收藏

            CSS切換皮膚切換代碼:


            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "<html xmlns="      <head>
                   
              <meta http-equiv="content-type" content="text/html;charset=gb2312" />
              <meta name="generator" content="" />
              <meta name="author" content="" />
                    <meta name="keywords" content="" />
                    <meta name="robots" content="index, follow" />
                    <meta name="googlebot" content="index, follow" />
              <title>     </title>
              <link rel="stylesheet" type="text/css" href="code/changestyle/styles1.css" title="styles1"  media="screen" />
             <link rel="alternate stylesheet" type="text/css" href="code/changestyle/styles2.css" title="styles2" media="screen" />
             <link rel="alternate stylesheet" type="text/css" href="code/changestyle/styles3.css" title="styles3" media="screen" />
              <script type="text/javascript">
            window.onload=function(){ var c = readCookie('style');
             if (c) switchStylestyle(c);
            };
            function switchStylestyle(styleName)
            {  aa=document.styleSheets;
            for(i=0;i<aa.length;i++)
             {
              aa[i].disabled = true;
              if (aa[i].title== styleName){aa[i].disabled = false;}
             };
             createCookie('style', styleName, 365);
            }
            function createCookie(name,value,days)
            {
             if (days)
             {
              var date = new Date();
              date.setTime(date.getTime()+(days*24*60*60*1000));
              var expires = "; expires="+date.toGMTString();
             }
             else var expires = "";
             document.cookie = name+"="+value+expires+"; path=/";
            }
            function readCookie(name)
            {
             var nameEQ = name + "=";
             var ca = document.cookie.split(';');
             for(var i=0;i < ca.length;i++)
             {
              var c = ca[i];
              while (c.charAt(0)==' ') c = c.substring(1,c.length);
              if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
             }
             return null;
            }
            function eraseCookie(name)
            {
             createCookie(name,"",-1);
            }
            // /cookie functions
              </script>
             </head>
             <body id="">
              <div id="wrapper">
               <ul>
              <li><a href="javascript:void(0);" onclick="switchStylestyle('styles1')">styles1</a></li>
              <li><a href="javascript:void(0);" onclick="switchStylestyle('styles2')">styles2</a></li>
              <li><a href="javascript:void(0);" onclick="switchStylestyle('styles3')">styles3</a></li>
             </ul
              </div>
             </body>
            </html>


            DLL注入程序的一般步驟:

            (1)取得宿主進程(即要注入木馬的進程)的進程ID dwRemoteProcessId;

            (2)取得DLL的完全路徑,并將其轉換為寬字符模式pszLibFileName;

            (3)利用Windows API OpenProcess打開宿主進程,應該開啟下列選項:

            a.PROCESS_CREATE_THREAD:允許在宿主進程中創(chuàng)建線程;

            b.PROCESS_VM_OPERATION:允許對宿主進程中進行VM操作;

            c.PROCESS_VM_WRITE:允許對宿主進程進行VM寫。

            (4)利用Windows API VirtualAllocEx函數(shù)在遠程線程的VM中分配DLL完整路徑寬字符所需的存儲空間,并利用Windows API WriteProcessMemory函數(shù)將完整路徑寫入該存儲空間;

            (5)利用Windows API GetProcAddress取得Kernel32模塊中LoadLibraryW函數(shù)的地址,這個函數(shù)將作為隨后將啟動的遠程線程的入口函數(shù);

            (6)利用Windows API CreateRemoteThread啟動遠程線程,將LoadLibraryW的地址作為遠程線程的入口函數(shù)地址,將宿主進程里被分配空間中存儲的完整DLL路徑作為線程入口函數(shù)的參數(shù)以另其啟動指定的DLL;

            (7)清理現(xiàn)場。
            posted @ 2009-03-13 19:56 幽幽 閱讀(435) | 評論 (0)編輯 收藏
            僅列出標題  下一頁

            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(6)

            隨筆分類(35)

            隨筆檔案(51)

            文章分類(3)

            文章檔案(3)

            相冊

            我的鏈接

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产毛片久久久久久国产毛片| 久久免费小视频| 国产精品成人久久久久三级午夜电影| 久久久久高潮毛片免费全部播放| 亚洲va久久久噜噜噜久久天堂| 伊人久久大香线蕉综合影院首页| 无码专区久久综合久中文字幕 | 精品99久久aaa一级毛片| 久久国产午夜精品一区二区三区| 中文字幕久久精品| 麻豆精品久久精品色综合| 欧美精品丝袜久久久中文字幕| 精品久久久久久国产潘金莲| 亚洲欧美另类日本久久国产真实乱对白 | 国产成人久久久精品二区三区| 日韩十八禁一区二区久久| 国内精品久久久久影院网站| 91久久福利国产成人精品| 午夜视频久久久久一区| 久久国产精品成人免费| 久久精品国产亚洲AV无码偷窥| 久久精品国产第一区二区| 精品久久久久久无码专区| 久久精品视频一| 久久久久人妻一区精品果冻| 久久丫忘忧草产品| 久久99亚洲网美利坚合众国| 久久久免费观成人影院 | 国内精品免费久久影院| 99久久99久久久精品齐齐| 久久免费小视频| 久久国产精品久久| 996久久国产精品线观看| 久久久久久国产精品无码超碰| 久久综合狠狠综合久久97色| 久久精品成人免费看| 久久国产一区二区| 久久久久免费视频| 国内精品综合久久久40p| 婷婷国产天堂久久综合五月| 美女久久久久久|