Funzione IoCreateFile (wdm.h)

La routine IoCreateFile determina la creazione di un nuovo file o di una nuova directory oppure apre un file, un dispositivo, una directory o un volume esistente, assegnando al chiamante un handle per l'oggetto file.

Sintassi

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
);

Parametri

[out] FileHandle

Puntatore a una variabile che riceve l'handle di file se la chiamata ha esito positivo. Il driver deve chiudere l'handle con ZwClose una volta che l'handle non è più in uso.

[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. Vedere il parametro IoStatusBlock di IoCreateFileEx.

[in, optional] AllocationSize

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

[in] FileAttributes

Gli attributi specificati in modo esplicito vengono applicati solo quando il file viene creato, sostituito o, in alcuni casi, sovrascritto. Per impostazione predefinita, questo valore è FILE_ATTRIBUTE_NORMAL, che può essere sottoposto a override da una combinazione ORed di uno o più flag FILE_ATTRIBUTE_XXX , definiti in Wdm.h. Per un elenco di flag che possono essere usati con IoCreateFile, vedere CreateFile.

[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] Disposition

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

Per i driver di dispositivo e intermedi, questo parametro deve essere un puntatore NULL .

[in] EaLength

Per i driver di dispositivo e intermedi, questo parametro deve essere zero.

[in] CreateFileType

I driver devono impostare questo parametro su CreateFileTypeNone.

[in, optional] InternalParameters

I driver devono impostare questo parametro su NULL.

[in] Options

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

IoCreateFile restituisce STATUS_SUCCESS o uno stato di errore appropriato. Valore NTSTATUS. Per un elenco dei possibili codici restituiti , vedere la sezione Valore restituito di IoCreateFileEx .

Commenti

La routine IoCreateFileEx è simile alla routine IoCreateFile , ma offre una maggiore funzionalità rispetto alla routine IoCreateFile , incluso l'accesso a parametri di creazione aggiuntivi (ECP), oggetti dispositivo e informazioni sulle transazioni.

L'handle ottenuto da IoCreateFile può essere usato dalle chiamate successive per modificare i dati all'interno del file o lo stato o gli attributi dell'oggetto file.

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

  1. Come percorso completo, fornito nel membro ObjectName di input ObjectAttributes

  2. Come pathname relativo al file di directory rappresentato dall'handle nel membro RootDirectory di input ObjectAttributes

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

  • Affinché un chiamante sincronizzi un completamento di I/O in attesa del fileHandle restituito, è necessario impostare il flag SYNCHRONIZE. In caso contrario, un chiamante che è un dispositivo o un driver intermedio deve sincronizzare un completamento di I/O usando un oggetto evento.

  • 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 verrà 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ò leggere o scrivere direttamente dati nel file usando l'oggetto FileHandle restituito, ovvero tutte le operazioni sul file vengono eseguite tramite il cercapersone di sistema in risposta alle istruzioni e agli accessi ai dati. I driver intermedi e del dispositivo non devono impostare il flag FILE_EXECUTE in DesiredAccess.

Il parametro ShareAccess determina se thread separati possono accedere allo stesso file, possibilmente contemporaneamente. A condizione che entrambi gli opener di file abbiano il privilegio di accedere a un file nel modo specificato, il file può essere aperto e condiviso correttamente. Se il chiamante originale di IoCreateFile non specifica FILE_SHARE_READ, FILE_SHARE_WRITE o FILE_SHARE_DELETE, non è possibile eseguire altre operazioni aperte sul file, ovvero al chiamante originale viene concesso l'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 ZwClose. Ovvero, l'oggetto DesiredAccess specificato in IoCreateFile per un determinato file non deve essere in conflitto con gli accessi non consentiti da altri opener del file.

Il valore Disposition FILE_SUPERSEDE richiede che il chiamante disponga dell'accesso DELETE a un oggetto file esistente. In tal caso, una chiamata a IoCreateFile con FILE_SUPERSEDE in un file esistente elimina in modo efficace 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 ShareAccesscon il flag FILE_SHARE_DELETE impostato. Si noti che questo tipo di eliminazione è coerente con lo stile POSIX dei file sovrascrivendo.

I valori Disposition FILE_OVERWRITE_IF e FILE_SUPERSEDE sono simili. Se IoCreateFile viene chiamato con un file esistente e uno di questi valori di Eliminazione , il file verrà 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 IoCreateFile non può disabilitare i flag FileAttributes esistenti, ma può abilitare flag aggiuntivi per lo stesso file.

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 Disposition incoerente, la chiamata a IoCreateFile avrà 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 alle routine ZwXxxFile , tra cui le seguenti:

  • Qualsiasi ByteOffset facoltativo passato a ZwReadFile o ZwWriteFile deve essere un integrale delle dimensioni del settore.

  • La lunghezza passata a ZwReadFile o ZwWriteFile deve essere un integrale 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 un numero minore di 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 sottostante. Queste informazioni possono essere ottenute chiamando IoCreateFile per ottenere un handle per l'oggetto file che rappresenta il dispositivo fisico e quindi chiamando ZwQueryInformationFile con tale handle. Per un elenco dei valori FILE_XXX_ALIGNMENT di sistema, vedere DEVICE_OBJECT.

  • Le chiamate a ZwSetInformationFile con il parametro FileInformationClass impostato su FilePositionInformation devono specificare un offset che è un integrale delle dimensioni del settore.

CreateOptions FILE_SYNCHRONOUS_IO_ALERT e FILE_SYNCHRONOUS_IO_NONALERT, che si escludono a vicenda come suggerisce i nomi, specificare che tutte le operazioni di I/O sul file devono essere sincrone purché si verifichino tramite l'oggetto file a cui fa riferimento l'oggetto FileHandle restituito. Tutte le operazioni di I/O in un file di questo tipo vengono serializzate in tutti i thread usando l'handle restituito. Con una di queste opzioni CreateOptions, il flag DesiredAccess SYNCHRONIZE deve essere impostato in modo che il gestore di I/O userà l'oggetto file come oggetto di sincronizzazione. Con uno di questi set CreateOptions , il gestore di I/O mantiene il "contesto di posizione file" per l'oggetto file, un offset di posizione del file interno e corrente. Questo offset può essere usato nelle chiamate a ZwReadFile e ZwWriteFile. La sua posizione può anche essere eseguita una query o impostata con ZwQueryInformationFile e ZwSetInformationFile.

Se il flag CreateOptions FILE_OPEN_REPARSE_POINT non è specificato e IoCreateFile tenta di aprire un file con un punto di correzione, viene eseguita la normale elaborazione dei punti di analisi per il file. Se, d'altra parte, viene specificato il flag FILE_OPEN_REPARSE_POINT, la normale elaborazione del reparse non viene eseguita e IoCreateFile tenta di aprire direttamente il file di reparse point. In entrambi i casi, se l'operazione di apertura ha avuto esito positivo, IoCreateFile restituisce STATUS_SUCCESS; in caso contrario, la routine restituisce un codice di errore NTSTATUS. IoCreateFile 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 consentire a terze parti di aprire il file e ottenere una violazione di condivisione. Un'applicazione può usare il flag FILE_OPEN_REQUIRING_OPLOCK in IoCreateFile e quindi richiedere qualsiasi oplock. Ciò garantisce che un proprietario di oplock riceverà una notifica di qualsiasi richiesta aperta successiva che causa una violazione di condivisione.

In Windows 7, se esistono altri handle nel file quando un'applicazione usa il flag 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à esistente 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 il flag FILE_OPEN_REQUIRING_OPLOCK deve richiedere un oplock dopo l'esito positivo di questa chiamata oppure tutti i tentativi successivi di aprire il file verranno bloccati senza il vantaggio della normale elaborazione di oplock. Analogamente, se la 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.

Il flag FILE_OPEN_REQUIRING_OPLOCK è disponibile in Windows 7, Windows Server 2008 R2 e versioni successive di Windows. I file system Microsoft che implementano questo flag in Windows 7 sono NTFS, FAT ed exFAT.

Il flag CreateOptions , FILE_RESERVE_OPFILTER, consente a un'applicazione di richiedere un oplock di livello 1, batch o filtro per impedire che altre applicazioni ottengano violazioni di condivisione. Tuttavia, FILE_RESERVE_OPFILTER è utile solo per i oplock di filtro. Per usarlo, è necessario seguire questa procedura:

  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 anche 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 3 rende questo pratico solo per i 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 | SYNCHRONIZE | READ_CONTROL e non interrompe ancora un oplock di filtro. Tuttavia, qualsiasi desiredAccess maggiore di FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE interromperà un oplock di livello 1 o batch e rende il flag FILE_RESERVE_OPFILTER inutile per tali tipi di oplock.

Il flag Options IO_NO_PARAMETER_CHECKING può essere utile se un driver esegue una richiesta di creazione in modalità kernel per conto di un'operazione avviata da un'applicazione in modalità utente. Poiché la richiesta si verifica all'interno di un contesto in modalità utente, per impostazione predefinita il gestore di I/O esegue il probe dei valori dei parametri forniti, che può causare una violazione di accesso se i parametri sono indirizzi in modalità kernel. Questo flag consente al chiamante di eseguire l'override di questo comportamento predefinito ed evitare la violazione di accesso.

Per la creazione di richieste di origine in modalità utente, se il driver imposta sia IO_NO_PARAMETER_CHECKING che IO_FORCE_ACCESS_CHECK nel parametro Options di IoCreateFile , deve anche impostare OBJ_FORCE_ACCESS_CHECK nel parametro ObjectAttributes . Per informazioni su questo flag, vedi il membro Attributes di OBJECT_ATTRIBUTES.

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

Le routine del driver eseguite in un contesto di processo diverso da quello del processo di sistema devono impostare l'attributo OBJ_KERNEL_HANDLE per il parametro ObjectAttributes di IoCreateFile. Ciò limita l'uso dell'handle restituito da IoCreateFile ai processi in esecuzione solo in modalità kernel. In caso contrario, l'handle può essere accessibile dal processo nel cui contesto è in esecuzione il driver. I driver possono chiamare InitializeObjectAttributes per impostare l'attributo OBJ_KERNEL_HANDLE come indicato di seguito.

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

Requisiti

Requisito Valore
Piattaforma di destinazione Universale
Intestazione wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
Libreria NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
Regole di conformità DDI HwStorPortProhibitedDDIs(storport), IrqlIoPassive4(wdm), PowerIrpDDis(wdm)

Vedi anche

ACCESS_MASK

InitializeObjectAttributes

IO_STATUS_BLOCK

IoCreateFileEx (parametro DesiredAccess )

OBJECT_ATTRIBUTES

ZwClose

ZwCreateFile

ZwQueryInformationFile

ZwReadFile

ZwSetInformationFile

ZwWriteFile