Author: dchapyshev Date: Sun Apr 13 13:20:21 2008 New Revision: 32945
URL: http://svn.reactos.org/svn/reactos?rev=32945&view=rev Log: Implemented (from Wine): GetCalendarInfoA, GetCalendarInfoW, EnumDateFormatsW, EnumCalendarInfoA, EnumCalendarInfoW, EnumCalendarInfoExA, EnumCalendarInfoExW, FindFirstVolumeA, FindFirstVolumeW, FindNextVolumeA, FindNextVolumeW.
Added: trunk/reactos/dll/win32/kernel32/misc/lcformat_private.h (with props) Modified: trunk/reactos/dll/win32/kernel32/misc/lang.c trunk/reactos/dll/win32/kernel32/misc/lcformat.c trunk/reactos/dll/win32/kernel32/misc/stubs.c
Modified: trunk/reactos/dll/win32/kernel32/misc/lang.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/lan... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/lang.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/lang.c [iso-8859-1] Sun Apr 13 13:20:21 2008 @@ -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);
@@ -95,52 +98,6 @@ return 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 @@ }
/* - * @unimplemented + * @implemented */ int STDCALL GetCalendarInfoA( - LCID Locale, - CALID Calendar, - CALTYPE CalType, - LPSTR lpCalData, - int cchData, - LPDWORD lpValue) -{ - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; + LCID lcid, + CALID Calendar, + CALTYPE CalType, + LPSTR lpCalData, + int cchData, + LPDWORD lpValue + ) +{ + 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 @@ 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; }
Modified: trunk/reactos/dll/win32/kernel32/misc/lcformat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/lcf... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/lcformat.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/lcformat.c [iso-8859-1] Sun Apr 13 13:20:21 2008 @@ -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 @@ /************************************************************************** * EnumDateFormatsW (KERNEL32.@) */ -BOOL WINAPI EnumDateFormatsW( DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags ) -{ - FIXME("(%p, %ld, %ld): stub\n", lpDateFmtEnumProc, Locale, dwFlags); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; +BOOL WINAPI EnumDateFormatsW( DATEFMT_ENUMPROCW proc, LCID lcid, DWORD flags ) +{ + 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; }
/************************************************************************** @@ -2081,11 +2111,184 @@ }
/****************************************************************************** + * 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.@] */ 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); +}
Added: trunk/reactos/dll/win32/kernel32/misc/lcformat_private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/lcf... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/lcformat_private.h (added) +++ trunk/reactos/dll/win32/kernel32/misc/lcformat_private.h [iso-8859-1] Sun Apr 13 13:20:21 2008 @@ -1,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 (dmitry@reactos.org) + */ + +#ifndef __LCFORMAT_PRIVATE_H +#define __LCFORMAT_PRIVATE_H + +/*lcformat.c */ +extern BOOL NLS_IsUnicodeOnlyLcid(LCID); + +#endif /* __LCFORMAT_PRIVATE_H */
Propchange: trunk/reactos/dll/win32/kernel32/misc/lcformat_private.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/kernel32/misc/stubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/stu... ============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/stubs.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/misc/stubs.c [iso-8859-1] Sun Apr 13 13:20:21 2008 @@ -730,8 +730,15 @@ 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 @@ BOOL STDCALL DnsHostnameToComputerNameW ( - LPCWSTR Hostname, - LPWSTR ComputerName, - LPDWORD nSize - ) -{ - STUB; - return 0; -} - -/* - * @unimplemented + LPCWSTR hostname, + LPWSTR computername, + LPDWORD size + ) +{ + 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; +} + +/* + * @implemented */ HANDLE STDCALL FindFirstVolumeW( - LPWSTR lpszVolumeName, - DWORD cchBufferLength - ) -{ - STUB; - return 0; + LPWSTR volume, + DWORD len + ) +{ + 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 @@ }
/* - * @unimplemented + * @implemented */ BOOL STDCALL FindNextVolumeW( - HANDLE hFindVolume, - LPWSTR lpszVolumeName, - DWORD cchBufferLength - ) -{ - STUB; - return 0; + HANDLE handle, + LPWSTR volume, + DWORD len + ) +{ + 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 @@ }
/* - * @unimplemented + * @implemented */ HANDLE STDCALL FindFirstVolumeA( - LPSTR lpszVolumeName, - DWORD cchBufferLength - ) -{ - STUB; - return 0; + LPSTR volume, + DWORD len + ) +{ + 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 @@ BOOL STDCALL FindNextVolumeA( - HANDLE hFindVolume, - LPSTR lpszVolumeName, - DWORD cchBufferLength - ) -{ - STUB; - return 0; + HANDLE handle, + LPSTR volume, + DWORD len + ) +{ + 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; }
/*