replace nob with ms' build, move disk creation to build.bat, major comment cleanup, remove old and stupid tests, overhaul interrupt management with per-CPU vector allocation, affinity migration and safe teardown, add proper IOAPIC routing and PCI MSI/MSI-X/INTx support, migrate drivers to the new interrupt API, integrate ACPICA with a proper OS services layer, move ACPI firmware events, power button handling and S5 shutdown into acpi.sys, add parallel driver startup and atomic publication, replace PnP arrays with dynamic lists, redesign service startup again to be asynchronous, add delayed startup mode for services, allow omitting keys in services.ini, fix acpi ec deferred work handling, fix kernel threads having garbage exit code.

This commit is contained in:
maksw committed 2026-10-28 15:18:43 +01:00
1 parent d36f19509c
commit 36eef8f58d
696 files changed
+147281 -7530

No files matched your search

+467
View File
@@ -0,0 +1,467 @@
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: buildscr.cpp
//
// Contents: Implementation of the code which talks to the MTScript engine
// when doing a distributed build using the build console.
//
//----------------------------------------------------------------------------
#include "scrproc.h"
#include "build.h"
#include "buildscr.h"
#define INITGUID
#include <guiddef.h>
DEFINE_GUID(CLSID_LocalScriptedProcess, 0x854c316f,0xc854,0x4a77,0xb1,0x89,0x60,0x68,0x59,0xe4,0x39,0x1b);
DEFINE_GUID(IID_IScriptedProcess, 0x854c3171,0xc854,0x4a77,0xb1,0x89,0x60,0x68,0x59,0xe4,0x39,0x1b);
DEFINE_GUID(IID_IScriptedProcessSink, 0x854c3172,0xc854,0x4a77,0xb1,0x89,0x60,0x68,0x59,0xe4,0x39,0x1b);
DEFINE_GUID(CLSID_ObjectDaemon,0x854c3184,0xc854,0x4a77,0xb1,0x89,0x60,0x68,0x59,0xE4,0x39,0x1b);
DEFINE_GUID(IID_IConnectedMachine,0x854c316c,0xc854,0x4a77,0xb1,0x89,0x60,0x68,0x59,0xe4,0x39,0x1b);
DEFINE_GUID(IID_IObjectDaemon,0x854c3183,0xc854,0x4a77,0xb1,0x89,0x60,0x68,0x59,0xE4,0x39,0x1b);
#define MAX_RETRIES 2
HANDLE g_hMTEvent = NULL;
HANDLE g_hMTThread = NULL;
DWORD g_dwMTThreadId = 0;
//+---------------------------------------------------------------------------
//
// Function: WaitForResume
//
// Synopsis: Sends a "phase complete" message to the script engine and then
// waits for it to tell us to resume (if specified).
//
// Arguments: [fPause] -- If TRUE, we wait for a resume command
// [pe] -- Message to send to the script engine
//
//----------------------------------------------------------------------------
void
WaitForResume(BOOL fPause, PROC_EVENTS pe)
{
if (g_hMTEvent)
{
HANDLE aHandles[2] = { g_hMTEvent, g_hMTThread };
ResetEvent(g_hMTEvent);
PostThreadMessage(g_dwMTThreadId, pe, 0, 0);
if (fPause)
{
// Wait until either the event object is signaled or the thread dies
WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);
}
}
}
//+---------------------------------------------------------------------------
//
// Function: ExitMTScriptThread
//
// Synopsis: Tells the thread talking to the MTScript engine to exit.
//
//----------------------------------------------------------------------------
void
ExitMTScriptThread()
{
if (g_hMTEvent)
{
PostThreadMessage(g_dwMTThreadId, PE_EXIT, 0, 0);
WaitForSingleObject(g_hMTThread, INFINITE);
CloseHandle(g_hMTThread);
CloseHandle(g_hMTEvent);
}
}
//+---------------------------------------------------------------------------
//
// Function: SendStatus
//
// Synopsis: Sends a status message to the MTScript engine with the
// current number of errors, warnings, and completed files.
//
// Arguments: [pSP] -- Pointer to MTScript engine interface
//
//----------------------------------------------------------------------------
void
SendStatus(IScriptedProcess *pSP)
{
wchar_t achBuf[300];
long lRet;
static ULONG cErrorsPrev = MAXDWORD;
static ULONG cWarnPrev = MAXDWORD;
static ULONG cFilesPrev = MAXDWORD;
ULONG cErrors = NumberCompileErrors + NumberLibraryErrors + NumberLinkErrors + NumberBinplaceErrors;
ULONG cWarn = NumberCompileWarnings + NumberLibraryWarnings + NumberLinkWarnings + NumberBinplaceWarnings;
ULONG cFiles = NumberCompiles + NumberLibraries + NumberLinks /* + NumberBinplaces */;
// Only send status if it's changed since last time we did it.
if ( cErrors != cErrorsPrev
|| cWarn != cWarnPrev
|| cFiles != cFilesPrev)
{
cErrorsPrev = cErrors;
cWarnPrev = cWarn;
cFilesPrev = cFiles;
wsprintfW(achBuf, L"errors=%d,warnings=%d,files=%d", cErrors, cWarn, cFiles);
pSP->SendData(L"status", achBuf, &lRet);
}
}
//+---------------------------------------------------------------------------
//
// Function: HandleMessage
//
// Synopsis: Handles a message that has come across our message queue.
//
// Arguments: [pmsg] -- Message
// [pSP] -- Pointer to MTScript engine interface
//
//----------------------------------------------------------------------------
BOOL
HandleMessage(MSG *pmsg, IScriptedProcess *pSP)
{
long lRet;
HRESULT hr = S_OK;
switch (pmsg->message)
{
case PE_PASS0_COMPLETE:
SendStatus(pSP);
hr = pSP->SendData(L"pass 0 complete", L"", &lRet);
break;
case PE_PASS1_COMPLETE:
SendStatus(pSP);
hr = pSP->SendData(L"pass 1 complete", L"", &lRet);
break;
case PE_PASS2_COMPLETE:
SendStatus(pSP);
hr = pSP->SendData(L"pass 2 complete", L"", &lRet);
break;
case PE_EXIT:
SendStatus(pSP);
hr = pSP->SendData(L"build complete", L"", &lRet);
return TRUE;
break;
}
if (hr)
{
BuildErrorRaw("\nBUILD: Communication with script engine failed: %x", hr);
}
return (hr) ? TRUE : FALSE;
}
const DWORD UPDATE_INTERVAL = 2 * 1000; // Update every 2 seconds
//+---------------------------------------------------------------------------
//
// Function: MTScriptThread
//
// Synopsis: Thread entrypoint. Initializes and then sits around
// handling various events.
//
// Arguments: [pv] -- Not used.
//
//----------------------------------------------------------------------------
DWORD WINAPI
MTScriptThread(LPVOID pv)
{
HRESULT hr;
IScriptedProcess * pSP = NULL;
wchar_t achBuf[100];
MSG msg;
DWORD dwRet;
CProcessSink cps;
BOOL fExit = FALSE;
int cRetries = 0;
BuildMsg("Establishing connection with Script engine...\n");
LogMsg("Establishing connection with Script engine...\n");
// Force Windows to create a message queue for this thread, since we will
// be communicated to via PostThreadMessage.
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
// If anything fails we just quit this thread and communication with
// the MTScript engine won't happen.
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
if (hr)
{
BuildErrorRaw("BUILD: CoInitializeEx failed with %x\n", hr);
goto Cleanup;
}
hr = S_FALSE;
while (hr)
{
pSP = NULL;
IObjectDaemon *pIObjectDaemon;
hr = CoCreateInstance(CLSID_ObjectDaemon, NULL, CLSCTX_SERVER,
IID_IObjectDaemon, (LPVOID*)&pIObjectDaemon);
if (!hr)
{
IDispatch *pIDispatch;
BSTR bstrProgID = SysAllocString(L"MTScript.Remote");
BSTR bstrIdentity = SysAllocString(_wgetenv(L"__MTSCRIPT_ENV_IDENTITY"));
hr = pIObjectDaemon->OpenInterface(bstrIdentity, bstrProgID, (BOOL)FALSE, (IDispatch**)&pIDispatch);
if (!hr)
{
IConnectedMachine *pIConnectedMachine;
hr = pIDispatch->QueryInterface(IID_IConnectedMachine, (LPVOID*)&pIConnectedMachine);
if (!hr)
{
hr = pIConnectedMachine->CreateIScriptedProcess(GetCurrentProcessId(), (wchar_t *)_wgetenv(L"__MTSCRIPT_ENV_ID"), (IScriptedProcess **)&pSP);
pIConnectedMachine->Release();
}
else
{
BuildMsg("CreateIScriptedProcess failed with %x.\n", hr);
LogMsg("CreateIScriptedProcess failed with %x.\n", hr);
}
pIDispatch->Release();
}
else
{
BuildMsg("OpenInterface failed with %x.\n", hr);
LogMsg("OpenInterface failed with %x.\n", hr);
}
SysFreeString(bstrProgID);
SysFreeString(bstrIdentity);
pIObjectDaemon->Release();
}
else
{
BuildMsg("CoCreateInstance failed with %x.\n", hr);
LogMsg("CoCreateInstance failed with %x.\n", hr);
}
if (!hr)
{
hr = pSP->SetProcessSink(&cps);
if (hr)
{
BuildMsg("SetProcessSink failed with %x.\n", hr);
LogMsg("SetProcessSink failed with %x.\n", hr);
}
}
if (hr)
{
if (cRetries >= MAX_RETRIES)
{
BuildErrorRaw("BUILD: FATAL: Connection to script engine could not be established. (%x)\n", hr);
goto Cleanup;
}
if (pSP)
{
pSP->Release();
pSP = NULL;
}
BuildMsg("Connection to script engine failed with %x, retries=%d...\n", hr, cRetries);
LogMsg("Connection to script engine failed with %x, retries=%d...\n", hr, cRetries);
Sleep(500);
cRetries++;
}
}
BuildMsg("Connection to script engine established...\n");
LogMsg("Connection to script engine established...\r\n");
// Tell build.c that it can continue
SetEvent(g_hMTEvent);
while (TRUE)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (HandleMessage(&msg, pSP))
{
fExit = TRUE;
}
}
if (fExit)
{
break;
}
dwRet = MsgWaitForMultipleObjects(0,
NULL,
FALSE,
UPDATE_INTERVAL,
QS_ALLINPUT);
if (dwRet == WAIT_OBJECT_0)
{
// A message is coming through on our message queue. Just loop
// around.
}
else if (dwRet == WAIT_TIMEOUT)
{
SendStatus(pSP);
}
else
{
// MWFMO failed. Just bail out.
break;
}
}
Cleanup:
if (pSP)
{
pSP->SetProcessSink(NULL);
pSP->Release();
}
CoUninitialize();
if (hr)
{
g_hMTThread = NULL;
}
SetEvent(g_hMTEvent);
return 0;
}
// ***********************************************************************
//
// CProcessSink implementation
//
// We hand this class to the MTScript engine so it can communicate back
// to us.
//
// ***********************************************************************
CProcessSink::CProcessSink()
{
_ulRefs = 1;
}
HRESULT
CProcessSink::QueryInterface(REFIID riid, LPVOID *ppv)
{
if (riid == IID_IUnknown || riid == IID_IScriptedProcessSink)
{
*ppv = (IScriptedProcessSink*)this;
}
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
((IUnknown *)*ppv)->AddRef();
return S_OK;
}
ULONG
CProcessSink::AddRef()
{
return InterlockedIncrement((long*)&_ulRefs);
}
ULONG
CProcessSink::Release()
{
if (InterlockedDecrement((long*)&_ulRefs) == 0)
{
_ulRefs = 0xFF;
delete this;
return 0;
}
return _ulRefs;
}
//+---------------------------------------------------------------------------
//
// Member: CProcessSink::RequestExit, public
//
// Synopsis: Called when the MTScript engine wants us to quit. If we don't,
// it will terminate us.
//
//----------------------------------------------------------------------------
HRESULT
CProcessSink::RequestExit()
{
// There is no easy way to tell build.exe to abort. We'll just let
// MTScript terminate us.
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CProcessSink::ReceiveData, public
//
// Synopsis: Called when the MTScript engine wants to send us a message.
//
// Arguments: [pszType] -- String giving the message
// [pszData] -- String giving data associated with the message.
// [plReturn] -- A place we can return a value back.
//
//----------------------------------------------------------------------------
HRESULT
CProcessSink::ReceiveData(wchar_t *pszType, wchar_t *pszData, long *plReturn)
{
*plReturn = 0;
if (wcscmp(pszType, L"resume") == 0)
{
SetEvent(g_hMTEvent);
}
else
{
*plReturn = -1; // Signals an error
}
return S_OK;
}