- Added forgotten PRF_NOTIFYONDEATH definition (Sszymczy, check this!)
[AROS.git] / arch / all-mingw32 / devs / filesys / emul_handler / emul_handler_native.c
blob623c6458372d078155dc0dd393fbd448aec31b66
1 /*
2 * emul_handler_native.c
3 * AROS
5 * Created by Daniel Oberhoff on 06.04.08.
6 * Copyright 2008 __MyCompanyName__. All rights reserved.
8 */
10 #define _WIN32_IE 0x0500
11 #include <windows.h>
12 #include <shlobj.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include <sys/param.h>
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <dirent.h>
20 #include <unistd.h>
21 #include <stdio.h>
22 #include <stdlib.h>
24 #include "dos_native.h"
26 #define ST_ROOT 1
27 #define ST_USERDIR 2
28 #define ST_FILE -3
30 #define D(x) x
32 /* Make an AROS error-code (<dos/dos.h>) out of an Windows error-code. */
33 static DWORD u2a[][2]=
35 { ERROR_NOT_ENOUGH_MEMORY, ERROR_NO_FREE_STORE },
36 { ERROR_FILE_NOT_FOUND, AROS_ERROR_OBJECT_NOT_FOUND },
37 { ERROR_FILE_EXISTS, ERROR_OBJECT_EXISTS },
38 { ERROR_WRITE_PROTECT, ERROR_WRITE_PROTECTED },
39 { ERROR_DISK_FULL, AROS_ERROR_DISK_FULL },
40 { ERROR_DIR_NOT_EMPTY, ERROR_DIRECTORY_NOT_EMPTY },
41 { ERROR_SHARING_VIOLATION, ERROR_OBJECT_IN_USE },
42 { ERROR_LOCK_VIOLATION, ERROR_OBJECT_IN_USE },
43 { ERROR_BUFFER_OVERFLOW, ERROR_OBJECT_TOO_LARGE },
44 { 0, ERROR_UNKNOWN }
47 /* Make unix protection bits out of AROS protection bits. */
48 mode_t prot_a2u(ULONG protect)
50 mode_t uprot = 0;
52 /* The following three flags are low-active! */
53 if (!(protect & FIBF_EXECUTE))
54 uprot |= S_IXUSR;
55 if (!(protect & FIBF_WRITE))
56 uprot |= S_IWUSR;
57 if (!(protect & FIBF_READ))
58 uprot |= S_IRUSR;
60 /*if ((protect & FIBF_GRP_EXECUTE))
61 uprot |= S_IXGRP;
62 if ((protect & FIBF_GRP_WRITE))
63 uprot |= S_IWGRP;
64 if ((protect & FIBF_GRP_READ))
65 uprot |= S_IRGRP;
67 if ((protect & FIBF_OTR_EXECUTE))
68 uprot |= S_IXOTH;
69 if ((protect & FIBF_OTR_WRITE))
70 uprot |= S_IWOTH;
71 if ((protect & FIBF_OTR_READ))
72 uprot |= S_IROTH;
74 if ((protect & FIBF_SCRIPT))
75 uprot |= S_ISVTX;*/
77 return uprot;
80 /*********************************************************************************************/
82 /* Make AROS protection bits out of unix protection bits. */
83 ULONG prot_u2a(mode_t protect)
85 ULONG aprot = 0;
87 /* The following three (AROS) flags are low-active! */
88 if (!(protect & S_IRUSR))
89 aprot |= FIBF_READ;
90 if (!(protect & S_IWUSR))
91 aprot |= FIBF_WRITE;
92 if (!(protect & S_IXUSR))
93 aprot |= FIBF_EXECUTE;
95 /* The following flags are high-active again. */
96 /*if ((protect & S_IRGRP))
97 aprot |= FIBF_GRP_READ;
98 if ((protect & S_IWGRP))
99 aprot |= FIBF_GRP_WRITE;
100 if ((protect & S_IXGRP))
101 aprot |= FIBF_GRP_EXECUTE;
103 if ((protect & S_IROTH))
104 aprot |= FIBF_OTR_READ;
105 if ((protect & S_IWOTH))
106 aprot |= FIBF_OTR_WRITE;
107 if ((protect & S_IXOTH))
108 aprot |= FIBF_OTR_EXECUTE;
110 if ((protect & S_ISVTX))
111 aprot |= FIBF_SCRIPT;*/
113 return aprot;
116 void * __declspec(dllexport) EmulOpenDir(const char *path)
118 return opendir(path);
121 int __declspec(dllexport) EmulCloseDir(void *dir)
123 return closedir((DIR *)dir);
126 int __declspec(dllexport) EmulClose(int fd)
128 return close(fd);
131 char * __declspec(dllexport) EmulGetCWD(char *buf, long len)
133 char * retval = 0;
134 if (buf != 0) //do not alloc mem here!
135 retval = getcwd(buf,len);
136 printf("[EmulHandler] cwd: \"%s\"\n",retval);
137 return (struct TagItem *)retval;
140 int __declspec(dllexport) EmulOpen(const char *path, int mode, int protect)
142 int flags=(mode&FMF_CREATE?O_CREAT:0)|(mode&FMF_CLEAR?O_TRUNC:0);
144 if(mode&FMF_WRITE)
145 flags|=mode&FMF_READ?O_RDWR:O_WRONLY;
146 else
147 flags|=O_RDONLY;
148 protect = prot_a2u(protect);
149 return open(path, flags, protect);
152 long __declspec(dllexport) EmulLSeek(int fd, long offset, long base)
154 return lseek(fd,offset,base);
157 int __declspec(dllexport) EmulRead(int fd, char *buf, long len)
159 return read(fd,buf,len);
162 int __declspec(dllexport) EmulWrite(int fd, char *buf, long len)
164 return write(fd,buf,len);
167 int __declspec(dllexport) EmulChmod(const char *path, int protect)
169 protect = prot_a2u(protect);
170 return chmod(path,protect);
173 int __declspec(dllexport) EmulMKDir(const char *path, int protect)
175 int r;
177 protect = prot_a2u(protect);
178 r = mkdir(path);
179 if (!r)
180 r = chmod(path, protect);
181 return r;
185 int __declspec(dllexport) EmulIsatty(int fd)
187 return isatty(fd);
190 int __declspec(dllexport) EmulChDir(const char *path)
192 return chdir(path);
196 int __declspec(dllexport) EmulStatFS(const char *path, struct InfoData *id)
198 char buf[256];
199 DWORD buflen;
200 LPTSTR c;
201 DWORD SectorsPerCluster, BytesPerSector, FreeBlocks;
202 int retval = 0;
203 LPTSTR newbuf = NULL;
205 D(printf("[EmulHandler] StatFS(\"%s\")\n", path));
206 buflen = GetFullPathName(path, sizeof(buf), buf, &c);
207 if (buflen) {
208 if (buflen > sizeof(buf)) {
209 newbuf = LocalAlloc(LMEM_FIXED, buflen);
210 if (newbuf) {
211 GetFullPathName(path, buflen, newbuf, &c);
212 } else
213 return 0;
214 } else
215 newbuf = buf;
216 D(printf("[EmulHandler] Full path: %s\n", newbuf));
217 /* TODO: this works only with drive letters, no mounts/UNC paths support yet */
218 for (c = newbuf; *c; c++) {
219 if (*c == '\\') {
220 c[1] = 0;
221 break;
224 if (*c) {
225 D(printf("[EmulHandler] Root path: %s\n", newbuf));
226 retval = GetDiskFreeSpace(newbuf, &SectorsPerCluster, &BytesPerSector, &FreeBlocks, &id->id_NumBlocks);
227 id->id_NumSoftErrors = 0;
228 id->id_UnitNumber = 0;
229 id->id_DiskState = ID_VALIDATED;
230 id->id_NumBlocksUsed = id->id_NumBlocks - FreeBlocks;
231 id->id_BytesPerBlock = SectorsPerCluster*BytesPerSector;
232 id->id_DiskType = ID_DOS_DISK;
233 id->id_InUse = TRUE;
234 } else
235 SetLastError(ERROR_BAD_PATHNAME);
236 if (newbuf != buf)
237 LocalFree(newbuf);
239 return retval;
242 unsigned long __declspec(dllexport) EmulGetHome(const char *name, char *home)
244 HRESULT res;
246 /* TODO: currently username is ignored, however we should acquire an access token for it */
247 res = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_DEFAULT, home);
248 if (res)
249 return AROS_ERROR_OBJECT_NOT_FOUND;
250 else
251 return 0;
254 void __declspec(dllexport) EmulDelete(const char *filename)
256 struct stat st;
257 if (!stat(filename,&st))
259 if (S_ISDIR(st.st_mode))
260 rmdir(filename);
261 else
262 unlink(filename);
266 const char * __declspec(dllexport) EmulDirName(void *dir)
268 struct dirent * entry = readdir((DIR *)dir);
269 const char * name = entry ? entry->d_name : NULL;
270 return name;
273 int __declspec(dllexport) EmulTellDir(void *dir)
275 return telldir((DIR *)dir);
278 void __declspec(dllexport) EmulRewindDir(void *dir)
280 rewinddir((DIR *)dir);
283 void __declspec(dllexport) EmulSeekDir(void *dir, long loc)
285 seekdir((DIR *)dir,loc);
288 void stat2FIB(struct stat * s, struct FileInfoBlock * FIB)
290 FIB->fib_OwnerUID = s->st_uid;
291 FIB->fib_OwnerGID = s->st_gid;
292 FIB->fib_Comment[0] = '\0'; /* no comments available yet! */
293 FIB->fib_Date.ds_Days = s->st_ctime/(60*60*24) - (6*365 + 2*366);
294 FIB->fib_Date.ds_Minute = (s->st_ctime/60)%(60*24);
295 FIB->fib_Date.ds_Tick = (s->st_ctime%60)*TICKS_PER_SECOND;
296 FIB->fib_Protection = s->st_mode;
297 FIB->fib_Size = s->st_size;
299 if (S_ISDIR(s->st_mode))
301 FIB->fib_DirEntryType = ST_USERDIR;
303 else
305 FIB->fib_DirEntryType = ST_FILE;
309 int __declspec(dllexport) EmulStat(const char *path, struct FileInfoBlock *FIB)
311 struct stat st;
312 int retval = stat(path,&st);
313 int m = st.st_mode;
315 D(printf("[EmulHandler] stat(%s) returned %i kind: ",path,retval));
316 if (retval == 0)
318 if (S_ISREG(m)) {
319 retval = 1;
320 D(printf("regular\n"));
321 } else if (S_ISDIR(m)) {
322 retval = 2;
323 D(printf("directory\n"));
324 } else {
325 retval = -1;
326 D(printf("other\n"));
329 D(else printf("unknown or not existing\n");)
330 if (FIB)
332 stat2FIB(&st,FIB);
334 return retval;
337 int __declspec(dllexport) EmulRename(const char *spath, const char *dpath)
339 return rename(spath,dpath);
342 int __declspec(dllexport) EmulErrno(void)
344 ULONG i;
345 DWORD e = GetLastError();
347 D(printf("[EmulHandler] Win32 error code: %lu\n", e));
348 for(i=0;i<sizeof(u2a)/sizeof(u2a[0]);i++)
349 if(u2a[i][0]==e) {
350 D(printf("[EmulHandler] Translated to AROS error code: %lu\n", u2a[i][1]));
351 return u2a[i][1];
353 D(printf("[EmulHandler] Unknown error code\n"));
354 #if PassThroughErrnos
355 return e+PassThroughErrnos;
356 #else
357 return ERROR_UNKNOWN;
358 #endif