/*
 * Command line Registry implementation
 *
 * Copyright 1999 Sylvain St-Germain
 *
 * Note: Please consult the README file for more information.
 *
 */

#include <stdio.h>
#include <malloc.h>
#include <windows.h>
#include <winreg.h>
#include <winerror.h>
#include <winnt.h>
#include <string.h>
#include <shell.h>

/******************************************************************************
 * Defines and consts
 */
#define IDENTICAL             0 
#define COMMAND_COUNT         5

#define KEY_MAX_LEN           1024 
#define STDIN_MAX_LEN         2048

/* Return values */
#define COMMAND_NOT_FOUND     -1
#define SUCCESS               0
#define NOT_ENOUGH_MEMORY     1
#define KEY_VALUE_ALREADY_SET 2
#define COMMAND_NOT_SUPPORTED 3

/* Generic global */
static BOOL bForce            = FALSE; /* Is set to TRUE when -force is
                                          passed on the command line */

/* Globals used by the api setValue, queryValue */
static LPSTR currentKeyName   = NULL;
static HKEY  currentKeyClass  = NULL;
static HKEY  currentKeyHandle = NULL;
static BOOL  bTheKeyIsOpen    = FALSE;

/* Delimitors used to parse the "value"="data" pair for setValue*/
#define SET_VALUE_MAX_ARGS    2 
/* Delimitors used to parse the "value" to query queryValue*/
#define QUERY_VALUE_MAX_ARGS  1 

static const char *setValueDelim[SET_VALUE_MAX_ARGS]   = {"=", ""};  
static const char *queryValueDelim[QUERY_VALUE_MAX_ARGS]   = {""};  

/* Array used to extract the data type from a string in getDataType. */
typedef struct tagDataTypeMap
{
  char  mask[15];
  DWORD dataType;
} dataTypeMap; 
  
static const dataTypeMap typeMap[] = 
{
  {"hex:",            REG_BINARY},/* could be REG_NONE (?) */
  {"dword:",          REG_DWORD},
  {"hex(0):",         REG_NONE},
  {"hex(1):",         REG_SZ},
  {"hex(2):",         REG_EXPAND_SZ},
  {"hex(3):",         REG_BINARY},
  {"hex(4):",         REG_DWORD},
  {"hex(5):",         REG_DWORD_BIG_ENDIAN},
  {"hex(6):",         REG_LINK},
  {"hex(7):",         REG_MULTI_SZ},
  {"hex(8):",         REG_RESOURCE_LIST},
  {"hex(9):",         REG_FULL_RESOURCE_DESCRIPTOR},
  {"hex(80000000):",  REG_NONE},
  {"hex(80000001):",  REG_SZ},
  {"hex(80000002):",  REG_EXPAND_SZ},
  {"hex(80000003):",  REG_BINARY},
  {"hex(80000004):",  REG_DWORD},
  {"hex(80000005):",  REG_DWORD_BIG_ENDIAN},
  {"hex(80000006):",  REG_LINK},
  {"hex(80000007):",  REG_MULTI_SZ},
  {"hex(80000008):",  REG_RESOURCE_LIST},
  {"hex(80000009):",  REG_FULL_RESOURCE_DESCRIPTOR},
  {"hex(8000000a):",  REG_BINARY}, /* REG_RESOURCE_REQUIREMENTS_LIST}, !Exist */
  {"hex(8000000A):",  REG_BINARY}, /* REG_RESOURCE_REQUIREMENTS_LIST}, !Exist */
};
const static int LAST_TYPE_MAP = sizeof(typeMap)/sizeof(dataTypeMap);


/* 
 * Forward declaration 
 */
typedef void (*commandAPI)(LPSTR lpsLine);

static void doSetValue(LPSTR lpsLine);
static void doDeleteValue(LPSTR lpsLine);
static void doCreateKey(LPSTR lpsLine);
static void doDeleteKey(LPSTR lpsLine);
static void doQueryValue(LPSTR lpsLine);

/*
 * current suuported api
 */
static const char* commandNames[COMMAND_COUNT] = {
  "setValue", 
  "deleteValue", 
  "createKey",
  "deleteKey",
  "queryValue"
};

/*
 * Pointers to processing entry points
 */
static const commandAPI commandAPIs[COMMAND_COUNT] = {
  doSetValue, 
  doDeleteValue, 
  doCreateKey,
  doDeleteKey,
  doQueryValue
};

/* 
 * This array controls the registry saving needs at the end of the process 
 */
static const BOOL commandSaveRegistry[COMMAND_COUNT] = {
  TRUE,
  TRUE,
  TRUE,
  TRUE,
  FALSE
};

/* 
 * Generic prototyes
 */
static HKEY    getDataType(LPSTR *lpValue);
static LPSTR   getRegKeyName(LPSTR lpLine);
static HKEY    getRegClass(LPSTR lpLine);
static LPSTR   getArg(LPSTR arg);
static INT     getCommand(LPSTR commandName);
static DWORD   convertHexToDWord(char *str, BYTE *buf);
static DWORD   convertHexCSVToHex(char *str, BYTE *buf, ULONG bufLen);
static LPSTR   convertHexToHexCSV( BYTE *buf, ULONG len);
static LPSTR   convertHexToDWORDStr( BYTE *buf, ULONG len);
static HRESULT openKey(LPSTR stdInput);
static void    closeKey();

/* 
 * api setValue prototypes
 */
static void    processSetValue(LPSTR cmdline);
static HRESULT setValue(LPSTR *argv);

/* 
 * api queryValue prototypes
 */
static void    processQueryValue(LPSTR cmdline);

/*
 * Help Text displyed when invalid parameters are provided
 */
static char helpText[] = "
NAME
          regapi - provide a command line interface to the wine registry.

SYNOPSYS
          regapi commandName [-force] < file

DESCRIPTION
          regapi allows editing the wine resgistry.  It processes the given 
          commandName for every line in the stdin data stream.  Input data 
          format may vary depending on the commandName see INPUT FILE FORMAT.

OPTIONS
          commandName
              Instruct regapi about what action to perform on the data stream.
              Currently, only setValue and queryValue are supported and 
              implemented.

          -force 
              When provided the action will be performed anyway.  This may 
              have a different meaning depending on the context.  For example,
              when providing -force to setValue, the value is set even if it 
              was previously set to another value.

          < file
              STDIN chanel, provide a file name with line of the appropriate
              format.

INPUT FILE FORMAT

          setValue
              The input file format required by the setValue command is similar
              to the one obtained from regedit.exe export option.  The only 
              difference is that multi line values are not supported, the 
              value data must be on a single line.

              [KEY_CLASS\\Some\\Path\\For\\A\\Key]
              \"Value1\"=\"Data1\"
              \"Value2\"=\"Data2\"
              \"Valuen\"=\"Datan\"
              ...

          queryValue
              The input file format required by the queryValue command is 
              similar to the one required by setValue.  The only 
              difference is that you only provide the value name.

              [KEY_CLASS\\Some\\Path\\For\\A\\Key]
              \"Value1\"
              \"Value2\"
              \"Valuen\"
              ...
                                February 1999.
";
              

/******************************************************************************
 * This funtion returns the HKEY associated with the data type encoded in the 
 * value.  It modify the input parameter (key value) in order to skip this 
 * "now useless" data type information.
 */
HKEY getDataType(LPSTR *lpValue) 
{
  INT   counter  = 0;
  DWORD dwReturn = REG_SZ;

  for (; counter < LAST_TYPE_MAP; counter++)
  {
    LONG len = strlen(typeMap[counter].mask);
    if ( strncmp( *lpValue, typeMap[counter].mask, len) == IDENTICAL)
    {
      /*
       * We found it, modify the value's pointer in order to skip the data 
       * type identifier, set the return value and exit the loop.
       */
      (*lpValue) += len;
      dwReturn    = typeMap[counter].dataType;
      break; 
    }
  }

  return dwReturn;
}
/******************************************************************************
 * Extracts from a [HKEY\some\key\path] type of line the key name (what starts 
 * after the first '\' and end before the ']'
 */
LPSTR getRegKeyName(LPSTR lpLine) 
{
  LPSTR keyNameBeg = NULL;
  LPSTR keyNameEnd = NULL;
  char  lpLineCopy[KEY_MAX_LEN];

  if (lpLine == NULL)
    return NULL;

  strcpy(lpLineCopy, lpLine);

  keyNameBeg  = strstr(lpLineCopy, "\\");  /* The key name start by '\' */
  keyNameBeg++;                            /* but is not part of the key name */
  keyNameEnd  = strstr(lpLineCopy, "]");   /* The key name end by ']' */
  *keyNameEnd = NULL;                      /* Isolate the key name */
 
  currentKeyName = HeapAlloc(GetProcessHeap(), 0, strlen(keyNameBeg)+1);
  if (currentKeyName != NULL)
    strcpy(currentKeyName, keyNameBeg);
 
  return currentKeyName;
}

/******************************************************************************
 * Extracts from a [HKEY/some/key/path] type of line the key class (what 
 * starts after the '[' and end before the first '\'
 */
static HKEY getRegClass(LPSTR lpClass) 
{
  LPSTR classNameEnd;
  LPSTR classNameBeg;

  char  lpClassCopy[KEY_MAX_LEN];
  
  if (lpClass == NULL)
    return ERROR_INVALID_PARAMETER;

  strcpy(lpClassCopy, lpClass);

  classNameEnd  = strstr(lpClassCopy, "\\");  /* The class name end by '\' */
  *classNameEnd = NULL;                       /* Isolate the class name */
  classNameBeg  = &lpClassCopy[1];            /* Skip the '[' */
  
  if      (strcmp( classNameBeg, "HKEY_LOCAL_MACHINE") == IDENTICAL )
    return  HKEY_LOCAL_MACHINE;
  else if (strcmp( classNameBeg, "HKEY_USERS") == IDENTICAL )
    return  HKEY_USERS;
  else if (strcmp( classNameBeg, "HKEY_CLASSES_ROOT") == IDENTICAL )
    return  HKEY_CLASSES_ROOT;
  else if (strcmp( classNameBeg, "HKEY_CURRENT_CONFIG") == IDENTICAL )
    return  HKEY_CURRENT_CONFIG;
  else if (strcmp( classNameBeg, "HKEY_CURRENT_USER") == IDENTICAL )
    return  HKEY_CURRENT_USER;
  else
    return ERROR_INVALID_PARAMETER;
}

/******************************************************************************
 * Returns an allocated buffer with a cleaned copy (removed the surrounding 
 * dbl quotes) of the passed value.
 */
static LPSTR getArg( LPSTR arg)
{
  LPSTR tmp = NULL;
  ULONG len;

  if (arg == NULL)
    return NULL;

  /*
   * Get rid of surrounding quotes
   */
  len = strlen(arg); 

  if( arg[len-1] == '\"' ) arg[len-1] = NULL;
  if( arg[0]     == '\"' ) arg++;

  tmp = HeapAlloc(GetProcessHeap(), 0, strlen(arg)+1);
  strcpy(tmp, arg);

  return tmp;
}

/******************************************************************************
 * Returns the index in the commands array of the command to process.
 */
static INT getCommand(LPSTR commandName)
{
  INT count;
  for (count=0; count < COMMAND_COUNT; count++)
    if ( strcmp(commandName, commandNames[count]) == IDENTICAL) 
      return count;

  return COMMAND_NOT_FOUND;
}

/******************************************************************************
 * Converts a hex representation of a DWORD into a DWORD.
 */
static DWORD convertHexToDWord(char *str, BYTE *buf)
{
  char  *s        = str;  /* Pointer to current */
  char  *b        = buf;  /* Pointer to result  */
  ULONG strPos    = 0;    

  memset(buf, 0, 4);

  while (strPos < 4)  /* 8 byte in a DWORD */
  {
    char xbuf[3];
    char wc;

    memcpy(xbuf,s,2); xbuf[2]='\0';
    sscanf(xbuf,"%02x",(UINT*)&wc);
    *b++ =(unsigned char)wc;

    s+=2;
    strPos+=1;
  }                                   

  return 4; /* always 4 byte for the word */
}

/******************************************************************************
 * Converts a hex buffer into a hex coma separated values 
 */
static char* convertHexToHexCSV(BYTE *buf, ULONG bufLen)
{
  char* str;
  char* ptrStr;
  BYTE* ptrBuf;

  ULONG current = 0;

  str    = HeapAlloc(GetProcessHeap(), 0, (bufLen+1)*2);
  memset(str, 0, (bufLen+1)*2);
  ptrStr = str;  /* Pointer to result  */
  ptrBuf = buf;  /* Pointer to current */

  while (current < bufLen)
  {
    BYTE bCur = ptrBuf[current++];
    char res[3];

    sprintf(res, "%02x", (unsigned int)*&bCur);
    strcat(str, res);
    strcat(str, ",");
  }                                   

  /* Get rid of the last coma */
  str[strlen(str)-1] = NULL;
  return str;
}

/******************************************************************************
 * Converts a hex buffer into a DWORD string
 */
static char* convertHexToDWORDStr(BYTE *buf, ULONG bufLen)
{
  char* str;
  char* ptrStr;
  BYTE* ptrBuf;

  ULONG current = 0;

  str    = HeapAlloc(GetProcessHeap(), 0, (bufLen*2)+1);
  memset(str, 0, (bufLen*2)+1);
  ptrStr = str;  /* Pointer to result  */
  ptrBuf = buf;  /* Pointer to current */

  while (current < bufLen)
  {
    BYTE bCur = ptrBuf[current++];
    char res[3];

    sprintf(res, "%02x", (unsigned int)*&bCur);
    strcat(str, res);
  }                                   

  /* Get rid of the last coma */
  return str;
}
/******************************************************************************
 * Converts a hex coma separated values list into a hex list.
 */
static DWORD convertHexCSVToHex(char *str, BYTE *buf, ULONG bufLen)
{
  char *s = str;  /* Pointer to current */
  char *b = buf;  /* Pointer to result  */

  ULONG strLen    = strlen(str);
  ULONG strPos    = 0;
  DWORD byteCount = 0;

  memset(buf, 0, bufLen);

  /*
   * warn the user if we are here with a string longer than 2 bytes that does
   * not contains ",".  It is more likely because the data is invalid.
   */
  if ( ( strlen(str) > 2) && ( strstr(str, ",") == NULL) )
    printf("regapi: WARNING converting CSV hex stream with no coma, "
           "input data seems invalid.\n");

  while (strPos < strLen)
  {
    char xbuf[3];
    char wc;

    memcpy(xbuf,s,2); xbuf[3]='\0';
    sscanf(xbuf,"%02x",(UINT*)&wc);
    *b++ =(unsigned char)wc;

    s+=3;
    strPos+=3;
    byteCount++;
  }                                   

  return byteCount;
}


/******************************************************************************
 * Sets the value in argv[0] to the data in argv[1] for the currently 
 * opened key.
 */
static HRESULT setValue(LPSTR *argv)
{
  HRESULT hRes;
  DWORD   dwSize          = KEY_MAX_LEN;
  DWORD   dwType          = NULL;
  DWORD   dwDataType;

  CHAR    lpsCurrentValue[KEY_MAX_LEN];

  LPSTR   keyValue = argv[0];
  LPSTR   keyData  = argv[1];

  /* Make some checks */
  if ( (keyValue == NULL) || (keyData == NULL) )
    return ERROR_INVALID_PARAMETER;

  /*
   * Default registry values are encoded in the input stream as '@' but as 
   * blank in the wine registry.
   */
  if( (keyValue[0] == '@') && (strlen(keyValue) == 1) )
    keyValue[0] = NULL;

  /* Get the data type stored into the value field */
  dwDataType = getDataType(&keyData);
    
  memset(lpsCurrentValue, 0, KEY_MAX_LEN);
  hRes = RegQueryValueExA(
          currentKeyHandle, 
          keyValue, 
          NULL, 
          &dwType, 
          (LPBYTE)lpsCurrentValue, 
          &dwSize);

  if( ( strlen(lpsCurrentValue) == 0 ) ||  /* The value is not existing */
      ( bForce ))         /* -force option */ 
  { 
    LPBYTE lpbData;
    BYTE   convert[KEY_MAX_LEN];
    DWORD  dwLen;

    if ( dwDataType == REG_SZ )        /* no convertion for string */
    {
      dwLen   = strlen(keyData);
      lpbData = keyData;
    } 
    else if (dwDataType == REG_DWORD)  /* Convert the dword types */
    {
      dwLen   = convertHexToDWord(keyData, convert);
      lpbData = convert;
    }
    else                               /* Convert the hexadecimal types */
    {
      dwLen   = convertHexCSVToHex(keyData, convert, KEY_MAX_LEN);
      lpbData = convert;
    }

    hRes = RegSetValueEx(
            currentKeyHandle, 
            keyValue,
            0,                  /* Reserved */
            dwDataType,
            lpbData,
            dwLen);
  }
  else
  {
    /* return the current value data into argv[1] */
    if (argv[1] != NULL)
    {
      HeapFree(GetProcessHeap(), 0, argv[1]);
      argv[1] = HeapAlloc(GetProcessHeap(), 0, dwSize+1);

      if ( argv[1] != NULL )
        strncpy(argv[1], lpsCurrentValue, dwSize);
    }

    return KEY_VALUE_ALREADY_SET;
  }
  return hRes;
}


/******************************************************************************
 * Open the key
 */
static HRESULT openKey( LPSTR stdInput)
{
  DWORD   dwDisp;  
  HRESULT hRes;

  /* Sanity checks */
  if (stdInput == NULL) 
    return ERROR_INVALID_PARAMETER;

  /* Get the registry class */
  currentKeyClass = getRegClass(stdInput); /* Sets global variable */
  if (currentKeyClass == ERROR_INVALID_PARAMETER)
    return ERROR_INVALID_PARAMETER;

  /* Get the key name */
  currentKeyName = getRegKeyName(stdInput); /* Sets global variable */
  if (currentKeyName == NULL)
    return ERROR_INVALID_PARAMETER;
    
  hRes = RegCreateKeyEx( 
          currentKeyClass,          /* Class     */
          currentKeyName,           /* Sub Key   */
          0,                        /* MUST BE 0 */
          NULL,                     /* object type */
          REG_OPTION_NON_VOLATILE,  /* option, REG_OPTION_NON_VOLATILE ... */
          KEY_ALL_ACCESS,           /* access mask, KEY_ALL_ACCESS */
          NULL,                     /* security attribute */
          &currentKeyHandle,        /* result */
          &dwDisp);                 /* disposition, REG_CREATED_NEW_KEY or
                                                    REG_OPENED_EXISTING_KEY */

  if (hRes == ERROR_SUCCESS)
    bTheKeyIsOpen = TRUE;

  return hRes;

}
/******************************************************************************
 * This function is a wrapper arround the setValue function.  It prepares the 
 * land and clean the area once completed.
 */
static void processSetValue(LPSTR cmdline)
{
  LPSTR argv[SET_VALUE_MAX_ARGS];  /* args storage    */

  LPSTR token         = NULL;      /* current token analized */
  ULONG argCounter    = 0;         /* counter of args */
  INT   counter;
  HRESULT hRes = NULL;

  /*
   * Init storage and parse the line
   */
  for (counter=0; counter<SET_VALUE_MAX_ARGS; counter++)
    argv[counter]=NULL;

  while( (token = strsep(&cmdline, setValueDelim[argCounter])) != NULL ) 
  {
    argv[argCounter++] = getArg(token);

    if (argCounter == SET_VALUE_MAX_ARGS)
      break;  /* Stop processing args no matter what */
  }

  hRes = setValue(argv);
  if ( hRes == ERROR_SUCCESS ) 
    printf(
      "regapi: Value \"%s\" has been set to \"%s\" in key [%s]\n", 
      argv[0], 
      argv[1],
      currentKeyName);

  else if ( hRes == KEY_VALUE_ALREADY_SET ) 
    printf(
      "regapi: Value \"%s\" already set to \"%s\" in key [%s]\n", 
      argv[0], 
      argv[1], 
      currentKeyName);
  
  else
    printf("regapi: ERROR Key %s not created. Value: %s, Data: %s\n",
      currentKeyName,
      argv[0], 
      argv[1]);
    
  /*
   * Do some cleanup
   */
  for (counter=0; counter<argCounter; counter++)
    if (argv[counter] != NULL)
      HeapFree(GetProcessHeap(), 0, argv[counter]);
}

/******************************************************************************
 * This function is a wrapper arround the queryValue function.  It prepares the 
 * land and clean the area once completed.
 */
static void processQueryValue(LPSTR cmdline)
{
  LPSTR   argv[QUERY_VALUE_MAX_ARGS];/* args storage    */
  LPSTR   token      = NULL;         /* current token analized */
  ULONG   argCounter = 0;            /* counter of args */
  INT     counter;
  HRESULT hRes       = NULL;
  LPSTR   keyValue   = NULL;
  LPSTR   lpsRes     = NULL;

  /*
   * Init storage and parse the line
   */
  for (counter=0; counter<QUERY_VALUE_MAX_ARGS; counter++)
    argv[counter]=NULL;

  while( (token = strsep(&cmdline, queryValueDelim[argCounter])) != NULL ) 
  {
    argv[argCounter++] = getArg(token);

    if (argCounter == QUERY_VALUE_MAX_ARGS)
      break;  /* Stop processing args no matter what */
  }

  /* The value we look for is the first token on the line */
  if ( argv[0] == NULL )
    return; /* SHOULD NOT OCCURS */
  else
    keyValue = argv[0]; 

  if( (keyValue[0] == '@') && (strlen(keyValue) == 1) ) 
  {
    LONG  lLen  = KEY_MAX_LEN;
    CHAR  lpsData[KEY_MAX_LEN];
    /* 
     * We need to query the key default value
     */
    hRes = RegQueryValue(
             currentKeyHandle, 
             currentKeyName, 
             (LPBYTE)lpsData,
             &lLen);

    if (hRes == ERROR_SUCCESS)
    {
      lpsRes = HeapAlloc( GetProcessHeap(), 0, lLen);
      strncpy(lpsRes, lpsData, lLen);
    }
  }
  else 
  {
    DWORD  dwLen  = KEY_MAX_LEN;
    BYTE   lpbData[KEY_MAX_LEN];
    DWORD  dwType;
    /* 
     * We need to query a specific value for the key
     */
    hRes = RegQueryValueEx(
             currentKeyHandle, 
             keyValue, 
             0, 
             &dwType, 
             (LPBYTE)lpbData, 
             &dwLen);

    if (hRes == ERROR_SUCCESS)
    {
      /* 
       * Convert the returned data to a displayable format
       */
      switch ( dwType )
      {
        case REG_SZ:
        {
          lpsRes = HeapAlloc( GetProcessHeap(), 0, dwLen);
          strncpy(lpsRes, lpbData, dwLen);
          break;
        }
        case REG_DWORD:
        {
          lpsRes = convertHexToDWORDStr(lpbData, dwLen);
          break;
        }
        default:
        {
          lpsRes = convertHexToHexCSV(lpbData, dwLen);
          break;
        }
      } 
    }
  }
 
 
  if ( hRes == ERROR_SUCCESS ) 
    printf(
      "regapi: Value \"%s\" = \"%s\" in key [%s]\n", 
      keyValue, 
      lpsRes,
      currentKeyName);

  else
    printf("regapi: ERROR Value \"%s\" not found. for key \"%s\"\n",
      keyValue, 
      currentKeyName);
    
  /*
   * Do some cleanup
   */
  for (counter=0; counter<argCounter; counter++)
    if (argv[counter] != NULL)
      HeapFree(GetProcessHeap(), 0, argv[counter]);

  if (lpsRes != NULL)
    HeapFree(GetProcessHeap(), 0, lpsRes);

}

/******************************************************************************
 * Close the currently opened key.
 */
static void closeKey()
{
  RegCloseKey(currentKeyHandle); 

  HeapFree(GetProcessHeap(), 0, currentKeyName); /* Allocated by getKeyName */

  bTheKeyIsOpen    = FALSE;

  currentKeyName   = NULL;
  currentKeyClass  = NULL;
  currentKeyHandle = NULL;
}

/******************************************************************************
 * This funtion is the main entry point to the setValue type of action.  It 
 * receives the currently read line and dispatch the work depending on the 
 * context.
 */
static void doSetValue(LPSTR stdInput)
{
  /* 
   * We encoutered the end of the file, make sure we 
   * close the opened key and exit
   */ 
  if (stdInput == NULL)             
  {
    if (bTheKeyIsOpen != FALSE) 
      closeKey();                    

    return;
  }
    
  if      ( stdInput[0] == '[')      /* We are reading a new key */
  {
    if ( bTheKeyIsOpen != FALSE )      
      closeKey();                    /* Close the previous key before */

    if ( openKey(stdInput) != ERROR_SUCCESS )
      printf ("regapi: doSetValue failed to open key %s\n", stdInput);
  }
  else if( ( bTheKeyIsOpen ) && 
           (( stdInput[0] == '@') || /* reading a default @=data pair */
            ( stdInput[0] == '\"'))) /* reading a new value=data pair */
  {
    processSetValue(stdInput);
  }
  else                               /* since we are assuming that the */
  {                                  /* file format is valid we must   */ 
    if ( bTheKeyIsOpen )             /* be reading a blank line which  */
      closeKey();                    /* indicate end of this key processing */ 
  }
}

/******************************************************************************
 * This funtion is the main entry point to the queryValue type of action.  It 
 * receives the currently read line and dispatch the work depending on the 
 * context.
 */
static void doQueryValue(LPSTR stdInput) { 
  /* 
   * We encoutered the end of the file, make sure we 
   * close the opened key and exit
   */ 
  if (stdInput == NULL)             
  {
    if (bTheKeyIsOpen != FALSE) 
      closeKey();                    

    return;
  }
    
  if      ( stdInput[0] == '[')      /* We are reading a new key */
  {
    if ( bTheKeyIsOpen != FALSE )      
      closeKey();                    /* Close the previous key before */

    if ( openKey(stdInput) != ERROR_SUCCESS )
      printf ("regapi: doSetValue failed to open key %s\n", stdInput);
  }
  else if( ( bTheKeyIsOpen ) && 
           (( stdInput[0] == '@') || /* reading a default @=data pair */
            ( stdInput[0] == '\"'))) /* reading a new value=data pair */
  {
    processQueryValue(stdInput);
  }
  else                               /* since we are assuming that the */
  {                                  /* file format is valid we must   */ 
    if ( bTheKeyIsOpen )             /* be reading a blank line which  */
      closeKey();                    /* indicate end of this key processing */ 
  }
}

/******************************************************************************
 * This funtion is the main entry point to the deletetValue type of action.  It 
 * receives the currently read line and dispatch the work depending on the 
 * context.
 */
static void doDeleteValue(LPSTR line) { 
  printf ("regapi: deleteValue not yet implemented\n");
}
/******************************************************************************
 * This funtion is the main entry point to the deleteKey type of action.  It 
 * receives the currently read line and dispatch the work depending on the 
 * context.
 */
static void doDeleteKey(LPSTR line)   { 
  printf ("regapi: deleteKey not yet implemented\n");
}
/******************************************************************************
 * This funtion is the main entry point to the createKey type of action.  It 
 * receives the currently read line and dispatch the work depending on the 
 * context.
 */
static void doCreateKey(LPSTR line)   { 
  printf ("regapi: createKey not yet implemented\n");
}

/******************************************************************************
 * MAIN - The main simply validate the first parameter (command to perform)
 *        It then read the STDIN lines by lines forwarding their processing
 *        to the appropriate method.
 */
int PASCAL WinMain (HANDLE inst, HANDLE prev, LPSTR cmdline, int show)
{
  LPSTR  token          = NULL;  /* current token analized */
  LPSTR  stdInput       = NULL;  /* line read from stdin */
  INT    cmdIndex       = -1;    /* index of the command in array */

  stdInput = HeapAlloc(GetProcessHeap(), 0, STDIN_MAX_LEN); 
  if (stdInput == NULL)
    return NOT_ENOUGH_MEMORY;

  /*
   * get the command, should be the first arg (modify cmdLine)
   */ 
  token = strsep(&cmdline, " "); 
  if (token != NULL) 
  {
    cmdIndex = getCommand(token);
    if (cmdIndex == COMMAND_NOT_FOUND)
    {
      printf("regapi: Command \"%s\" is not supported.\n", token);
      printf(helpText);
      return COMMAND_NOT_SUPPORTED;
    }
  }    
  else
  {
    printf(
      "regapi: The first item on the command line must be the command name.\n");
    printf(helpText);
    return COMMAND_NOT_SUPPORTED;
  }

  /* 
   * check to see weather we force the action 
   * (meaning differ depending on the command performed)
   */
  if ( cmdline != NULL ) /* will be NULL if '-force' is not provided */
    if ( strstr(cmdline, "-force") != NULL )
      bForce = TRUE;

  printf("Processing stdin...\n");

  while ( TRUE )
  {
    /* 
     * read a line
     */
    stdInput = fgets(stdInput, STDIN_MAX_LEN, stdin);
   
    /* 
     * Make some handy generic stuff here... 
     */
    if ( stdInput != NULL )
    {
      stdInput[strlen(stdInput) -1] = NULL; /* get rid of new line */

      if( stdInput[0] == '#' )              /* this is a comment, skip */
        continue;
    }

    /* 
     * We process every lines even the NULL (last) line, to indicate the 
     * end of the processing to the specific process.
     */
    commandAPIs[cmdIndex](stdInput);       

    if (stdInput == NULL)  /* EOF encountered */
      break;
  }

  /* 
   * Save the registry only if it was modified 
   */
  if ( commandSaveRegistry[cmdIndex] != FALSE )
    SHELL_SaveRegistry();

  HeapFree(GetProcessHeap(), 0, stdInput);
  return SUCCESS;
}



