プライベートネームスペース単一インスタンスプログラムの作成


// 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
"), GetLastError()); return ; } } if(NULL == m_hBoundary) { DUMPINFO(_T("m_hBoundarg is NULL\r
")); 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
"), GetLastError()); return ; } // Associate the local admin SID to the boundary descriptor if(!AddSIDToBoundaryDescriptor(&m_hBoundary, pSID)) { DUMPINFO(_T("AddSIDToBoundaryDescriptor failed, error code : %d\r
"), 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
"), 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
"), dwRet); return ; } else { m_hNamespace = OpenPrivateNamespace(m_hBoundary, lpszNamespace); if(NULL == m_hNamespace) { DUMPINFO(_T("OpenPrivateNamespace failed, error code : %d\r
"), dwRet); return ; } m_bNamespaceOpen = TRUE; } } } if(NULL == lpszNamespace) { DUMPINFO(_T("lpszNamespace is NULL\r
")); 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
"), dwRet); return FALSE; } if(ERROR_ALREADY_EXISTS == dwRet) { DUMPINFO(_T("The another instance of App is running ...\r
")); return TRUE; } else { DUMPINFO(_T("The first instance of App ...\r
")); } } 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;
 }
 ...
}