blob: 1e2ade24d1e869d4a9f5b0b0240de88457fefdf1 [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
cristy309042f2012-02-20 18:59:35 +000058#include "MagickCore/nt-base.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
cristyfc0f64b2009-09-09 18:57:08 +0000890static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
891 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 */
cristyfc0f64b2009-09-09 18:57:08 +0000910 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
911 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
cristydefb3f02009-09-10 02:18:35 +0000932static int NTLocateGhostscript(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;
cristye66bcb42009-09-17 13:31:08 +0000971 mode=KEY_READ;
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
1016static int NTGhostscriptGetString(const char *name,char *value,
1017 const size_t length)
1018{
cristy3ed852e2009-09-05 21:47:34 +00001019 char
cristy3ed852e2009-09-05 21:47:34 +00001020 key[MaxTextExtent];
1021
1022 int
cristyfc0f64b2009-09-09 18:57:08 +00001023 i,
1024 extent;
cristy82b15832009-10-06 19:17:37 +00001025
cristyfc0f64b2009-09-09 18:57:08 +00001026 static const char
cristydefb3f02009-09-10 02:18:35 +00001027 *product_family = (const char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001028
cristyfc0f64b2009-09-09 18:57:08 +00001029 static int
1030 major_version=0,
1031 minor_version=0;
cristy3ed852e2009-09-05 21:47:34 +00001032
cristyfc0f64b2009-09-09 18:57:08 +00001033 struct
1034 {
1035 const HKEY
1036 hkey;
cristy3ed852e2009-09-05 21:47:34 +00001037
cristyfc0f64b2009-09-09 18:57:08 +00001038 const char
1039 *name;
1040 }
1041 hkeys[2] =
1042 {
1043 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
1044 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
1045 };
1046
1047 /*
1048 Get a string from the installed Ghostscript.
1049 */
cristydefb3f02009-09-10 02:18:35 +00001050 *value='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001051 if (product_family == NULL)
cristydefb3f02009-09-10 02:18:35 +00001052 (void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
cristyfc0f64b2009-09-09 18:57:08 +00001053 if (product_family == NULL)
1054 return(FALSE);
cristyb51dff52011-05-19 16:55:47 +00001055 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
cristyfc0f64b2009-09-09 18:57:08 +00001056 product_family,major_version,minor_version);
cristybb503372010-05-27 20:51:26 +00001057 for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +00001058 {
cristy76319442009-09-22 02:04:05 +00001059 extent=(int) length;
cristyfc0f64b2009-09-09 18:57:08 +00001060 if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
1061 {
1062 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1063 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
1064 return(TRUE);
1065 }
1066 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1067 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
1068 }
cristy3ed852e2009-09-05 21:47:34 +00001069 return(FALSE);
1070}
1071
cristyf7836bf2012-02-20 16:32:47 +00001072MagickExport int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001073{
cristy4c11ed82009-09-11 03:36:46 +00001074 static char
1075 dll[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001076
1077 *path='\0';
cristy4c11ed82009-09-11 03:36:46 +00001078 if ((*dll == '\0') &&
1079 (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
cristy106919c2009-09-11 03:46:56 +00001080 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001081 (void) CopyMagickString(path,dll,length);
cristy3ed852e2009-09-05 21:47:34 +00001082 return(TRUE);
1083}
1084
1085/*
1086%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087% %
1088% %
1089% %
1090% N T G h o s t s c r i p t D L L V e c t o r s %
1091% %
1092% %
1093% %
1094%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095%
cristydefb3f02009-09-10 02:18:35 +00001096% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
1097% function vectors to invoke Ghostscript DLL functions. A null pointer is
1098% returned if there is an error when loading the DLL or retrieving the
1099% function vectors.
cristy3ed852e2009-09-05 21:47:34 +00001100%
1101% The format of the NTGhostscriptDLLVectors method is:
1102%
cristydefb3f02009-09-10 02:18:35 +00001103% const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001104%
1105*/
cristydaeba5e2011-10-13 17:32:44 +00001106MagickExport const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001107{
cristyfc0f64b2009-09-09 18:57:08 +00001108 if (NTGhostscriptLoadDLL() == FALSE)
cristydefb3f02009-09-10 02:18:35 +00001109 return((GhostInfo *) NULL);
1110 return(&ghost_info);
cristy3ed852e2009-09-05 21:47:34 +00001111}
1112
1113/*
1114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1115% %
1116% %
1117% %
1118% N T G h o s t s c r i p t E X E %
1119% %
1120% %
1121% %
1122%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1123%
1124% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
cristyfc0f64b2009-09-09 18:57:08 +00001125% The method returns FALSE if a full path value is not obtained and returns
1126% a default path of gswin32c.exe.
cristy3ed852e2009-09-05 21:47:34 +00001127%
1128% The format of the NTGhostscriptEXE method is:
1129%
cristyfc0f64b2009-09-09 18:57:08 +00001130% int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001131%
1132% A description of each parameter follows:
1133%
cristyfc0f64b2009-09-09 18:57:08 +00001134% o path: return the Ghostscript executable path here.
cristy3ed852e2009-09-05 21:47:34 +00001135%
cristyb32b90a2009-09-07 21:45:48 +00001136% o length: length of buffer.
cristy3ed852e2009-09-05 21:47:34 +00001137%
1138*/
cristyf7836bf2012-02-20 16:32:47 +00001139MagickExport int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001140{
cristy4c11ed82009-09-11 03:36:46 +00001141 register char
cristy3ed852e2009-09-05 21:47:34 +00001142 *p;
1143
cristyfc0f64b2009-09-09 18:57:08 +00001144 static char
cristy4c11ed82009-09-11 03:36:46 +00001145 program[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001146
cristyb32b90a2009-09-07 21:45:48 +00001147 (void) CopyMagickString(path,"gswin32c.exe",length);
cristy4c11ed82009-09-11 03:36:46 +00001148 if ((*program == '\0') &&
1149 (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE))
cristyb32b90a2009-09-07 21:45:48 +00001150 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001151 p=strrchr(program,'\\');
cristy7ba1b042011-02-05 19:07:50 +00001152 if (p != (char *) NULL)
cristy4c11ed82009-09-11 03:36:46 +00001153 {
1154 p++;
1155 *p='\0';
1156 (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program));
1157 }
1158 (void) CopyMagickString(path,program,length);
cristyb32b90a2009-09-07 21:45:48 +00001159 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001160}
1161
1162/*
1163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1164% %
1165% %
1166% %
1167% N T G h o s t s c r i p t F o n t s %
1168% %
1169% %
1170% %
1171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1172%
cristyfc0f64b2009-09-09 18:57:08 +00001173% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1174% returns FALSE if it cannot determine the font path.
cristy3ed852e2009-09-05 21:47:34 +00001175%
1176% The format of the NTGhostscriptFonts method is:
1177%
cristyfc0f64b2009-09-09 18:57:08 +00001178% int NTGhostscriptFonts(char *path, int length)
cristy3ed852e2009-09-05 21:47:34 +00001179%
1180% A description of each parameter follows:
1181%
cristyfc0f64b2009-09-09 18:57:08 +00001182% o path: return the font path here.
cristy3ed852e2009-09-05 21:47:34 +00001183%
cristyfc0f64b2009-09-09 18:57:08 +00001184% o length: length of the path buffer.
cristy3ed852e2009-09-05 21:47:34 +00001185%
1186*/
cristyf7836bf2012-02-20 16:32:47 +00001187MagickExport int NTGhostscriptFonts(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001188{
1189 char
1190 buffer[MaxTextExtent],
1191 filename[MaxTextExtent];
1192
cristy3ed852e2009-09-05 21:47:34 +00001193 register char
1194 *p,
1195 *q;
1196
1197 *path='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001198 if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE)
cristy3ed852e2009-09-05 21:47:34 +00001199 return(FALSE);
1200 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1201 {
1202 (void) CopyMagickString(path,p+1,length+1);
1203 q=strchr(path,DirectoryListSeparator);
1204 if (q != (char *) NULL)
1205 *q='\0';
cristyb51dff52011-05-19 16:55:47 +00001206 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path,
cristy3ed852e2009-09-05 21:47:34 +00001207 DirectorySeparator);
1208 if (IsPathAccessible(filename) != MagickFalse)
1209 return(TRUE);
1210 }
1211 return(FALSE);
1212}
1213
1214/*
1215%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1216% %
1217% %
1218% %
1219% N T G h o s t s c r i p t L o a d D L L %
1220% %
1221% %
1222% %
1223%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1224%
1225% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
cristyfc0f64b2009-09-09 18:57:08 +00001226% TRUE if it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001227%
1228% The format of the NTGhostscriptLoadDLL method is:
1229%
1230% int NTGhostscriptLoadDLL(void)
1231%
1232*/
cristyf7836bf2012-02-20 16:32:47 +00001233MagickExport int NTGhostscriptLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001234{
1235 char
cristyfc0f64b2009-09-09 18:57:08 +00001236 path[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001237
cristydefb3f02009-09-10 02:18:35 +00001238 if (ghost_handle != (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001239 return(TRUE);
1240 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1241 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001242 ghost_handle=lt_dlopen(path);
1243 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001244 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001245 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1246 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1247 lt_dlsym(ghost_handle,"gsapi_exit");
1248 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1249 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1250 ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1251 lt_dlsym(ghost_handle,"gsapi_new_instance"));
1252 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1253 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1254 ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1255 lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1256 if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1257 (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1258 (ghost_info.delete_instance == NULL))
cristyfc0f64b2009-09-09 18:57:08 +00001259 return(FALSE);
1260 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001261}
1262
1263/*
1264%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1265% %
1266% %
1267% %
1268% N T G h o s t s c r i p t U n L o a d D L L %
1269% %
1270% %
1271% %
1272%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1273%
cristyfc0f64b2009-09-09 18:57:08 +00001274% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1275% it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001276%
1277% The format of the NTGhostscriptUnLoadDLL method is:
1278%
1279% int NTGhostscriptUnLoadDLL(void)
1280%
1281*/
cristydaeba5e2011-10-13 17:32:44 +00001282MagickExport int NTGhostscriptUnLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001283{
cristyfc0f64b2009-09-09 18:57:08 +00001284 int
1285 status;
1286
cristydefb3f02009-09-10 02:18:35 +00001287 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001288 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001289 status=lt_dlclose(ghost_handle);
1290 ghost_handle=(void *) NULL;
1291 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
cristyfc0f64b2009-09-09 18:57:08 +00001292 return(status);
cristy3ed852e2009-09-05 21:47:34 +00001293}
1294
1295/*
1296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1297% %
1298% %
1299% %
1300% N T I n i t i a l i z e L i b r a r y %
1301% %
1302% %
1303% %
1304%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1305%
1306% NTInitializeLibrary() initializes the dynamic module loading subsystem.
1307%
1308% The format of the NTInitializeLibrary method is:
1309%
1310% int NTInitializeLibrary(void)
1311%
1312*/
cristyf7836bf2012-02-20 16:32:47 +00001313MagickExport int NTInitializeLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +00001314{
1315 return(0);
1316}
1317
1318/*
1319%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1320% %
1321% %
1322% %
1323+ N T M a p M e m o r y %
1324% %
1325% %
1326% %
1327%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1328%
1329% Mmap() emulates the Unix method of the same name.
1330%
1331% The format of the NTMapMemory method is:
1332%
cristyf7836bf2012-02-20 16:32:47 +00001333% MagickExport void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001334% int access,int file,MagickOffsetType offset)
1335%
1336*/
cristyf7836bf2012-02-20 16:32:47 +00001337MagickExport void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001338 int flags,int file,MagickOffsetType offset)
1339{
1340 DWORD
1341 access_mode,
1342 high_length,
1343 high_offset,
1344 low_length,
1345 low_offset,
1346 protection_mode;
1347
1348 HANDLE
1349 file_handle,
1350 map_handle;
1351
1352 void
1353 *map;
1354
cristy3b743bb2009-09-14 16:07:59 +00001355 (void) address;
cristy3ed852e2009-09-05 21:47:34 +00001356 access_mode=0;
1357 file_handle=INVALID_HANDLE_VALUE;
1358 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1359 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1360 map_handle=INVALID_HANDLE_VALUE;
1361 map=(void *) NULL;
1362 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1363 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1364 protection_mode=0;
1365 if (protection & PROT_WRITE)
1366 {
1367 access_mode=FILE_MAP_WRITE;
1368 if (!(flags & MAP_PRIVATE))
1369 protection_mode=PAGE_READWRITE;
1370 else
1371 {
1372 access_mode=FILE_MAP_COPY;
1373 protection_mode=PAGE_WRITECOPY;
1374 }
1375 }
1376 else
1377 if (protection & PROT_READ)
1378 {
1379 access_mode=FILE_MAP_READ;
1380 protection_mode=PAGE_READONLY;
1381 }
1382 if ((file == -1) && (flags & MAP_ANONYMOUS))
1383 file_handle=INVALID_HANDLE_VALUE;
1384 else
1385 file_handle=(HANDLE) _get_osfhandle(file);
1386 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1387 low_length,0);
1388 if (map_handle)
1389 {
1390 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1391 length);
1392 CloseHandle(map_handle);
1393 }
1394 if (map == (void *) NULL)
1395 return((void *) MAP_FAILED);
1396 return((void *) ((char *) map));
1397}
1398
1399/*
1400%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401% %
1402% %
1403% %
1404% N T O p e n D i r e c t o r y %
1405% %
1406% %
1407% %
1408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409%
1410% NTOpenDirectory() opens the directory named by filename and associates a
1411% directory stream with it.
1412%
1413% The format of the NTOpenDirectory method is:
1414%
1415% DIR *NTOpenDirectory(const char *path)
1416%
1417% A description of each parameter follows:
1418%
1419% o entry: Specifies a pointer to a DIR structure.
1420%
1421*/
cristyf7836bf2012-02-20 16:32:47 +00001422MagickExport DIR *NTOpenDirectory(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00001423{
1424 char
1425 file_specification[MaxTextExtent];
1426
1427 DIR
1428 *entry;
1429
1430 size_t
1431 length;
1432
1433 assert(path != (const char *) NULL);
1434 length=CopyMagickString(file_specification,path,MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001435 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001436 return((DIR *) NULL);
1437 length=ConcatenateMagickString(file_specification,DirectorySeparator,
1438 MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001439 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001440 return((DIR *) NULL);
cristy73bd4a52010-10-05 11:24:23 +00001441 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
cristy3ed852e2009-09-05 21:47:34 +00001442 if (entry != (DIR *) NULL)
1443 {
1444 entry->firsttime=TRUE;
1445 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1446 }
1447 if (entry->hSearch == INVALID_HANDLE_VALUE)
1448 {
1449 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001450 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001451 {
1452 entry=(DIR *) RelinquishMagickMemory(entry);
1453 return((DIR *) NULL);
1454 }
1455 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1456 if (entry->hSearch == INVALID_HANDLE_VALUE)
1457 {
1458 entry=(DIR *) RelinquishMagickMemory(entry);
1459 return((DIR *) NULL);
1460 }
1461 }
1462 return(entry);
1463}
1464
1465/*
1466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1467% %
1468% %
1469% %
1470% N T O p e n L i b r a r y %
1471% %
1472% %
1473% %
1474%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1475%
1476% NTOpenLibrary() loads a dynamic module into memory and returns a handle that
1477% can be used to access the various procedures in the module.
1478%
1479% The format of the NTOpenLibrary method is:
1480%
1481% void *NTOpenLibrary(const char *filename)
1482%
1483% A description of each parameter follows:
1484%
1485% o path: Specifies a pointer to string representing dynamic module that
1486% is to be loaded.
1487%
1488*/
1489
1490static const char *GetSearchPath( void )
1491{
1492#if defined(MAGICKCORE_LTDL_DELEGATE)
1493 return(lt_dlgetsearchpath());
1494#else
1495 return(lt_slsearchpath);
1496#endif
1497}
1498
cristyf7836bf2012-02-20 16:32:47 +00001499MagickExport void *NTOpenLibrary(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +00001500{
1501#define MaxPathElements 31
1502
1503 char
1504 buffer[MaxTextExtent];
1505
1506 int
1507 index;
1508
1509 register const char
1510 *p,
1511 *q;
1512
1513 register int
1514 i;
1515
1516 UINT
1517 mode;
1518
1519 void
1520 *handle;
1521
1522 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1523 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1524 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL))
1525 {
1526 SetErrorMode(mode);
1527 return(handle);
1528 }
1529 p=(char *) GetSearchPath();
1530 index=0;
1531 while (index < MaxPathElements)
1532 {
1533 q=strchr(p,DirectoryListSeparator);
1534 if (q == (char *) NULL)
1535 {
1536 (void) CopyMagickString(buffer,p,MaxTextExtent);
1537 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1538 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1539 handle=(void *) LoadLibraryEx(buffer,NULL,
1540 LOAD_WITH_ALTERED_SEARCH_PATH);
1541 break;
1542 }
1543 i=q-p;
1544 (void) CopyMagickString(buffer,p,i+1);
1545 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1546 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1547 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1548 if (handle != (void *) NULL)
1549 break;
1550 p=q+1;
1551 }
1552 SetErrorMode(mode);
1553 return(handle);
1554}
1555
1556/*
1557%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1558% %
1559% %
1560% %
1561% N T R e a d D i r e c t o r y %
1562% %
1563% %
1564% %
1565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1566%
1567% NTReadDirectory() returns a pointer to a structure representing the
1568% directory entry at the current position in the directory stream to which
1569% entry refers.
1570%
1571% The format of the NTReadDirectory
1572%
1573% NTReadDirectory(entry)
1574%
1575% A description of each parameter follows:
1576%
1577% o entry: Specifies a pointer to a DIR structure.
1578%
1579*/
cristyf7836bf2012-02-20 16:32:47 +00001580MagickExport struct dirent *NTReadDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00001581{
1582 int
1583 status;
1584
1585 size_t
1586 length;
1587
1588 if (entry == (DIR *) NULL)
1589 return((struct dirent *) NULL);
1590 if (!entry->firsttime)
1591 {
1592 status=FindNextFile(entry->hSearch,&entry->Win32FindData);
1593 if (status == 0)
1594 return((struct dirent *) NULL);
1595 }
1596 length=CopyMagickString(entry->file_info.d_name,
1597 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name));
1598 if (length >= sizeof(entry->file_info.d_name))
1599 return((struct dirent *) NULL);
1600 entry->firsttime=FALSE;
1601 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1602 return(&entry->file_info);
1603}
1604
1605/*
1606%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1607% %
1608% %
1609% %
1610% N T R e g i s t r y K e y L o o k u p %
1611% %
1612% %
1613% %
1614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1615%
1616% NTRegistryKeyLookup() returns ImageMagick installation path settings
1617% stored in the Windows Registry. Path settings are specific to the
1618% installed ImageMagick version so that multiple Image Magick installations
1619% may coexist.
1620%
1621% Values are stored in the registry under a base path path similar to
cristyf7836bf2012-02-20 16:32:47 +00001622% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\6.7.4\Q:16" or
1623% "HKEY_CURRENT_USER/SOFTWARE\ImageMagick\6.7.4\Q:16". The provided subkey
cristy3ed852e2009-09-05 21:47:34 +00001624% is appended to this base path to form the full key.
1625%
1626% The format of the NTRegistryKeyLookup method is:
1627%
1628% unsigned char *NTRegistryKeyLookup(const char *subkey)
1629%
1630% A description of each parameter follows:
1631%
1632% o subkey: Specifies a string that identifies the registry object.
1633% Currently supported sub-keys include: "BinPath", "ConfigurePath",
1634% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1635%
1636*/
cristyf7836bf2012-02-20 16:32:47 +00001637MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
cristy3ed852e2009-09-05 21:47:34 +00001638{
1639 char
1640 package_key[MaxTextExtent];
1641
1642 DWORD
1643 size,
1644 type;
1645
1646 HKEY
1647 registry_key;
1648
1649 LONG
1650 status;
1651
1652 unsigned char
1653 *value;
1654
1655 /*
1656 Look-up base key.
1657 */
cristyb51dff52011-05-19 16:55:47 +00001658 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
cristy3ed852e2009-09-05 21:47:34 +00001659 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
1660 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
1661 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1662 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,&registry_key);
1663 if (status != ERROR_SUCCESS)
cristyd06bf862011-12-21 02:18:45 +00001664 status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ,
1665 &registry_key);
1666 if (status != ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +00001667 {
1668 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1669 return((unsigned char *) NULL);
1670 }
1671 /*
1672 Look-up sub key.
1673 */
1674 size=32;
1675 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
1676 if (value == (unsigned char *) NULL)
1677 {
1678 RegCloseKey(registry_key);
1679 return((unsigned char *) NULL);
1680 }
1681 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey);
1682 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1683 if ((status == ERROR_MORE_DATA) && (type == REG_SZ))
1684 {
1685 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
1686 if (value == (BYTE *) NULL)
1687 {
1688 RegCloseKey(registry_key);
1689 return((unsigned char *) NULL);
1690 }
1691 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1692 }
1693 RegCloseKey(registry_key);
1694 if ((type != REG_SZ) || (status != ERROR_SUCCESS))
1695 value=(unsigned char *) RelinquishMagickMemory(value);
1696 return((unsigned char *) value);
1697}
1698
1699/*
1700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1701% %
1702% %
1703% %
1704% N T R e p o r t E v e n t %
1705% %
1706% %
1707% %
1708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1709%
1710% NTReportEvent() reports an event.
1711%
1712% The format of the NTReportEvent method is:
1713%
1714% MagickBooleanType NTReportEvent(const char *event,
1715% const MagickBooleanType error)
1716%
1717% A description of each parameter follows:
1718%
1719% o event: the event.
1720%
1721% o error: MagickTrue the event is an error.
1722%
1723*/
cristyf7836bf2012-02-20 16:32:47 +00001724MagickExport MagickBooleanType NTReportEvent(const char *event,
cristy3ed852e2009-09-05 21:47:34 +00001725 const MagickBooleanType error)
1726{
1727 const char
1728 *events[1];
1729
1730 HANDLE
1731 handle;
1732
1733 WORD
1734 type;
1735
1736 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1737 if (handle == NULL)
1738 return(MagickFalse);
1739 events[0]=event;
1740 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1741 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1742 DeregisterEventSource(handle);
1743 return(MagickTrue);
1744}
1745
1746/*
1747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1748% %
1749% %
1750% %
1751% N T R e s o u r c e T o B l o b %
1752% %
1753% %
1754% %
1755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1756%
1757% NTResourceToBlob() returns a blob containing the contents of the resource
1758% in the current executable specified by the id parameter. This currently
1759% used to retrieve MGK files tha have been embedded into the various command
1760% line utilities.
1761%
1762% The format of the NTResourceToBlob method is:
1763%
1764% unsigned char *NTResourceToBlob(const char *id)
1765%
1766% A description of each parameter follows:
1767%
1768% o id: Specifies a string that identifies the resource.
1769%
1770*/
cristyf7836bf2012-02-20 16:32:47 +00001771MagickExport unsigned char *NTResourceToBlob(const char *id)
cristy3ed852e2009-09-05 21:47:34 +00001772{
1773 char
1774 path[MaxTextExtent];
1775
1776 DWORD
1777 length;
1778
1779 HGLOBAL
1780 global;
1781
1782 HMODULE
1783 handle;
1784
1785 HRSRC
1786 resource;
1787
1788 unsigned char
1789 *blob,
1790 *value;
1791
1792 assert(id != (const char *) NULL);
1793 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
cristyb51dff52011-05-19 16:55:47 +00001794 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +00001795 DirectorySeparator,GetClientName());
1796 if (IsPathAccessible(path) != MagickFalse)
1797 handle=GetModuleHandle(path);
1798 else
1799 handle=GetModuleHandle(0);
1800 if (!handle)
1801 return((unsigned char *) NULL);
1802 resource=FindResource(handle,id,"IMAGEMAGICK");
1803 if (!resource)
1804 return((unsigned char *) NULL);
1805 global=LoadResource(handle,resource);
1806 if (!global)
1807 return((unsigned char *) NULL);
1808 length=SizeofResource(handle,resource);
1809 value=(unsigned char *) LockResource(global);
1810 if (!value)
1811 {
1812 FreeResource(global);
1813 return((unsigned char *) NULL);
1814 }
1815 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
1816 sizeof(*blob));
1817 if (blob != (unsigned char *) NULL)
1818 {
1819 (void) CopyMagickMemory(blob,value,length);
1820 blob[length]='\0';
1821 }
1822 UnlockResource(global);
1823 FreeResource(global);
1824 return(blob);
1825}
1826
1827/*
1828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1829% %
1830% %
1831% %
1832% N T S e e k D i r e c t o r y %
1833% %
1834% %
1835% %
1836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1837%
1838% NTSeekDirectory() sets the position of the next NTReadDirectory() operation
1839% on the directory stream.
1840%
1841% The format of the NTSeekDirectory method is:
1842%
cristybb503372010-05-27 20:51:26 +00001843% void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001844%
1845% A description of each parameter follows:
1846%
1847% o entry: Specifies a pointer to a DIR structure.
1848%
1849% o position: specifies the position associated with the directory
1850% stream.
1851%
1852*/
cristyf7836bf2012-02-20 16:32:47 +00001853MagickExport void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001854{
cristy3b743bb2009-09-14 16:07:59 +00001855 (void) position;
cristy3ed852e2009-09-05 21:47:34 +00001856 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1857 assert(entry != (DIR *) NULL);
1858}
1859
1860/*
1861%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1862% %
1863% %
1864% %
1865% N T S e t S e a r c h P a t h %
1866% %
1867% %
1868% %
1869%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870%
1871% NTSetSearchPath() sets the current locations that the subsystem should
1872% look at to find dynamically loadable modules.
1873%
1874% The format of the NTSetSearchPath method is:
1875%
1876% int NTSetSearchPath(const char *path)
1877%
1878% A description of each parameter follows:
1879%
1880% o path: Specifies a pointer to string representing the search path
1881% for DLL's that can be dynamically loaded.
1882%
1883*/
cristyf7836bf2012-02-20 16:32:47 +00001884MagickExport int NTSetSearchPath(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00001885{
1886#if defined(MAGICKCORE_LTDL_DELEGATE)
1887 lt_dlsetsearchpath(path);
1888#else
1889 if (lt_slsearchpath != (char *) NULL)
1890 lt_slsearchpath=DestroyString(lt_slsearchpath);
1891 if (path != (char *) NULL)
1892 lt_slsearchpath=AcquireString(path);
1893#endif
1894 return(0);
1895}
1896
1897/*
1898%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1899% %
1900% %
1901% %
1902+ N T S y n c M e m o r y %
1903% %
1904% %
1905% %
1906%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1907%
1908% NTSyncMemory() emulates the Unix method of the same name.
1909%
1910% The format of the NTSyncMemory method is:
1911%
1912% int NTSyncMemory(void *address,size_t length,int flags)
1913%
1914% A description of each parameter follows:
1915%
1916% o address: the address of the binary large object.
1917%
1918% o length: the length of the binary large object.
1919%
1920% o flags: Option flags (ignored for Windows).
1921%
1922*/
cristyf7836bf2012-02-20 16:32:47 +00001923MagickExport int NTSyncMemory(void *address,size_t length,int flags)
cristy3ed852e2009-09-05 21:47:34 +00001924{
cristy3b743bb2009-09-14 16:07:59 +00001925 (void) flags;
cristy3ed852e2009-09-05 21:47:34 +00001926 if (FlushViewOfFile(address,length) == MagickFalse)
1927 return(-1);
1928 return(0);
1929}
1930
1931/*
1932%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1933% %
1934% %
1935% %
1936% N T S y s t e m C o m m a n d %
1937% %
1938% %
1939% %
1940%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1941%
1942% NTSystemCommand() executes the specified command and waits until it
1943% terminates. The returned value is the exit status of the command.
1944%
cristyb32b90a2009-09-07 21:45:48 +00001945% The format of the NTSystemCommand method is:
cristy3ed852e2009-09-05 21:47:34 +00001946%
cristy6de4bc22010-01-12 17:10:35 +00001947% int NTSystemCommand(MagickFalse,const char *command)
cristy3ed852e2009-09-05 21:47:34 +00001948%
1949% A description of each parameter follows:
1950%
1951% o command: This string is the command to execute.
1952%
1953*/
cristyf7836bf2012-02-20 16:32:47 +00001954MagickExport int NTSystemCommand(const char *command)
cristy3ed852e2009-09-05 21:47:34 +00001955{
1956 char
1957 local_command[MaxTextExtent];
1958
1959 DWORD
1960 child_status;
1961
1962 int
1963 status;
1964
1965 MagickBooleanType
1966 background_process;
1967
1968 PROCESS_INFORMATION
1969 process_info;
1970
1971 STARTUPINFO
1972 startup_info;
1973
1974 if (command == (char *) NULL)
1975 return(-1);
1976 GetStartupInfo(&startup_info);
1977 startup_info.dwFlags=STARTF_USESHOWWINDOW;
1978 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
1979 (void) CopyMagickString(local_command,command,MaxTextExtent);
1980 background_process=command[strlen(command)-1] == '&' ? MagickTrue :
1981 MagickFalse;
1982 if (background_process)
1983 local_command[strlen(command)-1]='\0';
1984 if (command[strlen(command)-1] == '|')
1985 local_command[strlen(command)-1]='\0';
1986 else
1987 startup_info.wShowWindow=SW_SHOWDEFAULT;
1988 status=CreateProcess((LPCTSTR) NULL,local_command,
1989 (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,
1990 (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
1991 &process_info);
1992 if (status == 0)
1993 return(-1);
1994 if (background_process)
1995 return(status == 0);
1996 status=WaitForSingleObject(process_info.hProcess,INFINITE);
1997 if (status != WAIT_OBJECT_0)
1998 return(status);
1999 status=GetExitCodeProcess(process_info.hProcess,&child_status);
2000 if (status == 0)
2001 return(-1);
2002 CloseHandle(process_info.hProcess);
2003 CloseHandle(process_info.hThread);
2004 return((int) child_status);
2005}
2006
2007/*
2008%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2009% %
2010% %
2011% %
2012% N T S y s t e m C o n i f i g u r a t i o n %
2013% %
2014% %
2015% %
2016%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2017%
2018% NTSystemConfiguration() provides a way for the application to determine
2019% values for system limits or options at runtime.
2020%
2021% The format of the exit method is:
2022%
cristybb503372010-05-27 20:51:26 +00002023% ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002024%
2025% A description of each parameter follows:
2026%
2027% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
2028%
2029*/
cristyf7836bf2012-02-20 16:32:47 +00002030MagickExport ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002031{
2032 switch (name)
2033 {
2034 case _SC_PAGESIZE:
2035 {
2036 SYSTEM_INFO
2037 system_info;
2038
2039 GetSystemInfo(&system_info);
2040 return(system_info.dwPageSize);
2041 }
2042 case _SC_PHYS_PAGES:
2043 {
2044 HMODULE
2045 handle;
2046
2047 LPFNDLLFUNC2
2048 module;
2049
2050 NTMEMORYSTATUSEX
2051 status;
2052
2053 SYSTEM_INFO
2054 system_info;
2055
2056 handle=GetModuleHandle("kernel32.dll");
2057 if (handle == (HMODULE) NULL)
2058 return(0L);
2059 GetSystemInfo(&system_info);
2060 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
2061 if (module == (LPFNDLLFUNC2) NULL)
2062 {
2063 MEMORYSTATUS
2064 status;
2065
2066 GlobalMemoryStatus(&status);
cristybb503372010-05-27 20:51:26 +00002067 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002068 }
2069 status.dwLength=sizeof(status);
2070 if (module(&status) == 0)
2071 return(0L);
cristybb503372010-05-27 20:51:26 +00002072 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002073 }
2074 case _SC_OPEN_MAX:
2075 return(2048);
2076 default:
2077 break;
2078 }
2079 return(-1);
2080}
2081
2082/*
2083%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2084% %
2085% %
2086% %
2087% N T T e l l D i r e c t o r y %
2088% %
2089% %
2090% %
2091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2092%
2093% NTTellDirectory() returns the current location associated with the named
2094% directory stream.
2095%
2096% The format of the NTTellDirectory method is:
2097%
cristybb503372010-05-27 20:51:26 +00002098% ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002099%
2100% A description of each parameter follows:
2101%
2102% o entry: Specifies a pointer to a DIR structure.
2103%
2104*/
cristyf7836bf2012-02-20 16:32:47 +00002105MagickExport ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002106{
2107 assert(entry != (DIR *) NULL);
2108 return(0);
2109}
2110
2111/*
2112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2113% %
2114% %
2115% %
2116% N T T r u n c a t e F i l e %
2117% %
2118% %
2119% %
2120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121%
2122% NTTruncateFile() truncates a file to a specified length.
2123%
2124% The format of the NTTruncateFile method is:
2125%
2126% int NTTruncateFile(int file,off_t length)
2127%
2128% A description of each parameter follows:
2129%
2130% o file: the file.
2131%
2132% o length: the file length.
2133%
2134*/
cristyf7836bf2012-02-20 16:32:47 +00002135MagickExport int NTTruncateFile(int file,off_t length)
cristy3ed852e2009-09-05 21:47:34 +00002136{
2137 DWORD
2138 file_pointer;
2139
cristyfeb262e2010-06-04 22:57:35 +00002140 long
cristy3ed852e2009-09-05 21:47:34 +00002141 file_handle,
2142 high,
2143 low;
2144
2145 file_handle=_get_osfhandle(file);
2146 if (file_handle == -1L)
2147 return(-1);
cristyfeb262e2010-06-04 22:57:35 +00002148 low=(long) (length & 0xffffffffUL);
2149 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
cristy3ed852e2009-09-05 21:47:34 +00002150 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2151 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2152 return(-1);
2153 if (SetEndOfFile((HANDLE) file_handle) == 0)
2154 return(-1);
2155 return(0);
2156}
2157
2158/*
2159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2160% %
2161% %
2162% %
2163+ N T U n m a p M e m o r y %
2164% %
2165% %
2166% %
2167%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168%
2169% NTUnmapMemory() emulates the Unix munmap method.
2170%
2171% The format of the NTUnmapMemory method is:
2172%
2173% int NTUnmapMemory(void *map,size_t length)
2174%
2175% A description of each parameter follows:
2176%
2177% o map: the address of the binary large object.
2178%
2179% o length: the length of the binary large object.
2180%
2181*/
cristyf7836bf2012-02-20 16:32:47 +00002182MagickExport int NTUnmapMemory(void *map,size_t length)
cristy3ed852e2009-09-05 21:47:34 +00002183{
cristy3b743bb2009-09-14 16:07:59 +00002184 (void) length;
cristy3ed852e2009-09-05 21:47:34 +00002185 if (UnmapViewOfFile(map) == 0)
2186 return(-1);
2187 return(0);
2188}
2189
2190/*
2191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2192% %
2193% %
2194% %
2195% N T U s e r T i m e %
2196% %
2197% %
2198% %
2199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2200%
2201% NTUserTime() returns the total time the process has been scheduled (e.g.
2202% seconds) since the last call to StartTimer().
2203%
2204% The format of the UserTime method is:
2205%
2206% double NTUserTime(void)
2207%
2208*/
cristyf7836bf2012-02-20 16:32:47 +00002209MagickExport double NTUserTime(void)
cristy3ed852e2009-09-05 21:47:34 +00002210{
2211 DWORD
2212 status;
2213
2214 FILETIME
2215 create_time,
2216 exit_time;
2217
2218 OSVERSIONINFO
2219 OsVersionInfo;
2220
2221 union
2222 {
2223 FILETIME
2224 filetime;
2225
2226 __int64
2227 filetime64;
2228 } kernel_time;
2229
2230 union
2231 {
2232 FILETIME
2233 filetime;
2234
2235 __int64
2236 filetime64;
2237 } user_time;
2238
2239 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2240 GetVersionEx(&OsVersionInfo);
2241 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2242 return(NTElapsedTime());
2243 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2244 &kernel_time.filetime,&user_time.filetime);
2245 if (status != TRUE)
2246 return(0.0);
2247 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2248}
2249
2250/*
2251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2252% %
2253% %
2254% %
2255% N T W a r n i n g H a n d l e r %
2256% %
2257% %
2258% %
2259%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2260%
2261% NTWarningHandler() displays a warning reason.
2262%
2263% The format of the NTWarningHandler method is:
2264%
cristy3b743bb2009-09-14 16:07:59 +00002265% void NTWarningHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +00002266% const char *description)
2267%
2268% A description of each parameter follows:
2269%
cristy3b743bb2009-09-14 16:07:59 +00002270% o severity: Specifies the numeric warning category.
cristy3ed852e2009-09-05 21:47:34 +00002271%
2272% o reason: Specifies the reason to display before terminating the
2273% program.
2274%
2275% o description: Specifies any description to the reason.
2276%
2277*/
cristy417d8452011-10-13 17:09:49 +00002278MagickExport void NTWarningHandler(const ExceptionType severity,
cristy3ed852e2009-09-05 21:47:34 +00002279 const char *reason,const char *description)
2280{
2281 char
2282 buffer[2*MaxTextExtent];
2283
cristy3b743bb2009-09-14 16:07:59 +00002284 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +00002285 if (reason == (char *) NULL)
2286 return;
2287 if (description == (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00002288 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
cristy3ed852e2009-09-05 21:47:34 +00002289 reason);
2290 else
cristyb51dff52011-05-19 16:55:47 +00002291 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +00002292 GetClientName(),reason,description);
2293 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2294 MB_SETFOREGROUND | MB_ICONINFORMATION);
2295}
2296#endif