delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/2003/01/17/17:07:04

Mailing-List: contact cygwin-developers-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-developers-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT cygwin DOT com>
List-Help: <mailto:cygwin-developers-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-developers-owner AT cygwin DOT com
Delivered-To: mailing list cygwin-developers AT cygwin DOT com
From: "Gerald S. Williams" <gsw AT agere DOT com>
To: <cygwin-developers AT cygwin DOT com>
Subject: True case-sensitive filenames
Date: Fri, 17 Jan 2003 17:06:40 -0500
Message-ID: <GBEGLOMMCLDACBPKDIHFKEMMDAAA.gsw@agere.com>
MIME-Version: 1.0
X-Priority: 3 (Normal)
X-MSMail-Priority: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
Importance: Normal
Note-from-DJ: This may be spam

This is a multi-part message in MIME format.

------=_NextPart_000_0028_01C2BE4A.CDA44F30
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

The Perl File::Spec thread/rant/whatever on the cygwin list got
me thinking. To resolve the Windows case-insensitivity problem
(e.g., "makefile" == "Makefile"), Linda W. seemed to suggest
creating a new file system driver with a special Cygwin API.

I don't know if she really meant that or I just misinterpreted
it, but I got to thinking that something like this must already
exist for Windows. Sure enough, you can accomplish it using the
Native API. To see for myself, I created the attached test,
which creates /cygdrive/c/makefile and /cygdrive/c/Makefile.
You can even see both files from Cygwin, but when you try to
access either one, you will always get Makefile (after you
delete it, you get makefile of course).

Filenames already are case-sensitive, but the problem is in the
opening of files under Windows. This is normally done using a
case-insensitive search. The Native API function allows you to
choose and actually defaults to using case-sensitive searching.

Of course, this would only work for Windows NT/2000/XP, but I
think it should be pretty easy to make fhandler_disk_file use
case-sensitive searches when opening files. I think this would
be a big boon for Cygwin, and worth creating slightly different
behavior between NT/2000/XP and 9x/ME. We could even fall back
to case-insensitive searching by default, I suppose.

There is already some precedent for using Native API calls in
the fhandler code: fhandler_dev_raw does it.

Any interest in taking this further?

-Jerry

------=_NextPart_000_0028_01C2BE4A.CDA44F30
Content-Type: application/octet-stream;
	name="create_raw.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="create_raw.c"

#include <windows.h>=0A=
#include <ntdef.h>=0A=
#include <stdio.h>=0A=
=0A=
/* compile as follows: gcc -o create_raw create_raw.c -lntdll */=0A=
=0A=
typedef struct _IO_STATUS_BLOCK=0A=
{=0A=
  NTSTATUS Status;=0A=
  ULONG Information;=0A=
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;=0A=
=0A=
NTSTATUS NTAPI ZwCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,=0A=
			     PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,=0A=
                             ULONG, ULONG, PVOID, ULONG);=0A=
NTSTATUS NTAPI ZwClose (HANDLE);=0A=
=0A=
#define sys_mbstowcs(_t,_s,_l) =
MultiByteToWideChar(CP_ACP,0,(_s),-1,(_t),(_l))=0A=
=0A=
static void=0A=
str2buf2uni (UNICODE_STRING *tgt, WCHAR *buf, const char *srcstr)=0A=
{=0A=
  tgt->Length =3D strlen (srcstr) * sizeof (WCHAR);=0A=
  tgt->MaximumLength =3D tgt->Length + sizeof(WCHAR);=0A=
  tgt->Buffer =3D (PWCHAR) buf;=0A=
  sys_mbstowcs (buf, srcstr, tgt->MaximumLength);=0A=
}=0A=
=0A=
#define _SHARED         (FILE_SHARE_READ | FILE_SHARE_WRITE | =
FILE_SHARE_DELETE)=0A=
#define _CASE_SENSITIVE (0)=0A=
=0A=
/* NT Create CreateDisposition values */=0A=
#define FILE_SUPERSEDE				(0)=0A=
#define FILE_OPEN				(1)=0A=
#define FILE_CREATE				(2)=0A=
#define FILE_OPEN_IF				(3)=0A=
#define FILE_OVERWRITE				(4)=0A=
#define FILE_OVERWRITE_IF			(5)=0A=
/* NT Create CreateOptions bits */=0A=
#define FILE_DIRECTORY_FILE			(0x00000001)=0A=
#define FILE_WRITE_THROUGH			(0x00000002)=0A=
#define FILE_SEQUENTIAL_ONLY			(0x00000004)=0A=
#define FILE_NON_DIRECTORY_FILE			(0x00000040)=0A=
#define FILE_NO_EA_KNOWLEDGE			(0x00000200)=0A=
#define FILE_EIGHT_DOT_THREE_ONLY		(0x00000400)=0A=
#define FILE_RANDOM_ACCESS			(0x00000800)=0A=
#define FILE_DELETE_ON_CLOSE			(0x00001000)=0A=
/* NT Create SecurityFlags bits */=0A=
#define SMB_SECURITY_DYNAMIC_TRACKING	        (0x01)=0A=
#define SMB_SECURITY_EFFECTIVE_ONLY		(0x02)=0A=
/* NT Create CreateAction return values */=0A=
#define FILE_SUPERSEDED				(0)=0A=
#define FILE_OPENED				(1)=0A=
#define FILE_CREATED				(2)=0A=
#define FILE_OVERWRITTEN			(3)=0A=
#define FILE_EXISTS				(4)=0A=
#define FILE_DOES_NOT_EXIST			(5)=0A=
=0A=
#define STATUS_OBJECT_NAME_NOT_FOUND     0xC0000034=0A=
#define STATUS_OBJECT_PATH_SYNTAX_BAD    0xC000003B=0A=
=0A=
#define _ACCESS (GENERIC_READ | GENERIC_WRITE)=0A=
=0A=
int main()=0A=
{=0A=
    UNICODE_STRING dev;=0A=
    WCHAR devname[MAX_PATH + 1];=0A=
    OBJECT_ATTRIBUTES attr;=0A=
    HANDLE h;=0A=
    HANDLE hd;=0A=
    IO_STATUS_BLOCK io;=0A=
    NTSTATUS status;=0A=
=0A=
    /*=0A=
     * Create /cygdrive/c/makefile=0A=
     */=0A=
    str2buf2uni (&dev, devname, "\\??\\C:\\makefile");=0A=
    InitializeObjectAttributes (&attr, &dev, _CASE_SENSITIVE, NULL, =
NULL);=0A=
=0A=
    status =3D ZwCreateFile (&h, _ACCESS, &attr, &io, NULL, =
FILE_ATTRIBUTE_NORMAL,=0A=
                           _SHARED, FILE_OPEN_IF, =
FILE_NON_DIRECTORY_FILE,=0A=
                           NULL, 0);=0A=
=0A=
    if (!NT_SUCCESS (status))=0A=
    {=0A=
        printf("ERROR: %08lx (%08lx, %08lx)\n",=0A=
               status, io.Status, io.Information);=0A=
        return 1;=0A=
    }=0A=
=0A=
    if (!h)=0A=
    {=0A=
        printf("ERROR: no handle\n");=0A=
        return 1;=0A=
    }=0A=
=0A=
    status =3D ZwClose (h);=0A=
=0A=
    if (!NT_SUCCESS (status))=0A=
    {=0A=
        printf("ERROR: %08lx\n", status);=0A=
        return 1;=0A=
    }=0A=
=0A=
    /*=0A=
     * Create /cygdrive/c/Makefile=0A=
     */=0A=
    str2buf2uni (&dev, devname, "\\??\\C:\\Makefile");=0A=
    InitializeObjectAttributes (&attr, &dev, _CASE_SENSITIVE, NULL, =
NULL);=0A=
=0A=
    status =3D ZwCreateFile (&h, _ACCESS, &attr, &io, NULL, =
FILE_ATTRIBUTE_NORMAL,=0A=
                           _SHARED, FILE_OPEN_IF, =
FILE_NON_DIRECTORY_FILE,=0A=
                           NULL, 0);=0A=
=0A=
    if (!NT_SUCCESS (status))=0A=
    {=0A=
        printf("ERROR: %08lx (%08lx, %08lx)\n",=0A=
               status, io.Status, io.Information);=0A=
        return 1;=0A=
    }=0A=
=0A=
    if (!h)=0A=
    {=0A=
        printf("ERROR: no handle\n");=0A=
        return 1;=0A=
    }=0A=
=0A=
    status =3D ZwClose (h);=0A=
=0A=
    if (!NT_SUCCESS (status))=0A=
    {=0A=
        printf("ERROR: %08lx\n", status);=0A=
        return 1;=0A=
    }=0A=
=0A=
    return 0;=0A=
}=0A=

------=_NextPart_000_0028_01C2BE4A.CDA44F30--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019