Função IoCreateFile (wdm.h)

A rotina IoCreateFile faz com que um novo arquivo ou diretório seja criado ou abra um arquivo, dispositivo, diretório ou volume existente, dando ao chamador um identificador para o objeto de arquivo.

Sintaxe

NTSTATUS IoCreateFile(
  [out]          PHANDLE            FileHandle,
  [in]           ACCESS_MASK        DesiredAccess,
  [in]           POBJECT_ATTRIBUTES ObjectAttributes,
  [out]          PIO_STATUS_BLOCK   IoStatusBlock,
  [in, optional] PLARGE_INTEGER     AllocationSize,
  [in]           ULONG              FileAttributes,
  [in]           ULONG              ShareAccess,
  [in]           ULONG              Disposition,
  [in]           ULONG              CreateOptions,
  [in, optional] PVOID              EaBuffer,
  [in]           ULONG              EaLength,
  [in]           CREATE_FILE_TYPE   CreateFileType,
  [in, optional] PVOID              InternalParameters,
  [in]           ULONG              Options
);

Parâmetros

[out] FileHandle

Ponteiro para uma variável que recebe o identificador de arquivo se a chamada for bem-sucedida. O driver deve fechar o identificador com ZwClose depois que o identificador não estiver mais em uso.

[in] DesiredAccess

Uma máscara de bits de sinalizadores que especifica o tipo de acesso ao arquivo ou diretório exigido pelo chamador. Consulte o parâmetro DesiredAccess de IoCreateFileEx para obter mais informações sobre esse parâmetro e para obter a lista de valores de sinalizador.

[in] ObjectAttributes

Ponteiro para uma estrutura de OBJECT_ATTRIBUTES opaca que já está inicializada com InitializeObjectAttributes. Consulte o parâmetro ObjectAttributes de IoCreateFileEx para obter mais informações e para obter uma descrição de cada membro da estrutura.

[out] IoStatusBlock

Ponteiro para uma estrutura de IO_STATUS_BLOCK que recebe o status de conclusão final e informações sobre a operação solicitada. Consulte o parâmetro IoStatusBlock de IoCreateFileEx.

[in, optional] AllocationSize

Opcionalmente, especifica o tamanho da alocação inicial em bytes para o arquivo. Um valor diferente de zero não tem efeito, a menos que o arquivo esteja sendo criado, substituído ou substituído.

[in] FileAttributes

Atributos especificados explicitamente são aplicados somente quando o arquivo é criado, substituído ou, em alguns casos, substituído. Por padrão, esse valor é FILE_ATTRIBUTE_NORMAL, que pode ser substituído por uma combinação ORed de um ou mais sinalizadores FILE_ATTRIBUTE_XXX , que são definidos em Wdm.h. Para obter uma lista de sinalizadores que podem ser usados com IoCreateFile, consulte CreateFile.

[in] ShareAccess

Especifica o tipo de acesso de compartilhamento ao arquivo que o chamador requer, como zero ou um, ou uma combinação dos sinalizadores. Consulte o parâmetro ShareAccess de IoCreateFileEx para obter mais detalhes e para obter a lista de sinalizadores.

[in] Disposition

Especifica um valor que determina a ação a ser tomada, dependendo se o arquivo já existe. Consulte o parâmetro Disposition de IoCreateFileEx para obter a lista de valores possíveis.

[in] CreateOptions

Especifica as opções a serem aplicadas ao criar ou abrir o arquivo. Esse parâmetro é uma combinação compatível dos sinalizadores listados e descritos no parâmetro CreateOptions de IoCreateFileEx.

[in, optional] EaBuffer

Para drivers intermediários e de dispositivo, esse parâmetro deve ser um ponteiro NULL .

[in] EaLength

Para drivers intermediários e de dispositivo, esse parâmetro deve ser zero.

[in] CreateFileType

Os drivers devem definir esse parâmetro como CreateFileTypeNone.

[in, optional] InternalParameters

Os drivers devem definir esse parâmetro como NULL.

[in] Options

Especifica as opções a serem usadas durante a criação da solicitação de criação. Consulte o parâmetro Options de IoCreateFileEx para obter a lista de opções possíveis.

Retornar valor

IoCreateFile retorna STATUS_SUCCESS ou um erro apropriado status. Valor NTSTATUS. Consulte a seção Valor retornado de IoCreateFileEx para obter uma lista de possíveis códigos de retorno.

Comentários

A rotina IoCreateFileEx é semelhante à rotina IoCreateFile , mas fornece uma funcionalidade maior do que a rotina IoCreateFile , incluindo acesso a ECPs (parâmetros de criação extra), objetos de dispositivo e informações de transação.

O identificador obtido por IoCreateFile pode ser usado por chamadas subsequentes para manipular dados dentro do arquivo ou do estado ou atributos do objeto de arquivo.

Há duas maneiras alternativas de especificar o nome do arquivo a ser criado ou aberto com IoCreateFile:

  1. Como um nome de caminho totalmente qualificado, fornecido no membro ObjectName da entrada ObjectAttributes

  2. Como pathname relativo ao arquivo de diretório representado pelo identificador no membro RootDirectory do ObjectAttributes de entrada

Determinados sinalizadores DesiredAccess e combinações de sinalizadores têm os seguintes efeitos:

  • Para que um chamador sincronize uma conclusão de E/S aguardando o FileHandle retornado, o sinalizador SYNCHRONIZE deve ser definido. Caso contrário, um chamador que seja um dispositivo ou driver intermediário deve sincronizar uma conclusão de E/S usando um objeto de evento.

  • Se apenas os sinalizadores FILE_APPEND_DATA e SYNCHRONIZE estiverem definidos, o chamador poderá gravar somente no final do arquivo e todas as informações de deslocamento sobre gravações no arquivo serão ignoradas. No entanto, o arquivo será automaticamente estendido conforme necessário para esse tipo de operação de gravação.

  • Definir o sinalizador FILE_WRITE_DATA para um arquivo também permite que as gravações além do final do arquivo ocorram. O arquivo também é estendido automaticamente para esse tipo de gravação.

  • Se apenas os sinalizadores FILE_EXECUTE e SYNCHRONIZE estiverem definidos, o chamador não poderá ler ou gravar dados diretamente no arquivo usando o FileHandle retornado: ou seja, todas as operações no arquivo ocorrem por meio do pager do sistema em resposta a instruções e acessos a dados. Os drivers intermediários e de dispositivo não devem definir o sinalizador FILE_EXECUTE em DesiredAccess.

O parâmetro ShareAccess determina se threads separados podem acessar o mesmo arquivo, possivelmente simultaneamente. Desde que ambos os abridores de arquivos tenham o privilégio de acessar um arquivo da maneira especificada, o arquivo pode ser aberto e compartilhado com êxito. Se o chamador original de IoCreateFile não especificar FILE_SHARE_READ, FILE_SHARE_WRITE ou FILE_SHARE_DELETE, nenhuma outra operação aberta poderá ser executada no arquivo: ou seja, o chamador original terá acesso exclusivo ao arquivo.

Para que um arquivo compartilhado seja aberto com êxito, o DesiredAccess solicitado para o arquivo deve ser compatível com as especificações DesiredAccess e ShareAccess de todas as aberturas anteriores que ainda não foram lançadas com zwClose. Ou seja, o DesiredAccess especificado para IoCreateFile para um determinado arquivo não deve entrar em conflito com os acessos que outros abridores do arquivo não permitiram.

O valor disposition FILE_SUPERSEDE requer que o chamador tenha acesso DELETE a um objeto de arquivo existente. Nesse caso, uma chamada bem-sucedida para IoCreateFile com FILE_SUPERSEDE em um arquivo existente exclui efetivamente esse arquivo e o recria. Isso implica que, se o arquivo já tiver sido aberto por outro thread, ele abriu o arquivo especificando um parâmetro ShareAccesscom o sinalizador FILE_SHARE_DELETE definido. Observe que esse tipo de disposição é consistente com o estilo POSIX de substituir arquivos.

Os valores disposição FILE_OVERWRITE_IF e FILE_SUPERSEDE são semelhantes. Se IoCreateFile for chamado com um arquivo existente e qualquer um desses valores disposition , o arquivo será substituído.

Substituir um arquivo é semanticamente equivalente a uma operação de substituição, exceto pelo seguinte:

  • O chamador deve ter acesso de gravação ao arquivo, em vez de excluir o acesso. Isso implica que, se o arquivo já tiver sido aberto por outro thread, ele abriu o arquivo com o sinalizador FILE_SHARE_WRITE definido no ShareAccess de entrada.

  • Os atributos de arquivo especificados são logicamente ORed com aqueles que já estão no arquivo. Isso implica que, se o arquivo já tiver sido aberto por outro thread, um chamador subsequente de IoCreateFile não poderá desabilitar sinalizadores FileAttributes existentes , mas poderá habilitar sinalizadores adicionais para o mesmo arquivo.

O valor FILE_DIRECTORY_FILE CreateOptions especifica que o arquivo a ser criado ou aberto é um arquivo de diretório. Quando um arquivo de diretório é criado, o sistema de arquivos cria uma estrutura apropriada no disco para representar um diretório vazio para a estrutura no disco desse sistema de arquivos específico. Se essa opção tiver sido especificada e o arquivo fornecido a ser aberto não for um arquivo de diretório ou se o chamador tiver especificado um valor de CreateOptions ou Disposition inconsistente, a chamada para IoCreateFile falhará.

O sinalizador CreateOptions FILE_NO_INTERMEDIATE_BUFFERING impede que o sistema de arquivos execute qualquer buffer intermediário em nome do chamador. Especificar esse valor coloca determinadas restrições nos parâmetros do chamador para as rotinas do Arquivo ZwXxx, incluindo o seguinte:

  • Qualquer ByteOffset opcional passado para ZwReadFile ou ZwWriteFile deve ser uma parte integrante do tamanho do setor.

  • O Length passado para ZwReadFile ou ZwWriteFile deve ser uma parte integrante do tamanho do setor. Observe que especificar uma operação de leitura para um buffer cujo comprimento é exatamente o tamanho do setor pode resultar em um número menor de bytes significativos sendo transferidos para esse buffer se o final do arquivo foi atingido durante a transferência.

  • Os buffers devem ser alinhados de acordo com o requisito de alinhamento do dispositivo subjacente. Essas informações podem ser obtidas chamando IoCreateFile para obter um identificador para o objeto de arquivo que representa o dispositivo físico e, em seguida, chamando ZwQueryInformationFile com esse identificador. Para obter uma lista dos valores FILE_XXX_ALIGNMENT do sistema, consulte DEVICE_OBJECT.

  • As chamadas para ZwSetInformationFile com o parâmetro FileInformationClass definido como FilePositionInformation devem especificar um deslocamento que seja uma parte integrante do tamanho do setor.

As FILE_SYNCHRONOUS_IO_ALERT e FILE_SYNCHRONOUS_IO_NONALERT CreateOptions , que são mutuamente exclusivas como seus nomes sugerem, especificam que todas as operações de E/S no arquivo devem ser síncronas, desde que ocorram por meio do objeto de arquivo referido pelo FileHandle retornado. Toda a E/S em um arquivo desse tipo é serializada em todos os threads usando o identificador retornado. Com qualquer uma dessas CreateOptions, o sinalizador DesiredAccess SYNCHRONIZE deve ser definido para que o gerenciador de E/S use o objeto de arquivo como um objeto de sincronização. Com qualquer um desses Conjuntos de CreateOptions , o gerenciador de E/S mantém o "contexto de posição do arquivo" para o objeto de arquivo, um deslocamento de posição de arquivo interno e atual. Esse deslocamento pode ser usado em chamadas para ZwReadFile e ZwWriteFile. Sua posição também pode ser consultada ou definida com ZwQueryInformationFile e ZwSetInformationFile.

Se o sinalizador CreateOptions FILE_OPEN_REPARSE_POINT não for especificado e IoCreateFile tentar abrir um arquivo com um ponto de nova análise, o processamento normal de ponto de nova análise ocorrerá para o arquivo. Se, por outro lado, o sinalizador FILE_OPEN_REPARSE_POINT for especificado, o processamento normal de nova análise não ocorrerá e IoCreateFile tentará abrir diretamente o arquivo de ponto de nova análise. Em ambos os casos, se a operação aberta tiver sido bem-sucedida, IoCreateFile retornará STATUS_SUCCESS; caso contrário, a rotina retorna um código de erro NTSTATUS. IoCreateFile nunca retorna STATUS_REPARSE.

O sinalizador CreateOptions FILE_OPEN_REQUIRING_OPLOCK elimina o tempo entre quando você abre o arquivo e solicita um oplock que poderia potencialmente permitir que terceiros abrissem o arquivo e recebessem uma violação de compartilhamento. Um aplicativo pode usar o sinalizador FILE_OPEN_REQUIRING_OPLOCK em IoCreateFile e solicitar qualquer oplock. Isso garante que um proprietário do oplock seja notificado de qualquer solicitação aberta posterior que cause uma violação de compartilhamento.

No Windows 7, se outros identificadores existirem no arquivo quando um aplicativo usar o sinalizador FILE_OPEN_REQUIRING_OPLOCK, a operação de criação falhará com STATUS_OPLOCK_NOT_GRANTED. Essa restrição não existe mais começando com Windows 8.

Se essa operação de criação interromper um oplock que já existe no arquivo, definir o sinalizador FILE_OPEN_REQUIRING_OPLOCK fará com que a operação de criação falhe com STATUS_CANNOT_BREAK_OPLOCK. O oplock existente não será quebrado por essa operação de criação.

Um aplicativo que usa o sinalizador FILE_OPEN_REQUIRING_OPLOCK deve solicitar um oplock depois que essa chamada for bem-sucedida ou todas as tentativas subsequentes de abrir o arquivo serão bloqueadas sem o benefício do processamento de oplock normal. Da mesma forma, se essa chamada for bem-sucedida, mas a solicitação oplock subsequente falhar, um aplicativo que usa esse sinalizador deverá fechar seu identificador depois de detectar que a solicitação oplock falhou.

O sinalizador FILE_OPEN_REQUIRING_OPLOCK está disponível no Windows 7, Windows Server 2008 R2 e versões posteriores do Windows. Os sistemas de arquivos da Microsoft que implementam esse sinalizador no Windows 7 são NTFS, FAT e exFAT.

O sinalizador CreateOptions , FILE_RESERVE_OPFILTER, permite que um aplicativo solicite um oplock de nível 1, lote ou filtro para impedir que outros aplicativos sejam violações de compartilhamento. No entanto, FILE_RESERVE_OPFILTER só é útil para oplocks de filtro. Para usá-lo, você deve seguir estas etapas:

  1. Emita uma solicitação de criação com CreateOptions de FILE_RESERVE_OPFILTER, DesiredAccess de exatamente FILE_READ_ATTRIBUTES e ShareAccess de exatamente FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.

    • Se já houver identificadores abertos, a solicitação de criação falhará com STATUS_OPLOCK_NOT_GRANTED e o próximo oplock solicitado também falhará.

    • Se você abrir com mais acesso ou menos compartilhamento, também causará uma falha de STATUS_OPLOCK_NOT_GRANTED.

  2. Se a solicitação de criação for bem-sucedida, solicite um oplock.

  3. Abra outro identificador no arquivo para fazer E/S.

A etapa 3 torna isso prático apenas para oplocks de filtro. O identificador aberto na etapa 3 pode ter um DesiredAccess que contém um máximo de FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNCHRONIZE | READ_CONTROL e ainda não quebrar um oplock de filtro. No entanto, qualquer DesiredAccess maior que FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE interromperá um oplock de nível 1 ou lote e tornará o sinalizador FILE_RESERVE_OPFILTER inútil para esses tipos de oplock.

O sinalizador Options IO_NO_PARAMETER_CHECKING poderá ser útil se um driver estiver emitindo uma solicitação de criação no modo kernel em nome de uma operação iniciada por um aplicativo de modo de usuário. Como a solicitação ocorre em um contexto de modo de usuário, o gerenciador de E/S, por padrão, investiga os valores de parâmetro fornecidos, o que pode causar uma violação de acesso se os parâmetros forem endereços no modo kernel. Esse sinalizador permite que o chamador substitua esse comportamento padrão e evite a violação de acesso.

Para solicitações de criação originadas no modo de usuário, se o driver definir IO_NO_PARAMETER_CHECKING e IO_FORCE_ACCESS_CHECK no parâmetro Options de IoCreateFile , ele também deverá definir OBJ_FORCE_ACCESS_CHECK no parâmetro ObjectAttributes . Para obter informações sobre esse sinalizador, consulte o membro Atributos de OBJECT_ATTRIBUTES.

O NTFS é o único sistema de arquivos da Microsoft que implementa FILE_RESERVE_OPFILTER.

As rotinas de driver executadas em um contexto de processo diferente do processo do sistema devem definir o atributo OBJ_KERNEL_HANDLE para o parâmetro ObjectAttributes de IoCreateFile. Isso restringe o uso do identificador retornado por IoCreateFile a processos em execução somente no modo kernel. Caso contrário, o identificador pode ser acessado pelo processo em cujo contexto o driver está em execução. Os drivers podem chamar InitializeObjectAttributes para definir o atributo OBJ_KERNEL_HANDLE da seguinte maneira.

InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

Requisitos

Requisito Valor
Plataforma de Destino Universal
Cabeçalho wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Biblioteca NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
Regras de conformidade de DDI HwStorPortProhibitedDIs(storport), IrqlIoPassive4(wdm), PowerIrpDDis(wdm)

Confira também

ACCESS_MASK

InitializeObjectAttributes

IO_STATUS_BLOCK

IoCreateFileEx (parâmetro DesiredAccess )

OBJECT_ATTRIBUTES

ZwClose

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile