blob: 18a3e83ad41ee181e52e1d5e72cdc0b794fc756b [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% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 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*/
cristy309042f2012-02-20 18:59:35 +000041#include "MagickCore/studio.h"
cristy0157aea2010-04-24 21:12:18 +000042#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy309042f2012-02-20 18:59:35 +000043#include "MagickCore/client.h"
44#include "MagickCore/exception-private.h"
45#include "MagickCore/locale_.h"
46#include "MagickCore/log.h"
47#include "MagickCore/magick.h"
48#include "MagickCore/memory_.h"
49#include "MagickCore/resource_.h"
cristy6e2469f2012-02-21 13:57:36 +000050#include "MagickCore/resource-private.h"
cristy309042f2012-02-20 18:59:35 +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
cristy2c5fc272012-02-22 01:27:46 +000058#include "MagickCore/nt-base-private.h"
cristy3ed852e2009-09-05 21:47:34 +000059#if defined(MAGICKCORE_CIPHER_SUPPORT)
60#include <ntsecapi.h>
61#include <wincrypt.h>
62#endif
63
64/*
65 Define declarations.
66*/
67#if !defined(MAP_FAILED)
68#define MAP_FAILED ((void *) -1)
69#endif
70
71/*
72 Static declarations.
73*/
74#if !defined(MAGICKCORE_LTDL_DELEGATE)
75static char
76 *lt_slsearchpath = (char *) NULL;
77#endif
78
cristydefb3f02009-09-10 02:18:35 +000079static GhostInfo
80 ghost_info;
cristy3ed852e2009-09-05 21:47:34 +000081
82static void
cristydefb3f02009-09-10 02:18:35 +000083 *ghost_handle = (void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +000084
85/*
86 External declarations.
87*/
cristy0157aea2010-04-24 21:12:18 +000088#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000089extern "C" BOOL WINAPI
90 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
91#endif
92
93/*
94%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95% %
96% %
97% %
98% D l l M a i n %
99% %
100% %
101% %
102%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
103%
104% DllMain() is an entry point to the DLL which is called when processes and
105% threads are initialized and terminated, or upon calls to the Windows
106% LoadLibrary and FreeLibrary functions.
107%
108% The function returns TRUE of it succeeds, or FALSE if initialization fails.
109%
110% The format of the DllMain method is:
111%
112% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
113%
114% A description of each parameter follows:
115%
116% o handle: handle to the DLL module
117%
118% o reason: reason for calling function:
119%
120% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
121% space of current process.
122% DLL_THREAD_ATTACH - Indicates that the current process is
123% creating a new thread. Called under the
124% context of the new thread.
125% DLL_THREAD_DETACH - Indicates that the thread is exiting.
126% Called under the context of the exiting
127% thread.
128% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
129% from the virtual address space of the
130% current process.
131%
132% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
133% and DLL_PROCESS_DETACH.
134%
135*/
136#if defined(_DLL) && defined( ProvideDllMain )
137BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
138{
139 switch (reason)
140 {
141 case DLL_PROCESS_ATTACH:
142 {
143 char
144 *module_path;
145
146 ssize_t
147 count;
148
149 module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
150 sizeof(*module_path));
151 if (module_path == (char *) NULL)
152 return(FALSE);
153 count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
154 if (count != 0)
155 {
156 char
157 *path;
158
159 for ( ; count > 0; count--)
160 if (module_path[count] == '\\')
161 {
162 module_path[count+1]='\0';
163 break;
164 }
165 MagickCoreGenesis(module_path,MagickFalse);
166 path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
167 if (path == (char *) NULL)
168 {
169 module_path=DestroyString(module_path);
170 return(FALSE);
171 }
172 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
173 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
174 {
175 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
176 {
177 char
178 *variable;
179
180 variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
181 sizeof(*variable));
182 if (variable == (char *) NULL)
183 {
184 path=DestroyString(path);
185 module_path=DestroyString(module_path);
186 return(FALSE);
187 }
cristyb51dff52011-05-19 16:55:47 +0000188 (void) FormatLocaleString(variable,16*MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000189 "%s;%s",module_path,path);
190 SetEnvironmentVariable("PATH",variable);
191 variable=DestroyString(variable);
192 }
193 }
194 path=DestroyString(path);
195 }
196 module_path=DestroyString(module_path);
197 break;
198 }
199 case DLL_PROCESS_DETACH:
200 {
201 MagickCoreTerminus();
202 break;
203 }
204 default:
205 break;
206 }
207 return(TRUE);
208}
209#endif
210
211/*
212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213% %
214% %
215% %
216% E x i t %
217% %
218% %
219% %
220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221%
222% Exit() calls TerminateProcess for Win95.
223%
224% The format of the exit method is:
225%
226% int Exit(int status)
227%
228% A description of each parameter follows:
229%
230% o status: an integer value representing the status of the terminating
231% process.
232%
233*/
cristyf7836bf2012-02-20 16:32:47 +0000234MagickExport int Exit(int status)
cristy3ed852e2009-09-05 21:47:34 +0000235{
236 if (IsWindows95())
237 TerminateProcess(GetCurrentProcess(),(unsigned int) status);
238 exit(status);
239 return(0);
240}
241
cristy0157aea2010-04-24 21:12:18 +0000242#if !defined(__MINGW32__)
cristy3ed852e2009-09-05 21:47:34 +0000243/*
244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245% %
246% %
247% %
cristy6d71f8d2010-02-28 00:46:02 +0000248% g e t t i m e o f d a y %
249% %
250% %
251% %
252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
253%
254% The gettimeofday() method get the time of day.
255%
256% The format of the gettimeofday method is:
257%
258% int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
259%
260% A description of each parameter follows:
261%
262% o time_value: the time value.
263%
264% o time_zone: the time zone.
265%
266*/
cristyf7836bf2012-02-20 16:32:47 +0000267MagickExport int gettimeofday (struct timeval *time_value,
cristy6d71f8d2010-02-28 00:46:02 +0000268 struct timezone *time_zone)
269{
cristyc05bf172010-06-04 19:53:53 +0000270#define EpochFiletime MagickLLConstant(116444736000000000)
cristy6d71f8d2010-02-28 00:46:02 +0000271
272 static int
273 is_tz_set;
274
275 if (time_value != (struct timeval *) NULL)
276 {
277 FILETIME
278 file_time;
279
280 __int64
281 time;
282
283 LARGE_INTEGER
284 date_time;
285
286 GetSystemTimeAsFileTime(&file_time);
287 date_time.LowPart=file_time.dwLowDateTime;
288 date_time.HighPart=file_time.dwHighDateTime;
289 time=date_time.QuadPart;
cristy99881662010-03-04 14:25:26 +0000290 time-=EpochFiletime;
cristy6d71f8d2010-02-28 00:46:02 +0000291 time/=10;
cristybb503372010-05-27 20:51:26 +0000292 time_value->tv_sec=(ssize_t) (time / 1000000);
293 time_value->tv_usec=(ssize_t) (time % 1000000);
cristy6d71f8d2010-02-28 00:46:02 +0000294 }
295 if (time_zone != (struct timezone *) NULL)
296 {
297 if (is_tz_set == 0)
298 {
299 _tzset();
300 is_tz_set++;
301 }
302 time_zone->tz_minuteswest=_timezone/60;
303 time_zone->tz_dsttime=_daylight;
304 }
305 return(0);
306}
cristy807fd932010-04-24 03:38:46 +0000307#endif
cristy6d71f8d2010-02-28 00:46:02 +0000308
309/*
310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311% %
312% %
313% %
cristy3ed852e2009-09-05 21:47:34 +0000314% I s W i n d o w s 9 5 %
315% %
316% %
317% %
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319%
320% IsWindows95() returns true if the system is Windows 95.
321%
322% The format of the IsWindows95 method is:
323%
324% int IsWindows95()
325%
326*/
cristyf7836bf2012-02-20 16:32:47 +0000327MagickExport int IsWindows95()
cristy3ed852e2009-09-05 21:47:34 +0000328{
329 OSVERSIONINFO
330 version_info;
331
332 version_info.dwOSVersionInfoSize=sizeof(version_info);
333 if (GetVersionEx(&version_info) &&
334 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
335 return(1);
336 return(0);
337}
338
339/*
340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341% %
342% %
343% %
cristy66f9c3c2011-08-13 17:12:28 +0000344% N T A r g v T o U T F 8 %
345% %
346% %
347% %
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349%
350% NTArgvToUTF8() converts the wide command line arguments to UTF-8 to ensure
351% compatibility with Linux.
352%
353% The format of the NTArgvToUTF8 method is:
354%
355% char **NTArgvToUTF8(const int argc,wchar_t **argv)
356%
357% A description of each parameter follows:
358%
359% o argc: the number of command line arguments.
360%
361% o argv: the wide-character command line arguments.
362%
363*/
cristydaeba5e2011-10-13 17:32:44 +0000364MagickExport char **NTArgvToUTF8(const int argc,wchar_t **argv)
cristy66f9c3c2011-08-13 17:12:28 +0000365{
366 char
367 **utf8;
368
369 ssize_t
370 i;
371
372 utf8=(char **) AcquireQuantumMemory(argc,sizeof(*utf8));
373 if (utf8 == (char **) NULL)
374 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
375 for (i=0; i < (ssize_t) argc; i++)
376 {
377 ssize_t
378 count;
379
380 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,NULL,0,NULL,NULL);
381 if (count < 0)
382 count=0;
383 utf8[i]=(char *) AcquireQuantumMemory(count+1,sizeof(**utf8));
384 if (utf8[i] == (char *) NULL)
385 {
386 for (i--; i >= 0; i--)
387 utf8[i]=DestroyString(utf8[i]);
388 utf8=(char **) RelinquishMagickMemory(utf8);
389 ThrowFatalException(ResourceLimitFatalError,
390 "UnableToConvertStringToARGV");
391 }
392 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,utf8[i],count,NULL,NULL);
393 utf8[i][count]=0;
394 }
395 return(utf8);
396}
397
398/*
399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400% %
401% %
402% %
cristy3ed852e2009-09-05 21:47:34 +0000403% N T C l o s e D i r e c t o r y %
404% %
405% %
406% %
407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408%
409% NTCloseDirectory() closes the named directory stream and frees the DIR
410% structure.
411%
412% The format of the NTCloseDirectory method is:
413%
414% int NTCloseDirectory(DIR *entry)
415%
416% A description of each parameter follows:
417%
418% o entry: Specifies a pointer to a DIR structure.
419%
420*/
cristyf7836bf2012-02-20 16:32:47 +0000421MagickExport int NTCloseDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +0000422{
423 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
424 assert(entry != (DIR *) NULL);
425 FindClose(entry->hSearch);
426 entry=(DIR *) RelinquishMagickMemory(entry);
427 return(0);
428}
429
430/*
431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432% %
433% %
434% %
435% N T C l o s e L i b r a r y %
436% %
437% %
438% %
439%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440%
441% NTCloseLibrary() unloads the module associated with the passed handle.
442%
443% The format of the NTCloseLibrary method is:
444%
445% void NTCloseLibrary(void *handle)
446%
447% A description of each parameter follows:
448%
449% o handle: Specifies a handle to a previously loaded dynamic module.
450%
451*/
cristyf7836bf2012-02-20 16:32:47 +0000452MagickExport int NTCloseLibrary(void *handle)
cristy3ed852e2009-09-05 21:47:34 +0000453{
454 if (IsWindows95())
455 return(FreeLibrary((HINSTANCE) handle));
456 return(!(FreeLibrary((HINSTANCE) handle)));
457}
458
459/*
460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461% %
462% %
463% %
464% N T C o n t r o l H a n d l e r %
465% %
466% %
467% %
468%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469%
470% NTControlHandler() registers a control handler that is activated when, for
471% example, a ctrl-c is received.
472%
473% The format of the NTControlHandler method is:
474%
475% int NTControlHandler(void)
476%
477*/
478
479static BOOL ControlHandler(DWORD type)
480{
cristy3b743bb2009-09-14 16:07:59 +0000481 (void) type;
cristyf34a1452009-10-24 22:29:27 +0000482 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +0000483 return(FALSE);
484}
485
cristyf7836bf2012-02-20 16:32:47 +0000486MagickExport int NTControlHandler(void)
cristy3ed852e2009-09-05 21:47:34 +0000487{
488 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
489}
490
491/*
492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493% %
494% %
495% %
496% N T E l a p s e d T i m e %
497% %
498% %
499% %
500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501%
502% NTElapsedTime() returns the elapsed time (in seconds) since the last call to
503% StartTimer().
504%
505% The format of the ElapsedTime method is:
506%
507% double NTElapsedTime(void)
508%
509*/
cristyf7836bf2012-02-20 16:32:47 +0000510MagickExport double NTElapsedTime(void)
cristy3ed852e2009-09-05 21:47:34 +0000511{
512 union
513 {
514 FILETIME
515 filetime;
516
517 __int64
518 filetime64;
519 } elapsed_time;
520
521 SYSTEMTIME
522 system_time;
523
524 GetSystemTime(&system_time);
525 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
526 return((double) 1.0e-7*elapsed_time.filetime64);
527}
528
529/*
530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531% %
532% %
533% %
534+ N T E r r o r H a n d l e r %
535% %
536% %
537% %
538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539%
540% NTErrorHandler() displays an error reason and then terminates the program.
541%
542% The format of the NTErrorHandler method is:
543%
cristy3b743bb2009-09-14 16:07:59 +0000544% void NTErrorHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +0000545% const char *description)
546%
547% A description of each parameter follows:
548%
cristy3b743bb2009-09-14 16:07:59 +0000549% o severity: Specifies the numeric error category.
cristy3ed852e2009-09-05 21:47:34 +0000550%
551% o reason: Specifies the reason to display before terminating the
552% program.
553%
554% o description: Specifies any description to the reason.
555%
556*/
cristy417d8452011-10-13 17:09:49 +0000557MagickExport void NTErrorHandler(const ExceptionType severity,
cristy3b743bb2009-09-14 16:07:59 +0000558 const char *reason,const char *description)
cristy3ed852e2009-09-05 21:47:34 +0000559{
560 char
561 buffer[3*MaxTextExtent],
562 *message;
563
cristy3b743bb2009-09-14 16:07:59 +0000564 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +0000565 if (reason == (char *) NULL)
566 {
567 MagickCoreTerminus();
568 exit(0);
569 }
570 message=GetExceptionMessage(errno);
571 if ((description != (char *) NULL) && errno)
cristyb51dff52011-05-19 16:55:47 +0000572 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000573 GetClientName(),reason,description,message);
574 else
575 if (description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000576 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +0000577 GetClientName(),reason,description);
578 else
579 if (errno != 0)
cristyb51dff52011-05-19 16:55:47 +0000580 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000581 GetClientName(),reason,message);
582 else
cristyb51dff52011-05-19 16:55:47 +0000583 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",
cristy3ed852e2009-09-05 21:47:34 +0000584 GetClientName(),reason);
585 message=DestroyString(message);
586 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
587 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
588 MagickCoreTerminus();
589 exit(0);
590}
591
592/*
593%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
594% %
595% %
596% %
597% N T E x i t L i b r a r y %
598% %
599% %
600% %
601%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602%
603% NTExitLibrary() exits the dynamic module loading subsystem.
604%
605% The format of the NTExitLibrary method is:
606%
607% int NTExitLibrary(void)
608%
609*/
cristyf7836bf2012-02-20 16:32:47 +0000610MagickExport int NTExitLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +0000611{
612 return(0);
613}
614
615/*
616%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617% %
618% %
619% %
620% N T G a t h e r R a n d o m D a t a %
621% %
622% %
623% %
624%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
625%
626% NTGatherRandomData() gathers random data and returns it.
627%
628% The format of the GatherRandomData method is:
629%
630% MagickBooleanType NTGatherRandomData(const size_t length,
631% unsigned char *random)
632%
633% A description of each parameter follows:
634%
635% length: the length of random data buffer
636%
637% random: the random data is returned here.
638%
639*/
cristyf7836bf2012-02-20 16:32:47 +0000640MagickExport MagickBooleanType NTGatherRandomData(const size_t length,
cristy3ed852e2009-09-05 21:47:34 +0000641 unsigned char *random)
642{
643#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
644 HCRYPTPROV
645 handle;
646
647 int
648 status;
649
650 handle=(HCRYPTPROV) NULL;
651 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
652 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
653 if (status == 0)
654 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
655 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
656 if (status == 0)
657 return(MagickFalse);
658 status=CryptGenRandom(handle,(DWORD) length,random);
659 if (status == 0)
660 {
661 status=CryptReleaseContext(handle,0);
662 return(MagickFalse);
663 }
664 status=CryptReleaseContext(handle,0);
665 if (status == 0)
666 return(MagickFalse);
cristy3b743bb2009-09-14 16:07:59 +0000667#else
668 (void) random;
669 (void) length;
cristy3ed852e2009-09-05 21:47:34 +0000670#endif
671 return(MagickTrue);
672}
673
674/*
675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
676% %
677% %
678% %
679% N T G e t E x e c u t i o n P a t h %
680% %
681% %
682% %
683%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
684%
685% NTGetExecutionPath() returns the execution path of a program.
686%
687% The format of the GetExecutionPath method is:
688%
689% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
690%
691% A description of each parameter follows:
692%
693% o path: the pathname of the executable that started the process.
694%
695% o extent: the maximum extent of the path.
696%
697*/
cristyf7836bf2012-02-20 16:32:47 +0000698MagickExport MagickBooleanType NTGetExecutionPath(char *path,
cristy3ed852e2009-09-05 21:47:34 +0000699 const size_t extent)
700{
701 GetModuleFileName(0,path,(DWORD) extent);
702 return(MagickTrue);
703}
704
705/*
706%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707% %
708% %
709% %
710% N T G e t L a s t E r r o r %
711% %
712% %
713% %
714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715%
716% NTGetLastError() returns the last error that occurred.
717%
718% The format of the NTGetLastError method is:
719%
720% char *NTGetLastError(void)
721%
722*/
cristyf7836bf2012-02-20 16:32:47 +0000723char *NTGetLastError(void)
cristy3ed852e2009-09-05 21:47:34 +0000724{
725 char
726 *reason;
727
728 int
729 status;
730
731 LPVOID
732 buffer;
733
734 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
735 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
736 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
737 if (!status)
738 reason=AcquireString("An unknown error occurred");
739 else
740 {
741 reason=AcquireString((const char *) buffer);
742 LocalFree(buffer);
743 }
744 return(reason);
745}
746
747/*
748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749% %
750% %
751% %
752% N T G e t L i b r a r y E r r o r %
753% %
754% %
755% %
756%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757%
758% Lt_dlerror() returns a pointer to a string describing the last error
759% associated with a lt_dl method. Note that this function is not thread
760% safe so it should only be used under the protection of a lock.
761%
762% The format of the NTGetLibraryError method is:
763%
764% const char *NTGetLibraryError(void)
765%
766*/
cristyf7836bf2012-02-20 16:32:47 +0000767MagickExport const char *NTGetLibraryError(void)
cristy3ed852e2009-09-05 21:47:34 +0000768{
769 static char
770 last_error[MaxTextExtent];
771
772 char
773 *error;
774
775 *last_error='\0';
776 error=NTGetLastError();
777 if (error)
778 (void) CopyMagickString(last_error,error,MaxTextExtent);
779 error=DestroyString(error);
780 return(last_error);
781}
782
783/*
784%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
785% %
786% %
787% %
788% N T G e t L i b r a r y S y m b o l %
789% %
790% %
791% %
792%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793%
794% NTGetLibrarySymbol() retrieve the procedure address of the method
795% specified by the passed character string.
796%
797% The format of the NTGetLibrarySymbol method is:
798%
799% void *NTGetLibrarySymbol(void *handle,const char *name)
800%
801% A description of each parameter follows:
802%
803% o handle: Specifies a handle to the previously loaded dynamic module.
804%
805% o name: Specifies the procedure entry point to be returned.
806%
807*/
808void *NTGetLibrarySymbol(void *handle,const char *name)
809{
810 LPFNDLLFUNC1
811 lpfnDllFunc1;
812
813 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
814 if (!lpfnDllFunc1)
815 return((void *) NULL);
816 return((void *) lpfnDllFunc1);
817}
818
819/*
820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821% %
822% %
823% %
824% N T G e t M o d u l e P a t h %
825% %
826% %
827% %
828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829%
830% NTGetModulePath() returns the path of the specified module.
831%
832% The format of the GetModulePath method is:
833%
834% MagickBooleanType NTGetModulePath(const char *module,char *path)
835%
836% A description of each parameter follows:
837%
838% modith: the module name.
839%
840% path: the module path is returned here.
841%
842*/
cristyf7836bf2012-02-20 16:32:47 +0000843MagickExport MagickBooleanType NTGetModulePath(const char *module,char *path)
cristy3ed852e2009-09-05 21:47:34 +0000844{
845 char
846 module_path[MaxTextExtent];
847
848 HMODULE
849 handle;
850
cristybb503372010-05-27 20:51:26 +0000851 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000852 length;
853
854 *path='\0';
855 handle=GetModuleHandle(module);
856 if (handle == (HMODULE) NULL)
857 return(MagickFalse);
858 length=GetModuleFileName(handle,module_path,MaxTextExtent);
859 if (length != 0)
860 GetPathComponent(module_path,HeadPath,path);
861 return(MagickTrue);
862}
863
864/*
865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866% %
867% %
868% %
869% N T G h o s t s c r i p t D L L %
870% %
871% %
872% %
873%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874%
cristydefb3f02009-09-10 02:18:35 +0000875% NTGhostscriptDLL() returns the path to the most recent Ghostscript version
876% DLL. The method returns TRUE on success otherwise FALSE.
cristy3ed852e2009-09-05 21:47:34 +0000877%
878% The format of the NTGhostscriptDLL method is:
879%
cristyfc0f64b2009-09-09 18:57:08 +0000880% int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +0000881%
882% A description of each parameter follows:
883%
cristyfc0f64b2009-09-09 18:57:08 +0000884% o path: return the Ghostscript DLL path here.
cristy3ed852e2009-09-05 21:47:34 +0000885%
cristyfc0f64b2009-09-09 18:57:08 +0000886% o length: the buffer length.
cristy3ed852e2009-09-05 21:47:34 +0000887%
888*/
889
cristy945364f2012-03-14 11:13:17 +0000890static int NTGetRegistryValue(HKEY root,const char *key,DWORD flags,const char *name,
cristyfc0f64b2009-09-09 18:57:08 +0000891 char *value,int *length)
cristy3ed852e2009-09-05 21:47:34 +0000892{
cristyfc0f64b2009-09-09 18:57:08 +0000893 BYTE
894 byte,
cristy3ed852e2009-09-05 21:47:34 +0000895 *p;
896
cristyfc0f64b2009-09-09 18:57:08 +0000897 DWORD
898 extent,
899 type;
cristy3ed852e2009-09-05 21:47:34 +0000900
cristy3ed852e2009-09-05 21:47:34 +0000901 HKEY
902 hkey;
903
cristy3ed852e2009-09-05 21:47:34 +0000904 LONG
cristyfc0f64b2009-09-09 18:57:08 +0000905 status;
cristy3ed852e2009-09-05 21:47:34 +0000906
cristyfc0f64b2009-09-09 18:57:08 +0000907 /*
cristydefb3f02009-09-10 02:18:35 +0000908 Get a registry value: key = root\\key, named value = name.
909 */
cristy945364f2012-03-14 11:13:17 +0000910 if (RegOpenKeyExA(root,key,0,KEY_READ | flags,&hkey) != ERROR_SUCCESS)
cristyfc0f64b2009-09-09 18:57:08 +0000911 return(1); /* no match */
912 p=(BYTE *) value;
913 type=REG_SZ;
914 extent=(*length);
915 if (p == (BYTE *) NULL)
cristydefb3f02009-09-10 02:18:35 +0000916 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
cristyfc0f64b2009-09-09 18:57:08 +0000917 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
918 RegCloseKey(hkey);
919 if (status == ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +0000920 {
cristyfc0f64b2009-09-09 18:57:08 +0000921 *length=extent;
922 return(0); /* return the match */
923 }
924 if (status == ERROR_MORE_DATA)
925 {
926 *length=extent;
cristydefb3f02009-09-10 02:18:35 +0000927 return(-1); /* buffer not large enough */
cristy3ed852e2009-09-05 21:47:34 +0000928 }
929 return(1); /* not found */
930}
931
cristy945364f2012-03-14 11:13:17 +0000932static int NTLocateGhostscript(DWORD flags,const char **product_family,int *major_version,
cristyfc0f64b2009-09-09 18:57:08 +0000933 int *minor_version)
cristy3ed852e2009-09-05 21:47:34 +0000934{
cristyfc0f64b2009-09-09 18:57:08 +0000935 int
936 i;
cristy3ed852e2009-09-05 21:47:34 +0000937
cristyfc0f64b2009-09-09 18:57:08 +0000938 MagickBooleanType
939 status;
940
941 static const char
942 *products[4] =
943 {
944 "GPL Ghostscript",
945 "GNU Ghostscript",
946 "AFPL Ghostscript",
cristy82b15832009-10-06 19:17:37 +0000947 "Aladdin Ghostscript"
cristyfc0f64b2009-09-09 18:57:08 +0000948 };
949
950 /*
951 Find the most recent version of Ghostscript.
952 */
953 status=FALSE;
954 *product_family=NULL;
955 *major_version=5;
956 *minor_version=49; /* min version of Ghostscript is 5.50 */
cristybb503372010-05-27 20:51:26 +0000957 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +0000958 {
959 char
960 key[MaxTextExtent];
961
962 HKEY
963 hkey,
964 root;
965
cristye66bcb42009-09-17 13:31:08 +0000966 REGSAM
967 mode;
968
cristyb51dff52011-05-19 16:55:47 +0000969 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
cristyfc0f64b2009-09-09 18:57:08 +0000970 root=HKEY_LOCAL_MACHINE;
cristy945364f2012-03-14 11:13:17 +0000971 mode=KEY_READ | flags;
cristye66bcb42009-09-17 13:31:08 +0000972 if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
cristyfc0f64b2009-09-09 18:57:08 +0000973 {
974 DWORD
975 extent;
976
977 int
978 j;
979
980 /*
981 Now enumerate the keys.
982 */
983 extent=sizeof(key)/sizeof(char);
984 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
985 {
986 int
987 major,
988 minor;
989
990 major=0;
991 minor=0;
992 if (sscanf(key,"%d.%d",&major,&minor) != 2)
993 continue;
994 if ((major > *major_version) || ((major == *major_version) &&
995 (minor > *minor_version)))
996 {
997 *product_family=products[i];
998 *major_version=major;
999 *minor_version=minor;
cristy37f63772009-11-16 17:06:36 +00001000 status=TRUE;
cristyfc0f64b2009-09-09 18:57:08 +00001001 }
cristyfc0f64b2009-09-09 18:57:08 +00001002 }
cristye66bcb42009-09-17 13:31:08 +00001003 (void) RegCloseKey(hkey);
1004 }
1005 }
cristy37f63772009-11-16 17:06:36 +00001006 if (status == FALSE)
cristyfc0f64b2009-09-09 18:57:08 +00001007 {
1008 *major_version=0;
1009 *minor_version=0;
1010 }
1011 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
1012 "version %d.%02d",*product_family,*major_version,*minor_version);
1013 return(status);
1014}
1015
cristy945364f2012-03-14 11:13:17 +00001016static BOOL NTIs64BitPlatform()
1017{
1018#if defined(_WIN64)
1019 return(TRUE);
1020#else
1021 BOOL is64=FALSE;
1022 return(IsWow64Process(GetCurrentProcess(), &is64) && is64);
1023#endif
1024}
1025
1026static int NTGhostscriptGetString(const char *name,BOOL *is_64_bit,char *value,
cristyfc0f64b2009-09-09 18:57:08 +00001027 const size_t length)
1028{
cristy3ed852e2009-09-05 21:47:34 +00001029 char
cristy3ed852e2009-09-05 21:47:34 +00001030 key[MaxTextExtent];
1031
1032 int
cristyfc0f64b2009-09-09 18:57:08 +00001033 i,
1034 extent;
cristy82b15832009-10-06 19:17:37 +00001035
cristyfc0f64b2009-09-09 18:57:08 +00001036 static const char
cristydefb3f02009-09-10 02:18:35 +00001037 *product_family = (const char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001038
cristy945364f2012-03-14 11:13:17 +00001039 static BOOL
1040 is_64_bit_version = FALSE;
1041
cristyfc0f64b2009-09-09 18:57:08 +00001042 static int
cristy945364f2012-03-14 11:13:17 +00001043 flags=0,
cristyfc0f64b2009-09-09 18:57:08 +00001044 major_version=0,
1045 minor_version=0;
cristy3ed852e2009-09-05 21:47:34 +00001046
cristyfc0f64b2009-09-09 18:57:08 +00001047 struct
1048 {
1049 const HKEY
1050 hkey;
cristy3ed852e2009-09-05 21:47:34 +00001051
cristyfc0f64b2009-09-09 18:57:08 +00001052 const char
1053 *name;
1054 }
1055 hkeys[2] =
1056 {
1057 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
1058 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
1059 };
1060
1061 /*
1062 Get a string from the installed Ghostscript.
1063 */
cristy945364f2012-03-14 11:13:17 +00001064 if (is_64_bit!=NULL)
1065 *is_64_bit=FALSE;
cristydefb3f02009-09-10 02:18:35 +00001066 *value='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001067 if (product_family == NULL)
cristy945364f2012-03-14 11:13:17 +00001068 {
1069 flags=NTIs64BitPlatform() ? KEY_WOW64_64KEY : 0;
1070 (void) NTLocateGhostscript(flags,&product_family,&major_version,&minor_version);
1071 if (product_family == NULL)
1072 {
1073 if (flags!=0)
1074 {
1075 /* We are running on a 64 bit platform - check for a 32 bit Ghostscript, too */
1076 flags=KEY_WOW64_32KEY;
1077 (void) NTLocateGhostscript(flags,&product_family,&major_version,&minor_version);
1078 }
1079 }
1080 else
1081 is_64_bit_version=NTIs64BitPlatform();
1082 }
1083 if (is_64_bit!=NULL)
1084 *is_64_bit=is_64_bit_version;
cristyfc0f64b2009-09-09 18:57:08 +00001085 if (product_family == NULL)
1086 return(FALSE);
cristyb51dff52011-05-19 16:55:47 +00001087 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
cristyfc0f64b2009-09-09 18:57:08 +00001088 product_family,major_version,minor_version);
cristybb503372010-05-27 20:51:26 +00001089 for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +00001090 {
cristy76319442009-09-22 02:04:05 +00001091 extent=(int) length;
cristy945364f2012-03-14 11:13:17 +00001092 if (NTGetRegistryValue(hkeys[i].hkey,key,flags,name,value,&extent) == 0)
cristyfc0f64b2009-09-09 18:57:08 +00001093 {
1094 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1095 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
1096 return(TRUE);
1097 }
1098 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1099 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
1100 }
cristy3ed852e2009-09-05 21:47:34 +00001101 return(FALSE);
1102}
1103
cristyf7836bf2012-02-20 16:32:47 +00001104MagickExport int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001105{
cristy4c11ed82009-09-11 03:36:46 +00001106 static char
1107 dll[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001108
cristy945364f2012-03-14 11:13:17 +00001109 static BOOL
1110 is_64_bit_version;
1111
cristy3ed852e2009-09-05 21:47:34 +00001112 *path='\0';
cristy4c11ed82009-09-11 03:36:46 +00001113 if ((*dll == '\0') &&
cristy945364f2012-03-14 11:13:17 +00001114 (NTGhostscriptGetString("GS_DLL",&is_64_bit_version,dll,sizeof(dll)) == FALSE))
cristy106919c2009-09-11 03:46:56 +00001115 return(FALSE);
cristy945364f2012-03-14 11:13:17 +00001116
1117#if defined(_WIN64)
1118 if (!is_64_bit_version)
1119 return(FALSE);
1120#else
1121 if (is_64_bit_version)
1122 return(FALSE);
1123#endif
cristy4c11ed82009-09-11 03:36:46 +00001124 (void) CopyMagickString(path,dll,length);
cristy3ed852e2009-09-05 21:47:34 +00001125 return(TRUE);
1126}
1127
1128/*
1129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130% %
1131% %
1132% %
1133% N T G h o s t s c r i p t D L L V e c t o r s %
1134% %
1135% %
1136% %
1137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1138%
cristydefb3f02009-09-10 02:18:35 +00001139% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
1140% function vectors to invoke Ghostscript DLL functions. A null pointer is
1141% returned if there is an error when loading the DLL or retrieving the
1142% function vectors.
cristy3ed852e2009-09-05 21:47:34 +00001143%
1144% The format of the NTGhostscriptDLLVectors method is:
1145%
cristydefb3f02009-09-10 02:18:35 +00001146% const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001147%
1148*/
cristydaeba5e2011-10-13 17:32:44 +00001149MagickExport const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001150{
cristyfc0f64b2009-09-09 18:57:08 +00001151 if (NTGhostscriptLoadDLL() == FALSE)
cristydefb3f02009-09-10 02:18:35 +00001152 return((GhostInfo *) NULL);
1153 return(&ghost_info);
cristy3ed852e2009-09-05 21:47:34 +00001154}
1155
1156/*
1157%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1158% %
1159% %
1160% %
1161% N T G h o s t s c r i p t E X E %
1162% %
1163% %
1164% %
1165%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166%
1167% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
cristyfc0f64b2009-09-09 18:57:08 +00001168% The method returns FALSE if a full path value is not obtained and returns
1169% a default path of gswin32c.exe.
cristy3ed852e2009-09-05 21:47:34 +00001170%
1171% The format of the NTGhostscriptEXE method is:
1172%
cristyfc0f64b2009-09-09 18:57:08 +00001173% int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001174%
1175% A description of each parameter follows:
1176%
cristyfc0f64b2009-09-09 18:57:08 +00001177% o path: return the Ghostscript executable path here.
cristy3ed852e2009-09-05 21:47:34 +00001178%
cristyb32b90a2009-09-07 21:45:48 +00001179% o length: length of buffer.
cristy3ed852e2009-09-05 21:47:34 +00001180%
1181*/
cristyf7836bf2012-02-20 16:32:47 +00001182MagickExport int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001183{
cristy4c11ed82009-09-11 03:36:46 +00001184 register char
cristy3ed852e2009-09-05 21:47:34 +00001185 *p;
1186
cristyfc0f64b2009-09-09 18:57:08 +00001187 static char
cristy4c11ed82009-09-11 03:36:46 +00001188 program[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001189
cristy945364f2012-03-14 11:13:17 +00001190 static BOOL
1191 is_64_bit_version = FALSE;
1192
cristyb32b90a2009-09-07 21:45:48 +00001193 (void) CopyMagickString(path,"gswin32c.exe",length);
cristy4c11ed82009-09-11 03:36:46 +00001194 if ((*program == '\0') &&
cristy945364f2012-03-14 11:13:17 +00001195 (NTGhostscriptGetString("GS_DLL",&is_64_bit_version,program,sizeof(program)) == FALSE))
cristyb32b90a2009-09-07 21:45:48 +00001196 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001197 p=strrchr(program,'\\');
cristy7ba1b042011-02-05 19:07:50 +00001198 if (p != (char *) NULL)
cristy4c11ed82009-09-11 03:36:46 +00001199 {
1200 p++;
1201 *p='\0';
cristy945364f2012-03-14 11:13:17 +00001202 (void) ConcatenateMagickString(program,is_64_bit_version ? "gswin64c.exe" : "gswin32c.exe",sizeof(program));
cristy4c11ed82009-09-11 03:36:46 +00001203 }
1204 (void) CopyMagickString(path,program,length);
cristyb32b90a2009-09-07 21:45:48 +00001205 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001206}
1207
1208/*
1209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1210% %
1211% %
1212% %
1213% N T G h o s t s c r i p t F o n t s %
1214% %
1215% %
1216% %
1217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1218%
cristyfc0f64b2009-09-09 18:57:08 +00001219% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1220% returns FALSE if it cannot determine the font path.
cristy3ed852e2009-09-05 21:47:34 +00001221%
1222% The format of the NTGhostscriptFonts method is:
1223%
cristyfc0f64b2009-09-09 18:57:08 +00001224% int NTGhostscriptFonts(char *path, int length)
cristy3ed852e2009-09-05 21:47:34 +00001225%
1226% A description of each parameter follows:
1227%
cristyfc0f64b2009-09-09 18:57:08 +00001228% o path: return the font path here.
cristy3ed852e2009-09-05 21:47:34 +00001229%
cristyfc0f64b2009-09-09 18:57:08 +00001230% o length: length of the path buffer.
cristy3ed852e2009-09-05 21:47:34 +00001231%
1232*/
cristyf7836bf2012-02-20 16:32:47 +00001233MagickExport int NTGhostscriptFonts(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001234{
1235 char
1236 buffer[MaxTextExtent],
1237 filename[MaxTextExtent];
1238
cristy3ed852e2009-09-05 21:47:34 +00001239 register char
1240 *p,
1241 *q;
1242
1243 *path='\0';
cristy945364f2012-03-14 11:13:17 +00001244 if (NTGhostscriptGetString("GS_LIB",NULL,buffer,MaxTextExtent) == FALSE)
cristy3ed852e2009-09-05 21:47:34 +00001245 return(FALSE);
1246 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1247 {
1248 (void) CopyMagickString(path,p+1,length+1);
1249 q=strchr(path,DirectoryListSeparator);
1250 if (q != (char *) NULL)
1251 *q='\0';
cristyb51dff52011-05-19 16:55:47 +00001252 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path,
cristy3ed852e2009-09-05 21:47:34 +00001253 DirectorySeparator);
1254 if (IsPathAccessible(filename) != MagickFalse)
1255 return(TRUE);
1256 }
1257 return(FALSE);
1258}
1259
1260/*
1261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262% %
1263% %
1264% %
1265% N T G h o s t s c r i p t L o a d D L L %
1266% %
1267% %
1268% %
1269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1270%
1271% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
cristyfc0f64b2009-09-09 18:57:08 +00001272% TRUE if it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001273%
1274% The format of the NTGhostscriptLoadDLL method is:
1275%
1276% int NTGhostscriptLoadDLL(void)
1277%
1278*/
cristyf7836bf2012-02-20 16:32:47 +00001279MagickExport int NTGhostscriptLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001280{
1281 char
cristyfc0f64b2009-09-09 18:57:08 +00001282 path[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001283
cristydefb3f02009-09-10 02:18:35 +00001284 if (ghost_handle != (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001285 return(TRUE);
1286 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1287 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001288 ghost_handle=lt_dlopen(path);
1289 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001290 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001291 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1292 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1293 lt_dlsym(ghost_handle,"gsapi_exit");
1294 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1295 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1296 ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1297 lt_dlsym(ghost_handle,"gsapi_new_instance"));
1298 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1299 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1300 ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1301 lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1302 if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1303 (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1304 (ghost_info.delete_instance == NULL))
cristyfc0f64b2009-09-09 18:57:08 +00001305 return(FALSE);
1306 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001307}
1308
1309/*
1310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1311% %
1312% %
1313% %
1314% N T G h o s t s c r i p t U n L o a d D L L %
1315% %
1316% %
1317% %
1318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319%
cristyfc0f64b2009-09-09 18:57:08 +00001320% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1321% it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001322%
1323% The format of the NTGhostscriptUnLoadDLL method is:
1324%
1325% int NTGhostscriptUnLoadDLL(void)
1326%
1327*/
cristydaeba5e2011-10-13 17:32:44 +00001328MagickExport int NTGhostscriptUnLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001329{
cristyfc0f64b2009-09-09 18:57:08 +00001330 int
1331 status;
1332
cristydefb3f02009-09-10 02:18:35 +00001333 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001334 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001335 status=lt_dlclose(ghost_handle);
1336 ghost_handle=(void *) NULL;
1337 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
cristyfc0f64b2009-09-09 18:57:08 +00001338 return(status);
cristy3ed852e2009-09-05 21:47:34 +00001339}
1340
1341/*
1342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1343% %
1344% %
1345% %
1346% N T I n i t i a l i z e L i b r a r y %
1347% %
1348% %
1349% %
1350%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351%
1352% NTInitializeLibrary() initializes the dynamic module loading subsystem.
1353%
1354% The format of the NTInitializeLibrary method is:
1355%
1356% int NTInitializeLibrary(void)
1357%
1358*/
cristyf7836bf2012-02-20 16:32:47 +00001359MagickExport int NTInitializeLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +00001360{
1361 return(0);
1362}
1363
1364/*
1365%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1366% %
1367% %
1368% %
1369+ N T M a p M e m o r y %
1370% %
1371% %
1372% %
1373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1374%
1375% Mmap() emulates the Unix method of the same name.
1376%
1377% The format of the NTMapMemory method is:
1378%
cristyf7836bf2012-02-20 16:32:47 +00001379% MagickExport void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001380% int access,int file,MagickOffsetType offset)
1381%
1382*/
cristyf7836bf2012-02-20 16:32:47 +00001383MagickExport void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001384 int flags,int file,MagickOffsetType offset)
1385{
1386 DWORD
1387 access_mode,
1388 high_length,
1389 high_offset,
1390 low_length,
1391 low_offset,
1392 protection_mode;
1393
1394 HANDLE
1395 file_handle,
1396 map_handle;
1397
1398 void
1399 *map;
1400
cristy3b743bb2009-09-14 16:07:59 +00001401 (void) address;
cristy3ed852e2009-09-05 21:47:34 +00001402 access_mode=0;
1403 file_handle=INVALID_HANDLE_VALUE;
1404 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1405 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1406 map_handle=INVALID_HANDLE_VALUE;
1407 map=(void *) NULL;
1408 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1409 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1410 protection_mode=0;
1411 if (protection & PROT_WRITE)
1412 {
1413 access_mode=FILE_MAP_WRITE;
1414 if (!(flags & MAP_PRIVATE))
1415 protection_mode=PAGE_READWRITE;
1416 else
1417 {
1418 access_mode=FILE_MAP_COPY;
1419 protection_mode=PAGE_WRITECOPY;
1420 }
1421 }
1422 else
1423 if (protection & PROT_READ)
1424 {
1425 access_mode=FILE_MAP_READ;
1426 protection_mode=PAGE_READONLY;
1427 }
1428 if ((file == -1) && (flags & MAP_ANONYMOUS))
1429 file_handle=INVALID_HANDLE_VALUE;
1430 else
1431 file_handle=(HANDLE) _get_osfhandle(file);
1432 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1433 low_length,0);
1434 if (map_handle)
1435 {
1436 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1437 length);
1438 CloseHandle(map_handle);
1439 }
1440 if (map == (void *) NULL)
1441 return((void *) MAP_FAILED);
1442 return((void *) ((char *) map));
1443}
1444
1445/*
1446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1447% %
1448% %
1449% %
1450% N T O p e n D i r e c t o r y %
1451% %
1452% %
1453% %
1454%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1455%
1456% NTOpenDirectory() opens the directory named by filename and associates a
1457% directory stream with it.
1458%
1459% The format of the NTOpenDirectory method is:
1460%
1461% DIR *NTOpenDirectory(const char *path)
1462%
1463% A description of each parameter follows:
1464%
1465% o entry: Specifies a pointer to a DIR structure.
1466%
1467*/
cristyf7836bf2012-02-20 16:32:47 +00001468MagickExport DIR *NTOpenDirectory(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00001469{
1470 char
1471 file_specification[MaxTextExtent];
1472
1473 DIR
1474 *entry;
1475
1476 size_t
1477 length;
1478
1479 assert(path != (const char *) NULL);
1480 length=CopyMagickString(file_specification,path,MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001481 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001482 return((DIR *) NULL);
1483 length=ConcatenateMagickString(file_specification,DirectorySeparator,
1484 MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001485 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001486 return((DIR *) NULL);
cristy73bd4a52010-10-05 11:24:23 +00001487 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
cristy3ed852e2009-09-05 21:47:34 +00001488 if (entry != (DIR *) NULL)
1489 {
1490 entry->firsttime=TRUE;
1491 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1492 }
1493 if (entry->hSearch == INVALID_HANDLE_VALUE)
1494 {
1495 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001496 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001497 {
1498 entry=(DIR *) RelinquishMagickMemory(entry);
1499 return((DIR *) NULL);
1500 }
1501 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1502 if (entry->hSearch == INVALID_HANDLE_VALUE)
1503 {
1504 entry=(DIR *) RelinquishMagickMemory(entry);
1505 return((DIR *) NULL);
1506 }
1507 }
1508 return(entry);
1509}
1510
1511/*
1512%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1513% %
1514% %
1515% %
1516% N T O p e n L i b r a r y %
1517% %
1518% %
1519% %
1520%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1521%
1522% NTOpenLibrary() loads a dynamic module into memory and returns a handle that
1523% can be used to access the various procedures in the module.
1524%
1525% The format of the NTOpenLibrary method is:
1526%
1527% void *NTOpenLibrary(const char *filename)
1528%
1529% A description of each parameter follows:
1530%
1531% o path: Specifies a pointer to string representing dynamic module that
1532% is to be loaded.
1533%
1534*/
1535
1536static const char *GetSearchPath( void )
1537{
1538#if defined(MAGICKCORE_LTDL_DELEGATE)
1539 return(lt_dlgetsearchpath());
1540#else
1541 return(lt_slsearchpath);
1542#endif
1543}
1544
cristyf7836bf2012-02-20 16:32:47 +00001545MagickExport void *NTOpenLibrary(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +00001546{
1547#define MaxPathElements 31
1548
1549 char
1550 buffer[MaxTextExtent];
1551
1552 int
1553 index;
1554
1555 register const char
1556 *p,
1557 *q;
1558
1559 register int
1560 i;
1561
1562 UINT
1563 mode;
1564
1565 void
1566 *handle;
1567
1568 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1569 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1570 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL))
1571 {
1572 SetErrorMode(mode);
1573 return(handle);
1574 }
1575 p=(char *) GetSearchPath();
1576 index=0;
1577 while (index < MaxPathElements)
1578 {
1579 q=strchr(p,DirectoryListSeparator);
1580 if (q == (char *) NULL)
1581 {
1582 (void) CopyMagickString(buffer,p,MaxTextExtent);
1583 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1584 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1585 handle=(void *) LoadLibraryEx(buffer,NULL,
1586 LOAD_WITH_ALTERED_SEARCH_PATH);
1587 break;
1588 }
1589 i=q-p;
1590 (void) CopyMagickString(buffer,p,i+1);
1591 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1592 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1593 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1594 if (handle != (void *) NULL)
1595 break;
1596 p=q+1;
1597 }
1598 SetErrorMode(mode);
1599 return(handle);
1600}
1601
1602/*
1603%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1604% %
1605% %
1606% %
1607% N T R e a d D i r e c t o r y %
1608% %
1609% %
1610% %
1611%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1612%
1613% NTReadDirectory() returns a pointer to a structure representing the
1614% directory entry at the current position in the directory stream to which
1615% entry refers.
1616%
1617% The format of the NTReadDirectory
1618%
1619% NTReadDirectory(entry)
1620%
1621% A description of each parameter follows:
1622%
1623% o entry: Specifies a pointer to a DIR structure.
1624%
1625*/
cristyf7836bf2012-02-20 16:32:47 +00001626MagickExport struct dirent *NTReadDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00001627{
1628 int
1629 status;
1630
1631 size_t
1632 length;
1633
1634 if (entry == (DIR *) NULL)
1635 return((struct dirent *) NULL);
1636 if (!entry->firsttime)
1637 {
1638 status=FindNextFile(entry->hSearch,&entry->Win32FindData);
1639 if (status == 0)
1640 return((struct dirent *) NULL);
1641 }
1642 length=CopyMagickString(entry->file_info.d_name,
1643 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name));
1644 if (length >= sizeof(entry->file_info.d_name))
1645 return((struct dirent *) NULL);
1646 entry->firsttime=FALSE;
1647 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1648 return(&entry->file_info);
1649}
1650
1651/*
1652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1653% %
1654% %
1655% %
1656% N T R e g i s t r y K e y L o o k u p %
1657% %
1658% %
1659% %
1660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1661%
1662% NTRegistryKeyLookup() returns ImageMagick installation path settings
1663% stored in the Windows Registry. Path settings are specific to the
1664% installed ImageMagick version so that multiple Image Magick installations
1665% may coexist.
1666%
1667% Values are stored in the registry under a base path path similar to
cristyf7836bf2012-02-20 16:32:47 +00001668% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\6.7.4\Q:16" or
1669% "HKEY_CURRENT_USER/SOFTWARE\ImageMagick\6.7.4\Q:16". The provided subkey
cristy3ed852e2009-09-05 21:47:34 +00001670% is appended to this base path to form the full key.
1671%
1672% The format of the NTRegistryKeyLookup method is:
1673%
1674% unsigned char *NTRegistryKeyLookup(const char *subkey)
1675%
1676% A description of each parameter follows:
1677%
1678% o subkey: Specifies a string that identifies the registry object.
1679% Currently supported sub-keys include: "BinPath", "ConfigurePath",
1680% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1681%
1682*/
cristyf7836bf2012-02-20 16:32:47 +00001683MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
cristy3ed852e2009-09-05 21:47:34 +00001684{
1685 char
1686 package_key[MaxTextExtent];
1687
1688 DWORD
1689 size,
1690 type;
1691
1692 HKEY
1693 registry_key;
1694
1695 LONG
1696 status;
1697
1698 unsigned char
1699 *value;
1700
1701 /*
1702 Look-up base key.
1703 */
cristyb51dff52011-05-19 16:55:47 +00001704 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
cristy3ed852e2009-09-05 21:47:34 +00001705 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
1706 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
1707 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1708 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,&registry_key);
1709 if (status != ERROR_SUCCESS)
cristyd06bf862011-12-21 02:18:45 +00001710 status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ,
1711 &registry_key);
1712 if (status != ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +00001713 {
1714 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1715 return((unsigned char *) NULL);
1716 }
1717 /*
1718 Look-up sub key.
1719 */
1720 size=32;
1721 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
1722 if (value == (unsigned char *) NULL)
1723 {
1724 RegCloseKey(registry_key);
1725 return((unsigned char *) NULL);
1726 }
1727 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey);
1728 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1729 if ((status == ERROR_MORE_DATA) && (type == REG_SZ))
1730 {
1731 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
1732 if (value == (BYTE *) NULL)
1733 {
1734 RegCloseKey(registry_key);
1735 return((unsigned char *) NULL);
1736 }
1737 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1738 }
1739 RegCloseKey(registry_key);
1740 if ((type != REG_SZ) || (status != ERROR_SUCCESS))
1741 value=(unsigned char *) RelinquishMagickMemory(value);
1742 return((unsigned char *) value);
1743}
1744
1745/*
1746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1747% %
1748% %
1749% %
1750% N T R e p o r t E v e n t %
1751% %
1752% %
1753% %
1754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1755%
1756% NTReportEvent() reports an event.
1757%
1758% The format of the NTReportEvent method is:
1759%
1760% MagickBooleanType NTReportEvent(const char *event,
1761% const MagickBooleanType error)
1762%
1763% A description of each parameter follows:
1764%
1765% o event: the event.
1766%
1767% o error: MagickTrue the event is an error.
1768%
1769*/
cristyf7836bf2012-02-20 16:32:47 +00001770MagickExport MagickBooleanType NTReportEvent(const char *event,
cristy3ed852e2009-09-05 21:47:34 +00001771 const MagickBooleanType error)
1772{
1773 const char
1774 *events[1];
1775
1776 HANDLE
1777 handle;
1778
1779 WORD
1780 type;
1781
1782 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1783 if (handle == NULL)
1784 return(MagickFalse);
1785 events[0]=event;
1786 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1787 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1788 DeregisterEventSource(handle);
1789 return(MagickTrue);
1790}
1791
1792/*
1793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1794% %
1795% %
1796% %
1797% N T R e s o u r c e T o B l o b %
1798% %
1799% %
1800% %
1801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1802%
1803% NTResourceToBlob() returns a blob containing the contents of the resource
1804% in the current executable specified by the id parameter. This currently
1805% used to retrieve MGK files tha have been embedded into the various command
1806% line utilities.
1807%
1808% The format of the NTResourceToBlob method is:
1809%
1810% unsigned char *NTResourceToBlob(const char *id)
1811%
1812% A description of each parameter follows:
1813%
1814% o id: Specifies a string that identifies the resource.
1815%
1816*/
cristyf7836bf2012-02-20 16:32:47 +00001817MagickExport unsigned char *NTResourceToBlob(const char *id)
cristy3ed852e2009-09-05 21:47:34 +00001818{
1819 char
1820 path[MaxTextExtent];
1821
1822 DWORD
1823 length;
1824
1825 HGLOBAL
1826 global;
1827
1828 HMODULE
1829 handle;
1830
1831 HRSRC
1832 resource;
1833
1834 unsigned char
1835 *blob,
1836 *value;
1837
1838 assert(id != (const char *) NULL);
1839 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
cristyb51dff52011-05-19 16:55:47 +00001840 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +00001841 DirectorySeparator,GetClientName());
1842 if (IsPathAccessible(path) != MagickFalse)
1843 handle=GetModuleHandle(path);
1844 else
1845 handle=GetModuleHandle(0);
1846 if (!handle)
1847 return((unsigned char *) NULL);
1848 resource=FindResource(handle,id,"IMAGEMAGICK");
1849 if (!resource)
1850 return((unsigned char *) NULL);
1851 global=LoadResource(handle,resource);
1852 if (!global)
1853 return((unsigned char *) NULL);
1854 length=SizeofResource(handle,resource);
1855 value=(unsigned char *) LockResource(global);
1856 if (!value)
1857 {
1858 FreeResource(global);
1859 return((unsigned char *) NULL);
1860 }
1861 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
1862 sizeof(*blob));
1863 if (blob != (unsigned char *) NULL)
1864 {
1865 (void) CopyMagickMemory(blob,value,length);
1866 blob[length]='\0';
1867 }
1868 UnlockResource(global);
1869 FreeResource(global);
1870 return(blob);
1871}
1872
1873/*
1874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1875% %
1876% %
1877% %
1878% N T S e e k D i r e c t o r y %
1879% %
1880% %
1881% %
1882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1883%
1884% NTSeekDirectory() sets the position of the next NTReadDirectory() operation
1885% on the directory stream.
1886%
1887% The format of the NTSeekDirectory method is:
1888%
cristybb503372010-05-27 20:51:26 +00001889% void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001890%
1891% A description of each parameter follows:
1892%
1893% o entry: Specifies a pointer to a DIR structure.
1894%
1895% o position: specifies the position associated with the directory
1896% stream.
1897%
1898*/
cristyf7836bf2012-02-20 16:32:47 +00001899MagickExport void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001900{
cristy3b743bb2009-09-14 16:07:59 +00001901 (void) position;
cristy3ed852e2009-09-05 21:47:34 +00001902 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1903 assert(entry != (DIR *) NULL);
1904}
1905
1906/*
1907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1908% %
1909% %
1910% %
1911% N T S e t S e a r c h P a t h %
1912% %
1913% %
1914% %
1915%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1916%
1917% NTSetSearchPath() sets the current locations that the subsystem should
1918% look at to find dynamically loadable modules.
1919%
1920% The format of the NTSetSearchPath method is:
1921%
1922% int NTSetSearchPath(const char *path)
1923%
1924% A description of each parameter follows:
1925%
1926% o path: Specifies a pointer to string representing the search path
1927% for DLL's that can be dynamically loaded.
1928%
1929*/
cristyf7836bf2012-02-20 16:32:47 +00001930MagickExport int NTSetSearchPath(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00001931{
1932#if defined(MAGICKCORE_LTDL_DELEGATE)
1933 lt_dlsetsearchpath(path);
1934#else
1935 if (lt_slsearchpath != (char *) NULL)
1936 lt_slsearchpath=DestroyString(lt_slsearchpath);
1937 if (path != (char *) NULL)
1938 lt_slsearchpath=AcquireString(path);
1939#endif
1940 return(0);
1941}
1942
1943/*
1944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1945% %
1946% %
1947% %
1948+ N T S y n c M e m o r y %
1949% %
1950% %
1951% %
1952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1953%
1954% NTSyncMemory() emulates the Unix method of the same name.
1955%
1956% The format of the NTSyncMemory method is:
1957%
1958% int NTSyncMemory(void *address,size_t length,int flags)
1959%
1960% A description of each parameter follows:
1961%
1962% o address: the address of the binary large object.
1963%
1964% o length: the length of the binary large object.
1965%
1966% o flags: Option flags (ignored for Windows).
1967%
1968*/
cristyf7836bf2012-02-20 16:32:47 +00001969MagickExport int NTSyncMemory(void *address,size_t length,int flags)
cristy3ed852e2009-09-05 21:47:34 +00001970{
cristy3b743bb2009-09-14 16:07:59 +00001971 (void) flags;
cristy3ed852e2009-09-05 21:47:34 +00001972 if (FlushViewOfFile(address,length) == MagickFalse)
1973 return(-1);
1974 return(0);
1975}
1976
1977/*
1978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979% %
1980% %
1981% %
1982% N T S y s t e m C o m m a n d %
1983% %
1984% %
1985% %
1986%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1987%
1988% NTSystemCommand() executes the specified command and waits until it
1989% terminates. The returned value is the exit status of the command.
1990%
cristyb32b90a2009-09-07 21:45:48 +00001991% The format of the NTSystemCommand method is:
cristy3ed852e2009-09-05 21:47:34 +00001992%
cristy6de4bc22010-01-12 17:10:35 +00001993% int NTSystemCommand(MagickFalse,const char *command)
cristy3ed852e2009-09-05 21:47:34 +00001994%
1995% A description of each parameter follows:
1996%
1997% o command: This string is the command to execute.
1998%
1999*/
cristyf7836bf2012-02-20 16:32:47 +00002000MagickExport int NTSystemCommand(const char *command)
cristy3ed852e2009-09-05 21:47:34 +00002001{
2002 char
2003 local_command[MaxTextExtent];
2004
2005 DWORD
2006 child_status;
2007
2008 int
2009 status;
2010
2011 MagickBooleanType
2012 background_process;
2013
2014 PROCESS_INFORMATION
2015 process_info;
2016
2017 STARTUPINFO
2018 startup_info;
2019
2020 if (command == (char *) NULL)
2021 return(-1);
2022 GetStartupInfo(&startup_info);
2023 startup_info.dwFlags=STARTF_USESHOWWINDOW;
2024 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
2025 (void) CopyMagickString(local_command,command,MaxTextExtent);
2026 background_process=command[strlen(command)-1] == '&' ? MagickTrue :
2027 MagickFalse;
cristy99a00592012-02-25 02:33:01 +00002028 if (background_process != MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00002029 local_command[strlen(command)-1]='\0';
2030 if (command[strlen(command)-1] == '|')
2031 local_command[strlen(command)-1]='\0';
2032 else
2033 startup_info.wShowWindow=SW_SHOWDEFAULT;
cristy99a00592012-02-25 02:33:01 +00002034 status=CreateProcess((LPCTSTR) NULL,local_command,(LPSECURITY_ATTRIBUTES)
2035 NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,(DWORD)
2036 NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
cristy3ed852e2009-09-05 21:47:34 +00002037 &process_info);
2038 if (status == 0)
2039 return(-1);
cristy99a00592012-02-25 02:33:01 +00002040 if (background_process != MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00002041 return(status == 0);
2042 status=WaitForSingleObject(process_info.hProcess,INFINITE);
2043 if (status != WAIT_OBJECT_0)
2044 return(status);
2045 status=GetExitCodeProcess(process_info.hProcess,&child_status);
2046 if (status == 0)
2047 return(-1);
2048 CloseHandle(process_info.hProcess);
2049 CloseHandle(process_info.hThread);
2050 return((int) child_status);
2051}
2052
2053/*
2054%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2055% %
2056% %
2057% %
2058% N T S y s t e m C o n i f i g u r a t i o n %
2059% %
2060% %
2061% %
2062%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2063%
2064% NTSystemConfiguration() provides a way for the application to determine
2065% values for system limits or options at runtime.
2066%
2067% The format of the exit method is:
2068%
cristybb503372010-05-27 20:51:26 +00002069% ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002070%
2071% A description of each parameter follows:
2072%
2073% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
2074%
2075*/
cristyf7836bf2012-02-20 16:32:47 +00002076MagickExport ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002077{
2078 switch (name)
2079 {
2080 case _SC_PAGESIZE:
2081 {
2082 SYSTEM_INFO
2083 system_info;
2084
2085 GetSystemInfo(&system_info);
2086 return(system_info.dwPageSize);
2087 }
2088 case _SC_PHYS_PAGES:
2089 {
2090 HMODULE
2091 handle;
2092
2093 LPFNDLLFUNC2
2094 module;
2095
2096 NTMEMORYSTATUSEX
2097 status;
2098
2099 SYSTEM_INFO
2100 system_info;
2101
2102 handle=GetModuleHandle("kernel32.dll");
2103 if (handle == (HMODULE) NULL)
2104 return(0L);
2105 GetSystemInfo(&system_info);
2106 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
2107 if (module == (LPFNDLLFUNC2) NULL)
2108 {
2109 MEMORYSTATUS
2110 status;
2111
2112 GlobalMemoryStatus(&status);
cristybb503372010-05-27 20:51:26 +00002113 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002114 }
2115 status.dwLength=sizeof(status);
2116 if (module(&status) == 0)
2117 return(0L);
cristybb503372010-05-27 20:51:26 +00002118 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002119 }
2120 case _SC_OPEN_MAX:
2121 return(2048);
2122 default:
2123 break;
2124 }
2125 return(-1);
2126}
2127
2128/*
2129%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2130% %
2131% %
2132% %
2133% N T T e l l D i r e c t o r y %
2134% %
2135% %
2136% %
2137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2138%
2139% NTTellDirectory() returns the current location associated with the named
2140% directory stream.
2141%
2142% The format of the NTTellDirectory method is:
2143%
cristybb503372010-05-27 20:51:26 +00002144% ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002145%
2146% A description of each parameter follows:
2147%
2148% o entry: Specifies a pointer to a DIR structure.
2149%
2150*/
cristyf7836bf2012-02-20 16:32:47 +00002151MagickExport ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002152{
2153 assert(entry != (DIR *) NULL);
2154 return(0);
2155}
2156
2157/*
2158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2159% %
2160% %
2161% %
2162% N T T r u n c a t e F i l e %
2163% %
2164% %
2165% %
2166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2167%
2168% NTTruncateFile() truncates a file to a specified length.
2169%
2170% The format of the NTTruncateFile method is:
2171%
2172% int NTTruncateFile(int file,off_t length)
2173%
2174% A description of each parameter follows:
2175%
2176% o file: the file.
2177%
2178% o length: the file length.
2179%
2180*/
cristyf7836bf2012-02-20 16:32:47 +00002181MagickExport int NTTruncateFile(int file,off_t length)
cristy3ed852e2009-09-05 21:47:34 +00002182{
2183 DWORD
2184 file_pointer;
2185
cristyfeb262e2010-06-04 22:57:35 +00002186 long
cristy3ed852e2009-09-05 21:47:34 +00002187 file_handle,
2188 high,
2189 low;
2190
2191 file_handle=_get_osfhandle(file);
2192 if (file_handle == -1L)
2193 return(-1);
cristyfeb262e2010-06-04 22:57:35 +00002194 low=(long) (length & 0xffffffffUL);
2195 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
cristy3ed852e2009-09-05 21:47:34 +00002196 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2197 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2198 return(-1);
2199 if (SetEndOfFile((HANDLE) file_handle) == 0)
2200 return(-1);
2201 return(0);
2202}
2203
2204/*
2205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2206% %
2207% %
2208% %
2209+ N T U n m a p M e m o r y %
2210% %
2211% %
2212% %
2213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2214%
2215% NTUnmapMemory() emulates the Unix munmap method.
2216%
2217% The format of the NTUnmapMemory method is:
2218%
2219% int NTUnmapMemory(void *map,size_t length)
2220%
2221% A description of each parameter follows:
2222%
2223% o map: the address of the binary large object.
2224%
2225% o length: the length of the binary large object.
2226%
2227*/
cristyf7836bf2012-02-20 16:32:47 +00002228MagickExport int NTUnmapMemory(void *map,size_t length)
cristy3ed852e2009-09-05 21:47:34 +00002229{
cristy3b743bb2009-09-14 16:07:59 +00002230 (void) length;
cristy3ed852e2009-09-05 21:47:34 +00002231 if (UnmapViewOfFile(map) == 0)
2232 return(-1);
2233 return(0);
2234}
2235
2236/*
2237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2238% %
2239% %
2240% %
2241% N T U s e r T i m e %
2242% %
2243% %
2244% %
2245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2246%
2247% NTUserTime() returns the total time the process has been scheduled (e.g.
2248% seconds) since the last call to StartTimer().
2249%
2250% The format of the UserTime method is:
2251%
2252% double NTUserTime(void)
2253%
2254*/
cristyf7836bf2012-02-20 16:32:47 +00002255MagickExport double NTUserTime(void)
cristy3ed852e2009-09-05 21:47:34 +00002256{
2257 DWORD
2258 status;
2259
2260 FILETIME
2261 create_time,
2262 exit_time;
2263
2264 OSVERSIONINFO
2265 OsVersionInfo;
2266
2267 union
2268 {
2269 FILETIME
2270 filetime;
2271
2272 __int64
2273 filetime64;
2274 } kernel_time;
2275
2276 union
2277 {
2278 FILETIME
2279 filetime;
2280
2281 __int64
2282 filetime64;
2283 } user_time;
2284
2285 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2286 GetVersionEx(&OsVersionInfo);
2287 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2288 return(NTElapsedTime());
2289 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2290 &kernel_time.filetime,&user_time.filetime);
2291 if (status != TRUE)
2292 return(0.0);
2293 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2294}
2295
2296/*
2297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2298% %
2299% %
2300% %
2301% N T W a r n i n g H a n d l e r %
2302% %
2303% %
2304% %
2305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2306%
2307% NTWarningHandler() displays a warning reason.
2308%
2309% The format of the NTWarningHandler method is:
2310%
cristy3b743bb2009-09-14 16:07:59 +00002311% void NTWarningHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +00002312% const char *description)
2313%
2314% A description of each parameter follows:
2315%
cristy3b743bb2009-09-14 16:07:59 +00002316% o severity: Specifies the numeric warning category.
cristy3ed852e2009-09-05 21:47:34 +00002317%
2318% o reason: Specifies the reason to display before terminating the
2319% program.
2320%
2321% o description: Specifies any description to the reason.
2322%
2323*/
cristy417d8452011-10-13 17:09:49 +00002324MagickExport void NTWarningHandler(const ExceptionType severity,
cristy3ed852e2009-09-05 21:47:34 +00002325 const char *reason,const char *description)
2326{
2327 char
2328 buffer[2*MaxTextExtent];
2329
cristy3b743bb2009-09-14 16:07:59 +00002330 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +00002331 if (reason == (char *) NULL)
2332 return;
2333 if (description == (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00002334 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
cristy3ed852e2009-09-05 21:47:34 +00002335 reason);
2336 else
cristyb51dff52011-05-19 16:55:47 +00002337 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +00002338 GetClientName(),reason,description);
2339 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2340 MB_SETFOREGROUND | MB_ICONINFORMATION);
2341}
2342#endif