1 /* $Id: tif_win32.c,v 1.42 2017-01-11 19:02:49 erouault Exp $ */ 2 3 /* 4 * Copyright (c) 1988-1997 Sam Leffler 5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 6 * 7 * Permission to use, copy, modify, distribute, and sell this software and 8 * its documentation for any purpose is hereby granted without fee, provided 9 * that (i) the above copyright notices and this permission notice appear in 10 * all copies of the software and related documentation, and (ii) the names of 11 * Sam Leffler and Silicon Graphics may not be used in any advertising or 12 * publicity relating to the software without the specific, prior written 13 * permission of Sam Leffler and Silicon Graphics. 14 * 15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 18 * 19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 24 * OF THIS SOFTWARE. 25 */ 26 27 /* 28 * TIFF Library Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by 29 * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA 30 */ 31 32 /* 33 CreateFileA/CreateFileW return type 'HANDLE'. 34 35 thandle_t is declared like 36 37 DECLARE_HANDLE(thandle_t); 38 39 in tiffio.h. 40 41 Windows (from winnt.h) DECLARE_HANDLE logic looks like 42 43 #ifdef STRICT 44 typedef void *HANDLE; 45 #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name 46 #else 47 typedef PVOID HANDLE; 48 #define DECLARE_HANDLE(name) typedef HANDLE name 49 #endif 50 51 See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64 52 builds resulting from this. Unfortunately, the proposed patch was lost. 53 54 */ 55 56 #include <precomp.h> 57 58 #include <stdlib.h> 59 #include <windef.h> 60 #include <winbase.h> 61 #include <winuser.h> 62 #include <winnls.h> 63 64 static tmsize_t 65 _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) 66 { 67 /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes 68 * 32bit sizes, so we loop through the data in suitable 32bit sized 69 * chunks */ 70 uint8* ma; 71 uint64 mb; 72 DWORD n; 73 DWORD o; 74 tmsize_t p; 75 ma=(uint8*)buf; 76 mb=size; 77 p=0; 78 while (mb>0) 79 { 80 n=0x80000000UL; 81 if ((uint64)n>mb) 82 n=(DWORD)mb; 83 if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL)) 84 return(0); 85 ma+=o; 86 mb-=o; 87 p+=o; 88 if (o!=n) 89 break; 90 } 91 return(p); 92 } 93 94 static tmsize_t 95 _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) 96 { 97 /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes 98 * 32bit sizes, so we loop through the data in suitable 32bit sized 99 * chunks */ 100 uint8* ma; 101 uint64 mb; 102 DWORD n; 103 DWORD o; 104 tmsize_t p; 105 ma=(uint8*)buf; 106 mb=size; 107 p=0; 108 while (mb>0) 109 { 110 n=0x80000000UL; 111 if ((uint64)n>mb) 112 n=(DWORD)mb; 113 if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL)) 114 return(0); 115 ma+=o; 116 mb-=o; 117 p+=o; 118 if (o!=n) 119 break; 120 } 121 return(p); 122 } 123 124 static uint64 125 _tiffSeekProc(thandle_t fd, uint64 off, int whence) 126 { 127 LARGE_INTEGER offli; 128 DWORD dwMoveMethod; 129 offli.QuadPart = off; 130 switch(whence) 131 { 132 case SEEK_SET: 133 dwMoveMethod = FILE_BEGIN; 134 break; 135 case SEEK_CUR: 136 dwMoveMethod = FILE_CURRENT; 137 break; 138 case SEEK_END: 139 dwMoveMethod = FILE_END; 140 break; 141 default: 142 dwMoveMethod = FILE_BEGIN; 143 break; 144 } 145 offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod); 146 if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR)) 147 offli.QuadPart=0; 148 return(offli.QuadPart); 149 } 150 151 static int 152 _tiffCloseProc(thandle_t fd) 153 { 154 return (CloseHandle(fd) ? 0 : -1); 155 } 156 157 static uint64 158 _tiffSizeProc(thandle_t fd) 159 { 160 ULARGE_INTEGER m; 161 m.LowPart=GetFileSize(fd,&m.HighPart); 162 return(m.QuadPart); 163 } 164 165 static int 166 _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) 167 { 168 (void) fd; 169 (void) pbase; 170 (void) psize; 171 return (0); 172 } 173 174 /* 175 * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>: 176 * 177 * Windows uses both a handle and a pointer for file mapping, 178 * but according to the SDK documentation and Richter's book 179 * "Advanced Windows Programming" it is safe to free the handle 180 * after obtaining the file mapping pointer 181 * 182 * This removes a nasty OS dependency and cures a problem 183 * with Visual C++ 5.0 184 */ 185 static int 186 _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) 187 { 188 uint64 size; 189 tmsize_t sizem; 190 HANDLE hMapFile; 191 192 size = _tiffSizeProc(fd); 193 sizem = (tmsize_t)size; 194 if ((uint64)sizem!=size) 195 return (0); 196 197 /* By passing in 0 for the maximum file size, it specifies that we 198 create a file mapping object for the full file size. */ 199 hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); 200 if (hMapFile == NULL) 201 return (0); 202 *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); 203 CloseHandle(hMapFile); 204 if (*pbase == NULL) 205 return (0); 206 *psize = size; 207 return(1); 208 } 209 210 static void 211 _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) 212 { 213 (void) fd; 214 (void) base; 215 (void) size; 216 } 217 218 static void 219 _tiffUnmapProc(thandle_t fd, void* base, toff_t size) 220 { 221 (void) fd; 222 (void) size; 223 UnmapViewOfFile(base); 224 } 225 226 /* 227 * Open a TIFF file descriptor for read/writing. 228 * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode 229 * string, which forces the file to be opened unmapped. 230 */ 231 TIFF* 232 TIFFFdOpen(int ifd, const char* name, const char* mode) 233 { 234 TIFF* tif; 235 int fSuppressMap; 236 int m; 237 fSuppressMap=0; 238 for (m=0; mode[m]!=0; m++) 239 { 240 if (mode[m]=='u') 241 { 242 fSuppressMap=1; 243 break; 244 } 245 } 246 tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */ 247 _tiffReadProc, _tiffWriteProc, 248 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, 249 fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, 250 fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); 251 if (tif) 252 tif->tif_fd = ifd; 253 return (tif); 254 } 255 256 #ifndef _WIN32_WCE 257 258 /* 259 * Open a TIFF file for read/writing. 260 */ 261 TIFF* 262 TIFFOpen(const char* name, const char* mode) 263 { 264 static const char module[] = "TIFFOpen"; 265 thandle_t fd; 266 int m; 267 DWORD dwMode; 268 TIFF* tif; 269 270 m = _TIFFgetMode(mode, module); 271 272 switch(m) { 273 case O_RDONLY: dwMode = OPEN_EXISTING; break; 274 case O_RDWR: dwMode = OPEN_ALWAYS; break; 275 case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; 276 case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; 277 case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; 278 default: return ((TIFF*)0); 279 } 280 281 fd = (thandle_t)CreateFileA(name, 282 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), 283 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, 284 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, 285 NULL); 286 if (fd == INVALID_HANDLE_VALUE) { 287 TIFFErrorExt(0, module, "%s: Cannot open", name); 288 return ((TIFF *)0); 289 } 290 291 tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */ 292 if(!tif) 293 CloseHandle(fd); 294 return tif; 295 } 296 297 /* 298 * Open a TIFF file with a Unicode filename, for read/writing. 299 */ 300 TIFF* 301 TIFFOpenW(const wchar_t* name, const char* mode) 302 { 303 static const char module[] = "TIFFOpenW"; 304 thandle_t fd; 305 int m; 306 DWORD dwMode; 307 int mbsize; 308 char *mbname; 309 TIFF *tif; 310 311 m = _TIFFgetMode(mode, module); 312 313 switch(m) { 314 case O_RDONLY: dwMode = OPEN_EXISTING; break; 315 case O_RDWR: dwMode = OPEN_ALWAYS; break; 316 case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; 317 case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; 318 case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; 319 default: return ((TIFF*)0); 320 } 321 322 fd = (thandle_t)CreateFileW(name, 323 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), 324 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, 325 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, 326 NULL); 327 if (fd == INVALID_HANDLE_VALUE) { 328 TIFFErrorExt(0, module, "%S: Cannot open", name); 329 return ((TIFF *)0); 330 } 331 332 mbname = NULL; 333 mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); 334 if (mbsize > 0) { 335 mbname = (char *)_TIFFmalloc(mbsize); 336 if (!mbname) { 337 TIFFErrorExt(0, module, 338 "Can't allocate space for filename conversion buffer"); 339 return ((TIFF*)0); 340 } 341 342 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, 343 NULL, NULL); 344 } 345 346 tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */ 347 (mbname != NULL) ? mbname : "<unknown>", mode); 348 if(!tif) 349 CloseHandle(fd); 350 351 _TIFFfree(mbname); 352 353 return tif; 354 } 355 356 #endif /* ndef _WIN32_WCE */ 357 358 void* 359 _TIFFmalloc(tmsize_t s) 360 { 361 if (s == 0) 362 return ((void *) NULL); 363 364 return (malloc((size_t) s)); 365 } 366 367 void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) 368 { 369 if( nmemb == 0 || siz == 0 ) 370 return ((void *) NULL); 371 372 return calloc((size_t) nmemb, (size_t)siz); 373 } 374 375 void 376 _TIFFfree(void* p) 377 { 378 free(p); 379 } 380 381 void* 382 _TIFFrealloc(void* p, tmsize_t s) 383 { 384 return (realloc(p, (size_t) s)); 385 } 386 387 void 388 _TIFFmemset(void* p, int v, tmsize_t c) 389 { 390 memset(p, v, (size_t) c); 391 } 392 393 void 394 _TIFFmemcpy(void* d, const void* s, tmsize_t c) 395 { 396 memcpy(d, s, (size_t) c); 397 } 398 399 int 400 _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) 401 { 402 return (memcmp(p1, p2, (size_t) c)); 403 } 404 405 #ifndef _WIN32_WCE 406 407 #if (_MSC_VER < 1500) 408 # define vsnprintf _vsnprintf 409 #endif 410 411 static void 412 Win32WarningHandler(const char* module, const char* fmt, va_list ap) 413 { 414 #ifndef TIF_PLATFORM_CONSOLE 415 LPTSTR szTitle; 416 LPTSTR szTmp; 417 LPCTSTR szTitleText = "%s Warning"; 418 LPCTSTR szDefaultModule = "LIBTIFF"; 419 LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; 420 SIZE_T nBufSize = (strlen(szTmpModule) + 421 strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char); 422 423 if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL) 424 return; 425 sprintf(szTitle, szTitleText, szTmpModule); 426 szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); 427 vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap); 428 MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION); 429 LocalFree(szTitle); 430 431 return; 432 #else 433 if (module != NULL) 434 fprintf(stderr, "%s: ", module); 435 fprintf(stderr, "Warning, "); 436 vfprintf(stderr, fmt, ap); 437 fprintf(stderr, ".\n"); 438 #endif 439 } 440 TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; 441 442 static void 443 Win32ErrorHandler(const char* module, const char* fmt, va_list ap) 444 { 445 #ifndef TIF_PLATFORM_CONSOLE 446 LPTSTR szTitle; 447 LPTSTR szTmp; 448 LPCTSTR szTitleText = "%s Error"; 449 LPCTSTR szDefaultModule = "LIBTIFF"; 450 LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; 451 SIZE_T nBufSize = (strlen(szTmpModule) + 452 strlen(szTitleText) + strlen(fmt) + 256)*sizeof(char); 453 454 if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, nBufSize)) == NULL) 455 return; 456 sprintf(szTitle, szTitleText, szTmpModule); 457 szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); 458 vsnprintf(szTmp, nBufSize-(strlen(szTitle)+2)*sizeof(char), fmt, ap); 459 MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION); 460 LocalFree(szTitle); 461 return; 462 #else 463 if (module != NULL) 464 fprintf(stderr, "%s: ", module); 465 vfprintf(stderr, fmt, ap); 466 fprintf(stderr, ".\n"); 467 #endif 468 } 469 TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; 470 471 #endif /* ndef _WIN32_WCE */ 472 473 /* vim: set ts=8 sts=8 sw=8 noet: */ 474 /* 475 * Local Variables: 476 * mode: c 477 * c-basic-offset: 8 478 * fill-column: 78 479 * End: 480 */ 481