Implemented a Wine-only scheme for interprocess WinHelp message
passing.
diff --git a/windows/winhelp.c b/windows/winhelp.c
index 6cb6abd..b9bfd85 100644
--- a/windows/winhelp.c
+++ b/windows/winhelp.c
@@ -2,6 +2,7 @@
* Windows Help
*
* Copyright 1996 Martin von Loewis
+ * 2002 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,17 +28,31 @@
# include <unistd.h>
#endif
#include "wine/debug.h"
-#include "windef.h"
+#include "winbase.h"
#include "wingdi.h"
-#include "wownt32.h"
-#include "wine/winuser16.h"
-#include "wine/winbase16.h"
-#include "win.h"
+#include "winuser.h"
+#include "winnls.h"
WINE_DEFAULT_DEBUG_CHANNEL(win);
-
-/* WinHelp internal structure */
+/* Wine doesn't use the way WinHelp API sends information in Windows, because:
+ * 1/ it's not consistent acrosss Win9x, NT...
+ * 2/ NT implementation is not yet fully understood (and includes some shared
+ * memory mechanism)
+ * 3/ uses a dynamically allocated message number (WM_WINHELP), which
+ * obfuscates the code
+ *
+ * So we use (for now) the simple protocol:
+ * 1/ it's based on copy data
+ * 2/ we tag the message with a magic number, to make it a bit more robust
+ * (even if it's not 100% safe)
+ * 3/ data structure (WINHELP) has the same layout that the one used on Win95.
+ * This doesn't bring much, except not going to far away from real
+ * implementation.
+ *
+ * This means anyway that native winhelp.exe and winhlp32.exe cannot be
+ * called/manipulated from WinHelp API.
+ */
typedef struct
{
WORD size;
@@ -46,117 +61,100 @@
LONG reserved;
WORD ofsFilename;
WORD ofsData;
-} WINHELP,*LPWINHELP;
+} WINHELP;
-/**********************************************************************
- * WinHelp (USER.171)
+/* magic number for this message:
+ * aide means help is French ;-)
+ * SOS means ???
*/
-BOOL16 WINAPI WinHelp16( HWND16 hWnd, LPCSTR lpHelpFile, UINT16 wCommand,
- DWORD dwData )
-{
- BOOL ret;
- DWORD mutex_count;
-
- /* We might call WinExec() */
- ReleaseThunkLock( &mutex_count );
-
- if (!(ret = WinHelpA( WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData) )))
- {
- /* try to start the 16-bit winhelp */
- if (WinExec( "winhelp.exe -x", SW_SHOWNORMAL ) >= 32)
- {
- K32WOWYield16();
- ret = WinHelpA( WIN_Handle32(hWnd), lpHelpFile, wCommand, (DWORD)MapSL(dwData) );
- }
- }
-
- RestoreThunkLock( mutex_count );
- return ret;
-}
-
+#define WINHELP_MAGIC 0xA1DE505
/**********************************************************************
* WinHelpA (USER32.@)
*/
BOOL WINAPI WinHelpA( HWND hWnd, LPCSTR lpHelpFile, UINT wCommand, ULONG_PTR dwData )
{
- static WORD WM_WINHELP = 0;
- HWND hDest;
- LPWINHELP lpwh;
- HGLOBAL16 hwh;
- int size,dsize,nlen;
+ COPYDATASTRUCT cds;
+ HWND hDest;
+ int size, dsize, nlen;
+ WINHELP* lpwh;
-
- if(!WM_WINHELP)
- {
- WM_WINHELP=RegisterWindowMessageA("WM_WINHELP");
- if(!WM_WINHELP)
- return FALSE;
- }
-
- hDest = FindWindowA( "MS_WINHELP", NULL );
- if(!hDest) {
- if(wCommand == HELP_QUIT) return TRUE;
- if (WinExec ( "winhlp32.exe -x", SW_SHOWNORMAL ) < 32) {
- ERR("can't start winhlp32.exe -x ?\n");
- return FALSE;
- }
- if ( ! ( hDest = FindWindowA ( "MS_WINHELP", NULL ) )) {
- FIXME("did not find MS_WINHELP (FindWindow() failed, maybe global window handling still unimplemented)\n");
- return FALSE;
- }
+ hDest = FindWindowA("MS_WINHELP", NULL);
+ if (!hDest)
+ {
+ if (wCommand == HELP_QUIT) return TRUE;
+ if (WinExec("winhelp.exe -x", SW_SHOWNORMAL) < 32)
+ {
+ ERR("can't start winhelp.exe -x ?\n");
+ return FALSE;
}
+ if (!(hDest = FindWindowA("MS_WINHELP", NULL)))
+ {
+ FIXME("Did not find a MS_WINHELP Window\n");
+ return FALSE;
+ }
+ }
+ switch (wCommand)
+ {
+ case HELP_CONTEXT:
+ case HELP_SETCONTENTS:
+ case HELP_CONTENTS:
+ case HELP_CONTEXTPOPUP:
+ case HELP_FORCEFILE:
+ case HELP_HELPONHELP:
+ case HELP_FINDER:
+ case HELP_QUIT:
+ dsize = 0;
+ break;
+ case HELP_KEY:
+ case HELP_PARTIALKEY:
+ case HELP_COMMAND:
+ dsize = dwData ? strlen((LPSTR)dwData) + 1 : 0;
+ break;
+ case HELP_MULTIKEY:
+ dsize = ((LPMULTIKEYHELPA)dwData)->mkSize;
+ break;
+ case HELP_SETWINPOS:
+ dsize = ((LPHELPWININFOA)dwData)->wStructSize;
+ break;
+ default:
+ FIXME("Unknown help command %d\n", wCommand);
+ return FALSE;
+ }
+ if (lpHelpFile)
+ nlen = strlen(lpHelpFile) + 1;
+ else
+ nlen = 0;
+ size = sizeof(WINHELP) + nlen + dsize;
- switch(wCommand)
- {
- case HELP_CONTEXT:
- case HELP_SETCONTENTS:
- case HELP_CONTENTS:
- case HELP_CONTEXTPOPUP:
- case HELP_FORCEFILE:
- case HELP_HELPONHELP:
- case HELP_FINDER:
- case HELP_QUIT:
- dsize=0;
- break;
- case HELP_KEY:
- case HELP_PARTIALKEY:
- case HELP_COMMAND:
- dsize = dwData ? strlen( (LPSTR)dwData )+1: 0;
- break;
- case HELP_MULTIKEY:
- dsize = ((LPMULTIKEYHELPA)dwData)->mkSize;
- break;
- case HELP_SETWINPOS:
- dsize = ((LPHELPWININFOA)dwData)->wStructSize;
- break;
- default:
- FIXME("Unknown help command %d\n",wCommand);
- return FALSE;
- }
- if(lpHelpFile)
- nlen = strlen(lpHelpFile)+1;
- else
- nlen = 0;
- size = sizeof(WINHELP) + nlen + dsize;
- hwh = GlobalAlloc16(0,size);
- lpwh = GlobalLock16(hwh);
- lpwh->size = size;
- lpwh->command = wCommand;
- lpwh->data = dwData;
- if(nlen) {
- strcpy(((char*)lpwh) + sizeof(WINHELP),lpHelpFile);
- lpwh->ofsFilename = sizeof(WINHELP);
- } else
- lpwh->ofsFilename = 0;
- if(dsize) {
- memcpy(((char*)lpwh)+sizeof(WINHELP)+nlen,(LPSTR)dwData,dsize);
- lpwh->ofsData = sizeof(WINHELP)+nlen;
- } else
- lpwh->ofsData = 0;
- GlobalUnlock16(hwh);
- return SendMessage16(HWND_16(hDest),WM_WINHELP,HWND_16(hWnd),hwh);
+ lpwh = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!lpwh) return FALSE;
+
+ cds.dwData = WINHELP_MAGIC;
+ cds.cbData = size;
+ cds.lpData = (void*)lpwh;
+
+ lpwh->size = size;
+ lpwh->command = wCommand;
+ lpwh->data = dwData;
+ if (nlen)
+ {
+ strcpy(((char*)lpwh) + sizeof(WINHELP), lpHelpFile);
+ lpwh->ofsFilename = sizeof(WINHELP);
+ } else
+ lpwh->ofsFilename = 0;
+ if (dsize)
+ {
+ memcpy(((char*)lpwh) + sizeof(WINHELP) + nlen, (LPSTR)dwData, dsize);
+ lpwh->ofsData = sizeof(WINHELP) + nlen;
+ } else
+ lpwh->ofsData = 0;
+ WINE_TRACE("Sending[%u]: cmd=%u data=%08lx fn=%s\n",
+ lpwh->size, lpwh->command, lpwh->data,
+ lpwh->ofsFilename ? (LPSTR)lpwh + lpwh->ofsFilename : "");
+
+ return SendMessageA(hDest, WM_COPYDATA, hWnd, (LPARAM)&cds);
}