| Previous | Main | Next | Site Index | Download | Disclaimer | Privacy |


 

 

 

 

 

WINDOWS THREAD SYNCHRONIZATION REFERENCES 2

 

 

 

 

 

 

 

The Windows Process, thread and synchronization: Functions, structures and other related items used in program examples of Windows Process, Thread & Synchronization 1, Windows Process, Thread & Synchronization 2, Windows Process, Thread & Synchronization 3, Windows Process, Thread & Synchronization 4, Windows Process, Thread & Synchronization 5 and Windows Process, Thread & Synchronization 6, wherever applicable. To learn about function you can jump to C & C++ function tutorials.

 

The Page Index:

  1. GetEnvironmentStrings()

  2. GetEnvironmentVariable()

  3. SetEnvironmentVariable()

  4. GetEnvironmentStrings()

  5. FreeEnvironmentStrings()

  6. CreateWaitableTimer()

  7. GetStdHandle()

  8. CreatePipe()

  9. DuplicateHandle()

  10. GetCurrentProcess()

  11. CreateFile()

  12. ReadFile()

 

 

GetEnvironmentStrings()

 

Item

Description

Function

GetEnvironmentStrings().

Use

Retrieves the environment variables for the current process.

Prototype

LPVOID GetEnvironmentStrings(void);

Parameters

This function has no parameters.

Return value

If the function succeeds, the return value is a pointer to the environment block of the current process.  If the function fails, the return value is NULL.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  The GetEnvironmentStrings() function returns a pointer to a block of memory that contains the environment variables of the calling process. Treat this memory as read-only; do not modify it directly. To add or change an environment variable, use the GetEnvironmentVariable() and SetEnvironmentVariable() functions. When the block returned by GetEnvironmentStrings() is no longer needed, it should be freed by calling the FreeEnvironmentStrings() function. Windows Me/98/95:   GetEnvironmentStringsW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

Table 1.

 

 

 

 

 

 

 

 

 

 

 

 

 

GetEnvironmentVariable()

 

Item

Description

Function

GetEnvironmentVariable().

Use

Retrieves the contents of the specified variable from the environment block of the calling process. The contents are in the form of a null-terminated string of characters.

Prototype

DWORD GetEnvironmentVariable( LPCTSTR lpName, LPTSTR lpBuffer, DWORD nSize );

Parameters

lpName - [in] Pointer to a null-terminated string that specifies the name of the environment variable.

lpBuffer - [out] Pointer to a buffer that receives the contents of the specified environment variable. An environment variable has a maximum size limit of 32,767 characters, including the null-terminating character.

nSize - [in] Size of the buffer pointed to by the lpBuffer parameter, in bytes.

Return value

If the function succeeds, the return value is the number of bytes stored in the buffer pointed to by lpBuffer, not including the terminating null character.  If lpBuffer is not large enough to hold the data, the return value is the buffer size, in bytes, required to hold the value string and its terminating null character.  If the function fails, the return value is zero. If the specified environment variable was not found in the environment block, GetLastError() returns ERROR_ENVVAR_NOT_FOUND.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  Windows Me/98/95:  GetEnvironmentVariableW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

Table 2.

 

SetEnvironmentVariable()

 

Item

Description

Function

SetEnvironmentVariable().

Use

Sets the contents of the specified environment variable for the current process.

Prototype

BOOL SetEnvironmentVariable(LPCTSTR lpName, LPCTSTR lpValue);

Parameters

lpName - [in] Pointer to a null-terminated string that specifies the name of the environment variable. The operating system creates the environment variable if it does not exist and lpValue is not NULL.

lpValue - [in] Pointer to a null-terminated string that specifies the contents of the environment variable. An environment variable has a maximum size limit of 32,767 characters, including the trailing null terminator.  If this parameter is NULL, the variable is deleted from the current process's environment.

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().

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode. This function has no effect on the system environment variables or the environment variables of other processes. Windows Me/98/95:   SetEnvironmentVariableW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

Table 3.

 

GetEnvironmentStrings()

 

Item

Description

Function

GetEnvironmentStrings().

Use

Retrieves the environment variables for the current process.

Prototype

LPVOID GetEnvironmentStrings(void);

Parameters

This function has no parameters.

Return value

If the function succeeds, the return value is a pointer to the environment block of the current process.  If the function fails, the return value is NULL.

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  The GetEnvironmentStrings() function returns a pointer to a block of memory that contains the environment variables of the calling process. Treat this memory as read-only; do not modify it directly. To add or change an environment variable, use the GetEnvironmentVariable() and SetEnvironmentVariable() functions.

When the block returned by GetEnvironmentStrings() is no longer needed, it should be freed by calling the FreeEnvironmentStrings() function.

Windows Me/98/95:   GetEnvironmentStringsW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

Table 4.

 

FreeEnvironmentStrings()

 

Item

Description

Function

FreeEnvironmentStrings().

Use

Frees a block of environment strings.

Prototype

BOOL FreeEnvironmentStrings(LPTSTR lpszEnvironmentBlock);

Parameters

lpszEnvironmentBlock - [in] Pointer to a block of environment strings. The pointer to the block must be obtained by calling the GetEnvironmentStrings() function.

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().

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode. Windows Me/98/95:  FreeEnvironmentStringsW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

Table 5.

 

CreateWaitableTimer()

 

Item

Description

Function

CreateWaitableTimer().

Use

Creates or opens a waitable timer object.

Prototype

HANDLE CreateWaitableTimer( LPSECURITY_ATTRIBUTES lpTimerAttributes, BOOL bManualReset, LPCTSTR lpTimerName );

Parameters

See below.

Return value

If the function succeeds, the return value is a handle to the timer object. If the named timer object exists 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().

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  More remarks below.

 

Table 6.

 

Parameters

 

lpTimerAttributes - [in] Pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new timer object and determines whether child processes can inherit the returned handle. If lpTimerAttributes is NULL, the timer object gets a default security descriptor and the handle cannot be inherited. The ACLs in the default security descriptor for a timer come from the primary or impersonation token of the creator. bManualReset - [in] If this parameter is TRUE, the timer is a manual-reset notification timer. Otherwise, the timer is a synchronization timer. lpTimerName - [in] Pointer to a null-terminated string specifying the name of the timer object. The name is limited to MAX_PATH characters. Name comparison is case sensitive. If lpTimerName is NULL, the timer object is created without a name. If lpTimerName matches the name of an existing event, semaphore, mutex, job, or file-mapping object, the function fails and GetLastError() returns ERROR_INVALID_HANDLE. This occurs because these objects share the same name space. Terminal Services:  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 (\).

Windows XP Home Edition:  Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. 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. Windows NT:  The name can contain any character except the backslash character. Windows 98/Me:  The name can contain any character except the backslash character. The empty string ("") is a valid object name.

 

Some Remarks

 

The handle returned by CreateWaitableTimer() is created with the TIMER_ALL_ACCESS access right. This handle can be used in any function that requires a handle to a timer object.  Any thread of the calling process can specify the timer object handle in a call to one of the wait functions.  Multiple processes can have handles to the same timer object, enabling use of the object for interprocess synchronization.

  1. A process created by the CreateProcess() function can inherit a handle to a timer object if the lpTimerAttributes parameter of CreateWaitableTimer() enables inheritance.

  2. A process can specify the timer object handle in a call to the DuplicateHandle() function. The resulting handle can be used by another process.

  3. A process can specify the name of a timer object in a call to the OpenWaitableTimer() or CreateWaitableTimer() function.

 

Use the CloseHandle() function to close the handle. The system closes the handle automatically when the process terminates. The timer object is destroyed when its last handle has been closed. Windows Me/98:  CreateWaitableTimerW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows Me/98/95 Systems.

 

GetStdHandle()

 

Item

Description

Function

GetStdHandle().

Use

Retrieves a handle for the standard input, standard output, or standard error device.

Prototype

HANDLE GetStdHandle(DWORD nStdHandle);

Parameters

See below.

Return value

If the function succeeds, the return value is a handle to the specified device, or a redirected handle set by a previous call to SetStdHandle(). The handle has GENERIC_READ and GENERIC_WRITE access rights, unless the application has used SetStdHandle() to set a standard handle with lesser access.  If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError(). If an application does not have associated standard handles, such as a service running on an interactive desktop, and has not redirected them, the return value is NULL.

Include file

<windows.h>

Remark

Handles returned by GetStdHandle() can be used by applications that need to read from or write to the console. When a console is created, the standard input handle is a handle to the console's input buffer, and the standard output and standard error handles are handles of the console's active screen buffer. These handles can be used by the ReadFile() and WriteFile() functions, or by any of the console functions that access the console input buffer or a screen buffer (for example, the ReadConsoleInput(), WriteConsole(), or GetConsoleScreenBufferInfo() functions).

The standard handles of a process may be redirected by a call to SetStdHandle(), in which case GetStdHandle() returns the redirected handle. If the standard handles have been redirected, you can specify the CONIN$ value in a call to the CreateFile() function to get a handle to a console's input buffer. Similarly, you can specify the CONOUT$ value to get a handle to a console's active screen buffer.

 

Table 7.

 

Parameters

 

nStdHandle - [in] Standard device for which a handle is to be returned. This parameter can be one of the following values.

 

Value

Meaning

STD_INPUT_HANDLE

Handle to the standard input device. Initially, this is a handle to the console input buffer, CONIN$.

STD_OUTPUT_HANDLE

Handle to the standard output device. Initially, this is a handle to the active console screen buffer, CONOUT$.

STD_ERROR_HANDLE

Handle to the standard error device. Initially, this is a handle to the active console screen buffer, CONOUT$.

 

Table 8

 

CreatePipe()

 

Item

Description

Function

CreatePipe().

Use

Creates an anonymous pipe, and returns handles to the read and write ends of the pipe.

Prototype

BOOL CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize);

Parameters

hReadPipe - [out] Pointer to a variable that receives the read handle for the pipe.

hWritePipe - [out] Pointer to a variable that receives the write handle for the pipe.

lpPipeAttributes - [in] Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpPipeAttributes is NULL, the handle cannot be inherited. The lpSecurityDescriptor member of the structure specifies a security descriptor for the new pipe. If lpPipeAttributes is NULL, the pipe gets a default security descriptor. The ACLs in the default security descriptor for a pipe come from the primary or impersonation token of the creator.

nSize - [in] Size of the buffer for the pipe, in bytes. The size is only a suggestion; the system uses the value to calculate an appropriate buffering mechanism. If this parameter is zero, the system uses the default buffer size.

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().

Include file

<windows.h>

Remark

CreatePipe() creates the pipe, assigning the specified pipe size to the storage buffer. CreatePipe() also creates handles that the process uses to read from and write to the buffer in subsequent calls to the ReadFile() and WriteFile() functions. To read from the pipe, a process uses the read handle in a call to the ReadFile() function. ReadFile() returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs. When a process uses WriteFile() to write to an anonymous pipe, the write operation is not completed until all bytes are written. If the pipe buffer is full before all bytes are written, WriteFile() does not return until another process or thread uses ReadFile() to make more buffer space available.

Anonymous pipes are implemented using a named pipe with a unique name. Therefore, you can often pass a handle to an anonymous pipe to a function that requires a handle to a named pipe.

 

Table 9.

 

DuplicateHandle()

 

Item

Description

Function

DuplicateHandle().

Use

Duplicates an object handle.

Prototype

BOOL DuplicateHandle( HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, LPHANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions );

Parameters

See below.

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().

Include file

<windows.h>

Remark

See below.

 

Table 10.

 

Parameters

 

hSourceProcessHandle - [in] Handle to the process with the handle to duplicate. The handle must have the PROCESS_DUP_HANDLE access right.

hSourceHandle - [in] Handle to duplicate. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles can be duplicated, see the following Remarks section.

hTargetProcessHandle - [in] Handle to the process that is to receive the duplicated handle. The handle must have the PROCESS_DUP_HANDLE access right.

lpTargetHandle - [out] Pointer to a variable that receives the duplicate handle. This handle value is valid in the context of the target process. If hSourceHandle is a pseudo handle returned by GetCurrentProcess() or GetCurrentThread(), DuplicateHandle() converts it to a real handle to a process or thread, respectively. If lpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the caller. This behavior exists only for backward compatibility with previous versions of this function. You should not use this feature, as you will lose system resources until the target process terminates.

dwDesiredAccess - [in] Access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section. This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on the type of object whose handle is to be duplicated.

bInheritHandle - [in] Indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the target process. If FALSE, the new handle cannot be inherited.  

dwOptions - [in] Optional actions. This parameter can be zero, or any combination of the following values.

 

Value

Meaning

DUPLICATE_CLOSE_SOURCE

Closes the source handle. This occurs regardless of any error status returned.

DUPLICATE_SAME_ACCESS

Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.

 

Table 11

 

Some Remarks

 

The duplicate handle refers to the same object as the original handle. Therefore, any changes to the object are reflected through both handles. For example, the current file mark for a file handle is always the same for both handles. DuplicateHandle() can be called by either the source process or the target process (or a process that is both the source and target process). For example, a process can use DuplicateHandle() to create a non-inheritable duplicate of an inheritable handle, or a handle with different access than the original handle. The source process uses the GetCurrentProcess() function to get a handle to itself. This handle is a pseudo handle, but DuplicateHandle() converts it to a real process handle. To get the target process handle, it may be necessary to use some form of interprocess communication (for example, a named pipe or shared memory) to communicate the process identifier to the source process. The source process can use this identifier in the OpenProcess() function to obtain a handle to the target process. If the process that calls DuplicateHandle() is not also the target process, the source process must use interprocess communication to pass the value of the duplicate handle to the target process. DuplicateHandle() can duplicate handles to the following types of objects.

 

Object

Description

Access token

The handle is returned by the CreateRestrictedToken(), DuplicateToken(), DuplicateTokenEx(), OpenProcessToken(), or OpenThreadToken() function.

Change notification

The handle is returned by the FindFirstChangeNotification() function.

Communications device

The handle is returned by the CreateFile() function.

Console input

The handle is returned by the CreateFile() function when CONIN$ is specified, or by the GetStdHandle() function when STD_INPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.

Console screen buffer

The handle is returned by the CreateFile() function when CONOUT$ is specified, or by the GetStdHandle() function when STD_OUTPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.

Desktop

The handle is returned by the GetThreadDesktop() function.

Event

The handle is returned by the CreateEvent() or OpenEvent() function.

File

The handle is returned by the CreateFile() function.

File mapping

The handle is returned by the CreateFileMapping() function.

Job

The handle is returned by the CreateJobObject() function.

Mailslot

The handle is returned by the CreateMailslot() function.

Mutex

The handle is returned by the CreateMutex() or OpenMutex() function.

Pipe

A named pipe handle is returned by the CreateNamedPipe() or CreateFile() function. An anonymous pipe handle is returned by the CreatePipe() function.

Process

The handle is returned by the CreateProcess(), GetCurrentProcess(), or OpenProcess() function.

Registry key

The handle is returned by the RegCreateKey(), RegCreateKeyEx(), RegOpenKey(), or RegOpenKeyEx() function. Note that registry key handles returned by the RegConnectRegistry() function cannot be used in a call to DuplicateHandle().

Windows Me/98/95:  You cannot use DuplicateHandle to duplicate registry key handles.

Semaphore

The handle is returned by the CreateSemaphore() or OpenSemaphore() function.

Socket

The handle is returned by the socket or accept function.

Thread

The handle is returned by the CreateProcess(), CreateThread(), CreateRemoteThread(), or GetCurrentThread() function

Timer

The handle is returned by the CreateWaitableTimer() or OpenWaitableTimer() function.

Window station

The handle is returned by the GetProcessWindowStation() function.

 

Table 12

 

Note that DuplicateHandle() should not be used to duplicate handles to I/O completion ports. In this case, no error is returned, but the duplicate handle cannot be used.  In addition to STANDARD_RIGHTS_REQUIRED, the following access rights can be specified in the dwDesiredAccess parameter for the different object types:

  1. Desktop Security and Access Rights.

  2. File Security and Access Rights.

  3. File-Mapping Security and Access Rights.

  4. Job Object Security and Access Rights.

  5. Process Security and Access Rights.

  6. Registry Key Security and Access Rights.

  7. Synchronization Object Security and Access Rights.

  8. Thread Security and Access Rights.

  9. Window-Station Security and Access Rights.

 

In some cases, the new handle can have more access rights than the original handle. However, in other cases, DuplicateHandle() cannot create a handle with more access rights than the original. For example, a file handle created with the GENERIC_READ access right cannot be duplicated so that it has both the GENERIC_READ and GENERIC_WRITE access right.

 

GetCurrentProcess()

 

Item

Description

Function

GetCurrentProcess().

Use

Retrieves a pseudo handle for the current process.

Prototype

HANDLE GetCurrentProcess(void);

Parameters

This function has no parameters.

Return value

The return value is a pseudo handle to the current process.

Include file

<windows.h>

Remark

A pseudo handle is a special constant, currently (HANDLE)-1, that is interpreted as the current process handle. For compatibility with future operating systems, it is best to call GetCurrentProcess() instead of hard-coding this constant value. The calling process can use a pseudo handle to specify its own process whenever a process handle is required. Pseudo handles are not inherited by child processes.

This handle has the maximum possible access to the process object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is PROCESS_ALL_ACCESS.

A process can create a "real" handle to itself that is valid in the context of other processes, or that can be inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle() function. A process can also use the OpenProcess() function to open a real handle to itself.

The pseudo handle need not be closed when it is no longer needed. Calling the CloseHandle() function with a pseudo handle has no effect. If the pseudo handle is duplicated by DuplicateHandle(), the duplicate handle must be closed.

 

Table 13.

 

CreateFile()

 

Item

Description

Function

CreateFile().

Use

Creates or opens a file, directory, physical disk, volume, console buffer, tape drive, communications resource, mailslot, or named pipe. The function returns a handle that can be used to access the object.

Windows Me/98/95:   The file system restricts CreateFile() to creating or opening files; you cannot create or open the other objects mentioned above.

Prototype

HANDLE CreateFile( LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );

Parameters

See below.

Return value

If the function succeeds, the return value is an open handle to the specified file. If the specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError() returns ERROR_ALREADY_EXISTS (even though the function has succeeded). If the file does not exist before the call, GetLastError() returns zero.  If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError().

Include file

<windows.h>

Remark

Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.  More remarks below.

 

Table 14.

 

Parameters

 

lpFileName - [in] Pointer to a null-terminated string that specifies the name of the object to create or open.

In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. Windows Me/98/95:  This string must not exceed MAX_PATH characters.

dwDesiredAccess - [in] Access to the object (reading, writing, or both). You cannot request an access mode that conflicts with the sharing mode specified in a previous open request whose handle is still open. If this parameter is zero, the application can query file and device attributes without accessing the device. This is useful if an application wants to determine the size of a floppy disk drive and the formats it supports without requiring a floppy in the drive. It can also be used to test for the file's or directory's existence without opening it for read or write access.

dwShareMode - [in] Sharing mode of the object (reading, writing, both, or neither). You cannot request a sharing mode that conflicts with the access mode specified in a previous open request whose handle is still open. Doing so would result in a sharing violation (ERROR_SHARING_VIOLATION). If this parameter is zero and CreateFile succeeds, the object cannot be shared and cannot be opened again until the handle is closed. To enable other processes to share the object while your process has it open, use a combination of one or more of the following values to specify the access mode they can request when they open the object. These sharing options remain in effect until you close the handle to the object.

 

Value

Meaning

FILE_SHARE_DELETE

Enables subsequent open operations on the object to request delete access. Otherwise, other processes cannot open the object if they request delete access.  For Windows Me/98/95:  This flag is not supported.

FILE_SHARE_READ

Enables subsequent open operations on the object to request read access. Otherwise, other processes cannot open the object if they request read access.

FILE_SHARE_WRITE

Enables subsequent open operations on the object to request write access. Otherwise, other processes cannot open the object if they request write access.

 

Table 15

 

lpSecurityAttributes - [in] Pointer to a SECURITY_ATTRIBUTES structure that determines whether the returned handle can be inherited by child processes. If lpSecurityAttributes is NULL, the handle cannot be inherited. The lpSecurityDescriptor member of the structure specifies a security descriptor for the object. If lpSecurityAttributes is NULL, the object gets a default security descriptor. The ACLs in the default security descriptor for a file or directory are inherited from its parent directory. Note that the target file system must support security on files and directories for this parameter to have an effect on them. (This is indicated when GetVolumeInformation() returns FS_PERSISTENT_ACLS). CreateFile() ignores lpSecurityDescriptor when opening an existing file, but continues to use the other structure members.

dwCreationDisposition - [in] Action to take on files that exist, and which action to take when files do not exist. For more information about this parameter, see the Remarks section. This parameter must be one of the following values.

 

Value

Meaning

CREATE_ALWAYS

Creates a new file. If the file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor specified by the SECURITY_ATTRIBUTES structure.

CREATE_NEW

Creates a new file. The function fails if the specified file already exists.

OPEN_ALWAYS

Opens the file, if it exists. If the file does not exist, the function creates the file as if dwCreationDisposition were CREATE_NEW.

OPEN_EXISTING

Opens the file. The function fails if the file does not exist.

For a discussion of why you should use OPEN_EXISTING for devices, see Remarks.

TRUNCATE_EXISTING

Opens the file and truncates it so that its size is zero bytes. The calling process must open the file with the GENERIC_WRITE access right. The function fails if the file does not exist.

 

Table 16

 

dwFlagsAndAttributes - [in] File attributes and flags. The following file attributes and flags are used only for file objects, not other types of objects created by CreateFile(). When CreateFile() opens an existing file, it combines the file flags with existing file attributes, and ignores any supplied file attributes.  This parameter can include any combination of the file attributes (noting that all other file attributes override FILE_ATTRIBUTE_NORMAL).

 

Attribute

Meaning

FILE_ATTRIBUTE_ARCHIVE

The file should be archived. Applications use this attribute to mark files for backup or removal.

FILE_ATTRIBUTE_ENCRYPTED

The file or directory is encrypted. For a file, this means that all data in the file is encrypted. For a directory, this means that encryption is the default for newly created files and subdirectories.  This flag has no effect if FILE_ATTRIBUTE_SYSTEM is also specified.

FILE_ATTRIBUTE_HIDDEN

The file is hidden. It is not to be included in an ordinary directory listing.

FILE_ATTRIBUTE_NORMAL

The file has no other attributes set. This attribute is valid only if used alone.

FILE_ATTRIBUTE_NOT_CONTENT_INDEXED

The file will not be indexed by the content indexing service.

FILE_ATTRIBUTE_OFFLINE

The data of the file is not immediately available. This attribute indicates that the file data has been physically moved to offline storage. This attribute is used by Remote Storage, the hierarchical storage management software. Applications should not arbitrarily change this attribute.

FILE_ATTRIBUTE_READONLY

The file is read only. Applications can read the file but cannot write to it or delete it.

FILE_ATTRIBUTE_SYSTEM

The file is part of or is used exclusively by the operating system.

FILE_ATTRIBUTE_TEMPORARY

The file is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because often the application deletes the temporary file shortly after the handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data will be written after the handle is closed.

 

Table 17

 

This parameter can also include any combination of the following flags.

 

Flag

Meaning

FILE_FLAG_BACKUP_SEMANTICS

The file is being opened or created for a backup or restore operation. The system ensures that the calling process overrides file security checks, provided it has the SE_BACKUP_NAME and SE_RESTORE_NAME privileges.

You can also set this flag to obtain a handle to a directory. Where indicated, a directory handle can be passed to some functions in place of a file handle.

Windows Me/98/95:  This flag is not supported.

FILE_FLAG_DELETE_ON_CLOSE

The system is to delete the file immediately after all of its handles have been closed, not just the specified handle but also any other open or duplicated handles.

If there are existing open handles to the file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode.

Subsequent open requests for the file will fail, unless they specify the FILE_SHARE_DELETE share mode.

FILE_FLAG_NO_BUFFERING

The system is to open the file with no system caching. This flag has no effect on hard disk caching. When combined with FILE_FLAG_OVERLAPPED, the flag gives maximum asynchronous performance, because the I/O does not rely on the synchronous operations of the memory manager. However, some I/O operations will take longer, because data is not being held in the cache. Also, the file metadata may still be cached. To flush the metadata to disk, use the FlushFileBuffers() function.

An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

File access must begin at byte offsets within the file that are integer multiples of the volume's sector size.

File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.

Buffer addresses for read and write operations should be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). Depending on the disk, this requirement may not be enforced.

One way to align buffers on integer multiples of the volume sector size is to use VirtualAlloc() to allocate the buffers. It allocates memory that is aligned on addresses that are integer multiples of the operating system's memory page size. Because both memory page and volume sector sizes are powers of 2, this memory is also aligned on addresses that are integer multiples of a volume's sector size.

An application can determine a volume's sector size by calling the GetDiskFreeSpace() function.

FILE_FLAG_OPEN_NO_RECALL

The file data is requested, but it should continue to reside in remote storage. It should not be transported back to local storage. This flag is intended for use by remote storage systems.

FILE_FLAG_OPEN_REPARSE_POINT

The system is to inhibit the reparse behavior of NTFS reparse points. When the file is opened, a file handle is returned, whether the filter that controls the reparse point is operational or not. This flag cannot be used with the CREATE_ALWAYS flag.

FILE_FLAG_OVERLAPPED

The file is being opened or created for asynchronous I/O. When the operation is finished, the event specified to the call in the OVERLAPPED structure is set to the signaled state. Operations that take a significant amount of time to process return ERROR_IO_PENDING.

If this flag is specified, the file can be used for simultaneous read and write operations. The system does not maintain the file pointer; therefore you must pass the file position to the read and write functions in the OVERLAPPED structure or update the file pointer.

If this flag is not specified, then I/O operations are serialized, even if the calls to the read and write functions specify an OVERLAPPED structure.

FILE_FLAG_POSIX_SEMANTICS

Indicates that the file is to be accessed according to POSIX rules. This includes allowing multiple files with names, differing only in case, for file systems that support such naming. Use care when using this option because files created with this flag may not be accessible by applications written for MS-DOS or 16-bit Windows.

FILE_FLAG_RANDOM_ACCESS

Indicates that the file is accessed randomly. The system can use this as a hint to optimize file caching.

FILE_FLAG_SEQUENTIAL_SCAN

Indicates that the file is to be accessed sequentially from beginning to end. The system can use this as a hint to optimize file caching. If an application moves the file pointer for random access, optimum caching may not occur; however, correct operation is still guaranteed.

Specifying this flag can increase performance for applications that read large files using sequential access. Performance gains can be even more noticeable for applications that read large files mostly sequentially, but occasionally skip over small ranges of bytes.

FILE_FLAG_WRITE_THROUGH

Instructs the system to write through any intermediate cache and go directly to disk.

If FILE_FLAG_NO_BUFFERING is not also specified, so that system caching is in effect, then the data is written to the system cache, but is flushed to disk without delay.

If FILE_FLAG_NO_BUFFERING is also specified, so that system caching is not in effect, then the data is immediately flushed to disk without going through the system cache. The operating system also requests a write-through the hard disk cache to persistent media. However, not all hardware supports this write-through capability.

 

Table 18

 

 

If the CreateFile() function opens the client side of a named pipe, the dwFlagsAndAttributes parameter can also contain Security Quality of Service information. When the calling application specifies the SECURITY_SQOS_PRESENT flag, the dwFlagsAndAttributes parameter can contain one or more of the following values.

 

Value

Meaning

SECURITY_ANONYMOUS

Impersonate the client at the Anonymous impersonation level.

SECURITY_CONTEXT_TRACKING

The security tracking mode is dynamic. If this flag is not specified, the security tracking mode is static.

SECURITY_DELEGATION

Impersonate the client at the Delegation impersonation level.

SECURITY_EFFECTIVE_ONLY

Only the enabled aspects of the client's security context are available to the server. If you do not specify this flag, all aspects of the client's security context are available.

This allows the client to limit the groups and privileges that a server can use while impersonating the client.

SECURITY_IDENTIFICATION

Impersonate the client at the Identification impersonation level.

SECURITY_IMPERSONATION

Impersonate the client at the Impersonation impersonation level.

 

Table 19

 

hTemplateFile - [in] Handle to a template file, with the GENERIC_READ access right. The template file supplies file attributes and extended attributes for the file being created. This parameter can be NULL. If opening an existing file, CreateFile() ignores the template file. Windows Me/98/95:  The hTemplateFile parameter must be NULL. If you supply a handle, the call fails and GetLastError() returns ERROR_NOT_SUPPORTED.

 

Some Remarks

 

Use the CloseHandle() function to close an object handle returned by CreateFile(). Windows Server 2003, Windows XP, Windows 2000:  A sharing violation will occur if an attempt is made to open a file or directory for deletion on a remote computer when the value of the dwDesiredAccess parameter is the DELETE access flag OR'ed with any other access flag, and the remote file or directory has not been opened with FILE_SHARE_DELETE. To avoid the sharing violation in this scenario, open the remote file or directory with the DELETE access right only or call DeleteFile() without first opening the file or directory for deletion. Some file systems, such as NTFS, support compression or encryption for individual files and directories. On volumes formatted for such a file system, a new file inherits the compression and encryption attributes of its directory. You cannot use CreateFile() to control compression on a file or directory.

Windows Server 2003, Windows XP, Windows 2000:  For backward compatibility purposes, CreateFile() does not apply inheritance rules when you specify a security descriptor in lpSecurityAttributes. To support inheritance, functions that later query the security descriptor of this object may heuristically determine and report that inheritance is in effect. For Windows Me/98/95:  CreateFileW() is supported by the Microsoft Layer for Unicode. To use this, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.

 

Files

 

If you are attempting to create a file on a floppy drive that does not have a floppy disk or a CD-ROM drive that does not have a CD, the system displays a message box asking the user to insert a disk or a CD, respectively. To prevent the system from displaying this message box, call the SetErrorMode() function with SEM_FAILCRITICALERRORS. Windows Server 2003, Windows XP, Windows 2000:  If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile() will fail and set the last error to ERROR_ACCESS_DENIED if the file exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM attribute. To avoid the error, specify the same attributes as the existing file.

If you rename or delete a file, then restore it shortly thereafter, the system searches the cache for file information to restore. Cached information includes its short/long name pair and creation time. Windows Me/98/95:  This remark does not apply. If you call CreateFile() on a file that is pending deletion as a result of a previous call to DeleteFile(), the function fails. The operating system delays file deletion until all handles to the file are closed. GetLastError() returns ERROR_ACCESS_DENIED. When an application creates a file across the network, it is better to use GENERIC_READ | GENERIC_WRITE than to use GENERIC_WRITE alone. The resulting code will be faster because the redirector can use the cache manager and send fewer SMBs with more data. This combination also avoids an issue where writing to the file across the network can occasionally return ERROR_ACCESS_DENIED.

 

Directories

 

An application cannot create a directory with CreateFile(); it must call CreateDirectory() or CreateDirectoryEx() to create a directory. Opening a directory with CreateFile() requires the FILE_FLAG_BACKUP_SEMANTICS flag. When using CreateFile() to open a directory during defragmentation of a FAT or FAT32 volume, do not specify the MAXIMUM_ALLOWED access right. Access to the directory will be denied if this is done. Specify the GENERIC_READ access right instead.

 

Physical Disks and Volumes

 

You can use the CreateFile() function to open a physical disk drive or a volume. The function returns a handle that can be used with the DeviceIoControl() function. This enables you to access the disk's partition table. It is potentially dangerous to do so, since an incorrect write to a disk could make its contents inaccessible. The following requirements must be met for such a call to succeed:

  1. The caller must have administrative privileges.

  2. The dwCreationDisposition parameter must have the OPEN_EXISTING flag.

  3. When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITE flag.

 

When opening a physical drive, x, the lpFileName string should be of the form: \\.\PHYSICALDRIVE<x>

Hard disk numbers start at zero. The following table shows some example physical drive strings.

 

String

Meaning

\\.\PHYSICALDRIVE0

Opens the first physical drive.

\\.\PHYSICALDRIVE2

Opens the third physical drive.

 

Table

 

When opening a volume or floppy drive, the lpFileName string should be of the form: \\.\<x>:

 

Do not use a trailing backslash. This would indicate the root directory of the drive. The following table shows some example drive strings.

 

String

Meaning

\\.\A:

Opens drive A (floppy drive).

\\.\C:

Opens drive C (volume).

 

Table 20

 

You can also open a volume by referring to its volume name.  Volume handles may be opened as non-cached at the discretion of the file system, even when the non-cached option is not specified with CreateFile(). You should assume that all Microsoft file systems open volume handles as non-cached. The restrictions on non-cached I/O for files apply to volumes as well. A file system may or may not require buffer alignment even though the data is non-cached. However, if the non-cached option is specified when opening a volume, buffer alignment is enforced regardless of the file system on the volume. It is recommended on all file systems that you open volume handles as non-cached and follow the non-cached I/O restrictions.

 

Tape Drives

 

You can open tape drives using a file name of the form:  \\.\TAPE<x>. Where <x> is a number indicating which drive to open, starting with tape drive 0. To open tape drive 0 in an application written in C or C++, use the file name "\\\\.\\TAPE0". For Windows Me/98/95:  Opening tape drives is not supported.

 

Communications Resources

 

The CreateFile() function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, and the hTemplate parameter must be NULL. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O.

 

Consoles

 

The CreateFile() function can create a handle to console input (CONIN$). If the process has an open handle to it as a result of inheritance or duplication, it can also create a handle to the active screen buffer (CONOUT$). The calling process must be attached to an inherited console or one allocated by the AllocConsole() function. For console handles, set the CreateFile() parameters as follows.

 

Parameters

Value

lpFileName

Use the CONIN$ value to specify console input and the CONOUT$ value to specify console output.  CONIN$ gets a handle to the console's input buffer, even if the SetStdHandle() function redirected the standard input handle. To get the standard input handle, use the GetStdHandle() function.  CONOUT$ gets a handle to the active screen buffer, even if SetStdHandle() redirected the standard output handle. To get the standard output handle, use GetStdHandle().

dwDesiredAccess

GENERIC_READ | GENERIC_WRITE is preferred, but either one can limit access.

dwShareMode

When opening CONIN$, be sure to specify FILE_SHARE_READ. When opening CONOUT$, be sure to specify FILE_SHARE_WRITE.

If the calling process inherited the console or if a child process should be able to access the console, this parameter must be FILE_SHARE_READ | FILE_SHARE_WRITE.

lpSecurityAttributes

If you want the console to be inherited, the bInheritHandle member of the SECURITY_ATTRIBUTES structure must be TRUE.

dwCreationDisposition

You should specify OPEN_EXISTING when using CreateFile() to open the console.

dwFlagsAndAttributes

Ignored.

hTemplateFile

Ignored.

 

Table 21

 

The following list shows the effects of various settings of dwDesiredAccess and lpFileName.

 

lpFileName

dwDesiredAccess

Result

CON

GENERIC_READ

Opens console for input.

CON

GENERIC_WRITE

Opens console for output.

CON

GENERIC_READ GENERIC_WRITE

Causes CreateFile() to fail; GetLastError() returns ERROR_FILE_NOT_FOUND. For Windows Me/98/95:  Causes CreateFile() to fail; GetLastError() returns ERROR_PATH_NOT_FOUND.

 

Table 22

 

Mailslots

 

If CreateFile() opens the client end of a mailslot, the function returns INVALID_HANDLE_VALUE if the mailslot client attempts to open a local mailslot before the mailslot server has created it with the CreateMailSlot() function.

 

Pipes

 

If CreateFile() opens the client end of a named pipe, the function uses any instance of the named pipe that is in the listening state. The opening process can duplicate the handle as many times as required but, once opened, the named pipe instance cannot be opened by another client. The access specified when a pipe is opened must be compatible with the access specified in the dwOpenMode parameter of the CreateNamedPipe() function.

 

ReadFile()

 

Item

Description

Function

ReadFile().

Use

Reads data from a file, starting at the position indicated by the file pointer. This function is designed for both synchronous and asynchronous operation.  The ReadFileEx() function is designed solely for asynchronous operation.

Prototype

BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped );

Parameters

See below.

Return value

The ReadFile() function returns when one of the following conditions is met: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs. 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().  If the return value is nonzero and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation. However, if the file was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is zero and GetLastError() returns ERROR_HANDLE_EOF when the file pointer goes beyond the current end of file.

Include file

<windows.h>

Remark

See below.

 

Table 23.

 

Parameters

 

hFile - [in] Handle to the file to be read. The file handle must have been created with the GENERIC_READ access right.

For asynchronous read operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile() function, or a socket handle returned by the socket or accept function. Windows Me/98/95:  For asynchronous read operations, hFile can be a communications resource opened with the FILE_FLAG_OVERLAPPED flag by CreateFile(), or a socket handle returned by socket or accept. You cannot perform asynchronous read operations on mailslots, named pipes, or disk files.

lpBuffer - [out] Pointer to the buffer that receives the data read from the file.

nNumberOfBytesToRead - [in] Number of bytes to be read from the file.

lpNumberOfBytesRead - [out] Pointer to the variable that receives the number of bytes read. ReadFile() sets this value to zero before doing any work or error checking. If this parameter is zero when ReadFile() returns TRUE on a named pipe, the other end of the message-mode pipe called the WriteFile() function with nNumberOfBytesToWrite set to zero. If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL. If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult(). If hFile is associated with an I/O completion port, you can get the number of bytes read by calling GetQueuedCompletionStatus().

If I/O completion ports are used and you are using a callback routine to free the memory allocated to the OVERLAPPED structure pointed to by the lpOverlapped parameter, specify NULL as the value of this parameter to avoid a memory corruption problem during the de-allocation. This memory corruption problem will cause an invalid number of bytes to be returned in this parameter. For Windows Me/98/95:  This parameter cannot be NULL.

lpOverlapped - [in] Pointer to an OVERLAPPED structure. This structure is required if hFile was created with FILE_FLAG_OVERLAPPED.

If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile() may return before the read operation has been completed. In this case, ReadFile() returns FALSE and the GetLastError() function returns ERROR_IO_PENDING. This allows the calling process to continue while the read operation finishes. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation. The caller must adjust the position of the file pointer upon completion. If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile() does not return until the operation has been completed. The system updates the file pointer upon completion.

If hFile is not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure. ReadFile() does not return until the read operation has been completed. The system updates the file pointer upon completion. Windows 95/98/Me:  For operations on files, disks, pipes, or mailslots, this parameter must be NULL; a pointer to an OVERLAPPED structure causes the call to fail. However, you can perform overlapped I/O on serial and parallel ports.

 

Some Remarks

 

If part of the file is locked by another process and the read operation overlaps the locked portion, this function fails. An application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING:

  1. File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. To determine a volume's sector size, call the GetDiskFreeSpace() function.

  2. File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.

  3. Buffer addresses for read and write operations must be sector aligned (aligned on addresses in memory that are integer multiples of the volume's sector size). One way to sector align buffers is to use the VirtualAlloc() function to allocate the buffers. This function allocates memory that is aligned on addresses that are integer multiples of the system's page size. Because both page and volume sector sizes are powers of 2, memory aligned by multiples of the system's page size is also aligned by multiples of the volume's sector size.

 

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. 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. 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 may be read by a subsequent call to the ReadFile() or PeekNamedPipe() function. When reading from a communications device, the behavior of ReadFile() is governed by the current communication time-outs as set and retrieved using the SetCommTimeouts() and GetCommTimeouts() functions. Unpredictable results can occur if you fail to set the time-out values. If ReadFile() attempts to read from a mailslot whose buffer is too small, the function returns FALSE and GetLastError() returns ERROR_INSUFFICIENT_BUFFER. If the anonymous write pipe handle has been closed and ReadFile() attempts to read using the corresponding anonymous read pipe handle, the function returns FALSE and GetLastError() returns ERROR_BROKEN_PIPE. The ReadFile() function may fail and return ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests. The ReadFile() code to check for the end-of-file condition (eof) differs for synchronous and asynchronous read operations. When a synchronous read operation reaches the end of a file, ReadFile() returns TRUE and sets *lpNumberOfBytesRead to zero. The following sample code tests for end-of-file for a synchronous read operation:

// Attempt a synchronous read operation.

bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL) ;

// Check for end of file.

if (bResult &&  nBytesRead == 0, )

{

    // we're at the end of the file

}

An asynchronous read operation can encounter the end of a file during the initiating call to ReadFile(), or during subsequent asynchronous operation. If EOF is detected at ReadFile() time for an asynchronous read operation, ReadFile() returns FALSE and GetLastError() returns ERROR_HANDLE_EOF. If EOF is detected during subsequent asynchronous operation, the call to GetOverlappedResult() to obtain the results of that operation returns FALSE and GetLastError() returns ERROR_HANDLE_EOF. To cancel all pending asynchronous I/O operations, use the CancelIo() function. This function only cancels operations issued by the calling thread for the specified file handle. I/O operations that are canceled complete with the error ERROR_OPERATION_ABORTED. If you are attempting to read from a floppy drive that does not have a floppy disk, the system displays a message box prompting the user to retry the operation. To prevent the system from displaying this message box, call the SetErrorMode() function with SEM_NOOPENFILEERRORBOX.  The following sample code illustrates testing for end-of-file for an asynchronous read operation:

 

// set up overlapped structure fields

gOverLapped.Offset     = 0;

gOverLapped.OffsetHigh = 0;

gOverLapped.hEvent     = hEvent;

 

// attempt an asynchronous read operation

bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, &gOverlapped);

// if there was a problem, or the async. operation's still pending...

if (!bResult)

{

    // deal with the error code

    switch (dwError = GetLastError())

    {

        case ERROR_HANDLE_EOF:

        {

            // we have reached the end of the file  during the call to ReadFile code to handle that

        }

        case ERROR_IO_PENDING:

        {

            // asynchronous i/o is still in progress do something else for a while

            GoDoSomethingElse();

            // check on the results of the asynchronous read

            bResult = GetOverlappedResult(hFile, &gOverlapped, &nBytesRead, FALSE);

            // if there was a problem...

            if (!bResult)

            {

                // deal with the error code

                switch (dwError = GetLastError())

                {

                    case ERROR_HANDLE_EOF:

                    {

                        // we have reached the end of the file during asynchronous operation

                    }

                    // deal with other error cases

                }   // end switch (dwError = GetLastError())

              }

        } // end case

        // deal with other error cases

    } // end  switch (dwError = GetLastError())

 } // end if

 

 

---------------------------------------------------Part 4/5-----------------------------------------------------

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Microsoft Visual C++, online MSDN.

  2. Structure, enum, union and typedef story can be found in C struct, enum, typedef etc.

  3. For Multibytes, Unicode characters and Localization please refer to Unicode & Multibyte 1 (Story) and Unicode & Multibyte 2 (Implementation).

  4. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

 

 

| Previous | Main | Next | Site Index | Download | Disclaimer | Privacy |