windows核心编程单例模式代码

Singleton.cpp
/******************************************************************************
Module: Singleton.cpp
Notices: Copyright (c) 2008 Jeffrey Richter & Christophe Nasarre
******************************************************************************/
#include "resource.h"
#include "..CommonFilesCmnHdr.h" /* See Appendix A. */
#include <windowsx.h>
#include <Sddl.h> // for SID management
#include <tchar.h>
#include <strsafe.h>
///////////////////////////////////////////////////////////////////////////////
// Main dialog
HWND g_hDlg;
// Mutex, boundary and namespace used to detect previous running instance
HANDLE g_hSingleton = NULL;
HANDLE g_hBoundary = NULL;
HANDLE g_hNamespace = NULL;
// Keep track whether or not the namespace was created or open for clean-up
BOOL g_bNamespaceOpened = FALSE;
// Names of boundary and private namespace
PCTSTR g_szBoundary = TEXT("3-Boundary");
PCTSTR g_szNamespace = TEXT("3-Namespace");
#define DETAILS_CTRL GetDlgItem(g_hDlg, IDC_EDIT_DETAILS)
///////////////////////////////////////////////////////////////////////////////
// Adds a string to the "Details" edit control
void AddText(PCTSTR pszFormat, ...) 
{
	va_list argList;
	va_start(argList, pszFormat);
	TCHAR sz[20 * 1024];
	Edit_GetText(DETAILS_CTRL, sz, _countof(sz));
	_vstprintf_s(
		_tcschr(sz, TEXT(' ')), _countof(sz) - _tcslen(sz),
		pszFormat, argList);
	Edit_SetText(DETAILS_CTRL, sz);
	va_end(argList);
}
///////////////////////////////////////////////////////////////////////////////
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) 
{
	switch (id) 
	{
	case IDOK:
	case IDCANCEL:
		// User has clicked on the Exit button
		// or dismissed the dialog with ESCAPE
		EndDialog(hwnd, id);
		break;
	}
}
///////////////////////////////////////////////////////////////////////////////
void CheckInstances() 
{
	// Create the boundary descriptor
	g_hBoundary = CreateBoundaryDescriptor(g_szBoundary, 0);
	// Create a SID corresponding to the Local Administrator group
	BYTE localAdminSID[SECURITY_MAX_SID_SIZE];
	PSID pLocalAdminSID = &localAdminSID;
	DWORD cbSID = sizeof(localAdminSID);
	if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, pLocalAdminSID, &cbSID) ) 
	{
		AddText(TEXT("AddSIDToBoundaryDescriptor failed: %u
"), GetLastError());
		return;
	}
	// Associate the Local Admin SID to the boundary descriptor
	// --> only applications running under an administrator user
	// will be able to access the kernel objects in the same namespace
	if (!AddSIDToBoundaryDescriptor(&g_hBoundary, pLocalAdminSID)) 
	{
		AddText(TEXT("AddSIDToBoundaryDescriptor failed: %u
"), GetLastError());
		return;
	}
	// Create the namespace for Local Administrators only
	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.bInheritHandle = FALSE;
	if (!ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT("D:(A;;GA;;;BA)"), SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL)) 
	{
		AddText(TEXT("Security Descriptor creation failed: %u
"), GetLastError());
		return;
	}
	g_hNamespace =CreatePrivateNamespace(&sa, g_hBoundary, g_szNamespace);
	// Don't forget to release memory for the security descriptor
	LocalFree(sa.lpSecurityDescriptor);
	// Check the private namespace creation result
	DWORD dwLastError = GetLastError();
	if (g_hNamespace == NULL) 
	{
		// Nothing to do if access is denied
		// --> this code must run under a Local Administrator account
		if (dwLastError == ERROR_ACCESS_DENIED) 
		{
			AddText(TEXT("Access denied when creating the namespace.
"));
			AddText(TEXT(" You must be running as Administrator.

"));
			return;
		} 
		else 
		{
			if (dwLastError == ERROR_ALREADY_EXISTS) 
			{
				// If another instance has already created the namespace,
				// we need to open it instead.
				AddText(TEXT("CreatePrivateNamespace failed: %u
"), dwLastError);
				g_hNamespace = OpenPrivateNamespace(g_hBoundary, g_szNamespace);
				if (g_hNamespace == NULL) 
				{
					AddText(TEXT(" and OpenPrivateNamespace failed: %u
"), dwLastError);
					return;
				} 
				else 
				{
					g_bNamespaceOpened = TRUE;
					AddText(TEXT(" but OpenPrivateNamespace succeeded

"));
				}
			} 
			else 
			{
				AddText(TEXT("Unexpected error occured: %u

"), dwLastError);
				return;
			}
		}
	}
	// Try to create the mutex object with a name
	// based on the private namespace
	TCHAR szMutexName[64];
	StringCchPrintf(szMutexName, _countof(szMutexName), TEXT("%s\%s"), g_szNamespace, TEXT("Singleton"));
	g_hSingleton = CreateMutex(NULL, FALSE, szMutexName);
	if (GetLastError() == ERROR_ALREADY_EXISTS) 
	{
		// There is already an instance of this Singleton object
		AddText(TEXT("Another instance of Singleton is running:
"));
		AddText(TEXT("--> Impossible to access application features.
"));
	} 
	else 
	{
		// First time the Singleton object is created
		AddText(TEXT("First instance of Singleton:
"));
		AddText(TEXT("--> Access application features now.
"));
	}
}
///////////////////////////////////////////////////////////////////////////////
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) 
{
	chSETDLGICONS(hwnd, IDI_SINGLETON);
	// Keep track of the main dialog window handle
	g_hDlg = hwnd;
	// Check whether another instance is already running
	CheckInstances();
	return(TRUE);
}
///////////////////////////////////////////////////////////////////////////////
INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{
	switch (uMsg) 
	{
		chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
		chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
	}
	
	return(FALSE);
}
///////////////////////////////////////////////////////////////////////////////