wineboot: Start items in StartUp folder on boot.

Misha Koshelev mk144210 at bcm.tmc.edu
Fri Feb 9 22:12:16 CST 2007


Hi,

As you all may have noticed, I have been making quite a few patches
within the last two weeks (or at least quite a few when compared to zero
before then) because I had figured out that the Vector NTI program that
is quite important in molecular biologThis 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.y (and freely available to academic researchers) can be
installed on Wine and run with quite little problem with a quite
complicated install script I made
http://misha680.googlepages.com/InstallVectorNTI10.sh). There was one
pretty significant bug, but after that I wanted to try to track down and
patch other bugs that forced the above script to be required. With the
exception of a pretty significant lack of JScript support in wine/MSI
which causes installation of quite a few files to fail (and thus still
require native jscript.dll and native MSI), this final patch I just sent
out makes the install work from start to finish, which is quite a change
from before.

I posted two patches earlier (a conformance test and a fix) that adds
path searching to shell link creation (which the conformance test shows
exists in Windows for a file like rundll32.exe that is not found in the
current directory), and if anyone has comments about those patches
please send them to me. My last patch ensures that this shelllink that
the Vector NTI installer creates every time it tries to restart (about
six or so times after every Microsoft component it installs that it
needs and comes with) will be executed, and in fact is meant to
reproduce the Windows behavior of starting items in the StartUp program
group on login that occurs in Windows. I am new to the whole
IShellFolder thing, though, and I tried to make it as proper as I could.
But I certainly feel that I would like to have someone more experience
to look at it. 

Oh, and I just wanted to say a big thanks to Dan Kegel, James Hawkings,
Mike McCormack, and others who have helped me so far (not to mention
Alexandre Julliard for committing some of my patches).

Misha
-------------- 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-devel mailing list