Question 1 :
What is handle?
Handle value is actually the index into the process's handle table that identifies where the kernel object's information is stored.
Question 2 :
How the handle helps in manipulating the kernel objects?
Whenever you call a function that accepts a kernel object handle as an argument, you pass the value returned by one of the Create* functions. Internally, the function looks in your process's handle table to get the address of the kernel object you want to manipulate and then manipulates the object's data structure in a well-defined fashion.
Question 3 :
What happens when the CloseHandle(handle) is called?
This function first checks the calling process's handle table to ensure that the index (handle) passed to it identifies an object that the process does in fact have access to. If the index is valid, the system gets the address of the kernel object's data structure and decrements the usage count member in the structure; if the count is zero, the kernel destroys the kernel object from memory.
Question 4 :
You forget to call CloseHandle - will there be a memory leak?
Well, yes and no. It is possible for a process to leak resources (such as kernel objects) while the process runs. However, when the process terminates, the operating system ensures that any and all resources used by the process are freed—this is guaranteed. For kernel objects, the system performs the following actions: When your process terminates, the system automatically scans the process's handle table. If the table has any valid entries (objects that you didn't close before terminating), the system closes these object handles for you. If the usage count of any of these objects goes to zero, the kernel destroys the object.
Question 5 :
What is the need of process relative handles?
The most important reason was robustness. If kernel object handles were system-wide values, one process could easily obtain the handle to an object that another process was using and wreak havoc on that process. Another reason for process-relative handles is security. Kernel objects are protected with security, and a process must request permission to manipulate an object before attempting to manipulate it. The creator of the object can prevent an unauthorized user from touching the object simply by denying access to it
Question 6 :
How the handles are handled in the child process?
The operating system creates the new child process but does not allow the child process to begin executing its code right away. Of course, the system creates a new, empty process handle table for the child process just as it would for any new process. But because you passed TRUE to CreateProcess's bInheritHandles parameter, the system does one more thing: it walks the parent process's handle table, and for each entry it finds that contains a valid inheritable handle, the system copies the entry exactly into the child process's handle table. The entry is copied to the exact same position in the child process's handle table as in the parent's handle table.
Question 7 :
Why the entries in the parent process table and child table are same?
It means that the handle value that identifies a kernel object is identical in both the parent and the child processes.
Question 8 :
What about the usage count in the parent child process tables?
The system increments the usage count of the kernel object because two processes are now using the object. For the kernel object to be destroyed, both the parent process and the child process must either call CloseHandle on the object or terminate.
Question 9 :
What are Named Objects?
Method available for sharing kernel objects across process boundaries is to name the objects. Below are the kernel named objects:
There are APIs to create these objects with last parameter as the object name.
Question 10 :
What do you mean by unnamed object?
When you are creating the kernel objects with the help of API's like CreateMutex(, , , ,pzname). And the Pzname parameter is NULL , you are indicating to the system that you want to create an unnamed (anonymous) kernel object. When you create an unnamed object, you can share the object across processes by using either inheritance or DuplicateHandle