Simplify directory checking for winOpen and add checking to winDelete.

FossilOrigin-Name: b08530e1a02cba03afefd65dc101e074e8847c07
diff --git a/manifest b/manifest
index 3527b8b..18cba5b 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Do\snot\sdo\sthe\sAV\sretry\sloop\son\sopen\sif\sthe\sfile\sthat\sis\sattempting\sto\sbe\nopened\sis\sreally\sa\sdirectory.
-D 2012-05-07T13:15:20.389
+C Simplify\sdirectory\schecking\sfor\swinOpen\sand\sadd\schecking\sto\swinDelete.
+D 2012-05-07T17:16:07.404
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -160,7 +160,7 @@
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
 F src/os_unix.c 424d46e0edab969293c2223f09923b2178171f47
-F src/os_win.c 5245515000a855dd0fe4f6e86dfe599cd7865b7b
+F src/os_win.c 412d6434133c7c81dc48b7702f3ea5e61c309e5c
 F src/pager.c bb5635dde0b152797836d1c72275284724bb563c
 F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5
 F src/parse.y eb054bb40a5bf90d3422a01ed0e5df229461727a
@@ -175,7 +175,7 @@
 F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1
 F src/select.c d7b9018b7dd2e821183d69477ab55c39b8272335
 F src/shell.c 04399b2f9942bd02ed5ffee3b84bcdb39c52a1e6
-F src/sqlite.h.in 4338f299fc83dada8407358d585c0e240ecb76a3
+F src/sqlite.h.in b8c6d77179cee6e4b8d6eb9f3c2917626d58acd3
 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
 F src/sqliteInt.h c5e917c4f1453f3972b1fd0c81105dfe4f09cc32
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
@@ -995,10 +995,7 @@
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P bfa61e781cb442be641486e7e55a1518e888d830
-R 6a3c8de48e2cdbaf71c115aca5627de9
-T *branch * win-check-dir
-T *sym-win-check-dir *
-T -sym-trunk *
-U drh
-Z 19d1e551d55fac16aea402b33644e4b5
+P 03875633f465e82fbe99829f96db25f6d32bd333
+R fce36c453dc0cfdd0c18e985348b50c5
+U mistachkin
+Z fd728781c5f339cf39ec6076396580d7
diff --git a/manifest.uuid b/manifest.uuid
index 24ae4d7..e5ce379 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-03875633f465e82fbe99829f96db25f6d32bd333
\ No newline at end of file
+b08530e1a02cba03afefd65dc101e074e8847c07
\ No newline at end of file
diff --git a/src/os_win.c b/src/os_win.c
index 0f32561..fcfe011 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -3031,27 +3031,33 @@
   return SQLITE_OK; 
 }
 
-/* Forward reference */
-static int winAccess(sqlite3_vfs*,const char*,int,int*);
-
 /*
 ** Return TRUE if the named file is really a directory.  Return false if
 ** it is something other than a directory, or if there is any kind of memory
 ** allocation failure.
 */
-static int winIsDir(sqlite3_vfs *pVfs, const char *zName){
-  int isDir = 0;
-  int rc;
-  char *zDirName;
+static int winIsDir(const void *zConverted){
+  DWORD attr;
+  int rc = 0;
+  DWORD lastErrno;
 
-  zDirName = sqlite3_mprintf("%s/nul", zName);
-  if( zDirName ){
-    rc = winAccess(pVfs, zDirName, SQLITE_ACCESS_EXISTS, &isDir);
-    sqlite3_free(zDirName);
+  if( isNT() ){
+    int cnt = 0;
+    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
+    memset(&sAttrData, 0, sizeof(sAttrData));
+    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
+                             GetFileExInfoStandard,
+                             &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){}
+    if( !rc ){
+      return 0; /* Invalid name? */
+    }
+    attr = sAttrData.dwFileAttributes;
+#if SQLITE_OS_WINCE==0
   }else{
-    rc = SQLITE_NOMEM;
+    attr = osGetFileAttributesA((char*)zConverted);
+#endif
   }
-  return rc==SQLITE_OK && isDir;
+  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
 }
 
 /*
@@ -3160,6 +3166,11 @@
     return SQLITE_IOERR_NOMEM;
   }
 
+  if( winIsDir(zConverted) ){
+    sqlite3_free(zConverted);
+    return SQLITE_CANTOPEN_ISDIR;
+  }
+
   if( isReadWrite ){
     dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
   }else{
@@ -3208,9 +3219,8 @@
                               dwShareMode, NULL,
                               dwCreationDisposition,
                               dwFlagsAndAttributes,
-                              NULL))==INVALID_HANDLE_VALUE
-        && !winIsDir(pVfs, zName)
-        && retryIoerr(&cnt, &lastErrno) ){
+                              NULL))==INVALID_HANDLE_VALUE &&
+                              retryIoerr(&cnt, &lastErrno) ){
                /* Noop */
     }
 #if SQLITE_OS_WINCE==0
@@ -3221,7 +3231,9 @@
                               dwCreationDisposition,
                               dwFlagsAndAttributes,
                               NULL))==INVALID_HANDLE_VALUE &&
-                              retryIoerr(&cnt, &lastErrno) ){}
+                              retryIoerr(&cnt, &lastErrno) ){
+               /* Noop */
+    }
 #endif
   }
 
@@ -3301,6 +3313,7 @@
 ){
   int cnt = 0;
   int rc;
+  DWORD attr;
   DWORD lastErrno;
   void *zConverted;
   UNUSED_PARAMETER(pVfs);
@@ -3312,20 +3325,50 @@
     return SQLITE_IOERR_NOMEM;
   }
   if( isNT() ){
-    rc = 1;
-    while( osGetFileAttributesW(zConverted)!=INVALID_FILE_ATTRIBUTES &&
-         (rc = osDeleteFileW(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){}
-    rc = rc ? SQLITE_OK : SQLITE_ERROR;
+    do {
+      attr = osGetFileAttributesW(zConverted);
+      if ( attr==INVALID_FILE_ATTRIBUTES ){
+        rc = SQLITE_OK; /* Already gone? */
+        break;
+      }
+      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
+        rc = SQLITE_ERROR; /* Files only. */
+        break;
+      }
+      if ( osDeleteFileW(zConverted) ){
+        rc = SQLITE_OK; /* Deleted OK. */
+        break;
+      }
+      if ( !retryIoerr(&cnt, &lastErrno) ){
+        rc = SQLITE_ERROR; /* No more retries. */
+        break;
+      }
+    } while(1);
 /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
 ** Since the ANSI version of these Windows API do not exist for WINCE,
 ** it's important to not reference them for WINCE builds.
 */
 #if SQLITE_OS_WINCE==0
   }else{
-    rc = 1;
-    while( osGetFileAttributesA(zConverted)!=INVALID_FILE_ATTRIBUTES &&
-         (rc = osDeleteFileA(zConverted))==0 && retryIoerr(&cnt, &lastErrno) ){}
-    rc = rc ? SQLITE_OK : SQLITE_ERROR;
+    do {
+      attr = osGetFileAttributesA(zConverted);
+      if ( attr==INVALID_FILE_ATTRIBUTES ){
+        rc = SQLITE_OK; /* Already gone? */
+        break;
+      }
+      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
+        rc = SQLITE_ERROR; /* Files only. */
+        break;
+      }
+      if ( osDeleteFileA(zConverted) ){
+        rc = SQLITE_OK; /* Deleted OK. */
+        break;
+      }
+      if ( !retryIoerr(&cnt, &lastErrno) ){
+        rc = SQLITE_ERROR; /* No more retries. */
+        break;
+      }
+    } while(1);
 #endif
   }
   if( rc ){
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index d10ddaa..655f8d2 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -453,6 +453,7 @@
 #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
 #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
+#define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
 #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))