Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

uilist.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 uilist.c 00008 00009 Abstract: 00010 00011 Contains routine to convert a list of workstation names from UI/Service 00012 list format to API list format 00013 00014 Contents: 00015 RtlConvertUiListToApiList 00016 (NextElement) 00017 (ValidateName) 00018 00019 Author: 00020 00021 Richard L Firth (rfirth) 01-May-1992 00022 00023 Environment: 00024 00025 User mode (makes Windows calls) 00026 00027 Revision History: 00028 00029 --*/ 00030 00031 #include <nt.h> 00032 #include <ntrtl.h> 00033 #include <nturtl.h> 00034 #include <windows.h> 00035 #include <wchar.h> 00036 00037 // 00038 // macros 00039 // 00040 00041 #define IS_DELIMITER(c,_BlankOk) \ 00042 (((c) == L' ' && (_BlankOk)) || \ 00043 ((c) == L'\t') || ((c) == L',') || ((c) == L';')) 00044 00045 00046 // 00047 // prototypes 00048 // 00049 00050 static 00051 ULONG 00052 NextElement( 00053 IN OUT PWSTR* InputBuffer, 00054 IN OUT PULONG InputBufferLength, 00055 OUT PWSTR OutputBuffer, 00056 IN ULONG OutputBufferLength, 00057 IN BOOLEAN BlankIsDelimiter 00058 ); 00059 00060 static 00061 BOOLEAN 00062 ValidateName( 00063 IN PWSTR Name, 00064 IN ULONG Length 00065 ); 00066 00067 // 00068 // functions 00069 // 00070 00071 NTSTATUS 00072 RtlConvertUiListToApiList( 00073 IN PUNICODE_STRING UiList OPTIONAL, 00074 OUT PUNICODE_STRING ApiList, 00075 IN BOOLEAN BlankIsDelimiter 00076 ) 00077 00078 /*++ 00079 00080 Routine Description: 00081 00082 Converts a list of workstation names in UI/Service format into a list of 00083 canonicalized names in API list format. UI/Service list format allows 00084 multiple delimiters, leading and trailing delimiters. Delimiters are the 00085 set "\t,;". API list format has no leading or trailing delimiters and 00086 elements are delimited by a single comma character. 00087 00088 For each name parsed from UiList, the name is canonicalized (which checks 00089 the character set and name length) as a workstation name. If this fails, 00090 an error is returned. No information is returned as to which element 00091 failed canonicalization: the list should be discarded and a new one re-input 00092 00093 Arguments: 00094 00095 UiList - The list to canonicalize in UI/Service list format 00096 ApiList - The place to store the canonicalized version of the list in 00097 API list format. The list will have a trailing zero character. 00098 BlankIsDelimiter - TRUE indicates blank should be considered a delimiter 00099 character. 00100 00101 Return Value: 00102 00103 NTSTATUS 00104 Success = STATUS_SUCCESS 00105 List converted ok 00106 00107 Failure = STATUS_INVALID_PARAMETER 00108 UiList parameter is in error 00109 00110 STATUS_INVALID_COMPUTER_NAME 00111 A name parsed from UiList has an incorrect format for a 00112 computer (aka workstation) name 00113 --*/ 00114 00115 { 00116 NTSTATUS status = STATUS_SUCCESS; 00117 ULONG inLen; 00118 PWSTR input; 00119 PWSTR buffer; 00120 PWSTR output; 00121 ULONG cLen; 00122 ULONG len; 00123 ULONG outLen = 0; 00124 WCHAR element[MAX_COMPUTERNAME_LENGTH+1]; 00125 BOOLEAN firstElement = TRUE; 00126 BOOLEAN ok; 00127 00128 try { 00129 if (ARGUMENT_PRESENT(UiList)) { 00130 inLen = UiList->MaximumLength; // read memory test 00131 inLen = UiList->Length; 00132 input = UiList->Buffer; 00133 if (inLen & sizeof(WCHAR)-1) { 00134 status = STATUS_INVALID_PARAMETER; 00135 } 00136 } 00137 RtlInitUnicodeString(ApiList, NULL); 00138 } except (EXCEPTION_EXECUTE_HANDLER) { 00139 status = STATUS_ACCESS_VIOLATION; 00140 } 00141 if (NT_SUCCESS(status) && ARGUMENT_PRESENT(UiList) && inLen) { 00142 buffer = RtlAllocateHeap(RtlProcessHeap(), 0, inLen + sizeof(WCHAR)); 00143 if (buffer == NULL) { 00144 status = STATUS_NO_MEMORY; 00145 } else { 00146 ApiList->Buffer = buffer; 00147 ApiList->MaximumLength = (USHORT)inLen + sizeof(WCHAR); 00148 output = buffer; 00149 ok = TRUE; 00150 while (len = NextElement(&input, 00151 &inLen, 00152 element, 00153 sizeof(element) - sizeof(element[0]), 00154 BlankIsDelimiter )) { 00155 if (len == (ULONG)-1L) { 00156 ok = FALSE; 00157 } else { 00158 cLen = len/sizeof(WCHAR); 00159 element[cLen] = 0; 00160 ok = ValidateName(element, cLen); 00161 } 00162 if (ok) { 00163 if (!firstElement) { 00164 *output++ = L','; 00165 00166 // 00167 // BUGBUG sizeof(L',') returns 4, not 2!! 00168 // 00169 00170 // outLen += sizeof(L','); 00171 outLen += sizeof(WCHAR); 00172 } else { 00173 firstElement = FALSE; 00174 } 00175 wcscpy(output, element); 00176 outLen += len; 00177 output += cLen; 00178 } else { 00179 RtlFreeHeap(RtlProcessHeap(), 0, buffer); 00180 ApiList->Buffer = NULL; 00181 status = STATUS_INVALID_COMPUTER_NAME; 00182 break; 00183 } 00184 } 00185 } 00186 if (NT_SUCCESS(status)) { 00187 ApiList->Length = (USHORT)outLen; 00188 if (!outLen) { 00189 ApiList->MaximumLength = 0; 00190 ApiList->Buffer = NULL; 00191 RtlFreeHeap(RtlProcessHeap(), 0, buffer); 00192 } 00193 } 00194 } 00195 return status; 00196 } 00197 00198 static 00199 ULONG 00200 NextElement( 00201 IN OUT PWSTR* InputBuffer, 00202 IN OUT PULONG InputBufferLength, 00203 OUT PWSTR OutputBuffer, 00204 IN ULONG OutputBufferLength, 00205 IN BOOLEAN BlankIsDelimiter 00206 ) 00207 00208 /*++ 00209 00210 Routine Description: 00211 00212 Locates the next (non-delimter) element in a string and extracts it to a 00213 buffer. Delimiters are the set [\t,;] 00214 00215 Arguments: 00216 00217 InputBuffer - pointer to pointer to input buffer including delimiters 00218 Updated on successful return 00219 InputBufferLength - pointer to length of characters in InputBuffer. 00220 Updated on successful return 00221 OutputBuffer - pointer to buffer where next element is copied 00222 OutputBufferLength - size of OutputBuffer (in bytes) 00223 BlankIsDelimiter - TRUE indicates blank should be considered a delimiter 00224 character. 00225 00226 Return Value: 00227 00228 ULONG 00229 -1 = error - extracted element breaks OutputBuffer 00230 0 = no element extracted (buffer is empty or all 00231 delimiters) 00232 1..OutputBufferLength = OutputBuffer contains extracted element 00233 00234 --*/ 00235 00236 { 00237 ULONG elementLength = 0; 00238 ULONG inputLength = *InputBufferLength; 00239 PWSTR input = *InputBuffer; 00240 00241 while (IS_DELIMITER(*input, BlankIsDelimiter) && inputLength) { 00242 ++input; 00243 inputLength -= sizeof(*input); 00244 } 00245 while (!IS_DELIMITER(*input, BlankIsDelimiter) && inputLength) { 00246 if (!OutputBufferLength) { 00247 return (ULONG)-1L; 00248 } 00249 *OutputBuffer++ = *input++; 00250 OutputBufferLength -= sizeof(*input); 00251 elementLength += sizeof(*input); 00252 inputLength -= sizeof(*input); 00253 } 00254 *InputBuffer = input; 00255 *InputBufferLength = inputLength; 00256 return elementLength; 00257 } 00258 00259 // 00260 // BUGBUG - illegal names characters same as those in net\api. Move to common 00261 // include directory 00262 // 00263 00264 #define ILLEGAL_NAME_CHARS L"\001\002\003\004\005\006\007" \ 00265 L"\010\011\012\013\014\015\016\017" \ 00266 L"\020\021\022\023\024\025\026\027" \ 00267 L"\030\031\032\033\034\035\036\037" \ 00268 L"\"/\\[]:|<>+=;,?*" 00269 00270 static 00271 BOOLEAN 00272 ValidateName( 00273 IN PWSTR Name, 00274 IN ULONG Length 00275 ) 00276 00277 /*++ 00278 00279 Routine Description: 00280 00281 Determines whether a computer name is valid or not 00282 00283 Arguments: 00284 00285 Name - pointer to zero terminated wide-character computer name 00286 Length - of Name in characters, excluding zero-terminator 00287 00288 Return Value: 00289 00290 BOOLEAN 00291 TRUE Name is valid computer name 00292 FALSE Name is not valid computer name 00293 00294 --*/ 00295 00296 { 00297 if (Length > MAX_COMPUTERNAME_LENGTH || Length < 1) { 00298 return FALSE; 00299 } 00300 00301 // 00302 // Don't allow leading or trailing blanks in the computername. 00303 // 00304 00305 if ( Name[0] == ' ' || Name[Length-1] == ' ' ) { 00306 return(FALSE); 00307 } 00308 00309 return (BOOLEAN)((ULONG)wcscspn(Name, ILLEGAL_NAME_CHARS) == Length); 00310 }

Generated on Sat May 15 19:42:10 2004 for test by doxygen 1.3.7