《Windows核心編程》筆記2 — 核心對象二

來源:互聯網
上載者:User
續上......

核心對象如何在進程邊界共用?
1.物件控點的繼承
    當進程具有父子關係,就能使用物件控點的繼承性。父進程有一個或多個物件控點,並且父進程可以決定產生一個子進程,為子進程賦於父進程的核心對象的訪問權。
    具體實現:
    在安全性描述元中指定,如:
   

SECURITY_ATTRIGBUTES sa
    sa.nLength=sizeof(sa);
    sa.lpSecuntyDescriptor=null;
    sa.bInherithandle=TRUE; //指定子進程可以繼承該父進程的核心對象。
    HANDLE hMutex    =    CreateMutex(@sa,FALSE,NULL);

   
    然後,在進程中使用CreateProcess函數: BOOL CreateProcess(
   PCTSTR pszApplicationName,
   PTSTR pszCommandLine,
   PSECURITY_ATTRIBUTES psaProcess,
   PSECURITY_ATTRIBUTES psaThread,
   BOOL bInheritHandles,
   DWORD fdwCreale,
   PVOIO pvEnvironment,
   PCTSTR pszCurDir,
   PSTARTUPINFO psiStartInfo,
   PPROCESS_INFORMATION ppiProcInfo);

為bInheritHandles指定TRUE,則告訴系統,子進程繼承父進程的控制代碼表中的可繼承控制代碼。

2.改變控制代碼標誌:
    因為每個進程都會有個核心物件控點表,指明該進程所擁有的控制代碼資訊。那麼,我們可以直接設定進程的控制代碼表,以擷取某個核心對象的訪問權。
    控制代碼表的樣式:

索引 核心對象記憶體塊的指標 訪問屏蔽(標誌位的D W O R D ) 標誌(標誌位的D W O R D )
1 0 x 0 0 0 0 0 0 0 0 (無) (無)
2 0 x 0 0 0 0 0 0 0 0 (無) (無)
3 0 x F 0 0 0 0 0 1 0 0 x ? ? ? ? ? ? ? ? 0 x 0 0 0 0 0 0 0 1

    設定控制代碼標誌的函數: BOOL SetHandleInformation(
   HANDLE hObject,
   DWORD dwMask,
   DWORD dwFlags);

可以看到,該函數擁有3 個參數。第一個參數h O b j e c t 用於標識一個有效控制代碼。第二個參數d w M a s k 告訴該函數想要改變哪個或那幾個標誌。目前有兩個標誌與每個控制代碼相關聯: #define HANDLE FLAG_INHERIT 0x00000001
#define HANDLE FLAG PROTECT FROM CLOSE 0x00000002

比如,開啟一個核心對象的繼承標誌,則可以這樣:
SetHandleInformation(hobj, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
關閉該標誌,則可以:
SetHandleInformation(hobj, HANDLE_FLAG_INHERIT, 0);

3.給核心對象命名
    建立許多核心對象可以進行命名,如:
   

HANDLE CreateMutex(
   PSLCURITY_ATTRIBUTES psa,
   BOOL bInitialOwner,
   PCTSTR pszName);

HANDLE CreateEvent(
   PSECURITY_ATTRIBUTES psa,
   BOOL bManualReset,
   BOOL bInitialState,
   PCTSTR pszName);

HANDLE CreateSemaphore(
   PSECURITY_ATTRIBUTES psa,
   LONG lInitialCount,
   LONG lMaximumCount,
   PCTSTR pszNarne);

HANDLE CreateWaitableTimer(
   PSLCURITY_ATTRIBUTES psa,
   BOOL bManualReset,
   PCTSTR pszName);

HANDLE CreateFileMapping(
   HANDLE hFile,
   PSECURITY_ATTRIBUTES psa,
   DWORD flProtect,
   DWORD dwMaximumSizeHigh,
   DWORD dwMaximumSizeLow,
   PCTSTR pszName);

    如果建立時最後的參數設定NULL,則建立一個末名命的核心對象當建立一個未命名的對象時,可以通過使用繼承性(如上一節介紹的那樣)或D u p l i c a t e H a n d l e (下一節將要介紹)共用跨越進程的對象。若要按名字共用對象,必須為對象賦予一個名字
    實現:我們在ProcessA中建立一個核心對象:
    HANDLE hMutexPronessA = CreateMutex(NULL, FALSE, "JeffMutex");
    然後,在ProcessB中建立一個與ProcessA中同名的核心對象:
    HANDLE hMutexProcessB = CreateMutex(NULL, FALSE, "JeffMutex");
    下面,會發生什麼情況?以下是書中所揭示的:
    當Process B 調用C r e a t e M u t e x 時,系統首先要查看是否已經存在一個名字為“J e ff M u t e x ”的核心對象。由於確實存在一個帶有該名字的對象,因此核心要檢查對象的類型。由於試圖建立一個互斥對象,而名字為“J e ff M u t e x ”的對象也是個互斥對象,因此系統會執行一次安全檢查,以確定調用者是否擁有對該對象的完整的訪問權。如果擁有這種訪問權,系統就在Process B 的控制代碼表中找出一個空項目,並對該項目進行初始化,使該項目指向現有的核心對象。如果該物件類型不匹配,或者調用者被拒絕訪問,那麼C r e a t e M u t e x 將運行失敗(返回N U L L )。當Process B 對C r e a t e M u t e x 的調用取得成功時,它並不實際建立一個互斥對象。相反,Process B 只是被賦予一個與進程相關的控制代碼值,用於標識核心中現有的互斥對象。當然,由於Process B 的控制代碼表中的一個新項目要引用該對象,互斥對象的使用計數就會遞增。在Process A和Process B 同時關閉它們的物件控點之前,該對象是不會被撤消的。請注意,這兩個進程中的控制代碼值很可能是不同的值。這是可以的。Process A 將使用它的控制代碼值,而Process B 則使用它自己的控制代碼值來操作一個互斥核心對象。

按名字共用對象的另一種方法是,進程不調用C r e a t e *函數,而是調用下面顯示的O p e n *函數中的某一個,如: HANDLE OpenMutex(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);

HANDLE OpenEvent(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);

HANDLE OpenSemaphore(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);

HANDLE OpenWaitableTimer(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);

HANDLE OpenFileMapping(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);

調用Create*與調用Open*來建立開啟核心對象有什麼區別呢?
調用C r e a t e *函數與調用O p e n *函數之間的主要差別是,如果對象並不存在,那麼C r e a t e *函數將建立該對象,而O p e n *函數則運行失敗。

4.複製核心物件控點:
    共用跨越進程邊界的核心對象的最後一個方法是使用D u p l i c a t e H a n d l e 函數: BOOL DuplicateHandle(
   HANDLE hSourceProcessHandle,
   HANDLE hSourceHandle,
   HANDLE hTargetProcessHandle,
   PHANDLE phTargetHandle,
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   DWORD dwOptions);

簡單說來,該函數取出一個進程的控制代碼表中的項目,並將該項目拷貝到另一個進程的控制代碼表中。

二,進程

1.何為進程,進程有何特性?
    所謂進程,就是一個正在運行程式的執行個體。它由兩部分組成:
    • 一個是作業系統用來管理進程的核心對象。
    • 另一個是地址空間,它包含所有可執行模組或D L L 模組的代碼和資料。它還包含動態記憶體分配的空間。如線程堆棧和堆分配空間。

   注意,進程是不活潑的,即進程完成的操作,是需要靠進程中的線程來完成。每個進程都必須有一個線程,也可以有多個線程。線程負責執行包含在進程地址空間內的代碼。所謂多線程,就是多個線程同時執行包含在地址空間內的代碼。
    若要使線程執行進程內的代碼,作業系統必須為線程分配CPU時間片。它是以一種迴圈的方式來提供時間片的,即給每個線程多少時間,時間完成之後,收回CPU,轉交給另外的線程。
    建立一個進程,系統會自動為其進程建立一個主線程。然後,可利用該線程可以建立其它的線程,其正是多線程。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.