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