Одно и то же имя мьютекса для службы Windows и исполняемого файла в Windows 7

Я хочу создать мьютекс службой Windows и исполняемым файлом с одинаковыми именами с помощью функции CreateMutex. Если мьютекс создается службой Windows, и когда исполняемый файл пытается создать другой мьютекс с тем же именем, он преуспевает без каких-либо ошибок, таких как ERROR_ALREADY_EXIST.

Это происходит только в Windows 7. Но для Windows XP отображается ERROR_ALREADY_EXIST. Я не могу понять причину этой разницы в ОС и как исправить эту проблему.

Пример кода

Для служебного кода

#include<iostream>
#include<windows.h>
#include<winbase.h>
using namespace std;
#define SLEEP_TIME 50000

typedef void* handle;
typedef WINADVAPI BOOL (WINAPI *PInitializeSecurityDescriptor)(PSECURITY_DESCRIPTOR, DWORD);
typedef WINADVAPI BOOL (WINAPI *PSetSecurityDescriptorDacl)(PSECURITY_DESCRIPTOR, BOOL, PACL, BOOL);
#define LOGFILE "D:\\result.txt"
handle temp=NULL;
static int a=65;
char muname[]={"NewMutex2"};
int errNm;
char *str;
FILE* log;

SECURITY_ATTRIBUTES  *g_pSaCms;
SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hStatus; 

void  ServiceMain(int argc, char** argv); 
void  ControlHandler(DWORD request); 
int InitService();


bool Win32Mutex(char muname[8])
{

    HINSTANCE hAdvApi = LoadLibrary("Advapi32.DLL");
    PInitializeSecurityDescriptor pInitializeSecurityDescriptor = 0;
    PSetSecurityDescriptorDacl pSetSecurityDescriptorDacl = 0;
    PSECURITY_DESCRIPTOR pSD = 0;
    g_pSaCms = new SECURITY_ATTRIBUTES;
    if (g_pSaCms == 0)
    {
        prinerr();
        return 1;
    }
    memset(g_pSaCms,0X0, sizeof(*g_pSaCms));
    g_pSaCms->nLength = sizeof(*g_pSaCms);
    g_pSaCms->bInheritHandle = 1;

    pSD = new SECURITY_DESCRIPTOR;

    if (pSD == 0)
    {
        printerr();
            goto LABEL_CSA_ERROR;
    }

    pInitializeSecurityDescriptor = (PInitializeSecurityDescriptor)GetProcAddress(hAdvApi,"InitializeSecurityDescriptor");

    if (pInitializeSecurityDescriptor == 0)
    {
        printerr();
            goto LABEL_CSA_ERROR;
    }

    pSetSecurityDescriptorDacl = (PSetSecurityDescriptorDacl)GetProcAddress(hAdvApi, "SetSecurityDescriptorDacl");

    if (pSetSecurityDescriptorDacl == 0)
    {
            goto LABEL_CSA_ERROR;
    }

    if (!(*pInitializeSecurityDescriptor)(pSD, SECURITY_DESCRIPTOR_REVISION)
            || (!(*pSetSecurityDescriptorDacl)(pSD, TRUE, (PACL)0, FALSE)))
    {
            goto LABEL_CSA_ERROR;
    }

    (void)FreeLibrary(hAdvApi);
    g_pSaCms->lpSecurityDescriptor=pSD;
    goto LABEL_CSA_PASS;

LABEL_CSA_ERROR:
    (void)FreeLibrary(hAdvApi);

    if (pSD != 0)
    {
        delete pSD;
        pSD = 0;
    }

    if (g_pSaCms != 0)
    {
        delete g_pSaCms;
        g_pSaCms = 0;
    }


LABEL_CSA_PASS:
    temp=::CreateMutex(g_pSaCms,0,muname); //for icdcomm
    errNm=GetLastError();
    if (!temp)
    {
        print_err();
    }
    else
    {
        print_err();
    }
    if ((!temp) || errNm == ERROR_ALREADY_EXISTS)
    {
            if(temp)
            {
            (void)CloseHandle(temp);
            a++;
            muname[8]=a;
            Win32Mutex(muname);
            }
            else
            {
            printInf()
            }
            return 0;
    }
    return 1;
}



int main()
{ 
    SERVICE_TABLE_ENTRY ServiceTable[2];
    ServiceTable[0].lpServiceName = "MemoryStatus";
    ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

    ServiceTable[1].lpServiceName = NULL;
    ServiceTable[1].lpServiceProc = NULL;
    StartServiceCtrlDispatcher(ServiceTable);  
    return 0;
}

void ServiceMain(int argc, char** argv) 
{
    int error; 
    ServiceStatus.dwServiceType        = SERVICE_WIN32; 
    ServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
    ServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode      = 0; 
    ServiceStatus.dwServiceSpecificExitCode = 0; 
    ServiceStatus.dwCheckPoint         = 0; 
    ServiceStatus.dwWaitHint           = 0; 

    hStatus = RegisterServiceCtrlHandler(
        "MemoryStatus", 
        (LPHANDLER_FUNCTION)ControlHandler); 
    if (hStatus == (SERVICE_STATUS_HANDLE)0) 
    { 
        // Registering Control Handler failed
        return; 
    }  
    // Initialize Service 
    error = InitService(); 
    if (error) 
    {
        // Initialization failed
        ServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
        ServiceStatus.dwWin32ExitCode      = -1; 
        SetServiceStatus(hStatus, &ServiceStatus); 
        return; 
    } 

    // My service
    muname[8]=a;
    Win32Mutex(muname);

    // We report the running status to SCM. 
    ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
    SetServiceStatus (hStatus, &ServiceStatus);


    // The worker loop of a service
    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        Sleep(SLEEP_TIME);
    }
    return;
}

// Control handler function
void ControlHandler(DWORD request) 
{ 
    switch(request) 
    { 
        case SERVICE_CONTROL_STOP: 
            ServiceStatus.dwWin32ExitCode = 0; 
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
            SetServiceStatus (hStatus, &ServiceStatus);
            return; 

        case SERVICE_CONTROL_SHUTDOWN: 

            ServiceStatus.dwWin32ExitCode = 0; 
            ServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
            SetServiceStatus (hStatus, &ServiceStatus);
            return; 

        default:
            break;
    } 

    // Report current status
    SetServiceStatus (hStatus,  &ServiceStatus);

    return; 
} 

Для исполняемого кода (код остается прежним, buc изменяется только в основной функции)

int main()
{ 
    muname[8]=a;
    Win32Mutex(muname);
    Sleep(SLEEP_TIME);
    return 0;
}
5
задан Baplix 10 February 2012 в 13:27
поделиться