diff --git a/03-Singleton.vcproj b/03-Singleton.vcproj
new file mode 100644
index 0000000..ffc99c5
--- /dev/null
+++ b/03-Singleton.vcproj
@@ -0,0 +1,342 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/03-Singleton.vcxproj b/03-Singleton.vcxproj
new file mode 100644
index 0000000..59c7afb
--- /dev/null
+++ b/03-Singleton.vcxproj
@@ -0,0 +1,176 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {6519CE30-7D1C-4A57-AA09-35BAFD171AFD}
+ My03Singleton
+ Win32Proj
+
+
+
+ Application
+ Unicode
+ true
+
+
+ Application
+ Unicode
+
+
+ Application
+ Unicode
+ true
+
+
+ Application
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.40219.1
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ true
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ false
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ true
+ $(SolutionDir)$(Platform)\$(Configuration)\
+ $(Platform)\$(Configuration)\
+ false
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+
+
+
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ EditAndContinue
+
+
+ true
+ Windows
+ MachineX86
+
+
+
+
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ true
+ true
+ MachineX86
+
+
+
+
+ X64
+
+
+ Disabled
+ WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ MachineX64
+
+
+
+
+ X64
+
+
+ WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+ ProgramDatabase
+
+
+ true
+ Windows
+ true
+ true
+ MachineX64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/03-Singleton.vcxproj.user b/03-Singleton.vcxproj.user
new file mode 100644
index 0000000..695b5c7
--- /dev/null
+++ b/03-Singleton.vcxproj.user
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Resource.h b/Resource.h
index 1382402..ec2f013 100644
--- a/Resource.h
+++ b/Resource.h
@@ -1,21 +1,20 @@
//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by ErrorShow.rc
+// Microsoft Visual C++ generated include file.
+// Used by Singleton.rc
//
-#define IDD_ERRORSHOW 101
-#define IDI_ERRORSHOW 102
-#define IDC_ERRORCODE 1000
-#define IDC_ERRORTEXT 1001
-#define IDC_ALWAYSONTOP 1002
-#define IDC_STATIC (-1) // all static controls
+#define IDI_SINGLETON 102
+#define IDD_SINGLETON 129
+#define IDC_EDIT_DETAILS 1000
+#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 104
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1005
-#define _APS_NEXT_SYMED_VALUE 101
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 130
+#define _APS_NEXT_COMMAND_VALUE 32771
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
diff --git a/Singleton.aps b/Singleton.aps
new file mode 100644
index 0000000..1ec2e00
Binary files /dev/null and b/Singleton.aps differ
diff --git a/Singleton.cpp b/Singleton.cpp
new file mode 100644
index 0000000..cadc667
--- /dev/null
+++ b/Singleton.cpp
@@ -0,0 +1,238 @@
+/******************************************************************************
+Module: Singleton.cpp
+Notices: Copyright (c) 2008 Jeffrey Richter & Christophe Nasarre
+******************************************************************************/
+
+
+#include "resource.h"
+
+#include "..\CommonFiles\CmnHdr.h" /* See Appendix A. */
+#include
+#include // for SID management
+#include
+#include
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+// 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('\0')), _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\r\n"),
+ 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\r\n"),
+ 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\r\n"), 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.\r\n"));
+ AddText(TEXT(" You must be running as Administrator.\r\n\r\n"));
+ 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\r\n"), dwLastError);
+ g_hNamespace = OpenPrivateNamespace(g_hBoundary, g_szNamespace);
+ if (g_hNamespace == NULL) {
+ AddText(TEXT(" and OpenPrivateNamespace failed: %u\r\n"),
+ dwLastError);
+ return;
+ } else {
+ g_bNamespaceOpened = TRUE;
+ AddText(TEXT(" but OpenPrivateNamespace succeeded\r\n\r\n"));
+ }
+ } else {
+ AddText(TEXT("Unexpected error occured: %u\r\n\r\n"),
+ 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:\r\n"));
+ AddText(TEXT("--> Impossible to access application features.\r\n"));
+ } else {
+ // First time the Singleton object is created
+ AddText(TEXT("First instance of Singleton:\r\n"));
+ AddText(TEXT("--> Access application features now.\r\n"));
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+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);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+
+int APIENTRY _tWinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
+{
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+
+ // Show main window
+ DialogBox(hInstance, MAKEINTRESOURCE(IDD_SINGLETON), NULL, Dlg_Proc);
+
+ // Don't forget to clean up and release kernel resources
+ if (g_hSingleton != NULL) {
+ CloseHandle(g_hSingleton);
+ }
+
+ if (g_hNamespace != NULL) {
+ if (g_bNamespaceOpened) { // Open namespace
+ ClosePrivateNamespace(g_hNamespace, 0);
+ } else { // Created namespace
+ ClosePrivateNamespace(g_hNamespace, PRIVATE_NAMESPACE_FLAG_DESTROY);
+ }
+ }
+
+ if (g_hBoundary != NULL) {
+ DeleteBoundaryDescriptor(g_hBoundary);
+ }
+
+ return(0);
+}
+
+
+//////////////////////////////// End of File //////////////////////////////////
diff --git a/Singleton.ico b/Singleton.ico
new file mode 100644
index 0000000..b96aa0e
Binary files /dev/null and b/Singleton.ico differ
diff --git a/Singleton.rc b/Singleton.rc
new file mode 100644
index 0000000..8b4db2d
--- /dev/null
+++ b/Singleton.rc
@@ -0,0 +1,111 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include "windows.h"
+#undef APSTUDIO_HIDDEN_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_SINGLETON ICON "Singleton.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_SINGLETON DIALOGEX 0, 0, 195, 95
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Singleton"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ DEFPUSHBUTTON "E&xit",IDOK,140,76,50,14
+ EDITTEXT IDC_EDIT_DETAILS,4,5,186,67,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_SINGLETON, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 188
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 88
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+