wineboot: Start items in StartUp folder on boot.

Misha Koshelev mk144210 at bcm.tmc.edu
Fri Feb 9 22:04:18 CST 2007


This patch makes sure that wine will start items in the StartUp folder
(Programs) just like Windows. The reason this is necessary, well #1 this
is something Windows does that Wine doesn't do, but #2 this is required
by the Vector NTI installer (bug #7384), which installs necessary
dependencies (MDAC and about 6 other things) by installing one, then
placing a link to itself in StartUp, then rebooting. With this patch, it
will actually restart correctly, and in fact just running wine
installer.exe will actually successfully do the install from start to
finish (for the alternative to install this prior to this and a few
other patches, see my shell script
http://misha680.googlepages.com/InstallVectorNTI10.sh). There is still
the lack of JScript support which fails to install some things, but
that's about it.

Oh, and I would appreciate if someone who is more experience can look
over this patch, as I am quite new to this IShellFolder thing. Thanks.

Changelog:

	* wineboot: Start items in StartUp folder on boot.
-------------- next part --------------
From 446dbc9d3f961bff416e20b3504305763d145a78 Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at bcm.tmc.edu>
Date: Fri, 9 Feb 2007 21:48:21 -0600
Subject: wineboot: Start items in StartUp folder on boot.
---
 programs/wineboot/Makefile.in |    3 +
 programs/wineboot/wineboot.c  |   92 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+), 2 deletions(-)

diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in
index 08c27a5..bf1b723 100644
--- a/programs/wineboot/Makefile.in
+++ b/programs/wineboot/Makefile.in
@@ -4,7 +4,8 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = wineboot.exe
 APPMODE   = -mconsole
-IMPORTS   = version user32 advapi32 kernel32
+IMPORTS   = version user32 advapi32 kernel32 shell32 shlwapi
+EXTRALIBS = -luuid
 
 C_SRCS = \
 	shutdown.c \
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 1434003..bda10b1 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -63,6 +63,12 @@ #endif
 #include <windows.h>
 #include <wine/debug.h>
 
+#define COBJMACROS
+#include <shlobj.h>
+#include <shobjidl.h>
+#include <shlwapi.h>
+#include <shellapi.h>
+
 WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
 
 #define MAX_LINE_LENGTH (2*MAX_PATH+2)
@@ -616,6 +622,88 @@ static int ProcessWindowsFileProtection(
     return 1;
 }
 
+/* Process items in the StartUp group of the user's Programs under the Start Menu. Some installers put
+ * shell links here to restart themselves after boot. */
+static BOOL ProcessStartupItems()
+{
+    BOOL ret = FALSE;
+    HRESULT hr;
+    int iRet;
+    IMalloc *ppM = NULL;
+    IShellFolder *psfDesktop = NULL, *psfStartup = NULL;
+    LPITEMIDLIST pidlStartup = NULL, pidlItem;
+    ULONG NumPIDLs;
+    IEnumIDList *iEnumList = NULL;
+    STRRET strret;
+    WCHAR wszCommand[MAX_PATH];
+
+    WINE_TRACE("Processing items in the StartUp folder.\n");
+
+    hr = SHGetMalloc(&ppM);
+    if (FAILED(hr)) 
+    {
+	WINE_ERR("Couldn't get IMalloc object.\n");
+	goto done;
+    }
+
+    hr = SHGetDesktopFolder(&psfDesktop);
+    if (FAILED(hr))
+    {
+	WINE_ERR("Couldn't get desktop folder.\n");
+	goto done;
+    }
+
+    hr = SHGetSpecialFolderLocation(NULL, CSIDL_STARTUP, &pidlStartup);
+    if (FAILED(hr))
+    {
+	WINE_TRACE("Couldn't get StartUp folder location.\n");
+	goto done;
+    }
+  
+    hr = IShellFolder_BindToObject(psfDesktop, pidlStartup, NULL, &IID_IShellFolder, (LPVOID*)&psfStartup);
+    if (FAILED(hr))
+    {
+	WINE_TRACE("Couldn't bind IShellFolder to StartUp folder.\n");
+	goto done;
+    }
+
+    hr = IShellFolder_EnumObjects(psfStartup, NULL, SHCONTF_NONFOLDERS | SHCONTF_INCLUDEHIDDEN, &iEnumList);
+    if (FAILED(hr))
+    {
+	WINE_TRACE("Unable to enumerate StartUp objects.\n");
+	goto done;
+    }
+
+    while (IEnumIDList_Next(iEnumList, 1, &pidlItem, &NumPIDLs) == S_OK && 
+	   (NumPIDLs) == 1) 
+    {
+	hr = IShellFolder_GetDisplayNameOf(psfStartup, pidlItem, SHGDN_FORPARSING, &strret);
+	if (FAILED(hr)) 
+	    WINE_TRACE("Unable to get display name of enumeration item.\n");
+	else 
+	{
+	    hr = StrRetToBufW(&strret, pidlItem, wszCommand, MAX_PATH);
+	    if (FAILED(hr))
+		WINE_TRACE("Unable to parse display name.\n");
+	    else
+		if ((iRet = (int)ShellExecuteW(NULL, NULL, wszCommand, NULL, NULL, 0)) <= 32)
+		    WINE_ERR("Error %d executing command %s.\n", iRet, wine_dbgstr_w(wszCommand));
+	}
+
+	IMalloc_Free(ppM, pidlItem);
+    }
+
+    /* Return success */
+    ret = TRUE;
+  
+done:
+    if (iEnumList) IEnumIDList_Release(iEnumList);
+    if (psfStartup) IShellFolder_Release(psfStartup);
+    if (pidlStartup) IMalloc_Free(ppM, pidlStartup); 
+
+    return ret;
+}
+
 static void usage(void)
 {
     WINE_MESSAGE( "Usage: wineboot [options]\n" );
@@ -732,7 +820,9 @@ int main( int argc, char *argv[] )
                 FALSE, FALSE )) &&
         (!ops.postlogin || !ops.startup ||
          ProcessRunKeys( HKEY_CURRENT_USER, runkeys_names[RUNKEY_RUN],
-                FALSE, FALSE ));
+                FALSE, FALSE )) &&
+	(!ops.postlogin || !ops.startup ||
+	 ProcessStartupItems( ));
 
     WINE_TRACE("Operation done\n");
 
-- 
1.4.1



More information about the wine-patches mailing list