天天看點

服務級程序的建立

服務級程序的建立

大 中 小

1. File/New/Projects:Win32 Console Application/Project name: testsystem/選擇第二個: A simple application .

2. 添加代碼.

3. 把要建立程序服務的exe放到項目的同一目錄下.

// testok.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include <windows.h>

#include <stdio.h>

#include <Tlhelp32.h>

#include <AccCtrl.h>

#include <Aclapi.h>

#include <wtsapi32.h>

#pragma comment(lib, "wtsapi32")

HANDLE OpenSystemProcess()

{

    HANDLE hSnapshot = NULL;

    HANDLE hProc     = NULL;

    __try

    {

        // Get a snapshot of the processes in the system

        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        if (hSnapshot == NULL)

        {

            printf("OpenSystemProcess CreateToolhelp32Snapshot Failed");

            __leave;

        }

        PROCESSENTRY32 pe32;

        pe32.dwSize = sizeof(pe32);

        // Find the "System" process

        BOOL fProcess = Process32First(hSnapshot, &pe32);

        while (fProcess && (lstrcmpi(pe32.szExeFile, TEXT("SYSTEM")) != 0))

            fProcess = Process32Next(hSnapshot, &pe32);

        if (!fProcess)

        {

            printf("OpenSystemProcess Not Found SYSTEM");

            __leave;    // Didn't find "System" process

        }

        // Open the process with PROCESS_QUERY_INFORMATION access

        hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,

            pe32.th32ProcessID);

        if (hProc == NULL)

        {

            printf("OpenSystemProcess OpenProcess Failed");

            __leave;

        }

    }

    __finally

    {

        // Cleanup the snapshot

  if (hSnapshot != NULL)

   CloseHandle(hSnapshot);

  return(hProc);

    }

}

BOOL EnablePrivilege (PCSTR name)

{

    HANDLE hToken;

    BOOL rv;

    TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} };

    LookupPrivilegeValue (

        0,

        name,

        &priv.Privileges[0].Luid

  );

    OpenProcessToken(

        GetCurrentProcess (),

        TOKEN_ADJUST_PRIVILEGES,

        &hToken

  );

    AdjustTokenPrivileges (

        hToken,

        FALSE,

        &priv,

        sizeof priv,

        0,

  );

    rv = GetLastError () == ERROR_SUCCESS;

    CloseHandle (hToken);

    return rv;

}

#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))

BOOL ModifySecurity(HANDLE hProc, DWORD dwAccess)

{

    PACL pAcl        = NULL;

    PACL pNewAcl     = NULL;

    PACL pSacl       = NULL;

    PSID pSidOwner   = NULL;

    PSID pSidPrimary = NULL;

    BOOL fSuccess    = TRUE;

    PSECURITY_DESCRIPTOR pSD = NULL;

    __try

    {

        // Find the length of the security object for the kernel object

        DWORD dwSDLength;

        if (GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD, 0,

            &dwSDLength) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))

        {

            printf("ModifySecurity GetKernelObjectSecurity Size Failed");

            __leave;

        }

        // Allocate a buffer of that length

        pSD = LocalAlloc(LPTR, dwSDLength);

        if (pSD == NULL)

        {

            printf("ModifySecurity LocalAlloc Failed");

            __leave;

        }

        // Retrieve the kernel object

        if (!GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD,

            dwSDLength, &dwSDLength))

        {

            printf("ModifySecurity GetKernelObjectSecurity Failed");

            __leave;

        }

        // Get a pointer to the DACL of the SD

        BOOL fDaclPresent;

        BOOL fDaclDefaulted;

        if (!GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl,

            &fDaclDefaulted))

        {

            printf("ModifySecurity GetSecurityDescriptorDacl Failed");

            __leave;

        }

        // Get the current user's name

        TCHAR szName[1024];

        DWORD dwLen = chDIMOF(szName);

        if (!GetUserName(szName, &dwLen))

        {

            printf("ModifySecurity GetUserName Failed");

            __leave;

        }

        // Build an EXPLICIT_ACCESS structure for the ace we wish to add.

        EXPLICIT_ACCESS ea;

        BuildExplicitAccessWithName(&ea, szName, dwAccess, GRANT_ACCESS, 0);

        ea.Trustee.TrusteeType = TRUSTEE_IS_USER;

        // We are allocating a new ACL with a new ace inserted.  The new

        // ACL must be LocalFree'd

        if(ERROR_SUCCESS != SetEntriesInAcl(1, &ea, pAcl, &pNewAcl))

        {

            printf("ModifySecurity SetEntriesInAcl Failed");

            pNewAcl = NULL;

            __leave;

        }

        // Find the buffer sizes we would need to make our SD absolute

        pAcl               = NULL;

        dwSDLength         = 0;

        DWORD dwAclSize    = 0;

        DWORD dwSaclSize   = 0;

        DWORD dwSidOwnLen  = 0;

        DWORD dwSidPrimLen = 0;

        PSECURITY_DESCRIPTOR pAbsSD = NULL;

        if(MakeAbsoluteSD(pSD, pAbsSD, &dwSDLength, pAcl, &dwAclSize, pSacl,

            &dwSaclSize, pSidOwner, &dwSidOwnLen, pSidPrimary, &dwSidPrimLen)

            || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))

        {

            printf("ModifySecurity MakeAbsoluteSD Size Failed");

            __leave;

        }

        // Allocate the buffers

        pAcl = (PACL) LocalAlloc(LPTR, dwAclSize);

        pSacl = (PACL) LocalAlloc(LPTR, dwSaclSize);

        pSidOwner = (PSID) LocalAlloc(LPTR, dwSidOwnLen);

        pSidPrimary = (PSID) LocalAlloc(LPTR, dwSidPrimLen);

        pAbsSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, dwSDLength);

        if(!(pAcl && pSacl && pSidOwner && pSidPrimary && pAbsSD))

        {

            printf("ModifySecurity Invalid SID Found");

            __leave;

        }

        // And actually make our SD absolute

        if(!MakeAbsoluteSD(pSD, pAbsSD, &dwSDLength, pAcl, &dwAclSize, pSacl,

            &dwSaclSize, pSidOwner, &dwSidOwnLen, pSidPrimary, &dwSidPrimLen))

        {

            printf("ModifySecurity MakeAbsoluteSD Failed");

            __leave;

        }

        // Now set the security descriptor DACL

        if(!SetSecurityDescriptorDacl(pAbsSD, fDaclPresent, pNewAcl,

            fDaclDefaulted))

        {

            printf("ModifySecurity SetSecurityDescriptorDacl Failed");

            __leave;

        }

        // And set the security for the object

        if(!SetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pAbsSD))

        {

            printf("ModifySecurity SetKernelObjectSecurity Failed");

            __leave;

        }

        fSuccess = TRUE;

    }

    __finally

    {

        // Cleanup

        if (pNewAcl == NULL)

            LocalFree(pNewAcl);

        if (pSD == NULL)

            LocalFree(pSD);

        if (pAcl == NULL)

            LocalFree(pAcl);

        if (pSacl == NULL)

            LocalFree(pSacl);

        if (pSidOwner == NULL)

            LocalFree(pSidOwner);

        if (pSidPrimary == NULL)

            LocalFree(pSidPrimary);

        if(!fSuccess)

        {

            printf("ModifySecurity exception caught in __finally");

        }

        return(fSuccess);

    }

}

HANDLE GetLSAToken()

{

    HANDLE hProc  = NULL;

    HANDLE hToken = NULL;

    BOOL bSuccess = FALSE;

    __try

    {

        // Enable the SE_DEBUG_NAME privilege in our process token

        if (!EnablePrivilege(SE_DEBUG_NAME))

        {

            printf("GetLSAToken EnablePrivilege Failed");

            __leave;

        }

        // Retrieve a handle to the "System" process

        hProc = OpenSystemProcess();

        if(hProc == NULL)

        {

            printf("GetLSAToken OpenSystemProcess Failed");

            __leave;

        }

        // Open the process token with READ_CONTROL and WRITE_DAC access.  We

        // will use this access to modify the security of the token so that we

        // retrieve it again with a more complete set of rights.

        BOOL fResult = OpenProcessToken(hProc, READ_CONTROL | WRITE_DAC,

            &hToken);

        if(FALSE == fResult) 

        {

            printf("GetLSAToken OpenProcessToken Failed");

            __leave;

        }

        // Add an ace for the current user for the token.  This ace will add

        // TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY rights.

        if (!ModifySecurity(hToken, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY

            | TOKEN_QUERY | TOKEN_ADJUST_SESSIONID))

        {

            printf("GetLSAToken ModifySecurity Failed");

            __leave;

        }

        // Reopen the process token now that we have added the rights to

        // query the token, duplicate it, and assign it.

        fResult = OpenProcessToken(hProc, TOKEN_QUERY | TOKEN_DUPLICATE  | TOKEN_ASSIGN_PRIMARY | READ_CONTROL | WRITE_DAC, &hToken);

        if (FALSE == fResult) 

        {

            printf("GetLSAToken OpenProcessToken Failed");

            __leave;

        }

        bSuccess = TRUE;

    }

    __finally

    {

        // Close the System process handle

        if (hProc != NULL)    CloseHandle(hProc);

        if(bSuccess)

            return hToken;

        else

        {

            ::CloseHandle(hToken);

            return NULL;

        }

    }

}

#define DESKTOP_ALL (DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | /

 DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | /

 DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | /

DESKTOP_SWITCHDESKTOP | STANDARD_RIGHTS_REQUIRED)

#define WINSTA_ALL (WINSTA_ENUMDESKTOPS | WINSTA_READATTRIBUTES |  /

    WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | /

 WINSTA_WRITEATTRIBUTES | WINSTA_ACCESSGLOBALATOMS | /

 WINSTA_EXITWINDOWS | WINSTA_ENUMERATE | /

 WINSTA_READSCREEN | /

STANDARD_RIGHTS_REQUIRED)

#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)

BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid);

BOOL AddAceToDesktop(HDESK hdesk, PSID psid);

BOOL GetLogonSID(HANDLE hToken, PSID *ppsid)

{

    PWTS_PROCESS_INFO pProcessInfo = NULL;

    DWORD             ProcessCount = 0;

    BOOL                ret=FALSE;

    if (WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pProcessInfo, &ProcessCount))

    {

        // dump each process description

        for (DWORD CurrentProcess = 0; CurrentProcess < ProcessCount; CurrentProcess++)

        {

            if( strcmp(pProcessInfo[CurrentProcess].pProcessName, "System") == 0 )

            {

                //*ppsid = pProcessInfo[CurrentProcess].pUserSid;

                DWORD dwLength = GetLengthSid(pProcessInfo[CurrentProcess].pUserSid);

                *ppsid = (PSID) HeapAlloc(GetProcessHeap(),

     HEAP_ZERO_MEMORY, dwLength);

                if (*ppsid == NULL)

                    break;

                if (!CopySid(dwLength, *ppsid, pProcessInfo[CurrentProcess].pUserSid))

                {

                    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);

                    break;

                }

                ret=TRUE;

                break;

            }

        }

        WTSFreeMemory(pProcessInfo);

    }

    return ret;

}

BOOL GetLogonSID_1 (HANDLE hToken, PSID *ppsid)

{

 BOOL bSuccess = FALSE;

 DWORD dwIndex;

 DWORD dwLength = 0;

 PTOKEN_GROUPS ptg = NULL;

 // Verify the parameter passed in is not NULL.

    if (NULL == ppsid)

        goto Cleanup;

 // Get required buffer size and allocate the TOKEN_GROUPS buffer.

 if (!GetTokenInformation(

  hToken,         // handle to the access token

  TokenGroups,    // get information about the token's groups

  (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer

  0,              // size of buffer

  &dwLength       // receives required buffer size

  ))

 {

  if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)

   goto Cleanup;

  ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(),

   HEAP_ZERO_MEMORY, dwLength);

  if (ptg == NULL)

   goto Cleanup;

 }

 // Get the token group information from the access token.

 if (!GetTokenInformation(

  hToken,         // handle to the access token

  TokenGroups,    // get information about the token's groups

  (LPVOID) ptg,   // pointer to TOKEN_GROUPS buffer

  dwLength,       // size of buffer

  &dwLength       // receives required buffer size

  ))

 {

  goto Cleanup;

 }

 // Loop through the groups to find the logon SID.

 for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++)

  if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID)

   ==  SE_GROUP_LOGON_ID)

  {

   // Found the logon SID; make a copy of it.

   dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid);

   *ppsid = (PSID) HeapAlloc(GetProcessHeap(),

    HEAP_ZERO_MEMORY, dwLength);

   if (*ppsid == NULL)

    goto Cleanup;

   if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid))

   {

    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);

    goto Cleanup;

   }

   break;

  }

  bSuccess = TRUE;

Cleanup:

  // Free the buffer for the token groups.

  if (ptg != NULL)

   HeapFree(GetProcessHeap(), 0, (LPVOID)ptg);

  return bSuccess;

}

VOID FreeLogonSID (PSID *ppsid)

{

    HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid);

}

BOOL StartInteractiveClientProcess (

         LPTSTR lpszUsername,    // client to log on

         LPTSTR lpszDomain,      // domain of client's account

         LPTSTR lpszPassword,    // client's password

         LPTSTR lpCommandLine,    // command line to execute

         HANDLE Token = NULL

         )

{

 HANDLE      hToken;

 HDESK       hdesk = NULL;

 HWINSTA     hwinsta = NULL, hwinstaSave = NULL;

 PROCESS_INFORMATION pi;

 PSID pSid = NULL;

 STARTUPINFO si;

 BOOL bResult = FALSE;

 // Log the client on to the local computer.

 if(Token!=NULL)

 {

  printf("%08x/n", Token);

  hToken = Token;

 }

 else if (!LogonUser(

  lpszUsername,

  lpszDomain,

  lpszPassword,

  LOGON32_LOGON_INTERACTIVE,

  LOGON32_PROVIDER_DEFAULT,

  &hToken) )

 {

  goto Cleanup;

 }

 // Save a handle to the caller's current window station.

 if ( (hwinstaSave = GetProcessWindowStation() ) == NULL)

  goto Cleanup;

 // Get a handle to the interactive window station.

 hwinsta = OpenWindowStation(

  "winsta0",                   // the interactive window station

  FALSE,                       // handle is not inheritable

  READ_CONTROL | WRITE_DAC);   // rights to read/write the DACL

 if (hwinsta == NULL)

  goto Cleanup;

 // To get the correct default desktop, set the caller's

 // window station to the interactive window station.

 if (!SetProcessWindowStation(hwinsta))

  goto Cleanup;

 // Get a handle to the interactive desktop.

 hdesk = OpenDesktop(

  "default",     // the interactive window station

  0,             // no interaction with other desktop processes

  FALSE,         // handle is not inheritable

  READ_CONTROL | // request the rights to read and write the DACL

  WRITE_DAC |

  DESKTOP_WRITEOBJECTS |

  DESKTOP_READOBJECTS);

 // Restore the caller's window station.

 if (!SetProcessWindowStation(hwinstaSave))

  goto Cleanup;

 if (hdesk == NULL)

  goto Cleanup;

 // Get the SID for the client's logon session.

 if (!GetLogonSID(hToken, &pSid))

  goto Cleanup;

 // Allow logon SID full access to interactive window station.

 if (! AddAceToWindowStation(hwinsta, pSid) )

  goto Cleanup;

 // Allow logon SID full access to interactive desktop.

 if (! AddAceToDesktop(hdesk, pSid) )

  goto Cleanup;

 // Impersonate client to ensure access to executable file.

 if (! ImpersonateLoggedOnUser(hToken) )

  goto Cleanup;

 // Initialize the STARTUPINFO structure.

 // Specify that the process runs in the interactive desktop.

 ZeroMemory(&si, sizeof(STARTUPINFO));

 si.cb= sizeof(STARTUPINFO);

 si.lpDesktop = TEXT("winsta0//default");  //You can use EnumWindowStations to enum desktop

 // Launch the process in the client's logon session.

 bResult = CreateProcessAsUser(

  hToken,            // client's access token

  NULL,              // file to execute

  lpCommandLine,     // command line

  NULL,              // pointer to process SECURITY_ATTRIBUTES

  NULL,              // pointer to thread SECURITY_ATTRIBUTES

  FALSE,             // handles are not inheritable

  NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,   // creation flags

  NULL,              // pointer to new environment block

  NULL,              // name of current directory

  &si,               // pointer to STARTUPINFO structure

  &pi                // receives information about new process

  );

 // End impersonation of client.

 RevertToSelf();

 goto Cleanup;

 //return bResult; <------------------------------------------------------------------------

 if (bResult && pi.hProcess != INVALID_HANDLE_VALUE)

 {

  WaitForSingleObject(pi.hProcess, INFINITE);

  CloseHandle(pi.hProcess);

 }

 if (pi.hThread != INVALID_HANDLE_VALUE)

  CloseHandle(pi.hThread); 

Cleanup:

 if (hwinstaSave != NULL)

  SetProcessWindowStation (hwinstaSave);

 // Free the buffer for the logon SID.

 if (pSid)

  FreeLogonSID(&pSid);

 // Close the handles to the interactive window station and desktop.

 if (hwinsta)

  CloseWindowStation(hwinsta);

 if (hdesk)

  CloseDesktop(hdesk);

 // Close the handle to the client's access token.

 if (hToken != INVALID_HANDLE_VALUE)

  CloseHandle(hToken); 

 return bResult;

}

BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)

{

 ACCESS_ALLOWED_ACE   *pace;

 ACL_SIZE_INFORMATION aclSizeInfo;

 BOOL                 bDaclExist;

 BOOL                 bDaclPresent;

 BOOL                 bSuccess = FALSE;

 DWORD                dwNewAclSize;

 DWORD                dwSidSize = 0;

 DWORD                dwSdSizeNeeded;

 PACL                 pacl;

 PACL                 pNewAcl;

 PSECURITY_DESCRIPTOR psd = NULL;

 PSECURITY_DESCRIPTOR psdNew = NULL;

 PVOID                pTempAce;

 SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

 unsigned int         i;

 __try

 {

  // Obtain the DACL for the window station.

  if (!GetUserObjectSecurity(

   hwinsta,

   &si,

   psd,

   dwSidSize,

   &dwSdSizeNeeded)

   )

   if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

   {

    psd = (PSECURITY_DESCRIPTOR)HeapAlloc(

     GetProcessHeap(),

     HEAP_ZERO_MEMORY,

     dwSdSizeNeeded);

    if (psd == NULL)

     __leave;

    psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(

     GetProcessHeap(),

     HEAP_ZERO_MEMORY,

     dwSdSizeNeeded);

    if (psdNew == NULL)

     __leave;

    dwSidSize = dwSdSizeNeeded;

    if (!GetUserObjectSecurity(

     hwinsta,

     &si,

     psd,

     dwSidSize,

     &dwSdSizeNeeded)

     )

     __leave;

   }

   else

    __leave;

   // Create a new DACL.

   if (!InitializeSecurityDescriptor(

    psdNew,

    SECURITY_DESCRIPTOR_REVISION)

    )

    __leave;

   // Get the DACL from the security descriptor.

   if (!GetSecurityDescriptorDacl(

    psd,

    &bDaclPresent,

    &pacl,

    &bDaclExist)

    )

    __leave;

   // Initialize the ACL.

   ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));

   aclSizeInfo.AclBytesInUse = sizeof(ACL);

   // Call only if the DACL is not NULL.

   if (pacl != NULL)

   {

    // get the file ACL size info

    if (!GetAclInformation(

     pacl,

     (LPVOID)&aclSizeInfo,

     sizeof(ACL_SIZE_INFORMATION),

     AclSizeInformation)

     )

     __leave;

   }

   // Compute the size of the new ACL.

   dwNewAclSize = aclSizeInfo.AclBytesInUse + (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) - (2*sizeof(DWORD));

   // Allocate memory for the new ACL.

   pNewAcl = (PACL)HeapAlloc(

    GetProcessHeap(),

    HEAP_ZERO_MEMORY,

    dwNewAclSize);

   if (pNewAcl == NULL)

    __leave;

   // Initialize the new DACL.

   if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))

    __leave;

   // If DACL is present, copy it to a new DACL.

   if (bDaclPresent)

   {

    // Copy the ACEs to the new ACL.

    if (aclSizeInfo.AceCount)

    {

     for (i=0; i < aclSizeInfo.AceCount; i++)

     {

      // Get an ACE.

      if (!GetAce(pacl, i, &pTempAce))

       __leave;

      // Add the ACE to the new ACL.

      if (!AddAce(

       pNewAcl,

       ACL_REVISION,

       MAXDWORD,

       pTempAce,

       ((PACE_HEADER)pTempAce)->AceSize)

       )

       __leave;

     }

    }

   }

   // Add the first ACE to the window station.

   pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(

    GetProcessHeap(),

    HEAP_ZERO_MEMORY,

    sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -

    sizeof(DWORD));

   if (pace == NULL)

    __leave;

   pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;

   pace->Header.AceFlags = CONTAINER_INHERIT_ACE |

    INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;

   pace->Header.AceSize  = sizeof(ACCESS_ALLOWED_ACE) +

    GetLengthSid(psid) - sizeof(DWORD);

   pace->Mask            = GENERIC_ACCESS;

   if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))

    __leave;

   if (!AddAce(

    pNewAcl,

    ACL_REVISION,

    MAXDWORD,

    (LPVOID)pace,

    pace->Header.AceSize)

    )

    __leave;

   // Add the second ACE to the window station.

   pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;

   pace->Mask            = WINSTA_ALL;

   if (!AddAce(

    pNewAcl,

    ACL_REVISION,

    MAXDWORD,

    (LPVOID)pace,

    pace->Header.AceSize)

    )

    __leave;

   // Set a new DACL for the security descriptor.

   if (!SetSecurityDescriptorDacl(

    psdNew,

    TRUE,

    pNewAcl,

    FALSE)

    )

    __leave;

   // Set the new security descriptor for the window station.

   if (!SetUserObjectSecurity(hwinsta, &si, psdNew))

    __leave;

   // Indicate success.

   bSuccess = TRUE;

   }

   __finally

   {

    // Free the allocated buffers.

    if (pace != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)pace);

    if (pNewAcl != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

    if (psd != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

    if (psdNew != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);

   }

   return bSuccess;

}

BOOL AddAceToDesktop(HDESK hdesk, PSID psid)

{

 ACL_SIZE_INFORMATION aclSizeInfo;

 BOOL                 bDaclExist;

 BOOL                 bDaclPresent;

 BOOL                 bSuccess = FALSE;

 DWORD                dwNewAclSize;

 DWORD                dwSidSize = 0;

 DWORD                dwSdSizeNeeded;

 PACL                 pacl;

 PACL                 pNewAcl;

 PSECURITY_DESCRIPTOR psd = NULL;

 PSECURITY_DESCRIPTOR psdNew = NULL;

 PVOID                pTempAce;

 SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;

 unsigned int         i;

 __try

 {

  // Obtain the security descriptor for the desktop object.

  if (!GetUserObjectSecurity(

            hdesk,

            &si,

            psd,

            dwSidSize,

            &dwSdSizeNeeded))

  {

   if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)

   {

    psd = (PSECURITY_DESCRIPTOR)HeapAlloc(

     GetProcessHeap(),

     HEAP_ZERO_MEMORY,

     dwSdSizeNeeded );

    if (psd == NULL)

     __leave;

    psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(

     GetProcessHeap(),

     HEAP_ZERO_MEMORY,

     dwSdSizeNeeded);

    if (psdNew == NULL)

     __leave;

    dwSidSize = dwSdSizeNeeded;

    if (!GetUserObjectSecurity(

     hdesk,

     &si,

     psd,

     dwSidSize,

     &dwSdSizeNeeded)

     )

     __leave;

   }

   else

    __leave;

  }

  // Create a new security descriptor.

  if (!InitializeSecurityDescriptor(

            psdNew,

            SECURITY_DESCRIPTOR_REVISION)

   )

   __leave;

  // Obtain the DACL from the security descriptor.

  if (!GetSecurityDescriptorDacl(

            psd,

            &bDaclPresent,

            &pacl,

            &bDaclExist)

   )

   __leave;

  // Initialize.

  ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));

  aclSizeInfo.AclBytesInUse = sizeof(ACL);

  // Call only if NULL DACL.

  if (pacl != NULL)

  {

   // Determine the size of the ACL information.

   if (!GetAclInformation(

    pacl,

    (LPVOID)&aclSizeInfo,

    sizeof(ACL_SIZE_INFORMATION),

    AclSizeInformation)

    )

    __leave;

  }

  // Compute the size of the new ACL.

  dwNewAclSize = aclSizeInfo.AclBytesInUse +

            sizeof(ACCESS_ALLOWED_ACE) +

            GetLengthSid(psid) - sizeof(DWORD);

  // Allocate buffer for the new ACL.

  pNewAcl = (PACL)HeapAlloc(

            GetProcessHeap(),

            HEAP_ZERO_MEMORY,

            dwNewAclSize);

  if (pNewAcl == NULL)

   __leave;

  // Initialize the new ACL.

  if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))

   __leave;

  // If DACL is present, copy it to a new DACL.

  if (bDaclPresent)

  {

   // Copy the ACEs to the new ACL.

   if (aclSizeInfo.AceCount)

   {

    for (i=0; i < aclSizeInfo.AceCount; i++)

    {

     // Get an ACE.

     if (!GetAce(pacl, i, &pTempAce))

      __leave;

     // Add the ACE to the new ACL.

     if (!AddAce(

      pNewAcl,

      ACL_REVISION,

      MAXDWORD,

      pTempAce,

      ((PACE_HEADER)pTempAce)->AceSize)

      )

      __leave;

    }

   }

  }

  // Add ACE to the DACL.

  if (!AddAccessAllowedAce(

            pNewAcl,

            ACL_REVISION,

            DESKTOP_ALL,

            psid)

   )

   __leave;

  // Set new DACL to the new security descriptor.

  if (!SetSecurityDescriptorDacl(

            psdNew,

            TRUE,

            pNewAcl,

            FALSE)

   )

   __leave;

  // Set the new security descriptor for the desktop object.

  if (!SetUserObjectSecurity(hdesk, &si, psdNew))

   __leave;

  // Indicate success.

  bSuccess = TRUE;

   }

   __finally

   {

    // Free buffers.

    if (pNewAcl != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

    if (psd != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

    if (psdNew != NULL)

     HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);

   }

   return bSuccess;

}

int main(int argc, char* argv[])

{

 HANDLE hToken = NULL;

    EnablePrivilege(SE_DEBUG_NAME);

    hToken = GetLSAToken();

 在項目下放個ckNetcartTest.exe

    StartInteractiveClientProcess(NULL, NULL, NULL, argc==2?argv[1]:"ckNetcartTest.exe", hToken);

 return 0;

}

繼續閱讀