nt-base.c revision d2a7a2d4a46c82a8679688ae763ef9d7bb53ccd7
1/* 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% Cristy % 17% December 1996 % 18% % 19% % 20% Copyright 1999-2016 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 "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/nt-base.h" 50#include "MagickCore/nt-base-private.h" 51#include "MagickCore/resource_.h" 52#include "MagickCore/resource-private.h" 53#include "MagickCore/timer.h" 54#include "MagickCore/string_.h" 55#include "MagickCore/string-private.h" 56#include "MagickCore/utility.h" 57#include "MagickCore/utility-private.h" 58#include "MagickCore/version.h" 59#if defined(MAGICKCORE_LTDL_DELEGATE) 60# include "ltdl.h" 61#endif 62#if defined(MAGICKCORE_CIPHER_SUPPORT) 63#include <ntsecapi.h> 64#include <wincrypt.h> 65#endif 66 67/* 68 Define declarations. 69*/ 70#if !defined(MAP_FAILED) 71#define MAP_FAILED ((void *)(LONG_PTR)-1) 72#endif 73 74/* 75 Typdef declarations. 76*/ 77 78/* 79 We need to make sure only one instance is created for each process and that 80 is why we wrap the new/delete instance methods. 81 82 From: http://www.ghostscript.com/doc/current/API.htm 83 "The Win32 DLL gsdll32.dll can be used by multiple programs simultaneously, 84 but only once within each process" 85*/ 86typedef struct _NTGhostInfo 87{ 88 void 89 (MagickDLLCall *delete_instance)(gs_main_instance *); 90 91 int 92 (MagickDLLCall *new_instance)(gs_main_instance **,void *); 93 94 MagickBooleanType 95 has_instance; 96} NTGhostInfo; 97 98/* 99 Static declarations. 100*/ 101#if !defined(MAGICKCORE_LTDL_DELEGATE) 102static char 103 *lt_slsearchpath = (char *) NULL; 104#endif 105 106static NTGhostInfo 107 nt_ghost_info; 108 109static GhostInfo 110 ghost_info; 111 112static void 113 *ghost_handle = (void *) NULL; 114 115static SemaphoreInfo 116 *ghost_semaphore = (SemaphoreInfo *) NULL, 117 *winsock_semaphore = (SemaphoreInfo *) NULL; 118 119static WSADATA 120 *wsaData = (WSADATA*) NULL; 121 122struct 123{ 124 const HKEY 125 hkey; 126 127 const char 128 *name; 129} 130const registry_roots[2] = 131{ 132 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" }, 133 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" } 134}; 135 136/* 137 External declarations. 138*/ 139#if !defined(MAGICKCORE_WINDOWS_SUPPORT) 140extern "C" BOOL WINAPI 141 DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved); 142#endif 143 144static void MagickDLLCall NTGhostscriptDeleteInstance( 145 gs_main_instance *instance) 146{ 147 LockSemaphoreInfo(ghost_semaphore); 148 nt_ghost_info.delete_instance(instance); 149 nt_ghost_info.has_instance=MagickFalse; 150 UnlockSemaphoreInfo(ghost_semaphore); 151} 152 153static int MagickDLLCall NTGhostscriptNewInstance(gs_main_instance **pinstance, 154 void *caller_handle) 155{ 156 int 157 status; 158 159 LockSemaphoreInfo(ghost_semaphore); 160 status=-1; 161 if (nt_ghost_info.has_instance == MagickFalse) 162 { 163 status=nt_ghost_info.new_instance(pinstance,caller_handle); 164 if (status >= 0) 165 nt_ghost_info.has_instance=MagickTrue; 166 } 167 UnlockSemaphoreInfo(ghost_semaphore); 168 return(status); 169} 170 171static inline char *create_utf8_string(const wchar_t *wideChar) 172{ 173 char 174 *utf8; 175 176 int 177 count; 178 179 count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,NULL,0,NULL,NULL); 180 if (count < 0) 181 return((char *) NULL); 182 utf8=(char *) AcquireQuantumMemory(count+1,sizeof(*utf8)); 183 if (utf8 == (char *) NULL) 184 return((char *) NULL); 185 count=WideCharToMultiByte(CP_UTF8,0,wideChar,-1,utf8,count,NULL,NULL); 186 if (count == 0) 187 { 188 utf8=DestroyString(utf8); 189 return((char *) NULL); 190 } 191 utf8[count]=0; 192 return(utf8); 193} 194 195/* 196%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 197% % 198% % 199% % 200% D l l M a i n % 201% % 202% % 203% % 204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 205% 206% DllMain() is an entry point to the DLL which is called when processes and 207% threads are initialized and terminated, or upon calls to the Windows 208% LoadLibrary and FreeLibrary functions. 209% 210% The function returns TRUE of it succeeds, or FALSE if initialization fails. 211% 212% The format of the DllMain method is: 213% 214% BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved) 215% 216% A description of each parameter follows: 217% 218% o handle: handle to the DLL module 219% 220% o reason: reason for calling function: 221% 222% DLL_PROCESS_ATTACH - DLL is being loaded into virtual address 223% space of current process. 224% DLL_THREAD_ATTACH - Indicates that the current process is 225% creating a new thread. Called under the 226% context of the new thread. 227% DLL_THREAD_DETACH - Indicates that the thread is exiting. 228% Called under the context of the exiting 229% thread. 230% DLL_PROCESS_DETACH - Indicates that the DLL is being unloaded 231% from the virtual address space of the 232% current process. 233% 234% o lpvReserved: Used for passing additional info during DLL_PROCESS_ATTACH 235% and DLL_PROCESS_DETACH. 236% 237*/ 238#if defined(_DLL) && defined(ProvideDllMain) 239BOOL WINAPI DllMain(HINSTANCE handle,DWORD reason,LPVOID lpvReserved) 240{ 241 switch (reason) 242 { 243 case DLL_PROCESS_ATTACH: 244 { 245 char 246 *module_path; 247 248 ssize_t 249 count; 250 251 wchar_t 252 *wide_path; 253 254 MagickCoreGenesis((const char *) NULL,MagickFalse); 255 wide_path=(wchar_t *) AcquireQuantumMemory(MagickPathExtent, 256 sizeof(*wide_path)); 257 if (wide_path == (wchar_t *) NULL) 258 return(FALSE); 259 count=(ssize_t) GetModuleFileNameW(handle,wide_path,MagickPathExtent); 260 if (count != 0) 261 { 262 char 263 *path; 264 265 module_path=create_utf8_string(wide_path); 266 for ( ; count > 0; count--) 267 if (module_path[count] == '\\') 268 { 269 module_path[count+1]='\0'; 270 break; 271 } 272 path=(char *) AcquireQuantumMemory(16UL*MagickPathExtent,sizeof(*path)); 273 if (path == (char *) NULL) 274 { 275 module_path=DestroyString(module_path); 276 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path); 277 return(FALSE); 278 } 279 count=(ssize_t) GetEnvironmentVariable("PATH",path,16*MagickPathExtent); 280 if ((count != 0) && (strstr(path,module_path) == (char *) NULL)) 281 { 282 if ((strlen(module_path)+count+1) < (16*MagickPathExtent-1)) 283 { 284 char 285 *variable; 286 287 variable=(char *) AcquireQuantumMemory(16UL*MagickPathExtent, 288 sizeof(*variable)); 289 if (variable == (char *) NULL) 290 { 291 path=DestroyString(path); 292 module_path=DestroyString(module_path); 293 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path); 294 return(FALSE); 295 } 296 (void) FormatLocaleString(variable,16*MagickPathExtent, 297 "%s;%s",module_path,path); 298 SetEnvironmentVariable("PATH",variable); 299 variable=DestroyString(variable); 300 } 301 } 302 path=DestroyString(path); 303 module_path=DestroyString(module_path); 304 } 305 wide_path=(wchar_t *) RelinquishMagickMemory(wide_path); 306 break; 307 } 308 case DLL_PROCESS_DETACH: 309 { 310 MagickCoreTerminus(); 311 break; 312 } 313 default: 314 break; 315 } 316 return(TRUE); 317} 318#endif 319 320/* 321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 322% % 323% % 324% % 325% E x i t % 326% % 327% % 328% % 329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 330% 331% Exit() calls TerminateProcess for Win95. 332% 333% The format of the exit method is: 334% 335% int Exit(int status) 336% 337% A description of each parameter follows: 338% 339% o status: an integer value representing the status of the terminating 340% process. 341% 342*/ 343MagickPrivate int Exit(int status) 344{ 345 if (IsWindows95()) 346 { 347 TerminateProcess(GetCurrentProcess(),(unsigned int) status); 348 return(0); 349 } 350 exit(status); 351} 352 353#if !defined(__MINGW32__) && !defined(__MINGW64__) 354/* 355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 356% % 357% % 358% % 359% g e t t i m e o f d a y % 360% % 361% % 362% % 363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 364% 365% The gettimeofday() method get the time of day. 366% 367% The format of the gettimeofday method is: 368% 369% int gettimeofday(struct timeval *time_value,struct timezone *time_zone) 370% 371% A description of each parameter follows: 372% 373% o time_value: the time value. 374% 375% o time_zone: the time zone. 376% 377*/ 378MagickPrivate int gettimeofday (struct timeval *time_value, 379 struct timezone *time_zone) 380{ 381#define EpochFiletime MagickLLConstant(116444736000000000) 382 383 static int 384 is_tz_set; 385 386 if (time_value != (struct timeval *) NULL) 387 { 388 FILETIME 389 file_time; 390 391 __int64 392 time; 393 394 LARGE_INTEGER 395 date_time; 396 397 GetSystemTimeAsFileTime(&file_time); 398 date_time.LowPart=file_time.dwLowDateTime; 399 date_time.HighPart=file_time.dwHighDateTime; 400 time=date_time.QuadPart; 401 time-=EpochFiletime; 402 time/=10; 403 time_value->tv_sec=(ssize_t) (time / 1000000); 404 time_value->tv_usec=(ssize_t) (time % 1000000); 405 } 406 if (time_zone != (struct timezone *) NULL) 407 { 408 if (is_tz_set == 0) 409 { 410 _tzset(); 411 is_tz_set++; 412 } 413 time_zone->tz_minuteswest=_timezone/60; 414 time_zone->tz_dsttime=_daylight; 415 } 416 return(0); 417} 418#endif 419 420/* 421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 422% % 423% % 424% % 425% I s W i n d o w s 9 5 % 426% % 427% % 428% % 429%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 430% 431% IsWindows95() returns true if the system is Windows 95. 432% 433% The format of the IsWindows95 method is: 434% 435% int IsWindows95() 436% 437*/ 438MagickPrivate int IsWindows95() 439{ 440 OSVERSIONINFO 441 version_info; 442 443 version_info.dwOSVersionInfoSize=sizeof(version_info); 444 if (GetVersionEx(&version_info) && 445 (version_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) 446 return(1); 447 return(0); 448} 449 450/* 451%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 452% % 453% % 454% % 455% N T A r g v T o U T F 8 % 456% % 457% % 458% % 459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 460% 461% NTArgvToUTF8() converts the wide command line arguments to UTF-8 to ensure 462% compatibility with Linux. 463% 464% The format of the NTArgvToUTF8 method is: 465% 466% char **NTArgvToUTF8(const int argc,wchar_t **argv) 467% 468% A description of each parameter follows: 469% 470% o argc: the number of command line arguments. 471% 472% o argv: the wide-character command line arguments. 473% 474*/ 475MagickPrivate char **NTArgvToUTF8(const int argc,wchar_t **argv) 476{ 477 char 478 **utf8; 479 480 ssize_t 481 i; 482 483 utf8=(char **) AcquireQuantumMemory(argc,sizeof(*utf8)); 484 if (utf8 == (char **) NULL) 485 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV"); 486 for (i=0; i < (ssize_t) argc; i++) 487 { 488 utf8[i]=create_utf8_string(argv[i]); 489 if (utf8[i] == (char *) NULL) 490 { 491 for (i--; i >= 0; i--) 492 utf8[i]=DestroyString(utf8[i]); 493 ThrowFatalException(ResourceLimitFatalError, 494 "UnableToConvertStringToARGV"); 495 } 496 } 497 return(utf8); 498} 499 500/* 501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 502% % 503% % 504% % 505% N T C l o s e D i r e c t o r y % 506% % 507% % 508% % 509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 510% 511% NTCloseDirectory() closes the named directory stream and frees the DIR 512% structure. 513% 514% The format of the NTCloseDirectory method is: 515% 516% int NTCloseDirectory(DIR *entry) 517% 518% A description of each parameter follows: 519% 520% o entry: Specifies a pointer to a DIR structure. 521% 522*/ 523MagickPrivate int NTCloseDirectory(DIR *entry) 524{ 525 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 526 assert(entry != (DIR *) NULL); 527 FindClose(entry->hSearch); 528 entry=(DIR *) RelinquishMagickMemory(entry); 529 return(0); 530} 531 532/* 533%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 534% % 535% % 536% % 537% N T C l o s e L i b r a r y % 538% % 539% % 540% % 541%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 542% 543% NTCloseLibrary() unloads the module associated with the passed handle. 544% 545% The format of the NTCloseLibrary method is: 546% 547% void NTCloseLibrary(void *handle) 548% 549% A description of each parameter follows: 550% 551% o handle: Specifies a handle to a previously loaded dynamic module. 552% 553*/ 554MagickPrivate int NTCloseLibrary(void *handle) 555{ 556 if (IsWindows95()) 557 return(FreeLibrary((HINSTANCE) handle)); 558 return(!(FreeLibrary((HINSTANCE) handle))); 559} 560 561/* 562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 563% % 564% % 565% % 566% N T C o n t r o l H a n d l e r % 567% % 568% % 569% % 570%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 571% 572% NTControlHandler() registers a control handler that is activated when, for 573% example, a ctrl-c is received. 574% 575% The format of the NTControlHandler method is: 576% 577% int NTControlHandler(void) 578% 579*/ 580 581static BOOL ControlHandler(DWORD type) 582{ 583 (void) type; 584 AsynchronousResourceComponentTerminus(); 585 return(FALSE); 586} 587 588MagickPrivate int NTControlHandler(void) 589{ 590 return(SetConsoleCtrlHandler((PHANDLER_ROUTINE) ControlHandler,TRUE)); 591} 592 593/* 594%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 595% % 596% % 597% % 598% N T E l a p s e d T i m e % 599% % 600% % 601% % 602%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 603% 604% NTElapsedTime() returns the elapsed time (in seconds) since the last call to 605% StartTimer(). 606% 607% The format of the ElapsedTime method is: 608% 609% double NTElapsedTime(void) 610% 611*/ 612MagickPrivate double NTElapsedTime(void) 613{ 614 union 615 { 616 FILETIME 617 filetime; 618 619 __int64 620 filetime64; 621 } elapsed_time; 622 623 SYSTEMTIME 624 system_time; 625 626 GetSystemTime(&system_time); 627 SystemTimeToFileTime(&system_time,&elapsed_time.filetime); 628 return((double) 1.0e-7*elapsed_time.filetime64); 629} 630 631/* 632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 633% % 634% % 635% % 636+ N T E r r o r H a n d l e r % 637% % 638% % 639% % 640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 641% 642% NTErrorHandler() displays an error reason and then terminates the program. 643% 644% The format of the NTErrorHandler method is: 645% 646% void NTErrorHandler(const ExceptionType severity,const char *reason, 647% const char *description) 648% 649% A description of each parameter follows: 650% 651% o severity: Specifies the numeric error category. 652% 653% o reason: Specifies the reason to display before terminating the 654% program. 655% 656% o description: Specifies any description to the reason. 657% 658*/ 659MagickPrivate void NTErrorHandler(const ExceptionType severity, 660 const char *reason,const char *description) 661{ 662 char 663 buffer[3*MagickPathExtent], 664 *message; 665 666 (void) severity; 667 if (reason == (char *) NULL) 668 { 669 MagickCoreTerminus(); 670 exit(0); 671 } 672 message=GetExceptionMessage(errno); 673 if ((description != (char *) NULL) && errno) 674 (void) FormatLocaleString(buffer,MagickPathExtent,"%s: %s (%s) [%s].\n", 675 GetClientName(),reason,description,message); 676 else 677 if (description != (char *) NULL) 678 (void) FormatLocaleString(buffer,MagickPathExtent,"%s: %s (%s).\n", 679 GetClientName(),reason,description); 680 else 681 if (errno != 0) 682 (void) FormatLocaleString(buffer,MagickPathExtent,"%s: %s [%s].\n", 683 GetClientName(),reason,message); 684 else 685 (void) FormatLocaleString(buffer,MagickPathExtent,"%s: %s.\n", 686 GetClientName(),reason); 687 message=DestroyString(message); 688 (void) MessageBox(NULL,buffer,"ImageMagick Exception",MB_OK | MB_TASKMODAL | 689 MB_SETFOREGROUND | MB_ICONEXCLAMATION); 690 MagickCoreTerminus(); 691 exit(0); 692} 693 694/* 695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 696% % 697% % 698% % 699% N T E x i t L i b r a r y % 700% % 701% % 702% % 703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 704% 705% NTExitLibrary() exits the dynamic module loading subsystem. 706% 707% The format of the NTExitLibrary method is: 708% 709% int NTExitLibrary(void) 710% 711*/ 712MagickPrivate int NTExitLibrary(void) 713{ 714 return(0); 715} 716 717/* 718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 719% % 720% % 721% % 722% N T G a t h e r R a n d o m D a t a % 723% % 724% % 725% % 726%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 727% 728% NTGatherRandomData() gathers random data and returns it. 729% 730% The format of the GatherRandomData method is: 731% 732% MagickBooleanType NTGatherRandomData(const size_t length, 733% unsigned char *random) 734% 735% A description of each parameter follows: 736% 737% length: the length of random data buffer 738% 739% random: the random data is returned here. 740% 741*/ 742MagickPrivate MagickBooleanType NTGatherRandomData(const size_t length, 743 unsigned char *random) 744{ 745#if defined(MAGICKCORE_CIPHER_SUPPORT) && defined(_MSC_VER) && (_MSC_VER > 1200) 746 HCRYPTPROV 747 handle; 748 749 int 750 status; 751 752 handle=(HCRYPTPROV) NULL; 753 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL, 754 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)); 755 if (status == 0) 756 status=CryptAcquireContext(&handle,NULL,MS_DEF_PROV,PROV_RSA_FULL, 757 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)); 758 if (status == 0) 759 return(MagickFalse); 760 status=CryptGenRandom(handle,(DWORD) length,random); 761 if (status == 0) 762 { 763 status=CryptReleaseContext(handle,0); 764 return(MagickFalse); 765 } 766 status=CryptReleaseContext(handle,0); 767 if (status == 0) 768 return(MagickFalse); 769#else 770 (void) random; 771 (void) length; 772#endif 773 return(MagickTrue); 774} 775 776/* 777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 778% % 779% % 780% % 781% N T G e t E x e c u t i o n P a t h % 782% % 783% % 784% % 785%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 786% 787% NTGetExecutionPath() returns the execution path of a program. 788% 789% The format of the GetExecutionPath method is: 790% 791% MagickBooleanType NTGetExecutionPath(char *path,const size_t extent) 792% 793% A description of each parameter follows: 794% 795% o path: the pathname of the executable that started the process. 796% 797% o extent: the maximum extent of the path. 798% 799*/ 800MagickPrivate MagickBooleanType NTGetExecutionPath(char *path, 801 const size_t extent) 802{ 803 wchar_t 804 wide_path[MagickPathExtent]; 805 806 (void) GetModuleFileNameW((HMODULE) NULL,wide_path,(DWORD) extent); 807 (void) WideCharToMultiByte(CP_UTF8,0,wide_path,-1,path,(int) extent,NULL, 808 NULL); 809 return(MagickTrue); 810} 811 812/* 813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 814% % 815% % 816% % 817% N T G e t L a s t E r r o r % 818% % 819% % 820% % 821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 822% 823% NTGetLastError() returns the last error that occurred. 824% 825% The format of the NTGetLastError method is: 826% 827% char *NTGetLastError(void) 828% 829*/ 830char *NTGetLastError(void) 831{ 832 char 833 *reason; 834 835 int 836 status; 837 838 LPVOID 839 buffer; 840 841 status=FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 842 FORMAT_MESSAGE_FROM_SYSTEM,NULL,GetLastError(), 843 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR) &buffer,0,NULL); 844 if (!status) 845 reason=AcquireString("An unknown error occurred"); 846 else 847 { 848 reason=AcquireString((const char *) buffer); 849 LocalFree(buffer); 850 } 851 return(reason); 852} 853 854/* 855%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 856% % 857% % 858% % 859% N T G e t L i b r a r y E r r o r % 860% % 861% % 862% % 863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 864% 865% Lt_dlerror() returns a pointer to a string describing the last error 866% associated with a lt_dl method. Note that this function is not thread 867% safe so it should only be used under the protection of a lock. 868% 869% The format of the NTGetLibraryError method is: 870% 871% const char *NTGetLibraryError(void) 872% 873*/ 874MagickPrivate const char *NTGetLibraryError(void) 875{ 876 static char 877 last_error[MagickPathExtent]; 878 879 char 880 *error; 881 882 *last_error='\0'; 883 error=NTGetLastError(); 884 if (error) 885 (void) CopyMagickString(last_error,error,MagickPathExtent); 886 error=DestroyString(error); 887 return(last_error); 888} 889 890/* 891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 892% % 893% % 894% % 895% N T G e t L i b r a r y S y m b o l % 896% % 897% % 898% % 899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 900% 901% NTGetLibrarySymbol() retrieve the procedure address of the method 902% specified by the passed character string. 903% 904% The format of the NTGetLibrarySymbol method is: 905% 906% void *NTGetLibrarySymbol(void *handle,const char *name) 907% 908% A description of each parameter follows: 909% 910% o handle: Specifies a handle to the previously loaded dynamic module. 911% 912% o name: Specifies the procedure entry point to be returned. 913% 914*/ 915void *NTGetLibrarySymbol(void *handle,const char *name) 916{ 917 LPFNDLLFUNC1 918 lpfnDllFunc1; 919 920 lpfnDllFunc1=(LPFNDLLFUNC1) GetProcAddress((HINSTANCE) handle,name); 921 if (!lpfnDllFunc1) 922 return((void *) NULL); 923 return((void *) lpfnDllFunc1); 924} 925 926/* 927%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 928% % 929% % 930% % 931% N T G e t M o d u l e P a t h % 932% % 933% % 934% % 935%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 936% 937% NTGetModulePath() returns the path of the specified module. 938% 939% The format of the GetModulePath method is: 940% 941% MagickBooleanType NTGetModulePath(const char *module,char *path) 942% 943% A description of each parameter follows: 944% 945% modith: the module name. 946% 947% path: the module path is returned here. 948% 949*/ 950MagickPrivate MagickBooleanType NTGetModulePath(const char *module,char *path) 951{ 952 char 953 module_path[MagickPathExtent]; 954 955 HMODULE 956 handle; 957 958 ssize_t 959 length; 960 961 *path='\0'; 962 handle=GetModuleHandle(module); 963 if (handle == (HMODULE) NULL) 964 return(MagickFalse); 965 length=GetModuleFileName(handle,module_path,MagickPathExtent); 966 if (length != 0) 967 GetPathComponent(module_path,HeadPath,path); 968 return(MagickTrue); 969} 970 971/* 972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 973% % 974% % 975% % 976% N T G h o s t s c r i p t D L L % 977% % 978% % 979% % 980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 981% 982% NTGhostscriptDLL() returns the path to the most recent Ghostscript version 983% DLL. The method returns TRUE on success otherwise FALSE. 984% 985% The format of the NTGhostscriptDLL method is: 986% 987% int NTGhostscriptDLL(char *path,int length) 988% 989% A description of each parameter follows: 990% 991% o path: return the Ghostscript DLL path here. 992% 993% o length: the buffer length. 994% 995*/ 996 997static int NTGetRegistryValue(HKEY root,const char *key,DWORD flags, 998 const char *name,char *value,int *length) 999{ 1000 BYTE 1001 byte, 1002 *p; 1003 1004 DWORD 1005 extent, 1006 type; 1007 1008 HKEY 1009 hkey; 1010 1011 LONG 1012 status; 1013 1014 /* 1015 Get a registry value: key = root\\key, named value = name. 1016 */ 1017 if (RegOpenKeyExA(root,key,0,KEY_READ | flags,&hkey) != ERROR_SUCCESS) 1018 return(1); /* no match */ 1019 p=(BYTE *) value; 1020 type=REG_SZ; 1021 extent=(*length); 1022 if (p == (BYTE *) NULL) 1023 p=(&byte); /* ERROR_MORE_DATA only if value is NULL */ 1024 status=RegQueryValueExA(hkey,(char *) name,0,&type,p,&extent); 1025 RegCloseKey(hkey); 1026 if (status == ERROR_SUCCESS) 1027 { 1028 *length=extent; 1029 return(0); /* return the match */ 1030 } 1031 if (status == ERROR_MORE_DATA) 1032 { 1033 *length=extent; 1034 return(-1); /* buffer not large enough */ 1035 } 1036 return(1); /* not found */ 1037} 1038 1039static int NTLocateGhostscript(DWORD flags,int *root_index, 1040 const char **product_family,int *major_version,int *minor_version) 1041{ 1042 int 1043 i; 1044 1045 MagickBooleanType 1046 status; 1047 1048 static const char 1049 *products[4] = 1050 { 1051 "GPL Ghostscript", 1052 "GNU Ghostscript", 1053 "AFPL Ghostscript", 1054 "Aladdin Ghostscript" 1055 }; 1056 1057 /* 1058 Find the most recent version of Ghostscript. 1059 */ 1060 status=MagickFalse; 1061 *root_index=0; 1062 *product_family=NULL; 1063 *major_version=5; 1064 *minor_version=49; /* min version of Ghostscript is 5.50 */ 1065 for (i=0; i < (ssize_t) (sizeof(products)/sizeof(products[0])); i++) 1066 { 1067 char 1068 key[MagickPathExtent]; 1069 1070 HKEY 1071 hkey; 1072 1073 int 1074 j; 1075 1076 REGSAM 1077 mode; 1078 1079 (void) FormatLocaleString(key,MagickPathExtent,"SOFTWARE\\%s",products[i]); 1080 for (j=0; j < (ssize_t) (sizeof(registry_roots)/sizeof(registry_roots[0])); 1081 j++) 1082 { 1083 mode=KEY_READ | flags; 1084 if (RegOpenKeyExA(registry_roots[j].hkey,key,0,mode,&hkey) == 1085 ERROR_SUCCESS) 1086 { 1087 DWORD 1088 extent; 1089 1090 int 1091 k; 1092 1093 /* 1094 Now enumerate the keys. 1095 */ 1096 extent=sizeof(key)/sizeof(char); 1097 for (k=0; RegEnumKeyA(hkey,k,key,extent) == ERROR_SUCCESS; k++) 1098 { 1099 int 1100 major, 1101 minor; 1102 1103 major=0; 1104 minor=0; 1105 if (sscanf(key,"%d.%d",&major,&minor) != 2) 1106 continue; 1107 if ((major > *major_version) || ((major == *major_version) && 1108 (minor > *minor_version))) 1109 { 1110 *root_index=j; 1111 *product_family=products[i]; 1112 *major_version=major; 1113 *minor_version=minor; 1114 status=MagickTrue; 1115 } 1116 } 1117 (void) RegCloseKey(hkey); 1118 } 1119 } 1120 } 1121 if (status == MagickFalse) 1122 { 1123 *major_version=0; 1124 *minor_version=0; 1125 } 1126 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) " 1127 "version %d.%02d",*product_family,*major_version,*minor_version); 1128 return(status); 1129} 1130 1131static int NTGhostscriptGetString(const char *name,BOOL *is_64_bit, 1132 char *value,const size_t length) 1133{ 1134 char 1135 buffer[MagickPathExtent], 1136 *directory; 1137 1138 int 1139 extent; 1140 1141 static const char 1142 *product_family=(const char *) NULL; 1143 1144 static BOOL 1145 is_64_bit_version=FALSE; 1146 1147 static int 1148 flags=0, 1149 major_version=0, 1150 minor_version=0, 1151 root_index=0; 1152 1153 /* 1154 Get a string from the installed Ghostscript. 1155 */ 1156 *value='\0'; 1157 directory=(char *) NULL; 1158 if (LocaleCompare(name, "GS_DLL") == 0) 1159 { 1160 directory=GetEnvironmentValue("MAGICK_GHOSTSCRIPT_PATH"); 1161 if (directory != (char *) NULL) 1162 { 1163 (void) FormatLocaleString(buffer,MagickPathExtent,"%s%sgsdll32.dll", 1164 directory,DirectorySeparator); 1165 if (IsPathAccessible(buffer) != MagickFalse) 1166 { 1167 directory=DestroyString(directory); 1168 (void) CopyMagickString(value,buffer,length); 1169 if (is_64_bit != NULL) 1170 *is_64_bit=FALSE; 1171 return(TRUE); 1172 } 1173 (void) FormatLocaleString(buffer,MagickPathExtent,"%s%sgsdll64.dll", 1174 directory,DirectorySeparator); 1175 if (IsPathAccessible(buffer) != MagickFalse) 1176 { 1177 directory=DestroyString(directory); 1178 (void) CopyMagickString(value,buffer,length); 1179 if (is_64_bit != NULL) 1180 *is_64_bit=TRUE; 1181 return(TRUE); 1182 } 1183 return(FALSE); 1184 } 1185 } 1186 if (product_family == NULL) 1187 { 1188 flags=0; 1189#if defined(KEY_WOW64_32KEY) 1190#if defined(_WIN64) 1191 flags=KEY_WOW64_64KEY; 1192#else 1193 flags=KEY_WOW64_32KEY; 1194#endif 1195 (void) NTLocateGhostscript(flags,&root_index,&product_family, 1196 &major_version,&minor_version); 1197 if (product_family == NULL) 1198#if defined(_WIN64) 1199 flags=KEY_WOW64_32KEY; 1200 else 1201 is_64_bit_version=TRUE; 1202#else 1203 flags=KEY_WOW64_64KEY; 1204#endif 1205#endif 1206 } 1207 if (product_family == NULL) 1208 { 1209 (void) NTLocateGhostscript(flags,&root_index,&product_family, 1210 &major_version,&minor_version); 1211#if !defined(_WIN64) 1212 is_64_bit_version=TRUE; 1213#endif 1214 } 1215 if (product_family == NULL) 1216 return(FALSE); 1217 if (is_64_bit != NULL) 1218 *is_64_bit=is_64_bit_version; 1219 (void) FormatLocaleString(buffer,MagickPathExtent,"SOFTWARE\\%s\\%d.%02d", 1220 product_family,major_version,minor_version); 1221 extent=(int) length; 1222 if (NTGetRegistryValue(registry_roots[root_index].hkey,buffer,flags,name, 1223 value,&extent) == 0) 1224 { 1225 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 1226 "registry: \"%s\\%s\\%s\"=\"%s\"",registry_roots[root_index].name, 1227 buffer,name,value); 1228 return(TRUE); 1229 } 1230 return(FALSE); 1231} 1232 1233MagickPrivate int NTGhostscriptDLL(char *path,int length) 1234{ 1235 static char 1236 dll[MagickPathExtent] = { "" }; 1237 1238 static BOOL 1239 is_64_bit_version; 1240 1241 *path='\0'; 1242 if ((*dll == '\0') && 1243 (NTGhostscriptGetString("GS_DLL",&is_64_bit_version,dll,sizeof(dll)) == FALSE)) 1244 return(FALSE); 1245 1246#if defined(_WIN64) 1247 if (!is_64_bit_version) 1248 return(FALSE); 1249#else 1250 if (is_64_bit_version) 1251 return(FALSE); 1252#endif 1253 (void) CopyMagickString(path,dll,length); 1254 return(TRUE); 1255} 1256 1257/* 1258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1259% % 1260% % 1261% % 1262% N T G h o s t s c r i p t D L L V e c t o r s % 1263% % 1264% % 1265% % 1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1267% 1268% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes 1269% function vectors to invoke Ghostscript DLL functions. A null pointer is 1270% returned if there is an error when loading the DLL or retrieving the 1271% function vectors. 1272% 1273% The format of the NTGhostscriptDLLVectors method is: 1274% 1275% const GhostInfo *NTGhostscriptDLLVectors(void) 1276% 1277*/ 1278MagickPrivate const GhostInfo *NTGhostscriptDLLVectors(void) 1279{ 1280 if (NTGhostscriptLoadDLL() == FALSE) 1281 return((GhostInfo *) NULL); 1282 return(&ghost_info); 1283} 1284 1285/* 1286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1287% % 1288% % 1289% % 1290% N T G h o s t s c r i p t E X E % 1291% % 1292% % 1293% % 1294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1295% 1296% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable. 1297% The method returns FALSE if a full path value is not obtained and returns 1298% a default path of gswin32c.exe. 1299% 1300% The format of the NTGhostscriptEXE method is: 1301% 1302% int NTGhostscriptEXE(char *path,int length) 1303% 1304% A description of each parameter follows: 1305% 1306% o path: return the Ghostscript executable path here. 1307% 1308% o length: length of buffer. 1309% 1310*/ 1311MagickPrivate int NTGhostscriptEXE(char *path,int length) 1312{ 1313 register char 1314 *p; 1315 1316 static char 1317 program[MagickPathExtent] = { "" }; 1318 1319 static BOOL 1320 is_64_bit_version = FALSE; 1321 1322 (void) CopyMagickString(path,"gswin32c.exe",length); 1323 if ((*program == '\0') && 1324 (NTGhostscriptGetString("GS_DLL",&is_64_bit_version,program,sizeof(program)) == FALSE)) 1325 return(FALSE); 1326 p=strrchr(program,'\\'); 1327 if (p != (char *) NULL) 1328 { 1329 p++; 1330 *p='\0'; 1331 (void) ConcatenateMagickString(program,is_64_bit_version ? 1332 "gswin64c.exe" : "gswin32c.exe",sizeof(program)); 1333 } 1334 (void) CopyMagickString(path,program,length); 1335 return(TRUE); 1336} 1337 1338/* 1339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1340% % 1341% % 1342% % 1343% N T G h o s t s c r i p t F o n t s % 1344% % 1345% % 1346% % 1347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1348% 1349% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method 1350% returns FALSE if it cannot determine the font path. 1351% 1352% The format of the NTGhostscriptFonts method is: 1353% 1354% int NTGhostscriptFonts(char *path, int length) 1355% 1356% A description of each parameter follows: 1357% 1358% o path: return the font path here. 1359% 1360% o length: length of the path buffer. 1361% 1362*/ 1363MagickPrivate int NTGhostscriptFonts(char *path,int length) 1364{ 1365 char 1366 buffer[MagickPathExtent], 1367 *directory, 1368 filename[MagickPathExtent]; 1369 1370 register char 1371 *p, 1372 *q; 1373 1374 *path='\0'; 1375 directory=GetEnvironmentValue("MAGICK_GHOSTSCRIPT_FONT_PATH"); 1376 if (directory != (char *) NULL) 1377 { 1378 (void) CopyMagickString(buffer,directory,MagickPathExtent); 1379 directory=DestroyString(directory); 1380 } 1381 else 1382 { 1383 if (NTGhostscriptGetString("GS_LIB",NULL,buffer,MagickPathExtent) == FALSE) 1384 return(FALSE); 1385 } 1386 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator)) 1387 { 1388 (void) CopyMagickString(path,p+1,length+1); 1389 q=strchr(path,DirectoryListSeparator); 1390 if (q != (char *) NULL) 1391 *q='\0'; 1392 (void) FormatLocaleString(filename,MagickPathExtent,"%s%sfonts.dir",path, 1393 DirectorySeparator); 1394 if (IsPathAccessible(filename) != MagickFalse) 1395 return(TRUE); 1396 } 1397 *path='\0'; 1398 return(FALSE); 1399} 1400 1401/* 1402%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1403% % 1404% % 1405% % 1406% N T G h o s t s c r i p t L o a d D L L % 1407% % 1408% % 1409% % 1410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1411% 1412% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns 1413% TRUE if it succeeds. 1414% 1415% The format of the NTGhostscriptLoadDLL method is: 1416% 1417% int NTGhostscriptLoadDLL(void) 1418% 1419*/ 1420static inline int NTGhostscriptHasValidHandle() 1421{ 1422 if ((nt_ghost_info.delete_instance == NULL) || (ghost_info.exit == NULL) || 1423 (ghost_info.init_with_args == NULL) || 1424 (nt_ghost_info.new_instance == NULL) || 1425 (ghost_info.run_string == NULL) || (ghost_info.set_stdio == NULL) || 1426 (ghost_info.revision == NULL)) 1427 { 1428 return(FALSE); 1429 } 1430 return(TRUE); 1431} 1432 1433MagickPrivate int NTGhostscriptLoadDLL(void) 1434{ 1435 char 1436 path[MagickPathExtent]; 1437 1438 if (ghost_semaphore == (SemaphoreInfo *) NULL) 1439 ActivateSemaphoreInfo(&ghost_semaphore); 1440 LockSemaphoreInfo(ghost_semaphore); 1441 if (ghost_handle != (void *) NULL) 1442 { 1443 UnlockSemaphoreInfo(ghost_semaphore); 1444 return(NTGhostscriptHasValidHandle()); 1445 } 1446 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE) 1447 { 1448 UnlockSemaphoreInfo(ghost_semaphore); 1449 return(FALSE); 1450 } 1451 ghost_handle=lt_dlopen(path); 1452 if (ghost_handle == (void *) NULL) 1453 { 1454 UnlockSemaphoreInfo(ghost_semaphore); 1455 return(FALSE); 1456 } 1457 (void) ResetMagickMemory((void *) &nt_ghost_info,0,sizeof(NTGhostInfo)); 1458 nt_ghost_info.delete_instance=(void (MagickDLLCall *)(gs_main_instance *)) ( 1459 lt_dlsym(ghost_handle,"gsapi_delete_instance")); 1460 nt_ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **, 1461 void *)) (lt_dlsym(ghost_handle,"gsapi_new_instance")); 1462 nt_ghost_info.has_instance=MagickFalse; 1463 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo)); 1464 ghost_info.delete_instance=NTGhostscriptDeleteInstance; 1465 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*)) 1466 lt_dlsym(ghost_handle,"gsapi_exit"); 1467 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int, 1468 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args")); 1469 ghost_info.new_instance=NTGhostscriptNewInstance; 1470 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *, 1471 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string")); 1472 ghost_info.set_stdio=(int (MagickDLLCall *)(gs_main_instance *,int( 1473 MagickDLLCall *)(void *,char *,int),int(MagickDLLCall *)(void *, 1474 const char *,int),int(MagickDLLCall *)(void *,const char *,int))) 1475 (lt_dlsym(ghost_handle,"gsapi_set_stdio")); 1476 ghost_info.revision=(int (MagickDLLCall *)(gsapi_revision_t *,int)) ( 1477 lt_dlsym(ghost_handle,"gsapi_revision")); 1478 UnlockSemaphoreInfo(ghost_semaphore); 1479 return(NTGhostscriptHasValidHandle()); 1480} 1481 1482/* 1483%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1484% % 1485% % 1486% % 1487% N T G h o s t s c r i p t U n L o a d D L L % 1488% % 1489% % 1490% % 1491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1492% 1493% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if 1494% it succeeds. 1495% 1496% The format of the NTGhostscriptUnLoadDLL method is: 1497% 1498% int NTGhostscriptUnLoadDLL(void) 1499% 1500*/ 1501MagickPrivate void NTGhostscriptUnLoadDLL(void) 1502{ 1503 if (ghost_semaphore == (SemaphoreInfo *) NULL) 1504 ActivateSemaphoreInfo(&ghost_semaphore); 1505 LockSemaphoreInfo(ghost_semaphore); 1506 if (ghost_handle != (void *) NULL) 1507 { 1508 (void) lt_dlclose(ghost_handle); 1509 ghost_handle=(void *) NULL; 1510 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo)); 1511 } 1512 UnlockSemaphoreInfo(ghost_semaphore); 1513 RelinquishSemaphoreInfo(&ghost_semaphore); 1514} 1515 1516/* 1517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1518% % 1519% % 1520% % 1521% N T I n i t i a l i z e L i b r a r y % 1522% % 1523% % 1524% % 1525%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1526% 1527% NTInitializeLibrary() initializes the dynamic module loading subsystem. 1528% 1529% The format of the NTInitializeLibrary method is: 1530% 1531% int NTInitializeLibrary(void) 1532% 1533*/ 1534MagickPrivate int NTInitializeLibrary(void) 1535{ 1536 return(0); 1537} 1538 1539/* 1540%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1541% % 1542% % 1543% % 1544% N T I n i t i a l i z e W i n s o c k % 1545% % 1546% % 1547% % 1548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1549% 1550% NTInitializeWinsock() initializes Winsock. 1551% 1552% The format of the NTInitializeWinsock method is: 1553% 1554% void NTInitializeWinsock(void) 1555% 1556*/ 1557MagickPrivate void NTInitializeWinsock(MagickBooleanType use_lock) 1558{ 1559 if (use_lock) 1560 { 1561 if (winsock_semaphore == (SemaphoreInfo *) NULL) 1562 ActivateSemaphoreInfo(&winsock_semaphore); 1563 LockSemaphoreInfo(winsock_semaphore); 1564 } 1565 if (wsaData == (WSADATA *) NULL) 1566 { 1567 wsaData=(WSADATA *) AcquireMagickMemory(sizeof(WSADATA)); 1568 if (WSAStartup(MAKEWORD(2,2),wsaData) != 0) 1569 ThrowFatalException(CacheFatalError,"WSAStartup failed"); 1570 } 1571 if (use_lock) 1572 UnlockSemaphoreInfo(winsock_semaphore); 1573} 1574 1575/* 1576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1577% % 1578% % 1579% % 1580+ N T M a p M e m o r y % 1581% % 1582% % 1583% % 1584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1585% 1586% Mmap() emulates the Unix method of the same name. 1587% 1588% The format of the NTMapMemory method is: 1589% 1590% MagickPrivate void *NTMapMemory(char *address,size_t length,int protection, 1591% int access,int file,MagickOffsetType offset) 1592% 1593*/ 1594MagickPrivate void *NTMapMemory(char *address,size_t length,int protection, 1595 int flags,int file,MagickOffsetType offset) 1596{ 1597 DWORD 1598 access_mode, 1599 high_length, 1600 high_offset, 1601 low_length, 1602 low_offset, 1603 protection_mode; 1604 1605 HANDLE 1606 file_handle, 1607 map_handle; 1608 1609 void 1610 *map; 1611 1612 (void) address; 1613 access_mode=0; 1614 file_handle=INVALID_HANDLE_VALUE; 1615 low_length=(DWORD) (length & 0xFFFFFFFFUL); 1616 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL); 1617 map_handle=INVALID_HANDLE_VALUE; 1618 map=(void *) NULL; 1619 low_offset=(DWORD) (offset & 0xFFFFFFFFUL); 1620 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL); 1621 protection_mode=0; 1622 if (protection & PROT_WRITE) 1623 { 1624 access_mode=FILE_MAP_WRITE; 1625 if (!(flags & MAP_PRIVATE)) 1626 protection_mode=PAGE_READWRITE; 1627 else 1628 { 1629 access_mode=FILE_MAP_COPY; 1630 protection_mode=PAGE_WRITECOPY; 1631 } 1632 } 1633 else 1634 if (protection & PROT_READ) 1635 { 1636 access_mode=FILE_MAP_READ; 1637 protection_mode=PAGE_READONLY; 1638 } 1639 if ((file == -1) && (flags & MAP_ANONYMOUS)) 1640 file_handle=INVALID_HANDLE_VALUE; 1641 else 1642 file_handle=(HANDLE) _get_osfhandle(file); 1643 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length, 1644 low_length,0); 1645 if (map_handle) 1646 { 1647 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset, 1648 length); 1649 CloseHandle(map_handle); 1650 } 1651 if (map == (void *) NULL) 1652 return((void *) ((char *) MAP_FAILED)); 1653 return((void *) ((char *) map)); 1654} 1655 1656/* 1657%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1658% % 1659% % 1660% % 1661% N T O p e n D i r e c t o r y % 1662% % 1663% % 1664% % 1665%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1666% 1667% NTOpenDirectory() opens the directory named by filename and associates a 1668% directory stream with it. 1669% 1670% The format of the NTOpenDirectory method is: 1671% 1672% DIR *NTOpenDirectory(const char *path) 1673% 1674% A description of each parameter follows: 1675% 1676% o entry: Specifies a pointer to a DIR structure. 1677% 1678*/ 1679MagickPrivate DIR *NTOpenDirectory(const char *path) 1680{ 1681 DIR 1682 *entry; 1683 1684 size_t 1685 length; 1686 1687 wchar_t 1688 file_specification[MagickPathExtent]; 1689 1690 assert(path != (const char *) NULL); 1691 length=MultiByteToWideChar(CP_UTF8,0,path,-1,file_specification, 1692 MagickPathExtent); 1693 if (length == 0) 1694 return((DIR *) NULL); 1695 if(wcsncat(file_specification,(const wchar_t*) DirectorySeparator, 1696 MagickPathExtent-wcslen(file_specification)-1) == (wchar_t*) NULL) 1697 return((DIR *) NULL); 1698 entry=(DIR *) AcquireMagickMemory(sizeof(DIR)); 1699 if (entry != (DIR *) NULL) 1700 { 1701 entry->firsttime=TRUE; 1702 entry->hSearch=FindFirstFileW(file_specification,&entry->Win32FindData); 1703 } 1704 if (entry->hSearch == INVALID_HANDLE_VALUE) 1705 { 1706 if(wcsncat(file_specification,L"*.*", 1707 MagickPathExtent-wcslen(file_specification)-1) == (wchar_t*) NULL) 1708 { 1709 entry=(DIR *) RelinquishMagickMemory(entry); 1710 return((DIR *) NULL); 1711 } 1712 entry->hSearch=FindFirstFileW(file_specification,&entry->Win32FindData); 1713 if (entry->hSearch == INVALID_HANDLE_VALUE) 1714 { 1715 entry=(DIR *) RelinquishMagickMemory(entry); 1716 return((DIR *) NULL); 1717 } 1718 } 1719 return(entry); 1720} 1721 1722/* 1723%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1724% % 1725% % 1726% % 1727% N T O p e n L i b r a r y % 1728% % 1729% % 1730% % 1731%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1732% 1733% NTOpenLibrary() loads a dynamic module into memory and returns a handle that 1734% can be used to access the various procedures in the module. 1735% 1736% The format of the NTOpenLibrary method is: 1737% 1738% void *NTOpenLibrary(const char *filename) 1739% 1740% A description of each parameter follows: 1741% 1742% o path: Specifies a pointer to string representing dynamic module that 1743% is to be loaded. 1744% 1745*/ 1746 1747static inline const char *GetSearchPath(void) 1748{ 1749#if defined(MAGICKCORE_LTDL_DELEGATE) 1750 return(lt_dlgetsearchpath()); 1751#else 1752 return(lt_slsearchpath); 1753#endif 1754} 1755 1756static UINT ChangeErrorMode(void) 1757{ 1758 typedef UINT 1759 (CALLBACK *GETERRORMODE)(void); 1760 1761 GETERRORMODE 1762 getErrorMode; 1763 1764 HMODULE 1765 handle; 1766 1767 UINT 1768 mode; 1769 1770 mode=SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX; 1771 1772 handle=GetModuleHandle("kernel32.dll"); 1773 if (handle == (HMODULE) NULL) 1774 return SetErrorMode(mode); 1775 1776 getErrorMode=(GETERRORMODE) NTGetLibrarySymbol(handle,"GetErrorMode"); 1777 if (getErrorMode != (GETERRORMODE) NULL) 1778 mode=getErrorMode() | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX; 1779 1780 return SetErrorMode(mode); 1781} 1782 1783static inline void *NTLoadLibrary(const char *filename) 1784{ 1785 int 1786 length; 1787 1788 wchar_t 1789 path[MagickPathExtent]; 1790 1791 length=MultiByteToWideChar(CP_UTF8,0,filename,-1,path,MagickPathExtent); 1792 if (length == 0) 1793 return((void *) NULL); 1794 return (void *) LoadLibraryExW(path,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); 1795} 1796 1797MagickPrivate void *NTOpenLibrary(const char *filename) 1798{ 1799 char 1800 path[MagickPathExtent]; 1801 1802 register const char 1803 *p, 1804 *q; 1805 1806 UINT 1807 mode; 1808 1809 void 1810 *handle; 1811 1812 mode=ChangeErrorMode(); 1813 handle=NTLoadLibrary(filename); 1814 if (handle == (void *) NULL) 1815 { 1816 p=GetSearchPath(); 1817 while (p != (const char*) NULL) 1818 { 1819 q=strchr(p,DirectoryListSeparator); 1820 if (q != (const char*) NULL) 1821 (void) CopyMagickString(path,p,q-p+1); 1822 else 1823 (void) CopyMagickString(path,p,MagickPathExtent); 1824 (void) ConcatenateMagickString(path,DirectorySeparator,MagickPathExtent); 1825 (void) ConcatenateMagickString(path,filename,MagickPathExtent); 1826 handle=NTLoadLibrary(path); 1827 if (handle != (void *) NULL || q == (const char*) NULL) 1828 break; 1829 p=q+1; 1830 } 1831 } 1832 SetErrorMode(mode); 1833 return(handle); 1834} 1835 1836/* 1837%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1838% % 1839% % 1840% % 1841% N T R e a d D i r e c t o r y % 1842% % 1843% % 1844% % 1845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1846% 1847% NTReadDirectory() returns a pointer to a structure representing the 1848% directory entry at the current position in the directory stream to which 1849% entry refers. 1850% 1851% The format of the NTReadDirectory 1852% 1853% NTReadDirectory(entry) 1854% 1855% A description of each parameter follows: 1856% 1857% o entry: Specifies a pointer to a DIR structure. 1858% 1859*/ 1860MagickPrivate struct dirent *NTReadDirectory(DIR *entry) 1861{ 1862 int 1863 status; 1864 1865 size_t 1866 length; 1867 1868 if (entry == (DIR *) NULL) 1869 return((struct dirent *) NULL); 1870 if (!entry->firsttime) 1871 { 1872 status=FindNextFileW(entry->hSearch,&entry->Win32FindData); 1873 if (status == 0) 1874 return((struct dirent *) NULL); 1875 } 1876 length=WideCharToMultiByte(CP_UTF8,0,entry->Win32FindData.cFileName,-1, 1877 entry->file_info.d_name,sizeof(entry->file_info.d_name),NULL,NULL); 1878 if (length == 0) 1879 return((struct dirent *) NULL); 1880 entry->firsttime=FALSE; 1881 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name); 1882 return(&entry->file_info); 1883} 1884 1885/* 1886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1887% % 1888% % 1889% % 1890% N T R e g i s t r y K e y L o o k u p % 1891% % 1892% % 1893% % 1894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1895% 1896% NTRegistryKeyLookup() returns ImageMagick installation path settings 1897% stored in the Windows Registry. Path settings are specific to the 1898% installed ImageMagick version so that multiple Image Magick installations 1899% may coexist. 1900% 1901% Values are stored in the registry under a base path path similar to 1902% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\6.7.4\Q:16" or 1903% "HKEY_CURRENT_USER/SOFTWARE\ImageMagick\6.7.4\Q:16". The provided subkey 1904% is appended to this base path to form the full key. 1905% 1906% The format of the NTRegistryKeyLookup method is: 1907% 1908% unsigned char *NTRegistryKeyLookup(const char *subkey) 1909% 1910% A description of each parameter follows: 1911% 1912% o subkey: Specifies a string that identifies the registry object. 1913% Currently supported sub-keys include: "BinPath", "ConfigurePath", 1914% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath". 1915% 1916*/ 1917MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey) 1918{ 1919 char 1920 package_key[MagickPathExtent]; 1921 1922 DWORD 1923 size, 1924 type; 1925 1926 HKEY 1927 registry_key; 1928 1929 LONG 1930 status; 1931 1932 unsigned char 1933 *value; 1934 1935 /* 1936 Look-up base key. 1937 */ 1938 (void) FormatLocaleString(package_key,MagickPathExtent,"SOFTWARE\\%s\\%s\\Q:%d", 1939 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH); 1940 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key); 1941 registry_key=(HKEY) INVALID_HANDLE_VALUE; 1942 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,®istry_key); 1943 if (status != ERROR_SUCCESS) 1944 status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ, 1945 ®istry_key); 1946 if (status != ERROR_SUCCESS) 1947 { 1948 registry_key=(HKEY) INVALID_HANDLE_VALUE; 1949 return((unsigned char *) NULL); 1950 } 1951 /* 1952 Look-up sub key. 1953 */ 1954 size=32; 1955 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value)); 1956 if (value == (unsigned char *) NULL) 1957 { 1958 RegCloseKey(registry_key); 1959 return((unsigned char *) NULL); 1960 } 1961 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey); 1962 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size); 1963 if ((status == ERROR_MORE_DATA) && (type == REG_SZ)) 1964 { 1965 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value)); 1966 if (value == (BYTE *) NULL) 1967 { 1968 RegCloseKey(registry_key); 1969 return((unsigned char *) NULL); 1970 } 1971 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size); 1972 } 1973 RegCloseKey(registry_key); 1974 if ((type != REG_SZ) || (status != ERROR_SUCCESS)) 1975 value=(unsigned char *) RelinquishMagickMemory(value); 1976 return((unsigned char *) value); 1977} 1978 1979/* 1980%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1981% % 1982% % 1983% % 1984% N T R e p o r t E v e n t % 1985% % 1986% % 1987% % 1988%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1989% 1990% NTReportEvent() reports an event. 1991% 1992% The format of the NTReportEvent method is: 1993% 1994% MagickBooleanType NTReportEvent(const char *event, 1995% const MagickBooleanType error) 1996% 1997% A description of each parameter follows: 1998% 1999% o event: the event. 2000% 2001% o error: MagickTrue the event is an error. 2002% 2003*/ 2004MagickPrivate MagickBooleanType NTReportEvent(const char *event, 2005 const MagickBooleanType error) 2006{ 2007 const char 2008 *events[1]; 2009 2010 HANDLE 2011 handle; 2012 2013 WORD 2014 type; 2015 2016 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME); 2017 if (handle == NULL) 2018 return(MagickFalse); 2019 events[0]=event; 2020 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE; 2021 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL); 2022 DeregisterEventSource(handle); 2023 return(MagickTrue); 2024} 2025 2026/* 2027%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2028% % 2029% % 2030% % 2031% N T R e s o u r c e T o B l o b % 2032% % 2033% % 2034% % 2035%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2036% 2037% NTResourceToBlob() returns a blob containing the contents of the resource 2038% in the current executable specified by the id parameter. This currently 2039% used to retrieve MGK files tha have been embedded into the various command 2040% line utilities. 2041% 2042% The format of the NTResourceToBlob method is: 2043% 2044% unsigned char *NTResourceToBlob(const char *id) 2045% 2046% A description of each parameter follows: 2047% 2048% o id: Specifies a string that identifies the resource. 2049% 2050*/ 2051MagickPrivate unsigned char *NTResourceToBlob(const char *id) 2052{ 2053 2054#ifndef MAGICKCORE_LIBRARY_NAME 2055 char 2056 path[MagickPathExtent]; 2057#endif 2058 2059 DWORD 2060 length; 2061 2062 HGLOBAL 2063 global; 2064 2065 HMODULE 2066 handle; 2067 2068 HRSRC 2069 resource; 2070 2071 unsigned char 2072 *blob, 2073 *value; 2074 2075 assert(id != (const char *) NULL); 2076 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id); 2077#ifdef MAGICKCORE_LIBRARY_NAME 2078 handle=GetModuleHandle(MAGICKCORE_LIBRARY_NAME); 2079#else 2080 (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",GetClientPath(), 2081 DirectorySeparator,GetClientName()); 2082 if (IsPathAccessible(path) != MagickFalse) 2083 handle=GetModuleHandle(path); 2084 else 2085 handle=GetModuleHandle(0); 2086#endif 2087 if (!handle) 2088 return((unsigned char *) NULL); 2089 resource=FindResource(handle,id,"IMAGEMAGICK"); 2090 if (!resource) 2091 return((unsigned char *) NULL); 2092 global=LoadResource(handle,resource); 2093 if (!global) 2094 return((unsigned char *) NULL); 2095 length=SizeofResource(handle,resource); 2096 value=(unsigned char *) LockResource(global); 2097 if (!value) 2098 { 2099 FreeResource(global); 2100 return((unsigned char *) NULL); 2101 } 2102 blob=(unsigned char *) AcquireQuantumMemory(length+MagickPathExtent, 2103 sizeof(*blob)); 2104 if (blob != (unsigned char *) NULL) 2105 { 2106 (void) CopyMagickMemory(blob,value,length); 2107 blob[length]='\0'; 2108 } 2109 UnlockResource(global); 2110 FreeResource(global); 2111 return(blob); 2112} 2113 2114/* 2115%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2116% % 2117% % 2118% % 2119% N T S e e k D i r e c t o r y % 2120% % 2121% % 2122% % 2123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2124% 2125% NTSeekDirectory() sets the position of the next NTReadDirectory() operation 2126% on the directory stream. 2127% 2128% The format of the NTSeekDirectory method is: 2129% 2130% void NTSeekDirectory(DIR *entry,ssize_t position) 2131% 2132% A description of each parameter follows: 2133% 2134% o entry: Specifies a pointer to a DIR structure. 2135% 2136% o position: specifies the position associated with the directory 2137% stream. 2138% 2139*/ 2140MagickPrivate void NTSeekDirectory(DIR *entry,ssize_t position) 2141{ 2142 (void) position; 2143 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2144 assert(entry != (DIR *) NULL); 2145} 2146 2147/* 2148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2149% % 2150% % 2151% % 2152% N T S e t S e a r c h P a t h % 2153% % 2154% % 2155% % 2156%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2157% 2158% NTSetSearchPath() sets the current locations that the subsystem should 2159% look at to find dynamically loadable modules. 2160% 2161% The format of the NTSetSearchPath method is: 2162% 2163% int NTSetSearchPath(const char *path) 2164% 2165% A description of each parameter follows: 2166% 2167% o path: Specifies a pointer to string representing the search path 2168% for DLL's that can be dynamically loaded. 2169% 2170*/ 2171MagickPrivate int NTSetSearchPath(const char *path) 2172{ 2173#if defined(MAGICKCORE_LTDL_DELEGATE) 2174 lt_dlsetsearchpath(path); 2175#else 2176 if (lt_slsearchpath != (char *) NULL) 2177 lt_slsearchpath=DestroyString(lt_slsearchpath); 2178 if (path != (char *) NULL) 2179 lt_slsearchpath=AcquireString(path); 2180#endif 2181 return(0); 2182} 2183 2184/* 2185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2186% % 2187% % 2188% % 2189+ N T S y n c M e m o r y % 2190% % 2191% % 2192% % 2193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2194% 2195% NTSyncMemory() emulates the Unix method of the same name. 2196% 2197% The format of the NTSyncMemory method is: 2198% 2199% int NTSyncMemory(void *address,size_t length,int flags) 2200% 2201% A description of each parameter follows: 2202% 2203% o address: the address of the binary large object. 2204% 2205% o length: the length of the binary large object. 2206% 2207% o flags: Option flags (ignored for Windows). 2208% 2209*/ 2210MagickPrivate int NTSyncMemory(void *address,size_t length,int flags) 2211{ 2212 (void) flags; 2213 if (FlushViewOfFile(address,length) == MagickFalse) 2214 return(-1); 2215 return(0); 2216} 2217 2218/* 2219%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2220% % 2221% % 2222% % 2223% N T S y s t e m C o m m a n d % 2224% % 2225% % 2226% % 2227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2228% 2229% NTSystemCommand() executes the specified command and waits until it 2230% terminates. The returned value is the exit status of the command. 2231% 2232% The format of the NTSystemCommand method is: 2233% 2234% int NTSystemCommand(MagickFalse,const char *command) 2235% 2236% A description of each parameter follows: 2237% 2238% o command: This string is the command to execute. 2239% 2240% o output: an optional buffer to store the output from stderr/stdout. 2241% 2242*/ 2243MagickPrivate int NTSystemCommand(const char *command,char *output) 2244{ 2245#define CleanupOutputHandles \ 2246 if (read_output != (HANDLE) NULL) \ 2247 { \ 2248 CloseHandle(read_output); \ 2249 read_output=(HANDLE) NULL; \ 2250 CloseHandle(write_output); \ 2251 write_output=(HANDLE) NULL; \ 2252 } 2253 2254#define CopyLastError \ 2255 if (output != (char *) NULL) \ 2256 { \ 2257 error=NTGetLastError(); \ 2258 if (error != (char *) NULL) \ 2259 { \ 2260 CopyMagickString(output,error,MagickPathExtent); \ 2261 error=DestroyString(error); \ 2262 } \ 2263 } 2264 2265 char 2266 *error, 2267 local_command[MagickPathExtent]; 2268 2269 DWORD 2270 bytes_read, 2271 child_status, 2272 size; 2273 2274 int 2275 status; 2276 2277 MagickBooleanType 2278 asynchronous; 2279 2280 HANDLE 2281 read_output, 2282 write_output; 2283 2284 PROCESS_INFORMATION 2285 process_info; 2286 2287 SECURITY_ATTRIBUTES 2288 sa; 2289 2290 STARTUPINFO 2291 startup_info; 2292 2293 if (command == (char *) NULL) 2294 return(-1); 2295 read_output=(HANDLE) NULL; 2296 write_output=(HANDLE) NULL; 2297 GetStartupInfo(&startup_info); 2298 startup_info.dwFlags=STARTF_USESHOWWINDOW; 2299 startup_info.wShowWindow=SW_SHOWMINNOACTIVE; 2300 (void) CopyMagickString(local_command,command,MagickPathExtent); 2301 asynchronous=command[strlen(command)-1] == '&' ? MagickTrue : MagickFalse; 2302 if (asynchronous != MagickFalse) 2303 { 2304 local_command[strlen(command)-1]='\0'; 2305 startup_info.wShowWindow=SW_SHOWDEFAULT; 2306 } 2307 else 2308 { 2309 if (command[strlen(command)-1] == '|') 2310 local_command[strlen(command)-1]='\0'; 2311 else 2312 startup_info.wShowWindow=SW_HIDE; 2313 read_output=(HANDLE) NULL; 2314 if (output != (char *) NULL) 2315 { 2316 sa.nLength=sizeof(SECURITY_ATTRIBUTES); 2317 sa.bInheritHandle=TRUE; 2318 sa.lpSecurityDescriptor=NULL; 2319 if (CreatePipe(&read_output,&write_output,NULL,0)) 2320 { 2321 if (SetHandleInformation(write_output,HANDLE_FLAG_INHERIT, 2322 HANDLE_FLAG_INHERIT)) 2323 { 2324 startup_info.dwFlags|=STARTF_USESTDHANDLES; 2325 startup_info.hStdOutput=write_output; 2326 startup_info.hStdError=write_output; 2327 } 2328 else 2329 CleanupOutputHandles; 2330 } 2331 else 2332 read_output=(HANDLE) NULL; 2333 } 2334 } 2335 status=CreateProcess((LPCTSTR) NULL,local_command,(LPSECURITY_ATTRIBUTES) 2336 NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) TRUE,(DWORD) 2337 NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info, 2338 &process_info); 2339 if (status == 0) 2340 { 2341 CopyLastError; 2342 CleanupOutputHandles; 2343 return(-1); 2344 } 2345 if (asynchronous != MagickFalse) 2346 return(status == 0); 2347 status=WaitForSingleObject(process_info.hProcess,INFINITE); 2348 if (status != WAIT_OBJECT_0) 2349 { 2350 CopyLastError; 2351 CleanupOutputHandles; 2352 return(status); 2353 } 2354 status=GetExitCodeProcess(process_info.hProcess,&child_status); 2355 if (status == 0) 2356 { 2357 CopyLastError; 2358 CleanupOutputHandles; 2359 return(-1); 2360 } 2361 CloseHandle(process_info.hProcess); 2362 CloseHandle(process_info.hThread); 2363 if (read_output != (HANDLE) NULL) 2364 if (PeekNamedPipe(read_output,(LPVOID) NULL,0,(LPDWORD) NULL,&size, 2365 (LPDWORD) NULL)) 2366 if ((size > 0) && (ReadFile(read_output,output,MagickPathExtent-1, 2367 &bytes_read,NULL))) 2368 output[bytes_read]='\0'; 2369 CleanupOutputHandles; 2370 return((int) child_status); 2371} 2372 2373/* 2374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2375% % 2376% % 2377% % 2378% N T S y s t e m C o n i f i g u r a t i o n % 2379% % 2380% % 2381% % 2382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2383% 2384% NTSystemConfiguration() provides a way for the application to determine 2385% values for system limits or options at runtime. 2386% 2387% The format of the exit method is: 2388% 2389% ssize_t NTSystemConfiguration(int name) 2390% 2391% A description of each parameter follows: 2392% 2393% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES. 2394% 2395*/ 2396MagickPrivate ssize_t NTSystemConfiguration(int name) 2397{ 2398 switch (name) 2399 { 2400 case _SC_PAGESIZE: 2401 { 2402 SYSTEM_INFO 2403 system_info; 2404 2405 GetSystemInfo(&system_info); 2406 return(system_info.dwPageSize); 2407 } 2408 case _SC_PHYS_PAGES: 2409 { 2410 HMODULE 2411 handle; 2412 2413 LPFNDLLFUNC2 2414 module; 2415 2416 NTMEMORYSTATUSEX 2417 status; 2418 2419 SYSTEM_INFO 2420 system_info; 2421 2422 handle=GetModuleHandle("kernel32.dll"); 2423 if (handle == (HMODULE) NULL) 2424 return(0L); 2425 GetSystemInfo(&system_info); 2426 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx"); 2427 if (module == (LPFNDLLFUNC2) NULL) 2428 { 2429 MEMORYSTATUS 2430 global_status; 2431 2432 GlobalMemoryStatus(&global_status); 2433 return((ssize_t) global_status.dwTotalPhys/system_info.dwPageSize/4); 2434 } 2435 status.dwLength=sizeof(status); 2436 if (module(&status) == 0) 2437 return(0L); 2438 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize/4); 2439 } 2440 case _SC_OPEN_MAX: 2441 return(2048); 2442 default: 2443 break; 2444 } 2445 return(-1); 2446} 2447 2448/* 2449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2450% % 2451% % 2452% % 2453% N T T e l l D i r e c t o r y % 2454% % 2455% % 2456% % 2457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2458% 2459% NTTellDirectory() returns the current location associated with the named 2460% directory stream. 2461% 2462% The format of the NTTellDirectory method is: 2463% 2464% ssize_t NTTellDirectory(DIR *entry) 2465% 2466% A description of each parameter follows: 2467% 2468% o entry: Specifies a pointer to a DIR structure. 2469% 2470*/ 2471MagickPrivate ssize_t NTTellDirectory(DIR *entry) 2472{ 2473 assert(entry != (DIR *) NULL); 2474 return(0); 2475} 2476 2477/* 2478%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2479% % 2480% % 2481% % 2482% N T T r u n c a t e F i l e % 2483% % 2484% % 2485% % 2486%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2487% 2488% NTTruncateFile() truncates a file to a specified length. 2489% 2490% The format of the NTTruncateFile method is: 2491% 2492% int NTTruncateFile(int file,off_t length) 2493% 2494% A description of each parameter follows: 2495% 2496% o file: the file. 2497% 2498% o length: the file length. 2499% 2500*/ 2501MagickPrivate int NTTruncateFile(int file,off_t length) 2502{ 2503 DWORD 2504 file_pointer; 2505 2506 HANDLE 2507 file_handle; 2508 2509 long 2510 high, 2511 low; 2512 2513 file_handle=(HANDLE) _get_osfhandle(file); 2514 if (file_handle == INVALID_HANDLE_VALUE) 2515 return(-1); 2516 low=(long) (length & 0xffffffffUL); 2517 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL); 2518 file_pointer=SetFilePointer(file_handle,low,&high,FILE_BEGIN); 2519 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) 2520 return(-1); 2521 if (SetEndOfFile(file_handle) == 0) 2522 return(-1); 2523 return(0); 2524} 2525 2526/* 2527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2528% % 2529% % 2530% % 2531+ N T U n m a p M e m o r y % 2532% % 2533% % 2534% % 2535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2536% 2537% NTUnmapMemory() emulates the Unix munmap method. 2538% 2539% The format of the NTUnmapMemory method is: 2540% 2541% int NTUnmapMemory(void *map,size_t length) 2542% 2543% A description of each parameter follows: 2544% 2545% o map: the address of the binary large object. 2546% 2547% o length: the length of the binary large object. 2548% 2549*/ 2550MagickPrivate int NTUnmapMemory(void *map,size_t length) 2551{ 2552 (void) length; 2553 if (UnmapViewOfFile(map) == 0) 2554 return(-1); 2555 return(0); 2556} 2557 2558/* 2559%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2560% % 2561% % 2562% % 2563% N T U s e r T i m e % 2564% % 2565% % 2566% % 2567%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2568% 2569% NTUserTime() returns the total time the process has been scheduled (e.g. 2570% seconds) since the last call to StartTimer(). 2571% 2572% The format of the UserTime method is: 2573% 2574% double NTUserTime(void) 2575% 2576*/ 2577MagickPrivate double NTUserTime(void) 2578{ 2579 DWORD 2580 status; 2581 2582 FILETIME 2583 create_time, 2584 exit_time; 2585 2586 OSVERSIONINFO 2587 OsVersionInfo; 2588 2589 union 2590 { 2591 FILETIME 2592 filetime; 2593 2594 __int64 2595 filetime64; 2596 } kernel_time; 2597 2598 union 2599 { 2600 FILETIME 2601 filetime; 2602 2603 __int64 2604 filetime64; 2605 } user_time; 2606 2607 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); 2608 GetVersionEx(&OsVersionInfo); 2609 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) 2610 return(NTElapsedTime()); 2611 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time, 2612 &kernel_time.filetime,&user_time.filetime); 2613 if (status != TRUE) 2614 return(0.0); 2615 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64)); 2616} 2617 2618/* 2619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2620% % 2621% % 2622% % 2623% N T W a r n i n g H a n d l e r % 2624% % 2625% % 2626% % 2627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2628% 2629% NTWarningHandler() displays a warning reason. 2630% 2631% The format of the NTWarningHandler method is: 2632% 2633% void NTWarningHandler(const ExceptionType severity,const char *reason, 2634% const char *description) 2635% 2636% A description of each parameter follows: 2637% 2638% o severity: Specifies the numeric warning category. 2639% 2640% o reason: Specifies the reason to display before terminating the 2641% program. 2642% 2643% o description: Specifies any description to the reason. 2644% 2645*/ 2646MagickPrivate void NTWarningHandler(const ExceptionType severity, 2647 const char *reason,const char *description) 2648{ 2649 char 2650 buffer[2*MagickPathExtent]; 2651 2652 (void) severity; 2653 if (reason == (char *) NULL) 2654 return; 2655 if (description == (char *) NULL) 2656 (void) FormatLocaleString(buffer,MagickPathExtent,"%s: %s.\n",GetClientName(), 2657 reason); 2658 else 2659 (void) FormatLocaleString(buffer,MagickPathExtent,"%s: %s (%s).\n", 2660 GetClientName(),reason,description); 2661 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL | 2662 MB_SETFOREGROUND | MB_ICONINFORMATION); 2663} 2664 2665/* 2666%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2667% % 2668% % 2669% % 2670% N T W i n d o w s G e n e s i s % 2671% % 2672% % 2673% % 2674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2675% 2676% NTWindowsGenesis() initializes the MagickCore Windows environment. 2677% 2678% The format of the NTWindowsGenesis method is: 2679% 2680% void NTWindowsGenesis(void) 2681% 2682*/ 2683 2684static LONG WINAPI NTUncaughtException(EXCEPTION_POINTERS *info) 2685{ 2686 (void) info; 2687 AsynchronousResourceComponentTerminus(); 2688 return(EXCEPTION_CONTINUE_SEARCH); 2689} 2690 2691MagickPrivate void NTWindowsGenesis(void) 2692{ 2693 char 2694 *mode; 2695 2696 SetUnhandledExceptionFilter(NTUncaughtException); 2697 mode=GetEnvironmentValue("MAGICK_ERRORMODE"); 2698 if (mode != (char *) NULL) 2699 { 2700 (void) SetErrorMode(StringToInteger(mode)); 2701 mode=DestroyString(mode); 2702 } 2703#if defined(_DEBUG) && !defined(__BORLANDC__) && !defined(__MINGW32__) && !defined(__MINGW64__) 2704 if (IsEventLogging() != MagickFalse) 2705 { 2706 int 2707 debug; 2708 2709 debug=_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); 2710 debug|=_CRTDBG_CHECK_ALWAYS_DF | _CRTDBG_DELAY_FREE_MEM_DF | 2711 _CRTDBG_LEAK_CHECK_DF; 2712 (void) _CrtSetDbgFlag(debug); 2713 _ASSERTE(_CrtCheckMemory()); 2714 } 2715#endif 2716} 2717 2718/* 2719%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2720% % 2721% % 2722% % 2723% N T W i n d o w s T e r m i n u s % 2724% % 2725% % 2726% % 2727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2728% 2729% NTWindowsTerminus() terminates the MagickCore Windows environment. 2730% 2731% The format of the NTWindowsTerminus method is: 2732% 2733% void NTWindowsTerminus(void) 2734% 2735*/ 2736MagickPrivate void NTWindowsTerminus(void) 2737{ 2738 NTGhostscriptUnLoadDLL(); 2739 if (winsock_semaphore == (SemaphoreInfo *) NULL) 2740 ActivateSemaphoreInfo(&winsock_semaphore); 2741 LockSemaphoreInfo(winsock_semaphore); 2742 if (wsaData != (WSADATA *) NULL) 2743 { 2744 WSACleanup(); 2745 wsaData=(WSADATA *) RelinquishMagickMemory((void *) wsaData); 2746 } 2747 UnlockSemaphoreInfo(winsock_semaphore); 2748 RelinquishSemaphoreInfo(&winsock_semaphore); 2749} 2750#endif 2751