Quando o redirecionador de rede acessa arquivos em servidores remotos, ele solicita o oplock do servidor remoto. Os aplicativos cliente solicitam oplocks diretamente somente quando o bloqueio é destinado a um arquivo no servidor local.
Os Oplocks são solicitados por meio de FSCTLs. As seguintes FSCTLs são usadas para os diferentes tipos oplock, que os aplicativos de modo de usuário e os drivers de modo kernel podem emitir:
Especifique o sinalizador REQUEST_OPLOCK_INPUT_FLAG_REQUEST no membro Flags da estrutura REQUEST_OPLOCK_INPUT_BUFFER , que é passado como o parâmetro lpInBuffer .
De maneira semelhante, para solicitar oplocks do Windows 7 no modo kernel:
Um minifiltro de sistema não arquivo pode chamar ZwFsControlFile.
Para especificar qual dos quatro oplocks do Windows 7 é necessário, defina um ou mais dos seguintes sinalizadores no membro RequestedOplockLevel da estrutura REQUEST_OPLOCK_INPUT_BUFFER :
Se o oplock solicitado puder ser concedido, o sistema de arquivos retornará STATUS_PENDING. Por esse motivo, os oplocks nunca são concedidos para E/S síncrona. O IRP FSCTL não é concluído até que o oplock seja quebrado.
Se o oplock não puder ser concedido, o sistema de arquivos retornará um código de erro apropriado. Os códigos de erro retornados com mais frequência são STATUS_OPLOCK_NOT_GRANTED e STATUS_INVALID_PARAMETER (e seus análogos de modo de usuário equivalentes).
O oplock Filter permite que um aplicativo "faça backup" quando outros aplicativos/clientes tentarem acessar o mesmo fluxo. Esse mecanismo permite que um aplicativo acesse um fluxo sem fazer com que outros acessadores do fluxo recebam violações de compartilhamento ao tentar abrir o fluxo. Para evitar violações de compartilhamento, um procedimento especial de três etapas deve ser usado para solicitar um filtro oplock (FSCTL_REQUEST_FILTER_OPLOCK):
Abra o arquivo com um acesso necessário de FILE_READ_ATTRIBUTES e um modo de compartilhamento de FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
Solicite um Oplock de filtro no identificador da etapa 1.
Abra o arquivo novamente para acesso de leitura.
O identificador aberto na etapa 1 não fará com que outros aplicativos recebam violações de compartilhamento, pois está aberto apenas para acesso a atributos (FILE_READ_ATTRIBUTES) e não acesso a dados (FILE_READ_DATA). Esse identificador é adequado para solicitar o oplock de filtro, mas não para executar E/S real no fluxo de dados. O identificador aberto na etapa 3 permite que o titular do oplock execute E/S no fluxo; o oplock concedido na etapa 2 permite que o titular do oplock "saia do caminho" sem causar uma violação de compartilhamento para outro aplicativo que tenta acessar o fluxo.
O sistema de arquivos NTFS fornece uma otimização para esse procedimento por meio do sinalizador de opção FILE_RESERVE_OPFILTER create. Se esse sinalizador for especificado na etapa 1 do procedimento anterior, ele permitirá que o sistema de arquivos falhe na solicitação de criação com STATUS_OPLOCK_NOT_GRANTED se o sistema de arquivos puder determinar se a etapa 2 falhará. Se a etapa 1 for bem-sucedida, não haverá garantia de que a etapa 2 terá êxito, mesmo que FILE_RESERVE_OPFILTER tenha sido especificado para a solicitação de criação.
A tabela a seguir identifica as condições necessárias para conceder um oplock.
Tipo de solicitação
Condições
Nível 1
Filtrar
Lote
Concedido somente se todas as seguintes condições forem verdadeiras:
A solicitação é para um determinado fluxo de um arquivo.
Se um diretório, STATUS_INVALID_PARAMETER será retornado.
O fluxo é aberto para acesso ASSÍNCROno.
Se aberto para acesso SÍNCRONO, STATUS_OPLOCK_NOT_GRANTED é retornado (oplocks não são concedidos para solicitações de E/S síncronas).
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Não há outras aberturas no fluxo (mesmo pelo mesmo thread).
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Se o estado atual do oplock for:
Sem oplock: a solicitação é concedida.
Nível 2: a solicitação de Nível 2 original é interrompida com FILE_OPLOCK_BROKEN_TO_NONE. O oplock exclusivo solicitado é concedido.
Nível 1, Lote, Filtro, Leitura, Identificador de Leitura, Leitura/Gravação ou Identificador de Leitura/Gravação: STATUS_OPLOCK_NOT_GRANTED é retornado.
Nível 2
Concedido somente se todas as seguintes condições forem verdadeiras:
A solicitação é para um determinado fluxo de um arquivo.
Se um diretório, STATUS_INVALID_PARAMETER será retornado.
O fluxo é aberto para acesso ASSÍNCROno.
Se aberto para acesso SÍNCRONO, STATUS_OPLOCK_NOT_GRANTED será retornado.
Não há transações TxF no arquivo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Não há bloqueios de intervalo de bytes atuais no fluxo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Antes do Windows 7, o sistema operacional verifica se um bloqueio de intervalo de bytes já existia no fluxo desde a última vez em que foi aberto e falha na solicitação em caso afirmativo.
Se o estado atual do oplock for:
Sem oplock: a solicitação é concedida.
Nível 2 e/ou Leitura: a solicitação é concedida. Você pode ter vários oplocks de Nível 2/Leitura concedidos no mesmo fluxo ao mesmo tempo. Vários oplocks de Nível 2 (mas não Leitura) podem existir no mesmo identificador.
Se um oplock de leitura for solicitado em um identificador que já tenha um Oplock de leitura concedido a ele, o PRIMEIRO IRP do Oplock de Leitura será concluído com STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE antes que o segundo oplock de leitura seja concedido.
Nível 1, Lote, Filtro, Identificador de Leitura, Leitura/Gravação, Identificador de Leitura/Gravação: STATUS_OPLOCK_NOT_GRANTED é retornado.
Ler
Concedido somente se todas as seguintes condições forem verdadeiras:
A solicitação é para um determinado fluxo de um arquivo.
O fluxo é aberto para acesso ASSÍNCROno.
Se aberto para acesso SÍNCRONO, STATUS_OPLOCK_NOT_GRANTED será retornado.
Não há transações TxF no arquivo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Não há bloqueios de intervalo de bytes atuais no fluxo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Lembre-se de que, se o estado atual do oplock for:
Sem oplock: a solicitação é concedida.
Nível 2 e/ou Leitura: a solicitação é concedida. Você pode ter vários oplocks de Nível 2/Leitura concedidos no mesmo fluxo ao mesmo tempo.
Além disso, se um oplock existente tiver a mesma chave oplock que a nova solicitação, seu IRP será concluído com STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.
Read-Handle e o oplock existente têm uma chave oplock diferente da nova solicitação: a solicitação é concedida. Vários oplocks de leitura e Read-Handle podem coexistir no mesmo fluxo (consulte a observação a seguir nesta tabela).
Caso contrário ,as chaves oplock são as mesmas) STATUS_OPLOCK_NOT_GRANTED é retornado.
Nível 1, Lote, Filtro, Leitura/Gravação, Identificador de Leitura/Gravação: STATUS_OPLOCK_NOT_GRANTED é retornado.
Read-Handle
Concedido somente se todas as seguintes condições forem verdadeiras:
A solicitação é para um determinado fluxo de um arquivo.
O fluxo é aberto para acesso ASYNCHRONOUS.
Se aberto para acesso SÍNCRONO, STATUS_OPLOCK_NOT_GRANTED será retornado.
Não há transações TxF no arquivo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Não há bloqueios de intervalo de bytes atuais no fluxo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Se o estado atual do oplock for:
Sem oplock: a solicitação é concedida.
Leia: a solicitação é concedida.
Se um Oplock de Leitura existente tiver a mesma chave oplock que a nova solicitação, seu IRP será concluído com STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE. O resultado é que o oplock é atualizado de Leitura para Identificador de Leitura.
Qualquer oplock de leitura existente que não tenha a mesma chave oplock que a nova solicitação permanece inalterada.
Nível 2, Nível 1, Lote, Filtro, Leitura/Gravação, Identificador de Leitura/Gravação: STATUS_OPLOCK_NOT_GRANTED é retornado.
Leitura-Gravação
Concedido somente se todas as seguintes condições forem verdadeiras:
A solicitação é para um determinado fluxo de um arquivo.
Se um diretório, STATUS_INVALID_PARAMETER será retornado.
O fluxo é aberto para acesso ASYNCHRONOUS.
Se aberto para acesso SÍNCRONO, STATUS_OPLOCK_NOT_GRANTED será retornado.
Não há transações TxF no arquivo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Se houver outras aberturas no fluxo (mesmo pelo mesmo thread), elas deverão ter a mesma chave oplock.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Se o estado atual do oplock for:
Sem oplock: a solicitação é concedida.
Ler ou Read-Write e o oplock existente tem a mesma chave oplock que a solicitação: o IRP do oplock existente é concluído com STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE, a solicitação é concedida.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Nível 2, Nível 1, Lote, Filtro, Identificador de Leitura, Identificador de Leitura/Gravação: STATUS_OPLOCK_NOT_GRANTED é retornado.
Identificador de leitura/gravação
Concedido somente se todos os seguintes itens forem verdadeiros:
A solicitação é para um determinado fluxo de um arquivo.
Se um diretório, STATUS_INVALID_PARAMETER será retornado.
O fluxo é aberto para acesso ASYNCHRONOUS.
Se aberto para acesso SÍNCRONO, STATUS_OPLOCK_NOT_GRANTED será retornado.
Não há transações TxF no arquivo.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Se houver outras solicitações abertas no fluxo (mesmo pelo mesmo thread), elas deverão ter a mesma chave oplock.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Se o estado atual do oplock for:
Sem oplock: a solicitação é concedida.
Read, Read-Handle, Read-Write ou Read-Write-Handle e o oplock existente têm a mesma chave oplock que a solicitação: o IRP do oplock existente é concluído com STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE, a solicitação é concedida.
Caso contrário, STATUS_OPLOCK_NOT_GRANTED é retornado.
Nível 2, Nível 1, Lote, Filtro: STATUS_OPLOCK_NOT_GRANTED é retornado.
Observação
Os oplocks de Leitura e Nível 2 podem coexistir no mesmo fluxo e oplocks de leitura e Read-Handle podem coexistir, mas oplocks de Nível 2 e Read-Handle não podem coexistir.