Hi all!
I tried to build a module to detect vmware. Attached is the module and a test 
grub.cfg
It is basically working though I have some questions:

can i use the return value of the function (e.g. vmware_detect) to give back a 
value or am I supposed to always return something like GRUB_ERR_NONE?

is there a script to add a module to the makefile or do I have to copy/paste 
it?

if I use this:
        if vmware_detect = 1; then set foo=1 else set foo=0 fi
I get syntax error and unknown command in an infinite loop is this expected? 
It should not be a problem with my module, as it also happend while testing a 
environment variable.
So, is it a problem with my if-syntax?

greetings
 Martin

PS:*ahem* I tested against 1.95+20070604 of the debian tree. I will test 
against current cvs as soon as possible  / as soon as someone tells me how to 
automate the makefile updating
insmod vmware-detect
vmware_detect
set default=2
if vmware = 0; then set default=1 else set default=0 fi
menuentry "nummer0" {
 linux (hd0,6)/boot/vmlinuz
}
menuentry "nummer1" {
 linux (hd0,6)/boot/vmlinuz
}
 
/* vmware-detect.c - module to detect vmware  */
/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2007 Martin Haaß
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  VMWARE detection code taken from 
 *  http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
 */

#include <grub/normal.h>
#include <grub/dl.h>
#include <grub/arg.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/env.h>

//this gives a warning, but looks more fancy than VMWARE_MAGIC 0x564D5868
#define VMWARE_MAGIC 'VMXh'
#define VMWARE_COMMAND_GETVERSION 0x000a
#define VMWARE_PORTNUMBER 0x5658 


static void vmware_getversion( unsigned int *version_number, unsigned int *magic_number, 
                               unsigned int *product_type) 
{
  grub_dprintf ("vmware","requesting vmware version\n"); 
 
  //reference for this is given at top of file,
  //no further magic involved than inline asm
  __asm__("inl %%dx, %%eax\n\t"
          //outputs
          : "=a" (*version_number),
            "=b" (*magic_number),
            "=c" (*product_type)
          //inputs
          : "a" (VMWARE_MAGIC),
            "b" (0),
            "c" (VMWARE_COMMAND_GETVERSION),
            "d" (VMWARE_PORTNUMBER)
  );
  grub_dprintf("vmware","magic:0x%x, version:0x%x, product 0x%x\n",*magic_number, *version_number, *product_type);
}

static grub_err_t
grub_cmd_vmwaredetect (struct grub_arg_list *state __attribute__ ((unused)),
		int argc __attribute__ ((unused)),
		char **args __attribute__ ((unused)))
{
  unsigned int version_number; 
  unsigned int magic_number;
  unsigned int product_type;

  vmware_getversion(&version_number,&magic_number,&product_type);
  if (magic_number == VMWARE_MAGIC) {
    grub_dprintf("vmware","inside in a vmware\n");
    grub_env_set("vmware","1");
    return 1;
  } else {
    grub_dprintf("vmware","not in a vmware\n");
    grub_env_set("vmware","0");
    return 0;
  }
}

static grub_err_t
    grub_cmd_vmwareversion (struct grub_arg_list *state __attribute__ ((unused)),
                           int argc __attribute__ ((unused)),
                               char **args __attribute__ ((unused)))
{
  unsigned int version_number; 
  unsigned int magic_number;
  unsigned int product_type;

  vmware_getversion(&version_number,&magic_number,&product_type);  
  if (magic_number == VMWARE_MAGIC) {
    grub_dprintf("vmware","version number 0x%x\n",version_number);
    return version_number;
  } else {
    grub_dprintf("vmware","not in a vmware\n");
    return 0;
  }
}

static grub_err_t
    grub_cmd_vmwaretype (struct grub_arg_list *state __attribute__ ((unused)),
                           int argc __attribute__ ((unused)),
                               char **args __attribute__ ((unused)))
{
  unsigned int version_number; 
  unsigned int magic_number;
  unsigned int product_type;

  vmware_getversion(&version_number,&magic_number,&product_type);
  if (magic_number == VMWARE_MAGIC) {
    grub_dprintf("vmware","product type 0x%x\n",product_type);
    return product_type;
  }  else {
    grub_dprintf("vmware","not in a vmware\n");
    return 0;
  }
}

GRUB_MOD_INIT(vmwaredetect)
{
  (void)mod;			/* To stop warning. */
  grub_register_command ("vmware_detect", grub_cmd_vmwaredetect, GRUB_COMMAND_FLAG_BOTH,
                         "vmware_detect", "returns 1 if inside vmware, 0 otherwise. "
                         "set debug=\"vmware\" to see more", 0);
  grub_register_command ("vmware_version", grub_cmd_vmwareversion, GRUB_COMMAND_FLAG_BOTH,
                         "vmware_version", "returns version number(always 6?)", 0);
  grub_register_command ("vmware_type", grub_cmd_vmwaretype, GRUB_COMMAND_FLAG_BOTH,
                         "vmware_type", "returns product type", 0);
}

GRUB_MOD_FINI(vmwaredetect)
{
  grub_unregister_command ("vmware_detect");
  grub_unregister_command ("vmware_version");
  grub_unregister_command ("vmware_type");
}
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to