diff --git a/reactos/lib/shlwapi/Makefile.in b/reactos/lib/shlwapi/Makefile.in index a2f1d67a4c2..a1a08a92d7e 100644 --- a/reactos/lib/shlwapi/Makefile.in +++ b/reactos/lib/shlwapi/Makefile.in @@ -12,6 +12,7 @@ C_SRCS = \ assoc.c \ clist.c \ istream.c \ + msgbox.c \ ordinal.c \ path.c \ reg.c \ @@ -23,6 +24,9 @@ C_SRCS = \ url.c \ wsprintf.c +RC_SRCS = \ + shlwapi.rc + SUBDIRS = tests @MAKE_DLL_RULES@ diff --git a/reactos/lib/shlwapi/msgbox.c b/reactos/lib/shlwapi/msgbox.c new file mode 100644 index 00000000000..d61c5f9815d --- /dev/null +++ b/reactos/lib/shlwapi/msgbox.c @@ -0,0 +1,297 @@ +/* + * SHLWAPI message box 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 + */ + +#define COM_NO_WINDOWS_H +#include "config.h" +#include "wine/port.h" + +#include +#include + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "shlwapi.h" +#include "wine/unicode.h" +#include "wine/debug.h" +#include "resource.h" + + +WINE_DEFAULT_DEBUG_CHANNEL(shell); + +extern HINSTANCE shlwapi_hInstance; /* in shlwapi_main.c */ + +static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w', + 'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0' +}; + +INT_PTR WINAPI SHMessageBoxCheckExW(HWND,HINSTANCE,LPCWSTR,DLGPROC,LPARAM,INT_PTR,LPCWSTR); +INT_PTR WINAPI SHMessageBoxCheckW(HWND,LPCWSTR,LPCWSTR,DWORD,INT_PTR,LPCWSTR); + +/* Data held by each general message boxes */ +typedef struct tagDLGDATAEX +{ + DLGPROC dlgProc; /* User supplied DlgProc */ + LPARAM lParam; /* User supplied LPARAM for dlgProc */ + LPCWSTR lpszId; /* Name of reg key holding whether to skip */ +} DLGDATAEX; + +/* Dialogue procedure for general message boxes */ +static INT_PTR CALLBACK SHDlgProcEx(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + DLGDATAEX *d = (DLGDATAEX *)GetWindowLongW(hDlg, DWL_USER); + + TRACE("(%p,%u,%d,%ld) data %p\n", hDlg, uMsg, wParam, lParam, d); + + switch (uMsg) + { + case WM_INITDIALOG: + { + /* FIXME: Not sure where native stores its lParam */ + SetWindowLongW(hDlg, DWL_USER, lParam); + d = (DLGDATAEX *)lParam; + TRACE("WM_INITDIALOG: %p, %s,%p,%p\n", hDlg, debugstr_w(d->lpszId), + d->dlgProc, (void*)d->lParam); + if (d->dlgProc) + return d->dlgProc(hDlg, uMsg, wParam, d->lParam); + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDYES: + LOWORD(wParam) = IDOK; + /* Fall through ... */ + case IDNO: + if (LOWORD(wParam) == IDNO) + LOWORD(wParam) = IDCANCEL; + /* Fall through ... */ + case IDOK: + case IDCANCEL: + + TRACE("WM_COMMAND: id=%s data=%p\n", + LOWORD(wParam) == IDOK ? "IDOK" : "IDCANCEL", d); + + if (SendMessageW(GetDlgItem(hDlg, IDC_ERR_DONT_SHOW), BM_GETCHECK, 0L, 0L)) + { + DWORD dwZero = 0; + + /* The user clicked 'don't show again', so set the key */ + SHRegSetUSValueW(szDontShowKey, d->lpszId, REG_DWORD, &dwZero, + sizeof(dwZero), SHREGSET_DEFAULT); + } + if (!d->dlgProc || !d->dlgProc(hDlg, uMsg, wParam, lParam)) + EndDialog(hDlg, wParam); + return TRUE; + } + break; + + default: + break; + } + + if (d && d->dlgProc) + return d->dlgProc(hDlg, uMsg, wParam, lParam); + return FALSE; +} + +/************************************************************************* + * @ [SHLWAPI.291] + * + * Pop up a 'Don't show this message again' dialogue box. + * + * PARAMS + * hWnd [I] Window to be the dialogues' parent + * hInst [I] Instance of the module holding the dialogue resource + * lpszName [I] Resource Id of the dialogue resource + * dlgProc [I] Dialog procedure, or NULL for default handling + * lParam [I] LPARAM to pass to dlgProc + * iRet [I] Value to return if dialogue is not shown + * lpszId [I] Name of registry subkey which determines whether to show the dialog + * + * RETURNS + * Success: The value returned from the dialogue procedure. + * Failure: iRet, if the dialogue resource could not be loaded or the dialogue + * should not be shown. + * + * NOTES + * Both lpszName and lpszId must be less than MAX_PATH in length. + */ +INT_PTR WINAPI SHMessageBoxCheckExA(HWND hWnd, HINSTANCE hInst, LPCSTR lpszName, + DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet, + LPCSTR lpszId) +{ + WCHAR szNameBuff[MAX_PATH], szIdBuff[MAX_PATH]; + LPCWSTR szName = szNameBuff; + + if (HIWORD(lpszName)) + MultiByteToWideChar(CP_ACP, 0, lpszName, -1, szNameBuff, MAX_PATH); + else + szName = (LPCWSTR)lpszName; /* Resource Id or NULL */ + + MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH); + + return SHMessageBoxCheckExW(hWnd, hInst, szName, dlgProc, lParam, iRet, szIdBuff); +} + +/************************************************************************* + * @ [SHLWAPI.292] + * + * Unicode version of SHMessageBoxCheckExW. + */ +INT_PTR WINAPI SHMessageBoxCheckExW(HWND hWnd, HINSTANCE hInst, LPCWSTR lpszName, + DLGPROC dlgProc, LPARAM lParam, INT_PTR iRet, LPCWSTR lpszId) +{ + DLGDATAEX d; + + if (!SHRegGetBoolUSValueW(szDontShowKey, lpszId, FALSE, TRUE)) + return iRet; + + d.dlgProc = dlgProc; + d.lParam = lParam; + d.lpszId = lpszId; + return DialogBoxParamW(hInst, (LPCWSTR)lpszName, hWnd, SHDlgProcEx, (LPARAM)&d); +} + +/* Data held by each shlwapi message box */ +typedef struct tagDLGDATA +{ + LPCWSTR lpszTitle; /* User supplied message title */ + LPCWSTR lpszText; /* User supplied message text */ + DWORD dwType; /* Message box type */ +} DLGDATA; + +/* Dialogue procedure for shlwapi message boxes */ +static INT_PTR CALLBACK SHDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + TRACE("(%p,%u,%d,%ld)\n", hDlg, uMsg, wParam, lParam); + + switch (uMsg) + { + case WM_INITDIALOG: + { + DLGDATA *d = (DLGDATA *)lParam; + TRACE("WM_INITDIALOG: %p, %s,%s,%ld\n", hDlg, debugstr_w(d->lpszTitle), + debugstr_w(d->lpszText), d->dwType); + + SetWindowTextW(hDlg, d->lpszTitle); + SetWindowTextW(GetDlgItem(hDlg, IDS_ERR_USER_MSG), d->lpszText); + + /* Set buttons according to dwType */ + switch (d->dwType) + { + case 0: + ShowWindow(GetDlgItem(hDlg, IDCANCEL), FALSE); + /* FIXME: Move OK button to position of the Cancel button (cosmetic) */ + case 1: + ShowWindow(GetDlgItem(hDlg, IDYES), FALSE); + ShowWindow(GetDlgItem(hDlg, IDNO), FALSE); + break; + default: + ShowWindow(GetDlgItem(hDlg, IDOK), FALSE); + ShowWindow(GetDlgItem(hDlg, IDCANCEL), FALSE); + break; + } + return TRUE; + } + default: + break; + } + return FALSE; +} + +/************************************************************************* + * @ [SHLWAPI.185] + * + * Pop up a 'Don't show this message again' dialogue box. + * + * PARAMS + * hWnd [I] Window to be the dialogues' parent + * lpszText [I] Text of the message to show + * lpszTitle [I] Title of the dialogue box + * dwType [I] Type of dialogue buttons (See below) + * iRet [I] Value to return if dialogue is not shown + * lpszId [I] Name of registry subkey which determines whether to show the dialog + * + * RETURNS + * Success: The value returned from the dialogue procedure (e.g. IDOK). + * Failure: iRet, if the default dialogue resource could not be loaded or the + * dialogue should not be shown. + * + * NOTES + * - Both lpszTitle and lpszId must be less than MAX_PATH in length. + * - Possible values for dwType are: + *| Value Buttons + *| ----- ------- + *| 0 OK + *| 1 OK/Cancel + *| 2 Yes/No + */ +INT_PTR WINAPI SHMessageBoxCheckA(HWND hWnd, LPCSTR lpszText, LPCSTR lpszTitle, + DWORD dwType, INT_PTR iRet, LPCSTR lpszId) +{ + WCHAR szTitleBuff[MAX_PATH], szIdBuff[MAX_PATH]; + WCHAR *szTextBuff = NULL; + int iLen; + INT_PTR iRetVal; + + if (lpszTitle) + MultiByteToWideChar(CP_ACP, 0, lpszTitle, -1, szTitleBuff, MAX_PATH); + + if (lpszText) + { + iLen = MultiByteToWideChar(CP_ACP, 0, lpszText, -1, NULL, 0); + szTextBuff = HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, lpszText, -1, szTextBuff, iLen); + } + + MultiByteToWideChar(CP_ACP, 0, lpszId, -1, szIdBuff, MAX_PATH); + + iRetVal = SHMessageBoxCheckW(hWnd, szTextBuff, lpszTitle ? szTitleBuff : NULL, + dwType, iRet, szIdBuff); + if (szTextBuff) + HeapFree(GetProcessHeap(), 0, szTextBuff); + return iRetVal; +} + +/************************************************************************* + * @ [SHLWAPI.191] + * + * Unicode version of SHMessageBoxCheckA. + */ +INT_PTR WINAPI SHMessageBoxCheckW(HWND hWnd, LPCWSTR lpszText, LPCWSTR lpszTitle, + DWORD dwType, INT_PTR iRet, LPCWSTR lpszId) +{ + DLGDATA d; + + d.lpszTitle = lpszTitle; + d.lpszText = lpszText; + d.dwType = dwType; + + return SHMessageBoxCheckExW(hWnd, shlwapi_hInstance, (LPCWSTR)IDD_ERR_DIALOG, + SHDlgProc, (LPARAM)&d, iRet, lpszId); +} diff --git a/reactos/lib/shlwapi/ordinal.c b/reactos/lib/shlwapi/ordinal.c index 96b4b67a6ef..4c0766e6260 100644 --- a/reactos/lib/shlwapi/ordinal.c +++ b/reactos/lib/shlwapi/ordinal.c @@ -45,7 +45,6 @@ #include "wine/unicode.h" #include "servprov.h" #include "winreg.h" -#include "winuser.h" #include "wine/debug.h" #include "shlwapi.h" @@ -1902,41 +1901,6 @@ DWORD WINAPI IUnknown_OnFocusOCS(IUnknown *lpUnknown, IDispatch** lppDisp) return hRet; } -static const WCHAR szDontShowKey[] = { 'S','o','f','t','w','a','r','e','\\', - 'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\', - 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', - 'E','x','p','l','o','r','e','r','\\','D','o','n','t','S','h','o','w', - 'M','e','T','h','i','s','D','i','a','l','o','g','A','g','a','i','n','\0' -}; - -/************************************************************************* - * @ [SHLWAPI.191] - * - * Pop up a 'Don't show this message again' error dialog box. - * - * PARAMS - * hWnd [I] Window to own the dialog box - * arg2 [I] Unknown - * arg3 [I] Unknown - * arg4 [I] Unknown - * arg5 [I] Unknown - * lpszValue [I] Registry value holding boolean show/don't show. - * - * RETURNS - * Nothing. - */ -void WINAPI SHMessageBoxCheckW(HWND hWnd, PVOID arg2, PVOID arg3, PVOID arg4, PVOID arg5, LPCWSTR lpszValue) -{ - FIXME("(%p,%p,%p,%p,%p,%s) - stub!\n", hWnd, arg2, arg3, arg4, arg5, debugstr_w(lpszValue)); - - if (SHRegGetBoolUSValueW(szDontShowKey, lpszValue, FALSE, TRUE)) - { - /* FIXME: Should use DialogBoxParamW to load a dialog box; its dlgproc - * should accept clicks on 'Don't show' and set the reg value appropriately. - */ - } -} - /************************************************************************* * @ [SHLWAPI.192] * @@ -1988,6 +1952,41 @@ DWORD WINAPI SHGetCurColorRes() return ret; } +/************************************************************************* + * @ [SHLWAPI.194] + * + * Wait for a message to arrive, with a timeout. + * + * PARAMS + * hand [I] Handle to query + * dwTimeout [I] Timeout in ticks or INFINITE to never timeout + * + * RETURNS + * STATUS_TIMEOUT if no message is received before dwTimeout ticks passes. + * Otherwise returns the value from MsgWaitForMultipleObjectsEx when a + * message is available. + */ +DWORD WINAPI SHWaitForSendMessageThread(HANDLE hand, DWORD dwTimeout) +{ + DWORD dwEndTicks = GetTickCount() + dwTimeout; + DWORD dwRet; + + while ((dwRet = MsgWaitForMultipleObjectsEx(1, &hand, dwTimeout, QS_SENDMESSAGE, 0)) == 1) + { + MSG msg; + + PeekMessageW(&msg, NULL, 0, 0, PM_NOREMOVE); + + if (dwTimeout != INFINITE) + { + if ((int)(dwTimeout = dwEndTicks - GetTickCount()) <= 0) + return WAIT_TIMEOUT; + } + } + + return dwRet; +} + /************************************************************************* * @ [SHLWAPI.197] * @@ -2009,6 +2008,43 @@ DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef) return 0; } +/************************************************************************* + * @ [SHLWAPI.198] + * + * Return the value asociated with a key in a map. + * + * PARAMS + * lpKeys [I] A list of keys of length iLen + * lpValues [I] A list of values associated with lpKeys, of length iLen + * iLen [I] Length of both lpKeys and lpValues + * iKey [I] The key value to look up in lpKeys + * + * RETURNS + * The value in lpValues associated with iKey, or -1 if iKey is not + * found in lpKeys. + * + * NOTES + * - If two elements in the map share the same key, this function returns + * the value closest to the start of the map + * - The native version of this function crashes if lpKeys or lpValues is NULL. + */ +int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey) +{ + if (lpKeys && lpValues) + { + int i = 0; + + while (i < iLen) + { + if (lpKeys[i] == iKey) + return lpValues[i]; /* Found */ + i++; + } + } + return -1; /* Not found */ +} + + /************************************************************************* * @ [SHLWAPI.199] * @@ -2421,12 +2457,12 @@ static WCHAR strRegistryPolicyW[] = {'S','o','f','t','w','a','r','e','\\','M','i */ DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpValue) { - DWORD retval, datsize = 4; + DWORD retval, datsize = sizeof(retval); HKEY hKey; if (!lpSubKey) lpSubKey = (LPCWSTR)strRegistryPolicyW; - + retval = RegOpenKeyW(HKEY_LOCAL_MACHINE, lpSubKey, &hKey); if (retval != ERROR_SUCCESS) retval = RegOpenKeyW(HKEY_CURRENT_USER, lpSubKey, &hKey); @@ -2435,7 +2471,7 @@ DWORD WINAPI SHGetRestriction(LPCWSTR lpSubKey, LPCWSTR lpSubName, LPCWSTR lpVal SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize); RegCloseKey(hKey); - return retval; + return retval; } /************************************************************************* @@ -3801,6 +3837,31 @@ DWORD WINAPI SHMenuIndexFromID(HMENU hMenu, UINT uID) return GetMenuPosFromID(hMenu, uID); } + +/************************************************************************* + * @ [SHLWAPI.448] + */ +VOID WINAPI FixSlashesAndColonW(LPWSTR lpwstr) +{ + while (*lpwstr) + { + if (*lpwstr == '/') + *lpwstr = '\\'; + lpwstr++; + } +} + + +/************************************************************************* + * @ [SHLWAPI.461] + */ +DWORD WINAPI SHGetAppCompatFlags() +{ + FIXME("stub\n"); + return 0; +} + + /************************************************************************* * @ [SHLWAPI.549] */ diff --git a/reactos/lib/shlwapi/reg.c b/reactos/lib/shlwapi/reg.c index d51a9a0994b..f18409bba74 100644 --- a/reactos/lib/shlwapi/reg.c +++ b/reactos/lib/shlwapi/reg.c @@ -47,11 +47,12 @@ static const WCHAR szExtensionW[] = { 'E', 'x', 't','e','n','s','i','o','n','\0' /* internal structure of what the HUSKEY points to */ typedef struct { - HKEY HKCUkey; /* HKEY of opened HKCU key */ - HKEY HKLMkey; /* HKEY of opened HKLM key */ - HKEY start; /* HKEY of where to start */ - WCHAR key_string[MAX_PATH]; /* additional path from 'start' */ -} Internal_HUSKEY, *LPInternal_HUSKEY; + HKEY HKCUstart; /* Start key in CU hive */ + HKEY HKCUkey; /* Opened key in CU hive */ + HKEY HKLMstart; /* Start key in LM hive */ + HKEY HKLMkey; /* Opened key in LM hive */ + WCHAR lpszPath[MAX_PATH]; +} SHUSKEY, *LPSHUSKEY; DWORD WINAPI SHStringFromGUIDW(REFGUID,LPWSTR,INT); HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY); @@ -68,7 +69,7 @@ HRESULT WINAPI SHRegGetCLSIDKeyW(REFGUID,LPCWSTR,BOOL,BOOL,PHKEY); static HKEY WINAPI REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which) { HKEY test = (HKEY) hUSKey; - LPInternal_HUSKEY mihk = (LPInternal_HUSKEY) hUSKey; + LPSHUSKEY mihk = (LPSHUSKEY) hUSKey; if ((test == HKEY_CLASSES_ROOT) || (test == HKEY_CURRENT_CONFIG) || @@ -89,72 +90,29 @@ static HKEY WINAPI REG_GetHKEYFromHUSKEY(HUSKEY hUSKey, BOOL which) /************************************************************************* * SHRegOpenUSKeyA [SHLWAPI.@] * - * Opens a user-specific registry key + * Open a user-specific registry key. + * + * PARAMS + * Path [I] Key name to open + * AccessType [I] Access type + * hRelativeUSKey [I] Relative user key + * phNewUSKey [O] Destination for created key + * fIgnoreHKCU [I] TRUE=Don't check HKEY_CURRENT_USER * * RETURNS * Success: ERROR_SUCCESS * Failure: An error code from RegOpenKeyExA(). */ -LONG WINAPI SHRegOpenUSKeyA( - LPCSTR Path, /* [I] Key name to open */ - REGSAM AccessType, /* [I] Access type */ - HUSKEY hRelativeUSKey, /* [I] Relative user key */ - PHUSKEY phNewUSKey, /* [O] Destination for created key */ - BOOL fIgnoreHKCU) /* [I] TRUE=Don't check HKEY_CURRENT_USER */ +LONG WINAPI SHRegOpenUSKeyA(LPCSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, + PHUSKEY phNewUSKey, BOOL fIgnoreHKCU) { - HKEY openHKCUkey=0; - HKEY openHKLMkey=0; - LONG ret2, ret1 = ~ERROR_SUCCESS; - LPInternal_HUSKEY ihky; + WCHAR szPath[MAX_PATH]; - TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_a(Path), - (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, - (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM"); + if (Path) + MultiByteToWideChar(CP_ACP, 0, Path, -1, szPath, MAX_PATH); - /* now create the internal version of HUSKEY */ - ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , - sizeof(Internal_HUSKEY)); - MultiByteToWideChar(0, 0, Path, -1, ihky->key_string, - sizeof(ihky->key_string)-1); - - if (hRelativeUSKey) { - openHKCUkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKCUkey; - openHKLMkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKLMkey; - } - else { - openHKCUkey = HKEY_CURRENT_USER; - openHKLMkey = HKEY_LOCAL_MACHINE; - } - - ihky->HKCUkey = 0; - ihky->HKLMkey = 0; - if (!fIgnoreHKCU) { - ret1 = RegOpenKeyExA(openHKCUkey, Path, - 0, AccessType, &ihky->HKCUkey); - /* if successful, then save real starting point */ - if (ret1 != ERROR_SUCCESS) - ihky->HKCUkey = 0; - } - ret2 = RegOpenKeyExA(openHKLMkey, Path, - 0, AccessType, &ihky->HKLMkey); - if (ret2 != ERROR_SUCCESS) - ihky->HKLMkey = 0; - - if ((ret1 != ERROR_SUCCESS) || (ret2 != ERROR_SUCCESS)) - TRACE("one or more opens failed: HKCU=%ld HKLM=%ld\n", ret1, ret2); - - /* if all attempts have failed then bail */ - if ((ret1 != ERROR_SUCCESS) && (ret2 != ERROR_SUCCESS)) { - HeapFree(GetProcessHeap(), 0, ihky); - if (phNewUSKey) - *phNewUSKey = NULL; - return ret2; - } - - TRACE("HUSKEY=%p\n", ihky); - if (phNewUSKey) - *phNewUSKey = (HUSKEY)ihky; - return ERROR_SUCCESS; + return SHRegOpenUSKeyW(Path ? szPath : NULL, AccessType, hRelativeUSKey, + phNewUSKey, fIgnoreHKCU); } /************************************************************************* @@ -162,64 +120,61 @@ LONG WINAPI SHRegOpenUSKeyA( * * See SHRegOpenUSKeyA. */ -LONG WINAPI SHRegOpenUSKeyW( - LPCWSTR Path, - REGSAM AccessType, - HUSKEY hRelativeUSKey, - PHUSKEY phNewUSKey, - BOOL fIgnoreHKCU) +LONG WINAPI SHRegOpenUSKeyW(LPCWSTR Path, REGSAM AccessType, HUSKEY hRelativeUSKey, + PHUSKEY phNewUSKey, BOOL fIgnoreHKCU) { - HKEY openHKCUkey=0; - HKEY openHKLMkey=0; LONG ret2, ret1 = ~ERROR_SUCCESS; - LPInternal_HUSKEY ihky; + LPSHUSKEY hKey; - TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_w(Path), - (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey, - (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM"); + TRACE("(%s,0x%lx,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType, + hRelativeUSKey, phNewUSKey, fIgnoreHKCU); - /* now create the internal version of HUSKEY */ - ihky = (LPInternal_HUSKEY)HeapAlloc(GetProcessHeap(), 0 , - sizeof(Internal_HUSKEY)); - lstrcpynW(ihky->key_string, Path, sizeof(ihky->key_string)); - - if (hRelativeUSKey) { - openHKCUkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKCUkey; - openHKLMkey = ((LPInternal_HUSKEY)hRelativeUSKey)->HKLMkey; - } - else { - openHKCUkey = HKEY_CURRENT_USER; - openHKLMkey = HKEY_LOCAL_MACHINE; - } - - ihky->HKCUkey = 0; - ihky->HKLMkey = 0; - if (!fIgnoreHKCU) { - ret1 = RegOpenKeyExW(openHKCUkey, Path, - 0, AccessType, &ihky->HKCUkey); - /* if successful, then save real starting point */ - if (ret1 != ERROR_SUCCESS) - ihky->HKCUkey = 0; - } - ret2 = RegOpenKeyExW(openHKLMkey, Path, - 0, AccessType, &ihky->HKLMkey); - if (ret2 != ERROR_SUCCESS) - ihky->HKLMkey = 0; - - if ((ret1 != ERROR_SUCCESS) || (ret2 != ERROR_SUCCESS)) - TRACE("one or more opens failed: HKCU=%ld HKLM=%ld\n", ret1, ret2); - - /* if all attempts have failed then bail */ - if ((ret1 != ERROR_SUCCESS) && (ret2 != ERROR_SUCCESS)) { - HeapFree(GetProcessHeap(), 0, ihky); - if (phNewUSKey) - *phNewUSKey = NULL; - return ret2; - } - - TRACE("HUSKEY=0x%08lx\n", (LONG)ihky); if (phNewUSKey) - *phNewUSKey = (HUSKEY)ihky; + *phNewUSKey = NULL; + + /* Create internal HUSKEY */ + hKey = (LPSHUSKEY)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*hKey)); + lstrcpynW(hKey->lpszPath, Path, sizeof(hKey->lpszPath)); + + if (hRelativeUSKey) + { + hKey->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKCU)); + hKey->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(hRelativeUSKey, REG_HKLM)); + + /* FIXME: if either of these keys is NULL, create the start key from + * the relative keys start+path + */ + } + else + { + hKey->HKCUstart = HKEY_CURRENT_USER; + hKey->HKLMstart = HKEY_LOCAL_MACHINE; + } + + if (!fIgnoreHKCU) + { + ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey); + if (ret1) + hKey->HKCUkey = 0; + } + + ret2 = RegOpenKeyExW(hKey->HKLMstart, hKey->lpszPath, 0, AccessType, &hKey->HKLMkey); + if (ret2) + hKey->HKLMkey = 0; + + if (ret1 || ret2) + TRACE("one or more opens failed: HKCU=%ld HKLM=%ld\n", ret1, ret2); + + if (ret1 && ret2) + { + /* Neither open succeeded: fail */ + SHRegCloseUSKey(hKey); + return ret2; + } + + TRACE("HUSKEY=%p\n", hKey); + if (phNewUSKey) + *phNewUSKey = (HUSKEY)hKey; return ERROR_SUCCESS; } @@ -235,14 +190,19 @@ LONG WINAPI SHRegOpenUSKeyW( LONG WINAPI SHRegCloseUSKey( HUSKEY hUSKey) /* [I] Key to close */ { - LPInternal_HUSKEY mihk = (LPInternal_HUSKEY)hUSKey; + LPSHUSKEY hKey = (LPSHUSKEY)hUSKey; LONG ret = ERROR_SUCCESS; - if (mihk->HKCUkey) - ret = RegCloseKey(mihk->HKCUkey); - if (mihk->HKLMkey) - ret = RegCloseKey(mihk->HKLMkey); - HeapFree(GetProcessHeap(), 0, mihk); + if (hKey->HKCUkey) + ret = RegCloseKey(hKey->HKCUkey); + if (hKey->HKCUstart && hKey->HKCUstart != HKEY_CURRENT_USER) + ret = RegCloseKey(hKey->HKCUstart); + if (hKey->HKLMkey) + ret = RegCloseKey(hKey->HKLMkey); + if (hKey->HKLMstart && hKey->HKLMstart != HKEY_LOCAL_MACHINE) + ret = RegCloseKey(hKey->HKCUstart); + + HeapFree(GetProcessHeap(), 0, hKey); return ret; } @@ -429,6 +389,14 @@ LONG WINAPI SHRegGetUSValueW( * * Set a user-specific registry value. * + * PARAMS + * pszSubKey [I] Name of key to set the value in + * pszValue [I] Name of value under pszSubKey to set the value in + * dwType [I] Type of the value + * pvData [I] Data to set as the value + * cbData [I] length of pvData + * dwFlags [I] SHREGSET_ flags from "shlwapi.h" + * * RETURNS * Success: ERROR_SUCCESS * Failure: An error code from SHRegOpenUSKeyA() or SHRegWriteUSValueA(), or @@ -437,31 +405,29 @@ LONG WINAPI SHRegGetUSValueW( * NOTES * This function opens pszSubKey, sets the value, and then closes the key. */ -LONG WINAPI SHRegSetUSValueA( - LPCSTR pszSubKey, /* [I] Name of key to set the value in */ - LPCSTR pszValue, /* [I] Name of value under pszSubKey to set the value in */ - DWORD dwType, /* [I] Type of the value */ - LPVOID pvData, /* [I] Data to set as the value */ - DWORD cbData, /* [I] length of pvData */ - DWORD dwFlags) /* [I] SHREGSET_ flags from "shlwapi.h" */ +LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType, + LPVOID pvData, DWORD cbData, DWORD dwFlags) { - HUSKEY myhuskey; - LONG ret; - BOOL ignoreHKCU; + BOOL ignoreHKCU = TRUE; + HUSKEY hkey; + LONG ret; - if (!pvData) return ERROR_INVALID_FUNCTION; - TRACE("key '%s', value '%s', datalen %ld\n", - debugstr_a(pszSubKey), debugstr_a(pszValue), cbData); + TRACE("(%s,%s,%ld,%p,%ld,0x%08lx\n", debugstr_a(pszSubKey), debugstr_a(pszValue), + dwType, pvData, cbData, dwFlags); - ignoreHKCU = ((dwFlags == SHREGSET_HKLM) || (dwFlags == SHREGSET_FORCE_HKLM)); + if (!pvData) + return ERROR_INVALID_FUNCTION; - ret = SHRegOpenUSKeyA(pszSubKey, 0x1, 0, &myhuskey, ignoreHKCU); - if (ret == ERROR_SUCCESS) { - ret = SHRegWriteUSValueA(myhuskey, pszValue, dwType, pvData, - cbData, dwFlags); - SHRegCloseUSKey(myhuskey); - } - return ret; + if (dwFlags & SHREGSET_HKCU || dwFlags & SHREGSET_FORCE_HKCU) + ignoreHKCU = FALSE; + + ret = SHRegOpenUSKeyA(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU); + if (ret == ERROR_SUCCESS) + { + ret = SHRegWriteUSValueA(hkey, pszValue, dwType, pvData, cbData, dwFlags); + SHRegCloseUSKey(hkey); + } + return ret; } /************************************************************************* @@ -469,31 +435,29 @@ LONG WINAPI SHRegSetUSValueA( * * See SHRegSetUSValueA. */ -LONG WINAPI SHRegSetUSValueW( - LPCWSTR pszSubKey, - LPCWSTR pszValue, - DWORD dwType, - LPVOID pvData, - DWORD cbData, - DWORD dwFlags) +LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType, + LPVOID pvData, DWORD cbData, DWORD dwFlags) { - HUSKEY myhuskey; - LONG ret; - BOOL ignoreHKCU; + BOOL ignoreHKCU = TRUE; + HUSKEY hkey; + LONG ret; - if (!pvData) return ERROR_INVALID_FUNCTION; - TRACE("key '%s', value '%s', datalen %ld\n", - debugstr_w(pszSubKey), debugstr_w(pszValue), cbData); + TRACE("(%s,%s,%ld,%p,%ld,0x%08lx\n", debugstr_w(pszSubKey), debugstr_w(pszValue), + dwType, pvData, cbData, dwFlags); - ignoreHKCU = ((dwFlags == SHREGSET_HKLM) || (dwFlags == SHREGSET_FORCE_HKLM)); + if (!pvData) + return ERROR_INVALID_FUNCTION; - ret = SHRegOpenUSKeyW(pszSubKey, 0x1, 0, &myhuskey, ignoreHKCU); - if (ret == ERROR_SUCCESS) { - ret = SHRegWriteUSValueW(myhuskey, pszValue, dwType, pvData, - cbData, dwFlags); - SHRegCloseUSKey(myhuskey); - } - return ret; + if (dwFlags & SHREGSET_HKCU || dwFlags & SHREGSET_FORCE_HKCU) + ignoreHKCU = FALSE; + + ret = SHRegOpenUSKeyW(pszSubKey, KEY_ALL_ACCESS, 0, &hkey, ignoreHKCU); + if (ret == ERROR_SUCCESS) + { + ret = SHRegWriteUSValueW(hkey, pszValue, dwType, pvData, cbData, dwFlags); + SHRegCloseUSKey(hkey); + } + return ret; } /************************************************************************* @@ -801,31 +765,22 @@ LONG WINAPI SHRegEnumUSKeyW( * * RETURNS * Success: ERROR_SUCCESS. - * Failure: An error code from RegSetValueExA(). + * Failure: ERROR_INVALID_PARAMETER, if any parameter is invalid, otherwise + * an error code from RegSetValueExA(). + * + * NOTES + * dwFlags must have at least SHREGSET_FORCE_HKCU or SHREGSET_FORCE_HKLM set. */ LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType, - LPVOID pvData, DWORD cbData, DWORD dwFlags) + LPVOID pvData, DWORD cbData, DWORD dwFlags) { - HKEY dokey; + WCHAR szValue[MAX_PATH]; - TRACE("(%p,%s,%ld,%p,%ld,%ld)\n", - hUSKey, debugstr_a(pszValue), dwType, pvData, cbData, dwFlags); + if (pszValue) + MultiByteToWideChar(CP_ACP, 0, pszValue, -1, szValue, MAX_PATH); - if ((dwFlags & SHREGSET_FORCE_HKCU) && - (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { - RegSetValueExA(dokey, pszValue, 0, dwType, pvData, cbData); - } - - if ((dwFlags & SHREGSET_FORCE_HKLM) && - (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { - RegSetValueExA(dokey, pszValue, 0, dwType, pvData, cbData); - } - - if (dwFlags & (SHREGSET_FORCE_HKCU | SHREGSET_FORCE_HKLM)) - return ERROR_SUCCESS; - - FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n"); - return ERROR_SUCCESS; + return SHRegWriteUSValueW(hUSKey, pszValue ? szValue : NULL, dwType, + pvData, cbData, dwFlags); } /************************************************************************* @@ -834,28 +789,72 @@ LONG WINAPI SHRegWriteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, DWORD dwType, * See SHRegWriteUSValueA. */ LONG WINAPI SHRegWriteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, DWORD dwType, - LPVOID pvData, DWORD cbData, DWORD dwFlags) + LPVOID pvData, DWORD cbData, DWORD dwFlags) { - HKEY dokey; + LONG dummy; + LPSHUSKEY hKey = (LPSHUSKEY)hUSKey; + LONG ret = ERROR_SUCCESS; - TRACE("(%p,%s,%ld,%p,%ld,%ld)\n", - hUSKey, debugstr_w(pszValue), dwType, pvData, cbData, dwFlags); + TRACE("(%p,%s,%ld,%p,%ld,%ld)\n", hUSKey, debugstr_w(pszValue), + dwType, pvData, cbData, dwFlags); - if ((dwFlags & SHREGSET_FORCE_HKCU) && - (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKCU))) { - RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData); + if (!hUSKey || IsBadWritePtr(hUSKey, sizeof(SHUSKEY)) || + !(dwFlags & (SHREGSET_FORCE_HKCU|SHREGSET_FORCE_HKLM))) + return ERROR_INVALID_PARAMETER; + + if (dwFlags & (SHREGSET_FORCE_HKCU|SHREGSET_HKCU)) + { + if (!hKey->HKCUkey) + { + /* Create the key */ + ret = RegCreateKeyW(hKey->HKCUstart, hKey->lpszPath, &hKey->HKCUkey); + TRACE("Creating HKCU key, ret = %ld\n", ret); + if (ret && (dwFlags & (SHREGSET_FORCE_HKCU))) + { + hKey->HKCUkey = 0; + return ret; + } + } + + if (!ret) + { + if ((dwFlags & SHREGSET_FORCE_HKCU) || + RegQueryValueExW(hKey->HKCUkey, pszValue, NULL, NULL, NULL, &dummy)) + { + /* Doesn't exist or we are forcing: Write value */ + ret = RegSetValueExW(hKey->HKCUkey, pszValue, 0, dwType, pvData, cbData); + TRACE("Writing HKCU value, ret = %ld\n", ret); + } + } } - if ((dwFlags & SHREGSET_FORCE_HKLM) && - (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) { - RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData); + if (dwFlags & (SHREGSET_FORCE_HKLM|SHREGSET_HKLM)) + { + if (!hKey->HKLMkey) + { + /* Create the key */ + ret = RegCreateKeyW(hKey->HKLMstart, hKey->lpszPath, &hKey->HKLMkey); + TRACE("Creating HKLM key, ret = %ld\n", ret); + if (ret && (dwFlags & (SHREGSET_FORCE_HKLM))) + { + hKey->HKLMkey = 0; + return ret; + } + } + + if (!ret) + { + if ((dwFlags & SHREGSET_FORCE_HKLM) || + RegQueryValueExW(hKey->HKLMkey, pszValue, NULL, NULL, NULL, &dummy)) + { + /* Doesn't exist or we are forcing: Write value */ + ret = RegSetValueExW(hKey->HKLMkey, pszValue, 0, dwType, pvData, cbData); + TRACE("Writing HKLM value, ret = %ld\n", ret); + } + } } - if (dwFlags & (SHREGSET_FORCE_HKCU | SHREGSET_FORCE_HKLM)) - return ERROR_SUCCESS; - - FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n"); - return ERROR_SUCCESS; + return ret; } /************************************************************************* diff --git a/reactos/lib/shlwapi/resource.h b/reactos/lib/shlwapi/resource.h new file mode 100644 index 00000000000..d922ceb3e08 --- /dev/null +++ b/reactos/lib/shlwapi/resource.h @@ -0,0 +1,29 @@ +/* + * Resource defines for shlwapi + * + * 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 + */ +#ifndef WINE_SHLWAPI_RESOURCE_H +#define WINE_SHLWAPI_RESOURCE_H + +/* These numbers match native ID's and shouldn't be abitrarily changed */ +#define IDD_ERR_DIALOG 0x1200 +#define IDS_ERR_USER_MSG 0x1201 +#define IDC_ERR_DONT_SHOW 0x1202 +#define IDS_ERR_USER_MSG2 0x1203 + +#endif /* WINE_SHLWAPI_RESOURCE_H */ diff --git a/reactos/lib/shlwapi/shlwapi.rc b/reactos/lib/shlwapi/shlwapi.rc new file mode 100644 index 00000000000..6e663615ff0 --- /dev/null +++ b/reactos/lib/shlwapi/shlwapi.rc @@ -0,0 +1,27 @@ +/* + * Top level resource file for shlwapi + * + * 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 + */ + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "resource.h" + +#include "shlwapi_En.rc" +#include "shlwapi_Es.rc" diff --git a/reactos/lib/shlwapi/shlwapi.spec b/reactos/lib/shlwapi/shlwapi.spec index 262e5c259e4..32b962c62de 100644 --- a/reactos/lib/shlwapi/shlwapi.spec +++ b/reactos/lib/shlwapi/shlwapi.spec @@ -182,20 +182,20 @@ 182 stdcall -noname SHCheckMenuItem(long long long) 183 stdcall -noname SHRegisterClassA(ptr) 184 stdcall @(ptr ptr long) SHLWAPI_184 -185 stub -noname SHMessageBoxCheckA +185 stdcall -noname SHMessageBoxCheckA(ptr str str long long str) 186 stub -noname SHSimulateDrop 187 stdcall -noname SHLoadFromPropertyBag(ptr ptr) 188 stub -noname IUnknown_TranslateAcceleratorOCS 189 stdcall -noname IUnknown_OnFocusOCS(ptr ptr) 190 stub -noname IUnknown_HandleIRestrict -191 stub -noname SHMessageBoxCheckW +191 stdcall -noname SHMessageBoxCheckW(ptr wstr wstr long long wstr) 192 stdcall -noname SHGetMenuFromID(ptr long) 193 stdcall -noname SHGetCurColorRes() -194 stub -noname SHWaitForSendMessageThread +194 stdcall -noname SHWaitForSendMessageThread(ptr long) 195 stub -noname SHIsExpandableFolder 196 stub -noname DnsRecordSetCompare 197 stdcall -noname SHFillRectClr(long ptr long) -198 stub -noname SHSearchMapInt +198 stdcall -noname SHSearchMapInt(ptr ptr long long) 199 stdcall -noname IUnknown_Set(ptr ptr) 200 stub -noname MayQSForward 201 stdcall -noname MayExecForward(ptr long ptr long long ptr ptr) @@ -213,7 +213,7 @@ 213 stdcall -noname IStream_Reset(ptr) 214 stdcall -noname IStream_Size(ptr ptr) 215 stdcall -noname SHAnsiToUnicode(str ptr long) -216 stub -noname SHAnsiToUnicodeCP +216 stdcall -noname SHAnsiToUnicodeCP(long str ptr long) 217 stdcall -noname SHUnicodeToAnsi(wstr ptr ptr) 218 stdcall -noname SHUnicodeToAnsiCP(long wstr ptr ptr) 219 stdcall -noname QISearch(long long long long) @@ -222,7 +222,7 @@ 222 stdcall -noname _SHGlobalCounterCreate(long) 223 stdcall -noname _SHGlobalCounterGetValue(long) 224 stdcall -noname _SHGlobalCounterIncrement(long) -225 stub -noname SHStripMneumonicW +225 stdcall -noname SHStripMneumonicW(wstr) 226 stub -noname ZoneCheckPathA 227 stub -noname ZoneCheckPathW 228 stub -noname ZoneCheckUrlA @@ -288,8 +288,8 @@ 288 stub -noname IUnknown_CPContainerInvokeIndirect 289 stdcall -noname PlaySoundWrapW(wstr long long) 290 stub -noname SHMirrorIcon -291 stub -noname SHMessageBoxCheckExA -292 stub -noname SHMessageBoxCheckExW +291 stdcall -noname SHMessageBoxCheckExA(ptr ptr ptr ptr ptr long str) +292 stdcall -noname SHMessageBoxCheckExW(ptr ptr ptr ptr ptr long wstr) 293 stub -noname SHCancelUserWorkItems 294 stdcall -noname SHGetIniStringW(long long long long long) 295 stdcall -noname SHSetIniStringW(wstr ptr wstr wstr) @@ -445,7 +445,7 @@ 445 stdcall -noname PathFileExistsAndAttributesA(str ptr) 446 stdcall -noname PathFileExistsAndAttributesW(wstr ptr) 447 stub -noname FixSlashesAndColonA -448 stub -noname FixSlashesAndColonW +448 stdcall -noname FixSlashesAndColonW(wstr) 449 stub -noname NextPathA 450 stub -noname NextPathW 451 stub -noname CharUpperNoDBCSA @@ -458,7 +458,7 @@ 458 stub -noname GetLongPathNameWrapA 459 stub -noname SHExpandEnvironmentStringsA 460 stub -noname SHExpandEnvironmentStringsW -461 stub -noname SHGetAppCompatFlags +461 stdcall -noname SHGetAppCompatFlags() 462 stub -noname UrlFixupW 463 stub -noname SHExpandEnvironmentStringsForUserA 464 stub -noname SHExpandEnvironmentStringsForUserW diff --git a/reactos/lib/shlwapi/shlwapi_En.rc b/reactos/lib/shlwapi/shlwapi_En.rc new file mode 100644 index 00000000000..8b3b4699bf7 --- /dev/null +++ b/reactos/lib/shlwapi/shlwapi_En.rc @@ -0,0 +1,35 @@ +/* + * English resources for shlwapi + * + * 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 + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +IDD_ERR_DIALOG DIALOG MOVEABLE DISCARDABLE 0, 0, 220, 60 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Error!" +FONT 8, "MS Shell Dlg" +{ + LTEXT "", IDS_ERR_USER_MSG2, 15, 5, 28, 20 + LTEXT "", IDS_ERR_USER_MSG, 15, 5, 210, 8 + CHECKBOX "Don't show me th&is message again", IDC_ERR_DONT_SHOW, 5, 20, 210, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&OK" IDOK, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&Cancel" IDCANCEL, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&Yes" IDYES, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&No" IDNO, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/lib/shlwapi/shlwapi_Es.rc b/reactos/lib/shlwapi/shlwapi_Es.rc new file mode 100644 index 00000000000..802c9d917fc --- /dev/null +++ b/reactos/lib/shlwapi/shlwapi_Es.rc @@ -0,0 +1,35 @@ +/* + * Spanish resources for shlwapi + * + * Copyright 2004 José Manuel Ferrer Ortiz + * + * 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 + */ + +LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT + +IDD_ERR_DIALOG DIALOG MOVEABLE DISCARDABLE 0, 0, 220, 60 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "ˇError!" +FONT 8, "MS Shell Dlg" +{ + LTEXT "", IDS_ERR_USER_MSG2, 15, 5, 28, 20 + LTEXT "", IDS_ERR_USER_MSG, 15, 5, 210, 8 + CHECKBOX "No volver a mostrar este &mensaje", IDC_ERR_DONT_SHOW, 5, 20, 210, 10, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&Aceptar" IDOK, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&Cancelar" IDCANCEL, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&Sí" IDYES, 105, 40, 50, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON L"&No" IDNO, 160, 40, 50, 14, WS_GROUP | WS_TABSTOP +} diff --git a/reactos/lib/shlwapi/string.c b/reactos/lib/shlwapi/string.c index d2c12776b17..b7cbda009dc 100644 --- a/reactos/lib/shlwapi/string.c +++ b/reactos/lib/shlwapi/string.c @@ -2434,6 +2434,63 @@ char WINAPI SHStripMneumonicA(LPCSTR lpszStr) return ch; } +/************************************************************************* + * @ [SHLWAPI.225] + * + * Unicode version of SHStripMneumonicA. + */ +WCHAR WINAPI SHStripMneumonicW(LPCWSTR lpszStr) +{ + LPWSTR lpszIter, lpszTmp; + WCHAR ch; + + TRACE("(%s)\n", debugstr_w(lpszStr)); + + ch = *lpszStr; + + if ((lpszIter = StrChrW(lpszStr, '&'))) + { + lpszTmp = CharNextW(lpszIter); + if (lpszTmp && *lpszTmp) + { + if (*lpszTmp != '&') + ch = *lpszTmp; + + while (lpszIter && *lpszIter) + { + lpszTmp = CharNextW(lpszIter); + *lpszIter = *lpszTmp; + lpszIter = lpszTmp; + } + } + } + + return ch; +} + +/************************************************************************* + * @ [SHLWAPI.216] + * + * Convert an Ascii string to Unicode. + * + * PARAMS + * dwCp [I] Code page for the conversion + * 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 SHAnsiToUnicodeCP(DWORD dwCp, LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen) +{ + DWORD dwRet; + + dwRet = MultiByteToWideChar(dwCp, 0, lpSrcStr, -1, lpDstStr, iLen); + TRACE("%s->%s,ret=%ld\n", debugstr_a(lpSrcStr), debugstr_w(lpDstStr), dwRet); + return dwRet; +} + /************************************************************************* * @ [SHLWAPI.215] * @@ -2446,14 +2503,13 @@ char WINAPI SHStripMneumonicA(LPCSTR lpszStr) * * RETURNS * The return value of the MultiByteToWideChar() function called on lpSrcStr. + * + * NOTES + * This function simply calls SHAnsiToUnicodeCP with code page CP_ACP. */ 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; + return SHAnsiToUnicodeCP(CP_ACP, lpSrcStr, lpDstStr, iLen); } /************************************************************************* diff --git a/reactos/lib/shlwapi/url.c b/reactos/lib/shlwapi/url.c index 019a0860a57..4e4f7664dc4 100644 --- a/reactos/lib/shlwapi/url.c +++ b/reactos/lib/shlwapi/url.c @@ -581,6 +581,9 @@ HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, TRACE("Simplified, orig <%s>, simple <%s>\n", debugstr_w(pszUrl), debugstr_w(lpszUrlCpy)); } + nLen = lstrlenW(lpszUrlCpy); + while ((nLen > 0) && ((lpszUrlCpy[nLen-1] == '\r')||(lpszUrlCpy[nLen-1] == '\n'))) + lpszUrlCpy[--nLen]=0; if(dwFlags & URL_UNESCAPE) UrlUnescapeW(lpszUrlCpy, NULL, NULL, URL_UNESCAPE_INPLACE);