p11_mmap_open (const char *path,
               struct stat *sb,
               void **data,
               size_t *size)
{
	HANDLE mapping;
	LARGE_INTEGER large;
	DWORD errn;
	p11_mmap *map;

	map = calloc (1, sizeof (p11_mmap));
	if (map == NULL) {
		errno = ENOMEM;
		return NULL;
	}

	map->file  = CreateFile (path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
	if (map->file == INVALID_HANDLE_VALUE) {
		errn = GetLastError ();
		free (map);
		SetLastError (errn);
		if (errn == ERROR_PATH_NOT_FOUND || errn == ERROR_FILE_NOT_FOUND)
			errno = ENOENT;
		else if (errn == ERROR_ACCESS_DENIED)
			errno = EPERM;
		return NULL;
	}

	if (sb == NULL) {
		if (!GetFileSizeEx (map->file, &large)) {
			errn = GetLastError ();
			CloseHandle (map->file);
			free (map);
			SetLastError (errn);
			if (errn == ERROR_ACCESS_DENIED)
				errno = EPERM;
			return NULL;
		}
	} else {
		large.QuadPart = sb->st_size;
	}

	mapping = CreateFileMapping (map->file, NULL, PAGE_READONLY, 0, 0, NULL);
	if (!mapping) {
		errn = GetLastError ();
		CloseHandle (map->file);
		free (map);
		SetLastError (errn);
		if (errn == ERROR_ACCESS_DENIED)
			errno = EPERM;
		return NULL;
	}

	map->data = MapViewOfFile (mapping, FILE_MAP_READ, 0, 0, large.QuadPart);
	CloseHandle (mapping);

	if (map->data == NULL) {
		errn = GetLastError ();
		CloseHandle (map->file);
		free (map);
		SetLastError (errn);
		if (errn == ERROR_ACCESS_DENIED)
			errno = EPERM;
		return NULL;
	}

	*data = map->data;
	*size = large.QuadPart;
	return map;
}
p11_mmap_open (const char *path,
               struct stat *sb,
               void **data,
               size_t *size)
{
	HANDLE mapping;
	LARGE_INTEGER large;
	DWORD errn;
	p11_mmap *map;

	map = calloc (1, sizeof (p11_mmap));
	if (map == NULL) {
		errno = ENOMEM;
		return NULL;
	}

	map->file  = CreateFile (path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
	if (map->file == INVALID_HANDLE_VALUE) {
		errn = GetLastError ();
		free (map);
		SetLastError (errn);
		if (errn == ERROR_PATH_NOT_FOUND || errn == ERROR_FILE_NOT_FOUND)
			errno = ENOENT;
		else if (errn == ERROR_ACCESS_DENIED)
			errno = EPERM;
		return NULL;
	}

	if (sb == NULL) {
		if (!GetFileSizeEx (map->file, &large)) {
			errn = GetLastError ();
			CloseHandle (map->file);
			free (map);
			SetLastError (errn);
			if (errn == ERROR_ACCESS_DENIED)
				errno = EPERM;
			return NULL;
		}
	} else {
		large.QuadPart = sb->st_size;
	}

	mapping = CreateFileMapping (map->file, NULL, PAGE_READONLY, 0, 0, NULL);
	if (!mapping) {
		errn = GetLastError ();
		CloseHandle (map->file);
		free (map);
		SetLastError (errn);
		if (errn == ERROR_ACCESS_DENIED)
			errno = EPERM;
		return NULL;
	}

	map->data = MapViewOfFile (mapping, FILE_MAP_READ, 0, 0, large.QuadPart);
	CloseHandle (mapping);

	if (map->data == NULL) {
		errn = GetLastError ();
		CloseHandle (map->file);
		free (map);
		SetLastError (errn);
		if (errn == ERROR_ACCESS_DENIED)
			errno = EPERM;
		return NULL;
	}

	*data = map->data;
	*size = large.QuadPart;
	return map;
}