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