Basso livello di C ++ app si blocca in Windows Vista / 7 A meno che l'esecuzione in modalità di compatibilità XP

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

Domanda

Ho un basso livello (come davvero di basso livello, è fondamentalmente tutte le chiamate IOCTL e diverse chiamate alla API di enumerazione) che si blocca sporadicamente su Windows Vista / 7 sui computer client. Purtroppo, non sono stato in grado di procurarsi eventuali crash dump ma utile utente ha menzionato che l'esecuzione del programma in modalità compatibilità XP risolto il problema.

L'applicazione è sempre lanciata con pieni diritti di amministratore (è lanciato da un altro programma che richiede l'autorizzazione admin), quindi non è un problema di UAC. Io non uso alcun API deprecate e non sto contando su eventuali hack del Registro di sistema, ecc sto solo l'emissione di chiamate verso i dischi numerati quindi utilizzando i comandi IOCTL per ottenere un po 'di basso livello informazioni tutti i dispositivi collegati.

Che cosa succede in modalità XP di compatibilità? Che cosa significa iniettare di Windows nella mia applicazione o no sandbox con che gli impedisce di schiantarsi su Vista / 7? Avevo inizialmente sospettato di corruzione heap (anche se ho tirato fuori i miei capelli di tentare di replicare o per rintracciare il problema), prima di essere detto che funziona benissimo in modalità di compatibilità XP.

Qualcuno può suggerire eventuali problemi che potrebbero essere evitati in modalità XP Compat che dovrei esaminare per cercare di risolvere questo problema? Grazie!

EDIT:

Una cosa che probabilmente è molto importante ricordare:. Sto chiamando funzioni DDK / Kernel dallo userspace al fine di ottenere in alcune funzioni non esposte tramite l'API Win32

sto usando ZwReadFile, ZwCreateFile, ZwWriteFile, RtlInitUnicodeString, ZwQueryVolumeInformationFile, ZwDeviceIoControlFile, ZwSetInformationFile, ZwClose.

Gli IOCTL sto chiamando includono IOCTL_DISK_GET_PARTITION_INFO_EX, IOCTL_STORAGE_GET_DEVICE_NUMBER, IOCTL_DISK_GET_LENGTH_INFO e IOCTL_DISK_GET_DRIVE_LAYOUT_EX.

È stato utile?

Soluzione

Questo è molto strano, ma mi stava chiamando ZwQueryVolumeInformationFile con FsInformationClass set per FileFsVolumeInformation.

I era passato in un buffer di FILE_FS_VOLUME_INFORMATION primo normalmente allocato, quindi sovrassegnata a (sizeof(FILE_FS_VOLUME_INFORMATION) + sizeof(TCHAR)*FILE_FS_VOLUME_INFORMATION->VolumeLabelLength).

Poi ho chiamato FILE_FS_VOLUME_INFORMATION->VolumeLabel[FILE_FS_VOLUME_INFORMATION->VolumeLabelLength/2] = _T('\0'); e solo su alcune macchine Questo comporterebbe il danneggiamento della memoria.

A prescindere dalle dimensioni della sovrassegnazione (anche cercato l'assegnazione di ben 256 caratteri in più!), Questo sarebbe affidabile causare il danneggiamento di heap anche quando si utilizza un vector<unsigned char> come il buffer FILE_FS_VOLUME_INFORMATION.

Sembra che il kernel pone una sorta di protezione da scrittura sul buffer in qualche modo che è stato conseguente corruzione indipendentemente dalle dimensioni. Copiando i primi byte VolumeLableLength ad un secondo buffer, poi post-attesa _T('\0') risolto il problema. Non so come / perché di Windows stava facendo il buffer che I allocata e passata come parametro di sola lettura o se è stato immagazzinando dopo struct FILE_FS_VOLUME_INFORMATION (che dovrebbe end con l'array di caratteri!), ma semplicemente non modificare tutti i dati nel buffer che ho passato ha fatto il trucco .... che è pazzo, perché succede solo (in modo coerente e 100% riproducibili ) su alcune macchine.

In ogni caso: problema risolto * phew *

Altri suggerimenti

Ci sono stati molti cambiamenti nel driver di basso livello di da XP a Vista. Ho il sospetto che si sta utilizzando un IOCTL che è influenzata da esso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top