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