]> granicus.if.org Git - imagemagick/blob - MagickCore/nt-feature.c
Added missing calls to xmlFreeDoc to fix memory leak reported in #1766.
[imagemagick] / MagickCore / nt-feature.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                                                                             %
7 %                                 N   N  TTTTT                                %
8 %                                 NN  N    T                                  %
9 %                                 N N N    T                                  %
10 %                                 N  NN    T                                  %
11 %                                 N   N    T                                  %
12 %                                                                             %
13 %                                                                             %
14 %                   Windows NT Feature Methods for MagickCore                 %
15 %                                                                             %
16 %                               Software Design                               %
17 %                                    Cristy                                   %
18 %                                December 1996                                %
19 %                                                                             %
20 %                                                                             %
21 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
22 %  dedicated to making software imaging solutions freely available.           %
23 %                                                                             %
24 %  You may not use this file except in compliance with the License.  You may  %
25 %  obtain a copy of the License at                                            %
26 %                                                                             %
27 %    https://imagemagick.org/script/license.php                               %
28 %                                                                             %
29 %  Unless required by applicable law or agreed to in writing, software        %
30 %  distributed under the License is distributed on an "AS IS" BASIS,          %
31 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
32 %  See the License for the specific language governing permissions and        %
33 %  limitations under the License.                                             %
34 %                                                                             %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 %
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__)
45 #define WIN32_LEAN_AND_MEAN
46 #define VC_EXTRALEAN
47 #include <windows.h>
48 #include "MagickCore/cache.h"
49 #include "MagickCore/colorspace.h"
50 #include "MagickCore/colorspace-private.h"
51 #include "MagickCore/draw.h"
52 #include "MagickCore/exception.h"
53 #include "MagickCore/exception-private.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/memory_.h"
56 #include "MagickCore/memory-private.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/nt-base.h"
60 #include "MagickCore/nt-base-private.h"
61 #include "MagickCore/pixel-accessor.h"
62 #include "MagickCore/quantum.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/token.h"
65 #include "MagickCore/splay-tree.h"
66 #include "MagickCore/utility.h"
67 \f
68 /*
69 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70 %                                                                             %
71 %                                                                             %
72 %                                                                             %
73 %   I s M a g i c k C o n f l i c t                                           %
74 %                                                                             %
75 %                                                                             %
76 %                                                                             %
77 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 %
79 %  IsMagickConflict() returns true if the image format conflicts with a logical
80 %  drive (.e.g. X:).
81 %
82 %  The format of the IsMagickConflict method is:
83 %
84 %      MagickBooleanType IsMagickConflict(const char *magick)
85 %
86 %  A description of each parameter follows:
87 %
88 %    o magick: Specifies the image format.
89 %
90 */
91 MagickExport MagickBooleanType NTIsMagickConflict(const char *magick)
92 {
93   MagickBooleanType
94     status;
95
96   assert(magick != (char *) NULL);
97   if (strlen(magick) > 1)
98     return(MagickFalse);
99   status=(GetLogicalDrives() & (1 << ((LocaleUppercase((int)
100     (*magick)))-'A'))) != 0 ? MagickTrue : MagickFalse;
101   return(status);
102 }
103 \f
104 /*
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
106 %                                                                             %
107 %                                                                             %
108 %                                                                             %
109 %   N T A c q u i r e T y p e C a c h e                                       %
110 %                                                                             %
111 %                                                                             %
112 %                                                                             %
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 %
115 %  NTAcquireTypeCache() loads a Windows TrueType fonts.
116 %
117 %  The format of the NTAcquireTypeCache method is:
118 %
119 %      MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache)
120 %
121 %  A description of each parameter follows:
122 %
123 %    o type_cache: A linked list of fonts.
124 %
125 */
126 MagickExport MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *type_cache,
127   ExceptionInfo *exception)
128 {
129   HKEY
130     reg_key = (HKEY) INVALID_HANDLE_VALUE;
131
132   LONG
133     res;
134
135   int
136     list_entries = 0;
137
138   char
139     buffer[MagickPathExtent],
140     system_root[MagickPathExtent],
141     font_root[MagickPathExtent];
142
143   DWORD
144     type,
145     system_root_length;
146
147   MagickBooleanType
148     status;
149
150   /*
151     Try to find the right Windows*\CurrentVersion key, the SystemRoot and
152     then the Fonts key
153   */
154   res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
155     "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &reg_key);
156   if (res == ERROR_SUCCESS) {
157     system_root_length=sizeof(system_root)-1;
158     res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type,
159       (BYTE*) system_root, &system_root_length);
160   }
161   if (res != ERROR_SUCCESS) {
162     res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
163       "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &reg_key);
164     if (res == ERROR_SUCCESS) {
165       system_root_length=sizeof(system_root)-1;
166       res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type,
167         (BYTE*)system_root, &system_root_length);
168     }
169   }
170   if (res == ERROR_SUCCESS)
171     res = RegOpenKeyExA (reg_key, "Fonts",0, KEY_READ, &reg_key);
172   if (res != ERROR_SUCCESS)
173     return(MagickFalse);
174   *font_root='\0';
175   (void) CopyMagickString(buffer,system_root,MagickPathExtent);
176   (void) ConcatenateMagickString(buffer,"\\fonts\\arial.ttf",MagickPathExtent);
177   if (IsPathAccessible(buffer) != MagickFalse)
178     {
179       (void) CopyMagickString(font_root,system_root,MagickPathExtent);
180       (void) ConcatenateMagickString(font_root,"\\fonts\\",MagickPathExtent);
181     }
182   else
183     {
184       (void) CopyMagickString(font_root,system_root,MagickPathExtent);
185       (void) ConcatenateMagickString(font_root,"\\",MagickPathExtent);
186     }
187
188   {
189     TypeInfo
190       *type_info;
191
192     DWORD
193       registry_index = 0,
194       value_data_size,
195       value_name_length;
196
197     char
198       value_data[MagickPathExtent],
199       value_name[MagickPathExtent];
200
201     res = ERROR_SUCCESS;
202
203     while (res != ERROR_NO_MORE_ITEMS)
204       {
205         char
206           *family_extent,
207           token[MagickPathExtent],
208           *pos,
209           *q;
210
211         value_name_length = sizeof(value_name) - 1;
212         value_data_size = sizeof(value_data) - 1;
213         res = RegEnumValueA ( reg_key, registry_index, value_name,
214           &value_name_length, 0, &type, (BYTE*)value_data, &value_data_size);
215         registry_index++;
216         if (res != ERROR_SUCCESS)
217           continue;
218         if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL )
219           continue;
220         *pos='\0'; /* Remove (TrueType) from string */
221
222         type_info=(TypeInfo *) AcquireCriticalMemory(sizeof(*type_info));
223         (void) memset(type_info,0,sizeof(TypeInfo));
224
225         type_info->path=ConstantString("Windows Fonts");
226         type_info->signature=MagickCoreSignature;
227
228         /* Name */
229         (void) CopyMagickString(buffer,value_name,MagickPathExtent);
230         for(pos = buffer; *pos != 0 ; pos++)
231           if (*pos == ' ')
232             *pos = '-';
233         type_info->name=ConstantString(buffer);
234
235         /* Fullname */
236         type_info->description=ConstantString(value_name);
237
238         /* Format */
239         type_info->format=ConstantString("truetype");
240
241         /* Glyphs */
242         if (strchr(value_data,'\\') != (char *) NULL)
243           (void) CopyMagickString(buffer,value_data,MagickPathExtent);
244         else
245           {
246             (void) CopyMagickString(buffer,font_root,MagickPathExtent);
247             (void) ConcatenateMagickString(buffer,value_data,MagickPathExtent);
248           }
249
250         LocaleLower(buffer);
251         type_info->glyphs=ConstantString(buffer);
252
253         type_info->stretch=NormalStretch;
254         type_info->style=NormalStyle;
255         type_info->weight=400;
256
257         /* Some fonts are known to require special encodings */
258         if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) ||
259              (LocaleCompare(type_info->name, "Wingdings") == 0 ) ||
260              (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) ||
261              (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) )
262           type_info->encoding=ConstantString("AppleRoman");
263
264         family_extent=value_name;
265
266         for (q=value_name; *q != '\0'; )
267           {
268             (void) GetNextToken(q,(const char **) &q,MagickPathExtent,token);
269             if (*token == '\0')
270               break;
271
272             if (LocaleCompare(token,"Italic") == 0)
273               {
274                 type_info->style=ItalicStyle;
275               }
276
277             else if (LocaleCompare(token,"Oblique") == 0)
278               {
279                 type_info->style=ObliqueStyle;
280               }
281
282             else if (LocaleCompare(token,"Bold") == 0)
283               {
284                 type_info->weight=700;
285               }
286
287             else if (LocaleCompare(token,"Thin") == 0)
288               {
289                 type_info->weight=100;
290               }
291
292             else if ( (LocaleCompare(token,"ExtraLight") == 0) ||
293                       (LocaleCompare(token,"UltraLight") == 0) )
294               {
295                 type_info->weight=200;
296               }
297
298             else if (LocaleCompare(token,"Light") == 0)
299               {
300                 type_info->weight=300;
301               }
302
303             else if ( (LocaleCompare(token,"Normal") == 0) ||
304                       (LocaleCompare(token,"Regular") == 0) )
305               {
306                 type_info->weight=400;
307               }
308
309             else if (LocaleCompare(token,"Medium") == 0)
310               {
311                 type_info->weight=500;
312               }
313
314             else if ( (LocaleCompare(token,"SemiBold") == 0) ||
315                       (LocaleCompare(token,"DemiBold") == 0) )
316               {
317                 type_info->weight=600;
318               }
319
320             else if ( (LocaleCompare(token,"ExtraBold") == 0) ||
321                       (LocaleCompare(token,"UltraBold") == 0) )
322               {
323                 type_info->weight=800;
324               }
325
326             else if ( (LocaleCompare(token,"Heavy") == 0) ||
327                       (LocaleCompare(token,"Black") == 0) )
328               {
329                 type_info->weight=900;
330               }
331
332             else if (LocaleCompare(token,"Condensed") == 0)
333               {
334                 type_info->stretch = CondensedStretch;
335               }
336
337             else if (LocaleCompare(token,"Expanded") == 0)
338               {
339                 type_info->stretch = ExpandedStretch;
340               }
341
342             else if (LocaleCompare(token,"ExtraCondensed") == 0)
343               {
344                 type_info->stretch = ExtraCondensedStretch;
345               }
346
347             else if (LocaleCompare(token,"ExtraExpanded") == 0)
348               {
349                 type_info->stretch = ExtraExpandedStretch;
350               }
351
352             else if (LocaleCompare(token,"SemiCondensed") == 0)
353               {
354                 type_info->stretch = SemiCondensedStretch;
355               }
356
357             else if (LocaleCompare(token,"SemiExpanded") == 0)
358               {
359                 type_info->stretch = SemiExpandedStretch;
360               }
361
362             else if (LocaleCompare(token,"UltraCondensed") == 0)
363               {
364                 type_info->stretch = UltraCondensedStretch;
365               }
366
367             else if (LocaleCompare(token,"UltraExpanded") == 0)
368               {
369                 type_info->stretch = UltraExpandedStretch;
370               }
371
372             else
373               {
374                 family_extent=q;
375               }
376           }
377
378         (void) CopyMagickString(buffer,value_name,family_extent-value_name+1);
379         StripString(buffer);
380         type_info->family=ConstantString(buffer);
381
382         list_entries++;
383         status=AddValueToSplayTree(type_cache,type_info->name,type_info);
384         if (status == MagickFalse)
385           (void) ThrowMagickException(exception,GetMagickModule(),
386             ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
387       }
388   }
389   RegCloseKey ( reg_key );
390   return(MagickTrue);
391 }
392 \f
393 #endif