Release 961102

Sat Nov  2 12:50:40 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/dos_fs.c]
	Added long file name mask in DOSFS_FindNext().

	* [loader/pe_image.c] [loader/task.c]
	Moved Win32 task startup into TASK_CallToStart().

	* [objects/dc.c]
	Fixed SetDCState() for memory DC (thanks to Constantine
	Sapuntzakis for spotting this one).

	* [windows/winpos.c]
	Fixed WINPOS_ForceXWindowRaise() to preserve correct Z-order.

	* [*/*]
	Added Win32 version for many graphics functions.

Thu Oct 31 10:00:18 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>

	* [controls/button.c]
	BUTTON_CheckAutoRadioButton() unchecks only auto radio buttons.

	* [controls/edit.c]
	EM_GETSEL result should have HIWORD(result) >= LOWORD(result); old
	EDIT_EM_GetSel() renamed to EDIT_GetSel(). 

	* [windows/dialog.c]
	DS_LOCALEDIT is a dialog style not an edit style.

	* [windows/winproc.c]
	Stop stack trashing when wndPtr->text == NULL.

Tue Oct 29 23:35:04 1996   Constantine P Sapuntzakis <csapuntz@mit.edu>

	* [windows/dce.c]
	GetDCEx32 - The determination of whether to use the DC cache or
 	not should be independent of DCX_USESTYLE.

Sat Oct 26 17:31:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [files/directory.c]
	Added errno.h to #includes

	* [tools/makedep.c]
	Close files once they have been processed.
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 4ed1544..3e3c8dc 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -244,11 +244,11 @@
 
 
 /***********************************************************************
- *           DOSFS_Match
+ *           DOSFS_MatchShort
  *
  * Check a DOS file name against a mask (both in FCB format).
  */
-int DOSFS_Match( const char *mask, const char *name )
+static int DOSFS_MatchShort( const char *mask, const char *name )
 {
     int i;
     for (i = 11; i > 0; i--, mask++, name++)
@@ -258,6 +258,40 @@
 
 
 /***********************************************************************
+ *           DOSFS_MatchLong
+ *
+ * Check a long file name against a mask.
+ */
+static int DOSFS_MatchLong( const char *mask, const char *name,
+                            int case_sensitive )
+{
+    while (*name && *mask)
+    {
+        if (*mask == '*')
+        {
+            mask++;
+            while (*mask == '*') mask++;  /* Skip consecutive '*' */
+            if (!*mask) return 1;
+            if (case_sensitive) while (*name && (*name != *mask)) name++;
+            else while (*name && (toupper(*name) != toupper(*mask))) name++;
+            if (!*name) return 0;
+        }
+        else if (*mask != '?')
+        {
+            if (case_sensitive)
+            {
+                if (*mask != *name) return 0;
+            }
+            else if (toupper(*mask) != toupper(*name)) return 0;
+        }
+        mask++;
+        name++;
+    }
+    return (!*name && !*mask);
+}
+
+
+/***********************************************************************
  *           DOSFS_ToDosDateTime
  *
  * Convert a Unix time in the DOS date/time format.
@@ -274,6 +308,31 @@
 
 
 /***********************************************************************
+ *           DOSFS_UnixTimeToFileTime
+ *
+ * Convert a Unix time to FILETIME format.
+ */
+void DOSFS_UnixTimeToFileTime( time_t unixtime, FILETIME *filetime )
+{
+    /* FIXME :-) */
+    filetime->dwLowDateTime  = unixtime;
+    filetime->dwHighDateTime = 0;
+}
+
+
+/***********************************************************************
+ *           DOSFS_FileTimeToUnixTime
+ *
+ * Convert a FILETIME format to Unix time.
+ */
+time_t DOSFS_FileTimeToUnixTime( FILETIME *filetime )
+{
+    /* FIXME :-) */
+    return filetime->dwLowDateTime;
+}
+
+
+/***********************************************************************
  *           DOSFS_Hash
  *
  * Transform a Unix file name into a hashed DOS name. If the name is a valid
@@ -665,9 +724,12 @@
  *
  * Find the next matching file. Return the number of entries read to find
  * the matching one, or 0 if no more entries.
+ * 'short_mask' is the 8.3 mask (in FCB format), 'long_mask' is the long
+ * file name mask. Either or both can be NULL.
  */
-int DOSFS_FindNext( const char *path, const char *mask, int drive,
-                    BYTE attr, int skip, DOS_DIRENT *entry )
+int DOSFS_FindNext( const char *path, const char *short_mask,
+                    const char *long_mask, int drive, BYTE attr,
+                    int skip, DOS_DIRENT *entry )
 {
     static DIR *dir = NULL;
     struct dirent *dirent;
@@ -714,20 +776,38 @@
     p = buffer + strlen(buffer);
     attr |= FA_UNUSED | FA_ARCHIVE | FA_RDONLY;
     flags = DRIVE_GetFlags( drive );
+    hash_name = NULL;
 
     while ((dirent = readdir( dir )) != NULL)
     {
         if (skip-- > 0) continue;
         count++;
-        hash_name = DOSFS_Hash( dirent->d_name, TRUE,
-                                !(flags & DRIVE_CASE_SENSITIVE) );
-        if (!DOSFS_Match( mask, hash_name )) continue;
+
         /* Don't return '.' and '..' in the root of the drive */
         if (drive_root && (dirent->d_name[0] == '.') &&
             (!dirent->d_name[1] ||
              ((dirent->d_name[1] == '.') && !dirent->d_name[2]))) continue;
-        lstrcpyn32A( p, dirent->d_name, sizeof(buffer) - (int)(p - buffer) );
 
+        /* Check the long mask */
+
+        if (long_mask)
+        {
+            if (!DOSFS_MatchLong( long_mask, dirent->d_name,
+                                  flags & DRIVE_CASE_SENSITIVE )) continue;
+        }
+
+        /* Check the short mask */
+
+        if (short_mask)
+        {
+            hash_name = DOSFS_Hash( dirent->d_name, TRUE,
+                                    !(flags & DRIVE_CASE_SENSITIVE) );
+            if (!DOSFS_MatchShort( short_mask, hash_name )) continue;
+        }
+
+        /* Check the file attributes */
+
+        lstrcpyn32A( p, dirent->d_name, sizeof(buffer) - (int)(p - buffer) );
         if (!FILE_Stat( buffer, &entry->attr, &entry->size,
                         &entry->date, &entry->time ))
         {
@@ -735,6 +815,12 @@
             continue;
         }
         if (entry->attr & ~attr) continue;
+
+        /* We now have a matching entry; fill the result and return */
+
+        if (!hash_name)
+            hash_name = DOSFS_Hash( dirent->d_name, TRUE,
+                                    !(flags & DRIVE_CASE_SENSITIVE) );
         strcpy( entry->name, hash_name );
         lstrcpyn32A( entry->unixname, dirent->d_name, sizeof(entry->unixname));
         if (!(flags & DRIVE_CASE_PRESERVING)) AnsiLower( entry->unixname );
@@ -778,6 +864,7 @@
     return strlen(dostruename);
 }
 
+
 /***********************************************************************
  *           GetFullPathNameA   (KERNEL32.272)
  */