c语言osversioninfoex,xi52qian
頭文件
一. 對終端的操作
相關頭文件#include
1. 輸入istream
2. 輸出ostream
3. iostream繼承istream和ostream 所以它具有輸入輸出功能。
為了方便這個庫定義了下列三個標準流對象:
1. cin? 代表標準輸入istream類對象一般地cin使我們能夠從用戶終端讀入數據。
2. cout 代表標準輸出ostream類對象一般地cout使我們能夠向用戶終端寫數據。
3. cerr 代表標準錯誤ostream類對象一般地cerr是導出程序錯誤消息的地方。
另外,輸出主要由重載的左移操作符<< 來完成類似地輸入主要由重載的右移操作符>>來完成。
Demo1:
#include
#include
int main() {
string in_string;
// 向用戶終端寫字符串
std::cout << "Please enter your name:";
// 把用戶輸入的讀取到 in_string 中
std::cin >> in_string;
if ( in_string.empty() )
// 產生一個錯誤消息輸出到用戶終端
std::cerr << "error: input string is empty!\n";
else std::cout << "hello," << in_string << "!\n";
}
二. 對文件的操作
相關頭#include
1. ifstream 從istream 派生把一個文件綁到程序上從文件讀取數據用來輸入。
2. ofstream 從ostream 派生把一個文件綁到程序上用來向文件寫入數據。
3. fstream 從iostream 派生把一個文件綁到程序上用來輸入和輸出。
注:由于在fstream 頭文件中也包含了iostream 頭文件所以我們不需要同時包含這兩個文
件C++對于文件的輸入輸出也支持同樣的輸入和輸出操作符。
Demo2:
#include
#include
#include
#include
int main()
{
string ifile;
cout << "Please enter file to sort:";
cin >> ifile;
// 構造一個 ifstream 輸入文件對象
ifstream infile( ifile.c_str() );
if( ! infile ) {
cerr << "error: unable to open input file:" << ifile << endl;
return -1;
}
string ofile = ifile + ".sort";
// 構造一個 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;
}
三. 對字符流操作
相關的頭文件#include
1 istringstream 從istream 派生從一個字符串中讀取數據。
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. 支持所有的內置數據類型 包括string ,const char* 和complex。以及函數的調用。
2. endl等價于輸出換行操作符,然后再刷新緩存區。cout << '\n' << flush;
3. <
4. cout << p << &i << endl;會輸出指針的地址(p是int *,i是int)。如果是const char * pcStr不會輸出指針地址值,
輸出的是字符串。轉換為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 >> 變量)的時候有兩種情況會讓循環停止(false):
(1) 讀到文件結束在這種情況下我們已經正確地讀完文件中所有的值。
(2) 遇到一個無效的值比如3.14159小數點是非法的1e-1字符文字e是非法的或者一般的任意字符串文字在讀入一個無效值的
情況下istream對象被放置到一種錯誤的狀態中并且對于值的所有讀入動作都將停止。
2. 預定義的輸入操作符可以接受任何的內置數據類型包括C 風格字符由以及標準庫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()方法一個個讀入,或者設置skipws和noskipws選項(后面介紹)。
5. isream_iterator和cin關聯使用。
Demo6:
#include
#include
#include
#include
int main()
{
istream_iterator< string > in( cin ), eos ;
vector< string > text ;
// 從標準輸入向 text 拷貝值
copy( in , eos , back_inserter( text ) ) ;
sort( text.begin() , text.end() ) ;
// 刪除所有重復的值
vector< string >::iterator it ;
it = unique( text.begin() , text.end() ) ;
text.erase( it , text.end() ) ;
// 顯示結果 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函數:防止讀入字符串益處(char[4],輸入4個以上字節),while ( cin >> setw( bufSize ) >> buf )
這里bufSize是字符數組buf的長度setw()把長度等于或大于bufSize 的字符串分成最大長度為bufSize - 1的兩個
或多個字符串,在每個新串的末尾放一個空字符為了使用setw()要求程序包含iomanip頭文件#include 。
2. 用string沒有char *那些長度和內存溢出問題,更容易使用。
20.3 其他輸入輸出操作符
一. istream的成員get()一次讀入一個字節。屬于istream
1. get(char& ch)從輸入流中提取一個字符包括空白字符并將它存儲在ch中它返回被應用的istream對象。
與之對應的是ostream的put()方法,每次讀入一個字節,然后返回ostream。
2. get()的第二個版本也從輸入流讀入一個字符區別是它返回該字符值而不是被應用的istream 對象它的返回類型
是int 而不是char 因為它也返回文件尾的標志end-of-file該標志通常用-1 來表示以便與字符集區分開為測試返回
值是否為文件尾我們將它與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 代表一個字符數組用來存放被讀取到的字符。
(2) size 代表可以從istream 中讀入的字符的最大數目。
(3) delimiter 表示如果遇到它就結束讀取字符的動作delimiter 字符本身不會被讀入而是留在istream 中作為istream 的
下一個字符一種常見的錯誤是在執行第二個get()之前忘了去掉delimiter。
二. ignore( streamsize length = 1, int delim = traits::eof )函數: 屬于istream
我們用istream 成員函數ignore()來去掉delimiter
缺省情況下換行符被用作delimiter。
三. gcount()函數: 屬于istream
它返回由最后的get()或getline()調用實際提取的字符數。
Demo8:
#include
int main()
{
const int max_line = 1024;
char line[ max_line ];
while ( cin.get( line, max_line ))
{
// 最大讀取數量 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
提供了另外一種方法可以輸出字符數組”它不是輸出直到終止空字符為止的所有字符“而是輸出某個長度的字符序列包括內含的
空字符它的函數。length 指定要顯示的字符個數write()返回當前被調用的ostream 類對象。
六. read( char* addr, streamsize size )屬于istream
read()從輸入流中提取size 個連續的字節并將其放在地址從addr 開始的內存中gcount()返回由最后一個read()調用提取的字
節數而read()返回當前被調用的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();
// 統計: 行數最長行
++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()實例的行為如下讀入最大數目為str::max_size-1 個字符如果輸入序列超出這個限制則讀操作失敗
并且istream 對象被設置為錯誤狀態否則當讀到delimiter 它被從istream 中丟棄但沒有被插入到string 中或遇
到文件結束符時輸入結束。
八. 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 <
{
// 準備對象的特定邏輯
// 成員的實際輸出
os << // ...
// 返回 ostream 對象
return os;
}
注:因為第一個實參是一個ostream 引用所以輸出操作符必須定義為非成員函數,當輸出操作符要求訪問非公有成員
時必須將它聲明為該類的友元。
20.5 重載輸入操作符>>
1 由于不正確的格式而導致失敗istream 應該把狀態標記為fail。setstate( ios_base::failbit )。
2 對于錯誤狀態中的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;
/* 讀入小于符號, 如果不存在
* 則設置 istream 為失敗狀態并退出
*/
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的構造函數要制定打開模式
輸出模式ios_base::out 或附加模式ios_base::app 等等。在缺省情況下ostream文件以輸出模式打開。
注:如果在輸出模式下打開已經存在的文件則所有存儲在該文件中的數據都將被丟棄如果我們希望增加而不是替換現
有文件中的數據則應該以附加模式打開文件于是新寫到文件中的數據將添加到文件尾部在這兩種模式下如果文件不存
在程序都會創建一個新文件。
2. 判斷是否打開if (!outFile /*ofstream對象*/)
3. 因為ofstream派生于ostream,所以ofstream擁有ostream的操作,比如put()等等。
4. 自定義<
5. 用ifstream讀入一個文件,派生于istream,所有擁有istream的操作,比如get()等等。
6. close()函數斷開和文件的關聯。
7. fstream派生于iostream,它具有對文件的讀寫操作。
8. seekg和seekp標記當前位置,g是在讀文件中使用,p再寫文件中使用。
注:第二個參數標示定位標記:
(1) ios_base::beg 文件的開始
(2) ios_base::cur 文件的當前位置
(3) ios_base::end 文件的結尾
9. tellg()或tellp()返回當前位置,g和p意義同seekg和seekp。返回值是ios_base::pos_type。
10. clear()函數:清除狀態。
20.7 條件狀態
一. 條件狀態
1 如果一個流遇到文件結束符則eof()返回true。
2 如果試圖做一個無效的操作比如seeking 重定位操作超出了文件尾則bad()返回true,一般地這表示該流由于某種
未定義的方式而被破壞了。
3 如果操作不成功比如打開一個文件流對象失敗或遇到一種無效的輸入格式則fail()
返回true 例如
ifstream iFile( filename, ios_base::in );
if ( iFile.fail() ) // 不能打開
error_message( ... );
4 如果其他條件都不為true 則good()返回true
二. 改變狀態
1. clear()函數,狀態變為顯示。
2. setstate()函數,添加狀態。參數設置為:
ios_base::badbit
ios_base::eofbit
ios_base::failbit
ios_base::goodbit
3. rdstate()獲取成員狀態,返回值ios_base::iostate。
20.8 string 流
1. 包括頭文件#include
2. str()返回與ostringstream 類對象相關聯的string 對象。
20.9 格式狀態
操 作 符??????????????????? 含 義
boolalpha?????????????? 把true 和false 表示為字符串
*noboolalpha??????????? 把true 和false 表示為0 1
showbase??????????????? 產生前綴指示數值的進制基數
*noshowbase???????????? 不產生進制基數前綴
showpoint?????????????? 總是顯示小數點
*noshowpoint??????????? 只有當小數部分存在時才顯示小數點
Showpos???????????????? 在非負數值中顯示+
*noshowpos????????????? 在非負數值中不顯示+
*skipws???????????????? 輸入操作符跳過空白字符
noskipws??????????????? 輸入操作符不跳過空白字符
uppercase?????????????? 在十六進制下顯示0X 科學計數法中顯示E
*nouppercase??????????? 在十六進制下顯示0x 科學計數法中顯示e
*dec??????????????????? 以十進制顯示
hex???????????????????? 以十六進制顯示
oct???????????????????? 以八進制顯示
left??????????????????? 將填充字符加到數值的右邊
right?????????????????? 將填充字符加到數值的左邊
Internal??????????????? 將填充字符加到符號和數值的中間
*fixed????????????????? 以小數形式顯示浮點數
scientific????????????? 以科學計數法形式顯示浮點數
flush?????????????????? 刷新ostream 緩沖區
ends??????????????????? 插入空字符然后刷新ostream 緩沖區
endl??????????????????? 插入換行符然后刷新ostream 緩沖區
ws????????????????????? 吃掉 空白字符
// 以下這些要求 #include
setfill(ch)??????????? 用ch 填充空白字符
setprecision(n)??????? 將浮點精度設置為n
setw(w)??????????????? 按照w 個字符來讀或者寫數值
setbase(b)???????????? 以進制基數b 輸出整數值
注*表示缺省的流狀態
20.10 強類型庫
iostream庫是強類型的例如試圖從一個ostream 讀數據或者寫數據到一個istream都會在編譯時刻被捕獲到并標記為類型違例。
posted @ 2011-03-03 08:37 xi52qian 閱讀(222) | 評論 (0) |?編輯?收藏
3.1 什么是內核對象
內核對象就是內核中的一塊內存,是一個結構,并且只能由內核對象訪問,應用程序只能通過調用Windows提供的函數來操作內核對象。每個內核對象都有相同的部分比如安全屬性和使用計數器。
3.1.1 內核對象的使用計數
內核對象中的使用計數和進程無關,當進程第一次創建某個內核對象時候使用計數變為1,當另一個進程也調用此內核對象時計數變為2。當進程釋放時或者關閉內核對象時(CloseHandle),內核的使用計數減去1,如果使用計數不為0的話,內核不會釋放此內核對象。
3.2.2 安全性
內核對象能夠得到安全描述符的保護,安全描述符定義了誰能夠創建,訪問和使用該對象,一般在服務器代碼中使用,客戶端可以忽略。
所有創建內核對象的函數的參數都有一個指向SECURITY_ATTRIBUTES結構的指針。typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;只有lpSecurityDescriptor成員和安全屬性有關。一般此參數傳遞NULL,表示默認的安全描述。如果需要:
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
HANDLE h = CreateMutex(&sa, FALSE, "XI");
其余進程可用用OpenMutex函數打開,如果權限可以就返回句柄,如果失敗返回NULL,GetLastError被設置為ERROR_ACCESS_DENIED。
Windows除了內核對象之外還有GDI和用戶對象,區分它們的簡單辦法就是,創建函數中帶有安全描述符參數的就是內核對象。
3.2 進程的內核對象句柄表
索引???????????????????????? 內核對象內存塊得指針???????????????????????????? 訪問屏蔽(標志位的DWORD)????????????????????? 標志(標志位的DWORD)
1?????????????????????????????? 0x??????????????????????????????????????????????????????? 0x??????????????????????????????????????????????????????????????? 0x????????
2?????????????????????????????? 0x??????????????????????????????????????????????????????? 0x??????????????????????????????????????????????????????????????? 0x????????
…?????????????????????????????? …?????????????????????????????????????????????????????????????? …?????????????????????????????????????????????????????????????????????? …
3.2.1 創建內核對象
調用Create&函數族來創建相應的內核對象,返回的是內核對象的句柄(也有個說法就是句柄表的索引),如果創建失敗一般會返回0(NULL),也有的會返回INVALID_HANDLE_VALUE=-1,比如CreateFile失敗后會返回后者,失敗的原因有可能是內存不足或者是安全問題等等。其他對內核操作的函數都需要此句柄值作為參數傳遞進去,如果傳遞一個無效的句柄進去,那么GetLastError函數的值將被置為6(ERROR_INVALID_HANDLE)。
3.2.2 關閉內核對象
BOOL CloseHandle(HANDLE hobj);
調用此函數,系統會了清理進程的句柄表中的對應項目,如果使用計數器為0,內核釋放該內核對象的資源,如果使用計數器不為0,說明其他進程還在使用此內核對象,則不釋放資源。
當進程忘記調用CloseHandle函數,可能造成內存泄露,但是當進程結束的時候資源一樣會被釋放。
如果傳遞的參數無效,則函數返回FALSE,并且GetLastError函數的值被設置成ERROR_INVALID_HANDLE。如果是DEBUG階段,則返回錯誤信息。
3.3 跨越進程邊界共享內核對象
3.3.1 對象句柄的繼承性
在父進程創建子進程的時候,將參數SECURITY_ATTRIBUTES結構的Inherithandle字段設置為TRUE的話,再父進程句柄表中標示該內核對象的項的標志位的值將會變成TRUE,標示該內核對象是可以讓子進程繼承的,具有可繼承性(僅僅標示 該句柄值具有可繼承性,而內核對象沒有可繼承性)。
將CreateProcess的參數bInherithandle參數的值設置為TRUE,標示創建的進程可以繼承有繼承性的父進程句柄。
子進程創建后不會先加載程序,它先搜索父進程的句柄表將有繼承性的項目原封不動的拷貝給自己(索引也沒有變,所以句柄值也不變)。
父進程可以有3種方式將句柄值傳遞給子進程,參數傳遞,進程間通信和環境變量(GetEnvironmentVariavle函數解析)。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
);注意:子進程再創建其子進程,如果滿足上面方式,可以繼續繼承。如果父進程再創建子進程后,再創建句柄,子進程不會被繼承。3.3.2 改變句柄標志
BOOL SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags);
改變句柄的標志,目前可改變的標志有兩種
#define HANDLE_FLAG_INHERIT?? 0x00000001? // 繼承標志
#define HANDLE_FLAG_PROJECT_FROM_CLOSE?? 0x00000001 // 保護不允許關閉句柄標志
可以用OR操作同時設置2個標志。第一個參數是要設置的句柄值,第二個就是要改變的標志,第三個參數是將標志改編成什么值。
BOOL GetHandleInformation(HANDLE hObkect, PDWORD pdwFlags);
獲取當前句柄的標志的值。
// 設置句柄值可繼承:
SetHandleInformation(hObject, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
// 設置句柄不可繼承:
SetHandleInformation(hObject, HANDLE_FLAG_INHERIT, 0);
// 設置句柄值不可關閉,受保護:
SetHandleInformation(hObject, HANDLE_FLAG_PROJECT_FROM_CLOSE, HANDLE_FLAG_PROJECT_FROM_CLOSE);
// 設置句柄值可關閉,不受保護:
SetHandleInformation(hObject, HANDLE_FLAG_PROJECT_FROM_CLOSE, 0);
3.3.3 命名對象
創建內核對象函數族Create&中的最后一個參數是pszName,該參數是如果傳遞NULL,表示是匿名內核對象,可以通過其他倆種方式來使用其他進程的內核對象。當pszName參數傳遞以’\0’(最多長度為MAX_PATH 260字符)結尾的字符串時,表示啟用命名對象,比如進程A調用CreateMutex(NULL, FALSE, “XI”)的時候,他將創建內核對象名字為“XI”,之后某一時刻如果進程B也調用CreateMutex(NULL, FALSE, “XI”)函數他將經過以下幾步:
判斷內核對象名稱是否相同。
判斷內核對象類型是否相同,如果名字相同但是類型不相同則Create&函數族返回NULL,GetLastError函數值為6(ERROR_INVALID_HANDLE)。
判斷安全性,返回同2步,GetLastError值同2步。
如果驗證通過則返回句柄(返回句柄的值和該內核對象其他句柄的值不一定相同),GetLastError的值等于ERROR_ALREADY_EXISTS。
也可以用Open&函數族來打開已經創建的句柄,成功后GetLastError也不會被設置。具體如下
HANDLE Open&(DWORD, BOOL, PCSTR);
第一個參數:表示訪問權限。
第二個參數:表示新創建的句柄是否有繼承性(注意不是內核對象!)。
第三個參數:不能傳遞NULL。如果該句柄不存在則返回NULL,GetLastError被設置為2(ERROR_FILE_NOT_FOUND)。
3.3.4 終端服務器的名字空間
Globad,Local,Session程序保留關鍵字,具體的沒弄明白,理解的就是說當服務器的時候,客戶端可以訪問以這些名字開頭的內核對象。
3.3.5 復制對象句柄
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE TargetProcessHandle,
PHANDLE phTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwOptions);
執行DuplicateHandle函數的進程為ProcessC,原進程為ProcessS,目標進程為ProcessT。則hSourceProcessHandle為進程ProcessS的進程句柄,TargetProcessHandle為進程ProcessT的進程句柄,ProcessC將句柄hSourceHandle從ProcessC拷貝到ProcessT中,值存在phTargetHandle中,dwDesiredAccess新句柄的反問權限,bInheritHandle新句柄的繼承性,參數dwOptions有兩種類型分別是:
DUPLICATE_SAME_ACCESS忽略參數dwDesiredAccess,新句柄和原進程句柄具有相同的反問權限。
DUPLICATE_CLOSE_SOURCE關閉ProcessS中的拷貝句柄,內核對象的計數不變。
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函數沒有在三個進程中使用,因為很難知道原進程的句柄值。
要使用IPC機制通知目標進程,新句柄已經拷貝過去。
posted @ 2011-03-03 08:35 xi52qian 閱讀(197) | 評論 (1) |?編輯?收藏
總結
以上是生活随笔為你收集整理的c语言osversioninfoex,xi52qian的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言动画原理,动画详解十大经典排序算法
- 下一篇: 位置环PID模糊C语言,PID和位置环