プライベートネームスペース単一インスタンスプログラムの作成
4557 ワード
// 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;
}
...
}