2000-08-04 06:21:02 +02:00
|
|
|
/*
|
|
|
|
* Misc USER functions
|
|
|
|
*
|
|
|
|
* Copyright 1995 Thomas Sandford
|
|
|
|
* Copyright 1997 Marcus Meissner
|
2002-03-10 00:29:33 +01:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2000-08-04 06:21:02 +02:00
|
|
|
*/
|
|
|
|
|
2003-09-06 01:08:26 +02:00
|
|
|
#include <stdarg.h>
|
|
|
|
|
2000-08-04 06:21:02 +02:00
|
|
|
#include "windef.h"
|
|
|
|
#include "winbase.h"
|
|
|
|
#include "winuser.h"
|
2004-03-09 01:41:39 +01:00
|
|
|
#include "winnls.h"
|
2000-08-04 06:21:02 +02:00
|
|
|
|
2002-03-10 00:29:33 +01:00
|
|
|
#include "wine/debug.h"
|
2000-08-04 06:21:02 +02:00
|
|
|
|
2002-03-10 00:29:33 +01:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(win);
|
2000-08-04 06:21:02 +02:00
|
|
|
|
2004-03-09 01:41:39 +01:00
|
|
|
/* callback to allow EnumDesktopsA to use EnumDesktopsW */
|
|
|
|
typedef struct {
|
|
|
|
DESKTOPENUMPROCA lpEnumFunc;
|
|
|
|
LPARAM lParam;
|
|
|
|
} ENUMDESKTOPS_LPARAM;
|
|
|
|
|
|
|
|
/* EnumDesktopsA passes this callback function to EnumDesktopsW.
|
|
|
|
* It simply converts the string to ASCII and calls the callback
|
|
|
|
* function provided by the original caller
|
|
|
|
*/
|
|
|
|
static BOOL CALLBACK EnumDesktopProcWtoA(LPWSTR lpszDesktop, LPARAM lParam)
|
|
|
|
{
|
|
|
|
LPSTR buffer;
|
|
|
|
INT len;
|
|
|
|
BOOL ret;
|
|
|
|
ENUMDESKTOPS_LPARAM *data = (ENUMDESKTOPS_LPARAM *)lParam;
|
|
|
|
|
|
|
|
len = WideCharToMultiByte(CP_ACP, 0, lpszDesktop, -1, NULL, 0, NULL, NULL);
|
|
|
|
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len))) return FALSE;
|
|
|
|
WideCharToMultiByte(CP_ACP, 0, lpszDesktop, -1, buffer, len, NULL, NULL);
|
|
|
|
|
|
|
|
ret = data->lpEnumFunc(buffer, data->lParam);
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, buffer);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2000-08-04 06:21:02 +02:00
|
|
|
/**********************************************************************
|
2005-04-20 17:18:42 +02:00
|
|
|
* SetLastErrorEx [USER32.@]
|
|
|
|
*
|
|
|
|
* Sets the last-error code.
|
2000-08-04 06:21:02 +02:00
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* None.
|
|
|
|
*/
|
|
|
|
void WINAPI SetLastErrorEx(
|
|
|
|
DWORD error, /* [in] Per-thread error code */
|
|
|
|
DWORD type) /* [in] Error type */
|
|
|
|
{
|
|
|
|
TRACE("(0x%08lx, 0x%08lx)\n", error,type);
|
|
|
|
switch(type) {
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case SLE_ERROR:
|
|
|
|
case SLE_MINORERROR:
|
|
|
|
case SLE_WARNING:
|
|
|
|
/* Fall through for now */
|
|
|
|
default:
|
|
|
|
FIXME("(error=%08lx, type=%08lx): Unhandled type\n", error,type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
SetLastError( error );
|
|
|
|
}
|
|
|
|
|
2005-04-20 17:18:42 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* GetAltTabInfoA [USER32.@]
|
|
|
|
*/
|
2005-01-03 18:02:34 +01:00
|
|
|
BOOL WINAPI GetAltTabInfoA(HWND hwnd, int iItem, PALTTABINFO pati, LPSTR pszItemText, UINT cchItemText)
|
|
|
|
{
|
|
|
|
FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText, cchItemText);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-04-20 17:18:42 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* GetAltTabInfoW [USER32.@]
|
|
|
|
*/
|
2005-01-03 18:02:34 +01:00
|
|
|
BOOL WINAPI GetAltTabInfoW(HWND hwnd, int iItem, PALTTABINFO pati, LPWSTR pszItemText, UINT cchItemText)
|
|
|
|
{
|
|
|
|
FIXME("(%p, 0x%08x, %p, %p, 0x%08x)\n", hwnd, iItem, pati, pszItemText, cchItemText);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2000-08-04 06:21:02 +02:00
|
|
|
|
|
|
|
/******************************************************************************
|
2005-04-20 17:18:42 +02:00
|
|
|
* GetProcessWindowStation [USER32.@]
|
|
|
|
*
|
|
|
|
* Returns handle of window station
|
2000-08-04 06:21:02 +02:00
|
|
|
*
|
|
|
|
* NOTES
|
|
|
|
* Docs say the return value is HWINSTA
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Handle to window station associated with calling process
|
|
|
|
* Failure: NULL
|
|
|
|
*/
|
2001-01-09 21:56:06 +01:00
|
|
|
HWINSTA WINAPI GetProcessWindowStation(void)
|
2000-08-04 06:21:02 +02:00
|
|
|
{
|
|
|
|
FIXME("(void): stub\n");
|
2001-01-09 21:56:06 +01:00
|
|
|
return (HWINSTA)1;
|
2000-08-04 06:21:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
2005-04-20 17:18:42 +02:00
|
|
|
* GetThreadDesktop [USER32.@]
|
|
|
|
*
|
|
|
|
* Returns handle to desktop
|
2000-08-04 06:21:02 +02:00
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* dwThreadId [I] Thread identifier
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Handle to desktop associated with specified thread
|
|
|
|
* Failure: NULL
|
|
|
|
*/
|
2004-04-06 05:21:13 +02:00
|
|
|
HDESK WINAPI GetThreadDesktop( DWORD dwThreadId )
|
2000-08-04 06:21:02 +02:00
|
|
|
{
|
|
|
|
FIXME("(%lx): stub\n",dwThreadId);
|
2004-04-06 05:21:13 +02:00
|
|
|
return (HDESK)1;
|
2000-08-04 06:21:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* SetDebugErrorLevel [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
* Sets the minimum error level for generating debugging events
|
|
|
|
*
|
|
|
|
* PARAMS
|
|
|
|
* dwLevel [I] Debugging error level
|
|
|
|
*/
|
|
|
|
VOID WINAPI SetDebugErrorLevel( DWORD dwLevel )
|
|
|
|
{
|
|
|
|
FIXME("(%ld): stub\n", dwLevel);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* GetProcessDefaultLayout [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
*
|
|
|
|
* Gets the default layout for parentless windows.
|
|
|
|
* Right now, just returns 0 (left-to-right).
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Nonzero
|
|
|
|
* Failure: Zero
|
|
|
|
*
|
|
|
|
* BUGS
|
|
|
|
* No RTL
|
|
|
|
*/
|
|
|
|
BOOL WINAPI GetProcessDefaultLayout( DWORD *pdwDefaultLayout )
|
|
|
|
{
|
|
|
|
if ( !pdwDefaultLayout ) {
|
|
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
FIXME( "( %p ): No BiDi\n", pdwDefaultLayout );
|
|
|
|
*pdwDefaultLayout = 0;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* SetProcessDefaultLayout [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
*
|
|
|
|
* Sets the default layout for parentless windows.
|
|
|
|
* Right now, only accepts 0 (left-to-right).
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Success: Nonzero
|
|
|
|
* Failure: Zero
|
|
|
|
*
|
|
|
|
* BUGS
|
|
|
|
* No RTL
|
|
|
|
*/
|
|
|
|
BOOL WINAPI SetProcessDefaultLayout( DWORD dwDefaultLayout )
|
|
|
|
{
|
|
|
|
if ( dwDefaultLayout == 0 )
|
|
|
|
return TRUE;
|
|
|
|
FIXME( "( %08lx ): No BiDi\n", dwDefaultLayout );
|
|
|
|
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* OpenDesktopA [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
*
|
|
|
|
* Not supported on Win9x - returns NULL and calls SetLastError.
|
|
|
|
*/
|
2004-04-06 05:21:13 +02:00
|
|
|
HDESK WINAPI OpenDesktopA( LPCSTR lpszDesktop, DWORD dwFlags,
|
2000-08-04 06:21:02 +02:00
|
|
|
BOOL fInherit, DWORD dwDesiredAccess )
|
|
|
|
{
|
|
|
|
FIXME("(%s,%lx,%i,%lx): stub\n",debugstr_a(lpszDesktop),dwFlags,
|
|
|
|
fInherit,dwDesiredAccess);
|
|
|
|
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-10-18 21:38:01 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* OpenInputDesktop [USER32.@]
|
|
|
|
*
|
|
|
|
* Not supported on Win9x - returns NULL and calls SetLastError.
|
|
|
|
*/
|
|
|
|
HDESK WINAPI OpenInputDesktop( DWORD dwFlags, BOOL fInherit, ACCESS_MASK dwDesiredAccess )
|
|
|
|
{
|
|
|
|
FIXME("(%lx,%i,%lx): stub\n",dwFlags, fInherit,dwDesiredAccess);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-03-09 01:41:39 +01:00
|
|
|
/******************************************************************************
|
|
|
|
* EnumDesktopsA [USER32.@]
|
|
|
|
*/
|
|
|
|
BOOL WINAPI EnumDesktopsA( HWINSTA hwinsta, DESKTOPENUMPROCA lpEnumFunc,
|
|
|
|
LPARAM lParam )
|
|
|
|
{
|
|
|
|
ENUMDESKTOPS_LPARAM caller_data;
|
|
|
|
|
|
|
|
caller_data.lpEnumFunc = lpEnumFunc;
|
|
|
|
caller_data.lParam = lParam;
|
|
|
|
|
|
|
|
return EnumDesktopsW(hwinsta, EnumDesktopProcWtoA, (LPARAM) &caller_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumDesktopsW [USER32.@]
|
|
|
|
*/
|
|
|
|
BOOL WINAPI EnumDesktopsW( HWINSTA hwinsta, DESKTOPENUMPROCW lpEnumFunc,
|
|
|
|
LPARAM lParam )
|
|
|
|
{
|
|
|
|
FIXME("%p,%p,%lx): stub\n",hwinsta,lpEnumFunc,lParam);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2000-08-04 06:21:02 +02:00
|
|
|
|
2004-04-07 21:41:21 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* EnumWindowStationsA [USER32.@]
|
|
|
|
*/
|
|
|
|
BOOL WINAPI EnumWindowStationsA( WINSTAENUMPROCA lpEnumFunc, LPARAM lParam)
|
|
|
|
{
|
|
|
|
FIXME("%p,%lx): stub\n",lpEnumFunc,lParam);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
* EnumWindowStationsW [USER32.@]
|
|
|
|
*/
|
|
|
|
BOOL WINAPI EnumWindowStationsW( WINSTAENUMPROCW lpEnumFunc, LPARAM lParam)
|
|
|
|
{
|
|
|
|
FIXME("%p,%lx): stub\n",lpEnumFunc,lParam);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2000-08-04 06:21:02 +02:00
|
|
|
/******************************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* SetUserObjectInformationA (USER32.@)
|
2000-08-04 06:21:02 +02:00
|
|
|
*/
|
2002-06-01 01:06:46 +02:00
|
|
|
BOOL WINAPI SetUserObjectInformationA( HANDLE hObj, INT nIndex,
|
2000-08-04 06:21:02 +02:00
|
|
|
LPVOID pvInfo, DWORD nLength )
|
|
|
|
{
|
2002-11-22 22:22:14 +01:00
|
|
|
FIXME("(%p,%d,%p,%lx): stub\n",hObj,nIndex,pvInfo,nLength);
|
2000-08-04 06:21:02 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* SetThreadDesktop (USER32.@)
|
2000-08-04 06:21:02 +02:00
|
|
|
*/
|
|
|
|
BOOL WINAPI SetThreadDesktop( HANDLE hDesktop )
|
|
|
|
{
|
2002-11-22 22:22:14 +01:00
|
|
|
FIXME("(%p): stub\n",hDesktop);
|
2000-08-04 06:21:02 +02:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* RegisterShellHookWindow [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
*/
|
2003-01-13 21:36:39 +01:00
|
|
|
BOOL WINAPI RegisterShellHookWindow ( HWND hWnd )
|
2000-08-04 06:21:02 +02:00
|
|
|
{
|
2003-01-13 21:36:39 +01:00
|
|
|
FIXME("(%p): stub\n", hWnd);
|
2000-08-04 06:21:02 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* DeregisterShellHookWindow [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
*/
|
|
|
|
HRESULT WINAPI DeregisterShellHookWindow ( DWORD u )
|
|
|
|
{
|
|
|
|
FIXME("0x%08lx stub\n",u);
|
|
|
|
return 0;
|
2002-06-01 01:06:46 +02:00
|
|
|
|
2000-08-04 06:21:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
2001-01-25 23:22:21 +01:00
|
|
|
* RegisterTasklist [USER32.@]
|
2000-08-04 06:21:02 +02:00
|
|
|
*/
|
2000-11-25 22:43:04 +01:00
|
|
|
DWORD WINAPI RegisterTasklist (DWORD x)
|
2000-08-04 06:21:02 +02:00
|
|
|
{
|
|
|
|
FIXME("0x%08lx\n",x);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2000-08-06 04:42:46 +02:00
|
|
|
|
2002-07-29 01:48:27 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* GetAppCompatFlags (USER32.@)
|
|
|
|
*/
|
|
|
|
DWORD WINAPI GetAppCompatFlags( HTASK hTask )
|
|
|
|
{
|
|
|
|
FIXME("stub\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-01-13 21:36:39 +01:00
|
|
|
/***********************************************************************
|
|
|
|
* AlignRects (USER32.@)
|
|
|
|
*/
|
|
|
|
BOOL WINAPI AlignRects(LPRECT rect, DWORD b, DWORD c, DWORD d)
|
|
|
|
{
|
|
|
|
FIXME("(%p, %ld, %ld, %ld): stub\n", rect, b, c, d);
|
|
|
|
if (rect)
|
|
|
|
FIXME("rect: [[%ld, %ld], [%ld, %ld]]\n", rect->left, rect->top, rect->right, rect->bottom);
|
|
|
|
/* Calls OffsetRect */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-08-06 04:42:46 +02:00
|
|
|
/***********************************************************************
|
2001-07-02 21:59:40 +02:00
|
|
|
* USER_489 (USER.489)
|
2000-08-06 04:42:46 +02:00
|
|
|
*/
|
|
|
|
LONG WINAPI stub_USER_489(void) { FIXME("stub\n"); return 0; }
|
|
|
|
|
|
|
|
/***********************************************************************
|
2001-07-02 21:59:40 +02:00
|
|
|
* USER_490 (USER.490)
|
2000-08-06 04:42:46 +02:00
|
|
|
*/
|
|
|
|
LONG WINAPI stub_USER_490(void) { FIXME("stub\n"); return 0; }
|
|
|
|
|
|
|
|
/***********************************************************************
|
2001-07-02 21:59:40 +02:00
|
|
|
* USER_492 (USER.492)
|
2000-08-06 04:42:46 +02:00
|
|
|
*/
|
|
|
|
LONG WINAPI stub_USER_492(void) { FIXME("stub\n"); return 0; }
|
|
|
|
|
|
|
|
/***********************************************************************
|
2001-07-02 21:59:40 +02:00
|
|
|
* USER_496 (USER.496)
|
2000-08-06 04:42:46 +02:00
|
|
|
*/
|
|
|
|
LONG WINAPI stub_USER_496(void) { FIXME("stub\n"); return 0; }
|
2004-04-01 04:12:41 +02:00
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
* User32InitializeImmEntryTable
|
|
|
|
*/
|
2005-01-07 18:15:30 +01:00
|
|
|
BOOL WINAPI User32InitializeImmEntryTable(LPVOID ptr)
|
|
|
|
{
|
|
|
|
FIXME("(%p): stub\n", ptr);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* WINNLSGetIMEHotkey [USER32.@]
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
UINT WINAPI WINNLSGetIMEHotkey(HWND hUnknown1)
|
|
|
|
{
|
|
|
|
FIXME("hUnknown1 %p: stub!\n", hUnknown1);
|
|
|
|
return 0; /* unknown */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* WINNLSEnableIME [USER32.@]
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
BOOL WINAPI WINNLSEnableIME(HWND hUnknown1, BOOL bUnknown2)
|
|
|
|
{
|
|
|
|
FIXME("hUnknown1 %p bUnknown2 %d: stub!\n", hUnknown1, bUnknown2);
|
|
|
|
return TRUE; /* success (?) */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* WINNLSGetEnableStatus [USER32.@]
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
BOOL WINAPI WINNLSGetEnableStatus(HWND hUnknown1)
|
|
|
|
{
|
|
|
|
FIXME("hUnknown1 %p: stub!\n", hUnknown1);
|
|
|
|
return TRUE; /* success (?) */
|
2004-04-01 04:12:41 +02:00
|
|
|
}
|
2005-01-20 20:57:58 +01:00
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* SendIMEMessageExA [USER32.@]
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI SendIMEMessageExA(HWND p1, LPARAM p2)
|
|
|
|
{
|
|
|
|
FIXME("(%p,%lx): stub\n", p1, p2);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**********************************************************************
|
|
|
|
* SendIMEMessageExW [USER32.@]
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
LRESULT WINAPI SendIMEMessageExW(HWND p1, LPARAM p2)
|
|
|
|
{
|
|
|
|
FIXME("(%p,%lx): stub\n", p1, p2);
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
return 0;
|
|
|
|
}
|