创建桌面交互式服务与非交互式服务的区别

 

      

创建桌面交互式服务与非交互式服务的区别

 

顾名思义,交互式服务可以与界面进行交互,比如弹出对话框,日志窗口输出等。交互服务不允许访问网络共享资源,比如网络影射路径等。

 

如果需要访问网络共享资源,则需要创建非交互式服务。非交互服务不允许与桌面直接交互,如需交互可通过其他折中方式比如socket, name pipe等。

 

(Copy from MSDN

Note  It is possible to display a message box from a service, even if it is not running in the LocalSystem account or not configured to run interactively. Simply call the MessageBox function using the MB_SERVICE_NOTIFICATION flag. Do not call MessageBox during service initialization or from the HandlerEx routine, unless you call it from a separate thread, so that you return to the SCM in a timely manner.

It is also possible to interact with the desktop from a non-interactive service by modifying the DACLs on the interface window station and desktop or by impersonating the logged-on user and opening the interactive window station and desktop directly. For more information, see Interacting with the User in a Service.

)

 

代码范例(c/c++)

 

SC_HANDLE hService;

       if (strlen(m_szServiceUser) == 0 || strlen(m_szServicePassword) == 0)      

       {

              hService= ::CreateService(

                     hSCM, m_szServiceName, m_szServiceName,

                     SERVICE_ALL_ACCESS,

// SERVICE_INTERACTIVE_PROCESS, enable service to interact with desktop (window)

// If SERVICE_INTERACTIVE_PROCESS is set, network share resource will not be allowed to access (for example net share files or directories).

SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,

                     SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,

// If the user & password is set to NULL, the service will be created with localsystem, shared object created in the service can not be accessed by other process

                     szFilePath, NULL, NULL, _T("RPCSS/0"), NULL, NULL);             

       }

       else

       {

              hService= ::CreateService(

                     hSCM, m_szServiceName, m_szServiceName,

// If SERVICE_INTERACTIVE_PROCESS is not set, windows can not be created.

                     SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,

                     SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,

                     szFilePath, NULL, NULL, _T("RPCSS/0"), m_szServiceUser, m_szServicePassword);

             

// Grant the user the privilege to logon, else if user login with admin or other user name, the service can not be started

              GrantLoginPrivilege(m_szServiceUser);

          }

 

// copy from MSDN

//

 

/*

#ifndef UNICODE

#define UNICODE

#endif // UNICODE

*/

#include "stdafx.h"

#include <windows.h>

#include <stdio.h>

#include <TCHAR.h>

#include "ntsecapi.h"

 

 

NTSTATUS

OpenPolicy(

    LPWSTR ServerName,          // machine to open policy on (Unicode)

    DWORD DesiredAccess,        // desired access to policy

    PLSA_HANDLE PolicyHandle    // resultant policy handle

    );

 

BOOL

GetAccountSid(

    LPCTSTR SystemName,          // where to lookup account

    LPCTSTR AccountName,         // account of interest

    PSID *Sid                   // resultant buffer containing SID

    );

 

NTSTATUS

SetPrivilegeOnAccount(

    LSA_HANDLE PolicyHandle,    // open policy handle

    PSID AccountSid,            // SID to grant privilege to

    LPWSTR PrivilegeName,       // privilege to grant (Unicode)

    BOOL bEnable                // enable or disable

    );

 

void

InitLsaString(

    PLSA_UNICODE_STRING LsaString, // destination

    LPWSTR String                  // source (Unicode)

    );

 

void

DisplayNtStatus(

    LPSTR szAPI,                // pointer to function name (ANSI)

    NTSTATUS Status             // NTSTATUS error value

    );

 

void

DisplayWinError(

    LPSTR szAPI,                // pointer to function name (ANSI)

    DWORD WinError              // DWORD WinError

    );

 

//

// If you have the ddk, include ntstatus.h.

//

#ifndef STATUS_SUCCESS

#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)

#endif

 

extern "C" bool GrantLoginPrivilege(LPCTSTR lpszAccountName)

{

    LSA_HANDLE PolicyHandle;

    PSID pSid;

    NTSTATUS Status;

       bool bSuccess = false;

    WCHAR wComputerName[256]=L"";   // static machine name buffer

 

    //

    // Open the policy on the target machine.

    //

    Status = OpenPolicy(

                wComputerName,      // target machine

                POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,

                &PolicyHandle       // resultant policy handle

                );

 

    if(Status != STATUS_SUCCESS)

       {

        DisplayNtStatus("OpenPolicy", Status);

        return false;

    }

 

       //

       //Remove Domain name if lpszAccountName include one.

       //

 

       TCHAR szName[256];

       TCHAR* p = _tcschr(lpszAccountName, _T('//'));

       if(p != NULL)

       {

              _tcscpy(szName, p+1);

       }

       else

       {

              _tcscpy(szName, lpszAccountName);

       }

 

    //

    // Obtain the SID of the user/group.

    // Note that we could target a specific machine, but we don't.

    // Specifying NULL for target machine searches for the SID in the

    // following order: well-known, Built-in and local, primary domain,

    // trusted domains.

    //

 

 

    if(GetAccountSid(

            NULL,       // default lookup logic

            szName,// account to obtain SID

            &pSid       // buffer to allocate to contain resultant SID

            ))

       {

        //

        // We only grant the privilege if we succeeded in obtaining the

        // SID. We can actually add SIDs which cannot be looked up, but

        // looking up the SID is a good sanity check which is suitable for

        // most cases.

 

        //

        // Grant the SeServiceLogonRight to users represented by pSid.

        //

        Status = SetPrivilegeOnAccount(

                    PolicyHandle,           // policy handle

                    pSid,                   // SID to grant privilege

                    L"SeServiceLogonRight", // Unicode privilege

                    TRUE                    // enable the privilege

                    );

 

        if(Status == STATUS_SUCCESS)

              {

            bSuccess = true;

              }

        else

              {

            DisplayNtStatus("SetPrivilegeOnAccount", Status);

              }

    }

    else

       {

        //

        // Error obtaining SID.

        //

        DisplayWinError("GetAccountSid", GetLastError());

    }

 

    //

    // Close the policy handle.

    //

    LsaClose(PolicyHandle);

 

    //

    // Free memory allocated for SID.

    //

    if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid);

 

    return bSuccess;

}

 

 

/*++

This function attempts to obtain a SID representing the supplied

account on the supplied system.

 

If the function succeeds, the return value is TRUE. A buffer is

allocated which contains the SID representing the supplied account.

This buffer should be freed when it is no longer needed by calling

HeapFree(GetProcessHeap(), 0, buffer)

 

If the function fails, the return value is FALSE. Call GetLastError()

to obtain extended error information.

 

Scott Field (sfield)    12-Jul-95

--*/

 

BOOL

GetAccountSid(

    LPCTSTR SystemName,

    LPCTSTR AccountName,

    PSID *Sid

    )

{

    LPTSTR ReferencedDomain=NULL;

    DWORD cbSid=128;    // initial allocation attempt

    DWORD cchReferencedDomain=16; // initial allocation size

    SID_NAME_USE peUse;

    BOOL bSuccess=FALSE; // assume this function will fail

 

    __try {

 

    //

    // initial memory allocations

    //

    *Sid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);

 

    if(*Sid == NULL) __leave;

 

    ReferencedDomain = (LPTSTR)HeapAlloc(

                    GetProcessHeap(),

                    0,

                    cchReferencedDomain * sizeof(TCHAR)

                    );

 

    if(ReferencedDomain == NULL) __leave;

 

    //

    // Obtain the SID of the specified account on the specified system.

    //

    while(!LookupAccountName(

                    SystemName,         // machine to lookup account on

                    AccountName,        // account to lookup

                    *Sid,               // SID of interest

                    &cbSid,             // size of SID

                    ReferencedDomain,   // domain account was found on

                    &cchReferencedDomain,

                    &peUse

                    ))

       {

        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

              {

            //

            // reallocate memory

            //

            *Sid = (PSID)HeapReAlloc(

                        GetProcessHeap(),

                        0,

                        *Sid,

                        cbSid

                        );

            if(*Sid == NULL) __leave;

 

            ReferencedDomain = (LPTSTR)HeapReAlloc(

                        GetProcessHeap(),

                        0,

                        ReferencedDomain,

                        cchReferencedDomain * sizeof(TCHAR)

                        );

            if(ReferencedDomain == NULL) __leave;

        }

        else __leave;

    }

 

    //

    // Indicate success.

    //

    bSuccess = TRUE;

 

    } // try

    __finally {

 

    //

    // Cleanup and indicate failure, if appropriate.

    //

 

    HeapFree(GetProcessHeap(), 0, ReferencedDomain);

 

    if(!bSuccess) {

        if(*Sid != NULL) {

            HeapFree(GetProcessHeap(), 0, *Sid);

            *Sid = NULL;

        }

    }

 

    } // finally

 

    return bSuccess;

}

 

NTSTATUS

SetPrivilegeOnAccount(

    LSA_HANDLE PolicyHandle,    // open policy handle

    PSID AccountSid,            // SID to grant privilege to

    LPWSTR PrivilegeName,       // privilege to grant (Unicode)

    BOOL bEnable                // enable or disable

    )

{

    LSA_UNICODE_STRING PrivilegeString;

 

    //

    // Create a LSA_UNICODE_STRING for the privilege name.

    //

    InitLsaString(&PrivilegeString, PrivilegeName);

 

    //

    // grant or revoke the privilege, accordingly

    //

    if(bEnable) {

        return LsaAddAccountRights(

                PolicyHandle,       // open policy handle

                AccountSid,         // target SID

                &PrivilegeString,   // privileges

                1                   // privilege count

                );

    }

    else {

        return LsaRemoveAccountRights(

                PolicyHandle,       // open policy handle

                AccountSid,         // target SID

                FALSE,              // do not disable all rights

                &PrivilegeString,   // privileges

                1                   // privilege count

                );

    }

}

 

void

InitLsaString(

    PLSA_UNICODE_STRING LsaString,

    LPWSTR String

    )

{

    DWORD StringLength;

 

    if(String == NULL) {

        LsaString->Buffer = NULL;

        LsaString->Length = 0;

        LsaString->MaximumLength = 0;

        return;

    }

 

    StringLength = lstrlenW(String);

    LsaString->Buffer = String;

    LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);

    LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);

}

 

NTSTATUS

OpenPolicy(

    LPWSTR ServerName,

    DWORD DesiredAccess,

    PLSA_HANDLE PolicyHandle

    )

{

    LSA_OBJECT_ATTRIBUTES ObjectAttributes;

    LSA_UNICODE_STRING ServerString;

    PLSA_UNICODE_STRING Server;

 

    //

    // Always initialize the object attributes to all zeroes.

    //

    ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));

 

    if (ServerName != NULL) {

        //

        // Make a LSA_UNICODE_STRING out of the LPWSTR passed in

        //

        InitLsaString(&ServerString, ServerName);

        Server = &ServerString;

    } else {

        Server = NULL;

    }

 

    //

    // Attempt to open the policy.

    //

    return LsaOpenPolicy(

                Server,

                &ObjectAttributes,

                DesiredAccess,

                PolicyHandle

                );

}

 

void

DisplayNtStatus(

    LPSTR szAPI,

    NTSTATUS Status

    )

{

    //

    // Convert the NTSTATUS to Winerror. Then call DisplayWinError().

    //

    DisplayWinError(szAPI, LsaNtStatusToWinError(Status));

}

 

void

DisplayWinError(

    LPSTR szAPI,

    DWORD WinError

    )

{

    LPSTR MessageBuffer;

    DWORD dwBufferLength;

 

    if(dwBufferLength=FormatMessageA(

                        FORMAT_MESSAGE_ALLOCATE_BUFFER |

                        FORMAT_MESSAGE_FROM_SYSTEM,

                        NULL,

                        WinError,

                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

                        (LPSTR) &MessageBuffer,

                        0,

                        NULL

                        ))

    {

              char szCaption[256];

              sprintf(szCaption,"GrantLoginPrivilege:%s", szAPI);

              ::MessageBox(NULL, MessageBuffer, szCaption, MB_OK|MB_ICONSTOP);

 

        //

        // Free the buffer allocated by the system.

        //

        LocalFree(MessageBuffer);

    }

}

         

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值