Process Creation Functions Part 1
السلام عليكم ورحمة الله وبركاته
المقالة هذه ( وسلسلة المقالات اللاحقة إن يسرها الله ) تلخيص لقرائتي لبعض الفصول من كتاب Windowns Internals 7th Edition
قبل أن نبدأ أود الاشارة بأن سلسلة المقالات هذه تتوقع من القارئ الإلمام بمفاهيم أنظمة التشغيل ولغات البرمجة ، فلن يتم الاسهاب في هذا الجانب
- الطلاب الأعزاء الذين يقرأون السلسلة، مُرحب بأسئلتكم هنا
بسم الله نبدأ
ماهي العمليات ( Processes ) ؟
عرّف الكتاب العمليات كالآتي :
A program is a static sequence of instructions, whereas a process is a container for a set of resources used when executing the instance of the program.
في نظري هذا من أذكى التعاريف التي مرّت عليّ في شرح معنى العمليات، فقد أظهر المعنى الحقيقي للعمليات بطريقة واضحة ومُختصرة
يخبرنا الكتاب أن العمليات ماهي إلّا Container
يحوي العديد من المصادر حتى يُتم البرنامج عمله .. بلغة أخرى ـوكما سنعرف لاحقًا- ليست العمليات بحد ذاتها التي تقوم بتنفيذ ( Execute
) البرنامج ، انما هي مخزن -إن صح التعبير- يحوي المصادر التي يحتاجها البرنامج
مكوّنات العمليات
في أنظمة Windows
تتكوّن العمليات من الآتي ( القائمة تطول لكن هذه أهم النقاط بشكل عام ) :
A Private Virtual Address Space
: مساحة من العناوين الخاصة بالعملية، كل عملية لديها مجال ذاكرة افتراضي خاص بها ولا يمكن الوصول إليه من قبل عمليات أخرى إلا إذا كان مشتركًا ، لا تستطيع العمليات كذلك معرفة الـphysical address
ولا تحتاج لذلكAn Executable Program
: يشير الى البرنامج الذي سيتم تنفيذهA List of Open Handles
: في نظام ويندوز يوجد ما يسمى بالـHandles
الفكرة من هذا المفهوم بشكل مختصر جدًا هو أن المصادر في نظام التشغيل ( مثل العمليات / الملفات وغيرها ) يمكن الاشارة لها بمعرف، بمعنى آخر للوصول للعملية للتعامل معها يجب الوصول أولًا للـ handle المتاح لها ، سيتم إيضاح هذه النقطة لاحقًا في الكودA Security Context
: يمثّل مايرتبط بالعملية من ناحية أمنية ، على وجه التحديد نقصد الـaccess token
والتي تحتوي على : المستخدم الذي قام بإنشاء العملية، المجموعة التي ينتمي لها المستخدم، الصلاحيات وغيرهاA Process ID
: معرّف يشير الى رقم العملية ، هذه القيمة من الممكن أن تتكرر ، لكن ليس لعمليتين تعملان في نفس الوقتAt Least One Thread of Execution
: الـThread
هو الجزء المسؤول عن تنفيذ الكود ، ويجب أن تحتوي العملية علىThread
واحد على الأقل
دوال العمليات في Windows
الجدول التالي يلخص أهم دوال العمليات في نظام ويندوز
الدالة | الوصف | DLL |
---|---|---|
CreateProcess | تنشئ عملية جديدة والـ Thread الخاص بها. تعمل العملية الجديدة ضمن صلاحيات العملية التي قامت بإنشاء هذه العملية ( Caller ). | Kernel32.dll |
CreateProcessAsUser | تنشئ عملية جديدة والـ Thread الخاص بها. تعمل العملية الجديدة ضمن صلاحيات المستخدم المحدد. | Advapi32.dll |
CreateProcessWithLogonW | مشابهة لدالة CreateProcessAsUser لكن تختلف عنها في انه لا حاجة لنداء دالة LogonUser . دالة LogonUser تتيح تعريف الـ logon session والـ security token للمستخدم. | Advapi32.dll |
CreateProcessWithTokenW | تنشئ عملية جديدة والـ Thread الخاص بها. تعمل العملية الجديدة ضمن صلاحيات المستخدم المحدد باستخدام الـ Token . | Advapi32.dll |
OpenProcess | تمكننا هذه الدالة من الوصول إلى عملية تم إنشاءها مسبقًا. | Kernel32.dll |
لمزيد من التفاصيل حول هذه الدوال أرشّح الاطلاع على هذا المرجع
دالة CreateProceess
الكود التالي مثال على استخدام دالة CreateProcess
و إنشاء عملية تبدأ برنامج الـ Notepad
// CreateProcess.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <windows.h>
#include <stdio.h>
int main()
{
// Declare variables
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL result;
DWORD exitCode;
// Initialize variables
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Create a process using the command line argument
result = CreateProcess(
L"C:\\Windows\\System32\\notepad.exe", // Module name
NULL, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi); // Pointer to PROCESS_INFORMATION structure
if (!result)
{
printf("CreateProcess failed (%d).\n", GetLastError());
return -1;
}
// Wait until child process exits
WaitForSingleObject(pi.hProcess, INFINITE);
// Get the exit code of the child process
GetExitCodeProcess(pi.hProcess, &exitCode);
printf("Child process exited with code %d.\n", exitCode);
// Close process and thread handles
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}