//------------------------------------------------------------------------------
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);
    }
  }
}
//------------------------------------------------------------------------------
//extraction des données de la valeur F du profil
DWORD TestUserDataFromSAM_F(USERS_INFOS *User_infos, char*buffer)
{
  User_infos->last_logon[0]            = 0;
  User_infos->last_password_change[0]  = 0;
  User_infos->nb_connexion             = 0;
  User_infos->state_id                 = 0;

  DWORD userRID = 0;

  if (strlen(buffer)>0x8F)
  {
    char tmp[MAX_PATH];

    //Offset 0008 : date de dernière connexion
    FILETIME FileTime;

    tmp[0] = buffer[0x16];
    tmp[1] = buffer[0x17];
    tmp[2] = buffer[0x14];
    tmp[3] = buffer[0x15];
    tmp[4] = buffer[0x12];
    tmp[5] = buffer[0x13];
    tmp[6] = buffer[0x10];
    tmp[7] = buffer[0x11];
    FileTime.dwLowDateTime = HTDF(tmp,8);

    tmp[0] = buffer[0x1E];
    tmp[1] = buffer[0x1F];
    tmp[2] = buffer[0x1C];
    tmp[3] = buffer[0x1D];
    tmp[4] = buffer[0x1A];
    tmp[5] = buffer[0x1B];
    tmp[6] = buffer[0x18];
    tmp[7] = buffer[0x19];
    FileTime.dwHighDateTime = HTDF(tmp,8);
    if ((FileTime.dwHighDateTime == 0) && (FileTime.dwLowDateTime == 0))strncpy(User_infos->last_logon,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX);
    else
    {
      filetimeToString_GMT(FileTime, User_infos->last_logon, DATE_SIZE_MAX);
      if (User_infos->last_logon[0] == 0)strncpy(User_infos->last_logon,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX);
    }

    //Last password change
    tmp[0] = buffer[0x36];
    tmp[1] = buffer[0x37];
    tmp[2] = buffer[0x34];
    tmp[3] = buffer[0x35];
    tmp[4] = buffer[0x32];
    tmp[5] = buffer[0x33];
    tmp[6] = buffer[0x30];
    tmp[7] = buffer[0x31];
    FileTime.dwLowDateTime = HTDF(tmp,8);

    tmp[0] = buffer[0x3E];
    tmp[1] = buffer[0x3F];
    tmp[2] = buffer[0x3C];
    tmp[3] = buffer[0x3D];
    tmp[4] = buffer[0x3A];
    tmp[5] = buffer[0x3B];
    tmp[6] = buffer[0x38];
    tmp[7] = buffer[0x39];
    FileTime.dwHighDateTime = HTDF(tmp,8);
    if ((FileTime.dwHighDateTime == 0) && (FileTime.dwLowDateTime == 0))strncpy(User_infos->last_password_change,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX);
    else
    {
      filetimeToString_GMT(FileTime, User_infos->last_password_change, DATE_SIZE_MAX);
      if (User_infos->last_password_change[0] == 0)strncpy(User_infos->last_password_change,cps[TXT_MSG_NEVER].c,DATE_SIZE_MAX);
    }

    //Offste 0038, second digit = State
    if (buffer[0x71]=='0')User_infos->state_id=301;
    else User_infos->state_id=300;

    //Password Expire
    if ((buffer[0x73]=='2')||(buffer[0x73]=='3')||(buffer[0x73]=='6')||(buffer[0x73]=='7')||(buffer[0x73]=='A')||(buffer[0x73]=='B')||(buffer[0x73]=='E')||(buffer[0x73]=='F'))
    {
      strncat(User_infos->last_password_change," (",MAX_PATH);
      strncat(User_infos->last_password_change,cps[TXT_MSG_MDP_NEVER_EXP].c,MAX_PATH);
      strncat(User_infos->last_password_change,")\0",MAX_PATH);
    }

    //nombre de connexion 0x42
    tmp[0] = buffer[0x86];
    tmp[1] = buffer[0x87];
    tmp[2] = buffer[0x84];
    tmp[3] = buffer[0x85];
    User_infos->nb_connexion = HTDF(tmp,4);

    //Offset 0030 : user RID
    tmp[0] = buffer[0x66];
    tmp[1] = buffer[0x67];
    tmp[2] = buffer[0x64];
    tmp[3] = buffer[0x65];
    tmp[4] = buffer[0x62];
    tmp[5] = buffer[0x63];
    tmp[6] = buffer[0x60];
    tmp[7] = buffer[0x61];
    userRID = HTDF(tmp,8);
  }

  return userRID;
}
//------------------------------------------------------------------------------
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;
}
//------------------------------------------------------------------------------
BOOL TestUserDataFromSAM_V(USERS_INFOS *User_infos, char *buffer, char *computer)
{
  //init
  User_infos->name[0]                  = 0;
  User_infos->RID[0]                   = 0;
  User_infos->SID[0]                   = 0;
  User_infos->group[0]                 = 0;
  User_infos->type[0]                  = 0;
  User_infos->description[0]           = 0;
  User_infos->pwdump_pwd_raw_format[0] = 0;
  User_infos->pwdump_pwd_format[0]     = 0;

  //get datas
  BOOL ret = FALSE;
  char tmp[MAX_PATH],tmp2[MAX_PATH],tmp3[MAX_PATH];
  unsigned long int size_total = strlen(buffer);
  if (size_total < 350)return FALSE;

  //possibilité aussi de chercher :
  //chercher dans la chaine la chaine suivante : 000001020000000520000000200200000102000000052000000020020000
  //+Nom(Wildstring) + 0000 + Description + 0100/0102/FFFF

//--name
  //emplacement du nom (taille de la strcuturitem[10].c[0]=0;e d'entête + emplacement)
  //0x0C
  tmp[0] = buffer[30];
  tmp[1] = buffer[31];
  tmp[2] = buffer[28];
  tmp[3] = buffer[29];
  tmp[4] = buffer[26];
  tmp[5] = buffer[27];
  tmp[6] = buffer[24];
  tmp[7] = buffer[25];
  unsigned int of_name = (204+ HTDF(tmp,8))*2;
  //lecture de la taille du nom sur 1 int  = 4octets
  //0x10 = taille nom user
  tmp[0] = buffer[38];
  tmp[1] = buffer[39];
  tmp[2] = buffer[36];
  tmp[3] = buffer[37];
  tmp[4] = buffer[34];
  tmp[5] = buffer[35];
  tmp[6] = buffer[32];
  tmp[7] = buffer[33];
  unsigned int taille_nom = HTDF(tmp,8)/2;

//-- nom complet
  //emplacement de la description (taille de la strcuture d'entête + emplacement)
  //0x18
  tmp[0] = buffer[54];
  tmp[1] = buffer[55];
  tmp[2] = buffer[52];
  tmp[3] = buffer[53];
  tmp[4] = buffer[50];
  tmp[5] = buffer[51];
  tmp[6] = buffer[48];
  tmp[7] = buffer[49];
  unsigned int of_full_name = (204+ HTDF(tmp,8))*2;
  //lecture de la taille du nom complet sur 1 int  = 4octets
  //0x1C = taille du nom complet
  tmp[0] = buffer[62];
  tmp[1] = buffer[63];
  tmp[2] = buffer[60];
  tmp[3] = buffer[61];
  tmp[4] = buffer[58];
  tmp[5] = buffer[59];
  tmp[6] = buffer[56];
  tmp[7] = buffer[57];
  unsigned int taille_full_name = HTDF(tmp,8)/2;

//--description
  //emplacement de la description (taille de la strcuture d'entête + emplacement)
  //0x24
  tmp[0] = buffer[78];
  tmp[1] = buffer[79];
  tmp[2] = buffer[76];
  tmp[3] = buffer[77];
  tmp[4] = buffer[74];
  tmp[5] = buffer[75];
  tmp[6] = buffer[72];
  tmp[7] = buffer[73];
  unsigned int of_description = (204+ HTDF(tmp,8))*2;
  //lecture de la taille de la description sur 1 int  = 4octets
  //0x28 = taille de description
  tmp[0] = buffer[86];
  tmp[1] = buffer[87];
  tmp[2] = buffer[84];
  tmp[3] = buffer[85];
  tmp[4] = buffer[82];
  tmp[5] = buffer[83];
  tmp[6] = buffer[80];
  tmp[7] = buffer[81];
  unsigned int taille_description = HTDF(tmp,8)/2;

//password hash
//-- LM PASSWORD
  //0x9C
  tmp[0] = buffer[318];
  tmp[1] = buffer[319];
  tmp[2] = buffer[316];
  tmp[3] = buffer[317];
  tmp[4] = buffer[314];
  tmp[5] = buffer[315];
  tmp[6] = buffer[312];
  tmp[7] = buffer[313];
  unsigned int of_lmpw = (204+ HTDF(tmp,8))*2;
  //0xA0
  tmp[0] = buffer[326];
  tmp[1] = buffer[327];
  tmp[2] = buffer[324];
  tmp[3] = buffer[325];
  tmp[4] = buffer[322];
  tmp[5] = buffer[323];
  tmp[6] = buffer[320];
  tmp[7] = buffer[321];
  unsigned int taille_lmpw = HTDF(tmp,8)*2;

//-- NT PASSWORD
  //0xA8
  tmp[0] = buffer[342];
  tmp[1] = buffer[343];
  tmp[2] = buffer[340];
  tmp[3] = buffer[341];
  tmp[4] = buffer[338];
  tmp[5] = buffer[339];
  tmp[6] = buffer[336];
  tmp[7] = buffer[337];
  unsigned int of_ntpw = (204+ HTDF(tmp,8))*2;
  //0xAC
  tmp[0] = buffer[350];
  tmp[1] = buffer[351];
  tmp[2] = buffer[348];
  tmp[3] = buffer[349];
  tmp[4] = buffer[346];
  tmp[5] = buffer[347];
  tmp[6] = buffer[344];
  tmp[7] = buffer[345];
  unsigned int taille_ntpw = HTDF(tmp,8)*2;

  //---results---
  //name
  if ((taille_nom>0) && (taille_nom<size_total) && (of_name>0) && (of_name<size_total))
  {
    tmp[0] = 0;
    tmp2[0] = 0;
    strncpy(tmp,(char*)(buffer+of_name),MAX_PATH);
    SHexaToString(tmp,tmp2,MAX_PATH);
    if (taille_nom<MAX_PATH)tmp2[taille_nom]=0;
    else tmp2[MAX_PATH-1]=0;

    if (computer[0] == 0)strncpy(User_infos->name,tmp2,MAX_PATH);
    else snprintf(User_infos->name,MAX_PATH,"%s\\%s",computer,tmp2);
    ret = TRUE;
  }
  //lecture de la description (fullname)
  if ((taille_full_name>0) && (taille_full_name<size_total) && (of_full_name>0) && (of_full_name<size_total))
  {
    tmp[0]  = 0;
    tmp2[0] = 0;
    strncpy(tmp,(char*)(buffer+of_full_name),MAX_PATH);
    SHexaToString(tmp,tmp2,MAX_PATH);
    if (taille_full_name<MAX_PATH)tmp2[taille_full_name]=0;
    else tmp2[MAX_PATH-1]=0;
    ret = TRUE;
  }else tmp2[0] = 0;

  //lecture de la description (comment)
  if ((taille_description>0) && (taille_description<size_total) && (of_description>0) && (of_description<size_total))
  {
    tmp[0]  = 0;
    tmp3[0] = 0;
    strncpy(tmp,(char*)(buffer+of_description),MAX_PATH);
    SHexaToString(tmp,tmp3,MAX_PATH);
    if (taille_description<MAX_PATH)tmp3[taille_description]=0;
    else tmp3[MAX_PATH-1]=0;

    if (tmp2[0] != 0)snprintf(User_infos->description,MAX_PATH,"(%s) %s",tmp2,tmp3);
    else snprintf(User_infos->description,MAX_PATH,"%s",tmp3);
    ret = TRUE;
  }else if ((taille_full_name>0) && (tmp2[0] != 0)) snprintf(User_infos->description,MAX_PATH,"(%s)",tmp2);

  //type
  if (((buffer[8]=='B') || (buffer[8]=='b')) && ((buffer[9]=='C') || (buffer[9]=='c')))snprintf(User_infos->type,MAX_PATH,"2 : %s",cps[TXT_MSG_ADMIN].c);
  else if (((buffer[8]=='B') || (buffer[8]=='b')) && (buffer[9]=='0'))snprintf(User_infos->type,MAX_PATH,"0 : %s",cps[TXT_MSG_GUEST].c);
  else if (((buffer[8]=='D') || (buffer[8]=='d')) && (buffer[9]=='4'))snprintf(User_infos->type,MAX_PATH,"1 : %s",cps[TXT_MSG_USER].c);
  else snprintf(User_infos->type,MAX_PATH,"0x%c%c : %s",buffer[8],buffer[9],cps[TXT_MSG_UNK].c);

  //SID+RID
  //SID : après 12 octets donc 24 caractères + dernière clée : 2o donc 4caractères : 2400 4400 0200 0105 0000 0000 0005 1500 0000
  //fin : 0000
  //SID = col3
  tmp3[0] = 0;
  unsigned long int type_id = 0, type_id2=0, last_id=0;
  unsigned long int i = Contient(buffer,"2400440002000105000000000005"); // 1500 0000 = 21 le SID de début
  if ((i>0) && (i<(strlen(buffer)-40)))
  {
    //création du SID : 4o-4o-4o-4o-4o
    sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+6],buffer[i+7],buffer[i+4],buffer[i+5],buffer[i+2],buffer[i+3],buffer[i],buffer[i+1]);
    type_id = HTD(tmp);
    snprintf(tmp2,MAX_PATH,"S-1-5-%lu",type_id);
    strcpy(tmp3,tmp2);

    sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+14],buffer[i+15],buffer[i+12],buffer[i+13],buffer[i+10],buffer[i+11],buffer[i+8],buffer[i+9]);
    type_id2 = HTD(tmp);
    snprintf(tmp2,MAX_PATH,"-%lu",type_id2);
    strncat(tmp3,tmp2,MAX_PATH);

    sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+22],buffer[i+23],buffer[i+20],buffer[i+21],buffer[i+18],buffer[i+19],buffer[i+16],buffer[i+17]);
    snprintf(tmp2,MAX_PATH,"-%lu",HTD(tmp));
    strncat(tmp3,tmp2,MAX_PATH);

    sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+30],buffer[i+31],buffer[i+28],buffer[i+29],buffer[i+26],buffer[i+27],buffer[i+24],buffer[i+25]);
    snprintf(tmp2,MAX_PATH,"-%lu",HTD(tmp));
    strncat(tmp3,tmp2,MAX_PATH);

    sprintf(tmp,"%c%c%c%c%c%c%c%c",buffer[i+38],buffer[i+39],buffer[i+36],buffer[i+37],buffer[i+34],buffer[i+35],buffer[i+32],buffer[i+33]);
    last_id = HTD(tmp);
    snprintf(tmp2,MAX_PATH,"-%lu",last_id);
    strncat(tmp3,tmp2,MAX_PATH);
    strncat(tmp3,"\0",MAX_PATH);

    strncpy(User_infos->SID,tmp3,MAX_PATH);
    snprintf(User_infos->RID,MAX_PATH,"%05lu",last_id);

    //descriptions infos +
    switch (type_id)
    {
      case 1: strncat(User_infos->description," Rights : Dialup\0",MAX_PATH);
      case 2: strncat(User_infos->description," Rights : Network\0",MAX_PATH);
      case 3: strncat(User_infos->description," Rights : Batch\0",MAX_PATH);
      case 4: strncat(User_infos->description," Rights : Interative\0",MAX_PATH);
      case 5: strncat(User_infos->description," Rights : Driver\0",MAX_PATH);
      case 6: strncat(User_infos->description," Rights : Service\0",MAX_PATH);
      case 7: strncat(User_infos->description," Rights : Anonymous logon\0",MAX_PATH);
      case 8: strncat(User_infos->description," Rights : Proxy\0",MAX_PATH);
      case 9: strncat(User_infos->description," Rights : Entreprise domain controllers\0",MAX_PATH);
      case 10: strncat(User_infos->description," Rights : Self\0",MAX_PATH);
      case 11: strncat(User_infos->description," Rights : Authenticated Users\0",MAX_PATH);
      case 12: strncat(User_infos->description," Rights : Restricted\0",MAX_PATH);
      case 13: strncat(User_infos->description," Rights : Terminal server user\0",MAX_PATH);
      case 14: strncat(User_infos->description," Rights : Remote interactive logon\0",MAX_PATH);
      case 15: strncat(User_infos->description," Rights : This Organization\0",MAX_PATH);
      case 18: strncat(User_infos->description," Rights : System\0",MAX_PATH);
      case 19: strncat(User_infos->description," Rights : Local service\0",MAX_PATH);
      case 20: strncat(User_infos->description," Rights : Network service\0",MAX_PATH);
      case 21:
        switch(last_id)
        {
          case 500 : strncat(User_infos->description," Rights : Local Administrator\0",MAX_PATH);break;
          case 501 : strncat(User_infos->description," Rights : Local Guest\0",MAX_PATH);break;
          case 502 : strncat(User_infos->description," Rights : Krbtgt\0",MAX_PATH);break;
          case 512 : strncat(User_infos->description," Rights : Domain Admins\0",MAX_PATH);break;
          case 513 : strncat(User_infos->description," Rights : Domain Users\0",MAX_PATH);break;
          case 514 : strncat(User_infos->description," Rights : Domain Guests\0",MAX_PATH);break;
          case 515 : strncat(User_infos->description," Rights : Domain Computers\0",MAX_PATH);break;
          case 516 : strncat(User_infos->description," Rights : Domain Controllers\0",MAX_PATH);break;
          case 517 : strncat(User_infos->description," Rights : Cert Publishers\0",MAX_PATH);break;
          case 518 : strncat(User_infos->description," Rights : Schema Admins\0",MAX_PATH);break;
          case 519 : strncat(User_infos->description," Rights : Enterprise Admins\0",MAX_PATH);break;
          case 520 : strncat(User_infos->description," Rights : Group Policy Creator Owners\0",MAX_PATH);break;
          case 553 : strncat(User_infos->description," Rights : RAS and IAS Servers\0",MAX_PATH);break;
        }
      break;
      case 32:
        switch(last_id)
        {
          case 544 : strncat(User_infos->description," Rights : Administrators\0",MAX_PATH);break;
          case 545 : strncat(User_infos->description," Rights : Users\0",MAX_PATH);break;
          case 546 : strncat(User_infos->description," Rights : Guests\0",MAX_PATH);break;
          case 547 : strncat(User_infos->description," Rights : Power Users\0",MAX_PATH);break;
          case 548 : strncat(User_infos->description," Rights : Account Operators\0",MAX_PATH);break;
          case 549 : strncat(User_infos->description," Rights : Server Operators\0",MAX_PATH);break;
          case 550 : strncat(User_infos->description," Rights : Print Operators\0",MAX_PATH);break;
          case 551 : strncat(User_infos->description," Rights : Backup Operators\0",MAX_PATH);break;
          case 552 : strncat(User_infos->description," Rights : Replicator \0",MAX_PATH);break;
          case 554 : strncat(User_infos->description," Rights : Pre-Windows 2000 Compatible Access\0",MAX_PATH);break;
          case 555 : strncat(User_infos->description," Rights : Remote Desktop Users\0",MAX_PATH);break;
          case 556 : strncat(User_infos->description," Rights : Network Configuration Operators\0",MAX_PATH);break;
          case 557 : strncat(User_infos->description," Rights : Incoming Forest Trust Builders\0",MAX_PATH);break;
          case 558 : strncat(User_infos->description," Rights : Performance Monitor Users\0",MAX_PATH);break;
          case 559 : strncat(User_infos->description," Rights : Performance Log Users\0",MAX_PATH);break;
          case 560 : strncat(User_infos->description," Rights : Windows Authorization Access Group\0",MAX_PATH);break;
          case 561 : strncat(User_infos->description," Rights : Terminal Server License Servers\0",MAX_PATH);break;
        }
      break;
      case 64:
        switch(last_id)
        {
          case 10 : strncat(User_infos->description," Rights : NTLM Authentication\0",MAX_PATH);break;
          case 14 : strncat(User_infos->description," Rights : SChannel Authentication\0",MAX_PATH);break;
          case 21 : strncat(User_infos->description," Rights : Digest Authentication\0",MAX_PATH);break;
        }
      break;
    }
    ret = TRUE;
  }
  //hash NT::LM
  if (ret)
  {
    tmp2[0]=0;
    tmp3[0]=0;
    //8 => 4 size of separator
    if ((taille_lmpw > 8) && (of_lmpw>0) && ((of_lmpw + 8+ taille_lmpw)<=size_total))
    {
      strncpy(tmp2,buffer+of_lmpw+8,MAX_PATH);
      tmp2[32]=0;
    }else strcpy(tmp2,"NO PASSWORD*********************");//LM

    if ((taille_ntpw > 8) && (of_ntpw>0) && ((of_ntpw + taille_ntpw)<=size_total))
    {
      strncpy(tmp3,buffer+(of_ntpw+8),MAX_PATH);
      tmp3[32]=0;
    }else strcpy(tmp3,"NO PASSWORD*********************");//NT

    if ((tmp2[0]!=0) && (tmp3[0]!=0))
    {
      //pwdump format
      //<user>:<id>:<lanman pw>:<NT pw>:comment:homedir:
      //snprintf(item[10].c,MAX_PATH,"%s:%lu:%s:%s:::",item[2].c,last_id,tmp2,tmp3);
      snprintf(User_infos->pwdump_pwd_raw_format,MAX_PATH,":%s:%s",tmp2,tmp3);
    }
  }
  return ret;
}
//0x28 = début du 1er SID structure + 52
//0x30 = nombre d'instances (user + paddings)
void TraiterGroupDataFromSAM_C(char *buffer, unsigned int rid, char *group, unsigned int group_size_max)
{
  char tmp[MAX_LINE_SIZE];
  unsigned long int size_total = strlen(buffer);

  char group_name[MAX_PATH]="";

  //lecture de la taille du nom sur 1 int  = 4octets
  //0x14 = taille nom de groupe
  tmp[0] = buffer[46];
  tmp[1] = buffer[47];
  tmp[2] = buffer[44];
  tmp[3] = buffer[45];
  tmp[4] = buffer[42];
  tmp[5] = buffer[43];
  tmp[6] = buffer[40];
  tmp[7] = buffer[41];
  unsigned int taille_nom = HTDF(tmp,8)/2;

  //lecture de la taille de la description sur 1 int  = 4octets
  //0x20 = taille de description
  /*tmp[0] = buffer[70];
  tmp[1] = buffer[71];
  tmp[2] = buffer[68];
  tmp[3] = buffer[69];
  tmp[4] = buffer[66];
  tmp[5] = buffer[67];
  tmp[6] = buffer[64];
  tmp[7] = buffer[65];
  unsigned int taille_description = HTDF(tmp,8)/2;*/

  //0x10 = emplacement nom de groupe en unicode (taille totale) + 52
  tmp[0] = buffer[38];
  tmp[1] = buffer[39];
  tmp[2] = buffer[36];
  tmp[3] = buffer[37];
  tmp[4] = buffer[34];
  tmp[5] = buffer[35];
  tmp[6] = buffer[32];
  tmp[7] = buffer[33];
  unsigned int of_name = (52+ HTDF(tmp,8))*2;

  //0x1C = emplacement description + 52
  /*tmp[0] = buffer[62];
  tmp[1] = buffer[63];
  tmp[2] = buffer[60];
  tmp[3] = buffer[61];
  tmp[4] = buffer[58];
  tmp[5] = buffer[59];
  tmp[6] = buffer[56];
  tmp[7] = buffer[57];
  unsigned int of_description = (52+ HTDF(tmp,8))*2;*/

  //0x28 = début du 1er SID structure + 52
  tmp[0] = buffer[86];
  tmp[1] = buffer[87];
  tmp[2] = buffer[84];
  tmp[3] = buffer[85];
  tmp[4] = buffer[82];
  tmp[5] = buffer[83];
  tmp[6] = buffer[80];
  tmp[7] = buffer[81];
  unsigned int of_sid = (52+ HTDF(tmp,8))*2;

  //0x30 = nombre d'instances (user)
  tmp[0] = buffer[102];
  tmp[1] = buffer[103];
  tmp[2] = buffer[100];
  tmp[3] = buffer[101];
  tmp[4] = buffer[98];
  tmp[5] = buffer[99];
  tmp[6] = buffer[96];
  tmp[7] = buffer[97];
  DWORD nb_sid = HTDF(tmp,8);

  //2 = name
  if ((taille_nom>0) && (taille_nom<size_total) && (of_name>0) && (of_name<size_total))
  {
    strncpy(tmp,(char*)(buffer+of_name),MAX_LINE_SIZE);
    SHexaToString(tmp,group_name,MAX_PATH);
    if (taille_nom<MAX_PATH)group_name[taille_nom]=0;
    else group_name[MAX_PATH-1]=0;
  }

  //4 = description
  /*if (taille_description>0 && taille_description<size_total && of_description>0 && of_description<size_total)
  {
    tmp[0]=0;
    strncpy(tmp,(char*)(item[12].c+of_description),MAX_LINE_SIZE);
    SHexaToString(tmp,item[4].c);
    item[4].c[taille_description]=0;
  }*/

  //3 = sid
  #define DATA_USER_HEADER_SIZE  8
  /*typedef struct data_user
  {
    char valid;       //0x01
    char nb_sid;      //0x05 ou 0x01
    char padding[5];  //0x0000 0000 00
    char type;        //0x05
    char sid[1];      //par defaut découpé en section de 2octet *nb_part
  }DATA_USER;
  */

  //cas de groupes vides
  if (of_sid+(DATA_USER_HEADER_SIZE+nb_sid*4)*2>size_total)return;

  DWORD i, nb_c_sid;
  char *d,*c = &buffer[of_sid];
  for (i=0;i<nb_sid;i++)
  {
    //lecture du nombre de sid
    nb_c_sid = HexaToDecS(c+2);
    if (nb_c_sid != 1)
    {
      d = c+(DATA_USER_HEADER_SIZE*2)+(nb_c_sid-1)*8; // 48 = 6*8
      tmp[0] = d[6];
      tmp[1] = d[7];
      tmp[2] = d[4];
      tmp[3] = d[5];
      tmp[4] = d[2];
      tmp[5] = d[3];
      tmp[6] = d[0];
      tmp[7] = d[1];

      if(HTDF(tmp,8) == rid)
      {
        if (group[0] != 0)strncat(group,", ",group_size_max);
        strncat(group,group_name,group_size_max);
        strncat(group,"\0",group_size_max);
        return;
      }
    }

    //next
    c = c+((DATA_USER_HEADER_SIZE+nb_c_sid*4)*2);
  }
}