nt-base.c revision 45ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7
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__) 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=FALSE; 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=TRUE; 1003 } 1004 } 1005 (void) RegCloseKey(hkey); 1006 } 1007 } 1008 if (status == FALSE) 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 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 1557MagickPrivate void *NTOpenLibrary(const char *filename) 1558{ 1559#define MaxPathElements 31 1560 1561 char 1562 buffer[MaxTextExtent]; 1563 1564 int 1565 index; 1566 1567 register const char 1568 *p, 1569 *q; 1570 1571 register int 1572 i; 1573 1574 UINT 1575 mode; 1576 1577 void 1578 *handle; 1579 1580 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); 1581 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); 1582 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL)) 1583 { 1584 SetErrorMode(mode); 1585 return(handle); 1586 } 1587 p=(char *) GetSearchPath(); 1588 index=0; 1589 while (index < MaxPathElements) 1590 { 1591 q=strchr(p,DirectoryListSeparator); 1592 if (q == (char *) NULL) 1593 { 1594 (void) CopyMagickString(buffer,p,MaxTextExtent); 1595 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent); 1596 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent); 1597 handle=(void *) LoadLibraryEx(buffer,NULL, 1598 LOAD_WITH_ALTERED_SEARCH_PATH); 1599 break; 1600 } 1601 i=q-p; 1602 (void) CopyMagickString(buffer,p,i+1); 1603 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent); 1604 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent); 1605 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); 1606 if (handle != (void *) NULL) 1607 break; 1608 p=q+1; 1609 } 1610 SetErrorMode(mode); 1611 return(handle); 1612} 1613 1614/* 1615%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1616% % 1617% % 1618% % 1619% N T R e a d D i r e c t o r y % 1620% % 1621% % 1622% % 1623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1624% 1625% NTReadDirectory() returns a pointer to a structure representing the 1626% directory entry at the current position in the directory stream to which 1627% entry refers. 1628% 1629% The format of the NTReadDirectory 1630% 1631% NTReadDirectory(entry) 1632% 1633% A description of each parameter follows: 1634% 1635% o entry: Specifies a pointer to a DIR structure. 1636% 1637*/ 1638MagickPrivate struct dirent *NTReadDirectory(DIR *entry) 1639{ 1640 int 1641 status; 1642 1643 size_t 1644 length; 1645 1646 if (entry == (DIR *) NULL) 1647 return((struct dirent *) NULL); 1648 if (!entry->firsttime) 1649 { 1650 status=FindNextFile(entry->hSearch,&entry->Win32FindData); 1651 if (status == 0) 1652 return((struct dirent *) NULL); 1653 } 1654 length=CopyMagickString(entry->file_info.d_name, 1655 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name)); 1656 if (length >= sizeof(entry->file_info.d_name)) 1657 return((struct dirent *) NULL); 1658 entry->firsttime=FALSE; 1659 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name); 1660 return(&entry->file_info); 1661} 1662 1663/* 1664%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1665% % 1666% % 1667% % 1668% N T R e g i s t r y K e y L o o k u p % 1669% % 1670% % 1671% % 1672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1673% 1674% NTRegistryKeyLookup() returns ImageMagick installation path settings 1675% stored in the Windows Registry. Path settings are specific to the 1676% installed ImageMagick version so that multiple Image Magick installations 1677% may coexist. 1678% 1679% Values are stored in the registry under a base path path similar to 1680% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\6.7.4\Q:16" or 1681% "HKEY_CURRENT_USER/SOFTWARE\ImageMagick\6.7.4\Q:16". The provided subkey 1682% is appended to this base path to form the full key. 1683% 1684% The format of the NTRegistryKeyLookup method is: 1685% 1686% unsigned char *NTRegistryKeyLookup(const char *subkey) 1687% 1688% A description of each parameter follows: 1689% 1690% o subkey: Specifies a string that identifies the registry object. 1691% Currently supported sub-keys include: "BinPath", "ConfigurePath", 1692% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath". 1693% 1694*/ 1695MagickPrivate unsigned char *NTRegistryKeyLookup(const char *subkey) 1696{ 1697 char 1698 package_key[MaxTextExtent]; 1699 1700 DWORD 1701 size, 1702 type; 1703 1704 HKEY 1705 registry_key; 1706 1707 LONG 1708 status; 1709 1710 unsigned char 1711 *value; 1712 1713 /* 1714 Look-up base key. 1715 */ 1716 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d", 1717 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH); 1718 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key); 1719 registry_key=(HKEY) INVALID_HANDLE_VALUE; 1720 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,®istry_key); 1721 if (status != ERROR_SUCCESS) 1722 status=RegOpenKeyExA(HKEY_CURRENT_USER,package_key,0,KEY_READ, 1723 ®istry_key); 1724 if (status != ERROR_SUCCESS) 1725 { 1726 registry_key=(HKEY) INVALID_HANDLE_VALUE; 1727 return((unsigned char *) NULL); 1728 } 1729 /* 1730 Look-up sub key. 1731 */ 1732 size=32; 1733 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value)); 1734 if (value == (unsigned char *) NULL) 1735 { 1736 RegCloseKey(registry_key); 1737 return((unsigned char *) NULL); 1738 } 1739 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey); 1740 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size); 1741 if ((status == ERROR_MORE_DATA) && (type == REG_SZ)) 1742 { 1743 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value)); 1744 if (value == (BYTE *) NULL) 1745 { 1746 RegCloseKey(registry_key); 1747 return((unsigned char *) NULL); 1748 } 1749 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size); 1750 } 1751 RegCloseKey(registry_key); 1752 if ((type != REG_SZ) || (status != ERROR_SUCCESS)) 1753 value=(unsigned char *) RelinquishMagickMemory(value); 1754 return((unsigned char *) value); 1755} 1756 1757/* 1758%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1759% % 1760% % 1761% % 1762% N T R e p o r t E v e n t % 1763% % 1764% % 1765% % 1766%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1767% 1768% NTReportEvent() reports an event. 1769% 1770% The format of the NTReportEvent method is: 1771% 1772% MagickBooleanType NTReportEvent(const char *event, 1773% const MagickBooleanType error) 1774% 1775% A description of each parameter follows: 1776% 1777% o event: the event. 1778% 1779% o error: MagickTrue the event is an error. 1780% 1781*/ 1782MagickPrivate MagickBooleanType NTReportEvent(const char *event, 1783 const MagickBooleanType error) 1784{ 1785 const char 1786 *events[1]; 1787 1788 HANDLE 1789 handle; 1790 1791 WORD 1792 type; 1793 1794 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME); 1795 if (handle == NULL) 1796 return(MagickFalse); 1797 events[0]=event; 1798 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE; 1799 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL); 1800 DeregisterEventSource(handle); 1801 return(MagickTrue); 1802} 1803 1804/* 1805%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1806% % 1807% % 1808% % 1809% N T R e s o u r c e T o B l o b % 1810% % 1811% % 1812% % 1813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1814% 1815% NTResourceToBlob() returns a blob containing the contents of the resource 1816% in the current executable specified by the id parameter. This currently 1817% used to retrieve MGK files tha have been embedded into the various command 1818% line utilities. 1819% 1820% The format of the NTResourceToBlob method is: 1821% 1822% unsigned char *NTResourceToBlob(const char *id) 1823% 1824% A description of each parameter follows: 1825% 1826% o id: Specifies a string that identifies the resource. 1827% 1828*/ 1829MagickPrivate unsigned char *NTResourceToBlob(const char *id) 1830{ 1831 char 1832 path[MaxTextExtent]; 1833 1834 DWORD 1835 length; 1836 1837 HGLOBAL 1838 global; 1839 1840 HMODULE 1841 handle; 1842 1843 HRSRC 1844 resource; 1845 1846 unsigned char 1847 *blob, 1848 *value; 1849 1850 assert(id != (const char *) NULL); 1851 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id); 1852 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(), 1853 DirectorySeparator,GetClientName()); 1854 if (IsPathAccessible(path) != MagickFalse) 1855 handle=GetModuleHandle(path); 1856 else 1857 handle=GetModuleHandle(0); 1858 if (!handle) 1859 return((unsigned char *) NULL); 1860 resource=FindResource(handle,id,"IMAGEMAGICK"); 1861 if (!resource) 1862 return((unsigned char *) NULL); 1863 global=LoadResource(handle,resource); 1864 if (!global) 1865 return((unsigned char *) NULL); 1866 length=SizeofResource(handle,resource); 1867 value=(unsigned char *) LockResource(global); 1868 if (!value) 1869 { 1870 FreeResource(global); 1871 return((unsigned char *) NULL); 1872 } 1873 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent, 1874 sizeof(*blob)); 1875 if (blob != (unsigned char *) NULL) 1876 { 1877 (void) CopyMagickMemory(blob,value,length); 1878 blob[length]='\0'; 1879 } 1880 UnlockResource(global); 1881 FreeResource(global); 1882 return(blob); 1883} 1884 1885/* 1886%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1887% % 1888% % 1889% % 1890% N T S e e k D i r e c t o r y % 1891% % 1892% % 1893% % 1894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1895% 1896% NTSeekDirectory() sets the position of the next NTReadDirectory() operation 1897% on the directory stream. 1898% 1899% The format of the NTSeekDirectory method is: 1900% 1901% void NTSeekDirectory(DIR *entry,ssize_t position) 1902% 1903% A description of each parameter follows: 1904% 1905% o entry: Specifies a pointer to a DIR structure. 1906% 1907% o position: specifies the position associated with the directory 1908% stream. 1909% 1910*/ 1911MagickPrivate void NTSeekDirectory(DIR *entry,ssize_t position) 1912{ 1913 (void) position; 1914 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1915 assert(entry != (DIR *) NULL); 1916} 1917 1918/* 1919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1920% % 1921% % 1922% % 1923% N T S e t S e a r c h P a t h % 1924% % 1925% % 1926% % 1927%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1928% 1929% NTSetSearchPath() sets the current locations that the subsystem should 1930% look at to find dynamically loadable modules. 1931% 1932% The format of the NTSetSearchPath method is: 1933% 1934% int NTSetSearchPath(const char *path) 1935% 1936% A description of each parameter follows: 1937% 1938% o path: Specifies a pointer to string representing the search path 1939% for DLL's that can be dynamically loaded. 1940% 1941*/ 1942MagickPrivate int NTSetSearchPath(const char *path) 1943{ 1944#if defined(MAGICKCORE_LTDL_DELEGATE) 1945 lt_dlsetsearchpath(path); 1946#else 1947 if (lt_slsearchpath != (char *) NULL) 1948 lt_slsearchpath=DestroyString(lt_slsearchpath); 1949 if (path != (char *) NULL) 1950 lt_slsearchpath=AcquireString(path); 1951#endif 1952 return(0); 1953} 1954 1955/* 1956%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1957% % 1958% % 1959% % 1960+ N T S y n c M e m o r y % 1961% % 1962% % 1963% % 1964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1965% 1966% NTSyncMemory() emulates the Unix method of the same name. 1967% 1968% The format of the NTSyncMemory method is: 1969% 1970% int NTSyncMemory(void *address,size_t length,int flags) 1971% 1972% A description of each parameter follows: 1973% 1974% o address: the address of the binary large object. 1975% 1976% o length: the length of the binary large object. 1977% 1978% o flags: Option flags (ignored for Windows). 1979% 1980*/ 1981MagickPrivate int NTSyncMemory(void *address,size_t length,int flags) 1982{ 1983 (void) flags; 1984 if (FlushViewOfFile(address,length) == MagickFalse) 1985 return(-1); 1986 return(0); 1987} 1988 1989/* 1990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1991% % 1992% % 1993% % 1994% N T S y s t e m C o m m a n d % 1995% % 1996% % 1997% % 1998%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1999% 2000% NTSystemCommand() executes the specified command and waits until it 2001% terminates. The returned value is the exit status of the command. 2002% 2003% The format of the NTSystemCommand method is: 2004% 2005% int NTSystemCommand(MagickFalse,const char *command) 2006% 2007% A description of each parameter follows: 2008% 2009% o command: This string is the command to execute. 2010% 2011*/ 2012MagickPrivate int NTSystemCommand(const char *command) 2013{ 2014 char 2015 local_command[MaxTextExtent]; 2016 2017 DWORD 2018 child_status; 2019 2020 int 2021 status; 2022 2023 MagickBooleanType 2024 background_process; 2025 2026 PROCESS_INFORMATION 2027 process_info; 2028 2029 STARTUPINFO 2030 startup_info; 2031 2032 if (command == (char *) NULL) 2033 return(-1); 2034 GetStartupInfo(&startup_info); 2035 startup_info.dwFlags=STARTF_USESHOWWINDOW; 2036 startup_info.wShowWindow=SW_SHOWMINNOACTIVE; 2037 (void) CopyMagickString(local_command,command,MaxTextExtent); 2038 background_process=command[strlen(command)-1] == '&' ? MagickTrue : 2039 MagickFalse; 2040 if (background_process != MagickFalse) 2041 local_command[strlen(command)-1]='\0'; 2042 if (command[strlen(command)-1] == '|') 2043 local_command[strlen(command)-1]='\0'; 2044 else 2045 startup_info.wShowWindow=SW_SHOWDEFAULT; 2046 status=CreateProcess((LPCTSTR) NULL,local_command,(LPSECURITY_ATTRIBUTES) 2047 NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE,(DWORD) 2048 NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info, 2049 &process_info); 2050 if (status == 0) 2051 return(-1); 2052 if (background_process != MagickFalse) 2053 return(status == 0); 2054 status=WaitForSingleObject(process_info.hProcess,INFINITE); 2055 if (status != WAIT_OBJECT_0) 2056 return(status); 2057 status=GetExitCodeProcess(process_info.hProcess,&child_status); 2058 if (status == 0) 2059 return(-1); 2060 CloseHandle(process_info.hProcess); 2061 CloseHandle(process_info.hThread); 2062 return((int) child_status); 2063} 2064 2065/* 2066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2067% % 2068% % 2069% % 2070% N T S y s t e m C o n i f i g u r a t i o n % 2071% % 2072% % 2073% % 2074%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2075% 2076% NTSystemConfiguration() provides a way for the application to determine 2077% values for system limits or options at runtime. 2078% 2079% The format of the exit method is: 2080% 2081% ssize_t NTSystemConfiguration(int name) 2082% 2083% A description of each parameter follows: 2084% 2085% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES. 2086% 2087*/ 2088MagickPrivate ssize_t NTSystemConfiguration(int name) 2089{ 2090 switch (name) 2091 { 2092 case _SC_PAGESIZE: 2093 { 2094 SYSTEM_INFO 2095 system_info; 2096 2097 GetSystemInfo(&system_info); 2098 return(system_info.dwPageSize); 2099 } 2100 case _SC_PHYS_PAGES: 2101 { 2102 HMODULE 2103 handle; 2104 2105 LPFNDLLFUNC2 2106 module; 2107 2108 NTMEMORYSTATUSEX 2109 status; 2110 2111 SYSTEM_INFO 2112 system_info; 2113 2114 handle=GetModuleHandle("kernel32.dll"); 2115 if (handle == (HMODULE) NULL) 2116 return(0L); 2117 GetSystemInfo(&system_info); 2118 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx"); 2119 if (module == (LPFNDLLFUNC2) NULL) 2120 { 2121 MEMORYSTATUS 2122 status; 2123 2124 GlobalMemoryStatus(&status); 2125 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize); 2126 } 2127 status.dwLength=sizeof(status); 2128 if (module(&status) == 0) 2129 return(0L); 2130 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize); 2131 } 2132 case _SC_OPEN_MAX: 2133 return(2048); 2134 default: 2135 break; 2136 } 2137 return(-1); 2138} 2139 2140/* 2141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2142% % 2143% % 2144% % 2145% N T T e l l D i r e c t o r y % 2146% % 2147% % 2148% % 2149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2150% 2151% NTTellDirectory() returns the current location associated with the named 2152% directory stream. 2153% 2154% The format of the NTTellDirectory method is: 2155% 2156% ssize_t NTTellDirectory(DIR *entry) 2157% 2158% A description of each parameter follows: 2159% 2160% o entry: Specifies a pointer to a DIR structure. 2161% 2162*/ 2163MagickPrivate ssize_t NTTellDirectory(DIR *entry) 2164{ 2165 assert(entry != (DIR *) NULL); 2166 return(0); 2167} 2168 2169/* 2170%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2171% % 2172% % 2173% % 2174% N T T r u n c a t e F i l e % 2175% % 2176% % 2177% % 2178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2179% 2180% NTTruncateFile() truncates a file to a specified length. 2181% 2182% The format of the NTTruncateFile method is: 2183% 2184% int NTTruncateFile(int file,off_t length) 2185% 2186% A description of each parameter follows: 2187% 2188% o file: the file. 2189% 2190% o length: the file length. 2191% 2192*/ 2193MagickPrivate int NTTruncateFile(int file,off_t length) 2194{ 2195 DWORD 2196 file_pointer; 2197 2198 long 2199 file_handle, 2200 high, 2201 low; 2202 2203 file_handle=_get_osfhandle(file); 2204 if (file_handle == -1L) 2205 return(-1); 2206 low=(long) (length & 0xffffffffUL); 2207 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL); 2208 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN); 2209 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) 2210 return(-1); 2211 if (SetEndOfFile((HANDLE) file_handle) == 0) 2212 return(-1); 2213 return(0); 2214} 2215 2216/* 2217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2218% % 2219% % 2220% % 2221+ N T U n m a p M e m o r y % 2222% % 2223% % 2224% % 2225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2226% 2227% NTUnmapMemory() emulates the Unix munmap method. 2228% 2229% The format of the NTUnmapMemory method is: 2230% 2231% int NTUnmapMemory(void *map,size_t length) 2232% 2233% A description of each parameter follows: 2234% 2235% o map: the address of the binary large object. 2236% 2237% o length: the length of the binary large object. 2238% 2239*/ 2240MagickPrivate int NTUnmapMemory(void *map,size_t length) 2241{ 2242 (void) length; 2243 if (UnmapViewOfFile(map) == 0) 2244 return(-1); 2245 return(0); 2246} 2247 2248/* 2249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2250% % 2251% % 2252% % 2253% N T U s e r T i m e % 2254% % 2255% % 2256% % 2257%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2258% 2259% NTUserTime() returns the total time the process has been scheduled (e.g. 2260% seconds) since the last call to StartTimer(). 2261% 2262% The format of the UserTime method is: 2263% 2264% double NTUserTime(void) 2265% 2266*/ 2267MagickPrivate double NTUserTime(void) 2268{ 2269 DWORD 2270 status; 2271 2272 FILETIME 2273 create_time, 2274 exit_time; 2275 2276 OSVERSIONINFO 2277 OsVersionInfo; 2278 2279 union 2280 { 2281 FILETIME 2282 filetime; 2283 2284 __int64 2285 filetime64; 2286 } kernel_time; 2287 2288 union 2289 { 2290 FILETIME 2291 filetime; 2292 2293 __int64 2294 filetime64; 2295 } user_time; 2296 2297 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); 2298 GetVersionEx(&OsVersionInfo); 2299 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) 2300 return(NTElapsedTime()); 2301 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time, 2302 &kernel_time.filetime,&user_time.filetime); 2303 if (status != TRUE) 2304 return(0.0); 2305 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64)); 2306} 2307 2308/* 2309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2310% % 2311% % 2312% % 2313% N T W a r n i n g H a n d l e r % 2314% % 2315% % 2316% % 2317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2318% 2319% NTWarningHandler() displays a warning reason. 2320% 2321% The format of the NTWarningHandler method is: 2322% 2323% void NTWarningHandler(const ExceptionType severity,const char *reason, 2324% const char *description) 2325% 2326% A description of each parameter follows: 2327% 2328% o severity: Specifies the numeric warning category. 2329% 2330% o reason: Specifies the reason to display before terminating the 2331% program. 2332% 2333% o description: Specifies any description to the reason. 2334% 2335*/ 2336MagickPrivate void NTWarningHandler(const ExceptionType severity, 2337 const char *reason,const char *description) 2338{ 2339 char 2340 buffer[2*MaxTextExtent]; 2341 2342 (void) severity; 2343 if (reason == (char *) NULL) 2344 return; 2345 if (description == (char *) NULL) 2346 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(), 2347 reason); 2348 else 2349 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n", 2350 GetClientName(),reason,description); 2351 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL | 2352 MB_SETFOREGROUND | MB_ICONINFORMATION); 2353} 2354#endif 2355