Commit 2e2d6ec7 authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

Stub the stopwatch API.

Implement DoesStringRoundTripW,@371-3,@392. Move a couple of string functions into string.c
parent 1c63357e
...@@ -17,6 +17,7 @@ C_SRCS = \ ...@@ -17,6 +17,7 @@ C_SRCS = \
reg.c \ reg.c \
regstream.c \ regstream.c \
shlwapi_main.c \ shlwapi_main.c \
stopwatch.c \
string.c \ string.c \
thread.c \ thread.c \
url.c \ url.c \
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "winbase.h" #include "winbase.h"
#include "winuser.h" #include "winuser.h"
#include "winnls.h" #include "winnls.h"
#include "ddeml.h"
#include "docobj.h" #include "docobj.h"
#include "exdisp.h" #include "exdisp.h"
#include "shlguid.h" #include "shlguid.h"
...@@ -70,7 +69,6 @@ extern HMODULE SHLWAPI_hwinmm; ...@@ -70,7 +69,6 @@ extern HMODULE SHLWAPI_hwinmm;
extern HMODULE SHLWAPI_hcomdlg32; extern HMODULE SHLWAPI_hcomdlg32;
extern HMODULE SHLWAPI_hcomctl32; extern HMODULE SHLWAPI_hcomctl32;
extern HMODULE SHLWAPI_hmpr; extern HMODULE SHLWAPI_hmpr;
extern HMODULE SHLWAPI_hmlang;
extern HMODULE SHLWAPI_hurlmon; extern HMODULE SHLWAPI_hurlmon;
extern HMODULE SHLWAPI_hversion; extern HMODULE SHLWAPI_hversion;
...@@ -86,8 +84,6 @@ static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00}; ...@@ -86,8 +84,6 @@ static DWORD id2[4] = {0x79eac9ee, 0x11cebaf9, 0xaa00828c, 0x0ba94b00};
/* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */ /* Function pointers for GET_FUNC macro; these need to be global because of gcc bug */
typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW); typedef LPITEMIDLIST (WINAPI *fnpSHBrowseForFolderW)(LPBROWSEINFOW);
static fnpSHBrowseForFolderW pSHBrowseForFolderW; static fnpSHBrowseForFolderW pSHBrowseForFolderW;
typedef HRESULT (WINAPI *fnpConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
static fnpConvertINetUnicodeToMultiByte pConvertINetUnicodeToMultiByte;
typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD); typedef BOOL (WINAPI *fnpPlaySoundW)(LPCWSTR, HMODULE, DWORD);
static fnpPlaySoundW pPlaySoundW; static fnpPlaySoundW pPlaySoundW;
typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT); typedef DWORD (WINAPI *fnpSHGetFileInfoW)(LPCWSTR,DWORD,SHFILEINFOW*,UINT,UINT);
...@@ -585,7 +581,7 @@ HRESULT WINAPI GetAcceptLanguagesA( ...@@ -585,7 +581,7 @@ HRESULT WINAPI GetAcceptLanguagesA(
/************************************************************************* /*************************************************************************
* @ [SHLWAPI.15] * @ [SHLWAPI.15]
* *
* Unicode version of SHLWAPI_14. * Unicode version of GetAcceptLanguagesA.
*/ */
HRESULT WINAPI GetAcceptLanguagesW( HRESULT WINAPI GetAcceptLanguagesW(
LPWSTR langbuf, LPWSTR langbuf,
...@@ -670,7 +666,7 @@ INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax) ...@@ -670,7 +666,7 @@ INT WINAPI SHStringFromGUIDW(REFGUID guid, LPWSTR lpszDest, INT cchMax)
{ {
char xguid[40]; char xguid[40];
INT iLen = SHStringFromGUIDA(guid, xguid, cchMax); INT iLen = SHStringFromGUIDA(guid, xguid, cchMax);
if (iLen) if (iLen)
MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax); MultiByteToWideChar(CP_ACP, 0, xguid, -1, lpszDest, cchMax);
return iLen; return iLen;
...@@ -1169,38 +1165,6 @@ BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen) ...@@ -1169,38 +1165,6 @@ BOOL WINAPI SHAboutInfoW(LPWSTR lpszDest, DWORD dwDestLen)
} }
/************************************************************************* /*************************************************************************
* @ [SHLWAPI.162]
*
* Remove a hanging lead byte from the end of a string, if present.
*
* PARAMS
* lpStr [I] String to check for a hanging lead byte
* size [I] Length of lpStr
*
* RETURNS
* Success: The new length of the string. Any hanging lead bytes are removed.
* Failure: 0, if any parameters are invalid.
*/
DWORD WINAPI SHTruncateString(LPSTR lpStr, DWORD size)
{
if (lpStr && size)
{
LPSTR lastByte = lpStr + size - 1;
while(lpStr < lastByte)
lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
{
*lpStr = '\0';
size--;
}
return size;
}
return 0;
}
/*************************************************************************
* @ [SHLWAPI.163] * @ [SHLWAPI.163]
* *
* Call IOleCommandTarget_QueryStatus() on an object. * Call IOleCommandTarget_QueryStatus() on an object.
...@@ -2176,148 +2140,6 @@ DWORD WINAPI FDSA_DeleteItem( ...@@ -2176,148 +2140,6 @@ DWORD WINAPI FDSA_DeleteItem(
return 1; return 1;
} }
/*************************************************************************
* @ [SHLWAPI.215]
*
* NOTES
* check me!
*/
DWORD WINAPI SHAnsiToUnicode(
LPCSTR lpStrSrc,
LPWSTR lpwStrDest,
int len)
{
INT len_a, ret;
len_a = lstrlenA(lpStrSrc);
ret = MultiByteToWideChar(0, 0, lpStrSrc, len_a, lpwStrDest, len);
TRACE("%s %s %d, ret=%d\n",
debugstr_a(lpStrSrc), debugstr_w(lpwStrDest), len, ret);
return ret;
}
/*************************************************************************
* @ [SHLWAPI.218]
*
* WideCharToMultiByte with support for multiple codepages.
*
* PARAMS
* CodePage [I] Code page to use for the conversion
* lpSrcStr [I] Source Unicode string to convert
* lpDstStr [O] Destination for converted Ascii string
* lpnMultiCharCount [O] Input length of lpDstStr/destination for length of lpDstStr
*
* RETURNS
* Success: The number of characters that result from the conversion.
* Failure: 0.
*/
INT WINAPI SHUnicodeToAnsiCP(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
LPINT lpnMultiCharCount)
{
WCHAR emptyW[] = { '\0' };
int len , reqLen;
LPSTR mem;
if (!lpDstStr || !lpnMultiCharCount)
return 0;
if (!lpSrcStr)
lpSrcStr = emptyW;
*lpDstStr = '\0';
len = strlenW(lpSrcStr) + 1;
switch (CodePage)
{
case CP_WINUNICODE:
CodePage = CP_UTF8; /* Fall through... */
case 0x0000C350: /* FIXME: CP_ #define */
case CP_UTF7:
case CP_UTF8:
{
DWORD dwMode = 0;
INT nWideCharCount = len - 1;
GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
lpnMultiCharCount))
return 0;
if (nWideCharCount < len - 1)
{
mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpnMultiCharCount);
if (!mem)
return 0;
*lpnMultiCharCount = 0;
if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpnMultiCharCount))
{
SHTruncateString(mem, *lpnMultiCharCount);
lstrcpynA(lpDstStr, mem, *lpnMultiCharCount + 1);
return *lpnMultiCharCount + 1;
}
HeapFree(GetProcessHeap(), 0, mem);
return *lpnMultiCharCount;
}
lpDstStr[*lpnMultiCharCount] = '\0';
return *lpnMultiCharCount;
}
break;
default:
break;
}
reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
*lpnMultiCharCount, NULL, NULL);
if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
if (reqLen)
{
mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
if (mem)
{
reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
reqLen, NULL, NULL);
reqLen = SHTruncateString(mem, *lpnMultiCharCount);
reqLen++;
lstrcpynA(lpDstStr, mem, *lpnMultiCharCount);
HeapFree(GetProcessHeap(), 0, mem);
}
}
}
return reqLen;
}
/*************************************************************************
* @ [SHLWAPI.217]
*
* WideCharToMultiByte with support for multiple codepages.
*
* PARAMS
* lpSrcStr [I] Source Unicode string to convert
* lpDstStr [O] Destination for converted Ascii string
* lpnMultiCharCount [O] Input length of lpDstStr/destination for length of lpDstStr
*
* RETURNS
* See SHUnicodeToAnsiCP
* NOTES
* This function simply calls SHUnicodeToAnsiCP with CodePage = CP_ACP.
*/
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT MultiCharCount)
{
INT myint = MultiCharCount;
return SHUnicodeToAnsiCP(CP_ACP, lpSrcStr, lpDstStr, &myint);
}
typedef struct { typedef struct {
REFIID refid; REFIID refid;
DWORD indx; DWORD indx;
...@@ -2515,16 +2337,6 @@ LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM ...@@ -2515,16 +2337,6 @@ LRESULT CALLBACK SHDefWindowProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM
} }
/************************************************************************* /*************************************************************************
* @ [SHLWAPI.241]
*
*/
DWORD WINAPI StopWatchMode()
{
FIXME("()stub\n");
return /* 0xabba1243 */ 0;
}
/*************************************************************************
* @ [SHLWAPI.257] * @ [SHLWAPI.257]
* *
* Create a worker window using CreateWindowExA(). * Create a worker window using CreateWindowExA().
...@@ -3358,25 +3170,6 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST ...@@ -3358,25 +3170,6 @@ HRESULT WINAPI SHInvokeCommand(HWND hWnd, IShellFolder* lpFolder, LPCITEMIDLIST
} }
/************************************************************************* /*************************************************************************
* @ [SHLWAPI.364]
*
* Copy one string to another, up to a given length.
*
* PARAMS
* lpszSrc [I] Source string to copy
* lpszDst [O] Destination for copied string
* iLen [I] Number of characters to copy
*
* RETURNS
* TRUE.
*/
DWORD WINAPI DoesStringRoundTripA(LPCSTR lpszSrc, LPSTR lpszDst, INT iLen)
{
lstrcpynA(lpszDst, lpszSrc, iLen);
return TRUE;
}
/*************************************************************************
* @ [SHLWAPI.370] * @ [SHLWAPI.370]
* *
* See ExtractIconW. * See ExtractIconW.
......
...@@ -239,17 +239,17 @@ ...@@ -239,17 +239,17 @@
239 stdcall -noname SHUnregisterClassesW(ptr ptr long) 239 stdcall -noname SHUnregisterClassesW(ptr ptr long)
240 stdcall -noname SHDefWindowProc(long long long long) 240 stdcall -noname SHDefWindowProc(long long long long)
241 stdcall -noname StopWatchMode() 241 stdcall -noname StopWatchMode()
242 stub -noname StopWatchFlush 242 stdcall -noname StopWatchFlush()
243 stub -noname StopWatchA 243 stdcall -noname StopWatchA(long str long long long)
244 stub -noname StopWatchW 244 stdcall -noname StopWatchW(long wstr long long long)
245 stub -noname StopWatch_TimerHandler 245 stdcall -noname StopWatch_TimerHandler(ptr ptr long ptr)
246 stub -noname StopWatch_CheckMsg 246 stub -noname StopWatch_CheckMsg
247 stub -noname StopWatch_MarkFrameStart 247 stdcall -noname StopWatch_MarkFrameStart(str)
248 stub -noname StopWatch_MarkSameFramStart 248 stub -noname StopWatch_MarkSameFrameStart
249 stub -noname StopWatch_MarkJavaStop 249 stdcall -noname StopWatch_MarkJavaStop(wstr ptr long)
250 stub -noname GetPerfTime 250 stdcall -noname GetPerfTime()
251 stub -noname StopWatch_DispatchTime 251 stub -noname StopWatch_DispatchTime
252 stub -noname StopWatch_SetMsgLastLocation 252 stdcall -noname StopWatch_SetMsgLastLocation(long)
253 stub -noname StopWatchExA 253 stub -noname StopWatchExA
254 stub -noname StopWatchExW 254 stub -noname StopWatchExW
255 stub -noname EventTraceHandler 255 stub -noname EventTraceHandler
...@@ -361,16 +361,16 @@ ...@@ -361,16 +361,16 @@
361 stdcall @(wstr ptr long) kernel32.GetShortPathNameW 361 stdcall @(wstr ptr long) kernel32.GetShortPathNameW
362 stdcall @(ptr ptr) advapi32.GetUserNameW 362 stdcall @(ptr ptr) advapi32.GetUserNameW
363 stdcall -noname SHInvokeCommand(ptr ptr ptr long) 363 stdcall -noname SHInvokeCommand(ptr ptr ptr long)
364 stdcall -noname DoesStringRoundTripA(str str long) 364 stdcall -noname DoesStringRoundTripA(str ptr long)
365 stub -noname DoesStringRoundTripW 365 stdcall -noname DoesStringRoundTripW(wstr ptr long)
366 stdcall @(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumValueW 366 stdcall @(long long ptr ptr ptr ptr ptr ptr) advapi32.RegEnumValueW
367 stdcall @(wstr wstr ptr long wstr) kernel32.WritePrivateProfileStructW 367 stdcall @(wstr wstr ptr long wstr) kernel32.WritePrivateProfileStructW
368 stdcall @(wstr wstr ptr long wstr) kernel32.GetPrivateProfileStructW 368 stdcall @(wstr wstr ptr long wstr) kernel32.GetPrivateProfileStructW
369 stdcall @(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW 369 stdcall @(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW
370 stdcall -noname ExtractIconWrapW(long wstr long) 370 stdcall -noname ExtractIconWrapW(long wstr long)
371 stub -noname DdeInitializeWrapW 371 stdcall -noname DdeInitializeWrapW(ptr ptr long long) user32.DdeInitializeW
372 stub -noname DdeCreateStringHandleWrapW 372 stdcall -noname DdeCreateStringHandleWrapW(long ptr long) user32.DdeCreateStringHandleW
373 stub -noname DdeQueryStringWrapW 373 stdcall -noname DdeQueryStringWrapW(long ptr wstr long long) user32.DdeQueryStringW
374 stub -noname SHCheckDiskForMediaA 374 stub -noname SHCheckDiskForMediaA
375 stub -noname SHCheckDiskForMediaW 375 stub -noname SHCheckDiskForMediaW
376 stdcall -noname MLGetUILanguage() # kernel32.GetUserDefaultUILanguage 376 stdcall -noname MLGetUILanguage() # kernel32.GetUserDefaultUILanguage
...@@ -389,7 +389,7 @@ ...@@ -389,7 +389,7 @@
389 stdcall -noname GetSaveFileNameWrapW(ptr) 389 stdcall -noname GetSaveFileNameWrapW(ptr)
390 stdcall -noname WNetRestoreConnectionWrapW(long wstr) 390 stdcall -noname WNetRestoreConnectionWrapW(long wstr)
391 stdcall -noname WNetGetLastErrorWrapW(ptr ptr long ptr long) 391 stdcall -noname WNetGetLastErrorWrapW(ptr ptr long ptr long)
392 stub -noname EndDialogWrap 392 stdcall -noname EndDialogWrap(ptr ptr) user32.EndDialog
393 stdcall @(long ptr long ptr long) user32.CreateDialogIndirectParamW 393 stdcall @(long ptr long ptr long) user32.CreateDialogIndirectParamW
394 stdcall @(long ptr long ptr long) user32.CreateDialogIndirectParamA 394 stdcall @(long ptr long ptr long) user32.CreateDialogIndirectParamA
395 stub -noname MLWinHelpA 395 stub -noname MLWinHelpA
......
/*
* Stopwatch Functions
*
* Copyright 2004 Jon Griffiths
*
* 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
*
* NOTES
* These functions probably never need to be implemented unless we
* A) Rewrite explorer from scratch, and
* B) Want to use a substandard API to tune its performance.
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "wine/unicode.h"
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winreg.h"
#define NO_SHLWAPI_STREAM
#include "shlwapi.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/*************************************************************************
* @ [SHLWAPI.241]
*
* Get the current performance monitoring mode.
*
* PARAMS
* None.
*
* RETURNS
* The current performance monitoring mode. This is zero if monitoring
* is disabled (the default).
*
* NOTES
* If this function returns 0, no further StopWatch functions should be called.
*/
DWORD WINAPI StopWatchMode()
{
FIXME("() stub!\n");
return 0;
}
/*************************************************************************
* @ [SHLWAPI.242]
*
* Write captured performance nodes to a log file.
*
* PARAMS
* None.
*
* RETURNS
* Nothing.
*/
void WINAPI StopWatchFlush()
{
FIXME("() stub!\n");
}
/*************************************************************************
* @ [SHLWAPI.243]
*
* Write a performance event to a log file
*
* PARAMS
* dwClass [I] Class of event
* lpszStr [I] Text of event to log
* dwUnknown [I] Unknown
* dwMode [I] Mode flags
* dwTimeStamp [I] Timestamp
*
* RETURNS
* Success: ERROR_SUCCESS.
* Failure: A standard Win32 error code indicating the failure.
*/
DWORD WINAPI StopWatchA(DWORD dwClass, LPCSTR lpszStr, DWORD dwUnknown,
DWORD dwMode, DWORD dwTimeStamp)
{
FIXME("(%ld,%s,%ld,%ld,%ld) stub!\n", dwClass, debugstr_a(lpszStr),
dwUnknown, dwMode, dwTimeStamp);
return ERROR_SUCCESS;
}
/*************************************************************************
* @ [SHLWAPI.244]
*
* See StopWatchA.
*/
DWORD WINAPI StopWatchW(DWORD dwClass, LPCWSTR lpszStr, DWORD dwUnknown,
DWORD dwMode, DWORD dwTimeStamp)
{
char szBuff[MAX_PATH];
if(!WideCharToMultiByte(0, 0, lpszStr, -1, szBuff, MAX_PATH, 0, 0))
return ERROR_NOT_ENOUGH_MEMORY;
return StopWatchA(dwClass, szBuff, dwUnknown, dwMode, dwTimeStamp);
}
/*************************************************************************
* @ [SHLWAPI.245]
*
* Log a shell frame event.
*
* PARAMS
* hWnd [I] Window having the event
* pvUnknown1 [I] Unknown
* bUnknown2 [I] Unknown
* pClassWnd [I] Window of class to log
*
* RETURNS
* Nothing.
*/
void WINAPI StopWatch_TimerHandler(HWND hWnd, PVOID pvUnknown1, BOOL bUnknown2, HWND *pClassWnd)
{
FIXME("(%p,%p,%d,%p) stub!\n", hWnd, pvUnknown1, bUnknown2 ,pClassWnd);
}
/* FIXME: Parameters for @246:StopWatch_CheckMsg unknown */
/*************************************************************************
* @ [SHLWAPI.247]
*
* Log the start of an applet.
*
* PARAMS
* lpszName [I] Name of the applet
*
* RETURNS
* Nothing.
*/
void WINAPI StopWatch_MarkFrameStart(LPCSTR lpszName)
{
FIXME("(%s) stub!\n", debugstr_a(lpszName));
}
/* FIXME: Parameters for @248:StopWatch_MarkSameFrameStart unknown */
/*************************************************************************
* @ [SHLWAPI.249]
*
* Log a java applet stopping.
*
* PARAMS
* lpszEvent [I] Name of the event (applet)
* hWnd [I] Window running the applet
* dwReserved [I] Unused
*
* RETURNS
* Nothing.
*/
void WINAPI StopWatch_MarkJavaStop(LPCWSTR lpszEvent, HWND hWnd, DWORD dwReserved)
{
FIXME("(%s,%p,0x%08lx) stub!\n", debugstr_w(lpszEvent), hWnd, dwReserved);
}
/*************************************************************************
* @ [SHLWAPI.250]
*
* Read the performance counter.
*
* PARAMS
* None.
*
* RETURNS
* The low 32 bits of the current performance counter reading.
*/
DWORD WINAPI GetPerfTime()
{
static LONG64 iCounterFreq = 0;
LARGE_INTEGER iCounter;
TRACE("()\n");
if (!iCounterFreq)
QueryPerformanceFrequency((LARGE_INTEGER*)&iCounterFreq);
QueryPerformanceCounter(&iCounter);
iCounter.QuadPart = iCounter.QuadPart * 1000 / iCounterFreq;
return iCounter.u.LowPart;
}
/* FIXME: Parameters for @251:StopWatch_DispatchTime unknown */
/*************************************************************************
* @ [SHLWAPI.252]
*
* Set an as yet unidentified performance value.
*
* PARAMS
* dwUnknown [I] Value to set
*
* RETURNS
* dwUnknown.
*/
DWORD WINAPI StopWatch_SetMsgLastLocation(DWORD dwUnknown)
{
FIXME("(%ld) stub!\n", dwUnknown);
return dwUnknown;
}
/* FIXME: Parameters for @253:StopWatchExA, 254:StopWatchExW unknown */
...@@ -38,11 +38,27 @@ ...@@ -38,11 +38,27 @@
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "shlobj.h" #include "shlobj.h"
#include "ddeml.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell); WINE_DEFAULT_DEBUG_CHANNEL(shell);
/* Get a function pointer from a DLL handle */
#define GET_FUNC(func, module, name, fail) \
do { \
if (!func) { \
if (!SHLWAPI_h##module && !(SHLWAPI_h##module = LoadLibraryA(#module ".dll"))) return fail; \
func = (fn##func)GetProcAddress(SHLWAPI_h##module, name); \
if (!func) return fail; \
} \
} while (0)
extern HMODULE SHLWAPI_hmlang;
typedef HRESULT (WINAPI *fnpConvertINetUnicodeToMultiByte)(LPDWORD,DWORD,LPCWSTR,LPINT,LPSTR,LPINT);
static fnpConvertINetUnicodeToMultiByte pConvertINetUnicodeToMultiByte;
static HRESULT WINAPI _SHStrDupAA(LPCSTR,LPSTR*); static HRESULT WINAPI _SHStrDupAA(LPCSTR,LPSTR*);
static HRESULT WINAPI _SHStrDupAW(LPCWSTR,LPSTR*); static HRESULT WINAPI _SHStrDupAW(LPCWSTR,LPSTR*);
...@@ -2390,6 +2406,38 @@ LPSTR WINAPI StrFormatByteSizeA(DWORD dwBytes, LPSTR lpszDest, UINT cchMax) ...@@ -2390,6 +2406,38 @@ LPSTR WINAPI StrFormatByteSizeA(DWORD dwBytes, LPSTR lpszDest, UINT cchMax)
} }
/************************************************************************* /*************************************************************************
* @ [SHLWAPI.162]
*
* Remove a hanging lead byte from the end of a string, if present.
*
* PARAMS
* lpStr [I] String to check for a hanging lead byte
* size [I] Length of lpStr
*
* RETURNS
* Success: The new length of the string. Any hanging lead bytes are removed.
* Failure: 0, if any parameters are invalid.
*/
DWORD WINAPI SHTruncateString(LPSTR lpStr, DWORD size)
{
if (lpStr && size)
{
LPSTR lastByte = lpStr + size - 1;
while(lpStr < lastByte)
lpStr += IsDBCSLeadByte(*lpStr) ? 2 : 1;
if(lpStr == lastByte && IsDBCSLeadByte(*lpStr))
{
*lpStr = '\0';
size--;
}
return size;
}
return 0;
}
/*************************************************************************
* @ [SHLWAPI.203] * @ [SHLWAPI.203]
* *
* Remove a single non-trailing ampersand ('&') from a string. * Remove a single non-trailing ampersand ('&') from a string.
...@@ -2429,3 +2477,189 @@ char WINAPI SHStripMneumonicA(LPCSTR lpszStr) ...@@ -2429,3 +2477,189 @@ char WINAPI SHStripMneumonicA(LPCSTR lpszStr)
return ch; return ch;
} }
/*************************************************************************
* @ [SHLWAPI.215]
*
* Convert an Ascii string to Unicode.
*
* PARAMS
* lpSrcStr [I] Source Ascii string to convert
* lpDstStr [O] Destination for converted Unicode string
* iLen [I] Length of lpDstStr
*
* RETURNS
* The return value of the MultiByteToWideChar() function called on lpSrcStr.
*/
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
{
DWORD dwRet;
dwRet = MultiByteToWideChar(CP_ACP, 0, lpSrcStr, -1, lpDstStr, iLen);
TRACE("%s->%s,ret=%ld\n", debugstr_a(lpSrcStr), debugstr_w(lpDstStr), dwRet);
return dwRet;
}
/*************************************************************************
* @ [SHLWAPI.218]
*
* Convert a Unicode string to Ascii.
*
* PARAMS
* CodePage [I] Code page to use for the conversion
* lpSrcStr [I] Source Unicode string to convert
* lpDstStr [O] Destination for converted Ascii string
* lpiLen [I/O] Input length of lpDstStr/destination for length of lpDstStr
*
* RETURNS
* Success: The number of characters that result from the conversion.
* Failure: 0.
*/
INT WINAPI SHUnicodeToAnsiCP(UINT CodePage, LPCWSTR lpSrcStr, LPSTR lpDstStr,
LPINT lpiLen)
{
WCHAR emptyW[] = { '\0' };
int len , reqLen;
LPSTR mem;
if (!lpDstStr || !lpiLen)
return 0;
if (!lpSrcStr)
lpSrcStr = emptyW;
*lpDstStr = '\0';
len = strlenW(lpSrcStr) + 1;
switch (CodePage)
{
case CP_WINUNICODE:
CodePage = CP_UTF8; /* Fall through... */
case 0x0000C350: /* FIXME: CP_ #define */
case CP_UTF7:
case CP_UTF8:
{
DWORD dwMode = 0;
INT nWideCharCount = len - 1;
GET_FUNC(pConvertINetUnicodeToMultiByte, mlang, "ConvertINetUnicodeToMultiByte", 0);
if (!pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &nWideCharCount, lpDstStr,
lpiLen))
return 0;
if (nWideCharCount < len - 1)
{
mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, *lpiLen);
if (!mem)
return 0;
*lpiLen = 0;
if (pConvertINetUnicodeToMultiByte(&dwMode, CodePage, lpSrcStr, &len, mem, lpiLen))
{
SHTruncateString(mem, *lpiLen);
lstrcpynA(lpDstStr, mem, *lpiLen + 1);
return *lpiLen + 1;
}
HeapFree(GetProcessHeap(), 0, mem);
return *lpiLen;
}
lpDstStr[*lpiLen] = '\0';
return *lpiLen;
}
break;
default:
break;
}
reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, lpDstStr,
*lpiLen, NULL, NULL);
if (!reqLen && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, NULL, 0, NULL, NULL);
if (reqLen)
{
mem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, reqLen);
if (mem)
{
reqLen = WideCharToMultiByte(CodePage, 0, lpSrcStr, len, mem,
reqLen, NULL, NULL);
reqLen = SHTruncateString(mem, *lpiLen);
reqLen++;
lstrcpynA(lpDstStr, mem, *lpiLen);
HeapFree(GetProcessHeap(), 0, mem);
}
}
}
return reqLen;
}
/*************************************************************************
* @ [SHLWAPI.217]
*
* Convert a Unicode string to Ascii.
*
* PARAMS
* lpSrcStr [I] Source Unicode string to convert
* lpDstStr [O] Destination for converted Ascii string
* iLen [O] Length of lpDstStr in characters
*
* RETURNS
* See SHUnicodeToAnsiCP
* NOTES
* This function simply calls SHUnicodeToAnsiCP() with CodePage = CP_ACP.
*/
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
{
INT myint = iLen;
return SHUnicodeToAnsiCP(CP_ACP, lpSrcStr, lpDstStr, &myint);
}
/*************************************************************************
* @ [SHLWAPI.364]
*
* Determine if an Ascii string converts to Unicode and back identically.
*
* PARAMS
* lpSrcStr [I] Source Unicode string to convert
* lpDst [O] Destination for resulting Ascii string
* iLen [I] Length of lpDst in characters
*
* RETURNS
* TRUE, since Ascii strings always convert identically.
*/
BOOL WINAPI DoesStringRoundTripA(LPCSTR lpSrcStr, LPSTR lpDst, INT iLen)
{
lstrcpynA(lpDst, lpSrcStr, iLen);
return TRUE;
}
/*************************************************************************
* @ [SHLWAPI.365]
*
* Determine if a Unicode string converts to Ascii and back identically.
*
* PARAMS
* lpSrcStr [I] Source Unicode string to convert
* lpDst [O] Destination for resulting Ascii string
* iLen [I] Length of lpDst in characters
*
* RETURNS
* TRUE, if lpSrcStr converts to Ascii and back identically,
* FALSE otherwise.
*/
BOOL WINAPI DoesStringRoundTripW(LPCWSTR lpSrcStr, LPSTR lpDst, INT iLen)
{
WCHAR szBuff[MAX_PATH];
SHUnicodeToAnsi(lpSrcStr, lpDst, iLen);
SHAnsiToUnicode(lpDst, szBuff, MAX_PATH);
return !strcmpW(lpSrcStr, szBuff);
}
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