c语言osversioninfoex,xi52qian
頭文件
一. 對終端的操作
相關(guān)頭文件#include
1. 輸入istream
2. 輸出ostream
3. iostream繼承istream和ostream 所以它具有輸入輸出功能。
為了方便這個庫定義了下列三個標(biāo)準(zhǔn)流對象:
1. cin? 代表標(biāo)準(zhǔn)輸入istream類對象一般地cin使我們能夠從用戶終端讀入數(shù)據(jù)。
2. cout 代表標(biāo)準(zhǔn)輸出ostream類對象一般地cout使我們能夠向用戶終端寫數(shù)據(jù)。
3. cerr 代表標(biāo)準(zhǔn)錯誤ostream類對象一般地cerr是導(dǎo)出程序錯誤消息的地方。
另外,輸出主要由重載的左移操作符<< 來完成類似地輸入主要由重載的右移操作符>>來完成。
Demo1:
#include
#include
int main() {
string in_string;
// 向用戶終端寫字符串
std::cout << "Please enter your name:";
// 把用戶輸入的讀取到 in_string 中
std::cin >> in_string;
if ( in_string.empty() )
// 產(chǎn)生一個錯誤消息輸出到用戶終端
std::cerr << "error: input string is empty!\n";
else std::cout << "hello," << in_string << "!\n";
}
二. 對文件的操作
相關(guān)頭#include
1. ifstream 從istream 派生把一個文件綁到程序上從文件讀取數(shù)據(jù)用來輸入。
2. ofstream 從ostream 派生把一個文件綁到程序上用來向文件寫入數(shù)據(jù)。
3. fstream 從iostream 派生把一個文件綁到程序上用來輸入和輸出。
注:由于在fstream 頭文件中也包含了iostream 頭文件所以我們不需要同時包含這兩個文
件C++對于文件的輸入輸出也支持同樣的輸入和輸出操作符。
Demo2:
#include
#include
#include
#include
int main()
{
string ifile;
cout << "Please enter file to sort:";
cin >> ifile;
// 構(gòu)造一個 ifstream 輸入文件對象
ifstream infile( ifile.c_str() );
if( ! infile ) {
cerr << "error: unable to open input file:" << ifile << endl;
return -1;
}
string ofile = ifile + ".sort";
// 構(gòu)造一個 ofstream 輸出文件對象
ofstream outfile( ofile.c_str() );
if( !outfile ) {
cerr << "error: unable to open output file:" << ofile << endl;
return -2;
}
string buffer;
vector text;
int cnt = 1;
while ( infile >> buffer ) {
text.push_back( buffer );
cout << buffer << ( cnt++ % 8 ? "" : "\n" );
}
sort( text.begin(), text.end() );
// ok: 把排序后的詞打印到 outfile
vector::iterator iter = text.begin();
for ( cnt = 1; iter != text.end(); ++iter, ++cnt )
outfile << *iter << (cnt%8 ? "" : "\n" );
return 0;
}
三. 對字符流操作
相關(guān)的頭文件#include
1 istringstream 從istream 派生從一個字符串中讀取數(shù)據(jù)。
2 ostringstream 從ostream 派生寫入到一個字符串中。
3 stringstream 從iostream 派生從字符串中讀取或者寫入到字符串中。
Demo3:
#include
string program_name( "our_program" );
string version( "0.01" );
// ...
string mumble( int *array, int size )
{
if ( ! array ) {
ostringstream out_message;
out_message << "error:"
<< program_name << "--" << version
<< ":" << __FILE__ << ":" << __LINE__
<
<< "must address some array.\n";
// 返回底層 string 對象
return out_message.str();
}
四. wchar_t型
支持wchar_t類型的流讀寫操作
wcin wcout wcerr wiostream 等等....
20.1 輸出操作符<<
1. 支持所有的內(nèi)置數(shù)據(jù)類型 包括string ,const char* 和complex。以及函數(shù)的調(diào)用。
2. endl等價于輸出換行操作符,然后再刷新緩存區(qū)。cout << '\n' << flush;
3. <
4. cout << p << &i << endl;會輸出指針的地址(p是int *,i是int)。如果是const char * pcStr不會輸出指針地址值,
輸出的是字符串。轉(zhuǎn)換為cout << static_cast(const_cast(pcStr));
5. <
6. ostream_iterator和cout的使用。
Demo4:
#include
#include
#include
#include
string pooh_pals[] = {
"Tigger", "Piglet", "Eeyore", "Rabbit"
};
int main()
{
vector ppals( pooh_pals, pooh_pals+4 );
vector::iterator iter = ppals.begin();
vector::iterator iter_end = ppals.end();
cout << "These are Pooh's pals:";
// 把每個元素拷貝到 cout ...
ostream_iterator< string > output( cout, "" );
copy( iter, iter_end, output );
cout << endl;
}
7. cout << 遇到‘\0’會定制輸出。
20.2 輸入操作符>>
1. while(cin >> 變量)的時候有兩種情況會讓循環(huán)停止(false):
(1) 讀到文件結(jié)束在這種情況下我們已經(jīng)正確地讀完文件中所有的值。
(2) 遇到一個無效的值比如3.14159小數(shù)點是非法的1e-1字符文字e是非法的或者一般的任意字符串文字在讀入一個無效值的
情況下istream對象被放置到一種錯誤的狀態(tài)中并且對于值的所有讀入動作都將停止。
2. 預(yù)定義的輸入操作符可以接受任何的內(nèi)置數(shù)據(jù)類型包括C 風(fēng)格字符由以及標(biāo)準(zhǔn)庫string和complex 類類型。
3. 缺省情況下輸入操作符丟棄任何中間空白空格制表符換行符走紙以及回車。
Demo5:
#include
#include
int main()
{
int item_number;
string item_name;
double item_price;
cout << "Please enter the item_number, item_name, and price:" << endl;
cin >> item_number;
cin >> item_name;
cin >> item_price;
cout << "The values entered are: item#"
<< item_number << ""
<< item_name << "@$"
<< item_price << endl;
}
4. 如果希望讀入空白符號可以利用cin.get()方法一個個讀入,或者設(shè)置skipws和noskipws選項(后面介紹)。
5. isream_iterator和cin關(guān)聯(lián)使用。
Demo6:
#include
#include
#include
#include
int main()
{
istream_iterator< string > in( cin ), eos ;
vector< string > text ;
// 從標(biāo)準(zhǔn)輸入向 text 拷貝值
copy( in , eos , back_inserter( text ) ) ;
sort( text.begin() , text.end() ) ;
// 刪除所有重復(fù)的值
vector< string >::iterator it ;
it = unique( text.begin() , text.end() ) ;
text.erase( it , text.end() ) ;
// 顯示結(jié)果 vector
int line_cnt = 1 ;
for ( vector< string >::iterator iter = text.begin();
iter != text.end() ; ++iter , ++line_cnt )
cout << *iter
<< ( line_cnt % 9 ? "" : "\n" ) ;
cout << endl;
}
20.2.1 字符串輸入
1. setw函數(shù):防止讀入字符串益處(char[4],輸入4個以上字節(jié)),while ( cin >> setw( bufSize ) >> buf )
這里bufSize是字符數(shù)組buf的長度setw()把長度等于或大于bufSize 的字符串分成最大長度為bufSize - 1的兩個
或多個字符串,在每個新串的末尾放一個空字符為了使用setw()要求程序包含iomanip頭文件#include 。
2. 用string沒有char *那些長度和內(nèi)存溢出問題,更容易使用。
20.3 其他輸入輸出操作符
一. istream的成員get()一次讀入一個字節(jié)。屬于istream
1. get(char& ch)從輸入流中提取一個字符包括空白字符并將它存儲在ch中它返回被應(yīng)用的istream對象。
與之對應(yīng)的是ostream的put()方法,每次讀入一個字節(jié),然后返回ostream。
2. get()的第二個版本也從輸入流讀入一個字符區(qū)別是它返回該字符值而不是被應(yīng)用的istream 對象它的返回類型
是int 而不是char 因為它也返回文件尾的標(biāo)志end-of-file該標(biāo)志通常用-1 來表示以便與字符集區(qū)分開為測試返回
值是否為文件尾我們將它與iostream 頭文件中定義的常量EOF 做比較。
Demo7:
#include
int main()
{
int ch;
// 或使用:
// while (( ch = cin.get() ) && ch != EOF)
while (( ch = cin.get()) != EOF)
cout.put(ch);
return 0;
}
3. get(char *sink, streamsize size, char delimiter='\n')
(1) sink 代表一個字符數(shù)組用來存放被讀取到的字符。
(2) size 代表可以從istream 中讀入的字符的最大數(shù)目。
(3) delimiter 表示如果遇到它就結(jié)束讀取字符的動作delimiter 字符本身不會被讀入而是留在istream 中作為istream 的
下一個字符一種常見的錯誤是在執(zhí)行第二個get()之前忘了去掉delimiter。
二. ignore( streamsize length = 1, int delim = traits::eof )函數(shù): 屬于istream
我們用istream 成員函數(shù)ignore()來去掉delimiter
缺省情況下?lián)Q行符被用作delimiter。
三. gcount()函數(shù): 屬于istream
它返回由最后的get()或getline()調(diào)用實際提取的字符數(shù)。
Demo8:
#include
int main()
{
const int max_line = 1024;
char line[ max_line ];
while ( cin.get( line, max_line ))
{
// 最大讀取數(shù)量 max_line - 1, 也可以為 null
int get_count = cin.gcount();
cout << "characters actually read:"
<< get_count << endl;
// 處理每一行
// 如果遇到換行符
// 在讀下一行之前去掉它
if ( get_count & max_line-1 )
cin.ignore();
}
}
四. getline(char *sink, streamsize size, char delimiter='\n')屬于istream
五. write( const char *sink, streamsize length )屬于ostream
提供了另外一種方法可以輸出字符數(shù)組”它不是輸出直到終止空字符為止的所有字符“而是輸出某個長度的字符序列包括內(nèi)含的
空字符它的函數(shù)。length 指定要顯示的字符個數(shù)write()返回當(dāng)前被調(diào)用的ostream 類對象。
六. read( char* addr, streamsize size )屬于istream
read()從輸入流中提取size 個連續(xù)的字節(jié)并將其放在地址從addr 開始的內(nèi)存中g(shù)count()返回由最后一個read()調(diào)用提取的字
節(jié)數(shù)而read()返回當(dāng)前被調(diào)用的istream 類對象。
Demo9:
#include
int main()
{
const lineSize = 1024;
int lcnt = 0; // 讀入多少行
int max = -1; // 最長行的長度
char inBuf[ lineSize ];
// 讀取 1024 個字符或者遇到換行符
while (cin.getline( inBuf, lineSize ))
{
// 實際讀入多少字符
int readin = cin.gcount();
// 統(tǒng)計: 行數(shù)最長行
++lcnt;
if ( readin > max )
max = readin;
cout << "Line #" << lcnt
<< "\tChars read:" << readin << endl;
cout.write( inBuf, readin).put('\n').put('\n');
}
cout << "Total lines read:" << lcnt << endl;
cout << "Longest line read:" << max << endl;
}
七. getline( istream &is, string str, char delimiter );
這個getline()實例的行為如下讀入最大數(shù)目為str::max_size-1 個字符如果輸入序列超出這個限制則讀操作失敗
并且istream 對象被設(shè)置為錯誤狀態(tài)否則當(dāng)讀到delimiter 它被從istream 中丟棄但沒有被插入到string 中或遇
到文件結(jié)束符時輸入結(jié)束。
八. putback( char c ); 將字符放回 iostream。
九. unget();往回重置下一個 istream 項。
十. peek(); 返回下一個字符或 EOF,但不要提取出來。
Demo10:
char ch, next, lookahead;
while ( cin.get( ch ))
{
switch (ch) {
case '/':
// 是注釋行嗎? 用 peek() 看一看:
// 是的? ignore() 余下的行
next = cin.peek();
if ( next == '/' )
cin.ignore( lineSize, '\n' );
break;
case '>':
// 查找 >>=
next = cin.peek();
if ( next == '>' ) {
lookahead = cin.get();
next = cin.peek();
if ( next != '=' )
cin.putback( lookahead );
}
20.4 重載輸出操作符<<
輸出操作符是一個雙目操作符它返回一個ostream 引用重載定義的通用框架如下
// 重載 output 操作符的通用框架
ostream&
operator <
{
// 準(zhǔn)備對象的特定邏輯
// 成員的實際輸出
os << // ...
// 返回 ostream 對象
return os;
}
注:因為第一個實參是一個ostream 引用所以輸出操作符必須定義為非成員函數(shù),當(dāng)輸出操作符要求訪問非公有成員
時必須將它聲明為該類的友元。
20.5 重載輸入操作符>>
1 由于不正確的格式而導(dǎo)致失敗istream 應(yīng)該把狀態(tài)標(biāo)記為fail。setstate( ios_base::failbit )。
2 對于錯誤狀態(tài)中的iostream 插入和提取操作沒有影響。
Demo11:
#include
#include "WordCount.h"
/* 必須修改 WordCount, 指定輸入操作符為友元
class WordCount {
friend ostream& operator<
friend istream& operator>>( istream&, WordCount& );
*/
istream&
operator>>( istream &is, WordCount &wd )
{
/* WordCount 對象被讀入的格式:
* <2> string
* <7,3> <12,36>
*/
int ch;
/* 讀入小于符號, 如果不存在
* 則設(shè)置 istream 為失敗狀態(tài)并退出
*/
if ((ch = is.get()) != '
{
is.setstate( ios_base::failbit );
return is;
}
// 讀入多少個
int occurs;
is >> occurs;
// 取 >; 不檢查錯誤
while ( is && (ch = is.get()) != '>' );
is >> wd._word;
// 讀入位置
// 每個位置的格式: < line, col >
for ( int ix = 0; ix < occurs; ++ix )
{
int line, col;
// 提取值
while (is && (ch = is.get())!= '
is >> line;
while (is && (ch = is.get())!= ',' );
is >> col;
while (is && (ch = is.get())!= '>' );
wd.occurList.push_back( Location( line, col ));
}
return is;
}
20.6 文件輸入和輸出
包含頭文件#include
1. ofstream的構(gòu)造函數(shù)要制定打開模式
輸出模式ios_base::out 或附加模式ios_base::app 等等。在缺省情況下ostream文件以輸出模式打開。
注:如果在輸出模式下打開已經(jīng)存在的文件則所有存儲在該文件中的數(shù)據(jù)都將被丟棄如果我們希望增加而不是替換現(xiàn)
有文件中的數(shù)據(jù)則應(yīng)該以附加模式打開文件于是新寫到文件中的數(shù)據(jù)將添加到文件尾部在這兩種模式下如果文件不存
在程序都會創(chuàng)建一個新文件。
2. 判斷是否打開if (!outFile /*ofstream對象*/)
3. 因為ofstream派生于ostream,所以ofstream擁有ostream的操作,比如put()等等。
4. 自定義<
5. 用ifstream讀入一個文件,派生于istream,所有擁有istream的操作,比如get()等等。
6. close()函數(shù)斷開和文件的關(guān)聯(lián)。
7. fstream派生于iostream,它具有對文件的讀寫操作。
8. seekg和seekp標(biāo)記當(dāng)前位置,g是在讀文件中使用,p再寫文件中使用。
注:第二個參數(shù)標(biāo)示定位標(biāo)記:
(1) ios_base::beg 文件的開始
(2) ios_base::cur 文件的當(dāng)前位置
(3) ios_base::end 文件的結(jié)尾
9. tellg()或tellp()返回當(dāng)前位置,g和p意義同seekg和seekp。返回值是ios_base::pos_type。
10. clear()函數(shù):清除狀態(tài)。
20.7 條件狀態(tài)
一. 條件狀態(tài)
1 如果一個流遇到文件結(jié)束符則eof()返回true。
2 如果試圖做一個無效的操作比如seeking 重定位操作超出了文件尾則bad()返回true,一般地這表示該流由于某種
未定義的方式而被破壞了。
3 如果操作不成功比如打開一個文件流對象失敗或遇到一種無效的輸入格式則fail()
返回true 例如
ifstream iFile( filename, ios_base::in );
if ( iFile.fail() ) // 不能打開
error_message( ... );
4 如果其他條件都不為true 則good()返回true
二. 改變狀態(tài)
1. clear()函數(shù),狀態(tài)變?yōu)轱@示。
2. setstate()函數(shù),添加狀態(tài)。參數(shù)設(shè)置為:
ios_base::badbit
ios_base::eofbit
ios_base::failbit
ios_base::goodbit
3. rdstate()獲取成員狀態(tài),返回值ios_base::iostate。
20.8 string 流
1. 包括頭文件#include
2. str()返回與ostringstream 類對象相關(guān)聯(lián)的string 對象。
20.9 格式狀態(tài)
操 作 符??????????????????? 含 義
boolalpha?????????????? 把true 和false 表示為字符串
*noboolalpha??????????? 把true 和false 表示為0 1
showbase??????????????? 產(chǎn)生前綴指示數(shù)值的進(jìn)制基數(shù)
*noshowbase???????????? 不產(chǎn)生進(jìn)制基數(shù)前綴
showpoint?????????????? 總是顯示小數(shù)點
*noshowpoint??????????? 只有當(dāng)小數(shù)部分存在時才顯示小數(shù)點
Showpos???????????????? 在非負(fù)數(shù)值中顯示+
*noshowpos????????????? 在非負(fù)數(shù)值中不顯示+
*skipws???????????????? 輸入操作符跳過空白字符
noskipws??????????????? 輸入操作符不跳過空白字符
uppercase?????????????? 在十六進(jìn)制下顯示0X 科學(xué)計數(shù)法中顯示E
*nouppercase??????????? 在十六進(jìn)制下顯示0x 科學(xué)計數(shù)法中顯示e
*dec??????????????????? 以十進(jìn)制顯示
hex???????????????????? 以十六進(jìn)制顯示
oct???????????????????? 以八進(jìn)制顯示
left??????????????????? 將填充字符加到數(shù)值的右邊
right?????????????????? 將填充字符加到數(shù)值的左邊
Internal??????????????? 將填充字符加到符號和數(shù)值的中間
*fixed????????????????? 以小數(shù)形式顯示浮點數(shù)
scientific????????????? 以科學(xué)計數(shù)法形式顯示浮點數(shù)
flush?????????????????? 刷新ostream 緩沖區(qū)
ends??????????????????? 插入空字符然后刷新ostream 緩沖區(qū)
endl??????????????????? 插入換行符然后刷新ostream 緩沖區(qū)
ws????????????????????? 吃掉 空白字符
// 以下這些要求 #include
setfill(ch)??????????? 用ch 填充空白字符
setprecision(n)??????? 將浮點精度設(shè)置為n
setw(w)??????????????? 按照w 個字符來讀或者寫數(shù)值
setbase(b)???????????? 以進(jìn)制基數(shù)b 輸出整數(shù)值
注*表示缺省的流狀態(tài)
20.10 強類型庫
iostream庫是強類型的例如試圖從一個ostream 讀數(shù)據(jù)或者寫數(shù)據(jù)到一個istream都會在編譯時刻被捕獲到并標(biāo)記為類型違例。
posted @ 2011-03-03 08:37 xi52qian 閱讀(222) | 評論 (0) |?編輯?收藏
3.1 什么是內(nèi)核對象
內(nèi)核對象就是內(nèi)核中的一塊內(nèi)存,是一個結(jié)構(gòu),并且只能由內(nèi)核對象訪問,應(yīng)用程序只能通過調(diào)用Windows提供的函數(shù)來操作內(nèi)核對象。每個內(nèi)核對象都有相同的部分比如安全屬性和使用計數(shù)器。
3.1.1 內(nèi)核對象的使用計數(shù)
內(nèi)核對象中的使用計數(shù)和進(jìn)程無關(guān),當(dāng)進(jìn)程第一次創(chuàng)建某個內(nèi)核對象時候使用計數(shù)變?yōu)?,當(dāng)另一個進(jìn)程也調(diào)用此內(nèi)核對象時計數(shù)變?yōu)?。當(dāng)進(jìn)程釋放時或者關(guān)閉內(nèi)核對象時(CloseHandle),內(nèi)核的使用計數(shù)減去1,如果使用計數(shù)不為0的話,內(nèi)核不會釋放此內(nèi)核對象。
3.2.2 安全性
內(nèi)核對象能夠得到安全描述符的保護(hù),安全描述符定義了誰能夠創(chuàng)建,訪問和使用該對象,一般在服務(wù)器代碼中使用,客戶端可以忽略。
所有創(chuàng)建內(nèi)核對象的函數(shù)的參數(shù)都有一個指向SECURITY_ATTRIBUTES結(jié)構(gòu)的指針。typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;只有l(wèi)pSecurityDescriptor成員和安全屬性有關(guān)。一般此參數(shù)傳遞NULL,表示默認(rèn)的安全描述。如果需要:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
HANDLE h = CreateMutex(&sa, FALSE, "XI");
其余進(jìn)程可用用OpenMutex函數(shù)打開,如果權(quán)限可以就返回句柄,如果失敗返回NULL,GetLastError被設(shè)置為ERROR_ACCESS_DENIED。
Windows除了內(nèi)核對象之外還有GDI和用戶對象,區(qū)分它們的簡單辦法就是,創(chuàng)建函數(shù)中帶有安全描述符參數(shù)的就是內(nèi)核對象。
3.2 進(jìn)程的內(nèi)核對象句柄表
索引???????????????????????? 內(nèi)核對象內(nèi)存塊得指針???????????????????????????? 訪問屏蔽(標(biāo)志位的DWORD)????????????????????? 標(biāo)志(標(biāo)志位的DWORD)
1?????????????????????????????? 0x??????????????????????????????????????????????????????? 0x??????????????????????????????????????????????????????????????? 0x????????
2?????????????????????????????? 0x??????????????????????????????????????????????????????? 0x??????????????????????????????????????????????????????????????? 0x????????
…?????????????????????????????? …?????????????????????????????????????????????????????????????? …?????????????????????????????????????????????????????????????????????? …
3.2.1 創(chuàng)建內(nèi)核對象
調(diào)用Create&函數(shù)族來創(chuàng)建相應(yīng)的內(nèi)核對象,返回的是內(nèi)核對象的句柄(也有個說法就是句柄表的索引),如果創(chuàng)建失敗一般會返回0(NULL),也有的會返回INVALID_HANDLE_VALUE=-1,比如CreateFile失敗后會返回后者,失敗的原因有可能是內(nèi)存不足或者是安全問題等等。其他對內(nèi)核操作的函數(shù)都需要此句柄值作為參數(shù)傳遞進(jìn)去,如果傳遞一個無效的句柄進(jìn)去,那么GetLastError函數(shù)的值將被置為6(ERROR_INVALID_HANDLE)。
3.2.2 關(guān)閉內(nèi)核對象
BOOL CloseHandle(HANDLE hobj);
調(diào)用此函數(shù),系統(tǒng)會了清理進(jìn)程的句柄表中的對應(yīng)項目,如果使用計數(shù)器為0,內(nèi)核釋放該內(nèi)核對象的資源,如果使用計數(shù)器不為0,說明其他進(jìn)程還在使用此內(nèi)核對象,則不釋放資源。
當(dāng)進(jìn)程忘記調(diào)用CloseHandle函數(shù),可能造成內(nèi)存泄露,但是當(dāng)進(jìn)程結(jié)束的時候資源一樣會被釋放。
如果傳遞的參數(shù)無效,則函數(shù)返回FALSE,并且GetLastError函數(shù)的值被設(shè)置成ERROR_INVALID_HANDLE。如果是DEBUG階段,則返回錯誤信息。
3.3 跨越進(jìn)程邊界共享內(nèi)核對象
3.3.1 對象句柄的繼承性
在父進(jìn)程創(chuàng)建子進(jìn)程的時候,將參數(shù)SECURITY_ATTRIBUTES結(jié)構(gòu)的Inherithandle字段設(shè)置為TRUE的話,再父進(jìn)程句柄表中標(biāo)示該內(nèi)核對象的項的標(biāo)志位的值將會變成TRUE,標(biāo)示該內(nèi)核對象是可以讓子進(jìn)程繼承的,具有可繼承性(僅僅標(biāo)示 該句柄值具有可繼承性,而內(nèi)核對象沒有可繼承性)。
將CreateProcess的參數(shù)bInherithandle參數(shù)的值設(shè)置為TRUE,標(biāo)示創(chuàng)建的進(jìn)程可以繼承有繼承性的父進(jìn)程句柄。
子進(jìn)程創(chuàng)建后不會先加載程序,它先搜索父進(jìn)程的句柄表將有繼承性的項目原封不動的拷貝給自己(索引也沒有變,所以句柄值也不變)。
父進(jìn)程可以有3種方式將句柄值傳遞給子進(jìn)程,參數(shù)傳遞,進(jìn)程間通信和環(huán)境變量(GetEnvironmentVariavle函數(shù)解析)。BOOL
WINAPI
CreateProcess(
__in_opt LPCSTR lpApplicationName,
__inout_opt LPSTR lpCommandLine,
__in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in BOOL bInheritHandles,
__in DWORD dwCreationFlags,
__in_opt LPVOID lpEnvironment,
__in_opt LPCSTR lpCurrentDirectory,
__in LPSTARTUPINFOA lpStartupInfo,
__out LPPROCESS_INFORMATION lpProcessInformation
);注意:子進(jìn)程再創(chuàng)建其子進(jìn)程,如果滿足上面方式,可以繼續(xù)繼承。如果父進(jìn)程再創(chuàng)建子進(jìn)程后,再創(chuàng)建句柄,子進(jìn)程不會被繼承。3.3.2 改變句柄標(biāo)志
BOOL SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags);
改變句柄的標(biāo)志,目前可改變的標(biāo)志有兩種
#define HANDLE_FLAG_INHERIT?? 0x00000001? // 繼承標(biāo)志
#define HANDLE_FLAG_PROJECT_FROM_CLOSE?? 0x00000001 // 保護(hù)不允許關(guān)閉句柄標(biāo)志
可以用OR操作同時設(shè)置2個標(biāo)志。第一個參數(shù)是要設(shè)置的句柄值,第二個就是要改變的標(biāo)志,第三個參數(shù)是將標(biāo)志改編成什么值。
BOOL GetHandleInformation(HANDLE hObkect, PDWORD pdwFlags);
獲取當(dāng)前句柄的標(biāo)志的值。
// 設(shè)置句柄值可繼承:
SetHandleInformation(hObject, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
// 設(shè)置句柄不可繼承:
SetHandleInformation(hObject, HANDLE_FLAG_INHERIT, 0);
// 設(shè)置句柄值不可關(guān)閉,受保護(hù):
SetHandleInformation(hObject, HANDLE_FLAG_PROJECT_FROM_CLOSE, HANDLE_FLAG_PROJECT_FROM_CLOSE);
// 設(shè)置句柄值可關(guān)閉,不受保護(hù):
SetHandleInformation(hObject, HANDLE_FLAG_PROJECT_FROM_CLOSE, 0);
3.3.3 命名對象
創(chuàng)建內(nèi)核對象函數(shù)族Create&中的最后一個參數(shù)是pszName,該參數(shù)是如果傳遞NULL,表示是匿名內(nèi)核對象,可以通過其他倆種方式來使用其他進(jìn)程的內(nèi)核對象。當(dāng)pszName參數(shù)傳遞以’\0’(最多長度為MAX_PATH 260字符)結(jié)尾的字符串時,表示啟用命名對象,比如進(jìn)程A調(diào)用CreateMutex(NULL, FALSE, “XI”)的時候,他將創(chuàng)建內(nèi)核對象名字為“XI”,之后某一時刻如果進(jìn)程B也調(diào)用CreateMutex(NULL, FALSE, “XI”)函數(shù)他將經(jīng)過以下幾步:
判斷內(nèi)核對象名稱是否相同。
判斷內(nèi)核對象類型是否相同,如果名字相同但是類型不相同則Create&函數(shù)族返回NULL,GetLastError函數(shù)值為6(ERROR_INVALID_HANDLE)。
判斷安全性,返回同2步,GetLastError值同2步。
如果驗證通過則返回句柄(返回句柄的值和該內(nèi)核對象其他句柄的值不一定相同),GetLastError的值等于ERROR_ALREADY_EXISTS。
也可以用Open&函數(shù)族來打開已經(jīng)創(chuàng)建的句柄,成功后GetLastError也不會被設(shè)置。具體如下
HANDLE Open&(DWORD, BOOL, PCSTR);
第一個參數(shù):表示訪問權(quán)限。
第二個參數(shù):表示新創(chuàng)建的句柄是否有繼承性(注意不是內(nèi)核對象!)。
第三個參數(shù):不能傳遞NULL。如果該句柄不存在則返回NULL,GetLastError被設(shè)置為2(ERROR_FILE_NOT_FOUND)。
3.3.4 終端服務(wù)器的名字空間
Globad,Local,Session程序保留關(guān)鍵字,具體的沒弄明白,理解的就是說當(dāng)服務(wù)器的時候,客戶端可以訪問以這些名字開頭的內(nèi)核對象。
3.3.5 復(fù)制對象句柄
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE TargetProcessHandle,
PHANDLE phTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions);
執(zhí)行DuplicateHandle函數(shù)的進(jìn)程為ProcessC,原進(jìn)程為ProcessS,目標(biāo)進(jìn)程為ProcessT。則hSourceProcessHandle為進(jìn)程ProcessS的進(jìn)程句柄,TargetProcessHandle為進(jìn)程ProcessT的進(jìn)程句柄,ProcessC將句柄hSourceHandle從ProcessC拷貝到ProcessT中,值存在phTargetHandle中,dwDesiredAccess新句柄的反問權(quán)限,bInheritHandle新句柄的繼承性,參數(shù)dwOptions有兩種類型分別是:
DUPLICATE_SAME_ACCESS忽略參數(shù)dwDesiredAccess,新句柄和原進(jìn)程句柄具有相同的反問權(quán)限。
DUPLICATE_CLOSE_SOURCE關(guān)閉ProcessS中的拷貝句柄,內(nèi)核對象的計數(shù)不變。
HANDLE hObjProcessS = CreateMutex(NULL, FALSE, NULL);
HANDLE hProcessT = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessIdT);
HANDLE hObjProcessT;
DuplicateHandle(GetCurrentProcess(), hObjProcessS, hProcessT , &hObjProcessT, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle(hObjProcessS);
CloseHandle(hProcessT);注意:
一般DuplicateHandle函數(shù)沒有在三個進(jìn)程中使用,因為很難知道原進(jìn)程的句柄值。
要使用IPC機制通知目標(biāo)進(jìn)程,新句柄已經(jīng)拷貝過去。
posted @ 2011-03-03 08:35 xi52qian 閱讀(197) | 評論 (1) |?編輯?收藏
總結(jié)
以上是生活随笔為你收集整理的c语言osversioninfoex,xi52qian的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言动画原理,动画详解十大经典排序算法
- 下一篇: 位置环PID模糊C语言,PID和位置环