test

test

2010年4月3日 星期六

CreateFile - 新建檔案

VB2008:
以下程式碼包含了GetSystemDirectory, CreateFile, WriteFile, CloseHandle四支Windows API
另,部份相關知識可參考MSDN:http://msdn.microsoft.com/zh-tw/library/w4byd5y4(VS.80).aspx
也可查閱PINVOKE.NET網站:http://www.pinvoke.net/index.aspx
Imports System.Runtime.InteropServices

Public Class Form1
'Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As Byte(), ByVal uSize As Integer) As Integer
'底下用法必須引用System.Runtime.InteropServices
_
Private Shared Function GetSystemDirectory(ByVal lpBuffer As Byte(), ByVal uSize As Integer) As Integer
End Function


'Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As EFileAccess, ByVal dwShareMode As EFileShare, ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As ECreationDisposition, ByVal dwFlagsAndAttributes As EFileAttributes, ByVal hTemplateFile As IntPtr) As IntPtr
_
Private Shared Function CreateFile(ByVal lpFileName As String, ByVal dwDesiredAccess As EFileAccess, ByVal dwShareMode As EFileShare, ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As ECreationDisposition, ByVal dwFlagsAndAttributes As EFileAttributes, ByVal hTemplateFile As IntPtr) As IntPtr
End Function


'Private Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As IntPtr, ByVal lpBuffer As String, ByVal nNumberOfBytesWritten As Integer, ByVal lpNumberOfBytesWritten As Integer, ByRef lpOverlapped As OVERLAPPED) As Boolean
_
Public Shared Function WriteFile(ByVal hFile As IntPtr, ByVal lpBuffer As String, ByVal nNumberOfBytesWritten As Integer, ByVal lpNumberOfBytesWritten As Integer, ByRef lpOverlapped As OVERLAPPED) As Boolean
End Function


'Public Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As IntPtr) As Boolean
_
Public Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
End Function


Private Structure LPSECURITY_ATTRIBUTE
Dim nLength As Integer
Dim lpSecurityDescription As Integer
Dim hInheritHandle As Integer
End Structure
Structure OVERLAPPED
Dim Internal As Integer
Dim InternalHigh As Integer
Dim offset As Integer
Dim OffsetHigh As Integer
Dim hEvent As Integer
End Structure


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim nMAX_PATH As Integer = 260
'Dim sSystemDir As String = Strings.StrDup(nMAX_PATH, " ")
Dim bSystemDir As Byte()
ReDim bSystemDir(nMAX_PATH)
'獲取系統目錄
Dim nStrLen As Integer = GetSystemDirectory(bSystemDir, nMAX_PATH)
'sSystemDir = Strings.Left(sSystemDir, nStrLen) '去除實際字串尾端由chr(0)起所截斷的部份
Dim sSystemDir As String = System.Text.Encoding.Default.GetString(bSystemDir)
sSystemDir = Strings.Left(sSystemDir, nStrLen) '去除實際字串尾端由chr(0)起所截斷的部份


'底下用到EFileAccess, EFileShare, ECreationDisposition, EFileAttributes 四組Enum
Dim hFile As Int32 = CreateFile("c:\systemroot.txt", EFileAccess.GENERIC_WRITE, EFileShare.FILE_SHARE_NONE, 0, ECreationDisposition.CREATE_ALWAYS, EFileAttributes.FILE_ATTRIBUTE_NORMAL, vbNull)
If hFile = -1 Then MsgBox("CreateFile錯誤, 可能檔案已存在. CreateFile之CreationDisposition參數若改用CREATE_ALWAYS則永遠都會建立之") : Exit Sub
If Not WriteFile(hFile, sSystemDir, Len(sSystemDir), 0, New OVERLAPPED) Then
MsgBox("Error Number:" & Err.LastDllError)
End If


CloseHandle(hFile)
MsgBox(sSystemDir & "---")
End Sub
End Class


Friend Enum EFileAccess As System.Int32
''
'' The following are masks for the predefined standard access types
''


DELETE = &H10000
READ_CONTROL = &H20000
WRITE_DAC = &H40000
WRITE_OWNER = &H80000
SYNCHRONIZE = &H100000


STANDARD_RIGHTS_REQUIRED = &HF0000
STANDARD_RIGHTS_READ = READ_CONTROL
STANDARD_RIGHTS_WRITE = READ_CONTROL
STANDARD_RIGHTS_EXECUTE = READ_CONTROL
STANDARD_RIGHTS_ALL = &H1F0000
SPECIFIC_RIGHTS_ALL = &HFFFF


''
'' AccessSystemAcl access type
''


ACCESS_SYSTEM_SECURITY = &H1000000


''
'' MaximumAllowed access type
''


MAXIMUM_ALLOWED = &H2000000


''
'' These are the generic rights.
''


GENERIC_READ = &H80000000
GENERIC_WRITE = &H40000000
GENERIC_EXECUTE = &H20000000
GENERIC_ALL = &H10000000
End Enum


Friend Enum EFileShare
FILE_SHARE_NONE = &H0
FILE_SHARE_READ = &H1
FILE_SHARE_WRITE = &H2
FILE_SHARE_DELETE = &H4
End Enum


Friend Enum ECreationDisposition
'''


''' Creates a new file, only if it does not already exist.
''' If the specified file exists, the function fails and the last-error code is set to ERROR_FILE_EXISTS (80).
''' If the specified file does not exist and is a valid path to a writable location, a new file is created.
'''

CREATE_NEW = 1


'''


''' Creates a new file, always.
''' If the specified file exists and is writable, the function overwrites the file, the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS (183).
''' If the specified file does not exist and is a valid path, a new file is created, the function succeeds, and the last-error code is set to zero.
''' For more information, see the Remarks section of this topic.
'''

CREATE_ALWAYS = 2


'''


''' Opens a file or device, only if it exists.
''' If the specified file or device does not exist, the function fails and the last-error code is set to ERROR_FILE_NOT_FOUND (2).
''' For more information about devices, see the Remarks section.
'''

OPEN_EXISTING = 3


'''


''' Opens a file, always.
''' If the specified file exists, the function succeeds and the last-error code is set to ERROR_ALREADY_EXISTS (183).
''' If the specified file does not exist and is a valid path to a writable location, the function creates a file and the last-error code is set to zero.
'''

OPEN_ALWAYS = 4


'''


''' Opens a file and truncates it so that its size is zero bytes, only if it exists.
''' If the specified file does not exist, the function fails and the last-error code is set to ERROR_FILE_NOT_FOUND (2).
''' The calling process must open the file with the GENERIC_WRITE bit set as part of the dwDesiredAccess parameter.
'''

TRUNCATE_EXISTING = 5
End Enum


Friend Enum EFileAttributes
FILE_ATTRIBUTE_READONLY = &H1
FILE_ATTRIBUTE_HIDDEN = &H2
FILE_ATTRIBUTE_SYSTEM = &H4
FILE_ATTRIBUTE_DIRECTORY = &H10
FILE_ATTRIBUTE_ARCHIVE = &H20
FILE_ATTRIBUTE_DEVICE = &H40
FILE_ATTRIBUTE_NORMAL = &H80
FILE_ATTRIBUTE_TEMPORARY = &H100
FILE_ATTRIBUTE_SPARSE_FILE = &H200
FILE_ATTRIBUTE_REPARSE_POINT = &H400
FILE_ATTRIBUTE_COMPRESSED = &H800
FILE_ATTRIBUTE_OFFLINE = &H1000
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = &H2000
FILE_ATTRIBUTE_ENCRYPTED = &H4000
FILE_ATTRIBUTE_VIRTUAL = &H10000


'This parameter can also contain combinations of flags (FILE_FLAG_*)
FILE_FLAG_BACKUP_SEMANTICS = &H2000000
FILE_FLAG_DELETE_ON_CLOSE = &H4000000
FILE_FLAG_NO_BUFFERING = &H2000000
FILE_FLAG_OPEN_NO_RECALL = &H100000
FILE_FLAG_OPEN_REPARSE_POINT = &H200000
FILE_FLAG_OVERLAPPED = &H40000000
FILE_FLAG_POSIX_SEMANTICS = &H100000
FILE_FLAG_RANDOM_ACCESS = &H10000000
FILE_FLAG_SEQUENTIAL_SCAN = &H8000000
FILE_FLAG_WRITE_THROUGH = &H80000000
End Enum



VC++2008:
#include <windows.h>

int main(int argc, TCHAR argv[])
{
//檔案處理
HANDLE hFile;
DWORD dwWritten;
//字串變數,用於儲存系統目錄
TCHAR szSystemDir[MAX_PATH];
//獲取系統目錄
GetSystemDirectory(szSystemDir, MAX_PATH);

//建立檔案systemroot.txt
hFile=CreateFile("systemroot.txt",
GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
//判斷檔案是否建立成功
if(hFile != INVALID_HANDLE_VALUE)
{
//將系統目錄系統資訊寫入檔案
if(!WriteFile(hFile,szSystemDir,lstrlen(szSystemDir),&dwWritten,NULL))
{
return GetLastError();
}
}
//關閉檔案,回傳
CloseHandle(hFile);
return 0;
}


WinBase.h:
WINBASEAPI
__out
HANDLE
WINAPI
CreateFileA(
__in LPCSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);


WINBASEAPI
__out
HANDLE
WINAPI
CreateFileW(
__in LPCWSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);


#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif // !UNICODE



WinNT.h:
//
// These are the generic rights.
//

#define GENERIC_READ (0x80000000L)
#define GENERIC_WRITE (0x40000000L)
#define GENERIC_EXECUTE (0x20000000L)
#define GENERIC_ALL (0x10000000L)


MSDN:
CreateFile Function

Creates or opens a file, file stream, 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.

To perform this operation as a transacted operation, use the CreateFileTransacted function.


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

Parameters
lpFileName
The name of the object to be created or opened.

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. For more information, see Naming a File. For information on special device names, see Defining an MS-DOS Device Name.

To specify a COM port number greater than 9, use the following syntax: "\\.\COM10". This syntax works for all port numbers and hardware that allows COM port numbers to be specified.

To create a file stream, specify the name of the file, a colon, and then the name of the stream. For more information, see File Streams.

dwDesiredAccess
The access to the object, which can be read, write, or both.

For more information, see File Security and Access Rights. You cannot request an access mode that conflicts with the sharing mode that is specified in an open request that has an open handle.

If this parameter is zero (0), the application can query file and device attributes without accessing a device. This is useful for an application to determine the size of a floppy disk drive and the formats it supports without requiring a floppy in a drive. It can also be used to test for the existence of a file or directory without opening them for read or write access.

dwShareMode
The sharing mode of an object, which can be read, write, both, or none.

You cannot request a sharing mode that conflicts with the access mode that is specified in an open request that has an open handle, because that would result in the following sharing violation: ERROR_SHARING_VIOLATION. For more information, see Creating and Opening Files.

If this parameter is zero (0) and CreateFile succeeds, the object cannot be shared and cannot be opened again until the handle is closed. For more information, see the Remarks section of this topic.

The sharing options remain in effect until you close the handle to an object.

To enable a process to share an object while another process has the object open, use a combination of one or more of the following values to specify the access mode they can request to open the object.

Value Meaning
FILE_SHARE_DELETE
Enables subsequent open operations on an object to request delete access.

Otherwise, other processes cannot open the object if they request delete access.

If this flag is not specified, but the object has been opened for delete access, the function fails.

FILE_SHARE_READ
Enables subsequent open operations on an object to request read access.

Otherwise, other processes cannot open the object if they request read access.

If this flag is not specified, but the object has been opened for read access, the function fails.

FILE_SHARE_WRITE
Enables subsequent open operations on an object to request write access.

Otherwise, other processes cannot open the object if they request write access.

If this flag is not specified, but the object has been opened for write access or has a file mapping with write access, the function fails.


lpSecurityAttributes
A pointer to a SECURITY_ATTRIBUTES structure that determines whether or not 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 an object. If lpSecurityAttributes is NULL, the object gets a default security descriptor. The access control lists (ACL) in the default security descriptor for a file or directory are inherited from its parent directory.

The target file system must support security on files and directories for this parameter to have an effect on them, which 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
An action to take on files that exist and do not exist.

For more information, see the Remarks section of this topic.

This parameter must be one of the following values.

Value Meaning
CREATE_ALWAYS
Creates a new file, always.

If a 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 that the SECURITY_ATTRIBUTES structure specifies.

CREATE_NEW
Creates a new file.

The function fails if a specified file exists.

OPEN_ALWAYS
Opens a file, always.

If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.

OPEN_EXISTING
Opens a file.

The function fails if the file does not exist.

For more information, see the Remarks section of this topic.

TRUNCATE_EXISTING
Opens a file and truncates it so that its size is zero (0) bytes.

The function fails if the file does not exist.

The calling process must open the file with the GENERIC_WRITE access right.


dwFlagsAndAttributes
The file attributes and flags.

This parameter can include any combination of the file attributes. All other file attributes override FILE_ATTRIBUTE_NORMAL.

When CreateFile opens a file, it combines the file flags with existing file attributes, and ignores any supplied file attributes.

The following file attributes and flags are used only for file objects, not other types of objects that CreateFile creates.

Attribute Meaning
FILE_ATTRIBUTE_ARCHIVE
32
0x20
The file should be archived. Applications use this attribute to mark files for backup or removal.

FILE_ATTRIBUTE_ENCRYPTED
16384
0x4000
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. For more information, see File Encryption.

This flag has no effect if FILE_ATTRIBUTE_SYSTEM is also specified.

FILE_ATTRIBUTE_HIDDEN
2
0x2
The file is hidden. Do not include it in an ordinary directory listing.

FILE_ATTRIBUTE_NORMAL
128
0x80
The file does not have other attributes set. This attribute is valid only if used alone.

FILE_ATTRIBUTE_OFFLINE
4096
0x1000
The data of a file is not immediately available. This attribute indicates that file data is 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
1
0x1
The file is read only. Applications can read the file, but cannot write to or delete it.

FILE_ATTRIBUTE_SYSTEM
4
0x4
The file is part of or used exclusively by an operating system.

FILE_ATTRIBUTE_TEMPORARY
256
0x100
The file is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because an application deletes a temporary file after a handle is closed. In that case, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.


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

Value 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 when the process has SE_BACKUP_NAME and SE_RESTORE_NAME privileges. For more information, see Changing Privileges in a Token.

You must set this flag to obtain a handle to a directory. A directory handle can be passed to some functions instead of a file handle. For more information, see Directory Handles.

FILE_FLAG_DELETE_ON_CLOSE
The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles.

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

Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified.

FILE_FLAG_NO_BUFFERING
The file is being opened with no system caching. This flag does not affect hard disk caching or memory mapped files. 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 take more time, 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 that are opened with FILE_FLAG_NO_BUFFERING:


File access must begin at byte offsets within a file that are integer multiples of the volume sector size.
File access must be for numbers of bytes that are integer multiples of the volume sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, 1536, or 2048 bytes, but not of 335, 981, or 7171 bytes.
Buffer addresses for read and write operations should be sector aligned, which means aligned on addresses in memory that are integer multiples of the volume 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 sector size. Memory pages are 4-8 KB in size; sectors are 512 bytes (hard disks) or 2048 bytes (CD), and therefore, volume sectors can never be larger than memory pages.

An application can determine a volume sector size by calling the GetDiskFreeSpace function.

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

FILE_FLAG_OPEN_REPARSE_POINT
Normal reparse point processing will not occur; CreateFile will attempt to open the reparse point. When a file is opened, a file handle is returned, whether or not the filter that controls the reparse point is operational. 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 complete, the event specified 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
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 that naming. Use care when using this option, because files created with this flag may not be accessible by applications that are written for MS-DOS or 16-bit Windows.

FILE_FLAG_RANDOM_ACCESS
The file is to be accessed randomly. The system can use this as a hint to optimize file caching.

FILE_FLAG_SEQUENTIAL_SCAN
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.

This flag has no effect if the file system does not support cached I/O and FILE_FLAG_NO_BUFFERING.

FILE_FLAG_WRITE_THROUGH
Write operations will not go through any intermediate cache, they will 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.


The dwFlagsAndAttributes parameter can also contain Security Quality of Service information. For more information, see Impersonation Levels. 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
Impersonates a 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
Impersonates a 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
Impersonates a client at the Identification impersonation level.

SECURITY_IMPERSONATION
Impersonate a client at the impersonation level.


hTemplateFile
A handle to a template file with the GENERIC_READ access right. The template file supplies file attributes and extended attributes for the file that is being created. This parameter can be NULL.

When opening an existing file, CreateFile ignores the template file.

When opening a new EFS-encrypted file, the file inherits the DACL from its parent directory.

Return Value
If the function succeeds, the return value is an open handle to a specified file. If a specified file exists before the function call and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS, even when the function succeeds. If a file does not exist before the call, GetLastError returns zero (0).

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

Remarks
Use the CloseHandle function to close an object handle that CreateFile returns.

Windows Server 2003 and Windows XP/2000: A sharing violation occurs 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 the NTFS file system, support compression or encryption for individual files and directories. On volumes that are formatted for that kind of 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. For more information, see File Compression and Decompression, and File Encryption.

Windows Server 2003 and Windows XP/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 more information, see Automatic Propagation of Inheritable ACEs.
The flags FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING are independent. If you specify write-through but not no-buffering, then data will be written into the file cache and will also be issued to the hardware immediately, flagged as write-through. A write-through request also causes NTFS to flush any metadata changes that result from processing the request.

Symbolic link behavior—If the call to this function creates a new file, there is no change in behavior.

If FILE_FLAG_OPEN_REPARSE_POINT is specified and:


If an existing file is opened and it is a symbolic link, the handle returned is a handle to the symbolic link.
If CREATE_ALWAYS, TRUNCATE_EXISTING, or FILE_FLAG_DELETE_ON_CLOSE are specified, the file affected is a symbolic link.
If FILE_FLAG_OPEN_REPARSE_POINT is not specified and:

If an existing file is opened and it is a symbolic link, the handle returned is a handle to the target.
If CREATE_ALWAYS, TRUNCATE_EXISTING, or FILE_FLAG_DELETE_ON_CLOSE are specified, the file affected is the target.

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). A single-sector write is atomic. Multi-sector writes that are cached may not always be written to the disk; therefore, specify FILE_FLAG_WRITE_THROUGH to ensure that an entire multi-sector write is written to the disk without caching.

Files
If you try 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 for the user to insert a disk or a CD. To prevent the system from displaying this message, call the SetErrorMode function with SEM_FAILCRITICALERRORS.

Windows Server 2003 and Windows XP/2000: If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile fails and sets 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.
For more information, see Creating and Opening Files.

If you rename or delete a file and then restore it shortly afterward, the system searches the cache for file information to restore. Cached information includes its short/long name pair and creation time.

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 a network, it is better to use GENERIC_READ GENERIC_WRITE than touse GENERIC_WRITE alone. The resulting code is 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 a file across a network can occasionally return ERROR_ACCESS_DENIED.

File Streams
On NTFS file systems, you can use CreateFile to create separate streams within a file. For more information, see File Streams.

Directories
An application cannot create a directory by using CreateFile. The application must call CreateDirectory or CreateDirectoryEx to create a directory. To open a directory by using CreateFile, use the FILE_FLAG_BACKUP_SEMANTICS flag.

When using CreateFile to open a directory during defragmentation of a FAT or FAT32 file system volume, do not specify the MAXIMUM_ALLOWED access right. Access to the directory is 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 partition table. However, it is potentially dangerous to do so, because an incorrect write to a disk could make its contents inaccessible. The following requirements must be met for such a call to succeed:


The caller must have administrative privileges. For more information, see Running with Special Privileges.
The dwCreationDisposition parameter must have the OPEN_EXISTING flag.
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 the following form: \\.\PhysicalDriveX. Hard disk numbers start at zero (0). The following table shows some examples of physical drive strings.

String Meaning
\\.\PhysicalDrive0 Opens the first physical drive.
\\.\PhysicalDrive2 Opens the third physical drive.

To obtain the physical drive for a volume, open a handle to the volume and call the DeviceIoControl function with IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS. This control code returns the disk number of offset for each of the volume's extents; a volume can span disks.

For an example of opening a physical drive, see Calling DeviceIoControl.

When opening a volume or floppy drive, the lpFileName string should be the following form: \\.\X:. Do not use a trailing backslash, which indicates the root directory of a drive. The following table shows some examples of drive strings.

String Meaning
\\.\A: Opens drive A (floppy drive).
\\.\C: Opens drive C (volume).

You can also open a volume by referring to its volume name. For more information, see Naming a Volume.

Volume handles can be opened as noncached at the discretion of the file system, even when the noncached option is not specified in CreateFile. You should assume that all Microsoft file systems open volume handles as noncached. The restrictions on noncached I/O for files also apply to volumes.

A file system may or may not require buffer alignment even though the data is noncached. However, if the noncached 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 noncached, and follow the noncached I/O restrictions.

To read or write to the last few sectors of the volume, you must call Calling DeviceIoControl and specify FSCTL_ALLOW_EXTENDED_DASD_IO. This signals the file system driver not to perform any I/O boundary checks on partition read or write calls. Instead, boundary checks are performed by the device driver.

Changer Device
The IOCTL_CHANGER_* control codes accept a handle to a changer device. To open a changer device, use a file name of the following form: \\.\Changerx where x is a number that indicates which device to open, starting with zero (0). To open changer device zero (0) in an application that is written in C or C++, use the following file name: "\\\\.\\Changer0".

Tape Drives
You can open tape drives by using a file name of the following form: \\.\TAPEx where x is a number that indicates which drive to open, starting with tape drive zero (0). To open tape drive zero (0) in an application that is written in C or C++, use the following file name: "\\\\.\\TAPE0". For more information, see Backup.

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 template parameter must be NULL. Read, write, or read/write access can be specified, and the handle can be opened for overlapped I/O. For more information about communications, see Communications.

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 Alloc console function. For console handles, set the CreateFile parameters as follows.

Parameters Value
lpFileName Use the CONIN$ value to specify console input.

Use the CONOUT$ value to specify console output.

CONIN$ gets a handle to the console input buffer, even if the SetStdHandle function redirects 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 redirects 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$, specify FILE_SHARE_READ. When opening CONOUT$, specify FILE_SHARE_WRITE.

If the calling process inherits 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.

The following table shows 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.

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. For more information, see Mailslots.

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 after it is opened, the named pipe instance cannot be opened by another client. The access that is specified when a pipe is opened must be compatible with the access that is specified in the dwOpenMode parameter of the CreateNamedPipe function. For more information, see Pipes.

Example Code
For an example, see Opening a File for Reading or Writing.

Requirements
Client
Requires Windows Vista, Windows XP, or Windows 2000 Professional.

Server
Requires Windows Server 2008, Windows Server 2003, or Windows 2000 Server.

Header
Declared in WinBase.h; include Windows.h.

Library
Use Kernel32.lib.

DLL
Requires Kernel32.dll.

Unicode
Implemented as CreateFileW (Unicode) and CreateFileA (ANSI).

GetSystemDirectory-取得系統目錄

VB2008:
Public Class Form1
Private Declare Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" (ByVal lpBuffer As String, ByVal uSize As Integer) As Integer

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim nMAX_PATH As Integer = 260
Dim sSystemDir As String = Strings.StrDup(nMAX_PATH, " ")
Dim nStrLen As Integer = GetSystemDirectory(sSystemDir, nMAX_PATH)
sSystemDir = Strings.Left(sSystemDir, nStrLen) '去除實際字串尾端由chr(0)起所截斷的部份
MsgBox(sSystemDir & "---")
End Sub
End Class


VC++2008:
#include <windows.h>

int main(int argc, TCHAR argv[])
{
//檔案處理
HANDLE hFile;
DWORD dwWritten;
//字串變數,用於儲存系統目錄
TCHAR szSystemDir[MAX_PATH];
//獲取系統目錄
GetSystemDirectory(szSystemDir, MAX_PATH);

//建立檔案systemroot.txt
hFile=CreateFile("systemroot.txt",
GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
//判斷檔案是否建立成功
if(hFile != INVALID_HANDLE_VALUE)
{
//將系統目錄系統資訊寫入檔案
if(!WriteFile(hFile,szSystemDir,lstrlen(szSystemDir),&dwWritten,NULL))
{
return GetLastError();
}
}
//關閉檔案,回傳
CloseHandle(hFile);
return 0;
}


WinBase.h:
WINBASEAPI
UINT
WINAPI
GetSystemDirectoryA(
__out_ecount_part_opt(uSize, return + 1) LPSTR lpBuffer,
__in UINT uSize
);


WINBASEAPI
UINT
WINAPI
GetSystemDirectoryW(
__out_ecount_part_opt(uSize, return + 1) LPWSTR lpBuffer,
__in UINT uSize
);


#ifdef UNICODE
#define GetSystemDirectory GetSystemDirectoryW
#else
#define GetSystemDirectory GetSystemDirectoryA
#endif // !UNICODE



MSDN:
GetSystemDirectory Function


Retrieves the path of the system directory. The system directory contains system files such as dynamic-link libraries, drivers, and font files.


This function is provided primarily for compatibility. Applications should store code in the Program Files folder and persistent data in the Application Data folder in the user's profile. For more information, see ShGetFolderPath.



UINT WINAPI GetSystemDirectory(
__out LPTSTR lpBuffer,
__in UINT uSize
);


Parameters
lpBuffer
A pointer to the buffer to receive the path. This path does not end with a backslash unless the system directory is the root directory. For example, if the system directory is named Windows\System on drive C, the path of the system directory retrieved by this function is C:\Windows\System.


uSize
The maximum size of the buffer, in TCHARs.


Return Value
If the function succeeds, the return value is the length, in TCHARs, of the string copied to the buffer, not including the terminating null character. If the length is greater than the size of the buffer, the return value is the size of the buffer required to hold the path, including the terminating null character.


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


Remarks
Applications should not create files in the system directory. If the user is running a shared version of the operating system, the application does not have write access to the system directory.


Example Code
For an example, see Getting System Information.


Requirements
Client
Requires Windows Vista, Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.
Server
Requires Windows Server 2008, Windows Server 2003, Windows 2000 Server, or Windows NT Server.
Header
Declared in Winbase.h; include Windows.h.
Library
Use Kernel32.lib.
DLL
Requires Kernel32.dll.
Unicode
Implemented as GetSystemDirectoryW (Unicode) and GetSystemDirectoryA (ANSI).

2010年4月1日 星期四

CopyMemory-記憶體區塊複製

VB2008:
from MicoAg:
[ VB2008 ]中如何使用 Copymemory API ?

下列說明:
1. ByVal、ByRef?
2. CopyMemory API 原型?
3. 何謂型別?
4. 範例。

1. ByVal、ByRef與VB6無差異, ByVal傳值與ByRef傳址。VB6預設參數為 ByRef,VB2005(.Net 1.0以後)改為 ByVal。

2. CopyMemory 是針對記憶體區塊做操作,很重要的參數 Destination、Source。
Destination [in] :A pointer to the starting address of the copied block's destination.
Source [in] :A pointer to the starting address of the block of memory to copy.
Length [in] :The size of the block of memory to copy, in bytes.
Destination、Source 都是以記憶體地址來操作,所以 ByVal、ByRef 傳值、傳址結果要指向記憶體地址


3. 型別?區分 (Value Type) 實值型別、(Reference Type) 參考型別、其他型別,在記憶體區塊配置有很大不同。
實值型別是將實際資料放在 Stack 區;而參考型別是將實際資料放在 Managed Heap 區,但是會將指標地址放在 Stack 區。Stack 記憶體區塊小,Heap 記憶體區塊為 2GB,Managed Heap 受.NET記憶體回收器(GC _ Garbage Collection)控管。

4.範例:From:MicoAg
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination
As Integer, ByVal Source As Integer, ByVal Length As Integer)
Private Declare Sub CopyMemoryDate Lib "kernel32" Alias "RtlMoveMemory" (ByVal
Destination As Integer, ByRef SourceDate As Date, ByVal Length As Integer)

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
Dim tInt As Integer = &H4030201
Dim tLng As Long = &H807060504030201
Dim tSng As Single = 10.25
Dim tDouble As Double = 0.125
Dim tStr As String = "_MicoAg_"
Dim tArray() As Byte = {&H10, &H20, &H30, &H40}
Dim tDate As Date = Now
Dim B() As Byte
' (Value Type) 實值型別
ReDim B(3)
CopyMemory(VarPtr(B), VarPtr(tInt), 4)
ReDim B(7)
CopyMemory(VarPtr(B), VarPtr(tLng), 8)
ReDim B(3)
CopyMemory(VarPtr(B), VarPtr(tSng), 4)
ReDim B(7)
CopyMemory(VarPtr(B), VarPtr(tDouble), 8)
' (Reference Type) 參考型別
ReDim B(15)
CopyMemory(VarPtr(B), VarPtr(tstr), 16)
ReDim B(3)
CopyMemory(VarPtr(B), VarPtr(tArray), 4)
' 其他型別
ReDim B(8)
CopyMemoryDate(VarPtr(B), tDate, 8)
End Sub
Private Function VarPtr(ByVal e As Object) As Integer
Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32
GC.Free()
Return GC2
End Function
End Class

有了 VarPtr(),相信VB6走向VB2008的使用者會很受用。


字串(string)複製到字串數組(byte()):
Imports System.Runtime.InteropServices

Public Class Form1
Private Declare Function MessageBox Lib "User32" Alias "MessageBoxA" (ByVal hWnd As Integer, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Integer) As Integer
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Integer, ByVal Source As Integer, ByVal Length As Integer)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sText As String = "Windows data type, string."
Dim bText As Byte()
ReDim bText(Strings.Len(sText) * 2 - 1)

MessageBox(Me.Handle, sText, "String", 0)
CopyMemory(VarPtr(bText), VarPtr(sText), bText.Length)
MessageBox(Me.Handle, System.Text.Encoding.Unicode.GetString(bText), "BYTE", 0)
End Sub

Private Function VarPtr(ByVal e As Object) As Integer
Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32
GC.Free()
Return GC2
End Function
End Class


上面程式改成底下這樣也可以:
Public Class Form1
Private Declare Function MessageBox Lib "User32" Alias "MessageBoxA" (ByVal hWnd As Integer, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Integer) As Integer
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal Destination As Byte(), ByVal Source As String, ByVal Length As Integer)

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim sText As String = "Windows data type, string."
Dim bText As Byte()
ReDim bText(Len(sText))

MessageBox(Me.Handle, sText, "String", 0)
CopyMemory(bText, sText, bText.Length)
MessageBox(Me.Handle, System.Text.Encoding.Default.GetChars(bText), "BYTE", 0)
End Sub
End Class


VC++:
#include <windows.h>
#include <stdio.h>

int WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
//定義字串
LPSTR szString = "Windows data type, string.";
//定義字串數組
CHAR lpString[120]; //要大於szString的長度
//定義DWORD類型的資料
DWORD dwMax = 0xFFFFFFFF;
DWORD dwOne = 0x1;
//定義INT類型的資料
INT iMax = 0xFFFFFFFF;
INT iOne = 0x1;

//顯示字串
MessageBox(NULL,szString,"LPSTR",MB_OK);
//複製記憶體,將字串複製到數組中(包括NULL結束符號)
CopyMemory(lpString, szString, lstrlen(szString)+1);
//顯示複製的字串
MessageBox(NULL,lpString,"CHAR[]",MB_OK);

//比較DWORD並顯示結果
if(dwMax>dwOne)
{
MessageBox(NULL,"DWORD類型的資料0xFFFFFFFF > 0x1", "DWORD",MB_OK);
}
//比較INT並顯示結果
if(iMax < iOne)
{
MessageBox(NULL,"INT類型的資料0xFFFFFFFF < 0x1", "INT", MB_OK);
}
return 0;
}


WinBase.h:
#define MoveMemory RtlMoveMemory
#define CopyMemory RtlCopyMemory
#define FillMemory RtlFillMemory
#define ZeroMemory RtlZeroMemory
#define SecureZeroMemory RtlSecureZeroMemory
#define CaptureStackBackTrace RtlCaptureStackBackTrace


WinNT.h:
#define RtlEqualMemory(Destination,Source,Length) (!memcmp((Destination),(Source),(Length)))
#define RtlMoveMemory(Destination,Source,Length) memmove((Destination),(Source),(Length))
#define RtlCopyMemory(Destination,Source,Length) memcpy((Destination),(Source),(Length))
#define RtlFillMemory(Destination,Length,Fill) memset((Destination),(Fill),(Length))
#define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length))


MSDN:
void CopyMemory(
__in PVOID Destination,
__in const VOID *Source,
__in SIZE_T Length
);


Parameters
Destination [in]
A pointer to the starting address of the copied block's destination.

Source [in]
A pointer to the starting address of the block of memory to copy.

Length [in]
The size of the block of memory to copy, in bytes.


Return Value
This function has no return value.


Remarks
This function is defined as the RtlCopyMemory function. Its implementation is provided inline. For more information, see Winbase.h and Winnt.h.

If the source and destination blocks overlap, the results are undefined. For overlapped blocks, use the MoveMemory function.

2010年3月31日 星期三

MessageBox-使用訊息對話方塊

●The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, plus any combination of predefined icons and push buttons.

●VB6建議宣告法: Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
VB2008宣告法: Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Integer, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Integer) As Integer

●用法
VB6:
傳回值 = MessageBox(擁有者的handle, "要顯示的文字", "視窗抬頭", 視窗種類)
Private Sub COmmand1_Click()
Dim Rtvl As Ling
Rtvl = MessageBox(Me.hWnd, "你好嗎?", "問候", 32 OR 4)
End Sub


VB2008:
Public Class Form1

Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hWnd As Integer, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Integer) As Integer

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim rtl As Integer = MessageBox(Me.Handle, "開始學習Windows編程", "訊息對話框", 32 Or 4)
MsgBox(rtl)
End Sub
End Class


VC++:
#include <windows.h>

#pragma comment (lib, "User32.lib")

int WinMain(
HINSTANCE hInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
MessageBox(NULL,
TEXT("開始學習Windows編程"),
TEXT("訊息對話框"),
MB_OK);
return 0;
}


視窗種類 = 按鈕種類 OR 圖示種類

按鈕種類
1 確定、取消
2 異常終止、重試、略過
3 是、否、取消
4 是、否
5 重試、取消
6 說明(無法關閉)
7 無按鈕(無法關閉)
8 取消、說明
9 無按鈕(無法關閉)
10 確定、取消、說明
11 無按鈕(無法關閉)
12 說明、確定、取消、說明
13 無按鈕(無法關閉)
14 確定、取消、說明、異常終止、取消

圖示種類
0 第一個按鈕為預設
16 叉叉
32 問號
48 驚嘆號
64 資訊
256 第二個按鈕為預設
512 第三個按鈕為預設

傳回值代表按下那個按鈕
1 確定
2 取消
3 中斷
4 重試
5 忽略
6 是
7 否

●VB也提供了MsgBox函數,兩者執行來最大的差別是,一樣都是視窗動結,然而MsgBox會使得整個程式停止,等待使用者結束MessageBox的使用,而MessageBox函數則只會凍結視窗而不會終止程式的執行。

MSDN:
MessageBox Function

--------------------------------------------------------------------------------

The MessageBox function creates, displays, and operates a message box. The message box contains an application-defined message and title, along with any combination of predefined icons and push buttons.


Syntax


int MessageBox( HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
);
Parameters


hWnd
[in] Handle to the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.
lpText
[in] Pointer to a null-terminated string that contains the message to be displayed.
lpCaption
[in] Pointer to a null-terminated string that contains the dialog box title. If this parameter is NULL, the default title Error is used.
uType
[in] Specifies the contents and behavior of the dialog box. This parameter can be a combination of flags from the following groups of flags.


To indicate the buttons displayed in the message box, specify one of the following values.


MB_ABORTRETRYIGNORE (0x00000002L)
The message box contains three push buttons: Abort, Retry, and Ignore.
MB_CANCELTRYCONTINUE (0x00000006L)
Microsoft Windows 2000/XP: The message box contains three push buttons: Cancel, Try Again, Continue. Use this message box type instead of MB_ABORTRETRYIGNORE.
MB_HELP (0x00004000L)
Windows 95/98/Me, Windows NT 4.0 and later: Adds a Help button to the message box. When the user clicks the Help button or presses F1, the system sends a WM_HELP message to the owner.
MB_OK (0x00000000L)
The message box contains one push button: OK. This is the default.
MB_OKCANCEL (0x00000001L)
The message box contains two push buttons: OK and Cancel.
MB_RETRYCANCEL (0x00000005L)
The message box contains two push buttons: Retry and Cancel.
MB_YESNO (0x00000004L)
The message box contains two push buttons: Yes and No.
MB_YESNOCANCEL (0x00000003L)
The message box contains three push buttons: Yes, No, and Cancel.
To display an icon in the message box, specify one of the following values.
MB_ICONEXCLAMATION (0x00000030L)
An exclamation-point icon appears in the message box.
MB_ICONWARNING (MB_ICONEXCLAMATION)
An exclamation-point icon appears in the message box.
MB_ICONINFORMATION (MB_ICONASTERISK)
An icon consisting of a lowercase letter i in a circle appears in the message box.
MB_ICONASTERISK (0x00000040L)
An icon consisting of a lowercase letter i in a circle appears in the message box.
MB_ICONQUESTION (0x00000020L)
A question-mark icon appears in the message box. The question-mark message icon is no longer recommended because it does not clearly represent a specific type of message and because the phrasing of a message as a question could apply to any message type. In addition, users can confuse the message symbol question mark with Help information. Therefore, do not use this question mark message symbol in your message boxes. The system continues to support its inclusion only for backward compatibility.
MB_ICONSTOP (MB_ICONHAND)
A stop-sign icon appears in the message box.
MB_ICONERROR (MB_ICONHAND)
A stop-sign icon appears in the message box.
MB_ICONHAND (0x00000010L)
A stop-sign icon appears in the message box.
To indicate the default button, specify one of the following values.
MB_DEFBUTTON1 (0x00000000L)
The first button is the default button.
MB_DEFBUTTON1 is the default unless MB_DEFBUTTON2, MB_DEFBUTTON3, or MB_DEFBUTTON4 is specified.

MB_DEFBUTTON2 (0x00000100L)
The second button is the default button.
MB_DEFBUTTON3 (0x00000200L)
The third button is the default button.
MB_DEFBUTTON4 (0x00000300L)
The fourth button is the default button.
To indicate the modality of the dialog box, specify one of the following values.
MB_APPLMODAL (0x00000000L)
The user must respond to the message box before continuing work in the window identified by the hWnd parameter. However, the user can move to the windows of other threads and work in those windows.
Depending on the hierarchy of windows in the application, the user may be able to move to other windows within the thread. All child windows of the parent of the message box are automatically disabled, but pop-up windows are not.

MB_APPLMODAL is the default if neither MB_SYSTEMMODAL nor MB_TASKMODAL is specified.

MB_SYSTEMMODAL (0x00001000L)
Same as MB_APPLMODAL except that the message box has the WS_EX_TOPMOST style. Use system-modal message boxes to notify the user of serious, potentially damaging errors that require immediate attention (for example, running out of memory). This flag has no effect on the user's ability to interact with windows other than those associated with hWnd.
MB_TASKMODAL (0x00002000L)
Same as MB_APPLMODAL except that all the top-level windows belonging to the current thread are disabled if the hWnd parameter is NULL. Use this flag when the calling application or library does not have a window handle available but still needs to prevent input to other windows in the calling thread without suspending other threads.
To specify other options, use one or more of the following values.
MB_DEFAULT_DESKTOP_ONLY (0x00020000L)
Windows NT/2000/XP: Same as desktop of the interactive window station. For more information, see Window Stations.
Windows NT 4.0 and earlier: If the current input desktop is not the default desktop, MessageBox fails.


Windows 2000/XP: If the current input desktop is not the default desktop, MessageBox does not return until the user switches to the default desktop.


Windows 95/98/Me: This flag has no effect.


MB_RIGHT (0x00080000L)
The text is right-justified.
MB_RTLREADING (0x00100000L)
Displays message and caption text using right-to-left reading order on Hebrew and Arabic systems.
MB_SETFOREGROUND (0x00010000L)
The message box becomes the foreground window. Internally, the system calls the SetForegroundWindow function for the message box.
MB_TOPMOST (0x00040000L)
The message box is created with the WS_EX_TOPMOST window style.
MB_SERVICE_NOTIFICATION (0x00200000L)
Windows NT/2000/XP: The caller is a service notifying the user of an event. The function displays a message box on the current active desktop, even if there is no user logged on to the computer.
Terminal Services: If the calling thread has an impersonation token, the function directs the message box to the session specified in the impersonation token.


If this flag is set, the hWnd parameter must be NULL. This is so that the message box can appear on a desktop other than the desktop corresponding to the hWnd.

For more information on the changes between Microsoft Windows NT 3.51 and Windows NT 4.0, see Remarks.

For information on security considerations in regard to using this flag, see Interactive Services.


MB_SERVICE_NOTIFICATION_NT3X (0x00040000L)
Windows NT/2000/XP: This value corresponds to the value defined for MB_SERVICE_NOTIFICATION for Windows NT version 3.51.
For more information on the changes between Windows NT 3.51 and Windows NT 4.0, see Remarks.

Return Value


If a message box has a Cancel button, the function returns the IDCANCEL value if either the ESC key is pressed or the Cancel button is selected. If the message box has no Cancel button, pressing ESC has no effect.


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


If the function succeeds, the return value is one of the following menu-item values.


IDABORT (3) Abort button was selected.
IDCANCEL (2) Cancel button was selected.
IDCONTINUE (11) Continue button was selected.
IDIGNORE (5) Ignore button was selected.
IDNO (7) No button was selected.
IDOK (1) OK button was selected.
IDRETRY (4) Retry button was selected.
IDTRYAGAIN (10) Try Again button was selected.
IDYES (6) Yes button was selected.



Remarks

Adding two right-to-left marks (RLMs), represented by Unicode formatting character U+200F, in the beginning of a MessageBox display string is interpreted by the Win32 MessageBox rendering engine so as to cause the reading order of the MessageBox to be rendered as right-to-left (RTL).

When you use a system-modal message box to indicate that the system is low on memory, the strings pointed to by the lpText and lpCaption parameters should not be taken from a resource file because an attempt to load the resource may fail.

If you create a message box while a dialog box is present, use a handle to the dialog box as the hWnd parameter. The hWnd parameter should not identify a child window, such as a control in a dialog box.

Windows 95/98/Me: The system can support a maximum of 16,364 window handles.

Windows NT/2000/XP: The value of MB_SERVICE_NOTIFICATION changed starting with Windows NT 4.0. Windows NT 4.0 provides backward compatibility for preexisting services by mapping the old value to the new value in the implementation of MessageBox. This mapping is done only for executables that have a version number earlier than 4.0, as set by the linker.

To build a service that uses MB_SERVICE_NOTIFICATION and can run on both Microsoft Windows NT 3.x and Windows NT 4.0, you can do one of the following.


At link-time, specify a version number less than 4.0.
At link-time, specify version 4.0. At run-time, use the GetVersionEx function to check the system version. Then, when running on Windows NT 3.x, use MB_SERVICE_NOTIFICATION_NT3X; and on Windows NT 4.0, use MB_SERVICE_NOTIFICATION.

Windows 95/98/Me: Even though MessageBoxW exists, it is supported by the Microsoft Layer for Unicode on Windows 95/98/Me Systems to give more consistent behavior across all Windows operating systems.


Example

For an example, see Displaying a Message Box.

Function Information

Minimum DLL Version user32.dll
Header Declared in Winuser.h, include Windows.h
Import library User32.lib
Minimum operating systems Windows 95, Windows NT 3.1
Unicode Implemented as ANSI and Unicode versions.



WinUser.h中之宣告:

/*
* MessageBox() Flags
*/
#define MB_OK 0x00000000L
#define MB_OKCANCEL 0x00000001L
#define MB_ABORTRETRYIGNORE 0x00000002L
#define MB_YESNOCANCEL 0x00000003L
#define MB_YESNO 0x00000004L
#define MB_RETRYCANCEL 0x00000005L
#if(WINVER >= 0x0500)
#define MB_CANCELTRYCONTINUE 0x00000006L
#endif /* WINVER >= 0x0500 */


#define MB_ICONHAND 0x00000010L
#define MB_ICONQUESTION 0x00000020L
#define MB_ICONEXCLAMATION 0x00000030L
#define MB_ICONASTERISK 0x00000040L

#if(WINVER >= 0x0400)
#define MB_USERICON 0x00000080L
#define MB_ICONWARNING MB_ICONEXCLAMATION
#define MB_ICONERROR MB_ICONHAND
#endif /* WINVER >= 0x0400 */

#define MB_ICONINFORMATION MB_ICONASTERISK
#define MB_ICONSTOP MB_ICONHAND

#define MB_DEFBUTTON1 0x00000000L
#define MB_DEFBUTTON2 0x00000100L
#define MB_DEFBUTTON3 0x00000200L
#if(WINVER >= 0x0400)
#define MB_DEFBUTTON4 0x00000300L
#endif /* WINVER >= 0x0400 */

#define MB_APPLMODAL 0x00000000L
#define MB_SYSTEMMODAL 0x00001000L
#define MB_TASKMODAL 0x00002000L
#if(WINVER >= 0x0400)
#define MB_HELP 0x00004000L // Help Button
#endif /* WINVER >= 0x0400 */

#define MB_NOFOCUS 0x00008000L
#define MB_SETFOREGROUND 0x00010000L
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000L

#if(WINVER >= 0x0400)
#define MB_TOPMOST 0x00040000L
#define MB_RIGHT 0x00080000L
#define MB_RTLREADING 0x00100000L


#endif /* WINVER >= 0x0400 */

#ifdef _WIN32_WINNT
#if (_WIN32_WINNT >= 0x0400)
#define MB_SERVICE_NOTIFICATION 0x00200000L
#else
#define MB_SERVICE_NOTIFICATION 0x00040000L
#endif
#define MB_SERVICE_NOTIFICATION_NT3X 0x00040000L
#endif

#define MB_TYPEMASK 0x0000000FL
#define MB_ICONMASK 0x000000F0L
#define MB_DEFMASK 0x00000F00L
#define MB_MODEMASK 0x00003000L
#define MB_MISCMASK 0x0000C000L


/*
* Dialog Box Command IDs
*/
#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
#if(WINVER >= 0x0400)
#define IDCLOSE 8
#define IDHELP 9
#endif /* WINVER >= 0x0400 */

#if(WINVER >= 0x0500)
#define IDTRYAGAIN 10
#define IDCONTINUE 11
#endif /* WINVER >= 0x0500 */

#if(WINVER >= 0x0501)
#ifndef IDTIMEOUT
#define IDTIMEOUT 32000
#endif
#endif /* WINVER >= 0x0501 */