管理员与命名空间绑定、只能运行一个事例、MFC改变图标(windows核心编程)

// Sets the dialog box icons
inline void CMFC_CORE_1Dlg::chSETDLGICONS(HWND hWnd, int idi) {
    ::SendMessage(hWnd, WM_SETICON, ICON_BIG,  (LPARAM)
        LoadIcon((HINSTANCE) ::GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
        MAKEINTRESOURCE(idi)));
    ::SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)
        LoadIcon((HINSTANCE) ::GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
        MAKEINTRESOURCE(idi)));
}
void CMFC_CORE_1Dlg::OnDestroy()
{
    CDialogEx::OnDestroy();

    // TODO: 在此处添加消息处理程序代码
    // 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);
    }
}

// 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");

void CMFC_CORE_1Dlg::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)
        ) {
            // Using Edit
            CString edit_tring;
            edit_tring.Format(TEXT("AddSIDToBoundaryDescriptor failed: %u\r\n"),GetLastError());
            SetDlgItemText(IDC_EDIT1,edit_tring);
            TRACE(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))
    {
        // Using Edit
        CString edit_tring;
        edit_tring.Format(TEXT("AddSIDToBoundaryDescriptor failed: %u\r\n"),GetLastError());
        SetDlgItemText(IDC_EDIT1,edit_tring);
        TRACE(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))
    {
        // Using Edit
        CString edit_tring;
        edit_tring.Format(TEXT("Security Descriptor creation failed: %u\r\n"), GetLastError());
        SetDlgItemText(IDC_EDIT1,edit_tring);
        TRACE(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) {
            // Using Edit
            CString edit_tring;
            edit_tring.Format(TEXT("Access denied when creating the namespace.\r\n   You must be running as Administrator.\r\n\r\n"));
            SetDlgItemText(IDC_EDIT1,edit_tring);

            TRACE(TEXT("Access denied when creating the namespace.\r\n"));
            TRACE(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.
                // Using Edit
                CString edit_tring;
                edit_tring.Format(TEXT("CreatePrivateNamespace failed: %u\r\n"), dwLastError);
                SetDlgItemText(IDC_EDIT1,edit_tring);
                TRACE(TEXT("CreatePrivateNamespace failed: %u\r\n"), dwLastError);
                g_hNamespace = OpenPrivateNamespace(g_hBoundary, g_szNamespace);
                if (g_hNamespace == NULL) {
                    edit_tring.Format(TEXT("   and OpenPrivateNamespace failed: %u\r\n"));
                    SetDlgItemText(IDC_EDIT1,edit_tring);
                    TRACE(TEXT("   and OpenPrivateNamespace failed: %u\r\n"),
                        dwLastError);
                    return;
                } else {
                    g_bNamespaceOpened = TRUE;
                    edit_tring.Format(TEXT("   but OpenPrivateNamespace succeeded\r\n\r\n"));
                    SetDlgItemText(IDC_EDIT1,edit_tring);
                    TRACE(TEXT("   but OpenPrivateNamespace succeeded\r\n\r\n"));
                }
            } else {
                // Using Edit
                CString edit_tring;
                edit_tring.Format(TEXT("Unexpected error occured: %u\r\n\r\n"));
                SetDlgItemText(IDC_EDIT1,edit_tring);
                TRACE(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
        // Using Edit
        CString edit_tring;
        edit_tring.Format(TEXT("Another instance of Singleton is running:\r\n--> Impossible to access application features.\r\n"));
        SetDlgItemText(IDC_EDIT1,edit_tring);

        TRACE(TEXT("Another instance of Singleton is running:\r\n"));
        TRACE(TEXT("--> Impossible to access application features.\r\n"));
    } else  {
        // First time the Singleton object is created
        // Using Edit
        CString edit_tring;
        edit_tring.Format(TEXT("First instance of Singleton:\r\n--> Access application features now.\r\n"));
        GetDlgItem(IDC_EDIT1)->SetWindowText(edit_tring);

        TRACE(TEXT("First instance of Singleton:\r\n"));
        TRACE(TEXT("--> Access application features now.\r\n"));
    }
}
时间: 2024-08-14 04:40:41

管理员与命名空间绑定、只能运行一个事例、MFC改变图标(windows核心编程)的相关文章

WinForm限制客户程序只能运行一个实例

WinForm限制客户程序只能运行一个实例: using System; using System.Threading; static void Main() { bool create = false; using (Mutex mu = new Mutex(true, Application.ProductName, out create)) { if (create) { Application.Run( new MainForm() ); } else { MessageBox.Show

同一个PC只能运行一个应用实例(考虑多个用户会话情况)

原文:同一个PC只能运行一个应用实例(考虑多个用户会话情况) 1 class Program 2 { 3 private static Mutex m; 4 5 [STAThread] 6 static void Main() 7 { 8 bool createNew = false; 9 10 /* 11 * 在运行终端服务的服务器上,已命名的系统 mutex 可以具有两级可见性. 12 * 如果名称以前缀“Global\”开头,则 mutex 在所有终端服务器会话中均为可见. 13 * 如果

让程序同时只能运行一个C++ Builder实现(转)

源:让程序同时只能运行一个 很多人都讨论过这个问题, 这里用Victor串口控件里面现成的共享内存功能来实现. 当程序运行第二次时只是激活第一次运行的窗口, 而不是再运行一个程序. 需要在主程序里实现, 下面蓝色的部分是增加的内容: #include <vcl.h> #pragma hdrstop #include "yb_base.h" //------------------------------------------------------------------

【windows核心编程】一个API拦截的例子

API拦截 修改PE文件导入段中的导入函数地址 为 新的函数地址 这涉及PE文件格式中的导入表和IAT,PE文件中每个隐式链接的DLL对应一个IMAGE_IMPORT_DESCRIPTOR描述符结构,而每个IMAGE_IMPORT_DESCRIPTOR结构中的FirstThunk指向一个IMAGE_THUNK_DATA结构数组的首地址. 在这个IAMGE_THUNK_DATA数组中,每一项对应一个该DLL模块的导入函数(对使用该DLL模块的PE文件来说是 导入).  结构大致如下 拦截某DLL模

只能运行一个程序,禁止运行多个相同的程序 C#

原文发布时间为:2009-04-06 -- 来源于本人的百度文章 [由搬家工具导入] Program.cs 里面改成如下: static void Main()        {            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);            bool bExist;            System.Threadin

java类内存中只能运行一个实例对象

方法:构造方法私有化(private) public class TestClass { private static TestClass obj = new TestClass (); //私有构造方法 private TestClass () { } public static TestClass getInstance() { return obj ; } } 使用: TestClass obj = TestClass.getInstance();

[C#]只能运行程序的一个实例

C#实现只能运行程序的一个实例(添加在窗体的Load事件中) 1. 根据进行名限制只能运行程序的一个实例 System.Diagnostics.Process process = System.Diagnostics.Process.GetCurrentProcess(); System.Diagnostics.Process[] processList = System.Diagnostics.Process.GetProcessesByName(process.ProcessName); 

只能同时运行一个实例的程序

很多情况下,程序会要求同一时间内只能运行一个实例,以免发生系统崩溃.数据遭破坏等后果.最常用被使用的是创建一个有名字的Mutex(互斥)的方法.程序的实例或对象含有Mutex之后,同一时间内将只能被一个线程访问. Windows给我们提供了CreateMutex函数来创建Mutex.原型如下: HANDLE WINAPI CreateMutex( __in_opt LPSECURITY_ATTRIBUTES lpMutexAttributes, __in BOOL bInitialOwner,/

Winform程序只允许运行一个程序实例

/// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); /* * 利用互斥变量来控制应用程序只能运行一个 */ bool bRun = true; va