MagickCore 6.9.13-5
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
nt-base.c
1/*
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% Cristy %
17% December 1996 %
18% %
19% %
20% Copyright 1999 ImageMagick Studio LLC, a non-profit organization %
21% 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% https://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*/
41#include "magick/studio.h"
42#if defined(MAGICKCORE_WINDOWS_SUPPORT)
43#include "magick/client.h"
44#include "magick/exception-private.h"
45#include "magick/image-private.h"
46#include "magick/locale_.h"
47#include "magick/log.h"
48#include "magick/magick.h"
49#include "magick/memory_.h"
50#include "magick/memory-private.h"
51#include "magick/nt-base.h"
52#include "magick/nt-base-private.h"
53#include "magick/resource_.h"
54#include "magick/timer.h"
55#include "magick/string_.h"
56#include "magick/string-private.h"
57#include "magick/utility.h"
58#include "magick/utility-private.h"
59#include "magick/version.h"
60#if defined(MAGICKCORE_LTDL_DELEGATE)
61# include "ltdl.h"
62#endif
63#if defined(MAGICKCORE_CIPHER_SUPPORT)
64#include <ntsecapi.h>
65#include <wincrypt.h>
66#endif
67
68/*
69 Define declarations.
70*/
71#if !defined(MAP_FAILED)
72#define MAP_FAILED ((void *)(LONG_PTR) -1)
73#endif
74#define MaxWideByteExtent 100
75
76/*
77 Typdef declarations.
78*/
79
80/*
81 We need to make sure only one instance is created for each process and that
82 is why we wrap the new/delete instance methods.
83
84 From: http://www.ghostscript.com/doc/current/API.htm
85 "The Win32 DLL gsdll32.dll can be used by multiple programs simultaneously,
86 but only once within each process"
87*/
88typedef struct _NTGhostInfo
89{
90 void
91 (MagickDLLCall *delete_instance)(gs_main_instance *);
92
93 int
94 (MagickDLLCall *new_instance)(gs_main_instance **, void *);
95
96 MagickBooleanType
97 has_instance;
98} NTGhostInfo;
99
100/*
101 Static declarations.
102*/
103#if !defined(MAGICKCORE_LTDL_DELEGATE)
104static char
105 *lt_slsearchpath = (char *) NULL;
106#endif
107
108static NTGhostInfo
109 nt_ghost_info;
110
111static GhostInfo
112 ghost_info;
113
114static void
115 *ghost_handle = (void *) NULL;
116
117static SemaphoreInfo
118 *ghost_semaphore = (SemaphoreInfo *) NULL,
119 *winsock_semaphore = (SemaphoreInfo *) NULL;
120
121static WSADATA
122 *wsaData = (WSADATA*) NULL;
123
124static size_t
125 long_paths_enabled = 2;
126
127struct
128{
129 const HKEY
130 hkey;
131
132 const char
133 *name;
134}
135const registry_roots[2] =
136{
137 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
138 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
139};
140
141/*
142 External declarations.
143*/
144#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
145extern "C" BOOL WINAPI
146 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
147#endif
148
149static void MagickDLLCall NTGhostscriptDeleteInstance(
150 gs_main_instance *instance)
151{
152 LockSemaphoreInfo(ghost_semaphore);
153 nt_ghost_info.delete_instance(instance);
154 nt_ghost_info.has_instance=MagickFalse;
155 UnlockSemaphoreInfo(ghost_semaphore);
156}
157
158static int MagickDLLCall NTGhostscriptNewInstance(gs_main_instance **pinstance,
159 void *caller_handle)
160{
161 int
162 status;
163
164 LockSemaphoreInfo(ghost_semaphore);
165 status=-1;
166 if (nt_ghost_info.has_instance == MagickFalse)
167 {
168 status=nt_ghost_info.new_instance(pinstance,caller_handle);
169 if (status >= 0)
170 nt_ghost_info.has_instance=MagickTrue;
171 }
172 UnlockSemaphoreInfo(ghost_semaphore);
173 return(status);
174}
175
176static inline char *create_utf8_string(const wchar_t *wideChar)
177{
178 char
179 *utf8;
180
181 int
182 count;
183
184 count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,NULL,0,NULL,NULL);
185 if (count < 0)
186 return((char *) NULL);
187 utf8=(char *) NTAcquireQuantumMemory(count+1,sizeof(*utf8));
188 if (utf8 == (char *) NULL)
189 return((char *) NULL);
190 count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,utf8,count,NULL,NULL);
191 if (count == 0)
192 {
193 utf8=DestroyString(utf8);
194 return((char *) NULL);
195 }
196 utf8[count]=0;
197 return(utf8);
198}
199
200static unsigned char *NTGetRegistryValue(HKEY root,const char *key,DWORD flags,
201 const char *name)
202{
203 unsigned char
204 *value;
205
206 HKEY
207 registry_key;
208
209 DWORD
210 size,
211 type;
212
213 LSTATUS
214 status;
215
216 wchar_t
217 wide_name[MaxWideByteExtent];
218
219 value=(unsigned char *) NULL;
220 status=RegOpenKeyExA(root,key,0,(KEY_READ | flags),&registry_key);
221 if (status != ERROR_SUCCESS)
222 return(value);
223 if (MultiByteToWideChar(CP_UTF8,0,name,-1,wide_name,MaxWideByteExtent) == 0)
224 {
225 RegCloseKey(registry_key);
226 return(value);
227 }
228 status=RegQueryValueExW(registry_key,wide_name,0,&type,0,&size);
229 if ((status == ERROR_SUCCESS) && (type == REG_SZ))
230 {
231 LPBYTE
232 wide;
233
234 wide=(LPBYTE) NTAcquireQuantumMemory((const size_t) size,sizeof(*wide));
235 if (wide != (LPBYTE) NULL)
236 {
237 status=RegQueryValueExW(registry_key,wide_name,0,&type,wide,&size);
238 if ((status == ERROR_SUCCESS) && (type == REG_SZ))
239 value=(unsigned char *) create_utf8_string((const wchar_t *) wide);
240 wide=(LPBYTE) RelinquishMagickMemory(wide);
241 }
242 }
243 RegCloseKey(registry_key);
244 return(value);
245}
246
247/*
248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249% %
250% %
251% %
252% D l l M a i n %
253% %
254% %
255% %
256%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257%
258% DllMain() is an entry point to the DLL which is called when processes and
259% threads are initialized and terminated, or upon calls to the Windows
260% LoadLibrary and FreeLibrary functions.
261%
262% The function returns TRUE of it succeeds, or FALSE if initialization fails.
263%
264% The format of the DllMain method is:
265%
266% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
267%
268% A description of each parameter follows:
269%
270% o handle: handle to the DLL module
271%
272% o reason: reason for calling function:
273%
274% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
275% space of current process.
276% DLL_THREAD_ATTACH - Indicates that the current process is
277% creating a new thread. Called under the
278% context of the new thread.
279% DLL_THREAD_DETACH - Indicates that the thread is exiting.
280% Called under the context of the exiting
281% thread.
282% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
283% from the virtual address space of the
284% current process.
285%
286% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
287% and DLL_PROCESS_DETACH.
288%
289*/
290#if defined(_DLL) && defined(ProvideDllMain)
291BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
292{
293 magick_unreferenced(lpvReserved);
294
295 switch (reason)
296 {
297 case DLL_PROCESS_ATTACH:
298 {
299 char
300 *module_path;
301
302 ssize_t
303 count;
304
305 wchar_t
306 *wide_path;
307
308 MagickCoreGenesis((const char*) NULL,MagickFalse);
309 wide_path=(wchar_t *) NTAcquireQuantumMemory(MaxTextExtent,
310 sizeof(*wide_path));
311 if (wide_path == (wchar_t *) NULL)
312 return(FALSE);
313 count=(ssize_t) GetModuleFileNameW(handle,wide_path,MaxTextExtent);
314 if (count != 0)
315 {
316 char
317 *path;
318
319 module_path=create_utf8_string(wide_path);
320 for ( ; count > 0; count--)
321 if (module_path[count] == '\\')
322 {
323 module_path[count+1]='\0';
324 break;
325 }
326 path=(char *) NTAcquireQuantumMemory(MaxTextExtent,16*sizeof(*path));
327 if (path == (char *) NULL)
328 {
329 module_path=DestroyString(module_path);
330 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
331 return(FALSE);
332 }
333 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
334 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
335 {
336 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
337 {
338 char
339 *variable;
340
341 variable=(char *) NTAcquireQuantumMemory(MaxTextExtent,
342 16*sizeof(*variable));
343 if (variable == (char *) NULL)
344 {
345 path=DestroyString(path);
346 module_path=DestroyString(module_path);
347 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
348 return(FALSE);
349 }
350 (void) FormatLocaleString(variable,16*MaxTextExtent,
351 "%s;%s",module_path,path);
352 SetEnvironmentVariable("PATH",variable);
353 variable=DestroyString(variable);
354 }
355 }
356 path=DestroyString(path);
357 module_path=DestroyString(module_path);
358 }
359 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path);
360 break;
361 }
362 case DLL_PROCESS_DETACH:
363 {
364 MagickCoreTerminus();
365 break;
366 }
367 default:
368 break;
369 }
370 return(TRUE);
371}
372#endif
373
374#if !defined(__MINGW32__)
375/*
376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377% %
378% %
379% %
380% g e t t i m e o f d a y %
381% %
382% %
383% %
384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385%
386% The gettimeofday() method get the time of day.
387%
388% The format of the gettimeofday method is:
389%
390% int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
391%
392% A description of each parameter follows:
393%
394% o time_value: the time value.
395%
396% o time_zone: the time zone.
397%
398*/
399MagickPrivate int gettimeofday (struct timeval *time_value,
400 struct timezone *time_zone)
401{
402#define EpochFiletime MagickLLConstant(116444736000000000)
403
404 static int
405 is_tz_set;
406
407 if (time_value != (struct timeval *) NULL)
408 {
409 FILETIME
410 file_time;
411
412 __int64
413 time;
414
415 LARGE_INTEGER
416 date_time;
417
418 GetSystemTimeAsFileTime(&file_time);
419 date_time.LowPart=file_time.dwLowDateTime;
420 date_time.HighPart=file_time.dwHighDateTime;
421 time=date_time.QuadPart;
422 time-=EpochFiletime;
423 time/=10;
424 time_value->tv_sec=(ssize_t) (time / 1000000);
425 time_value->tv_usec=(ssize_t) (time % 1000000);
426 }
427 if (time_zone != (struct timezone *) NULL)
428 {
429 if (is_tz_set == 0)
430 {
431 _tzset();
432 is_tz_set++;
433 }
434 time_zone->tz_minuteswest=_timezone/60;
435 time_zone->tz_dsttime=_daylight;
436 }
437 return(0);
438}
439#endif
440
441/*
442%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
443% %
444% %
445% %
446% N T A r g v T o U T F 8 %
447% %
448% %
449% %
450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451%
452% NTArgvToUTF8() converts the wide command line arguments to UTF-8 to ensure
453% compatibility with Linux.
454%
455% The format of the NTArgvToUTF8 method is:
456%
457% char **NTArgvToUTF8(const int argc,wchar_t **argv)
458%
459% A description of each parameter follows:
460%
461% o argc: the number of command line arguments.
462%
463% o argv: the wide-character command line arguments.
464%
465*/
466MagickPrivate char **NTArgvToUTF8(const int argc,wchar_t **argv)
467{
468 char
469 **utf8;
470
471 ssize_t
472 i;
473
474 utf8=(char **) NTAcquireQuantumMemory(argc,sizeof(*utf8));
475 if (utf8 == (char **) NULL)
476 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
477 for (i=0; i < (ssize_t) argc; i++)
478 {
479 utf8[i]=create_utf8_string(argv[i]);
480 if (utf8[i] == (char *) NULL)
481 {
482 for (i--; i >= 0; i--)
483 utf8[i]=DestroyString(utf8[i]);
484 ThrowFatalException(ResourceLimitFatalError,
485 "UnableToConvertStringToARGV");
486 }
487 }
488 return(utf8);
489}
490
491/*
492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493% %
494% %
495% %
496% N T C l o s e D i r e c t o r y %
497% %
498% %
499% %
500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501%
502% NTCloseDirectory() closes the named directory stream and frees the DIR
503% structure.
504%
505% The format of the NTCloseDirectory method is:
506%
507% int NTCloseDirectory(DIR *entry)
508%
509% A description of each parameter follows:
510%
511% o entry: Specifies a pointer to a DIR structure.
512%
513*/
514MagickPrivate int NTCloseDirectory(DIR *entry)
515{
516 assert(entry != (DIR *) NULL);
517 if (IsEventLogging() != MagickFalse)
518 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
519 FindClose(entry->hSearch);
520 entry=(DIR *) RelinquishMagickMemory(entry);
521 return(0);
522}
523
524/*
525%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
526% %
527% %
528% %
529% N T C l o s e L i b r a r y %
530% %
531% %
532% %
533%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
534%
535% NTCloseLibrary() unloads the module associated with the passed handle.
536%
537% The format of the NTCloseLibrary method is:
538%
539% void NTCloseLibrary(void *handle)
540%
541% A description of each parameter follows:
542%
543% o handle: Specifies a handle to a previously loaded dynamic module.
544%
545*/
546MagickPrivate int NTCloseLibrary(void *handle)
547{
548 return(!(FreeLibrary((HINSTANCE) handle)));
549}
550
551/*
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553% %
554% %
555% %
556% N T C o n t r o l H a n d l e r %
557% %
558% %
559% %
560%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561%
562% NTControlHandler() registers a control handler that is activated when, for
563% example, a ctrl-c is received.
564%
565% The format of the NTControlHandler method is:
566%
567% int NTControlHandler(void)
568%
569*/
570
571static BOOL ControlHandler(DWORD type)
572{
573 (void) type;
574 AsynchronousResourceComponentTerminus();
575 return(FALSE);
576}
577
578MagickPrivate int NTControlHandler(void)
579{
580 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
581}
582
583/*
584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585% %
586% %
587% %
588% N T E l a p s e d T i m e %
589% %
590% %
591% %
592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593%
594% NTElapsedTime() returns the elapsed time (in seconds) since the last call to
595% StartTimer().
596%
597% The format of the ElapsedTime method is:
598%
599% double NTElapsedTime(void)
600%
601*/
602MagickPrivate double NTElapsedTime(void)
603{
604 union
605 {
606 FILETIME
607 filetime;
608
609 __int64
610 filetime64;
611 } elapsed_time;
612
613 LARGE_INTEGER
614 performance_count;
615
616 static LARGE_INTEGER
617 frequency = { 0 };
618
619 SYSTEMTIME
620 system_time;
621
622 if (frequency.QuadPart == 0)
623 {
624 if (QueryPerformanceFrequency(&frequency) == 0)
625 frequency.QuadPart=1;
626 }
627 if (frequency.QuadPart > 1)
628 {
629 QueryPerformanceCounter(&performance_count);
630 return((double) performance_count.QuadPart/frequency.QuadPart);
631 }
632 GetSystemTime(&system_time);
633 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
634 return((double) 1.0e-7*elapsed_time.filetime64);
635}
636
637/*
638%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639% %
640% %
641% %
642+ N T E r r o r H a n d l e r %
643% %
644% %
645% %
646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647%
648% NTErrorHandler() displays an error reason and then terminates the program.
649%
650% The format of the NTErrorHandler method is:
651%
652% void NTErrorHandler(const ExceptionType severity,const char *reason,
653% const char *description)
654%
655% A description of each parameter follows:
656%
657% o severity: Specifies the numeric error category.
658%
659% o reason: Specifies the reason to display before terminating the
660% program.
661%
662% o description: Specifies any description to the reason.
663%
664*/
665MagickPrivate void NTErrorHandler(const ExceptionType severity,
666 const char *reason,const char *description)
667{
668 char
669 buffer[3*MaxTextExtent],
670 *message;
671
672 (void) severity;
673 if (reason == (char *) NULL)
674 {
675 MagickCoreTerminus();
676 exit(0);
677 }
678 message=GetExceptionMessage(errno);
679 if ((description != (char *) NULL) && errno)
680 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
681 GetClientName(),reason,description,message);
682 else
683 if (description != (char *) NULL)
684 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
685 GetClientName(),reason,description);
686 else
687 if (errno != 0)
688 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s [%s].\n",
689 GetClientName(),reason,message);
690 else
691 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",
692 GetClientName(),reason);
693 message=DestroyString(message);
694 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
695 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
696 MagickCoreTerminus();
697 exit(0);
698}
699
700/*
701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702% %
703% %
704% %
705% N T E x i t L i b r a r y %
706% %
707% %
708% %
709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710%
711% NTExitLibrary() exits the dynamic module loading subsystem.
712%
713% The format of the NTExitLibrary method is:
714%
715% int NTExitLibrary(void)
716%
717*/
718MagickPrivate int NTExitLibrary(void)
719{
720 return(0);
721}
722
723/*
724%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
725% %
726% %
727% %
728% N T G a t h e r R a n d o m D a t a %
729% %
730% %
731% %
732%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733%
734% NTGatherRandomData() gathers random data and returns it.
735%
736% The format of the GatherRandomData method is:
737%
738% MagickBooleanType NTGatherRandomData(const size_t length,
739% unsigned char *random)
740%
741% A description of each parameter follows:
742%
743% length: the length of random data buffer
744%
745% random: the random data is returned here.
746%
747*/
748MagickPrivate MagickBooleanType NTGatherRandomData(const size_t length,
749 unsigned char *random)
750{
751#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
752 HCRYPTPROV
753 handle;
754
755 int
756 status;
757
758 handle=(HCRYPTPROV) NULL;
759 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
760 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
761 if (status == 0)
762 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
763 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
764 if (status == 0)
765 return(MagickFalse);
766 status=CryptGenRandom(handle,(DWORD) length,random);
767 if (status == 0)
768 {
769 status=CryptReleaseContext(handle,0);
770 return(MagickFalse);
771 }
772 status=CryptReleaseContext(handle,0);
773 if (status == 0)
774 return(MagickFalse);
775#else
776 (void) random;
777 (void) length;
778#endif
779 return(MagickTrue);
780}
781
782/*
783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784% %
785% %
786% %
787% N T G e t E n v i r o n m e n t V a l u e %
788% %
789% %
790% %
791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792%
793% NTGetEnvironmentValue() returns the environment string that matches the
794% specified name.
795%
796% The format of the NTGetEnvironmentValue method is:
797%
798% char *GetEnvironmentValue(const char *name)
799%
800% A description of each parameter follows:
801%
802% o name: the environment name.
803%
804*/
805extern MagickPrivate char *NTGetEnvironmentValue(const char *name)
806{
807 char
808 *environment = (char *) NULL;
809
810 DWORD
811 size;
812
813 LPWSTR
814 wide;
815
816 wchar_t
817 wide_name[MaxWideByteExtent];
818
819 if (MultiByteToWideChar(CP_UTF8,0,name,-1,wide_name,MaxWideByteExtent) == 0)
820 return(environment);
821 size=GetEnvironmentVariableW(wide_name,(LPWSTR) NULL,0);
822 if (size == 0)
823 return(environment);
824 wide=(LPWSTR) NTAcquireQuantumMemory((const size_t) size,sizeof(*wide));
825 if (wide == (LPWSTR) NULL)
826 return(environment);
827 if (GetEnvironmentVariableW(wide_name,wide,size) != 0)
828 environment=create_utf8_string(wide);
829 wide=(LPWSTR) RelinquishMagickMemory(wide);
830 return(environment);
831}
832
833/*
834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835% %
836% %
837% %
838% N T G e t E x e c u t i o n P a t h %
839% %
840% %
841% %
842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843%
844% NTGetExecutionPath() returns the execution path of a program.
845%
846% The format of the GetExecutionPath method is:
847%
848% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
849%
850% A description of each parameter follows:
851%
852% o path: the pathname of the executable that started the process.
853%
854% o extent: the maximum extent of the path.
855%
856*/
857MagickPrivate MagickBooleanType NTGetExecutionPath(char *path,
858 const size_t extent)
859{
860 wchar_t
861 wide_path[MaxTextExtent];
862
863 (void) GetModuleFileNameW((HMODULE) NULL,wide_path,(DWORD) extent);
864 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL,
865 NULL);
866 return(MagickTrue);
867}
868
869/*
870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871% %
872% %
873% %
874% N T G e t L a s t E r r o r %
875% %
876% %
877% %
878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879%
880% NTGetLastError() returns the last error that occurred.
881%
882% The format of the NTGetLastError method is:
883%
884% char *NTGetLastError(void)
885%
886*/
887char *NTGetLastError(void)
888{
889 char
890 *reason;
891
892 int
893 status;
894
895 LPVOID
896 buffer = (LPVOID) NULL;
897
898 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
899 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
900 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
901 if (!status)
902 reason=AcquireString("An unknown error occurred");
903 else
904 {
905 reason=AcquireString((const char *) buffer);
906 LocalFree(buffer);
907 }
908 return(reason);
909}
910
911/*
912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913% %
914% %
915% %
916% N T G e t L i b r a r y E r r o r %
917% %
918% %
919% %
920%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921%
922% Lt_dlerror() returns a pointer to a string describing the last error
923% associated with a lt_dl method. Note that this function is not thread
924% safe so it should only be used under the protection of a lock.
925%
926% The format of the NTGetLibraryError method is:
927%
928% const char *NTGetLibraryError(void)
929%
930*/
931MagickPrivate const char *NTGetLibraryError(void)
932{
933 static char
934 last_error[MaxTextExtent];
935
936 char
937 *error;
938
939 *last_error='\0';
940 error=NTGetLastError();
941 if (error)
942 (void) CopyMagickString(last_error,error,MaxTextExtent);
943 error=DestroyString(error);
944 return(last_error);
945}
946
947/*
948%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949% %
950% %
951% %
952% N T G e t L i b r a r y S y m b o l %
953% %
954% %
955% %
956%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957%
958% NTGetLibrarySymbol() retrieve the procedure address of the method
959% specified by the passed character string.
960%
961% The format of the NTGetLibrarySymbol method is:
962%
963% void *NTGetLibrarySymbol(void *handle,const char *name)
964%
965% A description of each parameter follows:
966%
967% o handle: Specifies a handle to the previously loaded dynamic module.
968%
969% o name: Specifies the procedure entry point to be returned.
970%
971*/
972void *NTGetLibrarySymbol(void *handle,const char *name)
973{
974 FARPROC
975 proc_address;
976
977 proc_address=GetProcAddress((HMODULE) handle,(LPCSTR) name);
978 if (proc_address == (FARPROC) NULL)
979 return((void *) NULL);
980 return((void *) proc_address);
981}
982
983/*
984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985% %
986% %
987% %
988% N T G e t M o d u l e P a t h %
989% %
990% %
991% %
992%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
993%
994% NTGetModulePath() returns the path of the specified module.
995%
996% The format of the GetModulePath method is:
997%
998% MagickBooleanType NTGetModulePath(const char *module,char *path)
999%
1000% A description of each parameter follows:
1001%
1002% modith: the module name.
1003%
1004% path: the module path is returned here.
1005%
1006*/
1007MagickPrivate MagickBooleanType NTGetModulePath(const char *module,char *path)
1008{
1009 char
1010 module_path[MaxTextExtent];
1011
1012 HMODULE
1013 handle;
1014
1015 ssize_t
1016 length;
1017
1018 *path='\0';
1019 handle=GetModuleHandle(module);
1020 if (handle == (HMODULE) NULL)
1021 return(MagickFalse);
1022 length=GetModuleFileName(handle,module_path,MaxTextExtent);
1023 if (length != 0)
1024 GetPathComponent(module_path,HeadPath,path);
1025 return(MagickTrue);
1026}
1027
1028/*
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030% %
1031% %
1032% %
1033% N T G h o s t s c r i p t D L L V e c t o r s %
1034% %
1035% %
1036% %
1037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038%
1039% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
1040% function vectors to invoke Ghostscript DLL functions. A null pointer is
1041% returned if there is an error when loading the DLL or retrieving the
1042% function vectors.
1043%
1044% The format of the NTGhostscriptDLLVectors method is:
1045%
1046% const GhostInfo *NTGhostscriptDLLVectors(void)
1047%
1048*/
1049static int NTLocateGhostscript(DWORD flags,int *root_index,
1050 const char **product_family,int *major_version,int *minor_version,
1051 int *patch_version)
1052{
1053 int
1054 i;
1055
1056 MagickBooleanType
1057 status;
1058
1059 static const char
1060 *products[2] =
1061 {
1062 "Artifex Ghostscript",
1063 "GPL Ghostscript"
1064 };
1065
1066 /*
1067 Find the most recent version of Ghostscript.
1068 */
1069 status=MagickFalse;
1070 *root_index=0;
1071 *product_family=NULL;
1072 *major_version=5;
1073 *minor_version=49; /* min version of Ghostscript is 5.50 */
1074 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
1075 {
1076 char
1077 key[MagickPathExtent];
1078
1079 HKEY
1080 hkey;
1081
1082 int
1083 j;
1084
1085 REGSAM
1086 mode;
1087
1088 (void) FormatLocaleString(key,MagickPathExtent,"SOFTWARE\\%s",products[i]);
1089 for (j=0; j < (ssize_t) (sizeof(registry_roots)/sizeof(registry_roots[0]));
1090 j++)
1091 {
1092 mode=KEY_READ | flags;
1093 if (RegOpenKeyExA(registry_roots[j].hkey,key,0,mode,&hkey) ==
1094 ERROR_SUCCESS)
1095 {
1096 DWORD
1097 extent;
1098
1099 int
1100 k;
1101
1102 /*
1103 Now enumerate the keys.
1104 */
1105 extent=sizeof(key)/sizeof(char);
1106 for (k=0; RegEnumKeyA(hkey,k,key,extent) == ERROR_SUCCESS; k++)
1107 {
1108 int
1109 major,
1110 minor,
1111 patch;
1112
1113 major=0;
1114 minor=0;
1115 patch=0;
1116 if (sscanf(key,"%d.%d.%d",&major,&minor,&patch) != 3)
1117 if (sscanf(key,"%d.%d",&major,&minor) != 2)
1118 continue;
1119 if ((major > *major_version) ||
1120 ((major == *major_version) && (minor > *minor_version)) ||
1121 ((minor == *minor_version) && (patch > *patch_version)))
1122 {
1123 *root_index=j;
1124 *product_family=products[i];
1125 *major_version=major;
1126 *minor_version=minor;
1127 *patch_version=patch;
1128 status=MagickTrue;
1129 }
1130 }
1131 (void) RegCloseKey(hkey);
1132 }
1133 }
1134 }
1135 if (status == MagickFalse)
1136 {
1137 *major_version=0;
1138 *minor_version=0;
1139 *patch_version=0;
1140 }
1141 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
1142 "version %d.%d.%d",*product_family,*major_version,*minor_version,*patch_version);
1143 return(status);
1144}
1145
1146static MagickBooleanType NTGhostscriptGetString(const char *name,
1147 BOOL *is_64_bit,char *value,const size_t length)
1148{
1149 char
1150 buffer[MagickPathExtent],
1151 *directory;
1152
1153 static const char
1154 *product_family = (const char *) NULL;
1155
1156 static BOOL
1157 is_64_bit_version = FALSE;
1158
1159 static int
1160 flags = 0,
1161 major_version = 0,
1162 minor_version = 0,
1163 patch_version = 0,
1164 root_index = 0;
1165
1166 unsigned char
1167 *registry_value;
1168
1169 /*
1170 Get a string from the installed Ghostscript.
1171 */
1172 *value='\0';
1173 directory=(char *) NULL;
1174 if (LocaleCompare(name,"GS_DLL") == 0)
1175 {
1176 directory=GetEnvironmentValue("MAGICK_GHOSTSCRIPT_PATH");
1177 if (directory != (char *) NULL)
1178 {
1179 (void) FormatLocaleString(buffer,MagickPathExtent,"%s%sgsdll64.dll",
1180 directory,DirectorySeparator);
1181 if (IsPathAccessible(buffer) != MagickFalse)
1182 {
1183 directory=DestroyString(directory);
1184 (void) CopyMagickString(value,buffer,length);
1185 if (is_64_bit != NULL)
1186 *is_64_bit=TRUE;
1187 return(MagickTrue);
1188 }
1189 (void) FormatLocaleString(buffer,MagickPathExtent,"%s%sgsdll32.dll",
1190 directory,DirectorySeparator);
1191 if (IsPathAccessible(buffer) != MagickFalse)
1192 {
1193 directory=DestroyString(directory);
1194 (void) CopyMagickString(value,buffer,length);
1195 if (is_64_bit != NULL)
1196 *is_64_bit=FALSE;
1197 return(MagickTrue);
1198 }
1199 return(MagickFalse);
1200 }
1201 }
1202 if (product_family == (const char *) NULL)
1203 {
1204 flags=0;
1205#if defined(KEY_WOW64_32KEY)
1206#if defined(_WIN64)
1207 flags=KEY_WOW64_64KEY;
1208#else
1209 flags=KEY_WOW64_32KEY;
1210#endif
1211 (void) NTLocateGhostscript(flags,&root_index,&product_family,
1212 &major_version,&minor_version,&patch_version);
1213 if (product_family == (const char *) NULL)
1214#if defined(_WIN64)
1215 flags=KEY_WOW64_32KEY;
1216 else
1217 is_64_bit_version=TRUE;
1218#else
1219 flags=KEY_WOW64_64KEY;
1220#endif
1221#endif
1222 }
1223 if (product_family == (const char *) NULL)
1224 {
1225 (void) NTLocateGhostscript(flags,&root_index,&product_family,
1226 &major_version,&minor_version,&patch_version);
1227#if !defined(_WIN64)
1228 is_64_bit_version=TRUE;
1229#endif
1230 }
1231 if (product_family == (const char *) NULL)
1232 return(MagickFalse);
1233 if (is_64_bit != NULL)
1234 *is_64_bit=is_64_bit_version;
1235 (void) FormatLocaleString(buffer,MagickPathExtent,"SOFTWARE\\%s\\%d.%.2d.%d",
1236 product_family,major_version,minor_version,patch_version);
1237 registry_value=NTGetRegistryValue(registry_roots[root_index].hkey,buffer,
1238 flags,name);
1239 if (registry_value == (unsigned char *) NULL)
1240 {
1241 (void) FormatLocaleString(buffer,MagickPathExtent,"SOFTWARE\\%s\\%d.%02d",
1242 product_family,major_version,minor_version);
1243 registry_value=NTGetRegistryValue(registry_roots[root_index].hkey,buffer,
1244 flags,name);
1245 }
1246 if (registry_value == (unsigned char *) NULL)
1247 return(MagickFalse);
1248 (void) CopyMagickString(value,(const char *) registry_value,length);
1249 registry_value=(unsigned char *) RelinquishMagickMemory(registry_value);
1250 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1251 "registry: \"%s\\%s\\%s\"=\"%s\"",registry_roots[root_index].name,
1252 buffer,name,value);
1253 return(MagickTrue);
1254}
1255
1256static MagickBooleanType NTGhostscriptDLL(char *path,int length)
1257{
1258 static char
1259 dll[MagickPathExtent] = { "" };
1260
1261 static BOOL
1262 is_64_bit;
1263
1264 *path='\0';
1265 if ((*dll == '\0') &&
1266 (NTGhostscriptGetString("GS_DLL",&is_64_bit,dll,sizeof(dll)) != MagickTrue))
1267 return(MagickFalse);
1268#if defined(_WIN64)
1269 if (!is_64_bit)
1270 return(MagickFalse);
1271#else
1272 if (is_64_bit)
1273 return(MagickFalse);
1274#endif
1275 (void) CopyMagickString(path,dll,length);
1276 return(MagickTrue);
1277}
1278
1279static inline MagickBooleanType NTGhostscriptHasValidHandle()
1280{
1281 if ((nt_ghost_info.delete_instance == NULL) || (ghost_info.exit == NULL) ||
1282 (nt_ghost_info.new_instance == NULL) || (ghost_info.set_stdio == NULL) ||
1283 (ghost_info.init_with_args == NULL) || (ghost_info.revision == NULL))
1284 return(MagickFalse);
1285 return(MagickTrue);
1286}
1287
1288MagickPrivate const GhostInfo *NTGhostscriptDLLVectors(void)
1289{
1290 char
1291 path[MaxTextExtent];
1292
1293 if (ghost_semaphore == (SemaphoreInfo *) NULL)
1294 ActivateSemaphoreInfo(&ghost_semaphore);
1295 LockSemaphoreInfo(ghost_semaphore);
1296 if (ghost_handle != (void *) NULL)
1297 {
1298 UnlockSemaphoreInfo(ghost_semaphore);
1299 if (NTGhostscriptHasValidHandle() == MagickFalse)
1300 return((GhostInfo *) NULL);
1301 return(&ghost_info);
1302 }
1303 if (NTGhostscriptDLL(path,sizeof(path)) == MagickFalse)
1304 {
1305 UnlockSemaphoreInfo(ghost_semaphore);
1306 return(FALSE);
1307 }
1308 ghost_handle=lt_dlopen(path);
1309 if (ghost_handle == (void *) NULL)
1310 {
1311 UnlockSemaphoreInfo(ghost_semaphore);
1312 return(FALSE);
1313 }
1314 (void) memset((void *) &nt_ghost_info,0,sizeof(NTGhostInfo));
1315 nt_ghost_info.delete_instance=(void (MagickDLLCall *)(gs_main_instance *)) (
1316 lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1317 nt_ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,
1318 void *)) (lt_dlsym(ghost_handle,"gsapi_new_instance"));
1319 nt_ghost_info.has_instance=MagickFalse;
1320 (void) memset((void *) &ghost_info,0,sizeof(GhostInfo));
1321 ghost_info.delete_instance=NTGhostscriptDeleteInstance;
1322 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1323 lt_dlsym(ghost_handle,"gsapi_exit");
1324 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1325 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1326 ghost_info.new_instance=NTGhostscriptNewInstance;
1327 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1328 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1329 ghost_info.set_stdio=(int (MagickDLLCall *)(gs_main_instance *,int(
1330 MagickDLLCall *)(void *,char *,int),int(MagickDLLCall *)(void *,
1331 const char *,int),int(MagickDLLCall *)(void *,const char *,int)))
1332 (lt_dlsym(ghost_handle,"gsapi_set_stdio"));
1333 ghost_info.revision=(int (MagickDLLCall *)(gsapi_revision_t *,int)) (
1334 lt_dlsym(ghost_handle,"gsapi_revision"));
1335 UnlockSemaphoreInfo(ghost_semaphore);
1336 if (NTGhostscriptHasValidHandle() == MagickFalse)
1337 return((GhostInfo *) NULL);
1338 return(&ghost_info);
1339}
1340
1341/*
1342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1343% %
1344% %
1345% %
1346% N T G h o s t s c r i p t E X E %
1347% %
1348% %
1349% %
1350%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351%
1352% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
1353% The method returns FALSE if a full path value is not obtained and returns
1354% a default path of gswin32c.exe.
1355%
1356% The format of the NTGhostscriptEXE method is:
1357%
1358% int NTGhostscriptEXE(char *path,int length)
1359%
1360% A description of each parameter follows:
1361%
1362% o path: return the Ghostscript executable path here.
1363%
1364% o length: length of buffer.
1365%
1366*/
1367MagickPrivate int NTGhostscriptEXE(char *path,int length)
1368{
1369 char
1370 *p;
1371
1372 static char
1373 program[MaxTextExtent] = { "" };
1374
1375 static BOOL
1376 is_64_bit_version = FALSE;
1377
1378 if (*program == '\0')
1379 {
1380 if (ghost_semaphore == (SemaphoreInfo *) NULL)
1381 ActivateSemaphoreInfo(&ghost_semaphore);
1382 LockSemaphoreInfo(ghost_semaphore);
1383 if (*program == '\0')
1384 {
1385 if (NTGhostscriptGetString("GS_DLL",&is_64_bit_version,program,
1386 sizeof(program)) == MagickFalse)
1387 {
1388 UnlockSemaphoreInfo(ghost_semaphore);
1389#if defined(_WIN64)
1390 (void) CopyMagickString(program,"gswin64c.exe",sizeof(program));
1391#else
1392 (void) CopyMagickString(program,"gswin32c.exe",sizeof(program));
1393#endif
1394 (void) CopyMagickString(path,program,length);
1395 return(FALSE);
1396 }
1397 p=strrchr(program,'\\');
1398 if (p != (char *) NULL)
1399 {
1400 p++;
1401 *p='\0';
1402 (void) ConcatenateMagickString(program,is_64_bit_version ?
1403 "gswin64c.exe" : "gswin32c.exe",sizeof(program));
1404 }
1405 }
1406 UnlockSemaphoreInfo(ghost_semaphore);
1407 }
1408 (void) CopyMagickString(path,program,length);
1409 return(TRUE);
1410}
1411
1412/*
1413%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1414% %
1415% %
1416% %
1417% N T G h o s t s c r i p t F o n t s %
1418% %
1419% %
1420% %
1421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422%
1423% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1424% returns FALSE if it cannot determine the font path.
1425%
1426% The format of the NTGhostscriptFonts method is:
1427%
1428% int NTGhostscriptFonts(char *path,int length)
1429%
1430% A description of each parameter follows:
1431%
1432% o path: return the font path here.
1433%
1434% o length: length of the path buffer.
1435%
1436*/
1437MagickPrivate int NTGhostscriptFonts(char *path,int length)
1438{
1439 char
1440 buffer[MaxTextExtent],
1441 *directory,
1442 filename[MaxTextExtent];
1443
1444 char
1445 *p,
1446 *q;
1447
1448 *path='\0';
1449 directory=GetEnvironmentValue("MAGICK_GHOSTSCRIPT_FONT_PATH");
1450 if (directory != (char *) NULL)
1451 {
1452 (void) CopyMagickString(buffer,directory,MaxTextExtent);
1453 directory=DestroyString(directory);
1454 }
1455 else
1456 {
1457 if (NTGhostscriptGetString("GS_LIB",NULL,buffer,MaxTextExtent) == MagickFalse)
1458 return(FALSE);
1459 }
1460 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1461 {
1462 (void) CopyMagickString(path,p+1,length+1);
1463 q=strchr(path,DirectoryListSeparator);
1464 if (q != (char *) NULL)
1465 *q='\0';
1466 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path,
1467 DirectorySeparator);
1468 if (IsPathAccessible(filename) != MagickFalse)
1469 return(TRUE);
1470 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sn019003l.pfb",path,
1471 DirectorySeparator);
1472 if (IsPathAccessible(filename) != MagickFalse)
1473 return(TRUE);
1474 }
1475 *path='\0';
1476 return(FALSE);
1477}
1478
1479/*
1480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1481% %
1482% %
1483% %
1484% N T G h o s t s c r i p t U n L o a d D L L %
1485% %
1486% %
1487% %
1488%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1489%
1490% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1491% it succeeds.
1492%
1493% The format of the NTGhostscriptUnLoadDLL method is:
1494%
1495% int NTGhostscriptUnLoadDLL(void)
1496%
1497*/
1498MagickPrivate int NTGhostscriptUnLoadDLL(void)
1499{
1500 int
1501 status;
1502
1503 if (ghost_semaphore == (SemaphoreInfo *) NULL)
1504 ActivateSemaphoreInfo(&ghost_semaphore);
1505 LockSemaphoreInfo(ghost_semaphore);
1506 status=FALSE;
1507 if (ghost_handle != (void *) NULL)
1508 {
1509 status=lt_dlclose(ghost_handle);
1510 ghost_handle=(void *) NULL;
1511 (void) memset((void *) &ghost_info,0,sizeof(GhostInfo));
1512 }
1513 UnlockSemaphoreInfo(ghost_semaphore);
1514 DestroySemaphoreInfo(&ghost_semaphore);
1515 return(status);
1516}
1517
1518/*
1519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1520% %
1521% %
1522% %
1523% N T I n i t i a l i z e L i b r a r y %
1524% %
1525% %
1526% %
1527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1528%
1529% NTInitializeLibrary() initializes the dynamic module loading subsystem.
1530%
1531% The format of the NTInitializeLibrary method is:
1532%
1533% int NTInitializeLibrary(void)
1534%
1535*/
1536MagickPrivate int NTInitializeLibrary(void)
1537{
1538 return(0);
1539}
1540
1541/*
1542%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1543% %
1544% %
1545% %
1546% N T I n i t i a l i z e W i n s o c k %
1547% %
1548% %
1549% %
1550%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1551%
1552% NTInitializeWinsock() initializes Winsock.
1553%
1554% The format of the NTInitializeWinsock method is:
1555%
1556% void NTInitializeWinsock(void)
1557%
1558*/
1559MagickPrivate void NTInitializeWinsock(MagickBooleanType use_lock)
1560{
1561 if (use_lock)
1562 {
1563 if (winsock_semaphore == (SemaphoreInfo *) NULL)
1564 ActivateSemaphoreInfo(&winsock_semaphore);
1565 LockSemaphoreInfo(winsock_semaphore);
1566 }
1567 if (wsaData == (WSADATA *) NULL)
1568 {
1569 wsaData=(WSADATA *) AcquireMagickMemory(sizeof(WSADATA));
1570 if (WSAStartup(MAKEWORD(2,2),wsaData) != 0)
1571 ThrowFatalException(CacheFatalError,"WSAStartup failed");
1572 }
1573 if (use_lock)
1574 UnlockSemaphoreInfo(winsock_semaphore);
1575}
1576
1577/*
1578%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1579% %
1580% %
1581% %
1582% N T L o n g P a t h s E n a b l e d %
1583% %
1584% %
1585% %
1586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1587%
1588% NTLongPathsEnabled() returns a boolean indicating whether long paths are
1589$ enabled.
1590%
1591% The format of the NTLongPathsEnabled method is:
1592%
1593% MagickBooleanType NTLongPathsEnabled()
1594%
1595*/
1596MagickExport MagickBooleanType NTLongPathsEnabled()
1597{
1598 if (long_paths_enabled == 2)
1599 {
1600 DWORD
1601 size,
1602 type,
1603 value;
1604
1605 HKEY
1606 registry_key;
1607
1608 LONG
1609 status;
1610
1611 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1612 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,
1613 "SYSTEM\\CurrentControlSet\\Control\\FileSystem",0,KEY_READ,
1614 &registry_key);
1615 if (status != ERROR_SUCCESS)
1616 {
1617 long_paths_enabled=0;
1618 RegCloseKey(registry_key);
1619 return(MagickFalse);
1620 }
1621 value=0;
1622 status=RegQueryValueExA(registry_key,"LongPathsEnabled",0,&type,NULL,
1623 NULL);
1624 if ((status != ERROR_SUCCESS) || (type != REG_DWORD))
1625 {
1626 long_paths_enabled=0;
1627 RegCloseKey(registry_key);
1628 return(MagickFalse);
1629 }
1630 status=RegQueryValueExA(registry_key,"LongPathsEnabled",0,&type,
1631 (LPBYTE) &value,&size);
1632 RegCloseKey(registry_key);
1633 if (status != ERROR_SUCCESS)
1634 {
1635 long_paths_enabled=0;
1636 return(MagickFalse);
1637 }
1638 long_paths_enabled=(size_t) value;
1639 }
1640 return(long_paths_enabled == 1 ? MagickTrue : MagickFalse);
1641}
1642
1643/*
1644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1645% %
1646% %
1647% %
1648+ N T M a p M e m o r y %
1649% %
1650% %
1651% %
1652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1653%
1654% NTMapMemory() emulates the Unix method of the same name.
1655%
1656% The format of the NTMapMemory method is:
1657%
1658% void *NTMapMemory(char *address,size_t length,int protection,int access,
1659% int file,MagickOffsetType offset)
1660%
1661*/
1662MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
1663 int flags,int file,MagickOffsetType offset)
1664{
1665 DWORD
1666 access_mode,
1667 high_length,
1668 high_offset,
1669 low_length,
1670 low_offset,
1671 protection_mode;
1672
1673 HANDLE
1674 file_handle,
1675 map_handle;
1676
1677 void
1678 *map;
1679
1680 (void) address;
1681 access_mode=0;
1682 file_handle=INVALID_HANDLE_VALUE;
1683 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1684 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1685 map_handle=INVALID_HANDLE_VALUE;
1686 map=(void *) NULL;
1687 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1688 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1689 protection_mode=0;
1690 if (protection & PROT_WRITE)
1691 {
1692 access_mode=FILE_MAP_WRITE;
1693 if (!(flags & MAP_PRIVATE))
1694 protection_mode=PAGE_READWRITE;
1695 else
1696 {
1697 access_mode=FILE_MAP_COPY;
1698 protection_mode=PAGE_WRITECOPY;
1699 }
1700 }
1701 else
1702 if (protection & PROT_READ)
1703 {
1704 access_mode=FILE_MAP_READ;
1705 protection_mode=PAGE_READONLY;
1706 }
1707 if ((file == -1) && (flags & MAP_ANONYMOUS))
1708 file_handle=INVALID_HANDLE_VALUE;
1709 else
1710 file_handle=(HANDLE) _get_osfhandle(file);
1711 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1712 low_length,0);
1713 if (map_handle)
1714 {
1715 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1716 length);
1717 CloseHandle(map_handle);
1718 }
1719 if (map == (void *) NULL)
1720 return((void *) ((char *) MAP_FAILED));
1721 return((void *) ((char *) map));
1722}
1723
1724/*
1725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1726% %
1727% %
1728% %
1729% N T O p e n D i r e c t o r y %
1730% %
1731% %
1732% %
1733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1734%
1735% NTOpenDirectory() opens the directory named by filename and associates a
1736% directory stream with it.
1737%
1738% The format of the NTOpenDirectory method is:
1739%
1740% DIR *NTOpenDirectory(const char *path)
1741%
1742% A description of each parameter follows:
1743%
1744% o entry: Specifies a pointer to a DIR structure.
1745%
1746*/
1747MagickPrivate DIR *NTOpenDirectory(const char *path)
1748{
1749 DIR
1750 *entry;
1751
1752 size_t
1753 length;
1754
1755 wchar_t
1756 file_specification[MaxTextExtent];
1757
1758 assert(path != (const char *) NULL);
1759 length=MultiByteToWideChar(CP_UTF8,0,path,-1,file_specification,
1760 MaxTextExtent);
1761 if (length == 0)
1762 return((DIR *) NULL);
1763 if(wcsncat(file_specification,L"\\*.*",MaxTextExtent-wcslen(
1764 file_specification)-1) == (wchar_t*) NULL)
1765 return((DIR *) NULL);
1766 entry=(DIR *) AcquireCriticalMemory(sizeof(DIR));
1767 entry->firsttime=TRUE;
1768 entry->hSearch=FindFirstFileW(file_specification,&entry->Win32FindData);
1769 if (entry->hSearch == INVALID_HANDLE_VALUE)
1770 {
1771 entry=(DIR *) RelinquishMagickMemory(entry);
1772 return((DIR *) NULL);
1773 }
1774 return(entry);
1775}
1776
1777/*
1778%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1779% %
1780% %
1781% %
1782% N T O p e n L i b r a r y %
1783% %
1784% %
1785% %
1786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1787%
1788% NTOpenLibrary() loads a dynamic module into memory and returns a handle that
1789% can be used to access the various procedures in the module.
1790%
1791% The format of the NTOpenLibrary method is:
1792%
1793% void *NTOpenLibrary(const char *filename)
1794%
1795% A description of each parameter follows:
1796%
1797% o path: Specifies a pointer to string representing dynamic module that
1798% is to be loaded.
1799%
1800*/
1801
1802static inline const char *GetSearchPath(void)
1803{
1804#if defined(MAGICKCORE_LTDL_DELEGATE)
1805 return(lt_dlgetsearchpath());
1806#else
1807 return(lt_slsearchpath);
1808#endif
1809}
1810
1811static UINT ChangeErrorMode(void)
1812{
1813 typedef UINT
1814 (CALLBACK *GETERRORMODE)(void);
1815
1816 GETERRORMODE
1817 getErrorMode;
1818
1819 HMODULE
1820 handle;
1821
1822 UINT
1823 mode;
1824
1825 mode=SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
1826
1827 handle=GetModuleHandle("kernel32.dll");
1828 if (handle == (HMODULE) NULL)
1829 return SetErrorMode(mode);
1830
1831 getErrorMode=(GETERRORMODE) NTGetLibrarySymbol(handle,"GetErrorMode");
1832 if (getErrorMode != (GETERRORMODE) NULL)
1833 mode=getErrorMode() | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
1834
1835 return SetErrorMode(mode);
1836}
1837
1838static inline void *NTLoadLibrary(const char *filename)
1839{
1840 int
1841 length;
1842
1843 wchar_t
1844 path[MaxTextExtent];
1845
1846 length=MultiByteToWideChar(CP_UTF8,0,filename,-1,path,MaxTextExtent);
1847 if (length == 0)
1848 return((void *) NULL);
1849 return (void *) LoadLibraryExW(path,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1850}
1851
1852MagickPrivate void *NTOpenLibrary(const char *filename)
1853{
1854 char
1855 path[MaxTextExtent];
1856
1857 const char
1858 *p,
1859 *q;
1860
1861 UINT
1862 mode;
1863
1864 void
1865 *handle;
1866
1867 mode=ChangeErrorMode();
1868 handle=NTLoadLibrary(filename);
1869 if (handle == (void *) NULL)
1870 {
1871 p=GetSearchPath();
1872 while (p != (const char*) NULL)
1873 {
1874 q=strchr(p,DirectoryListSeparator);
1875 if (q != (const char*) NULL)
1876 (void) CopyMagickString(path,p,q-p+1);
1877 else
1878 (void) CopyMagickString(path,p,MaxTextExtent);
1879 (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
1880 (void) ConcatenateMagickString(path,filename,MaxTextExtent);
1881 handle=NTLoadLibrary(path);
1882 if (handle != (void *) NULL || q == (const char*) NULL)
1883 break;
1884 p=q+1;
1885 }
1886 }
1887 SetErrorMode(mode);
1888 return(handle);
1889}
1890
1891/*
1892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1893% %
1894% %
1895% %
1896% N T R e a d D i r e c t o r y %
1897% %
1898% %
1899% %
1900%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1901%
1902% NTReadDirectory() returns a pointer to a structure representing the
1903% directory entry at the current position in the directory stream to which
1904% entry refers.
1905%
1906% The format of the NTReadDirectory
1907%
1908% NTReadDirectory(entry)
1909%
1910% A description of each parameter follows:
1911%
1912% o entry: Specifies a pointer to a DIR structure.
1913%
1914*/
1915MagickPrivate struct dirent *NTReadDirectory(DIR *entry)
1916{
1917 int
1918 status;
1919
1920 size_t
1921 length;
1922
1923 if (entry == (DIR *) NULL)
1924 return((struct dirent *) NULL);
1925 if (!entry->firsttime)
1926 {
1927 status=FindNextFileW(entry->hSearch,&entry->Win32FindData);
1928 if (status == 0)
1929 return((struct dirent *) NULL);
1930 }
1931 length=WideCharToMultiByte(CP_UTF8,0,entry->Win32FindData.cFileName,-1,
1932 entry->file_info.d_name,sizeof(entry->file_info.d_name),NULL,NULL);
1933 if (length == 0)
1934 return((struct dirent *) NULL);
1935 entry->firsttime=FALSE;
1936 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1937 return(&entry->file_info);
1938}
1939
1940/*
1941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1942% %
1943% %
1944% %
1945% N T R e g i s t r y K e y L o o k u p %
1946% %
1947% %
1948% %
1949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1950%
1951% NTRegistryKeyLookup() returns ImageMagick installation path settings
1952% stored in the Windows Registry. Path settings are specific to the
1953% installed ImageMagick version so that multiple Image Magick installations
1954% may coexist.
1955%
1956% Values are stored in the registry under a base path similar to
1957% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\6.7.4\Q:16" or
1958% "HKEY_CURRENT_USER/SOFTWARE\ImageMagick\6.7.4\Q:16". The provided subkey
1959% is appended to this base path to form the full key.
1960%
1961% The format of the NTRegistryKeyLookup method is:
1962%
1963% unsigned char *NTRegistryKeyLookup(const char *subkey)
1964%
1965% A description of each parameter follows:
1966%
1967% o subkey: Specifies a string that identifies the registry object.
1968% Currently supported sub-keys include: "BinPath", "ConfigurePath",
1969% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1970%
1971*/
1972MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey)
1973{
1974 char
1975 package_key[MaxTextExtent] = "";
1976
1977 unsigned char
1978 *value;
1979
1980 (void) FormatLocaleString(package_key,MagickPathExtent,
1981 "SOFTWARE\\%s\\%s\\Q:%d",MagickPackageName,MagickLibVersionText,
1982 MAGICKCORE_QUANTUM_DEPTH);
1983 value=NTGetRegistryValue(HKEY_LOCAL_MACHINE,package_key,0,subkey);
1984 if (value == (unsigned char *) NULL)
1985 value=NTGetRegistryValue(HKEY_CURRENT_USER,package_key,0,subkey);
1986 return(value);
1987}
1988
1989/*
1990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1991% %
1992% %
1993% %
1994% N T R e p o r t E v e n t %
1995% %
1996% %
1997% %
1998%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1999%
2000% NTReportEvent() reports an event.
2001%
2002% The format of the NTReportEvent method is:
2003%
2004% MagickBooleanType NTReportEvent(const char *event,
2005% const MagickBooleanType error)
2006%
2007% A description of each parameter follows:
2008%
2009% o event: the event.
2010%
2011% o error: MagickTrue the event is an error.
2012%
2013*/
2014MagickPrivate MagickBooleanType NTReportEvent(const char *event,
2015 const MagickBooleanType error)
2016{
2017 const char
2018 *events[1];
2019
2020 HANDLE
2021 handle;
2022
2023 WORD
2024 type;
2025
2026 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
2027 if (handle == NULL)
2028 return(MagickFalse);
2029 events[0]=event;
2030 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
2031 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
2032 DeregisterEventSource(handle);
2033 return(MagickTrue);
2034}
2035
2036/*
2037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2038% %
2039% %
2040% %
2041% N T R e s o u r c e T o B l o b %
2042% %
2043% %
2044% %
2045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2046%
2047% NTResourceToBlob() returns a blob containing the contents of the resource
2048% in the current executable specified by the id parameter. This currently
2049% used to retrieve MGK files tha have been embedded into the various command
2050% line utilities.
2051%
2052% The format of the NTResourceToBlob method is:
2053%
2054% unsigned char *NTResourceToBlob(const char *id)
2055%
2056% A description of each parameter follows:
2057%
2058% o id: Specifies a string that identifies the resource.
2059%
2060*/
2061MagickPrivate unsigned char *NTResourceToBlob(const char *id)
2062{
2063
2064#ifndef MAGICKCORE_LIBRARY_NAME
2065 char
2066 path[MaxTextExtent];
2067#endif
2068
2069 DWORD
2070 length;
2071
2072 HGLOBAL
2073 global;
2074
2075 HMODULE
2076 handle;
2077
2078 HRSRC
2079 resource;
2080
2081 unsigned char
2082 *blob,
2083 *value;
2084
2085 assert(id != (const char *) NULL);
2086 if (IsEventLogging() != MagickFalse)
2087 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
2088#ifdef MAGICKCORE_LIBRARY_NAME
2089 handle=GetModuleHandle(MAGICKCORE_LIBRARY_NAME);
2090#else
2091 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
2092 DirectorySeparator,GetClientName());
2093 if (IsPathAccessible(path) != MagickFalse)
2094 handle=GetModuleHandle(path);
2095 else
2096 handle=GetModuleHandle(0);
2097#endif
2098 if (!handle)
2099 return((unsigned char *) NULL);
2100 resource=FindResource(handle,id,"IMAGEMAGICK");
2101 if (!resource)
2102 return((unsigned char *) NULL);
2103 global=LoadResource(handle,resource);
2104 if (!global)
2105 return((unsigned char *) NULL);
2106 length=SizeofResource(handle,resource);
2107 value=(unsigned char *) LockResource(global);
2108 if (!value)
2109 {
2110 FreeResource(global);
2111 return((unsigned char *) NULL);
2112 }
2113 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
2114 sizeof(*blob));
2115 if (blob != (unsigned char *) NULL)
2116 {
2117 (void) memcpy(blob,value,length);
2118 blob[length]='\0';
2119 }
2120 UnlockResource(global);
2121 FreeResource(global);
2122 return(blob);
2123}
2124
2125/*
2126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2127% %
2128% %
2129% %
2130% N T S e t S e a r c h P a t h %
2131% %
2132% %
2133% %
2134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2135%
2136% NTSetSearchPath() sets the current locations that the subsystem should
2137% look at to find dynamically loadable modules.
2138%
2139% The format of the NTSetSearchPath method is:
2140%
2141% int NTSetSearchPath(const char *path)
2142%
2143% A description of each parameter follows:
2144%
2145% o path: Specifies a pointer to string representing the search path
2146% for DLL's that can be dynamically loaded.
2147%
2148*/
2149MagickPrivate int NTSetSearchPath(const char *path)
2150{
2151#if defined(MAGICKCORE_LTDL_DELEGATE)
2152 lt_dlsetsearchpath(path);
2153#else
2154 if (lt_slsearchpath != (char *) NULL)
2155 lt_slsearchpath=DestroyString(lt_slsearchpath);
2156 if (path != (char *) NULL)
2157 lt_slsearchpath=AcquireString(path);
2158#endif
2159 return(0);
2160}
2161
2162/*
2163%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2164% %
2165% %
2166% %
2167% N T S y s t e m C o m m a n d %
2168% %
2169% %
2170% %
2171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2172%
2173% NTSystemCommand() executes the specified command and waits until it
2174% terminates. The returned value is the exit status of the command.
2175%
2176% The format of the NTSystemCommand method is:
2177%
2178% int NTSystemCommand(MagickFalse,const char *command)
2179%
2180% A description of each parameter follows:
2181%
2182% o command: This string is the command to execute.
2183%
2184% o output: an optional buffer to store the output from stderr/stdout.
2185%
2186*/
2187MagickPrivate int NTSystemCommand(const char *command,char *output)
2188{
2189#define CleanupOutputHandles \
2190 if (read_output != (HANDLE) NULL) \
2191 { \
2192 CloseHandle(read_output); \
2193 read_output=(HANDLE) NULL; \
2194 CloseHandle(write_output); \
2195 write_output=(HANDLE) NULL; \
2196 }
2197
2198#define CopyLastError \
2199 if (output != (char *) NULL) \
2200 { \
2201 error=NTGetLastError(); \
2202 if (error != (char *) NULL) \
2203 { \
2204 CopyMagickString(output,error,MaxTextExtent); \
2205 error=DestroyString(error); \
2206 } \
2207 }
2208
2209 char
2210 *error,
2211 local_command[MaxTextExtent];
2212
2213 DWORD
2214 child_status;
2215
2216 int
2217 status;
2218
2219 MagickBooleanType
2220 asynchronous;
2221
2222 HANDLE
2223 read_output,
2224 write_output;
2225
2226 PROCESS_INFORMATION
2227 process_info;
2228
2229 size_t
2230 output_offset;
2231
2232 STARTUPINFO
2233 startup_info;
2234
2235 if (command == (char *) NULL)
2236 return(-1);
2237 read_output=(HANDLE) NULL;
2238 write_output=(HANDLE) NULL;
2239 GetStartupInfo(&startup_info);
2240 startup_info.dwFlags=STARTF_USESHOWWINDOW;
2241 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
2242 (void) CopyMagickString(local_command,command,MaxTextExtent);
2243 asynchronous=command[strlen(command)-1] == '&' ? MagickTrue : MagickFalse;
2244 if (asynchronous != MagickFalse)
2245 {
2246 local_command[strlen(command)-1]='\0';
2247 startup_info.wShowWindow=SW_SHOWDEFAULT;
2248 }
2249 else
2250 {
2251 if (command[strlen(command)-1] == '|')
2252 local_command[strlen(command)-1]='\0';
2253 else
2254 startup_info.wShowWindow=SW_HIDE;
2255 read_output=(HANDLE) NULL;
2256 if (output != (char *) NULL)
2257 {
2258 if (CreatePipe(&read_output,&write_output,NULL,0))
2259 {
2260 if (SetHandleInformation(write_output,HANDLE_FLAG_INHERIT,
2261 HANDLE_FLAG_INHERIT))
2262 {
2263 startup_info.dwFlags|=STARTF_USESTDHANDLES;
2264 startup_info.hStdOutput=write_output;
2265 startup_info.hStdError=write_output;
2266 }
2267 else
2268 CleanupOutputHandles;
2269 }
2270 else
2271 read_output=(HANDLE) NULL;
2272 }
2273 }
2274 status=CreateProcess((LPCTSTR) NULL,local_command,(LPSECURITY_ATTRIBUTES)
2275 NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) TRUE,(DWORD)
2276 NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
2277 &process_info);
2278 if (status == 0)
2279 {
2280 CopyLastError;
2281 CleanupOutputHandles;
2282 return(-1);
2283 }
2284 if (output != (char *) NULL)
2285 *output='\0';
2286 if (asynchronous != MagickFalse)
2287 return(status == 0);
2288 output_offset=0;
2289 status=STATUS_TIMEOUT;
2290 while (status == STATUS_TIMEOUT)
2291 {
2292 DWORD
2293 size;
2294
2295 status=WaitForSingleObject(process_info.hProcess,1000);
2296 size=0;
2297 if (read_output != (HANDLE) NULL)
2298 if (!PeekNamedPipe(read_output,NULL,0,NULL,&size,NULL))
2299 break;
2300 while (size > 0)
2301 {
2302 char
2303 buffer[MagickPathExtent];
2304
2305 DWORD
2306 bytes_read;
2307
2308 if (ReadFile(read_output,buffer,MagickPathExtent-1,&bytes_read,NULL))
2309 {
2310 size_t
2311 count;
2312
2313 count=MagickMin(MagickPathExtent-output_offset,
2314 (size_t) bytes_read+1);
2315 if (count > 0)
2316 {
2317 CopyMagickString(output+output_offset,buffer,count);
2318 output_offset+=count-1;
2319 }
2320 }
2321 if (!PeekNamedPipe(read_output,NULL,0,NULL,&size,NULL))
2322 break;
2323 }
2324 }
2325 if (status != WAIT_OBJECT_0)
2326 {
2327 CopyLastError;
2328 CleanupOutputHandles;
2329 return(status);
2330 }
2331 status=GetExitCodeProcess(process_info.hProcess,&child_status);
2332 if (status == 0)
2333 {
2334 CopyLastError;
2335 CleanupOutputHandles;
2336 return(-1);
2337 }
2338 CloseHandle(process_info.hProcess);
2339 CloseHandle(process_info.hThread);
2340 CleanupOutputHandles;
2341 return((int) child_status);
2342}
2343
2344/*
2345%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2346% %
2347% %
2348% %
2349% N T S y s t e m C o n i f i g u r a t i o n %
2350% %
2351% %
2352% %
2353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2354%
2355% NTSystemConfiguration() provides a way for the application to determine
2356% values for system limits or options at runtime.
2357%
2358% The format of the exit method is:
2359%
2360% ssize_t NTSystemConfiguration(int name)
2361%
2362% A description of each parameter follows:
2363%
2364% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
2365%
2366*/
2367MagickPrivate ssize_t NTSystemConfiguration(int name)
2368{
2369 switch (name)
2370 {
2371 case _SC_PAGE_SIZE:
2372 {
2373 SYSTEM_INFO
2374 system_info;
2375
2376 GetSystemInfo(&system_info);
2377 return(system_info.dwPageSize);
2378 }
2379 case _SC_PHYS_PAGES:
2380 {
2381 MEMORYSTATUSEX
2382 status;
2383
2384 SYSTEM_INFO
2385 system_info;
2386
2387 status.dwLength=sizeof(status);
2388 if (GlobalMemoryStatusEx(&status) == 0)
2389 return(0L);
2390 GetSystemInfo(&system_info);
2391 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
2392 }
2393 case _SC_OPEN_MAX:
2394 return(2048);
2395 default:
2396 break;
2397 }
2398 return(-1);
2399}
2400
2401/*
2402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2403% %
2404% %
2405% %
2406% N T T r u n c a t e F i l e %
2407% %
2408% %
2409% %
2410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2411%
2412% NTTruncateFile() truncates a file to a specified length.
2413%
2414% The format of the NTTruncateFile method is:
2415%
2416% int NTTruncateFile(int file,off_t length)
2417%
2418% A description of each parameter follows:
2419%
2420% o file: the file.
2421%
2422% o length: the file length.
2423%
2424*/
2425MagickPrivate int NTTruncateFile(int file,off_t length)
2426{
2427 DWORD
2428 file_pointer;
2429
2430 HANDLE
2431 file_handle;
2432
2433 long
2434 high,
2435 low;
2436
2437 file_handle=(HANDLE) _get_osfhandle(file);
2438 if (file_handle == INVALID_HANDLE_VALUE)
2439 return(-1);
2440 low=(long) (length & 0xffffffffUL);
2441 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
2442 file_pointer=SetFilePointer(file_handle,low,&high,FILE_BEGIN);
2443 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2444 return(-1);
2445 if (SetEndOfFile(file_handle) == 0)
2446 return(-1);
2447 return(0);
2448}
2449
2450/*
2451%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2452% %
2453% %
2454% %
2455+ N T U n m a p M e m o r y %
2456% %
2457% %
2458% %
2459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2460%
2461% NTUnmapMemory() emulates the Unix munmap method.
2462%
2463% The format of the NTUnmapMemory method is:
2464%
2465% int NTUnmapMemory(void *map,size_t length)
2466%
2467% A description of each parameter follows:
2468%
2469% o map: the address of the binary large object.
2470%
2471% o length: the length of the binary large object.
2472%
2473*/
2474MagickPrivate int NTUnmapMemory(void *map,size_t length)
2475{
2476 (void) length;
2477 if (UnmapViewOfFile(map) == 0)
2478 return(-1);
2479 return(0);
2480}
2481
2482/*
2483%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2484% %
2485% %
2486% %
2487% N T U s e r T i m e %
2488% %
2489% %
2490% %
2491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2492%
2493% NTUserTime() returns the total time the process has been scheduled (e.g.
2494% seconds) since the last call to StartTimer().
2495%
2496% The format of the UserTime method is:
2497%
2498% double NTUserTime(void)
2499%
2500*/
2501MagickPrivate double NTUserTime(void)
2502{
2503 DWORD
2504 status;
2505
2506 FILETIME
2507 create_time,
2508 exit_time;
2509
2510 OSVERSIONINFO
2511 OsVersionInfo;
2512
2513 union
2514 {
2515 FILETIME
2516 filetime;
2517
2518 __int64
2519 filetime64;
2520 } kernel_time;
2521
2522 union
2523 {
2524 FILETIME
2525 filetime;
2526
2527 __int64
2528 filetime64;
2529 } user_time;
2530
2531 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2532 GetVersionEx(&OsVersionInfo);
2533 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2534 return(NTElapsedTime());
2535 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2536 &kernel_time.filetime,&user_time.filetime);
2537 if (status != TRUE)
2538 return(0.0);
2539 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2540}
2541
2542/*
2543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2544% %
2545% %
2546% %
2547% N T W a r n i n g H a n d l e r %
2548% %
2549% %
2550% %
2551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2552%
2553% NTWarningHandler() displays a warning reason.
2554%
2555% The format of the NTWarningHandler method is:
2556%
2557% void NTWarningHandler(const ExceptionType severity,const char *reason,
2558% const char *description)
2559%
2560% A description of each parameter follows:
2561%
2562% o severity: Specifies the numeric warning category.
2563%
2564% o reason: Specifies the reason to display before terminating the
2565% program.
2566%
2567% o description: Specifies any description to the reason.
2568%
2569*/
2570MagickPrivate void NTWarningHandler(const ExceptionType severity,
2571 const char *reason,const char *description)
2572{
2573 char
2574 buffer[2*MaxTextExtent];
2575
2576 (void) severity;
2577 if (reason == (char *) NULL)
2578 return;
2579 if (description == (char *) NULL)
2580 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
2581 reason);
2582 else
2583 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
2584 GetClientName(),reason,description);
2585 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2586 MB_SETFOREGROUND | MB_ICONINFORMATION);
2587}
2588
2589/*
2590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2591% %
2592% %
2593% %
2594% N T W i n d o w s G e n e s i s %
2595% %
2596% %
2597% %
2598%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2599%
2600% NTWindowsGenesis() initializes the MagickCore Windows environment.
2601%
2602% The format of the NTWindowsGenesis method is:
2603%
2604% void NTWindowsGenesis(void)
2605%
2606*/
2607MagickPrivate void NTWindowsGenesis(void)
2608{
2609 char
2610 *mode;
2611
2612 mode=GetEnvironmentValue("MAGICK_ERRORMODE");
2613 if (mode != (char *) NULL)
2614 {
2615 (void) SetErrorMode(StringToInteger(mode));
2616 mode=DestroyString(mode);
2617 }
2618#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
2619 if (IsEventLogging() != MagickFalse)
2620 {
2621 int
2622 debug;
2623
2624 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
2625 //debug |= _CRTDBG_CHECK_ALWAYS_DF;
2626 debug |= _CRTDBG_DELAY_FREE_MEM_DF;
2627 debug |= _CRTDBG_LEAK_CHECK_DF;
2628 (void) _CrtSetDbgFlag(debug);
2629
2630 //_ASSERTE(_CrtCheckMemory());
2631
2632 //_CrtSetBreakAlloc(42);
2633 }
2634#endif
2635#if defined(MAGICKCORE_INSTALLED_SUPPORT)
2636 {
2637 unsigned char
2638 *path;
2639
2640 path=NTRegistryKeyLookup("LibPath");
2641 if (path != (unsigned char *) NULL)
2642 {
2643 size_t
2644 length;
2645
2646 wchar_t
2647 lib_path[MagickPathExtent];
2648
2649 length=MultiByteToWideChar(CP_UTF8,0,(char *) path,-1,lib_path,
2650 MagickPathExtent);
2651 if (length != 0)
2652 SetDllDirectoryW(lib_path);
2653 path=(unsigned char *) RelinquishMagickMemory(path);
2654 }
2655 }
2656#endif
2657}
2658
2659/*
2660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2661% %
2662% %
2663% %
2664% N T W i n d o w s T e r m i n u s %
2665% %
2666% %
2667% %
2668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2669%
2670% NTWindowsTerminus() terminates the MagickCore Windows environment.
2671%
2672% The format of the NTWindowsTerminus method is:
2673%
2674% void NTWindowsTerminus(void)
2675%
2676*/
2677MagickPrivate void NTWindowsTerminus(void)
2678{
2679 NTGhostscriptUnLoadDLL();
2680 if (winsock_semaphore == (SemaphoreInfo *) NULL)
2681 ActivateSemaphoreInfo(&winsock_semaphore);
2682 LockSemaphoreInfo(winsock_semaphore);
2683 if (wsaData != (WSADATA *) NULL)
2684 {
2685 WSACleanup();
2686 wsaData=(WSADATA *) RelinquishMagickMemory((void *) wsaData);
2687 }
2688 UnlockSemaphoreInfo(winsock_semaphore);
2689 DestroySemaphoreInfo(&winsock_semaphore);
2690}
2691#endif
Definition: mac.h:42
Definition: mac.h:54