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