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