wine/programs/winemenubuilder winemenubuilder.c

Alexandre Julliard julliard at wine.codeweavers.com
Thu Nov 10 05:36:26 CST 2005


ChangeSet ID:	21212
CVSROOT:	/opt/cvs-commit
Module name:	wine
Changes by:	julliard at winehq.org	2005/11/10 05:36:26

Modified files:
	programs/winemenubuilder: winemenubuilder.c 

Log message:
	Francois Gouget <fgouget at codeweavers.com>
	Parse the command line returned by CommandLineFromMsiDescriptor() to
	extract the application path. Otherwise winemenubuilder ignores the
	.lnk file entirely.

Patch: http://cvs.winehq.org/patch.py?id=21212

Old revision  New revision  Changes     Path
 1.36          1.37          +91 -7      wine/programs/winemenubuilder/winemenubuilder.c

Index: wine/programs/winemenubuilder/winemenubuilder.c
diff -u -p wine/programs/winemenubuilder/winemenubuilder.c:1.36 wine/programs/winemenubuilder/winemenubuilder.c:1.37
--- wine/programs/winemenubuilder/winemenubuilder.c:1.36	10 Nov 2005 11:36:26 -0000
+++ wine/programs/winemenubuilder/winemenubuilder.c	10 Nov 2005 11:36:26 -0000
@@ -728,16 +728,22 @@ static BOOL GetLinkLocation( LPCWSTR lin
 }
 
 /* gets the target path directly or through MSI */
-static HRESULT get_path( IShellLinkW *sl, LPWSTR szPath, DWORD sz )
+static HRESULT get_cmdline( IShellLinkW *sl, LPWSTR szPath, DWORD pathSize,
+                            LPWSTR szArgs, DWORD argsSize)
 {
     IShellLinkDataList *dl = NULL;
     EXP_DARWIN_LINK *dar = NULL;
     HRESULT hr;
 
     szPath[0] = 0;
-    hr = IShellLinkW_GetPath( sl, szPath, MAX_PATH, NULL, SLGP_RAWPATH );
+    szArgs[0] = 0;
+
+    hr = IShellLinkW_GetPath( sl, szPath, pathSize, NULL, SLGP_RAWPATH );
     if (hr == S_OK && szPath[0])
+    {
+        IShellLinkW_GetArguments( sl, szArgs, argsSize );
         return hr;
+    }
 
     hr = IShellLinkW_QueryInterface( sl, &IID_IShellLinkDataList, (LPVOID*) &dl );
     if (FAILED(hr))
@@ -746,7 +752,88 @@ static HRESULT get_path( IShellLinkW *sl
     hr = IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG, (LPVOID*) &dar );
     if (SUCCEEDED(hr))
     {
-        CommandLineFromMsiDescriptor( dar->szwDarwinID, szPath, &sz );
+        WCHAR* szCmdline;
+        DWORD cmdSize;
+
+        cmdSize=0;
+        hr = CommandLineFromMsiDescriptor( dar->szwDarwinID, NULL, &cmdSize );
+        if (hr == ERROR_SUCCESS)
+        {
+            cmdSize++;
+            szCmdline = HeapAlloc( GetProcessHeap(), 0, cmdSize*sizeof(WCHAR) );
+            hr = CommandLineFromMsiDescriptor( dar->szwDarwinID, szCmdline, &cmdSize );
+            WINE_TRACE("      command    : %s\n", wine_dbgstr_w(szCmdline));
+            if (hr == ERROR_SUCCESS)
+            {
+                WCHAR *s, *d;
+                int bcount, in_quotes;
+
+                /* Extract the application path */
+                bcount=0;
+                in_quotes=0;
+                s=szCmdline;
+                d=szPath;
+                while (*s)
+                {
+                    if ((*s==0x0009 || *s==0x0020) && !in_quotes)
+                    {
+                        /* skip the remaining spaces */
+                        do {
+                            s++;
+                        } while (*s==0x0009 || *s==0x0020);
+                        break;
+                    }
+                    else if (*s==0x005c)
+                    {
+                        /* '\\' */
+                        *d++=*s++;
+                        bcount++;
+                    }
+                    else if (*s==0x0022)
+                    {
+                        /* '"' */
+                        if ((bcount & 1)==0)
+                        {
+                            /* Preceded by an even number of '\', this is
+                             * half that number of '\', plus a quote which
+                             * we erase.
+                             */
+                            d-=bcount/2;
+                            in_quotes=!in_quotes;
+                            s++;
+                        }
+                        else
+                        {
+                            /* Preceded by an odd number of '\', this is
+                             * half that number of '\' followed by a '"'
+                             */
+                            d=d-bcount/2-1;
+                            *d++='"';
+                            s++;
+                        }
+                        bcount=0;
+                    }
+                    else
+                    {
+                        /* a regular character */
+                        *d++=*s++;
+                        bcount=0;
+                    }
+                    if ((d-szPath) == pathSize)
+                    {
+                        /* Keep processing the path till we get to the
+                         * arguments, but 'stand still'
+                         */
+                        d--;
+                    }
+                }
+                /* Close the application path */
+                *d=0;
+
+                lstrcpynW(szArgs, s, argsSize);
+            }
+            HeapFree( GetProcessHeap(), 0, szCmdline );
+        }
         LocalFree( dar );
     }
 
@@ -788,11 +875,8 @@ static BOOL InvokeShellLinker( IShellLin
     IShellLinkW_GetDescription( sl, szDescription, INFOTIPSIZE );
     WINE_TRACE("description: %s\n", wine_dbgstr_w(szDescription));
 
-    get_path( sl, szPath, MAX_PATH );
+    get_cmdline( sl, szPath, MAX_PATH, szArgs, INFOTIPSIZE);
     WINE_TRACE("path       : %s\n", wine_dbgstr_w(szPath));
-
-    szArgs[0] = 0;
-    IShellLinkW_GetArguments( sl, szArgs, INFOTIPSIZE );
     WINE_TRACE("args       : %s\n", wine_dbgstr_w(szArgs));
 
     szIconPath[0] = 0;



More information about the wine-cvs mailing list