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