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