mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-15 11:41:13 +03:00
Use the unicode API to win32 where available.
Tickets #1407, #1396, #1331, #1243, #1206 (CVS 2656) FossilOrigin-Name: 3ec58c673ae4cf0695ea0c287cc9bcbdcdb1a200
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C Fix\sover-aggressive\soptimization\sof\sORDER\sBY\sas\sreported\son\sthe\smailing\slist.\s(CVS\s2655)
|
||||
D 2005-09-01T17:47:51
|
||||
C Use\sthe\sunicode\sAPI\sto\swin32\swhere\savailable.\r\nTickets\s#1407,\s#1396,\s#1331,\s#1243,\s#1206\s(CVS\s2656)
|
||||
D 2005-09-05T19:08:29
|
||||
F Makefile.in 12784cdce5ffc8dfb707300c34e4f1eb3b8a14f1
|
||||
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@@ -54,7 +54,7 @@ F src/os_test.c 91e5f22dd89491e5e1554820e715805f43fa4ece
|
||||
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
||||
F src/os_unix.c b4c4592589113db088662ef7570967ec36022b5d
|
||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||
F src/os_win.c fe7b99cfcfb61d9bf54493ddf5857885a657fb89
|
||||
F src/os_win.c 8b80f418aefd2ceabe3580f680f5dcc244cf2344
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c cd9896287a8fd33cc267bd0c2b69c421a4808169
|
||||
F src/pager.h 17b13225abd93c1e9f470060f40a21b9edb5a164
|
||||
@@ -69,7 +69,7 @@ F src/sqlite.h.in d6561d51025d08de4f455607f3f9f9aa76e855d5
|
||||
F src/sqliteInt.h 845ff6f8019f80baafb1bdbb8ef80fcd04d9d0f9
|
||||
F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
|
||||
F src/tclsqlite.c ac94682f9e601dd373912c46414a5a842db2089a
|
||||
F src/test1.c ca4b959ce0a966ede87727cd8d3f5905743dfd4e
|
||||
F src/test1.c 006fafaa3456d20db37951b94c9d9becac64568e
|
||||
F src/test2.c 792f203be69fea88668fa221321194f0a28dfdfa
|
||||
F src/test3.c f4e6a16a602091696619a1171bda25c0e3df49f7
|
||||
F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f
|
||||
@@ -306,7 +306,7 @@ F www/tclsqlite.tcl 3df553505b6efcad08f91e9b975deb2e6c9bb955
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 81259a01f1e85ba50a1d017b1282bf841b16f0a5
|
||||
R 9230534585e06aeccca811dde76702e9
|
||||
P efbb4bc83cd86b6a26d58c5818c58c2e3edaab18
|
||||
R d11951b0db345c53b16225d15ddfa80a
|
||||
U drh
|
||||
Z 91850feb3a4a5d6eb41e5886f9a1b320
|
||||
Z ce91eee65efcee02daeb83c44469f09e
|
||||
|
||||
@@ -1 +1 @@
|
||||
efbb4bc83cd86b6a26d58c5818c58c2e3edaab18
|
||||
3ec58c673ae4cf0695ea0c287cc9bcbdcdb1a200
|
||||
216
src/os_win.c
216
src/os_win.c
@@ -41,11 +41,99 @@
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
|
||||
/*
|
||||
** The following variable is (normally) set once and never changes
|
||||
** thereafter. It records whether the operating system is Win95
|
||||
** or WinNT.
|
||||
**
|
||||
** 0: Operating system unknown.
|
||||
** 1: Operating system is Win95.
|
||||
** 2: Operating system is WinNT.
|
||||
**
|
||||
** In order to facilitate testing on a WinNT system, the test fixture
|
||||
** can manually set this value to 1 to emulate Win98 behavior.
|
||||
*/
|
||||
int sqlite3_os_type = 0;
|
||||
|
||||
/*
|
||||
** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
|
||||
** Return false (zero) for Win95, Win98, or WinME.
|
||||
**
|
||||
** Here is an interesting observation: Win95, Win98, and WinME lack
|
||||
** the LockFileEx() API. But we can still statically link against that
|
||||
** API as long as we don't call it win running Win95/98/ME. A call to
|
||||
** this routine is used to determine if the host is Win95/98/ME or
|
||||
** WinNT/2K/XP so that we will know whether or not we can safely call
|
||||
** the LockFileEx() API.
|
||||
*/
|
||||
static int isNT(void){
|
||||
if( sqlite3_os_type==0 ){
|
||||
OSVERSIONINFO sInfo;
|
||||
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
||||
GetVersionEx(&sInfo);
|
||||
sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
|
||||
}
|
||||
return sqlite3_os_type==2;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert a UTF-8 string to UTF-32. Space to hold the returned string
|
||||
** is obtained from sqliteMalloc.
|
||||
*/
|
||||
static WCHAR *utf8ToUnicode(const char *zFilename){
|
||||
int nByte;
|
||||
WCHAR *zWideFilename;
|
||||
|
||||
if( !isNT() ){
|
||||
return 0;
|
||||
}
|
||||
nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0)*sizeof(WCHAR);
|
||||
zWideFilename = sqliteMalloc( nByte );
|
||||
if( zWideFilename==0 ){
|
||||
return 0;
|
||||
}
|
||||
nByte = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nByte);
|
||||
if( nByte==0 ){
|
||||
sqliteFree(zWideFilename);
|
||||
zWideFilename = 0;
|
||||
}
|
||||
return zWideFilename;
|
||||
}
|
||||
|
||||
/*
|
||||
** Convert UTF-32 to UTF-8. Space to hold the returned string is
|
||||
** obtained from sqliteMalloc().
|
||||
*/
|
||||
static char *unicodeToUtf8(const WCHAR *zWideFilename){
|
||||
int nByte;
|
||||
char *zFilename;
|
||||
|
||||
nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
|
||||
zFilename = sqliteMalloc( nByte );
|
||||
if( zFilename==0 ){
|
||||
return 0;
|
||||
}
|
||||
nByte = WideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
|
||||
0, 0);
|
||||
if( nByte == 0 ){
|
||||
sqliteFree(zFilename);
|
||||
zFilename = 0;
|
||||
}
|
||||
return zFilename;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Delete the named file
|
||||
*/
|
||||
int sqlite3OsDelete(const char *zFilename){
|
||||
WCHAR *zWide = utf8ToUnicode(zFilename);
|
||||
if( zWide ){
|
||||
DeleteFileW(zWide);
|
||||
sqliteFree(zWide);
|
||||
}else{
|
||||
DeleteFileA(zFilename);
|
||||
}
|
||||
TRACE2("DELETE \"%s\"\n", zFilename);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
@@ -54,7 +142,15 @@ int sqlite3OsDelete(const char *zFilename){
|
||||
** Return TRUE if the named file exists.
|
||||
*/
|
||||
int sqlite3OsFileExists(const char *zFilename){
|
||||
return GetFileAttributesA(zFilename) != 0xffffffff;
|
||||
int exists = 0;
|
||||
WCHAR *zWide = utf8ToUnicode(zFilename);
|
||||
if( zWide ){
|
||||
exists = GetFileAttributesW(zWide) != 0xffffffff;
|
||||
sqliteFree(zWide);
|
||||
}else{
|
||||
exists = GetFileAttributesA(zFilename) != 0xffffffff;
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -76,7 +172,36 @@ int sqlite3OsOpenReadWrite(
|
||||
int *pReadonly
|
||||
){
|
||||
HANDLE h;
|
||||
WCHAR *zWide = utf8ToUnicode(zFilename);
|
||||
assert( !id->isOpen );
|
||||
if( zWide ){
|
||||
h = CreateFileW(zWide,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
h = CreateFileW(zWide,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
sqliteFree(zWide);
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
*pReadonly = 1;
|
||||
}else{
|
||||
*pReadonly = 0;
|
||||
}
|
||||
sqliteFree(zWide);
|
||||
}else{
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
@@ -101,6 +226,7 @@ int sqlite3OsOpenReadWrite(
|
||||
}else{
|
||||
*pReadonly = 0;
|
||||
}
|
||||
}
|
||||
id->h = h;
|
||||
id->locktype = NO_LOCK;
|
||||
id->sharedLockByte = 0;
|
||||
@@ -128,6 +254,7 @@ int sqlite3OsOpenReadWrite(
|
||||
int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
HANDLE h;
|
||||
int fileflags;
|
||||
WCHAR *zWide = utf8ToUnicode(zFilename);
|
||||
assert( !id->isOpen );
|
||||
if( delFlag ){
|
||||
fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
|
||||
@@ -135,6 +262,17 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
}else{
|
||||
fileflags = FILE_FLAG_RANDOM_ACCESS;
|
||||
}
|
||||
if( zWide ){
|
||||
h = CreateFileW(zWide,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
fileflags,
|
||||
NULL
|
||||
);
|
||||
sqliteFree(zWide);
|
||||
}else{
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
@@ -143,6 +281,7 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
fileflags,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
@@ -164,7 +303,19 @@ int sqlite3OsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
|
||||
*/
|
||||
int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
HANDLE h;
|
||||
WCHAR *zWide = utf8ToUnicode(zFilename);
|
||||
assert( !id->isOpen );
|
||||
if( zWide ){
|
||||
h = CreateFileW(zWide,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
sqliteFree(zWide);
|
||||
}else{
|
||||
h = CreateFileA(zFilename,
|
||||
GENERIC_READ,
|
||||
0,
|
||||
@@ -173,6 +324,7 @@ int sqlite3OsOpenReadOnly(const char *zFilename, OsFile *id){
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
if( h==INVALID_HANDLE_VALUE ){
|
||||
return SQLITE_CANTOPEN;
|
||||
}
|
||||
@@ -229,6 +381,16 @@ int sqlite3OsTempFileName(char *zBuf){
|
||||
if( sqlite3_temp_directory ){
|
||||
strncpy(zTempPath, sqlite3_temp_directory, SQLITE_TEMPNAME_SIZE-30);
|
||||
zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
|
||||
}else if( isNT() ){
|
||||
char *zMulti;
|
||||
WCHAR zWidePath[SQLITE_TEMPNAME_SIZE];
|
||||
GetTempPathW(SQLITE_TEMPNAME_SIZE-30, zWidePath);
|
||||
zMulti = unicodeToUtf8(zWidePath);
|
||||
if( zMulti ){
|
||||
memcpy(zTempPath, zMulti, SQLITE_TEMPNAME_SIZE-30);
|
||||
zTempPath[SQLITE_TEMPNAME_SIZE-30] = 0;
|
||||
sqliteFree(zMulti);
|
||||
}
|
||||
}else{
|
||||
GetTempPathA(SQLITE_TEMPNAME_SIZE-30, zTempPath);
|
||||
}
|
||||
@@ -364,28 +526,6 @@ int sqlite3OsFileSize(OsFile *id, i64 *pSize){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
|
||||
** Return false (zero) for Win95, Win98, or WinME.
|
||||
**
|
||||
** Here is an interesting observation: Win95, Win98, and WinME lack
|
||||
** the LockFileEx() API. But we can still statically link against that
|
||||
** API as long as we don't call it win running Win95/98/ME. A call to
|
||||
** this routine is used to determine if the host is Win95/98/ME or
|
||||
** WinNT/2K/XP so that we will know whether or not we can safely call
|
||||
** the LockFileEx() API.
|
||||
*/
|
||||
static int isNT(void){
|
||||
static int osType = 0; /* 0=unknown 1=win95 2=winNT */
|
||||
if( osType==0 ){
|
||||
OSVERSIONINFO sInfo;
|
||||
sInfo.dwOSVersionInfoSize = sizeof(sInfo);
|
||||
GetVersionEx(&sInfo);
|
||||
osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
|
||||
}
|
||||
return osType==2;
|
||||
}
|
||||
|
||||
/*
|
||||
** Acquire a reader lock.
|
||||
** Different API routines are called depending on whether or not this
|
||||
@@ -426,11 +566,18 @@ static int unlockReadLock(OsFile *id){
|
||||
** Check that a given pathname is a directory and is writable
|
||||
**
|
||||
*/
|
||||
int sqlite3OsIsDirWritable(char *zBuf){
|
||||
int sqlite3OsIsDirWritable(char *zDirname){
|
||||
int fileAttr;
|
||||
if(! zBuf ) return 0;
|
||||
if(! isNT() && strlen(zBuf) > MAX_PATH ) return 0;
|
||||
fileAttr = GetFileAttributesA(zBuf);
|
||||
WCHAR *zWide;
|
||||
if( zDirname==0 ) return 0;
|
||||
if( !isNT() && strlen(zDirname)>MAX_PATH ) return 0;
|
||||
zWide = utf8ToUnicode(zDirname);
|
||||
if( zWide ){
|
||||
fileAttr = GetFileAttributesW(zWide);
|
||||
sqliteFree(zWide);
|
||||
}else{
|
||||
fileAttr = GetFileAttributesA(zDirname);
|
||||
}
|
||||
if( fileAttr == 0xffffffff ) return 0;
|
||||
if( (fileAttr & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ){
|
||||
return 0;
|
||||
@@ -641,6 +788,7 @@ int sqlite3OsUnlock(OsFile *id, int locktype){
|
||||
char *sqlite3OsFullPathname(const char *zRelative){
|
||||
char *zNotUsed;
|
||||
char *zFull;
|
||||
WCHAR *zWide;
|
||||
int nByte;
|
||||
#ifdef __CYGWIN__
|
||||
nByte = strlen(zRelative) + MAX_PATH + 1001;
|
||||
@@ -648,10 +796,22 @@ char *sqlite3OsFullPathname(const char *zRelative){
|
||||
if( zFull==0 ) return 0;
|
||||
if( cygwin_conv_to_full_win32_path(zRelative, zFull) ) return 0;
|
||||
#else
|
||||
zWide = utf8ToUnicode(zRelative);
|
||||
if( zWide ){
|
||||
WCHAR *zTemp, *zNotUsedW;
|
||||
nByte = GetFullPathNameW(zWide, 0, 0, &zNotUsedW) + 1;
|
||||
zTemp = sqliteMalloc( nByte*sizeof(zTemp[0]) );
|
||||
if( zTemp==0 ) return 0;
|
||||
GetFullPathNameW(zWide, nByte, zTemp, &zNotUsedW);
|
||||
sqliteFree(zWide);
|
||||
zFull = unicodeToUtf8(zTemp);
|
||||
sqliteFree(zTemp);
|
||||
}else{
|
||||
nByte = GetFullPathNameA(zRelative, 0, 0, &zNotUsed) + 1;
|
||||
zFull = sqliteMalloc( nByte );
|
||||
zFull = sqliteMalloc( nByte*sizeof(zFull[0]) );
|
||||
if( zFull==0 ) return 0;
|
||||
GetFullPathNameA(zRelative, nByte, zFull, &zNotUsed);
|
||||
}
|
||||
#endif
|
||||
return zFull;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.158 2005/09/01 12:16:29 drh Exp $
|
||||
** $Id: test1.c,v 1.159 2005/09/05 19:08:29 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -3157,6 +3157,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
extern int sqlite3_memMax;
|
||||
extern char sqlite3_query_plan[];
|
||||
extern int sqlite3_like_count;
|
||||
#if OS_WIN
|
||||
extern int sqlite3_os_type;
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
extern int sqlite3_vdbe_addop_trace;
|
||||
#endif
|
||||
@@ -3185,6 +3188,10 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
(char*)&sqlite3_os_trace, TCL_LINK_INT);
|
||||
Tcl_LinkVar(interp, "sqlite_where_trace",
|
||||
(char*)&sqlite3_where_trace, TCL_LINK_INT);
|
||||
#if OS_WIN
|
||||
Tcl_LinkVar(interp, "sqlite_os_type",
|
||||
(char*)&sqlite3_os_type, TCL_LINK_INT);
|
||||
#endif
|
||||
#ifdef SQLITE_DEBUG
|
||||
Tcl_LinkVar(interp, "sqlite_addop_trace",
|
||||
(char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT);
|
||||
|
||||
Reference in New Issue
Block a user