]> granicus.if.org Git - imagemagick/blob - magick/nt-base.c
(no commit message)
[imagemagick] / magick / nt-base.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                                 N   N  TTTTT                                %
7 %                                 NN  N    T                                  %
8 %                                 N N N    T                                  %
9 %                                 N  NN    T                                  %
10 %                                 N   N    T                                  %
11 %                                                                             %
12 %                                                                             %
13 %                   Windows NT Utility Methods for MagickCore                 %
14 %                                                                             %
15 %                               Software Design                               %
16 %                                 John Cristy                                 %
17 %                                December 1996                                %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2011 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 "magick/studio.h"
42 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
43 #include "magick/client.h"
44 #include "magick/log.h"
45 #include "magick/magick.h"
46 #include "magick/memory_.h"
47 #include "magick/resource_.h"
48 #include "magick/timer.h"
49 #include "magick/string_.h"
50 #include "magick/utility.h"
51 #include "magick/version.h"
52 #if defined(MAGICKCORE_LTDL_DELEGATE)
53 #  include "ltdl.h"
54 #endif
55 #include "magick/nt-base.h"
56 #if defined(MAGICKCORE_CIPHER_SUPPORT)
57 #include <ntsecapi.h>
58 #include <wincrypt.h>
59 #endif
60 \f
61 /*
62   Define declarations.
63 */
64 #if !defined(MAP_FAILED)
65 #define MAP_FAILED      ((void *) -1)
66 #endif
67 \f
68 /*
69   Static declarations.
70 */
71 #if !defined(MAGICKCORE_LTDL_DELEGATE)
72 static char
73   *lt_slsearchpath = (char *) NULL;
74 #endif
75
76 static GhostInfo
77   ghost_info;
78
79 static void
80   *ghost_handle = (void *) NULL;
81 \f
82 /*
83   External declarations.
84 */
85 #if !defined(MAGICKCORE_WINDOWS_SUPPORT)
86 extern "C" BOOL WINAPI
87   DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
88 #endif
89 \f
90 /*
91 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 %                                                                             %
93 %                                                                             %
94 %                                                                             %
95 %   D l l M a i n                                                             %
96 %                                                                             %
97 %                                                                             %
98 %                                                                             %
99 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100 %
101 %  DllMain() is an entry point to the DLL which is called when processes and
102 %  threads are initialized and terminated, or upon calls to the Windows
103 %  LoadLibrary and FreeLibrary functions.
104 %
105 %  The function returns TRUE of it succeeds, or FALSE if initialization fails.
106 %
107 %  The format of the DllMain method is:
108 %
109 %    BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
110 %
111 %  A description of each parameter follows:
112 %
113 %    o handle: handle to the DLL module
114 %
115 %    o reason: reason for calling function:
116 %
117 %      DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
118 %                           space of current process.
119 %      DLL_THREAD_ATTACH - Indicates that the current process is
120 %                          creating a new thread.  Called under the
121 %                          context of the new thread.
122 %      DLL_THREAD_DETACH - Indicates that the thread is exiting.
123 %                          Called under the context of the exiting
124 %                          thread.
125 %      DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
126 %                           from the virtual address space of the
127 %                           current process.
128 %
129 %    o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
130 %                   and DLL_PROCESS_DETACH.
131 %
132 */
133 #if defined(_DLL) && defined( ProvideDllMain )
134 BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
135 {
136   switch (reason)
137   {
138     case DLL_PROCESS_ATTACH:
139     {
140       char
141         *module_path;
142
143       ssize_t
144         count;
145
146       module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
147         sizeof(*module_path));
148       if (module_path == (char *) NULL)
149         return(FALSE);
150       count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
151       if (count != 0)
152         {
153           char
154             *path;
155
156           for ( ; count > 0; count--)
157             if (module_path[count] == '\\')
158               {
159                 module_path[count+1]='\0';
160                 break;
161               }
162           MagickCoreGenesis(module_path,MagickFalse);
163           path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
164           if (path == (char *) NULL)
165             {
166               module_path=DestroyString(module_path);
167               return(FALSE);
168             }
169           count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
170           if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
171             {
172               if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
173                 {
174                   char
175                     *variable;
176
177                   variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
178                     sizeof(*variable));
179                   if (variable == (char *) NULL)
180                     {
181                       path=DestroyString(path);
182                       module_path=DestroyString(module_path);
183                       return(FALSE);
184                     }
185                   (void) FormatMagickString(variable,16*MaxTextExtent,
186                     "%s;%s",module_path,path);
187                   SetEnvironmentVariable("PATH",variable);
188                   variable=DestroyString(variable);
189                 }
190             }
191           path=DestroyString(path);
192         }
193       module_path=DestroyString(module_path);
194       break;
195     }
196     case DLL_PROCESS_DETACH:
197     {
198       MagickCoreTerminus();
199       break;
200     }
201     default:
202       break;
203   }
204   return(TRUE);
205 }
206 #endif
207 \f
208 /*
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210 %                                                                             %
211 %                                                                             %
212 %                                                                             %
213 %   E x i t                                                                   %
214 %                                                                             %
215 %                                                                             %
216 %                                                                             %
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218 %
219 %  Exit() calls TerminateProcess for Win95.
220 %
221 %  The format of the exit method is:
222 %
223 %      int Exit(int status)
224 %
225 %  A description of each parameter follows:
226 %
227 %    o status: an integer value representing the status of the terminating
228 %      process.
229 %
230 */
231 MagickExport int Exit(int status)
232 {
233   if (IsWindows95())
234     TerminateProcess(GetCurrentProcess(),(unsigned int) status);
235   exit(status);
236   return(0);
237 }
238 \f
239 #if !defined(__MINGW32__)
240 /*
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242 %                                                                             %
243 %                                                                             %
244 %                                                                             %
245 %   g e t t i m e o f d a y                                                   %
246 %                                                                             %
247 %                                                                             %
248 %                                                                             %
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 %
251 %  The gettimeofday() method get the time of day.
252 %
253 %  The format of the gettimeofday method is:
254 %
255 %      int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
256 %
257 %  A description of each parameter follows:
258 %
259 %    o time_value: the time value.
260 %
261 %    o time_zone: the time zone.
262 %
263 */
264 MagickExport int gettimeofday (struct timeval *time_value,
265   struct timezone *time_zone)
266 {
267 #define EpochFiletime  MagickLLConstant(116444736000000000)
268
269   static int
270     is_tz_set;
271
272   if (time_value != (struct timeval *) NULL)
273     {
274       FILETIME
275         file_time;
276
277       __int64
278         time;
279
280       LARGE_INTEGER
281         date_time;
282
283       GetSystemTimeAsFileTime(&file_time);
284       date_time.LowPart=file_time.dwLowDateTime;
285       date_time.HighPart=file_time.dwHighDateTime;
286       time=date_time.QuadPart;
287       time-=EpochFiletime;
288       time/=10;
289       time_value->tv_sec=(ssize_t) (time / 1000000);
290       time_value->tv_usec=(ssize_t) (time % 1000000);
291     }
292   if (time_zone != (struct timezone *) NULL)
293     {
294       if (is_tz_set == 0)
295         {
296           _tzset();
297           is_tz_set++;
298         }
299       time_zone->tz_minuteswest=_timezone/60;
300       time_zone->tz_dsttime=_daylight;
301     }
302   return(0);
303 }
304 #endif
305 \f
306 /*
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 %                                                                             %
309 %                                                                             %
310 %                                                                             %
311 %   I s W i n d o w s 9 5                                                     %
312 %                                                                             %
313 %                                                                             %
314 %                                                                             %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316 %
317 %  IsWindows95() returns true if the system is Windows 95.
318 %
319 %  The format of the IsWindows95 method is:
320 %
321 %      int IsWindows95()
322 %
323 */
324 MagickExport int IsWindows95()
325 {
326   OSVERSIONINFO
327     version_info;
328
329   version_info.dwOSVersionInfoSize=sizeof(version_info);
330   if (GetVersionEx(&version_info) &&
331       (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
332     return(1);
333   return(0);
334 }
335 \f
336 /*
337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 %                                                                             %
339 %                                                                             %
340 %                                                                             %
341 %   N T C l o s e D i r e c t o r y                                           %
342 %                                                                             %
343 %                                                                             %
344 %                                                                             %
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 %
347 %  NTCloseDirectory() closes the named directory stream and frees the DIR
348 %  structure.
349 %
350 %  The format of the NTCloseDirectory method is:
351 %
352 %      int NTCloseDirectory(DIR *entry)
353 %
354 %  A description of each parameter follows:
355 %
356 %    o entry: Specifies a pointer to a DIR structure.
357 %
358 */
359 MagickExport int NTCloseDirectory(DIR *entry)
360 {
361   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
362   assert(entry != (DIR *) NULL);
363   FindClose(entry->hSearch);
364   entry=(DIR *) RelinquishMagickMemory(entry);
365   return(0);
366 }
367 \f
368 /*
369 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370 %                                                                             %
371 %                                                                             %
372 %                                                                             %
373 %   N T C l o s e L i b r a r y                                               %
374 %                                                                             %
375 %                                                                             %
376 %                                                                             %
377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
378 %
379 %  NTCloseLibrary() unloads the module associated with the passed handle.
380 %
381 %  The format of the NTCloseLibrary method is:
382 %
383 %      void NTCloseLibrary(void *handle)
384 %
385 %  A description of each parameter follows:
386 %
387 %    o handle: Specifies a handle to a previously loaded dynamic module.
388 %
389 */
390 MagickExport int NTCloseLibrary(void *handle)
391 {
392   if (IsWindows95())
393     return(FreeLibrary((HINSTANCE) handle));
394   return(!(FreeLibrary((HINSTANCE) handle)));
395 }
396 \f
397 /*
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
399 %                                                                             %
400 %                                                                             %
401 %                                                                             %
402 %   N T C o n t r o l H a n d l e r                                           %
403 %                                                                             %
404 %                                                                             %
405 %                                                                             %
406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407 %
408 %  NTControlHandler() registers a control handler that is activated when, for
409 %  example, a ctrl-c is received.
410 %
411 %  The format of the NTControlHandler method is:
412 %
413 %      int NTControlHandler(void)
414 %
415 */
416
417 static BOOL ControlHandler(DWORD type)
418 {
419   (void) type;
420   AsynchronousResourceComponentTerminus();
421   return(FALSE);
422 }
423
424 MagickExport int NTControlHandler(void)
425 {
426   return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
427 }
428 \f
429 /*
430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
431 %                                                                             %
432 %                                                                             %
433 %                                                                             %
434 %   N T E l a p s e d T i m e                                                 %
435 %                                                                             %
436 %                                                                             %
437 %                                                                             %
438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 %
440 %  NTElapsedTime() returns the elapsed time (in seconds) since the last call to
441 %  StartTimer().
442 %
443 %  The format of the ElapsedTime method is:
444 %
445 %      double NTElapsedTime(void)
446 %
447 */
448 MagickExport double NTElapsedTime(void)
449 {
450   union
451   {
452     FILETIME
453       filetime;
454
455     __int64
456       filetime64;
457   } elapsed_time;
458
459   SYSTEMTIME
460     system_time;
461
462   GetSystemTime(&system_time);
463   SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
464   return((double) 1.0e-7*elapsed_time.filetime64);
465 }
466 \f
467 /*
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469 %                                                                             %
470 %                                                                             %
471 %                                                                             %
472 +   N T E r r o r H a n d l e r                                               %
473 %                                                                             %
474 %                                                                             %
475 %                                                                             %
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477 %
478 %  NTErrorHandler() displays an error reason and then terminates the program.
479 %
480 %  The format of the NTErrorHandler method is:
481 %
482 %      void NTErrorHandler(const ExceptionType severity,const char *reason,
483 %        const char *description)
484 %
485 %  A description of each parameter follows:
486 %
487 %    o severity: Specifies the numeric error category.
488 %
489 %    o reason: Specifies the reason to display before terminating the
490 %      program.
491 %
492 %    o description: Specifies any description to the reason.
493 %
494 */
495 MagickExport void NTErrorHandler(const ExceptionType severity,
496   const char *reason,const char *description)
497 {
498   char
499     buffer[3*MaxTextExtent],
500     *message;
501
502   (void) severity;
503   if (reason == (char *) NULL)
504     {
505       MagickCoreTerminus();
506       exit(0);
507     }
508   message=GetExceptionMessage(errno);
509   if ((description != (char *) NULL) && errno)
510     (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
511       GetClientName(),reason,description,message);
512   else
513     if (description != (char *) NULL)
514       (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
515         GetClientName(),reason,description);
516     else
517       if (errno != 0)
518         (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s [%s].\n",
519           GetClientName(),reason,message);
520       else
521         (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",
522           GetClientName(),reason);
523   message=DestroyString(message);
524   (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
525     MB_SETFOREGROUND | MB_ICONEXCLAMATION);
526   MagickCoreTerminus();
527   exit(0);
528 }
529 \f
530 /*
531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532 %                                                                             %
533 %                                                                             %
534 %                                                                             %
535 %   N T E x i t L i b r a r y                                                 %
536 %                                                                             %
537 %                                                                             %
538 %                                                                             %
539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540 %
541 %  NTExitLibrary() exits the dynamic module loading subsystem.
542 %
543 %  The format of the NTExitLibrary method is:
544 %
545 %      int NTExitLibrary(void)
546 %
547 */
548 MagickExport int NTExitLibrary(void)
549 {
550   return(0);
551 }
552 \f
553 /*
554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555 %                                                                             %
556 %                                                                             %
557 %                                                                             %
558 %   N T G a t h e r R a n d o m D a t a                                       %
559 %                                                                             %
560 %                                                                             %
561 %                                                                             %
562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563 %
564 %  NTGatherRandomData() gathers random data and returns it.
565 %
566 %  The format of the GatherRandomData method is:
567 %
568 %      MagickBooleanType NTGatherRandomData(const size_t length,
569 %        unsigned char *random)
570 %
571 %  A description of each parameter follows:
572 %
573 %    length: the length of random data buffer
574 %
575 %    random: the random data is returned here.
576 %
577 */
578 MagickExport MagickBooleanType NTGatherRandomData(const size_t length,
579   unsigned char *random)
580 {
581 #if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
582   HCRYPTPROV
583     handle;
584
585   int
586     status;
587
588   handle=(HCRYPTPROV) NULL;
589   status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
590     (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
591   if (status == 0)
592     status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
593       (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
594   if (status == 0)
595     return(MagickFalse);
596   status=CryptGenRandom(handle,(DWORD) length,random);
597   if (status == 0)
598     {
599       status=CryptReleaseContext(handle,0);
600       return(MagickFalse);
601     }
602   status=CryptReleaseContext(handle,0);
603   if (status == 0)
604     return(MagickFalse);
605 #else
606   (void) random;
607   (void) length;
608 #endif
609   return(MagickTrue);
610 }
611 \f
612 /*
613 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614 %                                                                             %
615 %                                                                             %
616 %                                                                             %
617 %   N T G e t E x e c u t i o n P a t h                                       %
618 %                                                                             %
619 %                                                                             %
620 %                                                                             %
621 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 %
623 %  NTGetExecutionPath() returns the execution path of a program.
624 %
625 %  The format of the GetExecutionPath method is:
626 %
627 %      MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
628 %
629 %  A description of each parameter follows:
630 %
631 %    o path: the pathname of the executable that started the process.
632 %
633 %    o extent: the maximum extent of the path.
634 %
635 */
636 MagickExport MagickBooleanType NTGetExecutionPath(char *path,
637   const size_t extent)
638 {
639   GetModuleFileName(0,path,(DWORD) extent);
640   return(MagickTrue);
641 }
642 \f
643 /*
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 %                                                                             %
646 %                                                                             %
647 %                                                                             %
648 %   N T G e t L a s t E r r o r                                               %
649 %                                                                             %
650 %                                                                             %
651 %                                                                             %
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 %
654 %  NTGetLastError() returns the last error that occurred.
655 %
656 %  The format of the NTGetLastError method is:
657 %
658 %      char *NTGetLastError(void)
659 %
660 */
661 char *NTGetLastError(void)
662 {
663   char
664     *reason;
665
666   int
667     status;
668
669   LPVOID
670     buffer;
671
672   status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
673     FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
674     MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
675   if (!status)
676     reason=AcquireString("An unknown error occurred");
677   else
678     {
679       reason=AcquireString((const char *) buffer);
680       LocalFree(buffer);
681     }
682   return(reason);
683 }
684 \f
685 /*
686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687 %                                                                             %
688 %                                                                             %
689 %                                                                             %
690 %   N T G e t L i b r a r y E r r o r                                         %
691 %                                                                             %
692 %                                                                             %
693 %                                                                             %
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 %
696 %  Lt_dlerror() returns a pointer to a string describing the last error
697 %  associated with a lt_dl method.  Note that this function is not thread
698 %  safe so it should only be used under the protection of a lock.
699 %
700 %  The format of the NTGetLibraryError method is:
701 %
702 %      const char *NTGetLibraryError(void)
703 %
704 */
705 MagickExport const char *NTGetLibraryError(void)
706 {
707   static char
708     last_error[MaxTextExtent];
709
710   char
711     *error;
712
713   *last_error='\0';
714   error=NTGetLastError();
715   if (error)
716     (void) CopyMagickString(last_error,error,MaxTextExtent);
717   error=DestroyString(error);
718   return(last_error);
719 }
720 \f
721 /*
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 %                                                                             %
724 %                                                                             %
725 %                                                                             %
726 %   N T G e t L i b r a r y S y m b o l                                       %
727 %                                                                             %
728 %                                                                             %
729 %                                                                             %
730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731 %
732 %  NTGetLibrarySymbol() retrieve the procedure address of the method
733 %  specified by the passed character string.
734 %
735 %  The format of the NTGetLibrarySymbol method is:
736 %
737 %      void *NTGetLibrarySymbol(void *handle,const char *name)
738 %
739 %  A description of each parameter follows:
740 %
741 %    o handle: Specifies a handle to the previously loaded dynamic module.
742 %
743 %    o name: Specifies the procedure entry point to be returned.
744 %
745 */
746 void *NTGetLibrarySymbol(void *handle,const char *name)
747 {
748   LPFNDLLFUNC1
749     lpfnDllFunc1;
750
751   lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
752   if (!lpfnDllFunc1)
753     return((void *) NULL);
754   return((void *) lpfnDllFunc1);
755 }
756 \f
757 /*
758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 %                                                                             %
760 %                                                                             %
761 %                                                                             %
762 %   N T G e t M o d u l e P a t h                                             %
763 %                                                                             %
764 %                                                                             %
765 %                                                                             %
766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 %
768 %  NTGetModulePath() returns the path of the specified module.
769 %
770 %  The format of the GetModulePath method is:
771 %
772 %      MagickBooleanType NTGetModulePath(const char *module,char *path)
773 %
774 %  A description of each parameter follows:
775 %
776 %    modith: the module name.
777 %
778 %    path: the module path is returned here.
779 %
780 */
781 MagickExport MagickBooleanType NTGetModulePath(const char *module,char *path)
782 {
783   char
784     module_path[MaxTextExtent];
785
786   HMODULE
787     handle;
788
789   ssize_t
790     length;
791
792   *path='\0';
793   handle=GetModuleHandle(module);
794   if (handle == (HMODULE) NULL)
795     return(MagickFalse);
796   length=GetModuleFileName(handle,module_path,MaxTextExtent);
797   if (length != 0)
798     GetPathComponent(module_path,HeadPath,path);
799   return(MagickTrue);
800 }
801 \f
802 /*
803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804 %                                                                             %
805 %                                                                             %
806 %                                                                             %
807 %   N T G h o s t s c r i p t D L L                                           %
808 %                                                                             %
809 %                                                                             %
810 %                                                                             %
811 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
812 %
813 %  NTGhostscriptDLL() returns the path to the most recent Ghostscript version
814 %  DLL.  The method returns TRUE on success otherwise FALSE.
815 %
816 %  The format of the NTGhostscriptDLL method is:
817 %
818 %      int NTGhostscriptDLL(char *path,int length)
819 %
820 %  A description of each parameter follows:
821 %
822 %    o path: return the Ghostscript DLL path here.
823 %
824 %    o length: the buffer length.
825 %
826 */
827
828 static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
829   char *value,int *length)
830 {
831   BYTE
832     byte,
833     *p;
834
835   DWORD
836     extent,
837     type;
838
839   HKEY
840     hkey;
841
842   LONG
843     status;
844
845   /*
846     Get a registry value: key = root\\key, named value = name.
847   */
848   if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
849     return(1);  /* no match */
850   p=(BYTE *) value;
851   type=REG_SZ;
852   extent=(*length);
853   if (p == (BYTE *) NULL)
854     p=(&byte);  /* ERROR_MORE_DATA only if value is NULL */
855   status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
856   RegCloseKey(hkey);
857   if (status == ERROR_SUCCESS)
858     {
859       *length=extent;
860       return(0);  /* return the match */
861     }
862   if (status == ERROR_MORE_DATA)
863     {
864       *length=extent;
865       return(-1);  /* buffer not large enough */
866     }
867   return(1);  /* not found */
868 }
869
870 static int NTLocateGhostscript(const char **product_family,int *major_version,
871   int *minor_version)
872 {
873   int
874     i;
875
876   MagickBooleanType
877     status;
878
879   static const char
880     *products[4] =
881     {
882       "GPL Ghostscript",
883       "GNU Ghostscript",
884       "AFPL Ghostscript",
885       "Aladdin Ghostscript"
886     };
887
888   /*
889     Find the most recent version of Ghostscript.
890   */
891   status=FALSE;
892   *product_family=NULL;
893   *major_version=5;
894   *minor_version=49; /* min version of Ghostscript is 5.50 */
895   for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
896   {
897     char
898       key[MaxTextExtent];
899
900     HKEY
901       hkey,
902       root;
903
904     REGSAM
905       mode;
906
907     (void) FormatMagickString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
908     root=HKEY_LOCAL_MACHINE;
909     mode=KEY_READ;
910 #if defined(KEY_WOW64_32KEY)
911     mode|=KEY_WOW64_32KEY;
912 #endif
913     if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
914       {
915         DWORD
916           extent;
917
918         int
919           j;
920
921         /*
922           Now enumerate the keys.
923         */
924         extent=sizeof(key)/sizeof(char);
925         for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
926         {
927           int
928             major,
929             minor;
930
931           major=0;
932           minor=0;
933           if (sscanf(key,"%d.%d",&major,&minor) != 2)
934             continue;
935           if ((major > *major_version) || ((major == *major_version) &&
936               (minor > *minor_version)))
937             {
938               *product_family=products[i];
939               *major_version=major;
940               *minor_version=minor;
941               status=TRUE;
942             }
943        }
944        (void) RegCloseKey(hkey);
945      }
946   }
947   if (status == FALSE)
948     {
949       i=0;
950       *major_version=0;
951       *minor_version=0;
952     }
953   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
954     "version %d.%02d",*product_family,*major_version,*minor_version);
955   return(status);
956 }
957
958 static int NTGhostscriptGetString(const char *name,char *value,
959   const size_t length)
960 {
961   char
962     key[MaxTextExtent];
963
964   int
965     i,
966     extent;
967
968   static const char
969     *product_family = (const char *) NULL;
970
971   static int
972     major_version=0,
973     minor_version=0;
974
975   struct
976   {
977     const HKEY
978       hkey;
979
980     const char
981       *name;
982   }
983   hkeys[2] =
984   {
985     { HKEY_CURRENT_USER,  "HKEY_CURRENT_USER"  },
986     { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
987   };
988
989   /*
990     Get a string from the installed Ghostscript.
991   */
992   *value='\0';
993   if (product_family == NULL)
994     (void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
995   if (product_family == NULL)
996     return(FALSE);
997   (void) FormatMagickString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
998     product_family,major_version,minor_version);
999   for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
1000   {
1001     extent=(int) length;
1002     if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
1003       {
1004         (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1005           "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
1006         return(TRUE);
1007       }
1008     (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1009       "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
1010   }
1011   return(FALSE);
1012 }
1013
1014 MagickExport int NTGhostscriptDLL(char *path,int length)
1015 {
1016   static char
1017     dll[MaxTextExtent] = { "" };
1018
1019   *path='\0';
1020   if ((*dll == '\0') &&
1021       (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
1022     return(FALSE);
1023   (void) CopyMagickString(path,dll,length);
1024   return(TRUE);
1025 }
1026 \f
1027 /*
1028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1029 %                                                                             %
1030 %                                                                             %
1031 %                                                                             %
1032 %   N T G h o s t s c r i p t D L L V e c t o r s                             %
1033 %                                                                             %
1034 %                                                                             %
1035 %                                                                             %
1036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037 %
1038 %  NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
1039 %  function vectors to invoke Ghostscript DLL functions. A null pointer is
1040 %  returned if there is an error when loading the DLL or retrieving the
1041 %  function vectors.
1042 %
1043 %  The format of the NTGhostscriptDLLVectors method is:
1044 %
1045 %      const GhostInfo *NTGhostscriptDLLVectors(void)
1046 %
1047 */
1048 MagickExport const GhostInfo *NTGhostscriptDLLVectors(void)
1049 {
1050   if (NTGhostscriptLoadDLL() == FALSE)
1051     return((GhostInfo *) NULL);
1052   return(&ghost_info);
1053 }
1054 \f
1055 /*
1056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057 %                                                                             %
1058 %                                                                             %
1059 %                                                                             %
1060 %   N T G h o s t s c r i p t E X E                                           %
1061 %                                                                             %
1062 %                                                                             %
1063 %                                                                             %
1064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065 %
1066 %  NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
1067 %  The method returns FALSE if a full path value is not obtained and returns
1068 %  a default path of gswin32c.exe.
1069 %
1070 %  The format of the NTGhostscriptEXE method is:
1071 %
1072 %      int NTGhostscriptEXE(char *path,int length)
1073 %
1074 %  A description of each parameter follows:
1075 %
1076 %    o path: return the Ghostscript executable path here.
1077 %
1078 %    o length: length of buffer.
1079 %
1080 */
1081 MagickExport int NTGhostscriptEXE(char *path,int length)
1082 {
1083   register char
1084     *p;
1085
1086   static char
1087     program[MaxTextExtent] = { "" };
1088
1089   (void) CopyMagickString(path,"gswin32c.exe",length);
1090   if ((*program == '\0') &&
1091       (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE))
1092     return(FALSE);
1093   p=strrchr(program,'\\');
1094   if (p != (char *) NULL)
1095     {
1096       p++;
1097       *p='\0';
1098       (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program));
1099     }
1100   (void) CopyMagickString(path,program,length);
1101   return(TRUE);
1102 }
1103 \f
1104 /*
1105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1106 %                                                                             %
1107 %                                                                             %
1108 %                                                                             %
1109 %   N T G h o s t s c r i p t F o n t s                                       %
1110 %                                                                             %
1111 %                                                                             %
1112 %                                                                             %
1113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114 %
1115 %  NTGhostscriptFonts() obtains the path to the Ghostscript fonts.  The method
1116 %  returns FALSE if it cannot determine the font path.
1117 %
1118 %  The format of the NTGhostscriptFonts method is:
1119 %
1120 %      int NTGhostscriptFonts(char *path, int length)
1121 %
1122 %  A description of each parameter follows:
1123 %
1124 %    o path: return the font path here.
1125 %
1126 %    o length: length of the path buffer.
1127 %
1128 */
1129 MagickExport int NTGhostscriptFonts(char *path,int length)
1130 {
1131   char
1132     buffer[MaxTextExtent],
1133     filename[MaxTextExtent];
1134
1135   register char
1136     *p,
1137     *q;
1138
1139   *path='\0';
1140   if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE)
1141     return(FALSE);
1142   for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1143   {
1144     (void) CopyMagickString(path,p+1,length+1);
1145     q=strchr(path,DirectoryListSeparator);
1146     if (q != (char *) NULL)
1147       *q='\0';
1148     (void) FormatMagickString(filename,MaxTextExtent,"%s%sfonts.dir",path,
1149       DirectorySeparator);
1150     if (IsPathAccessible(filename) != MagickFalse)
1151       return(TRUE);
1152   }
1153   return(FALSE);
1154 }
1155 \f
1156 /*
1157 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1158 %                                                                             %
1159 %                                                                             %
1160 %                                                                             %
1161 %   N T G h o s t s c r i p t L o a d D L L                                   %
1162 %                                                                             %
1163 %                                                                             %
1164 %                                                                             %
1165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166 %
1167 %  NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
1168 %  TRUE if it succeeds.
1169 %
1170 %  The format of the NTGhostscriptLoadDLL method is:
1171 %
1172 %      int NTGhostscriptLoadDLL(void)
1173 %
1174 */
1175 MagickExport int NTGhostscriptLoadDLL(void)
1176 {
1177   char
1178     path[MaxTextExtent];
1179
1180   if (ghost_handle != (void *) NULL)
1181     return(TRUE);
1182   if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1183     return(FALSE);
1184   ghost_handle=lt_dlopen(path);
1185   if (ghost_handle == (void *) NULL)
1186     return(FALSE);
1187   (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1188   ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1189     lt_dlsym(ghost_handle,"gsapi_exit");
1190   ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1191     char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1192   ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1193     lt_dlsym(ghost_handle,"gsapi_new_instance"));
1194   ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1195     int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1196   ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1197     lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1198   if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1199       (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1200       (ghost_info.delete_instance == NULL))
1201     return(FALSE);
1202   return(TRUE);
1203 }
1204 \f
1205 /*
1206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1207 %                                                                             %
1208 %                                                                             %
1209 %                                                                             %
1210 %   N T G h o s t s c r i p t U n L o a d D L L                               %
1211 %                                                                             %
1212 %                                                                             %
1213 %                                                                             %
1214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1215 %
1216 %  NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1217 %  it succeeds.
1218 %
1219 %  The format of the NTGhostscriptUnLoadDLL method is:
1220 %
1221 %      int NTGhostscriptUnLoadDLL(void)
1222 %
1223 */
1224 MagickExport int NTGhostscriptUnLoadDLL(void)
1225 {
1226   int
1227     status;
1228
1229   if (ghost_handle == (void *) NULL)
1230     return(FALSE);
1231   status=lt_dlclose(ghost_handle);
1232   ghost_handle=(void *) NULL;
1233   (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1234   return(status);
1235 }
1236 \f
1237 /*
1238 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1239 %                                                                             %
1240 %                                                                             %
1241 %                                                                             %
1242 %   N T I n i t i a l i z e L i b r a r y                                     %
1243 %                                                                             %
1244 %                                                                             %
1245 %                                                                             %
1246 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1247 %
1248 %  NTInitializeLibrary() initializes the dynamic module loading subsystem.
1249 %
1250 %  The format of the NTInitializeLibrary method is:
1251 %
1252 %      int NTInitializeLibrary(void)
1253 %
1254 */
1255 MagickExport int NTInitializeLibrary(void)
1256 {
1257   return(0);
1258 }
1259 \f
1260 /*
1261 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262 %                                                                             %
1263 %                                                                             %
1264 %                                                                             %
1265 +  N T M a p M e m o r y                                                      %
1266 %                                                                             %
1267 %                                                                             %
1268 %                                                                             %
1269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1270 %
1271 %  Mmap() emulates the Unix method of the same name.
1272 %
1273 %  The format of the NTMapMemory method is:
1274 %
1275 %    MagickExport void *NTMapMemory(char *address,size_t length,int protection,
1276 %      int access,int file,MagickOffsetType offset)
1277 %
1278 */
1279 MagickExport void *NTMapMemory(char *address,size_t length,int protection,
1280   int flags,int file,MagickOffsetType offset)
1281 {
1282   DWORD
1283     access_mode,
1284     high_length,
1285     high_offset,
1286     low_length,
1287     low_offset,
1288     protection_mode;
1289
1290   HANDLE
1291     file_handle,
1292     map_handle;
1293
1294   void
1295     *map;
1296
1297   (void) address;
1298   access_mode=0;
1299   file_handle=INVALID_HANDLE_VALUE;
1300   low_length=(DWORD) (length & 0xFFFFFFFFUL);
1301   high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1302   map_handle=INVALID_HANDLE_VALUE;
1303   map=(void *) NULL;
1304   low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1305   high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1306   protection_mode=0;
1307   if (protection & PROT_WRITE)
1308     {
1309       access_mode=FILE_MAP_WRITE;
1310       if (!(flags & MAP_PRIVATE))
1311         protection_mode=PAGE_READWRITE;
1312       else
1313         {
1314           access_mode=FILE_MAP_COPY;
1315           protection_mode=PAGE_WRITECOPY;
1316         }
1317     }
1318   else
1319     if (protection & PROT_READ)
1320       {
1321         access_mode=FILE_MAP_READ;
1322         protection_mode=PAGE_READONLY;
1323       }
1324   if ((file == -1) && (flags & MAP_ANONYMOUS))
1325     file_handle=INVALID_HANDLE_VALUE;
1326   else
1327     file_handle=(HANDLE) _get_osfhandle(file);
1328   map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1329     low_length,0);
1330   if (map_handle)
1331     {
1332       map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1333         length);
1334       CloseHandle(map_handle);
1335     }
1336   if (map == (void *) NULL)
1337     return((void *) MAP_FAILED);
1338   return((void *) ((char *) map));
1339 }
1340 \f
1341 /*
1342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1343 %                                                                             %
1344 %                                                                             %
1345 %                                                                             %
1346 %   N T O p e n D i r e c t o r y                                             %
1347 %                                                                             %
1348 %                                                                             %
1349 %                                                                             %
1350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1351 %
1352 %  NTOpenDirectory() opens the directory named by filename and associates a
1353 %  directory stream with it.
1354 %
1355 %  The format of the NTOpenDirectory method is:
1356 %
1357 %      DIR *NTOpenDirectory(const char *path)
1358 %
1359 %  A description of each parameter follows:
1360 %
1361 %    o entry: Specifies a pointer to a DIR structure.
1362 %
1363 */
1364 MagickExport DIR *NTOpenDirectory(const char *path)
1365 {
1366   char
1367     file_specification[MaxTextExtent];
1368
1369   DIR
1370     *entry;
1371
1372   size_t
1373     length;
1374
1375   assert(path != (const char *) NULL);
1376   length=CopyMagickString(file_specification,path,MaxTextExtent);
1377   if (length >= MaxTextExtent)
1378     return((DIR *) NULL);
1379   length=ConcatenateMagickString(file_specification,DirectorySeparator,
1380     MaxTextExtent);
1381   if (length >= MaxTextExtent)
1382     return((DIR *) NULL);
1383   entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
1384   if (entry != (DIR *) NULL)
1385     {
1386       entry->firsttime=TRUE;
1387       entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1388     }
1389   if (entry->hSearch == INVALID_HANDLE_VALUE)
1390     {
1391       length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
1392       if (length >= MaxTextExtent)
1393         {
1394           entry=(DIR *) RelinquishMagickMemory(entry);
1395           return((DIR *) NULL);
1396         }
1397       entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1398       if (entry->hSearch == INVALID_HANDLE_VALUE)
1399         {
1400           entry=(DIR *) RelinquishMagickMemory(entry);
1401           return((DIR *) NULL);
1402         }
1403     }
1404   return(entry);
1405 }
1406 \f
1407 /*
1408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409 %                                                                             %
1410 %                                                                             %
1411 %                                                                             %
1412 %   N T O p e n L i b r a r y                                                 %
1413 %                                                                             %
1414 %                                                                             %
1415 %                                                                             %
1416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 %
1418 %  NTOpenLibrary() loads a dynamic module into memory and returns a handle that
1419 %  can be used to access the various procedures in the module.
1420 %
1421 %  The format of the NTOpenLibrary method is:
1422 %
1423 %      void *NTOpenLibrary(const char *filename)
1424 %
1425 %  A description of each parameter follows:
1426 %
1427 %    o path: Specifies a pointer to string representing dynamic module that
1428 %      is to be loaded.
1429 %
1430 */
1431
1432 static const char *GetSearchPath( void )
1433 {
1434 #if defined(MAGICKCORE_LTDL_DELEGATE)
1435   return(lt_dlgetsearchpath());
1436 #else
1437   return(lt_slsearchpath);
1438 #endif
1439 }
1440
1441 MagickExport void *NTOpenLibrary(const char *filename)
1442 {
1443 #define MaxPathElements  31
1444
1445   char
1446     buffer[MaxTextExtent];
1447
1448   int
1449     index;
1450
1451   register const char
1452     *p,
1453     *q;
1454
1455   register int
1456     i;
1457
1458   UINT
1459     mode;
1460
1461   void
1462     *handle;
1463
1464   mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1465   handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1466   if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL))
1467     {
1468       SetErrorMode(mode);
1469       return(handle);
1470     }
1471   p=(char *) GetSearchPath();
1472   index=0;
1473   while (index < MaxPathElements)
1474   {
1475     q=strchr(p,DirectoryListSeparator);
1476     if (q == (char *) NULL)
1477       {
1478         (void) CopyMagickString(buffer,p,MaxTextExtent);
1479         (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1480         (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1481         handle=(void *) LoadLibraryEx(buffer,NULL,
1482           LOAD_WITH_ALTERED_SEARCH_PATH);
1483         break;
1484       }
1485     i=q-p;
1486     (void) CopyMagickString(buffer,p,i+1);
1487     (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1488     (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1489     handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1490     if (handle != (void *) NULL)
1491       break;
1492     p=q+1;
1493   }
1494   SetErrorMode(mode);
1495   return(handle);
1496 }
1497 \f
1498 /*
1499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1500 %                                                                             %
1501 %                                                                             %
1502 %                                                                             %
1503 %    N T R e a d D i r e c t o r y                                            %
1504 %                                                                             %
1505 %                                                                             %
1506 %                                                                             %
1507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1508 %
1509 %  NTReadDirectory() returns a pointer to a structure representing the
1510 %  directory entry at the current position in the directory stream to which
1511 %  entry refers.
1512 %
1513 %  The format of the NTReadDirectory
1514 %
1515 %      NTReadDirectory(entry)
1516 %
1517 %  A description of each parameter follows:
1518 %
1519 %    o entry: Specifies a pointer to a DIR structure.
1520 %
1521 */
1522 MagickExport struct dirent *NTReadDirectory(DIR *entry)
1523 {
1524   int
1525     status;
1526
1527   size_t
1528     length;
1529
1530   if (entry == (DIR *) NULL)
1531     return((struct dirent *) NULL);
1532   if (!entry->firsttime)
1533     {
1534       status=FindNextFile(entry->hSearch,&entry->Win32FindData);
1535       if (status == 0)
1536         return((struct dirent *) NULL);
1537     }
1538   length=CopyMagickString(entry->file_info.d_name,
1539     entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name));
1540   if (length >= sizeof(entry->file_info.d_name))
1541     return((struct dirent *) NULL);
1542   entry->firsttime=FALSE;
1543   entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1544   return(&entry->file_info);
1545 }
1546 \f
1547 /*
1548 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1549 %                                                                             %
1550 %                                                                             %
1551 %                                                                             %
1552 %   N T R e g i s t r y K e y L o o k u p                                     %
1553 %                                                                             %
1554 %                                                                             %
1555 %                                                                             %
1556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1557 %
1558 %  NTRegistryKeyLookup() returns ImageMagick installation path settings
1559 %  stored in the Windows Registry.  Path settings are specific to the
1560 %  installed ImageMagick version so that multiple Image Magick installations
1561 %  may coexist.
1562 %
1563 %  Values are stored in the registry under a base path path similar to
1564 %  "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\5.5.7\Q:16". The provided subkey
1565 %  is appended to this base path to form the full key.
1566 %
1567 %  The format of the NTRegistryKeyLookup method is:
1568 %
1569 %      unsigned char *NTRegistryKeyLookup(const char *subkey)
1570 %
1571 %  A description of each parameter follows:
1572 %
1573 %    o subkey: Specifies a string that identifies the registry object.
1574 %      Currently supported sub-keys include: "BinPath", "ConfigurePath",
1575 %      "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1576 %
1577 */
1578 MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
1579 {
1580   char
1581     package_key[MaxTextExtent];
1582
1583   DWORD
1584     size,
1585     type;
1586
1587   HKEY
1588     registry_key;
1589
1590   LONG
1591     status;
1592
1593   unsigned char
1594     *value;
1595
1596   /*
1597     Look-up base key.
1598   */
1599   (void) FormatMagickString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
1600     MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
1601   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
1602   registry_key=(HKEY) INVALID_HANDLE_VALUE;
1603   status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,&registry_key);
1604   if (status != ERROR_SUCCESS)
1605     {
1606       registry_key=(HKEY) INVALID_HANDLE_VALUE;
1607       return((unsigned char *) NULL);
1608     }
1609   /*
1610     Look-up sub key.
1611   */
1612   size=32;
1613   value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
1614   if (value == (unsigned char *) NULL)
1615     {
1616       RegCloseKey(registry_key);
1617       return((unsigned char *) NULL);
1618     }
1619   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey);
1620   status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1621   if ((status == ERROR_MORE_DATA) && (type == REG_SZ))
1622     {
1623       value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
1624       if (value == (BYTE *) NULL)
1625         {
1626           RegCloseKey(registry_key);
1627           return((unsigned char *) NULL);
1628         }
1629       status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1630     }
1631   RegCloseKey(registry_key);
1632   if ((type != REG_SZ) || (status != ERROR_SUCCESS))
1633     value=(unsigned char *) RelinquishMagickMemory(value);
1634   return((unsigned char *) value);
1635 }
1636 \f
1637 /*
1638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1639 %                                                                             %
1640 %                                                                             %
1641 %                                                                             %
1642 %   N T R e p o r t E v e n t                                                 %
1643 %                                                                             %
1644 %                                                                             %
1645 %                                                                             %
1646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1647 %
1648 %  NTReportEvent() reports an event.
1649 %
1650 %  The format of the NTReportEvent method is:
1651 %
1652 %      MagickBooleanType NTReportEvent(const char *event,
1653 %        const MagickBooleanType error)
1654 %
1655 %  A description of each parameter follows:
1656 %
1657 %    o event: the event.
1658 %
1659 %    o error: MagickTrue the event is an error.
1660 %
1661 */
1662 MagickExport MagickBooleanType NTReportEvent(const char *event,
1663   const MagickBooleanType error)
1664 {
1665   const char
1666     *events[1];
1667
1668   HANDLE
1669     handle;
1670
1671   WORD
1672     type;
1673
1674   handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1675   if (handle == NULL)
1676     return(MagickFalse);
1677   events[0]=event;
1678   type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1679   ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1680   DeregisterEventSource(handle);
1681   return(MagickTrue);
1682 }
1683 \f
1684 /*
1685 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1686 %                                                                             %
1687 %                                                                             %
1688 %                                                                             %
1689 %   N T R e s o u r c e T o B l o b                                           %
1690 %                                                                             %
1691 %                                                                             %
1692 %                                                                             %
1693 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1694 %
1695 %  NTResourceToBlob() returns a blob containing the contents of the resource
1696 %  in the current executable specified by the id parameter. This currently
1697 %  used to retrieve MGK files tha have been embedded into the various command
1698 %  line utilities.
1699 %
1700 %  The format of the NTResourceToBlob method is:
1701 %
1702 %      unsigned char *NTResourceToBlob(const char *id)
1703 %
1704 %  A description of each parameter follows:
1705 %
1706 %    o id: Specifies a string that identifies the resource.
1707 %
1708 */
1709 MagickExport unsigned char *NTResourceToBlob(const char *id)
1710 {
1711   char
1712     path[MaxTextExtent];
1713
1714   DWORD
1715     length;
1716
1717   HGLOBAL
1718     global;
1719
1720   HMODULE
1721     handle;
1722
1723   HRSRC
1724     resource;
1725
1726   unsigned char
1727     *blob,
1728     *value;
1729
1730   assert(id != (const char *) NULL);
1731   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1732   (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
1733     DirectorySeparator,GetClientName());
1734   if (IsPathAccessible(path) != MagickFalse)
1735     handle=GetModuleHandle(path);
1736   else
1737     handle=GetModuleHandle(0);
1738   if (!handle)
1739     return((unsigned char *) NULL);
1740   resource=FindResource(handle,id,"IMAGEMAGICK");
1741   if (!resource)
1742     return((unsigned char *) NULL);
1743   global=LoadResource(handle,resource);
1744   if (!global)
1745     return((unsigned char *) NULL);
1746   length=SizeofResource(handle,resource);
1747   value=(unsigned char *) LockResource(global);
1748   if (!value)
1749     {
1750       FreeResource(global);
1751       return((unsigned char *) NULL);
1752     }
1753   blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
1754     sizeof(*blob));
1755   if (blob != (unsigned char *) NULL)
1756     {
1757       (void) CopyMagickMemory(blob,value,length);
1758       blob[length]='\0';
1759     }
1760   UnlockResource(global);
1761   FreeResource(global);
1762   return(blob);
1763 }
1764 \f
1765 /*
1766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1767 %                                                                             %
1768 %                                                                             %
1769 %                                                                             %
1770 %   N T S e e k D i r e c t o r y                                             %
1771 %                                                                             %
1772 %                                                                             %
1773 %                                                                             %
1774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1775 %
1776 %  NTSeekDirectory() sets the position of the next NTReadDirectory() operation
1777 %  on the directory stream.
1778 %
1779 %  The format of the NTSeekDirectory method is:
1780 %
1781 %      void NTSeekDirectory(DIR *entry,ssize_t position)
1782 %
1783 %  A description of each parameter follows:
1784 %
1785 %    o entry: Specifies a pointer to a DIR structure.
1786 %
1787 %    o position: specifies the position associated with the directory
1788 %      stream.
1789 %
1790 */
1791 MagickExport void NTSeekDirectory(DIR *entry,ssize_t position)
1792 {
1793   (void) position;
1794   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1795   assert(entry != (DIR *) NULL);
1796 }
1797 \f
1798 /*
1799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1800 %                                                                             %
1801 %                                                                             %
1802 %                                                                             %
1803 %   N T S e t S e a r c h P a t h                                             %
1804 %                                                                             %
1805 %                                                                             %
1806 %                                                                             %
1807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1808 %
1809 %  NTSetSearchPath() sets the current locations that the subsystem should
1810 %  look at to find dynamically loadable modules.
1811 %
1812 %  The format of the NTSetSearchPath method is:
1813 %
1814 %      int NTSetSearchPath(const char *path)
1815 %
1816 %  A description of each parameter follows:
1817 %
1818 %    o path: Specifies a pointer to string representing the search path
1819 %      for DLL's that can be dynamically loaded.
1820 %
1821 */
1822 MagickExport int NTSetSearchPath(const char *path)
1823 {
1824 #if defined(MAGICKCORE_LTDL_DELEGATE)
1825   lt_dlsetsearchpath(path);
1826 #else
1827   if (lt_slsearchpath != (char *) NULL)
1828     lt_slsearchpath=DestroyString(lt_slsearchpath);
1829   if (path != (char *) NULL)
1830     lt_slsearchpath=AcquireString(path);
1831 #endif
1832   return(0);
1833 }
1834 \f
1835 /*
1836 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1837 %                                                                             %
1838 %                                                                             %
1839 %                                                                             %
1840 +  N T S y n c M e m o r y                                                    %
1841 %                                                                             %
1842 %                                                                             %
1843 %                                                                             %
1844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1845 %
1846 %  NTSyncMemory() emulates the Unix method of the same name.
1847 %
1848 %  The format of the NTSyncMemory method is:
1849 %
1850 %      int NTSyncMemory(void *address,size_t length,int flags)
1851 %
1852 %  A description of each parameter follows:
1853 %
1854 %    o address: the address of the binary large object.
1855 %
1856 %    o length: the length of the binary large object.
1857 %
1858 %    o flags: Option flags (ignored for Windows).
1859 %
1860 */
1861 MagickExport int NTSyncMemory(void *address,size_t length,int flags)
1862 {
1863   (void) flags;
1864   if (FlushViewOfFile(address,length) == MagickFalse)
1865     return(-1);
1866   return(0);
1867 }
1868 \f
1869 /*
1870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1871 %                                                                             %
1872 %                                                                             %
1873 %                                                                             %
1874 %   N T S y s t e m C o m m a n d                                             %
1875 %                                                                             %
1876 %                                                                             %
1877 %                                                                             %
1878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1879 %
1880 %  NTSystemCommand() executes the specified command and waits until it
1881 %  terminates.  The returned value is the exit status of the command.
1882 %
1883 %  The format of the NTSystemCommand method is:
1884 %
1885 %      int NTSystemCommand(MagickFalse,const char *command)
1886 %
1887 %  A description of each parameter follows:
1888 %
1889 %    o command: This string is the command to execute.
1890 %
1891 */
1892 MagickExport int NTSystemCommand(const char *command)
1893 {
1894   char
1895     local_command[MaxTextExtent];
1896
1897   DWORD
1898     child_status;
1899
1900   int
1901     status;
1902
1903   MagickBooleanType
1904     background_process;
1905
1906   PROCESS_INFORMATION
1907     process_info;
1908
1909   STARTUPINFO
1910     startup_info;
1911
1912   if (command == (char *) NULL)
1913     return(-1);
1914   GetStartupInfo(&startup_info);
1915   startup_info.dwFlags=STARTF_USESHOWWINDOW;
1916   startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
1917   (void) CopyMagickString(local_command,command,MaxTextExtent);
1918   background_process=command[strlen(command)-1] == '&' ? MagickTrue :
1919     MagickFalse;
1920   if (background_process)
1921     local_command[strlen(command)-1]='\0';
1922   if (command[strlen(command)-1] == '|')
1923      local_command[strlen(command)-1]='\0';
1924    else
1925      startup_info.wShowWindow=SW_SHOWDEFAULT;
1926   status=CreateProcess((LPCTSTR) NULL,local_command,
1927     (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,
1928     (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
1929     &process_info);
1930   if (status == 0)
1931     return(-1);
1932   if (background_process)
1933     return(status == 0);
1934   status=WaitForSingleObject(process_info.hProcess,INFINITE);
1935   if (status != WAIT_OBJECT_0)
1936     return(status);
1937   status=GetExitCodeProcess(process_info.hProcess,&child_status);
1938   if (status == 0)
1939     return(-1);
1940   CloseHandle(process_info.hProcess);
1941   CloseHandle(process_info.hThread);
1942   return((int) child_status);
1943 }
1944 \f
1945 /*
1946 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1947 %                                                                             %
1948 %                                                                             %
1949 %                                                                             %
1950 %   N T S y s t e m C o n i f i g u r a t i o n                               %
1951 %                                                                             %
1952 %                                                                             %
1953 %                                                                             %
1954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1955 %
1956 %  NTSystemConfiguration() provides a way for the application to determine
1957 %  values for system limits or options at runtime.
1958 %
1959 %  The format of the exit method is:
1960 %
1961 %      ssize_t NTSystemConfiguration(int name)
1962 %
1963 %  A description of each parameter follows:
1964 %
1965 %    o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
1966 %
1967 */
1968 MagickExport ssize_t NTSystemConfiguration(int name)
1969 {
1970   switch (name)
1971   {
1972     case _SC_PAGESIZE:
1973     {
1974       SYSTEM_INFO
1975         system_info;
1976
1977       GetSystemInfo(&system_info);
1978       return(system_info.dwPageSize);
1979     }
1980     case _SC_PHYS_PAGES:
1981     {
1982       HMODULE
1983         handle;
1984
1985       LPFNDLLFUNC2
1986         module;
1987
1988       NTMEMORYSTATUSEX
1989         status;
1990
1991       SYSTEM_INFO
1992         system_info;
1993
1994       handle=GetModuleHandle("kernel32.dll");
1995       if (handle == (HMODULE) NULL)
1996         return(0L);
1997       GetSystemInfo(&system_info);
1998       module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
1999       if (module == (LPFNDLLFUNC2) NULL)
2000         {
2001           MEMORYSTATUS
2002             status;
2003
2004           GlobalMemoryStatus(&status);
2005           return((ssize_t) status.dwTotalPhys/system_info.dwPageSize);
2006         }
2007       status.dwLength=sizeof(status);
2008       if (module(&status) == 0)
2009         return(0L);
2010       return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
2011     }
2012     case _SC_OPEN_MAX:
2013       return(2048);
2014     default:
2015       break;
2016   }
2017   return(-1);
2018 }
2019 \f
2020 /*
2021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2022 %                                                                             %
2023 %                                                                             %
2024 %                                                                             %
2025 %   N T T e l l D i r e c t o r y                                             %
2026 %                                                                             %
2027 %                                                                             %
2028 %                                                                             %
2029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2030 %
2031 %  NTTellDirectory() returns the current location associated with the named
2032 %  directory stream.
2033 %
2034 %  The format of the NTTellDirectory method is:
2035 %
2036 %      ssize_t NTTellDirectory(DIR *entry)
2037 %
2038 %  A description of each parameter follows:
2039 %
2040 %    o entry: Specifies a pointer to a DIR structure.
2041 %
2042 */
2043 MagickExport ssize_t NTTellDirectory(DIR *entry)
2044 {
2045   assert(entry != (DIR *) NULL);
2046   return(0);
2047 }
2048 \f
2049 /*
2050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2051 %                                                                             %
2052 %                                                                             %
2053 %                                                                             %
2054 %   N T T r u n c a t e F i l e                                               %
2055 %                                                                             %
2056 %                                                                             %
2057 %                                                                             %
2058 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2059 %
2060 %  NTTruncateFile() truncates a file to a specified length.
2061 %
2062 %  The format of the NTTruncateFile method is:
2063 %
2064 %      int NTTruncateFile(int file,off_t length)
2065 %
2066 %  A description of each parameter follows:
2067 %
2068 %    o file: the file.
2069 %
2070 %    o length: the file length.
2071 %
2072 */
2073 MagickExport int NTTruncateFile(int file,off_t length)
2074 {
2075   DWORD
2076     file_pointer;
2077
2078   long
2079     file_handle,
2080     high,
2081     low;
2082
2083   file_handle=_get_osfhandle(file);
2084   if (file_handle == -1L)
2085     return(-1);
2086   low=(long) (length & 0xffffffffUL);
2087   high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
2088   file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2089   if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2090     return(-1);
2091   if (SetEndOfFile((HANDLE) file_handle) == 0)
2092     return(-1);
2093   return(0);
2094 }
2095 \f
2096 /*
2097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2098 %                                                                             %
2099 %                                                                             %
2100 %                                                                             %
2101 +  N T U n m a p M e m o r y                                                  %
2102 %                                                                             %
2103 %                                                                             %
2104 %                                                                             %
2105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2106 %
2107 %  NTUnmapMemory() emulates the Unix munmap method.
2108 %
2109 %  The format of the NTUnmapMemory method is:
2110 %
2111 %      int NTUnmapMemory(void *map,size_t length)
2112 %
2113 %  A description of each parameter follows:
2114 %
2115 %    o map: the address of the binary large object.
2116 %
2117 %    o length: the length of the binary large object.
2118 %
2119 */
2120 MagickExport int NTUnmapMemory(void *map,size_t length)
2121 {
2122   (void) length;
2123   if (UnmapViewOfFile(map) == 0)
2124     return(-1);
2125   return(0);
2126 }
2127 \f
2128 /*
2129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2130 %                                                                             %
2131 %                                                                             %
2132 %                                                                             %
2133 %   N T U s e r T i m e                                                       %
2134 %                                                                             %
2135 %                                                                             %
2136 %                                                                             %
2137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2138 %
2139 %  NTUserTime() returns the total time the process has been scheduled (e.g.
2140 %  seconds) since the last call to StartTimer().
2141 %
2142 %  The format of the UserTime method is:
2143 %
2144 %      double NTUserTime(void)
2145 %
2146 */
2147 MagickExport double NTUserTime(void)
2148 {
2149   DWORD
2150     status;
2151
2152   FILETIME
2153     create_time,
2154     exit_time;
2155
2156   OSVERSIONINFO
2157     OsVersionInfo;
2158
2159   union
2160   {
2161     FILETIME
2162       filetime;
2163
2164     __int64
2165       filetime64;
2166   } kernel_time;
2167
2168   union
2169   {
2170     FILETIME
2171       filetime;
2172
2173     __int64
2174       filetime64;
2175   } user_time;
2176
2177   OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2178   GetVersionEx(&OsVersionInfo);
2179   if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2180     return(NTElapsedTime());
2181   status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2182     &kernel_time.filetime,&user_time.filetime);
2183   if (status != TRUE)
2184     return(0.0);
2185   return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2186 }
2187 \f
2188 /*
2189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2190 %                                                                             %
2191 %                                                                             %
2192 %                                                                             %
2193 %   N T W a r n i n g H a n d l e r                                           %
2194 %                                                                             %
2195 %                                                                             %
2196 %                                                                             %
2197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2198 %
2199 %  NTWarningHandler() displays a warning reason.
2200 %
2201 %  The format of the NTWarningHandler method is:
2202 %
2203 %      void NTWarningHandler(const ExceptionType severity,const char *reason,
2204 %        const char *description)
2205 %
2206 %  A description of each parameter follows:
2207 %
2208 %    o severity: Specifies the numeric warning category.
2209 %
2210 %    o reason: Specifies the reason to display before terminating the
2211 %      program.
2212 %
2213 %    o description: Specifies any description to the reason.
2214 %
2215 */
2216 MagickExport void NTWarningHandler(const ExceptionType severity,
2217   const char *reason,const char *description)
2218 {
2219   char
2220     buffer[2*MaxTextExtent];
2221
2222   (void) severity;
2223   if (reason == (char *) NULL)
2224     return;
2225   if (description == (char *) NULL)
2226     (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
2227       reason);
2228   else
2229     (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
2230       GetClientName(),reason,description);
2231   (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2232     MB_SETFOREGROUND | MB_ICONINFORMATION);
2233 }
2234 #endif