O aplicativo C ++ de baixo nível trava no Windows Vista/7, a menos que seja executado no modo de compatibilidade XP

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

Pergunta

Eu tenho um nível baixo (como verdade Baixo nível, é basicamente todas as chamadas do IOCTL e várias chamadas para as APIs de enumeração) que travam esporadicamente no Windows Vista/7 nas máquinas dos clientes. Infelizmente, não consegui obter despejos de falhas, mas um usuário útil mencionou que a execução do programa no modo de compatibilidade XP resolveu o problema.

O aplicativo é sempre lançado com os direitos de administrador completos (é lançado a partir de outro programa que requer autorização administrativa) para que não seja um problema da UAC. Não uso nenhuma API depreciada e não estou confiando em nenhum hacker de registro, etc. Estou apenas emitindo chamadas para enumerar discos e, em seguida, usar comandos do IOCTL para obter mais informações sobre todos os dispositivos anexados.

O que acontece no modo de compatibilidade XP? O que o Windows injeta no meu aplicativo ou o Sandbox com que o impede de travar no Vista/7? Eu tinha suspeito de corrupção de heap originalmente (embora eu tenha puxado meu cabelo tentando replicar ou rastrear o problema) antes de me dizer que ele funciona bem no modo de compatibilidade XP.

Alguém pode sugerir quaisquer problemas possíveis que seriam evitados no modo XP Compat que eu deveria procurar para tentar resolver esse problema? Obrigado!

EDITAR:

Mais uma coisa que provavelmente é muito importante para mencionar: estou chamando as funções DDK/kernel do UsuáriosPace para obter determinados recursos não expostos pela API Win32.

Estou usando o zwreadfile, zwcreatefile, zwwritefile, rtlinitunicodestring, zwqueryvolumeInformationfile, zwdeviceiocontrolfile, zwsetInformationfile, zwclose.

Os ioctls que estou chamando incluem ioctl_disk_get_partition_info_ex, ioctl_storage_get_device_number, ioctl_disk_get_length_info e ioctl_disk_get_drive_layout_ex.

Foi útil?

Solução

Isso é muito estranho, mas eu estava chamando o zwQueryVolumeInformationFile com o FSInformationClass definido para o FileFSVolumeInformation.

Eu tinha passado em um buffer de file_fs_volume_information primeiro alocado normalmente e depois no geral (sizeof(FILE_FS_VOLUME_INFORMATION) + sizeof(TCHAR)*FILE_FS_VOLUME_INFORMATION->VolumeLabelLength).

Então eu ligueiFILE_FS_VOLUME_INFORMATION->VolumeLabel[FILE_FS_VOLUME_INFORMATION->VolumeLabelLength/2] = _T('\0'); e Somente em algumas máquinas Isso resultaria em corrupção de memória.

Independentemente do tamanho da localização geral (até tentei alocar um 256 chars completo!), Isso resultaria de maneira confiável em corrupção de heap até Ao usar a vector<unsigned char> como o buffer file_fs_volume_information.

Parece que o kernel coloca algum tipo de proteção de gravação no buffer de alguma forma que estava resultando em corrupção, independentemente do tamanho. Copiando os primeiros bytes volumelableLength para um segundo buffer, então pós-pendente _T('\0') resolveu o problema. Não tenho certeza de como/por que o Windows estava fazendo do buffer que EU alocado e passado como um parâmetro reado ou Se estava armazenando depois A estrutura FILE_FS_VOLume_information (que deve Termine com a matriz de caracteres!), Mas simplesmente não modificando nenhum dado no buffer que eu passei fez o truque ... o que é louco porque só acontece (de forma consistente e 100% reproduzível) em certas máquinas.

De qualquer forma: problema resolvido *ufa *!

Outras dicas

Houve muitas mudanças no motorista de baixo nível do XP para o Vista. Eu suspeito que você esteja usando um IOCTL afetado por ele.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top