|
|
@ -4140,23 +4140,31 @@ mdb_env_map(MDB_env *env, void *addr) |
|
|
|
int access = SECTION_MAP_READ; |
|
|
|
int access = SECTION_MAP_READ; |
|
|
|
HANDLE mh; |
|
|
|
HANDLE mh; |
|
|
|
void *map; |
|
|
|
void *map; |
|
|
|
SIZE_T msize = 0; |
|
|
|
SIZE_T msize; |
|
|
|
ULONG pageprot = PAGE_READONLY; |
|
|
|
ULONG pageprot = PAGE_READONLY, secprot, alloctype; |
|
|
|
|
|
|
|
|
|
|
|
if (flags & MDB_WRITEMAP) { |
|
|
|
if (flags & MDB_WRITEMAP) { |
|
|
|
access |= SECTION_MAP_WRITE; |
|
|
|
access |= SECTION_MAP_WRITE; |
|
|
|
pageprot = PAGE_READWRITE; |
|
|
|
pageprot = PAGE_READWRITE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (flags & MDB_RDONLY) { |
|
|
|
|
|
|
|
secprot = PAGE_READONLY; |
|
|
|
|
|
|
|
msize = 0; |
|
|
|
|
|
|
|
alloctype = 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
secprot = PAGE_READWRITE; |
|
|
|
|
|
|
|
msize = env->me_mapsize; |
|
|
|
|
|
|
|
alloctype = MEM_RESERVE; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rc = NtCreateSection(&mh, access, NULL, NULL, PAGE_READWRITE, SEC_RESERVE, env->me_fd); |
|
|
|
rc = NtCreateSection(&mh, access, NULL, NULL, secprot, SEC_RESERVE, env->me_fd); |
|
|
|
if (rc) |
|
|
|
if (rc) |
|
|
|
return rc; |
|
|
|
return rc; |
|
|
|
map = addr; |
|
|
|
map = addr; |
|
|
|
#ifdef MDB_VL32 |
|
|
|
#ifdef MDB_VL32 |
|
|
|
msize = 2 * env->me_psize; |
|
|
|
msize = 2 * env->me_psize; |
|
|
|
#else |
|
|
|
|
|
|
|
msize = env->me_mapsize; |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
rc = NtMapViewOfSection(mh, GetCurrentProcess(), &map, 0, 0, NULL, &msize, ViewUnmap, MEM_RESERVE, pageprot); |
|
|
|
rc = NtMapViewOfSection(mh, GetCurrentProcess(), &map, 0, 0, NULL, &msize, ViewUnmap, alloctype, pageprot); |
|
|
|
#ifdef MDB_VL32 |
|
|
|
#ifdef MDB_VL32 |
|
|
|
env->me_fmh = mh; |
|
|
|
env->me_fmh = mh; |
|
|
|
#else |
|
|
|
#else |
|
|
@ -4745,7 +4753,9 @@ mdb_env_setup_locks(MDB_env *env, char *lpath, int mode, int *excl) |
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _WIN32 |
|
|
|
wchar_t *wlpath; |
|
|
|
wchar_t *wlpath; |
|
|
|
utf8_to_utf16(lpath, -1, &wlpath, NULL); |
|
|
|
rc = utf8_to_utf16(lpath, -1, &wlpath, NULL); |
|
|
|
|
|
|
|
if (rc) |
|
|
|
|
|
|
|
return rc; |
|
|
|
env->me_lfd = CreateFileW(wlpath, GENERIC_READ|GENERIC_WRITE, |
|
|
|
env->me_lfd = CreateFileW(wlpath, GENERIC_READ|GENERIC_WRITE, |
|
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, |
|
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, |
|
|
|
FILE_ATTRIBUTE_NORMAL, NULL); |
|
|
|
FILE_ATTRIBUTE_NORMAL, NULL); |
|
|
@ -5093,7 +5103,9 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
len = OPEN_ALWAYS; |
|
|
|
len = OPEN_ALWAYS; |
|
|
|
} |
|
|
|
} |
|
|
|
mode = FILE_ATTRIBUTE_NORMAL; |
|
|
|
mode = FILE_ATTRIBUTE_NORMAL; |
|
|
|
utf8_to_utf16(dpath, -1, &wpath, NULL); |
|
|
|
rc = utf8_to_utf16(dpath, -1, &wpath, NULL); |
|
|
|
|
|
|
|
if (rc) |
|
|
|
|
|
|
|
goto leave; |
|
|
|
env->me_fd = CreateFileW(wpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE, |
|
|
|
env->me_fd = CreateFileW(wpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE, |
|
|
|
NULL, len, mode, NULL); |
|
|
|
NULL, len, mode, NULL); |
|
|
|
free(wpath); |
|
|
|
free(wpath); |
|
|
@ -5125,7 +5137,9 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _WIN32 |
|
|
|
len = OPEN_EXISTING; |
|
|
|
len = OPEN_EXISTING; |
|
|
|
utf8_to_utf16(dpath, -1, &wpath, NULL); |
|
|
|
rc = utf8_to_utf16(dpath, -1, &wpath, NULL); |
|
|
|
|
|
|
|
if (rc) |
|
|
|
|
|
|
|
goto leave; |
|
|
|
env->me_mfd = CreateFileW(wpath, oflags, |
|
|
|
env->me_mfd = CreateFileW(wpath, oflags, |
|
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len, |
|
|
|
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len, |
|
|
|
mode | FILE_FLAG_WRITE_THROUGH, NULL); |
|
|
|
mode | FILE_FLAG_WRITE_THROUGH, NULL); |
|
|
@ -5934,7 +5948,11 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) |
|
|
|
indx_t i; |
|
|
|
indx_t i; |
|
|
|
|
|
|
|
|
|
|
|
DPRINTF(("branch page %"Y"u has %u keys", mp->mp_pgno, NUMKEYS(mp))); |
|
|
|
DPRINTF(("branch page %"Y"u has %u keys", mp->mp_pgno, NUMKEYS(mp))); |
|
|
|
mdb_cassert(mc, NUMKEYS(mp) > 1); |
|
|
|
/* Don't assert on branch pages in the FreeDB. We can get here
|
|
|
|
|
|
|
|
* while in the process of rebalancing a FreeDB branch page; we must |
|
|
|
|
|
|
|
* let that proceed. ITS#8336 |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
mdb_cassert(mc, !mc->mc_dbi || NUMKEYS(mp) > 1); |
|
|
|
DPRINTF(("found index 0 to page %"Y"u", NODEPGNO(NODEPTR(mp, 0)))); |
|
|
|
DPRINTF(("found index 0 to page %"Y"u", NODEPGNO(NODEPTR(mp, 0)))); |
|
|
|
|
|
|
|
|
|
|
|
if (flags & (MDB_PS_FIRST|MDB_PS_LAST)) { |
|
|
|
if (flags & (MDB_PS_FIRST|MDB_PS_LAST)) { |
|
|
@ -7204,7 +7222,7 @@ more: |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
/* does data match? */ |
|
|
|
/* does data match? */ |
|
|
|
if (!dcmp(data, &olddata)) { |
|
|
|
if (!dcmp(data, &olddata)) { |
|
|
|
if (flags & MDB_NODUPDATA) |
|
|
|
if (flags & (MDB_NODUPDATA|MDB_APPENDDUP)) |
|
|
|
return MDB_KEYEXIST; |
|
|
|
return MDB_KEYEXIST; |
|
|
|
/* overwrite it */ |
|
|
|
/* overwrite it */ |
|
|
|
goto current; |
|
|
|
goto current; |
|
|
@ -10004,7 +10022,9 @@ mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags) |
|
|
|
* already in the OS cache. |
|
|
|
* already in the OS cache. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
#ifdef _WIN32 |
|
|
|
#ifdef _WIN32 |
|
|
|
utf8_to_utf16(lpath, -1, &wpath, NULL); |
|
|
|
rc = utf8_to_utf16(lpath, -1, &wpath, NULL); |
|
|
|
|
|
|
|
if (rc) |
|
|
|
|
|
|
|
return rc; |
|
|
|
newfd = CreateFileW(wpath, GENERIC_WRITE, 0, NULL, CREATE_NEW, |
|
|
|
newfd = CreateFileW(wpath, GENERIC_WRITE, 0, NULL, CREATE_NEW, |
|
|
|
FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL); |
|
|
|
FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL); |
|
|
|
free(wpath); |
|
|
|
free(wpath); |
|
|
@ -10199,6 +10219,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db |
|
|
|
MDB_db dummy; |
|
|
|
MDB_db dummy; |
|
|
|
int rc, dbflag, exact; |
|
|
|
int rc, dbflag, exact; |
|
|
|
unsigned int unused = 0, seq; |
|
|
|
unsigned int unused = 0, seq; |
|
|
|
|
|
|
|
char *namedup; |
|
|
|
size_t len; |
|
|
|
size_t len; |
|
|
|
|
|
|
|
|
|
|
|
if (flags & ~VALID_FLAGS) |
|
|
|
if (flags & ~VALID_FLAGS) |
|
|
@ -10260,8 +10281,16 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db |
|
|
|
MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); |
|
|
|
MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); |
|
|
|
if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) |
|
|
|
if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA) |
|
|
|
return MDB_INCOMPATIBLE; |
|
|
|
return MDB_INCOMPATIBLE; |
|
|
|
} else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) { |
|
|
|
} else if (! (rc == MDB_NOTFOUND && (flags & MDB_CREATE))) { |
|
|
|
/* Create if requested */ |
|
|
|
return rc; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Done here so we cannot fail after creating a new DB */ |
|
|
|
|
|
|
|
if ((namedup = strdup(name)) == NULL) |
|
|
|
|
|
|
|
return ENOMEM; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (rc) { |
|
|
|
|
|
|
|
/* MDB_NOTFOUND and MDB_CREATE: Create new DB */ |
|
|
|
data.mv_size = sizeof(MDB_db); |
|
|
|
data.mv_size = sizeof(MDB_db); |
|
|
|
data.mv_data = &dummy; |
|
|
|
data.mv_data = &dummy; |
|
|
|
memset(&dummy, 0, sizeof(dummy)); |
|
|
|
memset(&dummy, 0, sizeof(dummy)); |
|
|
@ -10271,10 +10300,12 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db |
|
|
|
dbflag |= DB_DIRTY; |
|
|
|
dbflag |= DB_DIRTY; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* OK, got info, add to table */ |
|
|
|
if (rc) { |
|
|
|
if (rc == MDB_SUCCESS) { |
|
|
|
free(namedup); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
/* Got info, register DBI in this txn */ |
|
|
|
unsigned int slot = unused ? unused : txn->mt_numdbs; |
|
|
|
unsigned int slot = unused ? unused : txn->mt_numdbs; |
|
|
|
txn->mt_dbxs[slot].md_name.mv_data = strdup(name); |
|
|
|
txn->mt_dbxs[slot].md_name.mv_data = namedup; |
|
|
|
txn->mt_dbxs[slot].md_name.mv_size = len; |
|
|
|
txn->mt_dbxs[slot].md_name.mv_size = len; |
|
|
|
txn->mt_dbxs[slot].md_rel = NULL; |
|
|
|
txn->mt_dbxs[slot].md_rel = NULL; |
|
|
|
txn->mt_dbflags[slot] = dbflag; |
|
|
|
txn->mt_dbflags[slot] = dbflag; |
|
|
@ -10735,6 +10766,8 @@ static int utf8_to_utf16(const char *src, int srcsize, wchar_t **dst, int *dstsi |
|
|
|
if (need == 0) |
|
|
|
if (need == 0) |
|
|
|
return EINVAL; |
|
|
|
return EINVAL; |
|
|
|
result = malloc(sizeof(wchar_t) * need); |
|
|
|
result = malloc(sizeof(wchar_t) * need); |
|
|
|
|
|
|
|
if (!result) |
|
|
|
|
|
|
|
return ENOMEM; |
|
|
|
MultiByteToWideChar(CP_UTF8, 0, src, srcsize, result, need); |
|
|
|
MultiByteToWideChar(CP_UTF8, 0, src, srcsize, result, need); |
|
|
|
if (dstsize) |
|
|
|
if (dstsize) |
|
|
|
*dstsize = need; |
|
|
|
*dstsize = need; |
|
|
|