Implemented (from Wine): GetCalendarInfoA, GetCalendarInfoW, EnumDateFormatsW, EnumCalendarInfoA, EnumCalendarInfoW, EnumCalendarInfoExA, EnumCalendarInfoExW, FindFirstVolumeA, FindFirstVolumeW, FindNextVolumeA, FindNextVolumeW.

svn path=/trunk/; revision=32945
This commit is contained in:
Dmitry Chapyshev
2008-04-13 18:20:21 +00:00
parent f87e400c88
commit 73c8871a92
4 changed files with 503 additions and 89 deletions
+152 -56
View File
@@ -20,12 +20,15 @@
#define NDEBUG
#include <debug.h>
#include "lcformat_private.h"
/* FIXME: these are included in winnls.h, however including this file causes alot of
conflicting type errors. */
#define LOCALE_RETURN_NUMBER 0x20000000
#define LOCALE_USE_CP_ACP 0x40000000
#define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|LOCALE_RETURN_NUMBER)
#define CALINFO_MAX_YEAR 2029
//static LCID SystemLocale = MAKELCID(LANG_ENGLISH, SORT_DEFAULT);
@@ -96,52 +99,6 @@ ConvertDefaultLocale(LCID lcid)
}
/*
* @unimplemented
*/
BOOL
STDCALL
EnumCalendarInfoExA(
CALINFO_ENUMPROCEXA lpCalInfoEnumProcEx,
LCID Locale,
CALID Calendar,
CALTYPE CalType)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
EnumCalendarInfoExW(
CALINFO_ENUMPROCEXW lpCalInfoEnumProcEx,
LCID Locale,
CALID Calendar,
CALTYPE CalType)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
STDCALL
EnumCalendarInfoW(
CALINFO_ENUMPROCW lpCalInfoEnumProcEx,
LCID Locale,
CALID Calendar,
CALTYPE CalType)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/**************************************************************************
* EnumDateFormatsExA (KERNEL32.@)
*
@@ -771,20 +728,38 @@ EnumUILanguagesW(
}
/*
* @unimplemented
* @implemented
*/
int
STDCALL
GetCalendarInfoA(
LCID Locale,
CALID Calendar,
CALTYPE CalType,
LPSTR lpCalData,
int cchData,
LPDWORD lpValue)
LCID lcid,
CALID Calendar,
CALTYPE CalType,
LPSTR lpCalData,
int cchData,
LPDWORD lpValue
)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
int ret;
LPWSTR lpCalDataW = NULL;
if (NLS_IsUnicodeOnlyLcid(lcid))
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (cchData &&
!(lpCalDataW = HeapAlloc(GetProcessHeap(), 0, cchData*sizeof(WCHAR))))
return 0;
ret = GetCalendarInfoW(lcid, Calendar, CalType, lpCalDataW, cchData, lpValue);
if(ret && lpCalDataW && lpCalData)
WideCharToMultiByte(CP_ACP, 0, lpCalDataW, cchData, lpCalData, cchData, NULL, NULL);
HeapFree(GetProcessHeap(), 0, lpCalDataW);
return ret;
}
@@ -801,7 +776,128 @@ GetCalendarInfoW(
int cchData,
LPDWORD lpValue)
{
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
if (CalType & CAL_NOUSEROVERRIDE)
DPRINT("FIXME: flag CAL_NOUSEROVERRIDE used, not fully implemented\n");
if (CalType & CAL_USE_CP_ACP)
DPRINT("FIXME: flag CAL_USE_CP_ACP used, not fully implemented\n");
if (CalType & CAL_RETURN_NUMBER) {
if (lpCalData != NULL)
DPRINT("WARNING: lpCalData not NULL (%p) when it should!\n", lpCalData);
if (cchData != 0)
DPRINT("WARNING: cchData not 0 (%d) when it should!\n", cchData);
} else {
if (lpValue != NULL)
DPRINT("WARNING: lpValue not NULL (%p) when it should!\n", lpValue);
}
/* FIXME: No verification is made yet wrt Locale
* for the CALTYPES not requiring GetLocaleInfoA */
switch (CalType & ~(CAL_NOUSEROVERRIDE|CAL_RETURN_NUMBER|CAL_USE_CP_ACP)) {
case CAL_ICALINTVALUE:
DPRINT("FIXME: Unimplemented caltype %d\n", CalType & 0xffff);
return E_FAIL;
case CAL_SCALNAME:
DPRINT("FIXME: Unimplemented caltype %d\n", CalType & 0xffff);
return E_FAIL;
case CAL_IYEAROFFSETRANGE:
DPRINT("FIXME: Unimplemented caltype %d\n", CalType & 0xffff);
return E_FAIL;
case CAL_SERASTRING:
DPRINT("FIXME: Unimplemented caltype %d\n", CalType & 0xffff);
return E_FAIL;
case CAL_SSHORTDATE:
return GetLocaleInfoW(Locale, LOCALE_SSHORTDATE, lpCalData, cchData);
case CAL_SLONGDATE:
return GetLocaleInfoW(Locale, LOCALE_SLONGDATE, lpCalData, cchData);
case CAL_SDAYNAME1:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME1, lpCalData, cchData);
case CAL_SDAYNAME2:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME2, lpCalData, cchData);
case CAL_SDAYNAME3:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME3, lpCalData, cchData);
case CAL_SDAYNAME4:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME4, lpCalData, cchData);
case CAL_SDAYNAME5:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME5, lpCalData, cchData);
case CAL_SDAYNAME6:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME6, lpCalData, cchData);
case CAL_SDAYNAME7:
return GetLocaleInfoW(Locale, LOCALE_SDAYNAME7, lpCalData, cchData);
case CAL_SABBREVDAYNAME1:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME1, lpCalData, cchData);
case CAL_SABBREVDAYNAME2:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME2, lpCalData, cchData);
case CAL_SABBREVDAYNAME3:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME3, lpCalData, cchData);
case CAL_SABBREVDAYNAME4:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME4, lpCalData, cchData);
case CAL_SABBREVDAYNAME5:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME5, lpCalData, cchData);
case CAL_SABBREVDAYNAME6:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME6, lpCalData, cchData);
case CAL_SABBREVDAYNAME7:
return GetLocaleInfoW(Locale, LOCALE_SABBREVDAYNAME7, lpCalData, cchData);
case CAL_SMONTHNAME1:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME1, lpCalData, cchData);
case CAL_SMONTHNAME2:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME2, lpCalData, cchData);
case CAL_SMONTHNAME3:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME3, lpCalData, cchData);
case CAL_SMONTHNAME4:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME4, lpCalData, cchData);
case CAL_SMONTHNAME5:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME5, lpCalData, cchData);
case CAL_SMONTHNAME6:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME6, lpCalData, cchData);
case CAL_SMONTHNAME7:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME7, lpCalData, cchData);
case CAL_SMONTHNAME8:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME8, lpCalData, cchData);
case CAL_SMONTHNAME9:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME9, lpCalData, cchData);
case CAL_SMONTHNAME10:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME10, lpCalData, cchData);
case CAL_SMONTHNAME11:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME11, lpCalData, cchData);
case CAL_SMONTHNAME12:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME12, lpCalData, cchData);
case CAL_SMONTHNAME13:
return GetLocaleInfoW(Locale, LOCALE_SMONTHNAME13, lpCalData, cchData);
case CAL_SABBREVMONTHNAME1:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME1, lpCalData, cchData);
case CAL_SABBREVMONTHNAME2:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME2, lpCalData, cchData);
case CAL_SABBREVMONTHNAME3:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME3, lpCalData, cchData);
case CAL_SABBREVMONTHNAME4:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME4, lpCalData, cchData);
case CAL_SABBREVMONTHNAME5:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME5, lpCalData, cchData);
case CAL_SABBREVMONTHNAME6:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME6, lpCalData, cchData);
case CAL_SABBREVMONTHNAME7:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME7, lpCalData, cchData);
case CAL_SABBREVMONTHNAME8:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME8, lpCalData, cchData);
case CAL_SABBREVMONTHNAME9:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME9, lpCalData, cchData);
case CAL_SABBREVMONTHNAME10:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME10, lpCalData, cchData);
case CAL_SABBREVMONTHNAME11:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME11, lpCalData, cchData);
case CAL_SABBREVMONTHNAME12:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME12, lpCalData, cchData);
case CAL_SABBREVMONTHNAME13:
return GetLocaleInfoW(Locale, LOCALE_SABBREVMONTHNAME13, lpCalData, cchData);
case CAL_SYEARMONTH:
return GetLocaleInfoW(Locale, LOCALE_SYEARMONTH, lpCalData, cchData);
case CAL_ITWODIGITYEARMAX:
if (lpValue) *lpValue = CALINFO_MAX_YEAR;
break;
default: DPRINT("Unknown caltype %d\n",CalType & 0xffff);
return E_FAIL;
}
return 0;
}
+208 -5
View File
@@ -37,6 +37,7 @@
#define TRACE DPRINT
#define WARN DPRINT1
#define ERR DPRINT1
#define FIXME DPRINT1
#define DATE_DATEVARSONLY 0x0100 /* only date stuff: yMdg */
@@ -1993,11 +1994,40 @@ BOOL WINAPI EnumDateFormatsA( DATEFMT_ENUMPROCA lpDateFmtEnumProc, LCID Locale,
/**************************************************************************
* EnumDateFormatsW (KERNEL32.@)
*/
BOOL WINAPI EnumDateFormatsW( DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags )
BOOL WINAPI EnumDateFormatsW( DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags )
{
FIXME("(%p, %ld, %ld): stub\n", lpDateFmtEnumProc, Locale, dwFlags);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
WCHAR buf[256];
if (!proc)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
switch (flags & ~LOCALE_USE_CP_ACP)
{
case 0:
case DATE_SHORTDATE:
if (GetLocaleInfoW(lcid, LOCALE_SSHORTDATE | (flags & LOCALE_USE_CP_ACP), buf, 256))
proc(buf);
break;
case DATE_LONGDATE:
if (GetLocaleInfoW(lcid, LOCALE_SLONGDATE | (flags & LOCALE_USE_CP_ACP), buf, 256))
proc(buf);
break;
case DATE_YEARMONTH:
if (GetLocaleInfoW(lcid, LOCALE_SYEARMONTH | (flags & LOCALE_USE_CP_ACP), buf, 256))
proc(buf);
break;
default:
FIXME("Unknown date format (%d)\n", flags);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
/**************************************************************************
@@ -2080,6 +2110,143 @@ BOOL WINAPI EnumTimeFormatsW( TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Locale,
return FALSE;
}
/******************************************************************************
* NLS_EnumCalendarInfoAW <internal>
* Enumerates calendar information for a specified locale.
*
* PARAMS
* calinfoproc [I] Pointer to the callback
* locale [I] The locale for which to retrieve calendar information.
* This parameter can be a locale identifier created by the
* MAKELCID macro, or one of the following values:
* LOCALE_SYSTEM_DEFAULT
* Use the default system locale.
* LOCALE_USER_DEFAULT
* Use the default user locale.
* calendar [I] The calendar for which information is requested, or
* ENUM_ALL_CALENDARS.
* caltype [I] The type of calendar information to be returned. Note
* that only one CALTYPE value can be specified per call
* of this function, except where noted.
* unicode [I] Specifies if the callback expects a unicode string.
* ex [I] Specifies if the callback needs the calendar identifier.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE. Use GetLastError() to determine the cause.
*
* NOTES
* When the ANSI version of this function is used with a Unicode-only LCID,
* the call can succeed because the system uses the system code page.
* However, characters that are undefined in the system code page appear
* in the string as a question mark (?).
*
* TODO
* The above note should be respected by GetCalendarInfoA.
*/
static BOOL NLS_EnumCalendarInfoAW(void *calinfoproc, LCID locale,
CALID calendar, CALTYPE caltype, BOOL unicode, BOOL ex )
{
WCHAR *buf, *opt = NULL, *iter = NULL;
BOOL ret = FALSE;
int bufSz = 200; /* the size of the buffer */
if (calinfoproc == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
buf = HeapAlloc(GetProcessHeap(), 0, bufSz);
if (buf == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
if (calendar == ENUM_ALL_CALENDARS)
{
int optSz = GetLocaleInfoW(locale, LOCALE_IOPTIONALCALENDAR, NULL, 0);
if (optSz > 1)
{
opt = HeapAlloc(GetProcessHeap(), 0, optSz * sizeof(WCHAR));
if (opt == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto NLS_EnumCalendarInfoAW_Cleanup;
}
if (GetLocaleInfoW(locale, LOCALE_IOPTIONALCALENDAR, opt, optSz))
iter = opt;
}
calendar = NLS_GetLocaleNumber(locale, LOCALE_ICALENDARTYPE);
}
while (TRUE) /* loop through calendars */
{
do /* loop until there's no error */
{
if (unicode)
ret = GetCalendarInfoW(locale, calendar, caltype, buf, bufSz / sizeof(WCHAR), NULL);
else ret = GetCalendarInfoA(locale, calendar, caltype, (CHAR*)buf, bufSz / sizeof(CHAR), NULL);
if (!ret)
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{ /* so resize it */
int newSz;
if (unicode)
newSz = GetCalendarInfoW(locale, calendar, caltype, NULL, 0, NULL) * sizeof(WCHAR);
else newSz = GetCalendarInfoA(locale, calendar, caltype, NULL, 0, NULL) * sizeof(CHAR);
if (bufSz >= newSz)
{
ERR("Buffer resizing disorder: was %d, requested %d.\n", bufSz, newSz);
goto NLS_EnumCalendarInfoAW_Cleanup;
}
bufSz = newSz;
WARN("Buffer too small; resizing to %d bytes.\n", bufSz);
buf = HeapReAlloc(GetProcessHeap(), 0, buf, bufSz);
if (buf == NULL)
goto NLS_EnumCalendarInfoAW_Cleanup;
} else goto NLS_EnumCalendarInfoAW_Cleanup;
}
} while (!ret);
/* Here we are. We pass the buffer to the correct version of
* the callback. Because it's not the same number of params,
* we must check for Ex, but we don't care about Unicode
* because the buffer is already in the correct format.
*/
if (ex) {
ret = ((CALINFO_ENUMPROCEXW)calinfoproc)(buf, calendar);
} else
ret = ((CALINFO_ENUMPROCW)calinfoproc)(buf);
if (!ret) { /* the callback told to stop */
ret = TRUE;
break;
}
if ((iter == NULL) || (*iter == 0)) /* no more calendars */
break;
calendar = 0;
while ((*iter >= '0') && (*iter <= '9'))
calendar = calendar * 10 + *iter++ - '0';
if (*iter++ != 0)
{
SetLastError(ERROR_BADDB);
ret = FALSE;
break;
}
}
NLS_EnumCalendarInfoAW_Cleanup:
HeapFree(GetProcessHeap(), 0, opt);
HeapFree(GetProcessHeap(), 0, buf);
return ret;
}
/******************************************************************************
* EnumCalendarInfoA [KERNEL32.@]
*/
@@ -2087,5 +2254,41 @@ BOOL WINAPI EnumCalendarInfoA( CALINFO_ENUMPROCA calinfoproc,LCID locale,
CALID calendar,CALTYPE caltype )
{
FIXME("(%p,0x%04lx,0x%08lx,0x%08lx),stub!\n",calinfoproc,locale,calendar,caltype);
return FALSE;
return NLS_EnumCalendarInfoAW(calinfoproc, locale, calendar, caltype, FALSE, FALSE);
}
/******************************************************************************
* EnumCalendarInfoW [KERNEL32.@]
*
* See EnumCalendarInfoAW.
*/
BOOL WINAPI EnumCalendarInfoW( CALINFO_ENUMPROCW calinfoproc,LCID locale,
CALID calendar,CALTYPE caltype )
{
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
return NLS_EnumCalendarInfoAW(calinfoproc, locale, calendar, caltype, TRUE, FALSE);
}
/******************************************************************************
* EnumCalendarInfoExA [KERNEL32.@]
*
* See EnumCalendarInfoAW.
*/
BOOL WINAPI EnumCalendarInfoExA( CALINFO_ENUMPROCEXA calinfoproc,LCID locale,
CALID calendar,CALTYPE caltype )
{
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
return NLS_EnumCalendarInfoAW(calinfoproc, locale, calendar, caltype, FALSE, TRUE);
}
/******************************************************************************
* EnumCalendarInfoExW [KERNEL32.@]
*
* See EnumCalendarInfoAW.
*/
BOOL WINAPI EnumCalendarInfoExW( CALINFO_ENUMPROCEXW calinfoproc,LCID locale,
CALID calendar,CALTYPE caltype )
{
TRACE("(%p,0x%08x,0x%08x,0x%08x)\n", calinfoproc, locale, calendar, caltype);
return NLS_EnumCalendarInfoAW(calinfoproc, locale, calendar, caltype, TRUE, TRUE);
}
@@ -0,0 +1,15 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS System Libraries
* FILE: lib/kernel32/misc/lcformat_private.h
* PURPOSE: Win32 Kernel Libary Header
* PROGRAMMER: Dmitry Chapyshev ([email protected])
*/
#ifndef __LCFORMAT_PRIVATE_H
#define __LCFORMAT_PRIVATE_H
/*lcformat.c */
extern BOOL NLS_IsUnicodeOnlyLcid(LCID);
#endif /* __LCFORMAT_PRIVATE_H */
+128 -28
View File
@@ -730,8 +730,15 @@ SetThreadExecutionState(
EXECUTION_STATE esFlags
)
{
STUB;
return 0;
static EXECUTION_STATE current =
ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED | ES_USER_PRESENT;
EXECUTION_STATE old = current;
DPRINT1("(0x%x): stub, harmless.\n", esFlags);
if (!(current & ES_CONTINUOUS) || (esFlags & ES_CONTINUOUS))
current = esFlags;
return old;
}
/*
@@ -785,27 +792,80 @@ DeleteVolumeMountPointW(
BOOL
STDCALL
DnsHostnameToComputerNameW (
LPCWSTR Hostname,
LPWSTR ComputerName,
LPDWORD nSize
LPCWSTR hostname,
LPWSTR computername,
LPDWORD size
)
{
STUB;
return 0;
DWORD len;
DPRINT("(%s, %p, %p): stub\n", hostname, computername, size);
if (!hostname || !size) return FALSE;
len = lstrlenW(hostname);
if (len > MAX_COMPUTERNAME_LENGTH)
len = MAX_COMPUTERNAME_LENGTH;
if (*size < len)
{
*size = len;
return FALSE;
}
if (!computername) return FALSE;
memcpy( computername, hostname, len * sizeof(WCHAR) );
computername[len + 1] = 0;
return TRUE;
}
/*
* @unimplemented
* @implemented
*/
HANDLE
STDCALL
FindFirstVolumeW(
LPWSTR lpszVolumeName,
DWORD cchBufferLength
LPWSTR volume,
DWORD len
)
{
STUB;
return 0;
DWORD size = 1024;
HANDLE mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0 );
if (mgr == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;
for (;;)
{
MOUNTMGR_MOUNT_POINT input;
MOUNTMGR_MOUNT_POINTS *output;
if (!(output = HeapAlloc( GetProcessHeap(), 0, size )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
break;
}
memset( &input, 0, sizeof(input) );
if (!DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_POINTS, &input, sizeof(input),
output, size, NULL, NULL ))
{
if (GetLastError() != ERROR_MORE_DATA) break;
size = output->Size;
HeapFree( GetProcessHeap(), 0, output );
continue;
}
CloseHandle( mgr );
/* abuse the Size field to store the current index */
output->Size = 0;
if (!FindNextVolumeW( output, volume, len ))
{
HeapFree( GetProcessHeap(), 0, output );
return INVALID_HANDLE_VALUE;
}
return (HANDLE)output;
}
CloseHandle( mgr );
return INVALID_HANDLE_VALUE;
}
/*
@@ -824,18 +884,40 @@ FindFirstVolumeMountPointW(
}
/*
* @unimplemented
* @implemented
*/
BOOL
STDCALL
FindNextVolumeW(
HANDLE hFindVolume,
LPWSTR lpszVolumeName,
DWORD cchBufferLength
HANDLE handle,
LPWSTR volume,
DWORD len
)
{
STUB;
return 0;
MOUNTMGR_MOUNT_POINTS *data = handle;
while (data->Size < data->NumberOfMountPoints)
{
static const WCHAR volumeW[] = {'\\','?','?','\\','V','o','l','u','m','e','{',};
WCHAR *link = (WCHAR *)((char *)data + data->MountPoints[data->Size].SymbolicLinkNameOffset);
DWORD size = data->MountPoints[data->Size].SymbolicLinkNameLength;
data->Size++;
/* skip non-volumes */
if (size < sizeof(volumeW) || memcmp( link, volumeW, sizeof(volumeW) )) continue;
if (size + sizeof(WCHAR) >= len * sizeof(WCHAR))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return FALSE;
}
memcpy( volume, link, size );
volume[1] = '\\'; /* map \??\ to \\?\ */
volume[size / sizeof(WCHAR)] = '\\'; /* Windows appends a backslash */
volume[size / sizeof(WCHAR) + 1] = 0;
DPRINT( "returning entry %u %s\n", data->Size - 1, volume );
return TRUE;
}
SetLastError( ERROR_NO_MORE_FILES );
return FALSE;
}
/*
@@ -977,17 +1059,28 @@ DnsHostnameToComputerNameA (
}
/*
* @unimplemented
* @implemented
*/
HANDLE
STDCALL
FindFirstVolumeA(
LPSTR lpszVolumeName,
DWORD cchBufferLength
LPSTR volume,
DWORD len
)
{
STUB;
return 0;
WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
HANDLE handle = FindFirstVolumeW( buffer, len );
if (handle != INVALID_HANDLE_VALUE)
{
if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, volume, len, NULL, NULL ))
{
FindVolumeClose( handle );
handle = INVALID_HANDLE_VALUE;
}
}
HeapFree( GetProcessHeap(), 0, buffer );
return handle;
}
/*
@@ -1011,13 +1104,20 @@ FindFirstVolumeMountPointA(
BOOL
STDCALL
FindNextVolumeA(
HANDLE hFindVolume,
LPSTR lpszVolumeName,
DWORD cchBufferLength
HANDLE handle,
LPSTR volume,
DWORD len
)
{
STUB;
return 0;
WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
BOOL ret;
if ((ret = FindNextVolumeW( handle, buffer, len )))
{
if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, volume, len, NULL, NULL )) ret = FALSE;
}
HeapFree( GetProcessHeap(), 0, buffer );
return ret;
}
/*