rundll patch

Eric Pouech Eric.Pouech at wanadoo.fr
Wed Feb 21 15:48:48 CST 2001


this patch is first stab at implementing the RunDLL function in shell32
basically, this now lets my Win98 control.exe and rundll32.exe work
there are a few unimplemented APIs that forbid some control panel
applets not to work... there'll be another patch for those...

A+
-- 
---------------
Eric Pouech (http://perso.wanadoo.fr/eric.pouech/)
"The future will be better tomorrow", Vice President Dan Quayle
-------------- next part --------------
Name: rundll
ChangeLog: a first stab at implementing the RunDll features
GenDate: 2001/02/21 21:41:33 UTC
ModifiedFiles: dlls/shell32/Makefile.in dlls/shell32/iconcache.c dlls/shell32/shell32.spec dlls/shell32/shell32_main.c dlls/shell32/shellord.c include/winuser.h
AddedFiles: dlls/shell32/control.c include/cpl.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/shell32/Makefile.in,v
retrieving revision 1.40
diff -u -u -r1.40 Makefile.in
--- dlls/shell32/Makefile.in	2000/12/06 01:50:49	1.40
+++ dlls/shell32/Makefile.in	2001/02/16 22:22:57
@@ -14,6 +14,7 @@
 	changenotify.c \
 	classes.c \
 	clipboard.c \
+	control.c \
 	dataobject.c \
 	dialogs.c \
 	enumidlist.c \
Index: dlls/shell32/iconcache.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/shell32/iconcache.c,v
retrieving revision 1.43
diff -u -u -r1.43 iconcache.c
--- dlls/shell32/iconcache.c	2001/01/17 22:05:25	1.43
+++ dlls/shell32/iconcache.c	2001/01/18 06:25:49
@@ -157,7 +157,7 @@
 	return ret;
 }
 /****************************************************************************
- * SIC_LoadIcon				[internal]
+ * SIC_GetIcon				[internal]
  *
  * NOTES
  *  retrives the specified icon from the iconcache. if not found try's to load the icon
Index: dlls/shell32/shell32.spec
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/shell32/shell32.spec,v
retrieving revision 1.40
diff -u -u -r1.40 shell32.spec
--- dlls/shell32/shell32.spec	2001/01/18 23:04:19	1.40
+++ dlls/shell32/shell32.spec	2001/02/17 17:58:29
@@ -14,7 +14,7 @@
 import kernel32.dll
 import ntdll.dll
 
-debug_channels (exec pidl shell)
+debug_channels (exec pidl shell shlctrl)
 
 # Functions exported by the Win95 shell32.dll 
 # (these need to have these exact ordinals, for some 
@@ -172,10 +172,10 @@
  164 stdcall Win32DeleteFile(str) Win32DeleteFile
  165 stdcall SHCreateDirectory(long long) SHCreateDirectory
  166 stub CallCPLEntry16
- 167 stub SHAddFromPropSheetExtArray
- 168 stub SHCreatePropSheetExtArray
- 169 stub SHDestroyPropSheetExtArray
- 170 stub SHReplaceFromPropSheetExtArray
+ 167 stdcall SHAddFromPropSheetExtArray(long long long) SHAddFromPropSheetExtArray
+ 168 stdcall SHCreatePropSheetExtArray(long str long) SHCreatePropSheetExtArray
+ 169 stdcall SHDestroyPropSheetExtArray(long) SHDestroyPropSheetExtArray
+ 170 stdcall SHReplaceFromPropSheetExtArray(long long long long) SHReplaceFromPropSheetExtArray
  171 stdcall PathCleanupSpec(ptr ptr) PathCleanupSpecAW
  172 stub SHCreateLinks
  173 stdcall SHValidateUNC(long long long)SHValidateUNC
Index: dlls/shell32/shell32_main.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/shell32/shell32_main.c,v
retrieving revision 1.71
diff -u -u -r1.71 shell32_main.c
--- dlls/shell32/shell32_main.c	2001/02/12 03:51:04	1.71
+++ dlls/shell32/shell32_main.c	2001/02/16 22:21:10
@@ -77,20 +77,6 @@
 }
 
 /*************************************************************************
- * Control_RunDLL			[SHELL32.12]
- *
- * Wild speculation in the following!
- *
- * http://premium.microsoft.com/msdn/library/techart/msdn193.htm
- */
-
-void WINAPI Control_RunDLL( HWND hwnd, LPCVOID code, LPCSTR cmd, DWORD arg4 )
-{
-    FIXME("(0x%08x, %p, %s, 0x%08lx): stub\n", hwnd, code,
-          debugstr_a(cmd), arg4);
-}
-
-/*************************************************************************
  * SHGetFileInfoA			[SHELL32.@]
  *
  */
Index: dlls/shell32/shellord.c
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/shell32/shellord.c,v
retrieving revision 1.76
diff -u -u -r1.76 shellord.c
--- dlls/shell32/shellord.c	2000/12/01 23:58:29	1.76
+++ dlls/shell32/shellord.c	2001/02/17 17:57:20
@@ -881,22 +881,6 @@
 	FIXME("%p 0x%08lx 0x%08lx stub\n", pidl, dwFlags, dwTimeout);
 	return 0;
 }
-/*************************************************************************
- * Control_FillCache_RunDLL			[SHELL32.8]
- *
- */
-HRESULT WINAPI Control_FillCache_RunDLL(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
-{	FIXME("0x%04x 0x%04x 0x%04lx 0x%04lx stub\n",hWnd, hModule,w,x);
-	return 0;
-}
-/*************************************************************************
- * RunDLL_CallEntry16				[SHELL32.122]
- * the name is propably wrong
- */
-HRESULT WINAPI RunDLL_CallEntry16(DWORD v, DWORD w, DWORD x, DWORD y, DWORD z)
-{	FIXME("0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",v,w,x,y,z);
-	return 0;
-}
 
 /************************************************************************
  *	shell32_654				[SHELL32.654]
@@ -981,5 +965,41 @@
 DWORD WINAPI SHELL32_714(LPVOID x)
 {
  	FIXME("(%s)stub\n", debugstr_w(x));
+	return 0;
+}
+
+/*************************************************************************
+ *      SHAddFromPropSheetExtArray	[SHELL32]
+ */
+DWORD WINAPI SHAddFromPropSheetExtArray(DWORD a, DWORD b, DWORD c)
+{
+ 	FIXME("(%08lx,%08lx,%08lx)stub\n", a, b, c);
+	return 0;
+}
+
+/*************************************************************************
+ *      SHCreatePropSheetExtArray	[SHELL32]
+ */
+DWORD WINAPI SHCreatePropSheetExtArray(DWORD a, LPCSTR b, DWORD c)
+{
+ 	FIXME("(%08lx,%s,%08lx)stub\n", a, debugstr_a(b), c);
+	return 0;
+}
+
+/*************************************************************************
+ *      SHReplaceFromPropSheetExtArray	[SHELL]
+ */
+DWORD WINAPI SHReplaceFromPropSheetExtArray(DWORD a, DWORD b, DWORD c, DWORD d)
+{
+ 	FIXME("(%08lx,%08lx,%08lx,%08lx)stub\n", a, b, c, d);
+	return 0;
+}
+
+/*************************************************************************
+ *      SHDestroyPropSheetExtArray	[SHELL32]
+ */
+DWORD WINAPI SHDestroyPropSheetExtArray(DWORD a)
+{
+ 	FIXME("(%08lx)stub\n", a);
 	return 0;
 }
Index: include/winuser.h
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/include/winuser.h,v
retrieving revision 1.101
diff -u -u -r1.101 winuser.h
--- include/winuser.h	2001/02/12 03:40:42	1.101
+++ include/winuser.h	2001/02/17 06:09:33
@@ -3083,10 +3083,6 @@
 #define DI_COMPAT               4
 #define DI_DEFAULTSIZE          8
 
-  /* misc messages */
-#define WM_CPL_LAUNCH       (WM_USER + 1000)
-#define WM_CPL_LAUNCHED     (WM_USER + 1001)
-
 /* WM_NOTIFYFORMAT commands and return values */
 #define NFR_ANSI	    1
 #define NFR_UNICODE	    2
--- /dev/null	Tue May  5 22:32:27 1998
+++ dlls/shell32/control.c	Sat Feb 17 22:14:15 2001
@@ -0,0 +1,386 @@
+/* Control Panel management */
+/* Eric Pouech 2001 */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "debugtools.h"
+#include "cpl.h"
+
+DEFAULT_DEBUG_CHANNEL(shlctrl);
+
+typedef struct CPlApplet {
+    struct CPlApplet*   next;		/* linked list */
+    HWND		hWnd;
+    unsigned		count;		/* number of subprograms */
+    HMODULE     	hModule;	/* module of loaded applet */
+    APPLET_PROC		proc;		/* entry point address */
+    NEWCPLINFOA		info[1];	/* array of count information. 
+					 * dwSize field is 0 if entry is invalid */
+} CPlApplet;
+
+typedef struct CPanel {
+    CPlApplet*		first;		/* linked list */
+    HWND		hWnd;
+    unsigned            status;
+    CPlApplet*		clkApplet;
+    unsigned            clkSP;
+} CPanel;
+
+static	CPlApplet*	Control_UnloadApplet(CPlApplet* applet)
+{
+    unsigned	i;
+    CPlApplet*	next;
+
+    for (i = 0; i < applet->count; i++) {
+        if (!applet->info[i].dwSize) continue;
+        applet->proc(applet->hWnd, CPL_STOP, i, applet->info[i].lData);
+    }
+    if (applet->proc) applet->proc(applet->hWnd, CPL_EXIT, 0L, 0L);
+    FreeLibrary(applet->hModule);
+    next = applet->next;
+    HeapFree(GetProcessHeap(), 0, applet);
+    return next;
+}
+
+static CPlApplet*	Control_LoadApplet(HWND hWnd, LPCSTR cmd, CPanel* panel)
+{
+    CPlApplet*	applet;
+    unsigned 	i;
+    CPLINFO	info;
+
+    if (!(applet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*applet))))
+       return applet;
+
+    applet->hWnd = hWnd;
+
+    if (!(applet->hModule = LoadLibraryA(cmd))) {
+        WARN("Cannot load control panel applet %s\n", cmd);
+	goto theError;
+    }
+    if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) {
+        WARN("Not a valid control panel applet %s\n", cmd);
+	goto theError;
+    }
+    if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) {
+        WARN("Init of applet has failed\n");
+	goto theError;
+    }
+    if ((applet->count = applet->proc(hWnd, CPL_GETCOUNT, 0L, 0L)) == 0) {
+        WARN("No subprogram in applet\n");
+	goto theError;
+    }
+
+    applet = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet, 
+			 sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOA));
+    
+    for (i = 0; i < applet->count; i++) {
+       applet->info[i].dwSize = sizeof(NEWCPLINFOA);
+       /* proc is supposed to return a null value upon success for
+	* CPL_INQUIRE and CPL_NEWINQUIRE
+	* However, real drivers don't seem to behave like this
+	* So, use introspection rather than return value
+	*/
+       applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&applet->info[i]);
+       if (applet->info[i].hIcon == 0) {
+	   applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info);
+	   if (info.idIcon == 0 || info.idName == 0) {
+	       WARN("Couldn't get info from sp %u\n", i);
+	       applet->info[i].dwSize = 0;
+	   } else {
+	       /* convert the old data into the new structure */
+	       applet->info[i].dwFlags = 0;
+	       applet->info[i].dwHelpContext = 0;
+	       applet->info[i].lData = info.lData;
+	       applet->info[i].hIcon = LoadIconA(applet->hModule, 
+						 MAKEINTRESOURCEA(info.idIcon));
+	       LoadStringA(applet->hModule, info.idName, 
+			   applet->info[i].szName, sizeof(applet->info[i].szName));
+	       LoadStringA(applet->hModule, info.idInfo, 
+			   applet->info[i].szInfo, sizeof(applet->info[i].szInfo));
+	       applet->info[i].szHelpFile[0] = '\0';
+	   }
+       }
+    }
+
+    applet->next = panel->first;
+    panel->first = applet;
+
+    return applet;
+
+ theError:
+    Control_UnloadApplet(applet);
+    return NULL;
+}
+
+static void 	 Control_WndProc_Create(HWND hWnd, const CREATESTRUCTA* cs)
+{
+   CPanel*	panel = (CPanel*)cs->lpCreateParams;
+
+   SetWindowLongA(hWnd, 0, (LPARAM)panel);
+   panel->status = 0;
+   panel->hWnd = hWnd;
+}
+
+#define	XICON	32
+#define XSTEP	128
+#define	YICON	32
+#define YSTEP	64
+
+static BOOL	Control_Localize(const CPanel* panel, unsigned cx, unsigned cy,
+				 CPlApplet** papplet, unsigned* psp)
+{
+    unsigned	i, x = (XSTEP-XICON)/2, y = 0;
+    CPlApplet*	applet;
+    RECT	rc;
+    
+    GetClientRect(panel->hWnd, &rc);
+    for (applet = panel->first; applet; applet = applet = applet->next) {
+        for (i = 0; i < applet->count; i++) {
+	    if (!applet->info[i].dwSize) continue;
+	    if (x + XSTEP >= rc.right - rc.left) {
+	        x = (XSTEP-XICON)/2;
+		y += YSTEP;
+	    }
+	    if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP) {
+	        *papplet = applet;
+	        *psp = i;
+		return TRUE;
+	    }
+	    x += XSTEP;
+	}
+    }
+    return FALSE;
+}
+
+static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam)
+{
+    HDC		hdc;
+    PAINTSTRUCT	ps;
+    RECT	rc, txtRect;
+    unsigned	i, x = 0, y = 0;
+    CPlApplet*	applet;
+    HGDIOBJ	hOldFont;
+
+    hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps);
+    hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
+    GetClientRect(panel->hWnd, &rc);
+    for (applet = panel->first; applet; applet = applet = applet->next) {
+        for (i = 0; i < applet->count; i++) {
+	    if (x + XSTEP >= rc.right - rc.left) {
+	        x = 0;
+		y += YSTEP;
+	    }
+	    if (!applet->info[i].dwSize) continue;
+	    DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon);
+	    txtRect.left = x;
+	    txtRect.right = x + XSTEP;
+	    txtRect.top = y + YICON;
+	    txtRect.bottom = y + YSTEP;
+	    DrawTextA(hdc, applet->info[i].szName, -1, &txtRect, 
+		      DT_CENTER | DT_VCENTER);
+	    x += XSTEP;
+	}
+    }
+    SelectObject(hdc, hOldFont);
+    if (!wParam) EndPaint(panel->hWnd, &ps);
+    return 0;
+}
+
+static LRESULT Control_WndProc_LButton(CPanel* panel, LPARAM lParam, BOOL up)
+{
+    unsigned	i;
+    CPlApplet*	applet;
+    
+    if (Control_Localize(panel, LOWORD(lParam), HIWORD(lParam), &applet, &i)) {
+       if (up) {
+	   if (panel->clkApplet == applet && panel->clkSP == i) {
+	       applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData);
+	   }
+       } else {
+	   panel->clkApplet = applet;
+	   panel->clkSP = i;
+       }
+    }
+    return 0;
+}
+
+static LRESULT WINAPI	Control_WndProc(HWND hWnd, UINT wMsg, 
+					WPARAM lParam1, LPARAM lParam2)
+{
+   CPanel*	panel = (CPanel*)GetWindowLongA(hWnd, 0);
+
+   if (panel || wMsg == WM_CREATE) {
+      switch (wMsg) {
+      case WM_CREATE:
+	 Control_WndProc_Create(hWnd, (CREATESTRUCTA*)lParam2);
+	 return 0;
+      case WM_DESTROY:
+	 while ((panel->first = Control_UnloadApplet(panel->first)));
+	 break;
+      case WM_PAINT:
+	 return Control_WndProc_Paint(panel, lParam1);
+      case WM_LBUTTONUP:
+	 return Control_WndProc_LButton(panel, lParam2, TRUE);
+      case WM_LBUTTONDOWN:
+	 return Control_WndProc_LButton(panel, lParam2, FALSE);
+/* EPP       case WM_COMMAND: */
+/* EPP 	 return Control_WndProc_Command(mwi, lParam1, lParam2); */
+      }
+   }
+
+   return DefWindowProcA(hWnd, wMsg, lParam1, lParam2);
+}
+
+static void    Control_DoInterface(CPanel* panel, HWND hWnd, HINSTANCE hInst)
+{
+    WNDCLASSA	wc;
+    MSG		msg;
+
+    wc.style = CS_HREDRAW|CS_VREDRAW;
+    wc.lpfnWndProc = Control_WndProc;
+    wc.cbClsExtra = 0;
+    wc.cbWndExtra = sizeof(CPlApplet*);
+    wc.hInstance = hInst;
+    wc.hIcon = 0;
+    wc.hCursor = 0;
+    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+    wc.lpszMenuName = NULL;
+    wc.lpszClassName = "Shell_Control_WndClass";
+
+    if (!RegisterClassA(&wc)) return;
+
+    CreateWindowExA(0, wc.lpszClassName, "Wine Control Panel", 
+		    WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
+		    CW_USEDEFAULT, CW_USEDEFAULT, 
+		    CW_USEDEFAULT, CW_USEDEFAULT, 
+		    hWnd, (HMENU)0, hInst, panel);
+    if (!panel->hWnd) return;
+    while (GetMessageA(&msg, panel->hWnd, 0, 0)) {
+        TranslateMessage(&msg);
+        DispatchMessageA(&msg);
+	if (!panel->first) break;
+    }
+}
+
+static	void	Control_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst)
+{
+    HANDLE		h;
+    WIN32_FIND_DATAA	fd;
+    char		buffer[MAX_PATH];
+
+    /* FIXME: should grab path somewhere from configuration */
+    if ((h = FindFirstFileA("c:\\windows\\system\\*.cpl", &fd)) != 0) {
+        do {
+	   sprintf(buffer, "c:\\windows\\system\\%s", fd.cFileName);
+	   Control_LoadApplet(hWnd, buffer, panel);
+	} while (FindNextFileA(h, &fd));
+	FindClose(h);
+    }
+
+    if (panel->first) Control_DoInterface(panel, hWnd, hInst);
+}
+
+static	void	Control_DoLaunch(CPanel* panel, HWND hWnd, LPCSTR cmd)
+   /* forms to parse:
+    *	foo.cpl, at sp,str
+    *	foo.cpl, at sp
+    *	foo.cpl,,str
+    *	foo.cpl @sp
+    *	foo.cpl str
+    */
+{
+    char*	buffer;
+    char*	beg = NULL;
+    char*	end;
+    char	ch;
+    unsigned 	sp = 0;
+    char*	extraPmts = NULL;
+
+    buffer = HeapAlloc(GetProcessHeap(), 0, strlen(cmd) + 1);
+    if (!buffer) return;
+
+    end = strcpy(buffer, cmd);
+
+    for (;;) {
+	ch = *end;
+	if (ch == ' ' || ch == ',' || ch == '\0') {
+	    *end = '\0';
+	    if (beg) {
+	        if (*beg == '@') {
+		    sp = atoi(beg + 1);
+		} else if (*beg == '\0') {
+		    sp = 0;
+		} else {
+		    extraPmts = beg;
+		}
+	    }
+	    if (ch == '\0') break;
+	    beg = end + 1;
+	    if (ch == ' ') while (end[1] == ' ') end++;
+	}
+	end++;
+    }
+    Control_LoadApplet(hWnd, buffer, panel);
+
+    if (panel->first) {
+       CPlApplet* applet = panel->first;
+
+       assert(applet && applet->next == NULL);
+       if (sp >= applet->count) {
+	  WARN("Out of bounds (%u >= %u), setting to 0\n", sp, applet->count);
+	  sp = 0;
+       }
+       if (applet->info[sp].dwSize) {
+	  if (!applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp, (LPARAM)extraPmts))
+	     applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].lData);
+       }
+       Control_UnloadApplet(applet);
+    }
+    HeapFree(GetProcessHeap(), 0, buffer);
+}
+
+/*************************************************************************
+ * Control_RunDLL			[SHELL32.12]
+ *
+ */
+void WINAPI Control_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
+{
+    CPanel	panel;
+
+    TRACE("(0x%08x, 0x%08lx, %s, 0x%08lx)\n", 
+	  hWnd, (DWORD)hInst, debugstr_a(cmd), nCmdShow);
+
+    memset(&panel, 0, sizeof(panel));
+
+    if (!cmd || !*cmd) {
+        Control_DoWindow(&panel, hWnd, hInst);
+    } else {
+        Control_DoLaunch(&panel, hWnd, cmd);
+    }
+}
+
+/*************************************************************************
+ * Control_FillCache_RunDLL			[SHELL32.8]
+ *
+ */
+HRESULT WINAPI Control_FillCache_RunDLL(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
+{
+    FIXME("0x%04x 0x%04x 0x%04lx 0x%04lx stub\n",hWnd, hModule, w, x);
+    return 0;
+}
+
+/*************************************************************************
+ * RunDLL_CallEntry16				[SHELL32.122]
+ * the name is propably wrong
+ */
+HRESULT WINAPI RunDLL_CallEntry16(DWORD v, DWORD w, DWORD x, DWORD y, DWORD z)
+{
+    FIXME("0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",v,w,x,y,z);
+    return 0;
+}
--- /dev/null	Tue May  5 22:32:27 1998
+++ include/cpl.h	Fri Feb 16 23:32:33 2001
@@ -0,0 +1,70 @@
+/* Control panel definition */
+
+#ifndef __WINE_CPL_H
+#define __WINE_CPL_H
+
+#include <pshpack1.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define WM_CPL_LAUNCH   (WM_USER+1000)
+#define WM_CPL_LAUNCHED (WM_USER+1001)
+
+typedef LONG (APIENTRY *APPLET_PROC)(HWND hwndCpl, UINT msg, LPARAM lParam1, LPARAM lParam2);
+
+typedef struct tagCPLINFO {
+    int     idIcon;
+    int     idName;
+    int     idInfo;
+    LONG    lData;
+} CPLINFO, *LPCPLINFO;
+
+typedef struct tagNEWCPLINFOA
+{
+    DWORD   dwSize;
+    DWORD   dwFlags;
+    DWORD   dwHelpContext;
+    LONG    lData;
+    HICON   hIcon;
+    CHAR    szName[32];
+    CHAR    szInfo[64];
+    CHAR    szHelpFile[128];
+} NEWCPLINFOA, *LPNEWCPLINFOA;
+
+typedef struct tagNEWCPLINFOW
+{
+    DWORD   dwSize;
+    DWORD   dwFlags;
+    DWORD   dwHelpContext;
+    LONG    lData;
+    HICON   hIcon;
+    WCHAR   szName[32];
+    WCHAR   szInfo[64];
+    WCHAR   szHelpFile[128];
+} NEWCPLINFOW, *LPNEWCPLINFOW;
+#define NEWCPLINFO WINELIB_NAME_AW(NEWCPLINFO)
+
+#define CPL_DYNAMIC_RES 	0
+#define CPL_INIT        	1
+#define CPL_GETCOUNT    	2
+#define CPL_INQUIRE     	3
+#define CPL_SELECT      	4
+#define CPL_DBLCLK      	5
+#define CPL_STOP        	6
+#define CPL_EXIT        	7
+#define CPL_NEWINQUIRE		8
+#define CPL_STARTWPARMSA 	9
+#define CPL_STARTWPARMSW 	10
+#define CPL_STARTWPARMS WINELIB_NAME_AW(CPL_STARTWPARMS)
+#define CPL_SETUP		200
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <poppack.h>
+
+#endif
+


More information about the wine-patches mailing list