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

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

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