blob: a1a5e4ddf05daad83060bc80ebf3af1716ccb8ad [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% N N TTTTT %
7% NN N T %
8% N N N T %
9% N NN T %
10% N N T %
11% %
12% %
13% Windows NT Utility Methods for MagickCore %
14% %
15% Software Design %
16% John Cristy %
17% December 1996 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38/*
39 Include declarations.
40*/
cristy4c08aed2011-07-01 19:47:50 +000041#include "MagickCore/studio.h"
cristy0157aea2010-04-24 21:12:18 +000042#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/client.h"
cristy66f9c3c2011-08-13 17:12:28 +000044#include "MagickCore/exception-private.h"
cristy4c08aed2011-07-01 19:47:50 +000045#include "MagickCore/locale_.h"
46#include "MagickCore/log.h"
47#include "MagickCore/magick.h"
48#include "MagickCore/memory_.h"
49#include "MagickCore/resource_.h"
cristy0a4d92f2011-08-31 19:25:00 +000050#include "MagickCore/resource-private.h"
cristy4c08aed2011-07-01 19:47:50 +000051#include "MagickCore/timer.h"
52#include "MagickCore/string_.h"
53#include "MagickCore/utility.h"
54#include "MagickCore/version.h"
cristy3ed852e2009-09-05 21:47:34 +000055#if defined(MAGICKCORE_LTDL_DELEGATE)
56# include "ltdl.h"
57#endif
cristy4c08aed2011-07-01 19:47:50 +000058#include "MagickCore/nt-base.h"
cristy30603ff2011-10-07 00:43:07 +000059#include "MagickCore/nt-base-private.h"
cristy3ed852e2009-09-05 21:47:34 +000060#if defined(MAGICKCORE_CIPHER_SUPPORT)
61#include <ntsecapi.h>
62#include <wincrypt.h>
63#endif
64
65/*
66 Define declarations.
67*/
68#if !defined(MAP_FAILED)
69#define MAP_FAILED ((void *) -1)
70#endif
71
72/*
73 Static declarations.
74*/
75#if !defined(MAGICKCORE_LTDL_DELEGATE)
76static char
77 *lt_slsearchpath = (char *) NULL;
78#endif
79
cristydefb3f02009-09-10 02:18:35 +000080static GhostInfo
81 ghost_info;
cristy3ed852e2009-09-05 21:47:34 +000082
83static void
cristydefb3f02009-09-10 02:18:35 +000084 *ghost_handle = (void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +000085
86/*
87 External declarations.
88*/
cristy0157aea2010-04-24 21:12:18 +000089#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000090extern "C" BOOL WINAPI
91 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
92#endif
93
94/*
95%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96% %
97% %
98% %
cristy30603ff2011-10-07 00:43:07 +000099% C r o p I m a g e T o H B i t m a p %
100% %
101% %
102% %
103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104%
105% CropImageToHBITMAP() extracts a specified region of the image and returns
106% it as a Windows HBITMAP. While the same functionality can be accomplished by
107% invoking CropImage() followed by ImageToHBITMAP(), this method is more
108% efficient since it copies pixels directly to the HBITMAP.
109%
110% The format of the CropImageToHBITMAP method is:
111%
112% HBITMAP CropImageToHBITMAP(Image* image,const RectangleInfo *geometry,
113% ExceptionInfo *exception)
114%
115% A description of each parameter follows:
116%
117% o image: the image.
118%
119% o geometry: Define the region of the image to crop with members
120% x, y, width, and height.
121%
122% o exception: return any errors or warnings in this structure.
123%
124*/
125MagickExport void *CropImageToHBITMAP(Image *image,
126 const RectangleInfo *geometry,ExceptionInfo *exception)
127{
128#define CropImageTag "Crop/Image"
129
130 BITMAP
131 bitmap;
132
133 HBITMAP
134 bitmapH;
135
136 HANDLE
137 bitmap_bitsH;
138
139 MagickBooleanType
140 proceed;
141
142 RectangleInfo
143 page;
144
145 register const Quantum
146 *p;
147
148 register RGBQUAD
149 *q;
150
151 RGBQUAD
152 *bitmap_bits;
153
154 ssize_t
155 y;
156
157 /*
158 Check crop geometry.
159 */
160 assert(image != (const Image *) NULL);
161 assert(image->signature == MagickSignature);
162 if (image->debug != MagickFalse)
163 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
164 assert(geometry != (const RectangleInfo *) NULL);
165 assert(exception != (ExceptionInfo *) NULL);
166 assert(exception->signature == MagickSignature);
167 if (((geometry->x+(ssize_t) geometry->width) < 0) ||
168 ((geometry->y+(ssize_t) geometry->height) < 0) ||
169 (geometry->x >= (ssize_t) image->columns) ||
170 (geometry->y >= (ssize_t) image->rows))
171 ThrowImageException(OptionError,"GeometryDoesNotContainImage");
172 page=(*geometry);
173 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
174 page.width=image->columns-page.x;
175 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
176 page.height=image->rows-page.y;
177 if (page.x < 0)
178 {
179 page.width+=page.x;
180 page.x=0;
181 }
182 if (page.y < 0)
183 {
184 page.height+=page.y;
185 page.y=0;
186 }
187
188 if ((page.width == 0) || (page.height == 0))
189 ThrowImageException(OptionError,"GeometryDimensionsAreZero");
190 /*
191 Initialize crop image attributes.
192 */
193 bitmap.bmType = 0;
194 bitmap.bmWidth = (LONG) page.width;
195 bitmap.bmHeight = (LONG) page.height;
196 bitmap.bmWidthBytes = bitmap.bmWidth * 4;
197 bitmap.bmPlanes = 1;
198 bitmap.bmBitsPixel = 32;
199 bitmap.bmBits = NULL;
200
201 bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,page.width*
202 page.height*bitmap.bmBitsPixel);
203 if (bitmap_bitsH == NULL)
204 return(NULL);
205 bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
206 if ( bitmap.bmBits == NULL )
207 bitmap.bmBits = bitmap_bits;
208 if (IsRGBColorspace(image->colorspace) == MagickFalse)
209 TransformImageColorspace(image,RGBColorspace);
210 /*
211 Extract crop image.
212 */
213 q=bitmap_bits;
214 for (y=0; y < (ssize_t) page.height; y++)
215 {
216 p=GetVirtualPixels(image,page.x,page.y+y,page.width,1,exception);
217 if (p == (const Quantum *) NULL)
218 break;
219
220#if MAGICKCORE_QUANTUM_DEPTH == 8
221 /* Form of PixelPacket is identical to RGBQUAD when MAGICKCORE_QUANTUM_DEPTH==8 */
222 CopyMagickMemory((void*)q,(const void*)p,page.width*sizeof(PixelPacket));
223 q += page.width;
224
225#else /* 16 or 32 bit Quantum */
226 {
227 ssize_t
228 x;
229
230 /* Transfer pixels, scaling to Quantum */
231 for( x=(ssize_t) page.width ; x> 0 ; x-- )
232 {
233 q->rgbRed = ScaleQuantumToChar(GetPixelRed(image,p));
234 q->rgbGreen = ScaleQuantumToChar(GetPixelGreen(image,p));
235 q->rgbBlue = ScaleQuantumToChar(GetPixelBlue(image,p));
236 q->rgbReserved = 0;
237 ++q;
238 ++p;
239 }
240 }
241#endif
242 proceed=SetImageProgress(image,CropImageTag,y,page.height);
243 if (proceed == MagickFalse)
244 break;
245 }
246 if (y < (ssize_t) page.height)
247 {
248 GlobalUnlock((HGLOBAL) bitmap_bitsH);
249 GlobalFree((HGLOBAL) bitmap_bitsH);
250 return((void *) NULL);
251 }
252 bitmap.bmBits=bitmap_bits;
253 bitmapH=CreateBitmapIndirect(&bitmap);
254 GlobalUnlock((HGLOBAL) bitmap_bitsH);
255 GlobalFree((HGLOBAL) bitmap_bitsH);
256 return((void *) bitmapH);
257}
258
259/*
260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
261% %
262% %
263% %
cristy3ed852e2009-09-05 21:47:34 +0000264% D l l M a i n %
265% %
266% %
267% %
268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
269%
270% DllMain() is an entry point to the DLL which is called when processes and
271% threads are initialized and terminated, or upon calls to the Windows
272% LoadLibrary and FreeLibrary functions.
273%
274% The function returns TRUE of it succeeds, or FALSE if initialization fails.
275%
276% The format of the DllMain method is:
277%
278% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
279%
280% A description of each parameter follows:
281%
282% o handle: handle to the DLL module
283%
284% o reason: reason for calling function:
285%
286% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
287% space of current process.
288% DLL_THREAD_ATTACH - Indicates that the current process is
289% creating a new thread. Called under the
290% context of the new thread.
291% DLL_THREAD_DETACH - Indicates that the thread is exiting.
292% Called under the context of the exiting
293% thread.
294% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
295% from the virtual address space of the
296% current process.
297%
298% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
299% and DLL_PROCESS_DETACH.
300%
301*/
302#if defined(_DLL) && defined( ProvideDllMain )
303BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
304{
305 switch (reason)
306 {
307 case DLL_PROCESS_ATTACH:
308 {
309 char
310 *module_path;
311
312 ssize_t
313 count;
314
315 module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
316 sizeof(*module_path));
317 if (module_path == (char *) NULL)
318 return(FALSE);
319 count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
320 if (count != 0)
321 {
322 char
323 *path;
324
325 for ( ; count > 0; count--)
326 if (module_path[count] == '\\')
327 {
328 module_path[count+1]='\0';
329 break;
330 }
331 MagickCoreGenesis(module_path,MagickFalse);
332 path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
333 if (path == (char *) NULL)
334 {
335 module_path=DestroyString(module_path);
336 return(FALSE);
337 }
338 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
339 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
340 {
341 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
342 {
343 char
344 *variable;
345
346 variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
347 sizeof(*variable));
348 if (variable == (char *) NULL)
349 {
350 path=DestroyString(path);
351 module_path=DestroyString(module_path);
352 return(FALSE);
353 }
cristyb51dff52011-05-19 16:55:47 +0000354 (void) FormatLocaleString(variable,16*MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000355 "%s;%s",module_path,path);
356 SetEnvironmentVariable("PATH",variable);
357 variable=DestroyString(variable);
358 }
359 }
360 path=DestroyString(path);
361 }
362 module_path=DestroyString(module_path);
363 break;
364 }
365 case DLL_PROCESS_DETACH:
366 {
367 MagickCoreTerminus();
368 break;
369 }
370 default:
371 break;
372 }
373 return(TRUE);
374}
375#endif
376
377/*
378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379% %
380% %
381% %
382% E x i t %
383% %
384% %
385% %
386%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387%
388% Exit() calls TerminateProcess for Win95.
389%
390% The format of the exit method is:
391%
392% int Exit(int status)
393%
394% A description of each parameter follows:
395%
396% o status: an integer value representing the status of the terminating
397% process.
398%
399*/
cristy30603ff2011-10-07 00:43:07 +0000400MagickPrivate int Exit(int status)
cristy3ed852e2009-09-05 21:47:34 +0000401{
402 if (IsWindows95())
403 TerminateProcess(GetCurrentProcess(),(unsigned int) status);
404 exit(status);
405 return(0);
406}
407
cristy0157aea2010-04-24 21:12:18 +0000408#if !defined(__MINGW32__)
cristy3ed852e2009-09-05 21:47:34 +0000409/*
410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
411% %
412% %
413% %
cristy6d71f8d2010-02-28 00:46:02 +0000414% g e t t i m e o f d a y %
415% %
416% %
417% %
418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
419%
420% The gettimeofday() method get the time of day.
421%
422% The format of the gettimeofday method is:
423%
424% int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
425%
426% A description of each parameter follows:
427%
428% o time_value: the time value.
429%
430% o time_zone: the time zone.
431%
432*/
cristy30603ff2011-10-07 00:43:07 +0000433MagickPrivate int gettimeofday (struct timeval *time_value,
cristy6d71f8d2010-02-28 00:46:02 +0000434 struct timezone *time_zone)
435{
cristyc05bf172010-06-04 19:53:53 +0000436#define EpochFiletime MagickLLConstant(116444736000000000)
cristy6d71f8d2010-02-28 00:46:02 +0000437
438 static int
439 is_tz_set;
440
441 if (time_value != (struct timeval *) NULL)
442 {
443 FILETIME
444 file_time;
445
446 __int64
447 time;
448
449 LARGE_INTEGER
450 date_time;
451
452 GetSystemTimeAsFileTime(&file_time);
453 date_time.LowPart=file_time.dwLowDateTime;
454 date_time.HighPart=file_time.dwHighDateTime;
455 time=date_time.QuadPart;
cristy99881662010-03-04 14:25:26 +0000456 time-=EpochFiletime;
cristy6d71f8d2010-02-28 00:46:02 +0000457 time/=10;
cristybb503372010-05-27 20:51:26 +0000458 time_value->tv_sec=(ssize_t) (time / 1000000);
459 time_value->tv_usec=(ssize_t) (time % 1000000);
cristy6d71f8d2010-02-28 00:46:02 +0000460 }
461 if (time_zone != (struct timezone *) NULL)
462 {
463 if (is_tz_set == 0)
464 {
465 _tzset();
466 is_tz_set++;
467 }
468 time_zone->tz_minuteswest=_timezone/60;
469 time_zone->tz_dsttime=_daylight;
470 }
471 return(0);
472}
cristy807fd932010-04-24 03:38:46 +0000473#endif
cristy6d71f8d2010-02-28 00:46:02 +0000474
475/*
476%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477% %
478% %
479% %
cristy30603ff2011-10-07 00:43:07 +0000480% I m a g e T o H B i t m a p %
481% %
482% %
483% %
484%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485%
486% ImageToHBITMAP() creates a Windows HBITMAP from an image.
487%
488% The format of the ImageToHBITMAP method is:
489%
490% HBITMAP ImageToHBITMAP(Image *image)
491%
492% A description of each parameter follows:
493%
494% o image: the image to convert.
495%
496*/
497MagickExport void *ImageToHBITMAP(Image *image)
498{
499 BITMAP
500 bitmap;
501
502 ExceptionInfo
503 *exception;
504
505 HANDLE
506 bitmap_bitsH;
507
508 HBITMAP
509 bitmapH;
510
511 register ssize_t
512 x;
513
514 register const Quantum
515 *p;
516
517 register RGBQUAD
518 *q;
519
520 RGBQUAD
521 *bitmap_bits;
522
523 size_t
524 length;
525
526 ssize_t
527 y;
528
529 (void) ResetMagickMemory(&bitmap,0,sizeof(bitmap));
530 bitmap.bmType=0;
531 bitmap.bmWidth=(LONG) image->columns;
532 bitmap.bmHeight=(LONG) image->rows;
533 bitmap.bmWidthBytes=4*bitmap.bmWidth;
534 bitmap.bmPlanes=1;
535 bitmap.bmBitsPixel=32;
536 bitmap.bmBits=NULL;
537 length=bitmap.bmWidthBytes*bitmap.bmHeight;
538 bitmap_bitsH=(HANDLE) GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE,length);
539 if (bitmap_bitsH == NULL)
540 {
541 char
542 *message;
543
544 message=GetExceptionMessage(errno);
545 (void) ThrowMagickException(&image->exception,GetMagickModule(),
546 ResourceLimitError,"MemoryAllocationFailed","`%s'",message);
547 message=DestroyString(message);
548 return(NULL);
549 }
550 bitmap_bits=(RGBQUAD *) GlobalLock((HGLOBAL) bitmap_bitsH);
551 q=bitmap_bits;
552 if (bitmap.bmBits == NULL)
553 bitmap.bmBits=bitmap_bits;
554 (void) TransformImageColorspace(image,RGBColorspace);
555 exception=(&image->exception);
556 for (y=0; y < (ssize_t) image->rows; y++)
557 {
558 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
559 if (p == (const Quantum *) NULL)
560 break;
561 for (x=0; x < (ssize_t) image->columns; x++)
562 {
563 q->rgbRed=ScaleQuantumToChar(GetPixelRed(image,p));
564 q->rgbGreen=ScaleQuantumToChar(GetPixelGreen(image,p));
565 q->rgbBlue=ScaleQuantumToChar(GetPixelBlue(image,p));
566 q->rgbReserved=0;
567 p+=GetPixelChannels(image);
568 q++;
569 }
570 }
571 bitmap.bmBits=bitmap_bits;
572 bitmapH=CreateBitmapIndirect(&bitmap);
573 if (bitmapH == NULL)
574 {
575 char
576 *message;
577
578 message=GetExceptionMessage(errno);
579 (void) ThrowMagickException(&image->exception,GetMagickModule(),
580 ResourceLimitError,"MemoryAllocationFailed","`%s'",message);
581 message=DestroyString(message);
582 }
583 GlobalUnlock((HGLOBAL) bitmap_bitsH);
584 GlobalFree((HGLOBAL) bitmap_bitsH);
585 return((void *) bitmapH);
586}
587
588#endif
589
590/*
591%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592% %
593% %
594% %
cristy3ed852e2009-09-05 21:47:34 +0000595% I s W i n d o w s 9 5 %
596% %
597% %
598% %
599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600%
601% IsWindows95() returns true if the system is Windows 95.
602%
603% The format of the IsWindows95 method is:
604%
605% int IsWindows95()
606%
607*/
cristy30603ff2011-10-07 00:43:07 +0000608MagickPrivate int IsWindows95(void)
cristy3ed852e2009-09-05 21:47:34 +0000609{
610 OSVERSIONINFO
611 version_info;
612
613 version_info.dwOSVersionInfoSize=sizeof(version_info);
614 if (GetVersionEx(&version_info) &&
615 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
616 return(1);
617 return(0);
618}
619
620/*
621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622% %
623% %
624% %
cristy66f9c3c2011-08-13 17:12:28 +0000625% N T A r g v T o U T F 8 %
626% %
627% %
628% %
629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630%
631% NTArgvToUTF8() converts the wide command line arguments to UTF-8 to ensure
632% compatibility with Linux.
633%
634% The format of the NTArgvToUTF8 method is:
635%
636% char **NTArgvToUTF8(const int argc,wchar_t **argv)
637%
638% A description of each parameter follows:
639%
640% o argc: the number of command line arguments.
641%
642% o argv: the wide-character command line arguments.
643%
644*/
cristy30603ff2011-10-07 00:43:07 +0000645MagickPrivate char **NTArgvToUTF8(const int argc,wchar_t **argv)
cristy66f9c3c2011-08-13 17:12:28 +0000646{
647 char
648 **utf8;
649
650 ssize_t
651 i;
652
653 utf8=(char **) AcquireQuantumMemory(argc,sizeof(*utf8));
654 if (utf8 == (char **) NULL)
655 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
656 for (i=0; i < (ssize_t) argc; i++)
657 {
658 ssize_t
659 count;
660
661 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,NULL,0,NULL,NULL);
662 if (count < 0)
663 count=0;
664 utf8[i]=(char *) AcquireQuantumMemory(count+1,sizeof(**utf8));
665 if (utf8[i] == (char *) NULL)
666 {
667 for (i--; i >= 0; i--)
668 utf8[i]=DestroyString(utf8[i]);
669 utf8=(char **) RelinquishMagickMemory(utf8);
670 ThrowFatalException(ResourceLimitFatalError,
671 "UnableToConvertStringToARGV");
672 }
673 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,utf8[i],count,NULL,NULL);
674 utf8[i][count]=0;
675 }
676 return(utf8);
677}
678
679/*
680%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681% %
682% %
683% %
cristy3ed852e2009-09-05 21:47:34 +0000684% N T C l o s e D i r e c t o r y %
685% %
686% %
687% %
688%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689%
690% NTCloseDirectory() closes the named directory stream and frees the DIR
691% structure.
692%
693% The format of the NTCloseDirectory method is:
694%
695% int NTCloseDirectory(DIR *entry)
696%
697% A description of each parameter follows:
698%
699% o entry: Specifies a pointer to a DIR structure.
700%
701*/
cristy30603ff2011-10-07 00:43:07 +0000702MagickPrivate int NTCloseDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +0000703{
704 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
705 assert(entry != (DIR *) NULL);
706 FindClose(entry->hSearch);
707 entry=(DIR *) RelinquishMagickMemory(entry);
708 return(0);
709}
710
711/*
712%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713% %
714% %
715% %
716% N T C l o s e L i b r a r y %
717% %
718% %
719% %
720%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721%
722% NTCloseLibrary() unloads the module associated with the passed handle.
723%
724% The format of the NTCloseLibrary method is:
725%
726% void NTCloseLibrary(void *handle)
727%
728% A description of each parameter follows:
729%
730% o handle: Specifies a handle to a previously loaded dynamic module.
731%
732*/
cristy30603ff2011-10-07 00:43:07 +0000733MagickPrivate int NTCloseLibrary(void *handle)
cristy3ed852e2009-09-05 21:47:34 +0000734{
735 if (IsWindows95())
736 return(FreeLibrary((HINSTANCE) handle));
737 return(!(FreeLibrary((HINSTANCE) handle)));
738}
739
740/*
741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742% %
743% %
744% %
745% N T C o n t r o l H a n d l e r %
746% %
747% %
748% %
749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750%
751% NTControlHandler() registers a control handler that is activated when, for
752% example, a ctrl-c is received.
753%
754% The format of the NTControlHandler method is:
755%
756% int NTControlHandler(void)
757%
758*/
759
760static BOOL ControlHandler(DWORD type)
761{
cristy3b743bb2009-09-14 16:07:59 +0000762 (void) type;
cristyf34a1452009-10-24 22:29:27 +0000763 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +0000764 return(FALSE);
765}
766
cristy30603ff2011-10-07 00:43:07 +0000767MagickPrivate int NTControlHandler(void)
cristy3ed852e2009-09-05 21:47:34 +0000768{
769 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
770}
771
772/*
773%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
774% %
775% %
776% %
777% N T E l a p s e d T i m e %
778% %
779% %
780% %
781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
782%
783% NTElapsedTime() returns the elapsed time (in seconds) since the last call to
784% StartTimer().
785%
786% The format of the ElapsedTime method is:
787%
788% double NTElapsedTime(void)
789%
790*/
cristy30603ff2011-10-07 00:43:07 +0000791MagickPrivate double NTElapsedTime(void)
cristy3ed852e2009-09-05 21:47:34 +0000792{
793 union
794 {
795 FILETIME
796 filetime;
797
798 __int64
799 filetime64;
800 } elapsed_time;
801
802 SYSTEMTIME
803 system_time;
804
805 GetSystemTime(&system_time);
806 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
807 return((double) 1.0e-7*elapsed_time.filetime64);
808}
809
810/*
811%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
812% %
813% %
814% %
815+ N T E r r o r H a n d l e r %
816% %
817% %
818% %
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820%
821% NTErrorHandler() displays an error reason and then terminates the program.
822%
823% The format of the NTErrorHandler method is:
824%
cristy3b743bb2009-09-14 16:07:59 +0000825% void NTErrorHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +0000826% const char *description)
827%
828% A description of each parameter follows:
829%
cristy3b743bb2009-09-14 16:07:59 +0000830% o severity: Specifies the numeric error category.
cristy3ed852e2009-09-05 21:47:34 +0000831%
832% o reason: Specifies the reason to display before terminating the
833% program.
834%
835% o description: Specifies any description to the reason.
836%
837*/
cristy30603ff2011-10-07 00:43:07 +0000838MagickPrivate void NTErrorHandler(const ExceptionType severity,
cristy3b743bb2009-09-14 16:07:59 +0000839 const char *reason,const char *description)
cristy3ed852e2009-09-05 21:47:34 +0000840{
841 char
842 buffer[3*MaxTextExtent],
843 *message;
844
cristy3b743bb2009-09-14 16:07:59 +0000845 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +0000846 if (reason == (char *) NULL)
847 {
848 MagickCoreTerminus();
849 exit(0);
850 }
851 message=GetExceptionMessage(errno);
852 if ((description != (char *) NULL) && errno)
cristyb51dff52011-05-19 16:55:47 +0000853 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000854 GetClientName(),reason,description,message);
855 else
856 if (description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000857 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +0000858 GetClientName(),reason,description);
859 else
860 if (errno != 0)
cristyb51dff52011-05-19 16:55:47 +0000861 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000862 GetClientName(),reason,message);
863 else
cristyb51dff52011-05-19 16:55:47 +0000864 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",
cristy3ed852e2009-09-05 21:47:34 +0000865 GetClientName(),reason);
866 message=DestroyString(message);
867 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
868 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
869 MagickCoreTerminus();
870 exit(0);
871}
872
873/*
874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875% %
876% %
877% %
878% N T E x i t L i b r a r y %
879% %
880% %
881% %
882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
883%
884% NTExitLibrary() exits the dynamic module loading subsystem.
885%
886% The format of the NTExitLibrary method is:
887%
888% int NTExitLibrary(void)
889%
890*/
cristy30603ff2011-10-07 00:43:07 +0000891MagickPrivate int NTExitLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +0000892{
893 return(0);
894}
895
896/*
897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898% %
899% %
900% %
901% N T G a t h e r R a n d o m D a t a %
902% %
903% %
904% %
905%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
906%
907% NTGatherRandomData() gathers random data and returns it.
908%
909% The format of the GatherRandomData method is:
910%
911% MagickBooleanType NTGatherRandomData(const size_t length,
912% unsigned char *random)
913%
914% A description of each parameter follows:
915%
916% length: the length of random data buffer
917%
918% random: the random data is returned here.
919%
920*/
cristy30603ff2011-10-07 00:43:07 +0000921MagickPrivate MagickBooleanType NTGatherRandomData(const size_t length,
cristy3ed852e2009-09-05 21:47:34 +0000922 unsigned char *random)
923{
924#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
925 HCRYPTPROV
926 handle;
927
928 int
929 status;
930
931 handle=(HCRYPTPROV) NULL;
932 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
933 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
934 if (status == 0)
935 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
936 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
937 if (status == 0)
938 return(MagickFalse);
939 status=CryptGenRandom(handle,(DWORD) length,random);
940 if (status == 0)
941 {
942 status=CryptReleaseContext(handle,0);
943 return(MagickFalse);
944 }
945 status=CryptReleaseContext(handle,0);
946 if (status == 0)
947 return(MagickFalse);
cristy3b743bb2009-09-14 16:07:59 +0000948#else
949 (void) random;
950 (void) length;
cristy3ed852e2009-09-05 21:47:34 +0000951#endif
952 return(MagickTrue);
953}
954
955/*
956%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957% %
958% %
959% %
960% N T G e t E x e c u t i o n P a t h %
961% %
962% %
963% %
964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965%
966% NTGetExecutionPath() returns the execution path of a program.
967%
968% The format of the GetExecutionPath method is:
969%
970% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
971%
972% A description of each parameter follows:
973%
974% o path: the pathname of the executable that started the process.
975%
976% o extent: the maximum extent of the path.
977%
978*/
cristy30603ff2011-10-07 00:43:07 +0000979MagickPrivate MagickBooleanType NTGetExecutionPath(char *path,
cristy3ed852e2009-09-05 21:47:34 +0000980 const size_t extent)
981{
982 GetModuleFileName(0,path,(DWORD) extent);
983 return(MagickTrue);
984}
985
986/*
987%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
988% %
989% %
990% %
991% N T G e t L a s t E r r o r %
992% %
993% %
994% %
995%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
996%
997% NTGetLastError() returns the last error that occurred.
998%
999% The format of the NTGetLastError method is:
1000%
1001% char *NTGetLastError(void)
1002%
1003*/
cristy30603ff2011-10-07 00:43:07 +00001004MagickPrivate char *NTGetLastError(void)
cristy3ed852e2009-09-05 21:47:34 +00001005{
1006 char
1007 *reason;
1008
1009 int
1010 status;
1011
1012 LPVOID
1013 buffer;
1014
1015 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
1016 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
1017 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
1018 if (!status)
1019 reason=AcquireString("An unknown error occurred");
1020 else
1021 {
1022 reason=AcquireString((const char *) buffer);
1023 LocalFree(buffer);
1024 }
1025 return(reason);
1026}
1027
1028/*
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030% %
1031% %
1032% %
1033% N T G e t L i b r a r y E r r o r %
1034% %
1035% %
1036% %
1037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038%
1039% Lt_dlerror() returns a pointer to a string describing the last error
1040% associated with a lt_dl method. Note that this function is not thread
1041% safe so it should only be used under the protection of a lock.
1042%
1043% The format of the NTGetLibraryError method is:
1044%
1045% const char *NTGetLibraryError(void)
1046%
1047*/
cristy30603ff2011-10-07 00:43:07 +00001048MagickPrivate const char *NTGetLibraryError(void)
cristy3ed852e2009-09-05 21:47:34 +00001049{
1050 static char
1051 last_error[MaxTextExtent];
1052
1053 char
1054 *error;
1055
1056 *last_error='\0';
1057 error=NTGetLastError();
1058 if (error)
1059 (void) CopyMagickString(last_error,error,MaxTextExtent);
1060 error=DestroyString(error);
1061 return(last_error);
1062}
1063
1064/*
1065%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1066% %
1067% %
1068% %
1069% N T G e t L i b r a r y S y m b o l %
1070% %
1071% %
1072% %
1073%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1074%
1075% NTGetLibrarySymbol() retrieve the procedure address of the method
1076% specified by the passed character string.
1077%
1078% The format of the NTGetLibrarySymbol method is:
1079%
1080% void *NTGetLibrarySymbol(void *handle,const char *name)
1081%
1082% A description of each parameter follows:
1083%
1084% o handle: Specifies a handle to the previously loaded dynamic module.
1085%
1086% o name: Specifies the procedure entry point to be returned.
1087%
1088*/
1089void *NTGetLibrarySymbol(void *handle,const char *name)
1090{
1091 LPFNDLLFUNC1
1092 lpfnDllFunc1;
1093
1094 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
1095 if (!lpfnDllFunc1)
1096 return((void *) NULL);
1097 return((void *) lpfnDllFunc1);
1098}
1099
1100/*
1101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102% %
1103% %
1104% %
1105% N T G e t M o d u l e P a t h %
1106% %
1107% %
1108% %
1109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110%
1111% NTGetModulePath() returns the path of the specified module.
1112%
1113% The format of the GetModulePath method is:
1114%
1115% MagickBooleanType NTGetModulePath(const char *module,char *path)
1116%
1117% A description of each parameter follows:
1118%
1119% modith: the module name.
1120%
1121% path: the module path is returned here.
1122%
1123*/
cristy30603ff2011-10-07 00:43:07 +00001124MagickPrivate MagickBooleanType NTGetModulePath(const char *module,char *path)
cristy3ed852e2009-09-05 21:47:34 +00001125{
1126 char
1127 module_path[MaxTextExtent];
1128
1129 HMODULE
1130 handle;
1131
cristybb503372010-05-27 20:51:26 +00001132 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001133 length;
1134
1135 *path='\0';
1136 handle=GetModuleHandle(module);
1137 if (handle == (HMODULE) NULL)
1138 return(MagickFalse);
1139 length=GetModuleFileName(handle,module_path,MaxTextExtent);
1140 if (length != 0)
1141 GetPathComponent(module_path,HeadPath,path);
1142 return(MagickTrue);
1143}
1144
1145/*
1146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147% %
1148% %
1149% %
cristy30603ff2011-10-07 00:43:07 +00001150+ N T G e t T y pe L i s t %
1151% %
1152% %
1153% %
1154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155%
1156% NTLoadTypeLists() loads a Windows TrueType fonts.
1157%
1158% The format of the NTLoadTypeLists method is:
1159%
1160% MagickBooleanType NTLoadTypeLists(SplayTreeInfo *type_list)
1161%
1162% A description of each parameter follows:
1163%
1164% o type_list: A linked list of fonts.
1165%
1166*/
1167MagickPrivate MagickBooleanType NTLoadTypeLists(SplayTreeInfo *type_list,
1168 ExceptionInfo *exception)
1169{
1170 HKEY
1171 reg_key = (HKEY) INVALID_HANDLE_VALUE;
1172
1173 LONG
1174 res;
1175
1176
1177 int
1178 list_entries = 0;
1179
1180 char
1181 buffer[MaxTextExtent],
1182 system_root[MaxTextExtent],
1183 font_root[MaxTextExtent];
1184
1185 DWORD
1186 type,
1187 system_root_length;
1188
1189 MagickBooleanType
1190 status;
1191
1192 /*
1193 Try to find the right Windows*\CurrentVersion key, the SystemRoot and
1194 then the Fonts key
1195 */
1196 res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
1197 "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &reg_key);
1198 if (res == ERROR_SUCCESS) {
1199 system_root_length=sizeof(system_root)-1;
1200 res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type,
1201 (BYTE*) system_root, &system_root_length);
1202 }
1203 if (res != ERROR_SUCCESS) {
1204 res = RegOpenKeyExA (HKEY_LOCAL_MACHINE,
1205 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", 0, KEY_READ, &reg_key);
1206 if (res == ERROR_SUCCESS) {
1207 system_root_length=sizeof(system_root)-1;
1208 res = RegQueryValueExA(reg_key,"SystemRoot",NULL, &type,
1209 (BYTE*)system_root, &system_root_length);
1210 }
1211 }
1212 if (res == ERROR_SUCCESS)
1213 res = RegOpenKeyExA (reg_key, "Fonts",0, KEY_READ, &reg_key);
1214 if (res != ERROR_SUCCESS)
1215 return(MagickFalse);
1216 *font_root='\0';
1217 (void) CopyMagickString(buffer,system_root,MaxTextExtent);
1218 (void) ConcatenateMagickString(buffer,"\\fonts\\arial.ttf",MaxTextExtent);
1219 if (IsPathAccessible(buffer) != MagickFalse)
1220 {
1221 (void) CopyMagickString(font_root,system_root,MaxTextExtent);
1222 (void) ConcatenateMagickString(font_root,"\\fonts\\",MaxTextExtent);
1223 }
1224 else
1225 {
1226 (void) CopyMagickString(font_root,system_root,MaxTextExtent);
1227 (void) ConcatenateMagickString(font_root,"\\",MaxTextExtent);
1228 }
1229
1230 {
1231 TypeInfo
1232 *type_info;
1233
1234 DWORD
1235 registry_index = 0,
1236 type,
1237 value_data_size,
1238 value_name_length;
1239
1240 char
1241 value_data[MaxTextExtent],
1242 value_name[MaxTextExtent];
1243
1244 res = ERROR_SUCCESS;
1245
1246 while (res != ERROR_NO_MORE_ITEMS)
1247 {
1248 char
1249 *family_extent,
1250 token[MaxTextExtent],
1251 *pos,
1252 *q;
1253
1254 value_name_length = sizeof(value_name) - 1;
1255 value_data_size = sizeof(value_data) - 1;
1256 res = RegEnumValueA ( reg_key, registry_index, value_name,
1257 &value_name_length, 0, &type, (BYTE*)value_data, &value_data_size);
1258 registry_index++;
1259 if (res != ERROR_SUCCESS)
1260 continue;
1261 if ( (pos = strstr(value_name, " (TrueType)")) == (char*) NULL )
1262 continue;
1263 *pos='\0'; /* Remove (TrueType) from string */
1264
1265 type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
1266 if (type_info == (TypeInfo *) NULL)
1267 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1268 (void) ResetMagickMemory(type_info,0,sizeof(TypeInfo));
1269
1270 type_info->path=ConstantString("Windows Fonts");
1271 type_info->signature=MagickSignature;
1272
1273 /* Name */
1274 (void) CopyMagickString(buffer,value_name,MaxTextExtent);
1275 for(pos = buffer; *pos != 0 ; pos++)
1276 if (*pos == ' ')
1277 *pos = '-';
1278 type_info->name=ConstantString(buffer);
1279
1280 /* Fullname */
1281 type_info->description=ConstantString(value_name);
1282
1283 /* Format */
1284 type_info->format=ConstantString("truetype");
1285
1286 /* Glyphs */
1287 if (strchr(value_data,'\\') != (char *) NULL)
1288 (void) CopyMagickString(buffer,value_data,MaxTextExtent);
1289 else
1290 {
1291 (void) CopyMagickString(buffer,font_root,MaxTextExtent);
1292 (void) ConcatenateMagickString(buffer,value_data,MaxTextExtent);
1293 }
1294
1295 LocaleLower(buffer);
1296 type_info->glyphs=ConstantString(buffer);
1297
1298 type_info->stretch=NormalStretch;
1299 type_info->style=NormalStyle;
1300 type_info->weight=400;
1301
1302 /* Some fonts are known to require special encodings */
1303 if ( (LocaleCompare(type_info->name, "Symbol") == 0 ) ||
1304 (LocaleCompare(type_info->name, "Wingdings") == 0 ) ||
1305 (LocaleCompare(type_info->name, "Wingdings-2") == 0 ) ||
1306 (LocaleCompare(type_info->name, "Wingdings-3") == 0 ) )
1307 type_info->encoding=ConstantString("AppleRoman");
1308
1309 family_extent=value_name;
1310
1311 for (q=value_name; *q != '\0'; )
1312 {
1313 GetMagickToken(q,(const char **) &q,token);
1314 if (*token == '\0')
1315 break;
1316
1317 if (LocaleCompare(token,"Italic") == 0)
1318 {
1319 type_info->style=ItalicStyle;
1320 }
1321
1322 else if (LocaleCompare(token,"Oblique") == 0)
1323 {
1324 type_info->style=ObliqueStyle;
1325 }
1326
1327 else if (LocaleCompare(token,"Bold") == 0)
1328 {
1329 type_info->weight=700;
1330 }
1331
1332 else if (LocaleCompare(token,"Thin") == 0)
1333 {
1334 type_info->weight=100;
1335 }
1336
1337 else if ( (LocaleCompare(token,"ExtraLight") == 0) ||
1338 (LocaleCompare(token,"UltraLight") == 0) )
1339 {
1340 type_info->weight=200;
1341 }
1342
1343 else if (LocaleCompare(token,"Light") == 0)
1344 {
1345 type_info->weight=300;
1346 }
1347
1348 else if ( (LocaleCompare(token,"Normal") == 0) ||
1349 (LocaleCompare(token,"Regular") == 0) )
1350 {
1351 type_info->weight=400;
1352 }
1353
1354 else if (LocaleCompare(token,"Medium") == 0)
1355 {
1356 type_info->weight=500;
1357 }
1358
1359 else if ( (LocaleCompare(token,"SemiBold") == 0) ||
1360 (LocaleCompare(token,"DemiBold") == 0) )
1361 {
1362 type_info->weight=600;
1363 }
1364
1365 else if ( (LocaleCompare(token,"ExtraBold") == 0) ||
1366 (LocaleCompare(token,"UltraBold") == 0) )
1367 {
1368 type_info->weight=800;
1369 }
1370
1371 else if ( (LocaleCompare(token,"Heavy") == 0) ||
1372 (LocaleCompare(token,"Black") == 0) )
1373 {
1374 type_info->weight=900;
1375 }
1376
1377 else if (LocaleCompare(token,"Condensed") == 0)
1378 {
1379 type_info->stretch = CondensedStretch;
1380 }
1381
1382 else if (LocaleCompare(token,"Expanded") == 0)
1383 {
1384 type_info->stretch = ExpandedStretch;
1385 }
1386
1387 else if (LocaleCompare(token,"ExtraCondensed") == 0)
1388 {
1389 type_info->stretch = ExtraCondensedStretch;
1390 }
1391
1392 else if (LocaleCompare(token,"ExtraExpanded") == 0)
1393 {
1394 type_info->stretch = ExtraExpandedStretch;
1395 }
1396
1397 else if (LocaleCompare(token,"SemiCondensed") == 0)
1398 {
1399 type_info->stretch = SemiCondensedStretch;
1400 }
1401
1402 else if (LocaleCompare(token,"SemiExpanded") == 0)
1403 {
1404 type_info->stretch = SemiExpandedStretch;
1405 }
1406
1407 else if (LocaleCompare(token,"UltraCondensed") == 0)
1408 {
1409 type_info->stretch = UltraCondensedStretch;
1410 }
1411
1412 else if (LocaleCompare(token,"UltraExpanded") == 0)
1413 {
1414 type_info->stretch = UltraExpandedStretch;
1415 }
1416
1417 else
1418 {
1419 family_extent=q;
1420 }
1421 }
1422
1423 (void) CopyMagickString(buffer,value_name,family_extent-value_name+1);
1424 StripString(buffer);
1425 type_info->family=ConstantString(buffer);
1426
1427 list_entries++;
1428 status=AddValueToSplayTree(type_list,ConstantString(type_info->name),
1429 type_info);
1430 if (status == MagickFalse)
1431 (void) ThrowMagickException(exception,GetMagickModule(),
1432 ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
1433 }
1434 }
1435 RegCloseKey ( reg_key );
1436 return(MagickTrue);
1437}
1438
1439/*
1440%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1441% %
1442% %
1443% %
cristy3ed852e2009-09-05 21:47:34 +00001444% N T G h o s t s c r i p t D L L %
1445% %
1446% %
1447% %
1448%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1449%
cristydefb3f02009-09-10 02:18:35 +00001450% NTGhostscriptDLL() returns the path to the most recent Ghostscript version
1451% DLL. The method returns TRUE on success otherwise FALSE.
cristy3ed852e2009-09-05 21:47:34 +00001452%
1453% The format of the NTGhostscriptDLL method is:
1454%
cristyfc0f64b2009-09-09 18:57:08 +00001455% int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001456%
1457% A description of each parameter follows:
1458%
cristyfc0f64b2009-09-09 18:57:08 +00001459% o path: return the Ghostscript DLL path here.
cristy3ed852e2009-09-05 21:47:34 +00001460%
cristyfc0f64b2009-09-09 18:57:08 +00001461% o length: the buffer length.
cristy3ed852e2009-09-05 21:47:34 +00001462%
1463*/
1464
cristyfc0f64b2009-09-09 18:57:08 +00001465static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
1466 char *value,int *length)
cristy3ed852e2009-09-05 21:47:34 +00001467{
cristyfc0f64b2009-09-09 18:57:08 +00001468 BYTE
1469 byte,
cristy3ed852e2009-09-05 21:47:34 +00001470 *p;
1471
cristyfc0f64b2009-09-09 18:57:08 +00001472 DWORD
1473 extent,
1474 type;
cristy3ed852e2009-09-05 21:47:34 +00001475
cristy3ed852e2009-09-05 21:47:34 +00001476 HKEY
1477 hkey;
1478
cristy3ed852e2009-09-05 21:47:34 +00001479 LONG
cristyfc0f64b2009-09-09 18:57:08 +00001480 status;
cristy3ed852e2009-09-05 21:47:34 +00001481
cristyfc0f64b2009-09-09 18:57:08 +00001482 /*
cristydefb3f02009-09-10 02:18:35 +00001483 Get a registry value: key = root\\key, named value = name.
1484 */
cristyfc0f64b2009-09-09 18:57:08 +00001485 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
1486 return(1); /* no match */
1487 p=(BYTE *) value;
1488 type=REG_SZ;
1489 extent=(*length);
1490 if (p == (BYTE *) NULL)
cristydefb3f02009-09-10 02:18:35 +00001491 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
cristyfc0f64b2009-09-09 18:57:08 +00001492 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
1493 RegCloseKey(hkey);
1494 if (status == ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +00001495 {
cristyfc0f64b2009-09-09 18:57:08 +00001496 *length=extent;
1497 return(0); /* return the match */
1498 }
1499 if (status == ERROR_MORE_DATA)
1500 {
1501 *length=extent;
cristydefb3f02009-09-10 02:18:35 +00001502 return(-1); /* buffer not large enough */
cristy3ed852e2009-09-05 21:47:34 +00001503 }
1504 return(1); /* not found */
1505}
1506
cristydefb3f02009-09-10 02:18:35 +00001507static int NTLocateGhostscript(const char **product_family,int *major_version,
cristyfc0f64b2009-09-09 18:57:08 +00001508 int *minor_version)
cristy3ed852e2009-09-05 21:47:34 +00001509{
cristyfc0f64b2009-09-09 18:57:08 +00001510 int
1511 i;
cristy3ed852e2009-09-05 21:47:34 +00001512
cristyfc0f64b2009-09-09 18:57:08 +00001513 MagickBooleanType
1514 status;
1515
1516 static const char
1517 *products[4] =
1518 {
1519 "GPL Ghostscript",
1520 "GNU Ghostscript",
1521 "AFPL Ghostscript",
cristy82b15832009-10-06 19:17:37 +00001522 "Aladdin Ghostscript"
cristyfc0f64b2009-09-09 18:57:08 +00001523 };
1524
1525 /*
1526 Find the most recent version of Ghostscript.
1527 */
1528 status=FALSE;
1529 *product_family=NULL;
1530 *major_version=5;
1531 *minor_version=49; /* min version of Ghostscript is 5.50 */
cristybb503372010-05-27 20:51:26 +00001532 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +00001533 {
1534 char
1535 key[MaxTextExtent];
1536
1537 HKEY
1538 hkey,
1539 root;
1540
cristye66bcb42009-09-17 13:31:08 +00001541 REGSAM
1542 mode;
1543
cristyb51dff52011-05-19 16:55:47 +00001544 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
cristyfc0f64b2009-09-09 18:57:08 +00001545 root=HKEY_LOCAL_MACHINE;
cristye66bcb42009-09-17 13:31:08 +00001546 mode=KEY_READ;
1547#if defined(KEY_WOW64_32KEY)
1548 mode|=KEY_WOW64_32KEY;
1549#endif
1550 if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
cristyfc0f64b2009-09-09 18:57:08 +00001551 {
1552 DWORD
1553 extent;
1554
1555 int
1556 j;
1557
1558 /*
1559 Now enumerate the keys.
1560 */
1561 extent=sizeof(key)/sizeof(char);
1562 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
1563 {
1564 int
1565 major,
1566 minor;
1567
1568 major=0;
1569 minor=0;
1570 if (sscanf(key,"%d.%d",&major,&minor) != 2)
1571 continue;
1572 if ((major > *major_version) || ((major == *major_version) &&
1573 (minor > *minor_version)))
1574 {
1575 *product_family=products[i];
1576 *major_version=major;
1577 *minor_version=minor;
cristy37f63772009-11-16 17:06:36 +00001578 status=TRUE;
cristyfc0f64b2009-09-09 18:57:08 +00001579 }
cristyfc0f64b2009-09-09 18:57:08 +00001580 }
cristye66bcb42009-09-17 13:31:08 +00001581 (void) RegCloseKey(hkey);
1582 }
1583 }
cristy37f63772009-11-16 17:06:36 +00001584 if (status == FALSE)
cristyfc0f64b2009-09-09 18:57:08 +00001585 {
1586 *major_version=0;
1587 *minor_version=0;
1588 }
1589 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
1590 "version %d.%02d",*product_family,*major_version,*minor_version);
1591 return(status);
1592}
1593
1594static int NTGhostscriptGetString(const char *name,char *value,
1595 const size_t length)
1596{
cristy3ed852e2009-09-05 21:47:34 +00001597 char
cristy3ed852e2009-09-05 21:47:34 +00001598 key[MaxTextExtent];
1599
1600 int
cristyfc0f64b2009-09-09 18:57:08 +00001601 i,
1602 extent;
cristy82b15832009-10-06 19:17:37 +00001603
cristyfc0f64b2009-09-09 18:57:08 +00001604 static const char
cristydefb3f02009-09-10 02:18:35 +00001605 *product_family = (const char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001606
cristyfc0f64b2009-09-09 18:57:08 +00001607 static int
1608 major_version=0,
1609 minor_version=0;
cristy3ed852e2009-09-05 21:47:34 +00001610
cristyfc0f64b2009-09-09 18:57:08 +00001611 struct
1612 {
1613 const HKEY
1614 hkey;
cristy3ed852e2009-09-05 21:47:34 +00001615
cristyfc0f64b2009-09-09 18:57:08 +00001616 const char
1617 *name;
1618 }
1619 hkeys[2] =
1620 {
1621 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
1622 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
1623 };
1624
1625 /*
1626 Get a string from the installed Ghostscript.
1627 */
cristydefb3f02009-09-10 02:18:35 +00001628 *value='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001629 if (product_family == NULL)
cristydefb3f02009-09-10 02:18:35 +00001630 (void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
cristyfc0f64b2009-09-09 18:57:08 +00001631 if (product_family == NULL)
1632 return(FALSE);
cristyb51dff52011-05-19 16:55:47 +00001633 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
cristyfc0f64b2009-09-09 18:57:08 +00001634 product_family,major_version,minor_version);
cristybb503372010-05-27 20:51:26 +00001635 for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +00001636 {
cristy76319442009-09-22 02:04:05 +00001637 extent=(int) length;
cristyfc0f64b2009-09-09 18:57:08 +00001638 if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
1639 {
1640 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1641 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
1642 return(TRUE);
1643 }
1644 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1645 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
1646 }
cristy3ed852e2009-09-05 21:47:34 +00001647 return(FALSE);
1648}
1649
cristy30603ff2011-10-07 00:43:07 +00001650MagickPrivate int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001651{
cristy4c11ed82009-09-11 03:36:46 +00001652 static char
1653 dll[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001654
1655 *path='\0';
cristy4c11ed82009-09-11 03:36:46 +00001656 if ((*dll == '\0') &&
1657 (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
cristy106919c2009-09-11 03:46:56 +00001658 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001659 (void) CopyMagickString(path,dll,length);
cristy3ed852e2009-09-05 21:47:34 +00001660 return(TRUE);
1661}
1662
1663/*
1664%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1665% %
1666% %
1667% %
1668% N T G h o s t s c r i p t D L L V e c t o r s %
1669% %
1670% %
1671% %
1672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673%
cristydefb3f02009-09-10 02:18:35 +00001674% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
1675% function vectors to invoke Ghostscript DLL functions. A null pointer is
1676% returned if there is an error when loading the DLL or retrieving the
1677% function vectors.
cristy3ed852e2009-09-05 21:47:34 +00001678%
1679% The format of the NTGhostscriptDLLVectors method is:
1680%
cristydefb3f02009-09-10 02:18:35 +00001681% const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001682%
1683*/
cristy30603ff2011-10-07 00:43:07 +00001684MagickPrivate const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001685{
cristyfc0f64b2009-09-09 18:57:08 +00001686 if (NTGhostscriptLoadDLL() == FALSE)
cristydefb3f02009-09-10 02:18:35 +00001687 return((GhostInfo *) NULL);
1688 return(&ghost_info);
cristy3ed852e2009-09-05 21:47:34 +00001689}
1690
1691/*
1692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693% %
1694% %
1695% %
1696% N T G h o s t s c r i p t E X E %
1697% %
1698% %
1699% %
1700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1701%
1702% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
cristyfc0f64b2009-09-09 18:57:08 +00001703% The method returns FALSE if a full path value is not obtained and returns
1704% a default path of gswin32c.exe.
cristy3ed852e2009-09-05 21:47:34 +00001705%
1706% The format of the NTGhostscriptEXE method is:
1707%
cristyfc0f64b2009-09-09 18:57:08 +00001708% int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001709%
1710% A description of each parameter follows:
1711%
cristyfc0f64b2009-09-09 18:57:08 +00001712% o path: return the Ghostscript executable path here.
cristy3ed852e2009-09-05 21:47:34 +00001713%
cristyb32b90a2009-09-07 21:45:48 +00001714% o length: length of buffer.
cristy3ed852e2009-09-05 21:47:34 +00001715%
1716*/
cristy30603ff2011-10-07 00:43:07 +00001717MagickPrivate int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001718{
cristy4c11ed82009-09-11 03:36:46 +00001719 register char
cristy3ed852e2009-09-05 21:47:34 +00001720 *p;
1721
cristyfc0f64b2009-09-09 18:57:08 +00001722 static char
cristy4c11ed82009-09-11 03:36:46 +00001723 program[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001724
cristyb32b90a2009-09-07 21:45:48 +00001725 (void) CopyMagickString(path,"gswin32c.exe",length);
cristy4c11ed82009-09-11 03:36:46 +00001726 if ((*program == '\0') &&
1727 (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE))
cristyb32b90a2009-09-07 21:45:48 +00001728 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001729 p=strrchr(program,'\\');
cristy7ba1b042011-02-05 19:07:50 +00001730 if (p != (char *) NULL)
cristy4c11ed82009-09-11 03:36:46 +00001731 {
1732 p++;
1733 *p='\0';
1734 (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program));
1735 }
1736 (void) CopyMagickString(path,program,length);
cristyb32b90a2009-09-07 21:45:48 +00001737 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001738}
1739
1740/*
1741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1742% %
1743% %
1744% %
1745% N T G h o s t s c r i p t F o n t s %
1746% %
1747% %
1748% %
1749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1750%
cristyfc0f64b2009-09-09 18:57:08 +00001751% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1752% returns FALSE if it cannot determine the font path.
cristy3ed852e2009-09-05 21:47:34 +00001753%
1754% The format of the NTGhostscriptFonts method is:
1755%
cristyfc0f64b2009-09-09 18:57:08 +00001756% int NTGhostscriptFonts(char *path, int length)
cristy3ed852e2009-09-05 21:47:34 +00001757%
1758% A description of each parameter follows:
1759%
cristyfc0f64b2009-09-09 18:57:08 +00001760% o path: return the font path here.
cristy3ed852e2009-09-05 21:47:34 +00001761%
cristyfc0f64b2009-09-09 18:57:08 +00001762% o length: length of the path buffer.
cristy3ed852e2009-09-05 21:47:34 +00001763%
1764*/
cristy30603ff2011-10-07 00:43:07 +00001765MagickPrivate int NTGhostscriptFonts(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001766{
1767 char
1768 buffer[MaxTextExtent],
1769 filename[MaxTextExtent];
1770
cristy3ed852e2009-09-05 21:47:34 +00001771 register char
1772 *p,
1773 *q;
1774
1775 *path='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001776 if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE)
cristy3ed852e2009-09-05 21:47:34 +00001777 return(FALSE);
1778 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1779 {
1780 (void) CopyMagickString(path,p+1,length+1);
1781 q=strchr(path,DirectoryListSeparator);
1782 if (q != (char *) NULL)
1783 *q='\0';
cristyb51dff52011-05-19 16:55:47 +00001784 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path,
cristy3ed852e2009-09-05 21:47:34 +00001785 DirectorySeparator);
1786 if (IsPathAccessible(filename) != MagickFalse)
1787 return(TRUE);
1788 }
1789 return(FALSE);
1790}
1791
1792/*
1793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1794% %
1795% %
1796% %
1797% N T G h o s t s c r i p t L o a d D L L %
1798% %
1799% %
1800% %
1801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1802%
1803% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
cristyfc0f64b2009-09-09 18:57:08 +00001804% TRUE if it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001805%
1806% The format of the NTGhostscriptLoadDLL method is:
1807%
1808% int NTGhostscriptLoadDLL(void)
1809%
1810*/
cristy30603ff2011-10-07 00:43:07 +00001811MagickPrivate int NTGhostscriptLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001812{
1813 char
cristyfc0f64b2009-09-09 18:57:08 +00001814 path[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001815
cristydefb3f02009-09-10 02:18:35 +00001816 if (ghost_handle != (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001817 return(TRUE);
1818 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1819 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001820 ghost_handle=lt_dlopen(path);
1821 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001822 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001823 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1824 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1825 lt_dlsym(ghost_handle,"gsapi_exit");
1826 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1827 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1828 ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1829 lt_dlsym(ghost_handle,"gsapi_new_instance"));
1830 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1831 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1832 ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1833 lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1834 if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1835 (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1836 (ghost_info.delete_instance == NULL))
cristyfc0f64b2009-09-09 18:57:08 +00001837 return(FALSE);
1838 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001839}
1840
1841/*
1842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1843% %
1844% %
1845% %
1846% N T G h o s t s c r i p t U n L o a d D L L %
1847% %
1848% %
1849% %
1850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1851%
cristyfc0f64b2009-09-09 18:57:08 +00001852% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1853% it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001854%
1855% The format of the NTGhostscriptUnLoadDLL method is:
1856%
1857% int NTGhostscriptUnLoadDLL(void)
1858%
1859*/
cristy30603ff2011-10-07 00:43:07 +00001860MagickPrivate int NTGhostscriptUnLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001861{
cristyfc0f64b2009-09-09 18:57:08 +00001862 int
1863 status;
1864
cristydefb3f02009-09-10 02:18:35 +00001865 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001866 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001867 status=lt_dlclose(ghost_handle);
1868 ghost_handle=(void *) NULL;
1869 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
cristyfc0f64b2009-09-09 18:57:08 +00001870 return(status);
cristy3ed852e2009-09-05 21:47:34 +00001871}
1872
1873/*
1874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1875% %
1876% %
1877% %
1878% N T I n i t i a l i z e L i b r a r y %
1879% %
1880% %
1881% %
1882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1883%
1884% NTInitializeLibrary() initializes the dynamic module loading subsystem.
1885%
1886% The format of the NTInitializeLibrary method is:
1887%
1888% int NTInitializeLibrary(void)
1889%
1890*/
cristy30603ff2011-10-07 00:43:07 +00001891MagickPrivate int NTInitializeLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +00001892{
1893 return(0);
1894}
1895
1896/*
1897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1898% %
1899% %
1900% %
cristy30603ff2011-10-07 00:43:07 +00001901% N T I s M a g i c k C o n f l i c t %
1902% %
1903% %
1904% %
1905%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1906%
1907% NTIsMagickConflict() returns true if the image format conflicts with a
1908% logical drive (.e.g. X:).
1909%
1910% The format of the IsMagickConflict method is:
1911%
1912% MagickBooleanType IsMagickConflict(const char *magick)
1913%
1914% A description of each parameter follows:
1915%
1916% o magick: Specifies the image format.
1917%
1918*/
1919MagickPrivate MagickBooleanType NTIsMagickConflict(const char *magick)
1920{
1921 MagickBooleanType
1922 status;
1923
1924 assert(magick != (char *) NULL);
1925 if (strlen(magick) > 1)
1926 return(MagickFalse);
1927 status=(GetLogicalDrives() & (1 << ((toupper((int) (*magick)))-'A'))) != 0 ?
1928 MagickTrue : MagickFalse;
1929 return(status);
1930}
1931
1932/*
1933%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1934% %
1935% %
1936% %
cristy3ed852e2009-09-05 21:47:34 +00001937+ N T M a p M e m o r y %
1938% %
1939% %
1940% %
1941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1942%
1943% Mmap() emulates the Unix method of the same name.
1944%
1945% The format of the NTMapMemory method is:
1946%
cristy30603ff2011-10-07 00:43:07 +00001947% MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001948% int access,int file,MagickOffsetType offset)
1949%
1950*/
cristy30603ff2011-10-07 00:43:07 +00001951MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001952 int flags,int file,MagickOffsetType offset)
1953{
1954 DWORD
1955 access_mode,
1956 high_length,
1957 high_offset,
1958 low_length,
1959 low_offset,
1960 protection_mode;
1961
1962 HANDLE
1963 file_handle,
1964 map_handle;
1965
1966 void
1967 *map;
1968
cristy3b743bb2009-09-14 16:07:59 +00001969 (void) address;
cristy3ed852e2009-09-05 21:47:34 +00001970 access_mode=0;
1971 file_handle=INVALID_HANDLE_VALUE;
1972 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1973 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1974 map_handle=INVALID_HANDLE_VALUE;
1975 map=(void *) NULL;
1976 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1977 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1978 protection_mode=0;
1979 if (protection & PROT_WRITE)
1980 {
1981 access_mode=FILE_MAP_WRITE;
1982 if (!(flags & MAP_PRIVATE))
1983 protection_mode=PAGE_READWRITE;
1984 else
1985 {
1986 access_mode=FILE_MAP_COPY;
1987 protection_mode=PAGE_WRITECOPY;
1988 }
1989 }
1990 else
1991 if (protection & PROT_READ)
1992 {
1993 access_mode=FILE_MAP_READ;
1994 protection_mode=PAGE_READONLY;
1995 }
1996 if ((file == -1) && (flags & MAP_ANONYMOUS))
1997 file_handle=INVALID_HANDLE_VALUE;
1998 else
1999 file_handle=(HANDLE) _get_osfhandle(file);
2000 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
2001 low_length,0);
2002 if (map_handle)
2003 {
2004 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
2005 length);
2006 CloseHandle(map_handle);
2007 }
2008 if (map == (void *) NULL)
2009 return((void *) MAP_FAILED);
2010 return((void *) ((char *) map));
2011}
2012
2013/*
2014%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2015% %
2016% %
2017% %
2018% N T O p e n D i r e c t o r y %
2019% %
2020% %
2021% %
2022%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2023%
2024% NTOpenDirectory() opens the directory named by filename and associates a
2025% directory stream with it.
2026%
2027% The format of the NTOpenDirectory method is:
2028%
2029% DIR *NTOpenDirectory(const char *path)
2030%
2031% A description of each parameter follows:
2032%
2033% o entry: Specifies a pointer to a DIR structure.
2034%
2035*/
cristy30603ff2011-10-07 00:43:07 +00002036MagickPrivate DIR *NTOpenDirectory(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00002037{
2038 char
2039 file_specification[MaxTextExtent];
2040
2041 DIR
2042 *entry;
2043
2044 size_t
2045 length;
2046
2047 assert(path != (const char *) NULL);
2048 length=CopyMagickString(file_specification,path,MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00002049 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002050 return((DIR *) NULL);
2051 length=ConcatenateMagickString(file_specification,DirectorySeparator,
2052 MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00002053 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002054 return((DIR *) NULL);
cristy73bd4a52010-10-05 11:24:23 +00002055 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
cristy3ed852e2009-09-05 21:47:34 +00002056 if (entry != (DIR *) NULL)
2057 {
2058 entry->firsttime=TRUE;
2059 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
2060 }
2061 if (entry->hSearch == INVALID_HANDLE_VALUE)
2062 {
2063 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00002064 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002065 {
2066 entry=(DIR *) RelinquishMagickMemory(entry);
2067 return((DIR *) NULL);
2068 }
2069 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
2070 if (entry->hSearch == INVALID_HANDLE_VALUE)
2071 {
2072 entry=(DIR *) RelinquishMagickMemory(entry);
2073 return((DIR *) NULL);
2074 }
2075 }
2076 return(entry);
2077}
2078
2079/*
2080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2081% %
2082% %
2083% %
2084% N T O p e n L i b r a r y %
2085% %
2086% %
2087% %
2088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2089%
2090% NTOpenLibrary() loads a dynamic module into memory and returns a handle that
2091% can be used to access the various procedures in the module.
2092%
2093% The format of the NTOpenLibrary method is:
2094%
2095% void *NTOpenLibrary(const char *filename)
2096%
2097% A description of each parameter follows:
2098%
2099% o path: Specifies a pointer to string representing dynamic module that
2100% is to be loaded.
2101%
2102*/
2103
2104static const char *GetSearchPath( void )
2105{
2106#if defined(MAGICKCORE_LTDL_DELEGATE)
2107 return(lt_dlgetsearchpath());
2108#else
2109 return(lt_slsearchpath);
2110#endif
2111}
2112
cristy30603ff2011-10-07 00:43:07 +00002113MagickPrivate void *NTOpenLibrary(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +00002114{
2115#define MaxPathElements 31
2116
2117 char
2118 buffer[MaxTextExtent];
2119
2120 int
2121 index;
2122
2123 register const char
2124 *p,
2125 *q;
2126
2127 register int
2128 i;
2129
2130 UINT
2131 mode;
2132
2133 void
2134 *handle;
2135
2136 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
2137 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
2138 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL))
2139 {
2140 SetErrorMode(mode);
2141 return(handle);
2142 }
2143 p=(char *) GetSearchPath();
2144 index=0;
2145 while (index < MaxPathElements)
2146 {
2147 q=strchr(p,DirectoryListSeparator);
2148 if (q == (char *) NULL)
2149 {
2150 (void) CopyMagickString(buffer,p,MaxTextExtent);
2151 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
2152 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
2153 handle=(void *) LoadLibraryEx(buffer,NULL,
2154 LOAD_WITH_ALTERED_SEARCH_PATH);
2155 break;
2156 }
2157 i=q-p;
2158 (void) CopyMagickString(buffer,p,i+1);
2159 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
2160 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
2161 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
2162 if (handle != (void *) NULL)
2163 break;
2164 p=q+1;
2165 }
2166 SetErrorMode(mode);
2167 return(handle);
2168}
2169
2170/*
2171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2172% %
2173% %
2174% %
2175% N T R e a d D i r e c t o r y %
2176% %
2177% %
2178% %
2179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2180%
2181% NTReadDirectory() returns a pointer to a structure representing the
2182% directory entry at the current position in the directory stream to which
2183% entry refers.
2184%
2185% The format of the NTReadDirectory
2186%
2187% NTReadDirectory(entry)
2188%
2189% A description of each parameter follows:
2190%
2191% o entry: Specifies a pointer to a DIR structure.
2192%
2193*/
cristy30603ff2011-10-07 00:43:07 +00002194MagickPrivate struct dirent *NTReadDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002195{
2196 int
2197 status;
2198
2199 size_t
2200 length;
2201
2202 if (entry == (DIR *) NULL)
2203 return((struct dirent *) NULL);
2204 if (!entry->firsttime)
2205 {
2206 status=FindNextFile(entry->hSearch,&entry->Win32FindData);
2207 if (status == 0)
2208 return((struct dirent *) NULL);
2209 }
2210 length=CopyMagickString(entry->file_info.d_name,
2211 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name));
2212 if (length >= sizeof(entry->file_info.d_name))
2213 return((struct dirent *) NULL);
2214 entry->firsttime=FALSE;
2215 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
2216 return(&entry->file_info);
2217}
2218
2219/*
2220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2221% %
2222% %
2223% %
2224% N T R e g i s t r y K e y L o o k u p %
2225% %
2226% %
2227% %
2228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2229%
2230% NTRegistryKeyLookup() returns ImageMagick installation path settings
2231% stored in the Windows Registry. Path settings are specific to the
2232% installed ImageMagick version so that multiple Image Magick installations
2233% may coexist.
2234%
2235% Values are stored in the registry under a base path path similar to
2236% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\5.5.7\Q:16". The provided subkey
2237% is appended to this base path to form the full key.
2238%
2239% The format of the NTRegistryKeyLookup method is:
2240%
2241% unsigned char *NTRegistryKeyLookup(const char *subkey)
2242%
2243% A description of each parameter follows:
2244%
2245% o subkey: Specifies a string that identifies the registry object.
2246% Currently supported sub-keys include: "BinPath", "ConfigurePath",
2247% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
2248%
2249*/
cristy30603ff2011-10-07 00:43:07 +00002250MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey)
cristy3ed852e2009-09-05 21:47:34 +00002251{
2252 char
2253 package_key[MaxTextExtent];
2254
2255 DWORD
2256 size,
2257 type;
2258
2259 HKEY
2260 registry_key;
2261
2262 LONG
2263 status;
2264
2265 unsigned char
2266 *value;
2267
2268 /*
2269 Look-up base key.
2270 */
cristyb51dff52011-05-19 16:55:47 +00002271 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
cristy3ed852e2009-09-05 21:47:34 +00002272 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
2273 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
2274 registry_key=(HKEY) INVALID_HANDLE_VALUE;
2275 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,&registry_key);
2276 if (status != ERROR_SUCCESS)
2277 {
2278 registry_key=(HKEY) INVALID_HANDLE_VALUE;
2279 return((unsigned char *) NULL);
2280 }
2281 /*
2282 Look-up sub key.
2283 */
2284 size=32;
2285 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
2286 if (value == (unsigned char *) NULL)
2287 {
2288 RegCloseKey(registry_key);
2289 return((unsigned char *) NULL);
2290 }
2291 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey);
2292 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
2293 if ((status == ERROR_MORE_DATA) && (type == REG_SZ))
2294 {
2295 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
2296 if (value == (BYTE *) NULL)
2297 {
2298 RegCloseKey(registry_key);
2299 return((unsigned char *) NULL);
2300 }
2301 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
2302 }
2303 RegCloseKey(registry_key);
2304 if ((type != REG_SZ) || (status != ERROR_SUCCESS))
2305 value=(unsigned char *) RelinquishMagickMemory(value);
2306 return((unsigned char *) value);
2307}
2308
2309/*
2310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2311% %
2312% %
2313% %
2314% N T R e p o r t E v e n t %
2315% %
2316% %
2317% %
2318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2319%
2320% NTReportEvent() reports an event.
2321%
2322% The format of the NTReportEvent method is:
2323%
2324% MagickBooleanType NTReportEvent(const char *event,
2325% const MagickBooleanType error)
2326%
2327% A description of each parameter follows:
2328%
2329% o event: the event.
2330%
2331% o error: MagickTrue the event is an error.
2332%
2333*/
cristy30603ff2011-10-07 00:43:07 +00002334MagickPrivate MagickBooleanType NTReportEvent(const char *event,
cristy3ed852e2009-09-05 21:47:34 +00002335 const MagickBooleanType error)
2336{
2337 const char
2338 *events[1];
2339
2340 HANDLE
2341 handle;
2342
2343 WORD
2344 type;
2345
2346 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
2347 if (handle == NULL)
2348 return(MagickFalse);
2349 events[0]=event;
2350 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
2351 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
2352 DeregisterEventSource(handle);
2353 return(MagickTrue);
2354}
2355
2356/*
2357%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2358% %
2359% %
2360% %
2361% N T R e s o u r c e T o B l o b %
2362% %
2363% %
2364% %
2365%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2366%
2367% NTResourceToBlob() returns a blob containing the contents of the resource
2368% in the current executable specified by the id parameter. This currently
2369% used to retrieve MGK files tha have been embedded into the various command
2370% line utilities.
2371%
2372% The format of the NTResourceToBlob method is:
2373%
2374% unsigned char *NTResourceToBlob(const char *id)
2375%
2376% A description of each parameter follows:
2377%
2378% o id: Specifies a string that identifies the resource.
2379%
2380*/
cristy30603ff2011-10-07 00:43:07 +00002381MagickPrivate unsigned char *NTResourceToBlob(const char *id)
cristy3ed852e2009-09-05 21:47:34 +00002382{
2383 char
2384 path[MaxTextExtent];
2385
2386 DWORD
2387 length;
2388
2389 HGLOBAL
2390 global;
2391
2392 HMODULE
2393 handle;
2394
2395 HRSRC
2396 resource;
2397
2398 unsigned char
2399 *blob,
2400 *value;
2401
2402 assert(id != (const char *) NULL);
2403 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
cristyb51dff52011-05-19 16:55:47 +00002404 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +00002405 DirectorySeparator,GetClientName());
2406 if (IsPathAccessible(path) != MagickFalse)
2407 handle=GetModuleHandle(path);
2408 else
2409 handle=GetModuleHandle(0);
2410 if (!handle)
2411 return((unsigned char *) NULL);
2412 resource=FindResource(handle,id,"IMAGEMAGICK");
2413 if (!resource)
2414 return((unsigned char *) NULL);
2415 global=LoadResource(handle,resource);
2416 if (!global)
2417 return((unsigned char *) NULL);
2418 length=SizeofResource(handle,resource);
2419 value=(unsigned char *) LockResource(global);
2420 if (!value)
2421 {
2422 FreeResource(global);
2423 return((unsigned char *) NULL);
2424 }
2425 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
2426 sizeof(*blob));
2427 if (blob != (unsigned char *) NULL)
2428 {
2429 (void) CopyMagickMemory(blob,value,length);
2430 blob[length]='\0';
2431 }
2432 UnlockResource(global);
2433 FreeResource(global);
2434 return(blob);
2435}
2436
2437/*
2438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2439% %
2440% %
2441% %
2442% N T S e e k D i r e c t o r y %
2443% %
2444% %
2445% %
2446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2447%
2448% NTSeekDirectory() sets the position of the next NTReadDirectory() operation
2449% on the directory stream.
2450%
2451% The format of the NTSeekDirectory method is:
2452%
cristybb503372010-05-27 20:51:26 +00002453% void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00002454%
2455% A description of each parameter follows:
2456%
2457% o entry: Specifies a pointer to a DIR structure.
2458%
2459% o position: specifies the position associated with the directory
2460% stream.
2461%
2462*/
cristy30603ff2011-10-07 00:43:07 +00002463MagickPrivate void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00002464{
cristy3b743bb2009-09-14 16:07:59 +00002465 (void) position;
cristy3ed852e2009-09-05 21:47:34 +00002466 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2467 assert(entry != (DIR *) NULL);
2468}
2469
2470/*
2471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2472% %
2473% %
2474% %
2475% N T S e t S e a r c h P a t h %
2476% %
2477% %
2478% %
2479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2480%
2481% NTSetSearchPath() sets the current locations that the subsystem should
2482% look at to find dynamically loadable modules.
2483%
2484% The format of the NTSetSearchPath method is:
2485%
2486% int NTSetSearchPath(const char *path)
2487%
2488% A description of each parameter follows:
2489%
2490% o path: Specifies a pointer to string representing the search path
2491% for DLL's that can be dynamically loaded.
2492%
2493*/
cristy30603ff2011-10-07 00:43:07 +00002494MagickPrivate int NTSetSearchPath(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00002495{
2496#if defined(MAGICKCORE_LTDL_DELEGATE)
2497 lt_dlsetsearchpath(path);
2498#else
2499 if (lt_slsearchpath != (char *) NULL)
2500 lt_slsearchpath=DestroyString(lt_slsearchpath);
2501 if (path != (char *) NULL)
2502 lt_slsearchpath=AcquireString(path);
2503#endif
2504 return(0);
2505}
2506
2507/*
2508%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2509% %
2510% %
2511% %
2512+ N T S y n c M e m o r y %
2513% %
2514% %
2515% %
2516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2517%
2518% NTSyncMemory() emulates the Unix method of the same name.
2519%
2520% The format of the NTSyncMemory method is:
2521%
2522% int NTSyncMemory(void *address,size_t length,int flags)
2523%
2524% A description of each parameter follows:
2525%
2526% o address: the address of the binary large object.
2527%
2528% o length: the length of the binary large object.
2529%
2530% o flags: Option flags (ignored for Windows).
2531%
2532*/
cristy30603ff2011-10-07 00:43:07 +00002533MagickPrivate int NTSyncMemory(void *address,size_t length,int flags)
cristy3ed852e2009-09-05 21:47:34 +00002534{
cristy3b743bb2009-09-14 16:07:59 +00002535 (void) flags;
cristy3ed852e2009-09-05 21:47:34 +00002536 if (FlushViewOfFile(address,length) == MagickFalse)
2537 return(-1);
2538 return(0);
2539}
2540
2541/*
2542%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2543% %
2544% %
2545% %
2546% N T S y s t e m C o m m a n d %
2547% %
2548% %
2549% %
2550%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2551%
2552% NTSystemCommand() executes the specified command and waits until it
2553% terminates. The returned value is the exit status of the command.
2554%
cristyb32b90a2009-09-07 21:45:48 +00002555% The format of the NTSystemCommand method is:
cristy3ed852e2009-09-05 21:47:34 +00002556%
cristy6de4bc22010-01-12 17:10:35 +00002557% int NTSystemCommand(MagickFalse,const char *command)
cristy3ed852e2009-09-05 21:47:34 +00002558%
2559% A description of each parameter follows:
2560%
2561% o command: This string is the command to execute.
2562%
2563*/
cristy30603ff2011-10-07 00:43:07 +00002564MagickPrivate int NTSystemCommand(const char *command)
cristy3ed852e2009-09-05 21:47:34 +00002565{
2566 char
2567 local_command[MaxTextExtent];
2568
2569 DWORD
2570 child_status;
2571
2572 int
2573 status;
2574
2575 MagickBooleanType
2576 background_process;
2577
2578 PROCESS_INFORMATION
2579 process_info;
2580
2581 STARTUPINFO
2582 startup_info;
2583
2584 if (command == (char *) NULL)
2585 return(-1);
2586 GetStartupInfo(&startup_info);
2587 startup_info.dwFlags=STARTF_USESHOWWINDOW;
2588 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
2589 (void) CopyMagickString(local_command,command,MaxTextExtent);
2590 background_process=command[strlen(command)-1] == '&' ? MagickTrue :
2591 MagickFalse;
2592 if (background_process)
2593 local_command[strlen(command)-1]='\0';
2594 if (command[strlen(command)-1] == '|')
2595 local_command[strlen(command)-1]='\0';
2596 else
2597 startup_info.wShowWindow=SW_SHOWDEFAULT;
2598 status=CreateProcess((LPCTSTR) NULL,local_command,
2599 (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,
2600 (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
2601 &process_info);
2602 if (status == 0)
2603 return(-1);
2604 if (background_process)
2605 return(status == 0);
2606 status=WaitForSingleObject(process_info.hProcess,INFINITE);
2607 if (status != WAIT_OBJECT_0)
2608 return(status);
2609 status=GetExitCodeProcess(process_info.hProcess,&child_status);
2610 if (status == 0)
2611 return(-1);
2612 CloseHandle(process_info.hProcess);
2613 CloseHandle(process_info.hThread);
2614 return((int) child_status);
2615}
2616
2617/*
2618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2619% %
2620% %
2621% %
2622% N T S y s t e m C o n i f i g u r a t i o n %
2623% %
2624% %
2625% %
2626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2627%
2628% NTSystemConfiguration() provides a way for the application to determine
2629% values for system limits or options at runtime.
2630%
2631% The format of the exit method is:
2632%
cristybb503372010-05-27 20:51:26 +00002633% ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002634%
2635% A description of each parameter follows:
2636%
2637% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
2638%
2639*/
cristy30603ff2011-10-07 00:43:07 +00002640MagickPrivate ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002641{
2642 switch (name)
2643 {
2644 case _SC_PAGESIZE:
2645 {
2646 SYSTEM_INFO
2647 system_info;
2648
2649 GetSystemInfo(&system_info);
2650 return(system_info.dwPageSize);
2651 }
2652 case _SC_PHYS_PAGES:
2653 {
2654 HMODULE
2655 handle;
2656
2657 LPFNDLLFUNC2
2658 module;
2659
2660 NTMEMORYSTATUSEX
2661 status;
2662
2663 SYSTEM_INFO
2664 system_info;
2665
2666 handle=GetModuleHandle("kernel32.dll");
2667 if (handle == (HMODULE) NULL)
2668 return(0L);
2669 GetSystemInfo(&system_info);
2670 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
2671 if (module == (LPFNDLLFUNC2) NULL)
2672 {
2673 MEMORYSTATUS
2674 status;
2675
2676 GlobalMemoryStatus(&status);
cristybb503372010-05-27 20:51:26 +00002677 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002678 }
2679 status.dwLength=sizeof(status);
2680 if (module(&status) == 0)
2681 return(0L);
cristybb503372010-05-27 20:51:26 +00002682 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002683 }
2684 case _SC_OPEN_MAX:
2685 return(2048);
2686 default:
2687 break;
2688 }
2689 return(-1);
2690}
2691
2692/*
2693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2694% %
2695% %
2696% %
2697% N T T e l l D i r e c t o r y %
2698% %
2699% %
2700% %
2701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2702%
2703% NTTellDirectory() returns the current location associated with the named
2704% directory stream.
2705%
2706% The format of the NTTellDirectory method is:
2707%
cristybb503372010-05-27 20:51:26 +00002708% ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002709%
2710% A description of each parameter follows:
2711%
2712% o entry: Specifies a pointer to a DIR structure.
2713%
2714*/
cristy30603ff2011-10-07 00:43:07 +00002715MagickPrivate ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002716{
2717 assert(entry != (DIR *) NULL);
2718 return(0);
2719}
2720
2721/*
2722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2723% %
2724% %
2725% %
2726% N T T r u n c a t e F i l e %
2727% %
2728% %
2729% %
2730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2731%
2732% NTTruncateFile() truncates a file to a specified length.
2733%
2734% The format of the NTTruncateFile method is:
2735%
2736% int NTTruncateFile(int file,off_t length)
2737%
2738% A description of each parameter follows:
2739%
2740% o file: the file.
2741%
2742% o length: the file length.
2743%
2744*/
cristy30603ff2011-10-07 00:43:07 +00002745MagickPrivate int NTTruncateFile(int file,off_t length)
cristy3ed852e2009-09-05 21:47:34 +00002746{
2747 DWORD
2748 file_pointer;
2749
cristyfeb262e2010-06-04 22:57:35 +00002750 long
cristy3ed852e2009-09-05 21:47:34 +00002751 file_handle,
2752 high,
2753 low;
2754
2755 file_handle=_get_osfhandle(file);
2756 if (file_handle == -1L)
2757 return(-1);
cristyfeb262e2010-06-04 22:57:35 +00002758 low=(long) (length & 0xffffffffUL);
2759 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
cristy3ed852e2009-09-05 21:47:34 +00002760 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2761 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2762 return(-1);
2763 if (SetEndOfFile((HANDLE) file_handle) == 0)
2764 return(-1);
2765 return(0);
2766}
2767
2768/*
2769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2770% %
2771% %
2772% %
2773+ N T U n m a p M e m o r y %
2774% %
2775% %
2776% %
2777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2778%
2779% NTUnmapMemory() emulates the Unix munmap method.
2780%
2781% The format of the NTUnmapMemory method is:
2782%
2783% int NTUnmapMemory(void *map,size_t length)
2784%
2785% A description of each parameter follows:
2786%
2787% o map: the address of the binary large object.
2788%
2789% o length: the length of the binary large object.
2790%
2791*/
cristy30603ff2011-10-07 00:43:07 +00002792MagickPrivate int NTUnmapMemory(void *map,size_t length)
cristy3ed852e2009-09-05 21:47:34 +00002793{
cristy3b743bb2009-09-14 16:07:59 +00002794 (void) length;
cristy3ed852e2009-09-05 21:47:34 +00002795 if (UnmapViewOfFile(map) == 0)
2796 return(-1);
2797 return(0);
2798}
2799
2800/*
2801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2802% %
2803% %
2804% %
2805% N T U s e r T i m e %
2806% %
2807% %
2808% %
2809%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2810%
2811% NTUserTime() returns the total time the process has been scheduled (e.g.
2812% seconds) since the last call to StartTimer().
2813%
2814% The format of the UserTime method is:
2815%
2816% double NTUserTime(void)
2817%
2818*/
cristy30603ff2011-10-07 00:43:07 +00002819MagickPrivate double NTUserTime(void)
cristy3ed852e2009-09-05 21:47:34 +00002820{
2821 DWORD
2822 status;
2823
2824 FILETIME
2825 create_time,
2826 exit_time;
2827
2828 OSVERSIONINFO
2829 OsVersionInfo;
2830
2831 union
2832 {
2833 FILETIME
2834 filetime;
2835
2836 __int64
2837 filetime64;
2838 } kernel_time;
2839
2840 union
2841 {
2842 FILETIME
2843 filetime;
2844
2845 __int64
2846 filetime64;
2847 } user_time;
2848
2849 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2850 GetVersionEx(&OsVersionInfo);
2851 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2852 return(NTElapsedTime());
2853 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2854 &kernel_time.filetime,&user_time.filetime);
2855 if (status != TRUE)
2856 return(0.0);
2857 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2858}
2859
2860/*
2861%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2862% %
2863% %
2864% %
2865% N T W a r n i n g H a n d l e r %
2866% %
2867% %
2868% %
2869%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2870%
2871% NTWarningHandler() displays a warning reason.
2872%
2873% The format of the NTWarningHandler method is:
2874%
cristy3b743bb2009-09-14 16:07:59 +00002875% void NTWarningHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +00002876% const char *description)
2877%
2878% A description of each parameter follows:
2879%
cristy3b743bb2009-09-14 16:07:59 +00002880% o severity: Specifies the numeric warning category.
cristy3ed852e2009-09-05 21:47:34 +00002881%
2882% o reason: Specifies the reason to display before terminating the
2883% program.
2884%
2885% o description: Specifies any description to the reason.
2886%
2887*/
cristy30603ff2011-10-07 00:43:07 +00002888MagickPrivate void NTWarningHandler(const ExceptionType severity,
cristy3ed852e2009-09-05 21:47:34 +00002889 const char *reason,const char *description)
2890{
2891 char
2892 buffer[2*MaxTextExtent];
2893
cristy3b743bb2009-09-14 16:07:59 +00002894 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +00002895 if (reason == (char *) NULL)
2896 return;
2897 if (description == (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00002898 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
cristy3ed852e2009-09-05 21:47:34 +00002899 reason);
2900 else
cristyb51dff52011-05-19 16:55:47 +00002901 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +00002902 GetClientName(),reason,description);
2903 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2904 MB_SETFOREGROUND | MB_ICONINFORMATION);
2905}
2906#endif