Ignore:
Timestamp:
Aug 10, 2001, 9:32:30 PM (24 years ago)
Author:
sandervl
Message:

minor updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/Fileio.cpp

    r6199 r6511  
    1 /* $Id: Fileio.cpp,v 1.51 2001-07-07 13:58:36 sandervl Exp $ */
     1/* $Id: Fileio.cpp,v 1.52 2001-08-10 19:32:23 sandervl Exp $ */
    22
    33/*
     
    3939ODINDEBUGCHANNEL(KERNEL32-FILEIO)
    4040
     41#include <ctype.h>
     42#include "fileio.h"
     43
     44#if 0
     45#define IS_END_OF_NAME(ch)  (!(ch) || ((ch) == '/') || ((ch) == '\\'))
     46#define INVALID_DOS_CHARS  "*?<>|\"+=,;[] \345"
     47#define FILE_toupper(a)         toupper(a)
     48#define FILE_tolower(a)         tolower(a)
     49
     50/***********************************************************************
     51 *           DOSFS_ValidDOSName
     52 *
     53 * Return 1 if Unix file 'name' is also a valid MS-DOS name
     54 * (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format).
     55 * File name can be terminated by '\0', '\\' or '/'.
     56 */
     57static int DOSFS_ValidDOSName( const char *name, int ignore_case )
     58{
     59    static const char invalid_chars[] = INVALID_DOS_CHARS;
     60    const char *p = name;
     61    const char *invalid = ignore_case ? (invalid_chars + 26) : invalid_chars;
     62    int len = 0;
     63
     64    if (*p == '.')
     65    {
     66        /* Check for "." and ".." */
     67        p++;
     68        if (*p == '.') p++;
     69        /* All other names beginning with '.' are invalid */
     70        return (IS_END_OF_NAME(*p));
     71    }
     72    while (!IS_END_OF_NAME(*p))
     73    {
     74        if (strchr( invalid, *p )) return 0;  /* Invalid char */
     75        if (*p == '.') break;  /* Start of the extension */
     76        if (++len > 8) return 0;  /* Name too long */
     77        p++;
     78    }
     79    if (*p != '.') return 1;  /* End of name */
     80    p++;
     81    if (IS_END_OF_NAME(*p)) return 0;  /* Empty extension not allowed */
     82    len = 0;
     83    while (!IS_END_OF_NAME(*p))
     84    {
     85        if (strchr( invalid, *p )) return 0;  /* Invalid char */
     86        if (*p == '.') return 0;  /* Second extension not allowed */
     87        if (++len > 3) return 0;  /* Extension too long */
     88        p++;
     89    }
     90    return 1;
     91}
     92
     93/***********************************************************************
     94 *           DOSFS_Hash
     95 *
     96 * Transform a Unix file name into a hashed DOS name. If the name is a valid
     97 * DOS name, it is converted to upper-case; otherwise it is replaced by a
     98 * hashed version that fits in 8.3 format.
     99 * File name can be terminated by '\0', '\\' or '/'.
     100 * 'buffer' must be at least 13 characters long.
     101 */
     102void DOSFS_Hash( LPCSTR name, LPSTR buffer, BOOL dir_format,
     103                 BOOL ignore_case )
     104{
     105    static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
     106    static const char hash_chars[33] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
     107
     108    const char *p, *ext;
     109    char *dst;
     110    unsigned short hash;
     111    int i;
     112
     113    if (dir_format) strcpy( buffer, "           " );
     114
     115    if (DOSFS_ValidDOSName( name, ignore_case ))
     116    {
     117        /* Check for '.' and '..' */
     118        if (*name == '.')
     119        {
     120            buffer[0] = '.';
     121            if (!dir_format) buffer[1] = buffer[2] = '\0';
     122            if (name[1] == '.') buffer[1] = '.';
     123            return;
     124        }
     125
     126        /* Simply copy the name, converting to uppercase */
     127
     128        for (dst = buffer; !IS_END_OF_NAME(*name) && (*name != '.'); name++)
     129            *dst++ = FILE_toupper(*name);
     130        if (*name == '.')
     131        {
     132            if (dir_format) dst = buffer + 8;
     133            else *dst++ = '.';
     134            for (name++; !IS_END_OF_NAME(*name); name++)
     135                *dst++ = FILE_toupper(*name);
     136        }
     137        if (!dir_format) *dst = '\0';
     138        return;
     139    }
     140
     141    /* Compute the hash code of the file name */
     142    /* If you know something about hash functions, feel free to */
     143    /* insert a better algorithm here... */
     144    if (ignore_case)
     145    {
     146        for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
     147            hash = (hash<<3) ^ (hash>>5) ^ FILE_tolower(*p) ^ (FILE_tolower(p[1]) << 8);
     148        hash = (hash<<3) ^ (hash>>5) ^ FILE_tolower(*p); /* Last character*/
     149    }
     150    else
     151    {
     152        for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
     153            hash = (hash << 3) ^ (hash >> 5) ^ *p ^ (p[1] << 8);
     154        hash = (hash << 3) ^ (hash >> 5) ^ *p;  /* Last character */
     155    }
     156
     157    /* Find last dot for start of the extension */
     158    for (p = name+1, ext = NULL; !IS_END_OF_NAME(*p); p++)
     159        if (*p == '.') ext = p;
     160    if (ext && IS_END_OF_NAME(ext[1]))
     161        ext = NULL;  /* Empty extension ignored */
     162
     163    /* Copy first 4 chars, replacing invalid chars with '_' */
     164    for (i = 4, p = name, dst = buffer; i > 0; i--, p++)
     165    {
     166        if (IS_END_OF_NAME(*p) || (p == ext)) break;
     167        *dst++ = strchr( invalid_chars, *p ) ? '_' : FILE_toupper(*p);
     168    }
     169    /* Pad to 5 chars with '~' */
     170    while (i-- >= 0) *dst++ = '~';
     171
     172    /* Insert hash code converted to 3 ASCII chars */
     173    *dst++ = hash_chars[(hash >> 10) & 0x1f];
     174    *dst++ = hash_chars[(hash >> 5) & 0x1f];
     175    *dst++ = hash_chars[hash & 0x1f];
     176
     177    /* Copy the first 3 chars of the extension (if any) */
     178    if (ext)
     179    {
     180        if (!dir_format) *dst++ = '.';
     181        for (i = 3, ext++; (i > 0) && !IS_END_OF_NAME(*ext); i--, ext++)
     182            *dst++ = strchr( invalid_chars, *ext ) ? '_' : FILE_toupper(*ext);
     183    }
     184    if (!dir_format) *dst = '\0';
     185}
     186#endif
    41187//******************************************************************************
    42188//******************************************************************************
     
    593739              LPCSTR, lpszFileName)
    594740{
    595  DWORD rc, error;
     741    DWORD rc, error;
    596742
    597743    if((NULL!=lpszFileName) && strlen(lpszFileName)==2 && lpszFileName[1] == ':')
     
    605751    }
    606752    else {
    607   rc = O32_GetFileAttributes((LPSTR)lpszFileName);
    608   if(rc == -1 && lpszFileName[strlen(lpszFileName)-1] != '\\') {
    609     char *filename = (char *)alloca(strlen(lpszFileName)+2); //+2!!!!!!
    610     strcpy(filename, lpszFileName);
    611                 strcat(filename, "\\");
    612     rc = O32_GetFileAttributes((LPSTR)filename);
    613   }
     753        rc = O32_GetFileAttributes((LPSTR)lpszFileName);
     754        if(rc == -1 && lpszFileName[strlen(lpszFileName)-1] != '\\') {
     755            char *filename = (char *)alloca(strlen(lpszFileName)+2); //+2!!!!!!
     756            strcpy(filename, lpszFileName);
     757            strcat(filename, "\\");
     758            rc = O32_GetFileAttributes((LPSTR)filename);
     759        }
    614760    }
    615761    //SvL: Open32 returns FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_NORMAL for
    616762    //     directories whereas NT 4 (SP6) only returns FILE_ATTRIBUTE_DIRECTORY
    617763    if(rc != -1 && (rc & FILE_ATTRIBUTE_DIRECTORY)) {
    618   rc = FILE_ATTRIBUTE_DIRECTORY;
     764        rc = FILE_ATTRIBUTE_DIRECTORY;
    619765    }
    620766
     
    11581304              DWORD, dwNotifyFilter)
    11591305{
    1160   dprintf(("KERNEL32:  FindFirstChangeNotificationA, Not implemented (faked)\n"));
     1306  dprintf(("KERNEL32:  FindFirstChangeNotificationA %s, Not implemented (faked)", lpPathName));
    11611307  return -1;
    11621308}
Note: See TracChangeset for help on using the changeset viewer.