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