CreateFile, ReadFile/WriteFile, DeviceIoControl


WaitForSingleObject Function ***************************************************

Waits until the specified object is in the signaled state or the time-out interval elapses.
To enter an alertable wait state, use the WaitForSingleObjectEx function.
To wait for multiple objects, use the WaitForMultipleObjects.

DWORD WINAPI WaitForSingleObject(
__in HANDLE hHandle,
__in DWORD dwMilliseconds
);

Parameters

hHandle [in]
A handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.
If this handle is closed while the wait is still pending, the function's behavior is undefined.

The handle must have the SYNCHRONIZE access right. For more information, see Standard Access Rights.

dwMilliseconds [in]
The time-out interval, in milliseconds.
If a nonzero value is specified, the function waits until the object is signaled or the interval elapses.
If dwMilliseconds is zero, the function does not enter a wait state if the object is not signaled; it always returns immediately.
If dwMilliseconds is INFINITE, the function will return only when the object is signaled.

Return Value

If the function succeeds, the return value indicates the event that caused the function to return.
It can be one of the following values.

WAIT_ABANDONED 0x00000080L
The specified object is a mutex object that was not released by the thread that owned the mutex object
before the owning thread terminated.
Ownership of the mutex object is granted to the calling thread and the mutex state is set to nonsignaled.
If the mutex was protecting persistent state information, you should check it for consistency.

WAIT_OBJECT_0 0x00000000L
The state of the specified object is signaled.

WAIT_TIMEOUT 0x00000102L
The time-out interval elapsed, and the object's state is nonsignaled.

WAIT_FAILED (DWORD)0xFFFFFFFF
The function has failed. To get extended error information, call GetLastError.

Remarks

The WaitForSingleObject function checks the current state of the specified object.
If the object's state is nonsignaled, the calling thread enters the wait state
until the object is signaled or the time-out interval elapses.

The function modifies the state of some types of synchronization objects.
Modification occurs only for the object whose signaled state caused the function to return.
For example, the count of a semaphore object is decreased by one.

The WaitForSingleObject function can wait for the following objects:

Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer

Use caution when calling the wait functions and code that directly or indirectly creates windows.
If a thread creates any windows, it must process messages.
Message broadcasts are sent to all windows in the system.
A thread that uses a wait function with no time-out interval may cause the system to become deadlocked.
Two examples of code that indirectly creates windows are DDE and the CoInitialize function.
Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx,
rather than WaitForSingleObject.


WaitForMultipleObjects Function ************************************************

Waits until one or all of the specified objects are in the signaled state
or the time-out interval elapses.

To enter an alertable wait state, use the WaitForMultipleObjectsEx function.

Syntax

Copy
DWORD WINAPI WaitForMultipleObjects(
__in DWORD nCount,
__in const HANDLE *lpHandles,
__in BOOL bWaitAll,
__in DWORD dwMilliseconds
);

Parameters

nCount [in]
The number of object handles in the array pointed to by lpHandles.
The maximum number of object handles is MAXIMUM_WAIT_OBJECTS.

lpHandles [in]
An array of object handles.
For a list of the object types whose handles can be specified, see the following Remarks section.
The array can contain handles to objects of different types.
It may not contain multiple copies of the same handle.
If one of these handles is closed while the wait is still pending, the function's behavior is undefined.
The handles must have the SYNCHRONIZE access right.
For more information, see Standard Access Rights.

bWaitAll [in]
If this parameter is TRUE, the function returns when the state of all objects in the lpHandles array is signaled.
If FALSE, the function returns when the state of any one of the objects is set to signaled.
In the latter case, the return value indicates the object whose state caused the function to return.

dwMilliseconds [in]
The time-out interval, in milliseconds.
If a nonzero value is specified, the function waits until the specified objects are signaled or the interval elapses.

If dwMilliseconds is zero, the function does not enter a wait state if the specified objects are not signaled;
it always returns immediately.

If dwMilliseconds is INFINITE, the function will return only when the specified objects are signaled.

Return Value

If the function succeeds, the return value indicates the event that caused the function to return.
It can be one of the following values.
(Note that WAIT_OBJECT_0 is defined as 0 and WAIT_ABANDONED_0 is defined as 0x00000080L.)

Return code/value Description
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1)
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled.

If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0
indicates the lpHandles array index of the object that satisfied the wait.

If more than one object became signaled during the call,
this is the array index of the signaled object with the smallest index value of all the signaled objects.

WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled
and at least one of the objects is an abandoned mutex object.

If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0
indicates the lpHandles array index of an abandoned mutex object that satisfied the wait.
Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.

If a mutex was protecting persistent state information, you should check it for consistency.

WAIT_TIMEOUT 0x00000102L
The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied.

WAIT_FAILED (DWORD)0xFFFFFFFF
The function has failed. To get extended error information, call GetLastError.

Remarks

The WaitForMultipleObjects function determines whether the wait criteria have been met.
If the criteria have not been met, the calling thread enters the wait state
until the conditions of the wait criteria have been met or the time-out interval elapses.

When bWaitAll is TRUE, the function's wait operation is completed
only when the states of all objects have been set to signaled.
The function does not modify the states of the specified objects
until the states of all objects have been set to signaled.
For example, a mutex can be signaled, but the thread does not get ownership
until the states of the other objects are also set to signaled.
In the meantime, some other thread may get ownership of the mutex,
thereby setting its state to nonsignaled.

When bWaitAll is FALSE, this function checks the handles in the array in order starting with index 0,
until one of the objects is signaled.
If multiple objects become signaled, the function returns the index of the first handle in the array
whose object was signaled.

The function modifies the state of some types of synchronization objects.
Modification occurs only for the object or objects whose signaled state caused the function to return.
For example, the count of a semaphore object is decreased by one. For more information,
see the documentation for the individual synchronization objects.

Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer

Use caution when calling the wait functions and code that directly or indirectly creates windows.
If a thread creates any windows, it must process messages.
Message broadcasts are sent to all windows in the system.
A thread that uses a wait function with no time-out interval may cause the system to become deadlocked.
Two examples of code that indirectly creates windows are DDE and the CoInitialize function.
Therefore, if you have a thread that creates windows,
use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForMultipleObjects.


GetOverlappedResult Function ***************************************************

Retrieves the results of an overlapped operation on the specified file, named pipe, or communications device.

BOOL WINAPI GetOverlappedResult(
__in HANDLE hFile,
__in LPOVERLAPPED lpOverlapped,
__out LPDWORD lpNumberOfBytesTransferred,
__in BOOL bWait
);

Parameters

hFile [in]
A handle to the file, named pipe, or communications device.
This is the same handle that was specified when the overlapped operation was started by a call
to the ReadFile, WriteFile, ConnectNamedPipe, TransactNamedPipe, DeviceIoControl, or WaitCommEvent function.

lpOverlapped [in]
A pointer to an OVERLAPPED structure that was specified when the overlapped operation was started.

lpNumberOfBytesTransferred [out]
A pointer to a variable that receives the number of bytes that were actually transferred by a read or write operation.
For a read or write operation, this is the number of bytes that were actually transferred
For a TransactNamedPipe operation, this is the number of bytes that were read from the pipe.
For a DeviceIoControl operation, this is the number of bytes of output data returned by the device driver.
For a ConnectNamedPipe or WaitCommEvent operation, this value is undefined.

bWait [in]
If this parameter is TRUE, the function does not return until the operation has been completed.
If this parameter is FALSE and the operation is still pending,
the function returns FALSE and the GetLastError function returns ERROR_IO_INCOMPLETE.

Return Value

If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The results reported by the GetOverlappedResult function are those of the specified handle's last overlapped operation
to which the specified OVERLAPPED structure was provided, and for which the operation's results were pending.

A pending operation is indicated when the function that started the operation returns FALSE,
and the GetLastError function returns ERROR_IO_PENDING.

When an I/O operation is pending, the function that started the operation
resets the hEvent member of the OVERLAPPED structure to the nonsignaled state.

Then when the pending operation has been completed, the system sets the event object to the signaled state.

Specify a manual-reset event object in the OVERLAPPED structure.
If an auto-reset event object is used,
the event handle must not be specified in any other wait operation in the interval
between starting the overlapped operation and the call to GetOverlappedResult.

For example, the event object is sometimes specified in one of the wait functions to wait for the operation's completion.
When the wait function returns, the system sets an auto-reset event's state to nonsignaled,
and a subsequent call to GetOverlappedResult with the bWait parameter set to TRUE
causes the function to be blocked indefinitely.

If the bWait parameter is TRUE, GetOverlappedResult determines
whether the pending operation has been completed by waiting for the event object to be in the signaled state.

If the hEvent member of the OVERLAPPED structure is NULL,
the system uses the state of the hFile handle to signal when the operation has been completed.

Use of file, named pipe, or communications-device handles for this purpose is discouraged.
It is safer to use an event object because of the confusion
that can occur when multiple simultaneous overlapped operations are performed
on the same file, named pipe, or communications device.

In this situation, there is no way to know which operation caused the object's state to be signaled.


*)

(*
HANDLE WINAPI CreateEvent(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes,
__in BOOL bManualReset,
__in BOOL bInitialState,
__in_opt LPCTSTR lpName
);

lpEventAttributes [in, optional]
A pointer to a SECURITY_ATTRIBUTES structure.
If this parameter is NULL, the handle cannot be inherited by child processes.

The lpSecurityDescriptor member of the structure specifies a security descriptor for the new event.
If lpEventAttributes is NULL, the event gets a default security descriptor.
The ACLs in the default security descriptor for an event come from the primary or impersonation token of the creator.

bManualReset [in]
If this parameter is TRUE, the function creates a manual-reset event object,
which requires the use of the ResetEvent function to set the event state to nonsignaled.

If this parameter is FALSE, the function creates an auto-reset event object,
and system automatically resets the event state to nonsignaled after a single waiting thread has been released.

bInitialState [in]
If this parameter is TRUE, the initial state of the event object is signaled; otherwise, it is nonsignaled.

lpName [in, optional]
The name of the event object. The name is limited to MAX_PATH characters. Name comparison is case sensitive.

If lpName matches the name of an existing named event object, this function requests the EVENT_ALL_ACCESS access right.
In this case, the bManualReset and bInitialState parameters are ignored because they have already been set by the creating process.

If the lpEventAttributes parameter is not NULL, it determines whether the handle can be inherited,
but its security-descriptor member is ignored.

If lpName is NULL, the event object is created without a name.
If lpName matches the name of another kind of object in the same name space
(such as an existing semaphore, mutex, waitable timer, job, or file-mapping object),
the function fails and the GetLastError function returns ERROR_INVALID_HANDLE.
This occurs because these objects share the same name space.

The name can have a "Global\" or "Local\" prefix to explicitly create the object
in the global or session name space.
The remainder of the name can contain any character except the backslash character (\).
For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions.
Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.

Windows 2000:
If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored.
The remainder of the name can contain any character except the backslash character.
The object can be created in a private namespace. For more information, see Object Namespaces.

Return Value

If the function succeeds, the return value is a handle to the event object.
If the named event object existed before the function call,
the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.

If the function fails, the return value is NULL.
To get extended error information, call GetLastError.

Remarks

The handle returned by CreateEvent has the EVENT_ALL_ACCESS access right;
it can be used in any function that requires a handle to an event object,
provided that the caller has been granted access.
If an event is created from a service or a thread that is impersonating a different user,
you can either apply a security descriptor to the event when you create it,
or change the default security descriptor for the creating process by changing its default DACL.

For more information, see Synchronization Object Security and Access Rights.

Any thread of the calling process can specify the event-object handle in a call to one of the wait functions.
The single-object wait functions return when the state of the specified object is signaled.
The multiple-object wait functions can be instructed to return either when any one
or when all of the specified objects are signaled.
When a wait function returns, the waiting thread is released to continue its execution.

The initial state of the event object is specified by the bInitialState parameter.
Use the SetEvent function to set the state of an event object to signaled.
Use the ResetEvent function to reset the state of an event object to nonsignaled.

When the state of a manual-reset event object is signaled,
it remains signaled until it is explicitly reset to nonsignaled by the ResetEvent function.
Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object,
can be released while the object's state is signaled.

When the state of an auto-reset event object is signaled,
it remains signaled until a single waiting thread is released;
the system then automatically resets the state to nonsignaled.
If no threads are waiting, the event object's state remains signaled.

Multiple processes can have handles of the same event object,
enabling use of the object for interprocess synchronization.
The following object-sharing mechanisms are available:

A child process created by the CreateProcess function can inherit a handle to an event object
if the lpEventAttributes parameter of CreateEvent enabled inheritance.
A process can specify the event-object handle in a call to the DuplicateHandle function
to create a duplicate handle that can be used by another process.
A process can specify the name of an event object in a call to the OpenEvent or CreateEvent function.

Use the CloseHandle function to close the handle.
The system closes the handle automatically when the process terminates.
The event object is destroyed when its last handle has been closed.

ReadFile Function **************************************************************

Reads data from the specified file or input/output (I/O) device.
Reads occur at the position specified by the file pointer if supported by the device.

This function is designed for both synchronous and asynchronous operations.
For a similar function designed solely for asynchronous operation, see ReadFileEx.

Syntax

Copy
BOOL WINAPI ReadFile(
__in HANDLE hFile,
__out LPVOID lpBuffer,
__in DWORD nNumberOfBytesToRead,
__out_opt LPDWORD lpNumberOfBytesRead,
__inout_opt LPOVERLAPPED lpOverlapped
);

hFile [in]
A handle to the device (for example, a file, file stream, physical disk, volume,
console buffer, tape drive, socket, communications resource, mailslot, or pipe).

The hFile parameter must have been created with read access.
For more information, see Generic Access Rights and File Security and Access Rights.

For asynchronous read operations, hFile can be any handle that
is opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function,
or a socket handle returned by the socket or accept function.

lpBuffer [out]
A pointer to the buffer that receives the data read from a file or device.

This buffer must remain valid for the duration of the read operation.
The caller must not use this buffer until the read operation is completed.

nNumberOfBytesToRead [in]
The maximum number of bytes to be read.

lpNumberOfBytesRead [out, optional]
A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter.
ReadFile sets this value to zero before doing any work or error checking.
Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.

This parameter can be NULL only when the lpOverlapped parameter is not NULL.
For more information, see the Remarks section.

lpOverlapped [in, out, optional]
A pointer to an OVERLAPPED structure is required if the hFile parameter
was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL.

If hFile is opened with FILE_FLAG_OVERLAPPED,
the lpOverlapped parameter must point to a valid and unique OVERLAPPED structure,
otherwise the function can incorrectly report that the read operation is complete.

For an hFile that supports byte offsets,
if you use this parameter you must specify a byte offset at which to start reading from the file or device.
This offset is specified by setting the Offset and OffsetHigh members of the OVERLAPPED structure.
For an hFile that does not support byte offsets, Offset and OffsetHigh are ignored.

For more information about different combinations of lpOverlapped and FILE_FLAG_OVERLAPPED,
see the Remarks section and the Synchronization and File Position section.

Return Value

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, or is completing asynchronously, the return value is zero (FALSE).
To get extended error information, call the GetLastError function.

Note The GetLastError code ERROR_IO_PENDING is not a failure;
it designates the read operation is pending completion asynchronously.
For more information, see Remarks.

Remarks

The ReadFile function returns when one of the following conditions occur:

The number of bytes requested is read.

A write operation completes on the write end of the pipe.

An asynchronous handle is being used and the read is occurring asynchronously.

An error occurs.

If the ReadFile function attempts to read past the end of the file,
the function returns zero, and GetLastError returns ERROR_HANDLE_EOF.

The ReadFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY
whenever there are too many outstanding asynchronous I/O requests.

To cancel all pending asynchronous I/O operations, use either:

CancelIo—this function only cancels operations issued by the calling thread for the specified file handle.

CancelIoEx—this function cancels all operations issued by the threads for the specified file handle.

Use CancelSynchronousIo to cancel pending synchronous I/O operations.

I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

The ReadFile function may fail with ERROR_NOT_ENOUGH_QUOTA,
which means the calling process's buffer could not be page-locked.
For additional information, see SetProcessWorkingSetSize.

If part of a file is locked by another process
and the read operation overlaps the locked portion, this function fails.

Accessing the input buffer while a read operation
is using the buffer may lead to corruption of the data read into that buffer.
Applications must not read from, write to, reallocate, or free the input buffer
that a read operation is using until the read operation completes.

This can be particularly problematic when using an asynchronous file handle.
Additional information regarding synchronous versus asynchronous file handles
can be found in the Synchronization and File Position section
and in the CreateFile reference topic.

Characters can be read from the console input buffer by using ReadFile with a handle to console input.
The console mode determines the exact behavior of the ReadFile function.
By default, the console mode is ENABLE_LINE_INPUT,
which indicates that ReadFile should read until it reaches a carriage return.
If you press Ctrl+C, the call succeeds, but GetLastError returns ERROR_OPERATION_ABORTED.
For more information, see CreateFile.

When reading from a communications device, the behavior of ReadFile
is determined by the current communication time-out as set
and retrieved by using the SetCommTimeouts and GetCommTimeouts functions.
Unpredictable results can occur if you fail to set the time-out values.
For more information about communication time-outs, see COMMTIMEOUTS.

If ReadFile attempts to read from a mailslot that has a buffer that is too small,
the function returns FALSE and GetLastError returns ERROR_INSUFFICIENT_BUFFER.

There are strict requirements for successfully working
with files opened with CreateFile using the FILE_FLAG_NO_BUFFERING flag.
For details see File Buffering.

If hFile was opened with FILE_FLAG_OVERLAPPED, the following conditions are in effect:

The lpOverlapped parameter must point to a valid and unique OVERLAPPED structure,
otherwise the function can incorrectly report that the read operation is complete.
The lpNumberOfBytesRead parameter should be set to NULL.
Use the GetOverlappedResult function to get the actual number of bytes read.
If the hFile parameter is associated with an I/O completion port,
you can also get the number of bytes read by calling the GetQueuedCompletionStatus function.

Synchronization and File Position

If hFile is opened with FILE_FLAG_OVERLAPPED, it is an asynchronous file handle;
otherwise it is synchronous.

The rules for using the OVERLAPPED structure are slightly different for each, as previously noted.

Note If a file or device is opened for asynchronous I/O,
subsequent calls to functions such as ReadFile using that handle generally return immediately,
but can also behave synchronously with respect to blocked execution.
For more information see http://support.microsoft.com/kb/156932.

Considerations for working with asynchronous file handles:

ReadFile may return before the read operation is complete.

In this scenario, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING,
******************************************************************************

which allows the calling process to continue while the system completes the read operation.

The lpOverlapped parameter must not be NULL and should be used with the following facts in mind:
Although the event specified in the OVERLAPPED structure is set and reset automatically by the system,
the offset that is specified in the OVERLAPPED structure is not automatically updated.

ReadFile resets the event to a nonsignaled state when it begins the I/O operation.

The event specified in the OVERLAPPED structure is set to a signaled state when the read operation is complete;
until that time, the read operation is considered pending.

Because the read operation starts at the offset that is specified in the OVERLAPPED structure,
and ReadFile may return before the system-level read operation is complete (read pending),
neither the offset nor any other part of the structure should be modified, freed,
or reused by the application until the event is signaled (that is, the read completes).

If end-of-file (EOF) is detected during asynchronous operations,
the call to GetOverlappedResult for that operation returns FALSE and GetLastError returns ERROR_HANDLE_EOF.

Considerations for working with synchronous file handles:

If lpOverlapped is NULL, the read operation starts at the current file position
and ReadFile does not return until the operation is complete,
and the system updates the file pointer before ReadFile returns.

If lpOverlapped is not NULL, the read operation starts at the offset
that is specified in the OVERLAPPED structure
and ReadFile does not return until the read operation is complete.

The system updates the OVERLAPPED offset before ReadFile returns.
When a synchronous read operation reaches the end of a file,
ReadFile returns TRUE and sets *lpNumberOfBytesRead to zero.

For more information, see CreateFile and Synchronous and Asynchronous I/O.

Pipes

If an anonymous pipe is being used and the write handle has been closed,
when ReadFile attempts to read using the pipe's corresponding read handle,
the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.

If a named pipe is being read in message mode and the next message
is longer than the nNumberOfBytesToRead parameter specifies,
ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA.

The remainder of the message can be read
by a subsequent call to the ReadFile or PeekNamedPipefunction.

If the lpNumberOfBytesRead parameter is zero when ReadFile returns TRUE on a pipe,
the other end of the pipe called the WriteFile function with nNumberOfBytesToWrite set to zero.

For more information about pipes, see Pipes.

Transacted Operations

If there is a transaction bound to the file handle,
then the function returns data from the transacted view of the file.
A transacted read handle is guaranteed to show the same view of a file for the duration of the handle.
For more information, see About Transactional NTFS.


WriteFile Function *************************************************************

Writes data to the specified file or input/output (I/O) device.

This function is designed for both synchronous and asynchronous operation.
For a similar function designed solely for asynchronous operation, see WriteFileEx.

Syntax

Copy
BOOL WINAPI WriteFile(
__in HANDLE hFile,
__in LPCVOID lpBuffer,
__in DWORD nNumberOfBytesToWrite,
__out_opt LPDWORD lpNumberOfBytesWritten,
__inout_opt LPOVERLAPPED lpOverlapped
);

hFile [in]
A handle to the file or I/O device (for example, a file, file stream,
physical disk, volume, console buffer, tape drive, socket,
communications resource, mailslot, or pipe).

The hFile parameter must have been created with the write access.
For more information, see Generic Access Rights and File Security and Access Rights.

For asynchronous write operations,
hFile can be any handle opened with the CreateFile function using the FILE_FLAG_OVERLAPPED flag
or a socket handle returned by the socket or accept function.

lpBuffer [in]
A pointer to the buffer containing the data to be written to the file or device.

This buffer must remain valid for the duration of the write operation.
The caller must not use this buffer until the write operation is completed.

nNumberOfBytesToWrite [in]
The number of bytes to be written to the file or device.

A value of zero specifies a null write operation. ZLP for usb ???
The behavior of a null write operation depends on the underlying file system or communications technology.

Pipe write operations across a network are limited to 65,535 bytes per write.
For more information regarding pipes, see the Remarks section.

lpNumberOfBytesWritten [out, optional]
A pointer to the variable that receives the number of bytes written when using a synchronous hFile parameter.
WriteFile sets this value to zero before doing any work or error checking.
Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.

This parameter can be NULL only when the lpOverlapped parameter is not NULL.

For more information, see the Remarks section.

lpOverlapped [in, out, optional]
A pointer to an OVERLAPPED structure is required if the hFile parameter
was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL.

For an hFile that supports byte offsets,
if you use this parameter you must specify a byte offset at which
to start writing to the file or device.
This offset is specified by setting the Offset and OffsetHigh members of the OVERLAPPED structure.
For an hFile that does not support byte offsets, Offset and OffsetHigh are ignored.

To write to the end of file, specify both the Offset and OffsetHigh members of the OVERLAPPED structure as 0xFFFFFFFF.
This is functionally equivalent to previously calling the CreateFile function to open hFile using FILE_APPEND_DATA access.

For more information about different combinations of lpOverlapped and FILE_FLAG_OVERLAPPED,
see the Remarks section and the Synchronization and File Position section.

Return Value

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, or is completing asynchronously, the return value is zero (FALSE).
To get extended error information, call the GetLastError function.

Note The GetLastError code ERROR_IO_PENDING is not a failure;
it designates the write operation is pending completion asynchronously.
For more information, see Remarks.

Remarks

The WriteFile function returns when one of the following conditions occur:

The number of bytes requested is written.
A read operation releases buffer space on the read end of the pipe (if the write was blocked).
For more information, see the Pipes section.
An asynchronous handle is being used and the write is occurring asynchronously.
An error occurs.
The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY
whenever there are too many outstanding asynchronous I/O requests.

To cancel all pending asynchronous I/O operations, use either:

CancelIo—this function cancels only operations issued by the calling thread for the specified file handle.
CancelIoEx—this function cancels all operations issued by the threads for the specified file handle.
Use the CancelSynchronousIo function to cancel pending synchronous I/O operations.

I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED.

The WriteFile function may fail with ERROR_NOT_ENOUGH_QUOTA,
which means the calling process's buffer could not be page-locked.
For more information, see SetProcessWorkingSetSize.

If part of the file is locked by another process
and the write operation overlaps the locked portion, WriteFile fails.

When writing to a file, the last write time is not fully updated
until all handles used for writing have been closed.
Therefore, to ensure an accurate last write time,
close the file handle immediately after writing to the file.

Accessing the output buffer while a write operation
is using the buffer may lead to corruption of the data written from that buffer.
Applications must not write to, reallocate,
or free the output buffer that a write operation is using until the write operation completes.
This can be particularly problematic when using an asynchronous file handle.
Additional information regarding synchronous versus asynchronous file handles
can be found later in the Synchronization and File Position section and Synchronous and Asynchronous I/O.

Note that the time stamps may not be updated correctly for a remote file.
To ensure consistent results, use unbuffered I/O.

The system interprets zero bytes to write as specifying a null write operation
and WriteFile does not truncate or extend the file. To truncate or extend a file,
use the SetEndOfFile function.

Characters can be written to the screen buffer using WriteFile with a handle to console output.
The exact behavior of the function is determined by the console mode.
The data is written to the current cursor position.
The cursor position is updated after the write operation.
For more information about console handles, see CreateFile.

When writing to a communications device,
the behavior of WriteFile is determined by the current communication time-out as set
and retrieved by using the SetCommTimeouts and GetCommTimeouts functions.
Unpredictable results can occur if you fail to set the time-out values.
For more information about communication time-outs, see COMMTIMEOUTS.

Although a single-sector write is atomic,
a multi-sector write is not guaranteed to be atomic unless you are using a transaction
(that is, the handle created is a transacted handle;
for example, a handle created using CreateFileTransacted).
Multi-sector writes that are cached may not always be written to the disk right away;
therefore, specify FILE_FLAG_WRITE_THROUGH in CreateFile
to ensure that an entire multi-sector write is written to the disk without potential caching delays.

If you write directly to a volume that has a mounted file system,
you must first obtain exclusive access to the volume. Otherwise,
you risk causing data corruption or system instability,
because your application's writes may conflict with other changes coming from the file system
and leave the contents of the volume in an inconsistent state.
To prevent these problems, the following changes have been made in Windows Vista and later:

A write on a volume handle will succeed if the volume does not have a mounted file system,
or if one of the following conditions is true:

The sectors to be written to are boot sectors.
The sectors to be written to reside outside of file system space.

You have explicitly locked or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.

The volume has no actual file system. (In other words, it has a RAW file system mounted.)
A write on a disk handle will succeed if one of the following conditions is true:
The sectors to be written to do not fall within a volume's extents.

The sectors to be written to fall within a mounted volume, but you have explicitly locked
or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.

The sectors to be written to fall within a volume that has no mounted file system other than RAW.
There are strict requirements for successfully working
with files opened with CreateFile using FILE_FLAG_NO_BUFFERING.
For details see File Buffering.

If hFile was opened with FILE_FLAG_OVERLAPPED, the following conditions are in effect:

The lpOverlapped parameter must point to a valid and unique OVERLAPPED structure,
otherwise the function can incorrectly report that the write operation is complete.
The lpNumberOfBytesWritten parameter should be set to NULL. To get the number of bytes written,
use the GetOverlappedResult function. If the hFile parameter is associated with an I/O completion port,
you can also get the number of bytes written by calling the GetQueuedCompletionStatus function.
Synchronization and File Position

If hFile is opened with FILE_FLAG_OVERLAPPED, it is an asynchronous file handle;
otherwise it is synchronous.
The rules for using the OVERLAPPED structure are slightly different for each,
as previously noted.

Note If a file or device is opened for asynchronous I/O,
subsequent calls to functions such as WriteFile using that handle generally return immediately,
but can also behave synchronously with respect to blocked execution.
For more information, see http://support.microsoft.com/kb/156932.

Considerations for working with asynchronous file handles:

WriteFile may return before the write operation is complete.
In this scenario, WriteFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING,
which allows the calling process to continue while the system completes the write operation.

The lpOverlapped parameter must not be NULL and should be used with the following facts in mind:
Although the event specified in the OVERLAPPED structure is set and reset automatically by the system,
the offset that is specified in the OVERLAPPED structure is not automatically updated.

WriteFile resets the event to a nonsignaled state when it begins the I/O operation.
The event specified in the OVERLAPPED structure is set to a signaled state
when the write operation is complete; until that time, the write operation is considered pending.

Because the write operation starts at the offset that is specified in the OVERLAPPED structure,
and WriteFile may return before the system-level write operation is complete (write pending),
neither the offset nor any other part of the structure should be modified, freed,
or reused by the application until the event is signaled (that is, the write completes).
Considerations for working with synchronous file handles:

If lpOverlapped is NULL,
the write operation starts at the current file position and WriteFile does not return
until the operation is complete, and the system updates the file pointer before WriteFile returns.

If lpOverlapped is not NULL,
the write operation starts at the offset that is specified in the OVERLAPPED structure
and WriteFile does not return until the write operation is complete.
The system updates the OVERLAPPED offset before WriteFile returns.
For more information, see CreateFile and Synchronous and Asynchronous I/O.

Pipes

If an anonymous pipe is being used and the read handle has been closed,
when WriteFile attempts to write using the pipe's corresponding write handle,
the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.

If the pipe buffer is full when an application uses the WriteFile function to write to a pipe,
the write operation may not finish immediately.
The write operation will be completed when a read operation (using the ReadFile function)
makes more system buffer space available for the pipe.

When writing to a non-blocking, byte-mode pipe handle with insufficient buffer space,
WriteFile returns TRUE with *lpNumberOfBytesWritten < nNumberOfBytesToWrite.

For more information about pipes, see Pipes.

Transacted Operations

If there is a transaction bound to the file handle, then the file write is transacted.
For more information, see About Transactional NTFS.

 

posted @ 2013-05-30 21:20  IAmAProgrammer  阅读(2302)  评论(0编辑  收藏  举报