Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendos8dot3.c
Go to the documentation of this file.
00001 /* COPYRIGHT: See COPYING in the top level directory 00002 * PROJECT: ReactOS system libraries 00003 * FILE: lib/rtl/dos8dot3.c 00004 * PURPOSE: Short name (8.3 name) functions 00005 * PROGRAMMER: Eric Kohl 00006 */ 00007 00008 /* INCLUDES ******************************************************************/ 00009 00010 #include <rtl.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 00016 /* CONSTANTS *****************************************************************/ 00017 00018 const PCHAR RtlpShortIllegals = ";+=[],\"*\\<>/?:|"; 00019 00020 00021 /* FUNCTIONS *****************************************************************/ 00022 00023 static BOOLEAN 00024 RtlpIsShortIllegal(CHAR Char) 00025 { 00026 return strchr(RtlpShortIllegals, Char) ? TRUE : FALSE; 00027 } 00028 00029 static USHORT 00030 RtlpGetCheckSum(PUNICODE_STRING Name) 00031 { 00032 USHORT Hash = 0; 00033 ULONG Length; 00034 PWCHAR c; 00035 00036 Length = Name->Length / sizeof(WCHAR); 00037 c = Name->Buffer; 00038 while(Length--) 00039 { 00040 Hash = (Hash + (*c << 4) + (*c >> 4)) * 11; 00041 c++; 00042 } 00043 return Hash; 00044 } 00045 00046 static ULONG 00047 RtlpGetIndexLength(ULONG Index) 00048 { 00049 ULONG Length = 0; 00050 while (Index) 00051 { 00052 Index /= 10; 00053 Length++; 00054 } 00055 return Length ? Length : 1; 00056 } 00057 00058 00059 /* 00060 * @implemented 00061 */ 00062 VOID NTAPI 00063 RtlGenerate8dot3Name(IN PUNICODE_STRING Name, 00064 IN BOOLEAN AllowExtendedCharacters, 00065 IN OUT PGENERATE_NAME_CONTEXT Context, 00066 OUT PUNICODE_STRING Name8dot3) 00067 { 00068 ULONG Count; 00069 WCHAR NameBuffer[8]; 00070 WCHAR ExtBuffer[4]; 00071 ULONG StrLength; 00072 ULONG NameLength; 00073 ULONG ExtLength; 00074 ULONG CopyLength; 00075 ULONG DotPos; 00076 ULONG i, j; 00077 ULONG IndexLength; 00078 ULONG CurrentIndex; 00079 USHORT Checksum; 00080 CHAR c; 00081 00082 StrLength = Name->Length / sizeof(WCHAR); 00083 DPRINT("StrLength: %lu\n", StrLength); 00084 00085 /* Find last dot in Name */ 00086 DotPos = StrLength; 00087 for (i = 0; i < StrLength; i++) 00088 { 00089 if (Name->Buffer[i] == L'.') 00090 { 00091 DotPos = i; 00092 } 00093 } 00094 00095 DPRINT("DotPos: %lu\n", DotPos); 00096 00097 /* Copy name (6 valid characters max) */ 00098 for (i = 0, NameLength = 0; NameLength < 6 && i < DotPos; i++) 00099 { 00100 c = 0; 00101 RtlUpcaseUnicodeToOemN(&c, sizeof(CHAR), &Count, &Name->Buffer[i], sizeof(WCHAR)); 00102 if (Count != 1 || c == 0 || RtlpIsShortIllegal(c)) 00103 { 00104 NameBuffer[NameLength++] = L'_'; 00105 } 00106 else if (c != '.' && c != ' ') 00107 { 00108 NameBuffer[NameLength++] = (WCHAR)c; 00109 } 00110 } 00111 00112 DPRINT("NameBuffer: '%.08S'\n", NameBuffer); 00113 DPRINT("NameLength: %lu\n", NameLength); 00114 00115 /* Copy extension (4 valid characters max) */ 00116 if (DotPos < StrLength) 00117 { 00118 for (i = DotPos, ExtLength = 0; ExtLength < 4 && i < StrLength; i++) 00119 { 00120 c = 0; 00121 RtlUpcaseUnicodeToOemN(&c, sizeof(CHAR), &Count, &Name->Buffer[i], sizeof(WCHAR)); 00122 if (Count != 1 || c == 0 || RtlpIsShortIllegal(c)) 00123 { 00124 ExtBuffer[ExtLength++] = L'_'; 00125 } 00126 else if (c != ' ') 00127 { 00128 ExtBuffer[ExtLength++] = c; 00129 } 00130 } 00131 } 00132 else 00133 { 00134 ExtLength = 0; 00135 } 00136 DPRINT("ExtBuffer: '%.04S'\n", ExtBuffer); 00137 DPRINT("ExtLength: %lu\n", ExtLength); 00138 00139 /* Determine next index */ 00140 IndexLength = RtlpGetIndexLength(Context->LastIndexValue); 00141 if (Context->CheckSumInserted) 00142 { 00143 CopyLength = min(NameLength, 8 - 4 - 1 - IndexLength); 00144 Checksum = RtlpGetCheckSum(Name); 00145 } 00146 else 00147 { 00148 CopyLength = min(NameLength, 8 - 1 - IndexLength); 00149 Checksum = 0; 00150 } 00151 00152 DPRINT("CopyLength: %lu\n", CopyLength); 00153 00154 if ((Context->NameLength == CopyLength) && 00155 (wcsncmp(Context->NameBuffer, NameBuffer, CopyLength) == 0) && 00156 (Context->ExtensionLength == ExtLength) && 00157 (wcsncmp(Context->ExtensionBuffer, ExtBuffer, ExtLength) == 0) && 00158 (Checksum == Context->Checksum) && 00159 (Context->LastIndexValue < 999)) 00160 { 00161 Context->LastIndexValue++; 00162 if (Context->CheckSumInserted == FALSE && 00163 Context->LastIndexValue > 9) 00164 { 00165 Context->CheckSumInserted = TRUE; 00166 Context->LastIndexValue = 1; 00167 Context->Checksum = RtlpGetCheckSum(Name); 00168 } 00169 } 00170 else 00171 { 00172 Context->LastIndexValue = 1; 00173 Context->CheckSumInserted = FALSE; 00174 } 00175 00176 IndexLength = RtlpGetIndexLength(Context->LastIndexValue); 00177 00178 DPRINT("CurrentIndex: %lu, IndexLength %lu\n", Context->LastIndexValue, IndexLength); 00179 00180 if (Context->CheckSumInserted) 00181 { 00182 CopyLength = min(NameLength, 8 - 4 - 1 - IndexLength); 00183 } 00184 else 00185 { 00186 CopyLength = min(NameLength, 8 - 1 - IndexLength); 00187 } 00188 00189 /* Build the short name */ 00190 memcpy(Name8dot3->Buffer, NameBuffer, CopyLength * sizeof(WCHAR)); 00191 j = CopyLength; 00192 if (Context->CheckSumInserted) 00193 { 00194 j += 3; 00195 Checksum = Context->Checksum; 00196 for (i = 0; i < 4; i++) 00197 { 00198 Name8dot3->Buffer[j--] = (Checksum % 16) > 9 ? (Checksum % 16) + L'A' - 10 : (Checksum % 16) + L'0'; 00199 Checksum /= 16; 00200 } 00201 j = CopyLength + 4; 00202 } 00203 Name8dot3->Buffer[j++] = L'~'; 00204 j += IndexLength - 1; 00205 CurrentIndex = Context->LastIndexValue; 00206 for (i = 0; i < IndexLength; i++) 00207 { 00208 Name8dot3->Buffer[j--] = (CurrentIndex % 10) + L'0'; 00209 CurrentIndex /= 10; 00210 } 00211 j += IndexLength + 1; 00212 00213 memcpy(Name8dot3->Buffer + j, ExtBuffer, ExtLength * sizeof(WCHAR)); 00214 Name8dot3->Length = (USHORT)(j + ExtLength) * sizeof(WCHAR); 00215 00216 DPRINT("Name8dot3: '%wZ'\n", Name8dot3); 00217 00218 /* Update context */ 00219 Context->NameLength = (UCHAR)CopyLength; 00220 Context->ExtensionLength = ExtLength; 00221 memcpy(Context->NameBuffer, NameBuffer, CopyLength * sizeof(WCHAR)); 00222 memcpy(Context->ExtensionBuffer, ExtBuffer, ExtLength * sizeof(WCHAR)); 00223 } 00224 00225 00226 /* 00227 * @implemented 00228 */ 00229 BOOLEAN 00230 NTAPI 00231 RtlIsNameLegalDOS8Dot3(IN PCUNICODE_STRING UnicodeName, 00232 IN OUT POEM_STRING AnsiName OPTIONAL, 00233 IN OUT PBOOLEAN SpacesFound OPTIONAL) 00234 { 00235 static const char Illegal[] = "*?<>|\"+=,;[]:/\\\345"; 00236 int Dot = -1; 00237 int i; 00238 char Buffer[12]; 00239 OEM_STRING OemString; 00240 BOOLEAN GotSpace = FALSE; 00241 00242 if (!AnsiName) 00243 { 00244 OemString.Length = sizeof(Buffer); 00245 OemString.MaximumLength = sizeof(Buffer); 00246 OemString.Buffer = Buffer; 00247 AnsiName = &OemString; 00248 } 00249 if (RtlUpcaseUnicodeStringToCountedOemString( AnsiName, UnicodeName, FALSE ) != STATUS_SUCCESS) 00250 return FALSE; 00251 00252 if ((AnsiName->Length > 12) || (AnsiName->Buffer == NULL)) return FALSE; 00253 00254 /* a starting . is invalid, except for . and .. */ 00255 if (AnsiName->Buffer[0] == '.') 00256 { 00257 if (AnsiName->Length != 1 && (AnsiName->Length != 2 || AnsiName->Buffer[1] != '.')) return FALSE; 00258 if (SpacesFound) *SpacesFound = FALSE; 00259 return TRUE; 00260 } 00261 00262 for (i = 0; i < AnsiName->Length; i++) 00263 { 00264 switch (AnsiName->Buffer[i]) 00265 { 00266 case ' ': 00267 /* leading/trailing spaces not allowed */ 00268 if (!i || i == AnsiName->Length-1 || AnsiName->Buffer[i+1] == '.') return FALSE; 00269 GotSpace = TRUE; 00270 break; 00271 case '.': 00272 if (Dot != -1) return FALSE; 00273 Dot = i; 00274 break; 00275 default: 00276 if (strchr(Illegal, AnsiName->Buffer[i])) return FALSE; 00277 break; 00278 } 00279 } 00280 /* check file part is shorter than 8, extension shorter than 3 00281 * dot cannot be last in string 00282 */ 00283 if (Dot == -1) 00284 { 00285 if (AnsiName->Length > 8) return FALSE; 00286 } 00287 else 00288 { 00289 if (Dot > 8 || (AnsiName->Length - Dot > 4) || Dot == AnsiName->Length - 1) return FALSE; 00290 } 00291 if (SpacesFound) *SpacesFound = GotSpace; 00292 return TRUE; 00293 } 00294 00295 /* 00296 * @unimplemented 00297 */ 00298 NTSTATUS 00299 NTAPI 00300 RtlVolumeDeviceToDosName( 00301 IN PVOID VolumeDeviceObject, 00302 OUT PUNICODE_STRING DosName 00303 ) 00304 { 00305 UNIMPLEMENTED; 00306 return STATUS_NOT_IMPLEMENTED; 00307 } 00308 00309 /* EOF */ Generated on Fri May 25 2012 04:34:50 for ReactOS by
1.7.6.1
|