ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

misc.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.