Маленькая шпаргалка-пример на тему совместного использования именованных объектов ядра несколькими процессами. Показан вариант размещения именованных объектов ядра в глобальном, локальном и приватном пространствах имён.
Исходный код примера:
#include <Windows.h>
#include <iostream>
#include <aclapi.h>
#include <exception>
#include <tchar.h>
using namespace std;
void PrintErrorMsg(LPCTSTR prefix);
int main(int argc, TCHAR *argv[])
try {
setlocale(LC_ALL, "Russian");
HANDLE hGlobalMutex = CreateMutex(NULL, FALSE, L"Global\\G_Mutex");
if (NULL == hGlobalMutex) {
PrintErrorMsg(L"Global Mutex: ");
}
else {
// Check the reason of success
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
wcout << L"Named global mutex opened." << endl;
}
else {
wcout << L"Named global mutex created." << endl;
}
}
HANDLE hLocalMutex = CreateMutex(NULL, FALSE, L"Local\\L_Mutex");
if (NULL == hLocalMutex) {
PrintErrorMsg(L"Local Mutex: ");
}
else {
// Check the reason of success
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
wcout << L"Named local mutex opened." << endl;
}
else {
wcout << L"Named local mutex created." << endl;
}
}
LPCTSTR boundaryName = L"BushmanBoundary";
HANDLE hBoundary = CreateBoundaryDescriptor(boundaryName, 0);
HANDLE hNamespase = NULL;
HANDLE hMutex = NULL;
if (NULL == hBoundary) {
PrintErrorMsg(L"CreateBoundaryDescriptor: ");
}
else {
wcout << L"Boundary descriptor created." << endl;
BYTE sid[SECURITY_MAX_SID_SIZE];
ZeroMemory(sid, sizeof(sid));
DWORD cbSID = sizeof(sid);
BOOL result = CreateWellKnownSid(WinWorldSid, NULL, &sid, &cbSID);
if (0 == result) {
PrintErrorMsg(L"CreateWellKnownSid: ");
}
else {
wcout << L"SID for boundary descriptor created." << endl;
result = AddSIDToBoundaryDescriptor(&hBoundary, &sid);
if (0 == result) {
PrintErrorMsg(L"AddSIDToBoundaryDescriptor: ");
}
else {
wcout << L"SID added to boundary descriptor." << endl;
SECURITY_ATTRIBUTES sa = { 0 };
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = NULL; // use the default value
LPCTSTR ns = L"Local\\BushNamespace";
hNamespase = CreatePrivateNamespace(&sa, hBoundary,
ns);
if (NULL == hNamespase) {
// Check the reason of failure
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
hNamespase = OpenPrivateNamespace(hBoundary, ns);
if (NULL == hNamespase) {
PrintErrorMsg(L"OpenPrivateNamespace: ");
}
else {
wcout << L"Namespace opened." << endl;
}
}
else {
PrintErrorMsg(L"CreateNamespace: ");
}
}
else {
wcout << L"Namespace created." << endl;
}
if (NULL != hNamespase) {
hMutex = CreateMutex(NULL, FALSE,
L"Local\\BushNamespace\\BushMutex");
if (NULL == hMutex) {
PrintErrorMsg(L"CreateNamespaceMutex: ");
}
else {
// Check the reason of success
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
wcout << L"Named mutex in private namespace opened."
<< endl;
}
else {
wcout << L"Named mutex in private namespace created."
<< endl;
}
}
}
}
}
}
wcout << L"Press any char for exit..." << endl;
wchar_t c;
wcin >> c;
if (NULL != hGlobalMutex) {
CloseHandle(hGlobalMutex);
hGlobalMutex = NULL;
}
if (NULL != hLocalMutex) {
CloseHandle(hLocalMutex);
hLocalMutex = NULL;
}
if (NULL == hMutex) {
CloseHandle(hMutex);
hMutex = NULL;
}
if (NULL != hNamespase) {
ClosePrivateNamespace(hNamespase, 0);
hNamespase = NULL;
}
if (NULL != hBoundary) {
DeleteBoundaryDescriptor(hBoundary);
hBoundary = NULL;
}
}
catch (...) {
wcerr << L"Unknown error." << endl;
return 1;
}
void PrintErrorMsg(LPCTSTR prefix) {
DWORD errCode = GetLastError();
LPTSTR msg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errCode, 0, (LPTSTR)&msg, 0, NULL);
wcerr << prefix << msg << endl;
HeapFree(GetProcessHeap(), 0, msg);
}
На скрине результат консольного вывода двух разных процессов:
В Process Explorer видим следующую картину (см. выделенное красным):
Смотрим WinObj, запустив её с правами администратора:
Исходный код примера:
#include <Windows.h>
#include <iostream>
#include <aclapi.h>
#include <exception>
#include <tchar.h>
using namespace std;
void PrintErrorMsg(LPCTSTR prefix);
int main(int argc, TCHAR *argv[])
try {
setlocale(LC_ALL, "Russian");
HANDLE hGlobalMutex = CreateMutex(NULL, FALSE, L"Global\\G_Mutex");
if (NULL == hGlobalMutex) {
PrintErrorMsg(L"Global Mutex: ");
}
else {
// Check the reason of success
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
wcout << L"Named global mutex opened." << endl;
}
else {
wcout << L"Named global mutex created." << endl;
}
}
HANDLE hLocalMutex = CreateMutex(NULL, FALSE, L"Local\\L_Mutex");
if (NULL == hLocalMutex) {
PrintErrorMsg(L"Local Mutex: ");
}
else {
// Check the reason of success
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
wcout << L"Named local mutex opened." << endl;
}
else {
wcout << L"Named local mutex created." << endl;
}
}
LPCTSTR boundaryName = L"BushmanBoundary";
HANDLE hBoundary = CreateBoundaryDescriptor(boundaryName, 0);
HANDLE hNamespase = NULL;
HANDLE hMutex = NULL;
if (NULL == hBoundary) {
PrintErrorMsg(L"CreateBoundaryDescriptor: ");
}
else {
wcout << L"Boundary descriptor created." << endl;
BYTE sid[SECURITY_MAX_SID_SIZE];
ZeroMemory(sid, sizeof(sid));
DWORD cbSID = sizeof(sid);
BOOL result = CreateWellKnownSid(WinWorldSid, NULL, &sid, &cbSID);
if (0 == result) {
PrintErrorMsg(L"CreateWellKnownSid: ");
}
else {
wcout << L"SID for boundary descriptor created." << endl;
result = AddSIDToBoundaryDescriptor(&hBoundary, &sid);
if (0 == result) {
PrintErrorMsg(L"AddSIDToBoundaryDescriptor: ");
}
else {
wcout << L"SID added to boundary descriptor." << endl;
SECURITY_ATTRIBUTES sa = { 0 };
sa.nLength = sizeof(sa);
sa.bInheritHandle = FALSE;
sa.lpSecurityDescriptor = NULL; // use the default value
LPCTSTR ns = L"Local\\BushNamespace";
hNamespase = CreatePrivateNamespace(&sa, hBoundary,
ns);
if (NULL == hNamespase) {
// Check the reason of failure
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
hNamespase = OpenPrivateNamespace(hBoundary, ns);
if (NULL == hNamespase) {
PrintErrorMsg(L"OpenPrivateNamespace: ");
}
else {
wcout << L"Namespace opened." << endl;
}
}
else {
PrintErrorMsg(L"CreateNamespace: ");
}
}
else {
wcout << L"Namespace created." << endl;
}
if (NULL != hNamespase) {
hMutex = CreateMutex(NULL, FALSE,
L"Local\\BushNamespace\\BushMutex");
if (NULL == hMutex) {
PrintErrorMsg(L"CreateNamespaceMutex: ");
}
else {
// Check the reason of success
DWORD errCode = GetLastError();
if (ERROR_ALREADY_EXISTS == errCode) {
wcout << L"Named mutex in private namespace opened."
<< endl;
}
else {
wcout << L"Named mutex in private namespace created."
<< endl;
}
}
}
}
}
}
wcout << L"Press any char for exit..." << endl;
wchar_t c;
wcin >> c;
if (NULL != hGlobalMutex) {
CloseHandle(hGlobalMutex);
hGlobalMutex = NULL;
}
if (NULL != hLocalMutex) {
CloseHandle(hLocalMutex);
hLocalMutex = NULL;
}
if (NULL == hMutex) {
CloseHandle(hMutex);
hMutex = NULL;
}
if (NULL != hNamespase) {
ClosePrivateNamespace(hNamespase, 0);
hNamespase = NULL;
}
if (NULL != hBoundary) {
DeleteBoundaryDescriptor(hBoundary);
hBoundary = NULL;
}
}
catch (...) {
wcerr << L"Unknown error." << endl;
return 1;
}
void PrintErrorMsg(LPCTSTR prefix) {
DWORD errCode = GetLastError();
LPTSTR msg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errCode, 0, (LPTSTR)&msg, 0, NULL);
wcerr << prefix << msg << endl;
HeapFree(GetProcessHeap(), 0, msg);
}
На скрине результат консольного вывода двух разных процессов:
В Process Explorer видим следующую картину (см. выделенное красным):
Смотрим WinObj, запустив её с правами администратора:
Комментариев нет:
Отправить комментарий