Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmisc.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS kernel 00003 * Copyright (C) 2002, 2004 ReactOS Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00018 */ 00019 /* $Id: misc.c 48494 2010-08-09 20:38:12Z fireball $ 00020 * 00021 * COPYRIGHT: See COPYING in the top level directory 00022 * PROJECT: ReactOS kernel 00023 * FILE: services/fs/cdfs/misc.c 00024 * PURPOSE: CDROM (ISO 9660) filesystem driver 00025 * PROGRAMMER: Eric Kohl 00026 * UPDATE HISTORY: 00027 */ 00028 00029 /* INCLUDES *****************************************************************/ 00030 00031 #include "cdfs.h" 00032 00033 #define NDEBUG 00034 #include <debug.h> 00035 00036 /* FUNCTIONS ****************************************************************/ 00037 00038 VOID 00039 CdfsSwapString(PWCHAR Out, 00040 PUCHAR In, 00041 ULONG Count) 00042 { 00043 PUCHAR t = (PUCHAR)Out; 00044 ULONG i; 00045 00046 for (i = 0; i < Count; i += 2) 00047 { 00048 t[i] = In[i+1]; 00049 t[i+1] = In[i]; 00050 if (t[i+1] == 0 && t[i] == ';') 00051 break; 00052 } 00053 if ((i>2)&&(t[i-2] == '.')) 00054 { 00055 t[i-2] = 0; 00056 t[i-1] = 0; 00057 } 00058 t[i] = 0; 00059 t[i+1] = 0; 00060 } 00061 00062 00063 VOID 00064 CdfsDateTimeToSystemTime(PFCB Fcb, 00065 PLARGE_INTEGER SystemTime) 00066 { 00067 TIME_FIELDS TimeFields; 00068 LARGE_INTEGER LocalTime; 00069 00070 TimeFields.Milliseconds = 0; 00071 TimeFields.Second = Fcb->Entry.Second; 00072 TimeFields.Minute = Fcb->Entry.Minute; 00073 TimeFields.Hour = Fcb->Entry.Hour; 00074 00075 TimeFields.Day = Fcb->Entry.Day; 00076 TimeFields.Month = Fcb->Entry.Month; 00077 TimeFields.Year = Fcb->Entry.Year + 1900; 00078 00079 RtlTimeFieldsToTime(&TimeFields, 00080 &LocalTime); 00081 ExLocalTimeToSystemTime(&LocalTime, SystemTime); 00082 } 00083 00084 00085 VOID 00086 CdfsFileFlagsToAttributes(PFCB Fcb, 00087 PULONG FileAttributes) 00088 { 00089 /* FIXME: Fix attributes */ 00090 00091 *FileAttributes = // FILE_ATTRIBUTE_READONLY | 00092 ((Fcb->Entry.FileFlags & FILE_FLAG_HIDDEN) ? FILE_ATTRIBUTE_HIDDEN : 0) | 00093 ((Fcb->Entry.FileFlags & FILE_FLAG_DIRECTORY) ? FILE_ATTRIBUTE_DIRECTORY : 0) | 00094 ((Fcb->Entry.FileFlags & FILE_FLAG_SYSTEM) ? FILE_ATTRIBUTE_SYSTEM : 0) | 00095 ((Fcb->Entry.FileFlags & FILE_FLAG_READONLY) ? FILE_ATTRIBUTE_READONLY : 0); 00096 } 00097 00098 BOOLEAN 00099 CdfsIsNameLegalDOS8Dot3(IN UNICODE_STRING FileName 00100 ) 00101 { 00102 ULONG i; 00103 STRING DbcsName; 00104 CHAR DbcsNameBuffer[12]; 00105 00106 /* 8dot3 filename is max 12 length */ 00107 if (FileName.Length / sizeof(WCHAR) > 12) 00108 { 00109 return FALSE; 00110 } 00111 00112 for (i = 0; i < FileName.Length / sizeof(WCHAR) ; i++) 00113 { 00114 /* Don't allow spaces in FileName */ 00115 if (FileName.Buffer[i] == L' ') 00116 return FALSE; 00117 } 00118 00119 /* If FileName is finishing with a dot, remove it */ 00120 if (FileName.Buffer[FileName.Length / sizeof(WCHAR) - 1] == '.') 00121 { 00122 FileName.Length -= sizeof(WCHAR); 00123 } 00124 00125 /* Finally, convert the string to call the FsRtl function */ 00126 DbcsName.MaximumLength = 12; 00127 DbcsName.Buffer = DbcsNameBuffer; 00128 if (!NT_SUCCESS(RtlUnicodeStringToCountedOemString(&DbcsName, 00129 &FileName, 00130 FALSE ))) 00131 { 00132 00133 return FALSE; 00134 } 00135 return FsRtlIsFatDbcsLegal(DbcsName, FALSE, FALSE, FALSE); 00136 } 00137 00138 VOID 00139 CdfsShortNameCacheGet 00140 (PFCB DirectoryFcb, 00141 PLARGE_INTEGER StreamOffset, 00142 PUNICODE_STRING LongName, 00143 PUNICODE_STRING ShortName) 00144 { 00145 PLIST_ENTRY Entry; 00146 PCDFS_SHORT_NAME ShortNameEntry; 00147 GENERATE_NAME_CONTEXT Context = { 0 }; 00148 00149 DPRINT("CdfsShortNameCacheGet(%I64u,%wZ)\n", StreamOffset->QuadPart, LongName); 00150 00151 /* Get the name list resource */ 00152 ExAcquireResourceExclusiveLite(&DirectoryFcb->NameListResource, TRUE); 00153 00154 /* Try to find the name in our cache */ 00155 for (Entry = DirectoryFcb->ShortNameList.Flink; 00156 Entry != &DirectoryFcb->ShortNameList; 00157 Entry = Entry->Flink) 00158 { 00159 ShortNameEntry = CONTAINING_RECORD(Entry, CDFS_SHORT_NAME, Entry); 00160 if (ShortNameEntry->StreamOffset.QuadPart == StreamOffset->QuadPart) 00161 { 00162 /* Cache hit */ 00163 RtlCopyMemory 00164 (ShortName->Buffer, ShortNameEntry->Name.Buffer, 00165 ShortNameEntry->Name.Length); 00166 ShortName->Length = ShortNameEntry->Name.Length; 00167 ExReleaseResourceLite(&DirectoryFcb->NameListResource); 00168 DPRINT("Yield short name %wZ from cache\n", ShortName); 00169 return; 00170 } 00171 } 00172 00173 /* Cache miss */ 00174 if (!CdfsIsNameLegalDOS8Dot3(*LongName)) 00175 { 00176 RtlGenerate8dot3Name(LongName, FALSE, &Context, ShortName); 00177 } 00178 else 00179 { 00180 /* copy short name */ 00181 RtlUpcaseUnicodeString 00182 (ShortName, 00183 LongName, 00184 FALSE); 00185 } 00186 00187 DPRINT("Initial Guess %wZ\n", ShortName); 00188 00189 /* Make it unique by scanning the cache and bumping */ 00190 /* Note that incrementing the ambiguous name is enough, since we add new 00191 * entries at the tail. We'll scan over all collisions. */ 00192 /* XXX could perform better. */ 00193 for (Entry = DirectoryFcb->ShortNameList.Flink; 00194 Entry != &DirectoryFcb->ShortNameList; 00195 Entry = Entry->Flink) 00196 { 00197 ShortNameEntry = CONTAINING_RECORD(Entry, CDFS_SHORT_NAME, Entry); 00198 if (RtlCompareUnicodeString 00199 (ShortName, 00200 &ShortNameEntry->Name, 00201 TRUE) == 0) /* Match */ 00202 { 00203 RtlGenerate8dot3Name(LongName, FALSE, &Context, ShortName); 00204 DPRINT("Collide; try %wZ\n", ShortName); 00205 } 00206 } 00207 00208 /* We've scanned over all entries and now have a unique one. Cache it. */ 00209 ShortNameEntry = ExAllocatePoolWithTag(PagedPool, sizeof(CDFS_SHORT_NAME), TAG_FCB); 00210 if (!ShortNameEntry) 00211 { 00212 /* We couldn't cache it, but we can return it. We run the risk of 00213 * generating a non-unique name later. */ 00214 ExReleaseResourceLite(&DirectoryFcb->NameListResource); 00215 DPRINT1("Couldn't cache potentially clashing 8.3 name %wZ\n", ShortName); 00216 return; 00217 } 00218 00219 ShortNameEntry->StreamOffset = *StreamOffset; 00220 ShortNameEntry->Name.Buffer = ShortNameEntry->NameBuffer; 00221 ShortNameEntry->Name.Length = ShortName->Length; 00222 ShortNameEntry->Name.MaximumLength = sizeof(ShortNameEntry->NameBuffer); 00223 RtlCopyMemory 00224 (ShortNameEntry->NameBuffer, 00225 ShortName->Buffer, 00226 ShortName->Length); 00227 InsertTailList(&DirectoryFcb->ShortNameList, &ShortNameEntry->Entry); 00228 ExReleaseResourceLite(&DirectoryFcb->NameListResource); 00229 00230 DPRINT("Returning short name %wZ for long name %wZ\n", ShortName, LongName); 00231 } 00232 00233 /* EOF */ Generated on Mon May 28 2012 04:16:50 for ReactOS by
1.7.6.1
|