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