July 19th, 2013

Nasty gotcha: STGM_READ | STGM_WRITE does not grant read/write access

You might think that if you want to get read/write access, you could pass STGM_READ | STGM_WRITE. You would be wrong. You have to pass STGM_READ­WRITE. The three flags STGM_READ, STGM_WRITE, and STGM_READ­WRITE are mutually exclusive. If you try to combine them, you get a weird mess. In particular, since the numerical value of STGM_READ is zero, passing STGM_READ | STGM_WRITE is numerically equivalent to passing STGM_WRITE, which grants write-only access. The documentation for the STGM_* constants specifically says “It is not valid to use more than one element from a single group,” and STGM_READ and STGM_WRITE belong to the Access group (as does STGM_READ­WRITE). These values date back to the days of MS-DOS, where function 3Dh (Open File) passed an access mode in the AL register.

7 6 5 4 3 2 1 0
0 0 0 0 0 access
mode

The bottom three bits specified the requested access (0 = read-only, 1 = write-only, 2 = read/write), and the remaining bits were reserved. Later, when networking support was added in approximately MS-DOS 3.5, three more bits were pressed into service:

7 6 5 4 3 2 1 0
0 share
mode
0 access
mode

Sharing modes were 0 = compatibility mode, 1 = deny all, 2 = deny write, 3 = deny read, 4 = deny none.

These values were carried forward into Windows as flags to the Open­File function:

Value Description
OF_READ
0x00000000
Opens a file for reading only.
OF_WRITE
0x00000001
Opens a file for write access only.
OF_READ­WRITE
0x00000002
Opens a file with read/write permissions.
OF_SHARE­COMPAT
0x00000000
Opens a file with compatibility mode, allows any process on a specified computer to open the file any number of times.
OF_SHARE­EXCLUSIVE
0x00000010
Opens a file with exclusive mode and denies both read/write ccess to other processes.
OF_SHARE­DENY­WRITE
0x00000020
Opens a file and denies write access to other processes.
OF_SHARE­DENY­READ
0x00000030
Opens a file and denies read access to other processes.
OF_SHARE­DENY­NONE
0x00000040
Opens a file without denying read or write access to other processes.

These flags were then carried forward into the STGM constants with the same numerical values.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments

Discussion are closed.