示例#1
0
文件: prstat.c 项目: andreiw/polaris
static void
fill_table(table_t *table, char *arg, char option)
{
	char *p = strtok(arg, ", ");

	if (p == NULL)
		Die(gettext("invalid argument for -%c\n"), option);

	add_element(table, (long)Atoi(p));
	while (p = strtok(NULL, ", "))
		add_element(table, (long)Atoi(p));
}
示例#2
0
文件: prstat.c 项目: andreiw/polaris
static void
fill_set_table(char *arg)
{
	char *p = strtok(arg, ", ");
	psetid_t id;

	if (p == NULL)
		Die(gettext("invalid argument for -C\n"));

	if ((id = Atoi(p)) == 0)
		id = PS_NONE;
	add_element(&set_tbl, id);
	while (p = strtok(NULL, ", ")) {
		if ((id = Atoi(p)) == 0)
			id = PS_NONE;
		if (!has_element(&set_tbl, id))
			add_element(&set_tbl, id);
	}
}
示例#3
0
文件: prstat.c 项目: andreiw/polaris
static void
fill_prj_table(char *arg)
{
	projid_t projid;
	char *p = strtok(arg, ", ");

	if (p == NULL)
		Die(gettext("invalid argument for -j\n"));

	if ((projid = getprojidbyname(p)) == -1)
		projid = Atoi(p);
	add_element(&prj_tbl, (long)projid);

	while (p = strtok(NULL, ", ")) {
		if ((projid = getprojidbyname(p)) == -1)
			projid = Atoi(p);
		add_element(&prj_tbl, (long)projid);
	}
}
示例#4
0
int	main(int ac, char **av)
{
    char	*str;
    int	size;

    if (ac < 2)
    {

    }
    str = Atoi(av[1]);
}
示例#5
0
文件: prstat.c 项目: andreiw/polaris
static int
nlines()
{
	struct winsize ws;
	char *envp;
	int n;
	if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
		if (ws.ws_row > 0)
			return (ws.ws_row);
	}
	if (envp = getenv("LINES")) {
		if ((n = Atoi(envp)) > 0) {
			opts.o_outpmode &= ~OPT_USEHOME;
			return (n);
		}
	}
	return (-1);
}
示例#6
0
void
add_uid(uidtbl_t *tbl, char *name)
{
    uid_t *uid;

    if (tbl->n_size == tbl->n_nent) {	/* reallocation */
        if ((tbl->n_size *= 2) == 0)
            tbl->n_size = 4;	/* first time */
        tbl->n_list = Realloc(tbl->n_list, tbl->n_size*sizeof (uid_t));
    }

    uid = &tbl->n_list[tbl->n_nent++];

    if (isdigit(name[0])) {
        *uid = Atoi(name);
    } else {
        *uid = pwd_getid(name);
    }
}
示例#7
0
EFI_DEBUG_STATUS
DebuggerCallStack (
  IN     CHAR16                    *CommandArg,
  IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
  IN     EFI_EXCEPTION_TYPE        ExceptionType,
  IN OUT EFI_SYSTEM_CONTEXT        SystemContext
  )
/*++

Routine Description:

  DebuggerCommand - CallStack
  
Arguments:

  CommandArg      - The argument for this command
  DebuggerPrivate - EBC Debugger private data structure
  InterruptType   - Interrupt type.
  SystemContext   - EBC system context.

Returns:

  EFI_DEBUG_CONTINUE - formal return value
  
--*/
{
  INTN                           Index;
  UINTN                          SubIndex;
  CHAR8                          *FuncName;
  EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry;
  BOOLEAN                        ShowParameter;
  UINTN                          ParameterNumber;

  ShowParameter = FALSE;
  ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER;

  //
  // Check argument
  //
  if (CommandArg != NULL) {
    if (EfiStriCmp (CommandArg, L"c") == 0) {
      //
      // Clear Call-Stack
      //
      DebuggerPrivate->CallStackEntryCount = 0;
      EfiZeroMem (DebuggerPrivate->CallStackEntry, sizeof(DebuggerPrivate->CallStackEntry));
      EDBPrint (L"Call-Stack is cleared\n");
      return EFI_DEBUG_CONTINUE;
    } else if (EfiStriCmp (CommandArg, L"p") == 0) {
      //
      // Print Call-Stack with parameter
      //
      ShowParameter = TRUE;
      CommandArg = StrGetNextTokenLine (L" ");
      if (CommandArg != NULL) {
        //
        // Try to get the parameter number
        //
        ParameterNumber = Atoi (CommandArg);
        if (ParameterNumber > 16) {
          EDBPrint (L"Call-Stack argument Invalid\n");
          return EFI_DEBUG_CONTINUE;
        }
      }
    } else {
      EDBPrint (L"Call-Stack argument Invalid\n");
      return EFI_DEBUG_CONTINUE;
    }
  }

  //
  // Check CallStack Entry Count
  //
  if (DebuggerPrivate->CallStackEntryCount == 0) {
    EDBPrint (L"No Call-Stack\n");
    return EFI_DEBUG_CONTINUE;
  } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
    EDBPrint (L"Call-Stack Crash, re-initialize!\n");
    DebuggerPrivate->CallStackEntryCount = 0;
    return EFI_DEBUG_CONTINUE;
  }

  //
  // Go through each CallStack entry and print
  //
  EDBPrint (L"Call-Stack (TOP):\n");
  EDBPrint (L"         Caller             Callee        Name\n");
  EDBPrint (L"  ================== ================== ========\n");
//EDBPrint (L"  0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n");
  for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) {
    //
    // Get CallStack and print
    //
    CallStackEntry = &DebuggerPrivate->CallStackEntry[Index];
    EDBPrint (
      L"  0x%016lx 0x%016lx",
      CallStackEntry->SourceAddress,
      CallStackEntry->DestAddress
      );
    FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress);
    if (FuncName != NULL) {
      EDBPrint (L" %a()", FuncName);
    }
    EDBPrint (L"\n");

    if (ShowParameter) {
      //
      // Print parameter
      //
      if (sizeof(UINTN) == sizeof(UINT64)) {
        EDBPrint (
          L"    Parameter Address (0x%016lx) (\n",
          CallStackEntry->ParameterAddr
          );
        if (ParameterNumber == 0) {
          EDBPrint (L"        )\n");
          continue;
        }
        //
        // Print each parameter
        //
        for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
          if (SubIndex % 2 == 0) {
            EDBPrint (L"        ");
          }
          EDBPrint (
            L"0x%016lx, ",
            CallStackEntry->Parameter[SubIndex]
            );
          if (SubIndex % 2 == 1) {
            EDBPrint (L"\n");
          }
        }
        if (SubIndex % 2 == 0) {
          EDBPrint (L"        ");
        }
        EDBPrint (
          L"0x%016lx\n",
          CallStackEntry->Parameter[SubIndex]
          );
        EDBPrint (L"        )\n");
        //
        // break only for parameter
        //
        if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
            (Index != 0)) {
          if (SetPageBreak ()) {
            break;
          }
        }
      } else {
        EDBPrint (
          L"    Parameter Address (0x%08x) (\n",
          CallStackEntry->ParameterAddr
          );
        if (ParameterNumber == 0) {
          EDBPrint (L"        )\n");
          continue;
        }
        //
        // Print each parameter
        //
        for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
          if (SubIndex % 4 == 0) {
            EDBPrint (L"        ");
          }
          EDBPrint (
            L"0x%08x, ",
            CallStackEntry->Parameter[SubIndex]
            );
          if (SubIndex % 4 == 3) {
            EDBPrint (L"\n");
          }
        }
        if (SubIndex % 4 == 0) {
          EDBPrint (L"        ");
        }
        EDBPrint (
          L"0x%08x\n",
          CallStackEntry->Parameter[SubIndex]
          );
        EDBPrint (L"        )\n");
        //
        // break only for parameter
        //
        if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
            (Index != 0)) {
          if (SetPageBreak ()) {
            break;
          }
        }
      }
    }
  }

  //
  // Done
  //
  return EFI_DEBUG_CONTINUE;
}
示例#8
0
文件: prstat.c 项目: andreiw/polaris
int
main(int argc, char **argv)
{
	DIR *procdir;
	char *p;
	char *sortk = "cpu";	/* default sort key */
	int opt;
	int timeout;
	struct pollfd pollset;
	char key;

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);
	Progname(argv[0]);
	lwpid_init();
	fd_init(Setrlimit());

	while ((opt = getopt(argc, argv, "vcmaRLtu:U:n:p:C:P:s:S:j:k:TJz:Z"))
	    != (int)EOF) {
		switch (opt) {
		case 'R':
			opts.o_outpmode |= OPT_REALTIME;
			break;
		case 'c':
			opts.o_outpmode &= ~OPT_TERMCAP;
			opts.o_outpmode &= ~OPT_FULLSCREEN;
			break;
		case 'm':
		case 'v':
			opts.o_outpmode &= ~OPT_PSINFO;
			opts.o_outpmode |=  OPT_MSACCT;
			break;
		case 't':
			opts.o_outpmode &= ~OPT_PSINFO;
			opts.o_outpmode |= OPT_USERS;
			break;
		case 'a':
			opts.o_outpmode |= OPT_SPLIT | OPT_USERS;
			break;
		case 'T':
			opts.o_outpmode |= OPT_SPLIT | OPT_TASKS;
			break;
		case 'J':
			opts.o_outpmode |= OPT_SPLIT | OPT_PROJECTS;
			break;
		case 'n':
			if ((p = strtok(optarg, ",")) == NULL)
				Die(gettext("invalid argument for -n\n"));
			opts.o_ntop = Atoi(p);
			if (p = strtok(NULL, ","))
				opts.o_nbottom = Atoi(p);
			opts.o_outpmode &= ~OPT_FULLSCREEN;
			break;
		case 's':
			opts.o_sortorder = -1;
			sortk = optarg;
			break;
		case 'S':
			opts.o_sortorder = 1;
			sortk = optarg;
			break;
		case 'u':
			if ((p = strtok(optarg, ", ")) == NULL)
				Die(gettext("invalid argument for -u\n"));
			add_uid(&euid_tbl, p);
			while (p = strtok(NULL, ", "))
				add_uid(&euid_tbl, p);
			break;
		case 'U':
			if ((p = strtok(optarg, ", ")) == NULL)
				Die(gettext("invalid argument for -U\n"));
			add_uid(&ruid_tbl, p);
			while (p = strtok(NULL, ", "))
				add_uid(&ruid_tbl, p);
			break;
		case 'p':
			fill_table(&pid_tbl, optarg, 'p');
			break;
		case 'C':
			fill_set_table(optarg);
			opts.o_outpmode |= OPT_PSETS;
			break;
		case 'P':
			fill_table(&cpu_tbl, optarg, 'P');
			break;
		case 'k':
			fill_table(&tsk_tbl, optarg, 'k');
			break;
		case 'j':
			fill_prj_table(optarg);
			break;
		case 'L':
			opts.o_outpmode |= OPT_LWPS;
			break;
		case 'z':
			if ((p = strtok(optarg, ", ")) == NULL)
				Die(gettext("invalid argument for -z\n"));
			add_zone(&zone_tbl, p);
			while (p = strtok(NULL, ", "))
				add_zone(&zone_tbl, p);
			break;
		case 'Z':
			opts.o_outpmode |= OPT_SPLIT | OPT_ZONES;
			break;
		default:
			Usage();
		}
	}

	(void) atexit(Exit);
	if ((opts.o_outpmode & OPT_USERS) &&
	    !(opts.o_outpmode & OPT_SPLIT))
		opts.o_nbottom = opts.o_ntop;
	if (opts.o_ntop == 0 || opts.o_nbottom == 0)
		Die(gettext("invalid argument for -n\n"));
	if (!(opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode & OPT_USERS) &&
	    ((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT))))
		Die(gettext("-t option cannot be used with -v or -m\n"));

	if ((opts.o_outpmode & OPT_SPLIT) && (opts.o_outpmode && OPT_USERS) &&
	    !((opts.o_outpmode & (OPT_PSINFO | OPT_MSACCT))))
		Die(gettext("-t option cannot be used with "
		    "-a, -J, -T or -Z\n"));

	if ((opts.o_outpmode & OPT_USERS) &&
	    (opts.o_outpmode & (OPT_TASKS | OPT_PROJECTS | OPT_ZONES)))
		Die(gettext("-a option cannot be used with "
		    "-t, -J, -T or -Z\n"));

	if (((opts.o_outpmode & OPT_TASKS) &&
	    (opts.o_outpmode & (OPT_PROJECTS|OPT_ZONES))) ||
	    ((opts.o_outpmode & OPT_PROJECTS) &&
	    (opts.o_outpmode & (OPT_TASKS|OPT_ZONES)))) {
		Die(gettext("-J, -T and -Z options are mutually exclusive\n"));
	}

	if (argc > optind)
		opts.o_interval = Atoi(argv[optind++]);
	if (argc > optind)
		opts.o_count = Atoi(argv[optind++]);
	if (opts.o_count == 0)
		Die(gettext("invalid counter value\n"));
	if (argc > optind)
		Usage();
	if (opts.o_outpmode & OPT_REALTIME)
		Priocntl("RT");
	if (isatty(STDOUT_FILENO) == 1 && isatty(STDIN_FILENO))
		opts.o_outpmode |= OPT_TTY;	/* interactive */
	if (!(opts.o_outpmode & OPT_TTY)) {
		opts.o_outpmode &= ~OPT_TERMCAP; /* no termcap for pipes */
		opts.o_outpmode &= ~OPT_FULLSCREEN;
	}
	if (opts.o_outpmode & OPT_TERMCAP)
		ldtermcap();		/* can turn OPT_TERMCAP off */
	if (opts.o_outpmode & OPT_TERMCAP)
		(void) setsize();
	list_alloc(&lwps, opts.o_ntop);
	list_alloc(&users, opts.o_nbottom);
	list_alloc(&tasks, opts.o_nbottom);
	list_alloc(&projects, opts.o_nbottom);
	list_alloc(&zones, opts.o_nbottom);
	list_setkeyfunc(sortk, &opts, &lwps, LT_LWPS);
	list_setkeyfunc(NULL, &opts, &users, LT_USERS);
	list_setkeyfunc(NULL, &opts, &tasks, LT_TASKS);
	list_setkeyfunc(NULL, &opts, &projects, LT_PROJECTS);
	list_setkeyfunc(NULL, &opts, &zones, LT_ZONES);
	if (opts.o_outpmode & OPT_TERMCAP)
		curses_on();
	if ((procdir = opendir("/proc")) == NULL)
		Die(gettext("cannot open /proc directory\n"));
	if (opts.o_outpmode & OPT_TTY) {
		(void) printf(gettext("Please wait...\r"));
		(void) fflush(stdout);
	}
	set_signals();
	pollset.fd = STDIN_FILENO;
	pollset.events = POLLIN;
	timeout = opts.o_interval * MILLISEC;

	/*
	 * main program loop
	 */
	do {
		if (sigterm == 1)
			break;
		if (sigtstp == 1) {
			curses_off();
			(void) signal(SIGTSTP, SIG_DFL);
			(void) kill(0, SIGTSTP);
			/*
			 * prstat stops here until it receives SIGCONT signal.
			 */
			sigtstp = 0;
			(void) signal(SIGTSTP, sig_handler);
			curses_on();
			print_movecur = FALSE;
			if (opts.o_outpmode & OPT_FULLSCREEN)
				sigwinch = 1;
		}
		if (sigwinch == 1) {
			if (setsize() == 1) {
				list_free(&lwps);
				list_free(&users);
				list_free(&tasks);
				list_free(&projects);
				list_free(&zones);
				list_alloc(&lwps, opts.o_ntop);
				list_alloc(&users, opts.o_nbottom);
				list_alloc(&tasks, opts.o_nbottom);
				list_alloc(&projects, opts.o_nbottom);
				list_alloc(&zones, opts.o_nbottom);
			}
			sigwinch = 0;
			(void) signal(SIGWINCH, sig_handler);
		}
		prstat_scandir(procdir);
		list_refresh(&lwps);
		if (print_movecur)
			(void) putp(movecur);
		print_movecur = TRUE;
		if ((opts.o_outpmode & OPT_PSINFO) ||
		    (opts.o_outpmode & OPT_MSACCT)) {
			list_sort(&lwps);
			list_print(&lwps);
		}
		if (opts.o_outpmode & OPT_USERS) {
			list_sort(&users);
			list_print(&users);
			list_clear(&users);
		}
		if (opts.o_outpmode & OPT_TASKS) {
			list_sort(&tasks);
			list_print(&tasks);
			list_clear(&tasks);
		}
		if (opts.o_outpmode & OPT_PROJECTS) {
			list_sort(&projects);
			list_print(&projects);
			list_clear(&projects);
		}
		if (opts.o_outpmode & OPT_ZONES) {
			list_sort(&zones);
			list_print(&zones);
			list_clear(&zones);
		}
		if (opts.o_count == 1)
			break;
		/*
		 * If poll() returns -1 and sets errno to EINTR here because
		 * the process received a signal, it is Ok to abort this
		 * timeout and loop around because we check the signals at the
		 * top of the loop.
		 */
		if (opts.o_outpmode & OPT_TTY) {
			if (poll(&pollset, (nfds_t)1, timeout) > 0) {
				if (read(STDIN_FILENO, &key, 1) == 1) {
					if (tolower(key) == 'q')
						break;
				}
			}
		} else {
			(void) sleep(opts.o_interval);
		}
	} while (opts.o_count == (-1) || --opts.o_count);

	if (opts.o_outpmode & OPT_TTY)
		(void) putchar('\r');
	return (0);
}
示例#9
0
文件: main.c 项目: diegocr/AISSTBC
STATIC ULONG GetStringInt( Object * obj, STRPTR def )
{
	return((ULONG) Atoi(GetString(obj,def)));
}
示例#10
0
EFI_STATUS
StallForKey (
  IN EFI_HANDLE         ImageHandle,
  IN EFI_SYSTEM_TABLE   *SystemTable
  )
{
  EFI_STATUS      Status;
  UINTN           Argc;
  CHAR16          **Argv;
  UINTN           Seconds;
  EFI_EVENT       TimerEvent;
  EFI_EVENT       WaitList[2];
  UINTN           WaitIndex;
  EFI_INPUT_KEY   Key;

  //
  // Initialize libraries
  //
  EFI_SHELL_APP_INIT (ImageHandle, SystemTable);

  //
  // Process the arguments
  //
  Argc = SI->Argc;
  Argv = SI->Argv;

  Seconds = DEFAULT_WAIT_TIME;
  if (Argc > 1) {
    Seconds = Atoi (Argv[1]);
  }

  //
  // Create timer event
  //
  Status = BS->CreateEvent (
                 EFI_EVENT_TIMER,
                 0,
                 NULL,
                 NULL,
                 &TimerEvent
                 );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Create event. %a:%d:%r\n", __FILE__, __LINE__, Status));
    return Status;
  }

  //
  // Set up the timer
  //
  Status = BS->SetTimer (
                 TimerEvent,
                 TimerPeriodic,
                 10000000                   // 1 second
                 );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Set timer. %a:%d:%r\n", __FILE__, __LINE__, Status));
    BS->CloseEvent (TimerEvent);
    return Status;
  }

  //
  // Set up waiting list
  //
  WaitList[0] = ST->ConIn->WaitForKey;
  WaitList[1] = TimerEvent;

  //
  // Do it until timeout
  //
  while (Seconds != 0) {
    //
    // Print the prompt information (The last blank char is used to clean up
    // the last string. Don't remove it.)
    //
    Print (L"Press any key within %d seconds \r", Seconds);

    //
    // Wait for timeout or key input
    //
    Status = BS->WaitForEvent (
                   2,
                   WaitList,
                   &WaitIndex
                   );
    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_ERROR, "Wait for event. %a:%d:%r\n", __FILE__, __LINE__, Status));
      break;
    }

    //
    // Check the triggered event
    //
    if (WaitIndex == 0) {
      //
      // Key input event is triggered
      //
      Key.ScanCode = SCAN_NULL;
      Status = ST->ConIn->ReadKeyStroke (ST->ConIn, &Key);
      if (!EFI_ERROR (Status)) {
        break;
      }

      DEBUG ((EFI_D_ERROR, "Read key stroke. %a:%d:%r\n", __FILE__, __LINE__, Status));
    } else {
      //
      // Timer event is triggered
      //
      Seconds --;
    }
  }

  //
  // Close the timer event
  //
  BS->CloseEvent (TimerEvent);

  //
  // Done
  //
  if (Seconds == 0) {
    return EFI_TIMEOUT;
  } else {
    return EFI_SUCCESS;
  }
}
示例#11
0
VOID
EFIAPI
WinNtIoProtocolNotifyFunction (
  IN EFI_EVENT                Event,
  IN VOID                     *Context
  )
/*++

Routine Description:
  This function will log memory size data to data hub.

Arguments:
Event        - Event whose notification function is being invoked.
Context      - Pointer to the notification function's context.

Returns:
    EFI_STATUS.

--*/
{
  EFI_STATUS                      Status;
  EFI_MEMORY_SUBCLASS_DRIVER_DATA MemorySubClassData;
  EFI_DATA_RECORD_HEADER          *Record;
  EFI_SUBCLASS_TYPE1_HEADER       *DataHeader;
  UINTN                           HandleCount;
  UINTN                           HandleIndex;
  UINT64                          MonotonicCount;
  BOOLEAN                         RecordFound;
  EFI_HANDLE                      *HandleBuffer;
  EFI_WIN_NT_IO_PROTOCOL          *WinNtIo;
  EFI_DATA_HUB_PROTOCOL           *DataHub;
  UINT64                          TotalMemorySize;

  DataHub         = NULL;
  MonotonicCount  = 0;
  RecordFound     = FALSE;

  //
  // Retrieve the list of all handles from the handle database.
  //
  Status = gBS->LocateHandleBuffer (
                  AllHandles,
                  &gEfiWinNtIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }
  //
  // Locate DataHub protocol.
  //
  Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, &DataHub);
  if (EFI_ERROR (Status)) {
    return ;
  }
  //
  // Search the Handle array to find the meory size information.
  //
  for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
    Status = gBS->OpenProtocol (
                    HandleBuffer[HandleIndex],
                    &gEfiWinNtIoProtocolGuid,
                    &WinNtIo,
                    Context,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    if ((WinNtIo->WinNtThunk->Signature == EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) &&
        EfiCompareGuid (WinNtIo->TypeGuid, &gEfiWinNtMemoryGuid)
          ) {
      //
      // Check if this record has been stored in data hub.
      //
      do {
        Status = DataHub->GetNextRecord (DataHub, &MonotonicCount, NULL, &Record);
        if (Record->DataRecordClass == EFI_DATA_RECORD_CLASS_DATA) {
          DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);
          if (EfiCompareGuid (&Record->DataRecordGuid, &gProcessorSubClassName) &&
              (DataHeader->RecordType == EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER)
              ) {
            RecordFound = TRUE;
          }
        }
      } while (MonotonicCount != 0);

      if (RecordFound) {
        RecordFound = FALSE;
        continue;
      }
      //
      // Initialize data record.
      //
      MemorySubClassData.Header.Instance    = 1;
      MemorySubClassData.Header.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
      MemorySubClassData.Header.RecordType  = EFI_MEMORY_ARRAY_START_ADDRESS_RECORD_NUMBER;

      TotalMemorySize                       = (UINT64) Atoi (WinNtIo->EnvString);

      MemorySubClassData.Record.ArrayStartAddress.MemoryArrayStartAddress               = 0;
      MemorySubClassData.Record.ArrayStartAddress.MemoryArrayEndAddress                 = LShiftU64 (TotalMemorySize, 20) - 1;
      MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.ProducerName  = gMemoryProducerGuid;
      MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.Instance      = 1;
      MemorySubClassData.Record.ArrayStartAddress.PhysicalMemoryArrayLink.SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;
      MemorySubClassData.Record.ArrayStartAddress.MemoryArrayPartitionWidth = 0;

      //
      // Store memory size data record to data hub.
      //
      Status = DataHub->LogData (
                          DataHub,
                          &gEfiMemorySubClassGuid,
                          &gMemoryProducerGuid,
                          EFI_DATA_RECORD_CLASS_DATA,
                          &MemorySubClassData,
                          sizeof (EFI_SUBCLASS_TYPE1_HEADER) + sizeof (EFI_MEMORY_ARRAY_START_ADDRESS)
                          );
    }

    gBS->CloseProtocol (
          HandleBuffer[HandleIndex],
          &gEfiWinNtIoProtocolGuid,
          Context,
          NULL
          );
  }
}