return E_NOTIMPL;
}
+static HRESULT variant_from_largeint(const ULARGE_INTEGER *src, VARIANT *v)
+{
+ HRESULT hr = S_OK;
+
+ if (src->u.HighPart || src->u.LowPart > INT_MAX)
+ {
+ V_VT(v) = VT_R8;
+ hr = VarR8FromUI8(src->QuadPart, &V_R8(v));
+ }
+ else
+ {
+ V_VT(v) = VT_I4;
+ V_I4(v) = src->u.LowPart;
+ }
+
+ return hr;
+}
+
static HRESULT WINAPI drive_get_AvailableSpace(IDrive *iface, VARIANT *v)
{
struct drive *This = impl_from_IDrive(iface);
if (!GetDiskFreeSpaceExW(This->root, &avail, NULL, NULL))
return E_FAIL;
- V_VT(v) = VT_R8;
- return VarR8FromUI8(avail.QuadPart, &V_R8(v));
+ return variant_from_largeint(&avail, v);
}
static HRESULT WINAPI drive_get_FreeSpace(IDrive *iface, VARIANT *v)
if (!GetDiskFreeSpaceExW(This->root, &freespace, NULL, NULL))
return E_FAIL;
- V_VT(v) = VT_R8;
- return VarR8FromUI8(freespace.QuadPart, &V_R8(v));
+ return variant_from_largeint(&freespace, v);
}
static HRESULT WINAPI drive_get_TotalSize(IDrive *iface, VARIANT *v)
if (!GetDiskFreeSpaceExW(This->root, NULL, &total, NULL))
return E_FAIL;
- V_VT(v) = VT_R8;
- return VarR8FromUI8(total.QuadPart, &V_R8(v));
+ return variant_from_largeint(&total, v);
}
static HRESULT WINAPI drive_get_VolumeName(IDrive *iface, BSTR *name)
{
struct drive *This = impl_from_IDrive(iface);
- FIXME("(%p)->(%p): stub\n", This, name);
- return E_NOTIMPL;
+ WCHAR nameW[MAX_PATH+1];
+ BOOL ret;
+
+ TRACE("(%p)->(%p)\n", This, name);
+
+ if (!name)
+ return E_POINTER;
+
+ *name = NULL;
+ ret = GetVolumeInformationW(This->root, nameW, sizeof(nameW)/sizeof(WCHAR), NULL, NULL, NULL, NULL, 0);
+ if (ret)
+ *name = SysAllocString(nameW);
+ return ret ? S_OK : E_FAIL;
}
static HRESULT WINAPI drive_put_VolumeName(IDrive *iface, BSTR name)
static HRESULT WINAPI drive_get_FileSystem(IDrive *iface, BSTR *fs)
{
struct drive *This = impl_from_IDrive(iface);
- FIXME("(%p)->(%p): stub\n", This, fs);
- return E_NOTIMPL;
+ WCHAR nameW[MAX_PATH+1];
+ BOOL ret;
+
+ TRACE("(%p)->(%p)\n", This, fs);
+
+ if (!fs)
+ return E_POINTER;
+
+ *fs = NULL;
+ ret = GetVolumeInformationW(This->root, NULL, 0, NULL, NULL, NULL, nameW, sizeof(nameW)/sizeof(WCHAR));
+ if (ret)
+ *fs = SysAllocString(nameW);
+ return ret ? S_OK : E_FAIL;
}
static HRESULT WINAPI drive_get_SerialNumber(IDrive *iface, LONG *serial)
{
struct drive *This = impl_from_IDrive(iface);
- FIXME("(%p)->(%p): stub\n", This, serial);
- return E_NOTIMPL;
+ BOOL ret;
+
+ TRACE("(%p)->(%p)\n", This, serial);
+
+ if (!serial)
+ return E_POINTER;
+
+ ret = GetVolumeInformationW(This->root, NULL, 0, (DWORD*)serial, NULL, NULL, NULL, 0);
+ return ret ? S_OK : E_FAIL;
}
static HRESULT WINAPI drive_get_IsReady(IDrive *iface, VARIANT_BOOL *ready)
strcpyW(pathW, path);
len = strlenW(pathW);
- if (pathW[len-1] != '\\')
+ if (len && pathW[len-1] != '\\')
strcatW(pathW, bsW);
strcatW(pathW, allW);
handle = FindFirstFileW(pathW, data);
static HRESULT WINAPI filecoll_get_Count(IFileCollection *iface, LONG *count)
{
struct filecollection *This = impl_from_IFileCollection(iface);
- FIXME("(%p)->(%p)\n", This, count);
- return E_NOTIMPL;
+ static const WCHAR allW[] = {'\\','*',0};
+ WIN32_FIND_DATAW data;
+ WCHAR pathW[MAX_PATH];
+ HANDLE handle;
+
+ TRACE("(%p)->(%p)\n", This, count);
+
+ if(!count)
+ return E_POINTER;
+
+ *count = 0;
+
+ strcpyW(pathW, This->path);
+ strcatW(pathW, allW);
+ handle = FindFirstFileW(pathW, &data);
+ if (handle == INVALID_HANDLE_VALUE)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ do
+ {
+ if (is_file_data(&data))
+ *count += 1;
+ } while (FindNextFileW(handle, &data));
+ FindClose(handle);
+
+ return S_OK;
}
static const IFileCollectionVtbl filecollectionvtbl = {
static HRESULT WINAPI file_get_Size(IFile *iface, VARIANT *pvarSize)
{
struct file *This = impl_from_IFile(iface);
+ ULARGE_INTEGER size;
WIN32_FIND_DATAW fd;
HANDLE f;
return create_error(GetLastError());
FindClose(f);
- if(fd.nFileSizeHigh || fd.nFileSizeLow>INT_MAX) {
- V_VT(pvarSize) = VT_R8;
- V_R8(pvarSize) = ((ULONGLONG)fd.nFileSizeHigh<<32) + fd.nFileSizeLow;
- }else {
- V_VT(pvarSize) = VT_I4;
- V_I4(pvarSize) = fd.nFileSizeLow;
- }
- return S_OK;
+ size.u.LowPart = fd.nFileSizeLow;
+ size.u.HighPart = fd.nFileSizeHigh;
+
+ return variant_from_largeint(&size, pvarSize);
}
static HRESULT WINAPI file_get_Type(IFile *iface, BSTR *pbstrType)
return E_FAIL;
}
- if(path[len-1]=='/' || path[len-1]=='\\')
- path[len-1] = 0;
-
attrs = GetFileAttributesW(f->path);
if(attrs==INVALID_FILE_ATTRIBUTES ||
(attrs&(FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_DEVICE))) {
return S_OK;
}
-static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR Path,
- BSTR *pbstrResult)
+static HRESULT WINAPI filesys_GetDriveName(IFileSystem3 *iface, BSTR path, BSTR *drive)
{
- FIXME("%p %s %p\n", iface, debugstr_w(Path), pbstrResult);
+ TRACE("(%p)->(%s %p)\n", iface, debugstr_w(path), drive);
- return E_NOTIMPL;
+ if (!drive)
+ return E_POINTER;
+
+ *drive = NULL;
+
+ if (path && strlenW(path) > 1 && path[1] == ':')
+ *drive = SysAllocStringLen(path, 2);
+
+ return S_OK;
}
static inline DWORD get_parent_folder_name(const WCHAR *path, DWORD len)
}
ret = VerQueryValueW(ptr, rootW, (void**)&info, &len);
- heap_free(ptr);
if (!ret)
+ {
+ heap_free(ptr);
return HRESULT_FROM_WIN32(GetLastError());
+ }
get_versionstring(info, ver);
+ heap_free(ptr);
+
*version = SysAllocString(ver);
TRACE("version=%s\n", debugstr_w(ver));