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