//------------------------------------------------------------------------------
int callback_sqlite_chrome(void *datas, int argc, char **argv, char **azColName)
{
  FORMAT_CALBAK_READ_INFO *type = datas;
  char tmp[MAX_PATH]="";
  char date[DATE_SIZE_MAX]="";
  unsigned int i,size=0;

  if (type->type <= nb_sql_CHROME)
  {
    //special case of password !!!
    if(sql_CHROME[type->type].test_string_id == SPECIAL_CASE_CHROME_PASSWORD)
    {
      char password[MAX_PATH]="", raw_password[MAX_PATH]="";

      //decrypt datas password !!!
      CRYPT_INTEGER_BLOB data_in, data_out;
      data_in.cbData = strlen(argv[3]);
      data_in.pbData = (BYTE*)argv[3];

      snprintf(tmp,MAX_PATH,"%s, %s",argv[1],argv[2]);
      snprintf(raw_password,MAX_PATH,"%s",argv[3]);

      if (CryptUnprotectData(&data_out,NULL,NULL,NULL,NULL,0,&data_in))
      {
        snprintf(password,MAX_PATH,"%s",data_out.pbData);
        LocalFree(data_out.pbData);
      }
      convertStringToSQL(tmp, MAX_PATH);
      convertStringToSQL(password, MAX_PATH);
      convertStringToSQL(raw_password, MAX_PATH);
      addPasswordtoDB(tmp_file_chrome,tmp,password,raw_password,SPECIAL_CASE_CHROME_PASSWORD,current_session_id,db_scan);
    }else
    {
      //copy datas
      for (i=0;i<argc && MAX_PATH-size > 0 && start_scan;i++)
      {
        if (argv[i] == NULL)continue;

        //date or not ?
        if (strlen(argv[i]) == DATE_SIZE_MAX-1)
        {
          if (argv[i][4] == '/' && argv[i][13] == ':')
          {
            if (strcmp("1970/01/01 01:00:00",argv[i])!=0 && strcmp("1601/01/01 01:00:00",argv[i])!=0)strncpy(date,argv[i],DATE_SIZE_MAX);
            continue;
          }
        }
        if (i>0)snprintf(tmp+size,MAX_PATH-size,", %s",convertUTF8toUTF16(argv[i], strlen(argv[i])+1));
        else snprintf(tmp+size,MAX_PATH-size,"%s",convertUTF8toUTF16(argv[i], strlen(argv[i])+1));
        size = strlen(tmp);
      }
      //get datas and write it
      convertStringToSQL(tmp, MAX_PATH);
      addChrometoDB(tmp_file_chrome,sql_CHROME[type->type].params,tmp,date,sql_CHROME[type->type].test_string_id,current_session_id,db_scan);
    }
  }
  return 0;
}
//------------------------------------------------------------------------------
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);
}
//------------------------------------------------------------------------------
void EnumShare(HK_F_OPEN *hks, unsigned int session_id, sqlite3 *db, char*reg_path)
{
  HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, reg_path);
  if (nk_h == NULL) return;

  DWORD i, nbSubValue = GetValueData(hks->buffer,hks->taille_fic, nk_h, (hks->pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
  char share[MAX_PATH], description[MAX_LINE_SIZE];
  for (i=0;i<nbSubValue;i++)
  {
    if (GetValueData(hks->buffer,hks->taille_fic, nk_h, (hks->pos_fhbin)+HBIN_HEADER_SIZE, i,share,MAX_PATH,description,MAX_LINE_SIZE))
    {
      convertStringToSQL(description, MAX_LINE_SIZE);
      addSharetoDB(hks->file,share, "", description, "", "", session_id, db);
    }
  }
}
//------------------------------------------------------------------------------
unsigned int ReadRecord(char *buffer, DWORD size, STRING_TABLE *my_s_table, char *eventfile, sqlite3 *db, unsigned int session_id)
{
  #define EVENTLOG_H_EVTX_SIZE                    4+4+8+8+6
  typedef struct _EVENTLOG_H_EVTX {
    unsigned char MagicString[4];                 //4 ** + 0x00 + 0x00
    unsigned int RecordSize;                      //4
    unsigned long long int RecordNumber;          //8   //RecordNumber
    unsigned long long int TimeCreated;           //8
    unsigned char padding_star_xml[6];            //6 : 0f01 0100 0c01
  }EVENTLOG_H_EVTX;
  EVENTLOG_H_EVTX *h_dheader = (EVENTLOG_H_EVTX *)buffer;

  char indx[DEFAULT_TMP_SIZE]="", log_id[DEFAULT_TMP_SIZE]="",
  send_date[DATE_SIZE_MAX]="", write_date[DATE_SIZE_MAX]="",
  source[MAX_PATH]="", description[MAX_LINE_SIZE]="",
  user[DEFAULT_TMP_SIZE]="", rid[DEFAULT_TMP_SIZE]="", sid[DEFAULT_TMP_SIZE]="",
  state[DEFAULT_TMP_SIZE]="", critical[DEFAULT_TMP_SIZE]="";

  DWORD id=0;

  //test de validité
  if (h_dheader->RecordSize <= size
   && h_dheader->MagicString[0] == '*' && h_dheader->MagicString[1] == '*' && h_dheader->MagicString[2] == 0 && h_dheader->MagicString[3] == 0)
  {
    //lecture des informations du header
    //id
    snprintf(indx,DEFAULT_TMP_SIZE,"%08lu",(long unsigned int)(h_dheader->RecordNumber));

    //date : send_date
    FILETIME FileTime;
    FileTime.dwLowDateTime = (DWORD) h_dheader->TimeCreated;
    FileTime.dwHighDateTime = (DWORD)(h_dheader->TimeCreated >> 32);
    filetimeToString_GMT(FileTime, send_date, DATE_SIZE_MAX);

    //date : write_date = same
    strcpy(write_date,send_date);

    //afin de passer les enregistrelent avec header on passe tant qu'on à pas accès au header attendu ^^
    //permet de traiter les cas de données corrompues
    //0x00 0000 0100 0400 0100 0400
    char *c = buffer+EVENTLOG_H_EVTX_SIZE;
    DWORD pos=EVENTLOG_H_EVTX_SIZE;
    BOOL ok =FALSE;
    do
    {
      if (*c == 0x00 && *(c+1) == 0x00 && *(c+2) == 0x00 &&
      *(c+3) == 0x01 && *(c+4) == 0x00 && *(c+5) == 0x04 && *(c+6) == 0x00 &&
      *(c+7) == 0x01 && *(c+8) == 0x00 && *(c+9) == 0x04 &&*(c+10) == 0x00)
      {
        ok = TRUE;
        break;
      }

      c++;
      pos++;
    }while(pos<h_dheader->RecordSize-12);

    //traitement de la suite ^^
    if (ok)
    {
      //recherche de l'id ^^ dans une zone de moins de 100octets ^^
      //0x2100 0400 0000 XXXX = ID
      typedef struct _ID
      {
        unsigned short param;   // 0x0021
        unsigned char end;
        unsigned char type;     // level
        unsigned short padding; // 0x0000
        unsigned short id;
      }M_ID;
      M_ID * mid;

      while(pos<h_dheader->RecordSize-10)
      {
        if (*c == 0x21 && *(c+1) == 0x00)
        {
          //id identifié ^^
          mid = (M_ID *)c;
          snprintf(log_id,DEFAULT_TMP_SIZE,"%08lu",(DWORD) mid->id);
          id = mid->id;

          //Type
          switch(mid->type)
          {
            case 0x00 : strcpy(state,"INFORMATION"); break;
            case 0x01 : strcpy(state,"WARNING"); break;
            case 0x02 : strcpy(state,"ERROR"); break;
            case 0x04 : strcpy(state,"CRITICAL"); break;
            case 0x08 : strcpy(state,"AUDIT_SUCCESS"); break;
            case 0x10 : strcpy(state,"AUDIT_FAILURE"); break;
            default :snprintf(state,MAX_LINE_SIZE,"UNKNOW (%d)",mid->type);break;
          }
        }
        c++;pos++;
      }
      c+=8; //on passe l'id + 6 octets de padding

      //Source
      char *desc = c;
      source[0] = 0;
      while(pos+4<h_dheader->RecordSize-10)
      {//0x05- 0x12 = S-1-5-18, revoir la phase de détection pour prendre en compte le SID !!!!
        if (*c != 0x00 && *(c+1) == 0x00) //unicode
          if (*(c+2) != 0x00 && *(c+3)==0x00)
          //if (*c == 0x05)
          {
            snprintf(source,MAX_LINE_SIZE,"%S",c);
            break;
          }
        c++;
        pos++;
      }

      //si aucune source n'est définie on ajoute le nom du fichier sans evtx ^^
      if (source[0] == 0)
      {
        char *n = eventfile;
        while (*n)n++;
        while (*n != '\\')n--;
        n++;
        snprintf(source,MAX_PATH,"%s",n);
        source[strlen(source)-5]=0;

        //on vérifie que pas de % dans le nom sinon on met 0 à sa place ^^
        n = source;
        while (*n)
        {
          if (*n == '%'){*n=0; break;}
          n++;
        }
      }

      //traitement de la description !!
      TraiterDescription (desc,h_dheader->RecordSize/*-pos*/,description,MAX_LINE_SIZE);
    }

    //add
    convertStringToSQL(source, MAX_PATH);
    convertStringToSQL(description, MAX_LINE_SIZE);
    addLogtoDB(eventfile, indx, log_id,
           send_date, write_date, source, description,
           user, rid, sid, state, critical, session_id, db);
  }
//------------------------------------------------------------------------------
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms649016%28v=vs.85%29.aspx
DWORD WINAPI Scan_clipboard(LPVOID lParam)
{
  //check if local or not :)
  if (!LOCAL_SCAN)
  {
    h_thread_test[(unsigned int)lParam] = 0;
    check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan
    return 0;
  }

  //db
  sqlite3 *db = (sqlite3 *)db_scan;
  if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"BEGIN TRANSACTION;", NULL, NULL, NULL);

  //lecture du contenu du presse papier et extraction
  if (OpenClipboard(0))
  {
    char description[MAX_LINE_SIZE], format[DEFAULT_TMP_SIZE],
    data[MAX_LINE_SIZE],user[NB_USERNAME_SIZE+1]="";
    unsigned int session_id = current_session_id;
    HGLOBAL hMem;

    //user
    DWORD s=NB_USERNAME_SIZE;
    GetUserName(user,&s);

    int nb_items = CountClipboardFormats();
    if (nb_items > 0)
    {
      unsigned int uFormat = EnumClipboardFormats(0);
      #ifdef CMD_LINE_ONLY_NO_DB
      printf("\"Clipboard\";\"format\";\"code\";\"description\";\"user\";\"session_id\";\"data\";\r\n");
      #endif // CMD_LINE_ONLY_NO_DB
      while (uFormat && start_scan && GetLastError() == ERROR_SUCCESS && --nb_items>0)
      {
        //check if ok
        if (IsClipboardFormatAvailable(uFormat) == FALSE)
        {
          uFormat = EnumClipboardFormats(uFormat);
          continue;
        }

        description[0] = 0;
        data[0]= 0;
        if (GetClipboardFormatName(uFormat, description, MAX_LINE_SIZE) != 0)
        {
          hMem = GetClipboardData(uFormat);
          if (hMem != NULL)
          {
            switch(uFormat)
            {
              case CF_TEXT:
                //format
                strncpy(format,"CF_TEXT",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Text",DEFAULT_TMP_SIZE);
                //datas
                strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE);
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_BITMAP:
                //format
                strncpy(format,"CF_BITMAP",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Bitmap Picture",DEFAULT_TMP_SIZE);
                //do in bitmap to hexa
                SaveBitmapToHexaStr((HBITMAP)hMem , data, MAX_LINE_SIZE);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_METAFILEPICT:
                //format
                strncpy(format,"CF_METAFILEPICT",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Meta-File Picture",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
                GlobalUnlock(hMem);
              break;
              case CF_SYLK:
                //format
                strncpy(format,"CF_SYLK",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Microsoft Symbolic Link (SYLK) data",DEFAULT_TMP_SIZE);
                //datas
                snprintf(data,MAX_LINE_SIZE,"%s",(char*)GlobalLock(hMem));
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_OEMTEXT:
                //format
                strncpy(format,"CF_OEMTEXT",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Text (OEM)",DEFAULT_TMP_SIZE);
                //datas
                strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE);
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_DIB:
                //format
                strncpy(format,"CF_DIB",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"DIB Bitmap Picture",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_DIF:
                //format
                strncpy(format,"CF_DIF",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Software Arts' Data Interchange information",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_TIFF:
                //format
                strncpy(format,"CF_TIFF",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Tagged Image File Format (TIFF) Picture",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_PALETTE:
                //format
                strncpy(format,"CF_PALETTE",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Colour Palette",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_PENDATA:
                //format
                strncpy(format,"CF_PENDATA",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Pen Data",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_UNICODETEXT:
                //format
                strncpy(format,"CF_UNICODETEXT",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Text Unicode",DEFAULT_TMP_SIZE);
                //datas
                snprintf(data,MAX_LINE_SIZE,"%S",GlobalLock(hMem));
                convertStringToSQL(data, MAX_LINE_SIZE);h_thread_test[(unsigned int)lParam] = 0;
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_RIFF:
                //format
                strncpy(format,"CF_RIFF",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"RIFF Audio data",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_WAVE:
                //format
                strncpy(format,"CF_WAVE",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Wave File",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_ENHMETAFILE:
                //format
                strncpy(format,"CF_ENHMETAFILE",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Enhanced Meta-File Picture",DEFAULT_TMP_SIZE);
                //datas
                DWORD dwSize = GetEnhMetaFileBits((HENHMETAFILE)hMem, 0, NULL);
                if (dwSize > 0)
                {
                  LPBYTE buffer = (LPBYTE)malloc(dwSize);
                  if (buffer != NULL)
                  {
                    if (GetEnhMetaFileBits((HENHMETAFILE)hMem, dwSize, buffer)!=0)
                    {
                      DatatoHexa(buffer, dwSize, data, MAX_LINE_SIZE);
                    }
                    free(buffer);
                  }
                }
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case CF_HDROP:
              {
                //format
                strncpy(format,"CF_HDROP",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"File List",DEFAULT_TMP_SIZE);

                HDROP H_DropInfo = (HDROP)hMem;
                char tmp[MAX_PATH];
                DWORD i,nb_path = DragQueryFile(H_DropInfo, 0xFFFFFFFF, tmp, MAX_PATH);
                long int s2 =MAX_LINE_SIZE;
                for (i=0;i<nb_path;i++)
                {
                  //traitement des données ^^
                  DragQueryFile(H_DropInfo, i, tmp, MAX_PATH);

                  //add
                  if (s2>0)
                  {
                    snprintf(data+strlen(data),s,"%s\r\n",tmp);
                    //strncpy(data+strlen(data),tmp,s);
                    s2-=strlen(data);
                  }
                }
                convertStringToSQL(data, MAX_LINE_SIZE);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              }
              break;
              case CF_LOCALE:
                //format
                strncpy(format,"CF_LOCALE",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Text Locale Identifier",DEFAULT_TMP_SIZE);
                //datas
                snprintf(data,MAX_LINE_SIZE,"0x%X",(unsigned int)GlobalLock(hMem));
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case 17: //CF_DIBV5
                //format
                strncpy(format,"CF_DIBV5",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), sizeof(BITMAPV5HEADER), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case 49155:
                //format
                strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"OwnerLink",DEFAULT_TMP_SIZE);
                //datas
                strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE);
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case 49156:
                //format
                strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Native Bitmap Picture",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case 49158:
                //format
                strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"FileName",DEFAULT_TMP_SIZE);
                //datas
                strncpy(data,GlobalLock(hMem),MAX_LINE_SIZE);
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case 49159:
                //format
                strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"FileNameW",DEFAULT_TMP_SIZE);
                //datas
                snprintf(data,MAX_LINE_SIZE,"%S",GlobalLock(hMem));
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              case 49298:
                //format
                strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE);
                if (description[0]==0)strncpy(description,"Rich Text Format",DEFAULT_TMP_SIZE);
                //datas
                snprintf(data,MAX_LINE_SIZE,"%s",(char*)GlobalLock(hMem));
                convertStringToSQL(data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
              default:
                //format
                strncpy(format,"UNKNOW",DEFAULT_TMP_SIZE);
                //datas
                DatatoHexa(GlobalLock(hMem), GlobalSize(hMem), data, MAX_LINE_SIZE);
                GlobalUnlock(hMem);
                addClipboardtoDB(format, uFormat, description, data, user, session_id, db);
              break;
            }
          }
        }
        uFormat = EnumClipboardFormats(uFormat);
      }
    }
    CloseClipboard();
  }
  if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"END TRANSACTION;", NULL, NULL, NULL);

  check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan
  h_thread_test[(unsigned int)lParam] = 0;
  return 0;
}
//------------------------------------------------------------------------------
int callback_sqlite_registry_local(void *datas, int argc, char **argv, char **azColName)
{
  if (argv[0] == 0)return 0;

  FORMAT_CALBAK_TYPE *type = datas;
  unsigned int session_id = current_session_id;
  switch(type->type)
  {
    case SQLITE_REGISTRY_TYPE_SETTINGS:
    {
      HKEY hk = hkStringtohkey(argv[0]);
      switch(atoi(argv[3]))//value_type
      {
        case TYPE_VALUE_STRING:
        {
          char tmp[MAX_PATH]="";
          if (ReadValue(hk,argv[1],argv[2],tmp, MAX_PATH))
          {
            char parent_key_update[DATE_SIZE_MAX];
            ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX);
            convertStringToSQL(tmp, MAX_PATH);
            addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
          }
        }
        break;
        case TYPE_VALUE_DWORD:
        {
          char tmp[MAX_PATH]="";
          long int value= ReadDwordValue(hk,argv[1],argv[2]);
          if (value != -1)
          {
            snprintf(tmp,MAX_PATH,"0x%08X",(unsigned int)value);
            char parent_key_update[DATE_SIZE_MAX];
            ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX);
            addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
          }
        }
        break;
        case TYPE_VALUE_MULTI_STRING:
        {
          char tmp[MAX_PATH]="";
          long int i, tmp_size = ReadValue(hk,argv[1],argv[2],tmp, MAX_PATH);
          if (tmp_size>0)
          {
            char parent_key_update[DATE_SIZE_MAX];
            ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX);
            for (i=0;i<tmp_size;i++)
            {
              if (tmp[i] == 0)tmp[i]=';';
            }
            convertStringToSQL(tmp, MAX_PATH);
            addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
          }
        }
        break;
        case TYPE_VALUE_MULTI_WSTRING:
          {
            char tmp[REQUEST_MAX_SIZE]="",data_read[REQUEST_MAX_SIZE];
            DWORD pos=0, data_size_read = ReadValue(hk,argv[1],argv[2],tmp, REQUEST_MAX_SIZE);

            if (data_size_read)
            {
              char parent_key_update[DATE_SIZE_MAX];
              ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX);

              while ((pos-1)*2<data_size_read)
              {
                snprintf(data_read+pos,REQUEST_MAX_SIZE,"%S;",tmp+(pos*2-1));
                pos = strlen(data_read);
              }

              convertStringToSQL(data_read, MAX_PATH);
              addRegistrySettingstoDB("", argv[0], argv[1], argv[2], data_read, argv[4], argv[5], parent_key_update, session_id, db_scan);
            }
          }
        break;
        case TYPE_VALUE_FILETIME:
        {
          char tmp[MAX_PATH]="";
          FILETIME ft;
          if (hk == 0 || argv[1][0]==0)break;
          ReadFILETIMEValue(hk,argv[1],argv[2],&ft);
          filetimeToString_GMT(ft, tmp, MAX_PATH);

          char parent_key_update[DATE_SIZE_MAX];
          ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX);
          addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
        }
        break;
        case TYPE_VALUE_WIN_SERIAL:
        {
          char tmp[MAX_PATH]="";
          if (GetWindowsCDKey_local(hk, argv[1], argv[2], tmp, MAX_PATH))
          {
            char parent_key_update[DATE_SIZE_MAX];
            ReadKeyUpdate(hk,argv[1], parent_key_update, DATE_SIZE_MAX);
            addRegistrySettingstoDB("", argv[0], argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
          }
        }
        break;
        case TYPE_ENUM_STRING_VALUE:
        {
          HKEY CleTmp=0;
          if (RegOpenKey(hk,argv[1],&CleTmp)!=ERROR_SUCCESS)return 0;

          FILETIME lastupdate;
          char parent_key_update[DATE_SIZE_MAX];

          DWORD NameSize, DataSize;
          char Name[MAX_PATH], Data[MAX_PATH], tmp[MAX_PATH];
          DWORD nbValue = 0, i,j, type2;
          if (RegQueryInfoKey (CleTmp,0,0,0,0,0,0,&nbValue,0,0,0,&lastupdate)==ERROR_SUCCESS)
          {
            filetimeToString_GMT(lastupdate, parent_key_update, DATE_SIZE_MAX);
            for (i=0;i<nbValue;i++)
            {
              NameSize = MAX_PATH;
              DataSize = MAX_PATH;
              Name[0]  = 0;
              Data[0]  = 0;
              type2     = 0;
              if (RegEnumValue (CleTmp,i,(LPTSTR)Name,(LPDWORD)&NameSize,0,(LPDWORD)&type2,(LPBYTE)Data,(LPDWORD)&DataSize)==ERROR_SUCCESS)
              {
                switch(type2)
                {
                  case REG_EXPAND_SZ:
                  case REG_SZ:addRegistrySettingstoDB("", argv[0], argv[1], Name, Data, argv[4], argv[5], parent_key_update, session_id, db_scan);break;
                  case REG_LINK:
                    snprintf(tmp,MAX_PATH,"%S",Data);
                    convertStringToSQL(tmp, MAX_PATH);
                    addRegistrySettingstoDB("", argv[0], argv[1], Name, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
                  break;
                  case REG_MULTI_SZ:
                    for (j=0;j<DataSize;j++)
                    {
                      if (Data[j] == 0)Data[j]=';';
                    }
                    convertStringToSQL(Data, MAX_PATH);
                    addRegistrySettingstoDB("", argv[0], argv[1], Name, Data, argv[4], argv[5], parent_key_update, session_id, db_scan);
                  break;
                  case REG_DWORD:
                    snprintf(tmp,MAX_PATH,"0x%08X",&Data[0]);
                    addRegistrySettingstoDB("", argv[0], argv[1], Name, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
                  break;
                  default : //binary/dword
                    strncpy(tmp,"0x",MAX_PATH);
                    NameSize = 0;
                    for (j=0;j<DataSize && NameSize<MAX_PATH;j++)
                    {
                      NameSize = strlen(tmp);
                      snprintf(tmp+NameSize,MAX_PATH-NameSize,"%02X",Data[j]&0xFF);
                    }
                    addRegistrySettingstoDB("", argv[0], argv[1], Name, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
                  break;
                }
              }
            }
          }
        }
        break;
      }
    }
    break;
  }
  return 0;
}
//------------------------------------------------------------------------------
int callback_sqlite_registry_file(void *datas, int argc, char **argv, char **azColName)
{
  FORMAT_CALBAK_TYPE *type = datas;
  unsigned int session_id = current_session_id;
  char tmp[MAX_LINE_SIZE];
  switch(type->type)
  {
    case SQLITE_REGISTRY_TYPE_SETTINGS:
    {
      switch(atoi(argv[3]))//value_type
      {
        case TYPE_VALUE_STRING:
        case TYPE_VALUE_DWORD:
        case TYPE_VALUE_MULTI_STRING:
          if (Readnk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,
                           argv[1], NULL, argv[2], tmp, MAX_LINE_SIZE))
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX];
            Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position,
                         argv[1], NULL, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0);

            //save
            convertStringToSQL(tmp, MAX_LINE_SIZE);
            addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
          }
        break;
        case TYPE_VALUE_MULTI_WSTRING:
        {
          char data_read[MAX_LINE_SIZE];
          DWORD pos=0, data_size_read = MAX_LINE_SIZE;
          if (ReadBinarynk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,
                                 argv[1], NULL, argv[2], tmp, &data_size_read))
          {
            if (data_size_read)
            {
              //data_read
              while ((pos-1)*2<data_size_read)
              {
                snprintf(data_read+pos,MAX_LINE_SIZE,"%S;",tmp+(pos*2-1));
                pos = strlen(data_read);
              }

              //key update
              char parent_key_update[DATE_SIZE_MAX];
              Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position,
                           argv[1], NULL, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0);

              //save
              convertStringToSQL(data_read, MAX_LINE_SIZE);
              addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], data_read, argv[4], argv[5], parent_key_update, session_id, db_scan);
            }
          }
        }
        break;
        case TYPE_VALUE_FILETIME:
        {
          DWORD data_size = sizeof(FILETIME)+1;
          FILETIME f_date;
          if (ReadBinarynk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,
                           argv[1], NULL, argv[2], (void*)&f_date, &data_size))
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX];
            Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position,
                         argv[1], NULL, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0);

            //convert date
            tmp[0] = 0;
            filetimeToString_GMT(f_date, tmp, DATE_SIZE_MAX);

            //save
            convertStringToSQL(tmp, MAX_LINE_SIZE);
            addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
          }
        }
        break;
        case TYPE_VALUE_WIN_SERIAL:
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,argv[1]);
          if (nk_h!=NULL)
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX];
            Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position,
                         NULL, nk_h, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0);



            //get value
            DWORD test_size = MAX_LINE_SIZE;
            DWORD serial_size;
            ReadBinarynk_Value(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,
                                                         NULL, nk_h, argv[2], (void*)tmp, &test_size);
            if (test_size>65)
            {
              char result[MAX_PATH]="";

              char key[25] = "BCDFGHJKMPQRTVWXY2346789";
              BYTE enc[MAX_PATH];
              char lpszSerial[MAX_PATH];
              int i,c=0,nCur=0;

              for(i=52;i<=66;i++)enc[i-52] = tmp[i];
              for(i=24;i>=0;i--)
              {
                nCur = 0;
                for(c=14;c>-1;c--)
                {
                  nCur = nCur * 256;
                  nCur ^= enc[c];
                  enc[c] = nCur / 24;
                  nCur %= 24;
                }
                lpszSerial[i] = key[nCur];
              }

              serial_size = 0;
              for(i=0;lpszSerial[i] && (i+i/5) < 30 && MAX_PATH>serial_size;i++)
              {
                if(i % 5 == 0 && i>0)snprintf(result+serial_size,MAX_PATH-serial_size,"-%c",lpszSerial[i]);
                else snprintf(result+serial_size,MAX_PATH-serial_size,"%c",lpszSerial[i]);
                serial_size = strlen(result);
              }

              //save
              convertStringToSQL(result, MAX_LINE_SIZE);
              addRegistrySettingstoDB(local_hks.file, "", argv[1], argv[2], result, argv[4], argv[5], parent_key_update, session_id, db_scan);
            }
          }
        }
        break;
        case TYPE_ENUM_STRING_VALUE:
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, local_hks.position,argv[1]);
          if (nk_h!=NULL)
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX];
            Readnk_Infos(local_hks.buffer,local_hks.taille_fic, (local_hks.pos_fhbin), local_hks.position,
                         NULL, nk_h, parent_key_update, DATE_SIZE_MAX, NULL, 0,NULL, 0);

            //get values
            char value[MAX_PATH];
            DWORD i, nbSubValue = GetValueData(local_hks.buffer,local_hks.taille_fic, nk_h, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
            for (i=0;i<nbSubValue;i++)
            {
              if (GetValueData(local_hks.buffer,local_hks.taille_fic, nk_h, (local_hks.pos_fhbin)+HBIN_HEADER_SIZE, i,value,MAX_PATH,tmp,MAX_LINE_SIZE))
              {
                //save
                convertStringToSQL(value, MAX_PATH);
                convertStringToSQL(tmp, MAX_LINE_SIZE);
                addRegistrySettingstoDB(local_hks.file, "", argv[1], value, tmp, argv[4], argv[5], parent_key_update, session_id, db_scan);
              }
            }
          }
        }
        break;
      }
    }
  }
  return 0;
}
//------------------------------------------------------------------------------
DWORD WINAPI Scan_share(LPVOID lParam)
{
  sqlite3 *db = (sqlite3 *)db_scan;
  unsigned int session_id = current_session_id;
  if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"BEGIN TRANSACTION;", NULL, NULL, NULL);
  #ifdef CMD_LINE_ONLY_NO_DB
  printf("\"Share\";\"file\";\"share\";\"path\";\"description\";\"type\";\"connexion\";\"session_id\";\r\n");
  #endif
  if (!LOCAL_SCAN)
  {
    //get in registry files
    char file[MAX_PATH];
    HK_F_OPEN hks;
    HTREEITEM hitem = (HTREEITEM)SendMessage(htrv_files, TVM_GETNEXTITEM,(WPARAM)TVGN_CHILD, (LPARAM)TRV_HTREEITEM_CONF[FILES_TITLE_REGISTRY]);
    while(hitem!=NULL)
    {
      file[0] = 0;
      GetTextFromTrv(hitem, file, MAX_PATH);
      if (file[0] != 0)
      {
        //open file + verify
        if(OpenRegFiletoMem(&hks, file))
        {
          EnumShare(&hks, session_id, db, "ControlSet001\\Services\\LanmanServer\\Shares");
          EnumShare(&hks, session_id, db, "ControlSet002\\Services\\LanmanServer\\Shares");
          EnumShare(&hks, session_id, db, "ControlSet003\\Services\\LanmanServer\\Shares");
          EnumShare(&hks, session_id, db, "ControlSet004\\Services\\LanmanServer\\Shares");
          CloseRegFiletoMem(&hks);
        }
      }
      hitem = (HTREEITEM)SendMessage(htrv_files, TVM_GETNEXTITEM,(WPARAM)TVGN_NEXT, (LPARAM)hitem);
    }
  }else
  {
    //init
    HMODULE hDLL = LoadLibrary("NETAPI32.dll");
    if (hDLL == NULL)return 0;

    typedef NET_API_STATUS (WINAPI *NETAPIBUFFERFREE)(LPVOID Buffer);
    NETAPIBUFFERFREE NetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress(hDLL,"NetApiBufferFree");

    typedef NET_API_STATUS (WINAPI *NETSHAREENUM)(LPWSTR servername, DWORD level, LPBYTE* bufptr, DWORD prefmaxlen, LPDWORD entriesread, LPDWORD totalentries, LPDWORD resume_handle);
    NETSHAREENUM NetShareEnum = (NETSHAREENUM) GetProcAddress(hDLL,"NetShareEnum");

    if (NetApiBufferFree != NULL && NetShareEnum != NULL )
    {
      NET_API_STATUS res;
      PSHARE_INFO_502 buffer,p;
      DWORD nb=0,tr=0,i;
      char share[DEFAULT_TMP_SIZE], path[MAX_PATH], description[MAX_PATH], type[DEFAULT_TMP_SIZE], connexion[DEFAULT_TMP_SIZE];

      do
      {
        res = NetShareEnum (0, 502, (LPBYTE *) &buffer,MAX_PREFERRED_LENGTH, &nb, &tr,0);
        if(res != ERROR_SUCCESS && res != ERROR_MORE_DATA)break;

        for(i=1,p=buffer;i<=nb;i++,p++)
        {
          snprintf(share,DEFAULT_TMP_SIZE,"%S",p->shi502_netname);
          snprintf(path,MAX_PATH,"%S",p->shi502_path);
          snprintf(description,MAX_PATH,"%S",p->shi502_remark);

          switch(p->shi502_type)
          {
            case STYPE_DISKTREE:  strncpy(type,"DISKTREE",DEFAULT_TMP_SIZE);break;
            case STYPE_PRINTQ:    strncpy(type,"PRINT",DEFAULT_TMP_SIZE);break;
            case STYPE_DEVICE:    strncpy(type,"DEVICE",DEFAULT_TMP_SIZE);break;
            case STYPE_IPC:       strncpy(type,"IPC",DEFAULT_TMP_SIZE);break;
            case STYPE_SPECIAL:   strncpy(type,"SPECIAL",DEFAULT_TMP_SIZE);break;
            case 0x40000000:      strncpy(type,"TEMPORARY",DEFAULT_TMP_SIZE);break;
            case -2147483645:     strncpy(type,"RPC",DEFAULT_TMP_SIZE);break;
            default :             snprintf(type,DEFAULT_TMP_SIZE,"UNKNOW (%lu)",p->shi502_type);break;
          }

          if (p->shi502_max_uses==-1)
            snprintf(connexion,DEFAULT_TMP_SIZE,"%lu/-",p->shi502_current_uses);
          else snprintf(connexion,DEFAULT_TMP_SIZE,"%lu/%lu",p->shi502_current_uses,p->shi502_max_uses);

          convertStringToSQL(path, MAX_PATH);
          convertStringToSQL(description, MAX_PATH);
          addSharetoDB("",share, path, description, type, connexion, session_id, db);
        }
      }while(res==ERROR_MORE_DATA);
    }
    FreeLibrary(hDLL);
  }

  if(!SQLITE_FULL_SPEED)sqlite3_exec(db_scan,"END TRANSACTION;", NULL, NULL, NULL);
  check_treeview(htrv_test, H_tests[(unsigned int)lParam], TRV_STATE_UNCHECK);//db_scan
  h_thread_test[(unsigned int)lParam] = 0;
  return 0;
}
//------------------------------------------------------------------------------
void Scan_registry_user_file(HK_F_OPEN *hks, sqlite3 *db, unsigned int session_id, char *computer_name)
{
  DWORD userRID = 0;
  USERS_INFOS User_infos;
  #ifdef CMD_LINE_ONLY_NO_DB
  printf("\"RegistryUser\";\"source\";\"name\";\"RID\";\"SID\";\"grp\";\"description\";\"last_logon\";\"last_password_change\";"
         "\"nb_connexion\";\"type\";\"state_id\";\"session_id\";\r\n");
  #endif
  //get ref key for hashs
  BYTE b_f[MAX_LINE_SIZE];
  Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, "SAM\\Domains\\Account", NULL,"F", b_f, MAX_LINE_SIZE);

  //enum all users
  //exist or not in the file ?
  HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, "SAM\\Domains\\Account\\Users");
  if (nk_h == NULL)return;

  HBIN_CELL_NK_HEADER *nk_h_tmp;
  DWORD valueSize;
  BOOL ok_test;
  char SubKeyName[MAX_PATH];
  char cbuffer[MAX_LINE_SIZE], buffer[MAX_LINE_SIZE];
  DWORD i,nbSubKey = GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, 0, NULL, 0);
  for (i=0;i<nbSubKey;i++)
  {
    ok_test = FALSE;
    //for each subkey
    if(GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, i, SubKeyName, MAX_PATH))
    {
      //get nk of key :)
      nk_h_tmp = GetSubNKtonk(hks->buffer, hks->taille_fic, nk_h, hks->position, i);
      if (nk_h_tmp == NULL)continue;

      //F
      buffer[0]  = 0;
      cbuffer[0] = 0;
      valueSize  = MAX_LINE_SIZE;
      if(ReadBinarynk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"F", buffer, &valueSize))
      {
        DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE);
        userRID = TestUserDataFromSAM_F(&User_infos,cbuffer);
        ok_test = TRUE;
      }

      //V
      buffer[0]  = 0;
      cbuffer[0] = 0;
      valueSize  = MAX_LINE_SIZE;
      if(ReadBinarynk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"V", buffer, &valueSize))
      {
        DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE);
        if(TestUserDataFromSAM_V(&User_infos,cbuffer,computer_name))
        {
          //test if rid and sid ok
          userRID = HTDF(SubKeyName,8);
          if(User_infos.RID[0] == 0)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID);
          if(User_infos.SID[0] == 0)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID);
        }else
        {
          if(User_infos.RID[0] == 0 && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID);
          if(User_infos.SID[0] == 0 && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID);
        }
        ok_test = TRUE;
      }else
      {
        if(User_infos.RID[0] == 0 && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID);
        if(User_infos.SID[0] == 0 && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID);
      }

      if (!ok_test)continue;

      //get groups
      if (userRID) GetUserGroupFRF(userRID, User_infos.group, MAX_PATH);

      //get hashs
      if(b_f[0] != 0 && _SYSKEY[0] != 0)
      {
        DecodeSAMHashXP(_SYSKEY,User_infos.pwdump_pwd_raw_format,userRID,User_infos.name,b_f);
      }

      //add user
      convertStringToSQL(User_infos.description, MAX_PATH);
      addRegistryUsertoDB(hks->file,User_infos.name, User_infos.RID, User_infos.SID, User_infos.group,
                          User_infos.description, User_infos.last_logon, User_infos.last_password_change,
                          User_infos.nb_connexion, User_infos.type, User_infos.state_id,session_id, db);

      //add password
      if (TEST_REG_PASSWORD_ENABLE)
        addPasswordtoDB(hks->file, User_infos.name, User_infos.pwdump_pwd_format, User_infos.pwdump_pwd_raw_format, REG_PASSWORD_STRING_LOCAL_USER, session_id, db);
    }
  }
}
//------------------------------------------------------------------------------
BOOL registry_users_extract(sqlite3 *db, unsigned int session_id)
{
  BOOL ok = FALSE;
  DWORD userRID;
  USERS_INFOS User_infos;

  //import syskey
  char sk[MAX_PATH]="";
  BOOL syskeyok = registry_syskey_local(sk, MAX_PATH);

  //get current computer name
  char computer_name[COMPUTER_NAME_SIZE_MAX]="";
  DWORD taille = COMPUTER_NAME_SIZE_MAX;
  GetComputerName(computer_name,&taille);

  //Set ACL in registry
  int ret = set_sam_tree_access(HKEY_LOCAL_MACHINE,"SECURITY\\SAM\\Domains\\Account\\Users");
  if (ret == 0)
  {
    //get reference key for users hashs
    HKEY CleTmp;
    BOOL ok_test;
    BYTE b_f[MAX_LINE_SIZE];
    if(ReadValue(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account", "F", (char*)b_f, MAX_LINE_SIZE)<= 0x80)b_f[0] = 0;

    //get users
    if (RegOpenKey(HKEY_LOCAL_MACHINE,"SAM\\SAM\\Domains\\Account\\Users\\",&CleTmp)==ERROR_SUCCESS)
    {
      DWORD i, valueSize, SizeSubKeyName, nbSubKey = 0;
      if (RegQueryInfoKey (CleTmp,0,0,0,&nbSubKey,0,0,0,0,0,0,0)==ERROR_SUCCESS)
      {
        char SubKeyName[MAX_PATH], path[MAX_PATH], buffer[MAX_LINE_SIZE], cbuffer[MAX_LINE_SIZE];

        for (i=0;i<nbSubKey;i++)
        {
          ok_test       = FALSE;
          SizeSubKeyName=MAX_PATH;// on reinitialise la taille a chaque fois sinon il ne lit pas la valeur suivant
          SubKeyName[0] = 0;
          if(RegEnumKeyEx (CleTmp,i,SubKeyName,&SizeSubKeyName,0,0,0,0)!=ERROR_SUCCESS)continue;

          //read value
          snprintf(path,MAX_PATH,"SAM\\SAM\\Domains\\Account\\Users\\%s",SubKeyName);

          //F value
          cbuffer[0]= 0;
          buffer[0] = 0;
          userRID   = 0;
          valueSize = ReadValue(HKEY_LOCAL_MACHINE, path, "F", buffer, MAX_LINE_SIZE);
          if (valueSize)
          {
            DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE);
            userRID = TestUserDataFromSAM_F(&User_infos,cbuffer);
            ok_test = TRUE;
         }

          //V value
          cbuffer[0]= 0;
          buffer[0] = 0;
          valueSize = ReadValue(HKEY_LOCAL_MACHINE, path, "V", buffer, MAX_LINE_SIZE);
          if (valueSize)
          {
            //read datas
            DataToHexaChar(buffer, valueSize, cbuffer, MAX_LINE_SIZE);
            if(TestUserDataFromSAM_V(&User_infos,cbuffer,computer_name))
            {
              //test if rid and sid ok
              userRID = HTDF(SubKeyName,8);
              if(User_infos.RID[0] == 0)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID);
              if(User_infos.SID[0] == 0)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID);
           }else
            {
              if((User_infos.RID[0] == 0) && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID);
              if((User_infos.SID[0] == 0) && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID);
            }
            ok_test = TRUE;
          }else
          {
            if((User_infos.RID[0] == 0) && userRID)snprintf(User_infos.RID,MAX_PATH,"%05lu",userRID);
            if((User_infos.SID[0] == 0) && userRID)snprintf(User_infos.SID,MAX_PATH,"S-1-5-?-?-?-?-%lu",userRID);
         }

          if (!ok_test)continue;

          //get groups
          if (userRID) GetUserGroup(userRID, User_infos.group, MAX_PATH);

          //get hashs
          if((b_f[0] != 0) && syskeyok)
          {
            DecodeSAMHashXP(sk,User_infos.pwdump_pwd_raw_format,userRID,User_infos.name,b_f);
          }

          //add user
          convertStringToSQL(User_infos.description, MAX_PATH);
          addRegistryUsertoDB("HKEY_LOCAL_MACHINE\\SAM",User_infos.name, User_infos.RID, User_infos.SID, User_infos.group,
                              User_infos.description, User_infos.last_logon, User_infos.last_password_change,
                              User_infos.nb_connexion, User_infos.type, User_infos.state_id,session_id, db);

          //add password
          if (TEST_REG_PASSWORD_ENABLE)
            addPasswordtoDB("HKEY_LOCAL_MACHINE\\SAM", User_infos.name, User_infos.pwdump_pwd_format, User_infos.pwdump_pwd_raw_format, REG_PASSWORD_STRING_LOCAL_USER, session_id, db);
          ok = TRUE;
        }
      }
      RegCloseKey(CleTmp);
    }
  }

  //Restore ACL in registry
  restore_sam_tree_access(HKEY_LOCAL_MACHINE,"SECURITY\\SAM\\Domains\\Account\\Users");

  return ok;
}
//------------------------------------------------------------------------------
//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);
}
//------------------------------------------------------------------------------
//file registry part
//------------------------------------------------------------------------------
void EnumPath_file(HK_F_OPEN *hks, char*key_before,char *key_after,unsigned int session_id, sqlite3 *db, BOOL direct)
{
  HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks->buffer,hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position,key_before);
  if (nk_h == NULL)return;

  char parent_key_update[DATE_SIZE_MAX] = "";
  char RID[MAX_PATH], sid[MAX_PATH];
  char value[MAX_PATH], data[MAX_PATH];

  char tmp_key[MAX_PATH],key_path[MAX_PATH];
  HBIN_CELL_NK_HEADER *nk_h_tmp;
  DWORD i,k, nbSubValue, nbSubKey;

  if(direct)
  {
    //get nk of key :)
    nk_h_tmp = GetRegistryNK(hks->buffer,hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position,key_before);
    if (nk_h_tmp == NULL)return;

    //key update
    Readnk_Infos(hks->buffer,hks->taille_fic, (hks->pos_fhbin), hks->position,
                 NULL, nk_h_tmp, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);
    //get values
    nbSubValue = GetValueData(hks->buffer,hks->taille_fic, nk_h_tmp, (hks->pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
    for (k=0;k<nbSubValue && start_scan;k++)
    {
      if (GetValueData(hks->buffer,hks->taille_fic, nk_h_tmp, (hks->pos_fhbin)+HBIN_HEADER_SIZE, k,value,MAX_PATH,data,MAX_PATH))
      {
        //save
        convertStringToSQL(value, MAX_PATH);
        convertStringToSQL(data, MAX_PATH);
        addRegistryPathtoDB(hks->file,"",key_before,value,data,"",RID,sid,parent_key_update,session_id,db);
      }
    }
  }else
  {
    nbSubKey = GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, 0, NULL, 0);
    for (i=0;i<nbSubKey && start_scan;i++)
    {
      //for each subkey
      if(GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, i, tmp_key, MAX_PATH))
      {
        if (key_after!=NULL) snprintf(key_path,MAX_PATH,"%s\\%s\\%s",key_before,tmp_key,key_after);
        else snprintf(key_path,MAX_PATH,"%s\\%s",key_before,tmp_key);

        //get nk of key :)
        nk_h_tmp = GetRegistryNK(hks->buffer,hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position,key_path);
        if (nk_h_tmp == NULL)continue;

        //key update
        Readnk_Infos(hks->buffer,hks->taille_fic, (hks->pos_fhbin), hks->position,
                     NULL, nk_h_tmp, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);
        //get values
        nbSubValue = GetValueData(hks->buffer,hks->taille_fic, nk_h_tmp, (hks->pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
        for (k=0;k<nbSubValue && start_scan;k++)
        {
          if (GetValueData(hks->buffer,hks->taille_fic, nk_h_tmp, (hks->pos_fhbin)+HBIN_HEADER_SIZE, k,value,MAX_PATH,data,MAX_PATH))
          {
            //save
            convertStringToSQL(value, MAX_PATH);
            convertStringToSQL(data, MAX_PATH);
            addRegistryPathtoDB(hks->file,"",key_path,value,data,"",RID,sid,parent_key_update,session_id,db);
          }
        }
      }
    }
  }
}
//------------------------------------------------------------------------------
int callback_sqlite_registry_mru_file(void *datas, int argc, char **argv, char **azColName)
{
  FORMAT_CALBAK_TYPE *type = datas;
  unsigned int session_id = current_session_id;
  char tmp[MAX_LINE_SIZE];

  switch(type->type)
  {
    case SQLITE_REGISTRY_TYPE_MRU:
    {
      switch(atoi(argv[3]))//value_type
      {
        case TYPE_VALUE_STRING:
        case TYPE_VALUE_WSTRING:
          if (Readnk_Value(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,
                           argv[1], NULL, argv[2], tmp, MAX_LINE_SIZE))
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX]="";
            char RID[MAX_PATH]="", sid[MAX_PATH]="";
            Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                         argv[1], NULL, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);
            //save
            convertStringToSQL(tmp, MAX_LINE_SIZE);
            addRegistryMRUtoDB(hks_mru.file,"",argv[1],argv[2],tmp,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
          }
        break;
        case TYPE_ENUM_STRING_RVALUE://all string under one key
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h!=NULL)
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX]="";
            char RID[MAX_PATH]="", sid[MAX_PATH]="";
            Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                         NULL, nk_h, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

            //get values
            char value[MAX_PATH];
            DWORD i, nbSubValue = GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);

            for (i=0;i<nbSubValue && start_scan;i++)
            {
              if (GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, i,value,MAX_PATH,tmp,MAX_LINE_SIZE))
              {
                //if (strcmp(charToLowChar(value),argv[2]) != 0)
                {
                  //save
                  convertStringToSQL(value, MAX_PATH);
                  convertStringToSQL(tmp, MAX_LINE_SIZE);
                  addRegistryMRUtoDB(hks_mru.file,"",argv[1],value,tmp,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                }
              }
            }
          }
        }
        break;
        case TYPE_ENUM_STRING_VALUE://list of all string in a directory and exclude "value"
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h!=NULL)
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX]="";
            char RID[MAX_PATH]="", sid[MAX_PATH]="";
            Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                         NULL, nk_h, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

            //get values
            char value[MAX_PATH];
            DWORD i, nbSubValue = GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
            for (i=0;i<nbSubValue && start_scan;i++)
            {
              if (GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, i,value,MAX_PATH,tmp,MAX_LINE_SIZE))
              {
                //if (strcmp(charToLowChar(value),argv[2]) != 0)
                {
                  //save
                  convertStringToSQL(value, MAX_PATH);
                  convertStringToSQL(tmp, MAX_LINE_SIZE);
                  addRegistryMRUtoDB(hks_mru.file,"",argv[1],value,tmp,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                }
              }
            }
          }
        }
        break;
        case TYPE_ENUM_STRING_NVALUE://list of all string in a directory with "value"
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h!=NULL)
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX]="";
            char RID[MAX_PATH]="", sid[MAX_PATH]="";
            Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                         NULL, nk_h, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

            //get values
            char value[MAX_PATH];
            DWORD i, nbSubValue = GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
            for (i=0;i<nbSubValue && start_scan;i++)
            {
              if (GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, i,value,MAX_PATH,tmp,MAX_LINE_SIZE))
              {
                if (Contient(charToLowChar(value),argv[2]))
                {
                  //save
                  convertStringToSQL(value, MAX_PATH);
                  convertStringToSQL(tmp, MAX_LINE_SIZE);
                  addRegistryMRUtoDB(hks_mru.file,"",argv[1],value,tmp,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                }
              }
            }
          }
        }
        break;
        case TYPE_ENUM_STRING_WVALUE:
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h!=NULL)
          {
            //key update
            char parent_key_update[DATE_SIZE_MAX]="";
            char RID[MAX_PATH]="", sid[MAX_PATH]="";
            Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                         NULL, nk_h, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

            //get values
            char value[MAX_PATH],data[MAX_LINE_SIZE];
            DWORD i, nbSubValue = GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
            DWORD sz_value = MAX_LINE_SIZE;
            for (i=0;i<nbSubValue && start_scan;i++)
            {
              sz_value = MAX_LINE_SIZE;
              if (GetBinaryValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, i,value,MAX_PATH,tmp,&sz_value))
              {
                //save
                convertStringToSQL(value, MAX_PATH);
                snprintf(data,MAX_LINE_SIZE,"%S",tmp);
                convertStringToSQL(tmp, MAX_LINE_SIZE);
                addRegistryMRUtoDB(hks_mru.file,"",argv[1],value,data,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
              }
            }
          }
        }
        break;

        case TYPE_ENUM_SUBNK_DATE:
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h!=NULL)
          {
            char parent_key_update[DATE_SIZE_MAX]="";
            char RID[MAX_PATH]="", sid[MAX_PATH]="";

            //get values
            char value[MAX_PATH], tmp_key[MAX_PATH];
            DWORD i, nbSubnk = GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0);

            for (i=0;i<nbSubnk && start_scan;i++)
            {
              if (GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, i, value, MAX_PATH))
              {
                snprintf(tmp_key,MAX_PATH,"%s\\%s",argv[1],value);
                HBIN_CELL_NK_HEADER *nk_ht = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,tmp_key);

                if (nk_ht!=NULL)
                {
                  //key update
                  Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                               NULL, nk_ht, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);
                  //save
                  convertStringToSQL(tmp_key, MAX_PATH);
                  addRegistryMRUtoDB(hks_mru.file,"",tmp_key,"","",argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                }
              }
            }
          }
        }
        break;
        case TYPE_DBL_ENUM_VALUE:
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h==NULL)break;

          char parent_key_update[DATE_SIZE_MAX]="";
          char RID[MAX_PATH]="", sid[MAX_PATH]="", data[MAX_PATH];
          HBIN_CELL_NK_HEADER *nk_ht, *nk_ht2;

          //get values
          char value2[MAX_PATH],value[MAX_PATH], tmp_key2[MAX_PATH], tmp_key[MAX_PATH];
          DWORD i,j, nbSubnk2, nbSubnk = GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0);
          for (i=0;i<nbSubnk && start_scan;i++)
          {
            if (GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, i, value, MAX_PATH))
            {
              snprintf(tmp_key,MAX_PATH,"%s\\%s\\AVGeneral\\cRecentFiles",argv[1],value);
              nk_ht = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,tmp_key);

              nbSubnk2 = GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_ht, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0);
              for (j=0;j<nbSubnk2 && start_scan;j++)
              {
                if (GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_ht, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, j, value2, MAX_PATH))
                {
                  snprintf(tmp_key2,MAX_PATH,"%s\\%s",tmp_key,value2);
                  nk_ht2 = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,tmp_key2);

                  //datas
                  if(Readnk_Value(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position, NULL, nk_ht2, argv[2],
                                  data, MAX_PATH))
                  {
                    //key update
                    Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                                 NULL, nk_ht2, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

                    //save
                    convertStringToSQL(data, MAX_PATH);
                    addRegistryMRUtoDB(hks_mru.file,"",tmp_key2,argv[2],data,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                  }
                }
              }
            }
          }
        }
        break;
        case TYPE_ENUM_STRING_RRVALUE://all string under thow key + key
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h == NULL)return 0;

          char parent_key_update[DATE_SIZE_MAX]="";
          char RID[MAX_PATH]="", sid[MAX_PATH]="";
          char value[MAX_PATH];

          char tmp_key[MAX_PATH], tmp_key2[MAX_PATH], key_path[MAX_PATH];
          HBIN_CELL_NK_HEADER *nk_h_tmp, *nk_h_tmp2;
          DWORD i,j,k, nbSubValue,nbSubKey2,nbSubKey = GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, hks_mru.position, 0, NULL, 0);
          for (i=0;i<nbSubKey && start_scan;i++)
          {
            if(GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, hks_mru.position, i, tmp_key, MAX_PATH))
            {
              //get nk of key :)
              nk_h_tmp = GetSubNKtonk(hks_mru.buffer, hks_mru.taille_fic, nk_h, hks_mru.position, i);
              if (nk_h_tmp == NULL)continue;

              nbSubKey2 = GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h_tmp, hks_mru.position, 0, NULL, 0);
              for (j=0;j<nbSubKey2 && start_scan;j++)
              {
                if(GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h_tmp, hks_mru.position, j, tmp_key2, MAX_PATH))
                {
                  //get nk of key :)
                  snprintf(key_path,MAX_PATH,"%s\\%s\\%s\\%s",argv[1],tmp_key,tmp_key2,argv[2]);
                  nk_h_tmp2 = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,key_path);
                  if (nk_h_tmp2 == NULL)continue;

                  //key update
                  Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                               NULL, nk_h_tmp2, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

                  //get values
                  nbSubValue = GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h_tmp2, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
                  for (k=0;k<nbSubValue;k++)
                  {
                    if (GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h_tmp2, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, k,value,MAX_PATH,tmp,MAX_LINE_SIZE))
                    {
                      //save
                      convertStringToSQL(value, MAX_PATH);
                      convertStringToSQL(tmp, MAX_LINE_SIZE);
                      addRegistryMRUtoDB(hks_mru.file,"",key_path,value,tmp,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                    }
                  }
                }
              }
            }
          }
        }
        break;
        case TYPE_ENUM_STRING_R_VALUE://all string under one key + key
        {
          HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,argv[1]);
          if (nk_h == NULL)return 0;

          char parent_key_update[DATE_SIZE_MAX]="";
          char RID[MAX_PATH]="", sid[MAX_PATH]="";
          char value[MAX_PATH];

          char tmp_key[MAX_PATH], key_path[MAX_PATH];
          HBIN_CELL_NK_HEADER *nk_h_tmp, *nk_h_tmp2;
          DWORD i,k, nbSubValue,nbSubKey = GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, hks_mru.position, 0, NULL, 0);
          for (i=0;i<nbSubKey && start_scan;i++)
          {
            if(GetSubNK(hks_mru.buffer, hks_mru.taille_fic, nk_h, hks_mru.position, i, tmp_key, MAX_PATH))
            {
              //get nk of key :)
              nk_h_tmp = GetSubNKtonk(hks_mru.buffer, hks_mru.taille_fic, nk_h, hks_mru.position, i);
              if (nk_h_tmp == NULL)continue;

              snprintf(key_path,MAX_PATH,"%s\\%s\\%s",argv[1],tmp_key,argv[2]);
              nk_h_tmp2 = GetRegistryNK(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, hks_mru.position,key_path);
              if (nk_h_tmp2 == NULL)continue;

              //key update
              Readnk_Infos(hks_mru.buffer,hks_mru.taille_fic, (hks_mru.pos_fhbin), hks_mru.position,
                           NULL, nk_h_tmp2, parent_key_update, DATE_SIZE_MAX, RID, MAX_PATH,sid, MAX_PATH);

              //get values
              nbSubValue = GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h_tmp2, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, 0, NULL, 0, NULL, 0);
              for (k=0;k<nbSubValue;k++)
              {
                if (GetValueData(hks_mru.buffer,hks_mru.taille_fic, nk_h_tmp2, (hks_mru.pos_fhbin)+HBIN_HEADER_SIZE, k,value,MAX_PATH,tmp,MAX_LINE_SIZE))
                {
                  //save
                  convertStringToSQL(value, MAX_PATH);
                  convertStringToSQL(tmp, MAX_LINE_SIZE);
                  addRegistryMRUtoDB(hks_mru.file,"",key_path,value,tmp,argv[5],"",RID,sid,parent_key_update,session_id,db_scan);
                }
              }
            }
          }
        }
        break;
      }
    }break;
  }
  return 0;
}
//------------------------------------------------------------------------------
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;
  }
}
//------------------------------------------------------------------------------
//local function part !!!
//------------------------------------------------------------------------------
void Scan_registry_service_local(char *ckey, sqlite3 *db, unsigned int session_id)
{
  HKEY CleTmp;
  if (RegOpenKey(HKEY_LOCAL_MACHINE,ckey,&CleTmp)==ERROR_SUCCESS)
  {
    DWORD i,nbSubKey = 0;
    if (RegQueryInfoKey (CleTmp,0,0,0,&nbSubKey,0,0,0,0,0,0,0)==ERROR_SUCCESS)
    {
      FILETIME LastWriteTime;
      char key[MAX_PATH],key_path[MAX_PATH];
      DWORD key_size;
      DWORD state_id,type_id;
      char lastupdate[DATE_SIZE_MAX],
      name[MAX_PATH],path[MAX_PATH],description[MAX_PATH];

      for (i=0;i<nbSubKey && start_scan;i++)
      {
        key_size  = MAX_PATH;
        key[0]    = 0;
        if (RegEnumKeyEx (CleTmp,i,key,&key_size,0,0,0,&LastWriteTime)==ERROR_SUCCESS)
        {
          //path
          snprintf(key_path,MAX_PATH,"%s%s",ckey,key);

          //read values
          name[0]       = 0;
          path[0]       = 0;
          description[0]= 0;
          lastupdate[0] = 0;

          //name
          if (ReadValue(HKEY_LOCAL_MACHINE,key_path,"DisplayName",name, MAX_PATH) == 0)
          {
            if (ReadValue(HKEY_LOCAL_MACHINE,key_path,"Group",name, MAX_PATH) == 0)continue;

            strncpy(name,key,MAX_PATH);
          }

          //state id
          state_id = ReadDwordValue(HKEY_LOCAL_MACHINE,key_path,"Start");
          switch(state_id)
          {
            case 0: state_id=210;break;//Kernel module   : 210
            case 1: state_id=211;break;//Start by system : 211
            case 2: state_id=212;break;//Automatic start : 212
            case 3: state_id=213;break;//Manual start    : 213
            case 4: state_id=214;break;//Disable         : 214
            default:state_id=215;break;//Unknow          : 215
          }

          //path : ImagePath
          ReadValue(HKEY_LOCAL_MACHINE,key_path,"ImagePath",path, MAX_PATH);

          //description : Description
          if(ReadValue(HKEY_LOCAL_MACHINE,key_path,"Description",description, MAX_PATH) == 0)
            ReadValue(HKEY_LOCAL_MACHINE,key_path,"Group",description, MAX_PATH);

          //type_id
          type_id = ReadDwordValue(HKEY_LOCAL_MACHINE,key_path,"Type");
          if (type_id == 1)type_id = 200; //SERVICE : 200
          else type_id = 201;             //DRIVER  : 201

          //last update
          filetimeToString_GMT(LastWriteTime, lastupdate, DATE_SIZE_MAX);

          convertStringToSQL(path, MAX_PATH);
          convertStringToSQL(description, MAX_PATH);

          addRegistryServicetoDB("", "HKEY_LOCAL_MACHINE", key_path, name,
                                  state_id, path, description, type_id,
                                  lastupdate, session_id, db);
        }
      }
    }
    RegCloseKey(CleTmp);
  }
}
//------------------------------------------------------------------------------
//file registry part
//------------------------------------------------------------------------------
void Scan_registry_service_file(HK_F_OPEN *hks, char *ckey, unsigned int session_id, sqlite3 *db)
{
  //exist or not in the file ?
  HBIN_CELL_NK_HEADER *nk_h = GetRegistryNK(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, ckey);
  if (nk_h == NULL)return;

  char tmp_key[MAX_PATH],key_path[MAX_PATH],state[MAX_PATH];
  DWORD state_id,type_id;
  char lastupdate[DATE_SIZE_MAX],
  name[MAX_PATH],path[MAX_PATH],description[MAX_PATH];

  HBIN_CELL_NK_HEADER *nk_h_tmp;
  DWORD i,nbSubKey = GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, 0, NULL, 0);
  for (i=0;i<nbSubKey;i++)
  {
    //for each subkey
    if(GetSubNK(hks->buffer, hks->taille_fic, nk_h, hks->position, i, tmp_key, MAX_PATH))
    {
      //get nk of key :)
      nk_h_tmp = GetSubNKtonk(hks->buffer, hks->taille_fic, nk_h, hks->position, i);
      if (nk_h_tmp == NULL)continue;

      //read datas ^^
      snprintf(key_path,MAX_PATH,"%s\\%s",ckey,tmp_key);

      if (Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"DisplayName", name, MAX_PATH)==FALSE)
      {
        if (Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"Group", name, MAX_PATH)==FALSE)continue;

        strncpy(name,tmp_key,MAX_PATH);
      }

      if(Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"Start", state, MAX_PATH))
      {
             if (strcmp(state,"0x00000000") == 0)state_id=210;//Kernel module   : 210
        else if (strcmp(state,"0x00000001") == 0)state_id=211;//Start by system : 211
        else if (strcmp(state,"0x00000002") == 0)state_id=212;//Automatic start : 212
        else if (strcmp(state,"0x00000003") == 0)state_id=213;//Manual start    : 213
        else if (strcmp(state,"0x00000004") == 0)state_id=214;//Disable         : 214
        else state_id=215;                                    //Unknow          : 215
      }else state_id = 0;

      Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"ImagePath", path, MAX_PATH);

      if(Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"Description", description, MAX_PATH)==FALSE)
        Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"Group", description, MAX_PATH);


      Readnk_Value(hks->buffer, hks->taille_fic, (hks->pos_fhbin)+HBIN_HEADER_SIZE, hks->position, NULL, nk_h_tmp,"Type", state, MAX_PATH);

      if (strcmp(state,"0x00000001") == 0)     type_id = 200;//Kernel driver
      else if (strcmp(state,"0x00000002") == 0)type_id = 201;//File system driver
      else if (strcmp(state,"0x00000010") == 0)type_id = 202;//Own process
      else if (strcmp(state,"0x00000020") == 0)type_id = 203;//Share process
      else if (strcmp(state,"0x00000100") == 0)type_id = 204;//Interactive
      else type_id = 215;

      Readnk_Infos(hks->buffer, hks->taille_fic, (hks->pos_fhbin), hks->position, NULL, nk_h_tmp,
                   lastupdate, DATE_SIZE_MAX, NULL, 0, NULL, 0);

      convertStringToSQL(path, MAX_PATH);
      convertStringToSQL(description, MAX_PATH);
      addRegistryServicetoDB(hks->file, "", key_path, name,
                             state_id, path, description, type_id,
                             lastupdate, session_id, db);
    }
  }
}