1355604Sdelphij/*
2355604Sdelphij                            __  __            _
3355604Sdelphij                         ___\ \/ /_ __   __ _| |_
4355604Sdelphij                        / _ \\  /| '_ \ / _` | __|
5355604Sdelphij                       |  __//  \| |_) | (_| | |_
6355604Sdelphij                        \___/_/\_\ .__/ \__,_|\__|
7355604Sdelphij                                 |_| XML parser
8355604Sdelphij
9355604Sdelphij   Copyright (c) 1997-2000 Thai Open Source Software Center Ltd
10355604Sdelphij   Copyright (c) 2000-2017 Expat development team
11355604Sdelphij   Licensed under the MIT license:
12355604Sdelphij
13355604Sdelphij   Permission is  hereby granted,  free of charge,  to any  person obtaining
14355604Sdelphij   a  copy  of  this  software   and  associated  documentation  files  (the
15355604Sdelphij   "Software"),  to  deal in  the  Software  without restriction,  including
16355604Sdelphij   without  limitation the  rights  to use,  copy,  modify, merge,  publish,
17355604Sdelphij   distribute, sublicense, and/or sell copies of the Software, and to permit
18355604Sdelphij   persons  to whom  the Software  is  furnished to  do so,  subject to  the
19355604Sdelphij   following conditions:
20355604Sdelphij
21355604Sdelphij   The above copyright  notice and this permission notice  shall be included
22355604Sdelphij   in all copies or substantial portions of the Software.
23355604Sdelphij
24355604Sdelphij   THE  SOFTWARE  IS  PROVIDED  "AS  IS",  WITHOUT  WARRANTY  OF  ANY  KIND,
25355604Sdelphij   EXPRESS  OR IMPLIED,  INCLUDING  BUT  NOT LIMITED  TO  THE WARRANTIES  OF
26355604Sdelphij   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
27355604Sdelphij   NO EVENT SHALL THE AUTHORS OR  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28355604Sdelphij   DAMAGES OR  OTHER LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT,  TORT OR
29355604Sdelphij   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
30355604Sdelphij   USE OR OTHER DEALINGS IN THE SOFTWARE.
31104349Sphk*/
32104349Sphk
33104349Sphk#define STRICT 1
34104349Sphk#define WIN32_LEAN_AND_MEAN 1
35104349Sphk
36104349Sphk#ifdef XML_UNICODE_WCHAR_T
37355604Sdelphij#  ifndef XML_UNICODE
38355604Sdelphij#    define XML_UNICODE
39355604Sdelphij#  endif
40104349Sphk#endif
41104349Sphk
42104349Sphk#ifdef XML_UNICODE
43355604Sdelphij#  define UNICODE
44355604Sdelphij#  define _UNICODE
45104349Sphk#endif /* XML_UNICODE */
46104349Sphk#include <windows.h>
47104349Sphk#include <stdio.h>
48104349Sphk#include <tchar.h>
49104349Sphk#include "filemap.h"
50104349Sphk
51104349Sphkstatic void win32perror(const TCHAR *);
52104349Sphk
53104349Sphkint
54104349Sphkfilemap(const TCHAR *name,
55104349Sphk        void (*processor)(const void *, size_t, const TCHAR *, void *arg),
56355604Sdelphij        void *arg) {
57104349Sphk  HANDLE f;
58104349Sphk  HANDLE m;
59104349Sphk  DWORD size;
60104349Sphk  DWORD sizeHi;
61104349Sphk  void *p;
62104349Sphk
63104349Sphk  f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
64355604Sdelphij                 FILE_FLAG_SEQUENTIAL_SCAN, NULL);
65104349Sphk  if (f == INVALID_HANDLE_VALUE) {
66104349Sphk    win32perror(name);
67104349Sphk    return 0;
68104349Sphk  }
69104349Sphk  size = GetFileSize(f, &sizeHi);
70104349Sphk  if (size == (DWORD)-1) {
71104349Sphk    win32perror(name);
72355604Sdelphij    CloseHandle(f);
73104349Sphk    return 0;
74104349Sphk  }
75355604Sdelphij  if (sizeHi || (size > XML_MAX_CHUNK_LEN)) {
76355604Sdelphij    CloseHandle(f);
77355604Sdelphij    return 2; /* Cannot be passed to XML_Parse in one go */
78104349Sphk  }
79104349Sphk  /* CreateFileMapping barfs on zero length files */
80104349Sphk  if (size == 0) {
81104349Sphk    static const char c = '\0';
82104349Sphk    processor(&c, 0, name, arg);
83104349Sphk    CloseHandle(f);
84104349Sphk    return 1;
85104349Sphk  }
86104349Sphk  m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
87104349Sphk  if (m == NULL) {
88104349Sphk    win32perror(name);
89104349Sphk    CloseHandle(f);
90104349Sphk    return 0;
91104349Sphk  }
92104349Sphk  p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0);
93104349Sphk  if (p == NULL) {
94104349Sphk    win32perror(name);
95104349Sphk    CloseHandle(m);
96104349Sphk    CloseHandle(f);
97104349Sphk    return 0;
98104349Sphk  }
99355604Sdelphij  processor(p, size, name, arg);
100104349Sphk  UnmapViewOfFile(p);
101104349Sphk  CloseHandle(m);
102104349Sphk  CloseHandle(f);
103104349Sphk  return 1;
104104349Sphk}
105104349Sphk
106104349Sphkstatic void
107355604Sdelphijwin32perror(const TCHAR *s) {
108104349Sphk  LPVOID buf;
109355604Sdelphij  if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
110355604Sdelphij                    NULL, GetLastError(),
111355604Sdelphij                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0,
112104349Sphk                    NULL)) {
113104349Sphk    _ftprintf(stderr, _T("%s: %s"), s, buf);
114104349Sphk    fflush(stderr);
115104349Sphk    LocalFree(buf);
116355604Sdelphij  } else
117104349Sphk    _ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
118104349Sphk}
119