- #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;
- }
- ...
- }