2 * reactos filesystem name strings functions emulation of libcaptive
3 * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "reactos/ddk/fsfuncs.h" /* self */
23 #include <glib/gmessages.h>
24 #include "captive/unicode.h"
25 #include "reactos/unicode.h" /* for ANSI_* */
26 #include "captive/macros.h"
30 UCHAR **FsRtlLegalAnsiCharacterArray;
34 * captive_FsRtlLegalAnsiCharacterArray_init:
36 * Initialize #FsRtlLegalAnsiCharacterArray character classes
37 * by appropriate #FSRTL_FAT_LEGAL etc. flags.
39 void captive_FsRtlLegalAnsiCharacterArray_init(void)
43 const gchar fat_valid[]="!#&(-./@_~";
45 /* Use allocation instead of static array to get ElectricFence sanity boundaries.
46 * Use even the negative 0x80 part as someone may access 'FsRtlLegalAnsiCharacterArray'
47 * with 'signed char' (but also with 'unsigned char'). See also memcpy(3) below.
49 captive_new0n(array,0x80+0x100);
52 for (ui=0;ui<0x100;ui++) {
55 if (isalnum(ui) || strchr(fat_valid,ui))
57 if (isalnum(ui) || strchr(fat_valid,ui))
59 if (isalnum(ui) || strchr(fat_valid,ui))
61 if (ui=='*' || ui=='?')
62 f|=FSRTL_WILD_CHARACTER;
66 array[(unsigned int)(unsigned char)ui]=f;
69 memcpy(array-0x80,array+0x80,0x80*sizeof(*array));
71 FsRtlLegalAnsiCharacterArray=&array;
76 * FsRtlDoesNameContainWildCards:
77 * @Name: Filename to check for wildcards.
78 * %NULL value is forbidden.
79 * Non-zero terminated #PUNICODE_STRING is permitted.
81 * Check if @Name contains wildcard markers as its substring(s).
83 * Returns: %TRUE if @Name contains "*", "?", %ANSI_DOS_STAR, %ANSI_DOS_DOT or %ANSI_DOS_QM.
85 BOOLEAN FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
87 const UNICODE_STRING *cName=Name;
90 g_return_val_if_fail(captive_validate_UnicodeString_noterm(cName),FALSE);
92 for (wcp=cName->Buffer;wcp<cName->Buffer+(cName->Length/sizeof(*cName->Buffer));*wcp++)
96 || *wcp==ANSI_DOS_STAR
106 * @Path_noterm: Initialized #UNICODE_STRING to parse.
107 * @FirstName: Returns the first filename from @Path_noterm.
108 * %NULL value is forbidden.
109 * @RemainingName: Returns the part of @Path_noterm behind @FirstName.
110 * %NULL value is forbidden.
112 * Will parse @Path_noterm as regex (FirstName,RemainingName)=/^\?([^/]*)/?(.*)$/;
113 * @FirstName and @RemainingName must be pointers to allocated #UNICODE_STRING
114 * but their #Buffer will be pointing to inside @Path_noterm buffer afterwards.
115 * Therefore do not free it! The returned strings may not be 0-terminated strings.
117 * @Path_noterm does not neet to be zero-terminated.
119 VOID FsRtlDissectName(IN UNICODE_STRING Path_noterm,OUT PUNICODE_STRING FirstName,OUT PUNICODE_STRING RemainingName)
122 PWSTR delim_FirstName_start ,delim_FirstName_end;
123 PWSTR delim_RemainingName_start,delim_RemainingName_end;
125 g_return_if_fail(captive_validate_UnicodeString_noterm(&Path_noterm));
126 g_return_if_fail(FirstName!=NULL);
127 g_return_if_fail(RemainingName!=NULL);
129 Path_end=Path_noterm.Buffer+Path_noterm.Length/sizeof(*Path_noterm.Buffer);
131 delim_FirstName_start=Path_noterm.Buffer;
132 if (delim_FirstName_start<Path_end && *delim_FirstName_start=='\\')
133 delim_FirstName_start++;
134 for (delim_FirstName_end=delim_FirstName_start;
135 delim_FirstName_end<Path_end && *delim_FirstName_end!='\\';
136 delim_FirstName_end++);
137 delim_RemainingName_start=delim_FirstName_end;
138 if (delim_RemainingName_start<Path_end && *delim_RemainingName_start=='\\')
139 delim_RemainingName_start++;
140 delim_RemainingName_end=Path_end;
142 g_assert(delim_FirstName_start <=delim_FirstName_end);
143 g_assert(delim_FirstName_end <=delim_RemainingName_start);
144 g_assert(delim_RemainingName_start<=delim_RemainingName_end);
146 FirstName->Buffer=delim_FirstName_start;
147 FirstName->Length=(delim_FirstName_end-delim_FirstName_start)*sizeof(*FirstName->Buffer);
148 FirstName->MaximumLength=FirstName->Length;
149 FirstName->Buffer=delim_FirstName_start;
151 RemainingName->Buffer=delim_RemainingName_start;
152 RemainingName->Length=(delim_RemainingName_end-delim_RemainingName_start)*sizeof(*RemainingName->Buffer);
153 RemainingName->MaximumLength=RemainingName->Length;
154 RemainingName->Buffer=delim_RemainingName_start;
159 * FsRtlAreNamesEqual:
160 * @Name1: First filesystem name (FIXME: pathname or basename?) of type #PUNICODE_STRING.
161 * Invalid string input is forbidden.
162 * @Name2: Second filesystem name (FIXME: pathname or basename?) of type #PUNICODE_STRING.
163 * Invalid string input is forbidden.
164 * @IgnoreCase: Compare @Name1 and @Name2 case-insensitively?
166 * %NULL value is required if @IgnoreCase==%FALSE.
167 * TODO: NOT IMPLEMENTED YET.
169 * Compare the given filenames if they match according to the specified criteria.
170 * FIXME: libcaptive implements this function currently as captive_UnicodeString_compare_insensitive()
171 * or captive_UnicodeString_compare(); How are filesystem names specific from regular strings?
173 * Returns: %TRUE if @Name1 and @Name2 match.
175 BOOLEAN FsRtlAreNamesEqual
176 (IN PUNICODE_STRING Name1,IN PUNICODE_STRING Name2,IN BOOLEAN IgnoreCase,IN PWCHAR UpcaseTable OPTIONAL)
178 g_return_val_if_fail(captive_validate_UnicodeString(Name1),FALSE);
179 g_return_val_if_fail(FsRtlDoesNameContainWildCards(Name1)==FALSE,FALSE);
180 g_return_val_if_fail(captive_validate_UnicodeString(Name2),FALSE);
181 g_return_val_if_fail(FsRtlDoesNameContainWildCards(Name2)==FALSE,FALSE);
182 g_return_val_if_fail(UpcaseTable==NULL,FALSE); /* TODO: NOT IMPLEMENTED YET */
183 /* Do not permit passing of 'UpcaseTable' if it would not make any sense.
184 * Just a sanity check, it should not harm. Such assertion is not mandatory by W32 doc.
186 g_return_val_if_fail((IgnoreCase==FALSE && UpcaseTable==NULL) || IgnoreCase==TRUE,FALSE);
189 return captive_UnicodeString_compare_insensitive(Name1,Name2);
191 return captive_UnicodeString_compare (Name1,Name2);