1104349Sphk/* Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
2104349Sphk   See the file COPYING for copying permission.
3104349Sphk*/
4104349Sphk
5104349Sphk#define STRICT 1
6104349Sphk#define WIN32_LEAN_AND_MEAN 1
7104349Sphk
8104349Sphk#ifdef XML_UNICODE_WCHAR_T
9104349Sphk#ifndef XML_UNICODE
10104349Sphk#define XML_UNICODE
11104349Sphk#endif
12104349Sphk#endif
13104349Sphk
14104349Sphk#ifdef XML_UNICODE
15104349Sphk#define UNICODE
16104349Sphk#define _UNICODE
17104349Sphk#endif /* XML_UNICODE */
18104349Sphk#include <windows.h>
19104349Sphk#include <stdio.h>
20104349Sphk#include <tchar.h>
21104349Sphk#include "filemap.h"
22104349Sphk
23104349Sphkstatic void win32perror(const TCHAR *);
24104349Sphk
25104349Sphkint
26104349Sphkfilemap(const TCHAR *name,
27104349Sphk        void (*processor)(const void *, size_t, const TCHAR *, void *arg),
28104349Sphk        void *arg)
29104349Sphk{
30104349Sphk  HANDLE f;
31104349Sphk  HANDLE m;
32104349Sphk  DWORD size;
33104349Sphk  DWORD sizeHi;
34104349Sphk  void *p;
35104349Sphk
36104349Sphk  f = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
37104349Sphk                          FILE_FLAG_SEQUENTIAL_SCAN, NULL);
38104349Sphk  if (f == INVALID_HANDLE_VALUE) {
39104349Sphk    win32perror(name);
40104349Sphk    return 0;
41104349Sphk  }
42104349Sphk  size = GetFileSize(f, &sizeHi);
43104349Sphk  if (size == (DWORD)-1) {
44104349Sphk    win32perror(name);
45104349Sphk    return 0;
46104349Sphk  }
47104349Sphk  if (sizeHi) {
48104349Sphk    _ftprintf(stderr, _T("%s: bigger than 2Gb\n"), name);
49104349Sphk    return 0;
50104349Sphk  }
51104349Sphk  /* CreateFileMapping barfs on zero length files */
52104349Sphk  if (size == 0) {
53104349Sphk    static const char c = '\0';
54104349Sphk    processor(&c, 0, name, arg);
55104349Sphk    CloseHandle(f);
56104349Sphk    return 1;
57104349Sphk  }
58104349Sphk  m = CreateFileMapping(f, NULL, PAGE_READONLY, 0, 0, NULL);
59104349Sphk  if (m == NULL) {
60104349Sphk    win32perror(name);
61104349Sphk    CloseHandle(f);
62104349Sphk    return 0;
63104349Sphk  }
64104349Sphk  p = MapViewOfFile(m, FILE_MAP_READ, 0, 0, 0);
65104349Sphk  if (p == NULL) {
66104349Sphk    win32perror(name);
67104349Sphk    CloseHandle(m);
68104349Sphk    CloseHandle(f);
69104349Sphk    return 0;
70104349Sphk  }
71104349Sphk  processor(p, size, name, arg);
72104349Sphk  UnmapViewOfFile(p);
73104349Sphk  CloseHandle(m);
74104349Sphk  CloseHandle(f);
75104349Sphk  return 1;
76104349Sphk}
77104349Sphk
78104349Sphkstatic void
79104349Sphkwin32perror(const TCHAR *s)
80104349Sphk{
81104349Sphk  LPVOID buf;
82104349Sphk  if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
83104349Sphk                    | FORMAT_MESSAGE_FROM_SYSTEM,
84104349Sphk                    NULL,
85104349Sphk                    GetLastError(),
86104349Sphk                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
87104349Sphk                    (LPTSTR) &buf,
88104349Sphk                    0,
89104349Sphk                    NULL)) {
90104349Sphk    _ftprintf(stderr, _T("%s: %s"), s, buf);
91104349Sphk    fflush(stderr);
92104349Sphk    LocalFree(buf);
93104349Sphk  }
94104349Sphk  else
95104349Sphk    _ftprintf(stderr, _T("%s: unknown Windows error\n"), s);
96104349Sphk}
97