Example #1
0
NTSTATUS
AllocW32Process(IN  PEPROCESS Process,
                OUT PPROCESSINFO* W32Process)
{
    PPROCESSINFO ppiCurrent;

    TRACE_CH(UserProcess, "In AllocW32Process(0x%p)\n", Process);

    /* Check that we were not called with an already existing Win32 process info */
    ppiCurrent = PsGetProcessWin32Process(Process);
    if (ppiCurrent) return STATUS_SUCCESS;

    /* Allocate a new Win32 process info */
    ppiCurrent = ExAllocatePoolWithTag(NonPagedPool,
                                       sizeof(*ppiCurrent),
                                       USERTAG_PROCESSINFO);
    if (ppiCurrent == NULL)
    {
        ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n",
               HandleToUlong(Process->UniqueProcessId));
        return STATUS_NO_MEMORY;
    }

    TRACE_CH(UserProcess, "Allocated ppi 0x%p for PID:0x%lx\n",
             ppiCurrent, HandleToUlong(Process->UniqueProcessId));

    RtlZeroMemory(ppiCurrent, sizeof(*ppiCurrent));

    PsSetProcessWin32Process(Process, ppiCurrent, NULL);
    IntReferenceProcessInfo(ppiCurrent);

    *W32Process = ppiCurrent;
    return STATUS_SUCCESS;
}
Example #2
0
/*
  Called from IntDereferenceThreadInfo.
 */
VOID
FASTCALL
UserDeleteW32Thread(PTHREADINFO pti)
{
    if (!pti->RefCount)
    {
        TRACE_CH(UserThread,"UserDeleteW32Thread pti 0x%p\n",pti);
        if (pti->hEventQueueClient != NULL)
            ZwClose(pti->hEventQueueClient);
        pti->hEventQueueClient = NULL;

        /* Free the message queue */
        if (pti->MessageQueue)
        {
            MsqDestroyMessageQueue(pti);
        }

        MsqCleanupThreadMsgs(pti);

        IntSetThreadDesktop(NULL, TRUE);

        PsSetThreadWin32Thread(pti->pEThread, NULL, pti);
        ExFreePoolWithTag(pti, USERTAG_THREADINFO);
    }
}
Example #3
0
VOID
WinLdrScanRegistry(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                   IN LPCSTR DirectoryPath)
{
	LONG rc = 0;
	FRLDRHKEY hGroupKey, hOrderKey, hServiceKey, hDriverKey;
	LPWSTR GroupNameBuffer;
	WCHAR ServiceName[256];
	ULONG OrderList[128];
	ULONG BufferSize;
	ULONG Index;
	ULONG TagIndex;
	LPWSTR GroupName;

	ULONG ValueSize;
	ULONG ValueType;
	ULONG StartValue;
	ULONG TagValue;
	WCHAR DriverGroup[256];
	ULONG DriverGroupSize;

	CHAR ImagePath[256];
	WCHAR TempImagePath[256];

	BOOLEAN Status;

	/* get 'service group order' key */
	rc = RegOpenKey(NULL,
		L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder",
		&hGroupKey);
	if (rc != ERROR_SUCCESS) {

		TRACE_CH(ODYSSEY, "Failed to open the 'ServiceGroupOrder' key (rc %d)\n", (int)rc);
		return;
	}

	/* get 'group order list' key */
	rc = RegOpenKey(NULL,
		L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\GroupOrderList",
		&hOrderKey);
	if (rc != ERROR_SUCCESS) {

		TRACE_CH(ODYSSEY, "Failed to open the 'GroupOrderList' key (rc %d)\n", (int)rc);
		return;
	}

	/* enumerate drivers */
	rc = RegOpenKey(NULL,
		L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services",
		&hServiceKey);
	if (rc != ERROR_SUCCESS)  {

		TRACE_CH(ODYSSEY, "Failed to open the 'Services' key (rc %d)\n", (int)rc);
		return;
	}

	/* Get the Name Group */
	BufferSize = 4096;
	GroupNameBuffer = MmHeapAlloc(BufferSize);
	rc = RegQueryValue(hGroupKey, L"List", NULL, (PUCHAR)GroupNameBuffer, &BufferSize);
	TRACE_CH(ODYSSEY, "RegQueryValue(): rc %d\n", (int)rc);
	if (rc != ERROR_SUCCESS)
		return;
	TRACE_CH(ODYSSEY, "BufferSize: %d \n", (int)BufferSize);
	TRACE_CH(ODYSSEY, "GroupNameBuffer: '%S' \n", GroupNameBuffer);

	/* Loop through each group */
	GroupName = GroupNameBuffer;
	while (*GroupName)
	{
		TRACE("Driver group: '%S'\n", GroupName);

		/* Query the Order */
		BufferSize = sizeof(OrderList);
		rc = RegQueryValue(hOrderKey, GroupName, NULL, (PUCHAR)OrderList, &BufferSize);
		if (rc != ERROR_SUCCESS) OrderList[0] = 0;

		/* enumerate all drivers */
		for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++)
		{
			Index = 0;

			while (TRUE)
			{
				/* Get the Driver's Name */
				ValueSize = sizeof(ServiceName);
				rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);
				//TRACE_CH(ODYSSEY, "RegEnumKey(): rc %d\n", (int)rc);

				/* Makre sure it's valid, and check if we're done */
				if (rc == ERROR_NO_MORE_ITEMS)
					break;
				if (rc != ERROR_SUCCESS)
				{
					MmHeapFree(GroupNameBuffer);
					return;
				}
				//TRACE_CH(ODYSSEY, "Service %d: '%S'\n", (int)Index, ServiceName);

				/* open driver Key */
				rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
				if (rc == ERROR_SUCCESS)
				{
					/* Read the Start Value */
					ValueSize = sizeof(ULONG);
					rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
					if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
					//TRACE_CH(ODYSSEY, "  Start: %x  \n", (int)StartValue);

					/* Read the Tag */
					ValueSize = sizeof(ULONG);
					rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
					if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
					//TRACE_CH(ODYSSEY, "  Tag:   %x  \n", (int)TagValue);

					/* Read the driver's group */
					DriverGroupSize = sizeof(DriverGroup);
					rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
					//TRACE_CH(ODYSSEY, "  Group: '%S'  \n", DriverGroup);

					/* Make sure it should be started */
					if ((StartValue == 0) &&
						(TagValue == OrderList[TagIndex]) &&
						(_wcsicmp(DriverGroup, GroupName) == 0)) {

							/* Get the Driver's Location */
							ValueSize = sizeof(TempImagePath);
							rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);

							/* Write the whole path if it suceeded, else prepare to fail */
							if (rc != ERROR_SUCCESS) {
								TRACE_CH(ODYSSEY, "ImagePath: not found\n");
								TempImagePath[0] = 0;
								sprintf(ImagePath, "%s\\system32\\drivers\\%S.sys", DirectoryPath, ServiceName);
							} else if (TempImagePath[0] != L'\\') {
								sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
							} else {
								sprintf(ImagePath, "%S", TempImagePath);
								TRACE_CH(ODYSSEY, "ImagePath: '%s'\n", ImagePath);
							}

							TRACE("Adding boot driver: '%s'\n", ImagePath);

							Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
								L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
								TempImagePath,
								ServiceName);

							if (!Status)
								ERR("Failed to add boot driver\n");
					} else
					{
						//TRACE("  Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current Tag %d, current group '%S')\n",
						//	ServiceName, StartValue, TagValue, DriverGroup, OrderList[TagIndex], GroupName);
					}
				}

				Index++;
			}
		}

		Index = 0;
		while (TRUE)
		{
			/* Get the Driver's Name */
			ValueSize = sizeof(ServiceName);
			rc = RegEnumKey(hServiceKey, Index, ServiceName, &ValueSize);

			//TRACE_CH(ODYSSEY, "RegEnumKey(): rc %d\n", (int)rc);
			if (rc == ERROR_NO_MORE_ITEMS)
				break;
			if (rc != ERROR_SUCCESS)
			{
				MmHeapFree(GroupNameBuffer);
				return;
			}
			//TRACE_CH(ODYSSEY, "Service %d: '%S'\n", (int)Index, ServiceName);

			/* open driver Key */
			rc = RegOpenKey(hServiceKey, ServiceName, &hDriverKey);
			if (rc == ERROR_SUCCESS)
			{
				/* Read the Start Value */
				ValueSize = sizeof(ULONG);
				rc = RegQueryValue(hDriverKey, L"Start", &ValueType, (PUCHAR)&StartValue, &ValueSize);
				if (rc != ERROR_SUCCESS) StartValue = (ULONG)-1;
				//TRACE_CH(ODYSSEY, "  Start: %x  \n", (int)StartValue);

				/* Read the Tag */
				ValueSize = sizeof(ULONG);
				rc = RegQueryValue(hDriverKey, L"Tag", &ValueType, (PUCHAR)&TagValue, &ValueSize);
				if (rc != ERROR_SUCCESS) TagValue = (ULONG)-1;
				//TRACE_CH(ODYSSEY, "  Tag:   %x  \n", (int)TagValue);

				/* Read the driver's group */
				DriverGroupSize = sizeof(DriverGroup);
				rc = RegQueryValue(hDriverKey, L"Group", NULL, (PUCHAR)DriverGroup, &DriverGroupSize);
				//TRACE_CH(ODYSSEY, "  Group: '%S'  \n", DriverGroup);

				for (TagIndex = 1; TagIndex <= OrderList[0]; TagIndex++) {
					if (TagValue == OrderList[TagIndex]) break;
				}

				if ((StartValue == 0) &&
					(TagIndex > OrderList[0]) &&
					(_wcsicmp(DriverGroup, GroupName) == 0)) {

						ValueSize = sizeof(TempImagePath);
						rc = RegQueryValue(hDriverKey, L"ImagePath", NULL, (PUCHAR)TempImagePath, &ValueSize);
						if (rc != ERROR_SUCCESS) {
							TRACE_CH(ODYSSEY, "ImagePath: not found\n");
							TempImagePath[0] = 0;
							sprintf(ImagePath, "%ssystem32\\drivers\\%S.sys", DirectoryPath, ServiceName);
						} else if (TempImagePath[0] != L'\\') {
							sprintf(ImagePath, "%s%S", DirectoryPath, TempImagePath);
						} else {
							sprintf(ImagePath, "%S", TempImagePath);
							TRACE_CH(ODYSSEY, "ImagePath: '%s'\n", ImagePath);
						}
						TRACE("  Adding boot driver: '%s'\n", ImagePath);

						Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
							L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
							TempImagePath,
							ServiceName);

						if (!Status)
							ERR(" Failed to add boot driver\n");
				} else
				{
					//TRACE("  Skipping driver '%S' with Start %d, Tag %d and Group '%S' (Current group '%S')\n",
					//	ServiceName, StartValue, TagValue, DriverGroup, GroupName);
				}
			}

			Index++;
		}

		/* Move to the next group name */
		GroupName = GroupName + wcslen(GroupName) + 1;
	}

	/* Free allocated memory */
	MmHeapFree(GroupNameBuffer);
}
Example #4
0
NTSTATUS
APIENTRY
Win32kProcessCallback(struct _EPROCESS *Process,
                      BOOLEAN Create)
{
    PPROCESSINFO ppiCurrent, *pppi;
    NTSTATUS Status;

    ASSERT(Process->Peb);

    UserEnterExclusive();

    if (Create)
    {
        SIZE_T ViewSize = 0;
        LARGE_INTEGER Offset;
        PVOID UserBase = NULL;
        PRTL_USER_PROCESS_PARAMETERS pParams = Process->Peb->ProcessParameters;

        /* We might be called with an already allocated win32 process */
        ppiCurrent = PsGetProcessWin32Process(Process);
        if (ppiCurrent != NULL)
        {
            /* There is no more to do for us (this is a success code!) */
            Status = STATUS_ALREADY_WIN32;
            goto Leave;
        }

        /* Allocate a new win32 process */
        ppiCurrent = ExAllocatePoolWithTag(NonPagedPool,
                                           sizeof(PROCESSINFO),
                                           USERTAG_PROCESSINFO);
        if (ppiCurrent == NULL)
        {
            ERR_CH(UserProcess, "Failed to allocate ppi for PID:0x%lx\n",
                   HandleToUlong(Process->UniqueProcessId));
            Status = STATUS_NO_MEMORY;
            goto Leave;
        }

        RtlZeroMemory(ppiCurrent, sizeof(PROCESSINFO));

        PsSetProcessWin32Process(Process, ppiCurrent, NULL);

#if DBG
        DbgInitDebugChannels();
#if KDBG
        KdRosRegisterCliCallback(DbgGdiKdbgCliCallback);
#endif
#endif

        TRACE_CH(UserProcess,"Allocated ppi 0x%p for PID:0x%lx\n", ppiCurrent, HandleToUlong(Process->UniqueProcessId));

        /* map the global heap into the process */
        Offset.QuadPart = 0;
        Status = MmMapViewOfSection(GlobalUserHeapSection,
                                    PsGetCurrentProcess(),
                                    &UserBase,
                                    0,
                                    0,
                                    &Offset,
                                    &ViewSize,
                                    ViewUnmap,
                                    SEC_NO_CHANGE,
                                    PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
        if (!NT_SUCCESS(Status))
        {
            TRACE_CH(UserProcess,"Failed to map the global heap! 0x%x\n", Status);
            goto Leave;
        }
        ppiCurrent->HeapMappings.Next = NULL;
        ppiCurrent->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
        ppiCurrent->HeapMappings.UserMapping = UserBase;
        ppiCurrent->HeapMappings.Count = 1;

        InitializeListHead(&ppiCurrent->MenuListHead);

        InitializeListHead(&ppiCurrent->GDIBrushAttrFreeList);
        InitializeListHead(&ppiCurrent->GDIDcAttrFreeList);

        InitializeListHead(&ppiCurrent->PrivateFontListHead);
        ExInitializeFastMutex(&ppiCurrent->PrivateFontListLock);

        InitializeListHead(&ppiCurrent->DriverObjListHead);
        ExInitializeFastMutex(&ppiCurrent->DriverObjListLock);

        ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
        if (!EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent))
        {
            KeBugCheck(0);
        }

        KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE);


        /* map the gdi handle table to user land */
        Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
        Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
        pParams = Process->Peb->ProcessParameters;

        ppiCurrent->peProcess = Process;
        /* setup process flags */
        ppiCurrent->W32PF_flags = W32PF_THREADCONNECTED;

        if ( pParams &&
                pParams->WindowFlags & STARTF_SCRNSAVER )
        {
            ppiScrnSaver = ppiCurrent;
            ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER;
        }

        // Fixme check if this process is allowed.
        ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off.

        /* Create pools for GDI object attributes */
        ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
        ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
        ppiCurrent->pPoolRgnAttr = GdiPoolCreate(sizeof(RGN_ATTR), 'agrG');
        ASSERT(ppiCurrent->pPoolDcAttr);
        ASSERT(ppiCurrent->pPoolBrushAttr);
        ASSERT(ppiCurrent->pPoolRgnAttr);

        /* Add the process to the global list */
        ppiCurrent->ppiNext = gppiList;
        gppiList = ppiCurrent;
    }
    else
    {
        /* Get the Win32 Process */
        ppiCurrent = PsGetProcessWin32Process(Process);

        ASSERT(ppiCurrent);

        TRACE_CH(UserProcess, "Destroying ppi 0x%p\n", ppiCurrent);
        ppiCurrent->W32PF_flags |= W32PF_TERMINATED;

        if (ppiScrnSaver == ppiCurrent)
            ppiScrnSaver = NULL;

        if (ppiCurrent->InputIdleEvent)
        {
            EngFreeMem(ppiCurrent->InputIdleEvent);
            ppiCurrent->InputIdleEvent = NULL;
        }

        IntCleanupMenus(Process, ppiCurrent);
        IntCleanupCurIcons(Process, ppiCurrent);


        GDI_CleanupForProcess(Process);

        co_IntGraphicsCheck(FALSE);

        /*
         * Deregister logon application automatically
         */
        if(LogonProcess == ppiCurrent)
        {
            LogonProcess = NULL;
        }

        /* Close the startup desktop */
        if(ppiCurrent->rpdeskStartup)
            ObDereferenceObject(ppiCurrent->rpdeskStartup);
        if(ppiCurrent->hdeskStartup)
            ZwClose(ppiCurrent->hdeskStartup);

        /* Close the current window station */
        UserSetProcessWindowStation(NULL);

        /* Destroy GDI pools */
        GdiPoolDestroy(ppiCurrent->pPoolDcAttr);
        GdiPoolDestroy(ppiCurrent->pPoolBrushAttr);
        GdiPoolDestroy(ppiCurrent->pPoolRgnAttr);

        if (gppiInputProvider == ppiCurrent) gppiInputProvider = NULL;

        pppi = &gppiList;
        while (*pppi != NULL && *pppi != ppiCurrent)
            pppi = &(*pppi)->ppiNext;

        ASSERT(*pppi == ppiCurrent);

        *pppi = ppiCurrent->ppiNext;

        TRACE_CH(UserProcess,"Freeing ppi 0x%p\n", ppiCurrent);
#if DBG
        if (DBG_IS_CHANNEL_ENABLED(ppiCurrent, DbgChUserObj, WARN_LEVEL))
        {
            DbgUserDumpHandleTable();
        }
#endif

        /* Free the PROCESSINFO */
        PsSetProcessWin32Process(Process, NULL, ppiCurrent);
        ExFreePoolWithTag(ppiCurrent, USERTAG_PROCESSINFO);
    }

    Status = STATUS_SUCCESS;

Leave:
    UserLeave();
    return Status;
}
Example #5
0
NTSTATUS
NTAPI
UserDestroyThreadInfo(struct _ETHREAD *Thread)
{
    PTHREADINFO *ppti;
    PSINGLE_LIST_ENTRY psle;
    PPROCESSINFO ppiCurrent;
    struct _EPROCESS *Process;
    PTHREADINFO ptiCurrent;

    Process = Thread->ThreadsProcess;

    /* Get the Win32 Thread */
    ptiCurrent = PsGetThreadWin32Thread(Thread);

    ASSERT(ptiCurrent);

    TRACE_CH(UserThread,"Destroying pti 0x%p eThread 0x%p\n", ptiCurrent, Thread);

    ptiCurrent->TIF_flags |= TIF_INCLEANUP;
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;

    ppiCurrent = ptiCurrent->ppi;
    ASSERT(ppiCurrent);

    IsRemoveAttachThread(ptiCurrent);

    ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;

    /* Decrement thread count and check if its 0 */
    ppiCurrent->cThreads--;

    if(ptiCurrent->TIF_flags & TIF_GUITHREADINITIALIZED)
    {
        /* Do now some process cleanup that requires a valid win32 thread */
        if(ptiCurrent->ppi->cThreads == 0)
        {
            /* Check if we have registered the user api hook */
            if(ptiCurrent->ppi == ppiUahServer)
            {
                /* Unregister the api hook */
                UserUnregisterUserApiHook();
            }

            /* Notify logon application to restart shell if needed */
            if(ptiCurrent->pDeskInfo)
            {
                if(ptiCurrent->pDeskInfo->ppiShellProcess == ppiCurrent)
                {
                    DWORD ExitCode = PsGetProcessExitStatus(Process);

                    TRACE_CH(UserProcess, "Shell process is exiting (%lu)\n", ExitCode);

                    UserPostMessage(hwndSAS,
                                    WM_LOGONNOTIFY,
                                    LN_SHELL_EXITED,
                                    ExitCode);

                    ptiCurrent->pDeskInfo->ppiShellProcess = NULL;
                }
            }
        }

        DceFreeThreadDCE(ptiCurrent);
        HOOK_DestroyThreadHooks(Thread);
        EVENT_DestroyThreadEvents(Thread);
        DestroyTimersForThread(ptiCurrent);
        KeSetEvent(ptiCurrent->pEventQueueServer, IO_NO_INCREMENT, FALSE);
        UnregisterThreadHotKeys(ptiCurrent);
        /*
                if (IsListEmpty(&ptiCurrent->WindowListHead))
                {
                   ERR_CH(UserThread,"Thread Window List is Empty!\n");
                }
        */
        co_DestroyThreadWindows(Thread);

        if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
                ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
        {
            TRACE_CH(UserThread,"DestroyProcessClasses\n");
            /* no process windows should exist at this point, or the function will assert! */
            DestroyProcessClasses(ppiCurrent);
            ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
        }

        IntBlockInput(ptiCurrent, FALSE);
        IntCleanupThreadCallbacks(ptiCurrent);

        /* cleanup user object references stack */
        psle = PopEntryList(&ptiCurrent->ReferencesList);
        while (psle)
        {
            PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(psle, USER_REFERENCE_ENTRY, Entry);
            TRACE_CH(UserThread,"thread clean: remove reference obj 0x%p\n",ref->obj);
            UserDereferenceObject(ref->obj);

            psle = PopEntryList(&ptiCurrent->ReferencesList);
        }
    }

    /* Find the THREADINFO in the PROCESSINFO's list */
    ppti = &ppiCurrent->ptiList;
    while (*ppti != NULL && *ppti != ptiCurrent)
    {
        ppti = &((*ppti)->ptiSibling);
    }

    /* we must have found it */
    ASSERT(*ppti == ptiCurrent);

    /* Remove it from the list */
    *ppti = ptiCurrent->ptiSibling;

    if (ptiCurrent->KeyboardLayout)
        UserDereferenceObject(ptiCurrent->KeyboardLayout);

    if (gptiForeground == ptiCurrent)
    {
//       IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
//       IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);

        gptiForeground = NULL;
    }

    // Fixes CORE-6384 & CORE-7030.
    /*    if (ptiLastInput == ptiCurrent)
        {
           if (!ppiCurrent->ptiList)
              ptiLastInput = gptiForeground;
           else
              ptiLastInput = ppiCurrent->ptiList;
           ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
        }
    */
    TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);

    /* Free the THREADINFO */
    IntDereferenceThreadInfo(ptiCurrent);

    return STATUS_SUCCESS;
}
Example #6
0
NTSTATUS NTAPI
UserCreateThreadInfo(struct _ETHREAD *Thread)
{
    struct _EPROCESS *Process;
    PCLIENTINFO pci;
    PTHREADINFO ptiCurrent;
    int i;
    NTSTATUS Status = STATUS_SUCCESS;
    PTEB pTeb;
    LARGE_INTEGER LargeTickCount;

    Process = Thread->ThreadsProcess;

    pTeb = NtCurrentTeb();

    ASSERT(pTeb);

    ptiCurrent = ExAllocatePoolWithTag(NonPagedPool,
                                       sizeof(THREADINFO),
                                       USERTAG_THREADINFO);
    if (ptiCurrent == NULL)
    {
        ERR_CH(UserThread, "Failed to allocate pti for TID %p\n", Thread->Cid.UniqueThread);
        return STATUS_NO_MEMORY;
    }

    TRACE_CH(UserThread,"Create pti 0x%p eThread 0x%p\n", ptiCurrent, Thread);

    RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));

    /* Initialize the THREADINFO */

    PsSetThreadWin32Thread(Thread, ptiCurrent, NULL);
    IntReferenceThreadInfo(ptiCurrent);
    ptiCurrent->pEThread = Thread;
    ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
    pTeb->Win32ThreadInfo = ptiCurrent;
    ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;

    TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);

    InitializeListHead(&ptiCurrent->WindowListHead);
    InitializeListHead(&ptiCurrent->W32CallbackListHead);
    InitializeListHead(&ptiCurrent->PostedMessagesListHead);
    InitializeListHead(&ptiCurrent->SentMessagesListHead);
    InitializeListHead(&ptiCurrent->DispatchingMessagesHead);
    InitializeListHead(&ptiCurrent->LocalDispatchingMessagesHead);
    InitializeListHead(&ptiCurrent->PtiLink);
    for (i = 0; i < NB_HOOKS; i++)
    {
        InitializeListHead(&ptiCurrent->aphkStart[i]);
    }
    ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
    ptiCurrent->ppi->ptiList = ptiCurrent;
    ptiCurrent->ppi->cThreads++;

    ptiCurrent->hEventQueueClient = NULL;
    Status = ZwCreateEvent(&ptiCurrent->hEventQueueClient, EVENT_ALL_ACCESS,
                           NULL, SynchronizationEvent, FALSE);
    if (!NT_SUCCESS(Status))
    {
        goto error;
    }
    Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
                                       *ExEventObjectType, KernelMode,
                                       (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
    if (!NT_SUCCESS(Status))
    {
        ZwClose(ptiCurrent->hEventQueueClient);
        ptiCurrent->hEventQueueClient = NULL;
        goto error;
    }

    KeQueryTickCount(&LargeTickCount);
    ptiCurrent->timeLast = LargeTickCount.u.LowPart;

    ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
    if(ptiCurrent->MessageQueue == NULL)
    {
        ERR_CH(UserThread,"Failed to allocate message loop\n");
        Status = STATUS_NO_MEMORY;
        goto error;
    }
    ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
    if (ptiCurrent->KeyboardLayout)
        UserReferenceObject(ptiCurrent->KeyboardLayout);
    ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
    if (Process == gpepCSRSS) /* If this thread is owned by CSRSS, mark it as such */
        ptiCurrent->TIF_flags |= TIF_CSRSSTHREAD;
    ptiCurrent->pcti = &ptiCurrent->cti;

    /* Initialize the CLIENTINFO */
    pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
    RtlZeroMemory(pci, sizeof(CLIENTINFO));
    pci->ppi = ptiCurrent->ppi;
    pci->fsHooks = ptiCurrent->fsHooks;
    pci->dwTIFlags = ptiCurrent->TIF_flags;
    if (ptiCurrent->KeyboardLayout)
    {
        pci->hKL = ptiCurrent->KeyboardLayout->hkl;
        pci->CodePage = ptiCurrent->KeyboardLayout->CodePage;
    }

    /* Assign a default window station and desktop to the process */
    /* Do not try to open a desktop or window station before winlogon initializes */
    if(ptiCurrent->ppi->hdeskStartup == NULL && LogonProcess != NULL)
    {
        HWINSTA hWinSta = NULL;
        HDESK hDesk = NULL;
        UNICODE_STRING DesktopPath;
        PDESKTOP pdesk;
        PRTL_USER_PROCESS_PARAMETERS ProcessParams;

        /*
         * inherit the thread desktop and process window station (if not yet inherited) from the process startup
         * info structure. See documentation of CreateProcess()
         */
        ProcessParams = pTeb->ProcessEnvironmentBlock->ProcessParameters;

        Status = STATUS_UNSUCCESSFUL;
        if(ProcessParams && ProcessParams->DesktopInfo.Length > 0)
        {
            Status = IntSafeCopyUnicodeStringTerminateNULL(&DesktopPath, &ProcessParams->DesktopInfo);
        }
        if(!NT_SUCCESS(Status))
        {
            RtlInitUnicodeString(&DesktopPath, NULL);
        }

        Status = IntParseDesktopPath(Process,
                                     &DesktopPath,
                                     &hWinSta,
                                     &hDesk);

        if (DesktopPath.Buffer)
            ExFreePoolWithTag(DesktopPath.Buffer, TAG_STRING);

        if(!NT_SUCCESS(Status))
        {
            ERR_CH(UserThread, "Failed to assign default dekstop and winsta to process\n");
            goto error;
        }

        if(!UserSetProcessWindowStation(hWinSta))
        {
            Status = STATUS_UNSUCCESSFUL;
            ERR_CH(UserThread,"Failed to set initial process winsta\n");
            goto error;
        }

        /* Validate the new desktop. */
        Status = IntValidateDesktopHandle(hDesk, UserMode, 0, &pdesk);
        if(!NT_SUCCESS(Status))
        {
            ERR_CH(UserThread,"Failed to validate initial desktop handle\n");
            goto error;
        }

        /* Store the parsed desktop as the initial desktop */
        ptiCurrent->ppi->hdeskStartup = hDesk;
        ptiCurrent->ppi->rpdeskStartup = pdesk;
    }

    if (ptiCurrent->ppi->hdeskStartup != NULL)
    {
        if (!IntSetThreadDesktop(ptiCurrent->ppi->hdeskStartup, FALSE))
        {
            ERR_CH(UserThread,"Failed to set thread desktop\n");
            Status = STATUS_UNSUCCESSFUL;
            goto error;
        }
    }

    /* mark the thread as fully initialized */
    ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED;

    if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) &&
            (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi ))
    {
        ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
    }
    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
    TRACE_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent);
    return STATUS_SUCCESS;

error:
    ERR_CH(UserThread,"UserCreateThreadInfo failed! Freeing pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
    UserDestroyThreadInfo(Thread);
    return Status;
}