创建专有命名空间单实例程序

// Singleton.h
#pragma once

class CSingleton
{
public:
	CSingleton(LPCTSTR lpszBoundary = _T("MyAppBoundary"), LPCTSTR lpszNamespace = _T("MyAppNamespace"));
	virtual ~CSingleton(void);

public:
	BOOL IsInstanceExist(LPCTSTR lpszMutex);

private:
	void DUMPINFO(LPCTSTR lpszFormat, ...);

private:
	HANDLE m_hSingleton;
	HANDLE m_hBoundary;
	HANDLE m_hNamespace;
	BOOL m_bNamespaceOpen;
};

// Singleton.cpp
#include "stdafx.h"
#include "Singleton.h"
#include <sddl.h>
#pragma comment(lib, "Advapi32.lib")

#define MAX_BUFFER_LENGTH		(1024)

CSingleton::CSingleton(LPCTSTR lpszBoundary, LPCTSTR lpszNamespace) : m_hSingleton(NULL), m_hBoundary(NULL), m_hNamespace(NULL), m_bNamespaceOpen(FALSE)
{
	// Create the boundary descriptor
	if(lpszBoundary && _tcslen(lpszBoundary))
	{
		m_hBoundary = CreateBoundaryDescriptor(lpszBoundary, 0);
		if(NULL == m_hBoundary)
		{
			DUMPINFO(_T("CreateBoundaryDescriptor failed, error code : %d\r\n"), GetLastError());
			return ;
		}
	}
	if(NULL == m_hBoundary)
	{
		DUMPINFO(_T("m_hBoundarg is NULL\r\n"));
		return ;
	}
	// Create SID corresponding to the local Adminstrator group
	BYTE bySID[SECURITY_MAX_SID_SIZE] = {0};
	PSID pSID = bySID;
	DWORD dwSize = sizeof(bySID);
	if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, pSID, &dwSize))
	{
		DUMPINFO(_T("CreateWellKnownSid failed, error code : %d\r\n"), GetLastError());
		return ;
	}
	// Associate the local admin SID to the boundary descriptor
	if(!AddSIDToBoundaryDescriptor(&m_hBoundary, pSID))
	{
		DUMPINFO(_T("AddSIDToBoundaryDescriptor failed, error code : %d\r\n"), GetLastError());
		return ;
	}
	// Create the namespace for local administrator only
	SECURITY_ATTRIBUTES sa = {0};
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = FALSE;
	if(!ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:(A;;GA;;;BA)"), SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL))
	{
		DUMPINFO(_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed, error code : %d\r\n"), GetLastError());
		return ;
	}
	if(lpszNamespace && _tcslen(lpszNamespace))
	{
		m_hNamespace = CreatePrivateNamespace(&sa, m_hBoundary, lpszNamespace);
		DWORD dwRet = GetLastError();
		LocalFree(sa.lpSecurityDescriptor);
		if(NULL == m_hNamespace)
		{
			if(ERROR_ALREADY_EXISTS != dwRet)
			{
				DUMPINFO(_T("CreatePrivateNamespace failed, error code : %d\r\n"), dwRet);
				return ;
			}
			else
			{
				m_hNamespace = OpenPrivateNamespace(m_hBoundary, lpszNamespace);
				if(NULL == m_hNamespace)
				{
					DUMPINFO(_T("OpenPrivateNamespace failed, error code : %d\r\n"), dwRet);
					return ;
				}
				m_bNamespaceOpen = TRUE;
			}
		}
	}
	
	if(NULL == lpszNamespace)
	{
		DUMPINFO(_T("lpszNamespace is NULL\r\n"));
		return ;
	}
}


CSingleton::~CSingleton(void)
{
	if(NULL != m_hSingleton)
	{
		CloseHandle(m_hSingleton);
		m_hSingleton = NULL;
	}
	if(NULL != m_hNamespace)
	{
		ClosePrivateNamespace(m_hNamespace, m_bNamespaceOpen ? 0 : PRIVATE_NAMESPACE_FLAG_DESTROY);
		m_hNamespace = NULL;
	}
	if(NULL != m_hBoundary)
	{
		DeleteBoundaryDescriptor(m_hBoundary);
		m_hBoundary = NULL;
	}
}

void CSingleton::DUMPINFO(LPCTSTR lpszFormat, ...)
{
	TCHAR szText[MAX_BUFFER_LENGTH] = {0};
	va_list argList;
	va_start(argList, lpszFormat);
	_vstprintf_s(szText, _countof(szText), lpszFormat, argList);
	va_end(argList);

	OutputDebugString(szText);
}

BOOL CSingleton::IsInstanceExist(LPCTSTR lpszMutex)
{
	if(m_hBoundary && m_hNamespace && lpszMutex && _tcslen(lpszMutex))
	{
		m_hSingleton = CreateMutex(NULL, FALSE, lpszMutex);
		DWORD dwRet = GetLastError();
		if(NULL == m_hSingleton)
		{
			DUMPINFO(_T("CreateMutex failed, error code : %d\r\n"), dwRet);
			return FALSE;
		}
		if(ERROR_ALREADY_EXISTS == dwRet)
		{
			DUMPINFO(_T("The another instance of App is running ...\r\n"));
			return TRUE;
		}
		else
		{
			DUMPINFO(_T("The first instance of App ...\r\n"));
		}
	}
	return FALSE;
}
// 调用方法,主要修改App类的InitInstance函数
CSingleton* m_pSingleton = NULL; // 定义为App类的成员变量,并在App类的构造函数中初始化为NULL

m_pSingleton = new CSingleton(_T("Chapter3Boundary"), _T("Chapter3Namesapce"));

BOOL CXXXXXApp::InitInstance()
{
 // Check Instance of App
 if((NULL != m_pSingleton) && (m_pSingleton->IsInstanceExist(_T("Chapter3Mutex"))))
 {
   return FALSE;
 }
 ...
}

猜你喜欢

转载自blog.csdn.net/visualeleven/article/details/7906616
今日推荐