[NTOSKRNL]: Add and fix more glue code for EMS/Headless support. The SAC driver is at least correctly able to initialize now when /redirect is enabled.

[SACMSG]: SAC wants the message tables as Unicode, but the CMakeList has an obscure comment that Unicode MC needs "testing". Well, I'll be the first to test it and confirm it works -- implement a UNICODE_SOURCE_REALLY to get Unicode-mc.
[SACMSG]: Add a few more constants.
[SACDRV]: Implement InitializeMachineInformation.
[SACDRV]: Fix countless bugs. Now the entire driver initializes up to UTF8EncodeAndSend, which is unimplemented. We're almost there!

svn path=/trunk/; revision=59718
This commit is contained in:
Alex Ionescu 2013-08-13 03:18:03 +00:00
parent 1f8570be62
commit 7e5cd96267
8 changed files with 777 additions and 331 deletions

View file

@ -77,6 +77,8 @@ CreateDeviceSecurityDescriptor(IN PDEVICE_OBJECT *DeviceObject)
else else
{ {
SAC_DBG(SAC_DBG_INIT, "SAC CreateDeviceSecurityDescriptor : Unable to create Raw ACL, error : %x\n", Status); SAC_DBG(SAC_DBG_INIT, "SAC CreateDeviceSecurityDescriptor : Unable to create Raw ACL, error : %x\n", Status);
/* FIXME: Temporary hack */
Status = STATUS_SUCCESS;
goto CleanupPath; goto CleanupPath;
} }
@ -377,7 +379,7 @@ InitializeGlobalData(IN PUNICODE_STRING RegistryPath,
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");
/* If we already did this, bail out */ /* If we already did this, bail out */
if (!GlobalDataInitialized) goto SuccessExit; if (GlobalDataInitialized) goto SuccessExit;
/* Setup the symbolic link for Win32 support */ /* Setup the symbolic link for Win32 support */
RtlInitUnicodeString(&LinkName, L"\\DosDevices\\SAC"); RtlInitUnicodeString(&LinkName, L"\\DosDevices\\SAC");

View file

@ -93,6 +93,11 @@ MyAllocatePool(IN SIZE_T PoolSize,
IN PCHAR File, IN PCHAR File,
IN ULONG Line) IN ULONG Line)
{ {
PVOID p;
p = ExAllocatePoolWithTag(NonPagedPool, PoolSize, Tag);
SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", p);
return p;
#if 0
KIRQL OldIrql; KIRQL OldIrql;
PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor; PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor;
PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor; PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
@ -102,7 +107,7 @@ MyAllocatePool(IN SIZE_T PoolSize,
SAC_DBG(SAC_DBG_MM, "Entering.\n"); SAC_DBG(SAC_DBG_MM, "Entering.\n");
/* Acquire the memory allocation lock and align the size request */ /* Acquire the memory allocation lock and align the size request */
KeAcquireSpinLock(&MemoryLock, &OldIrql);; KeAcquireSpinLock(&MemoryLock, &OldIrql);
PoolSize = ALIGN_UP(PoolSize, ULONGLONG); PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
#if _USE_SAC_HEAP_ALLOCATOR_ #if _USE_SAC_HEAP_ALLOCATOR_
@ -220,12 +225,14 @@ MyAllocatePool(IN SIZE_T PoolSize,
Buffer = LocalDescriptor + 1; Buffer = LocalDescriptor + 1;
RtlZeroMemory(Buffer, PoolSize); RtlZeroMemory(Buffer, PoolSize);
return Buffer; return Buffer;
#endif
} }
VOID VOID
NTAPI NTAPI
MyFreePool(IN PVOID *Block) MyFreePool(IN PVOID *Block)
{ {
#if 0
PSAC_MEMORY_ENTRY NextDescriptor; PSAC_MEMORY_ENTRY NextDescriptor;
PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor; PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor;
PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY)); PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY));
@ -323,10 +330,10 @@ MyFreePool(IN PVOID *Block)
LocalSize = GlobalSize = 0; LocalSize = GlobalSize = 0;
ThisDescriptor = (PVOID)LocalSize; ThisDescriptor = (PVOID)LocalSize;
NextDescriptor = (PVOID)GlobalSize; NextDescriptor = (PVOID)GlobalSize;
GlobalDescriptor = (PVOID) ThisDescriptor; GlobalDescriptor = (PVOID)ThisDescriptor;
FoundDescriptor = (PVOID)GlobalDescriptor; FoundDescriptor = (PVOID)GlobalDescriptor;
GlobalDescriptor = (PVOID) NextDescriptor; GlobalDescriptor = (PVOID)NextDescriptor;
NextDescriptor = (PVOID) FoundDescriptor; NextDescriptor = (PVOID)FoundDescriptor;
/* Use the NT pool allocator*/ /* Use the NT pool allocator*/
ExFreePool(LocalDescriptor); ExFreePool(LocalDescriptor);
@ -334,6 +341,8 @@ MyFreePool(IN PVOID *Block)
/* Release the lock, delete the address, and return */ /* Release the lock, delete the address, and return */
KeReleaseSpinLock(&MemoryLock, OldIrql); KeReleaseSpinLock(&MemoryLock, OldIrql);
#endif
ExFreePool(*Block);
*Block = NULL; *Block = NULL;
SAC_DBG(SAC_DBG_MM, "exiting.\n"); SAC_DBG(SAC_DBG_MM, "exiting.\n");
} }

View file

@ -35,6 +35,7 @@
#define SAC_DBG_UTIL 0x02 #define SAC_DBG_UTIL 0x02
#define SAC_DBG_INIT 0x04 #define SAC_DBG_INIT 0x04
#define SAC_DBG_MM 0x1000 #define SAC_DBG_MM 0x1000
#define SAC_DBG_MACHINE 0x2000
#define SAC_DBG(x, ...) \ #define SAC_DBG(x, ...) \
if (SACDebug & x) \ if (SACDebug & x) \
{ \ { \

View file

@ -13,7 +13,7 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
PCHAR Utf8ConversionBuffer; PCHAR Utf8ConversionBuffer;
ULONG Utf8ConversionBufferSize; ULONG Utf8ConversionBufferSize = PAGE_SIZE;
PSAC_MACHINE_INFO MachineInformation; PSAC_MACHINE_INFO MachineInformation;
PVOID RequestSacCmdEventObjectBody; PVOID RequestSacCmdEventObjectBody;
PKEVENT RequestSacCmdEventWaitObjectBody; PKEVENT RequestSacCmdEventWaitObjectBody;
@ -122,7 +122,7 @@ NTSTATUS
NTAPI NTAPI
PreloadGlobalMessageTable(IN PVOID ImageBase) PreloadGlobalMessageTable(IN PVOID ImageBase)
{ {
NTSTATUS Status; NTSTATUS Status, Status2;
ULONG MessageId, TotalLength, TextSize, i; ULONG MessageId, TotalLength, TextSize, i;
PWCHAR StringBuffer; PWCHAR StringBuffer;
PMESSAGE_RESOURCE_ENTRY MessageEntry; PMESSAGE_RESOURCE_ENTRY MessageEntry;
@ -130,6 +130,7 @@ PreloadGlobalMessageTable(IN PVOID ImageBase)
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC PreloadGlobalMessageTable: Entering.\n"); SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC PreloadGlobalMessageTable: Entering.\n");
/* Nothing to do if we already have a table */ /* Nothing to do if we already have a table */
Status = STATUS_SUCCESS;
if (GlobalMessageTable) goto Exit; if (GlobalMessageTable) goto Exit;
/* Loop through up to 200 messages */ /* Loop through up to 200 messages */
@ -137,12 +138,12 @@ PreloadGlobalMessageTable(IN PVOID ImageBase)
for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) for (MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++)
{ {
/* Find this message ID in the string table*/ /* Find this message ID in the string table*/
Status = RtlFindMessage(ImageBase, Status2 = RtlFindMessage(ImageBase,
11, 11,
LANG_NEUTRAL, LANG_NEUTRAL,
MessageId, MessageId,
&MessageEntry); &MessageEntry);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status2))
{ {
/* Make sure it's Unicode */ /* Make sure it's Unicode */
ASSERT(MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE); ASSERT(MessageEntry->Flags & MESSAGE_RESOURCE_UNICODE);
@ -182,12 +183,12 @@ PreloadGlobalMessageTable(IN PVOID ImageBase)
for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++) for (i = 0, MessageId = 1; MessageId != SAC_MAX_MESSAGES; MessageId++)
{ {
/* Make sure the message is still there...! */ /* Make sure the message is still there...! */
Status = RtlFindMessage(ImageBase, Status2 = RtlFindMessage(ImageBase,
11, 11,
LANG_NEUTRAL, LANG_NEUTRAL,
MessageId, MessageId,
&MessageEntry); &MessageEntry);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status2))
{ {
/* Write the entry in the message table*/ /* Write the entry in the message table*/
GlobalMessageTable[i].Index = MessageId; GlobalMessageTable[i].Index = MessageId;
@ -202,7 +203,7 @@ PreloadGlobalMessageTable(IN PVOID ImageBase)
ASSERT((ULONG)(wcslen(StringBuffer)*sizeof(WCHAR)) <= TextSize); ASSERT((ULONG)(wcslen(StringBuffer)*sizeof(WCHAR)) <= TextSize);
/* Move to the next buffer space */ /* Move to the next buffer space */
StringBuffer += TextSize; StringBuffer += (TextSize / sizeof(WCHAR));
/* Move to the next entry, make sure the status is full success */ /* Move to the next entry, make sure the status is full success */
i++; i++;
@ -229,135 +230,6 @@ TearDownGlobalMessageTable(VOID)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS
NTAPI
TranslateMachineInformationXML(IN PWCHAR *Buffer,
IN PWCHAR ExtraData)
{
NTSTATUS Status;
ULONG Size;
PWCHAR p;
CHECK_PARAMETER1(Buffer);
Status = STATUS_SUCCESS;
Size = wcslen(L"<machine-info>\r\n");
if (MachineInformation->MachineName)
{
Size += wcslen(MachineInformation->MachineName);
Size += wcslen(L"<name>%s</name>\r\n");
}
if (MachineInformation->MachineGuid)
{
Size += wcslen(MachineInformation->MachineGuid);
Size += wcslen(L"<guid>%s</guid>\r\n");
}
if (MachineInformation->ProcessorArchitecture)
{
Size += wcslen(MachineInformation->ProcessorArchitecture);
Size += wcslen(L"<processor-architecture>%s</processor-architecture>\r\n");
}
if (MachineInformation->MajorVersion)
{
Size += wcslen(MachineInformation->MajorVersion);
Size += wcslen(L"<os-version>%s</os-version>\r\n");
}
if (MachineInformation->BuildNumber)
{
Size += wcslen(MachineInformation->BuildNumber);
Size += wcslen(L"<os-build-number>%s</os-build-number>\r\n");
}
if (MachineInformation->ProductType)
{
Size += wcslen(MachineInformation->ProductType);
Size += wcslen(L"<os-product>%s</os-product>\r\n");
}
if (MachineInformation->ServicePack)
{
Size += wcslen(MachineInformation->ServicePack);
Size += wcslen(L"<os-service-pack>%s</os-service-pack>\r\n");
}
if (ExtraData) Size += wcslen(ExtraData);
Size += wcslen(L"</machine-info>\r\n");
p = (PWCHAR)SacAllocatePool((Size + sizeof(ANSI_NULL)) * sizeof(WCHAR), GLOBAL_BLOCK_TAG);
*Buffer = p;
if (!p) return STATUS_NO_MEMORY;
Size = wcslen(L"<machine-info>\r\n");
wcscpy(p, L"<machine-info>\r\n");
p += Size;
if (MachineInformation->MachineName)
{
p += swprintf(p, L"<name>%s</name>\r\n", MachineInformation->MachineName);
}
if (MachineInformation->MachineGuid)
{
p += swprintf(p, L"<guid>%s</guid>\r\n", MachineInformation->MachineGuid);
}
if (MachineInformation->ProcessorArchitecture)
{
p += swprintf(p, L"<processor-architecture>%s</processor-architecture>\r\n", MachineInformation->ProcessorArchitecture);
}
if (MachineInformation->MajorVersion)
{
p += swprintf(p, L"<os-version>%s</os-version>\r\n", MachineInformation->MajorVersion);
}
if (MachineInformation->BuildNumber)
{
p += swprintf(p, L"<os-build-number>%s</os-build-number>\r\n", MachineInformation->BuildNumber);
}
if (MachineInformation->ProductType)
{
p += swprintf(p, L"<os-product>%s</os-product>\r\n", MachineInformation->ProductType);
}
if (MachineInformation->ServicePack)
{
p += swprintf(p, L"<os-service-pack>%s</os-service-pack>\r\n", MachineInformation->ServicePack);
}
if (ExtraData)
{
Size = wcslen(ExtraData);
wcscpy(p, ExtraData);
p += Size;
}
wcscpy(p, L"</machine-info>\r\n");
ASSERT((((ULONG) wcslen(*Buffer) + 1) * sizeof(WCHAR)) <= Size);
return Status;
}
VOID
NTAPI
InitializeMachineInformation(VOID)
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Entering.\n");
/* FIXME: TODO */
MachineInformation = NULL;
ASSERT(FALSE);
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n");
}
NTSTATUS NTSTATUS
NTAPI NTAPI
GetRegistryValueBuffer(IN PCWSTR KeyName, GetRegistryValueBuffer(IN PCWSTR KeyName,
@ -479,7 +351,7 @@ SetRegistryValue(IN PCWSTR KeyName,
NTSTATUS NTSTATUS
NTAPI NTAPI
CopyRegistryValueData(IN PULONG* Buffer, CopyRegistryValueData(IN PVOID* Buffer,
IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo) IN PKEY_VALUE_PARTIAL_INFORMATION PartialInfo)
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
@ -504,6 +376,446 @@ CopyRegistryValueData(IN PULONG* Buffer,
return Status; return Status;
} }
NTSTATUS
NTAPI
TranslateMachineInformationXML(IN PWCHAR *Buffer,
IN PWCHAR ExtraData)
{
NTSTATUS Status;
ULONG Size;
PWCHAR p;
CHECK_PARAMETER1(Buffer);
/* Start by believing the world is beautiful */
Status = STATUS_SUCCESS;
/* First, the header */
Size = wcslen(L"<machine-info>\r\n");
/* Do we have a machine name? */
if (MachineInformation->MachineName)
{
/* Go and add it in */
Size += wcslen(MachineInformation->MachineName);
Size += wcslen(L"<name>%s</name>\r\n");
}
/* Do we have a GUID? */
if (MachineInformation->MachineGuid)
{
/* Go and add it in */
Size += wcslen(MachineInformation->MachineGuid);
Size += wcslen(L"<guid>%s</guid>\r\n");
}
/* Do we know the processor? */
if (MachineInformation->ProcessorArchitecture)
{
/* Go and add it in */
Size += wcslen(MachineInformation->ProcessorArchitecture);
Size += wcslen(L"<processor-architecture>%s</processor-architecture>\r\n");
}
/* Do we have the version? */
if (MachineInformation->MajorVersion)
{
/* Go and add it in */
Size += wcslen(MachineInformation->MajorVersion);
Size += wcslen(L"<os-version>%s</os-version>\r\n");
}
/* Do we have the build? */
if (MachineInformation->BuildNumber)
{
/* Go and add it in */
Size += wcslen(MachineInformation->BuildNumber);
Size += wcslen(L"<os-build-number>%s</os-build-number>\r\n");
}
/* Do we have the product type? */
if (MachineInformation->ProductType)
{
/* Go and add it in */
Size += wcslen(MachineInformation->ProductType);
Size += wcslen(L"<os-product>%s</os-product>\r\n");
}
/* Do we have a service pack? */
if (MachineInformation->ServicePack)
{
/* Go and add it in */
Size += wcslen(MachineInformation->ServicePack);
Size += wcslen(L"<os-service-pack>%s</os-service-pack>\r\n");
}
/* Anything else we need to know? Add it in too */
if (ExtraData) Size += wcslen(ExtraData);
/* Finally, add the footer */
Size += wcslen(L"</machine-info>\r\n");
/* Convert to bytes and add a NULL */
Size += sizeof(ANSI_NULL);
Size *= sizeof(WCHAR);
/* Allocate space for the buffer */
p = SacAllocatePool(Size, GLOBAL_BLOCK_TAG);
*Buffer = p;
if (!p) return STATUS_NO_MEMORY;
wcscpy(p, L"<machine-info>\r\n");
p += wcslen(L"<machine-info>\r\n");;
if (MachineInformation->MachineName)
{
p += swprintf(p,
L"<name>%s</name>\r\n",
MachineInformation->MachineName);
}
if (MachineInformation->MachineGuid)
{
p += swprintf(p,
L"<guid>%s</guid>\r\n",
MachineInformation->MachineGuid);
}
if (MachineInformation->ProcessorArchitecture)
{
p += swprintf(p,
L"<processor-architecture>%s</processor-architecture>\r\n",
MachineInformation->ProcessorArchitecture);
}
if (MachineInformation->MajorVersion)
{
p += swprintf(p,
L"<os-version>%s</os-version>\r\n",
MachineInformation->MajorVersion);
}
if (MachineInformation->BuildNumber)
{
p += swprintf(p,
L"<os-build-number>%s</os-build-number>\r\n",
MachineInformation->BuildNumber);
}
if (MachineInformation->ProductType)
{
p += swprintf(p,
L"<os-product>%s</os-product>\r\n",
MachineInformation->ProductType);
}
if (MachineInformation->ServicePack)
{
p += swprintf(p,
L"<os-service-pack>%s</os-service-pack>\r\n",
MachineInformation->ServicePack);
}
if (ExtraData)
{
wcscpy(p, ExtraData);
p += wcslen(ExtraData);
}
wcscpy(p, L"</machine-info>\r\n");
SAC_DBG(SAC_DBG_ENTRY_EXIT, "MachineInformation: %S\n", *Buffer);
ASSERT((((ULONG)wcslen(*Buffer) + 1) * sizeof(WCHAR)) <= Size);
return Status;
}
VOID
NTAPI
InitializeMachineInformation(VOID)
{
NTSTATUS Status;
PWCHAR GuidString, MajorVersion, ServicePack, BuildNumber, MessageBuffer;
PWCHAR ProductType;
ULONG SuiteTypeMessage;
BOOLEAN SetupInProgress = FALSE;
GUID SystemGuid;
ULONG RealSize, Size, OutputSize;
PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
RTL_OSVERSIONINFOEXW VersionInformation;
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Entering.\n");
/* Don't do anything if we already quried this */
if (MachineInformation)
{
SAC_DBG(SAC_DBG_MACHINE, "SAC Initialize Machine Information:: MachineInformationBuffer already initialzied.\n");
return;
}
/* Allocate the machine information */
MachineInformation = SacAllocatePool(sizeof(*MachineInformation),
GLOBAL_BLOCK_TAG);
if (!MachineInformation)
{
goto Fail;
}
/* Zero it out for now */
RtlZeroMemory(MachineInformation, sizeof(*MachineInformation));
/* Query OS version */
RtlZeroMemory(&VersionInformation, sizeof(VersionInformation));
VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation);
Status = RtlGetVersion((PRTL_OSVERSIONINFOW)&VersionInformation);
if (!NT_SUCCESS(Status))
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (2).\n");
goto Fail;
}
/* Check if setup is in progress */
Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\Setup",
L"SystemSetupInProgress",
&PartialInfo);
if (NT_SUCCESS(Status))
{
/* The key is there, is the value set? */
if (*(PULONG)PartialInfo->Data) SetupInProgress = TRUE;
SacFreePool(PartialInfo);
if (SetupInProgress)
{
/* Yes, so we'll use a special hostname to identify this */
MessageBuffer = GetMessage(SAC_UNINITIALIZED_MSG);
Size = wcslen(MessageBuffer);
ASSERT(Size > 0);
RealSize = Size * sizeof(WCHAR) + sizeof(UNICODE_NULL);
/* Make room for it and copy it in there */
MachineInformation->MachineName = SacAllocatePool(RealSize,
GLOBAL_BLOCK_TAG);
if (MachineInformation->MachineName)
{
wcscpy(MachineInformation->MachineName, MessageBuffer);
}
}
}
/* If we are not in setup mode, or if we failed to check... */
if (!SetupInProgress)
{
/* Query the computer name */
Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\"
L"CurrentControlSet\\Control\\"
L"ComputerName\\ComputerName",
L"ComputerName",
&PartialInfo);
if (!NT_SUCCESS(Status))
{
/* It's not critical, but we won't have it */
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Failed to get machine name.\n");
}
else
{
/* We have the name, copy it from the registry */
Status = CopyRegistryValueData((PVOID*)&MachineInformation->
MachineName,
PartialInfo);
SacFreePool(PartialInfo);
if (!NT_SUCCESS(Status))
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (20).\n");
goto Fail;
}
}
}
/* Next step, try to get the machine GUID */
RtlZeroMemory(&SystemGuid, sizeof(SystemGuid));
OutputSize = sizeof(SystemGuid);
Status = HeadlessDispatch(HeadlessCmdQueryGUID,
NULL,
0,
&SystemGuid,
&OutputSize);
if (!NT_SUCCESS(Status))
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Failed to get Machine GUID.\n");
}
else
{
/* We have it -- make room for it */
GuidString = SacAllocatePool(0x50, GLOBAL_BLOCK_TAG);
if (!GuidString)
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (31).\n");
goto Fail;
}
/* Build the string with the GUID in it, and save the ppointer to it */
swprintf(GuidString,
L"%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
SystemGuid.Data1,
SystemGuid.Data2,
SystemGuid.Data3,
SystemGuid.Data4[0],
SystemGuid.Data4[1],
SystemGuid.Data4[2],
SystemGuid.Data4[3],
SystemGuid.Data4[4],
SystemGuid.Data4[5],
SystemGuid.Data4[6],
SystemGuid.Data4[7]);
MachineInformation->MachineGuid = GuidString;
}
/* Next, query the processor architecture */
Status = GetRegistryValueBuffer(L"\\Registry\\Machine\\System\\"
L"CurrentControlSet\\Control\\"
L"Session Manager\\Environment",
L"PROCESSOR_ARCHITECTURE",
&PartialInfo);
if (!NT_SUCCESS(Status))
{
/* It's not critical, but we won't have it */
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (30).\n");
}
else
{
/* We have it! Copy the value from the registry */
Status = CopyRegistryValueData((PVOID*)&MachineInformation->
ProcessorArchitecture,
PartialInfo);
SacFreePool(PartialInfo);
if (!NT_SUCCESS(Status))
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (30).\n");
goto Fail;
}
}
/* Now allocate a buffer for the OS version number */
MajorVersion = SacAllocatePool(0x18, GLOBAL_BLOCK_TAG);
if (!MajorVersion)
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (50).\n");
goto Fail;
}
/* Build the buffer and set a pointer to it */
swprintf(MajorVersion,
L"%d.%d",
VersionInformation.dwMajorVersion,
VersionInformation.dwMinorVersion);
MachineInformation->MajorVersion = MajorVersion;
/* Now allocate a buffer for the OS build number */
BuildNumber = SacAllocatePool(0xC, GLOBAL_BLOCK_TAG);
if (!BuildNumber)
{
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC InitializeMachineInformation: Exiting (60).\n");
goto Fail;
}
/* Build the buffer and set a pointer to it */
swprintf(BuildNumber, L"%d", VersionInformation.dwBuildNumber);
MachineInformation->BuildNumber = BuildNumber;
/* Now check what kind of SKU this is */
if (ExVerifySuite(DataCenter))
{
SuiteTypeMessage = SAC_DATACENTER_SUITE_MSG;
}
else if (ExVerifySuite(EmbeddedNT))
{
SuiteTypeMessage = SAC_EMBEDDED_SUITE_MSG;
}
else if (ExVerifySuite(Enterprise))
{
SuiteTypeMessage = SAC_ENTERPRISE_SUITE_MSG;
}
else
{
/* Unknown or perhaps a client SKU */
SuiteTypeMessage = SAC_NO_SUITE_MSG;
}
/* Get the string that correponds to the SKU type */
MessageBuffer = GetMessage(SuiteTypeMessage);
if (!MessageBuffer)
{
/* We won't have it, but this isn't critical */
SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed to get product type.\n");
}
else
{
/* Calculate the size we need to hold the string */
Size = wcslen(MessageBuffer);
ASSERT(Size > 0);
RealSize = Size * sizeof(WCHAR) + sizeof(UNICODE_NULL);
/* Allocate a buffer for it */
ProductType = SacAllocatePool(RealSize, GLOBAL_BLOCK_TAG);
if (!ProductType)
{
SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed product type memory allocation.\n");
goto Fail;
}
/* Copy the string and set the pointer */
RtlCopyMemory(ProductType, MessageBuffer, RealSize);
MachineInformation->ProductType = ProductType;
}
/* Check if this is a SP version or RTM version */
if (VersionInformation.wServicePackMajor)
{
/* This is a service pack, allocate a buffer for the version */
ServicePack = SacAllocatePool(0x18, GLOBAL_BLOCK_TAG);
if (ServicePack)
{
/* Build the buffer and set a pointer to it */
swprintf(ServicePack,
L"%d.%d",
VersionInformation.wServicePackMajor,
VersionInformation.wServicePackMinor);
MachineInformation->ServicePack = ServicePack;
/* We've collected all the machine info and are done! */
return;
}
/* This is the failure path */
SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed service pack memory allocation.\n");
}
else
{
/* Get a generic string that indicates there's no service pack */
MessageBuffer = GetMessage(SAC_NO_DATA_MSG);
Size = wcslen(MessageBuffer);
ASSERT(Size > 0);
RealSize = Size * sizeof(WCHAR) + sizeof(UNICODE_NULL);
/* Allocate memory for the "no service pack" string */
ServicePack = SacAllocatePool(RealSize, GLOBAL_BLOCK_TAG);
if (ServicePack)
{
/* Copy the buffer and set a pointer to it */
RtlCopyMemory(ServicePack, MessageBuffer, RealSize);
MachineInformation->ServicePack = ServicePack;
/* We've collected all the machine info and are done! */
return;
}
SAC_DBG(SAC_DBG_INIT, "SAC InitializeMachineInformation: Failed service pack memory allocation.\n");
}
Fail:
/* In the failure path, always cleanup the machine information buffer */
if (MachineInformation)
{
SacFreePool(MachineInformation);
}
SAC_DBG(SAC_DBG_ENTRY_EXIT, "SAC Initialize Machine Information : Exiting with error.\n");
}
NTSTATUS NTSTATUS
NTAPI NTAPI
GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission) GetCommandConsoleLaunchingPermission(OUT PBOOLEAN Permission)
@ -549,7 +861,7 @@ ImposeSacCmdServiceStartTypePolicy(VOID)
if (!Buffer) return STATUS_UNSUCCESSFUL; if (!Buffer) return STATUS_UNSUCCESSFUL;
/* Read the value */ /* Read the value */
Status = CopyRegistryValueData(&Data, Buffer); Status = CopyRegistryValueData((PVOID*)&Data, Buffer);
SacFreePool(Buffer); SacFreePool(Buffer);
if (!NT_SUCCESS(Status)) return Status; if (!NT_SUCCESS(Status)) return Status;
@ -632,7 +944,7 @@ NTAPI
RegisterBlueScreenMachineInformation(VOID) RegisterBlueScreenMachineInformation(VOID)
{ {
PWCHAR XmlBuffer; PWCHAR XmlBuffer;
PHEADLESS_BLUE_SCREEN_DATA BsBuffer; PHEADLESS_CMD_SET_BLUE_SCREEN_DATA BsBuffer;
ULONG Length, HeaderLength, TotalLength; ULONG Length, HeaderLength, TotalLength;
NTSTATUS Status; NTSTATUS Status;
ULONG i; ULONG i;
@ -653,15 +965,15 @@ RegisterBlueScreenMachineInformation(VOID)
CHECK_PARAMETER_WITH_STATUS(BsBuffer, STATUS_NO_MEMORY); CHECK_PARAMETER_WITH_STATUS(BsBuffer, STATUS_NO_MEMORY);
/* Copy the XML property name */ /* Copy the XML property name */
strcpy((PCHAR)BsBuffer->XMLData, "MACHINEINFO"); strcpy((PCHAR)BsBuffer->Data, "MACHINEINFO");
BsBuffer->Property = (PUCHAR)HeaderLength + sizeof(ANSI_NULL); BsBuffer->ValueIndex = HeaderLength + sizeof(ANSI_NULL);
/* Copy the data and NULL-terminate it */ /* Copy the data and NULL-terminate it */
for (i = 0; i < Length; i++) for (i = 0; i < Length; i++)
{ {
BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = XmlBuffer[i]; BsBuffer->Data[BsBuffer->ValueIndex + i] = XmlBuffer[i];
} }
BsBuffer->XMLData[HeaderLength + sizeof(ANSI_NULL) + i] = ANSI_NULL; BsBuffer->Data[BsBuffer->ValueIndex + i] = ANSI_NULL;
/* Let the OS save the buffer for later */ /* Let the OS save the buffer for later */
Status = HeadlessDispatch(HeadlessCmdSetBlueScreenData, Status = HeadlessDispatch(HeadlessCmdSetBlueScreenData,

View file

@ -7,9 +7,12 @@ list(APPEND UNICODE_SOURCE
neteventmsg.mc neteventmsg.mc
ntiologc.mc ntiologc.mc
ntstatus.mc ntstatus.mc
pciclass.mc pciclass.mc)
list(APPEND UNICODE_SOURCE_REALLY
sacmsg.mc) sacmsg.mc)
add_message_headers(ANSI ${ANSI_SOURCE}) add_message_headers(ANSI ${ANSI_SOURCE})
# FIXME: this needs testing before switching to unicode # FIXME: this needs testing before switching to unicode
add_message_headers(ANSI ${UNICODE_SOURCE}) add_message_headers(ANSI ${UNICODE_SOURCE})
add_message_headers(UNICODE ${UNICODE_SOURCE_REALLY})

View file

@ -461,7 +461,7 @@ Language=English
. .
MessageId=98 MessageId=98
SymbolicName=SACDRV_98 SymbolicName=SAC_NO_DATA_MSG
Language=English Language=English
None%0 None%0
. .
@ -473,25 +473,25 @@ Language=English
. .
MessageId=100 MessageId=100
SymbolicName=SACDRV_100 SymbolicName=SAC_DATACENTER_SUITE_MSG
Language=English Language=English
Windows Server 2003 Datacenter Edition%0 Windows Server 2003 Datacenter Edition%0
. .
MessageId=101 MessageId=101
SymbolicName=SACDRV_101 SymbolicName=SAC_EMBEDDED_SUITE_MSG
Language=English Language=English
Windows Server 2003 Embedded%0 Windows Server 2003 Embedded%0
. .
MessageId=102 MessageId=102
SymbolicName=SACDRV_102 SymbolicName=SAC_ENTERPRISE_SUITE_MSG
Language=English Language=English
Windows Server 2003 Enterprise Edition%0 Windows Server 2003 Enterprise Edition%0
. .
MessageId=103 MessageId=103
SymbolicName=SACDRV_103 SymbolicName=SAC_NO_SUITE_MSG
Language=English Language=English
Windows Server 2003%0 Windows Server 2003%0
. .
@ -695,7 +695,7 @@ The specified gateway IP address is invalid.
. .
MessageId=153 MessageId=153
SymbolicName=SACDRV_153 SymbolicName=SAC_UNINITIALIZED_MSG
Language=English Language=English
not yet initialized%0 not yet initialized%0
. .

View file

@ -17,111 +17,156 @@ PHEADLESS_GLOBALS HeadlessGlobals;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
FORCEINLINE
KIRQL
HdlspAcquireGlobalLock(VOID)
{
KIRQL OldIrql;
/* Don't acquire the lock if we are bugchecking */
if (!HeadlessGlobals->InBugCheck)
{
KeAcquireSpinLock(&HeadlessGlobals->SpinLock, &OldIrql);
}
else
{
OldIrql = 0xFF;
}
return OldIrql;
}
FORCEINLINE
VOID
HdlspReleaselobalLock(IN KIRQL OldIrql)
{
/* Only release the lock if we aren't bugchecking */
if (OldIrql != 0xFF)
{
KeReleaseSpinLock(&HeadlessGlobals->SpinLock, OldIrql);
}
else
{
ASSERT(HeadlessGlobals->InBugCheck == TRUE);
}
}
VOID VOID
NTAPI NTAPI
HdlspSendStringAtBaud( HdlspSendStringAtBaud(IN PUCHAR String)
IN PUCHAR String
)
{ {
/* Send every byte */ /* Send every byte */
while (*String++ != ANSI_NULL) while (*String++ != ANSI_NULL)
{ {
InbvPortPutByte(HeadlessGlobals->TerminalPort, *String); InbvPortPutByte(HeadlessGlobals->TerminalPort, *String);
} }
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
HdlspEnableTerminal( HdlspEnableTerminal(IN BOOLEAN Enable)
IN BOOLEAN Enable
)
{ {
/* Enable if requested, as long as this isn't a PCI serial port crashing */ /* Enable if requested, as long as this isn't a PCI serial port crashing */
if ((Enable) && if ((Enable) &&
!(HeadlessGlobals->TerminalEnabled) && !(HeadlessGlobals->TerminalEnabled) &&
!((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck))) !((HeadlessGlobals->IsMMIODevice) && (HeadlessGlobals->InBugCheck)))
{ {
/* Initialize the COM port with cportlib */ /* Initialize the COM port with cportlib */
HeadlessGlobals->TerminalEnabled = InbvPortInitialize( HeadlessGlobals->TerminalEnabled = InbvPortInitialize(HeadlessGlobals->
HeadlessGlobals->TerminalBaudRate, TerminalBaudRate,
HeadlessGlobals->TerminalPortNumber, HeadlessGlobals->
HeadlessGlobals->TerminalPortAddress, TerminalPortNumber,
&HeadlessGlobals->TerminalPort, HeadlessGlobals->
HeadlessGlobals->IsMMIODevice); TerminalPortAddress,
if (!HeadlessGlobals->TerminalEnabled) return STATUS_UNSUCCESSFUL; &HeadlessGlobals->
TerminalPort,
HeadlessGlobals->
IsMMIODevice);
if (!HeadlessGlobals->TerminalEnabled)
{
DPRINT1("Failed to initialize port through cportlib\n");
return STATUS_UNSUCCESSFUL;
}
/* Cleanup the screen and reset the cursor */ /* Cleanup the screen and reset the cursor */
HdlspSendStringAtBaud((PUCHAR)"\x1B[2J"); HdlspSendStringAtBaud((PUCHAR)"\x1B[2J");
HdlspSendStringAtBaud((PUCHAR)"\x1B[H"); HdlspSendStringAtBaud((PUCHAR)"\x1B[H");
/* Enable FIFO */ /* Enable FIFO */
InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE); InbvPortEnableFifo(HeadlessGlobals->TerminalPort, TRUE);
} }
else if (!Enable) else if (!Enable)
{ {
/* Specific case when headless is being disabled */ /* Specific case when headless is being disabled */
InbvPortTerminate(HeadlessGlobals->TerminalPort); InbvPortTerminate(HeadlessGlobals->TerminalPort);
HeadlessGlobals->TerminalPort = 0; HeadlessGlobals->TerminalPort = 0;
HeadlessGlobals->TerminalEnabled = FALSE; HeadlessGlobals->TerminalEnabled = FALSE;
} }
return STATUS_SUCCESS;
/* All done */
return STATUS_SUCCESS;
} }
VOID VOID
NTAPI NTAPI
INIT_FUNCTION INIT_FUNCTION
HeadlessInit( HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
{ {
PHEADLESS_LOADER_BLOCK HeadlessBlock; PHEADLESS_LOADER_BLOCK HeadlessBlock;
HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock; /* Only initialize further if the loader found EMS enabled */
if (!HeadlessBlock) return; HeadlessBlock = LoaderBlock->Extension->HeadlessLoaderBlock;
if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return; if (!HeadlessBlock) return;
HeadlessGlobals = ExAllocatePoolWithTag( /* Ignore invalid EMS settings */
NonPagedPool, if ((HeadlessBlock->PortNumber > 4) && (HeadlessBlock->UsedBiosSettings)) return;
sizeof(HEADLESS_GLOBALS),
'sldH');
if (!HeadlessGlobals) return;
/* Zero and copy loader data */ /* Allocate the global headless data */
RtlZeroMemory(HeadlessGlobals, sizeof(HEADLESS_GLOBALS)); HeadlessGlobals = ExAllocatePoolWithTag(NonPagedPool,
HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber; sizeof(*HeadlessGlobals),
HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress; 'sldH');
HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate; if (!HeadlessGlobals) return;
HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
/* These two are opposites of each other */ /* Zero and copy loader data */
if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE; RtlZeroMemory(HeadlessGlobals, sizeof(*HeadlessGlobals));
HeadlessGlobals->TerminalPortNumber = HeadlessBlock->PortNumber;
HeadlessGlobals->TerminalPortAddress = HeadlessBlock->PortAddress;
HeadlessGlobals->TerminalBaudRate = HeadlessBlock->BaudRate;
HeadlessGlobals->TerminalParity = HeadlessBlock->Parity;
HeadlessGlobals->TerminalStopBits = HeadlessBlock->StopBits;
HeadlessGlobals->UsedBiosSettings = HeadlessBlock->UsedBiosSettings;
HeadlessGlobals->IsMMIODevice = HeadlessBlock->IsMMIODevice;
HeadlessGlobals->TerminalType = HeadlessBlock->TerminalType;
HeadlessGlobals->SystemGUID = HeadlessBlock->SystemGUID;
DPRINT1("EMS on Port %d (0x%lx) at %d bps\n",
HeadlessGlobals->TerminalPortNumber,
HeadlessGlobals->TerminalPortAddress,
HeadlessGlobals->TerminalBaudRate);
/* Check for a PCI device, warn that this isn't supported */ /* These two are opposites of each other */
if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID) if (HeadlessGlobals->IsMMIODevice) HeadlessGlobals->IsNonLegacyDevice = TRUE;
{
DPRINT1("PCI Serial Ports not supported\n");
}
/* Log entries are not yet supported */ /* Check for a PCI device, warn that this isn't supported */
DPRINT1("FIXME: No Headless logging support\n"); if (HeadlessBlock->PciDeviceId != PCI_INVALID_VENDORID)
{
DPRINT1("PCI Serial Ports not supported\n");
}
/* Allocate temporary buffer */ /* Log entries are not yet supported */
HeadlessGlobals->TmpBuffer = ExAllocatePoolWithTag(NonPagedPool, 80, 'sldH'); DPRINT1("FIXME: No Headless logging support\n");
if (!HeadlessGlobals->TmpBuffer) return;
/* Windows seems to apply some special hacks for 9600 bps */ /* Allocate temporary buffer */
if (HeadlessGlobals->TerminalBaudRate == 9600) HeadlessGlobals->TmpBuffer = ExAllocatePoolWithTag(NonPagedPool, 80, 'sldH');
{ if (!HeadlessGlobals->TmpBuffer) return;
DPRINT1("Please use other baud rate than 9600bps for now\n");
}
/* Enable the terminal */ /* Windows seems to apply some special hacks for 9600 bps */
HdlspEnableTerminal(TRUE); if (HeadlessGlobals->TerminalBaudRate == 9600)
{
DPRINT1("Please use other baud rate than 9600bps for now\n");
}
/* Enable the terminal */
HdlspEnableTerminal(TRUE);
} }
VOID VOID
@ -197,59 +242,80 @@ HdlspPutString(
NTSTATUS NTSTATUS
NTAPI NTAPI
HdlspDispatch( HdlspDispatch(IN HEADLESS_CMD Command,
IN HEADLESS_CMD Command, IN PVOID InputBuffer,
IN PVOID InputBuffer, IN SIZE_T InputBufferSize,
IN SIZE_T InputBufferSize, OUT PVOID OutputBuffer,
OUT PVOID OutputBuffer, OUT PSIZE_T OutputBufferSize)
OUT PSIZE_T OutputBufferSize
)
{ {
//NTSTATUS Status = STATUS_NOT_IMPLEMENTED; KIRQL OldIrql;
ASSERT(HeadlessGlobals != NULL); PHEADLESS_RSP_QUERY_INFO HeadlessInfo;
PHEADLESS_CMD_PUT_STRING PutString;
PHEADLESS_CMD_ENABLE_TERMINAL EnableTerminal;
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
ASSERT(HeadlessGlobals != NULL);
// ASSERT(HeadlessGlobals->PageLockHandle != NULL); // ASSERT(HeadlessGlobals->PageLockHandle != NULL);
/* FIXME: This should be using the headless spinlock */ /* Ignore non-reentrant commands */
if ((Command != HeadlessCmdAddLogEntry) &&
(Command != HeadlessCmdStartBugCheck) &&
(Command != HeadlessCmdSendBlueScreenData) &&
(Command != HeadlessCmdDoBugCheckProcessing))
{
OldIrql = HdlspAcquireGlobalLock();
/* Ignore non-reentrant commands */ if (HeadlessGlobals->ProcessingCmd)
if ((Command != HeadlessCmdAddLogEntry) && {
(Command != HeadlessCmdStartBugCheck) && HdlspReleaselobalLock(OldIrql);
(Command != HeadlessCmdSendBlueScreenData) && return STATUS_UNSUCCESSFUL;
(Command != HeadlessCmdDoBugCheckProcessing)) }
{
if (HeadlessGlobals->ProcessingCmd) return STATUS_UNSUCCESSFUL;
/* Don't allow these commands next time */ /* Don't allow these commands next time */
HeadlessGlobals->ProcessingCmd = TRUE; HeadlessGlobals->ProcessingCmd = TRUE;
} HdlspReleaselobalLock(OldIrql);
}
/* Handle each command */
switch (Command)
{
case HeadlessCmdEnableTerminal:
/* Make sure the caller passed valid data */
if (!(InputBuffer) ||
(InputBufferSize != sizeof(*EnableTerminal)))
{
DPRINT1("Invalid buffer\n");
Status = STATUS_INVALID_PARAMETER;
break;
}
/* Go and enable it */
EnableTerminal = InputBuffer;
Status = HdlspEnableTerminal(EnableTerminal->Enable);
break;
/* Handle each command */
switch (Command)
{
case HeadlessCmdEnableTerminal:
break;
case HeadlessCmdCheckForReboot: case HeadlessCmdCheckForReboot:
break; break;
case HeadlessCmdPutString: case HeadlessCmdPutString:
/* Validate the existence of an input buffer */ /* Validate the existence of an input buffer */
if (!InputBuffer) if (!InputBuffer)
{ {
//Status = STATUS_INVALID_PARAMETER; Status = STATUS_INVALID_PARAMETER;
goto Reset; break;
} }
/* Terminal should be on */ /* Terminal should be on */
if (HeadlessGlobals->TerminalEnabled) if (HeadlessGlobals->TerminalEnabled)
{ {
/* Print each byte in the string making sure VT100 chars are used */ /* Print each byte in the string making sure VT100 chars are used */
PHEADLESS_CMD_PUT_STRING PutString = (PVOID)InputBuffer; PutString = InputBuffer;
HdlspPutString(PutString->String); HdlspPutString(PutString->String);
} }
/* Return success either way */ /* Return success either way */
//Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
case HeadlessCmdClearDisplay: case HeadlessCmdClearDisplay:
break; break;
@ -276,13 +342,62 @@ HdlspDispatch(
case HeadlessCmdDoBugCheckProcessing: case HeadlessCmdDoBugCheckProcessing:
break; break;
case HeadlessCmdQueryInformation: case HeadlessCmdQueryInformation:
break;
/* Make sure the caller passed valid data */
if (!(OutputBuffer) ||
!(OutputBufferSize) ||
(*OutputBufferSize < sizeof(*HeadlessInfo)))
{
DPRINT1("Invalid buffer\n");
Status = STATUS_INVALID_PARAMETER;
break;
}
/* If we got here, headless is enabled -- we know this much */
HeadlessInfo = OutputBuffer;
HeadlessInfo->PortType = HeadlessSerialPort;
HeadlessInfo->Serial.TerminalAttached = TRUE;
HeadlessInfo->Serial.UsedBiosSettings = HeadlessGlobals->UsedBiosSettings;
HeadlessInfo->Serial.TerminalBaudRate = HeadlessGlobals->TerminalBaudRate;
HeadlessInfo->Serial.TerminalType = HeadlessGlobals->TerminalType;
/* Now check on what port/baud it's enabled on */
if ((HeadlessGlobals->TerminalPortNumber >= 1) ||
(HeadlessGlobals->UsedBiosSettings))
{
/* Get the EMS information */
HeadlessInfo->Serial.TerminalPort = HeadlessGlobals->
TerminalPortNumber;
HeadlessInfo->Serial.TerminalPortBaseAddress = HeadlessGlobals->
TerminalPortAddress;
}
else
{
/* We don't know for sure */
HeadlessInfo->Serial.TerminalPort = SerialPortUndefined;
HeadlessInfo->Serial.TerminalPortBaseAddress = 0;
}
/* All done */
Status = STATUS_SUCCESS;
break;
case HeadlessCmdAddLogEntry: case HeadlessCmdAddLogEntry:
break; break;
case HeadlessCmdDisplayLog: case HeadlessCmdDisplayLog:
break; break;
case HeadlessCmdSetBlueScreenData: case HeadlessCmdSetBlueScreenData:
break;
/* Validate the existence of an input buffer */
if (!InputBuffer)
{
Status = STATUS_INVALID_PARAMETER;
break;
}
/* Lie so that we can get Hdl bringup a little bit further */
UNIMPLEMENTED;
Status = STATUS_SUCCESS;
break;
case HeadlessCmdSendBlueScreenData: case HeadlessCmdSendBlueScreenData:
break; break;
case HeadlessCmdQueryGUID: case HeadlessCmdQueryGUID:
@ -293,60 +408,60 @@ HdlspDispatch(
break; break;
} }
Reset: /* Unset processing state */
/* Unset prcessing state */ if ((Command != HeadlessCmdAddLogEntry) &&
if ((Command != HeadlessCmdAddLogEntry) && (Command != HeadlessCmdStartBugCheck) &&
(Command != HeadlessCmdStartBugCheck) && (Command != HeadlessCmdSendBlueScreenData) &&
(Command != HeadlessCmdSendBlueScreenData) && (Command != HeadlessCmdDoBugCheckProcessing))
(Command != HeadlessCmdDoBugCheckProcessing)) {
{ ASSERT(HeadlessGlobals->ProcessingCmd == TRUE);
ASSERT(HeadlessGlobals->ProcessingCmd == TRUE); HeadlessGlobals->ProcessingCmd = FALSE;
HeadlessGlobals->ProcessingCmd = FALSE; }
}
//UNIMPLEMENTED; /* All done */
return STATUS_SUCCESS; return Status;
} }
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
NTAPI NTAPI
HeadlessDispatch( HeadlessDispatch(IN HEADLESS_CMD Command,
IN HEADLESS_CMD Command, IN PVOID InputBuffer,
IN PVOID InputBuffer, IN SIZE_T InputBufferSize,
IN SIZE_T InputBufferSize, OUT PVOID OutputBuffer,
OUT PVOID OutputBuffer, OUT PSIZE_T OutputBufferSize)
OUT PSIZE_T OutputBufferSize
)
{ {
/* Check for stubs that will expect something even with headless off */ /* Check for stubs that will expect something even with headless off */
if (!HeadlessGlobals) if (!HeadlessGlobals)
{ {
/* Don't allow the SAC to connect */ /* Don't allow the SAC to connect */
if (Command == HeadlessCmdEnableTerminal) return STATUS_UNSUCCESSFUL; if (Command == HeadlessCmdEnableTerminal) return STATUS_UNSUCCESSFUL;
/* Send bogus reply */ /* Send bogus reply */
if ((Command == HeadlessCmdQueryInformation) || if ((Command == HeadlessCmdQueryInformation) ||
(Command == HeadlessCmdGetByte) || (Command == HeadlessCmdGetByte) ||
(Command == HeadlessCmdGetLine) || (Command == HeadlessCmdGetLine) ||
(Command == HeadlessCmdCheckForReboot) || (Command == HeadlessCmdCheckForReboot) ||
(Command == HeadlessCmdTerminalPoll)) (Command == HeadlessCmdTerminalPoll))
{ {
if (!(OutputBuffer) || !(OutputBufferSize)) return STATUS_INVALID_PARAMETER; if (!(OutputBuffer) || !(OutputBufferSize))
RtlZeroMemory(OutputBuffer, *OutputBufferSize); {
} return STATUS_INVALID_PARAMETER;
return STATUS_SUCCESS; }
}
RtlZeroMemory(OutputBuffer, *OutputBufferSize);
/* Do the real work */ }
return HdlspDispatch( return STATUS_SUCCESS;
Command, }
InputBuffer,
InputBufferSize, /* Do the real work */
OutputBuffer, return HdlspDispatch(Command,
OutputBufferSize); InputBuffer,
} InputBufferSize,
OutputBuffer,
OutputBufferSize);
}
/* EOF */ /* EOF */

View file

@ -72,12 +72,11 @@ typedef struct _HEADLESS_LOG_ENTRY
// //
// Headless Bugcheck Information // Headless Bugcheck Information
// //
typedef struct _HEADLESS_BLUE_SCREEN_DATA typedef struct _HEADLESS_CMD_SET_BLUE_SCREEN_DATA
{ {
PUCHAR Property; ULONG ValueIndex;
PUCHAR XMLData; UCHAR Data[ANYSIZE_ARRAY];
struct _HEADLESS_BLUE_SCREEN_DATA *Next; } HEADLESS_CMD_SET_BLUE_SCREEN_DATA, *PHEADLESS_CMD_SET_BLUE_SCREEN_DATA;
} HEADLESS_BLUE_SCREEN_DATA, * PHEADLESS_BLUE_SCREEN_DATA;
// //
// Headless Control Structure, mostly for !SAC // Headless Control Structure, mostly for !SAC
@ -89,7 +88,7 @@ typedef struct _HEADLESS_GLOBALS
PHEADLESS_LOG_ENTRY LogEntries; PHEADLESS_LOG_ENTRY LogEntries;
PUCHAR TmpBuffer; PUCHAR TmpBuffer;
PUCHAR InputBuffer; PUCHAR InputBuffer;
PHEADLESS_BLUE_SCREEN_DATA BlueScreenData; PHEADLESS_CMD_SET_BLUE_SCREEN_DATA BlueScreenData;
union union
{ {
struct struct
@ -183,6 +182,11 @@ typedef struct _HEADLESS_RSP_QUERY_INFO
}; };
} HEADLESS_RSP_QUERY_INFO, *PHEADLESS_RSP_QUERY_INFO; } HEADLESS_RSP_QUERY_INFO, *PHEADLESS_RSP_QUERY_INFO;
typedef struct _HEADLESS_CMD_ENABLE_TERMINAL
{
BOOLEAN Enable;
} HEADLESS_CMD_ENABLE_TERMINAL, *PHEADLESS_CMD_ENABLE_TERMINAL;
typedef struct _HEADLESS_CMD_PUT_STRING typedef struct _HEADLESS_CMD_PUT_STRING
{ {
UCHAR String[1]; UCHAR String[1];