blob: a8d3197e83e07935918f68b1ec3a39a451cacd12 [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% %
20% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38/*
39 Include declarations.
40*/
41#include "magick/studio.h"
42#if defined(__WINDOWS__)
43#include "magick/client.h"
44#include "magick/log.h"
45#include "magick/magick.h"
46#include "magick/memory_.h"
47#include "magick/resource_.h"
48#include "magick/timer.h"
49#include "magick/string_.h"
50#include "magick/utility.h"
51#include "magick/version.h"
52#if defined(MAGICKCORE_LTDL_DELEGATE)
53# include "ltdl.h"
54#endif
55#include "magick/nt-base.h"
56#if defined(MAGICKCORE_CIPHER_SUPPORT)
57#include <ntsecapi.h>
58#include <wincrypt.h>
59#endif
60
61/*
62 Define declarations.
63*/
64#if !defined(MAP_FAILED)
65#define MAP_FAILED ((void *) -1)
66#endif
67
68/*
69 Static declarations.
70*/
71#if !defined(MAGICKCORE_LTDL_DELEGATE)
72static char
73 *lt_slsearchpath = (char *) NULL;
74#endif
75
cristydefb3f02009-09-10 02:18:35 +000076static GhostInfo
77 ghost_info;
cristy3ed852e2009-09-05 21:47:34 +000078
79static void
cristydefb3f02009-09-10 02:18:35 +000080 *ghost_handle = (void *) NULL;
cristy3ed852e2009-09-05 21:47:34 +000081
82/*
83 External declarations.
84*/
85#if !defined(__WINDOWS__)
86extern "C" BOOL WINAPI
87 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
88#endif
89
90/*
91%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92% %
93% %
94% %
95% D l l M a i n %
96% %
97% %
98% %
99%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100%
101% DllMain() is an entry point to the DLL which is called when processes and
102% threads are initialized and terminated, or upon calls to the Windows
103% LoadLibrary and FreeLibrary functions.
104%
105% The function returns TRUE of it succeeds, or FALSE if initialization fails.
106%
107% The format of the DllMain method is:
108%
109% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
110%
111% A description of each parameter follows:
112%
113% o handle: handle to the DLL module
114%
115% o reason: reason for calling function:
116%
117% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address
118% space of current process.
119% DLL_THREAD_ATTACH - Indicates that the current process is
120% creating a new thread. Called under the
121% context of the new thread.
122% DLL_THREAD_DETACH - Indicates that the thread is exiting.
123% Called under the context of the exiting
124% thread.
125% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
126% from the virtual address space of the
127% current process.
128%
129% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
130% and DLL_PROCESS_DETACH.
131%
132*/
133#if defined(_DLL) && defined( ProvideDllMain )
134BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
135{
136 switch (reason)
137 {
138 case DLL_PROCESS_ATTACH:
139 {
140 char
141 *module_path;
142
143 ssize_t
144 count;
145
146 module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
147 sizeof(*module_path));
148 if (module_path == (char *) NULL)
149 return(FALSE);
150 count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
151 if (count != 0)
152 {
153 char
154 *path;
155
156 for ( ; count > 0; count--)
157 if (module_path[count] == '\\')
158 {
159 module_path[count+1]='\0';
160 break;
161 }
162 MagickCoreGenesis(module_path,MagickFalse);
163 path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
164 if (path == (char *) NULL)
165 {
166 module_path=DestroyString(module_path);
167 return(FALSE);
168 }
169 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
170 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
171 {
172 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
173 {
174 char
175 *variable;
176
177 variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
178 sizeof(*variable));
179 if (variable == (char *) NULL)
180 {
181 path=DestroyString(path);
182 module_path=DestroyString(module_path);
183 return(FALSE);
184 }
185 (void) FormatMagickString(variable,16*MaxTextExtent,
186 "%s;%s",module_path,path);
187 SetEnvironmentVariable("PATH",variable);
188 variable=DestroyString(variable);
189 }
190 }
191 path=DestroyString(path);
192 }
193 module_path=DestroyString(module_path);
194 break;
195 }
196 case DLL_PROCESS_DETACH:
197 {
198 MagickCoreTerminus();
199 break;
200 }
201 default:
202 break;
203 }
204 return(TRUE);
205}
206#endif
207
208/*
209%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
210% %
211% %
212% %
213% E x i t %
214% %
215% %
216% %
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218%
219% Exit() calls TerminateProcess for Win95.
220%
221% The format of the exit method is:
222%
223% int Exit(int status)
224%
225% A description of each parameter follows:
226%
227% o status: an integer value representing the status of the terminating
228% process.
229%
230*/
231MagickExport int Exit(int status)
232{
233 if (IsWindows95())
234 TerminateProcess(GetCurrentProcess(),(unsigned int) status);
235 exit(status);
236 return(0);
237}
238
239/*
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241% %
242% %
243% %
244% I s W i n d o w s 9 5 %
245% %
246% %
247% %
248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249%
250% IsWindows95() returns true if the system is Windows 95.
251%
252% The format of the IsWindows95 method is:
253%
254% int IsWindows95()
255%
256*/
257MagickExport int IsWindows95()
258{
259 OSVERSIONINFO
260 version_info;
261
262 version_info.dwOSVersionInfoSize=sizeof(version_info);
263 if (GetVersionEx(&version_info) &&
264 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
265 return(1);
266 return(0);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
274% N T C l o s e D i r e c t o r y %
275% %
276% %
277% %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
280% NTCloseDirectory() closes the named directory stream and frees the DIR
281% structure.
282%
283% The format of the NTCloseDirectory method is:
284%
285% int NTCloseDirectory(DIR *entry)
286%
287% A description of each parameter follows:
288%
289% o entry: Specifies a pointer to a DIR structure.
290%
291*/
292MagickExport int NTCloseDirectory(DIR *entry)
293{
294 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
295 assert(entry != (DIR *) NULL);
296 FindClose(entry->hSearch);
297 entry=(DIR *) RelinquishMagickMemory(entry);
298 return(0);
299}
300
301/*
302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303% %
304% %
305% %
306% N T C l o s e L i b r a r y %
307% %
308% %
309% %
310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311%
312% NTCloseLibrary() unloads the module associated with the passed handle.
313%
314% The format of the NTCloseLibrary method is:
315%
316% void NTCloseLibrary(void *handle)
317%
318% A description of each parameter follows:
319%
320% o handle: Specifies a handle to a previously loaded dynamic module.
321%
322*/
323MagickExport int NTCloseLibrary(void *handle)
324{
325 if (IsWindows95())
326 return(FreeLibrary((HINSTANCE) handle));
327 return(!(FreeLibrary((HINSTANCE) handle)));
328}
329
330/*
331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332% %
333% %
334% %
335% N T C o n t r o l H a n d l e r %
336% %
337% %
338% %
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340%
341% NTControlHandler() registers a control handler that is activated when, for
342% example, a ctrl-c is received.
343%
344% The format of the NTControlHandler method is:
345%
346% int NTControlHandler(void)
347%
348*/
349
350static BOOL ControlHandler(DWORD type)
351{
cristy3b743bb2009-09-14 16:07:59 +0000352 (void) type;
cristy3ed852e2009-09-05 21:47:34 +0000353 AsynchronousDestroyMagickResources();
354 return(FALSE);
355}
356
357MagickExport int NTControlHandler(void)
358{
359 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
360}
361
362/*
363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364% %
365% %
366% %
367% N T E l a p s e d T i m e %
368% %
369% %
370% %
371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372%
373% NTElapsedTime() returns the elapsed time (in seconds) since the last call to
374% StartTimer().
375%
376% The format of the ElapsedTime method is:
377%
378% double NTElapsedTime(void)
379%
380*/
381MagickExport double NTElapsedTime(void)
382{
383 union
384 {
385 FILETIME
386 filetime;
387
388 __int64
389 filetime64;
390 } elapsed_time;
391
392 SYSTEMTIME
393 system_time;
394
395 GetSystemTime(&system_time);
396 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
397 return((double) 1.0e-7*elapsed_time.filetime64);
398}
399
400/*
401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402% %
403% %
404% %
405+ N T E r r o r H a n d l e r %
406% %
407% %
408% %
409%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410%
411% NTErrorHandler() displays an error reason and then terminates the program.
412%
413% The format of the NTErrorHandler method is:
414%
cristy3b743bb2009-09-14 16:07:59 +0000415% void NTErrorHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +0000416% const char *description)
417%
418% A description of each parameter follows:
419%
cristy3b743bb2009-09-14 16:07:59 +0000420% o severity: Specifies the numeric error category.
cristy3ed852e2009-09-05 21:47:34 +0000421%
422% o reason: Specifies the reason to display before terminating the
423% program.
424%
425% o description: Specifies any description to the reason.
426%
427*/
cristy3b743bb2009-09-14 16:07:59 +0000428MagickExport void NTErrorHandler(const ExceptionType severity,
429 const char *reason,const char *description)
cristy3ed852e2009-09-05 21:47:34 +0000430{
431 char
432 buffer[3*MaxTextExtent],
433 *message;
434
cristy3b743bb2009-09-14 16:07:59 +0000435 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +0000436 if (reason == (char *) NULL)
437 {
438 MagickCoreTerminus();
439 exit(0);
440 }
441 message=GetExceptionMessage(errno);
442 if ((description != (char *) NULL) && errno)
443 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
444 GetClientName(),reason,description,message);
445 else
446 if (description != (char *) NULL)
447 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
448 GetClientName(),reason,description);
449 else
450 if (errno != 0)
451 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s [%s].\n",
452 GetClientName(),reason,message);
453 else
454 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",
455 GetClientName(),reason);
456 message=DestroyString(message);
457 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
458 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
459 MagickCoreTerminus();
460 exit(0);
461}
462
463/*
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465% %
466% %
467% %
468% N T E x i t L i b r a r y %
469% %
470% %
471% %
472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473%
474% NTExitLibrary() exits the dynamic module loading subsystem.
475%
476% The format of the NTExitLibrary method is:
477%
478% int NTExitLibrary(void)
479%
480*/
481MagickExport int NTExitLibrary(void)
482{
483 return(0);
484}
485
486/*
487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488% %
489% %
490% %
491% N T G a t h e r R a n d o m D a t a %
492% %
493% %
494% %
495%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496%
497% NTGatherRandomData() gathers random data and returns it.
498%
499% The format of the GatherRandomData method is:
500%
501% MagickBooleanType NTGatherRandomData(const size_t length,
502% unsigned char *random)
503%
504% A description of each parameter follows:
505%
506% length: the length of random data buffer
507%
508% random: the random data is returned here.
509%
510*/
511MagickExport MagickBooleanType NTGatherRandomData(const size_t length,
512 unsigned char *random)
513{
514#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
515 HCRYPTPROV
516 handle;
517
518 int
519 status;
520
521 handle=(HCRYPTPROV) NULL;
522 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
523 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
524 if (status == 0)
525 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
526 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
527 if (status == 0)
528 return(MagickFalse);
529 status=CryptGenRandom(handle,(DWORD) length,random);
530 if (status == 0)
531 {
532 status=CryptReleaseContext(handle,0);
533 return(MagickFalse);
534 }
535 status=CryptReleaseContext(handle,0);
536 if (status == 0)
537 return(MagickFalse);
cristy3b743bb2009-09-14 16:07:59 +0000538#else
539 (void) random;
540 (void) length;
cristy3ed852e2009-09-05 21:47:34 +0000541#endif
542 return(MagickTrue);
543}
544
545/*
546%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
547% %
548% %
549% %
550% N T G e t E x e c u t i o n P a t h %
551% %
552% %
553% %
554%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555%
556% NTGetExecutionPath() returns the execution path of a program.
557%
558% The format of the GetExecutionPath method is:
559%
560% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
561%
562% A description of each parameter follows:
563%
564% o path: the pathname of the executable that started the process.
565%
566% o extent: the maximum extent of the path.
567%
568*/
569MagickExport MagickBooleanType NTGetExecutionPath(char *path,
570 const size_t extent)
571{
572 GetModuleFileName(0,path,(DWORD) extent);
573 return(MagickTrue);
574}
575
576/*
577%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578% %
579% %
580% %
581% N T G e t L a s t E r r o r %
582% %
583% %
584% %
585%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
586%
587% NTGetLastError() returns the last error that occurred.
588%
589% The format of the NTGetLastError method is:
590%
591% char *NTGetLastError(void)
592%
593*/
594char *NTGetLastError(void)
595{
596 char
597 *reason;
598
599 int
600 status;
601
602 LPVOID
603 buffer;
604
605 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
606 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
607 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
608 if (!status)
609 reason=AcquireString("An unknown error occurred");
610 else
611 {
612 reason=AcquireString((const char *) buffer);
613 LocalFree(buffer);
614 }
615 return(reason);
616}
617
618/*
619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620% %
621% %
622% %
623% N T G e t L i b r a r y E r r o r %
624% %
625% %
626% %
627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628%
629% Lt_dlerror() returns a pointer to a string describing the last error
630% associated with a lt_dl method. Note that this function is not thread
631% safe so it should only be used under the protection of a lock.
632%
633% The format of the NTGetLibraryError method is:
634%
635% const char *NTGetLibraryError(void)
636%
637*/
638MagickExport const char *NTGetLibraryError(void)
639{
640 static char
641 last_error[MaxTextExtent];
642
643 char
644 *error;
645
646 *last_error='\0';
647 error=NTGetLastError();
648 if (error)
649 (void) CopyMagickString(last_error,error,MaxTextExtent);
650 error=DestroyString(error);
651 return(last_error);
652}
653
654/*
655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656% %
657% %
658% %
659% N T G e t L i b r a r y S y m b o l %
660% %
661% %
662% %
663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664%
665% NTGetLibrarySymbol() retrieve the procedure address of the method
666% specified by the passed character string.
667%
668% The format of the NTGetLibrarySymbol method is:
669%
670% void *NTGetLibrarySymbol(void *handle,const char *name)
671%
672% A description of each parameter follows:
673%
674% o handle: Specifies a handle to the previously loaded dynamic module.
675%
676% o name: Specifies the procedure entry point to be returned.
677%
678*/
679void *NTGetLibrarySymbol(void *handle,const char *name)
680{
681 LPFNDLLFUNC1
682 lpfnDllFunc1;
683
684 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
685 if (!lpfnDllFunc1)
686 return((void *) NULL);
687 return((void *) lpfnDllFunc1);
688}
689
690/*
691%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692% %
693% %
694% %
695% N T G e t M o d u l e P a t h %
696% %
697% %
698% %
699%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
700%
701% NTGetModulePath() returns the path of the specified module.
702%
703% The format of the GetModulePath method is:
704%
705% MagickBooleanType NTGetModulePath(const char *module,char *path)
706%
707% A description of each parameter follows:
708%
709% modith: the module name.
710%
711% path: the module path is returned here.
712%
713*/
714MagickExport MagickBooleanType NTGetModulePath(const char *module,char *path)
715{
716 char
717 module_path[MaxTextExtent];
718
719 HMODULE
720 handle;
721
722 long
723 length;
724
725 *path='\0';
726 handle=GetModuleHandle(module);
727 if (handle == (HMODULE) NULL)
728 return(MagickFalse);
729 length=GetModuleFileName(handle,module_path,MaxTextExtent);
730 if (length != 0)
731 GetPathComponent(module_path,HeadPath,path);
732 return(MagickTrue);
733}
734
735/*
736%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
737% %
738% %
739% %
740% N T G h o s t s c r i p t D L L %
741% %
742% %
743% %
744%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
745%
cristydefb3f02009-09-10 02:18:35 +0000746% NTGhostscriptDLL() returns the path to the most recent Ghostscript version
747% DLL. The method returns TRUE on success otherwise FALSE.
cristy3ed852e2009-09-05 21:47:34 +0000748%
749% The format of the NTGhostscriptDLL method is:
750%
cristyfc0f64b2009-09-09 18:57:08 +0000751% int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +0000752%
753% A description of each parameter follows:
754%
cristyfc0f64b2009-09-09 18:57:08 +0000755% o path: return the Ghostscript DLL path here.
cristy3ed852e2009-09-05 21:47:34 +0000756%
cristyfc0f64b2009-09-09 18:57:08 +0000757% o length: the buffer length.
cristy3ed852e2009-09-05 21:47:34 +0000758%
759*/
760
cristyfc0f64b2009-09-09 18:57:08 +0000761static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
762 char *value,int *length)
cristy3ed852e2009-09-05 21:47:34 +0000763{
cristyfc0f64b2009-09-09 18:57:08 +0000764 BYTE
765 byte,
cristy3ed852e2009-09-05 21:47:34 +0000766 *p;
767
cristyfc0f64b2009-09-09 18:57:08 +0000768 DWORD
769 extent,
770 type;
cristy3ed852e2009-09-05 21:47:34 +0000771
cristy3ed852e2009-09-05 21:47:34 +0000772 HKEY
773 hkey;
774
cristy3ed852e2009-09-05 21:47:34 +0000775 LONG
cristyfc0f64b2009-09-09 18:57:08 +0000776 status;
cristy3ed852e2009-09-05 21:47:34 +0000777
cristyfc0f64b2009-09-09 18:57:08 +0000778 /*
cristydefb3f02009-09-10 02:18:35 +0000779 Get a registry value: key = root\\key, named value = name.
780 */
cristyfc0f64b2009-09-09 18:57:08 +0000781 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
782 return(1); /* no match */
783 p=(BYTE *) value;
784 type=REG_SZ;
785 extent=(*length);
786 if (p == (BYTE *) NULL)
cristydefb3f02009-09-10 02:18:35 +0000787 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
cristyfc0f64b2009-09-09 18:57:08 +0000788 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
789 RegCloseKey(hkey);
790 if (status == ERROR_SUCCESS)
cristy3ed852e2009-09-05 21:47:34 +0000791 {
cristyfc0f64b2009-09-09 18:57:08 +0000792 *length=extent;
793 return(0); /* return the match */
794 }
795 if (status == ERROR_MORE_DATA)
796 {
797 *length=extent;
cristydefb3f02009-09-10 02:18:35 +0000798 return(-1); /* buffer not large enough */
cristy3ed852e2009-09-05 21:47:34 +0000799 }
800 return(1); /* not found */
801}
802
cristydefb3f02009-09-10 02:18:35 +0000803static int NTLocateGhostscript(const char **product_family,int *major_version,
cristyfc0f64b2009-09-09 18:57:08 +0000804 int *minor_version)
cristy3ed852e2009-09-05 21:47:34 +0000805{
cristyfc0f64b2009-09-09 18:57:08 +0000806 int
807 i;
cristy3ed852e2009-09-05 21:47:34 +0000808
cristyfc0f64b2009-09-09 18:57:08 +0000809 MagickBooleanType
810 status;
811
812 static const char
813 *products[4] =
814 {
815 "GPL Ghostscript",
816 "GNU Ghostscript",
817 "AFPL Ghostscript",
cristydefb3f02009-09-10 02:18:35 +0000818 "Aladdin Ghostscript"
cristyfc0f64b2009-09-09 18:57:08 +0000819 };
820
821 /*
822 Find the most recent version of Ghostscript.
823 */
824 status=FALSE;
825 *product_family=NULL;
826 *major_version=5;
827 *minor_version=49; /* min version of Ghostscript is 5.50 */
cristy3b743bb2009-09-14 16:07:59 +0000828 for (i=0; i < (long) (sizeof(products)/sizeof(products[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +0000829 {
830 char
831 key[MaxTextExtent];
832
833 HKEY
834 hkey,
835 root;
836
837 (void) FormatMagickString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
838 root=HKEY_LOCAL_MACHINE;
839 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) == ERROR_SUCCESS)
840 {
841 DWORD
842 extent;
843
844 int
845 j;
846
847 /*
848 Now enumerate the keys.
849 */
850 extent=sizeof(key)/sizeof(char);
851 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
852 {
853 int
854 major,
855 minor;
856
857 major=0;
858 minor=0;
859 if (sscanf(key,"%d.%d",&major,&minor) != 2)
860 continue;
861 if ((major > *major_version) || ((major == *major_version) &&
862 (minor > *minor_version)))
863 {
864 *product_family=products[i];
865 *major_version=major;
866 *minor_version=minor;
867 status=MagickTrue;
868 }
869 }
870 }
871 }
872 if (status == MagickFalse)
873 {
874 *major_version=0;
875 *minor_version=0;
876 }
877 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
878 "version %d.%02d",*product_family,*major_version,*minor_version);
879 return(status);
880}
881
882static int NTGhostscriptGetString(const char *name,char *value,
883 const size_t length)
884{
cristy3ed852e2009-09-05 21:47:34 +0000885 char
cristy3ed852e2009-09-05 21:47:34 +0000886 key[MaxTextExtent];
887
888 int
cristyfc0f64b2009-09-09 18:57:08 +0000889 i,
890 extent;
cristydefb3f02009-09-10 02:18:35 +0000891
cristyfc0f64b2009-09-09 18:57:08 +0000892 static const char
cristydefb3f02009-09-10 02:18:35 +0000893 *product_family = (const char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +0000894
cristyfc0f64b2009-09-09 18:57:08 +0000895 static int
896 major_version=0,
897 minor_version=0;
cristy3ed852e2009-09-05 21:47:34 +0000898
cristyfc0f64b2009-09-09 18:57:08 +0000899 struct
900 {
901 const HKEY
902 hkey;
cristy3ed852e2009-09-05 21:47:34 +0000903
cristyfc0f64b2009-09-09 18:57:08 +0000904 const char
905 *name;
906 }
907 hkeys[2] =
908 {
909 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
910 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
911 };
912
913 /*
914 Get a string from the installed Ghostscript.
915 */
cristydefb3f02009-09-10 02:18:35 +0000916 *value='\0';
cristyfc0f64b2009-09-09 18:57:08 +0000917 if (product_family == NULL)
cristydefb3f02009-09-10 02:18:35 +0000918 (void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
cristyfc0f64b2009-09-09 18:57:08 +0000919 if (product_family == NULL)
920 return(FALSE);
921 (void) FormatMagickString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
922 product_family,major_version,minor_version);
cristy3b743bb2009-09-14 16:07:59 +0000923 for (i=0; i < (long) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
cristyfc0f64b2009-09-09 18:57:08 +0000924 {
925 extent=length;
926 if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
927 {
928 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
929 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
930 return(TRUE);
931 }
932 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
933 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
934 }
cristy3ed852e2009-09-05 21:47:34 +0000935 return(FALSE);
936}
937
cristyfc0f64b2009-09-09 18:57:08 +0000938MagickExport int NTGhostscriptDLL(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +0000939{
cristy4c11ed82009-09-11 03:36:46 +0000940 static char
941 dll[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +0000942
943 *path='\0';
cristy4c11ed82009-09-11 03:36:46 +0000944 if ((*dll == '\0') &&
945 (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
cristy106919c2009-09-11 03:46:56 +0000946 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +0000947 (void) CopyMagickString(path,dll,length);
cristy3ed852e2009-09-05 21:47:34 +0000948 return(TRUE);
949}
950
951/*
952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953% %
954% %
955% %
956% N T G h o s t s c r i p t D L L V e c t o r s %
957% %
958% %
959% %
960%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961%
cristydefb3f02009-09-10 02:18:35 +0000962% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes
963% function vectors to invoke Ghostscript DLL functions. A null pointer is
964% returned if there is an error when loading the DLL or retrieving the
965% function vectors.
cristy3ed852e2009-09-05 21:47:34 +0000966%
967% The format of the NTGhostscriptDLLVectors method is:
968%
cristydefb3f02009-09-10 02:18:35 +0000969% const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +0000970%
971*/
cristydefb3f02009-09-10 02:18:35 +0000972MagickExport const GhostInfo *NTGhostscriptDLLVectors(void)
cristy3ed852e2009-09-05 21:47:34 +0000973{
cristyfc0f64b2009-09-09 18:57:08 +0000974 if (NTGhostscriptLoadDLL() == FALSE)
cristydefb3f02009-09-10 02:18:35 +0000975 return((GhostInfo *) NULL);
976 return(&ghost_info);
cristy3ed852e2009-09-05 21:47:34 +0000977}
978
979/*
980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981% %
982% %
983% %
984% N T G h o s t s c r i p t E X E %
985% %
986% %
987% %
988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989%
990% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
cristyfc0f64b2009-09-09 18:57:08 +0000991% The method returns FALSE if a full path value is not obtained and returns
992% a default path of gswin32c.exe.
cristy3ed852e2009-09-05 21:47:34 +0000993%
994% The format of the NTGhostscriptEXE method is:
995%
cristyfc0f64b2009-09-09 18:57:08 +0000996% int NTGhostscriptEXE(char *path,int length)
cristy3ed852e2009-09-05 21:47:34 +0000997%
998% A description of each parameter follows:
999%
cristyfc0f64b2009-09-09 18:57:08 +00001000% o path: return the Ghostscript executable path here.
cristy3ed852e2009-09-05 21:47:34 +00001001%
cristyb32b90a2009-09-07 21:45:48 +00001002% o length: length of buffer.
cristy3ed852e2009-09-05 21:47:34 +00001003%
1004*/
1005MagickExport int NTGhostscriptEXE(char *path,int length)
1006{
cristy4c11ed82009-09-11 03:36:46 +00001007 register char
cristy3ed852e2009-09-05 21:47:34 +00001008 *p;
1009
cristyfc0f64b2009-09-09 18:57:08 +00001010 static char
cristy4c11ed82009-09-11 03:36:46 +00001011 program[MaxTextExtent] = { "" };
cristy3ed852e2009-09-05 21:47:34 +00001012
cristyb32b90a2009-09-07 21:45:48 +00001013 (void) CopyMagickString(path,"gswin32c.exe",length);
cristy4c11ed82009-09-11 03:36:46 +00001014 if ((*program == '\0') &&
1015 (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE))
cristyb32b90a2009-09-07 21:45:48 +00001016 return(FALSE);
cristy4c11ed82009-09-11 03:36:46 +00001017 p=strrchr(program,'\\');
1018 if (p != (char *) NULL)
1019 {
1020 p++;
1021 *p='\0';
1022 (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program));
1023 }
1024 (void) CopyMagickString(path,program,length);
cristyb32b90a2009-09-07 21:45:48 +00001025 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001026}
1027
1028/*
1029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030% %
1031% %
1032% %
1033% N T G h o s t s c r i p t F o n t s %
1034% %
1035% %
1036% %
1037%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038%
cristyfc0f64b2009-09-09 18:57:08 +00001039% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1040% returns FALSE if it cannot determine the font path.
cristy3ed852e2009-09-05 21:47:34 +00001041%
1042% The format of the NTGhostscriptFonts method is:
1043%
cristyfc0f64b2009-09-09 18:57:08 +00001044% int NTGhostscriptFonts(char *path, int length)
cristy3ed852e2009-09-05 21:47:34 +00001045%
1046% A description of each parameter follows:
1047%
cristyfc0f64b2009-09-09 18:57:08 +00001048% o path: return the font path here.
cristy3ed852e2009-09-05 21:47:34 +00001049%
cristyfc0f64b2009-09-09 18:57:08 +00001050% o length: length of the path buffer.
cristy3ed852e2009-09-05 21:47:34 +00001051%
1052*/
1053MagickExport int NTGhostscriptFonts(char *path,int length)
1054{
1055 char
1056 buffer[MaxTextExtent],
1057 filename[MaxTextExtent];
1058
cristy3ed852e2009-09-05 21:47:34 +00001059 register char
1060 *p,
1061 *q;
1062
1063 *path='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001064 if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE)
cristy3ed852e2009-09-05 21:47:34 +00001065 return(FALSE);
1066 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1067 {
1068 (void) CopyMagickString(path,p+1,length+1);
1069 q=strchr(path,DirectoryListSeparator);
1070 if (q != (char *) NULL)
1071 *q='\0';
cristyfc0f64b2009-09-09 18:57:08 +00001072 (void) FormatMagickString(filename,MaxTextExtent,"%s%sfonts.dir",path,
cristy3ed852e2009-09-05 21:47:34 +00001073 DirectorySeparator);
1074 if (IsPathAccessible(filename) != MagickFalse)
1075 return(TRUE);
1076 }
1077 return(FALSE);
1078}
1079
1080/*
1081%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1082% %
1083% %
1084% %
1085% N T G h o s t s c r i p t L o a d D L L %
1086% %
1087% %
1088% %
1089%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1090%
1091% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
cristyfc0f64b2009-09-09 18:57:08 +00001092% TRUE if it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001093%
1094% The format of the NTGhostscriptLoadDLL method is:
1095%
1096% int NTGhostscriptLoadDLL(void)
1097%
1098*/
1099MagickExport int NTGhostscriptLoadDLL(void)
1100{
1101 char
cristyfc0f64b2009-09-09 18:57:08 +00001102 path[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +00001103
cristydefb3f02009-09-10 02:18:35 +00001104 if (ghost_handle != (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001105 return(TRUE);
1106 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1107 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001108 ghost_handle=lt_dlopen(path);
1109 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001110 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001111 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1112 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1113 lt_dlsym(ghost_handle,"gsapi_exit");
1114 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1115 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args"));
1116 ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) (
1117 lt_dlsym(ghost_handle,"gsapi_new_instance"));
1118 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *,
1119 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string"));
1120 ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) (
1121 lt_dlsym(ghost_handle,"gsapi_delete_instance"));
1122 if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) ||
1123 (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) ||
1124 (ghost_info.delete_instance == NULL))
cristyfc0f64b2009-09-09 18:57:08 +00001125 return(FALSE);
1126 return(TRUE);
cristy3ed852e2009-09-05 21:47:34 +00001127}
1128
1129/*
1130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1131% %
1132% %
1133% %
1134% N T G h o s t s c r i p t U n L o a d D L L %
1135% %
1136% %
1137% %
1138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1139%
cristyfc0f64b2009-09-09 18:57:08 +00001140% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1141% it succeeds.
cristy3ed852e2009-09-05 21:47:34 +00001142%
1143% The format of the NTGhostscriptUnLoadDLL method is:
1144%
1145% int NTGhostscriptUnLoadDLL(void)
1146%
1147*/
1148MagickExport int NTGhostscriptUnLoadDLL(void)
1149{
cristyfc0f64b2009-09-09 18:57:08 +00001150 int
1151 status;
1152
cristydefb3f02009-09-10 02:18:35 +00001153 if (ghost_handle == (void *) NULL)
cristyfc0f64b2009-09-09 18:57:08 +00001154 return(FALSE);
cristydefb3f02009-09-10 02:18:35 +00001155 status=lt_dlclose(ghost_handle);
1156 ghost_handle=(void *) NULL;
1157 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
cristyfc0f64b2009-09-09 18:57:08 +00001158 return(status);
cristy3ed852e2009-09-05 21:47:34 +00001159}
1160
1161/*
1162%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1163% %
1164% %
1165% %
1166% N T I n i t i a l i z e L i b r a r y %
1167% %
1168% %
1169% %
1170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1171%
1172% NTInitializeLibrary() initializes the dynamic module loading subsystem.
1173%
1174% The format of the NTInitializeLibrary method is:
1175%
1176% int NTInitializeLibrary(void)
1177%
1178*/
1179MagickExport int NTInitializeLibrary(void)
1180{
1181 return(0);
1182}
1183
1184/*
1185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1186% %
1187% %
1188% %
1189+ N T M a p M e m o r y %
1190% %
1191% %
1192% %
1193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1194%
1195% Mmap() emulates the Unix method of the same name.
1196%
1197% The format of the NTMapMemory method is:
1198%
1199% MagickExport void *NTMapMemory(char *address,size_t length,int protection,
1200% int access,int file,MagickOffsetType offset)
1201%
1202*/
1203MagickExport void *NTMapMemory(char *address,size_t length,int protection,
1204 int flags,int file,MagickOffsetType offset)
1205{
1206 DWORD
1207 access_mode,
1208 high_length,
1209 high_offset,
1210 low_length,
1211 low_offset,
1212 protection_mode;
1213
1214 HANDLE
1215 file_handle,
1216 map_handle;
1217
1218 void
1219 *map;
1220
cristy3b743bb2009-09-14 16:07:59 +00001221 (void) address;
cristy3ed852e2009-09-05 21:47:34 +00001222 access_mode=0;
1223 file_handle=INVALID_HANDLE_VALUE;
1224 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1225 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1226 map_handle=INVALID_HANDLE_VALUE;
1227 map=(void *) NULL;
1228 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1229 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1230 protection_mode=0;
1231 if (protection & PROT_WRITE)
1232 {
1233 access_mode=FILE_MAP_WRITE;
1234 if (!(flags & MAP_PRIVATE))
1235 protection_mode=PAGE_READWRITE;
1236 else
1237 {
1238 access_mode=FILE_MAP_COPY;
1239 protection_mode=PAGE_WRITECOPY;
1240 }
1241 }
1242 else
1243 if (protection & PROT_READ)
1244 {
1245 access_mode=FILE_MAP_READ;
1246 protection_mode=PAGE_READONLY;
1247 }
1248 if ((file == -1) && (flags & MAP_ANONYMOUS))
1249 file_handle=INVALID_HANDLE_VALUE;
1250 else
1251 file_handle=(HANDLE) _get_osfhandle(file);
1252 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1253 low_length,0);
1254 if (map_handle)
1255 {
1256 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1257 length);
1258 CloseHandle(map_handle);
1259 }
1260 if (map == (void *) NULL)
1261 return((void *) MAP_FAILED);
1262 return((void *) ((char *) map));
1263}
1264
1265/*
1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267% %
1268% %
1269% %
1270% N T O p e n D i r e c t o r y %
1271% %
1272% %
1273% %
1274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1275%
1276% NTOpenDirectory() opens the directory named by filename and associates a
1277% directory stream with it.
1278%
1279% The format of the NTOpenDirectory method is:
1280%
1281% DIR *NTOpenDirectory(const char *path)
1282%
1283% A description of each parameter follows:
1284%
1285% o entry: Specifies a pointer to a DIR structure.
1286%
1287*/
1288MagickExport DIR *NTOpenDirectory(const char *path)
1289{
1290 char
1291 file_specification[MaxTextExtent];
1292
1293 DIR
1294 *entry;
1295
1296 size_t
1297 length;
1298
1299 assert(path != (const char *) NULL);
1300 length=CopyMagickString(file_specification,path,MaxTextExtent);
1301 if (length >= MaxTextExtent)
1302 return((DIR *) NULL);
1303 length=ConcatenateMagickString(file_specification,DirectorySeparator,
1304 MaxTextExtent);
1305 if (length >= MaxTextExtent)
1306 return((DIR *) NULL);
1307 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
1308 if (entry != (DIR *) NULL)
1309 {
1310 entry->firsttime=TRUE;
1311 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1312 }
1313 if (entry->hSearch == INVALID_HANDLE_VALUE)
1314 {
1315 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
1316 if (length >= MaxTextExtent)
1317 {
1318 entry=(DIR *) RelinquishMagickMemory(entry);
1319 return((DIR *) NULL);
1320 }
1321 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1322 if (entry->hSearch == INVALID_HANDLE_VALUE)
1323 {
1324 entry=(DIR *) RelinquishMagickMemory(entry);
1325 return((DIR *) NULL);
1326 }
1327 }
1328 return(entry);
1329}
1330
1331/*
1332%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1333% %
1334% %
1335% %
1336% N T O p e n L i b r a r y %
1337% %
1338% %
1339% %
1340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1341%
1342% NTOpenLibrary() loads a dynamic module into memory and returns a handle that
1343% can be used to access the various procedures in the module.
1344%
1345% The format of the NTOpenLibrary method is:
1346%
1347% void *NTOpenLibrary(const char *filename)
1348%
1349% A description of each parameter follows:
1350%
1351% o path: Specifies a pointer to string representing dynamic module that
1352% is to be loaded.
1353%
1354*/
1355
1356static const char *GetSearchPath( void )
1357{
1358#if defined(MAGICKCORE_LTDL_DELEGATE)
1359 return(lt_dlgetsearchpath());
1360#else
1361 return(lt_slsearchpath);
1362#endif
1363}
1364
1365MagickExport void *NTOpenLibrary(const char *filename)
1366{
1367#define MaxPathElements 31
1368
1369 char
1370 buffer[MaxTextExtent];
1371
1372 int
1373 index;
1374
1375 register const char
1376 *p,
1377 *q;
1378
1379 register int
1380 i;
1381
1382 UINT
1383 mode;
1384
1385 void
1386 *handle;
1387
1388 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
1389 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1390 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL))
1391 {
1392 SetErrorMode(mode);
1393 return(handle);
1394 }
1395 p=(char *) GetSearchPath();
1396 index=0;
1397 while (index < MaxPathElements)
1398 {
1399 q=strchr(p,DirectoryListSeparator);
1400 if (q == (char *) NULL)
1401 {
1402 (void) CopyMagickString(buffer,p,MaxTextExtent);
1403 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1404 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1405 handle=(void *) LoadLibraryEx(buffer,NULL,
1406 LOAD_WITH_ALTERED_SEARCH_PATH);
1407 break;
1408 }
1409 i=q-p;
1410 (void) CopyMagickString(buffer,p,i+1);
1411 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent);
1412 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent);
1413 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1414 if (handle != (void *) NULL)
1415 break;
1416 p=q+1;
1417 }
1418 SetErrorMode(mode);
1419 return(handle);
1420}
1421
1422/*
1423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1424% %
1425% %
1426% %
1427% N T R e a d D i r e c t o r y %
1428% %
1429% %
1430% %
1431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1432%
1433% NTReadDirectory() returns a pointer to a structure representing the
1434% directory entry at the current position in the directory stream to which
1435% entry refers.
1436%
1437% The format of the NTReadDirectory
1438%
1439% NTReadDirectory(entry)
1440%
1441% A description of each parameter follows:
1442%
1443% o entry: Specifies a pointer to a DIR structure.
1444%
1445*/
1446MagickExport struct dirent *NTReadDirectory(DIR *entry)
1447{
1448 int
1449 status;
1450
1451 size_t
1452 length;
1453
1454 if (entry == (DIR *) NULL)
1455 return((struct dirent *) NULL);
1456 if (!entry->firsttime)
1457 {
1458 status=FindNextFile(entry->hSearch,&entry->Win32FindData);
1459 if (status == 0)
1460 return((struct dirent *) NULL);
1461 }
1462 length=CopyMagickString(entry->file_info.d_name,
1463 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name));
1464 if (length >= sizeof(entry->file_info.d_name))
1465 return((struct dirent *) NULL);
1466 entry->firsttime=FALSE;
1467 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1468 return(&entry->file_info);
1469}
1470
1471/*
1472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1473% %
1474% %
1475% %
1476% N T R e g i s t r y K e y L o o k u p %
1477% %
1478% %
1479% %
1480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1481%
1482% NTRegistryKeyLookup() returns ImageMagick installation path settings
1483% stored in the Windows Registry. Path settings are specific to the
1484% installed ImageMagick version so that multiple Image Magick installations
1485% may coexist.
1486%
1487% Values are stored in the registry under a base path path similar to
1488% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\5.5.7\Q:16". The provided subkey
1489% is appended to this base path to form the full key.
1490%
1491% The format of the NTRegistryKeyLookup method is:
1492%
1493% unsigned char *NTRegistryKeyLookup(const char *subkey)
1494%
1495% A description of each parameter follows:
1496%
1497% o subkey: Specifies a string that identifies the registry object.
1498% Currently supported sub-keys include: "BinPath", "ConfigurePath",
1499% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1500%
1501*/
1502MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
1503{
1504 char
1505 package_key[MaxTextExtent];
1506
1507 DWORD
1508 size,
1509 type;
1510
1511 HKEY
1512 registry_key;
1513
1514 LONG
1515 status;
1516
1517 unsigned char
1518 *value;
1519
1520 /*
1521 Look-up base key.
1522 */
1523 (void) FormatMagickString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
1524 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH);
1525 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key);
1526 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1527 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,&registry_key);
1528 if (status != ERROR_SUCCESS)
1529 {
1530 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1531 return((unsigned char *) NULL);
1532 }
1533 /*
1534 Look-up sub key.
1535 */
1536 size=32;
1537 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
1538 if (value == (unsigned char *) NULL)
1539 {
1540 RegCloseKey(registry_key);
1541 return((unsigned char *) NULL);
1542 }
1543 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey);
1544 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1545 if ((status == ERROR_MORE_DATA) && (type == REG_SZ))
1546 {
1547 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
1548 if (value == (BYTE *) NULL)
1549 {
1550 RegCloseKey(registry_key);
1551 return((unsigned char *) NULL);
1552 }
1553 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1554 }
1555 RegCloseKey(registry_key);
1556 if ((type != REG_SZ) || (status != ERROR_SUCCESS))
1557 value=(unsigned char *) RelinquishMagickMemory(value);
1558 return((unsigned char *) value);
1559}
1560
1561/*
1562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563% %
1564% %
1565% %
1566% N T R e p o r t E v e n t %
1567% %
1568% %
1569% %
1570%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1571%
1572% NTReportEvent() reports an event.
1573%
1574% The format of the NTReportEvent method is:
1575%
1576% MagickBooleanType NTReportEvent(const char *event,
1577% const MagickBooleanType error)
1578%
1579% A description of each parameter follows:
1580%
1581% o event: the event.
1582%
1583% o error: MagickTrue the event is an error.
1584%
1585*/
1586MagickExport MagickBooleanType NTReportEvent(const char *event,
1587 const MagickBooleanType error)
1588{
1589 const char
1590 *events[1];
1591
1592 HANDLE
1593 handle;
1594
1595 WORD
1596 type;
1597
1598 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1599 if (handle == NULL)
1600 return(MagickFalse);
1601 events[0]=event;
1602 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1603 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1604 DeregisterEventSource(handle);
1605 return(MagickTrue);
1606}
1607
1608/*
1609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1610% %
1611% %
1612% %
1613% N T R e s o u r c e T o B l o b %
1614% %
1615% %
1616% %
1617%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1618%
1619% NTResourceToBlob() returns a blob containing the contents of the resource
1620% in the current executable specified by the id parameter. This currently
1621% used to retrieve MGK files tha have been embedded into the various command
1622% line utilities.
1623%
1624% The format of the NTResourceToBlob method is:
1625%
1626% unsigned char *NTResourceToBlob(const char *id)
1627%
1628% A description of each parameter follows:
1629%
1630% o id: Specifies a string that identifies the resource.
1631%
1632*/
1633MagickExport unsigned char *NTResourceToBlob(const char *id)
1634{
1635 char
1636 path[MaxTextExtent];
1637
1638 DWORD
1639 length;
1640
1641 HGLOBAL
1642 global;
1643
1644 HMODULE
1645 handle;
1646
1647 HRSRC
1648 resource;
1649
1650 unsigned char
1651 *blob,
1652 *value;
1653
1654 assert(id != (const char *) NULL);
1655 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1656 (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
1657 DirectorySeparator,GetClientName());
1658 if (IsPathAccessible(path) != MagickFalse)
1659 handle=GetModuleHandle(path);
1660 else
1661 handle=GetModuleHandle(0);
1662 if (!handle)
1663 return((unsigned char *) NULL);
1664 resource=FindResource(handle,id,"IMAGEMAGICK");
1665 if (!resource)
1666 return((unsigned char *) NULL);
1667 global=LoadResource(handle,resource);
1668 if (!global)
1669 return((unsigned char *) NULL);
1670 length=SizeofResource(handle,resource);
1671 value=(unsigned char *) LockResource(global);
1672 if (!value)
1673 {
1674 FreeResource(global);
1675 return((unsigned char *) NULL);
1676 }
1677 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
1678 sizeof(*blob));
1679 if (blob != (unsigned char *) NULL)
1680 {
1681 (void) CopyMagickMemory(blob,value,length);
1682 blob[length]='\0';
1683 }
1684 UnlockResource(global);
1685 FreeResource(global);
1686 return(blob);
1687}
1688
1689/*
1690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1691% %
1692% %
1693% %
1694% N T S e e k D i r e c t o r y %
1695% %
1696% %
1697% %
1698%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1699%
1700% NTSeekDirectory() sets the position of the next NTReadDirectory() operation
1701% on the directory stream.
1702%
1703% The format of the NTSeekDirectory method is:
1704%
1705% void NTSeekDirectory(DIR *entry,long position)
1706%
1707% A description of each parameter follows:
1708%
1709% o entry: Specifies a pointer to a DIR structure.
1710%
1711% o position: specifies the position associated with the directory
1712% stream.
1713%
1714*/
1715MagickExport void NTSeekDirectory(DIR *entry,long position)
1716{
cristy3b743bb2009-09-14 16:07:59 +00001717 (void) position;
cristy3ed852e2009-09-05 21:47:34 +00001718 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1719 assert(entry != (DIR *) NULL);
1720}
1721
1722/*
1723%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1724% %
1725% %
1726% %
1727% N T S e t S e a r c h P a t h %
1728% %
1729% %
1730% %
1731%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1732%
1733% NTSetSearchPath() sets the current locations that the subsystem should
1734% look at to find dynamically loadable modules.
1735%
1736% The format of the NTSetSearchPath method is:
1737%
1738% int NTSetSearchPath(const char *path)
1739%
1740% A description of each parameter follows:
1741%
1742% o path: Specifies a pointer to string representing the search path
1743% for DLL's that can be dynamically loaded.
1744%
1745*/
1746MagickExport int NTSetSearchPath(const char *path)
1747{
1748#if defined(MAGICKCORE_LTDL_DELEGATE)
1749 lt_dlsetsearchpath(path);
1750#else
1751 if (lt_slsearchpath != (char *) NULL)
1752 lt_slsearchpath=DestroyString(lt_slsearchpath);
1753 if (path != (char *) NULL)
1754 lt_slsearchpath=AcquireString(path);
1755#endif
1756 return(0);
1757}
1758
1759/*
1760%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1761% %
1762% %
1763% %
1764+ N T S y n c M e m o r y %
1765% %
1766% %
1767% %
1768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1769%
1770% NTSyncMemory() emulates the Unix method of the same name.
1771%
1772% The format of the NTSyncMemory method is:
1773%
1774% int NTSyncMemory(void *address,size_t length,int flags)
1775%
1776% A description of each parameter follows:
1777%
1778% o address: the address of the binary large object.
1779%
1780% o length: the length of the binary large object.
1781%
1782% o flags: Option flags (ignored for Windows).
1783%
1784*/
1785MagickExport int NTSyncMemory(void *address,size_t length,int flags)
1786{
cristy3b743bb2009-09-14 16:07:59 +00001787 (void) flags;
cristy3ed852e2009-09-05 21:47:34 +00001788 if (FlushViewOfFile(address,length) == MagickFalse)
1789 return(-1);
1790 return(0);
1791}
1792
1793/*
1794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1795% %
1796% %
1797% %
1798% N T S y s t e m C o m m a n d %
1799% %
1800% %
1801% %
1802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1803%
1804% NTSystemCommand() executes the specified command and waits until it
1805% terminates. The returned value is the exit status of the command.
1806%
cristyb32b90a2009-09-07 21:45:48 +00001807% The format of the NTSystemCommand method is:
cristy3ed852e2009-09-05 21:47:34 +00001808%
cristyb32b90a2009-09-07 21:45:48 +00001809% int NTSystemCommand(const char *command)
cristy3ed852e2009-09-05 21:47:34 +00001810%
1811% A description of each parameter follows:
1812%
1813% o command: This string is the command to execute.
1814%
1815*/
1816MagickExport int NTSystemCommand(const char *command)
1817{
1818 char
1819 local_command[MaxTextExtent];
1820
1821 DWORD
1822 child_status;
1823
1824 int
1825 status;
1826
1827 MagickBooleanType
1828 background_process;
1829
1830 PROCESS_INFORMATION
1831 process_info;
1832
1833 STARTUPINFO
1834 startup_info;
1835
1836 if (command == (char *) NULL)
1837 return(-1);
1838 GetStartupInfo(&startup_info);
1839 startup_info.dwFlags=STARTF_USESHOWWINDOW;
1840 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
1841 (void) CopyMagickString(local_command,command,MaxTextExtent);
1842 background_process=command[strlen(command)-1] == '&' ? MagickTrue :
1843 MagickFalse;
1844 if (background_process)
1845 local_command[strlen(command)-1]='\0';
1846 if (command[strlen(command)-1] == '|')
1847 local_command[strlen(command)-1]='\0';
1848 else
1849 startup_info.wShowWindow=SW_SHOWDEFAULT;
1850 status=CreateProcess((LPCTSTR) NULL,local_command,
1851 (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,
1852 (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
1853 &process_info);
1854 if (status == 0)
1855 return(-1);
1856 if (background_process)
1857 return(status == 0);
1858 status=WaitForSingleObject(process_info.hProcess,INFINITE);
1859 if (status != WAIT_OBJECT_0)
1860 return(status);
1861 status=GetExitCodeProcess(process_info.hProcess,&child_status);
1862 if (status == 0)
1863 return(-1);
1864 CloseHandle(process_info.hProcess);
1865 CloseHandle(process_info.hThread);
1866 return((int) child_status);
1867}
1868
1869/*
1870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1871% %
1872% %
1873% %
1874% N T S y s t e m C o n i f i g u r a t i o n %
1875% %
1876% %
1877% %
1878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1879%
1880% NTSystemConfiguration() provides a way for the application to determine
1881% values for system limits or options at runtime.
1882%
1883% The format of the exit method is:
1884%
1885% long NTSystemConfiguration(int name)
1886%
1887% A description of each parameter follows:
1888%
1889% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
1890%
1891*/
1892MagickExport long NTSystemConfiguration(int name)
1893{
1894 switch (name)
1895 {
1896 case _SC_PAGESIZE:
1897 {
1898 SYSTEM_INFO
1899 system_info;
1900
1901 GetSystemInfo(&system_info);
1902 return(system_info.dwPageSize);
1903 }
1904 case _SC_PHYS_PAGES:
1905 {
1906 HMODULE
1907 handle;
1908
1909 LPFNDLLFUNC2
1910 module;
1911
1912 NTMEMORYSTATUSEX
1913 status;
1914
1915 SYSTEM_INFO
1916 system_info;
1917
1918 handle=GetModuleHandle("kernel32.dll");
1919 if (handle == (HMODULE) NULL)
1920 return(0L);
1921 GetSystemInfo(&system_info);
1922 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
1923 if (module == (LPFNDLLFUNC2) NULL)
1924 {
1925 MEMORYSTATUS
1926 status;
1927
1928 GlobalMemoryStatus(&status);
1929 return((long) status.dwTotalPhys/system_info.dwPageSize);
1930 }
1931 status.dwLength=sizeof(status);
1932 if (module(&status) == 0)
1933 return(0L);
1934 return((long) status.ullTotalPhys/system_info.dwPageSize);
1935 }
1936 case _SC_OPEN_MAX:
1937 return(2048);
1938 default:
1939 break;
1940 }
1941 return(-1);
1942}
1943
1944/*
1945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1946% %
1947% %
1948% %
1949% N T T e l l D i r e c t o r y %
1950% %
1951% %
1952% %
1953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1954%
1955% NTTellDirectory() returns the current location associated with the named
1956% directory stream.
1957%
1958% The format of the NTTellDirectory method is:
1959%
1960% long NTTellDirectory(DIR *entry)
1961%
1962% A description of each parameter follows:
1963%
1964% o entry: Specifies a pointer to a DIR structure.
1965%
1966*/
1967MagickExport long NTTellDirectory(DIR *entry)
1968{
1969 assert(entry != (DIR *) NULL);
1970 return(0);
1971}
1972
1973/*
1974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1975% %
1976% %
1977% %
1978% N T T r u n c a t e F i l e %
1979% %
1980% %
1981% %
1982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1983%
1984% NTTruncateFile() truncates a file to a specified length.
1985%
1986% The format of the NTTruncateFile method is:
1987%
1988% int NTTruncateFile(int file,off_t length)
1989%
1990% A description of each parameter follows:
1991%
1992% o file: the file.
1993%
1994% o length: the file length.
1995%
1996*/
1997MagickExport int NTTruncateFile(int file,off_t length)
1998{
1999 DWORD
2000 file_pointer;
2001
2002 long
2003 file_handle,
2004 high,
2005 low;
2006
2007 file_handle=_get_osfhandle(file);
2008 if (file_handle == -1L)
2009 return(-1);
2010 low=(long) (length & 0xffffffffUL);
2011 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
2012 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2013 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2014 return(-1);
2015 if (SetEndOfFile((HANDLE) file_handle) == 0)
2016 return(-1);
2017 return(0);
2018}
2019
2020/*
2021%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2022% %
2023% %
2024% %
2025+ N T U n m a p M e m o r y %
2026% %
2027% %
2028% %
2029%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2030%
2031% NTUnmapMemory() emulates the Unix munmap method.
2032%
2033% The format of the NTUnmapMemory method is:
2034%
2035% int NTUnmapMemory(void *map,size_t length)
2036%
2037% A description of each parameter follows:
2038%
2039% o map: the address of the binary large object.
2040%
2041% o length: the length of the binary large object.
2042%
2043*/
2044MagickExport int NTUnmapMemory(void *map,size_t length)
2045{
cristy3b743bb2009-09-14 16:07:59 +00002046 (void) length;
cristy3ed852e2009-09-05 21:47:34 +00002047 if (UnmapViewOfFile(map) == 0)
2048 return(-1);
2049 return(0);
2050}
2051
2052/*
2053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2054% %
2055% %
2056% %
2057% N T U s e r T i m e %
2058% %
2059% %
2060% %
2061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2062%
2063% NTUserTime() returns the total time the process has been scheduled (e.g.
2064% seconds) since the last call to StartTimer().
2065%
2066% The format of the UserTime method is:
2067%
2068% double NTUserTime(void)
2069%
2070*/
2071MagickExport double NTUserTime(void)
2072{
2073 DWORD
2074 status;
2075
2076 FILETIME
2077 create_time,
2078 exit_time;
2079
2080 OSVERSIONINFO
2081 OsVersionInfo;
2082
2083 union
2084 {
2085 FILETIME
2086 filetime;
2087
2088 __int64
2089 filetime64;
2090 } kernel_time;
2091
2092 union
2093 {
2094 FILETIME
2095 filetime;
2096
2097 __int64
2098 filetime64;
2099 } user_time;
2100
2101 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
2102 GetVersionEx(&OsVersionInfo);
2103 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2104 return(NTElapsedTime());
2105 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2106 &kernel_time.filetime,&user_time.filetime);
2107 if (status != TRUE)
2108 return(0.0);
2109 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2110}
2111
2112/*
2113%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2114% %
2115% %
2116% %
2117% N T W a r n i n g H a n d l e r %
2118% %
2119% %
2120% %
2121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2122%
2123% NTWarningHandler() displays a warning reason.
2124%
2125% The format of the NTWarningHandler method is:
2126%
cristy3b743bb2009-09-14 16:07:59 +00002127% void NTWarningHandler(const ExceptionType severity,const char *reason,
cristy3ed852e2009-09-05 21:47:34 +00002128% const char *description)
2129%
2130% A description of each parameter follows:
2131%
cristy3b743bb2009-09-14 16:07:59 +00002132% o severity: Specifies the numeric warning category.
cristy3ed852e2009-09-05 21:47:34 +00002133%
2134% o reason: Specifies the reason to display before terminating the
2135% program.
2136%
2137% o description: Specifies any description to the reason.
2138%
2139*/
cristy3b743bb2009-09-14 16:07:59 +00002140MagickExport void NTWarningHandler(const ExceptionType severity,
cristy3ed852e2009-09-05 21:47:34 +00002141 const char *reason,const char *description)
2142{
2143 char
2144 buffer[2*MaxTextExtent];
2145
cristy3b743bb2009-09-14 16:07:59 +00002146 (void) severity;
cristy3ed852e2009-09-05 21:47:34 +00002147 if (reason == (char *) NULL)
2148 return;
2149 if (description == (char *) NULL)
2150 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
2151 reason);
2152 else
2153 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
2154 GetClientName(),reason,description);
2155 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2156 MB_SETFOREGROUND | MB_ICONINFORMATION);
2157}
2158#endif