blob: ec38b6493f24ef7f6efe0028b6e915449cc9a0bb [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"
50#include "MagickCore/timer.h"
51#include "MagickCore/string_.h"
52#include "MagickCore/utility.h"
53#include "MagickCore/version.h"
cristy3ed852e2009-09-05 21:47:34 +000054#if defined(MAGICKCORE_LTDL_DELEGATE)
55# include "ltdl.h"
56#endif
cristy309042f2012-02-20 18:59:35 +000057#include "MagickCore/nt-base.h"
cristy3ed852e2009-09-05 21:47:34 +000058#if defined(MAGICKCORE_CIPHER_SUPPORT)
59#include <ntsecapi.h>
60#include <wincrypt.h>
61#endif
62
63/*
64 Define declarations.
65*/
66#if !defined(MAP_FAILED)
67#define MAP_FAILED ((void *) -1)
68#endif
69
70/*
71 Static declarations.
72*/
73#if !defined(MAGICKCORE_LTDL_DELEGATE)
74static char
75 *lt_slsearchpath = (char *) NULL;
76#endif
77
cristydefb3f02009-09-10 02:18:35 +000078static GhostInfo
79 ghost_info;
cristy3ed852e2009-09-05 21:47:34 +000080
81static void
cristydefb3f02009-09-10 02:18:35 +000082 *ghost_handle = (void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +000083
84/*
85 External declarations.
86*/
cristy0157aea2010-04-24 21:12:18 +000087#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000088extern "C" BOOL WINAPI
89 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
90#endif
91
92/*
93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94% %
95% %
96% %
97% D l l M a i n %
98% %
99% %
100% %
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102%
103% DllMain() is an entry point to the DLL which is called when processes and
104% threads are initialized and terminated, or upon calls to the Windows
105% LoadLibrary and FreeLibrary functions.
106%
107% The function returns TRUE of it succeeds, or FALSE if initialization fails.
108%
109% The format of the DllMain method is:
110%
111% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
112%
113% A description of each parameter follows:
114%
115% o handle: handle to the DLL module
116%
117% o reason: reason for calling function:
118%
119% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
120% space of current process.
121% DLL_THREAD_ATTACH - Indicates that the current process is
122% creating a new thread. Called under the
123% context of the new thread.
124% DLL_THREAD_DETACH - Indicates that the thread is exiting.
125% Called under the context of the exiting
126% thread.
127% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
128% from the virtual address space of the
129% current process.
130%
131% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
132% and DLL_PROCESS_DETACH.
133%
134*/
135#if defined(_DLL) && defined( ProvideDllMain )
136BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
137{
138 switch (reason)
139 {
140 case DLL_PROCESS_ATTACH:
141 {
142 char
143 *module_path;
144
145 ssize_t
146 count;
147
148 module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
149 sizeof(*module_path));
150 if (module_path == (char *) NULL)
151 return(FALSE);
152 count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
153 if (count != 0)
154 {
155 char
156 *path;
157
158 for ( ; count > 0; count--)
159 if (module_path[count] == '\\')
160 {
161 module_path[count+1]='\0';
162 break;
163 }
164 MagickCoreGenesis(module_path,MagickFalse);
165 path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
166 if (path == (char *) NULL)
167 {
168 module_path=DestroyString(module_path);
169 return(FALSE);
170 }
171 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
172 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
173 {
174 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
175 {
176 char
177 *variable;
178
179 variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
180 sizeof(*variable));
181 if (variable == (char *) NULL)
182 {
183 path=DestroyString(path);
184 module_path=DestroyString(module_path);
185 return(FALSE);
186 }
cristyb51dff52011-05-19 16:55:47 +0000187 (void) FormatLocaleString(variable,16*MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000188 "%s;%s",module_path,path);
189 SetEnvironmentVariable("PATH",variable);
190 variable=DestroyString(variable);
191 }
192 }
193 path=DestroyString(path);
194 }
195 module_path=DestroyString(module_path);
196 break;
197 }
198 case DLL_PROCESS_DETACH:
199 {
200 MagickCoreTerminus();
201 break;
202 }
203 default:
204 break;
205 }
206 return(TRUE);
207}
208#endif
209
210/*
211%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
212% %
213% %
214% %
215% E x i t %
216% %
217% %
218% %
219%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220%
221% Exit() calls TerminateProcess for Win95.
222%
223% The format of the exit method is:
224%
225% int Exit(int status)
226%
227% A description of each parameter follows:
228%
229% o status: an integer value representing the status of the terminating
230% process.
231%
232*/
cristyf7836bf2012-02-20 16:32:47 +0000233MagickExport int Exit(int status)
cristy3ed852e2009-09-05 21:47:34 +0000234{
235 if (IsWindows95())
236 TerminateProcess(GetCurrentProcess(),(unsigned int) status);
237 exit(status);
238 return(0);
239}
240
cristy0157aea2010-04-24 21:12:18 +0000241#if !defined(__MINGW32__)
cristy3ed852e2009-09-05 21:47:34 +0000242/*
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244% %
245% %
246% %
cristy6d71f8d2010-02-28 00:46:02 +0000247% g e t t i m e o f d a y %
248% %
249% %
250% %
251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252%
253% The gettimeofday() method get the time of day.
254%
255% The format of the gettimeofday method is:
256%
257% int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
258%
259% A description of each parameter follows:
260%
261% o time_value: the time value.
262%
263% o time_zone: the time zone.
264%
265*/
cristyf7836bf2012-02-20 16:32:47 +0000266MagickExport int gettimeofday (struct timeval *time_value,
cristy6d71f8d2010-02-28 00:46:02 +0000267 struct timezone *time_zone)
268{
cristyc05bf172010-06-04 19:53:53 +0000269#define EpochFiletime MagickLLConstant(116444736000000000)
cristy6d71f8d2010-02-28 00:46:02 +0000270
271 static int
272 is_tz_set;
273
274 if (time_value != (struct timeval *) NULL)
275 {
276 FILETIME
277 file_time;
278
279 __int64
280 time;
281
282 LARGE_INTEGER
283 date_time;
284
285 GetSystemTimeAsFileTime(&file_time);
286 date_time.LowPart=file_time.dwLowDateTime;
287 date_time.HighPart=file_time.dwHighDateTime;
288 time=date_time.QuadPart;
cristy99881662010-03-04 14:25:26 +0000289 time-=EpochFiletime;
cristy6d71f8d2010-02-28 00:46:02 +0000290 time/=10;
cristybb503372010-05-27 20:51:26 +0000291 time_value->tv_sec=(ssize_t) (time / 1000000);
292 time_value->tv_usec=(ssize_t) (time % 1000000);
cristy6d71f8d2010-02-28 00:46:02 +0000293 }
294 if (time_zone != (struct timezone *) NULL)
295 {
296 if (is_tz_set == 0)
297 {
298 _tzset();
299 is_tz_set++;
300 }
301 time_zone->tz_minuteswest=_timezone/60;
302 time_zone->tz_dsttime=_daylight;
303 }
304 return(0);
305}
cristy807fd932010-04-24 03:38:46 +0000306#endif
cristy6d71f8d2010-02-28 00:46:02 +0000307
308/*
309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310% %
311% %
312% %
cristy3ed852e2009-09-05 21:47:34 +0000313% I s W i n d o w s 9 5 %
314% %
315% %
316% %
317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318%
319% IsWindows95() returns true if the system is Windows 95.
320%
321% The format of the IsWindows95 method is:
322%
323% int IsWindows95()
324%
325*/
cristyf7836bf2012-02-20 16:32:47 +0000326MagickExport int IsWindows95()
cristy3ed852e2009-09-05 21:47:34 +0000327{
328 OSVERSIONINFO
329 version_info;
330
331 version_info.dwOSVersionInfoSize=sizeof(version_info);
332 if (GetVersionEx(&version_info) &&
333 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
334 return(1);
335 return(0);
336}
337
338/*
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340% %
341% %
342% %
cristy66f9c3c2011-08-13 17:12:28 +0000343% N T A r g v T o U T F 8 %
344% %
345% %
346% %
347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348%
349% NTArgvToUTF8() converts the wide command line arguments to UTF-8 to ensure
350% compatibility with Linux.
351%
352% The format of the NTArgvToUTF8 method is:
353%
354% char **NTArgvToUTF8(const int argc,wchar_t **argv)
355%
356% A description of each parameter follows:
357%
358% o argc: the number of command line arguments.
359%
360% o argv: the wide-character command line arguments.
361%
362*/
cristydaeba5e2011-10-13 17:32:44 +0000363MagickExport char **NTArgvToUTF8(const int argc,wchar_t **argv)
cristy66f9c3c2011-08-13 17:12:28 +0000364{
365 char
366 **utf8;
367
368 ssize_t
369 i;
370
371 utf8=(char **) AcquireQuantumMemory(argc,sizeof(*utf8));
372 if (utf8 == (char **) NULL)
373 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
374 for (i=0; i < (ssize_t) argc; i++)
375 {
376 ssize_t
377 count;
378
379 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,NULL,0,NULL,NULL);
380 if (count < 0)
381 count=0;
382 utf8[i]=(char *) AcquireQuantumMemory(count+1,sizeof(**utf8));
383 if (utf8[i] == (char *) NULL)
384 {
385 for (i--; i >= 0; i--)
386 utf8[i]=DestroyString(utf8[i]);
387 utf8=(char **) RelinquishMagickMemory(utf8);
388 ThrowFatalException(ResourceLimitFatalError,
389 "UnableToConvertStringToARGV");
390 }
391 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,utf8[i],count,NULL,NULL);
392 utf8[i][count]=0;
393 }
394 return(utf8);
395}
396
397/*
398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399% %
400% %
401% %
cristy3ed852e2009-09-05 21:47:34 +0000402% N T C l o s e D i r e c t o r y %
403% %
404% %
405% %
406%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407%
408% NTCloseDirectory() closes the named directory stream and frees the DIR
409% structure.
410%
411% The format of the NTCloseDirectory method is:
412%
413% int NTCloseDirectory(DIR *entry)
414%
415% A description of each parameter follows:
416%
417% o entry: Specifies a pointer to a DIR structure.
418%
419*/
cristyf7836bf2012-02-20 16:32:47 +0000420MagickExport int NTCloseDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +0000421{
422 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
423 assert(entry != (DIR *) NULL);
424 FindClose(entry->hSearch);
425 entry=(DIR *) RelinquishMagickMemory(entry);
426 return(0);
427}
428
429/*
430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431% %
432% %
433% %
434% N T C l o s e L i b r a r y %
435% %
436% %
437% %
438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439%
440% NTCloseLibrary() unloads the module associated with the passed handle.
441%
442% The format of the NTCloseLibrary method is:
443%
444% void NTCloseLibrary(void *handle)
445%
446% A description of each parameter follows:
447%
448% o handle: Specifies a handle to a previously loaded dynamic module.
449%
450*/
cristyf7836bf2012-02-20 16:32:47 +0000451MagickExport int NTCloseLibrary(void *handle)
cristy3ed852e2009-09-05 21:47:34 +0000452{
453 if (IsWindows95())
454 return(FreeLibrary((HINSTANCE) handle));
455 return(!(FreeLibrary((HINSTANCE) handle)));
456}
457
458/*
459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460% %
461% %
462% %
463% N T C o n t r o l H a n d l e r %
464% %
465% %
466% %
467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468%
469% NTControlHandler() registers a control handler that is activated when, for
470% example, a ctrl-c is received.
471%
472% The format of the NTControlHandler method is:
473%
474% int NTControlHandler(void)
475%
476*/
477
478static BOOL ControlHandler(DWORD type)
479{
cristy3b743bb2009-09-14 16:07:59 +0000480 (void) type;
cristyf34a1452009-10-24 22:29:27 +0000481 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +0000482 return(FALSE);
483}
484
cristyf7836bf2012-02-20 16:32:47 +0000485MagickExport int NTControlHandler(void)
cristy3ed852e2009-09-05 21:47:34 +0000486{
487 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
488}
489
490/*
491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
492% %
493% %
494% %
495% N T E l a p s e d T i m e %
496% %
497% %
498% %
499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
500%
501% NTElapsedTime() returns the elapsed time (in seconds) since the last call to
502% StartTimer().
503%
504% The format of the ElapsedTime method is:
505%
506% double NTElapsedTime(void)
507%
508*/
cristyf7836bf2012-02-20 16:32:47 +0000509MagickExport double NTElapsedTime(void)
cristy3ed852e2009-09-05 21:47:34 +0000510{
511 union
512 {
513 FILETIME
514 filetime;
515
516 __int64
517 filetime64;
518 } elapsed_time;
519
520 SYSTEMTIME
521 system_time;
522
523 GetSystemTime(&system_time);
524 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
525 return((double) 1.0e-7*elapsed_time.filetime64);
526}
527
528/*
529%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
530% %
531% %
532% %
533+ N T E r r o r H a n d l e r %
534% %
535% %
536% %
537%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
538%
539% NTErrorHandler() displays an error reason and then terminates the program.
540%
541% The format of the NTErrorHandler method is:
542%
cristy3b743bb2009-09-14 16:07:59 +0000543% void NTErrorHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +0000544% const char *description)
545%
546% A description of each parameter follows:
547%
cristy3b743bb2009-09-14 16:07:59 +0000548% o severity: Specifies the numeric error category.
cristy3ed852e2009-09-05 21:47:34 +0000549%
550% o reason: Specifies the reason to display before terminating the
551% program.
552%
553% o description: Specifies any description to the reason.
554%
555*/
cristy417d8452011-10-13 17:09:49 +0000556MagickExport void NTErrorHandler(const ExceptionType severity,
cristy3b743bb2009-09-14 16:07:59 +0000557 const char *reason,const char *description)
cristy3ed852e2009-09-05 21:47:34 +0000558{
559 char
560 buffer[3*MaxTextExtent],
561 *message;
562
cristy3b743bb2009-09-14 16:07:59 +0000563 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +0000564 if (reason == (char *) NULL)
565 {
566 MagickCoreTerminus();
567 exit(0);
568 }
569 message=GetExceptionMessage(errno);
570 if ((description != (char *) NULL) && errno)
cristyb51dff52011-05-19 16:55:47 +0000571 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000572 GetClientName(),reason,description,message);
573 else
574 if (description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000575 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +0000576 GetClientName(),reason,description);
577 else
578 if (errno != 0)
cristyb51dff52011-05-19 16:55:47 +0000579 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000580 GetClientName(),reason,message);
581 else
cristyb51dff52011-05-19 16:55:47 +0000582 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",
cristy3ed852e2009-09-05 21:47:34 +0000583 GetClientName(),reason);
584 message=DestroyString(message);
585 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
586 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
587 MagickCoreTerminus();
588 exit(0);
589}
590
591/*
592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593% %
594% %
595% %
596% N T E x i t L i b r a r y %
597% %
598% %
599% %
600%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601%
602% NTExitLibrary() exits the dynamic module loading subsystem.
603%
604% The format of the NTExitLibrary method is:
605%
606% int NTExitLibrary(void)
607%
608*/
cristyf7836bf2012-02-20 16:32:47 +0000609MagickExport int NTExitLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +0000610{
611 return(0);
612}
613
614/*
615%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616% %
617% %
618% %
619% N T G a t h e r R a n d o m D a t a %
620% %
621% %
622% %
623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624%
625% NTGatherRandomData() gathers random data and returns it.
626%
627% The format of the GatherRandomData method is:
628%
629% MagickBooleanType NTGatherRandomData(const size_t length,
630% unsigned char *random)
631%
632% A description of each parameter follows:
633%
634% length: the length of random data buffer
635%
636% random: the random data is returned here.
637%
638*/
cristyf7836bf2012-02-20 16:32:47 +0000639MagickExport MagickBooleanType NTGatherRandomData(const size_t length,
cristy3ed852e2009-09-05 21:47:34 +0000640 unsigned char *random)
641{
642#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
643 HCRYPTPROV
644 handle;
645
646 int
647 status;
648
649 handle=(HCRYPTPROV) NULL;
650 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
651 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
652 if (status == 0)
653 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
654 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
655 if (status == 0)
656 return(MagickFalse);
657 status=CryptGenRandom(handle,(DWORD) length,random);
658 if (status == 0)
659 {
660 status=CryptReleaseContext(handle,0);
661 return(MagickFalse);
662 }
663 status=CryptReleaseContext(handle,0);
664 if (status == 0)
665 return(MagickFalse);
cristy3b743bb2009-09-14 16:07:59 +0000666#else
667 (void) random;
668 (void) length;
cristy3ed852e2009-09-05 21:47:34 +0000669#endif
670 return(MagickTrue);
671}
672
673/*
674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
675% %
676% %
677% %
678% N T G e t E x e c u t i o n P a t h %
679% %
680% %
681% %
682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683%
684% NTGetExecutionPath() returns the execution path of a program.
685%
686% The format of the GetExecutionPath method is:
687%
688% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
689%
690% A description of each parameter follows:
691%
692% o path: the pathname of the executable that started the process.
693%
694% o extent: the maximum extent of the path.
695%
696*/
cristyf7836bf2012-02-20 16:32:47 +0000697MagickExport MagickBooleanType NTGetExecutionPath(char *path,
cristy3ed852e2009-09-05 21:47:34 +0000698 const size_t extent)
699{
700 GetModuleFileName(0,path,(DWORD) extent);
701 return(MagickTrue);
702}
703
704/*
705%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706% %
707% %
708% %
709% N T G e t L a s t E r r o r %
710% %
711% %
712% %
713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714%
715% NTGetLastError() returns the last error that occurred.
716%
717% The format of the NTGetLastError method is:
718%
719% char *NTGetLastError(void)
720%
721*/
cristyf7836bf2012-02-20 16:32:47 +0000722char *NTGetLastError(void)
cristy3ed852e2009-09-05 21:47:34 +0000723{
724 char
725 *reason;
726
727 int
728 status;
729
730 LPVOID
731 buffer;
732
733 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
734 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
735 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
736 if (!status)
737 reason=AcquireString("An unknown error occurred");
738 else
739 {
740 reason=AcquireString((const char *) buffer);
741 LocalFree(buffer);
742 }
743 return(reason);
744}
745
746/*
747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
748% %
749% %
750% %
751% N T G e t L i b r a r y E r r o r %
752% %
753% %
754% %
755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
756%
757% Lt_dlerror() returns a pointer to a string describing the last error
758% associated with a lt_dl method. Note that this function is not thread
759% safe so it should only be used under the protection of a lock.
760%
761% The format of the NTGetLibraryError method is:
762%
763% const char *NTGetLibraryError(void)
764%
765*/
cristyf7836bf2012-02-20 16:32:47 +0000766MagickExport const char *NTGetLibraryError(void)
cristy3ed852e2009-09-05 21:47:34 +0000767{
768 static char
769 last_error[MaxTextExtent];
770
771 char
772 *error;
773
774 *last_error='\0';
775 error=NTGetLastError();
776 if (error)
777 (void) CopyMagickString(last_error,error,MaxTextExtent);
778 error=DestroyString(error);
779 return(last_error);
780}
781
782/*
783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784% %
785% %
786% %
787% N T G e t L i b r a r y S y m b o l %
788% %
789% %
790% %
791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792%
793% NTGetLibrarySymbol() retrieve the procedure address of the method
794% specified by the passed character string.
795%
796% The format of the NTGetLibrarySymbol method is:
797%
798% void *NTGetLibrarySymbol(void *handle,const char *name)
799%
800% A description of each parameter follows:
801%
802% o handle: Specifies a handle to the previously loaded dynamic module.
803%
804% o name: Specifies the procedure entry point to be returned.
805%
806*/
807void *NTGetLibrarySymbol(void *handle,const char *name)
808{
809 LPFNDLLFUNC1
810 lpfnDllFunc1;
811
812 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
813 if (!lpfnDllFunc1)
814 return((void *) NULL);
815 return((void *) lpfnDllFunc1);
816}
817
818/*
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820% %
821% %
822% %
823% N T G e t M o d u l e P a t h %
824% %
825% %
826% %
827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828%
829% NTGetModulePath() returns the path of the specified module.
830%
831% The format of the GetModulePath method is:
832%
833% MagickBooleanType NTGetModulePath(const char *module,char *path)
834%
835% A description of each parameter follows:
836%
837% modith: the module name.
838%
839% path: the module path is returned here.
840%
841*/
cristyf7836bf2012-02-20 16:32:47 +0000842MagickExport MagickBooleanType NTGetModulePath(const char *module,char *path)
cristy3ed852e2009-09-05 21:47:34 +0000843{
844 char
845 module_path[MaxTextExtent];
846
847 HMODULE
848 handle;
849
cristybb503372010-05-27 20:51:26 +0000850 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000851 length;
852
853 *path='\0';
854 handle=GetModuleHandle(module);
855 if (handle == (HMODULE) NULL)
856 return(MagickFalse);
857 length=GetModuleFileName(handle,module_path,MaxTextExtent);
858 if (length != 0)
859 GetPathComponent(module_path,HeadPath,path);
860 return(MagickTrue);
861}
862
863/*
864%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865% %
866% %
867% %
868% N T G h o s t s c r i p t D L L %
869% %
870% %
871% %
872%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
873%
cristydefb3f02009-09-10 02:18:35 +0000874% NTGhostscriptDLL() returns the path to the most recent Ghostscript version
875% DLL. The method returns TRUE on success otherwise FALSE.
cristy3ed852e2009-09-05 21:47:34 +0000876%
877% The format of the NTGhostscriptDLL method is:
878%
cristyfc0f64b2009-09-09 18:57:08 +0000879% int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +0000880%
881% A description of each parameter follows:
882%
cristyfc0f64b2009-09-09 18:57:08 +0000883% o path: return the Ghostscript DLL path here.
cristy3ed852e2009-09-05 21:47:34 +0000884%
cristyfc0f64b2009-09-09 18:57:08 +0000885% o length: the buffer length.
cristy3ed852e2009-09-05 21:47:34 +0000886%
887*/
888
cristyfc0f64b2009-09-09 18:57:08 +0000889static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
890 char *value,int *length)
cristy3ed852e2009-09-05 21:47:34 +0000891{
cristyfc0f64b2009-09-09 18:57:08 +0000892 BYTE
893 byte,
cristy3ed852e2009-09-05 21:47:34 +0000894 *p;
895
cristyfc0f64b2009-09-09 18:57:08 +0000896 DWORD
897 extent,
898 type;
cristy3ed852e2009-09-05 21:47:34 +0000899
cristy3ed852e2009-09-05 21:47:34 +0000900 HKEY
901 hkey;
902
cristy3ed852e2009-09-05 21:47:34 +0000903 LONG
cristyfc0f64b2009-09-09 18:57:08 +0000904 status;
cristy3ed852e2009-09-05 21:47:34 +0000905
cristyfc0f64b2009-09-09 18:57:08 +0000906 /*
cristydefb3f02009-09-10 02:18:35 +0000907 Get a registry value: key = root\\key, named value = name.
908 */
cristyfc0f64b2009-09-09 18:57:08 +0000909 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
910 return(1); /* no match */
911 p=(BYTE *) value;
912 type=REG_SZ;
913 extent=(*length);
914 if (p == (BYTE *) NULL)
cristydefb3f02009-09-10 02:18:35 +0000915 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
cristyfc0f64b2009-09-09 18:57:08 +0000916 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
917 RegCloseKey(hkey);
918 if (status == ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +0000919 {
cristyfc0f64b2009-09-09 18:57:08 +0000920 *length=extent;
921 return(0); /* return the match */
922 }
923 if (status == ERROR_MORE_DATA)
924 {
925 *length=extent;
cristydefb3f02009-09-10 02:18:35 +0000926 return(-1); /* buffer not large enough */
cristy3ed852e2009-09-05 21:47:34 +0000927 }
928 return(1); /* not found */
929}
930
cristydefb3f02009-09-10 02:18:35 +0000931static int NTLocateGhostscript(const char **product_family,int *major_version,
cristyfc0f64b2009-09-09 18:57:08 +0000932 int *minor_version)
cristy3ed852e2009-09-05 21:47:34 +0000933{
cristyfc0f64b2009-09-09 18:57:08 +0000934 int
935 i;
cristy3ed852e2009-09-05 21:47:34 +0000936
cristyfc0f64b2009-09-09 18:57:08 +0000937 MagickBooleanType
938 status;
939
940 static const char
941 *products[4] =
942 {
943 "GPL Ghostscript",
944 "GNU Ghostscript",
945 "AFPL Ghostscript",
cristy82b15832009-10-06 19:17:37 +0000946 "Aladdin Ghostscript"
cristyfc0f64b2009-09-09 18:57:08 +0000947 };
948
949 /*
950 Find the most recent version of Ghostscript.
951 */
952 status=FALSE;
953 *product_family=NULL;
954 *major_version=5;
955 *minor_version=49; /* min version of Ghostscript is 5.50 */
cristybb503372010-05-27 20:51:26 +0000956 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +0000957 {
958 char
959 key[MaxTextExtent];
960
961 HKEY
962 hkey,
963 root;
964
cristye66bcb42009-09-17 13:31:08 +0000965 REGSAM
966 mode;
967
cristyb51dff52011-05-19 16:55:47 +0000968 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
cristyfc0f64b2009-09-09 18:57:08 +0000969 root=HKEY_LOCAL_MACHINE;
cristye66bcb42009-09-17 13:31:08 +0000970 mode=KEY_READ;
cristye66bcb42009-09-17 13:31:08 +0000971 if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
cristyfc0f64b2009-09-09 18:57:08 +0000972 {
973 DWORD
974 extent;
975
976 int
977 j;
978
979 /*
980 Now enumerate the keys.
981 */
982 extent=sizeof(key)/sizeof(char);
983 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
984 {
985 int
986 major,
987 minor;
988
989 major=0;
990 minor=0;
991 if (sscanf(key,"%d.%d",&major,&minor) != 2)
992 continue;
993 if ((major > *major_version) || ((major == *major_version) &&
994 (minor > *minor_version)))
995 {
996 *product_family=products[i];
997 *major_version=major;
998 *minor_version=minor;
cristy37f63772009-11-16 17:06:36 +0000999 status=TRUE;
cristyfc0f64b2009-09-09 18:57:08 +00001000 }
cristyfc0f64b2009-09-09 18:57:08 +00001001 }
cristye66bcb42009-09-17 13:31:08 +00001002 (void) RegCloseKey(hkey);
1003 }
1004 }
cristy37f63772009-11-16 17:06:36 +00001005 if (status == FALSE)
cristyfc0f64b2009-09-09 18:57:08 +00001006 {
1007 *major_version=0;
1008 *minor_version=0;
1009 }
1010 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
1011 "version %d.%02d",*product_family,*major_version,*minor_version);
1012 return(status);
1013}
1014
1015static int NTGhostscriptGetString(const char *name,char *value,
1016 const size_t length)
1017{
cristy3ed852e2009-09-05 21:47:34 +00001018 char
cristy3ed852e2009-09-05 21:47:34 +00001019 key[MaxTextExtent];
1020
1021 int
cristyfc0f64b2009-09-09 18:57:08 +00001022 i,
1023 extent;
cristy82b15832009-10-06 19:17:37 +00001024
cristyfc0f64b2009-09-09 18:57:08 +00001025 static const char
cristydefb3f02009-09-10 02:18:35 +00001026 *product_family = (const char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001027
cristyfc0f64b2009-09-09 18:57:08 +00001028 static int
1029 major_version=0,
1030 minor_version=0;
cristy3ed852e2009-09-05 21:47:34 +00001031
cristyfc0f64b2009-09-09 18:57:08 +00001032 struct
1033 {
1034 const HKEY
1035 hkey;
cristy3ed852e2009-09-05 21:47:34 +00001036
cristyfc0f64b2009-09-09 18:57:08 +00001037 const char
1038 *name;
1039 }
1040 hkeys[2] =
1041 {
1042 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
1043 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
1044 };
1045
1046 /*
1047 Get a string from the installed Ghostscript.
1048 */
cristydefb3f02009-09-10 02:18:35 +00001049 *value='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001050 if (product_family == NULL)
cristydefb3f02009-09-10 02:18:35 +00001051 (void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
cristyfc0f64b2009-09-09 18:57:08 +00001052 if (product_family == NULL)
1053 return(FALSE);
cristyb51dff52011-05-19 16:55:47 +00001054 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
cristyfc0f64b2009-09-09 18:57:08 +00001055 product_family,major_version,minor_version);
cristybb503372010-05-27 20:51:26 +00001056 for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +00001057 {
cristy76319442009-09-22 02:04:05 +00001058 extent=(int) length;
cristyfc0f64b2009-09-09 18:57:08 +00001059 if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
1060 {
1061 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1062 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
1063 return(TRUE);
1064 }
1065 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1066 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
1067 }
cristy3ed852e2009-09-05 21:47:34 +00001068 return(FALSE);
1069}
1070
cristyf7836bf2012-02-20 16:32:47 +00001071MagickExport int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001072{
cristy4c11ed82009-09-11 03:36:46 +00001073 static char
1074 dll[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001075
1076 *path='\0';
cristy4c11ed82009-09-11 03:36:46 +00001077 if ((*dll == '\0') &&
1078 (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
cristy106919c2009-09-11 03:46:56 +00001079 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001080 (void) CopyMagickString(path,dll,length);
cristy3ed852e2009-09-05 21:47:34 +00001081 return(TRUE);
1082}
1083
1084/*
1085%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086% %
1087% %
1088% %
1089% N T G h o s t s c r i p t D L L V e c t o r s %
1090% %
1091% %
1092% %
1093%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1094%
cristydefb3f02009-09-10 02:18:35 +00001095% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
1096% function vectors to invoke Ghostscript DLL functions. A null pointer is
1097% returned if there is an error when loading the DLL or retrieving the
1098% function vectors.
cristy3ed852e2009-09-05 21:47:34 +00001099%
1100% The format of the NTGhostscriptDLLVectors method is:
1101%
cristydefb3f02009-09-10 02:18:35 +00001102% const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001103%
1104*/
cristydaeba5e2011-10-13 17:32:44 +00001105MagickExport const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +00001106{
cristyfc0f64b2009-09-09 18:57:08 +00001107 if (NTGhostscriptLoadDLL() == FALSE)
cristydefb3f02009-09-10 02:18:35 +00001108 return((GhostInfo *) NULL);
1109 return(&ghost_info);
cristy3ed852e2009-09-05 21:47:34 +00001110}
1111
1112/*
1113%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114% %
1115% %
1116% %
1117% N T G h o s t s c r i p t E X E %
1118% %
1119% %
1120% %
1121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1122%
1123% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
cristyfc0f64b2009-09-09 18:57:08 +00001124% The method returns FALSE if a full path value is not obtained and returns
1125% a default path of gswin32c.exe.
cristy3ed852e2009-09-05 21:47:34 +00001126%
1127% The format of the NTGhostscriptEXE method is:
1128%
cristyfc0f64b2009-09-09 18:57:08 +00001129% int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001130%
1131% A description of each parameter follows:
1132%
cristyfc0f64b2009-09-09 18:57:08 +00001133% o path: return the Ghostscript executable path here.
cristy3ed852e2009-09-05 21:47:34 +00001134%
cristyb32b90a2009-09-07 21:45:48 +00001135% o length: length of buffer.
cristy3ed852e2009-09-05 21:47:34 +00001136%
1137*/
cristyf7836bf2012-02-20 16:32:47 +00001138MagickExport int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001139{
cristy4c11ed82009-09-11 03:36:46 +00001140 register char
cristy3ed852e2009-09-05 21:47:34 +00001141 *p;
1142
cristyfc0f64b2009-09-09 18:57:08 +00001143 static char
cristy4c11ed82009-09-11 03:36:46 +00001144 program[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001145
cristyb32b90a2009-09-07 21:45:48 +00001146 (void) CopyMagickString(path,"gswin32c.exe",length);
cristy4c11ed82009-09-11 03:36:46 +00001147 if ((*program == '\0') &&
1148 (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE))
cristyb32b90a2009-09-07 21:45:48 +00001149 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001150 p=strrchr(program,'\\');
cristy7ba1b042011-02-05 19:07:50 +00001151 if (p != (char *) NULL)
cristy4c11ed82009-09-11 03:36:46 +00001152 {
1153 p++;
1154 *p='\0';
1155 (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program));
1156 }
1157 (void) CopyMagickString(path,program,length);
cristyb32b90a2009-09-07 21:45:48 +00001158 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001159}
1160
1161/*
1162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1163% %
1164% %
1165% %
1166% N T G h o s t s c r i p t F o n t s %
1167% %
1168% %
1169% %
1170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1171%
cristyfc0f64b2009-09-09 18:57:08 +00001172% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1173% returns FALSE if it cannot determine the font path.
cristy3ed852e2009-09-05 21:47:34 +00001174%
1175% The format of the NTGhostscriptFonts method is:
1176%
cristyfc0f64b2009-09-09 18:57:08 +00001177% int NTGhostscriptFonts(char *path, int length)
cristy3ed852e2009-09-05 21:47:34 +00001178%
1179% A description of each parameter follows:
1180%
cristyfc0f64b2009-09-09 18:57:08 +00001181% o path: return the font path here.
cristy3ed852e2009-09-05 21:47:34 +00001182%
cristyfc0f64b2009-09-09 18:57:08 +00001183% o length: length of the path buffer.
cristy3ed852e2009-09-05 21:47:34 +00001184%
1185*/
cristyf7836bf2012-02-20 16:32:47 +00001186MagickExport int NTGhostscriptFonts(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +00001187{
1188 char
1189 buffer[MaxTextExtent],
1190 filename[MaxTextExtent];
1191
cristy3ed852e2009-09-05 21:47:34 +00001192 register char
1193 *p,
1194 *q;
1195
1196 *path='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001197 if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE)
cristy3ed852e2009-09-05 21:47:34 +00001198 return(FALSE);
1199 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1200 {
1201 (void) CopyMagickString(path,p+1,length+1);
1202 q=strchr(path,DirectoryListSeparator);
1203 if (q != (char *) NULL)
1204 *q='\0';
cristyb51dff52011-05-19 16:55:47 +00001205 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path,
cristy3ed852e2009-09-05 21:47:34 +00001206 DirectorySeparator);
1207 if (IsPathAccessible(filename) != MagickFalse)
1208 return(TRUE);
1209 }
1210 return(FALSE);
1211}
1212
1213/*
1214%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1215% %
1216% %
1217% %
1218% N T G h o s t s c r i p t L o a d D L L %
1219% %
1220% %
1221% %
1222%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1223%
1224% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
cristyfc0f64b2009-09-09 18:57:08 +00001225% TRUE if it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001226%
1227% The format of the NTGhostscriptLoadDLL method is:
1228%
1229% int NTGhostscriptLoadDLL(void)
1230%
1231*/
cristyf7836bf2012-02-20 16:32:47 +00001232MagickExport int NTGhostscriptLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001233{
1234 char
cristyfc0f64b2009-09-09 18:57:08 +00001235 path[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001236
cristydefb3f02009-09-10 02:18:35 +00001237 if (ghost_handle != (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001238 return(TRUE);
1239 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1240 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001241 ghost_handle=lt_dlopen(path);
1242 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001243 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001244 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1245 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1246 lt_dlsym(ghost_handle,"gsapi_exit");
1247 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1248 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1249 ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1250 lt_dlsym(ghost_handle,"gsapi_new_instance"));
1251 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1252 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1253 ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1254 lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1255 if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1256 (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1257 (ghost_info.delete_instance == NULL))
cristyfc0f64b2009-09-09 18:57:08 +00001258 return(FALSE);
1259 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001260}
1261
1262/*
1263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264% %
1265% %
1266% %
1267% N T G h o s t s c r i p t U n L o a d D L L %
1268% %
1269% %
1270% %
1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272%
cristyfc0f64b2009-09-09 18:57:08 +00001273% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1274% it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001275%
1276% The format of the NTGhostscriptUnLoadDLL method is:
1277%
1278% int NTGhostscriptUnLoadDLL(void)
1279%
1280*/
cristydaeba5e2011-10-13 17:32:44 +00001281MagickExport int NTGhostscriptUnLoadDLL(void)
cristy3ed852e2009-09-05 21:47:34 +00001282{
cristyfc0f64b2009-09-09 18:57:08 +00001283 int
1284 status;
1285
cristydefb3f02009-09-10 02:18:35 +00001286 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001287 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001288 status=lt_dlclose(ghost_handle);
1289 ghost_handle=(void *) NULL;
1290 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
cristyfc0f64b2009-09-09 18:57:08 +00001291 return(status);
cristy3ed852e2009-09-05 21:47:34 +00001292}
1293
1294/*
1295%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296% %
1297% %
1298% %
1299% N T I n i t i a l i z e L i b r a r y %
1300% %
1301% %
1302% %
1303%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1304%
1305% NTInitializeLibrary() initializes the dynamic module loading subsystem.
1306%
1307% The format of the NTInitializeLibrary method is:
1308%
1309% int NTInitializeLibrary(void)
1310%
1311*/
cristyf7836bf2012-02-20 16:32:47 +00001312MagickExport int NTInitializeLibrary(void)
cristy3ed852e2009-09-05 21:47:34 +00001313{
1314 return(0);
1315}
1316
1317/*
1318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319% %
1320% %
1321% %
1322+ N T M a p M e m o r y %
1323% %
1324% %
1325% %
1326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327%
1328% Mmap() emulates the Unix method of the same name.
1329%
1330% The format of the NTMapMemory method is:
1331%
cristyf7836bf2012-02-20 16:32:47 +00001332% MagickExport void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001333% int access,int file,MagickOffsetType offset)
1334%
1335*/
cristyf7836bf2012-02-20 16:32:47 +00001336MagickExport void *NTMapMemory(char *address,size_t length,int protection,
cristy3ed852e2009-09-05 21:47:34 +00001337 int flags,int file,MagickOffsetType offset)
1338{
1339 DWORD
1340 access_mode,
1341 high_length,
1342 high_offset,
1343 low_length,
1344 low_offset,
1345 protection_mode;
1346
1347 HANDLE
1348 file_handle,
1349 map_handle;
1350
1351 void
1352 *map;
1353
cristy3b743bb2009-09-14 16:07:59 +00001354 (void) address;
cristy3ed852e2009-09-05 21:47:34 +00001355 access_mode=0;
1356 file_handle=INVALID_HANDLE_VALUE;
1357 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1358 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1359 map_handle=INVALID_HANDLE_VALUE;
1360 map=(void *) NULL;
1361 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1362 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1363 protection_mode=0;
1364 if (protection & PROT_WRITE)
1365 {
1366 access_mode=FILE_MAP_WRITE;
1367 if (!(flags & MAP_PRIVATE))
1368 protection_mode=PAGE_READWRITE;
1369 else
1370 {
1371 access_mode=FILE_MAP_COPY;
1372 protection_mode=PAGE_WRITECOPY;
1373 }
1374 }
1375 else
1376 if (protection & PROT_READ)
1377 {
1378 access_mode=FILE_MAP_READ;
1379 protection_mode=PAGE_READONLY;
1380 }
1381 if ((file == -1) && (flags & MAP_ANONYMOUS))
1382 file_handle=INVALID_HANDLE_VALUE;
1383 else
1384 file_handle=(HANDLE) _get_osfhandle(file);
1385 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1386 low_length,0);
1387 if (map_handle)
1388 {
1389 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1390 length);
1391 CloseHandle(map_handle);
1392 }
1393 if (map == (void *) NULL)
1394 return((void *) MAP_FAILED);
1395 return((void *) ((char *) map));
1396}
1397
1398/*
1399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1400% %
1401% %
1402% %
1403% N T O p e n D i r e c t o r y %
1404% %
1405% %
1406% %
1407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1408%
1409% NTOpenDirectory() opens the directory named by filename and associates a
1410% directory stream with it.
1411%
1412% The format of the NTOpenDirectory method is:
1413%
1414% DIR *NTOpenDirectory(const char *path)
1415%
1416% A description of each parameter follows:
1417%
1418% o entry: Specifies a pointer to a DIR structure.
1419%
1420*/
cristyf7836bf2012-02-20 16:32:47 +00001421MagickExport DIR *NTOpenDirectory(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00001422{
1423 char
1424 file_specification[MaxTextExtent];
1425
1426 DIR
1427 *entry;
1428
1429 size_t
1430 length;
1431
1432 assert(path != (const char *) NULL);
1433 length=CopyMagickString(file_specification,path,MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001434 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001435 return((DIR *) NULL);
1436 length=ConcatenateMagickString(file_specification,DirectorySeparator,
1437 MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001438 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001439 return((DIR *) NULL);
cristy73bd4a52010-10-05 11:24:23 +00001440 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
cristy3ed852e2009-09-05 21:47:34 +00001441 if (entry != (DIR *) NULL)
1442 {
1443 entry->firsttime=TRUE;
1444 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1445 }
1446 if (entry->hSearch == INVALID_HANDLE_VALUE)
1447 {
1448 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001449 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001450 {
1451 entry=(DIR *) RelinquishMagickMemory(entry);
1452 return((DIR *) NULL);
1453 }
1454 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1455 if (entry->hSearch == INVALID_HANDLE_VALUE)
1456 {
1457 entry=(DIR *) RelinquishMagickMemory(entry);
1458 return((DIR *) NULL);
1459 }
1460 }
1461 return(entry);
1462}
1463
1464/*
1465%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1466% %
1467% %
1468% %
1469% N T O p e n L i b r a r y %
1470% %
1471% %
1472% %
1473%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1474%
1475% NTOpenLibrary() loads a dynamic module into memory and returns a handle that
1476% can be used to access the various procedures in the module.
1477%
1478% The format of the NTOpenLibrary method is:
1479%
1480% void *NTOpenLibrary(const char *filename)
1481%
1482% A description of each parameter follows:
1483%
1484% o path: Specifies a pointer to string representing dynamic module that
1485% is to be loaded.
1486%
1487*/
1488
1489static const char *GetSearchPath( void )
1490{
1491#if defined(MAGICKCORE_LTDL_DELEGATE)
1492 return(lt_dlgetsearchpath());
1493#else
1494 return(lt_slsearchpath);
1495#endif
1496}
1497
cristyf7836bf2012-02-20 16:32:47 +00001498MagickExport void *NTOpenLibrary(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +00001499{
1500#define MaxPathElements 31
1501
1502 char
1503 buffer[MaxTextExtent];
1504
1505 int
1506 index;
1507
1508 register const char
1509 *p,
1510 *q;
1511
1512 register int
1513 i;
1514
1515 UINT
1516 mode;
1517
1518 void
1519 *handle;
1520
1521 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1522 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1523 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL))
1524 {
1525 SetErrorMode(mode);
1526 return(handle);
1527 }
1528 p=(char *) GetSearchPath();
1529 index=0;
1530 while (index < MaxPathElements)
1531 {
1532 q=strchr(p,DirectoryListSeparator);
1533 if (q == (char *) NULL)
1534 {
1535 (void) CopyMagickString(buffer,p,MaxTextExtent);
1536 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1537 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1538 handle=(void *) LoadLibraryEx(buffer,NULL,
1539 LOAD_WITH_ALTERED_SEARCH_PATH);
1540 break;
1541 }
1542 i=q-p;
1543 (void) CopyMagickString(buffer,p,i+1);
1544 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1545 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1546 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1547 if (handle != (void *) NULL)
1548 break;
1549 p=q+1;
1550 }
1551 SetErrorMode(mode);
1552 return(handle);
1553}
1554
1555/*
1556%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1557% %
1558% %
1559% %
1560% N T R e a d D i r e c t o r y %
1561% %
1562% %
1563% %
1564%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565%
1566% NTReadDirectory() returns a pointer to a structure representing the
1567% directory entry at the current position in the directory stream to which
1568% entry refers.
1569%
1570% The format of the NTReadDirectory
1571%
1572% NTReadDirectory(entry)
1573%
1574% A description of each parameter follows:
1575%
1576% o entry: Specifies a pointer to a DIR structure.
1577%
1578*/
cristyf7836bf2012-02-20 16:32:47 +00001579MagickExport struct dirent *NTReadDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00001580{
1581 int
1582 status;
1583
1584 size_t
1585 length;
1586
1587 if (entry == (DIR *) NULL)
1588 return((struct dirent *) NULL);
1589 if (!entry->firsttime)
1590 {
1591 status=FindNextFile(entry->hSearch,&entry->Win32FindData);
1592 if (status == 0)
1593 return((struct dirent *) NULL);
1594 }
1595 length=CopyMagickString(entry->file_info.d_name,
1596 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name));
1597 if (length >= sizeof(entry->file_info.d_name))
1598 return((struct dirent *) NULL);
1599 entry->firsttime=FALSE;
1600 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1601 return(&entry->file_info);
1602}
1603
1604/*
1605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1606% %
1607% %
1608% %
1609% N T R e g i s t r y K e y L o o k u p %
1610% %
1611% %
1612% %
1613%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1614%
1615% NTRegistryKeyLookup() returns ImageMagick installation path settings
1616% stored in the Windows Registry. Path settings are specific to the
1617% installed ImageMagick version so that multiple Image Magick installations
1618% may coexist.
1619%
1620% Values are stored in the registry under a base path path similar to
cristyf7836bf2012-02-20 16:32:47 +00001621% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\6.7.4\Q:16" or
1622% "HKEY_CURRENT_USER/SOFTWARE\ImageMagick\6.7.4\Q:16". The provided subkey
cristy3ed852e2009-09-05 21:47:34 +00001623% is appended to this base path to form the full key.
1624%
1625% The format of the NTRegistryKeyLookup method is:
1626%
1627% unsigned char *NTRegistryKeyLookup(const char *subkey)
1628%
1629% A description of each parameter follows:
1630%
1631% o subkey: Specifies a string that identifies the registry object.
1632% Currently supported sub-keys include: "BinPath", "ConfigurePath",
1633% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1634%
1635*/
cristyf7836bf2012-02-20 16:32:47 +00001636MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
cristy3ed852e2009-09-05 21:47:34 +00001637{
1638 char
1639 package_key[MaxTextExtent];
1640
1641 DWORD
1642 size,
1643 type;
1644
1645 HKEY
1646 registry_key;
1647
1648 LONG
1649 status;
1650
1651 unsigned char
1652 *value;
1653
1654 /*
1655 Look-up base key.
1656 */
cristyb51dff52011-05-19 16:55:47 +00001657 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
cristy3ed852e2009-09-05 21:47:34 +00001658 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
1659 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
1660 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1661 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,&registry_key);
1662 if (status != ERROR_SUCCESS)
cristyd06bf862011-12-21 02:18:45 +00001663 status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ,
1664 &registry_key);
1665 if (status != ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +00001666 {
1667 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1668 return((unsigned char *) NULL);
1669 }
1670 /*
1671 Look-up sub key.
1672 */
1673 size=32;
1674 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
1675 if (value == (unsigned char *) NULL)
1676 {
1677 RegCloseKey(registry_key);
1678 return((unsigned char *) NULL);
1679 }
1680 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey);
1681 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1682 if ((status == ERROR_MORE_DATA) && (type == REG_SZ))
1683 {
1684 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
1685 if (value == (BYTE *) NULL)
1686 {
1687 RegCloseKey(registry_key);
1688 return((unsigned char *) NULL);
1689 }
1690 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1691 }
1692 RegCloseKey(registry_key);
1693 if ((type != REG_SZ) || (status != ERROR_SUCCESS))
1694 value=(unsigned char *) RelinquishMagickMemory(value);
1695 return((unsigned char *) value);
1696}
1697
1698/*
1699%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1700% %
1701% %
1702% %
1703% N T R e p o r t E v e n t %
1704% %
1705% %
1706% %
1707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1708%
1709% NTReportEvent() reports an event.
1710%
1711% The format of the NTReportEvent method is:
1712%
1713% MagickBooleanType NTReportEvent(const char *event,
1714% const MagickBooleanType error)
1715%
1716% A description of each parameter follows:
1717%
1718% o event: the event.
1719%
1720% o error: MagickTrue the event is an error.
1721%
1722*/
cristyf7836bf2012-02-20 16:32:47 +00001723MagickExport MagickBooleanType NTReportEvent(const char *event,
cristy3ed852e2009-09-05 21:47:34 +00001724 const MagickBooleanType error)
1725{
1726 const char
1727 *events[1];
1728
1729 HANDLE
1730 handle;
1731
1732 WORD
1733 type;
1734
1735 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1736 if (handle == NULL)
1737 return(MagickFalse);
1738 events[0]=event;
1739 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1740 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1741 DeregisterEventSource(handle);
1742 return(MagickTrue);
1743}
1744
1745/*
1746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1747% %
1748% %
1749% %
1750% N T R e s o u r c e T o B l o b %
1751% %
1752% %
1753% %
1754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1755%
1756% NTResourceToBlob() returns a blob containing the contents of the resource
1757% in the current executable specified by the id parameter. This currently
1758% used to retrieve MGK files tha have been embedded into the various command
1759% line utilities.
1760%
1761% The format of the NTResourceToBlob method is:
1762%
1763% unsigned char *NTResourceToBlob(const char *id)
1764%
1765% A description of each parameter follows:
1766%
1767% o id: Specifies a string that identifies the resource.
1768%
1769*/
cristyf7836bf2012-02-20 16:32:47 +00001770MagickExport unsigned char *NTResourceToBlob(const char *id)
cristy3ed852e2009-09-05 21:47:34 +00001771{
1772 char
1773 path[MaxTextExtent];
1774
1775 DWORD
1776 length;
1777
1778 HGLOBAL
1779 global;
1780
1781 HMODULE
1782 handle;
1783
1784 HRSRC
1785 resource;
1786
1787 unsigned char
1788 *blob,
1789 *value;
1790
1791 assert(id != (const char *) NULL);
1792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
cristyb51dff52011-05-19 16:55:47 +00001793 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +00001794 DirectorySeparator,GetClientName());
1795 if (IsPathAccessible(path) != MagickFalse)
1796 handle=GetModuleHandle(path);
1797 else
1798 handle=GetModuleHandle(0);
1799 if (!handle)
1800 return((unsigned char *) NULL);
1801 resource=FindResource(handle,id,"IMAGEMAGICK");
1802 if (!resource)
1803 return((unsigned char *) NULL);
1804 global=LoadResource(handle,resource);
1805 if (!global)
1806 return((unsigned char *) NULL);
1807 length=SizeofResource(handle,resource);
1808 value=(unsigned char *) LockResource(global);
1809 if (!value)
1810 {
1811 FreeResource(global);
1812 return((unsigned char *) NULL);
1813 }
1814 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
1815 sizeof(*blob));
1816 if (blob != (unsigned char *) NULL)
1817 {
1818 (void) CopyMagickMemory(blob,value,length);
1819 blob[length]='\0';
1820 }
1821 UnlockResource(global);
1822 FreeResource(global);
1823 return(blob);
1824}
1825
1826/*
1827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828% %
1829% %
1830% %
1831% N T S e e k D i r e c t o r y %
1832% %
1833% %
1834% %
1835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1836%
1837% NTSeekDirectory() sets the position of the next NTReadDirectory() operation
1838% on the directory stream.
1839%
1840% The format of the NTSeekDirectory method is:
1841%
cristybb503372010-05-27 20:51:26 +00001842% void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001843%
1844% A description of each parameter follows:
1845%
1846% o entry: Specifies a pointer to a DIR structure.
1847%
1848% o position: specifies the position associated with the directory
1849% stream.
1850%
1851*/
cristyf7836bf2012-02-20 16:32:47 +00001852MagickExport void NTSeekDirectory(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001853{
cristy3b743bb2009-09-14 16:07:59 +00001854 (void) position;
cristy3ed852e2009-09-05 21:47:34 +00001855 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1856 assert(entry != (DIR *) NULL);
1857}
1858
1859/*
1860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1861% %
1862% %
1863% %
1864% N T S e t S e a r c h P a t h %
1865% %
1866% %
1867% %
1868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1869%
1870% NTSetSearchPath() sets the current locations that the subsystem should
1871% look at to find dynamically loadable modules.
1872%
1873% The format of the NTSetSearchPath method is:
1874%
1875% int NTSetSearchPath(const char *path)
1876%
1877% A description of each parameter follows:
1878%
1879% o path: Specifies a pointer to string representing the search path
1880% for DLL's that can be dynamically loaded.
1881%
1882*/
cristyf7836bf2012-02-20 16:32:47 +00001883MagickExport int NTSetSearchPath(const char *path)
cristy3ed852e2009-09-05 21:47:34 +00001884{
1885#if defined(MAGICKCORE_LTDL_DELEGATE)
1886 lt_dlsetsearchpath(path);
1887#else
1888 if (lt_slsearchpath != (char *) NULL)
1889 lt_slsearchpath=DestroyString(lt_slsearchpath);
1890 if (path != (char *) NULL)
1891 lt_slsearchpath=AcquireString(path);
1892#endif
1893 return(0);
1894}
1895
1896/*
1897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1898% %
1899% %
1900% %
1901+ N T S y n c M e m o r y %
1902% %
1903% %
1904% %
1905%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1906%
1907% NTSyncMemory() emulates the Unix method of the same name.
1908%
1909% The format of the NTSyncMemory method is:
1910%
1911% int NTSyncMemory(void *address,size_t length,int flags)
1912%
1913% A description of each parameter follows:
1914%
1915% o address: the address of the binary large object.
1916%
1917% o length: the length of the binary large object.
1918%
1919% o flags: Option flags (ignored for Windows).
1920%
1921*/
cristyf7836bf2012-02-20 16:32:47 +00001922MagickExport int NTSyncMemory(void *address,size_t length,int flags)
cristy3ed852e2009-09-05 21:47:34 +00001923{
cristy3b743bb2009-09-14 16:07:59 +00001924 (void) flags;
cristy3ed852e2009-09-05 21:47:34 +00001925 if (FlushViewOfFile(address,length) == MagickFalse)
1926 return(-1);
1927 return(0);
1928}
1929
1930/*
1931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1932% %
1933% %
1934% %
1935% N T S y s t e m C o m m a n d %
1936% %
1937% %
1938% %
1939%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1940%
1941% NTSystemCommand() executes the specified command and waits until it
1942% terminates. The returned value is the exit status of the command.
1943%
cristyb32b90a2009-09-07 21:45:48 +00001944% The format of the NTSystemCommand method is:
cristy3ed852e2009-09-05 21:47:34 +00001945%
cristy6de4bc22010-01-12 17:10:35 +00001946% int NTSystemCommand(MagickFalse,const char *command)
cristy3ed852e2009-09-05 21:47:34 +00001947%
1948% A description of each parameter follows:
1949%
1950% o command: This string is the command to execute.
1951%
1952*/
cristyf7836bf2012-02-20 16:32:47 +00001953MagickExport int NTSystemCommand(const char *command)
cristy3ed852e2009-09-05 21:47:34 +00001954{
1955 char
1956 local_command[MaxTextExtent];
1957
1958 DWORD
1959 child_status;
1960
1961 int
1962 status;
1963
1964 MagickBooleanType
1965 background_process;
1966
1967 PROCESS_INFORMATION
1968 process_info;
1969
1970 STARTUPINFO
1971 startup_info;
1972
1973 if (command == (char *) NULL)
1974 return(-1);
1975 GetStartupInfo(&startup_info);
1976 startup_info.dwFlags=STARTF_USESHOWWINDOW;
1977 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
1978 (void) CopyMagickString(local_command,command,MaxTextExtent);
1979 background_process=command[strlen(command)-1] == '&' ? MagickTrue :
1980 MagickFalse;
1981 if (background_process)
1982 local_command[strlen(command)-1]='\0';
1983 if (command[strlen(command)-1] == '|')
1984 local_command[strlen(command)-1]='\0';
1985 else
1986 startup_info.wShowWindow=SW_SHOWDEFAULT;
1987 status=CreateProcess((LPCTSTR) NULL,local_command,
1988 (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,
1989 (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
1990 &process_info);
1991 if (status == 0)
1992 return(-1);
1993 if (background_process)
1994 return(status == 0);
1995 status=WaitForSingleObject(process_info.hProcess,INFINITE);
1996 if (status != WAIT_OBJECT_0)
1997 return(status);
1998 status=GetExitCodeProcess(process_info.hProcess,&child_status);
1999 if (status == 0)
2000 return(-1);
2001 CloseHandle(process_info.hProcess);
2002 CloseHandle(process_info.hThread);
2003 return((int) child_status);
2004}
2005
2006/*
2007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2008% %
2009% %
2010% %
2011% N T S y s t e m C o n i f i g u r a t i o n %
2012% %
2013% %
2014% %
2015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2016%
2017% NTSystemConfiguration() provides a way for the application to determine
2018% values for system limits or options at runtime.
2019%
2020% The format of the exit method is:
2021%
cristybb503372010-05-27 20:51:26 +00002022% ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002023%
2024% A description of each parameter follows:
2025%
2026% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
2027%
2028*/
cristyf7836bf2012-02-20 16:32:47 +00002029MagickExport ssize_t NTSystemConfiguration(int name)
cristy3ed852e2009-09-05 21:47:34 +00002030{
2031 switch (name)
2032 {
2033 case _SC_PAGESIZE:
2034 {
2035 SYSTEM_INFO
2036 system_info;
2037
2038 GetSystemInfo(&system_info);
2039 return(system_info.dwPageSize);
2040 }
2041 case _SC_PHYS_PAGES:
2042 {
2043 HMODULE
2044 handle;
2045
2046 LPFNDLLFUNC2
2047 module;
2048
2049 NTMEMORYSTATUSEX
2050 status;
2051
2052 SYSTEM_INFO
2053 system_info;
2054
2055 handle=GetModuleHandle("kernel32.dll");
2056 if (handle == (HMODULE) NULL)
2057 return(0L);
2058 GetSystemInfo(&system_info);
2059 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
2060 if (module == (LPFNDLLFUNC2) NULL)
2061 {
2062 MEMORYSTATUS
2063 status;
2064
2065 GlobalMemoryStatus(&status);
cristybb503372010-05-27 20:51:26 +00002066 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002067 }
2068 status.dwLength=sizeof(status);
2069 if (module(&status) == 0)
2070 return(0L);
cristybb503372010-05-27 20:51:26 +00002071 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
cristy3ed852e2009-09-05 21:47:34 +00002072 }
2073 case _SC_OPEN_MAX:
2074 return(2048);
2075 default:
2076 break;
2077 }
2078 return(-1);
2079}
2080
2081/*
2082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2083% %
2084% %
2085% %
2086% N T T e l l D i r e c t o r y %
2087% %
2088% %
2089% %
2090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2091%
2092% NTTellDirectory() returns the current location associated with the named
2093% directory stream.
2094%
2095% The format of the NTTellDirectory method is:
2096%
cristybb503372010-05-27 20:51:26 +00002097% ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002098%
2099% A description of each parameter follows:
2100%
2101% o entry: Specifies a pointer to a DIR structure.
2102%
2103*/
cristyf7836bf2012-02-20 16:32:47 +00002104MagickExport ssize_t NTTellDirectory(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00002105{
2106 assert(entry != (DIR *) NULL);
2107 return(0);
2108}
2109
2110/*
2111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2112% %
2113% %
2114% %
2115% N T T r u n c a t e F i l e %
2116% %
2117% %
2118% %
2119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2120%
2121% NTTruncateFile() truncates a file to a specified length.
2122%
2123% The format of the NTTruncateFile method is:
2124%
2125% int NTTruncateFile(int file,off_t length)
2126%
2127% A description of each parameter follows:
2128%
2129% o file: the file.
2130%
2131% o length: the file length.
2132%
2133*/
cristyf7836bf2012-02-20 16:32:47 +00002134MagickExport int NTTruncateFile(int file,off_t length)
cristy3ed852e2009-09-05 21:47:34 +00002135{
2136 DWORD
2137 file_pointer;
2138
cristyfeb262e2010-06-04 22:57:35 +00002139 long
cristy3ed852e2009-09-05 21:47:34 +00002140 file_handle,
2141 high,
2142 low;
2143
2144 file_handle=_get_osfhandle(file);
2145 if (file_handle == -1L)
2146 return(-1);
cristyfeb262e2010-06-04 22:57:35 +00002147 low=(long) (length & 0xffffffffUL);
2148 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
cristy3ed852e2009-09-05 21:47:34 +00002149 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2150 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2151 return(-1);
2152 if (SetEndOfFile((HANDLE) file_handle) == 0)
2153 return(-1);
2154 return(0);
2155}
2156
2157/*
2158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2159% %
2160% %
2161% %
2162+ N T U n m a p M e m o r y %
2163% %
2164% %
2165% %
2166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2167%
2168% NTUnmapMemory() emulates the Unix munmap method.
2169%
2170% The format of the NTUnmapMemory method is:
2171%
2172% int NTUnmapMemory(void *map,size_t length)
2173%
2174% A description of each parameter follows:
2175%
2176% o map: the address of the binary large object.
2177%
2178% o length: the length of the binary large object.
2179%
2180*/
cristyf7836bf2012-02-20 16:32:47 +00002181MagickExport int NTUnmapMemory(void *map,size_t length)
cristy3ed852e2009-09-05 21:47:34 +00002182{
cristy3b743bb2009-09-14 16:07:59 +00002183 (void) length;
cristy3ed852e2009-09-05 21:47:34 +00002184 if (UnmapViewOfFile(map) == 0)
2185 return(-1);
2186 return(0);
2187}
2188
2189/*
2190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2191% %
2192% %
2193% %
2194% N T U s e r T i m e %
2195% %
2196% %
2197% %
2198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2199%
2200% NTUserTime() returns the total time the process has been scheduled (e.g.
2201% seconds) since the last call to StartTimer().
2202%
2203% The format of the UserTime method is:
2204%
2205% double NTUserTime(void)
2206%
2207*/
cristyf7836bf2012-02-20 16:32:47 +00002208MagickExport double NTUserTime(void)
cristy3ed852e2009-09-05 21:47:34 +00002209{
2210 DWORD
2211 status;
2212
2213 FILETIME
2214 create_time,
2215 exit_time;
2216
2217 OSVERSIONINFO
2218 OsVersionInfo;
2219
2220 union
2221 {
2222 FILETIME
2223 filetime;
2224
2225 __int64
2226 filetime64;
2227 } kernel_time;
2228
2229 union
2230 {
2231 FILETIME
2232 filetime;
2233
2234 __int64
2235 filetime64;
2236 } user_time;
2237
2238 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2239 GetVersionEx(&OsVersionInfo);
2240 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2241 return(NTElapsedTime());
2242 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2243 &kernel_time.filetime,&user_time.filetime);
2244 if (status != TRUE)
2245 return(0.0);
2246 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2247}
2248
2249/*
2250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2251% %
2252% %
2253% %
2254% N T W a r n i n g H a n d l e r %
2255% %
2256% %
2257% %
2258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2259%
2260% NTWarningHandler() displays a warning reason.
2261%
2262% The format of the NTWarningHandler method is:
2263%
cristy3b743bb2009-09-14 16:07:59 +00002264% void NTWarningHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +00002265% const char *description)
2266%
2267% A description of each parameter follows:
2268%
cristy3b743bb2009-09-14 16:07:59 +00002269% o severity: Specifies the numeric warning category.
cristy3ed852e2009-09-05 21:47:34 +00002270%
2271% o reason: Specifies the reason to display before terminating the
2272% program.
2273%
2274% o description: Specifies any description to the reason.
2275%
2276*/
cristy417d8452011-10-13 17:09:49 +00002277MagickExport void NTWarningHandler(const ExceptionType severity,
cristy3ed852e2009-09-05 21:47:34 +00002278 const char *reason,const char *description)
2279{
2280 char
2281 buffer[2*MaxTextExtent];
2282
cristy3b743bb2009-09-14 16:07:59 +00002283 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +00002284 if (reason == (char *) NULL)
2285 return;
2286 if (description == (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +00002287 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
cristy3ed852e2009-09-05 21:47:34 +00002288 reason);
2289 else
cristyb51dff52011-05-19 16:55:47 +00002290 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +00002291 GetClientName(),reason,description);
2292 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2293 MB_SETFOREGROUND | MB_ICONINFORMATION);
2294}
2295#endif