MỤC LỤC 1. Mở đầu ..........................................................................................2 2. Khái niệm tiến trình ........................................................................2 3. Thao tác trên tiến trình ....................................................................2 a. Tạo tiến trình ....................................................................................................2 b. Chuỗi công việc tạo ra tiến trình ......................................................................3 c. Kết thúc tiến trình .............................................................................................3 d. Một số hàm quản lý tiến trình...........................................................................4 3.Tiny Shell .........................................................................................4 a. Menu chính :.......................................................................................................4 b. Tạo tiến trình ......................................................................................................5 c. In thông tin các tiến trình con được khởi tạo ...................................................6 d. Kết thúc tiến trình .............................................................................................8 e. Suspend, resume tiến trình ...............................................................................9 f.
Một số hàm khác sử dụng trong TinyShell ....................................................10
Bài tàp lớn TinyShell 1. Mở đầu Bài tập lớn xây dựng một chương trình nhỏ dùng để quản lý tiến trình. Chương trình có thế gọi tạo tiến trình, kết thúc tiến trình con vừa tạo, trì hoạt, khởi động lại tiến trình. In danh sách thông tin của tiến trình con được tạo như process ID, số luồng, id tiến trình cha.. Chương trình được viết trên C, dùng để quán lý các tiến trình chạy trên windows. Sử dụng menu nhập để thực hiện gọi lệnh của chương trình. Trước khi xây dựng được một Tiny shell, chúng cần hiểu rõ hơn về tiến trình cũng như các thao tác quán lý tiến trình.
2. Khái niệm tiến trình Tiến trình là một khái niệm được nhắc tới trong rất nhiều lĩnh vực công nghệ thông tin. Chúng ta sử dụng từ “tiến trình” (process) để diễn tả một thực thể trừu tượng thi hành một chương trình bên trong bộ xử lý. Khái niệm : Tiến trình là một bộ phận của một chương trình đang thực hiện, đơn vị thực hiện tiến trình là processer. Vì tiến trình là một bộ phận của chương trình nên tương tự như chương trình tiến trình bao gồm không gian địa chỉ : Text section (program code), data section (chứa global variables) sở hữu một con trỏ lệnh- program counter (PC), một con trỏ stack- stack pointer (SP), một tập các thanh ghimemory management registers, một không gian địa chỉ trong bộ nhớ chính, tất cả các thông tin cần thiết khác để tiến trình có thể hoạt động được(các open file,các quá trình con,…) , nó còn bao gồm hoạt động hiện hành như được hiện diện bởi giá trị của bộ đếm chương trình và nội dung các thanh ghi của bộ xử lý
3. Thao tác trên tiến trình a. Tạo tiến trình Một tiến trình của Win32 được tạo ra khi một chương trình ứng dụng gọi chức năng tạo tiến trình,ví dụ như một số lệnh: CreateProcess CreateProcessAsUser CreateProcessWithLogonW
Tạo ra một tiến trình và tuyến mới sử dụng sự bảo mật và chứng thực người gọi Tạo ra một tiến trình và tuyến mới với một dấu hiệu bảo mật xác định Tạo ra một tiến trình và tuyến mới với dấu hiệu bảo mật xác định,cho phép hồ sơ về
người sử dụng được nạp Chúng ta tìm hiểu về function CreateProcess,nó có 10 tham số bao gồm chương trình để thi hành,các tham số lệnh cho chương trình,các thuộc tính bảo mật khác,các bit mà điều khiển các file thừa hưởng có được mở hay không,thông tin ưu tiên,một đặc tả của window để khởi tạo cho tiến trình(nếu có),và một con trỏ tới cấu trúc mà thông tin về tiến trình mới đã khởi tạo được gửi lại tới người gọi.
CreateProcess( LPCTSTR lpApplicationName, //Tên của chương trình cần thực hiện LPTSTR lpCommandLine, //Tham số của dòng lệnh LPSECURITY_ATTRIBUTES lpProcessAttributes,//Thuộc tính an ninh tiến trình LPSECURITY_ATTRIBUTES lpThreadAttributes,// thuộc tính an ninh luồng BOOL bInheritHandles,//Cho phép kế thừa các thiết bị DWORD dwCreationFlags,//Cờ tạo tiến trình LPVOID lpEnvironment,//Trở tới khối môi trường LPCTSTR lpCurrentDirectory,//Đường dẫn đầy đủ đến chương trình
b. Chuỗi công việc tạo ra tiến trình Mét tiÕn tr×nh cña Win32 ®-îc t¹o ra khi mét ch-¬ng tr×nh øng dông gäi chøc n¨ng t¹o tiÕn tr×nh vÝ dô nh- CreateProcess , CreateProcessAsUser, hay CreateProcessWithLogonW . T¹o ra mét tiÕn tr×nh Win32 chøa mét vµi giai ®o¹n tiÕn hµnh trong ba phÇn cña hÖ ®iÒu hµnh : th- viÖn Kernell.dll cua Win32 , thùc hiÖn Windows 2000 , t¹o ra mét ®èi t-îng tiÕn tr×nh thùc hiÖn Windows 2000. Danh s¸ch d-íi ®©y tæng kÕt c¸c giai ®o¹n chÝnh trong viÖc t¹o ra mét tiÕn tr×nh Win32 víi hµm CreateProcess. Ho¹t ®éng nµy thùc hiÖn ë mçi giai ®o¹n ®-îc m« t¶ chi tiÕt trong c¸c phÇn d-íi ®©y. 1.Më mét file ¶nh (.exe) ®Ó thùc hiÖn trong tiÕn tr×nh 2.T¹o mét ®èi t-îng tiÕn tr×nh thùc hiÖn WindowsXP 3.T¹o ra mét tuyÕn khëi ®Çu (ng¨n xÕp, ng÷ c¶nh vµ tuyÕn thùc hiÖn WindowsXP) 4.Th«ng b¸o cho hÖ thèng con cña Win32 vÒ mét tiÕn tr×nh míi ®Ó nã cã thÓ khëi t¹o cho tuyÕn vµ tiÕn tr×nh míi. 5.Thi hµnh tuyÕn khëi ®Çu (trõ khi cê cña CREATE_SUSPENDED ®-îc chØ râ) 6. Khi cã tuyÕn vµ tiÕn tr×nh míi, hoµn thµnh sù khëi t¹o cña kh«ng gian ®Þa chØ Cùng với CreateProcess,Win32 có khoảng 100 hàm khác phục vụ việc quản lí và đồng bộ tiến trình liên quan
c. Kết thúc tiến trình Hầu hết các tiến trình kết thúc vì chúng đã được hoàn thành.Khi một trình biên dịch biên dịch xong một chương trình,trình biên dịch này thi hành một lời gọi hệ thống để báo với hệ điều hành rằng nó đã thành công.Lời gọi này là ExitProcess trong Windows.
VOID ExitProcess( UINT uExitCode );
Lí do thứ 2 cho việc kết thúc là tiến trình phát hiện lỗi nghiêm trọng.Ví dụ,nếu ta muốn biên dịch file mkb.c nhưng nó không tồn tại.Thay vì màn hiển thị tương tác các tiến trìh chung bị thoát khi đưa ra tham số sai,nó sẽ mở 1 hộp thoại và yêu cầu người sử dụng thử lại Lí do thứ 3 cho việc kết thúc là do lỗi của tiến trình,thường nhờ vào chương trình kiểm tra lỗi.Ví dụ khi nó có thi hành một lệnh không hợp lệ,ko đủ bộ nhớ hoặc chia cho 0 Lí do thứ 4 là một tiến trình thi hành một lời gọi hệ thống báo cho hệ điều hành hủy các tiến trình khác.Trong Windows hàm đó là TerminateProcess BOOL TerminateProcess( HANDLE hProcess, UINT uExitCode );
d. Một số hàm quản lý tiến trình Suspend một tiến trình DWORD WINAPI SuspendThread( __in HANDLE hThread //thẻ đối tượng );
Suspend một tiến trình DWORD WINAPI SuspendThread( __in HANDLE hThread //thẻ đối tượng );
3.Tiny Shell a. Menu chính :
Tinyshell gồm 9 mục nhỏ:
a. Mục 1, tạo 1 tiến trình con, chạy song song với shell b. Mục 2, tạo 1 tiến trình con, shell sẽ phải chờ tiến trình con thực hiện xong
c. d. e. f. g. h. i.
Mục 3, suspend tiến trình con đang chạy Mục 4, Resum lại tiến trình con vừa bị suspend Mục 5, Hủy tất cả các tiến trình con đang chạy Mục 6, Hủy tiến trình con vừa gọi Mục 7, In ra thông tin của tất cả các tiến trình con như PID, Thread count, Parrent ID… Mục 8, Gọi file run.bat chứa danh sách tiến trình cần thực hiện Mục 9, thoát khỏi shell
b. Tạo tiến trình Xây dựng hàm createprocees() DWORD creatProcess(char* cmline){ // Tao process si.cb = sizeof(si); ZeroMemory(&si, sizeof(si)); if(! CreateProcess(NULL, cmline, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) printf( "CreateProcess failed (%d).\n", GetLastError() ); else printf("Chay thanh cong"); return pi.dwProcessId;}
Để tạo tiến trình con chạy song song với shell gán có tiến trình cờ CREATE_NEW_CONSOLE Để bắt shell chờ cho đến khi tiến trình con thực hiện xong, sử dụng hàm DWORD WINAPI WaitForSingleObject( __in HANDLE hHandle,//Thẻ đối tượng __in DWORD dwMilliseconds //Thời gian chờ đợi
c. In thông tin các tiến trình con được khởi tạo HANDLE WINAPI CreateToolhelp32Snapshot( __in __in );
DWORD dwFlags, DWORD th32ProcessID
Mục đích: Tạo một ảnh chụp (snapshot) để lấy thông tin các tiến trình (cũng như các luồng , các modul) Tham số dwFlags để gọi cái cần liệt kê(để lấy snapshot), ở đây ta dùng TH32CS_SNAPPROCESS để lấy snapshot các tiến trình trong hệ thống, TH32CS_SNAPTHREAD để lấy snapshot các luồng có trong hệ thống. Tham số th32ProcessID để định danh chính xác tiến trình cần lấy snapshot. Để lấy hiện thị thông tin từ snapshot, ta sử dụng một struct có sẵn typedef struct tagPROCESSENTRY32 {
DWORD dwSize; //Kích thước của struct , sẽ được set khi gọi DWORD cntUsage; DWORD th32ProcessID; // Id của tiến trình ULONG_PTR th32DefaultHeapID; DWORD th32ModuleID; // associated exe DWORD cntThreads; //Số luồng của tiến trình DWORD th32ParentProcessID; // ID của tiến trình cha LONG pcPriClassBase; // Base priority of process's threads DWORD dwFlags; CHAR szExeFile[MAX_PATH]; // Tên của tiến trình } PROCESSENTRY32;
Sử dụng hàm sau để duyệt qua tất cả các process từ hệ thống BOOL WINAPI Process32Next( __in HANDLE hSnapshot,// thẻ đối tượng lấy từ hàm CreateToolhelp32Snapshot __out LPPROCESSENTRY32 lppe //Con trỏ đến struct PROCESSENTRY32 ); ----------------------------------------------------------------------------------------//Dùng hàm do while để duyệt tất cả các tiến trình, ví dụ dưới đây dùng để lấy thông t in của //các tiến trình có id tiến trình là processID do{ if(pe32.th32ProcessID==processID){ _tprintf( TEXT("\n\n=====================================================" )); _tprintf( TEXT("\nPROCESS NAME: %s"), pe32.szExeFile ); _tprintf( TEXT("\n-------------------------------------------------------" )); _tprintf( TEXT("\n Process ID = %d"), pe32.th32ProcessID ); // in id cua tien trinh _tprintf( TEXT("\n Thread count = %d"), pe32.cntThreads );//in so luong cua ti en trinh _tprintf( TEXT("\n Parent process ID = %d"), pe32.th32ParentProcessID ); _tprintf( TEXT("\n Priority base = %d"), pe32.pcPriClassBase ); }
}while( Process32Next( hProcessSnap, &pe32 ) );
Hàm lấy danh sách tiến trình BOOL GetProcessList(){ HANDLE hProcessSnap; PROCESSENTRY32 pe32; //Khoi tao con tro den struct DWORD ParentID; ParentID=GetParentID();//Lây id cua tien trinh cha từ hàm GetParentID hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if( hProcessSnap == INVALID_HANDLE_VALUE ) { printError( TEXT("CreateToolhelp32Snapshot (of processes)") ); return( FALSE ); }
// Cap bo nho cho struct truoc khi su dung pe32.dwSize = sizeof( PROCESSENTRY32 ); //Duyet qua snapshot cua tien trinh va hien thi thong tin do{ //Neu la con cua tien trinh cha da goi, //hien thi thong tin cac tien trinh con if(pe32.th32ParentProcessID==ParentID){ _tprintf( TEXT("\n\n===============================================" )); _tprintf( TEXT("\nPROCESS NAME:
%s"), pe32.szExeFile );
_tprintf( TEXT("\n-------------------------------------------------" )); _tprintf( TEXT("\n
Process ID
= %d"), pe32.th32ProcessID );
// in id cua tien trinh _tprintf( TEXT("\n
Thread count
= %d"),
pe32.cntThreads );
//in so luong cua tien trinh _tprintf( TEXT("\n
Parent process ID = %d"),pe32.th32ParentProcessID );
//in id cua tien trinh cha
_tprintf( TEXT("\n
Priority base
= %d"), pe32.pcPriClassBase );
} }while( Process32Next( hProcessSnap, &pe32 ) ); CloseHandle( hProcessSnap ); return( TRUE ); }
d. Kết thúc tiến trình Sử dụng
CreateToolhelp32Snapshot()
đẻ
lấy
snapshot
các
process
trong
hệ
thống.
Sử
dụng
Process32Next() (đã nêu ở trên) để tìm kiếm tiến trình con đang chạy, sử dụng hàm sau để kết thúc tiến trình BOOL TerminateProcess( HANDLE hProcess, UINT uExitCode );
Hàm Kill BOOL Kill(){ HANDLE hProcessSnap; HANDLE hProcess; PROCESSENTRY32 pe32; DWORD ParentID; ParentID=GetParentID(); // Lay 1 snapshot cho tat ca cac tien trinh trong he thong hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if( hProcessSnap == INVALID_HANDLE_VALUE ) { printError( TEXT("CreateToolhelp32Snapshot (of processes)") ); return FALSE; } pe32.dwSize = sizeof( PROCESSENTRY32 ); do{
if(pe32.th32ParentProcessID==ParentID) //Lay the tien trinh tu ID da co
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE,pe32.th32ProcessID); TerminateProcess(hProcess,0);
} while( Process32Next( hProcessSnap, &pe32 ) ); CloseHandle( hProcessSnap ); return TRUE; }
e. Suspend, resume tiến trình Sử dụng CreateToolhelp32Snapshot()(đã được nêu ở trên), để lấy snapshot các luồng đang chạy trong hệ thống, sau đó dùng hàm SuspendThread, ResumeThread để trì hoãn, khởi động lại tiến trình có PID đã biết trước //Ví dụ, Hàm
suspend tiến trình
BOOL Suspend(DWORD dwOwnerPID ) { HANDLE hThreadSnap = INVALID_HANDLE_VALUE; HANDLE hThread; THREADENTRY32 te32; //Lay tat ca cac luong CreateToolhelp32Snapshot()
dang
chay
,khai
báo
TH32CS_SNAPTHREAD
trong
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); if( hThreadSnap == INVALID_HANDLE_VALUE ) return( FALSE ); te32.dwSize = sizeof(THREADENTRY32); //Duyet toan bo cac luong dang chay do { hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID) ; if( te32.th32OwnerProcessID == dwOwnerPID ){ //Lenh suspend thread if(SuspendThread(hThread)==-1){ printf("\nSuspend that bai: Error %d", GetLastError()); return FALSE; }else{ // in ra thread id bi suspend _tprintf( TEXT("\n }
Da supend
THREAD co ID = %d"), te32.th32ThreadID );
hàm
} } while( Thread32Next(hThreadSnap, &te32 ) ); CloseHandle( hThreadSnap ); return( TRUE ); }
f. Một số hàm khác sử dụng trong TinyShell
Hàm này chỉ lấy được ID của tiến trình cha khi đã gọi tiến trình con.Bài Tiny Shell này vẫn chưa có cách lấy ID tiến trình cha mà không cần gọi tiến trình con
BOOL GetParentID() {
HANDLE hProcessSnap; PROCESSENTRY32 pe32; hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); if( hProcessSnap == INVALID_HANDLE_VALUE ) { printError( TEXT("CreateToolhelp32Snapshot (of processes)") ); return( FALSE );} pe32.dwSize = sizeof( PROCESSENTRY32 ); do{//Lấy id tiến trình cha của tiến trình con mới gọi là id cần tìm if(pe32.th32ProcessID==pi.dwProcessId) return(pe32.th32ParentProcessID);
}
while( Process32Next( hProcessSnap, &pe32 ) ); CloseHandle( hProcessSnap );}
Hàm thông báo lỗi void printError( TCHAR* msg ) { DWORD eNum; TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( ); //Lấy thông tin lỗi từ hàm GetLastError() FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, eNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), sysMsg, 256, NULL ); p = sysMsg; while( ( *p > 31 ) || ( *p == 9 ) ) ++p; do { *p-- = 0; } while( ( p >= sysMsg ) && ( ( *p == '.' ) || ( *p < 33 ) ) ); // Hiện thi thông báo lỗi _tprintf( TEXT("\n
WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );}
Để thực thi file run.bat chứa tiến trình cần thực hiện, dùng gọi hàm ShellExecute() để thực thi file run.bat Tạo file Run.bat chứa các tiến trình cần thực hiện TITLE CNTT1 echo TinyShell @echo off start mspaint.exe//tên file nạp vào start test.exe //nt
Cảm ơn thầy đã đọc bài báo cáo về TinyShell, báo cáo còn nhiều sai sót vì có nhiều vấn đề chưa hiểu, mong thầy góp ý để chúng em hiểu rõ và hoàn thiện hơn
Sinh viên thực hiện Trần Xuân Thủy_CNTT1_MSV_20102285 Phạm Văn Điều_CNTT1_MSV_20101374 Nguyễn Đức Trung_CNTT1_MSV_20102766 Đặng Ngọc Thuyên _CNTT1_20102277
TÀI LIỆU THAM KHẢO http://msdn.microsoft.com/en-us/library/windows/desktop/ms684847(v=vs.85).aspx
Slide Hệ điều hành, thầy Phạm Đăng Hải