標籤:des 使用 檔案 os 資料 for
正在拜讀《windows核心編程》,稍後總結。---------XiaoF
先說說為何要實現此功能
1,利用檔案對應物件,可以在同一電腦的不同進程之間共用資料區塊。
2,藉助郵件槽和具名管道,在網路中的不同電腦上啟動並執行進程相互發送訊息。
3,互斥量。訊號量。事件,允許不同進程中的線程做同步。
如何?,方法3種:使用物件控點繼承(父子進程);為對象命名;複製物件控點。
使用物件控點繼承
只有在父子進程關係,才可以用物件控點繼承方法。
步驟如下:
1,當父進程建立一個核心對象時,必須向系統指明這個物件控點是否希望子進程繼承。(對象繼承這種說法是不正確的,應
該是物件控點繼承。
為了建立一個可繼承的控制代碼,需分配並初始化 SECURITY_ATTRIBUTES結構,並將結構地址傳給Create*函數。
例如建立一個互斥量對象:
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE; // Make the returned handle inheritable
HANDLE hMutex= CreateMutex(&sa, FALSE , NULL);
註解:SECURITY_ATTRIBUTES 結構的成員變數,nLength結構體大小;lpSecurityDescriptor 為安全訪問描述符,如果想對
建立的對象記憶訪問限制,修改此值;bInheritHandle 此變數如果是true 則是可以繼承。
2,建立子進程
BOOL CreateProcess(PCTSTR pszApplicationName,PTSTR pszCommandLine,·······, Bool bInheritHandles, ······);
注意bInherithandles ,再產生一個進程時:此值決定子進程是否可以繼承父進程控制代碼表中的“可繼承控制代碼”;
如果bInheritHandles為True,系統會做三件事:1,建立子進程並建立一個新的進程控制代碼表;2:,遍曆父進程控制代碼表,凡是標誌是
可繼承的控制代碼,就複製到子進程的控制代碼表中(位置也一樣,完全一致);3, 系統還會遞增核心對象的使用計數。
註:物件控點的繼承只會發生在子進程產生時,假如父進程又建立了一個核心對象,並同樣將他的控制代碼設為可繼承的控制代碼。正在啟動並執行
子進程不會繼承這個核心對象的。
子進程是不會知道自己繼承的核心對象的控制代碼的。在子進程文檔中英指出他從另一個進程產生時,希望還獲得核心隊形控制代碼。
3,為了使子進程得到想要的核心物件控點,最常用的方法是:控制代碼值作為命令列參數傳給子進程;進程通迅技術(WaitForInputIdle函數);父進程想起環境快中添加環境變數;
整理一下思路,稍後繼續 ------XiaoF
對象命名
許多核心對象都可以進行命名。
1,在一個進程A中建立一個核心對象:
例如:上面所用例子:
HANDLE CreateMutex(
PECURITY_ATTRIBUTES psa,
BOOL bInitialOwner,
PCTSTR pszname);
最後一個參數pszName,向此參數傳入NULL,相當於讓系統建立一個未命名的核心對象,可以利用繼承技術來實現共用核心對象;如
果想使用對象命名來實現,必須為此函數賦值。
paName賦值是“以0為終止符的名稱字串”的地址。這個名稱可以長達MAX_PATH個位元組。
例如建立一個互斥對象:
HANDLE hMutex = CreateMutex(NULL,FALSE,TEXT("XiaoF_Object");
注意:Microsoft沒有提供任何機制來保證核心對象名稱的唯一性(解決名稱唯一的方法:專有命名空間)
,所以如果在名義一個XiaoF_Object的對象將會失敗
註解:例如在建立一個訊號對象:
HANDLE hSem = CreateSemaphore(NULL,1,1,TEXT("XiaoF_Object");
DWORD dwErrorCode = GetLastError();
結果dwErrorCode 的值為6(ERROR_INVALID_HANDLE),控制代碼錯誤。
2,在另一個進程中建立一個進程B:
在進程B中建立一個名稱為XiaoF_Object的對象。
系統會查看是否存在XiaoF_Object的對象,如果存在,接著檢查對象的類型,如果類型一致,接著執行一次安全檢查,驗證調用者是否對該對象擁有完整存取。如果是,系統就會在進程B的控制代碼表中找到空白項,初始化為指向現有的核心對象。如果對象的類型不符或者調用被拒絕,就會失敗(返回NULL);
調用Create*建立對象函數成功後,未建立對象,其實是process B分配了一個新的Handle,他表示了核心中現有的對象。
核心對象的計數+1;
還可以使用Open* 函數
參數和Create* 一樣。如果沒有找到同名的核心對象,函數返回NULL,GetLastError返回2(ERROR_FILE_NOT_FOUND); 如果找到同名的對象,但是類型不同,函數返回NULL,GetLastError返回6,(ERROR_INVALID_HANDLE);如果同名同類型,系統會檢查請求的訪問(通過dwDesiredAccess制定)是否允許。如果均通過,系統跟新調用進程的控制代碼表,並核心對象計數+1;
Create* 和Open* 的區別:如果核心對象不存在,Create*會建立核心對象,而Open* 只會返回失敗。