https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ee19792605da47f5ea783596383c0b35f93a2bef

commit ee19792605da47f5ea783596383c0b35f93a2bef
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Sat Feb 1 07:14:36 2025 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Sat Feb 1 07:14:36 2025 +0900

    [SHDOCVW][EXPLORER][RSHELL][SDK] Populate WinList_* stubs (#7691)
    
    Implementing missing features...
    JIRA issue: CORE-9368
    - Modify shdocvw.spec.
    - Add dll/win32/shdocvw/winlist.cpp.
    - Add stubs of WinList_* functions.
    - Add WinList_* function prototypes
      to <shdocvw_undoc.h>.
    - Adapt explorer and rshell to new
      WinList_Init prototype.
---
 base/shell/explorer/precomp.h       |   3 +-
 base/shell/explorer/rshell.cpp      |   6 +-
 base/shell/rshell/misc.cpp          |   6 -
 dll/win32/shdocvw/CMakeLists.txt    |   3 +-
 dll/win32/shdocvw/shdocvw.spec      |  12 +-
 dll/win32/shdocvw/shdocvw_main.c    |   2 +
 dll/win32/shdocvw/winlist.cpp       | 255 ++++++++++++++++++++++++++++++++++++
 sdk/include/reactos/shdocvw_undoc.h |  33 ++++-
 sdk/include/reactos/undocshell.h    |   1 -
 9 files changed, 300 insertions(+), 21 deletions(-)

diff --git a/base/shell/explorer/precomp.h b/base/shell/explorer/precomp.h
index df60ef3a6f5..f90ec62f1a8 100644
--- a/base/shell/explorer/precomp.h
+++ b/base/shell/explorer/precomp.h
@@ -42,6 +42,7 @@
 #include <shlwapi_undoc.h>
 #include <shlobj_undoc.h>
 #include <shlguid_undoc.h>
+#include <shdocvw_undoc.h>
 #include <undocshell.h>
 
 #include <ui/rosctrls.h>
@@ -119,7 +120,7 @@ VOID InitRSHELL(VOID);
 HRESULT WINAPI _CStartMenu_CreateInstance(REFIID riid, void **ppv);
 HANDLE WINAPI _SHCreateDesktop(IShellDesktopTray *ShellDesk);
 BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop);
-DWORD WINAPI _WinList_Init(void);
+BOOL WINAPI _WinList_Init(void);
 void WINAPI _ShellDDEInit(BOOL bInit);
 HRESULT WINAPI _CBandSiteMenu_CreateInstance(REFIID riid, void **ppv);
 HRESULT WINAPI _CBandSite_CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, 
void **ppv);
diff --git a/base/shell/explorer/rshell.cpp b/base/shell/explorer/rshell.cpp
index 9767c23504d..bdd5571ade6 100644
--- a/base/shell/explorer/rshell.cpp
+++ b/base/shell/explorer/rshell.cpp
@@ -105,9 +105,9 @@ BOOL WINAPI _SHDesktopMessageLoop(HANDLE hDesktop)
     return FALSE;
 }
 
-typedef DWORD(WINAPI* PWINLIST_INIT)(void);
+typedef BOOL (WINAPI *PWINLIST_INIT)(void);
 
-DWORD WINAPI _WinList_Init(void)
+BOOL WINAPI _WinList_Init(void)
 {
     HINSTANCE hFallback;
 
@@ -131,7 +131,7 @@ DWORD WINAPI _WinList_Init(void)
         }
     }
 
-    return 0;
+    return FALSE;
 }
 
 typedef void (WINAPI *PSHELLDDEINIT)(BOOL bInit);
diff --git a/base/shell/rshell/misc.cpp b/base/shell/rshell/misc.cpp
index d0ed8c83e1b..8e0403f4cfd 100644
--- a/base/shell/rshell/misc.cpp
+++ b/base/shell/rshell/misc.cpp
@@ -52,12 +52,6 @@ extern "C"
     HRESULT WINAPI RSHELL_CMergedFolder_CreateInstance(REFIID riid, LPVOID 
*ppv);
 }
 
-DWORD WINAPI WinList_Init(void)
-{
-    /* do something here (perhaps we may want to add our own implementation fo 
win8) */
-    return 0;
-}
-
 class CRShellModule : public CComModule
 {
 public:
diff --git a/dll/win32/shdocvw/CMakeLists.txt b/dll/win32/shdocvw/CMakeLists.txt
index 119e8aaf882..6d178708672 100644
--- a/dll/win32/shdocvw/CMakeLists.txt
+++ b/dll/win32/shdocvw/CMakeLists.txt
@@ -37,7 +37,8 @@ add_library(shdocvw_sublib OBJECT
     CNSCBand.cpp
     mrulist.cpp
     objects.cpp
-    utility.cpp)
+    utility.cpp
+    winlist.cpp)
 target_link_libraries(shdocvw_sublib PRIVATE atl_classes)
 target_compile_definitions(shdocvw_sublib PRIVATE 
$<TARGET_PROPERTY:shdocvw,COMPILE_DEFINITIONS>)
 target_compile_options(shdocvw_sublib PRIVATE 
$<TARGET_PROPERTY:shdocvw,COMPILE_OPTIONS>)
diff --git a/dll/win32/shdocvw/shdocvw.spec b/dll/win32/shdocvw/shdocvw.spec
index 0a8bd10cd84..e0b72b28de3 100644
--- a/dll/win32/shdocvw/shdocvw.spec
+++ b/dll/win32/shdocvw/shdocvw.spec
@@ -8,7 +8,7 @@
 @ stdcall -private DllGetClassObject(ptr ptr ptr)
 @ stdcall -private DllGetVersion(ptr)
 110 stdcall -noname WinList_Init()
-111 stub -noname WinList_Terminate
+111 stdcall -noname WinList_Terminate()
 @ stdcall -private DllInstall(long wstr)
 @ stdcall -private DllRegisterServer()
 @ stub DllRegisterWindowClasses
@@ -74,11 +74,11 @@
 174 stub -noname SHIsGlobalOffline
 175 stub -noname DetectAndFixAssociations
 176 stub -noname EnsureWebViewRegSettings
-177 stub -noname WinList_NotifyNewLocation
-178 stub -noname WinList_FindFolderWindow
-179 stub -noname WinList_GetShellWindows
-180 stub -noname WinList_RegisterPending
-181 stub -noname WinList_Revoke
+177 stdcall -noname WinList_NotifyNewLocation(ptr long ptr)
+178 stdcall -noname WinList_FindFolderWindow(ptr long ptr ptr)
+179 stdcall -noname WinList_GetShellWindows(long)
+180 stdcall -noname WinList_RegisterPending(long ptr long ptr)
+181 stdcall -noname WinList_Revoke(long)
 182 stdcall SetQueryNetSessionCount(long)
 183 stub -noname SHMapNbspToSp
 184 stub SetShellOfflineState
diff --git a/dll/win32/shdocvw/shdocvw_main.c b/dll/win32/shdocvw/shdocvw_main.c
index c817bbb3c5f..65e3c733c79 100644
--- a/dll/win32/shdocvw/shdocvw_main.c
+++ b/dll/win32/shdocvw/shdocvw_main.c
@@ -236,6 +236,7 @@ static BOOL SHDOCVW_LoadShell32(void)
      return ((SHDOCVW_hshell32 = LoadLibraryA("shell32.dll")) != NULL);
 }
 
+#ifndef __REACTOS__ /* See winlist.cpp */
 /***********************************************************************
  *             @ (SHDOCVW.110)
  *
@@ -247,6 +248,7 @@ DWORD WINAPI WinList_Init(void)
     FIXME("(), stub!\n");
     return 0x0deadfeed;
 }
+#endif /* ndef __REACTOS__ */
 
 /***********************************************************************
  *             @ (SHDOCVW.118)
diff --git a/dll/win32/shdocvw/winlist.cpp b/dll/win32/shdocvw/winlist.cpp
new file mode 100644
index 00000000000..72562d77b42
--- /dev/null
+++ b/dll/win32/shdocvw/winlist.cpp
@@ -0,0 +1,255 @@
+/*
+ * PROJECT:     ReactOS shdocvw
+ * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
+ * PURPOSE:     CLSID_ShellWindows and WinList_* functions
+ * COPYRIGHT:   Copyright 2025 Katayama Hirofumi MZ 
<katayama.hirofumi...@gmail.com>
+ */
+
+#include "objects.h"
+
+#include <wine/debug.h>
+WINE_DEFAULT_DEBUG_CHANNEL(shdocvw);
+
+static VARIANT s_vaEmpty = { VT_EMPTY };
+
+static HRESULT
+InitVariantFromBuffer(
+    _Out_ LPVARIANTARG pvarg,
+    _In_ LPCVOID pv,
+    _In_ SIZE_T cb)
+{
+    VariantInit(pvarg);
+
+    LPSAFEARRAY pArray = SafeArrayCreateVector(VT_UI1, 0, cb);
+    if (!pArray)
+    {
+        ERR("!pArray\n");
+        return E_OUTOFMEMORY;
+    }
+
+    V_ARRAY(pvarg) = pArray;
+    V_VT(pvarg) = VT_ARRAY | VT_UI1;
+    CopyMemory(pArray->pvData, pv, cb);
+    return S_OK;
+}
+
+static HRESULT
+InitVariantFromIDList(
+    _Out_ LPVARIANTARG pvarg,
+    _In_ LPCITEMIDLIST pidl)
+{
+    return InitVariantFromBuffer(pvarg, pidl, ILGetSize(pidl));
+}
+
+static HRESULT
+VariantClearLazy(_Inout_ LPVARIANTARG pvarg)
+{
+    switch (V_VT(pvarg))
+    {
+        case VT_EMPTY:
+        case VT_BOOL:
+        case VT_I4:
+        case VT_UI4:
+            break;
+        case VT_UNKNOWN:
+            if (V_UNKNOWN(pvarg))
+                V_UNKNOWN(pvarg)->Release();
+            break;
+        case VT_DISPATCH:
+            if (V_DISPATCH(pvarg))
+                V_DISPATCH(pvarg)->Release();
+            break;
+        case VT_SAFEARRAY:
+            SafeArrayDestroy(V_ARRAY(pvarg));
+            break;
+        default:
+            return VariantClear(pvarg);
+    }
+    V_VT(pvarg) = VT_EMPTY;
+    return S_OK;
+}
+
+/*************************************************************************
+ *    WinList_Init (SHDOCVW.110)
+ *
+ * Retired in NT 6.1.
+ */
+EXTERN_C
+BOOL WINAPI
+WinList_Init(VOID)
+{
+    FIXME("()\n");
+    return FALSE;
+}
+
+/*************************************************************************
+ *    WinList_Terminate (SHDOCVW.111)
+ *
+ * NT 4.71 and higher. Retired in NT 6.1.
+ */
+EXTERN_C
+VOID WINAPI
+WinList_Terminate(VOID)
+{
+    FIXME("()\n");
+}
+
+/*************************************************************************
+ *    WinList_GetShellWindows (SHDOCVW.179)
+ *
+ * NT 5.0 and higher.
+ * @see 
https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nn-exdisp-ishellwindows
+ */
+EXTERN_C
+IShellWindows* WINAPI
+WinList_GetShellWindows(
+    _In_ BOOL bCreate)
+{
+    FIXME("(%d)\n", bCreate);
+    return NULL;
+}
+
+/*************************************************************************
+ *    WinList_NotifyNewLocation (SHDOCVW.177)
+ *
+ * NT 5.0 and higher.
+ * @see 
https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-onnavigate
+ */
+EXTERN_C
+HRESULT WINAPI
+WinList_NotifyNewLocation(
+    _In_ IShellWindows *pShellWindows,
+    _In_ LONG lCookie,
+    _In_ LPCITEMIDLIST pidl)
+{
+    TRACE("(%p, %ld, %p)\n", pShellWindows, lCookie, pidl);
+
+    if (!pidl)
+    {
+        ERR("!pidl\n");
+        return E_UNEXPECTED;
+    }
+
+    VARIANTARG varg;
+    HRESULT hr = InitVariantFromIDList(&varg, pidl);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = pShellWindows->OnNavigate(lCookie, &varg);
+    VariantClearLazy(&varg);
+    return hr;
+}
+
+/*************************************************************************
+ *    WinList_FindFolderWindow (SHDOCVW.178)
+ *
+ * NT 5.0 and higher.
+ * @see 
https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-findwindowsw
+ */
+EXTERN_C
+HRESULT WINAPI
+WinList_FindFolderWindow(
+    _In_ LPCITEMIDLIST pidl,
+    _In_ DWORD dwUnused,
+    _Out_opt_ PLONG phwnd, // Stores a window handle but LONG type
+    _Out_opt_ IWebBrowserApp **ppWebBrowserApp)
+{
+    UNREFERENCED_PARAMETER(dwUnused);
+
+    TRACE("(%p, %ld, %p, %p)\n", pidl, dwUnused, phwnd, ppWebBrowserApp);
+
+    if (ppWebBrowserApp)
+        *ppWebBrowserApp = NULL;
+
+    if (phwnd)
+        *phwnd = 0;
+
+    if (!pidl)
+    {
+        ERR("!pidl\n");
+        return E_UNEXPECTED;
+    }
+
+    CComPtr<IShellWindows> 
pShellWindows(WinList_GetShellWindows(ppWebBrowserApp != NULL));
+    if (!pShellWindows)
+    {
+        ERR("!pShellWindows\n");
+        return E_UNEXPECTED;
+    }
+
+    VARIANTARG varg;
+    HRESULT hr = InitVariantFromIDList(&varg, pidl);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    CComPtr<IDispatch> pDispatch;
+    const INT options = SWFO_INCLUDEPENDING | (ppWebBrowserApp ? 
SWFO_NEEDDISPATCH : 0);
+    hr = pShellWindows->FindWindowSW(&varg, &s_vaEmpty, SWC_BROWSER, phwnd, 
options, &pDispatch);
+    if (pDispatch && ppWebBrowserApp)
+        hr = pDispatch->QueryInterface(IID_PPV_ARG(IWebBrowserApp, 
ppWebBrowserApp));
+
+    VariantClearLazy(&varg);
+    return hr;
+}
+
+/*************************************************************************
+ *    WinList_RegisterPending (SHDOCVW.180)
+ *
+ * NT 5.0 and higher.
+ * @see 
https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-registerpending
+ */
+EXTERN_C
+HRESULT WINAPI
+WinList_RegisterPending(
+    _In_ DWORD dwThreadId,
+    _In_ LPCITEMIDLIST pidl,
+    _In_ DWORD dwUnused,
+    _Out_ PLONG plCookie)
+{
+    TRACE("(%ld, %p, %ld, %p)\n", dwThreadId, pidl, dwUnused, plCookie);
+
+    if (!pidl)
+    {
+        ERR("!pidl\n");
+        return E_UNEXPECTED;
+    }
+
+    CComPtr<IShellWindows> pShellWindows(WinList_GetShellWindows(FALSE));
+    if (!pShellWindows)
+    {
+        ERR("!pShellWindows\n");
+        return E_UNEXPECTED;
+    }
+
+    VARIANTARG varg;
+    HRESULT hr = InitVariantFromIDList(&varg, pidl);
+    if (FAILED_UNEXPECTEDLY(hr))
+        return hr;
+
+    hr = pShellWindows->RegisterPending(dwThreadId, &varg, &s_vaEmpty, 
SWC_BROWSER, plCookie);
+    VariantClearLazy(&varg);
+    return hr;
+}
+
+/*************************************************************************
+ *    WinList_Revoke (SHDOCVW.181)
+ *
+ * NT 5.0 and higher.
+ * @see 
https://learn.microsoft.com/en-us/windows/win32/api/exdisp/nf-exdisp-ishellwindows-revoke
+ */
+EXTERN_C
+HRESULT WINAPI
+WinList_Revoke(
+    _In_ LONG lCookie)
+{
+    TRACE("(%ld)\n", lCookie);
+
+    CComPtr<IShellWindows> pShellWindows(WinList_GetShellWindows(TRUE));
+    if (!pShellWindows)
+    {
+        ERR("!pShellWindows\n");
+        return E_FAIL;
+    }
+
+    return pShellWindows->Revoke(lCookie);
+}
diff --git a/sdk/include/reactos/shdocvw_undoc.h 
b/sdk/include/reactos/shdocvw_undoc.h
index 57e3ee8b9d7..31be12fa29c 100644
--- a/sdk/include/reactos/shdocvw_undoc.h
+++ b/sdk/include/reactos/shdocvw_undoc.h
@@ -2,14 +2,16 @@
  * PROJECT:     ReactOS Headers
  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
  * PURPOSE:     shdocvw.dll undocumented APIs
- * COPYRIGHT:   Copyright 2024 Katayama Hirofumi MZ 
<katayama.hirofumi...@gmail.com>
+ * COPYRIGHT:   Copyright 2024-2025 Katayama Hirofumi MZ 
<katayama.hirofumi...@gmail.com>
  */
 
 #pragma once
 
+#include <exdisp.h> // For IShellWindows
+
 #ifdef __cplusplus
 extern "C" {
-#endif /* defined(__cplusplus) */
+#endif
 
 BOOL WINAPI
 IEILIsEqual(
@@ -17,6 +19,31 @@ IEILIsEqual(
     _In_ LPCITEMIDLIST pidl2,
     _In_ BOOL bUnknown);
 
+BOOL WINAPI WinList_Init(VOID);
+VOID WINAPI WinList_Terminate(VOID);
+HRESULT WINAPI WinList_Revoke(_In_ LONG lCookie);
+IShellWindows* WINAPI WinList_GetShellWindows(_In_ BOOL bCreate);
+
+HRESULT WINAPI
+WinList_NotifyNewLocation(
+    _In_ IShellWindows *pShellWindows,
+    _In_ LONG lCookie,
+    _In_ LPCITEMIDLIST pidl);
+
+HRESULT WINAPI
+WinList_FindFolderWindow(
+    _In_ LPCITEMIDLIST pidl,
+    _In_ DWORD dwUnused,
+    _Out_opt_ PLONG phwnd,
+    _Out_opt_ IWebBrowserApp **ppWebBrowserApp);
+
+HRESULT WINAPI
+WinList_RegisterPending(
+    _In_ DWORD dwThreadId,
+    _In_ LPCITEMIDLIST pidl,
+    _In_ DWORD dwUnused,
+    _Out_ PLONG plCookie);
+
 #ifdef __cplusplus
 } /* extern "C" */
-#endif /* defined(__cplusplus) */
+#endif
diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h
index 187a74f4d44..52ef6f27f0b 100644
--- a/sdk/include/reactos/undocshell.h
+++ b/sdk/include/reactos/undocshell.h
@@ -928,7 +928,6 @@ BOOL WINAPI SHSettingsChanged(LPCVOID unused, LPCWSTR 
pszKey);
 #define TABDMC_LOADINPROC 2
 
 void WINAPI ShellDDEInit(BOOL bInit);
-DWORD WINAPI WinList_Init(void);
 
 IStream* WINAPI SHGetViewStream(LPCITEMIDLIST, DWORD, LPCTSTR, LPCTSTR, 
LPCTSTR);
 

Reply via email to