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:
1 parent
d36f19509c
commit
36eef8f58d
696 files changed
+147281
-7530
No files matched your search
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user