From: mistachkin Date: Tue, 27 Jun 2017 18:15:38 +0000 (+0000) Subject: Implement xFullpath for Win32. X-Git-Tag: version-3.20.0~165^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=59b1dd3830cd1f5f53fe01b8d948971024215e03;p=thirdparty%2Fsqlite.git Implement xFullpath for Win32. FossilOrigin-Name: dbe9c8aa8d70051fafec569054eeda6c02efe9d036ab6beada00da3ed42e52d9 --- diff --git a/ext/lsm1/lsm_win32.c b/ext/lsm1/lsm_win32.c index 621b5de98b..8d9f7fd77d 100644 --- a/ext/lsm1/lsm_win32.c +++ b/ext/lsm1/lsm_win32.c @@ -45,8 +45,6 @@ struct Win32File { void **apShm; /* Array of 32K shared memory segments */ }; -int lsmWin32OsSleep(lsm_env *pEnv, int us); - static char *win32ShmFile(Win32File *p){ char *zShm; int nName = strlen(p->zName); @@ -58,6 +56,11 @@ static char *win32ShmFile(Win32File *p){ return zShm; } +static int win32Sleep(int us){ + Sleep((us + 999) / 1000); + return LSM_OK; +} + /* ** The number of times that an I/O operation will be retried following a ** locking error - probably caused by antivirus software. Also the initial @@ -115,13 +118,13 @@ static int win32RetryIoerr( } lastErrno = GetLastError(); if( win32IoerrCanRetry1(lastErrno) ){ - lsmWin32OsSleep(pEnv, win32IoerrRetryDelay*(1+*pnRetry)); + win32Sleep(win32IoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } #if defined(win32IoerrCanRetry2) else if( win32IoerrCanRetry2(lastErrno) ){ - lsmWin32OsSleep(pEnv, win32IoerrRetryDelay*(1+*pnRetry)); + win32Sleep(win32IoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } @@ -154,6 +157,31 @@ static LPWSTR win32Utf8ToUnicode(lsm_env *pEnv, const char *zText){ return zWideText; } +/* +** Convert a Microsoft Unicode string to UTF-8. +** +** Space to hold the returned string is obtained from lsmMalloc(). +*/ +static char *win32UnicodeToUtf8(lsm_env *pEnv, LPCWSTR zWideText){ + int nByte; + char *zText; + + nByte = WideCharToMultiByte(CP_UTF8, 0, zWideText, -1, 0, 0, 0, 0); + if( nByte == 0 ){ + return 0; + } + zText = lsmMallocZero(pEnv, nByte); + if( zText==0 ){ + return 0; + } + nByte = WideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, 0, 0); + if( nByte == 0 ){ + lsmFree(pEnv, zText); + zText = 0; + } + return zText; +} + #if !defined(win32IsNotFound) #define win32IsNotFound(a) (((a)==ERROR_FILE_NOT_FOUND) || \ ((a)==ERROR_PATH_NOT_FOUND)) @@ -172,7 +200,7 @@ static int lsmWin32OsOpen( if( pWin32File==0 ){ rc = LSM_NOMEM_BKPT; }else{ - LPCWSTR zConverted; + LPWSTR zConverted; int bReadonly = (flags & LSM_OPEN_READONLY); DWORD dwDesiredAccess; DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; @@ -334,13 +362,64 @@ static int lsmWin32OsRemap( return LSM_ERROR; } +static BOOL win32IsDriveLetterAndColon( + const char *zPathname +){ + return ( isalpha(zPathname[0]) && zPathname[1]==':' ); +} + static int lsmWin32OsFullpath( lsm_env *pEnv, const char *zName, char *zOut, int *pnOut ){ - return LSM_ERROR; + DWORD nByte; + void *zConverted; + LPWSTR zTempWide; + char *zTempUtf8; + + if( zName[0]=='/' && win32IsDriveLetterAndColon(zName+1) ){ + zName++; + } + zConverted = win32Utf8ToUnicode(pEnv, zName); + if( zConverted==0 ){ + return LSM_NOMEM_BKPT; + } + nByte = GetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); + if( nByte==0 ){ + lsmFree(pEnv, zConverted); + return LSM_IOERR_BKPT; + } + nByte += 3; + zTempWide = lsmMallocZero(pEnv, nByte * sizeof(zTempWide[0])); + if( zTempWide==0 ){ + lsmFree(pEnv, zConverted); + return LSM_NOMEM_BKPT; + } + nByte = GetFullPathNameW((LPCWSTR)zConverted, nByte, zTempWide, 0); + if( nByte==0 ){ + lsmFree(pEnv, zConverted); + lsmFree(pEnv, zTempWide); + return LSM_IOERR_BKPT; + } + lsmFree(pEnv, zConverted); + zTempUtf8 = win32UnicodeToUtf8(pEnv, zTempWide); + lsmFree(pEnv, zTempWide); + if( zTempUtf8 ){ + int nOut = *pnOut; + int nLen = strlen(zTempUtf8) + 1; + if( nLen>=nOut ){ + lsmFree(pEnv, zTempUtf8); + return LSM_IOERR_BKPT; + } + snprintf(zOut, nOut, "%s", zTempUtf8); + lsmFree(pEnv, zTempUtf8); + *pnOut = nLen; + return LSM_OK; + }else{ + return LSM_NOMEM_BKPT; + } } static int lsmWin32OsFileid( @@ -431,8 +510,7 @@ static int lsmWin32OsClose(lsm_file *pFile){ static int lsmWin32OsSleep(lsm_env *pEnv, int us){ unused_parameter(pEnv); - Sleep((us + 999) / 1000); - return LSM_OK; + return win32Sleep(us); } /**************************************************************************** diff --git a/manifest b/manifest index 8b249f9b49..c38929f7b1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scorrections\sto\sthe\sprevious\scheck-in. -D 2017-06-27T06:28:00.217 +C Implement\sxFullpath\sfor\sWin32. +D 2017-06-27T18:15:38.105 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d389c6fb3344ea6887b386d56784a6d8a5c85107294448aeda50ac404285a1ef @@ -248,7 +248,7 @@ F ext/lsm1/lsm_tree.c 5d9fb2bc58a1a70c75126bd8d7198f7b627e165b F ext/lsm1/lsm_unix.c ee0201dff10ce2008ef13a65f52a6ea348f287e795270f651596f812fcfccdcc F ext/lsm1/lsm_varint.c b19ae9bd26b5a1e8402fb8a564b25d9542338a41 F ext/lsm1/lsm_vtab.c fff303ce03168eca9e333add3c1429b3471674b0 -F ext/lsm1/lsm_win32.c cb130d4edfad397434ccfa5e033b6e19c10d46cad6915053071ababc67198cf3 +F ext/lsm1/lsm_win32.c fd1a47d851d1955846056df5644b6eea44912ffce56e02811e57d3daed9cdf38 F ext/misc/README.md 8e008c8d2b02e09096b31dfba033253ac27c6c06a18aa5826e299fa7601d90b2 F ext/misc/amatch.c 6db4607cb17c54b853a2d7c7c36046d004853f65b9b733e6f019d543d5dfae87 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb @@ -1623,7 +1623,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2017636e93cf810fe4d1247c18de9f316fca037035a026f77c4588563d7bf0cc -R 33974380484a54f34081aa045dcd78fa +P e1cf8a78a0bbd7b05cefab22a5c9676098887ee9811d37330ce89b3367856f92 +R 2b41b25f40e4c080242ad0e7f7bcc590 U mistachkin -Z 0a6fb032b2fe2b0d23746e9918f5e870 +Z e0848c84f070e42af46f00f70df25c0e diff --git a/manifest.uuid b/manifest.uuid index 989b71b3a8..dd51244ba2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1cf8a78a0bbd7b05cefab22a5c9676098887ee9811d37330ce89b3367856f92 \ No newline at end of file +dbe9c8aa8d70051fafec569054eeda6c02efe9d036ab6beada00da3ed42e52d9 \ No newline at end of file