IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Récupérer le contenu d'une donnée de type REG_BINARY


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Par défaut Récupérer le contenu d'une donnée de type REG_BINARY
    Bonsoir,

    Je ne sais pas si le forum débutant est le plus approprié pour ce type de question, mais comme je débute toujours, je préfère rester ici pour le moment.

    J'arrive à récupérer des données de type REG_SZ, REG_EXPAND_SZ et REG_DWORD, mais je bloque concernant les données de type REG_BINARY.

    J'aimerais faire afficher dans l'écran de la console le résultat et je ne sais pas quel switch de printf utiliser ( %s ? %u ? %f ? etc ).

    De plus je présume que pour afficher la valeur en binaire, il faudra faire des conversions je présume non ?

    Ce qui m'intéresse, c'est récupérer la valeur exacte contenue dans le registre.

    J'aurais besoin de quelques pistes, merci par avance.

    edit: Si je récupère l'entier que représente en écriture décimal le nombre binaire, donc avec le %u de printf() et qu'après j'appelle une fonction pour convertir l'entier en binaire, ça le ferait ?

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    REG_BINARY ne signifie pas "un truc en binaire", mais "des données brutes".

    Donc, je conseillerais le format le plus communément employé pour ça: Un dump hexadécimal+ASCII (possiblement étendu) sur 16 colonnes.

    Si tu double-cliques sur une REG_BINARY dans Regedit lui-même, tu verras qu'il fait un dump hexadécimal+ASCII étendu sur huit colonnes...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Par défaut
    Salut Médinoc,

    Merci pour ta réponse. Entre temps j'ai réussi à récupérer des données de type REG_MULTI_SZ.

    Si tu double-cliques sur une REG_BINARY dans Regedit lui-même, tu verras qu'il fait un dump hexadécimal+ASCII étendu sur huit colonnes...
    Oui je l'avais remarqué et je me demandais comment récupérer les données sous cette forme.

    Un dump hexadécimal+ASCII (possiblement étendu) sur 16 colonnes.
    Je ne sais pas ce qu'est un dump, et je ne vois pas comment faire pour trier les données sur 16 colonnes.

    Le buffer reçoit les données brutes, ça je suis d'accord, j'ai compris. Par exemple, pour du REG_MULTI_SZ, suffit de remplacer chaque caractère null, par un espace ou autre chose, puis ensuite de lire le buffer avec un printf("%s", buffer).

    Pour les REG_DWORD, j'ai aussi trouvé comment procéder, ce n'est pas trop dur.

    Pourrais-tu me donner un exemple de code ce que tu appelles Un dump hexadécimal+ASCII (possiblement étendu) sur 16 colonnes ?

    Et puis comme ça une fois que j'aurai compris, je pourrai récupérer le REG_EXPAND_SZ et le REG_MULTI_SZ en hex(2) et hex(7) respectivement, car je présume que c'est la même technique qui est employée que pour les REG_BINARY.

    Merci.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    J'avais bien ce code source, mais c'est un mélange de dump et de programmation système pour Windows (j'ai fait ça à une époque où je m'amusais à ne pas utiliser les fonctions C, mais seulement les fonctions système, une parodie de ce que font EPITA/EPITECH).
    Tu peux voir le commentaire "TODO" qui me conseillait de faire le nettoyage, mais je n'ai jamais eu le temps de le faire.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    #include "stdafx.h"//TODO: Faire une version "avec CRT" en bibliothèque.
    #include "TestSansCRT.h"
    #include "StringBufferC.h"
    #include "Inline.h"
     
    /* Helper macros
       ------------- */
    #define ADDRESS_LENGTH           (HEX_CHARBUF_SIZE(INT_PTR)-1)
    /* Write a char array, minus the terminating null character. */
    #define WRITEBUF(bufName)        WriteFile(hOut, bufName, sizeof bufName - sizeof *bufName, &nWritten, NULL)
    #define WRITECHAR_P(charName)    WriteFile(hOut, &(charName), 1, &nWritten, NULL)
    #define WRITECHAR_S(charStr)     WriteFile(hOut, charStr,   1, &nWritten, NULL)
     
    struct dumpParams
    {
    	unsigned int nBytesPerLine;
    	unsigned int nSpaces1;
    	unsigned int nSpaces2;
     
    	unsigned char const * pcByMem;
    	unsigned char const * pcStart;
    	unsigned char const * pcEnd; //pcEnd is the address IMMEDIATELY AFTER the last valid one.
    };
     
    /* Helper function for number of bytes to display
       ---------------------------------------------- */
    static unsigned int LowerPowerOfTwo(unsigned int in)
    {
    	//Search the first 'set' bit, from msb to lsb.
    	unsigned int bit = 0x80000000u;
    	if(in==0)
    		return 0;
     
    	while((in & bit)==0)
    	{
    		//Bit is too high: shift it and retry.
    		bit >>= 1;
    	}
    	return bit;
    }
     
    /* Helper function for calculating the dump parameters
       --------------------------------------------------- */
    static BOOL ProcessParams(
     struct dumpParams *pParams,    /*[out] */ 
     unsigned int nCols,            /*[in] */
     unsigned char const * pcByMem, /*[in] pcMem, implicitely cast as a char pointer. */
     size_t cbMem,                  /*[in] */
     BOOL bAlign                    /*[in] */
     )
    {
     
    	MY_ASSERT(pParams != NULL);
     
    	//Calculate number of bytes per line
    	{
    		int nSpaces = 0;
    		unsigned int nBytesPerLine = 0;
    		unsigned int const nColsBytes = nCols-1-ADDRESS_LENGTH-1; /*End-of-line, address-in-hex, space.*/
     
    		if(nCols <= 1+ADDRESS_LENGTH+1 || nColsBytes < 4)
    			return FALSE;
     
    		nBytesPerLine = LowerPowerOfTwo(nColsBytes/4);
    		MY_ASSERT(nBytesPerLine > 0); //shall be OK, since tested before.
     
    		//Additional spaces
    		nSpaces = (nColsBytes-(nBytesPerLine*4));
    		MY_ASSERT(nSpaces >= 0);
    		pParams->nSpaces2 = nSpaces/2;
    		pParams->nSpaces1 = nSpaces - pParams->nSpaces2;
    		pParams->nBytesPerLine = nBytesPerLine;
    	}
    	MY_ASSERT(pParams->nBytesPerLine > 0);
     
    	//Start&End pointers, with alignment.
    	{
    		unsigned int const nBytesPerLine = pParams->nBytesPerLine;
     
    		unsigned char const * pcStart = pcByMem;
    		unsigned char const * pcEnd = pcByMem+cbMem; //pcEnd is the address IMMEDIATELY AFTER the last valid one.
     
    		if(bAlign)
    		{
    			pcStart -= (INT_PTR)pcStart%nBytesPerLine;
    			MY_ASSERT((INT_PTR)pcStart%nBytesPerLine == 0);
    		}
     
    		//Always align pcEnd with pcStart
    		{
    			size_t unalEnd = (pcEnd-pcStart)%nBytesPerLine;
    			if(unalEnd!=0)
    			{
    				pcEnd += (nBytesPerLine-unalEnd);
    			}
    			MY_ASSERT((pcStart-pcEnd)%nBytesPerLine == 0);
    		}
     
    		//Set pointers in the parameter structure.
    		pParams->pcByMem = pcByMem;
    		pParams->pcStart = pcStart;
    		pParams->pcEnd = pcEnd;
    	}
    	return TRUE;
    }
     
    /* Helper function for writing a string of identical chars
       ------------------------------------------------------- */
    static CCPP_INLINE void WriteChars(HANDLE hOut, char c, unsigned int n)
    {
    	DWORD nWritten;
    	unsigned int i;
    	for(i=0 ; i<n ; i++)
    		WRITECHAR_P(c);
    }
     
    //-----------------------------------------------------------------------------
     
    /* Memory dump function
       -------------------- */
    EXTERN_C void DumpMemory(
     HANDLE hOut,        /*[in/modif] Output handle. */
     unsigned int nCols, /*[in] Number of columns of display. Must be at least 14 on 32-bit machines. */
     void const * pcMem, /*[in] Memory block to dump. */
     size_t cbMem,       /*[in] Size to dump, in bytes. */
     BOOL bAlign         /*[in] If true, lines start at addresses multiple of their size.*/
     )
    {
    	//static const struct dumpParams zeroDumpParams = {0};
    	struct dumpParams params;// = zeroDumpParams;
     
    	//Analyze the parameters to set variables such as the real start and end of the dump, 
    	//the number of bytes in one line, etc.
    	if(!ProcessParams(&params, nCols, pcMem, cbMem, bAlign))
    	{
    		char msg[] = "Error\n";
    		DWORD nWritten;
    		WRITEBUF(msg);
    		return;
    	}
     
    	//Dump the memory according to the processed parameters.
    	{
    		unsigned char const * pcCurrent = NULL;
    		size_t iByteLine = 0;
    		BUF_DECL(caracs, char, 40);
    		BOOL bBufIsValid = FALSE;
     
    		//The NUL terminator is not necessary here for WriteFile(), but it may be for other functions.
    		BUF_START(caracs, params.nBytesPerLine+1);
    		bBufIsValid = (BUF_GETCOUNT(caracs) >= params.nBytesPerLine+1);
    		if(bBufIsValid)
    			BUF_GET(caracs)[params.nBytesPerLine] = '\0';
     
    		for(pcCurrent = params.pcStart ; pcCurrent<params.pcEnd ; pcCurrent++)
    		{
    			DWORD nWritten;
     
    			//If at start of line, display address
    			if(iByteLine==0)
    			{
    				char bufAddr[HEX_CHARBUF_SIZE(INT_PTR)];
    				FormatHexadecimalFullA((ULONG_PTR)pcCurrent, bufAddr, ARRAYSIZE(bufAddr));
    				WRITEBUF(bufAddr);
     
    				//Write spaces
    				WriteChars(hOut, ' ', params.nSpaces1+1);
    			}
     
    			//If before the start or after the end, display spaces instead of the data.
    			//If in the right zone, display the byte data (The pointer is dereferenced only here).
    			if(pcCurrent < params.pcByMem || pcCurrent >= params.pcByMem+cbMem)
    			{
    				//Write two spaces instead of the byte.
    				WriteChars(hOut, ' ', 2);
    				//Add a space to the buffer instead of the character.
    				if(bBufIsValid)
    					BUF_GET(caracs)[iByteLine] = ' ';
    			}
    			else
    			{
    				//Write the byte
    				unsigned char const by = *pcCurrent;
    				char bufByte[HEX_CHARBUF_SIZE(unsigned char)];
    				FormatHexadecimalFullA(by, bufByte, ARRAYSIZE(bufByte));
    				WRITEBUF(bufByte);
    				//Add the character to the buffer
    				if(bBufIsValid)
    					BUF_GET(caracs)[iByteLine] = (by < 32 ? '.' : by);
    			}
     
    			//Increment iByteLine now, allowing correct position of the "minus" char.
    			iByteLine++;			
     
    			//Write the space between bytes.
    			{
    				if(iByteLine==params.nBytesPerLine/2 && iByteLine!=0)
    					WRITECHAR_S("-");
    				else
    					WRITECHAR_S(" ");
    			}
     
    			//If at end of line, display the character representation of the bytes.
    			if(iByteLine ==params.nBytesPerLine)
    			{
    				//Write spaces (no +1 here, because written above)
    				WriteChars(hOut, ' ', params.nSpaces2);
    				//Write the caracs
    				if(bBufIsValid)
    					WriteFile(hOut, BUF_GET(caracs), params.nBytesPerLine, &nWritten, NULL);
    				else
    					WriteChars(hOut, '-', params.nBytesPerLine);
     
    				//Next line.
    				iByteLine = 0;
    				WRITECHAR_S("\n");
    			}
    		}//for
     
    		//Debug: The NUL terminator must not have been overwritten
    		if(bBufIsValid)
    			MY_ASSERT( BUF_GET(caracs)[params.nBytesPerLine] == '\0' );
    		BUF_END(caracs);
    	}//local variables
    }
     
     
    /* Test helper macro */
    #define TESTDUMP(bufName, align) DumpMemory(hOut, 80, bufName, ARRAYSIZE(bufName), align)
     
    /* Test function 1
       --------------- */
    void TestDump1(void)
    {
    	char buf1[] = {0x11, 0x22, 0x33, 0x44, 0x55};
    	char buf2[] = {0x66, 0x77, 0x88, 0x99, 0xAA};
    	char buf3[] = {0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    	char msg1[] = "Aligned:\n";
    	char msg2[] = "Unaligned:\n";
    	char msg3[] = "----\n";
    	char msg4[] = "\n";
    	DWORD nWritten;
    	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
     
    	WRITEBUF(msg1);
    	TESTDUMP(buf1, TRUE);
    	WRITEBUF(msg3);
    	TESTDUMP(buf2, TRUE);
    	WRITEBUF(msg3);
    	TESTDUMP(buf3, TRUE);
     
    	WRITEBUF(msg4);
     
    	WRITEBUF(msg2);
    	TESTDUMP(buf1, FALSE);
    	WRITEBUF(msg3);
    	TESTDUMP(buf2, FALSE);
    	WRITEBUF(msg3);
    	TESTDUMP(buf3, FALSE);
    }
     
    /* Test helper macro */
    #define TESTDUMP2(bufName, size, align) DumpMemory(hOut, 80, bufName, size, align)
     
    /* Test function 2
       --------------- */
    void TestDump2(void)
    {
    	char buf4[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
    	char *ptr1 = buf4;
    	char *ptr2 = buf4+5;
    	char *ptr3 = buf4+10;
    	char buf5[] = "Ah que Coucou, C'est moi Frédéric! Je suis content, c'est moi qui ai programmé ça, nanana!";
    	char msg1[] = "Aligned:\n";
    	char msg2[] = "Unaligned:\n";
    	char msg3[] = "----\n";
    	char msg4[] = "\n";
    	DWORD nWritten;
    	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
     
    	WRITEBUF(msg1);
    	TESTDUMP2(ptr1, 5, TRUE);
    	WRITEBUF(msg3);
    	TESTDUMP2(ptr2, 5, TRUE);
    	WRITEBUF(msg3);
    	TESTDUMP2(ptr3, 5, TRUE);
     
    	WRITEBUF(msg4);
     
    	WRITEBUF(msg2);
    	TESTDUMP2(ptr1, 5, FALSE);
    	WRITEBUF(msg3);
    	TESTDUMP2(ptr2, 5, FALSE);
    	WRITEBUF(msg3);
    	TESTDUMP2(ptr3, 5, FALSE);
     
    	WRITEBUF(msg4);
    	WRITEBUF(msg1);
    	TESTDUMP2(buf5+7, ARRAYSIZE(buf5)-7, TRUE);
    	WRITEBUF(msg2);
    	TESTDUMP2(buf5+7, ARRAYSIZE(buf5)-7, FALSE);
    }
    Il manque des trucs, notamment des macros comme CCPP_INLINE (que tu peux définir à rien du tout) et celle-ci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    #define HEX_CHARBUF_SIZE(type) (sizeof(type)*2+1)
    Aussi, ce code utilise apparemment aussi des fonctions et macros pour déclarer un buffer de caractères sur la pile ou le tas:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    /*
    StringBufferC.h : Functions and macros for allocating a fixed-size buffer on the stack or a buffer on the heap.
    	May be used for any type of element, buf mostly useful for strings.
    */
    #pragma once
     
    #ifdef __cplusplus
    	#include <cstddef>
    #else
    	#include <stddef.h> /*For size_t*/
    #endif
     
    /* === String buffer functions. Not to be used directly === */
    #ifdef __cplusplus
    extern "C" {
    #endif
     
    /* NOTE: This function shall never return NULL. */
    void * BufInit(
     size_t * pCbAlloc,      /*[out] */
     size_t cbStaticBuf,     /*[in] */
     size_t cbElem,          /*[in] */
     size_t nRequestedElems, /*[in] */
     void * pStaticBuf       /*[in/nodef] */
     );
    /* NOTE: This function always returns NULL. */
    void * BufClear(
     void * pBuf,       /*[in/freed] */
     void * pStaticBuf, /*[in/noDeref] */
     size_t * pCbAlloc  /*[out] */
     );
     
    #ifdef __cplusplus
    }
    #endif
     
    /* === String buffer macros === */
    /* Variable name. */
    #if 1
    	/* No name translation. Allows use with pointers, aliases etc. */
    	#define BUF_VARNAME(name) name
    #else
    	/* The name is modified. This forbids use with pointers, aliases etc. */
    	#define BUF_VARNAME(name) name##Buffer
    #endif
    /* Structure type name */
    #define BUF_STRUCTNAME(name) str_##name##_buffer
    /* Pointer type: 
    	In C, the pointer has the element type.
    	In C++, pointer must be a void* and BUF_GET must be set the type.
    	This is all because a void* is not implicitely convertible into type* in C++ */
    #ifdef __cplusplus
    	#define BUF_POINTERTYPE(type) void
    #else
    	#define BUF_POINTERTYPE(type) type
    #endif
     
    /* Macros for declaration, access and function calls. */
     
    /* Declare a buffer with COUNT elements of type TYPE. */
    #define BUF_DECL(name, type, count) struct BUF_STRUCTNAME(name) { size_t cbAlloc;  BUF_POINTERTYPE(type) *p; type buf[count]; } \
                                         BUF_VARNAME(name)/* = {0, NULL, {0}}*/
     
    /* Request a buffer of COUNT elements. If greated than the static buffer, alloc from the heap. */
    #define BUF_START(name, count)      (BUF_VARNAME(name).p = BufInit( \
                                                                &(BUF_VARNAME(name).cbAlloc), \
                                                                sizeof(BUF_VARNAME(name).buf), \
                                                                sizeof(BUF_VARNAME(name).buf[0]), \
                                                                count, \
                                                                BUF_VARNAME(name).buf \
                                                                ))
    /* Free the buffer if needed. */
    #define BUF_END(name)               (BUF_VARNAME(name).p = BufClear( BUF_VARNAME(name).p, BUF_VARNAME(name).buf, &(BUF_VARNAME(name).cbAlloc) ))
     
    /* Get the buffer pointer. */
    #ifdef __cplusplus
    #define BUF_GETCPP(name, type)      static_cast< type * >(BUF_VARNAME(name).p)
    #else
    #define BUF_GET(name)               (BUF_VARNAME(name).p)
    #endif
    /* Get the allocated count of elements. 
    	Always equal or greater than the static buffer size.
    	May be less than the requested size if the heap allocation failed. */
    #define BUF_GETCOUNT(name)          (BUF_VARNAME(name).cbAlloc / sizeof(BUF_VARNAME(name).buf[0]))
    /* Get the allocated size, in bytes.
    	Always equal or greater than the static buffer size.
    	May be less than the requested size if the heap allocation failed. */
    #define BUF_GETSIZE(name)           (BUF_VARNAME(name).cbAlloc)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    #include "stdafx.h" //TODO: Faire une version indépendante de stdafx et TestSansCRT.
    #include "StringBufferC.h"
    #include "TestSansCRT.h"
     
    #ifndef MY_ASSERT
    #include <assert.h>
    #define MY_ASSERT(x) assert(x)
    #endif
    #define MY_MEMSET MemSet
     
    /* String buffer functions. Not to be used directly. */
    /* NOTE: This function shall never return NULL. */
    void * BufInit(
     size_t * pCbAlloc,      /*[out] */
     size_t cbStaticBuf,     /*[in] */
     size_t cbElem,          /*[in] */
     size_t nRequestedElems, /*[in] */
     void * pStaticBuf       /*[in/nodef] */
     )
    {
    	void *pBuf = NULL;
    	void *pAllocBuf = NULL;
    	size_t const cbRequested = nRequestedElems*cbElem;
    	MY_ASSERT(pCbAlloc != NULL);
    	MY_ASSERT(pStaticBuf != NULL);
    	MY_ASSERT(cbElem != 0);
    	//Ensure no overflow occurred
    	MY_ASSERT(cbRequested/cbElem == nRequestedElems);
    	MY_ASSERT(cbRequested/nRequestedElems == cbElem);
     
    	//If need more than the static buf has, try to alloc.
    	if(cbRequested > cbStaticBuf)
    	{
    		pAllocBuf = HeapAlloc(GetProcessHeap(), 0, cbRequested);
    	}
     
    	if(pAllocBuf != NULL)
    	{
    		//Alloc was tried and succeeded : set pBuf to the allocated buffer.
    		pBuf = pAllocBuf;
    		*pCbAlloc = cbRequested;
    	}
    	else
    	{
    		//Alloc was not necessary, or was tried and failed : set pBuf to the static buffer.
    		pBuf = pStaticBuf;
    		*pCbAlloc = cbStaticBuf;
    	}
    	MY_ASSERT(pBuf != NULL);
    	return pBuf;
    }
     
    /* NOTE: This function always returns NULL. */
    void * BufClear(
     void * pBuf,       /*[in/freed] */
     void * pStaticBuf, /*[in/noDeref] */
     size_t * pCbAlloc  /*[out] */
     )
    {
    	MY_ASSERT(pBuf != NULL); //Can't be NULL, since pStaticBuf can't be
    	MY_ASSERT(pStaticBuf != NULL);
    	MY_ASSERT(pCbAlloc != NULL);
     
    	if(pBuf != pStaticBuf)
    	{
    		//pBuf was allocated : Free it.
    		HeapFree(GetProcessHeap(), 0, pBuf);
    	}
    	*pCbAlloc = 0;
    	return NULL;
    }
     
    #define BUFFER_SIZE 80
     
    void TestStringBuffer(void)
    {
    	BUF_DECL(test, char, BUFFER_SIZE);
    	BUF_START(test, 42);
     
    	{
    		char * buf = BUF_GET(test);
    		size_t bufLength = BUF_GETCOUNT(test);
    		(void)buf;
    		(void)bufLength;
    		MY_ASSERT(buf != NULL);
    		MY_ASSERT(bufLength >= BUFFER_SIZE);
    	}
    	BUF_END(test);
    	MY_ASSERT(BUF_GET(test)==NULL);
    	MY_ASSERT(BUF_GETCOUNT(test)==0);
    }
    #undef BUFFER_SIZE
    En gros, il y a un énorme travail de nettoyage à faire, mais l'algo de dump est là. C'est une fonction qui s'adapte au nombre de colonnes de caractères que tu lui passes en paramètre (la taille standard est 80, ce qui correspond à un dump sur 16 colonnes).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Par défaut
    Merci

    Mais je crois qu'il me faudrait un exemple beaucoup plus simple pour comprendre, mais peut-être que ça ne se fait pas en quelques lignes de code.

    Ton morceau de code est un peu trop compliqué par rapport à mon niveau actuel.

    Je vais détailler un peu ce que je suis en train de faire comme programme, peut-être pourras-tu mieux m'aiguiller éventuellement.

    Mon objectif est de coder mon propre REG QUERY ( coder moi-même un équivalent de la partie QUERY de REG.exe ). J'ai déjà bien avancé sur plusieurs points :

    1) Switch /s réalisé ( j'ai créé un algorithme récursif pour y parvenir ).
    2) Je lis sans problème des données de type REG_DWORD, REG_SZ, REG_MULTI_SZ et REG_EXPAND_SZ, au format chaîne de caractères pour les deux derniers.
    Les ruches possibles sont :
    HKLM
    HKCU
    HKCR
    HKU
    3) Prise en compte de la valeur par défaut.
    4) Mise en forme soignée et travaillée.
    5) Récupérer les paramètres passer en invite de commande ( nom de l'exécutable, chemin d'accès de la clé, switchs... ).

    Mon but est de faire quelque d'aussi proche et efficace possible, et puis de le personnaliser ensuite selon mes propres besoins.

    Pour information, j'ai des délais de temps d'exécution largement inférieurs à ceux de REG.EXE, mais je reste prudent car comme je n'ai pas fini de coder, forcément, mon programme a moins de choses à faire que l'original. Mais cela m'indique toutefois que mon algorithme récursif pour lire toutes les sous-clés et leurs valeurs n'est pas trop mauvais. C'est rassurant quoi.

    Et mon gros souci actuellement, c'est comme faire pour afficher les données de type REG_BINARY...

    Peut-être vois-tu mieux ce que je fais. Si éventuellement tu veux un morceau de code de la partie que j'ai essayée de faire concernant les données de type REG_BINARY, tu me demandes.

    Je te remercie déjà de m'avoir répondu

    N.B : Si j'apprends le C, c'est pour faire de la programmation système sous Windows, c'est vraiment ce qui m'intéresse. J'ai pensé que commencer par les API registre serait plus facile que celles concernant les threads, processus, services, graphiques (mode fenêtre), sans parler des drivers... Je compte y aller doucement, en me fixant des objectifs à atteindre à chaque fois.

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Attention: Le dump est un format lisible pour les humains, mais pour une machine, il vaudrait mieux, à défaut des données brutes, de l'hexadécimal pur sans espace (voire, s'il est question d'un important volume de données et que la mémoire est importante, du base64).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [DOM] Récupérer le contenu d'une balise donnée
    Par mimi31110 dans le forum Format d'échange (XML, JSON...)
    Réponses: 4
    Dernier message: 26/06/2006, 23h46
  2. Récupérer le contenu d'une page PHP
    Par Pragmateek dans le forum Réseau
    Réponses: 37
    Dernier message: 28/05/2006, 22h00
  3. [MySQL] Tester une égalité avec une donnée de type PASSWORD
    Par tiyolx dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 12/03/2006, 16h06
  4. Récupérer les infos d'une colonne de type DataSet
    Par Zugg dans le forum Bases de données
    Réponses: 2
    Dernier message: 01/02/2006, 14h46
  5. [Servlet]Récupérer le contenu d'une page web
    Par Jarodnet dans le forum Servlets/JSP
    Réponses: 6
    Dernier message: 06/10/2005, 15h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo