41 #include "magick/studio.h"
42 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
43 #include "magick/client.h"
44 #include "magick/exception-private.h"
45 #include "magick/image-private.h"
46 #include "magick/locale_.h"
47 #include "magick/log.h"
48 #include "magick/magick.h"
49 #include "magick/memory_.h"
50 #include "magick/memory-private.h"
51 #include "magick/nt-base.h"
52 #include "magick/nt-base-private.h"
53 #include "magick/resource_.h"
54 #include "magick/timer.h"
55 #include "magick/string_.h"
56 #include "magick/string-private.h"
57 #include "magick/utility.h"
58 #include "magick/utility-private.h"
59 #include "magick/version.h"
60 #if defined(MAGICKCORE_LTDL_DELEGATE)
63 #if defined(MAGICKCORE_CIPHER_SUPPORT)
71 #if !defined(MAP_FAILED)
72 #define MAP_FAILED ((void *)(LONG_PTR) -1)
87 typedef struct _NTGhostInfo
90 (MagickDLLCall *delete_instance)(gs_main_instance *);
93 (MagickDLLCall *new_instance)(gs_main_instance **,
void *);
102 #if !defined(MAGICKCORE_LTDL_DELEGATE)
104 *lt_slsearchpath = (
char *) NULL;
114 *ghost_handle = (
void *) NULL;
121 *wsaData = (WSADATA*) NULL;
124 long_paths_enabled = 2;
134 const registry_roots[2] =
136 { HKEY_CURRENT_USER,
"HKEY_CURRENT_USER" },
137 { HKEY_LOCAL_MACHINE,
"HKEY_LOCAL_MACHINE" }
143 #if !defined(MAGICKCORE_WINDOWS_SUPPORT)
144 extern "C" BOOL WINAPI
145 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved);
148 static void MagickDLLCall NTGhostscriptDeleteInstance(
149 gs_main_instance *instance)
151 LockSemaphoreInfo(ghost_semaphore);
152 nt_ghost_info.delete_instance(instance);
153 nt_ghost_info.has_instance=MagickFalse;
154 UnlockSemaphoreInfo(ghost_semaphore);
157 static int MagickDLLCall NTGhostscriptNewInstance(gs_main_instance **pinstance,
163 LockSemaphoreInfo(ghost_semaphore);
165 if (nt_ghost_info.has_instance == MagickFalse)
167 status=nt_ghost_info.new_instance(pinstance,caller_handle);
169 nt_ghost_info.has_instance=MagickTrue;
171 UnlockSemaphoreInfo(ghost_semaphore);
175 static inline char *create_utf8_string(
const wchar_t *wideChar)
183 count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,NULL,0,NULL,NULL);
185 return((
char *) NULL);
186 utf8=(
char *) NTAcquireQuantumMemory(count+1,
sizeof(*utf8));
187 if (utf8 == (
char *) NULL)
188 return((
char *) NULL);
189 count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,utf8,count,NULL,NULL);
192 utf8=DestroyString(utf8);
193 return((
char *) NULL);
199 static unsigned char *NTGetRegistryValue(HKEY root,
const char *key,DWORD flags,
218 value=(
unsigned char *) NULL;
219 status=RegOpenKeyExA(root,key,0,(KEY_READ | flags),®istry_key);
220 if (status != ERROR_SUCCESS)
222 if (MultiByteToWideChar(CP_UTF8,0,name,-1,wide_name,100) == 0)
224 RegCloseKey(registry_key);
227 status=RegQueryValueExW(registry_key,wide_name,0,&type,0,&size);
228 if ((status == ERROR_SUCCESS) && (type == REG_SZ))
233 wide=(LPBYTE) NTAcquireQuantumMemory((
const size_t) size,
sizeof(*wide));
234 if (wide != (LPBYTE) NULL)
236 status=RegQueryValueExW(registry_key,wide_name,0,&type,wide,&size);
237 if ((status == ERROR_SUCCESS) && (type == REG_SZ))
238 value=(
unsigned char *) create_utf8_string((
const wchar_t *) wide);
239 wide=(LPBYTE) RelinquishMagickMemory(wide);
242 RegCloseKey(registry_key);
289 #if defined(_DLL) && defined(ProvideDllMain)
290 BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved)
292 magick_unreferenced(lpvReserved);
296 case DLL_PROCESS_ATTACH:
307 MagickCoreGenesis((
const char*) NULL,MagickFalse);
308 wide_path=(
wchar_t *) NTAcquireQuantumMemory(MaxTextExtent,
310 if (wide_path == (
wchar_t *) NULL)
312 count=(ssize_t) GetModuleFileNameW(handle,wide_path,MaxTextExtent);
318 module_path=create_utf8_string(wide_path);
319 for ( ; count > 0; count--)
320 if (module_path[count] ==
'\\')
322 module_path[count+1]=
'\0';
325 path=(
char *) NTAcquireQuantumMemory(MaxTextExtent,16*
sizeof(*path));
326 if (path == (
char *) NULL)
328 module_path=DestroyString(module_path);
329 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
332 count=(ssize_t) GetEnvironmentVariable(
"PATH",path,16*MaxTextExtent);
333 if ((count != 0) && (strstr(path,module_path) == (
char *) NULL))
335 if ((strlen(module_path)+count+1) < (16*MaxTextExtent-1))
340 variable=(
char *) NTAcquireQuantumMemory(MaxTextExtent,
341 16*
sizeof(*variable));
342 if (variable == (
char *) NULL)
344 path=DestroyString(path);
345 module_path=DestroyString(module_path);
346 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
349 (void) FormatLocaleString(variable,16*MaxTextExtent,
350 "%s;%s",module_path,path);
351 SetEnvironmentVariable(
"PATH",variable);
352 variable=DestroyString(variable);
355 path=DestroyString(path);
356 module_path=DestroyString(module_path);
358 wide_path=(
wchar_t *) RelinquishMagickMemory(wide_path);
361 case DLL_PROCESS_DETACH:
363 MagickCoreTerminus();
373 #if !defined(__MINGW32__)
398 MagickPrivate
int gettimeofday (
struct timeval *time_value,
399 struct timezone *time_zone)
401 #define EpochFiletime MagickLLConstant(116444736000000000)
406 if (time_value != (
struct timeval *) NULL)
417 GetSystemTimeAsFileTime(&file_time);
418 date_time.LowPart=file_time.dwLowDateTime;
419 date_time.HighPart=file_time.dwHighDateTime;
420 time=date_time.QuadPart;
423 time_value->tv_sec=(ssize_t) (time / 1000000);
424 time_value->tv_usec=(ssize_t) (time % 1000000);
426 if (time_zone != (
struct timezone *) NULL)
433 time_zone->tz_minuteswest=_timezone/60;
434 time_zone->tz_dsttime=_daylight;
465 MagickPrivate
char **NTArgvToUTF8(
const int argc,
wchar_t **argv)
473 utf8=(
char **) NTAcquireQuantumMemory(argc,
sizeof(*utf8));
474 if (utf8 == (
char **) NULL)
475 ThrowFatalException(ResourceLimitFatalError,
"UnableToConvertStringToARGV");
476 for (i=0; i < (ssize_t) argc; i++)
478 utf8[i]=create_utf8_string(argv[i]);
479 if (utf8[i] == (
char *) NULL)
481 for (i--; i >= 0; i--)
482 utf8[i]=DestroyString(utf8[i]);
483 ThrowFatalException(ResourceLimitFatalError,
484 "UnableToConvertStringToARGV");
513 MagickPrivate
int NTCloseDirectory(
DIR *entry)
515 assert(entry != (
DIR *) NULL);
516 if (IsEventLogging() != MagickFalse)
517 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
518 FindClose(entry->hSearch);
519 entry=(
DIR *) RelinquishMagickMemory(entry);
545 MagickPrivate
int NTCloseLibrary(
void *handle)
547 return(!(FreeLibrary((HINSTANCE) handle)));
570 static BOOL ControlHandler(DWORD type)
573 AsynchronousResourceComponentTerminus();
577 MagickPrivate
int NTControlHandler(
void)
579 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE));
601 MagickPrivate
double NTElapsedTime(
void)
621 if (frequency.QuadPart == 0)
623 if (QueryPerformanceFrequency(&frequency) == 0)
624 frequency.QuadPart=1;
626 if (frequency.QuadPart > 1)
628 QueryPerformanceCounter(&performance_count);
629 return((
double) performance_count.QuadPart/frequency.QuadPart);
631 GetSystemTime(&system_time);
632 SystemTimeToFileTime(&system_time,&elapsed_time.filetime);
633 return((
double) 1.0e-7*elapsed_time.filetime64);
664 MagickPrivate
void NTErrorHandler(
const ExceptionType severity,
665 const char *reason,
const char *description)
668 buffer[3*MaxTextExtent],
672 if (reason == (
char *) NULL)
674 MagickCoreTerminus();
677 message=GetExceptionMessage(errno);
678 if ((description != (
char *) NULL) && errno)
679 (void) FormatLocaleString(buffer,MaxTextExtent,
"%s: %s (%s) [%s].\n",
680 GetClientName(),reason,description,message);
682 if (description != (
char *) NULL)
683 (
void) FormatLocaleString(buffer,MaxTextExtent,
"%s: %s (%s).\n",
684 GetClientName(),reason,description);
687 (void) FormatLocaleString(buffer,MaxTextExtent,
"%s: %s [%s].\n",
688 GetClientName(),reason,message);
690 (
void) FormatLocaleString(buffer,MaxTextExtent,
"%s: %s.\n",
691 GetClientName(),reason);
692 message=DestroyString(message);
693 (void) MessageBox(NULL,buffer,
"ImageMagick Exception",MB_OK | MB_TASKMODAL |
694 MB_SETFOREGROUND | MB_ICONEXCLAMATION);
695 MagickCoreTerminus();
717 MagickPrivate
int NTExitLibrary(
void)
747 MagickPrivate MagickBooleanType NTGatherRandomData(
const size_t length,
748 unsigned char *random)
750 #if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200)
757 handle=(HCRYPTPROV) NULL;
758 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
759 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET));
761 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL,
762 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET));
765 status=CryptGenRandom(handle,(DWORD) length,random);
768 status=CryptReleaseContext(handle,0);
771 status=CryptReleaseContext(handle,0);
805 MagickPrivate MagickBooleanType NTGetExecutionPath(
char *path,
809 wide_path[MaxTextExtent];
811 (void) GetModuleFileNameW((HMODULE) NULL,wide_path,(DWORD) extent);
812 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(
int) extent,NULL,
835 char *NTGetLastError(
void)
846 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
847 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(),
848 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL);
850 reason=AcquireString(
"An unknown error occurred");
853 reason=AcquireString((
const char *) buffer);
879 MagickPrivate
const char *NTGetLibraryError(
void)
882 last_error[MaxTextExtent];
888 error=NTGetLastError();
890 (void) CopyMagickString(last_error,error,MaxTextExtent);
891 error=DestroyString(error);
920 void *NTGetLibrarySymbol(
void *handle,
const char *name)
925 proc_address=GetProcAddress((HMODULE) handle,(LPCSTR) name);
926 if (proc_address == (FARPROC) NULL)
927 return((
void *) NULL);
928 return((
void *) proc_address);
955 MagickPrivate MagickBooleanType NTGetModulePath(
const char *module,
char *path)
958 module_path[MaxTextExtent];
967 handle=GetModuleHandle(module);
968 if (handle == (HMODULE) NULL)
970 length=GetModuleFileName(handle,module_path,MaxTextExtent);
972 GetPathComponent(module_path,HeadPath,path);
997 static int NTLocateGhostscript(DWORD flags,
int *root_index,
998 const char **product_family,
int *major_version,
int *minor_version,
1013 "Aladdin Ghostscript"
1021 *product_family=NULL;
1024 for (i=0; i < (ssize_t) (
sizeof(products)/
sizeof(products[0])); i++)
1027 key[MagickPathExtent];
1038 (void) FormatLocaleString(key,MagickPathExtent,
"SOFTWARE\\%s",products[i]);
1039 for (j=0; j < (ssize_t) (
sizeof(registry_roots)/
sizeof(registry_roots[0]));
1042 mode=KEY_READ | flags;
1043 if (RegOpenKeyExA(registry_roots[j].hkey,key,0,mode,&hkey) ==
1055 extent=
sizeof(key)/
sizeof(
char);
1056 for (k=0; RegEnumKeyA(hkey,k,key,extent) == ERROR_SUCCESS; k++)
1066 if (sscanf(key,
"%d.%d.%d",&major,&minor,&patch) != 3)
1067 if (sscanf(key,
"%d.%d",&major,&minor) != 2)
1069 if ((major > *major_version) ||
1070 ((major == *major_version) && (minor > *minor_version)) ||
1071 ((minor == *minor_version) && (patch > *patch_version)))
1074 *product_family=products[i];
1075 *major_version=major;
1076 *minor_version=minor;
1077 *patch_version=patch;
1081 (void) RegCloseKey(hkey);
1085 if (status == MagickFalse)
1091 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
"Ghostscript (%s) "
1092 "version %d.%d.%d",*product_family,*major_version,*minor_version,*patch_version);
1096 static MagickBooleanType NTGhostscriptGetString(
const char *name,
1097 BOOL *is_64_bit,
char *value,
const size_t length)
1100 buffer[MagickPathExtent],
1104 *product_family = (
const char *) NULL;
1107 is_64_bit_version = FALSE;
1123 directory=(
char *) NULL;
1124 if (LocaleCompare(name,
"GS_DLL") == 0)
1126 directory=GetEnvironmentValue(
"MAGICK_GHOSTSCRIPT_PATH");
1127 if (directory != (
char *) NULL)
1129 (void) FormatLocaleString(buffer,MagickPathExtent,
"%s%sgsdll64.dll",
1130 directory,DirectorySeparator);
1131 if (IsPathAccessible(buffer) != MagickFalse)
1133 directory=DestroyString(directory);
1134 (void) CopyMagickString(value,buffer,length);
1135 if (is_64_bit != NULL)
1139 (void) FormatLocaleString(buffer,MagickPathExtent,
"%s%sgsdll32.dll",
1140 directory,DirectorySeparator);
1141 if (IsPathAccessible(buffer) != MagickFalse)
1143 directory=DestroyString(directory);
1144 (void) CopyMagickString(value,buffer,length);
1145 if (is_64_bit != NULL)
1149 return(MagickFalse);
1152 if (product_family == (
const char *) NULL)
1155 #if defined(KEY_WOW64_32KEY)
1157 flags=KEY_WOW64_64KEY;
1159 flags=KEY_WOW64_32KEY;
1161 (void) NTLocateGhostscript(flags,&root_index,&product_family,
1162 &major_version,&minor_version,&patch_version);
1163 if (product_family == (
const char *) NULL)
1165 flags=KEY_WOW64_32KEY;
1167 is_64_bit_version=TRUE;
1169 flags=KEY_WOW64_64KEY;
1173 if (product_family == (
const char *) NULL)
1175 (void) NTLocateGhostscript(flags,&root_index,&product_family,
1176 &major_version,&minor_version,&patch_version);
1177 #if !defined(_WIN64)
1178 is_64_bit_version=TRUE;
1181 if (product_family == (
const char *) NULL)
1182 return(MagickFalse);
1183 if (is_64_bit != NULL)
1184 *is_64_bit=is_64_bit_version;
1185 (void) FormatLocaleString(buffer,MagickPathExtent,
"SOFTWARE\\%s\\%d.%.2d.%d",
1186 product_family,major_version,minor_version,patch_version);
1187 registry_value=NTGetRegistryValue(registry_roots[root_index].hkey,buffer,
1189 if (registry_value == (
unsigned char *) NULL)
1191 (void) FormatLocaleString(buffer,MagickPathExtent,
"SOFTWARE\\%s\\%d.%02d",
1192 product_family,major_version,minor_version);
1193 registry_value=NTGetRegistryValue(registry_roots[root_index].hkey,buffer,
1196 if (registry_value == (
unsigned char *) NULL)
1197 return(MagickFalse);
1198 (void) CopyMagickString(value,(
const char *) registry_value,length);
1199 registry_value=(
unsigned char *) RelinquishMagickMemory(registry_value);
1200 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1201 "registry: \"%s\\%s\\%s\"=\"%s\"",registry_roots[root_index].name,
1206 static MagickBooleanType NTGhostscriptDLL(
char *path,
int length)
1209 dll[MagickPathExtent] = {
"" };
1215 if ((*dll ==
'\0') &&
1216 (NTGhostscriptGetString(
"GS_DLL",&is_64_bit,dll,
sizeof(dll)) != MagickTrue))
1217 return(MagickFalse);
1220 return(MagickFalse);
1223 return(MagickFalse);
1225 (void) CopyMagickString(path,dll,length);
1229 static inline MagickBooleanType NTGhostscriptHasValidHandle()
1231 if ((nt_ghost_info.delete_instance == NULL) || (ghost_info.exit == NULL) ||
1232 (nt_ghost_info.new_instance == NULL) || (ghost_info.set_stdio == NULL) ||
1233 (ghost_info.init_with_args == NULL) || (ghost_info.revision == NULL))
1234 return(MagickFalse);
1238 MagickPrivate
const GhostInfo *NTGhostscriptDLLVectors(
void)
1241 path[MaxTextExtent];
1244 ActivateSemaphoreInfo(&ghost_semaphore);
1245 LockSemaphoreInfo(ghost_semaphore);
1246 if (ghost_handle != (
void *) NULL)
1248 UnlockSemaphoreInfo(ghost_semaphore);
1249 if (NTGhostscriptHasValidHandle() == MagickFalse)
1251 return(&ghost_info);
1253 if (NTGhostscriptDLL(path,
sizeof(path)) == MagickFalse)
1255 UnlockSemaphoreInfo(ghost_semaphore);
1258 ghost_handle=lt_dlopen(path);
1259 if (ghost_handle == (
void *) NULL)
1261 UnlockSemaphoreInfo(ghost_semaphore);
1264 (void) memset((
void *) &nt_ghost_info,0,
sizeof(NTGhostInfo));
1265 nt_ghost_info.delete_instance=(void (MagickDLLCall *)(gs_main_instance *)) (
1266 lt_dlsym(ghost_handle,
"gsapi_delete_instance"));
1267 nt_ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,
1268 void *)) (lt_dlsym(ghost_handle,
"gsapi_new_instance"));
1269 nt_ghost_info.has_instance=MagickFalse;
1270 (void) memset((
void *) &ghost_info,0,
sizeof(
GhostInfo));
1271 ghost_info.delete_instance=NTGhostscriptDeleteInstance;
1272 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*))
1273 lt_dlsym(ghost_handle,
"gsapi_exit");
1274 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int,
1275 char **)) (lt_dlsym(ghost_handle,
"gsapi_init_with_args"));
1276 ghost_info.new_instance=NTGhostscriptNewInstance;
1277 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,
const char *,
1278 int,
int *)) (lt_dlsym(ghost_handle,
"gsapi_run_string"));
1279 ghost_info.set_stdio=(int (MagickDLLCall *)(gs_main_instance *,int(
1280 MagickDLLCall *)(
void *,
char *,int),
int(MagickDLLCall *)(
void *,
1281 const char *,int),
int(MagickDLLCall *)(
void *,
const char *,int)))
1282 (lt_dlsym(ghost_handle,
"gsapi_set_stdio"));
1284 lt_dlsym(ghost_handle,
"gsapi_revision"));
1285 UnlockSemaphoreInfo(ghost_semaphore);
1286 if (NTGhostscriptHasValidHandle() == MagickFalse)
1288 return(&ghost_info);
1317 MagickPrivate
int NTGhostscriptEXE(
char *path,
int length)
1323 program[MaxTextExtent] = {
"" };
1326 is_64_bit_version = FALSE;
1328 if (*program ==
'\0')
1331 ActivateSemaphoreInfo(&ghost_semaphore);
1332 LockSemaphoreInfo(ghost_semaphore);
1333 if (*program ==
'\0')
1335 if (NTGhostscriptGetString(
"GS_DLL",&is_64_bit_version,program,
1336 sizeof(program)) == MagickFalse)
1338 UnlockSemaphoreInfo(ghost_semaphore);
1340 (void) CopyMagickString(program,
"gswin64c.exe",
sizeof(program));
1342 (void) CopyMagickString(program,
"gswin32c.exe",
sizeof(program));
1344 (void) CopyMagickString(path,program,length);
1347 p=strrchr(program,
'\\');
1348 if (p != (
char *) NULL)
1352 (void) ConcatenateMagickString(program,is_64_bit_version ?
1353 "gswin64c.exe" :
"gswin32c.exe",
sizeof(program));
1356 UnlockSemaphoreInfo(ghost_semaphore);
1358 (void) CopyMagickString(path,program,length);
1387 MagickPrivate
int NTGhostscriptFonts(
char *path,
int length)
1390 buffer[MaxTextExtent],
1392 filename[MaxTextExtent];
1399 directory=GetEnvironmentValue(
"MAGICK_GHOSTSCRIPT_FONT_PATH");
1400 if (directory != (
char *) NULL)
1402 (void) CopyMagickString(buffer,directory,MaxTextExtent);
1403 directory=DestroyString(directory);
1407 if (NTGhostscriptGetString(
"GS_LIB",NULL,buffer,MaxTextExtent) == MagickFalse)
1410 for (p=buffer-1; p != (
char *) NULL; p=strchr(p+1,DirectoryListSeparator))
1412 (void) CopyMagickString(path,p+1,length+1);
1413 q=strchr(path,DirectoryListSeparator);
1414 if (q != (
char *) NULL)
1416 (void) FormatLocaleString(filename,MaxTextExtent,
"%s%sfonts.dir",path,
1417 DirectorySeparator);
1418 if (IsPathAccessible(filename) != MagickFalse)
1420 (void) FormatLocaleString(filename,MaxTextExtent,
"%s%sn019003l.pfb",path,
1421 DirectorySeparator);
1422 if (IsPathAccessible(filename) != MagickFalse)
1448 MagickPrivate
int NTGhostscriptUnLoadDLL(
void)
1454 ActivateSemaphoreInfo(&ghost_semaphore);
1455 LockSemaphoreInfo(ghost_semaphore);
1457 if (ghost_handle != (
void *) NULL)
1459 status=lt_dlclose(ghost_handle);
1460 ghost_handle=(
void *) NULL;
1461 (void) memset((
void *) &ghost_info,0,
sizeof(
GhostInfo));
1463 UnlockSemaphoreInfo(ghost_semaphore);
1464 DestroySemaphoreInfo(&ghost_semaphore);
1486 MagickPrivate
int NTInitializeLibrary(
void)
1509 MagickPrivate
void NTInitializeWinsock(MagickBooleanType use_lock)
1514 ActivateSemaphoreInfo(&winsock_semaphore);
1515 LockSemaphoreInfo(winsock_semaphore);
1517 if (wsaData == (WSADATA *) NULL)
1519 wsaData=(WSADATA *) AcquireMagickMemory(
sizeof(WSADATA));
1520 if (WSAStartup(MAKEWORD(2,2),wsaData) != 0)
1521 ThrowFatalException(CacheFatalError,
"WSAStartup failed");
1524 UnlockSemaphoreInfo(winsock_semaphore);
1546 MagickExport MagickBooleanType NTLongPathsEnabled()
1548 if (long_paths_enabled == 2)
1561 registry_key=(HKEY) INVALID_HANDLE_VALUE;
1562 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,
1563 "SYSTEM\\CurrentControlSet\\Control\\FileSystem",0,KEY_READ,
1565 if (status != ERROR_SUCCESS)
1567 long_paths_enabled=0;
1568 RegCloseKey(registry_key);
1569 return(MagickFalse);
1572 status=RegQueryValueExA(registry_key,
"LongPathsEnabled",0,&type,NULL,
1574 if ((status != ERROR_SUCCESS) || (type != REG_DWORD))
1576 long_paths_enabled=0;
1577 RegCloseKey(registry_key);
1578 return(MagickFalse);
1580 status=RegQueryValueExA(registry_key,
"LongPathsEnabled",0,&type,
1581 (LPBYTE) &value,&size);
1582 RegCloseKey(registry_key);
1583 if (status != ERROR_SUCCESS)
1585 long_paths_enabled=0;
1586 return(MagickFalse);
1588 long_paths_enabled=(size_t) value;
1590 return(long_paths_enabled == 1 ? MagickTrue : MagickFalse);
1612 MagickPrivate
void *NTMapMemory(
char *address,
size_t length,
int protection,
1613 int flags,
int file,MagickOffsetType offset)
1632 file_handle=INVALID_HANDLE_VALUE;
1633 low_length=(DWORD) (length & 0xFFFFFFFFUL);
1634 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
1635 map_handle=INVALID_HANDLE_VALUE;
1637 low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
1638 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
1640 if (protection & PROT_WRITE)
1642 access_mode=FILE_MAP_WRITE;
1643 if (!(flags & MAP_PRIVATE))
1644 protection_mode=PAGE_READWRITE;
1647 access_mode=FILE_MAP_COPY;
1648 protection_mode=PAGE_WRITECOPY;
1652 if (protection & PROT_READ)
1654 access_mode=FILE_MAP_READ;
1655 protection_mode=PAGE_READONLY;
1657 if ((file == -1) && (flags & MAP_ANONYMOUS))
1658 file_handle=INVALID_HANDLE_VALUE;
1660 file_handle=(HANDLE) _get_osfhandle(file);
1661 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
1665 map=(
void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
1667 CloseHandle(map_handle);
1669 if (map == (
void *) NULL)
1670 return((
void *) ((
char *) MAP_FAILED));
1671 return((
void *) ((
char *) map));
1697 MagickPrivate
DIR *NTOpenDirectory(
const char *path)
1706 file_specification[MaxTextExtent];
1708 assert(path != (
const char *) NULL);
1709 length=MultiByteToWideChar(CP_UTF8,0,path,-1,file_specification,
1712 return((
DIR *) NULL);
1713 if(wcsncat(file_specification,L
"\\*.*",MaxTextExtent-wcslen(
1714 file_specification)-1) == (
wchar_t*) NULL)
1715 return((
DIR *) NULL);
1716 entry=(
DIR *) AcquireCriticalMemory(
sizeof(
DIR));
1717 entry->firsttime=TRUE;
1718 entry->hSearch=FindFirstFileW(file_specification,&entry->Win32FindData);
1719 if (entry->hSearch == INVALID_HANDLE_VALUE)
1721 entry=(
DIR *) RelinquishMagickMemory(entry);
1722 return((
DIR *) NULL);
1752 static inline const char *GetSearchPath(
void)
1754 #if defined(MAGICKCORE_LTDL_DELEGATE)
1755 return(lt_dlgetsearchpath());
1757 return(lt_slsearchpath);
1761 static UINT ChangeErrorMode(
void)
1764 (CALLBACK *GETERRORMODE)(void);
1775 mode=SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
1777 handle=GetModuleHandle(
"kernel32.dll");
1778 if (handle == (HMODULE) NULL)
1779 return SetErrorMode(mode);
1781 getErrorMode=(GETERRORMODE) NTGetLibrarySymbol(handle,
"GetErrorMode");
1782 if (getErrorMode != (GETERRORMODE) NULL)
1783 mode=getErrorMode() | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX;
1785 return SetErrorMode(mode);
1788 static inline void *NTLoadLibrary(
const char *filename)
1794 path[MaxTextExtent];
1796 length=MultiByteToWideChar(CP_UTF8,0,filename,-1,path,MaxTextExtent);
1798 return((
void *) NULL);
1799 return (
void *) LoadLibraryExW(path,NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
1802 MagickPrivate
void *NTOpenLibrary(
const char *filename)
1805 path[MaxTextExtent];
1817 mode=ChangeErrorMode();
1818 handle=NTLoadLibrary(filename);
1819 if (handle == (
void *) NULL)
1822 while (p != (
const char*) NULL)
1824 q=strchr(p,DirectoryListSeparator);
1825 if (q != (
const char*) NULL)
1826 (void) CopyMagickString(path,p,q-p+1);
1828 (
void) CopyMagickString(path,p,MaxTextExtent);
1829 (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
1830 (void) ConcatenateMagickString(path,filename,MaxTextExtent);
1831 handle=NTLoadLibrary(path);
1832 if (handle != (
void *) NULL || q == (
const char*) NULL)
1865 MagickPrivate
struct dirent *NTReadDirectory(
DIR *entry)
1873 if (entry == (
DIR *) NULL)
1874 return((
struct dirent *) NULL);
1875 if (!entry->firsttime)
1877 status=FindNextFileW(entry->hSearch,&entry->Win32FindData);
1879 return((
struct dirent *) NULL);
1881 length=WideCharToMultiByte(CP_UTF8,0,entry->Win32FindData.cFileName,-1,
1882 entry->file_info.d_name,
sizeof(entry->file_info.d_name),NULL,NULL);
1884 return((
struct dirent *) NULL);
1885 entry->firsttime=FALSE;
1886 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name);
1887 return(&entry->file_info);
1922 MagickPrivate
unsigned char *NTRegistryKeyLookup(
const char *subkey)
1925 package_key[MaxTextExtent] =
"";
1930 value=NTGetRegistryValue(HKEY_LOCAL_MACHINE,package_key,0,subkey);
1931 if (value == (
unsigned char *) NULL)
1932 value=NTGetRegistryValue(HKEY_CURRENT_USER,package_key,0,subkey);
1961 MagickPrivate MagickBooleanType NTReportEvent(
const char *event,
1962 const MagickBooleanType error)
1973 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME);
1975 return(MagickFalse);
1977 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE;
1978 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL);
1979 DeregisterEventSource(handle);
2008 MagickPrivate
unsigned char *NTResourceToBlob(
const char *
id)
2011 #ifndef MAGICKCORE_LIBRARY_NAME
2013 path[MaxTextExtent];
2032 assert(
id != (
const char *) NULL);
2033 if (IsEventLogging() != MagickFalse)
2034 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",id);
2035 #ifdef MAGICKCORE_LIBRARY_NAME
2036 handle=GetModuleHandle(MAGICKCORE_LIBRARY_NAME);
2038 (void) FormatLocaleString(path,MaxTextExtent,
"%s%s%s",GetClientPath(),
2039 DirectorySeparator,GetClientName());
2040 if (IsPathAccessible(path) != MagickFalse)
2041 handle=GetModuleHandle(path);
2043 handle=GetModuleHandle(0);
2046 return((
unsigned char *) NULL);
2047 resource=FindResource(handle,
id,
"IMAGEMAGICK");
2049 return((
unsigned char *) NULL);
2050 global=LoadResource(handle,resource);
2052 return((
unsigned char *) NULL);
2053 length=SizeofResource(handle,resource);
2054 value=(
unsigned char *) LockResource(global);
2057 FreeResource(global);
2058 return((
unsigned char *) NULL);
2060 blob=(
unsigned char *) AcquireQuantumMemory(length+MaxTextExtent,
2062 if (blob != (
unsigned char *) NULL)
2064 (void) memcpy(blob,value,length);
2067 UnlockResource(global);
2068 FreeResource(global);
2096 MagickPrivate
int NTSetSearchPath(
const char *path)
2098 #if defined(MAGICKCORE_LTDL_DELEGATE)
2099 lt_dlsetsearchpath(path);
2101 if (lt_slsearchpath != (
char *) NULL)
2102 lt_slsearchpath=DestroyString(lt_slsearchpath);
2103 if (path != (
char *) NULL)
2104 lt_slsearchpath=AcquireString(path);
2134 MagickPrivate
int NTSystemCommand(
const char *command,
char *output)
2136 #define CleanupOutputHandles \
2137 if (read_output != (HANDLE) NULL) \
2139 CloseHandle(read_output); \
2140 read_output=(HANDLE) NULL; \
2141 CloseHandle(write_output); \
2142 write_output=(HANDLE) NULL; \
2145 #define CopyLastError \
2146 if (output != (char *) NULL) \
2148 error=NTGetLastError(); \
2149 if (error != (char *) NULL) \
2151 CopyMagickString(output,error,MaxTextExtent); \
2152 error=DestroyString(error); \
2158 local_command[MaxTextExtent];
2182 if (command == (
char *) NULL)
2184 read_output=(HANDLE) NULL;
2185 write_output=(HANDLE) NULL;
2186 GetStartupInfo(&startup_info);
2187 startup_info.dwFlags=STARTF_USESHOWWINDOW;
2188 startup_info.wShowWindow=SW_SHOWMINNOACTIVE;
2189 (void) CopyMagickString(local_command,command,MaxTextExtent);
2190 asynchronous=command[strlen(command)-1] ==
'&' ? MagickTrue : MagickFalse;
2191 if (asynchronous != MagickFalse)
2193 local_command[strlen(command)-1]=
'\0';
2194 startup_info.wShowWindow=SW_SHOWDEFAULT;
2198 if (command[strlen(command)-1] ==
'|')
2199 local_command[strlen(command)-1]=
'\0';
2201 startup_info.wShowWindow=SW_HIDE;
2202 read_output=(HANDLE) NULL;
2203 if (output != (
char *) NULL)
2205 if (CreatePipe(&read_output,&write_output,NULL,0))
2207 if (SetHandleInformation(write_output,HANDLE_FLAG_INHERIT,
2208 HANDLE_FLAG_INHERIT))
2210 startup_info.dwFlags|=STARTF_USESTDHANDLES;
2211 startup_info.hStdOutput=write_output;
2212 startup_info.hStdError=write_output;
2215 CleanupOutputHandles;
2218 read_output=(HANDLE) NULL;
2221 status=CreateProcess((LPCTSTR) NULL,local_command,(LPSECURITY_ATTRIBUTES)
2222 NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) TRUE,(DWORD)
2223 NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info,
2228 CleanupOutputHandles;
2231 if (output != (
char *) NULL)
2233 if (asynchronous != MagickFalse)
2234 return(status == 0);
2236 status=STATUS_TIMEOUT;
2237 while (status == STATUS_TIMEOUT)
2242 status=WaitForSingleObject(process_info.hProcess,1000);
2244 if (read_output != (HANDLE) NULL)
2245 if (!PeekNamedPipe(read_output,NULL,0,NULL,&size,NULL))
2250 buffer[MagickPathExtent];
2255 if (ReadFile(read_output,buffer,MagickPathExtent-1,&bytes_read,NULL))
2260 count=MagickMin(MagickPathExtent-output_offset,
2261 (
size_t) bytes_read+1);
2264 CopyMagickString(output+output_offset,buffer,count);
2265 output_offset+=count-1;
2268 if (!PeekNamedPipe(read_output,NULL,0,NULL,&size,NULL))
2272 if (status != WAIT_OBJECT_0)
2275 CleanupOutputHandles;
2278 status=GetExitCodeProcess(process_info.hProcess,&child_status);
2282 CleanupOutputHandles;
2285 CloseHandle(process_info.hProcess);
2286 CloseHandle(process_info.hThread);
2287 CleanupOutputHandles;
2288 return((
int) child_status);
2314 MagickPrivate ssize_t NTSystemConfiguration(
int name)
2323 GetSystemInfo(&system_info);
2324 return(system_info.dwPageSize);
2326 case _SC_PHYS_PAGES:
2334 status.dwLength=
sizeof(status);
2335 if (GlobalMemoryStatusEx(&status) == 0)
2337 GetSystemInfo(&system_info);
2338 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize);
2372 MagickPrivate
int NTTruncateFile(
int file,off_t length)
2384 file_handle=(HANDLE) _get_osfhandle(file);
2385 if (file_handle == INVALID_HANDLE_VALUE)
2387 low=(long) (length & 0xffffffffUL);
2388 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL);
2389 file_pointer=SetFilePointer(file_handle,low,&high,FILE_BEGIN);
2390 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR))
2392 if (SetEndOfFile(file_handle) == 0)
2421 MagickPrivate
int NTUnmapMemory(
void *map,
size_t length)
2424 if (UnmapViewOfFile(map) == 0)
2448 MagickPrivate
double NTUserTime(
void)
2478 OsVersionInfo.dwOSVersionInfoSize=
sizeof(OSVERSIONINFO);
2479 GetVersionEx(&OsVersionInfo);
2480 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
2481 return(NTElapsedTime());
2482 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time,
2483 &kernel_time.filetime,&user_time.filetime);
2486 return((
double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64));
2517 MagickPrivate
void NTWarningHandler(
const ExceptionType severity,
2518 const char *reason,
const char *description)
2521 buffer[2*MaxTextExtent];
2524 if (reason == (
char *) NULL)
2526 if (description == (
char *) NULL)
2527 (
void) FormatLocaleString(buffer,MaxTextExtent,
"%s: %s.\n",GetClientName(),
2530 (
void) FormatLocaleString(buffer,MaxTextExtent,
"%s: %s (%s).\n",
2531 GetClientName(),reason,description);
2532 (void) MessageBox(NULL,buffer,
"ImageMagick Warning",MB_OK | MB_TASKMODAL |
2533 MB_SETFOREGROUND | MB_ICONINFORMATION);
2555 static LONG WINAPI NTUncaughtException(EXCEPTION_POINTERS *info)
2557 magick_unreferenced(info);
2558 AsynchronousResourceComponentTerminus();
2559 return(EXCEPTION_CONTINUE_SEARCH);
2562 MagickPrivate
void NTWindowsGenesis(
void)
2567 SetUnhandledExceptionFilter(NTUncaughtException);
2568 mode=GetEnvironmentValue(
"MAGICK_ERRORMODE");
2569 if (mode != (
char *) NULL)
2571 (void) SetErrorMode(StringToInteger(mode));
2572 mode=DestroyString(mode);
2574 #if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__)
2575 if (IsEventLogging() != MagickFalse)
2580 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
2582 debug |= _CRTDBG_DELAY_FREE_MEM_DF;
2583 debug |= _CRTDBG_LEAK_CHECK_DF;
2584 (void) _CrtSetDbgFlag(debug);
2591 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
2596 path=NTRegistryKeyLookup(
"LibPath");
2597 if (path != (
unsigned char *) NULL)
2603 lib_path[MagickPathExtent];
2605 length=MultiByteToWideChar(CP_UTF8,0,(
char *) path,-1,lib_path,
2608 SetDllDirectoryW(lib_path);
2609 path=(
unsigned char *) RelinquishMagickMemory(path);
2633 MagickPrivate
void NTWindowsTerminus(
void)
2635 NTGhostscriptUnLoadDLL();
2637 ActivateSemaphoreInfo(&winsock_semaphore);
2638 LockSemaphoreInfo(winsock_semaphore);
2639 if (wsaData != (WSADATA *) NULL)
2642 wsaData=(WSADATA *) RelinquishMagickMemory((
void *) wsaData);
2644 UnlockSemaphoreInfo(winsock_semaphore);
2645 DestroySemaphoreInfo(&winsock_semaphore);