Rules for opening shared files
==============================

File is already open, with share set to none:

	Can not open again


File is already open for reading, with read share:

	Can open for reading only, share must include read (can have write too)


File is already open for reading, with write share:

	Can open for writing only, share must include read (can have write too)


File is already open for reading, with read + write share:

	Can open for read, writing or both, share must include read (can have write too)


File is already open for writing, with read share:

	Can open for reading only, share must include write (can have read too)


File is already open for writing, with write share:

	Can open for writing only, share must include write (can have read too)


File is already open for writing, with read + write share:

	Can open for reading, writing or both, share must include write (can have read too)


File is already open for reading + writing, with read share:

	Can open for reading only, share must be read + write


File is already open for reading + writing, with write share:

	Can open for for writing only, share must be read + write


File is already open for reading + writing, with read + write share:

	Can open for read, writing or both, share must be read + write



Executive Summary
-----------------

	Second open must have access within first share, must set second share to at least first access




Documenting code
----------------


#include <stdio.h>
#include <windows.h>

int access[] = {
	GENERIC_READ,
	GENERIC_WRITE,
	GENERIC_READ | GENERIC_WRITE
};

char *access_names[] = {
	"G_READ",
	"G_WRITE",
	"G_READ|G_WRITE"
};

int share[] = {
	FILE_SHARE_READ,
	FILE_SHARE_WRITE,
	FILE_SHARE_READ | FILE_SHARE_WRITE
};

char *share_names[] = {
	"SHARE_READ",
	"SHARE_WRITE",
	"SHARE_READ|SHARE_WRITE"
};

void lockfiles(int access1, int share1, int access2, int share2)
{
	HANDLE h1, h2;
	BOOL ret;

	if (access2 == 0 && share2 == 0) {
		printf("\n");
		printf("%22.22s\n%22.22s", access_names[access1], share_names[share1]);
	}

	h1 = CreateFile("lockedfile",
		access[access1],
		share[share1],
		NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (h1 == INVALID_HANDLE_VALUE) {
		printf("Open1 failed: %d\n", GetLastError());
		return;
	}

	h2 = CreateFile("lockedfile",
		access[access2],
		share[share2],
		NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (h2 == INVALID_HANDLE_VALUE) {
		printf(" %4.4s", "");
	} else {
		printf(" %4.4s", "OK");
		CloseHandle(h2);
	}

	CloseHandle(h1);
}

int main(int argc, char **argv)
{
	int i, j, k, l;

	printf("\t\t\t\t\t\t\tSecond Open\n");
	printf("%22.22s G_RE G_RE G_RE G_WR G_WR G_WR G_RW G_RW G_RW\n", "");
	printf("%22.22s S_RE S_WR S_RW S_RE S_WR S_RW S_RE S_WR S_RW", "First open --v ");
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 3; j++) {
			for (k = 0; k < 3; k++) {
				for (l = 0; l < 3; l++) {
					lockfiles(i, j, k, l);
				}
			}
		}
	}

	return(0);
}



Code output
-----------

                                                        Second Open
                       G_RE G_RE G_RE G_WR G_WR G_WR G_RW G_RW G_RW
       First open --v  S_RE S_WR S_RW S_RE S_WR S_RW S_RE S_WR S_RW
                G_READ
            SHARE_READ   OK        OK                              
                G_READ
           SHARE_WRITE                  OK        OK               
                G_READ
SHARE_READ|SHARE_WRITE   OK        OK   OK        OK   OK        OK
               G_WRITE
            SHARE_READ        OK   OK                              
               G_WRITE
           SHARE_WRITE                       OK   OK               
               G_WRITE
SHARE_READ|SHARE_WRITE        OK   OK        OK   OK        OK   OK
        G_READ|G_WRITE
            SHARE_READ             OK                              
        G_READ|G_WRITE
           SHARE_WRITE                            OK               
        G_READ|G_WRITE
SHARE_READ|SHARE_WRITE             OK             OK             OK

