PHP Processor Feature Checker

x BlueRobot

Administrator
Staff member
Joined
May 7, 2013
Posts
10,400
This is just a very small program which I wrote for fun; I haven't written any code for a long while, so there is probably a better method for implementing this.

Code:
#include <Windows.h>
#include <iostream>

int main() {

    int PAE_Support;
    int ProcessorChannel_Support;
    int NXBit_Support;
    int User_Choice;
    int User_Exit;

    while (User_Exit != 4) {

    std::cout << "Welcome to the Prcoessor Feature Checker!\n";
    std::cout << '\n';
    std::cout << "Which feature would like to check?\n";
    std::cout << '\n';
    std::cout << "1.PAE Support\n" << "2.Processor Channel Support\n" << "3.DEP Support\n" << "4.Exit\n";
    std::cout << '\n';
    std::cout << "Please select an option: ";
    std::cin >> User_Choice;
    std::cin.ignore();
    std::cout << '\n';

    switch (User_Choice) {

    case 1:

    PAE_Support = IsProcessorFeaturePresent(9);
    if (PAE_Support == 1) {

    std::cout << "PAE is supported on this processor.\n";
    std::cout << '\n';
    }

    else {

        std::cout << "PAE is not supported on this processor.\n";
        std::cout << '\n';
    }
    break;

    case 2:
        ProcessorChannel_Support = IsProcessorFeaturePresent(16);
        if (ProcessorChannel_Support == 1) {

        std::cout << "Processor Channels are enabled for this processor.\n";
        std::cout << '\n';
    }
    else {

        std::cout << "Processor Channels are disabled for this processor.\n";
        std::cout << '\n';
    }
    break;

    case 3: 
        NXBit_Support = IsProcessorFeaturePresent(12);
            if (NXBit_Support == 1) {

        std::cout << "Data Execution Protection is supported on this processor.\n";
        std::cout << '\n';
    }
    else {

        std::cout << "Data Execution Protection is not supported on this processor.\n";
        std::cout << '\n';
    }
        break;
    case 4:

        std::exit(EXIT_SUCCESS);
        break;
    }
    }

    std::cin.get();

    return 0;

}
 
Harry, rather than writing std::cout & std::cin everytime, why don't you just write the following line below the pre-processor directives?

Code:
using namespace std;

This way, you won't require std:: before cin & cout. They would work directly.


EDIT: How about adding if Virtualization is supported or not?:thumbsup2:
 
It's something which has always stayed with me, I would probably only use the entire namespace if I was using hundreds of functions defined in that namespace, and knew that program wouldn't be updated either.
 
If you write 'using namespace std;' it defeats the purpose of having namespaces really, and introduces a greater possibility of name conflicts, along with namespace pollution.

Some considerations:

1. Check the result of the insertion operation to see whether input was valid or not. If input was invalid, the stream sets the fail() bit and enters an invalid state, but the variable doesn't contain any usable value consequently either, and the stream still contains junk data that remains there.
2. Use more functions to separate things better
3. instead of writing 'std::cout << '\n';' in each code branch, you could remove all of them, and write it at the end of the loop after the switch statement to produce the same effect with less code written. Repeated code is not good.
4. You have std::cin.get() and return 0 after the while loop, which will never be executed because of the std::exit(0) call you have which make them both redundant lines of code
5. You've included <windows.h> why not use the actual predefined identifiers instead of their numeric values when you call the IsProcessorFeaturePresent function? Ex: IsProcessorFeaturePresent(PF_PAE_ENABLED), etc...
6. Why do you need all of these variables:
Code:
int PAE_Support;
  int ProcessorChannel_Support;
  int NXBit_Support;

You only use them to set the return from the function call, and they are only used once each to determine whether a feature is present or not. Instead, you could have just put the function within the if statement conditional, or used ONE variable to hold the return value, and use that to check what to output to stdout. Ex: *with better formatting; not all on a single line of course
Code:
if (IsProcessorFeaturePresent(PF_PAE_ENABLED)) { ... } else { ... }

7. The return of the function is already a BOOL -> you shouldn't have to compare to 1 with the == operator (see example in code snippet above where I call the function within the if statement conditional directly).
8. If you call std::exit(), no further code will be executed, therefore a break; statement is redundant here:
Code:
std::exit(EXIT_SUCCESS);
        break;

Keep up the good work though :)
 
Last edited:
Thank you Ace, here is the improved version:

Code:
#include <Windows.h>
#include <iostream>
#include <cctype>

void main() {
    
    int User_Choice;
    char User_Choice2;

    while (User_Choice != 5) {

    std::cout << "Welcome to the Prcoessor Feature Checker!\n";
    std::cout << '\n';
    std::cout << "Which feature would like to check?\n";
    std::cout << '\n';
    std::cout << "1.PAE Support\n" << "2.Processor Channel Support\n" << "3.DEP Support\n" << "4.Virtualisation\n" << "5.Exit\n";
    std::cout << '\n';
    std::cout << "Please select an option: ";
    std::cin >> User_Choice;
    std::cin.ignore();
    std::cout << '\n';

    if (User_Choice < 6 && User_Choice > 0) {

        Menu_Switch:
        
        switch (User_Choice) {

    case 1:

    if (IsProcessorFeaturePresent(PF_PAE_ENABLED)) {

    std::cout << "PAE is supported on this processor.\n";
    }

    else {

        std::cout << "PAE is not supported on this processor.\n";
        }
    break;

    case 2:
        if (IsProcessorFeaturePresent(PF_CHANNELS_ENABLED)) {

        std::cout << "Processor Channels are enabled for this processor.\n";
        }
    else {

        std::cout << "Processor Channels are disabled for this processor.\n";
        }
    break;

    case 3: 
        if (IsProcessorFeaturePresent(PF_NX_ENABLED)) {

        std::cout << "Data Execution Protection is supported on this processor.\n";
        }
    else {

        std::cout << "Data Execution Protection is not supported on this processor.\n";
        }
        break;
    case 4:
        if (IsProcessorFeaturePresent(21)) {
            std::cout << "Virtualisation is supported on this processor.\n";
        }
        else { 
            std::cout << "Virtualisation is not supported on this processor.\n";
        }
        break;
    case 5:
        std::exit(EXIT_SUCCESS);
        }
    }
    else {
        std::cin.clear();
        std::cout << "Clearing the input buffer...\n";
        std::cout << "Please press the Enter key to continue";
        std::cin.ignore(INT_MAX, '\n');
        std::cout << "Please enter a valid value (1 to 5): ";
        std::cin >> User_Choice;
        goto Menu_Switch;
        }
    
    std::cout << '\n';

    std::cout << "Would you like to try another option?\n";
    std::cout << "Please enter Y/N: ";
    std::cin >> User_Choice2;
    std::cin.ignore();
    std::cout << '\n';

    while (!isalpha(User_Choice2)) {
        std::cin.clear();
        std::cout << "Clearing the input buffer...\n";
        std::cout << "Please press the Enter key to continue";
        std::cin.ignore(INT_MAX, '\n');
        std::cout << "Please enter Y/N: ";
        std::cin >> User_Choice2;
        std::cout << '\n';
    }

    if (User_Choice2 != 'Y'){

        std::exit(EXIT_SUCCESS);
    }

    }
}

Please tell me if I've made any mistakes, or there is other methods.
 
I would replace this:
Code:
if (IsProcessorFeaturePresent(21))
with this:
Code:
if (IsProcessorFeaturePresent(PF_VIRT_FIRMWARE_ENABLED))
for consistency.

I would also change how you do your logic to exit the program, currently it is a bit clunky and awkward.

other than that looks solid. :thumbsup2:
 
I did use the PF_VIRT_FIRMWARE_ENABLED originally, but then the compiler threw a undefined error for some reason :noidea:

I'll think of some better logic tomorrow, but thanks for the recommended edits.
 
What compiler are you using? Are you sure about the spelling? Also, just FYI:
Code:
[plain]std::cout << "1.PAE Support\n" << "2.Processor Channel Support\n" << "3.DEP Support\n" << "4.Virtualisation\n" << "5.Exit\n";[/plain]

You can write that like this too:
Code:
[plain]std::cout << "1.PAE Support\n"
              "2.Processor Channel Support\n"
              "3.DEP Support\n"
              "4.Virtualisation\n"
              "5.Exit\n";[/plain]

It is valid code, and it makes it much cleaner. :)

This is also redundant:
Code:
if (User_Choice < 6 && User_Choice > 0)

If you use a default: case within the switch statement, anything not marked in any of the case statements will branch to the default code branch.

Code:
goto Menu_Switch;

AVOID goto's at all costs too... They are bad.

Also:
Code:
std::cin.ignore(INT_MAX, '\n');

The possible max is that of the std::streamsize datatype, not INT_MAX.

For input:
Code:
std::cin >> User_Choice;

You should check the state of the stream after using the >> operator, especially if you're dealing with std::cin as it can fail, and it's not a disposable stream as opposed to if you were to create a new std::istringstream on your own to use for parsing user input. That may look something like this:
Code:
#include <iostream>
#include <limits>

int main()
{
  int n = 0;
  while (!(std::cin >> n))
  {
    std::cerr << "Invalid input, try again..." << std::endl;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  }
  std::cout << "n = " << n << std::endl;
}

Lastly, and most importantly, NEVER EVER use 'void main()'
Code:
void main() {

avatar40_2.gif


int main() is the proper prototype. :thumbsup2:
 
Last edited:
Wow, look at the information present on this thread!

@Ace - I didn't know about that way of writing multiple statements with cout :0

Like Ace has mentioned Harry, it is a bad practice to use GOTO. If you happen to use GOTO anyways -
Code:
else {
        std::cin.clear();
        std::cout << "Clearing the input buffer...\n";
        std::cout << "Please press the Enter key to continue";
        std::cin.ignore(INT_MAX, '\n');
        std::cout << "Please enter a valid value (1 to 5): ";
        std::cin >> User_Choice;
        goto Menu_Switch;
        }
The above code will take input from the user and directly go to Menu_Switch label without actually verifying the input of the user which could lead to a loop.
 
@blueelvis: It's the way I construct version strings sometimes. :)
Ex:
Code:
#define VERSION "1.2.3.4"
Code:
"Application Version: " VERSION
* Same as "Application Version: " "1.2.3.4" or...
"Application Version: 1.2.3.4"

This is not a *feature* with std::cout, but rather c-style strings in general.

Also, the only time I find a goto absolutely necessary is if you are required to optimize code involving nested loops.
Code:
[NO-PARSE]int main()
{
  while (condition)
  {
    for (int i = 0; i < ??; ++i)
    {
      for (int j = i + 1; i < ?? || something(j); ++i)
      {
        if (some_other_condition(??)) goto outerscope;
      }
    }
  }

  outerscope:
  func();
}[/NO-PARSE]

Now this saves you from setting a boolean and checking that condition multiple times to break from each inner scope until you get to where you want to be.
 
Last edited:
I'm using Visual Studio 2010 Professional Edition. Furthermore, the max() function highlighted an error called error: expected a identifier. From what I read here, I used the

Code:
#undef max

and the code now works.

Code:
#include <Windows.h>
#include <iostream>
#include <cctype>
#include <limits>

#undef max

int main() {
    
    int User_Choice;
    char User_Choice2;

    while (User_Choice != 5) {

    std::cout << "Welcome to the Prcoessor Feature Checker!\n";
    std::cout << '\n';
    std::cout << "Which feature would like to check?\n";
    std::cout << '\n';
    std::cout << "1.PAE Support\n" 
                 "2.Processor Channel Support\n" 
                 "3.DEP Support\n"  
                 "4.Virtualisation\n"
                 "5.Exit\n";
    std::cout << '\n';
    std::cout << "Please select an option: ";
    std::cin >> User_Choice;
    std::cin.ignore();
    std::cout << '\n';

    switch (User_Choice) {

    case 1:

    if (IsProcessorFeaturePresent(PF_PAE_ENABLED)) {

    std::cout << "PAE is supported on this processor.\n";
    }

    else {

        std::cout << "PAE is not supported on this processor.\n";
        }
    break;

    case 2:
        if (IsProcessorFeaturePresent(PF_CHANNELS_ENABLED)) {

        std::cout << "Processor Channels are enabled for this processor.\n";
        }
    else {

        std::cout << "Processor Channels are disabled for this processor.\n";
        }
    break;

    case 3: 
        if (IsProcessorFeaturePresent(PF_NX_ENABLED)) {

        std::cout << "Data Execution Protection is supported on this processor.\n";
        }
    else {

        std::cout << "Data Execution Protection is not supported on this processor.\n";
        }
        break;
    case 4:
        if (IsProcessorFeaturePresent(21)) {
            std::cout << "Virtualisation is supported on this processor.\n";
        }
        else { 
            std::cout << "Virtualisation is not supported on this processor.\n";
        }
        break;
    case 5:
        std::exit(EXIT_SUCCESS);
        
        default: 
            std::cout << "Error, invalid value!\n";
            std::cin.clear();
            std::cout << "Clearing the input buffer...\n";
            std::cout << "Please press the Enter key to continue";
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Please enter a valid value (1 to 5): ";
            std::cin >> User_Choice;
        }
    
    
    std::cout << '\n';

    std::cout << "Would you like to try another option?\n";
    std::cout << "Please enter Y/N: ";
    std::cin >> User_Choice2;
    std::cin.ignore();
    std::cout << '\n';

    if (User_Choice2 != 'Y'){

        std::exit(EXIT_SUCCESS);
    }
    }

    while (!isalpha(User_Choice2)) {
        std::cout << "Error, invalid value!\n";
        std::cin.clear();
        std::cout << "Clearing the input buffer...\n";
        std::cout << "Please press the Enter key to continue";
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "Please enter Y/N: ";
        std::cin >> User_Choice2;
        std::cout << '\n';
    }

    

    }
 
I'm using Visual Studio 2010 Professional Edition. Furthermore, the max() function highlighted an error called error: expected a identifier. From what I read here, I used the

Code:
#undef max

and the code now works.

Code:
#include <Windows.h>
#include <iostream>
#include <cctype>
#include <limits>

#undef max

int main() {
    
    int User_Choice;
    char User_Choice2;

    while (User_Choice != 5) {

    std::cout << "Welcome to the Prcoessor Feature Checker!\n";
    std::cout << '\n';
    std::cout << "Which feature would like to check?\n";
    std::cout << '\n';
    std::cout << "1.PAE Support\n" 
                 "2.Processor Channel Support\n" 
                 "3.DEP Support\n"  
                 "4.Virtualisation\n"
                 "5.Exit\n";
    std::cout << '\n';
    std::cout << "Please select an option: ";
    std::cin >> User_Choice;
    std::cin.ignore();
    std::cout << '\n';

    switch (User_Choice) {

    case 1:

    if (IsProcessorFeaturePresent(PF_PAE_ENABLED)) {

    std::cout << "PAE is supported on this processor.\n";
    }

    else {

        std::cout << "PAE is not supported on this processor.\n";
        }
    break;

    case 2:
        if (IsProcessorFeaturePresent(PF_CHANNELS_ENABLED)) {

        std::cout << "Processor Channels are enabled for this processor.\n";
        }
    else {

        std::cout << "Processor Channels are disabled for this processor.\n";
        }
    break;

    case 3: 
        if (IsProcessorFeaturePresent(PF_NX_ENABLED)) {

        std::cout << "Data Execution Protection is supported on this processor.\n";
        }
    else {

        std::cout << "Data Execution Protection is not supported on this processor.\n";
        }
        break;
    case 4:
        if (IsProcessorFeaturePresent(21)) {
            std::cout << "Virtualisation is supported on this processor.\n";
        }
        else { 
            std::cout << "Virtualisation is not supported on this processor.\n";
        }
        break;
    case 5:
        std::exit(EXIT_SUCCESS);
        
        default: 
            std::cout << "Error, invalid value!\n";
            std::cin.clear();
            std::cout << "Clearing the input buffer...\n";
            std::cout << "Please press the Enter key to continue";
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            std::cout << "Please enter a valid value (1 to 5): ";
            std::cin >> User_Choice;
        }
    
    
    std::cout << '\n';

    std::cout << "Would you like to try another option?\n";
    std::cout << "Please enter Y/N: ";
    std::cin >> User_Choice2;
    std::cin.ignore();
    std::cout << '\n';

    if (User_Choice2 != 'Y'){

        std::exit(EXIT_SUCCESS);
    }
    }

    while (!isalpha(User_Choice2)) {
        std::cout << "Error, invalid value!\n";
        std::cin.clear();
        std::cout << "Clearing the input buffer...\n";
        std::cout << "Please press the Enter key to continue";
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::cout << "Please enter Y/N: ";
        std::cin >> User_Choice2;
        std::cout << '\n';
    }

    

    }

Visual studio has a 'max' macro defined if you're using <windows.h>, don't undefine it like that though, the proper way to remove it is to define NOMINMAX before including <windows.h>
Code:
[plain]#define NOMINMAX
#include <Windows.h>[/plain]

And now both 'max' and 'min' macros are not defined in the first place, and you don't have to worry about it being defined through <windows.h> then undefined within your code. You don't need them anyways, and if you do, you can create your own macros with better and more unique identifiers using your own calculation method (ternary operator does the trick for the naïve programmer), otherwise C++ has std::min() and std::max(), among others.

I hope this helps you out! Cheers friend :)
 
Last edited:

Has Sysnative Forums helped you? Please consider donating to help us support the site!

Back
Top