Konstantin Petrov wrote:
(Patch Edited)
There were the problem while I advert to dosdevices through WINE. I made the test (Windows vs Wine), which shows that in Windows there are available dosdevices-files (such as NUL, COM1, COM2,.., LPT1, ..), and in Wine aren't. The characteristic property of these files is that I can advert to them only directly. In other cases they are invisible.

patch for FinFrstFileExW

changelog
        file.c: fixed FindFirstFileExW for correct work with dosdevices.
HI Konstantin,

a couple of comments on your patch


------------------------------------------------------------------------

Fix dosdevice finding (by [EMAIL PROTECTED])

Index: dlls/kernel/file.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/file.c,v
retrieving revision 1.51
diff -u -p -u -r1.51 file.c
--- dlls/kernel/file.c  3 Apr 2006 19:46:58 -0000       1.51
+++ dlls/kernel/file.c  5 Apr 2006 05:43:28 -0000
@@ -1552,7 +1553,9 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR OBJECT_ATTRIBUTES attr;
     IO_STATUS_BLOCK io;
     NTSTATUS status;
+    ULONG dos_device;
+ TRACE("%s %d %p %d %p %lx\n", debugstr_w(filename), level, data, search_op, filter, flags); if ((search_op != FindExSearchNameMatch && search_op != FindExSearchLimitToDirectories) @@ -1575,8 +1578,74 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR if (!mask || !*mask)
     {
-        SetLastError( ERROR_FILE_NOT_FOUND );
-        goto error;
+        if(!mask && (dos_device = RtlIsDosDeviceName_U( filename )))
+        {
+            WIN32_FIND_DATAW *d = data;  //create file's attribute structure
+
+
+            /*LOWORD(dos_device) - quantity of symbols in the DOS device name 
(NUL, LPT1,...)
+              filename + HIWORD(dos_device) - points to the Dos device name's 
beginning */
+            if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info))))
+             {
+                SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+                goto error;
+             }
+
+            info->mask.Length = LOWORD(dos_device); /* in bytes, not in WCHAR; 
as USHORT Length */
+            info->mask.MaximumLength = nt_name.Length + sizeof(WCHAR);
+            info->mask.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, 
info->mask.MaximumLength);
+            memcpy( info->mask.Buffer, filename + 
HIWORD(dos_device)/sizeof(WCHAR), info->mask.Length);
+            info->mask.Buffer[info->mask.Length/sizeof(WCHAR)] = 0;  /* with 
'/' */
+
+            nt_name.Length = 4*sizeof(WCHAR) + HIWORD(dos_device);
+            nt_name.MaximumLength = nt_name.Length + sizeof(WCHAR);  /* + '0' 
at the end */
+            nt_name.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, 
nt_name.MaximumLength);
+            nt_name.Buffer[0] = '\\'; /* convert to NT' style path */
+            nt_name.Buffer[1] = nt_name.Buffer[2] = '?';
+            nt_name.Buffer[3] = '\\';
+            memcpy( (void *)(nt_name.Buffer + 4), filename, 
HIWORD(dos_device));
+            nt_name.Buffer[nt_name.Length/sizeof(WCHAR)] = 0; /* with '/' */
+
+            /* check if pftLastAccessTimeath is the root of the drive */
+            info->is_root = FALSE;
+
+            attr.Length = sizeof(attr);
+            attr.RootDirectory = 0;
+            attr.Attributes = OBJ_CASE_INSENSITIVE;
+            attr.ObjectName = &nt_name;
+            attr.SecurityDescriptor = NULL;
+            attr.SecurityQualityOfService = NULL;
+
+            /* check if nt_name is existing directory */
+            status = NtOpenFile( &info->handle, GENERIC_READ, &attr, &io,
+                                 FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                 FILE_DIRECTORY_FILE | 
FILE_SYNCHRONOUS_IO_NONALERT );
+
+            if (status != STATUS_SUCCESS)
+            {
+                RtlFreeUnicodeString( &info->mask );
+                SetLastError( RtlNtStatusToDosError(status) );
+                goto error;
+            }
+
+            RtlInitializeCriticalSection( &info->cs );
+            info->path     = nt_name;
+            info->magic    = FIND_FIRST_MAGIC;
+            info->data_pos = 0;
+            info->data_len = 0;
+            info->search_op = search_op;
+
+            memset(d, 0, sizeof(*d));
+            d->dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE;
+            memcpy( d->cFileName, filename + HIWORD(dos_device)/sizeof(WCHAR), 
LOWORD(dos_device));
+
+            return (HANDLE)info;
+        }
+        else
+        {
+            SetLastError( ERROR_FILE_NOT_FOUND );
+            goto error;
+        }
     }
most of the code here is rather close to the rest of the function, so you should try to factorize the two paths into a single one

if (!(info = HeapAlloc( GetProcessHeap(), 0, sizeof(*info)))) @@ -1612,6 +1681,7 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR attr.SecurityDescriptor = NULL;
     attr.SecurityQualityOfService = NULL;
+ /* check if nt_name is existing directory */
     status = NtOpenFile( &info->handle, GENERIC_READ, &attr, &io,
                          FILE_SHARE_READ | FILE_SHARE_WRITE,
                          FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
@@ -1819,6 +1889,14 @@ HANDLE WINAPI FindFirstFileExA( LPCSTR l
     FILE_name_WtoA( dataW.cFileName, -1, dataA->cFileName, 
sizeof(dataA->cFileName) );
     FILE_name_WtoA( dataW.cAlternateFileName, -1, dataA->cAlternateFileName,
                     sizeof(dataA->cAlternateFileName) );
+/******************************************************
+*                                                     *
+* In Windows fields dataA->dwReserved0 = 0x003D4830   *
+*               and dataA->dwReserved1 = 0x000000CC   *
+* But here these fields are not initialized and used  *
+*                                                     *
+******************************************************/
there's no need for this comment, unless you document what those fields are in real windows
+
     return handle;
 }


--
Eric Pouech



Reply via email to