blob: 38a00aa4f2d6e30900fb928888aca3d45d798af5 [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*/
cristy4c08aed2011-07-01 19:47:50 +000041#include "MagickCore/studio.h"
cristy0157aea2010-04-24 21:12:18 +000042#if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/client.h"
44#include "MagickCore/locale_.h"
45#include "MagickCore/log.h"
46#include "MagickCore/magick.h"
47#include "MagickCore/memory_.h"
48#include "MagickCore/resource_.h"
49#include "MagickCore/timer.h"
50#include "MagickCore/string_.h"
51#include "MagickCore/utility.h"
52#include "MagickCore/version.h"
cristy3ed852e2009-09-05 21:47:34 +000053#if defined(MAGICKCORE_LTDL_DELEGATE)
54# include "ltdl.h"
55#endif
cristy4c08aed2011-07-01 19:47:50 +000056#include "MagickCore/nt-base.h"
cristy3ed852e2009-09-05 21:47:34 +000057#if defined(MAGICKCORE_CIPHER_SUPPORT)
58#include <ntsecapi.h>
59#include <wincrypt.h>
60#endif
61
62/*
63 Define declarations.
64*/
65#if !defined(MAP_FAILED)
66#define MAP_FAILED ((void *) -1)
67#endif
68
69/*
70 Static declarations.
71*/
72#if !defined(MAGICKCORE_LTDL_DELEGATE)
73static char
74 *lt_slsearchpath = (char *) NULL;
75#endif
76
cristydefb3f02009-09-10 02:18:35 +000077static GhostInfo
78 ghost_info;
cristy3ed852e2009-09-05 21:47:34 +000079
80static void
cristydefb3f02009-09-10 02:18:35 +000081 *ghost_handle = (void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +000082
83/*
84 External declarations.
85*/
cristy0157aea2010-04-24 21:12:18 +000086#if !defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000087extern "C" BOOL WINAPI
88 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
89#endif
90
91/*
92%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93% %
94% %
95% %
96% D l l M a i n %
97% %
98% %
99% %
100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101%
102% DllMain() is an entry point to the DLL which is called when processes and
103% threads are initialized and terminated, or upon calls to the Windows
104% LoadLibrary and FreeLibrary functions.
105%
106% The function returns TRUE of it succeeds, or FALSE if initialization fails.
107%
108% The format of the DllMain method is:
109%
110% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
111%
112% A description of each parameter follows:
113%
114% o handle: handle to the DLL module
115%
116% o reason: reason for calling function:
117%
118% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
119% space of current process.
120% DLL_THREAD_ATTACH - Indicates that the current process is
121% creating a new thread. Called under the
122% context of the new thread.
123% DLL_THREAD_DETACH - Indicates that the thread is exiting.
124% Called under the context of the exiting
125% thread.
126% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
127% from the virtual address space of the
128% current process.
129%
130% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
131% and DLL_PROCESS_DETACH.
132%
133*/
134#if defined(_DLL) && defined( ProvideDllMain )
135BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
136{
137 switch (reason)
138 {
139 case DLL_PROCESS_ATTACH:
140 {
141 char
142 *module_path;
143
144 ssize_t
145 count;
146
147 module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
148 sizeof(*module_path));
149 if (module_path == (char *) NULL)
150 return(FALSE);
151 count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
152 if (count != 0)
153 {
154 char
155 *path;
156
157 for ( ; count > 0; count--)
158 if (module_path[count] == '\\')
159 {
160 module_path[count+1]='\0';
161 break;
162 }
163 MagickCoreGenesis(module_path,MagickFalse);
164 path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
165 if (path == (char *) NULL)
166 {
167 module_path=DestroyString(module_path);
168 return(FALSE);
169 }
170 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
171 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
172 {
173 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
174 {
175 char
176 *variable;
177
178 variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
179 sizeof(*variable));
180 if (variable == (char *) NULL)
181 {
182 path=DestroyString(path);
183 module_path=DestroyString(module_path);
184 return(FALSE);
185 }
cristyb51dff52011-05-19 16:55:47 +0000186 (void) FormatLocaleString(variable,16*MaxTextExtent,
cristy3ed852e2009-09-05 21:47:34 +0000187 "%s;%s",module_path,path);
188 SetEnvironmentVariable("PATH",variable);
189 variable=DestroyString(variable);
190 }
191 }
192 path=DestroyString(path);
193 }
194 module_path=DestroyString(module_path);
195 break;
196 }
197 case DLL_PROCESS_DETACH:
198 {
199 MagickCoreTerminus();
200 break;
201 }
202 default:
203 break;
204 }
205 return(TRUE);
206}
207#endif
208
209/*
210%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211% %
212% %
213% %
214% E x i t %
215% %
216% %
217% %
218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219%
220% Exit() calls TerminateProcess for Win95.
221%
222% The format of the exit method is:
223%
224% int Exit(int status)
225%
226% A description of each parameter follows:
227%
228% o status: an integer value representing the status of the terminating
229% process.
230%
231*/
232MagickExport int Exit(int status)
233{
234 if (IsWindows95())
235 TerminateProcess(GetCurrentProcess(),(unsigned int) status);
236 exit(status);
237 return(0);
238}
239
cristy0157aea2010-04-24 21:12:18 +0000240#if !defined(__MINGW32__)
cristy3ed852e2009-09-05 21:47:34 +0000241/*
242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243% %
244% %
245% %
cristy6d71f8d2010-02-28 00:46:02 +0000246% g e t t i m e o f d a y %
247% %
248% %
249% %
250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
251%
252% The gettimeofday() method get the time of day.
253%
254% The format of the gettimeofday method is:
255%
256% int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
257%
258% A description of each parameter follows:
259%
260% o time_value: the time value.
261%
262% o time_zone: the time zone.
263%
264*/
265MagickExport int gettimeofday (struct timeval *time_value,
266 struct timezone *time_zone)
267{
cristyc05bf172010-06-04 19:53:53 +0000268#define EpochFiletime MagickLLConstant(116444736000000000)
cristy6d71f8d2010-02-28 00:46:02 +0000269
270 static int
271 is_tz_set;
272
273 if (time_value != (struct timeval *) NULL)
274 {
275 FILETIME
276 file_time;
277
278 __int64
279 time;
280
281 LARGE_INTEGER
282 date_time;
283
284 GetSystemTimeAsFileTime(&file_time);
285 date_time.LowPart=file_time.dwLowDateTime;
286 date_time.HighPart=file_time.dwHighDateTime;
287 time=date_time.QuadPart;
cristy99881662010-03-04 14:25:26 +0000288 time-=EpochFiletime;
cristy6d71f8d2010-02-28 00:46:02 +0000289 time/=10;
cristybb503372010-05-27 20:51:26 +0000290 time_value->tv_sec=(ssize_t) (time / 1000000);
291 time_value->tv_usec=(ssize_t) (time % 1000000);
cristy6d71f8d2010-02-28 00:46:02 +0000292 }
293 if (time_zone != (struct timezone *) NULL)
294 {
295 if (is_tz_set == 0)
296 {
297 _tzset();
298 is_tz_set++;
299 }
300 time_zone->tz_minuteswest=_timezone/60;
301 time_zone->tz_dsttime=_daylight;
302 }
303 return(0);
304}
cristy807fd932010-04-24 03:38:46 +0000305#endif
cristy6d71f8d2010-02-28 00:46:02 +0000306
307/*
308%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309% %
310% %
311% %
cristy3ed852e2009-09-05 21:47:34 +0000312% I s W i n d o w s 9 5 %
313% %
314% %
315% %
316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317%
318% IsWindows95() returns true if the system is Windows 95.
319%
320% The format of the IsWindows95 method is:
321%
322% int IsWindows95()
323%
324*/
325MagickExport int IsWindows95()
326{
327 OSVERSIONINFO
328 version_info;
329
330 version_info.dwOSVersionInfoSize=sizeof(version_info);
331 if (GetVersionEx(&version_info) &&
332 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
333 return(1);
334 return(0);
335}
336
337/*
338%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339% %
340% %
341% %
342% N T C l o s e D i r e c t o r y %
343% %
344% %
345% %
346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347%
348% NTCloseDirectory() closes the named directory stream and frees the DIR
349% structure.
350%
351% The format of the NTCloseDirectory method is:
352%
353% int NTCloseDirectory(DIR *entry)
354%
355% A description of each parameter follows:
356%
357% o entry: Specifies a pointer to a DIR structure.
358%
359*/
360MagickExport int NTCloseDirectory(DIR *entry)
361{
362 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
363 assert(entry != (DIR *) NULL);
364 FindClose(entry->hSearch);
365 entry=(DIR *) RelinquishMagickMemory(entry);
366 return(0);
367}
368
369/*
370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371% %
372% %
373% %
374% N T C l o s e L i b r a r y %
375% %
376% %
377% %
378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379%
380% NTCloseLibrary() unloads the module associated with the passed handle.
381%
382% The format of the NTCloseLibrary method is:
383%
384% void NTCloseLibrary(void *handle)
385%
386% A description of each parameter follows:
387%
388% o handle: Specifies a handle to a previously loaded dynamic module.
389%
390*/
391MagickExport int NTCloseLibrary(void *handle)
392{
393 if (IsWindows95())
394 return(FreeLibrary((HINSTANCE) handle));
395 return(!(FreeLibrary((HINSTANCE) handle)));
396}
397
398/*
399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400% %
401% %
402% %
403% N T C o n t r o l H a n d l e r %
404% %
405% %
406% %
407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408%
409% NTControlHandler() registers a control handler that is activated when, for
410% example, a ctrl-c is received.
411%
412% The format of the NTControlHandler method is:
413%
414% int NTControlHandler(void)
415%
416*/
417
418static BOOL ControlHandler(DWORD type)
419{
cristy3b743bb2009-09-14 16:07:59 +0000420 (void) type;
cristyf34a1452009-10-24 22:29:27 +0000421 AsynchronousResourceComponentTerminus();
cristy3ed852e2009-09-05 21:47:34 +0000422 return(FALSE);
423}
424
425MagickExport int NTControlHandler(void)
426{
427 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
428}
429
430/*
431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432% %
433% %
434% %
435% N T E l a p s e d T i m e %
436% %
437% %
438% %
439%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440%
441% NTElapsedTime() returns the elapsed time (in seconds) since the last call to
442% StartTimer().
443%
444% The format of the ElapsedTime method is:
445%
446% double NTElapsedTime(void)
447%
448*/
449MagickExport double NTElapsedTime(void)
450{
451 union
452 {
453 FILETIME
454 filetime;
455
456 __int64
457 filetime64;
458 } elapsed_time;
459
460 SYSTEMTIME
461 system_time;
462
463 GetSystemTime(&system_time);
464 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
465 return((double) 1.0e-7*elapsed_time.filetime64);
466}
467
468/*
469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470% %
471% %
472% %
473+ N T E r r o r H a n d l e r %
474% %
475% %
476% %
477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478%
479% NTErrorHandler() displays an error reason and then terminates the program.
480%
481% The format of the NTErrorHandler method is:
482%
cristy3b743bb2009-09-14 16:07:59 +0000483% void NTErrorHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +0000484% const char *description)
485%
486% A description of each parameter follows:
487%
cristy3b743bb2009-09-14 16:07:59 +0000488% o severity: Specifies the numeric error category.
cristy3ed852e2009-09-05 21:47:34 +0000489%
490% o reason: Specifies the reason to display before terminating the
491% program.
492%
493% o description: Specifies any description to the reason.
494%
495*/
cristy3b743bb2009-09-14 16:07:59 +0000496MagickExport void NTErrorHandler(const ExceptionType severity,
497 const char *reason,const char *description)
cristy3ed852e2009-09-05 21:47:34 +0000498{
499 char
500 buffer[3*MaxTextExtent],
501 *message;
502
cristy3b743bb2009-09-14 16:07:59 +0000503 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +0000504 if (reason == (char *) NULL)
505 {
506 MagickCoreTerminus();
507 exit(0);
508 }
509 message=GetExceptionMessage(errno);
510 if ((description != (char *) NULL) && errno)
cristyb51dff52011-05-19 16:55:47 +0000511 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000512 GetClientName(),reason,description,message);
513 else
514 if (description != (char *) NULL)
cristyb51dff52011-05-19 16:55:47 +0000515 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +0000516 GetClientName(),reason,description);
517 else
518 if (errno != 0)
cristyb51dff52011-05-19 16:55:47 +0000519 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s [%s].\n",
cristy3ed852e2009-09-05 21:47:34 +0000520 GetClientName(),reason,message);
521 else
cristyb51dff52011-05-19 16:55:47 +0000522 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",
cristy3ed852e2009-09-05 21:47:34 +0000523 GetClientName(),reason);
524 message=DestroyString(message);
525 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
526 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
527 MagickCoreTerminus();
528 exit(0);
529}
530
531/*
532%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
533% %
534% %
535% %
536% N T E x i t L i b r a r y %
537% %
538% %
539% %
540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
541%
542% NTExitLibrary() exits the dynamic module loading subsystem.
543%
544% The format of the NTExitLibrary method is:
545%
546% int NTExitLibrary(void)
547%
548*/
549MagickExport int NTExitLibrary(void)
550{
551 return(0);
552}
553
554/*
555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556% %
557% %
558% %
559% N T G a t h e r R a n d o m D a t a %
560% %
561% %
562% %
563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564%
565% NTGatherRandomData() gathers random data and returns it.
566%
567% The format of the GatherRandomData method is:
568%
569% MagickBooleanType NTGatherRandomData(const size_t length,
570% unsigned char *random)
571%
572% A description of each parameter follows:
573%
574% length: the length of random data buffer
575%
576% random: the random data is returned here.
577%
578*/
579MagickExport MagickBooleanType NTGatherRandomData(const size_t length,
580 unsigned char *random)
581{
582#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
583 HCRYPTPROV
584 handle;
585
586 int
587 status;
588
589 handle=(HCRYPTPROV) NULL;
590 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
591 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
592 if (status == 0)
593 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
594 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
595 if (status == 0)
596 return(MagickFalse);
597 status=CryptGenRandom(handle,(DWORD) length,random);
598 if (status == 0)
599 {
600 status=CryptReleaseContext(handle,0);
601 return(MagickFalse);
602 }
603 status=CryptReleaseContext(handle,0);
604 if (status == 0)
605 return(MagickFalse);
cristy3b743bb2009-09-14 16:07:59 +0000606#else
607 (void) random;
608 (void) length;
cristy3ed852e2009-09-05 21:47:34 +0000609#endif
610 return(MagickTrue);
611}
612
613/*
614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
615% %
616% %
617% %
618% N T G e t E x e c u t i o n P a t h %
619% %
620% %
621% %
622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
623%
624% NTGetExecutionPath() returns the execution path of a program.
625%
626% The format of the GetExecutionPath method is:
627%
628% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
629%
630% A description of each parameter follows:
631%
632% o path: the pathname of the executable that started the process.
633%
634% o extent: the maximum extent of the path.
635%
636*/
637MagickExport MagickBooleanType NTGetExecutionPath(char *path,
638 const size_t extent)
639{
640 GetModuleFileName(0,path,(DWORD) extent);
641 return(MagickTrue);
642}
643
644/*
645%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646% %
647% %
648% %
649% N T G e t L a s t E r r o r %
650% %
651% %
652% %
653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654%
655% NTGetLastError() returns the last error that occurred.
656%
657% The format of the NTGetLastError method is:
658%
659% char *NTGetLastError(void)
660%
661*/
662char *NTGetLastError(void)
663{
664 char
665 *reason;
666
667 int
668 status;
669
670 LPVOID
671 buffer;
672
673 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
674 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
675 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
676 if (!status)
677 reason=AcquireString("An unknown error occurred");
678 else
679 {
680 reason=AcquireString((const char *) buffer);
681 LocalFree(buffer);
682 }
683 return(reason);
684}
685
686/*
687%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688% %
689% %
690% %
691% N T G e t L i b r a r y E r r o r %
692% %
693% %
694% %
695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696%
697% Lt_dlerror() returns a pointer to a string describing the last error
698% associated with a lt_dl method. Note that this function is not thread
699% safe so it should only be used under the protection of a lock.
700%
701% The format of the NTGetLibraryError method is:
702%
703% const char *NTGetLibraryError(void)
704%
705*/
706MagickExport const char *NTGetLibraryError(void)
707{
708 static char
709 last_error[MaxTextExtent];
710
711 char
712 *error;
713
714 *last_error='\0';
715 error=NTGetLastError();
716 if (error)
717 (void) CopyMagickString(last_error,error,MaxTextExtent);
718 error=DestroyString(error);
719 return(last_error);
720}
721
722/*
723%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
724% %
725% %
726% %
727% N T G e t L i b r a r y S y m b o l %
728% %
729% %
730% %
731%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
732%
733% NTGetLibrarySymbol() retrieve the procedure address of the method
734% specified by the passed character string.
735%
736% The format of the NTGetLibrarySymbol method is:
737%
738% void *NTGetLibrarySymbol(void *handle,const char *name)
739%
740% A description of each parameter follows:
741%
742% o handle: Specifies a handle to the previously loaded dynamic module.
743%
744% o name: Specifies the procedure entry point to be returned.
745%
746*/
747void *NTGetLibrarySymbol(void *handle,const char *name)
748{
749 LPFNDLLFUNC1
750 lpfnDllFunc1;
751
752 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
753 if (!lpfnDllFunc1)
754 return((void *) NULL);
755 return((void *) lpfnDllFunc1);
756}
757
758/*
759%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760% %
761% %
762% %
763% N T G e t M o d u l e P a t h %
764% %
765% %
766% %
767%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768%
769% NTGetModulePath() returns the path of the specified module.
770%
771% The format of the GetModulePath method is:
772%
773% MagickBooleanType NTGetModulePath(const char *module,char *path)
774%
775% A description of each parameter follows:
776%
777% modith: the module name.
778%
779% path: the module path is returned here.
780%
781*/
782MagickExport MagickBooleanType NTGetModulePath(const char *module,char *path)
783{
784 char
785 module_path[MaxTextExtent];
786
787 HMODULE
788 handle;
789
cristybb503372010-05-27 20:51:26 +0000790 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000791 length;
792
793 *path='\0';
794 handle=GetModuleHandle(module);
795 if (handle == (HMODULE) NULL)
796 return(MagickFalse);
797 length=GetModuleFileName(handle,module_path,MaxTextExtent);
798 if (length != 0)
799 GetPathComponent(module_path,HeadPath,path);
800 return(MagickTrue);
801}
802
803/*
804%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
805% %
806% %
807% %
808% N T G h o s t s c r i p t D L L %
809% %
810% %
811% %
812%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813%
cristydefb3f02009-09-10 02:18:35 +0000814% NTGhostscriptDLL() returns the path to the most recent Ghostscript version
815% DLL. The method returns TRUE on success otherwise FALSE.
cristy3ed852e2009-09-05 21:47:34 +0000816%
817% The format of the NTGhostscriptDLL method is:
818%
cristyfc0f64b2009-09-09 18:57:08 +0000819% int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +0000820%
821% A description of each parameter follows:
822%
cristyfc0f64b2009-09-09 18:57:08 +0000823% o path: return the Ghostscript DLL path here.
cristy3ed852e2009-09-05 21:47:34 +0000824%
cristyfc0f64b2009-09-09 18:57:08 +0000825% o length: the buffer length.
cristy3ed852e2009-09-05 21:47:34 +0000826%
827*/
828
cristyfc0f64b2009-09-09 18:57:08 +0000829static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
830 char *value,int *length)
cristy3ed852e2009-09-05 21:47:34 +0000831{
cristyfc0f64b2009-09-09 18:57:08 +0000832 BYTE
833 byte,
cristy3ed852e2009-09-05 21:47:34 +0000834 *p;
835
cristyfc0f64b2009-09-09 18:57:08 +0000836 DWORD
837 extent,
838 type;
cristy3ed852e2009-09-05 21:47:34 +0000839
cristy3ed852e2009-09-05 21:47:34 +0000840 HKEY
841 hkey;
842
cristy3ed852e2009-09-05 21:47:34 +0000843 LONG
cristyfc0f64b2009-09-09 18:57:08 +0000844 status;
cristy3ed852e2009-09-05 21:47:34 +0000845
cristyfc0f64b2009-09-09 18:57:08 +0000846 /*
cristydefb3f02009-09-10 02:18:35 +0000847 Get a registry value: key = root\\key, named value = name.
848 */
cristyfc0f64b2009-09-09 18:57:08 +0000849 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
850 return(1); /* no match */
851 p=(BYTE *) value;
852 type=REG_SZ;
853 extent=(*length);
854 if (p == (BYTE *) NULL)
cristydefb3f02009-09-10 02:18:35 +0000855 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
cristyfc0f64b2009-09-09 18:57:08 +0000856 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
857 RegCloseKey(hkey);
858 if (status == ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +0000859 {
cristyfc0f64b2009-09-09 18:57:08 +0000860 *length=extent;
861 return(0); /* return the match */
862 }
863 if (status == ERROR_MORE_DATA)
864 {
865 *length=extent;
cristydefb3f02009-09-10 02:18:35 +0000866 return(-1); /* buffer not large enough */
cristy3ed852e2009-09-05 21:47:34 +0000867 }
868 return(1); /* not found */
869}
870
cristydefb3f02009-09-10 02:18:35 +0000871static int NTLocateGhostscript(const char **product_family,int *major_version,
cristyfc0f64b2009-09-09 18:57:08 +0000872 int *minor_version)
cristy3ed852e2009-09-05 21:47:34 +0000873{
cristyfc0f64b2009-09-09 18:57:08 +0000874 int
875 i;
cristy3ed852e2009-09-05 21:47:34 +0000876
cristyfc0f64b2009-09-09 18:57:08 +0000877 MagickBooleanType
878 status;
879
880 static const char
881 *products[4] =
882 {
883 "GPL Ghostscript",
884 "GNU Ghostscript",
885 "AFPL Ghostscript",
cristy82b15832009-10-06 19:17:37 +0000886 "Aladdin Ghostscript"
cristyfc0f64b2009-09-09 18:57:08 +0000887 };
888
889 /*
890 Find the most recent version of Ghostscript.
891 */
892 status=FALSE;
893 *product_family=NULL;
894 *major_version=5;
895 *minor_version=49; /* min version of Ghostscript is 5.50 */
cristybb503372010-05-27 20:51:26 +0000896 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +0000897 {
898 char
899 key[MaxTextExtent];
900
901 HKEY
902 hkey,
903 root;
904
cristye66bcb42009-09-17 13:31:08 +0000905 REGSAM
906 mode;
907
cristyb51dff52011-05-19 16:55:47 +0000908 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
cristyfc0f64b2009-09-09 18:57:08 +0000909 root=HKEY_LOCAL_MACHINE;
cristye66bcb42009-09-17 13:31:08 +0000910 mode=KEY_READ;
911#if defined(KEY_WOW64_32KEY)
912 mode|=KEY_WOW64_32KEY;
913#endif
914 if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
cristyfc0f64b2009-09-09 18:57:08 +0000915 {
916 DWORD
917 extent;
918
919 int
920 j;
921
922 /*
923 Now enumerate the keys.
924 */
925 extent=sizeof(key)/sizeof(char);
926 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
927 {
928 int
929 major,
930 minor;
931
932 major=0;
933 minor=0;
934 if (sscanf(key,"%d.%d",&major,&minor) != 2)
935 continue;
936 if ((major > *major_version) || ((major == *major_version) &&
937 (minor > *minor_version)))
938 {
939 *product_family=products[i];
940 *major_version=major;
941 *minor_version=minor;
cristy37f63772009-11-16 17:06:36 +0000942 status=TRUE;
cristyfc0f64b2009-09-09 18:57:08 +0000943 }
cristyfc0f64b2009-09-09 18:57:08 +0000944 }
cristye66bcb42009-09-17 13:31:08 +0000945 (void) RegCloseKey(hkey);
946 }
947 }
cristy37f63772009-11-16 17:06:36 +0000948 if (status == FALSE)
cristyfc0f64b2009-09-09 18:57:08 +0000949 {
950 *major_version=0;
951 *minor_version=0;
952 }
953 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
954 "version %d.%02d",*product_family,*major_version,*minor_version);
955 return(status);
956}
957
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);
cristyb51dff52011-05-19 16:55:47 +0000997 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
cristyfc0f64b2009-09-09 18:57:08 +0000998 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,'\\');
cristy7ba1b042011-02-05 19:07:50 +00001094 if (p != (char *) NULL)
cristy4c11ed82009-09-11 03:36:46 +00001095 {
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';
cristyb51dff52011-05-19 16:55:47 +00001148 (void) FormatLocaleString(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);
cristy37e0b382011-06-07 13:31:21 +00001377 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001378 return((DIR *) NULL);
1379 length=ConcatenateMagickString(file_specification,DirectorySeparator,
1380 MaxTextExtent);
cristy37e0b382011-06-07 13:31:21 +00001381 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001382 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);
cristy37e0b382011-06-07 13:31:21 +00001392 if (length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001393 {
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 */
cristyb51dff52011-05-19 16:55:47 +00001599 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
cristy3ed852e2009-09-05 21:47:34 +00001600 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);
cristyb51dff52011-05-19 16:55:47 +00001732 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
cristy3ed852e2009-09-05 21:47:34 +00001733 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)
cristyb51dff52011-05-19 16:55:47 +00002226 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
cristy3ed852e2009-09-05 21:47:34 +00002227 reason);
2228 else
cristyb51dff52011-05-19 16:55:47 +00002229 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
cristy3ed852e2009-09-05 21:47:34 +00002230 GetClientName(),reason,description);
2231 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2232 MB_SETFOREGROUND | MB_ICONINFORMATION);
2233}
2234#endif