1 /*        $NetBSD: winfs.c,v 1.5 2009/03/14 21:04:09 dsl Exp $        */
2 
3 /*-
4  * Copyright (c) 1999 Shin Takemura.
5  * All rights reserved.
6  *
7  * This software is part of the PocketBSD.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *        This product includes software developed by the PocketBSD project
20  *        and its contributors.
21  * 4. Neither the name of the project nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  */
38 #define STANDALONE_WINDOWS_SIDE
39 #include <stand.h>
40 #include <winfs.h>
41 
42 #define MAXPATHLEN 1024
43 
44 /*
45  *  file system specific context.
46  */
47 struct winfs {
48           HANDLE    hDevice;
49 };
50 
51 
52 int
win_open(char * path,struct open_file * f)53 win_open(char *path, struct open_file *f)
54 {
55           TCHAR *wpath = (TCHAR*)path;
56           struct winfs *fsdata;
57 
58           fsdata = (struct winfs *)alloc(sizeof(*fsdata));
59           if (!fsdata) {
60                     return (ENOMEM);
61           }
62 
63           win_printf(TEXT("open(%s)\n"), wpath);
64           fsdata->hDevice = CreateFile(wpath, GENERIC_READ, 0, NULL,
65                                             OPEN_EXISTING, 0, NULL);
66           if (fsdata->hDevice == INVALID_HANDLE_VALUE) {
67                     win_printf(TEXT("can't open %s.\n"), wpath);
68                     dealloc(fsdata, sizeof(*fsdata));
69                     return (EIO);       /* XXX, We shuld check GetLastError(). */
70           }
71 
72           f->f_fsdata = (void *)fsdata;
73 
74           return (0);
75 }
76 
77 
78 int
win_close(struct open_file * f)79 win_close(struct open_file *f)
80 {
81           struct winfs *fsdata = (struct winfs *) f->f_fsdata;
82 
83           if (fsdata->hDevice != INVALID_HANDLE_VALUE) {
84                     CloseHandle(fsdata->hDevice);
85           }
86           dealloc(fsdata, sizeof(*fsdata));
87 
88           return (0);
89 }
90 
91 
92 int
win_read(struct open_file * f,void * addr,size_t size,size_t * resid)93 win_read(struct open_file *f, void *addr, size_t size, size_t *resid)
94           /* resid:  out */
95 {
96           struct winfs *fsdata = (struct winfs *) f->f_fsdata;
97           DWORD read_len;
98 
99           while (size > 0) {
100                     if (!ReadFile(fsdata->hDevice,
101                                     (u_char*)addr, size,
102                                     &read_len, NULL)) {
103                               win_printf(TEXT("ReadFile() failed.\n"));
104                     }
105 
106                     if (read_len == 0)
107                               break;    /* EOF */
108 
109                     (unsigned long)addr += read_len;
110                     size -= read_len;
111           }
112 
113           if (resid)
114                     *resid = size;
115           return (0);
116 }
117 
118 int
win_write(struct open_file * f,void * start,size_t size,size_t * resid)119 win_write(struct open_file *f, void *start, size_t size, size_t *resid)
120           /* resid:  out */
121 {
122           return (EROFS);     /* XXX */
123 }
124 
125 
126 int
win_stat(struct open_file * f,struct stat * sb)127 win_stat(struct open_file *f, struct stat *sb)
128 {
129           sb->st_mode = 0444;
130           sb->st_nlink = 1;
131           sb->st_uid = 0;
132           sb->st_gid = 0;
133           sb->st_size = -1;
134           return (0);
135 }
136 
137 off_t
win_seek(struct open_file * f,off_t offset,int whence)138 win_seek(struct open_file *f, off_t offset, int whence)
139 {
140           struct winfs *fsdata = (struct winfs *) f->f_fsdata;
141           DWORD dwPointer;
142           int winwhence;
143 
144           switch (whence) {
145           case SEEK_SET:
146                     winwhence = FILE_BEGIN;
147                     break;
148           case SEEK_CUR:
149                     winwhence = FILE_CURRENT;
150                     break;
151           case SEEK_END:
152                     winwhence = FILE_END;
153                     break;
154           default:
155                     errno = EOFFSET;
156                     return (-1);
157           }
158 
159           dwPointer = SetFilePointer(fsdata->hDevice, offset, NULL, winwhence);
160           if (dwPointer == 0xffffffff) {
161                     errno = EINVAL;     /* XXX, We shuld check GetLastError(). */
162                     return (-1);
163           }
164 
165           return (0);
166 }
167