Changeset 6511 for trunk/src/kernel32/Fileio.cpp
- Timestamp:
- Aug 10, 2001, 9:32:30 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/Fileio.cpp
r6199 r6511 1 /* $Id: Fileio.cpp,v 1.5 1 2001-07-07 13:58:36sandervl Exp $ */1 /* $Id: Fileio.cpp,v 1.52 2001-08-10 19:32:23 sandervl Exp $ */ 2 2 3 3 /* … … 39 39 ODINDEBUGCHANNEL(KERNEL32-FILEIO) 40 40 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 */ 57 static 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 */ 102 void 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 41 187 //****************************************************************************** 42 188 //****************************************************************************** … … 593 739 LPCSTR, lpszFileName) 594 740 { 595 DWORD rc, error;741 DWORD rc, error; 596 742 597 743 if((NULL!=lpszFileName) && strlen(lpszFileName)==2 && lpszFileName[1] == ':') … … 605 751 } 606 752 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 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 } 614 760 } 615 761 //SvL: Open32 returns FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_NORMAL for 616 762 // directories whereas NT 4 (SP6) only returns FILE_ATTRIBUTE_DIRECTORY 617 763 if(rc != -1 && (rc & FILE_ATTRIBUTE_DIRECTORY)) { 618 rc = FILE_ATTRIBUTE_DIRECTORY;764 rc = FILE_ATTRIBUTE_DIRECTORY; 619 765 } 620 766 … … 1158 1304 DWORD, dwNotifyFilter) 1159 1305 { 1160 dprintf(("KERNEL32: FindFirstChangeNotificationA , Not implemented (faked)\n"));1306 dprintf(("KERNEL32: FindFirstChangeNotificationA %s, Not implemented (faked)", lpPathName)); 1161 1307 return -1; 1162 1308 }
Note:
See TracChangeset
for help on using the changeset viewer.