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
23static void win32perror(const TCHAR *);
24
25int
26filemap(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
78static void
79win32perror(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