xref: /freebsd/contrib/expat/xmlwf/win32filemap.c (revision cc16dea626cf2fc80cde667ac4798065108e596c)
1 /* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2    See the file COPYING for copying permission.
3 */
4 
5 #define STRICT 1
6 #define WIN32_LEAN_AND_MEAN 1
7 
8 #ifdef XML_UNICODE_WCHAR_T
9 #ifndef XML_UNICODE
10 #define XML_UNICODE
11 #endif
12 #endif
13 
14 #ifdef XML_UNICODE
15 #define UNICODE
16 #define _UNICODE
17 #endif /* XML_UNICODE */
18 #include <windows.h>
19 #include <stdio.h>
20 #include <tchar.h>
21 #include "filemap.h"
22 
23 static void win32perror(const TCHAR *);
24 
25 int
26 filemap(const TCHAR *name,
27         void (*processor)(const void *, size_t, const TCHAR *, void *arg),
28         void *arg)
29 {
30   HANDLE f;
31   HANDLE m;
32   DWORD size;
33   DWORD sizeHi;
34   void *p;
35 
36   f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
37                           FILE_FLAG_SEQUENTIAL_SCAN, NULL);
38   if (f == INVALID_HANDLE_VALUE) {
39     win32perror(name);
40     return 0;
41   }
42   size = GetFileSize(f, &sizeHi);
43   if (size == (DWORD)-1) {
44     win32perror(name);
45     return 0;
46   }
47   if (sizeHi) {
48     _ftprintf(stderr, _T("%s: bigger than 2Gb\n"), name);
49     return 0;
50   }
51   /* CreateFileMapping barfs on zero length files */
52   if (size == 0) {
53     static const char c = '\0';
54     processor(&c, 0, name, arg);
55     CloseHandle(f);
56     return 1;
57   }
58   m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
59   if (m == NULL) {
60     win32perror(name);
61     CloseHandle(f);
62     return 0;
63   }
64   p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0);
65   if (p == NULL) {
66     win32perror(name);
67     CloseHandle(m);
68     CloseHandle(f);
69     return 0;
70   }
71   processor(p, size, name, arg);
72   UnmapViewOfFile(p);
73   CloseHandle(m);
74   CloseHandle(f);
75   return 1;
76 }
77 
78 static void
79 win32perror(const TCHAR *s)
80 {
81   LPVOID buf;
82   if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
83                     | FORMAT_MESSAGE_FROM_SYSTEM,
84                     NULL,
85                     GetLastError(),
86                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
87                     (LPTSTR) &buf,
88                     0,
89                     NULL)) {
90     _ftprintf(stderr, _T("%s: %s"), s, buf);
91     fflush(stderr);
92     LocalFree(buf);
93   }
94   else
95     _ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
96 }
97