//------------------------------------------------------------------------------
void reg_read_enum_MRUWvalues(HKEY hk,char *chkey,char *key,char *exclu,char* description_id,unsigned int session_id, sqlite3 *db)
{
  HKEY CleTmp;
  if (RegOpenKey(hk,key,&CleTmp)!=ERROR_SUCCESS)return;

  DWORD nbValue,i;
  FILETIME last_update;
  if (RegQueryInfoKey (CleTmp,0,0,0,0,0,0,&nbValue,0,0,0,&last_update)!=ERROR_SUCCESS)
  {
    RegCloseKey(CleTmp);
    return;
  }

  //get date
  char parent_key_update[DATE_SIZE_MAX] = "";
  filetimeToString_GMT(last_update, parent_key_update, DATE_SIZE_MAX);

  //read USER + RID + SID
  char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH];
  GetRegistryKeyOwner(CleTmp, user, RID, sid, MAX_PATH);

  //enum values
  char value[MAX_PATH], data[MAX_PATH], data_s[MAX_PATH];
  DWORD valueSize,dataSize,type;
  for (i=0;i<nbValue && start_scan;i++)
  {
    valueSize = MAX_PATH;
    dataSize  = MAX_PATH;
    value[0]  = 0;
    data[0]   = 0;
    type      = 0;
    if (RegEnumValue (CleTmp,i,(LPTSTR)value,(LPDWORD)&valueSize,0,(LPDWORD)&type,(LPBYTE)data,(LPDWORD)&dataSize)==ERROR_SUCCESS)
    {
      convertStringToSQL(value, MAX_PATH);
      snprintf(data_s,MAX_LINE_SIZE,"%S",data);
      convertStringToSQL(data_s, MAX_PATH);
      addRegistryMRUtoDB("",chkey,key,value,data_s,description_id,user,RID,sid,parent_key_update,session_id,db);
    }
  }
  RegCloseKey(CleTmp);
}
//------------------------------------------------------------------------------
//local function part !!!
//------------------------------------------------------------------------------
void reg_read_enum_PathValues(HKEY hk,char *chkey,char *key,unsigned int session_id, sqlite3 *db)
{
  HKEY CleTmp;
  if (RegOpenKey(hk,key,&CleTmp)!=ERROR_SUCCESS)return;

  DWORD nbValue,i,j;
  FILETIME last_update;
  if (RegQueryInfoKey (CleTmp,0,0,0,0,0,0,&nbValue,0,0,0,&last_update)!=ERROR_SUCCESS)
  {
    RegCloseKey(CleTmp);
    return;
  }

  //get date
  char parent_key_update[DATE_SIZE_MAX] = "";
  filetimeToString_GMT(last_update, parent_key_update, DATE_SIZE_MAX);

  //read USER + RID + SID
  char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH];
  GetRegistryKeyOwner(CleTmp, user, RID, sid, MAX_PATH);

  //enum values
  char value[MAX_PATH], data[MAX_PATH];
  DWORD valueSize,dataSize,type;
  for (i=0;i<nbValue && start_scan;i++)
  {
    valueSize = MAX_PATH;
    dataSize  = MAX_PATH;
    value[0]  = 0;
    type      = 0;
    if (RegEnumValue (CleTmp,i,(LPTSTR)value,(LPDWORD)&valueSize,0,(LPDWORD)&type,(LPBYTE)data,(LPDWORD)&dataSize)==ERROR_SUCCESS)
    {
      switch(type)
      {
        case REG_EXPAND_SZ:
        case REG_SZ:
          convertStringToSQL(value, MAX_PATH);
          convertStringToSQL(data, MAX_PATH);
          addRegistryPathtoDB("",chkey,key,value,data,user,RID,sid,parent_key_update,session_id,db);break;
        /*case REG_BINARY:
        case REG_LINK:
          {
            tmp[0] = 0;
            snprintf(tmp,MAX_PATH,"%S",data);
            convertStringToSQL(value, MAX_PATH);
            convertStringToSQL(tmp, MAX_PATH);
            addRegistryPathtoDB("",chkey,key,value,tmp,user,RID,sid,parent_key_update,session_id,db);
          }
        break;*/
        case REG_MULTI_SZ:
          for (j=0;j<dataSize;j++)
          {
            if (data[j] == 0)data[j]=';';
          }
          convertStringToSQL(value, MAX_PATH);
          convertStringToSQL(data, MAX_PATH);
          addRegistryPathtoDB("",chkey,key,value,data,user,RID,sid,parent_key_update,session_id,db);
        break;
      }
    }
  }
  RegCloseKey(CleTmp);
}
//------------------------------------------------------------------------------
void ReadDatas(unsigned int type, HKEY hk, char *chk, char *key_path, char *value, char*description_id, unsigned int session_id, sqlite3 *db)
{
  switch(type)//value_type
  {
    //list of all string in a directory and exclude "value"
    case TYPE_ENUM_STRING_VALUE:reg_read_enum_MRUvalues(hk, chk,key_path,value,description_id, session_id, db);break;
    case TYPE_ENUM_STRING_NVALUE:reg_read_enum_MRUNvalues(hk, chk,key_path,value,description_id, session_id, db);break;
    case TYPE_ENUM_STRING_WVALUE:reg_read_enum_MRUWvalues(hk, chk,key_path,value,description_id, session_id, db);break;

    case TYPE_ENUM_SUBNK_DATE:
    {
      //read all subkey
      HKEY CleTmp, CleTmp2;
      if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return;

      //enum keys
      DWORD nbSubKey=0,i;
      if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
      {
        RegCloseKey(CleTmp);
        return;
      }

      char key[MAX_PATH], tmp_key[MAX_PATH], lastupdate[DATE_SIZE_MAX] ="";
      DWORD key_size;
      FILETIME LastWriteTime;
      char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH];

      for (i=0;i<nbSubKey && start_scan;i++)
      {
        key[0]    = 0;
        key_size  = MAX_PATH;
        if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,&LastWriteTime)==ERROR_SUCCESS)
        {
          snprintf(tmp_key,MAX_PATH,"%s\\%s",key_path,key);
          if (RegOpenKey(hk,tmp_key,&CleTmp2)==ERROR_SUCCESS)
          {
            user[0] = 0;
            RID[0]  = 0;
            sid[0]  = 0;
            GetRegistryKeyOwner(CleTmp2, user, RID, sid, MAX_PATH);

            filetimeToString_GMT(LastWriteTime, lastupdate, DATE_SIZE_MAX);
            addRegistryMRUtoDB("",chk,tmp_key,"","",description_id,user,RID,sid,lastupdate,session_id,db);
            RegCloseKey(CleTmp2);
          }
        }
      }
      RegCloseKey(CleTmp);
    }
    break;

    case TYPE_DBL_ENUM_VALUE:
    {
      //read all subkey
      HKEY CleTmp, CleTmp2, CleTmp3;
      if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return;

      //enum keys
      DWORD nbSubKey=0, nbSubKey2,i,j;
      if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
      {
        RegCloseKey(CleTmp);
        return;
      }

      char key[MAX_PATH], key2[MAX_PATH], tmp_key[MAX_PATH], tmp_key2[MAX_PATH], lastupdate[DATE_SIZE_MAX] ="";
      DWORD key_size,key_size2;
      FILETIME LastWriteTime;
      char user[MAX_PATH], RID[MAX_PATH], sid[MAX_PATH], data[MAX_PATH];

      for (i=0;i<nbSubKey && start_scan;i++)
      {
        key[0]    = 0;
        key_size  = MAX_PATH;
        if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS)
        {
          snprintf(tmp_key,MAX_PATH,"%s\\%s\\AVGeneral\\cRecentFiles",key_path,key);
          if (RegOpenKey(hk,tmp_key,&CleTmp2)==ERROR_SUCCESS)
          {
            nbSubKey2 = 0;
            if (RegQueryInfoKey (CleTmp2,NULL,NULL,NULL,&nbSubKey2,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
            {
              RegCloseKey(CleTmp2);
              continue;
            }

            for (j=0;j<nbSubKey2 && start_scan;j++)
            {
              key2[0]    = 0;
              key_size2  = MAX_PATH;
              if (RegEnumKeyEx (CleTmp2,j,key2,(LPDWORD)&key_size2,NULL,NULL,NULL,&LastWriteTime)==ERROR_SUCCESS)
              {
                snprintf(tmp_key2,MAX_PATH,"%s\\%s",tmp_key,key2);
                if (RegOpenKey(hk,tmp_key2,&CleTmp3)==ERROR_SUCCESS)
                {
                  user[0] = 0;
                  RID[0]  = 0;
                  sid[0]  = 0;
                  data[0] = 0;
                  GetRegistryKeyOwner(CleTmp3, user, RID, sid, MAX_PATH);
                  filetimeToString_GMT(LastWriteTime, lastupdate, DATE_SIZE_MAX);

                  if(ReadValue(hk,tmp_key2,value,data, MAX_PATH))
                  {
                    convertStringToSQL(data, MAX_PATH);
                    addRegistryMRUtoDB("",chk,tmp_key2,value,data,description_id,user,RID,sid,lastupdate,session_id,db);
                  }
                  RegCloseKey(CleTmp3);
                }
              }
            }
            RegCloseKey(CleTmp2);
          }
        }
      }
      RegCloseKey(CleTmp);
    }
    break;

    //all string under one key
    case TYPE_ENUM_STRING_RVALUE:
    {
      //read all subkey
      HKEY CleTmp;
      if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return;

      DWORD nbSubKey=0,i;
      if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
      {
        RegCloseKey(CleTmp);
        return;
      }

      char key[MAX_PATH], tmp_key[MAX_PATH];
      DWORD key_size;
      for (i=0;i<nbSubKey && start_scan;i++)
      {
        key[0]    = 0;
        key_size  = MAX_PATH;
        if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS)
        {
          snprintf(tmp_key,MAX_PATH,"%s\\%s",key_path,key);
          reg_read_enum_MRUvalues(hk,chk,tmp_key,value,description_id, session_id, db_scan);
        }
      }
      RegCloseKey(CleTmp);

    }break;

    //all string under thow key + key
    case TYPE_ENUM_STRING_RRVALUE:
    {
      //read all subkey
      HKEY CleTmp,CleTmp2;
      if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return;

      DWORD nbSubKey=0,nbSubKey2,i,j;
      if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
      {
        RegCloseKey(CleTmp);
        return;
      }

      char key[MAX_PATH], tmp_key[MAX_PATH],key2[MAX_PATH], tmp_key2[MAX_PATH];
      DWORD key_size,key_size2;
      for (i=0;i<nbSubKey && start_scan;i++)
      {
        key[0]    = 0;
        key_size  = MAX_PATH;
        if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS)
        {
          snprintf(tmp_key,MAX_PATH,"%s\\%s",key_path,key);

          //second key !!!
          if (RegOpenKey(hk,tmp_key,&CleTmp2)!=ERROR_SUCCESS)continue;

          nbSubKey2 = 0;
          if (RegQueryInfoKey (CleTmp2,NULL,NULL,NULL,&nbSubKey2,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
          {
            RegCloseKey(CleTmp2);
            continue;
          }

          for (j=0;j<nbSubKey2 && start_scan;j++)
          {
            key2[0]    = 0;
            key_size2  = MAX_PATH;
            if (RegEnumKeyEx (CleTmp2,j,key2,(LPDWORD)&key_size2,NULL,NULL,NULL,NULL)==ERROR_SUCCESS)
            {
              snprintf(tmp_key2,MAX_PATH,"%s\\%s\\%s",tmp_key,key2,value);
              reg_read_enum_MRUvalues(hk,chk,tmp_key2,"",description_id, session_id, db_scan);
            }
          }
          RegCloseKey(CleTmp2);
        }
      }
      RegCloseKey(CleTmp);

    }break;

    //all string under one key + key
    case TYPE_ENUM_STRING_R_VALUE:
    {
      //read all subkey
      HKEY CleTmp;
      if (RegOpenKey(hk,key_path,&CleTmp)!=ERROR_SUCCESS)return;

      DWORD nbSubKey=0,i;
      if (RegQueryInfoKey (CleTmp,NULL,NULL,NULL,&nbSubKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL)!=ERROR_SUCCESS)
      {
        RegCloseKey(CleTmp);
        return;
      }

      char key[MAX_PATH], tmp_key[MAX_PATH];
      DWORD key_size;
      for (i=0;i<nbSubKey && start_scan;i++)
      {
        key[0]    = 0;
        key_size  = MAX_PATH;
        if (RegEnumKeyEx (CleTmp,i,key,(LPDWORD)&key_size,NULL,NULL,NULL,NULL)==ERROR_SUCCESS)
        {
          snprintf(tmp_key,MAX_PATH,"%s\\%s\\%s",key_path,key,value);
          reg_read_enum_MRUvalues(hk,chk,tmp_key,"",description_id, session_id, db_scan);
        }
      }
      RegCloseKey(CleTmp);
    }break;

    //only one value
    case TYPE_VALUE_STRING:
    {
      char data[MAX_PATH];
      if (ReadValue(hk,key_path,value,data, MAX_PATH))
      {
        HKEY CleTmp;
        if (RegOpenKey(hk,key_path,&CleTmp)==ERROR_SUCCESS)
        {
          char user[MAX_PATH]="", RID[MAX_PATH]="", SID[MAX_PATH]="";
          GetRegistryKeyOwner(CleTmp, user, RID, SID, MAX_PATH);
          RegCloseKey(CleTmp);

          char parent_key_update[DATE_SIZE_MAX]="";
          ReadKeyUpdate(hk,key_path, parent_key_update, DATE_SIZE_MAX);

          convertStringToSQL(data, MAX_PATH);
          addRegistryMRUtoDB("",chk,key_path,value,data,description_id,user,RID,SID,parent_key_update,session_id,db_scan);
        }
      }
    }break;
    //only one value
    case TYPE_VALUE_WSTRING:
    {
      char data[MAX_PATH],tmp[MAX_PATH];
      if (ReadValue(hk,key_path,value,tmp, MAX_PATH))
      {
        HKEY CleTmp;
        if (RegOpenKey(hk,key_path,&CleTmp)==ERROR_SUCCESS)
        {
          snprintf(data,MAX_PATH,"%S",tmp);

          char user[MAX_PATH]="", RID[MAX_PATH]="", SID[MAX_PATH]="";
          GetRegistryKeyOwner(CleTmp, user, RID, SID, MAX_PATH);
          RegCloseKey(CleTmp);

          char parent_key_update[DATE_SIZE_MAX]="";
          ReadKeyUpdate(hk,key_path, parent_key_update, DATE_SIZE_MAX);

          convertStringToSQL(data, MAX_PATH);
          addRegistryMRUtoDB("",chk,key_path,value,data,description_id,user,RID,SID,parent_key_update,session_id,db_scan);
        }
      }
    }break;
  }
}