Commit in reactos/lib/shlwapi on MAIN
msgbox.c+297added 1.1
resource.h+29added 1.1
shlwapi.rc+27added 1.1
shlwapi_En.rc+35added 1.1
shlwapi_Es.rc+35added 1.1
Makefile.in+41.4 -> 1.5
ordinal.c+100-391.6 -> 1.7
reg.c+198-1991.7 -> 1.8
shlwapi.spec+10-101.5 -> 1.6
string.c+59-31.6 -> 1.7
url.c+31.5 -> 1.6
+797-251
5 added + 6 modified, total 11 files
Sync to Wine-20040408:
Jon Griffiths <jon_p_griffiths@yahoo.com>
- Implement SHMessageBoxCheck functions && add dialog resources.
- Add SHWaitForSendMessageThread, SHAnsiToUnicodeCP,SHStripMneumonicW,
  SHSearchMapInt.
- Make copies of keys when creating, free them when done.
- Use KEY_ALL_ACCESS when writing US reg values.
- SHRegWriteUSValueW: Handle all flag combinations.
- Make some A calls use the W version.
Jose Manuel Ferrer Ortiz <jmfo1982@yahoo.es>
- Updated Spanish translations.
Ulrich Czekalla <ulrich@codeweavers.com>
- Implement FixSlashesAndColonW and add stub for SHGetAppCompatFlags.
Francois Gouget <fgouget@free.fr>
- Assorted spelling fixes.
Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
- UrlCanonicalizeW: Remove \r and \n at the end of lpszUrlCpy, with test
  cases.

reactos/lib/shlwapi
msgbox.c added at 1.1
diff -N msgbox.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ msgbox.c	16 Apr 2004 08:47:55 -0000	1.1
@@ -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 <stdarg.h>
+#include <string.h>
+
+#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);
+}

reactos/lib/shlwapi
resource.h added at 1.1
diff -N resource.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ resource.h	16 Apr 2004 08:47:55 -0000	1.1
@@ -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 */

reactos/lib/shlwapi
shlwapi.rc added at 1.1
diff -N shlwapi.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ shlwapi.rc	16 Apr 2004 08:47:55 -0000	1.1
@@ -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"

reactos/lib/shlwapi
shlwapi_En.rc added at 1.1
diff -N shlwapi_En.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ shlwapi_En.rc	16 Apr 2004 08:47:55 -0000	1.1
@@ -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
+}

reactos/lib/shlwapi
shlwapi_Es.rc added at 1.1
diff -N shlwapi_Es.rc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ shlwapi_Es.rc	16 Apr 2004 08:47:55 -0000	1.1
@@ -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
+}

reactos/lib/shlwapi
Makefile.in 1.4 -> 1.5
diff -u -r1.4 -r1.5
--- Makefile.in	11 Mar 2004 22:30:39 -0000	1.4
+++ Makefile.in	16 Apr 2004 08:47:55 -0000	1.5
@@ -12,6 +12,7 @@
 	assoc.c \
 	clist.c \
 	istream.c \
+	msgbox.c \
 	ordinal.c \
 	path.c \
 	reg.c \
@@ -23,6 +24,9 @@
 	url.c \
 	wsprintf.c
 
+RC_SRCS = \
+	shlwapi.rc
+
 SUBDIRS = tests
 
 @MAKE_DLL_RULES@

reactos/lib/shlwapi
ordinal.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- ordinal.c	11 Mar 2004 22:30:40 -0000	1.6
+++ ordinal.c	16 Apr 2004 08:47:55 -0000	1.7
@@ -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 @@
   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]
  *
@@ -1989,6 +1953,41 @@
 }
 
 /*************************************************************************
+ *      @	[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]
  *
  * Blank out a region of text by drawing the background only.
@@ -2010,6 +2009,43 @@
 }
 
 /*************************************************************************
+ *      @	[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]
  *
  * Copy an interface pointer
@@ -2421,12 +2457,12 @@
  */
 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 @@
 
 	SHGetValueW(hKey, lpSubName, lpValue, NULL, (LPBYTE)&retval, &datsize);
 	RegCloseKey(hKey);
-	return retval;  
+	return retval;
 }
 
 /*************************************************************************
@@ -3801,6 +3837,31 @@
     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]
  */

reactos/lib/shlwapi
reg.c 1.7 -> 1.8
diff -u -r1.7 -r1.8
--- reg.c	28 Jan 2004 21:57:41 -0000	1.7
+++ reg.c	16 Apr 2004 08:47:55 -0000	1.8
@@ -47,11 +47,12 @@
 
 /* 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 @@
 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 @@
 /*************************************************************************
  * 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;
-
-    TRACE("(%s, 0x%lx, 0x%lx, %p, %s)\n", debugstr_a(Path),
-	  (LONG)AccessType, (LONG)hRelativeUSKey, phNewUSKey,
-	  (fIgnoreHKCU) ? "Ignoring HKCU" : "Process HKCU then HKLM");
-
-    /* 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;
-    }
+    WCHAR szPath[MAX_PATH];
 
-    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;
-    }
+    if (Path)
+      MultiByteToWideChar(CP_ACP, 0, Path, -1, szPath, MAX_PATH);
 
-    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 @@
  *
  * 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");
-
-    /* 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;
+    TRACE("(%s,0x%lx,%p,%p,%d)\n", debugstr_w(Path),(LONG)AccessType,
+          hRelativeUSKey, phNewUSKey, fIgnoreHKCU);
+
+    if (phNewUSKey)
+        *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 {
-	openHKCUkey = HKEY_CURRENT_USER;
-	openHKLMkey = HKEY_LOCAL_MACHINE;
+    else
+    {
+        hKey->HKCUstart = HKEY_CURRENT_USER;
+        hKey->HKLMstart = 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;
+    if (!fIgnoreHKCU)
+    {
+        ret1 = RegOpenKeyExW(hKey->HKCUstart, hKey->lpszPath, 0, AccessType, &hKey->HKCUkey);
+        if (ret1)
+            hKey->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;
+
+    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=0x%08lx\n", (LONG)ihky);
+    TRACE("HUSKEY=%p\n", hKey);
     if (phNewUSKey)
-	*phNewUSKey = (HUSKEY)ihky;
+        *phNewUSKey = (HUSKEY)hKey;
     return ERROR_SUCCESS;
 }
 
@@ -235,14 +190,19 @@
 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 @@
  *
  * 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 @@
  * 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" */
-{
-        HUSKEY myhuskey;
-	LONG   ret;
-	BOOL   ignoreHKCU;
-
-        if (!pvData) return ERROR_INVALID_FUNCTION;
-	TRACE("key '%s', value '%s', datalen %ld\n",
-	      debugstr_a(pszSubKey), debugstr_a(pszValue), cbData);
+LONG WINAPI SHRegSetUSValueA(LPCSTR pszSubKey, LPCSTR pszValue, DWORD dwType,
+                             LPVOID pvData, DWORD cbData, DWORD dwFlags)
+{
+  BOOL ignoreHKCU = TRUE;
+  HUSKEY hkey;
+  LONG ret;
 
-	ignoreHKCU = ((dwFlags == SHREGSET_HKLM) || (dwFlags == SHREGSET_FORCE_HKLM));
+  TRACE("(%s,%s,%ld,%p,%ld,0x%08lx\n", debugstr_a(pszSubKey), debugstr_a(pszValue),
+        dwType, pvData, cbData, dwFlags);
 
-	ret = SHRegOpenUSKeyA(pszSubKey, 0x1, 0, &myhuskey, ignoreHKCU);
-	if (ret == ERROR_SUCCESS) {
- 	  ret = SHRegWriteUSValueA(myhuskey, pszValue, dwType, pvData,
-				   cbData, dwFlags);
-	    SHRegCloseUSKey(myhuskey);
-	}
-	return ret;
+  if (!pvData)
+    return ERROR_INVALID_FUNCTION;
+
+  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 @@
  *
  * See SHRegSetUSValueA.
  */
-LONG WINAPI SHRegSetUSValueW(
-	LPCWSTR pszSubKey,
-	LPCWSTR pszValue,
-	DWORD   dwType,
-	LPVOID  pvData,
-	DWORD   cbData,
-	DWORD   dwFlags)
-{
-        HUSKEY myhuskey;
-	LONG   ret;
-	BOOL   ignoreHKCU;
-
-        if (!pvData) return ERROR_INVALID_FUNCTION;
-	TRACE("key '%s', value '%s', datalen %ld\n",
-	      debugstr_w(pszSubKey), debugstr_w(pszValue), cbData);
+LONG WINAPI SHRegSetUSValueW(LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwType,
+                             LPVOID pvData, DWORD cbData, DWORD dwFlags)
+{
+  BOOL ignoreHKCU = TRUE;
+  HUSKEY hkey;
+  LONG ret;
 
-	ignoreHKCU = ((dwFlags == SHREGSET_HKLM) || (dwFlags == SHREGSET_FORCE_HKLM));
+  TRACE("(%s,%s,%ld,%p,%ld,0x%08lx\n", debugstr_w(pszSubKey), debugstr_w(pszValue),
+        dwType, pvData, cbData, dwFlags);
 
-	ret = SHRegOpenUSKeyW(pszSubKey, 0x1, 0, &myhuskey, ignoreHKCU);
-	if (ret == ERROR_SUCCESS) {
- 	  ret = SHRegWriteUSValueW(myhuskey, pszValue, dwType, pvData,
-				   cbData, dwFlags);
-	    SHRegCloseUSKey(myhuskey);
-	}
-	return ret;
+  if (!pvData)
+    return ERROR_INVALID_FUNCTION;
+
+  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 @@
  *
  * 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 @@
  * 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_HKLM) &&
-	    (dokey = REG_GetHKEYFromHUSKEY(hUSKey,REG_HKLM))) {
-	RegSetValueExW(dokey, pszValue, 0, dwType, pvData, cbData);
+    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_HKCU | SHREGSET_FORCE_HKLM))
-	return ERROR_SUCCESS;
+    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;
+            }
+        }
 
-    FIXME("SHREGSET_HKCU or SHREGSET_HKLM not supported\n");
-    return ERROR_SUCCESS;
+        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);
+            }
+        }
+    }
+
+    return ret;
 }
 
 /*************************************************************************

reactos/lib/shlwapi
shlwapi.spec 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- shlwapi.spec	11 Mar 2004 22:30:40 -0000	1.5
+++ shlwapi.spec	16 Apr 2004 08:47:55 -0000	1.6
@@ -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

reactos/lib/shlwapi
string.c 1.6 -> 1.7
diff -u -r1.6 -r1.7
--- string.c	11 Mar 2004 22:30:40 -0000	1.6
+++ string.c	16 Apr 2004 08:47:55 -0000	1.7
@@ -2435,11 +2435,46 @@
 }
 
 /*************************************************************************
- *      @	[SHLWAPI.215]
+ *      @	[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
@@ -2447,16 +2482,37 @@
  * RETURNS
  *  The return value of the MultiByteToWideChar() function called on lpSrcStr.
  */
-DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
+DWORD WINAPI SHAnsiToUnicodeCP(DWORD dwCp, LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
 {
   DWORD dwRet;
 
-  dwRet = MultiByteToWideChar(CP_ACP, 0, lpSrcStr, -1, lpDstStr, iLen);
+  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]
+ *
+ * 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.
+ *
+ * NOTES
+ *  This function simply calls SHAnsiToUnicodeCP with code page CP_ACP.
+ */
+DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
+{
+  return SHAnsiToUnicodeCP(CP_ACP, lpSrcStr, lpDstStr, iLen);
+}
+
+/*************************************************************************
  *      @	[SHLWAPI.218]
  *
  * Convert a Unicode string to Ascii.

reactos/lib/shlwapi
url.c 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- url.c	11 Mar 2004 22:30:40 -0000	1.5
+++ url.c	16 Apr 2004 08:47:55 -0000	1.6
@@ -581,6 +581,9 @@
 	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);
CVSspam 0.2.8