Quando il reindirizzamento di rete accede ai file nei server remoti, richiede il blocco dal server remoto. Le applicazioni client richiedono direttamente oplock solo quando il blocco è destinato a un file nel server locale.
Gli oplock vengono richiesti tramite LETLS. Per i diversi tipi di oplock vengono usati i seguenti tipi di oplock, che possono essere usata sia le applicazioni in modalità utente che i driver in modalità kernel:
Specificare il flag REQUEST_OPLOCK_INPUT_FLAG_REQUEST nel membro Flag della struttura REQUEST_OPLOCK_INPUT_BUFFER , passato come parametro lpInBuffer .
In modo simile, per richiedere oplock di Windows 7 in modalità kernel:
Un minifilter minifilter non file system può chiamare ZwFsControlFile.
Per specificare quale dei quattro oplock di Windows 7 è necessario, impostare uno o più dei flag seguenti nel membro RequestedOplockLevel della struttura REQUEST_OPLOCK_INPUT_BUFFER :
Se è possibile concedere l'oplock richiesto, il file system restituisce STATUS_PENDING. Per questo motivo, gli oplock non vengono mai concessi per I/O sincroni. L'IRP FSCTL non viene completato fino a quando il blocco non viene interrotto.
Se non è possibile concedere il blocco, il file system restituisce un codice di errore appropriato. I codici di errore restituiti più comunemente sono STATUS_OPLOCK_NOT_GRANTED e STATUS_INVALID_PARAMETER (e i relativi analogici in modalità utente equivalenti).
Il blocco filtro consente a un'applicazione di eseguire il "backout" quando altre applicazioni/client tentano di accedere allo stesso flusso. Questo meccanismo consente a un'applicazione di accedere a un flusso senza causare altre funzioni di accesso del flusso per ricevere violazioni di condivisione quando si tenta di aprire il flusso. Per evitare violazioni di condivisione, è consigliabile usare una procedura speciale in tre passaggi per richiedere un blocco di filtri (FSCTL_REQUEST_FILTER_OPLOCK):
Aprire il file con un accesso obbligatorio di FILE_READ_ATTRIBUTES e una modalità di condivisione di FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
Richiedere un blocco di filtro nell'handle dal passaggio 1.
Aprire di nuovo il file per l'accesso in lettura.
L'handle aperto nel passaggio 1 non causerà la ricezione di violazioni di condivisione da parte di altre applicazioni, poiché è aperta solo per l'accesso agli attributi (FILE_READ_ATTRIBUTES) e non l'accesso ai dati (FILE_READ_DATA). Questo handle è adatto per richiedere l'oplock Filtro, ma non per eseguire operazioni di I/O effettive nel flusso di dati. L'handle aperto nel passaggio 3 consente al titolare del blocco di eseguire operazioni di I/O nel flusso; il blocco concesso nel passaggio 2 consente al titolare del blocco di "uscire dal modo" senza causare una violazione di condivisione a un'altra applicazione che tenta di accedere al flusso.
Il file system NTFS fornisce un'ottimizzazione per questa procedura tramite il flag di opzione di creazione FILE_RESERVE_OPFILTER. Se questo flag viene specificato nel passaggio 1 della procedura precedente, consente al file system di non riuscire la richiesta di creazione con STATUS_OPLOCK_NOT_GRANTED se il file system può determinare che il passaggio 2 avrà esito negativo. Se il passaggio 1 ha esito positivo, non è garantito che il passaggio 2 abbia esito positivo, anche se FILE_RESERVE_OPFILTER è stato specificato per la richiesta di creazione.
La tabella seguente identifica le condizioni necessarie per concedere un oplock.
Tipo di richiesta
Condizioni
Livello 1
Filtra
Batch
Concesso solo se tutte le condizioni seguenti sono vere:
La richiesta è per un determinato flusso di un file.
Se viene restituita una directory, STATUS_INVALID_PARAMETER.
Il flusso viene aperto per l'accesso ASINCRONO.
Se aperto per l'accesso SINCRONO, viene restituito STATUS_OPLOCK_NOT_GRANTED (i blocchi non vengono concessi per le richieste di I/O sincrone).
Non sono presenti transazioni TxF in alcun flusso del file.
Viene restituito un altro STATUS_OPLOCK_NOT_GRANTED.
Non sono presenti altre finestre sul flusso (anche per lo stesso thread).
Viene restituito un altro STATUS_OPLOCK_NOT_GRANTED.
Se lo stato di oplock corrente è:
Nessun blocco: la richiesta viene concessa.
Livello 2: la richiesta di livello 2 originale viene interrotta con FILE_OPLOCK_BROKEN_TO_NONE. Viene quindi concesso l'oplock esclusivo richiesto.
Livello 1, Batch, Filter, Read, Read-Handle, Read-Write o Read-Write-Handle: viene restituito STATUS_OPLOCK_NOT_GRANTED.
Livello 2
Concesso solo se tutte le condizioni seguenti sono vere:
La richiesta è per un determinato flusso di un file.
Se viene restituita una directory, STATUS_INVALID_PARAMETER.
Il flusso viene aperto per l'accesso ASINCRONO.
Se aperto per l'accesso SINCRONO, viene restituito STATUS_OPLOCK_NOT_GRANTED.
Nel file non sono presenti transazioni TxF.
Viene restituito un altro STATUS_OPLOCK_NOT_GRANTED.
Non sono presenti blocchi di intervallo byte correnti nel flusso.
Viene restituito un altro STATUS_OPLOCK_NOT_GRANTED.
Prima di Windows 7, il sistema operativo verifica se esiste un blocco intervallo di byte nel flusso dall'ultima apertura e non riesce la richiesta in caso affermativo.
Se lo stato di oplock corrente è:
Nessun blocco: la richiesta viene concessa.
Livello 2 e/o Lettura: viene concessa la richiesta. È possibile disporre di più oplock di livello 2/lettura concessi allo stesso flusso contemporaneamente. Più operazioni di livello 2 (ma non di lettura) possono esistere anche nello stesso handle.
Se viene richiesto un oplock di lettura in un handle che dispone già di un blocco di lettura concesso a esso, il primo IRP di lettura viene completato con STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE prima che venga concesso il secondo blocco di lettura.
Livello 1, Batch, Filtro, Read-Handle, Read-Write, Read-Write-Handle: STATUS_OPLOCK_NOT_GRANTED viene restituito.
Lettura
Concesso solo se tutte le condizioni seguenti sono vere:
La richiesta è per un determinato flusso di un file.
Il flusso viene aperto per l'accesso ASINCRONO.
Se aperto per l'accesso SINCRONO, viene restituito STATUS_OPLOCK_NOT_GRANTED.
Nel file non sono presenti transazioni TxF.
Viene restituito un altro STATUS_OPLOCK_NOT_GRANTED.
Non sono presenti blocchi di intervallo byte correnti nel flusso.
Viene restituito un altro STATUS_OPLOCK_NOT_GRANTED.
Tenere presente che se lo stato di oplock corrente è:
Nessun blocco: la richiesta viene concessa.
Livello 2 e/o Lettura: viene concessa la richiesta. È possibile disporre di più oplock di livello 2/lettura concessi allo stesso flusso contemporaneamente.
Inoltre, se un oplock esistente ha la stessa chiave di oplock della nuova richiesta, il relativo IRP viene completato con STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE.
Read-Handle e l'oplock esistente hanno una chiave di oplock diversa dalla nuova richiesta: la richiesta viene concessa. Più operazioni di lettura e Read-Handle oplock possono coesistere nello stesso flusso (vedere la nota seguente questa tabella).
Else (le chiavi oplock sono uguali) STATUS_OPLOCK_NOT_GRANTED viene restituito.
Livello 1, Batch, Filtro, Lettura-Scrittura, Read-Write-Handle: STATUS_OPLOCK_NOT_GRANTED viene restituito.
Read-Handle
Concesso solo se tutte le condizioni seguenti sono vere:
La richiesta è per un determinato flusso di un file.
Il flusso viene aperto per l'accesso ASINCRONO.
Se aperto per l'accesso SINCRONOUS, viene restituito STATUS_OPLOCK_NOT_GRANTED.
Non sono presenti transazioni TxF nel file.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Non sono presenti blocchi di intervallo di byte correnti nel flusso.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Se lo stato di oplock corrente è:
Nessun oplock: la richiesta viene concessa.
Lettura: la richiesta viene concessa.
Se un oplock di lettura esistente ha la stessa chiave oplock della nuova richiesta, il relativo IRP viene completato con STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE. Il risultato è che l'oplock viene aggiornato da Read a Read-Handle.
Qualsiasi oplock di lettura esistente che non ha la stessa chiave oplock della nuova richiesta rimane invariata.
Livello 2, Livello 1, Batch, Filtro, Lettura-Scrittura, Read-Write-Handle: STATUS_OPLOCK_NOT_GRANTED viene restituito.
Read-Write
Concesso solo se tutte le condizioni seguenti sono vere:
La richiesta è per un determinato flusso di un file.
Se viene restituita una directory, STATUS_INVALID_PARAMETER.
Il flusso viene aperto per l'accesso ASINCRONO.
Se aperto per l'accesso SINCRONOUS, viene restituito STATUS_OPLOCK_NOT_GRANTED.
Non sono presenti transazioni TxF nel file.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Se nel flusso sono presenti altri elementi aperti (anche dallo stesso thread), devono avere la stessa chiave di oplock.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Se lo stato di oplock corrente è:
Nessun oplock: la richiesta viene concessa.
Lettura o Read-Write e l'oplock esistente ha la stessa chiave oplock della richiesta: l'IRP dell'oplock esistente viene completato con STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE, viene concessa la richiesta.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Livello 2, Livello 1, Batch, Filtro, Read-Handle, Read-Write-Handle: STATUS_OPLOCK_NOT_GRANTED viene restituito.
Read-Write-Handle
Concesso solo se tutte le condizioni seguenti sono vere:
La richiesta è per un determinato flusso di un file.
Se viene restituita una directory, STATUS_INVALID_PARAMETER.
Il flusso viene aperto per l'accesso ASINCRONO.
Se aperto per l'accesso SINCRONOUS, viene restituito STATUS_OPLOCK_NOT_GRANTED.
Non sono presenti transazioni TxF nel file.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Se nel flusso sono presenti altre richieste aperte (anche dallo stesso thread) devono avere la stessa chiave di oplock.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Se lo stato di oplock corrente è:
Nessun oplock: la richiesta viene concessa.
Read, Read-Handle, Read-Write o Read-Write-Handle e l'oplock esistente ha la stessa chiave oplock della richiesta: l'IRP esistente viene completato con STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE, viene concessa la richiesta.
Viene restituito STATUS_OPLOCK_NOT_GRANTED else.
Livello 2, Livello 1, Batch, Filtro: STATUS_OPLOCK_NOT_GRANTED viene restituito.
Nota
Gli oplock di lettura e di livello 2 possono coesistere nello stesso flusso e read e Read-Handle oplock possono coesistere, ma i oplock di livello 2 e Read-Handle non possono coesistere.