nt-base.c revision 139c684fa13d2ebfd735e0d092cfef982d2b9f0f
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/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.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(void) 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,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,&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(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; 972#if defined(KEY_WOW64_32KEY) 973 mode|=KEY_WOW64_32KEY; 974#endif 975 if (RegOpenKeyExA(root,key,0,mode,&hkey) == ERROR_SUCCESS) 976 { 977 DWORD 978 extent; 979 980 int 981 j; 982 983 /* 984 Now enumerate the keys. 985 */ 986 extent=sizeof(key)/sizeof(char); 987 for (j=0; RegEnumKeyA(hkey,j,key,extent) == ERROR_SUCCESS; j++) 988 { 989 int 990 major, 991 minor; 992 993 major=0; 994 minor=0; 995 if (sscanf(key,"%d.%d",&major,&minor) != 2) 996 continue; 997 if ((major > *major_version) || ((major == *major_version) && 998 (minor > *minor_version))) 999 { 1000 *product_family=products[i]; 1001 *major_version=major; 1002 *minor_version=minor; 1003 status=TRUE; 1004 } 1005 } 1006 (void) RegCloseKey(hkey); 1007 } 1008 } 1009 if (status == FALSE) 1010 { 1011 *major_version=0; 1012 *minor_version=0; 1013 } 1014 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"Ghostscript (%s) " 1015 "version %d.%02d",*product_family,*major_version,*minor_version); 1016 return(status); 1017} 1018 1019static int NTGhostscriptGetString(const char *name,char *value, 1020 const size_t length) 1021{ 1022 char 1023 key[MaxTextExtent]; 1024 1025 int 1026 i, 1027 extent; 1028 1029 static const char 1030 *product_family = (const char *) NULL; 1031 1032 static int 1033 major_version=0, 1034 minor_version=0; 1035 1036 struct 1037 { 1038 const HKEY 1039 hkey; 1040 1041 const char 1042 *name; 1043 } 1044 hkeys[2] = 1045 { 1046 { HKEY_CURRENT_USER, "HKEY_CURRENT_USER" }, 1047 { HKEY_LOCAL_MACHINE, "HKEY_LOCAL_MACHINE" } 1048 }; 1049 1050 /* 1051 Get a string from the installed Ghostscript. 1052 */ 1053 *value='\0'; 1054 if (product_family == NULL) 1055 (void) NTLocateGhostscript(&product_family,&major_version,&minor_version); 1056 if (product_family == NULL) 1057 return(FALSE); 1058 (void) FormatLocaleString(key,MaxTextExtent,"SOFTWARE\\%s\\%d.%02d", 1059 product_family,major_version,minor_version); 1060 for (i=0; i < (ssize_t) (sizeof(hkeys)/sizeof(hkeys[0])); i++) 1061 { 1062 extent=(int) length; 1063 if (NTGetRegistryValue(hkeys[i].hkey,key,name,value,&extent) == 0) 1064 { 1065 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 1066 "registry: \"%s\\%s\\%s\"=\"%s\"",hkeys[i].name,key,name,value); 1067 return(TRUE); 1068 } 1069 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 1070 "registry: \"%s\\%s\\%s\" (failed)",hkeys[i].name,key,name); 1071 } 1072 return(FALSE); 1073} 1074 1075MagickExport int NTGhostscriptDLL(char *path,int length) 1076{ 1077 static char 1078 dll[MaxTextExtent] = { "" }; 1079 1080 *path='\0'; 1081 if ((*dll == '\0') && 1082 (NTGhostscriptGetString("GS_DLL",dll,sizeof(dll)) == FALSE)) 1083 return(FALSE); 1084 (void) CopyMagickString(path,dll,length); 1085 return(TRUE); 1086} 1087 1088/* 1089%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1090% % 1091% % 1092% % 1093% N T G h o s t s c r i p t D L L V e c t o r s % 1094% % 1095% % 1096% % 1097%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1098% 1099% NTGhostscriptDLLVectors() returns a GhostInfo structure that includes 1100% function vectors to invoke Ghostscript DLL functions. A null pointer is 1101% returned if there is an error when loading the DLL or retrieving the 1102% function vectors. 1103% 1104% The format of the NTGhostscriptDLLVectors method is: 1105% 1106% const GhostInfo *NTGhostscriptDLLVectors(void) 1107% 1108*/ 1109MagickExport const GhostInfo *NTGhostscriptDLLVectors(void) 1110{ 1111 if (NTGhostscriptLoadDLL() == FALSE) 1112 return((GhostInfo *) NULL); 1113 return(&ghost_info); 1114} 1115 1116/* 1117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1118% % 1119% % 1120% % 1121% N T G h o s t s c r i p t E X E % 1122% % 1123% % 1124% % 1125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1126% 1127% NTGhostscriptEXE() obtains the path to the latest Ghostscript executable. 1128% The method returns FALSE if a full path value is not obtained and returns 1129% a default path of gswin32c.exe. 1130% 1131% The format of the NTGhostscriptEXE method is: 1132% 1133% int NTGhostscriptEXE(char *path,int length) 1134% 1135% A description of each parameter follows: 1136% 1137% o path: return the Ghostscript executable path here. 1138% 1139% o length: length of buffer. 1140% 1141*/ 1142MagickExport int NTGhostscriptEXE(char *path,int length) 1143{ 1144 register char 1145 *p; 1146 1147 static char 1148 program[MaxTextExtent] = { "" }; 1149 1150 (void) CopyMagickString(path,"gswin32c.exe",length); 1151 if ((*program == '\0') && 1152 (NTGhostscriptGetString("GS_DLL",program,sizeof(program)) == FALSE)) 1153 return(FALSE); 1154 p=strrchr(program,'\\'); 1155 if (p != (char *) NULL) 1156 { 1157 p++; 1158 *p='\0'; 1159 (void) ConcatenateMagickString(program,"gswin32c.exe",sizeof(program)); 1160 } 1161 (void) CopyMagickString(path,program,length); 1162 return(TRUE); 1163} 1164 1165/* 1166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1167% % 1168% % 1169% % 1170% N T G h o s t s c r i p t F o n t s % 1171% % 1172% % 1173% % 1174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1175% 1176% NTGhostscriptFonts() obtains the path to the Ghostscript fonts. The method 1177% returns FALSE if it cannot determine the font path. 1178% 1179% The format of the NTGhostscriptFonts method is: 1180% 1181% int NTGhostscriptFonts(char *path, int length) 1182% 1183% A description of each parameter follows: 1184% 1185% o path: return the font path here. 1186% 1187% o length: length of the path buffer. 1188% 1189*/ 1190MagickExport int NTGhostscriptFonts(char *path,int length) 1191{ 1192 char 1193 buffer[MaxTextExtent], 1194 filename[MaxTextExtent]; 1195 1196 register char 1197 *p, 1198 *q; 1199 1200 *path='\0'; 1201 if (NTGhostscriptGetString("GS_LIB",buffer,MaxTextExtent) == FALSE) 1202 return(FALSE); 1203 for (p=buffer-1; p != (char *) NULL; p=strchr(p+1,DirectoryListSeparator)) 1204 { 1205 (void) CopyMagickString(path,p+1,length+1); 1206 q=strchr(path,DirectoryListSeparator); 1207 if (q != (char *) NULL) 1208 *q='\0'; 1209 (void) FormatLocaleString(filename,MaxTextExtent,"%s%sfonts.dir",path, 1210 DirectorySeparator); 1211 if (IsPathAccessible(filename) != MagickFalse) 1212 return(TRUE); 1213 } 1214 return(FALSE); 1215} 1216 1217/* 1218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1219% % 1220% % 1221% % 1222% N T G h o s t s c r i p t L o a d D L L % 1223% % 1224% % 1225% % 1226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1227% 1228% NTGhostscriptLoadDLL() attempts to load the Ghostscript DLL and returns 1229% TRUE if it succeeds. 1230% 1231% The format of the NTGhostscriptLoadDLL method is: 1232% 1233% int NTGhostscriptLoadDLL(void) 1234% 1235*/ 1236MagickExport int NTGhostscriptLoadDLL(void) 1237{ 1238 char 1239 path[MaxTextExtent]; 1240 1241 if (ghost_handle != (void *) NULL) 1242 return(TRUE); 1243 if (NTGhostscriptDLL(path,sizeof(path)) == FALSE) 1244 return(FALSE); 1245 ghost_handle=lt_dlopen(path); 1246 if (ghost_handle == (void *) NULL) 1247 return(FALSE); 1248 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo)); 1249 ghost_info.exit=(int (MagickDLLCall *)(gs_main_instance*)) 1250 lt_dlsym(ghost_handle,"gsapi_exit"); 1251 ghost_info.init_with_args=(int (MagickDLLCall *)(gs_main_instance *,int, 1252 char **)) (lt_dlsym(ghost_handle,"gsapi_init_with_args")); 1253 ghost_info.new_instance=(int (MagickDLLCall *)(gs_main_instance **,void *)) ( 1254 lt_dlsym(ghost_handle,"gsapi_new_instance")); 1255 ghost_info.run_string=(int (MagickDLLCall *)(gs_main_instance *,const char *, 1256 int,int *)) (lt_dlsym(ghost_handle,"gsapi_run_string")); 1257 ghost_info.delete_instance=(void (MagickDLLCall *) (gs_main_instance *)) ( 1258 lt_dlsym(ghost_handle,"gsapi_delete_instance")); 1259 if ((ghost_info.exit == NULL) || (ghost_info.init_with_args == NULL) || 1260 (ghost_info.new_instance == NULL) || (ghost_info.run_string == NULL) || 1261 (ghost_info.delete_instance == NULL)) 1262 return(FALSE); 1263 return(TRUE); 1264} 1265 1266/* 1267%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1268% % 1269% % 1270% % 1271% N T G h o s t s c r i p t U n L o a d D L L % 1272% % 1273% % 1274% % 1275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1276% 1277% NTGhostscriptUnLoadDLL() unloads the Ghostscript DLL and returns TRUE if 1278% it succeeds. 1279% 1280% The format of the NTGhostscriptUnLoadDLL method is: 1281% 1282% int NTGhostscriptUnLoadDLL(void) 1283% 1284*/ 1285MagickExport int NTGhostscriptUnLoadDLL(void) 1286{ 1287 int 1288 status; 1289 1290 if (ghost_handle == (void *) NULL) 1291 return(FALSE); 1292 status=lt_dlclose(ghost_handle); 1293 ghost_handle=(void *) NULL; 1294 (void) ResetMagickMemory((void *) &ghost_info,0,sizeof(GhostInfo)); 1295 return(status); 1296} 1297 1298/* 1299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1300% % 1301% % 1302% % 1303% N T I n i t i a l i z e L i b r a r y % 1304% % 1305% % 1306% % 1307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1308% 1309% NTInitializeLibrary() initializes the dynamic module loading subsystem. 1310% 1311% The format of the NTInitializeLibrary method is: 1312% 1313% int NTInitializeLibrary(void) 1314% 1315*/ 1316MagickExport int NTInitializeLibrary(void) 1317{ 1318 return(0); 1319} 1320 1321/* 1322%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1323% % 1324% % 1325% % 1326+ N T M a p M e m o r y % 1327% % 1328% % 1329% % 1330%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1331% 1332% Mmap() emulates the Unix method of the same name. 1333% 1334% The format of the NTMapMemory method is: 1335% 1336% MagickExport void *NTMapMemory(char *address,size_t length,int protection, 1337% int access,int file,MagickOffsetType offset) 1338% 1339*/ 1340MagickExport void *NTMapMemory(char *address,size_t length,int protection, 1341 int flags,int file,MagickOffsetType offset) 1342{ 1343 DWORD 1344 access_mode, 1345 high_length, 1346 high_offset, 1347 low_length, 1348 low_offset, 1349 protection_mode; 1350 1351 HANDLE 1352 file_handle, 1353 map_handle; 1354 1355 void 1356 *map; 1357 1358 (void) address; 1359 access_mode=0; 1360 file_handle=INVALID_HANDLE_VALUE; 1361 low_length=(DWORD) (length & 0xFFFFFFFFUL); 1362 high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL); 1363 map_handle=INVALID_HANDLE_VALUE; 1364 map=(void *) NULL; 1365 low_offset=(DWORD) (offset & 0xFFFFFFFFUL); 1366 high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL); 1367 protection_mode=0; 1368 if (protection & PROT_WRITE) 1369 { 1370 access_mode=FILE_MAP_WRITE; 1371 if (!(flags & MAP_PRIVATE)) 1372 protection_mode=PAGE_READWRITE; 1373 else 1374 { 1375 access_mode=FILE_MAP_COPY; 1376 protection_mode=PAGE_WRITECOPY; 1377 } 1378 } 1379 else 1380 if (protection & PROT_READ) 1381 { 1382 access_mode=FILE_MAP_READ; 1383 protection_mode=PAGE_READONLY; 1384 } 1385 if ((file == -1) && (flags & MAP_ANONYMOUS)) 1386 file_handle=INVALID_HANDLE_VALUE; 1387 else 1388 file_handle=(HANDLE) _get_osfhandle(file); 1389 map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length, 1390 low_length,0); 1391 if (map_handle) 1392 { 1393 map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset, 1394 length); 1395 CloseHandle(map_handle); 1396 } 1397 if (map == (void *) NULL) 1398 return((void *) MAP_FAILED); 1399 return((void *) ((char *) map)); 1400} 1401 1402/* 1403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1404% % 1405% % 1406% % 1407% N T O p e n D i r e c t o r y % 1408% % 1409% % 1410% % 1411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1412% 1413% NTOpenDirectory() opens the directory named by filename and associates a 1414% directory stream with it. 1415% 1416% The format of the NTOpenDirectory method is: 1417% 1418% DIR *NTOpenDirectory(const char *path) 1419% 1420% A description of each parameter follows: 1421% 1422% o entry: Specifies a pointer to a DIR structure. 1423% 1424*/ 1425MagickExport DIR *NTOpenDirectory(const char *path) 1426{ 1427 char 1428 file_specification[MaxTextExtent]; 1429 1430 DIR 1431 *entry; 1432 1433 size_t 1434 length; 1435 1436 assert(path != (const char *) NULL); 1437 length=CopyMagickString(file_specification,path,MaxTextExtent); 1438 if (length >= (MaxTextExtent-1)) 1439 return((DIR *) NULL); 1440 length=ConcatenateMagickString(file_specification,DirectorySeparator, 1441 MaxTextExtent); 1442 if (length >= (MaxTextExtent-1)) 1443 return((DIR *) NULL); 1444 entry=(DIR *) AcquireMagickMemory(sizeof(DIR)); 1445 if (entry != (DIR *) NULL) 1446 { 1447 entry->firsttime=TRUE; 1448 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData); 1449 } 1450 if (entry->hSearch == INVALID_HANDLE_VALUE) 1451 { 1452 length=ConcatenateMagickString(file_specification,"\\*.*",MaxTextExtent); 1453 if (length >= (MaxTextExtent-1)) 1454 { 1455 entry=(DIR *) RelinquishMagickMemory(entry); 1456 return((DIR *) NULL); 1457 } 1458 entry->hSearch=FindFirstFile(file_specification,&entry->Win32FindData); 1459 if (entry->hSearch == INVALID_HANDLE_VALUE) 1460 { 1461 entry=(DIR *) RelinquishMagickMemory(entry); 1462 return((DIR *) NULL); 1463 } 1464 } 1465 return(entry); 1466} 1467 1468/* 1469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1470% % 1471% % 1472% % 1473% N T O p e n L i b r a r y % 1474% % 1475% % 1476% % 1477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1478% 1479% NTOpenLibrary() loads a dynamic module into memory and returns a handle that 1480% can be used to access the various procedures in the module. 1481% 1482% The format of the NTOpenLibrary method is: 1483% 1484% void *NTOpenLibrary(const char *filename) 1485% 1486% A description of each parameter follows: 1487% 1488% o path: Specifies a pointer to string representing dynamic module that 1489% is to be loaded. 1490% 1491*/ 1492 1493static const char *GetSearchPath( void ) 1494{ 1495#if defined(MAGICKCORE_LTDL_DELEGATE) 1496 return(lt_dlgetsearchpath()); 1497#else 1498 return(lt_slsearchpath); 1499#endif 1500} 1501 1502MagickExport void *NTOpenLibrary(const char *filename) 1503{ 1504#define MaxPathElements 31 1505 1506 char 1507 buffer[MaxTextExtent]; 1508 1509 int 1510 index; 1511 1512 register const char 1513 *p, 1514 *q; 1515 1516 register int 1517 i; 1518 1519 UINT 1520 mode; 1521 1522 void 1523 *handle; 1524 1525 mode=SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); 1526 handle=(void *) LoadLibraryEx(filename,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); 1527 if ((handle != (void *) NULL) || (GetSearchPath() == (char *) NULL)) 1528 { 1529 SetErrorMode(mode); 1530 return(handle); 1531 } 1532 p=(char *) GetSearchPath(); 1533 index=0; 1534 while (index < MaxPathElements) 1535 { 1536 q=strchr(p,DirectoryListSeparator); 1537 if (q == (char *) NULL) 1538 { 1539 (void) CopyMagickString(buffer,p,MaxTextExtent); 1540 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent); 1541 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent); 1542 handle=(void *) LoadLibraryEx(buffer,NULL, 1543 LOAD_WITH_ALTERED_SEARCH_PATH); 1544 break; 1545 } 1546 i=q-p; 1547 (void) CopyMagickString(buffer,p,i+1); 1548 (void) ConcatenateMagickString(buffer,"\\",MaxTextExtent); 1549 (void) ConcatenateMagickString(buffer,filename,MaxTextExtent); 1550 handle=(void *) LoadLibraryEx(buffer,NULL,LOAD_WITH_ALTERED_SEARCH_PATH); 1551 if (handle != (void *) NULL) 1552 break; 1553 p=q+1; 1554 } 1555 SetErrorMode(mode); 1556 return(handle); 1557} 1558 1559/* 1560%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1561% % 1562% % 1563% % 1564% N T R e a d D i r e c t o r y % 1565% % 1566% % 1567% % 1568%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1569% 1570% NTReadDirectory() returns a pointer to a structure representing the 1571% directory entry at the current position in the directory stream to which 1572% entry refers. 1573% 1574% The format of the NTReadDirectory 1575% 1576% NTReadDirectory(entry) 1577% 1578% A description of each parameter follows: 1579% 1580% o entry: Specifies a pointer to a DIR structure. 1581% 1582*/ 1583MagickExport struct dirent *NTReadDirectory(DIR *entry) 1584{ 1585 int 1586 status; 1587 1588 size_t 1589 length; 1590 1591 if (entry == (DIR *) NULL) 1592 return((struct dirent *) NULL); 1593 if (!entry->firsttime) 1594 { 1595 status=FindNextFile(entry->hSearch,&entry->Win32FindData); 1596 if (status == 0) 1597 return((struct dirent *) NULL); 1598 } 1599 length=CopyMagickString(entry->file_info.d_name, 1600 entry->Win32FindData.cFileName,sizeof(entry->file_info.d_name)); 1601 if (length >= sizeof(entry->file_info.d_name)) 1602 return((struct dirent *) NULL); 1603 entry->firsttime=FALSE; 1604 entry->file_info.d_namlen=(int) strlen(entry->file_info.d_name); 1605 return(&entry->file_info); 1606} 1607 1608/* 1609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1610% % 1611% % 1612% % 1613% N T R e g i s t r y K e y L o o k u p % 1614% % 1615% % 1616% % 1617%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1618% 1619% NTRegistryKeyLookup() returns ImageMagick installation path settings 1620% stored in the Windows Registry. Path settings are specific to the 1621% installed ImageMagick version so that multiple Image Magick installations 1622% may coexist. 1623% 1624% Values are stored in the registry under a base path path similar to 1625% "HKEY_LOCAL_MACHINE/SOFTWARE\ImageMagick\5.5.7\Q:16". The provided subkey 1626% is appended to this base path to form the full key. 1627% 1628% The format of the NTRegistryKeyLookup method is: 1629% 1630% unsigned char *NTRegistryKeyLookup(const char *subkey) 1631% 1632% A description of each parameter follows: 1633% 1634% o subkey: Specifies a string that identifies the registry object. 1635% Currently supported sub-keys include: "BinPath", "ConfigurePath", 1636% "LibPath", "CoderModulesPath", "FilterModulesPath", "SharePath". 1637% 1638*/ 1639MagickExport unsigned char *NTRegistryKeyLookup(const char *subkey) 1640{ 1641 char 1642 package_key[MaxTextExtent]; 1643 1644 DWORD 1645 size, 1646 type; 1647 1648 HKEY 1649 registry_key; 1650 1651 LONG 1652 status; 1653 1654 unsigned char 1655 *value; 1656 1657 /* 1658 Look-up base key. 1659 */ 1660 (void) FormatLocaleString(package_key,MaxTextExtent,"SOFTWARE\\%s\\%s\\Q:%d", 1661 MagickPackageName,MagickLibVersionText,MAGICKCORE_QUANTUM_DEPTH); 1662 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",package_key); 1663 registry_key=(HKEY) INVALID_HANDLE_VALUE; 1664 status=RegOpenKeyExA(HKEY_LOCAL_MACHINE,package_key,0,KEY_READ,®istry_key); 1665 if (status != ERROR_SUCCESS) 1666 { 1667 registry_key=(HKEY) INVALID_HANDLE_VALUE; 1668 return((unsigned char *) NULL); 1669 } 1670 /* 1671 Look-up sub key. 1672 */ 1673 size=32; 1674 value=(unsigned char *) AcquireQuantumMemory(size,sizeof(*value)); 1675 if (value == (unsigned char *) NULL) 1676 { 1677 RegCloseKey(registry_key); 1678 return((unsigned char *) NULL); 1679 } 1680 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),"%s",subkey); 1681 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size); 1682 if ((status == ERROR_MORE_DATA) && (type == REG_SZ)) 1683 { 1684 value=(unsigned char *) ResizeQuantumMemory(value,size,sizeof(*value)); 1685 if (value == (BYTE *) NULL) 1686 { 1687 RegCloseKey(registry_key); 1688 return((unsigned char *) NULL); 1689 } 1690 status=RegQueryValueExA(registry_key,subkey,0,&type,value,&size); 1691 } 1692 RegCloseKey(registry_key); 1693 if ((type != REG_SZ) || (status != ERROR_SUCCESS)) 1694 value=(unsigned char *) RelinquishMagickMemory(value); 1695 return((unsigned char *) value); 1696} 1697 1698/* 1699%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1700% % 1701% % 1702% % 1703% N T R e p o r t E v e n t % 1704% % 1705% % 1706% % 1707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1708% 1709% NTReportEvent() reports an event. 1710% 1711% The format of the NTReportEvent method is: 1712% 1713% MagickBooleanType NTReportEvent(const char *event, 1714% const MagickBooleanType error) 1715% 1716% A description of each parameter follows: 1717% 1718% o event: the event. 1719% 1720% o error: MagickTrue the event is an error. 1721% 1722*/ 1723MagickExport MagickBooleanType NTReportEvent(const char *event, 1724 const MagickBooleanType error) 1725{ 1726 const char 1727 *events[1]; 1728 1729 HANDLE 1730 handle; 1731 1732 WORD 1733 type; 1734 1735 handle=RegisterEventSource(NULL,MAGICKCORE_PACKAGE_NAME); 1736 if (handle == NULL) 1737 return(MagickFalse); 1738 events[0]=event; 1739 type=error ? EVENTLOG_ERROR_TYPE : EVENTLOG_WARNING_TYPE; 1740 ReportEvent(handle,type,0,0,NULL,1,0,events,NULL); 1741 DeregisterEventSource(handle); 1742 return(MagickTrue); 1743} 1744 1745/* 1746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1747% % 1748% % 1749% % 1750% N T R e s o u r c e T o B l o b % 1751% % 1752% % 1753% % 1754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1755% 1756% NTResourceToBlob() returns a blob containing the contents of the resource 1757% in the current executable specified by the id parameter. This currently 1758% used to retrieve MGK files tha have been embedded into the various command 1759% line utilities. 1760% 1761% The format of the NTResourceToBlob method is: 1762% 1763% unsigned char *NTResourceToBlob(const char *id) 1764% 1765% A description of each parameter follows: 1766% 1767% o id: Specifies a string that identifies the resource. 1768% 1769*/ 1770MagickExport unsigned char *NTResourceToBlob(const char *id) 1771{ 1772 char 1773 path[MaxTextExtent]; 1774 1775 DWORD 1776 length; 1777 1778 HGLOBAL 1779 global; 1780 1781 HMODULE 1782 handle; 1783 1784 HRSRC 1785 resource; 1786 1787 unsigned char 1788 *blob, 1789 *value; 1790 1791 assert(id != (const char *) NULL); 1792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id); 1793 (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",GetClientPath(), 1794 DirectorySeparator,GetClientName()); 1795 if (IsPathAccessible(path) != MagickFalse) 1796 handle=GetModuleHandle(path); 1797 else 1798 handle=GetModuleHandle(0); 1799 if (!handle) 1800 return((unsigned char *) NULL); 1801 resource=FindResource(handle,id,"IMAGEMAGICK"); 1802 if (!resource) 1803 return((unsigned char *) NULL); 1804 global=LoadResource(handle,resource); 1805 if (!global) 1806 return((unsigned char *) NULL); 1807 length=SizeofResource(handle,resource); 1808 value=(unsigned char *) LockResource(global); 1809 if (!value) 1810 { 1811 FreeResource(global); 1812 return((unsigned char *) NULL); 1813 } 1814 blob=(unsigned char *) AcquireQuantumMemory(length+MaxTextExtent, 1815 sizeof(*blob)); 1816 if (blob != (unsigned char *) NULL) 1817 { 1818 (void) CopyMagickMemory(blob,value,length); 1819 blob[length]='\0'; 1820 } 1821 UnlockResource(global); 1822 FreeResource(global); 1823 return(blob); 1824} 1825 1826/* 1827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1828% % 1829% % 1830% % 1831% N T S e e k D i r e c t o r y % 1832% % 1833% % 1834% % 1835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1836% 1837% NTSeekDirectory() sets the position of the next NTReadDirectory() operation 1838% on the directory stream. 1839% 1840% The format of the NTSeekDirectory method is: 1841% 1842% void NTSeekDirectory(DIR *entry,ssize_t position) 1843% 1844% A description of each parameter follows: 1845% 1846% o entry: Specifies a pointer to a DIR structure. 1847% 1848% o position: specifies the position associated with the directory 1849% stream. 1850% 1851*/ 1852MagickExport void NTSeekDirectory(DIR *entry,ssize_t position) 1853{ 1854 (void) position; 1855 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1856 assert(entry != (DIR *) NULL); 1857} 1858 1859/* 1860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1861% % 1862% % 1863% % 1864% N T S e t S e a r c h P a t h % 1865% % 1866% % 1867% % 1868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1869% 1870% NTSetSearchPath() sets the current locations that the subsystem should 1871% look at to find dynamically loadable modules. 1872% 1873% The format of the NTSetSearchPath method is: 1874% 1875% int NTSetSearchPath(const char *path) 1876% 1877% A description of each parameter follows: 1878% 1879% o path: Specifies a pointer to string representing the search path 1880% for DLL's that can be dynamically loaded. 1881% 1882*/ 1883MagickExport int NTSetSearchPath(const char *path) 1884{ 1885#if defined(MAGICKCORE_LTDL_DELEGATE) 1886 lt_dlsetsearchpath(path); 1887#else 1888 if (lt_slsearchpath != (char *) NULL) 1889 lt_slsearchpath=DestroyString(lt_slsearchpath); 1890 if (path != (char *) NULL) 1891 lt_slsearchpath=AcquireString(path); 1892#endif 1893 return(0); 1894} 1895 1896/* 1897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1898% % 1899% % 1900% % 1901+ N T S y n c M e m o r y % 1902% % 1903% % 1904% % 1905%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1906% 1907% NTSyncMemory() emulates the Unix method of the same name. 1908% 1909% The format of the NTSyncMemory method is: 1910% 1911% int NTSyncMemory(void *address,size_t length,int flags) 1912% 1913% A description of each parameter follows: 1914% 1915% o address: the address of the binary large object. 1916% 1917% o length: the length of the binary large object. 1918% 1919% o flags: Option flags (ignored for Windows). 1920% 1921*/ 1922MagickExport int NTSyncMemory(void *address,size_t length,int flags) 1923{ 1924 (void) flags; 1925 if (FlushViewOfFile(address,length) == MagickFalse) 1926 return(-1); 1927 return(0); 1928} 1929 1930/* 1931%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1932% % 1933% % 1934% % 1935% N T S y s t e m C o m m a n d % 1936% % 1937% % 1938% % 1939%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1940% 1941% NTSystemCommand() executes the specified command and waits until it 1942% terminates. The returned value is the exit status of the command. 1943% 1944% The format of the NTSystemCommand method is: 1945% 1946% int NTSystemCommand(MagickFalse,const char *command) 1947% 1948% A description of each parameter follows: 1949% 1950% o command: This string is the command to execute. 1951% 1952*/ 1953MagickExport int NTSystemCommand(const char *command) 1954{ 1955 char 1956 local_command[MaxTextExtent]; 1957 1958 DWORD 1959 child_status; 1960 1961 int 1962 status; 1963 1964 MagickBooleanType 1965 background_process; 1966 1967 PROCESS_INFORMATION 1968 process_info; 1969 1970 STARTUPINFO 1971 startup_info; 1972 1973 if (command == (char *) NULL) 1974 return(-1); 1975 GetStartupInfo(&startup_info); 1976 startup_info.dwFlags=STARTF_USESHOWWINDOW; 1977 startup_info.wShowWindow=SW_SHOWMINNOACTIVE; 1978 (void) CopyMagickString(local_command,command,MaxTextExtent); 1979 background_process=command[strlen(command)-1] == '&' ? MagickTrue : 1980 MagickFalse; 1981 if (background_process) 1982 local_command[strlen(command)-1]='\0'; 1983 if (command[strlen(command)-1] == '|') 1984 local_command[strlen(command)-1]='\0'; 1985 else 1986 startup_info.wShowWindow=SW_SHOWDEFAULT; 1987 status=CreateProcess((LPCTSTR) NULL,local_command, 1988 (LPSECURITY_ATTRIBUTES) NULL,(LPSECURITY_ATTRIBUTES) NULL,(BOOL) FALSE, 1989 (DWORD) NORMAL_PRIORITY_CLASS,(LPVOID) NULL,(LPCSTR) NULL,&startup_info, 1990 &process_info); 1991 if (status == 0) 1992 return(-1); 1993 if (background_process) 1994 return(status == 0); 1995 status=WaitForSingleObject(process_info.hProcess,INFINITE); 1996 if (status != WAIT_OBJECT_0) 1997 return(status); 1998 status=GetExitCodeProcess(process_info.hProcess,&child_status); 1999 if (status == 0) 2000 return(-1); 2001 CloseHandle(process_info.hProcess); 2002 CloseHandle(process_info.hThread); 2003 return((int) child_status); 2004} 2005 2006/* 2007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2008% % 2009% % 2010% % 2011% N T S y s t e m C o n i f i g u r a t i o n % 2012% % 2013% % 2014% % 2015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2016% 2017% NTSystemConfiguration() provides a way for the application to determine 2018% values for system limits or options at runtime. 2019% 2020% The format of the exit method is: 2021% 2022% ssize_t NTSystemConfiguration(int name) 2023% 2024% A description of each parameter follows: 2025% 2026% o name: _SC_PAGE_SIZE or _SC_PHYS_PAGES. 2027% 2028*/ 2029MagickExport ssize_t NTSystemConfiguration(int name) 2030{ 2031 switch (name) 2032 { 2033 case _SC_PAGESIZE: 2034 { 2035 SYSTEM_INFO 2036 system_info; 2037 2038 GetSystemInfo(&system_info); 2039 return(system_info.dwPageSize); 2040 } 2041 case _SC_PHYS_PAGES: 2042 { 2043 HMODULE 2044 handle; 2045 2046 LPFNDLLFUNC2 2047 module; 2048 2049 NTMEMORYSTATUSEX 2050 status; 2051 2052 SYSTEM_INFO 2053 system_info; 2054 2055 handle=GetModuleHandle("kernel32.dll"); 2056 if (handle == (HMODULE) NULL) 2057 return(0L); 2058 GetSystemInfo(&system_info); 2059 module=(LPFNDLLFUNC2) NTGetLibrarySymbol(handle,"GlobalMemoryStatusEx"); 2060 if (module == (LPFNDLLFUNC2) NULL) 2061 { 2062 MEMORYSTATUS 2063 status; 2064 2065 GlobalMemoryStatus(&status); 2066 return((ssize_t) status.dwTotalPhys/system_info.dwPageSize); 2067 } 2068 status.dwLength=sizeof(status); 2069 if (module(&status) == 0) 2070 return(0L); 2071 return((ssize_t) status.ullTotalPhys/system_info.dwPageSize); 2072 } 2073 case _SC_OPEN_MAX: 2074 return(2048); 2075 default: 2076 break; 2077 } 2078 return(-1); 2079} 2080 2081/* 2082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2083% % 2084% % 2085% % 2086% N T T e l l D i r e c t o r y % 2087% % 2088% % 2089% % 2090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2091% 2092% NTTellDirectory() returns the current location associated with the named 2093% directory stream. 2094% 2095% The format of the NTTellDirectory method is: 2096% 2097% ssize_t NTTellDirectory(DIR *entry) 2098% 2099% A description of each parameter follows: 2100% 2101% o entry: Specifies a pointer to a DIR structure. 2102% 2103*/ 2104MagickExport ssize_t NTTellDirectory(DIR *entry) 2105{ 2106 assert(entry != (DIR *) NULL); 2107 return(0); 2108} 2109 2110/* 2111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2112% % 2113% % 2114% % 2115% N T T r u n c a t e F i l e % 2116% % 2117% % 2118% % 2119%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2120% 2121% NTTruncateFile() truncates a file to a specified length. 2122% 2123% The format of the NTTruncateFile method is: 2124% 2125% int NTTruncateFile(int file,off_t length) 2126% 2127% A description of each parameter follows: 2128% 2129% o file: the file. 2130% 2131% o length: the file length. 2132% 2133*/ 2134MagickExport int NTTruncateFile(int file,off_t length) 2135{ 2136 DWORD 2137 file_pointer; 2138 2139 long 2140 file_handle, 2141 high, 2142 low; 2143 2144 file_handle=_get_osfhandle(file); 2145 if (file_handle == -1L) 2146 return(-1); 2147 low=(long) (length & 0xffffffffUL); 2148 high=(long) ((((MagickOffsetType) length) >> 32) & 0xffffffffUL); 2149 file_pointer=SetFilePointer((HANDLE) file_handle,low,&high,FILE_BEGIN); 2150 if ((file_pointer == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) 2151 return(-1); 2152 if (SetEndOfFile((HANDLE) file_handle) == 0) 2153 return(-1); 2154 return(0); 2155} 2156 2157/* 2158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2159% % 2160% % 2161% % 2162+ N T U n m a p M e m o r y % 2163% % 2164% % 2165% % 2166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2167% 2168% NTUnmapMemory() emulates the Unix munmap method. 2169% 2170% The format of the NTUnmapMemory method is: 2171% 2172% int NTUnmapMemory(void *map,size_t length) 2173% 2174% A description of each parameter follows: 2175% 2176% o map: the address of the binary large object. 2177% 2178% o length: the length of the binary large object. 2179% 2180*/ 2181MagickExport int NTUnmapMemory(void *map,size_t length) 2182{ 2183 (void) length; 2184 if (UnmapViewOfFile(map) == 0) 2185 return(-1); 2186 return(0); 2187} 2188 2189/* 2190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2191% % 2192% % 2193% % 2194% N T U s e r T i m e % 2195% % 2196% % 2197% % 2198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2199% 2200% NTUserTime() returns the total time the process has been scheduled (e.g. 2201% seconds) since the last call to StartTimer(). 2202% 2203% The format of the UserTime method is: 2204% 2205% double NTUserTime(void) 2206% 2207*/ 2208MagickExport double NTUserTime(void) 2209{ 2210 DWORD 2211 status; 2212 2213 FILETIME 2214 create_time, 2215 exit_time; 2216 2217 OSVERSIONINFO 2218 OsVersionInfo; 2219 2220 union 2221 { 2222 FILETIME 2223 filetime; 2224 2225 __int64 2226 filetime64; 2227 } kernel_time; 2228 2229 union 2230 { 2231 FILETIME 2232 filetime; 2233 2234 __int64 2235 filetime64; 2236 } user_time; 2237 2238 OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); 2239 GetVersionEx(&OsVersionInfo); 2240 if (OsVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) 2241 return(NTElapsedTime()); 2242 status=GetProcessTimes(GetCurrentProcess(),&create_time,&exit_time, 2243 &kernel_time.filetime,&user_time.filetime); 2244 if (status != TRUE) 2245 return(0.0); 2246 return((double) 1.0e-7*(kernel_time.filetime64+user_time.filetime64)); 2247} 2248 2249/* 2250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2251% % 2252% % 2253% % 2254% N T W a r n i n g H a n d l e r % 2255% % 2256% % 2257% % 2258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2259% 2260% NTWarningHandler() displays a warning reason. 2261% 2262% The format of the NTWarningHandler method is: 2263% 2264% void NTWarningHandler(const ExceptionType severity,const char *reason, 2265% const char *description) 2266% 2267% A description of each parameter follows: 2268% 2269% o severity: Specifies the numeric warning category. 2270% 2271% o reason: Specifies the reason to display before terminating the 2272% program. 2273% 2274% o description: Specifies any description to the reason. 2275% 2276*/ 2277MagickExport void NTWarningHandler(const ExceptionType severity, 2278 const char *reason,const char *description) 2279{ 2280 char 2281 buffer[2*MaxTextExtent]; 2282 2283 (void) severity; 2284 if (reason == (char *) NULL) 2285 return; 2286 if (description == (char *) NULL) 2287 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(), 2288 reason); 2289 else 2290 (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n", 2291 GetClientName(),reason,description); 2292 (void) MessageBox(NULL,buffer,"ImageMagick Warning",MB_OK | MB_TASKMODAL | 2293 MB_SETFOREGROUND | MB_ICONINFORMATION); 2294} 2295#endif 2296