Start DDE interface from Explorer Process. Add DDE stubs.

Jeremiah Flerchinger jeremiah.flerchinger at gmail.com
Tue Feb 10 18:34:18 CST 2009


Explorer.exe now calls ShellDdeInit. Progman stubs will now be started/used in Shell32.
Amazingly any apps with a Progman DDE interface will also be called. Shell32 can handle
all major functionality, but a running progman.exe (for example) will be able to
synchronize internal values with changes made by Shell32.
---
 dlls/shell32/dde.c          |   42 +++++++++---
 programs/explorer/desktop.c |   17 +++++
 programs/progman/main.c     |  147 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+), 11 deletions(-)

diff --git a/dlls/shell32/dde.c b/dlls/shell32/dde.c
index 129f753..da8af57 100644
--- a/dlls/shell32/dde.c
+++ b/dlls/shell32/dde.c
@@ -22,6 +22,7 @@
 
 #include "windef.h"
 #include "winbase.h"
+#include "winuser.h"
 #include "ddeml.h"
 #include "shellapi.h"
 
@@ -40,10 +41,12 @@ static HSZ hszFolders;
 static DWORD dwDDEInst;
 

-static inline BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
+BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
 {
     if ((hszTopic == hszProgmanTopic) && (hszService == hszProgmanService))
+    {
         return TRUE;
+    }
     if ((hszTopic == hszProgmanTopic) && (hszService == hszAppProperties))
         return TRUE;
     if ((hszTopic == hszShell) && (hszService == hszFolders))
@@ -53,25 +56,25 @@ static inline BOOL Dde_OnConnect(HSZ hszTopic, HSZ hszService)
     return FALSE;
 }
 
-static inline void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
+void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
 {
     FIXME("stub\n");
 }
 
-static inline BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
+BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
 {
     FIXME("stub\n");
     return FALSE;
 }
 
-static inline HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
+HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
                                      HSZ hszItem)
 {
     FIXME("stub\n");
     return NULL;
 }
 
-static inline DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
+DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
 {
     BYTE * pszCommand;
 
@@ -86,12 +89,12 @@ static inline DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
     return DDE_FNOTPROCESSED;
 }
 
-static inline void Dde_OnDisconnect(HCONV hconv)
+void Dde_OnDisconnect(HCONV hconv)
 {
     FIXME("stub\n");
 }
 
-static HDDEDATA CALLBACK DdeCallback(      
+HDDEDATA CALLBACK DdeCallback(
     UINT uType,
     UINT uFmt,
     HCONV hconv,
@@ -101,23 +104,43 @@ static HDDEDATA CALLBACK DdeCallback(
     ULONG_PTR dwData1,
     ULONG_PTR dwData2)
 {
+    char strBuff1[16];
+    char strBuff2[16];
+    if(DdeQueryStringA(dwDDEInst, hsz1, strBuff1, 16, CP_WINANSI) != 0)
+    {
+        if(DdeQueryStringA(dwDDEInst, hsz2, strBuff2, 16, CP_WINANSI) != 0)
+        {
+            FIXME("DdeCallback hszTopic=%s hszItem=%s \n", strBuff1, strBuff2);
+        }
+        else
+        {
+            FIXME("DdeCallback hszTopic=%s \n", strBuff1);
+        }
+    }
     switch (uType)
     {
     case XTYP_CONNECT:
+        FIXME("XTYP_CONNECT \n");
         return (HDDEDATA)(DWORD_PTR)Dde_OnConnect(hsz1, hsz2);
     case XTYP_CONNECT_CONFIRM:
+        FIXME("XTYP_CONNECT_CONFIRM \n");
         Dde_OnConnectConfirm(hconv, hsz1, hsz2);
         return NULL;
     case XTYP_WILDCONNECT:
+        FIXME("XTYP_WILDCONNECT \n");
         return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hsz1, hsz2);
     case XTYP_REQUEST:
+        FIXME("DXTYP_REQUEST \n");
         return Dde_OnRequest(uFmt, hconv, hsz1, hsz2);
     case XTYP_EXECUTE:
+        FIXME("XTYP_EXECUTE \n");
         return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hconv, hsz1, hdata);
     case XTYP_DISCONNECT:
+        FIXME("XTYP_DISCONNECT \n");
         Dde_OnDisconnect(hconv);
         return NULL;
     default:
+        FIXME("uType=%i \n",uType);
         return NULL;
     }
 }
@@ -147,8 +170,7 @@ void WINAPI ShellDDEInit(BOOL bInit)
             {'A','p','p','P','r','o','p','e','r','t','i','e','s',0};
         static const WCHAR wszFolders[] = {'F','o','l','d','e','r','s',0};
 
-        DdeInitializeW(&dwDDEInst, DdeCallback, CBF_FAIL_ADVISES | CBF_FAIL_POKES, 0);
-
+        DdeInitializeW(&dwDDEInst, DdeCallback, APPCLASS_STANDARD, 0);
         hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
         hszProgmanService = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
         hszAsterisk = DdeCreateStringHandleW(dwDDEInst, wszAsterisk, CP_WINUNICODE);
@@ -164,14 +186,12 @@ void WINAPI ShellDDEInit(BOOL bInit)
     {
         /* unregister all services */
         DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
-
         DdeFreeStringHandle(dwDDEInst, hszFolders);
         DdeFreeStringHandle(dwDDEInst, hszAppProperties);
         DdeFreeStringHandle(dwDDEInst, hszShell);
         DdeFreeStringHandle(dwDDEInst, hszAsterisk);
         DdeFreeStringHandle(dwDDEInst, hszProgmanService);
         DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
-
         DdeUninitialize(dwDDEInst);
     }
 }
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 480d245..80e68eb 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -359,6 +359,18 @@ void manage_desktop( WCHAR *arg )
         }
     }
 
+    HMODULE libShdocvw;
+    FARPROC ShellDDEInit = NULL;
+
+    libShdocvw = LoadLibraryA("Shdocvw.dll");
+    if (libShdocvw)
+    {
+        ShellDDEInit = (void *)GetProcAddress(libShdocvw, (LPCSTR)118);
+        if (ShellDDEInit != NULL)
+        {
+            ShellDDEInit(TRUE);
+        }
+    }
     /* run the desktop message loop */
     if (hwnd)
     {
@@ -366,6 +378,11 @@ void manage_desktop( WCHAR *arg )
         while (GetMessageW( &msg, 0, 0, 0 )) DispatchMessageW( &msg );
         WINE_TRACE( "desktop message loop exiting for hwnd %p\n", hwnd );
     }
+    
+    if (ShellDDEInit != NULL)
+    {
+        ShellDDEInit(FALSE);
+    }
 
     ExitProcess( 0 );
 }
diff --git a/programs/progman/main.c b/programs/progman/main.c
index 83a346c..4c34b98 100644
--- a/programs/progman/main.c
+++ b/programs/progman/main.c
@@ -29,6 +29,13 @@
 
 GLOBALS Globals;
 
+/* String handles */
+static HSZ hszProgmanTopic;
+static HSZ hszProgmanService;
+static HSZ hszAppProperties;
+/* DDE Instance ID */
+static DWORD dwDDEInst;
+
 static VOID MAIN_CreateGroups(void);
 static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
 static ATOM MAIN_RegisterMainWinClass(void);
@@ -40,6 +47,94 @@ static VOID WineWarranty(HWND Wnd);
 
 #define BUFFER_SIZE 1000
 
+void Dde_OnConnectConfirm(HCONV hconv, HSZ hszTopic, HSZ hszService)
+{
+    printf("Progman.exe: Dde_OnConnectConfirm stub\n");
+}
+
+BOOL Dde_OnWildConnect(HSZ hszTopic, HSZ hszService)
+{
+    printf("Progman.exe: Dde_OnWildConnect stub\n");
+    return FALSE;
+}
+
+HDDEDATA Dde_OnRequest(UINT uFmt, HCONV hconv, HSZ hszTopic,
+                                     HSZ hszItem)
+{
+    printf("Progman.exe: Dde_OnRequest stub\n");
+    return NULL;
+}
+
+DWORD Dde_OnExecute(HCONV hconv, HSZ hszTopic, HDDEDATA hdata)
+{
+    BYTE * pszCommand;
+
+    pszCommand = DdeAccessData(hdata, NULL);
+    if (!pszCommand)
+        return DDE_FNOTPROCESSED;
+
+    printf("Progman.exe: Dde_OnExecute stub: %s\n", pszCommand);
+
+    DdeUnaccessData(hdata);
+
+    return DDE_FNOTPROCESSED;
+}
+
+void Dde_OnDisconnect(HCONV hconv)
+{
+    printf("Progman.exe: Dde_OnDisconnect stub\n");
+}
+
+static HDDEDATA CALLBACK DdeCallback(UINT wType, UINT fmt, HCONV hConv, HSZ hszTopic, HSZ hszItem, HDDEDATA hData, DWORD dwData1, DWORD dwData2)
+{
+  char strBuff1[16];
+  char strBuff2[16];
+  if(DdeQueryString(dwDDEInst, hszTopic, strBuff1, 16, CP_WINANSI) != 0)
+  {
+    if(DdeQueryString(dwDDEInst, hszItem, strBuff2, 16, CP_WINANSI) != 0)
+    {
+      printf("Progman.exe: stub DdeCallback hszTopic=%s hszItem=%s \n", strBuff1, strBuff2);
+    }
+    else
+    {
+      printf("Progman.exe: stub DdeCallback hszTopic=%s \n", strBuff1);
+    }
+  }
+  switch (wType)
+  {
+    case XTYP_CONNECT:
+        printf("Progman.exe: XTYP_CONNECT stub return TRUE - Note DDE functionality is limited\n");
+        if ((hszTopic == hszProgmanTopic) && (hszItem == hszProgmanService))
+        {
+            printf("Progman.exe: XTYP_CONNECT stub return TRUE - Note DDE functionality is limited\n");
+            return TRUE;
+        }
+        printf("Progman.exe: XTYP_CONNECT stub return FALSE - DDE connection rejected\n");
+        return FALSE;
+    case XTYP_CONNECT_CONFIRM:
+        printf("Progman.exe: XTYP_CONNECT_CONFIRM stub\n");
+        Dde_OnConnectConfirm(hConv, hszTopic, hszItem);
+        return NULL;
+    case XTYP_WILDCONNECT:
+        printf("Progman.exe: XTYP_WILDCONNECT stub\n");
+        return (HDDEDATA)(DWORD_PTR)Dde_OnWildConnect(hszTopic, hszItem);
+    case XTYP_REQUEST:
+        printf("Progman.exe: XTYP_REQUEST stub\n");
+        return Dde_OnRequest(fmt, hConv, hszTopic, hszItem);
+    case XTYP_EXECUTE:
+        printf("Progman.exe: XTYP_EXECUTE stub\n");
+        return (HDDEDATA)(DWORD_PTR)Dde_OnExecute(hConv, hszTopic, hData);
+    case XTYP_DISCONNECT:
+        printf("Progman.exe: XTYP_DISCONNECT stub\n");
+        Dde_OnDisconnect(hConv);
+        return NULL;
+    default:
+        printf("Progman.exe: XTYP type=0h%X (%i) default stub\n", wType, wType);
+        return NULL;
+  }
+}
+
+
 /***********************************************************************
  *
  *           WinMain
@@ -48,6 +143,9 @@ static VOID WineWarranty(HWND Wnd);
 int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
 {
   MSG      msg;
+  static const WCHAR wszProgman[] = {'P','R','O','G','M','A','N',0};
+  static const WCHAR wszAppProperties[] =
+            {'A','p','p','P','r','o','p','e','r','t','i','e','s',0};
 
   Globals.lpszIniFile         = "progman.ini";
   Globals.lpszIcoFile         = "progman.ico";
@@ -56,6 +154,12 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show
   Globals.hGroups             = 0;
   Globals.hActiveGroup        = 0;
 
+  /* start dde */
+  DdeInitializeW(&dwDDEInst, DdeCallback, APPCLASS_STANDARD, 0);
+  hszProgmanTopic = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
+  hszProgmanService = DdeCreateStringHandleW(dwDDEInst, wszProgman, CP_WINUNICODE);
+  DdeNameService(dwDDEInst, hszProgmanService, 0, DNS_REGISTER);
+
   /* Read Options from `progman.ini' */
   Globals.bAutoArrange =
     GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
@@ -102,6 +206,14 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show
 	TranslateMessage (&msg);
 	DispatchMessage (&msg);
       }
+
+  /* close dde*/
+  DdeNameService(dwDDEInst, 0, 0, DNS_UNREGISTER);
+  DdeFreeStringHandle(dwDDEInst, hszProgmanService);
+  DdeFreeStringHandle(dwDDEInst, hszProgmanTopic);
+  DdeFreeStringHandle(dwDDEInst, hszAppProperties);
+
+  DdeUninitialize(dwDDEInst);
   return 0;
 }
 
@@ -167,6 +279,13 @@ VOID MAIN_AutoStart(void)
 static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
 				 WPARAM wParam, LPARAM lParam)
 {
+    int maxstrcount = 255;
+    int strcount;
+    char strService[maxstrcount];
+    char strTopic[maxstrcount];
+    UINT_PTR		uiLo, uiHi;
+    ATOM atomApplication;
+    ATOM atomTopic;
 #if 0
   printf("M %4.4x %4.4x\n", msg, wParam);
 #endif
@@ -190,6 +309,34 @@ static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
     case WM_DESTROY:
       PostQuitMessage (0);
       break;
+    case WM_DDE_INITIATE:
+      uiLo = LOWORD(lParam);
+      uiHi = HIWORD(lParam);
+      strcount = GlobalGetAtomName(uiLo, strService, maxstrcount);
+      strcount = GlobalGetAtomName(uiHi, strTopic, maxstrcount);
+      printf("Progman.exe: WM_DDE_INITIATE stub Service=%s Topic=%s \n", strService, strTopic);
+      break;
+    case WM_DDE_POKE:
+      printf("Progman.exe: WM_DDE_POKE stub \n");
+      break;
+    case WM_DDE_EXECUTE:
+      printf("Progman.exe: WM_DDE_EXECUTE stub \n");
+      break;
+    case WM_DDE_DATA:
+      printf("Progman.exe: WM_DDE_DATA stub \n");
+      break;
+    case WM_DDE_ADVISE:
+      printf("Progman.exe: WM_DDE_ADVISE stub \n");
+      break;
+    case WM_DDE_UNADVISE:
+      printf("Progman.exe: WM_DDE_UNADVISE stub \n");
+      break;
+    case WM_DDE_REQUEST:
+      printf("Progman.exe: WM_DDE_REQUEST stub \n");
+      break;
+    case WM_DDE_TERMINATE:
+      printf("Progman.exe: WM_DDE_TERMINATE stub \n");
+      break;
     }
   return(DefFrameProc(hWnd, Globals.hMDIWnd, msg, wParam, lParam));
 }
-- 
1.5.6.3




More information about the wine-patches mailing list