Question

Je tente d'exécuter certains pilotes codés pour Windows Vista (x86) sur win7 64 bits 32 bits (AMD64) et il n'a pas été en cours d'exécution. Après beaucoup de débogage, et délit de procès, je l'ai fait travailler sur ce dernier, mais je ne sais pas la raison pour laquelle il travaille. Voilà ce que je l'ai fait:

Dans de nombreux endroits, des pointeurs tampon souligné un tableau de structures (différentes à différents endroits), et de les incrémenter, à certains endroits ce type de déclaration a été utilisé:

ptr = (PVOID)((PCHAR)ptr + offset);

Et à certains endroits:

ptr = (PVOID)((ULONG)ptr + offset);

Le 2ème retournait les ordures, alors je les ai changé tout au 1er un. Mais j'ai trouvé beaucoup de pilotes d'échantillons sur le net suivant la deuxième. Mes questions:

  1. Où sont ces macros défini (Google n'a pas beaucoup d'aide)?
  2. Je comprends toutes les macros sont P_ pointeurs, pourquoi un pointeur casted à ULONG? Comment cela fonctionne sur 32 bits?
  3. PCHAR change évidemment la largeur en fonction de l'environnement. Connaissez-vous un endroit pour trouver de la documentation pour cela?
Était-ce utile?

La solution

  1. ils doivent être définis dans WinNT.h (ils sont dans le SDK, ne pas le DDK à la main)
  2. ULONG est unsigned long; sur un système 32 bits, ceci est la taille d'un pointeur. Ainsi, un pointeur peut être converti en arrière pour ULONG sans perte - mais pas sur un système 64 bits (Où la valeur sera coulée tronquer). Les gens exprimés à ULONG pour obtenir pointeur base d'octets arithmétique (même si cela a un comportement non défini, comme vous avez découvert)
  3. arithmétique pointeur fonctionne toujours dans les unités du type sous-jacent, à savoir CHARS pour PCHAR; ce qui correspond à l'arithmétique octets
  4. Tout livre C devrait préciser la sémantique précise de l'arithmétique de pointeur.

Autres conseils

La raison pour laquelle ce code échoue sur 64 bits est qu'il jette des pointeurs vers ULONG. ULONG est une valeur de 32 bits tandis que les pointeurs sur les 64 bits sont des valeurs 64 bits. Donc, vous serez tronquer le pointeur à chaque fois que vous utilisez la distribution ULONG.

La distribution de PCHAR, en supposant que PCHAR est défini comme char * est très bien, à condition que l'intention est d'incrémenter le pointeur par un nombre explicite d'octets.

Les deux macros ont la même intention, mais seulement l'un d'entre eux est valable où les pointeurs sont plus de 32 bits.

Pointer travaux arithmétiques comme celui-ci. Si vous avez:

T *p;

et que vous faites:

p + n;

(où n est un nombre), la valeur de p change de n * sizeof(T).

Pour donner un exemple concret, si vous avez un pointeur vers un DWORD:

DWORD *pdw = &some_dword_in_memory;

et vous ajoutez un à lui:

pdw = pdw + 1;

vous pointera à la prochaine DWORD. Les points de PDW adresse à aura augmenté de sizeof(DWORD), à savoir 4 octets.

Les macros que vous évoquez utilisent des moulages pour provoquer l'adresse des compensations qu'ils demandent à être multiplié par différentes quantités. Ceci est normalement fait dans le code de bas niveau qui a été adopté une BYTE (ou char ou vide) tampon mais connaît les données à l'intérieur, il est vraiment un autre type.

ULONG est défini dans Windef.h dans Windows SDK et est toujours 32 bits, alors quand vous lancez un pointeur 64 bits dans ULONG vous tronquer le pointeur sur 32 bits.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top