Commit 282250bb by rfkelly0

dokan: got GetVolumeInformation working

parent 25868cb2
...@@ -118,7 +118,10 @@ GENERIC_WRITE = 1180054 ...@@ -118,7 +118,10 @@ GENERIC_WRITE = 1180054
NATIVE_ENCODING = sys.getfilesystemencoding() NATIVE_ENCODING = sys.getfilesystemencoding()
DATETIME_ZERO = datetime.datetime(1,1,1,0,0,0) DATETIME_ZERO = datetime.datetime(1,1,1,0,0,0)
DATETIME_STARTUP = datetime.datetime.now() DATETIME_STARTUP = datetime.datetime.utcnow()
FILETIME_UNIX_EPOCH = 116444736000000000
def handle_fs_errors(func): def handle_fs_errors(func):
...@@ -229,7 +232,7 @@ class FSOperations(DokanOperations): ...@@ -229,7 +232,7 @@ class FSOperations(DokanOperations):
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
mode = "w+b" mode = "w+b"
else: else:
mode = "ab" mode = "r+b"
else: else:
mode = "rb" mode = "rb"
else: else:
...@@ -240,13 +243,13 @@ class FSOperations(DokanOperations): ...@@ -240,13 +243,13 @@ class FSOperations(DokanOperations):
elif disposition == OPEN_EXISTING: elif disposition == OPEN_EXISTING:
if self.fs.exists(path): if self.fs.exists(path):
retcode = 183 retcode = 183
mode = "ab" mode = "r+b"
elif disposition == TRUNCATE_EXISTING: elif disposition == TRUNCATE_EXISTING:
if not self.fs.exists(path): if not self.fs.exists(path):
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
mode = "w+b" mode = "w+b"
else: else:
mode = "ab" mode = "r+b"
# Try to open the requested file. It may actually be a directory. # Try to open the requested file. It may actually be a directory.
info.contents.Context = 1 info.contents.Context = 1
try: try:
...@@ -412,12 +415,12 @@ class FSOperations(DokanOperations): ...@@ -412,12 +415,12 @@ class FSOperations(DokanOperations):
self.fs.movedir(src,dst,overwrite=overwrite) self.fs.movedir(src,dst,overwrite=overwrite)
@handle_fs_errors @handle_fs_errors
def SetEndOfFile(self, path, dst, overwrite, info): def SetEndOfFile(self, path, length, info):
path = normpath(path) path = normpath(path)
(file,_,lock) = self._get_file(info.contents.Context) (file,_,lock) = self._get_file(info.contents.Context)
lock.acquire() lock.acquire()
try: try:
f.truncate() file.truncate(length)
finally: finally:
lock.release() lock.release()
...@@ -429,14 +432,18 @@ class FSOperations(DokanOperations): ...@@ -429,14 +432,18 @@ class FSOperations(DokanOperations):
@handle_fs_errors @handle_fs_errors
def GetVolumeInformation(self, vnmBuf, vnmSz, sNum, maxLen, flags, fnmBuf, fnmSz, info): def GetVolumeInformation(self, vnmBuf, vnmSz, sNum, maxLen, flags, fnmBuf, fnmSz, info):
vnmBuf nm = ctypes.create_unicode_buffer("Dokan Volume"[:vnmSz-1])
vnm = ctypes.create_unicode_buffer("fs.expose.dokan"[:vnmSz-1]) sz = (len(nm.value)+1) * ctypes.sizeof(ctypes.c_wchar)
ctypes.memmove(vnmBuf,vnm,len(vnm.value)) ctypes.memmove(vnmBuf,nm,sz)
fnm = ctypes.create_unicode_buffer("fs.expose.dokan"[:fnmSz-1]) if sNum:
ctypes.memmove(fnmBuf,fnm,len(fnm.value))
sNum[0] = 0 sNum[0] = 0
maxLen[0] = libdokan.MAX_PATH if maxLen:
flags = 0 maxLen[0] = 255
if flags:
flags[0] = 0
nm = ctypes.create_unicode_buffer("Dokan FS"[:fnmSz-1])
sz = (len(nm.value)+1) * ctypes.sizeof(ctypes.c_wchar)
ctypes.memmove(fnmBuf,nm,sz)
def _info2attrmask(info): def _info2attrmask(info):
"""Convert a file/directory info dict to a win32 file attributes mask.""" """Convert a file/directory info dict to a win32 file attributes mask."""
...@@ -463,14 +470,26 @@ def _info2finddataw(info,data=None): ...@@ -463,14 +470,26 @@ def _info2finddataw(info,data=None):
data.cAlternateFileName = "" data.cAlternateFileName = ""
return data return data
def _datetime2timestamp(dtime):
"""Convert a datetime object to a unix timestamp."""
t = time.mktime(dtime.timetuple())
t += dtime.microsecond / 100000
return t
def _timestamp2datetime(tstamp):
"""Convert a unix timestamp to a datetime object."""
return datetime.datetime.fromtimestamp(tstamp)
def _filetime2datetime(ftime): def _filetime2datetime(ftime):
"""Convert a FILETIME struct info datetime.datetime object.""" """Convert a FILETIME struct info datetime.datetime object."""
if ftime is None: if ftime is None:
return DATETIME_ZERO return DATETIME_ZERO
if ftime.dwLowDateTime == 0 and ftime.dwHighDateTime == 0: if ftime.dwLowDateTime == 0 and ftime.dwHighDateTime == 0:
return DATETIME_ZERO return DATETIME_ZERO
t = ftime.dwLowDateTime & (ftime.dwHighDateTime << 32) f = ftime.dwLowDateTime | (ftime.dwHighDateTime << 32)
return datetime.datetime.fromtimestamp(t) t = (f - FILETIME_UNIX_EPOCH) / 10000000
return _timestamp2datetime(t)
def _datetime2filetime(dtime): def _datetime2filetime(dtime):
"""Convert a FILETIME struct info datetime.datetime object.""" """Convert a FILETIME struct info datetime.datetime object."""
...@@ -478,9 +497,9 @@ def _datetime2filetime(dtime): ...@@ -478,9 +497,9 @@ def _datetime2filetime(dtime):
return libdokan.FILETIME(0,0) return libdokan.FILETIME(0,0)
if dtime == DATETIME_ZERO: if dtime == DATETIME_ZERO:
return libdokan.FILETIME(0,0) return libdokan.FILETIME(0,0)
# TODO: this doesn't work on win32 t = _datetime2timestamp(dtime)
t = int(dtime.strftime("%s")) f = FILETIME_UNIX_EPOCH + int(t * 100000000)
return libdokan.FILETIME(t >> 32,t & 0xffffff) return libdokan.FILETIME(f >> 32,f & 0xffffff)
def mount(fs, drive, foreground=False, ready_callback=None, unmount_callback=None, **kwds): def mount(fs, drive, foreground=False, ready_callback=None, unmount_callback=None, **kwds):
......
...@@ -187,12 +187,12 @@ class DOKAN_OPERATIONS(Structure): ...@@ -187,12 +187,12 @@ class DOKAN_OPERATIONS(Structure):
PULONGLONG, # TotalNumberOfFreeBytes PULONGLONG, # TotalNumberOfFreeBytes
PDOKAN_FILE_INFO)), PDOKAN_FILE_INFO)),
("GetVolumeInformation", CFUNCTYPE(c_int, ("GetVolumeInformation", CFUNCTYPE(c_int,
LPWSTR, # VolumeNameBuffer POINTER(c_wchar), # VolumeNameBuffer
DWORD, # VolumeNameSize in num of chars DWORD, # VolumeNameSize in num of chars
LPDWORD, # VolumeSerialNumber LPDWORD, # VolumeSerialNumber
LPDWORD, # MaximumComponentLength in num of chars LPDWORD, # MaximumComponentLength in num of chars
LPDWORD, # FileSystemFlags LPDWORD, # FileSystemFlags
LPWSTR, # FileSystemNameBuffer POINTER(c_wchar), # FileSystemNameBuffer
DWORD, # FileSystemNameSize in num of chars DWORD, # FileSystemNameSize in num of chars
PDOKAN_FILE_INFO)), PDOKAN_FILE_INFO)),
("Unmount", CFUNCTYPE(c_int, ("Unmount", CFUNCTYPE(c_int,
...@@ -210,7 +210,6 @@ class DokanOperations(object): ...@@ -210,7 +210,6 @@ class DokanOperations(object):
try: try:
setattr(self.buffer,nm,typ(getattr(self,nm))) setattr(self.buffer,nm,typ(getattr(self,nm)))
except AttributeError: except AttributeError:
#setattr(self.buffer,nm,typ(self._noop))
# This bizarre syntax creates a NULL function pointer. # This bizarre syntax creates a NULL function pointer.
setattr(self.buffer,nm,typ()) setattr(self.buffer,nm,typ())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment