Update for Dokany v1.0.0 RC2 (Windows) (#22)

* Fix compile error MaybeLocal not directly castable to Local

* Fix support for Dokany 1.0.0-RC2

* Fix pre-Visual Studio 2015 lacking struct timespec

* Add explanatory comment for #define FUSE_STAT

* Update README with new Windows info

* Tweak README Windows section a bit
Raymond Hammarling 8 years ago committed by Mathias Buus
parent 00acbbb310
commit 4af46f1f9d

@ -17,14 +17,16 @@ You need to have FUSE installed (or Dokany on Windows)
* On OSX
* if you use Brew, install [OSXFuse](http://osxfuse.github.com/) and `brew install pkg-config`
* if you use MacPorts, `sudo port install osxfuse +devel`
* On Windows see `Windows` down below...
* On Windows install [Dokany](https://github.com/dokan-dev/dokany)
### Windows
**WARNING**: Dokany is still not quite stable. It can cause BSODs. Be careful.
Using this on Windows is slightly more complicated. You need to install [Dokany](https://github.com/dokan-dev/dokany) (for `dokanfuse.lib`, `dokanctl.exe`, driver and service) **and** clone its repo (for the headers).
~~Using this on Windows is slightly more complicated. You need to install [Dokany](https://github.com/dokan-dev/dokany) (for `dokanfuse.lib`, `dokanctl.exe`, driver and service) **and** clone its repo (for the headers).~~
Once the Dokany repo is cloned, you also need to set environment variable `DOKAN_INSTALL_DIR` to the path to `DokenLibrary` of your Dokany installaton, and `DOKAN_FUSE_INCLUDE` to the path to `*dokany repo*\dokan_fuse\include`.
~~Once the Dokany repo is cloned, you also need to set environment variable `DOKAN_INSTALL_DIR` to the path to `DokenLibrary` of your Dokany installaton, and `DOKAN_FUSE_INCLUDE` to the path to `*dokany repo*\dokan_fuse\include`.~~
**EDIT**: Dokany now includes needed headers and sets proper environment variables when installing! Just install Dokany and this module should install and work just fine! (Drop an issue otherwise)
## Usage

@ -62,10 +62,18 @@ void thread_join (HANDLE thread) {
}
int fusermount (char *path) {
char* dokanPath = getenv("DOKAN_INSTALL_DIR");
char* dokanPath = getenv("DokanLibrary1");
char cmdLine[MAX_PATH];
if(dokanPath) sprintf(cmdLine, "\"%s/dokanctl.exe\" /u %s", dokanPath, path);
if(dokanPath) {
// Let's make sure there aren't no double slashes
const char* dokanPathLast = dokanPath + strlen(dokanPath) - 1;
const char* potentialEndSlash =
(*dokanPathLast == '/' || *dokanPathLast == '\\') ? "" : "\\";
sprintf(cmdLine, "\"%s%sdokanctl.exe\" /u %s", dokanPath, potentialEndSlash, path);
}
else sprintf(cmdLine, "dokanctl.exe /u %s", path);
STARTUPINFO info = {sizeof(info)};

@ -26,15 +26,25 @@
}
}],
['OS=="win"', {
"variables": {
'dokan__install_dir%': '$(DokanLibrary1)/include/fuse'
},
"include_dirs": [
"$(DOKAN_FUSE_INCLUDE)",
"<(dokan__install_dir)",
"$(INCLUDE)"
],
"link_settings": {
"libraries": [
"<!(echo %DOKAN_INSTALL_DIR%)/dokanfuse.lib"
"<(dokan__library)"
]
}
},
"conditions": [
['target_arch=="x64"', {
"variables": { 'dokan__library%': '$(DokanLibrary1_LibraryPath_x64)/dokanfuse1' }
}, {
"variables": { 'dokan__library%': '$(DokanLibrary1_LibraryPath_x86)/dokanfuse1' }
}]
]
}]
],
"configurations": {

@ -2,9 +2,23 @@
#define FUSE_USE_VERSION 29
#if defined(_WIN32) && _MSC_VER < 1900
// Visual Studio 2015 adds struct timespec,
// this #define will make Dokany define its
// own struct timespec on earlier versions
#define _CRT_NO_TIME_T
#endif
#include <fuse.h>
#include <fuse_opt.h>
#ifndef _MSC_VER
// Need to use FUSE_STAT when using Dokany with Visual Studio.
// To keep things simple, when not using Visual Studio,
// define FUSE_STAT to be "stat" so we can use FUSE_STAT in the code anyway.
#define FUSE_STAT stat
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
@ -56,7 +70,7 @@ enum bindings_ops_t {
static Nan::Persistent<Function> buffer_constructor;
static Nan::Callback *callback_constructor;
static struct stat empty_stat;
static struct FUSE_STAT empty_stat;
struct bindings_t {
int index;
@ -220,7 +234,7 @@ static int bindings_ftruncate (const char *path, FUSE_OFF_T size, struct fuse_fi
return bindings_call(b);
}
static int bindings_getattr (const char *path, struct stat *stat) {
static int bindings_getattr (const char *path, struct FUSE_STAT *stat) {
bindings_t *b = bindings_get_context();
b->op = OP_GETATTR;
@ -230,7 +244,7 @@ static int bindings_getattr (const char *path, struct stat *stat) {
return bindings_call(b);
}
static int bindings_fgetattr (const char *path, struct stat *stat, struct fuse_file_info *info) {
static int bindings_fgetattr (const char *path, struct FUSE_STAT *stat, struct fuse_file_info *info) {
bindings_t *b = bindings_get_context();
b->op = OP_FGETATTR;
@ -679,7 +693,6 @@ static thread_fn_rtn_t bindings_thread (void *data) {
return 0;
}
#ifndef _WIN32
NAN_INLINE static Local<Date> bindings_get_date (struct timespec *out) {
int ms = (out->tv_nsec / 1000);
return Nan::New<Date>(out->tv_sec * 1000 + ms).ToLocalChecked();
@ -693,19 +706,8 @@ NAN_INLINE static void bindings_set_date (struct timespec *out, Local<Date> date
out->tv_sec = secs;
out->tv_nsec = ns;
}
#else
NAN_INLINE static Local<Date> bindings_get_date (time_t *out) {
return Nan::New<Date>(*out * 1000.0);
}
NAN_INLINE static void bindings_set_date (time_t *out, Local<Date> date) {
double ms = date->NumberValue();
time_t secs = (time_t)(ms / 1000.0);
*out = secs;
}
#endif
NAN_INLINE static void bindings_set_stat (struct stat *stat, Local<Object> obj) {
NAN_INLINE static void bindings_set_stat (struct FUSE_STAT *stat, Local<Object> obj) {
if (obj->Has(LOCAL_STRING("dev"))) stat->st_dev = obj->Get(LOCAL_STRING("dev"))->NumberValue();
if (obj->Has(LOCAL_STRING("ino"))) stat->st_ino = obj->Get(LOCAL_STRING("ino"))->NumberValue();
if (obj->Has(LOCAL_STRING("mode"))) stat->st_mode = obj->Get(LOCAL_STRING("mode"))->Uint32Value();
@ -714,18 +716,12 @@ NAN_INLINE static void bindings_set_stat (struct stat *stat, Local<Object> obj)
if (obj->Has(LOCAL_STRING("gid"))) stat->st_gid = obj->Get(LOCAL_STRING("gid"))->NumberValue();
if (obj->Has(LOCAL_STRING("rdev"))) stat->st_rdev = obj->Get(LOCAL_STRING("rdev"))->NumberValue();
if (obj->Has(LOCAL_STRING("size"))) stat->st_size = obj->Get(LOCAL_STRING("size"))->NumberValue();
#ifndef _WIN32
if (obj->Has(LOCAL_STRING("blocks"))) stat->st_blocks = obj->Get(LOCAL_STRING("blocks"))->NumberValue();
if (obj->Has(LOCAL_STRING("blksize"))) stat->st_blksize = obj->Get(LOCAL_STRING("blksize"))->NumberValue();
#endif
#ifdef __APPLE__
if (obj->Has(LOCAL_STRING("mtime"))) bindings_set_date(&stat->st_mtimespec, obj->Get(LOCAL_STRING("mtime")).As<Date>());
if (obj->Has(LOCAL_STRING("ctime"))) bindings_set_date(&stat->st_ctimespec, obj->Get(LOCAL_STRING("ctime")).As<Date>());
if (obj->Has(LOCAL_STRING("atime"))) bindings_set_date(&stat->st_atimespec, obj->Get(LOCAL_STRING("atime")).As<Date>());
#elif defined(_WIN32)
if (obj->Has(LOCAL_STRING("mtime"))) bindings_set_date(&stat->st_mtime, obj->Get(LOCAL_STRING("mtime")).As<Date>());
if (obj->Has(LOCAL_STRING("ctime"))) bindings_set_date(&stat->st_ctime, obj->Get(LOCAL_STRING("ctime")).As<Date>());
if (obj->Has(LOCAL_STRING("atime"))) bindings_set_date(&stat->st_atime, obj->Get(LOCAL_STRING("atime")).As<Date>());
#else
if (obj->Has(LOCAL_STRING("mtime"))) bindings_set_date(&stat->st_mtim, obj->Get(LOCAL_STRING("mtime")).As<Date>());
if (obj->Has(LOCAL_STRING("ctime"))) bindings_set_date(&stat->st_ctim, obj->Get(LOCAL_STRING("ctime")).As<Date>());
@ -769,7 +765,7 @@ NAN_METHOD(OpCallback) {
case OP_GETATTR:
case OP_FGETATTR: {
if (info.Length() > 2 && info[2]->IsObject()) bindings_set_stat((struct stat *) b->data, info[2].As<Object>());
if (info.Length() > 2 && info[2]->IsObject()) bindings_set_stat((struct FUSE_STAT *) b->data, info[2].As<Object>());
}
break;
@ -1044,11 +1040,7 @@ static void bindings_dispatch (uv_async_t* handle, int status) {
return;
case OP_UTIMENS: {
#ifdef _WIN32
time_t *tv = (time_t *) b->data;
#else
struct timespec *tv = (struct timespec *) b->data;
#endif
Local<Value> tmp[] = {LOCAL_STRING(b->path), bindings_get_date(tv), bindings_get_date(tv + 1), callback};
bindings_call_op(b, b->ops_utimens, 4, tmp);
}

Loading…
Cancel
Save