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