核心物件的控制代碼是程序相關的,這樣更可靠,更安全;windows提供下列n種機制來允許程序共享核心物件。
只有程序間存在父子關係才能使用物件控制代碼繼承;系統會遍歷父程序的控制代碼表將所有有效的控制代碼完整的複製到子程序的控制代碼表中(這個動作只會在建立子程序的進行一次,後續父程序再建立控制代碼物件,子程序不會再繼承),並且增加控制代碼的使用計數(類似於智慧型指標,close等操作只是將使用計數減一)。
createprocess建立程序,指定引數binherithandles為true指定為父子程序,進行物件控制代碼繼承,控制代碼跟程序有關,只有繼承後子程序才能使用父程序控制代碼;
例如:通過命令列引數將控制代碼值傳遞給子程序)
通過設定父程序環境變數,子程序獲取getenvironmentvariable;
如果子程序是有視窗的程式 通過函式waitforinputidle等待視窗程式初始化完成後 向視窗發訊息;
父程序跟孫程序通訊,不讓子程序關閉控制代碼。通過sethandleinfomation改變具柄狀態,但是子程序也可以改這個狀態從而關閉控制代碼(這就很尷尬了)。
sethandleinformation具體使用請看msdn
bool winapi sethandleinformation(
_in_ handle hobject,//要設定其資訊的物件的控制代碼。
_in_ dword dwmask,
_in_ dword dwflags
);//每個控制代碼都關聯了兩個標誌
#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) ;
//handle_flag_protect_from_close標誌告訴系統不允許關閉控制代碼
sethandleinformation(hobj, handle_flag_protect_from_close, handle_flag_protect_from_close);
closehandle(h0bj); //會引發異常
通過物件的名稱來共享核心物件,並不需要父子程序關係; windows大多數物件都可以進行命名,但是並沒有提供保證為核心物件指定的名稱是唯一的,所以命名可以以「公司名稱+隨機字元+名稱」等方式來命名。以這樣的私有命名方式,防止單例項程式被攻擊(命名衝突,導致一直不能啟動程式)。
呼叫( create )系列函式可以通過呼叫getlasterror來判斷是開啟了乙個已用的物件還是建立了乙個新的物件。(open)系列函式如果不存在否則返回null。
應用例子:可以利用命名物件來防止程式執行多個例項。
handle createmutex(
lpsecurity_attributes lpmutexattributes,
bool binitialowner,
lpctstr lpname //物件名稱 傳入null建立匿名物件
); if ( hmutex )
else
獲得乙個程序的控制代碼表的乙個記錄項,然後在另外乙個程序的控制代碼表中建立這個記錄項的乙個副本。同樣的目標程序並不知道它能訪問什麼核心物件,必須使用程序間通訊方式告訴它控制代碼值;這時已經啟動,所以不能使用命令列引數或程序的環境變數。
bool winapi duplicatehandle(
_in_ handle hsourceprocesshandle, // 源程序核心物件
_in_ handle hsourcehandle, // 源任何型別核心物件;不能與呼叫duplicatehandle函式的程序相關,必須與hsourceprocesshandle控制代碼所標識的程序相關(除非hsourceprocesshandle就是呼叫duplicatehandle函式的程序,即當前程序)
_in_ handle htargetprocesshandle, // 目標程序核心物件
_out_ lphandle lptargethandle, // handle變數的位址,用來接收複製得到的handle值;不能呼叫closehandle(除非htargetprocesshandle就是呼叫duplicatehandle函式的程序,即當前程序)
_in_ dword dwdesiredaccess,
_in_ bool binherithandle,
_in_ dword dwoptions
);
btw:子程序與父程序通訊不應該使用程序id,應該使用核心物件或者視窗控制代碼等更持久的通訊機制。因為系統分配程序id是會**重新使用的。 Windows下程序間通訊及資料共享
程序是裝入記憶體並準備執行的程式,每個程序都有私有的虛擬位址空間,由 資料以及它可利用的系統資源 如檔案 管道等 組成。win32 api中共享記憶體 shared memory 實際就是檔案對映的一種特殊情況。程序在建立檔案對映物件時用0xffffffff來代替檔案控制代碼 handle 就表示了...
程序間共享記憶體
位於系統的交換分割槽 include incude int shmget key t key,size t size,int shm ipc excl ipc creat一起使用可確保共享記憶體已存在時返回錯誤 void shmat int shm id,const void shm addr,in...
Windows 下的程序間通訊及資料共享
windows 下有很多方法實現程序間通訊,比如用 socket,管道 pipe 信箱 mailslot 等等。但最基本最直接的還是使用記憶體共享。其他方法最終還是會繞道這裡。可想而知,如果物理記憶體只有乙份,讓這份內存在不同的程序中,對映到各自的虛擬位址空間上,每個程序都可以讀取同乙份資料,是一種...