2 * emul_handler_native.c
5 * Created by Daniel Oberhoff on 06.04.08.
6 * Copyright 2008 __MyCompanyName__. All rights reserved.
10 #define _WIN32_IE 0x0500
15 #include <sys/types.h>
16 #include <sys/param.h>
24 #include "dos_native.h"
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
},
47 /* Make unix protection bits out of AROS protection bits. */
48 mode_t
prot_a2u(ULONG protect
)
52 /* The following three flags are low-active! */
53 if (!(protect
& FIBF_EXECUTE
))
55 if (!(protect
& FIBF_WRITE
))
57 if (!(protect
& FIBF_READ
))
60 /*if ((protect & FIBF_GRP_EXECUTE))
62 if ((protect & FIBF_GRP_WRITE))
64 if ((protect & FIBF_GRP_READ))
67 if ((protect & FIBF_OTR_EXECUTE))
69 if ((protect & FIBF_OTR_WRITE))
71 if ((protect & FIBF_OTR_READ))
74 if ((protect & FIBF_SCRIPT))
80 /*********************************************************************************************/
82 /* Make AROS protection bits out of unix protection bits. */
83 ULONG
prot_u2a(mode_t protect
)
87 /* The following three (AROS) flags are low-active! */
88 if (!(protect
& S_IRUSR
))
90 if (!(protect
& S_IWUSR
))
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;*/
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
)
131 char * __declspec(dllexport
) EmulGetCWD(char *buf
, long len
)
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);
145 flags
|=mode
&FMF_READ
?O_RDWR
:O_WRONLY
;
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
)
177 protect
= prot_a2u(protect
);
180 r
= chmod(path
, protect
);
185 int __declspec(dllexport
) EmulIsatty(int fd
)
190 int __declspec(dllexport
) EmulChDir(const char *path
)
196 int __declspec(dllexport
) EmulStatFS(const char *path
, struct InfoData
*id
)
201 DWORD SectorsPerCluster
, BytesPerSector
, FreeBlocks
;
203 LPTSTR newbuf
= NULL
;
205 D(printf("[EmulHandler] StatFS(\"%s\")\n", path
));
206 buflen
= GetFullPathName(path
, sizeof(buf
), buf
, &c
);
208 if (buflen
> sizeof(buf
)) {
209 newbuf
= LocalAlloc(LMEM_FIXED
, buflen
);
211 GetFullPathName(path
, buflen
, newbuf
, &c
);
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
++) {
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
;
235 SetLastError(ERROR_BAD_PATHNAME
);
242 unsigned long __declspec(dllexport
) EmulGetHome(const char *name
, char *home
)
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
);
249 return AROS_ERROR_OBJECT_NOT_FOUND
;
254 void __declspec(dllexport
) EmulDelete(const char *filename
)
257 if (!stat(filename
,&st
))
259 if (S_ISDIR(st
.st_mode
))
266 const char * __declspec(dllexport
) EmulDirName(void *dir
)
268 struct dirent
* entry
= readdir((DIR *)dir
);
269 const char * name
= entry
? entry
->d_name
: NULL
;
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
;
305 FIB
->fib_DirEntryType
= ST_FILE
;
309 int __declspec(dllexport
) EmulStat(const char *path
, struct FileInfoBlock
*FIB
)
312 int retval
= stat(path
,&st
);
315 D(printf("[EmulHandler] stat(%s) returned %i kind: ",path
,retval
));
320 D(printf("regular\n"));
321 } else if (S_ISDIR(m
)) {
323 D(printf("directory\n"));
326 D(printf("other\n"));
329 D(else printf("unknown or not existing\n");)
337 int __declspec(dllexport
) EmulRename(const char *spath
, const char *dpath
)
339 return rename(spath
,dpath
);
342 int __declspec(dllexport
) EmulErrno(void)
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
++)
350 D(printf("[EmulHandler] Translated to AROS error code: %lu\n", u2a
[i
][1]));
353 D(printf("[EmulHandler] Unknown error code\n"));
354 #if PassThroughErrnos
355 return e
+PassThroughErrnos
;
357 return ERROR_UNKNOWN
;