Application à faible niveau C ++ Crashes sous Windows Vista / 7 À moins d'exécution en mode de compatibilité XP

StackOverflow https://stackoverflow.com/questions/2169092

Question

J'ai un faible niveau (comme vraiment de bas niveau, il est essentiellement tous les appels IOCTL et plusieurs appels à énumération API) qui se bloque de façon sporadique sur Windows Vista / 7 sur les ordinateurs des clients. Malheureusement, je ne l'ai pas été en mesure de se procurer des décharges d'accident, mais un utilisateur utile a mentionné que l'exécution du programme en mode de compatibilité XP a résolu le problème.

L'application est toujours lancé avec des droits d'administrateur complet (il est lancé à partir d'un autre programme qui nécessite l'autorisation admin) il est donc pas une question UAC. Je n'utilise pas API désapprouvées et je ne suis pas compter sur les hacks de registre, etc. Je suis juste émettre des appels d'énumérer les disques, puis en utilisant les commandes IOCTL pour obtenir un peu plus d'informations à faible niveau de tous les périphériques connectés.

Qu'est-ce qui se passe dans le mode de compatibilité XP? Que signifie Windows injectent dans mon application ou autre bac à sable avec qui l'empêche de se briser sur Vista / 7? J'avais initialement soupçonné de corruption tas (bien que j'ai tiré mes cheveux essayant de reproduire ou de traquer la question) avant d'être dit qu'il fonctionne bien en mode de compatibilité XP.

Quelqu'un peut-il suggérer d'éventuels problèmes qui seraient évitées en mode XP Compat que je devrais regarder dans pour tenter de résoudre ce problème? Merci!

EDIT:

Une autre chose qui est probablement très important de mentionner:. J'appelle les fonctions DDK / noyau de l'espace utilisateur afin d'obtenir à certaines fonctionnalités non exposées via l'API WIN32

J'utilise ZwReadFile, ZwCreateFile, ZwWriteFile, RtlInitUnicodeString, ZwQueryVolumeInformationFile, ZwDeviceIoControlFile, ZwSetInformationFile, ZwClose.

Les IOCTL J'appelle comprennent IOCTL_DISK_GET_PARTITION_INFO_EX, IOCTL_STORAGE_GET_DEVICE_NUMBER, IOCTL_DISK_GET_LENGTH_INFO et IOCTL_DISK_GET_DRIVE_LAYOUT_EX.

Était-ce utile?

La solution

Ceci est très étrange, mais j'appelle ZwQueryVolumeInformationFile avec FsInformationClass réglé sur FileFsVolumeInformation.

I était passé dans un tampon de premier FILE_FS_VOLUME_INFORMATION normalement attribué, puis surutilisées à (sizeof(FILE_FS_VOLUME_INFORMATION) + sizeof(TCHAR)*FILE_FS_VOLUME_INFORMATION->VolumeLabelLength).

Alors j'ai appelé FILE_FS_VOLUME_INFORMATION->VolumeLabel[FILE_FS_VOLUME_INFORMATION->VolumeLabelLength/2] = _T('\0'); et uniquement sur certaines machines ce provoquera la corruption de la mémoire.

Quelle que soit la taille de la surutilisation (même essayé allouer un plein 256 caractères supplémentaires!), Cela entraînerait sûrement la corruption du tas même lorsque vous utilisez un vector<unsigned char> comme tampon FILE_FS_VOLUME_INFORMATION.

Il semble que le noyau met une sorte de protection en écriture sur la mémoire tampon en quelque sorte que se soldait dans la corruption quelle que soit la taille. Copie des premiers octets VolumeLableLength à un second tampon, alors _T('\0') poste en attente résolu le problème. Je ne sais pas comment / pourquoi Windows a fait le tampon que I alloués et transmis en tant que paramètre readonly ou si elle stockait après la struct FILE_FS_VOLUME_INFORMATION (qui devrait fin avec le tableau de caractères!), mais simplement de ne pas modifier les données dans le tampon que je suis passé a fait l'affaire .... ce qui est fou, car il arrive que (de manière cohérente et reproductible à 100% ) sur certaines machines.

En tout cas: problème résolu * * ouf

Autres conseils

Il y a eu de nombreux changements dans de XP à vista du pilote de bas niveau. Je suppose que vous utilisez un IOCTL qui est affecté.

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