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