Funzione FltCreateFile (fltkernel.h)

I driver minifilter chiamano FltCreateFile per creare un nuovo file o aprire un file esistente.

Sintassi

NTSTATUS FLTAPI FltCreateFile(
  [in]           PFLT_FILTER        Filter,
  [in, optional] PFLT_INSTANCE      Instance,
  [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              CreateDisposition,
  [in]           ULONG              CreateOptions,
  [in, optional] PVOID              EaBuffer,
  [in]           ULONG              EaLength,
  [in]           ULONG              Flags
);

Parametri

[in] Filter

Puntatore di filtro opaco per il chiamante.

[in, optional] Instance

Puntatore di istanza opaco per l'istanza del driver minifilter a cui deve essere inviata la richiesta di creazione. L'istanza deve essere collegata al volume in cui risiede il file o la directory. Questo parametro è facoltativo e può essere NULL. Se questo parametro è NULL, la richiesta viene inviata all'oggetto dispositivo nella parte superiore dello stack di driver del file system per il volume. Se non è NULL, la richiesta viene inviata solo alle istanze del driver minifilter collegate sotto l'istanza specificata.

[out] FileHandle

Puntatore a una variabile allocata dal chiamante che riceve l'handle di file se la chiamata a FltCreateFile ha esito positivo.

[in] DesiredAccess

Maschera di bit di flag che specifica il tipo di accesso al file o alla directory richiesta dal chiamante. Per altre informazioni su questo parametro e per l'elenco dei valori di flag, vedere il parametro DesiredAccess di IoCreateFileEx .

[in] ObjectAttributes

Puntatore a una struttura OBJECT_ATTRIBUTES opaca già inizializzata con InitializeObjectAttributes. Per altre informazioni e per una descrizione di ogni membro della struttura, vedere il parametro ObjectAttributes di IoCreateFileEx .

[out] IoStatusBlock

Puntatore a una struttura IO_STATUS_BLOCK che riceve lo stato di completamento finale e informazioni sull'operazione richiesta. Per altre informazioni su questo parametro, vedere il parametro IoStatusBlock di IoCreateFileEx .

[in, optional] AllocationSize

Facoltativamente, specifica le dimensioni di allocazione iniziali, in byte, per il flusso di file. Un valore diverso da zero non ha alcun effetto a meno che il file non venga creato, sovrascritto o sostituito.

[in] FileAttributes

Specifica uno o più flag FILE_ATTRIBUTE_XXX , che rappresentano gli attributi di file da impostare se si sta creando, sostituisce o sovrascrivendo un file. Per altri dettagli e per l'elenco dei flag, vedere il parametro FileAttributes di IoCreateFileEx .

[in] ShareAccess

Specifica il tipo di accesso alla condivisione al file richiesto dal chiamante, come zero o uno o una combinazione dei flag. Per altri dettagli e per l'elenco dei flag, vedere il parametro ShareAccess di IoCreateFileEx .

[in] CreateDisposition

Specifica un valore che determina l'azione da eseguire, a seconda che il file esista già. Per l'elenco dei valori possibili, vedere il parametro Disposition di IoCreateFileEx .

[in] CreateOptions

Specifica le opzioni da applicare durante la creazione o l'apertura del file. Questo parametro è una combinazione compatibile dei flag elencati e descritti nel parametro CreateOptions di IoCreateFileEx.

[in, optional] EaBuffer

Puntatore a un buffer FILE_FULL_EA_INFORMATION strutturato fornito dal chiamante contenente informazioni sull'attributo esteso (EA) da applicare al file.

[in] EaLength

Lunghezza, in byte, di EaBuffer.

[in] Flags

Specifica le opzioni da utilizzare durante la creazione della richiesta di creazione. Per l'elenco delle opzioni possibili, vedere il parametro Options di IoCreateFileEx .

Valore restituito

FltCreateFile restituisce STATUS_SUCCESS o un valore NTSTATUS appropriato. Per un elenco dei possibili codici restituiti , vedere la sezione Valore restituito di IoCreateFileEx .

Nota

 FltCreateFile potrebbe restituire STATUS_FILE_LOCK_CONFLICT come valore restituito o nel membro Status della struttura IO_STATUS_BLOCK a cui punta il parametro IoStatusBlock. Ciò si verifica solo se il file di log NTFS è pieno e si verifica un errore mentre FltCreateFile tenta di gestire questa situazione.

Commenti

Nelle versioni di Windows precedenti a Microsoft Windows Update Rollup per Windows 2000 SP4 e Windows Server 2003 SP1, i driver minifilter devono chiamare FltCreateFile invece di IoCreateFile, IoCreateFileSpecifyDeviceObjectHint o ZwCreateFile per ottenere un handle di file da usare con le routine ZwReadFile e ZwQueryInformationFile.

In Microsoft Windows Update Rollup per Windows 2000 SP4, Windows Server 2003 SP1 e versioni successive, i driver minifilter possono usare FltCreateFileEx per ottenere un puntatore a oggetti file da usare con routine FltXxxFile come FltReadFile e FltWriteFile. Nelle versioni precedenti di Windows l'handle ottenuto da FltCreateFile può essere convertito in un puntatore a oggetti file chiamando ObReferenceObjectByHandle come indicato di seguito:

status = ObReferenceObjectByHandle(
           handle,                 //Handle
           0,                      //DesiredAccess
           NULL,                   //ObjectType
           KernelMode,             //AccessMode
           &handleFileObject,      //Object
           NULL);                  //HandleInformation</pre>

FltCreateFile invia la richiesta di creazione solo alle istanze collegate sotto l'istanza del driver minifilter specificata e al file system. L'istanza specificata e le istanze associate sopra non ricevono la richiesta di creazione. Se non viene specificata alcuna istanza, la richiesta passa all'inizio dello stack e viene ricevuta da tutte le istanze e dal file system.

Esistono due modi alternativi per specificare il nome del file da creare o aprire con FltCreateFile:

  • Come pathname completo, fornito nel membro ObjectName dell'oggetto ObjectAttributes di input.
  • Come percorso relativo al file di directory rappresentato dall'handle nel membro RootDirectory di input ObjectAttributes.

Qualsiasi handle ottenuto da FltCreateFile deve essere rilasciato chiamando FltClose.

Le routine del driver che non vengono eseguite nel contesto del processo di sistema devono impostare l'attributo OBJ_KERNEL_HANDLE per il parametro ObjectAttributes di FltCreateFile. L'impostazione di questo attributo limita l'uso dell'handle restituito da FltCreateFile ai processi in esecuzione in modalità kernel. In caso contrario, l'handle può essere accessibile dal processo nel cui contesto è in esecuzione il driver.

Nota

Non chiamare questa routine con un valore IRP di primo livello diverso da NULL, perché ciò può causare un deadlock di sistema.

Non chiamare questa routine con le APC disabilitate (un fsRtlEnterFileSystem o KeEnterCriticalRegion in sospeso, perché ciò può causare un deadlock del thread.

Alcuni flag DesiredAccess e combinazioni di flag hanno gli effetti seguenti:

  • Affinché un chiamante sincronizzi un completamento di I/O attende che il fileHandle restituito venga impostato sullo stato Segnalato, è necessario impostare il flag SYNCHRONIZE.

  • Se vengono impostati solo i flag FILE_APPEND_DATA e SYNCHRONIZE, il chiamante può scrivere solo alla fine del file e tutte le informazioni di offset sulle scritture nel file vengono ignorate. Tuttavia, il file viene esteso automaticamente in base alle esigenze per questo tipo di operazione di scrittura.

  • L'impostazione del flag FILE_WRITE_DATA per un file consente anche di scrivere oltre la fine del file. Il file viene esteso automaticamente anche per questo tipo di scrittura.

  • Se vengono impostati solo i flag FILE_EXECUTE e SYNCHRONIZE, il chiamante non può utilizzare l'oggetto FileHandle restituito per leggere o scrivere direttamente dati da o verso il file. Ovvero, tutte le operazioni sul file devono usare l'I/O di paging del sistema per leggere o scrivere dati di file.

Il parametro ShareAccess determina se thread separati possono accedere allo stesso file, possibilmente contemporaneamente. Se entrambi gli opener di file hanno il privilegio di accedere a un file nel modo specificato, il file può essere aperto e condiviso correttamente. Se il chiamante originale di FltCreateFile non specifica FILE_SHARE_READ, FILE_SHARE_WRITE o FILE_SHARE_DELETE, non è possibile eseguire altre operazioni aperte sul file perché il chiamante originale ha accesso esclusivo al file.

Affinché un file condiviso venga aperto correttamente, l'oggetto DesiredAccess richiesto al file deve essere compatibile con le specifiche DesiredAccess e ShareAccess di tutte le aperte precedenti che non sono ancora state rilasciate con FltClose. Ovvero, desiredAccess specificato in FltCreateFile per un determinato file non deve essere in conflitto con gli accessi non consentiti da altri opener del file.

Nota

Se IO_IGNORE_SHARE_ACCESS_CHECK viene specificato nel parametro Flags , il gestore di I/O ignora il parametro ShareAccess . Tuttavia, il file system potrebbe comunque eseguire controlli di accesso. È quindi importante specificare la modalità di condivisione desiderata per il parametro ShareAccess , anche quando si usa il flag IO_IGNORE_SHARE_ACCESS_CHECK. Si noti inoltre che, quando si specifica IO_IGNORE_SHARE_ACCESS_CHECK, il file system non tiene traccia dell'accesso desiderato o dell'accesso condiviso dell'apertura corrente. Per questo motivo, le successive chiamate aperte sullo stesso file possono avere esito positivo.

Il valore CreateDisposition FILE_SUPERSEDE richiede che il chiamante disponga dell'accesso DELETE a un oggetto file esistente. In tal caso, una chiamata a FltCreateFile con FILE_SUPERSEDE in un file esistente elimina effettivamente il file e quindi lo ricrea. Ciò implica che se il file è già stato aperto da un altro thread, ha aperto il file specificando un parametro ShareAccess con il flag FILE_SHARE_DELETE impostato. Si noti che questo tipo di eliminazione è coerente con lo stile POSIX dei file sovrascrivendo.

I valori CreateDisposition FILE_OVERWRITE_IF e FILE_SUPERSEDE sono simili. Se FltCreateFile viene chiamato con un file esistente e uno di questi valori CreateDisposition , il file viene sostituito.

La sovrascrittura di un file è semanticamente equivalente a un'operazione di sostituzione, ad eccezione dei seguenti:

  • Il chiamante deve avere accesso in scrittura al file, anziché eliminare l'accesso. Ciò implica che, se il file è già stato aperto da un altro thread, ha aperto il file con il flag FILE_SHARE_WRITE impostato nell'input ShareAccess.
  • Gli attributi di file specificati sono logicamente ORed con quelli già presenti nel file. Ciò implica che se il file è già stato aperto da un altro thread, un chiamante successivo di FltCreateFile non può disabilitare i flag FileAttributes esistenti, ma può abilitare flag aggiuntivi per lo stesso file. Si noti che questo stile di sovrascrittura dei file è coerente con MS-DOS, Windows 3.1 e OS/2.

Il valore createOptions FILE_DIRECTORY_FILE specifica che il file da creare o aprire è un file di directory. Quando viene creato un file di directory, il file system crea una struttura appropriata sul disco per rappresentare una directory vuota per la struttura su disco di quel particolare file system. Se questa opzione è stata specificata e il file specificato da aprire non è un file di directory o se il chiamante ha specificato un valore CreateOptions o CreateDisposition incoerente, la chiamata a FltCreateFile ha esito negativo.

Il flag CreateOptions FILE_NO_INTERMEDIATE_BUFFERING impedisce al file system di eseguire qualsiasi buffering intermedio per conto del chiamante. Se si specifica questo valore, vengono applicate determinate restrizioni ai parametri del chiamante a Zw.. Routine di file , tra cui le seguenti:

  • Qualsiasi valore offset di byte passato a ZwReadFile o ZwWriteFile deve essere un multiplo delle dimensioni del settore.
  • La lunghezza passata a ZwReadFile o ZwWriteFile deve essere un multiplo delle dimensioni del settore. Si noti che la specifica di un'operazione di lettura in un buffer la cui lunghezza è esattamente la dimensione del settore potrebbe comportare il trasferimento di meno byte significativi a tale buffer se la fine del file è stata raggiunta durante il trasferimento.
  • I buffer devono essere allineati in base al requisito di allineamento del dispositivo di archiviazione sottostante. Queste informazioni possono essere ottenute chiamando FltCreateFile per ottenere un handle per l'oggetto file che rappresenta il dispositivo fisico e quindi chiamando ZwQueryInformationFile con tale handle, specificando FileAlignmentInformation come FileInformationClass. Per altre informazioni sui valori di sistema FILE_XXX_ALIGNMENT, definiti in ntifs.h, vedere DEVICE_OBJECT e Inizializzazione di un oggetto Device.
  • Le chiamate a ZwSetInformationFile con il parametro FileInformationClass impostata su FilePositionInformation devono specificare un offset che corrisponde a più dimensioni del settore.

CreateOptions FILE_SYNCHRONOUS_IO_ALERT e FILE_SYNCHRONOUS_IO_NONALERT, che si escludono a vicenda come suggerisce i nomi, specificare che il file viene aperto per I/O sincrono. Ciò significa che tutte le operazioni di I/O sul file devono essere sincrone purché si verifichino tramite l'oggetto file a cui fa riferimento FileHandle restituito. Tutti gli I/O in un file di questo tipo vengono serializzati in tutti i thread usando l'handle restituito. Con uno di questi set CreateOptions , Gestione I/O mantiene l'offset di posizione del file corrente nel campo CurrentByteOffset dell'oggetto file. Questo offset può essere usato nelle chiamate a ZwReadFile e ZwWriteFile. Può anche essere eseguita una query o un set chiamando ZwQueryInformationFile o ZwSetInformationFile.

Se il flag CreateOptions FILE_OPEN_REPARSE_POINT non è specificato e FltCreateFile tenta di aprire un file con un punto di reparse, l'elaborazione normale del punto di ripristino si verifica per il file. Se, invece, viene specificato il flag di FILE_OPEN_REPARSE_POINT, l'elaborazione di riparse normale non si verifica e FltCreateFile tenta di aprire direttamente il file del punto di ripristino. In entrambi i casi, se l'operazione aperta ha avuto esito positivo, FltCreateFile restituisce STATUS_SUCCESS; in caso contrario, la routine restituisce un codice di errore NTSTATUS. FltCreateFile non restituisce mai STATUS_REPARSE.

Il flag CreateOptions FILE_OPEN_REQUIRING_OPLOCK elimina il tempo tra l'apertura del file e la richiesta di un oplock che potrebbe potenzialmente consentire a una terza parte di aprire il file e ottenere una violazione di condivisione. Un'applicazione può usare il flag di FILE_OPEN_REQUIRING_OPLOCK in FltCreateFile e quindi richiedere qualsiasi oplock. Ciò garantisce che un proprietario di oplock riceverà una notifica a qualsiasi richiesta aperta successiva che causa una violazione della condivisione.

In Windows 7, se esistono altri handle nel file quando un'applicazione usa il flag di FILE_OPEN_REQUIRING_OPLOCK, l'operazione di creazione avrà esito negativo con STATUS_OPLOCK_NOT_GRANTED. Questa restrizione non esiste più a partire da Windows 8.

Se questa operazione di creazione interrompe un oplock già presente nel file, l'impostazione del flag di FILE_OPEN_REQUIRING_OPLOCK causerà l'esito negativo dell'operazione di creazione con STATUS_CANNOT_BREAK_OPLOCK. L'oplock esistente non verrà interrotto da questa operazione di creazione.

Un'applicazione che usa questo flag deve richiedere un oplock dopo che questa chiamata ha esito positivo o tutti i tentativi successivi di aprire il file verranno bloccati senza il vantaggio dell'elaborazione tipica del blocco operativo. Analogamente, se questa chiamata ha esito positivo, ma la richiesta di oplock successiva ha esito negativo, un'applicazione che usa questo flag deve chiudere il relativo handle dopo aver rilevato che la richiesta di oplock non è riuscita.

Nota

Il flag FILE_OPEN_REQUIRING_OPLOCK è disponibile in Windows 7, Windows Server 2008 R2 e sistemi operativi Windows successivi. I file system Microsoft che implementano questo flag in Windows 7 sono NTFS, FAT e exFAT.

Il flag CreateOptions FILE_RESERVE_OPFILTER consente a un'applicazione di richiedere un oplock di livello 1, batch o filtro per impedire ad altre applicazioni di ottenere violazioni di condivisione. Tuttavia, FILE_RESERVE_OPFILTER è praticamente utile solo per gli oplock di filtro. Per usarlo, è necessario completare la procedura seguente:

  1. Eseguire una richiesta di creazione con CreateOptions di FILE_RESERVE_OPFILTER, DesiredAccess di esattamente FILE_READ_ATTRIBUTES e ShareAccess di esattamente FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.

    • Se sono già presenti handle aperti, la richiesta di creazione ha esito negativo con STATUS_OPLOCK_NOT_GRANTED e il successivo oplock richiesto ha esito negativo.
    • Se si apre con più accesso o meno condivisione, si verificherà anche un errore di STATUS_OPLOCK_NOT_GRANTED.
  2. Se la richiesta di creazione ha esito positivo, richiedere un oplock.

  3. Aprire un altro handle per il file per eseguire operazioni di I/O.

Il passaggio tre rende questa pratica solo per gli oplock di filtro. L'handle aperto nel passaggio 3 può avere un oggetto DesiredAccess che contiene un massimo di FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNC | READ_CONTROL e ancora non interrompere un blocco di filtri. Tuttavia, qualsiasi desiredAccess maggiore di FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNC interromperà un blocco di livello 1 o batch e renderà inutile il flag di FILE_RESERVE_OPFILTER per tali tipi di oplock.

NTFS è l'unico file system Microsoft che implementa FILE_RESERVE_OPFILTER.

I driver minifilter devono usare FltSetInformationFile, non ZwSetInformationFile, per rinominare un file.

Nota

Se si tenta di aprire un volume ma specificare solo una combinazione dei flag seguenti per il parametro DesiredAccess , FltCreateFile aprirà un handle, indipendentemente dal file system, che ha accesso diretto al dispositivo di archiviazione per il volume.

  • FILE_READ_ATTRIBUTES
  • READ_CONTROL
  • WRITE_DAC
  • WRITE_OWNER
  • SYNCHRONIZE

Non è necessario usare FltCreateFile per aprire un handle con accesso diretto al dispositivo di archiviazione per il volume oppure si perderanno le risorse di sistema. Se si vuole aprire un handle con accesso diretto a un dispositivo di archiviazione, chiamare invece la funzione IoCreateFileEx, IoCreateFileSpecifyDeviceObjectHint o ZwCreateFile.

Requisiti

Requisito Valore
Client minimo supportato Aggiornamento cumulativo di Windows 2000 1 per SP4, Windows XP SP2, Windows Server 2003 SP1
Piattaforma di destinazione Universale
Intestazione fltkernel.h (include FltKernel.h)
Libreria Fltmgr.lib
IRQL PASSIVE_LEVEL

Vedi anche

ACCESS_MASK

ACL

DEVICE_OBJECT

FILE_FULL_EA_INFORMATION

FltClose

FltCreateFileEx

FltCreateFileEx2

FltReadFile

FltWriteFile

InitializeObjectAttributes

IoCreateFile

IoCreateFileSpecifyDeviceObjectHint

ObReferenceObjectByHandle

SECURITY_DESCRIPTOR

UNICODE_STRING

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile