2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Windows NT Utility Methods for MagickCore %
20 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 #include "MagickCore/studio.h"
42 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
43 #include "MagickCore/client.h"
44 #include "MagickCore/exception-private.h"
45 #include "MagickCore/locale_.h"
46 #include "MagickCore/log.h"
47 #include "MagickCore/magick.h"
48 #include "MagickCore/memory_.h"
49 #include "MagickCore/resource_.h"
50 #include "MagickCore/resource-private.h"
51 #include "MagickCore/timer.h"
52 #include "MagickCore/string_.h"
53 #include "MagickCore/utility.h"
54 #include "MagickCore/version.h"
55 #if defined(MAGICKCORE_LTDL_DELEGATE)
58 #include "MagickCore/nt-base.h"
59 #if defined(MAGICKCORE_CIPHER_SUPPORT)
67 #if !defined(MAP_FAILED)
68 #define MAP_FAILED ((void *) -1)
74 #if !defined(MAGICKCORE_LTDL_DELEGATE)
76 *lt_slsearchpath = (char *) NULL;
83 *ghost_handle = (void *) NULL;
86 External declarations.
88 #if !defined(MAGICKCORE_WINDOWS_SUPPORT)
89 extern "C" BOOL WINAPI
90 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
94 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
108 % The function returns TRUE of it succeeds, or FALSE if initialization fails.
110 % The format of the DllMain method is:
112 % BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
114 % A description of each parameter follows:
116 % o handle: handle to the DLL module
118 % o reason: reason for calling function:
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
128 % DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded
129 % from the virtual address space of the
132 % o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH
133 % and DLL_PROCESS_DETACH.
136 #if defined(_DLL) && defined( ProvideDllMain )
137 BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
141 case DLL_PROCESS_ATTACH:
149 module_path=(char *) AcquireQuantumMemory(MaxTextExtent,
150 sizeof(*module_path));
151 if (module_path == (char *) NULL)
153 count=(ssize_t) GetModuleFileName(handle,module_path,MaxTextExtent);
159 for ( ; count > 0; count--)
160 if (module_path[count] == '\\')
162 module_path[count+1]='\0';
165 MagickCoreGenesis(module_path,MagickFalse);
166 path=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,sizeof(*path));
167 if (path == (char *) NULL)
169 module_path=DestroyString(module_path);
172 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MaxTextExtent);
173 if ((count != 0) && (strstr(path,module_path) == (char *) NULL))
175 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
180 variable=(char *) AcquireQuantumMemory(16UL*MaxTextExtent,
182 if (variable == (char *) NULL)
184 path=DestroyString(path);
185 module_path=DestroyString(module_path);
188 (void) FormatLocaleString(variable,16*MaxTextExtent,
189 "%s;%s",module_path,path);
190 SetEnvironmentVariable("PATH",variable);
191 variable=DestroyString(variable);
194 path=DestroyString(path);
196 module_path=DestroyString(module_path);
199 case DLL_PROCESS_DETACH:
201 MagickCoreTerminus();
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % Exit() calls TerminateProcess for Win95.
224 % The format of the exit method is:
226 % int Exit(int status)
228 % A description of each parameter follows:
230 % o status: an integer value representing the status of the terminating
234 MagickExport int Exit(int status)
237 TerminateProcess(GetCurrentProcess(),(unsigned int) status);
242 #if !defined(__MINGW32__)
244 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248 % g e t t i m e o f d a y %
252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254 % The gettimeofday() method get the time of day.
256 % The format of the gettimeofday method is:
258 % int gettimeofday(struct timeval *time_value,struct timezone *time_zone)
260 % A description of each parameter follows:
262 % o time_value: the time value.
264 % o time_zone: the time zone.
267 MagickExport int gettimeofday (struct timeval *time_value,
268 struct timezone *time_zone)
270 #define EpochFiletime MagickLLConstant(116444736000000000)
275 if (time_value != (struct timeval *) NULL)
286 GetSystemTimeAsFileTime(&file_time);
287 date_time.LowPart=file_time.dwLowDateTime;
288 date_time.HighPart=file_time.dwHighDateTime;
289 time=date_time.QuadPart;
292 time_value->tv_sec=(ssize_t) (time / 1000000);
293 time_value->tv_usec=(ssize_t) (time % 1000000);
295 if (time_zone != (struct timezone *) NULL)
302 time_zone->tz_minuteswest=_timezone/60;
303 time_zone->tz_dsttime=_daylight;
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 % I s W i n d o w s 9 5 %
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 % IsWindows95() returns true if the system is Windows 95.
322 % The format of the IsWindows95 method is:
327 MagickExport int IsWindows95(void)
332 version_info.dwOSVersionInfoSize=sizeof(version_info);
333 if (GetVersionEx(&version_info) &&
334 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 % N T A r g v T o U T F 8 %
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 % NTArgvToUTF8() converts the wide command line arguments to UTF-8 to ensure
351 % compatibility with Linux.
353 % The format of the NTArgvToUTF8 method is:
355 % char **NTArgvToUTF8(const int argc,wchar_t **argv)
357 % A description of each parameter follows:
359 % o argc: the number of command line arguments.
361 % o argv: the wide-character command line arguments.
364 MagickExport char **NTArgvToUTF8(const int argc,wchar_t **argv)
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++)
380 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,NULL,0,NULL,NULL);
383 utf8[i]=(char *) AcquireQuantumMemory(count+1,sizeof(**utf8));
384 if (utf8[i] == (char *) NULL)
386 for (i--; i >= 0; i--)
387 utf8[i]=DestroyString(utf8[i]);
388 utf8=(char **) RelinquishMagickMemory(utf8);
389 ThrowFatalException(ResourceLimitFatalError,
390 "UnableToConvertStringToARGV");
392 count=WideCharToMultiByte(CP_UTF8,0,argv[i],-1,utf8[i],count,NULL,NULL);
399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
403 % N T C l o s e D i r e c t o r y %
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 % NTCloseDirectory() closes the named directory stream and frees the DIR
412 % The format of the NTCloseDirectory method is:
414 % int NTCloseDirectory(DIR *entry)
416 % A description of each parameter follows:
418 % o entry: Specifies a pointer to a DIR structure.
421 MagickExport int NTCloseDirectory(DIR *entry)
423 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
424 assert(entry != (DIR *) NULL);
425 FindClose(entry->hSearch);
426 entry=(DIR *) RelinquishMagickMemory(entry);
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 % N T C l o s e L i b r a r y %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441 % NTCloseLibrary() unloads the module associated with the passed handle.
443 % The format of the NTCloseLibrary method is:
445 % void NTCloseLibrary(void *handle)
447 % A description of each parameter follows:
449 % o handle: Specifies a handle to a previously loaded dynamic module.
452 MagickExport int NTCloseLibrary(void *handle)
455 return(FreeLibrary((HINSTANCE) handle));
456 return(!(FreeLibrary((HINSTANCE) handle)));
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 % N T C o n t r o l H a n d l e r %
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 % NTControlHandler() registers a control handler that is activated when, for
471 % example, a ctrl-c is received.
473 % The format of the NTControlHandler method is:
475 % int NTControlHandler(void)
479 static BOOL ControlHandler(DWORD type)
482 AsynchronousResourceComponentTerminus();
486 MagickExport int NTControlHandler(void)
488 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496 % N T E l a p s e d T i m e %
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502 % NTElapsedTime() returns the elapsed time (in seconds) since the last call to
505 % The format of the ElapsedTime method is:
507 % double NTElapsedTime(void)
510 MagickExport double NTElapsedTime(void)
524 GetSystemTime(&system_time);
525 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
526 return((double) 1.0e-7*elapsed_time.filetime64);
530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
534 + N T E r r o r H a n d l e r %
538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540 % NTErrorHandler() displays an error reason and then terminates the program.
542 % The format of the NTErrorHandler method is:
544 % void NTErrorHandler(const ExceptionType severity,const char *reason,
545 % const char *description)
547 % A description of each parameter follows:
549 % o severity: Specifies the numeric error category.
551 % o reason: Specifies the reason to display before terminating the
554 % o description: Specifies any description to the reason.
557 MagickExport void NTErrorHandler(const ExceptionType severity,
558 const char *reason,const char *description)
561 buffer[3*MaxTextExtent],
565 if (reason == (char *) NULL)
567 MagickCoreTerminus();
570 message=GetExceptionMessage(errno);
571 if ((description != (char *) NULL) && errno)
572 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s) [%s].\n",
573 GetClientName(),reason,description,message);
575 if (description != (char *) NULL)
576 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
577 GetClientName(),reason,description);
580 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s [%s].\n",
581 GetClientName(),reason,message);
583 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",
584 GetClientName(),reason);
585 message=DestroyString(message);
586 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL |
587 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
588 MagickCoreTerminus();
593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 % N T E x i t L i b r a r y %
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 % NTExitLibrary() exits the dynamic module loading subsystem.
605 % The format of the NTExitLibrary method is:
607 % int NTExitLibrary(void)
610 MagickExport int NTExitLibrary(void)
616 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620 % N T G a t h e r R a n d o m D a t a %
624 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
626 % NTGatherRandomData() gathers random data and returns it.
628 % The format of the GatherRandomData method is:
630 % MagickBooleanType NTGatherRandomData(const size_t length,
631 % unsigned char *random)
633 % A description of each parameter follows:
635 % length: the length of random data buffer
637 % random: the random data is returned here.
640 MagickExport MagickBooleanType NTGatherRandomData(const size_t length,
641 unsigned char *random)
643 #if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
650 handle=(HCRYPTPROV) NULL;
651 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
652 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
654 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
655 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
658 status=CryptGenRandom(handle,(DWORD) length,random);
661 status=CryptReleaseContext(handle,0);
664 status=CryptReleaseContext(handle,0);
675 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 % N T G e t E x e c u t i o n P a t h %
683 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685 % NTGetExecutionPath() returns the execution path of a program.
687 % The format of the GetExecutionPath method is:
689 % MagickBooleanType NTGetExecutionPath(char *path,const size_t extent)
691 % A description of each parameter follows:
693 % o path: the pathname of the executable that started the process.
695 % o extent: the maximum extent of the path.
698 MagickExport MagickBooleanType NTGetExecutionPath(char *path,
701 GetModuleFileName(0,path,(DWORD) extent);
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % N T G e t L a s t E r r o r %
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 % NTGetLastError() returns the last error that occurred.
718 % The format of the NTGetLastError method is:
720 % char *NTGetLastError(void)
723 char *NTGetLastError(void)
734 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
735 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
736 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
738 reason=AcquireString("An unknown error occurred");
741 reason=AcquireString((const char *) buffer);
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752 % N T G e t L i b r a r y E r r o r %
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
762 % The format of the NTGetLibraryError method is:
764 % const char *NTGetLibraryError(void)
767 MagickExport const char *NTGetLibraryError(void)
770 last_error[MaxTextExtent];
776 error=NTGetLastError();
778 (void) CopyMagickString(last_error,error,MaxTextExtent);
779 error=DestroyString(error);
784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
788 % N T G e t L i b r a r y S y m b o l %
792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794 % NTGetLibrarySymbol() retrieve the procedure address of the method
795 % specified by the passed character string.
797 % The format of the NTGetLibrarySymbol method is:
799 % void *NTGetLibrarySymbol(void *handle,const char *name)
801 % A description of each parameter follows:
803 % o handle: Specifies a handle to the previously loaded dynamic module.
805 % o name: Specifies the procedure entry point to be returned.
808 void *NTGetLibrarySymbol(void *handle,const char *name)
813 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name);
815 return((void *) NULL);
816 return((void *) lpfnDllFunc1);
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 % N T G e t M o d u l e P a t h %
828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 % NTGetModulePath() returns the path of the specified module.
832 % The format of the GetModulePath method is:
834 % MagickBooleanType NTGetModulePath(const char *module,char *path)
836 % A description of each parameter follows:
838 % modith: the module name.
840 % path: the module path is returned here.
843 MagickExport MagickBooleanType NTGetModulePath(const char *module,char *path)
846 module_path[MaxTextExtent];
855 handle=GetModuleHandle(module);
856 if (handle == (HMODULE) NULL)
858 length=GetModuleFileName(handle,module_path,MaxTextExtent);
860 GetPathComponent(module_path,HeadPath,path);
865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869 % N T G h o s t s c r i p t D L L %
873 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875 % NTGhostscriptDLL() returns the path to the most recent Ghostscript version
876 % DLL. The method returns TRUE on success otherwise FALSE.
878 % The format of the NTGhostscriptDLL method is:
880 % int NTGhostscriptDLL(char *path,int length)
882 % A description of each parameter follows:
884 % o path: return the Ghostscript DLL path here.
886 % o length: the buffer length.
890 static int NTGetRegistryValue(HKEY root,const char *key,const char *name,
891 char *value,int *length)
908 Get a registry value: key = root\\key, named value = name.
910 if (RegOpenKeyExA(root,key,0,KEY_READ,&hkey) != ERROR_SUCCESS)
911 return(1); /* no match */
915 if (p == (BYTE *) NULL)
916 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */
917 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent);
919 if (status == ERROR_SUCCESS)
922 return(0); /* return the match */
924 if (status == ERROR_MORE_DATA)
927 return(-1); /* buffer not large enough */
929 return(1); /* not found */
932 static int NTLocateGhostscript(const char **product_family,int *major_version,
947 "Aladdin Ghostscript"
951 Find the most recent version of Ghostscript.
954 *product_family=NULL;
956 *minor_version=49; /* min version of Ghostscript is 5.50 */
957 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++)
969 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s",products[i]);
970 root=HKEY_LOCAL_MACHINE;
972 #if defined(KEY_WOW64_32KEY)
973 mode|=KEY_WOW64_32KEY;
975 if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS)
984 Now enumerate the keys.
986 extent=sizeof(key)/sizeof(char);
987 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++)
995 if (sscanf(key,"%d.%d",&major,&minor) != 2)
997 if ((major > *major_version) || ((major == *major_version) &&
998 (minor > *minor_version)))
1000 *product_family=products[i];
1001 *major_version=major;
1002 *minor_version=minor;
1006 (void) RegCloseKey(hkey);
1009 if (status == FALSE)
1014 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) "
1015 "version %d.%02d",*product_family,*major_version,*minor_version);
1019 static int NTGhostscriptGetString(const char *name,char *value,
1020 const size_t length)
1030 *product_family = (const char *) NULL;
1046 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" },
1047 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" }
1051 Get a string from the installed Ghostscript.
1054 if (product_family == NULL)
1055 (void) NTLocateGhostscript(&product_family,&major_version,&minor_version);
1056 if (product_family == NULL)
1058 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d",
1059 product_family,major_version,minor_version);
1060 for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++)
1062 extent=(int) length;
1063 if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0)
1065 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1066 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value);
1069 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1070 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name);
1075 MagickExport int NTGhostscriptDLL(char *path,int length)
1078 dll[MaxTextExtent] = { "" };
1081 if ((*dll == '\0') &&
1082 (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE))
1084 (void) CopyMagickString(path,dll,length);
1089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1093 % N T G h o s t s c r i p t D L L V e c t o r s %
1097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099 % 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
1104 % The format of the NTGhostscriptDLLVectors method is:
1106 % const GhostInfo *NTGhostscriptDLLVectors(void)
1109 MagickExport const GhostInfo *NTGhostscriptDLLVectors(void)
1111 if (NTGhostscriptLoadDLL() == FALSE)
1112 return((GhostInfo *) NULL);
1113 return(&ghost_info);
1117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 % N T G h o s t s c r i p t E X E %
1125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1127 % NTGhostscriptEXE() obtains the path to the latest Ghostscript executable.
1128 % The method returns FALSE if a full path value is not obtained and returns
1129 % a default path of gswin32c.exe.
1131 % The format of the NTGhostscriptEXE method is:
1133 % int NTGhostscriptEXE(char *path,int length)
1135 % A description of each parameter follows:
1137 % o path: return the Ghostscript executable path here.
1139 % o length: length of buffer.
1142 MagickExport int NTGhostscriptEXE(char *path,int length)
1148 program[MaxTextExtent] = { "" };
1150 (void) CopyMagickString(path,"gswin32c.exe",length);
1151 if ((*program == '\0') &&
1152 (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE))
1154 p=strrchr(program,'\\');
1155 if (p != (char *) NULL)
1159 (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program));
1161 (void) CopyMagickString(path,program,length);
1166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1170 % N T G h o s t s c r i p t F o n t s %
1174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1176 % NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method
1177 % returns FALSE if it cannot determine the font path.
1179 % The format of the NTGhostscriptFonts method is:
1181 % int NTGhostscriptFonts(char *path, int length)
1183 % A description of each parameter follows:
1185 % o path: return the font path here.
1187 % o length: length of the path buffer.
1190 MagickExport int NTGhostscriptFonts(char *path,int length)
1193 buffer[MaxTextExtent],
1194 filename[MaxTextExtent];
1201 if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE)
1203 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1205 (void) CopyMagickString(path,p+1,length+1);
1206 q=strchr(path,DirectoryListSeparator);
1207 if (q != (char *) NULL)
1209 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path,
1210 DirectorySeparator);
1211 if (IsPathAccessible(filename) != MagickFalse)
1218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1222 % N T G h o s t s c r i p t L o a d D L L %
1226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228 % NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns
1229 % TRUE if it succeeds.
1231 % The format of the NTGhostscriptLoadDLL method is:
1233 % int NTGhostscriptLoadDLL(void)
1236 MagickExport int NTGhostscriptLoadDLL(void)
1239 path[MaxTextExtent];
1241 if (ghost_handle != (void *) NULL)
1243 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE)
1245 ghost_handle=lt_dlopen(path);
1246 if (ghost_handle == (void *) NULL)
1248 (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))
1267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1271 % N T G h o s t s c r i p t U n L o a d D L L %
1275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1277 % NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if
1280 % The format of the NTGhostscriptUnLoadDLL method is:
1282 % int NTGhostscriptUnLoadDLL(void)
1285 MagickExport int NTGhostscriptUnLoadDLL(void)
1290 if (ghost_handle == (void *) NULL)
1292 status=lt_dlclose(ghost_handle);
1293 ghost_handle=(void *) NULL;
1294 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo));
1299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1303 % N T I n i t i a l i z e L i b r a r y %
1307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1309 % NTInitializeLibrary() initializes the dynamic module loading subsystem.
1311 % The format of the NTInitializeLibrary method is:
1313 % int NTInitializeLibrary(void)
1316 MagickExport int NTInitializeLibrary(void)
1322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326 + N T M a p M e m o r y %
1330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 % Mmap() emulates the Unix method of the same name.
1334 % The format of the NTMapMemory method is:
1336 % MagickExport void *NTMapMemory(char *address,size_t length,int protection,
1337 % int access,int file,MagickOffsetType offset)
1340 MagickExport void *NTMapMemory(char *address,size_t length,int protection,
1341 int flags,int file,MagickOffsetType offset)
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;
1365 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1366 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1368 if (protection & PROT_WRITE)
1370 access_mode=FILE_MAP_WRITE;
1371 if (!(flags & MAP_PRIVATE))
1372 protection_mode=PAGE_READWRITE;
1375 access_mode=FILE_MAP_COPY;
1376 protection_mode=PAGE_WRITECOPY;
1380 if (protection & PROT_READ)
1382 access_mode=FILE_MAP_READ;
1383 protection_mode=PAGE_READONLY;
1385 if ((file == -1) && (flags & MAP_ANONYMOUS))
1386 file_handle=INVALID_HANDLE_VALUE;
1388 file_handle=(HANDLE) _get_osfhandle(file);
1389 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1393 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1395 CloseHandle(map_handle);
1397 if (map == (void *) NULL)
1398 return((void *) MAP_FAILED);
1399 return((void *) ((char *) map));
1403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1407 % N T O p e n D i r e c t o r y %
1411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413 % NTOpenDirectory() opens the directory named by filename and associates a
1414 % directory stream with it.
1416 % The format of the NTOpenDirectory method is:
1418 % DIR *NTOpenDirectory(const char *path)
1420 % A description of each parameter follows:
1422 % o entry: Specifies a pointer to a DIR structure.
1425 MagickExport DIR *NTOpenDirectory(const char *path)
1428 file_specification[MaxTextExtent];
1436 assert(path != (const char *) NULL);
1437 length=CopyMagickString(file_specification,path,MaxTextExtent);
1438 if (length >= (MaxTextExtent-1))
1439 return((DIR *) NULL);
1440 length=ConcatenateMagickString(file_specification,DirectorySeparator,
1442 if (length >= (MaxTextExtent-1))
1443 return((DIR *) NULL);
1444 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
1445 if (entry != (DIR *) NULL)
1447 entry->firsttime=TRUE;
1448 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1450 if (entry->hSearch == INVALID_HANDLE_VALUE)
1452 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent);
1453 if (length >= (MaxTextExtent-1))
1455 entry=(DIR *) RelinquishMagickMemory(entry);
1456 return((DIR *) NULL);
1458 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData);
1459 if (entry->hSearch == INVALID_HANDLE_VALUE)
1461 entry=(DIR *) RelinquishMagickMemory(entry);
1462 return((DIR *) NULL);
1469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1473 % N T O p e n L i b r a r y %
1477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
1482 % The format of the NTOpenLibrary method is:
1484 % void *NTOpenLibrary(const char *filename)
1486 % A description of each parameter follows:
1488 % o path: Specifies a pointer to string representing dynamic module that
1493 static const char *GetSearchPath( void )
1495 #if defined(MAGICKCORE_LTDL_DELEGATE)
1496 return(lt_dlgetsearchpath());
1498 return(lt_slsearchpath);
1502 MagickExport void *NTOpenLibrary(const char *filename)
1504 #define MaxPathElements 31
1507 buffer[MaxTextExtent];
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))
1532 p=(char *) GetSearchPath();
1534 while (index < MaxPathElements)
1536 q=strchr(p,DirectoryListSeparator);
1537 if (q == (char *) NULL)
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);
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)
1560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564 % N T R e a d D i r e c t o r y %
1568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570 % NTReadDirectory() returns a pointer to a structure representing the
1571 % directory entry at the current position in the directory stream to which
1574 % The format of the NTReadDirectory
1576 % NTReadDirectory(entry)
1578 % A description of each parameter follows:
1580 % o entry: Specifies a pointer to a DIR structure.
1583 MagickExport struct dirent *NTReadDirectory(DIR *entry)
1591 if (entry == (DIR *) NULL)
1592 return((struct dirent *) NULL);
1593 if (!entry->firsttime)
1595 status=FindNextFile(entry->hSearch,&entry->Win32FindData);
1597 return((struct dirent *) NULL);
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);
1609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1613 % N T R e g i s t r y K e y L o o k u p %
1617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
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.
1628 % The format of the NTRegistryKeyLookup method is:
1630 % unsigned char *NTRegistryKeyLookup(const char *subkey)
1632 % A description of each parameter follows:
1634 % o subkey: Specifies a string that identifies the registry object.
1635 % Currently supported sub-keys include: "BinPath", "ConfigurePath",
1636 % "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath".
1639 MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey)
1642 package_key[MaxTextExtent];
1660 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d",
1661 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,®istry_key);
1665 if (status != ERROR_SUCCESS)
1667 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1668 return((unsigned char *) NULL);
1674 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value));
1675 if (value == (unsigned char *) NULL)
1677 RegCloseKey(registry_key);
1678 return((unsigned char *) NULL);
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))
1684 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value));
1685 if (value == (BYTE *) NULL)
1687 RegCloseKey(registry_key);
1688 return((unsigned char *) NULL);
1690 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size);
1692 RegCloseKey(registry_key);
1693 if ((type != REG_SZ) || (status != ERROR_SUCCESS))
1694 value=(unsigned char *) RelinquishMagickMemory(value);
1695 return((unsigned char *) value);
1699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1703 % N T R e p o r t E v e n t %
1707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1709 % NTReportEvent() reports an event.
1711 % The format of the NTReportEvent method is:
1713 % MagickBooleanType NTReportEvent(const char *event,
1714 % const MagickBooleanType error)
1716 % A description of each parameter follows:
1718 % o event: the event.
1720 % o error: MagickTrue the event is an error.
1723 MagickExport MagickBooleanType NTReportEvent(const char *event,
1724 const MagickBooleanType error)
1735 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1737 return(MagickFalse);
1739 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1740 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1741 DeregisterEventSource(handle);
1746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1750 % N T R e s o u r c e T o B l o b %
1754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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
1761 % The format of the NTResourceToBlob method is:
1763 % unsigned char *NTResourceToBlob(const char *id)
1765 % A description of each parameter follows:
1767 % o id: Specifies a string that identifies the resource.
1770 MagickExport unsigned char *NTResourceToBlob(const char *id)
1773 path[MaxTextExtent];
1791 assert(id != (const char *) NULL);
1792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1793 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(),
1794 DirectorySeparator,GetClientName());
1795 if (IsPathAccessible(path) != MagickFalse)
1796 handle=GetModuleHandle(path);
1798 handle=GetModuleHandle(0);
1800 return((unsigned char *) NULL);
1801 resource=FindResource(handle,id,"IMAGEMAGICK");
1803 return((unsigned char *) NULL);
1804 global=LoadResource(handle,resource);
1806 return((unsigned char *) NULL);
1807 length=SizeofResource(handle,resource);
1808 value=(unsigned char *) LockResource(global);
1811 FreeResource(global);
1812 return((unsigned char *) NULL);
1814 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
1816 if (blob != (unsigned char *) NULL)
1818 (void) CopyMagickMemory(blob,value,length);
1821 UnlockResource(global);
1822 FreeResource(global);
1827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1831 % N T S e e k D i r e c t o r y %
1835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1837 % NTSeekDirectory() sets the position of the next NTReadDirectory() operation
1838 % on the directory stream.
1840 % The format of the NTSeekDirectory method is:
1842 % void NTSeekDirectory(DIR *entry,ssize_t position)
1844 % A description of each parameter follows:
1846 % o entry: Specifies a pointer to a DIR structure.
1848 % o position: specifies the position associated with the directory
1852 MagickExport void NTSeekDirectory(DIR *entry,ssize_t position)
1855 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1856 assert(entry != (DIR *) NULL);
1860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1864 % N T S e t S e a r c h P a t h %
1868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870 % NTSetSearchPath() sets the current locations that the subsystem should
1871 % look at to find dynamically loadable modules.
1873 % The format of the NTSetSearchPath method is:
1875 % int NTSetSearchPath(const char *path)
1877 % A description of each parameter follows:
1879 % o path: Specifies a pointer to string representing the search path
1880 % for DLL's that can be dynamically loaded.
1883 MagickExport int NTSetSearchPath(const char *path)
1885 #if defined(MAGICKCORE_LTDL_DELEGATE)
1886 lt_dlsetsearchpath(path);
1888 if (lt_slsearchpath != (char *) NULL)
1889 lt_slsearchpath=DestroyString(lt_slsearchpath);
1890 if (path != (char *) NULL)
1891 lt_slsearchpath=AcquireString(path);
1897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1901 + N T S y n c M e m o r y %
1905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1907 % NTSyncMemory() emulates the Unix method of the same name.
1909 % The format of the NTSyncMemory method is:
1911 % int NTSyncMemory(void *address,size_t length,int flags)
1913 % A description of each parameter follows:
1915 % o address: the address of the binary large object.
1917 % o length: the length of the binary large object.
1919 % o flags: Option flags (ignored for Windows).
1922 MagickExport int NTSyncMemory(void *address,size_t length,int flags)
1925 if (FlushViewOfFile(address,length) == MagickFalse)
1931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1935 % N T S y s t e m C o m m a n d %
1939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1941 % NTSystemCommand() executes the specified command and waits until it
1942 % terminates. The returned value is the exit status of the command.
1944 % The format of the NTSystemCommand method is:
1946 % int NTSystemCommand(MagickFalse,const char *command)
1948 % A description of each parameter follows:
1950 % o command: This string is the command to execute.
1953 MagickExport int NTSystemCommand(const char *command)
1956 local_command[MaxTextExtent];
1973 if (command == (char *) NULL)
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 :
1981 if (background_process)
1982 local_command[strlen(command)-1]='\0';
1983 if (command[strlen(command)-1] == '|')
1984 local_command[strlen(command)-1]='\0';
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,
1993 if (background_process)
1994 return(status == 0);
1995 status=WaitForSingleObject(process_info.hProcess,INFINITE);
1996 if (status != WAIT_OBJECT_0)
1998 status=GetExitCodeProcess(process_info.hProcess,&child_status);
2001 CloseHandle(process_info.hProcess);
2002 CloseHandle(process_info.hThread);
2003 return((int) child_status);
2007 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011 % N T S y s t e m C o n i f i g u r a t i o n %
2015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2017 % NTSystemConfiguration() provides a way for the application to determine
2018 % values for system limits or options at runtime.
2020 % The format of the exit method is:
2022 % ssize_t NTSystemConfiguration(int name)
2024 % A description of each parameter follows:
2026 % o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES.
2029 MagickExport ssize_t NTSystemConfiguration(int name)
2038 GetSystemInfo(&system_info);
2039 return(system_info.dwPageSize);
2041 case _SC_PHYS_PAGES:
2055 handle=GetModuleHandle("kernel32.dll");
2056 if (handle == (HMODULE) NULL)
2058 GetSystemInfo(&system_info);
2059 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx");
2060 if (module == (LPFNDLLFUNC2) NULL)
2065 GlobalMemoryStatus(&status);
2066 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize);
2068 status.dwLength=sizeof(status);
2069 if (module(&status) == 0)
2071 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
2082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2086 % N T T e l l D i r e c t o r y %
2090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2092 % NTTellDirectory() returns the current location associated with the named
2095 % The format of the NTTellDirectory method is:
2097 % ssize_t NTTellDirectory(DIR *entry)
2099 % A description of each parameter follows:
2101 % o entry: Specifies a pointer to a DIR structure.
2104 MagickExport ssize_t NTTellDirectory(DIR *entry)
2106 assert(entry != (DIR *) NULL);
2111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2115 % N T T r u n c a t e F i l e %
2119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121 % NTTruncateFile() truncates a file to a specified length.
2123 % The format of the NTTruncateFile method is:
2125 % int NTTruncateFile(int file,off_t length)
2127 % A description of each parameter follows:
2131 % o length: the file length.
2134 MagickExport int NTTruncateFile(int file,off_t length)
2144 file_handle=_get_osfhandle(file);
2145 if (file_handle == -1L)
2147 low=(long) (length & 0xffffffffUL);
2148 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
2149 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN);
2150 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2152 if (SetEndOfFile((HANDLE) file_handle) == 0)
2158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2162 + N T U n m a p M e m o r y %
2166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168 % NTUnmapMemory() emulates the Unix munmap method.
2170 % The format of the NTUnmapMemory method is:
2172 % int NTUnmapMemory(void *map,size_t length)
2174 % A description of each parameter follows:
2176 % o map: the address of the binary large object.
2178 % o length: the length of the binary large object.
2181 MagickExport int NTUnmapMemory(void *map,size_t length)
2184 if (UnmapViewOfFile(map) == 0)
2190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2194 % N T U s e r T i m e %
2198 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2200 % NTUserTime() returns the total time the process has been scheduled (e.g.
2201 % seconds) since the last call to StartTimer().
2203 % The format of the UserTime method is:
2205 % double NTUserTime(void)
2208 MagickExport double NTUserTime(void)
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);
2246 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2254 % N T W a r n i n g H a n d l e r %
2258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2260 % NTWarningHandler() displays a warning reason.
2262 % The format of the NTWarningHandler method is:
2264 % void NTWarningHandler(const ExceptionType severity,const char *reason,
2265 % const char *description)
2267 % A description of each parameter follows:
2269 % o severity: Specifies the numeric warning category.
2271 % o reason: Specifies the reason to display before terminating the
2274 % o description: Specifies any description to the reason.
2277 MagickExport void NTWarningHandler(const ExceptionType severity,
2278 const char *reason,const char *description)
2281 buffer[2*MaxTextExtent];
2284 if (reason == (char *) NULL)
2286 if (description == (char *) NULL)
2287 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
2290 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
2291 GetClientName(),reason,description);
2292 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2293 MB_SETFOREGROUND | MB_ICONINFORMATION);