管理员与命名空间绑定、只能运行一个事例、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"));
    }
}

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。