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