Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

544 lines
11 KiB

#include "asl.h"
//
// Functions
//
VOID NullTok (VOID) { Vnone(); }
VOID IsZeroOp (VOID) { Vnone(); }
VOID VSn (VOID) { VAlArgs("S", NULL); }
VOID VOp (VOID) { VAlArgs("O", NULL); }
VOID VSnOp (VOID) { VAlArgs("SO", NULL); }
VOID VOpSn (VOID) { VAlArgs("OS", NULL); }
VOID VOpOp (VOID) { VAlArgs("OO", NULL); }
VOID VOpOpSn (VOID) { VAlArgs("OOS", NULL); }
VOID VOpOpOp (VOID) { VAlArgs("OOO", NULL); }
VOID VOpOpSnSn (VOID) { VAlArgs("OOSS", NULL); }
VOID VOpOpOpSn (VOID) { VAlArgs("OOOS", NULL); }
// not done..
VOID DefineTok (VOID) { AERROR ("Not complete: DefineTok"); }
VOID AliasOp (VOID) { AERROR ("Not complete: AliasOp"); }
VOID LoadOp (VOID) { AERROR ("Not complete: LoadOp"); }
UCHAR VAlArgMsg[] = "Argx";
BOOLEAN
VAlArg (
IN PUCHAR Msg,
IN PAL_DATA Arg,
IN UCHAR Type
)
//
// O - OpCode
// N - Name
// S - SuperName
// D - DefData
// Z - ASCIZ
//
{
BOOLEAN IsOpcode, IsSuperName, IsDefData, IsName, NotASLTerm, IsNumeric;
BOOLEAN Match, VerifyReference;
PUCHAR Data;
ULONG Len, SegLen;
UCHAR c;
PUCHAR p;
//
// If lower case, then a default value can be used
//
if (Type >= 'a' && Type <= 'z') {
if (Arg->Term == NullTok) {
return TRUE;
}
Type -= 'a' - 'A';
}
//
// Determine AL_DATA type
//
if (Arg->Term) {
//
// Is ASL term, type is encoded in term table
//
IsName = FALSE;
NotASLTerm = FALSE;
IsOpcode = Arg->Term->Flags & T_OPCODE ? TRUE : FALSE;
IsSuperName = Arg->Term->Flags & T_SUPERNAME ? TRUE : FALSE;
IsDefData = Arg->Term->Flags & T_DEFDATA ? TRUE : FALSE;
} else {
//
// Not ASL term, either a string or name refernce
//
IsOpcode = FALSE;
IsSuperName = FALSE;
IsDefData = FALSE;
IsNumeric = Arg->Flags & F_ISNUMERIC ? TRUE : FALSE;
NotASLTerm = TRUE;
IsName = FALSE;
GetAlData (Arg, &Data, &Len);
if (Len && !IsNumeric) {
//
// Determine if it's a valid name
//
IsName = TRUE;
SegLen = NAME_SEG_LENGTH;
while (Len) {
c = *Data;
if (c == '\\' || c == '^' || c == '.') {
SegLen = NAME_SEG_LENGTH;
} else if ( (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_') {
if (SegLen) {
SegLen -= 1;
} else {
IsName = FALSE;
break;
}
} else {
IsName = FALSE;
}
Len -= 1;
Data += 1;
}
}
}
Match = FALSE;
VerifyReference = FALSE;
switch (Type) {
case 'O': // opcode arg
p = "[Opcode|SuperName|Name]";
VerifyReference = NotASLTerm;
Match = IsOpcode || IsSuperName || IsName;
break;
case 'S': // supername arg
p = "[SuperName|Name]";
VerifyReference = NotASLTerm;
Match = IsSuperName || IsName;
break;
case 'N': // name arg
p = "Name";
VerifyReference = NotASLTerm;
Match = IsName;
break;
case 'D': // define data arg
p = "DataType";
Match = IsDefData;
break;
case 'V':
p = "Numeric";
Match = IsNumeric;
break;
case 'Z':
p = "ASCIZ";
Match = NotASLTerm;
break;
}
if (!Match) {
ERRORAL (AlLoc, "%s is invalid type. Expected %s", Msg, p);
} else if (VerifyReference && !(Arg->Flags & F_VERIFYREF)) {
ASSERT (Arg->u1.VerifyRef.Flink == NULL, "Can not have package");
Arg->Flags |= F_VERIFYREF;
InsertTailList (&VerifyRef, &Arg->u1.VerifyRef);
}
return Match;
}
BOOLEAN
VAlArgs (
IN PUCHAR Types,
OUT PAL_DATA *Args
)
// Verify AL ha a fixed list of the given type
{
ULONG len, noargs, i;
PAL_DATA Arg;
PLIST_ENTRY Link;
BOOLEAN Status, Missing;
Status = TRUE;
Missing = FALSE;
noargs = strlen(Types);
len = noargs;
if (len < AlLoc->FLCount) {
ERRORAL (AlLoc, "Too many args. (Have %d, Want %d)", AlLoc->FLCount, len);
Status = FALSE;
}
if (len > AlLoc->FLCount) {
len = AlLoc->FLCount;
}
//
// Walk each arg and verify it
//
Link = AlLoc->FixedList.Flink;
for (i=0; i < len; i++) {
Arg = CONTAINING_RECORD(Link, AL_DATA, Link);
Link = Link->Flink;
//
// Build arg array for caller
//
if (Args) {
Args[i] = Arg;
}
//
// Verify this arg's data type
//
VAlArgMsg[3] = '0' + i;
if (!VAlArg (VAlArgMsg, Arg, Types[i])) {
Status = FALSE;
}
}
//
// Verify each unsupplied arg as optional
//
for (; i < noargs; i++) {
if (Args) {
// allocate a null Al
Arg = AllocAl();
Arg->Flags |= F_AMLENCODE;
InsertTailList (&AlLoc->FixedList, &Arg->Link);
Args[i] = Arg;
}
if (Types[i] < 'a' || Types[i] > 'z') {
// not an optional arg
if (!Missing) {
ERRORAL (AlLoc, "Missing args. Need %d\n", len);
Missing = TRUE;
Status = FALSE;
}
}
}
return Status;
}
VOID
__cdecl SetAlData (
IN PAL_DATA Al,
IN PUCHAR Fmt,
...
)
{
ULONG i, j, plen;
ULONG Len;
PUCHAR Data;
UCHAR s[200];
union {
UCHAR c[4];
USHORT w;
ULONG d;
} u;
va_list args;
va_start (args, Fmt);
Len = 0;
for (i=0; Fmt[i]; i++) {
plen = 0;
switch (Fmt[i]) {
case 'O':
s[Len++] = Al->Term->Op1;
if (Al->Term->Op2) {
s[Len++] = Al->Term->Op2;
}
break;
case 'B':
u.c[0] = va_arg(args, UCHAR);
plen = sizeof(UCHAR);
break;
case 'W':
u.w = va_arg(args, USHORT);
plen = sizeof(USHORT);
break;
case 'D':
u.d = va_arg(args, ULONG);
plen = sizeof(ULONG);
break;
default:
ASSERT(FALSE, "SetAlData");
}
for (j=0; j < plen; j++) {
s[Len++] = u.c[j];
}
}
Data = SetAlDataLen(Al, Len);
memcpy (Data, s, Len);
}
VOID
Vnone (
VOID
)
{
if (AlLoc->FLCount) {
ERRORAL (AlLoc, "Too many args. (Have %d, Want 0)", AlLoc->FLCount);
}
}
VOID
ParseMethodReference(
VOID
)
{
BOOLEAN Status;
// verify AlLoc is a name & add it to the VerifyRef list
Status = VAlArg ("", AlLoc, 'N');
// Encode it
if (Status) {
AMLEncodeName (AlLoc);
}
// retire it
AlLoc = AlLoc->Parent;
}
VOID
IncludeTok (
VOID
)
{
PAL_DATA Args[2], Al;
PUCHAR Name;
ULONG Len;
BOOLEAN Status;
Status = VAlArgs ("Z", Args);
if (Status) {
GetAlData (Args[0], &Name, &Len);
IncludeSource (Name);
}
Al = AlLoc;
AlLoc = NULL;
FreeAl (Al);
}
VOID
MoveBodyToArg (
IN PAL_DATA BodyAl
)
{
PAL_DATA Al;
//
// If null list, then add nop
//
if (IsListEmpty(&BodyAl->u1.VariableList)) {
// add nop
Al = AllocAl();
InsertTailList(&BodyAl->u1.VariableList, &Al->Link);
Al->Flags |= F_AMLENCODE;
Al->u.Data.Length = 1;
Al->u.Data.Data[0] = AML_NOP;
}
//
// If Flink != Blink, there is more then one term in the body.
// Put it in a code package
//
if (BodyAl->u1.VariableList.Flink != BodyAl->u1.VariableList.Blink) {
Al = AllocAl();
Al->DataType = TypeCodePackage;
Al->Flags |= F_AMLPACKAGE | F_AMLENCODE;
Al->u.Data.Length = 1;
Al->u.Data.Data[0] = AML_CODEPACKAGE;
// move list to Al
Al->u1.VariableList.Flink = BodyAl->u1.VariableList.Flink;
Al->u1.VariableList.Blink = BodyAl->u1.VariableList.Blink;
Al->u1.VariableList.Flink->Blink = &Al->u1.VariableList;
Al->u1.VariableList.Blink->Flink = &Al->u1.VariableList;
} else {
Al = CONTAINING_RECORD(BodyAl->u1.VariableList.Flink, AL_DATA, Link);
}
// no longer a package
BodyAl->Flags &= ~F_AMLPACKAGE;
InitializeListHead (&BodyAl->u1.VariableList);
// append to fixed list
InsertTailList (&AlLoc->FixedList, &Al->Link);
}
VOID
WhileOp (
VOID
)
{
if (AlLoc->FLCount != 1) {
ERRORAL (AlLoc, "Syntax error in predicate");
return ;
}
MoveBodyToArg(AlLoc);
}
VOID
IfOp (
VOID
)
{
AlLoc->DataType = TypeIf;
if (AlLoc->FLCount != 1) {
ERRORAL (AlLoc, "Syntax error in predicate");
return ;
}
MoveBodyToArg(AlLoc);
}
VOID
ElseOp (
VOID
)
{
PAL_DATA Al, ElseAl;
PLIST_ENTRY Link;
if (AlLoc->FLCount != 0) {
ERRORAL (AlLoc, "Syntax error in predicate");
return ;
}
//
// Entry just before this one should be an If
//
Link = AlLoc->Parent->u1.VariableList.Blink;
ASSERT (Link == &AlLoc->Link, "Else not last term");
Al = CONTAINING_RECORD(Link->Blink, AL_DATA, Link);
if (Link->Blink == &AlLoc->Parent->u1.VariableList || Al->DataType != TypeIf) {
ERRORAL (AlLoc, "else unexpected");
return ;
}
//
// Convert 'if' to 'if-else', and add else body
//
Al->u.Data.Data[0] = AlLoc->u.Data.Data[0];
ElseAl = AlLoc;
AlLoc = Al;
MoveBodyToArg(ElseAl);
//
// Remove else
//
FreeAl (ElseAl);
}
VOID
StallOp (
VOID
)
{
PAL_DATA Arg;
BOOLEAN Status;
ULONG Stall;
// Get the Number arg
Status = VAlArgs ("V", &Arg);
if (Status) {
Stall = ArgToValue(&Arg, 0, "Stall(Arg0)", 0xff);
SetAlData (Arg, "B", Stall);
}
}
VOID
SleepOp (
VOID
)
{
PAL_DATA Arg;
BOOLEAN Status;
ULONG Sleep;
// Get the Number arg
Status = VAlArgs ("V", &Arg);
if (Status) {
Sleep = ArgToValue(&Arg, 0, "Sleep(Arg0)", 0xffff);
SetAlData (Arg, "W", Sleep);
}
}
VOID
FatalOp (
VOID
)
{
PAL_DATA Args[3];
BOOLEAN Status;
ULONG Type, Code;
// Get the Number arg
Status = VAlArgs ("VVO", Args);
if (Status) {
Type = ArgToValue(&Args, 0, "Fatal(Arg0)", 0xff);
Code = ArgToValue(&Args, 1, "Fatal(Arg0)", -1);
SetAlData (Args[0], "BD", Type, Code);
FreeAl (Args[1]);
}
}