+FsRtlLegalAnsiCharacterArray
authorshort <>
Fri, 17 Jan 2003 01:13:42 +0000 (01:13 +0000)
committershort <>
Fri, 17 Jan 2003 01:13:42 +0000 (01:13 +0000)
+FsRtlDissectName()

src/libcaptive/fs/name.c

index b5839e2..a8cab2c 100644 (file)
 #include <glib/gmessages.h>
 #include "captive/unicode.h"
 #include "reactos/unicode.h"   /* for ANSI_* */
+#include "captive/macros.h"
+#include <ctype.h>
+
+
+UCHAR **FsRtlLegalAnsiCharacterArray;
+
+
+/**
+ * captive_FsRtlLegalAnsiCharacterArray_init:
+ * Initialize #FsRtlLegalAnsiCharacterArray character classes
+ * by appropriate #FSRTL_FAT_LEGAL etc. flags.
+ */
+void captive_FsRtlLegalAnsiCharacterArray_init(void)
+{
+static UCHAR *array;
+guint ui;
+
+       /* Use allocation instead of static array to get ElectricFence sanity boundaries.
+        * Use even the negative 0x80 part as someone may access 'FsRtlLegalAnsiCharacterArray'
+        * with 'signed char' (but also with 'unsigned char'). See also memcpy(3) below.
+        */
+       captive_new0n(array,0x80+0x100);
+
+       for (ui=0;ui<0x100;ui++) {
+UCHAR f=0;
+
+               if (isalnum(ui))
+                       f|=FSRTL_FAT_LEGAL;
+               if (isalnum(ui))
+                       f|=FSRTL_HPFS_LEGAL;
+               if (isalnum(ui))
+                       f|=FSRTL_NTFS_LEGAL;
+               if (ui=='*' || ui=='?')
+                       f|=FSRTL_WILD_CHARACTER;
+               if (isalnum(ui))
+                       f|=FSRTL_OLE_LEGAL;
+
+               array[(unsigned int)(unsigned char)ui]=f;
+               }
+
+       memcpy(array-0x80,array+0x80,0x80*sizeof(*array));
+
+       FsRtlLegalAnsiCharacterArray=&array;
+}
 
 
 /**
@@ -52,3 +96,55 @@ const WCHAR *wcp;
                        return TRUE;
        return FALSE;
 }
+
+
+/**
+ * FsRtlDissectName:
+ * @Path: Initialized #UNICODE_STRING to parse.
+ * @FirstName: Returns the first filename from @Path.
+ * %NULL value is forbidden.
+ * @RemainingName: Returns the part of @Path behind @FirstName.
+ * %NULL value is forbidden.
+ *
+ * Will parse @Path as regex (FirstName,RemainingName)=/^\?([^/]*)/?(.*)$/;
+ * @FirstName and @RemainingName must be pointers to allocated #UNICODE_STRING
+ * but their #Buffer will be pointing to inside @Path buffer afterwards.
+ * Therefore do not free it! The returned strings may not be 0-terminated strings.
+ */
+VOID FsRtlDissectName(IN UNICODE_STRING Path,OUT PUNICODE_STRING FirstName,OUT PUNICODE_STRING RemainingName)
+{
+PWSTR Path_end;
+PWSTR delim_FirstName_start    ,delim_FirstName_end;
+PWSTR delim_RemainingName_start,delim_RemainingName_end;
+
+       g_return_if_fail(captive_validate_UnicodeString(&Path));
+       g_return_if_fail(FirstName!=NULL);
+       g_return_if_fail(RemainingName!=NULL);
+
+       Path_end=Path.Buffer+Path.Length/sizeof(*Path.Buffer);
+
+       delim_FirstName_start=Path.Buffer;
+       if (delim_FirstName_start<Path_end && *delim_FirstName_start=='\\')
+               delim_FirstName_start++;
+       for (delim_FirstName_end=delim_FirstName_start;
+                       delim_FirstName_end<Path_end && *delim_FirstName_end!='\\';
+                       delim_FirstName_end++);
+       delim_RemainingName_start=delim_FirstName_end;
+       if (delim_RemainingName_start<Path_end && *delim_RemainingName_start=='\\')
+               delim_RemainingName_start++;
+       delim_RemainingName_end=Path_end;
+
+       g_assert(delim_FirstName_start    <=delim_FirstName_end);
+       g_assert(delim_FirstName_end      <=delim_RemainingName_start);
+       g_assert(delim_RemainingName_start<=delim_RemainingName_end);
+
+       FirstName->Buffer=delim_FirstName_start;
+       FirstName->Length=(delim_FirstName_end-delim_FirstName_start)*sizeof(*FirstName->Buffer);
+       FirstName->MaximumLength=FirstName->Length;
+       FirstName->Buffer=delim_FirstName_start;
+
+       RemainingName->Buffer=delim_RemainingName_start;
+       RemainingName->Length=(delim_RemainingName_end-delim_RemainingName_start)*sizeof(*RemainingName->Buffer);
+       RemainingName->MaximumLength=RemainingName->Length;
+       RemainingName->Buffer=delim_RemainingName_start;
+}