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