Index: README
===================================================================
RCS file: /home/wine/wine/programs/uninstaller/README,v
retrieving revision 1.1
diff -u -r1.1 README
--- README	1 Aug 2000 00:27:35 -0000	1.1
+++ README	8 Mar 2005 09:07:50 -0000
@@ -1,20 +1,18 @@
 Uninstaller README
 
 Uninstaller, copyright 2000, Andreas Mohr
+Uninstaller, copyright 2005, Jonathan Ernst
 Uninstaller is to be distributed under the Wine License
 See the Wine License for further information.
 
 This is an uninstaller for all setup programs that put an uninstall entry
 into the registry, such as e.g. InstallShield or the WISE installer.
-Its files have been shamelessly ripped from WineMine partially :)
 
 TODO:
-    - implement sorting of the uninstall entries
     - let the uninstall happen in a separate thread in order to be able to
       uninstall several programs concurrently
 
 KNOWN BUGS:
-    - minimizing/maximizing is broken (just as with WineMine)
     - the icon is, ermm, wrong ;-))
 
 UNKNOWN BUGS:
Index: main.c
===================================================================
RCS file: /home/wine/wine/programs/uninstaller/main.c,v
retrieving revision 1.19
diff -u -r1.19 main.c
--- main.c	9 Dec 2004 14:07:59 -0000	1.19
+++ main.c	8 Mar 2005 09:07:51 -0000
@@ -1,8 +1,9 @@
 /*
- * Q&D Uninstaller (main.c)
+ * Uninstaller
  *
  * Copyright 2000 Andreas Mohr <andi@lisas.de>
  * Copyright 2004 Hannu Valtonen <Hannu.Valtonen@hut.fi>
+ * Copyright 2005 Jonathan Ernst <Jonathan@ErnstFamily.ch>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,95 +19,68 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * ToDo:
- * - add search box for locating entries quickly
+ * TODO: Some more unicodification
  */
 
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <time.h>
-#include <windows.h>
-#include "main.h"
+#include <windows.h>
+#include "resource.h" 
 #include "regstr.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(uninstaller);
 
-/* Work around a Wine bug which defines handles as UINT rather than LPVOID */
-#ifdef WINE_STRICT
-#define NULL_HANDLE NULL
-#else
-#define NULL_HANDLE 0
-#endif
-
-/* use multi-select listbox */
-#undef USE_MULTIPLESEL
-
-/* Delete uninstall registry key after execution.
- * This is probably a bad idea, because it's the
- * uninstall program that is supposed to do that.
- */
-#undef DEL_REG_KEY
-
-char appname[18];
-
-static char about_string[] =
-    "Wine Application Uninstaller (C) 2004 by Andreas Mohr <andi@lisas.de> and Hannu Valtonen <Hannu.Valtonen@hut.fi>";
-static char program_description[] =
-	"Please select the application you wish to uninstall:";
-
 typedef struct {
     char *key;
     WCHAR *descr;
     char *command;
     int active;
 } uninst_entry;
+static uninst_entry *entries = NULL;
+static unsigned int numentries = 0;
+static int list_need_update = 1;
+static int oldsel = -1;
+static WCHAR *sFilter;
+static WCHAR sAppName[MAX_STRING_LEN];
+static WCHAR sAboutTitle[MAX_STRING_LEN];
+static WCHAR sAbout[MAX_STRING_LEN];
+static WCHAR sRegistryKeyNotAvailable[MAX_STRING_LEN];
+static WCHAR sUninstallFailed[MAX_STRING_LEN];
+
+static int FetchUninstallInformation(void);
+static void UninstallProgram(void);
+static void UpdateList(HWND hList);
+static int cmp_by_name(const void *a, const void *b);
+static WCHAR *stristr(const WCHAR *String, const WCHAR *Pattern);
 
-uninst_entry *entries = NULL;
-
-unsigned int numentries = 0;
-int list_need_update = 1;
-int oldsel = -1;
-
-struct {
-    DWORD style;
-    LPCSTR text;
-    HWND hwnd;
-} button[] =
-{
-    { BS_PUSHBUTTON, "Add/Remove", 0 },
-    { BS_PUSHBUTTON, "About", 0 },
-    { BS_PUSHBUTTON, "Exit", 0 }
-};
-
-#define NUM (sizeof(button)/sizeof(button[0]))
-
-int FetchUninstallInformation(void);
-void UninstallProgram(void);
-
-void ListUninstallPrograms(void)
+/**
+ * Used to output program list when used with --list
+ */
+static void ListUninstallPrograms(void)
 {
     unsigned int i;
-    int len;
-    char *descr;
+ /*   int len;
+    WCHAR *descr;*/
 
     if (! FetchUninstallInformation())
         return;
 
     for (i=0; i < numentries; i++)
     {
+        /*
+        TELL ME: IS IT STILL NEEDED WITH UNICODE ???
         len = WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, NULL, 0, NULL, NULL); 
-        descr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-        WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, len, NULL, NULL); 
-        printf("%s|||%s\n", entries[i].key, descr);
-        HeapFree(GetProcessHeap(), 0, descr);
+        descr = HeapAlloc(GetProcessHeap(), 0, len);
+        WideCharToMultiByte(CP_UNIXCP, 0, entries[i].descr, -1, descr, len, NULL, NULL); */
+        printf("%s|||%s\n", entries[i].key, entries[i].descr);
+        /*HeapFree(GetProcessHeap(), 0, descr);*/
     }
 }
 
 
-void RemoveSpecificProgram(char *name)
+static void RemoveSpecificProgram(WCHAR *name)
 {
     unsigned int i;
 
@@ -130,80 +104,11 @@
     }
 }
 
-int main( int argc, char *argv[])
-{
-    MSG msg;
-    WNDCLASS wc;
-    HWND hWnd;
-    LPSTR token = NULL;
-    int i = 1;
-    HINSTANCE hInst = NULL;
-
-    while( i<argc )
-    {
-        token = argv[i++];
-
-        /* Handle requests just to list the applications */
-        if( !lstrcmpA( token, "--list" ) )
-        {
-            ListUninstallPrograms();
-            return 0;
-        }
-        else if( !lstrcmpA( token, "--remove" ) )
-        {
-            if( i >= argc )
-            {
-                WINE_ERR( "The remove option requires a parameter.\n");
-                return 1;
-            }
-
-            RemoveSpecificProgram( argv[i++] );
-            return 0;
-        }
-        else 
-        {
-            WINE_ERR( "unknown option %s\n",token);
-            return 1;
-        }
-    }
-
-    LoadString( hInst, IDS_APPNAME, appname, sizeof(appname));
-
-    wc.style = 0;
-    wc.lpfnWndProc = MainProc;
-    wc.cbClsExtra = 0;
-    wc.cbWndExtra = 0;
-    wc.hInstance = hInst;
-    wc.hIcon = LoadIcon( hInst, appname );
-    wc.hCursor = LoadCursor( NULL_HANDLE, IDI_APPLICATION );
-    wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
-    wc.lpszMenuName = NULL;
-    wc.lpszClassName = appname;
-
-    if (!RegisterClass(&wc)) exit(1);
-    hWnd = CreateWindow( appname, "Wine Application Uninstaller",
-        WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
-        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
-        NULL_HANDLE, NULL_HANDLE, hInst, NULL );
-
-    if (!hWnd) exit(1);
-
-    ShowWindow( hWnd, SW_SHOW );
-    UpdateWindow( hWnd );
-
-    while( GetMessage(&msg, NULL_HANDLE, 0, 0) ) {
-	TranslateMessage( &msg );
-        DispatchMessage( &msg );
-    }
-    return msg.wParam;
-}
-
-int cmp_by_name(const void *a, const void *b)
-{
-    return lstrcmpiW(((const uninst_entry *)a)->descr, ((const uninst_entry *)b)->descr);
-}
 
-int FetchUninstallInformation(void)
+/**
+ * Fetch informations from the uninstall key.
+ */
+static int FetchUninstallInformation(void)
 {
     HKEY hkeyUninst, hkeyApp;
     int i;
@@ -214,251 +119,294 @@
 
     numentries = 0;
     oldsel = -1;
-    if ( RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL,
-			    0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS )
+    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, 0, KEY_READ, &hkeyUninst) != ERROR_SUCCESS)
     {
-	MessageBox(0, "Uninstall registry key not available (yet), nothing to do !", appname, MB_OK);
-	return 0;
+        MessageBox(0, sRegistryKeyNotAvailable, sAppName, MB_OK);
+        return 0;
     }
 
     if (!entries)
-	entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));
+    entries = HeapAlloc(GetProcessHeap(), 0, sizeof(uninst_entry));
 
     strcpy(key_app, REGSTR_PATH_UNINSTALL);
     strcat(key_app, "\\");
     p = key_app+strlen(REGSTR_PATH_UNINSTALL)+1;
 
     sizeOfSubKeyName = 255;
-    for ( i=0;
-	  RegEnumKeyExA( hkeyUninst, i, subKeyName, &sizeOfSubKeyName,
-		  	 NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS;
-	  ++i )
+    for (i=0; RegEnumKeyExA( hkeyUninst, i, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, NULL ) != ERROR_NO_MORE_ITEMS; ++i)
     {
-	static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
-
-	strcpy(p, subKeyName);
-	RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, &hkeyApp);
-
-	if ( (RegQueryValueExW(hkeyApp, DisplayNameW,
-		0, 0, NULL, &displen) == ERROR_SUCCESS)
-	&&   (RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE,
-		0, 0, NULL, &uninstlen) == ERROR_SUCCESS) )
-	{
-	    numentries++;
-	    entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry));
-	    entries[numentries-1].key =
-		    HeapAlloc(GetProcessHeap(), 0, strlen(subKeyName)+1);
-	    strcpy(entries[numentries-1].key, subKeyName);
-	    entries[numentries-1].descr =
-		    HeapAlloc(GetProcessHeap(), 0, displen);
-	    RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0,
-			    (LPBYTE)entries[numentries-1].descr, &displen);
-	    entries[numentries-1].command =
-		    HeapAlloc(GetProcessHeap(), 0, uninstlen);
-	    entries[numentries-1].active = 0;
-	    RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, 0, 0,
-			    entries[numentries-1].command, &uninstlen);
-	    WINE_TRACE("allocated entry #%d: %s (%s), %s\n",
-		numentries, entries[numentries-1].key,
-		wine_dbgstr_w(entries[numentries-1].descr),
-		entries[numentries-1].command);
-	}
-	RegCloseKey(hkeyApp);
-
-	sizeOfSubKeyName = 255;
+        static const WCHAR DisplayNameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
+        strcpy(p, subKeyName);
+        RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_app, 0, KEY_READ, &hkeyApp);
+    
+        if ((RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, NULL, &displen) == ERROR_SUCCESS)
+        && (RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, 0, 0, NULL, &uninstlen) == ERROR_SUCCESS))
+        {
+            numentries++;
+            entries = HeapReAlloc(GetProcessHeap(), 0, entries, numentries*sizeof(uninst_entry));
+            entries[numentries-1].key = HeapAlloc(GetProcessHeap(), 0, strlen(subKeyName)+1);
+            strcpy(entries[numentries-1].key, subKeyName);
+            entries[numentries-1].descr = HeapAlloc(GetProcessHeap(), 0, displen);
+            RegQueryValueExW(hkeyApp, DisplayNameW, 0, 0, (LPBYTE)entries[numentries-1].descr, &displen);
+            entries[numentries-1].command = HeapAlloc(GetProcessHeap(), 0, uninstlen);
+            entries[numentries-1].active = 0;
+            RegQueryValueExA(hkeyApp, REGSTR_VAL_UNINSTALLER_COMMANDLINE, 0, 0, entries[numentries-1].command, &uninstlen);
+            WINE_TRACE("allocated entry #%d: %s (%s), %s\n",
+            numentries, entries[numentries-1].key, wine_dbgstr_w(entries[numentries-1].descr), entries[numentries-1].command);
+            if(sFilter != NULL && stristr(entries[numentries-1].descr,sFilter)==NULL)
+                numentries--;
+        }
+        RegCloseKey(hkeyApp);
+        sizeOfSubKeyName = 255;
     }
     qsort(entries, numentries, sizeof(uninst_entry), cmp_by_name);
     RegCloseKey(hkeyUninst);
     return 1;
 }
 
-void UninstallProgram(void)
+
+static void UninstallProgram(void)
 {
     unsigned int i;
-    char errormsg[1024];
+    WCHAR errormsg[1024];
     BOOL res;
     STARTUPINFO si;
     PROCESS_INFORMATION info;
     DWORD exit_code;
-#ifdef DEL_REG_KEY
     HKEY hkey;
-#endif
-
     for (i=0; i < numentries; i++)
     {
-	if (!(entries[i].active)) /* don't uninstall this one */
-	    continue;
-	WINE_TRACE("uninstalling %s\n", wine_dbgstr_w(entries[i].descr));
-	memset(&si, 0, sizeof(STARTUPINFO));
-	si.cb = sizeof(STARTUPINFO);
-	si.wShowWindow = SW_NORMAL;
-	res = CreateProcess(NULL, entries[i].command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info);
-	if (res)
-	{   /* wait for the process to exit */
-	    WaitForSingleObject(info.hProcess, INFINITE);
-	    res = GetExitCodeProcess(info.hProcess, &exit_code);
-	    WINE_TRACE("%d: %08lx\n", res, exit_code);
-#ifdef DEL_REG_KEY
-	    /* delete the application's uninstall entry */
-	    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL,
-		0, KEY_READ, &hkey) == ERROR_SUCCESS)
-	    {
-		RegDeleteKey(hkey, entries[i].key);
-		RegCloseKey(hkey);
-	    }
-#endif
-	}
-	else
-	{
-	    sprintf(errormsg, "Execution of uninstall command '%s' failed, perhaps due to missing executable.", entries[i].command);
-	    MessageBox(0, errormsg, appname, MB_OK);
-	}
+        if (!(entries[i].active)) /* don't uninstall this one */
+            continue;
+        WINE_TRACE("uninstalling %s\n", wine_dbgstr_w(entries[i].descr));
+        memset(&si, 0, sizeof(STARTUPINFO));
+        si.cb = sizeof(STARTUPINFO);
+        si.wShowWindow = SW_NORMAL;
+        res = CreateProcess(NULL, entries[i].command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info);
+        if (res)
+        {   /* wait for the process to exit */
+            WaitForSingleObject(info.hProcess, INFINITE);
+            res = GetExitCodeProcess(info.hProcess, &exit_code);
+            WINE_TRACE("%d: %08lx\n", res, exit_code);
+        }
+        else
+        {
+            sprintf(errormsg, sUninstallFailed, entries[i].command);
+            if(MessageBox(0, errormsg, sAppName, MB_YESNO | MB_ICONQUESTION)==IDYES)
+            {
+                /* delete the application's uninstall entry */
+                RegOpenKeyExA(HKEY_LOCAL_MACHINE, REGSTR_PATH_UNINSTALL, 0, KEY_READ, &hkey);
+                RegDeleteKey(hkey, entries[i].key);
+                RegCloseKey(hkey);
+            }
+        }
     }
     WINE_TRACE("finished uninstall phase.\n");
     list_need_update = 1;
 }
 
-LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+
+static void UpdateList(HWND hList)
 {
-    HFONT static_font, listbox_font;
-    HDC hdc;
-    PAINTSTRUCT ps;
-    TEXTMETRIC tm;
     unsigned int i;
-    int cxChar, cyChar, y, bx, maxx, maxy, wx, wy;
-    static HWND hwndList = 0, static_text = 0;
-    DWORD style;
-    RECT rect;
-
-    switch( msg ) {
-    case WM_CREATE:
-	{
-	hdc = GetDC(hWnd);
-	GetTextMetrics(hdc, &tm);
-	static_font = CreateFont(tm.tmHeight + tm.tmExternalLeading, 0, 0, 0, 600, FALSE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman");
-	listbox_font = CreateFont(tm.tmHeight + tm.tmExternalLeading, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, "Times New Roman");
-	cxChar = tm.tmAveCharWidth;
-	cyChar = tm.tmHeight + tm.tmExternalLeading;
-	ReleaseDC(hWnd, hdc);
-	/* FIXME: implement sorting and use LBS_SORT here ! */
-	style = (WS_CHILD|WS_VISIBLE|LBS_STANDARD) & ~LBS_SORT;
-#ifdef USE_MULTIPLESEL
-	style |= LBS_MULTIPLESEL;
-#endif
-	bx = maxx = cxChar * 3;
-	y = maxy = cyChar * 1;
-	static_text = CreateWindow("static", program_description,
-		WS_CHILD|WS_VISIBLE|SS_LEFT,
-		maxx, maxy,
-		cxChar * sizeof(program_description), cyChar * 1,
-		hWnd, (HMENU)1,
-		((LPCREATESTRUCT)lParam)->hInstance, NULL);
-	SendMessage(static_text, WM_SETFONT, (WPARAM)static_font, MAKELPARAM(FALSE, 0));
-	maxy += cyChar * 2; /*static text + distance */
-	hwndList = CreateWindow("listbox", NULL,
-		style,
-		maxx, maxy,
-		cxChar * 50 + GetSystemMetrics(SM_CXVSCROLL), cyChar * 10,
-		hWnd, (HMENU) 1,
-		(HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);
-	SendMessage(hwndList, WM_SETFONT, (WPARAM)listbox_font, MAKELPARAM(FALSE, 0));
-	GetWindowRect(hwndList, &rect);
-	maxx += (rect.right - rect.left)*1.1;	
-	maxy += (rect.bottom - rect.top)*1.1;
-	wx = 20*cxChar;
-	wy = 7*cyChar/4;
-	y = cyChar * 3;
-	for (i=0; i < NUM; i++)
-	{
-	    button[i].hwnd = CreateWindow("button", button[i].text,
-		WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,
-		maxx, y,
-		wx, wy,
-		hWnd, (HMENU)i,
-		((LPCREATESTRUCT)lParam)->hInstance, NULL);
-	    if (!button[i].hwnd)
-		    PostQuitMessage(0);
-	    y += 2*cyChar;
-	}
-	maxx += wx + cxChar * 4;
-	maxy += cyChar * 2; /* window border */
-	SetWindowPos(	hWnd, 0,
-			0, 0, maxx, maxy,
-			SWP_NOMOVE);
-        return 0;
-	}
+    if (list_need_update)
+    {
+        int prevsel;
+        prevsel = SendMessage(hList, LB_GETCURSEL, 0, 0);
+        if (!(FetchUninstallInformation()))
+        {
+            PostQuitMessage(0);
+        return;
+        }
+        SendMessage(hList, LB_RESETCONTENT, 0, 0);
+        SendMessage(hList, WM_SETREDRAW, FALSE, 0);
+        for (i=0; i < numentries; i++)
+        {
+            WINE_TRACE("adding %s\n", wine_dbgstr_w(entries[i].descr));
+            SendMessageW(hList, LB_ADDSTRING, 0, (LPARAM)entries[i].descr);
+        }
+        WINE_TRACE("setting prevsel %d\n", prevsel);
+        if (prevsel != -1)
+        SendMessage(hList, LB_SETCURSEL, prevsel, 0 );
+        SendMessage(hList, WM_SETREDRAW, TRUE, 0);
+        list_need_update = 0;
+    }
+}
 
-    case WM_PAINT:
-      {
-        hdc = BeginPaint( hWnd, &ps );
-	if (list_need_update)
-	{
-	    int prevsel;
-	    prevsel = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
-	    if (!(FetchUninstallInformation()))
-	    {
-	        PostQuitMessage(0);
-	        return 0;
-	    }
-	    SendMessage(hwndList, LB_RESETCONTENT, 0, 0);
-	    SendMessage(hwndList, WM_SETREDRAW, FALSE, 0);
-	    for (i=0; i < numentries; i++)
-	    {
-	        WINE_TRACE("adding %s\n", wine_dbgstr_w(entries[i].descr));
-	        SendMessageW(hwndList, LB_ADDSTRING, 0, (LPARAM)entries[i].descr);
-	    }
-	    WINE_TRACE("setting prevsel %d\n", prevsel);
-	    if (prevsel != -1)
-	        SendMessage(hwndList, LB_SETCURSEL, prevsel, 0 );
-	    SendMessage(hwndList, WM_SETREDRAW, TRUE, 0);
-	    list_need_update = 0;
-	}
-        EndPaint( hWnd, &ps );
-        return 0;
-      }
 
-    case WM_DESTROY:
-        PostQuitMessage( 0 );
-        return 0;
+INT_PTR CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
+{
+    TEXTMETRIC tm;
+    HDC hdc;
+    HWND hList = GetDlgItem(hwnd, IDC_LIST);
+    switch(Message)
+    {
+        case WM_INITDIALOG:
+            hdc = GetDC(hwnd);
+            GetTextMetrics(hdc, &tm);
+            UpdateList(hList);
+            ReleaseDC(hwnd, hdc);
+        break;
+        case WM_COMMAND:
+            switch(LOWORD(wParam))
+            {
+                case IDC_FILTER:
+                {
+                    if (HIWORD(wParam) == EN_CHANGE)
+                    {
+                        list_need_update = 1;
+                        int len = GetWindowTextLength(GetDlgItem(hwnd, IDC_FILTER));
+                        if(len > 0)
+                        {
+                            sFilter = (WCHAR*)GlobalAlloc(GPTR, len + 1);
+                            GetDlgItemText(hwnd, IDC_FILTER, sFilter, len + 1);
+                        }
+                        else sFilter = NULL;
+                        UpdateList(hList);
+                    }
+                }
+                break;
+                case IDC_UNINSTALL:
+                {
+                    int count = SendMessage(hList, LB_GETSELCOUNT, 0, 0);
+                    if(count != 0)
+                    {
+                        UninstallProgram();
+                        UpdateList(hList);
+                    }
+                }
+                break;
+                case IDC_LIST:
+                {
+                    if (HIWORD(wParam) == LBN_SELCHANGE)
+                    {
+                       int sel = SendMessage(hList, LB_GETCURSEL, 0, 0);
+               if (oldsel != -1)
+                       {
+                           entries[oldsel].active ^= 1; /* toggle */
+                           WINE_TRACE("toggling %d old %s\n", entries[oldsel].active,
+                           wine_dbgstr_w(entries[oldsel].descr));
+                       }
+                       entries[sel].active ^= 1; /* toggle */
+                       WINE_TRACE("toggling %d %s\n", entries[sel].active,
+                       wine_dbgstr_w(entries[oldsel].descr));
+                       oldsel = sel;
+                   }
+                }
+                break;
+                case IDC_ABOUT:
+                    MessageBox(0, sAbout, sAboutTitle, MB_OK);
+                break;
+                case IDC_EXIT:
+                    EndDialog(hwnd, 0);
+                break;
+            }
+        break;
+        default:
+            return FALSE;
+    }
+    return TRUE;
+}
 
-    case WM_COMMAND:
-	if ((HWND)lParam == hwndList)
-	{
-	    if (HIWORD(wParam) == LBN_SELCHANGE)
-	    {
-		int sel = SendMessage(hwndList, LB_GETCURSEL, 0, 0);
-
-#ifndef USE_MULTIPLESEL
-		if (oldsel != -1)
-		{
-		    entries[oldsel].active ^= 1; /* toggle */
-		    WINE_TRACE("toggling %d old %s\n", entries[oldsel].active,
-				wine_dbgstr_w(entries[oldsel].descr));
-		}
-#endif
-		entries[sel].active ^= 1; /* toggle */
-		WINE_TRACE("toggling %d %s\n", entries[sel].active,
-			    wine_dbgstr_w(entries[oldsel].descr));
-		oldsel = sel;
-	    }
-	}
-	else
-	if ((HWND)lParam == button[0].hwnd) /* Uninstall button */
-        {
-	    UninstallProgram();
 
-	    InvalidateRect(hWnd, NULL, TRUE);
-	    UpdateWindow(hWnd);
+int wmain(int argc, WCHAR *argv[])
+{
+    LPCWSTR token = NULL;
+    HINSTANCE hInst = GetModuleHandle(0);
+    static const WCHAR listW[] = { '-','-','l','i','s','t',0 };
+    static const WCHAR removeW[] = { '-','-','r','e','m','o','v','e',0 };
+    int i = 1;
+
+    while( i<argc )
+    {
+        token = argv[i++];
+        
+        /* Handle requests just to list the applications */
+        if(!lstrcmp( token, listW ) )
+        {
+            ListUninstallPrograms();
+            return 0;
+        }
+        else if( !lstrcmp( token, removeW ) )
+        {
+            if( i >= argc )
+            {
+                WINE_ERR( "The remove option requires a parameter.\n");
+                return 1;
+            }
 
+            RemoveSpecificProgram( argv[i++] );
+            return 0;
+        }
+        else 
+        {
+            WINE_ERR( "unknown option %s\n",token);
+            return 1;
         }
-	else
-	if ((HWND)lParam == button[1].hwnd) /* About button */
-	    MessageBox(0, about_string, "About Wine Application Uninstaller", MB_OK);
-	else
-	if ((HWND)lParam == button[2].hwnd) /* Exit button */
-	    PostQuitMessage(0);
-	return 0;
     }
 
-    return( DefWindowProc( hWnd, msg, wParam, lParam ));
+    /* Load MessageBox's strings */
+    LoadString(hInst, IDS_APPNAME, sAppName, sizeof(sAppName));
+    LoadString(hInst, IDS_ABOUTTITLE, sAboutTitle, sizeof(sAboutTitle));
+    LoadString(hInst, IDS_ABOUT, sAbout, sizeof(sAbout));
+    LoadString(hInst, IDS_REGISTRYKEYNOTAVAILABLE, sRegistryKeyNotAvailable, sizeof(sRegistryKeyNotAvailable));
+    LoadString(hInst, IDS_UNINSTALLFAILED, sUninstallFailed, sizeof(sUninstallFailed));
+
+    return DialogBox(hInst, MAKEINTRESOURCE(IDD_UNINSTALLER), NULL, DlgProc);
+}
+
+
+/**
+ * Used to sort entries by name.
+ */
+static int cmp_by_name(const void *a, const void *b)
+{
+    return lstrcmpiW(((const uninst_entry *)a)->descr, ((const uninst_entry *)b)->descr);
+}
+
+
+/**
+ * Case insensitive substring search.
+ * 
+ * Public domain code found here: http://fux0r.phathookups.com/programming-tutorials/C/C-snippits/stristr.c
+ *
+ */
+static WCHAR *stristr(const WCHAR *String, const WCHAR *Pattern)
+{
+    const WCHAR *pptr, *sptr, *start;
+    uint  slen, plen;
+
+    for (start = (WCHAR *)String,
+         pptr  = (WCHAR *)Pattern,
+         slen  = strlen(String),
+         plen  = strlen(Pattern);
+         /* while string length not shorter than pattern length */
+         slen >= plen;
+         start++, slen--)
+    {
+        /* find start of pattern in string */
+        while (toupper(*start) != toupper(*Pattern))
+        {
+            start++;
+            slen--;
+
+            /* if pattern longer than string */
+            if (slen < plen)
+                return(NULL);
+        }
+
+        sptr = start;
+        pptr = (WCHAR *)Pattern;
+
+        while (toupper(*sptr) == toupper(*pptr))
+        {
+            sptr++;
+            pptr++;
+
+            /* if end of pattern then pattern was found */
+            if ('\0' == *pptr)
+                return (start);
+        }
+    }
+    return(NULL);
 }
Index: rsrc.rc
===================================================================
RCS file: /home/wine/wine/programs/uninstaller/rsrc.rc,v
retrieving revision 1.12
diff -u -r1.12 rsrc.rc
--- rsrc.rc	18 Oct 2004 19:42:43 -0000	1.12
+++ rsrc.rc	8 Mar 2005 09:07:51 -0000
@@ -1,141 +1,18 @@
-/*
- * Uninstaller (rsrc.rc)
- *
- * Copyright 2000 Andreas Mohr <andi@lisas.de>
- * Copyright 2003 Vincent B�ron
- * Copyright 2003 Ivan Leo Puoti
- * Copyright 2004 David Kredba
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
 #include <windows.h>
-#include "main.h"
-
-/* BINRES uninstaller.ico */
-UNINSTALLER ICON MOVEABLE uninstaller.ico
-/* {
- '00 00 01 00 01 00 20 20 10 00 00 00 00 00 E8 02'
- '00 00 16 00 00 00 28 00 00 00 20 00 00 00 40 00'
- '00 00 01 00 04 00 00 00 00 00 00 02 00 00 00 00'
- '00 00 00 00 00 00 10 00 00 00 00 00 00 00 FF 19'
- '00 00 00 00 00 00 7F 7F 7F 00 FF FF FF 00 00 00'
- 'FF 00 D6 D6 D6 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
- '00 00 00 00 00 00 00 00 00 00 00 00 00 00 44 11'
- '11 11 11 11 11 11 11 11 11 11 11 11 11 44 44 41'
- '11 11 11 11 11 11 11 11 11 11 11 11 14 44 44 44'
- '00 00 00 00 00 00 00 00 00 00 00 00 44 41 14 44'
- '40 00 00 00 00 00 00 00 00 00 00 04 44 11 11 14'
- '44 00 00 00 00 00 00 00 00 00 00 44 41 11 11 10'
- '44 43 33 33 33 33 33 33 33 33 34 44 01 11 11 10'
- '04 44 33 33 33 33 33 33 33 33 44 40 01 11 11 10'
- '00 44 42 22 22 33 32 22 22 24 44 00 01 11 11 10'
- '00 34 44 33 33 33 33 33 33 44 43 00 01 11 11 10'
- '00 32 44 42 22 22 22 22 24 44 33 00 01 11 11 10'
- '00 33 34 44 33 33 33 33 44 43 33 00 01 11 11 10'
- '00 32 22 44 42 23 32 24 44 23 33 00 01 11 11 10'
- '00 33 33 34 44 33 33 44 43 33 33 00 01 11 11 10'
- '00 32 22 22 44 43 24 44 22 23 33 00 01 11 11 10'
- '00 33 33 33 34 44 44 43 33 33 33 00 01 11 11 10'
- '00 32 22 22 22 44 44 33 33 33 33 00 01 11 11 10'
- '00 33 33 33 33 44 44 33 33 33 33 00 01 11 11 10'
- '00 00 00 00 04 44 44 40 00 00 00 00 01 11 11 10'
- '00 00 00 00 44 40 04 44 00 00 00 00 01 11 11 10'
- '00 00 00 04 44 00 00 44 40 00 00 00 01 11 11 10'
- '00 00 05 44 45 55 55 54 44 00 00 00 01 11 11 10'
- '00 00 04 44 55 55 55 00 44 40 00 00 01 11 11 10'
- '00 00 44 45 55 55 55 00 04 44 00 00 01 11 11 10'
- '00 04 44 55 55 55 55 00 05 44 40 00 01 11 11 10'
- '00 44 45 55 55 55 55 00 05 54 44 00 01 11 11 10'
- '04 44 05 55 55 55 55 00 05 50 44 40 11 11 11 10'
- '44 40 05 55 55 55 55 00 05 50 04 44 41 11 11 14'
- '44 00 05 55 55 55 55 00 05 50 00 44 44 41 14 44'
- '40 00 05 55 55 55 55 55 55 50 01 14 44 44 14 44'
- '11 11 11 11 11 11 11 11 11 11 11 11 44 44 44 41'
- '11 11 11 11 11 11 11 11 11 11 11 11 14 44 44 11'
- '11 11 11 11 11 11 11 11 11 11 11 11 11 44 3F FF'
- 'FF FC 00 00 00 00 80 00 00 01 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 03 C0 00 00 03 C0 00'
- '00 03 C0 00 00 03 C0 00 00 0F C0 00 00 07 C0 00'
- '00 03 80 00 00 31 1F FF FF F8 3F FF FF FC'
-} */
-
-/* Czech Resources */
-LANGUAGE LANG_CZECH, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "Deinstal�tor"
-
-     }
-/* End of Czech Resources */
-
-/* English-US Resources */
-LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "Uninstaller"
-
-}
-/* End of English-US Resources */
-
-/* French Resources */
-LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "D�sinstalleur"
+#include "resource.h"
+#include "Cz.rc"
+#include "En.rc"
+#include "Fr.rc"
+#include "De.rc"
+#include "It.rc"
+#include "Pt.rc"
+#include "Sp.rc"
 
-}
-/* End of French Resources */
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
 
-/* German Resources */
-LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "Uninstaller"
-
-}
-/* End of German Resources */
-
-/* Italian Resources */
-LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "Disinstallatore"
-
-}
-/* End of Italian Resources */
-
-/* Portuguese Resources */
-LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "Desinstalador"
-
-}
-/* End of Portuguese Resources */
-
-/* Spanish Resources */
-LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
-
-STRINGTABLE {
-     IDS_APPNAME, "Desinstalador"
+/*
+ Icon
+*/
 
-}
-/* End of Spanish Resources */
+/* BINRES uninstaller.ico */
+IDI_TASKMANAGER         ICON    DISCARDABLE uninstaller.ico
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ resource.h	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,13 @@
+#define IDD_UNINSTALLER                 101
+#define IDC_FILTER                      1001
+#define IDC_LIST                        1002
+#define IDC_UNINSTALL                   1003
+#define IDC_ABOUT                       1004
+#define IDC_EXIT                        1005
+#define IDC_PLEASESELECT                1006
+#define IDS_APPNAME                     1007
+#define IDS_ABOUT                       1008
+#define IDS_ABOUTTITLE                  1009
+#define IDS_REGISTRYKEYNOTAVAILABLE     1010
+#define IDS_UNINSTALLFAILED             1011
+#define MAX_STRING_LEN                  255     
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ En.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * Uninstaller (English Resources)
+ *
+ * Copyright 2005 Jonathan Ernst <Jonathan@ErnstFamily.ch>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+IDD_UNINSTALLER DIALOG DISCARDABLE  0, 0, 330, 160
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "Wine Application Uninstaller"
+FONT 10, "MS Sans Serif"
+BEGIN
+    LTEXT           "Please select the application you wish to uninstall:",IDC_PLEASESELECT,10,10,250,14
+    EDITTEXT        IDC_FILTER,10,25,250,14,ES_AUTOHSCROLL
+    LISTBOX         IDC_LIST,10,43,250,106,LBS_NOINTEGRALHEIGHT | 
+                    LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "&Uninstall",IDC_UNINSTALL,270,48,50,14
+    PUSHBUTTON      "&About",IDC_ABOUT,270,65,50,14
+    PUSHBUTTON      "&Exit",IDC_EXIT,270,81,50,14
+END
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "Wine Application Unsinstaller"
+     IDS_ABOUT, "Wine Application Uninstaller (C) 2005 by Andreas Mohr <andi@lisas.de>, Hannu Valtonen <Hannu.Valtonen@hut.fi> and Jonathan Ernst <Jonathan@ErnstFamily.ch>"
+     IDS_ABOUTTITLE, "About Unsinstaller"
+     IDS_REGISTRYKEYNOTAVAILABLE, "Uninstall registry key not available (yet), nothing to do !"
+     IDS_UNINSTALLFAILED, "Execution of uninstall command '%s' failed, perhaps due to missing executable.\n\rDo you want to remove the uninstall entry from the registry ?"
+}
+
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ Fr.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,46 @@
+/*
+ * Uninstaller (French Resources)
+ *
+ * Copyright 2005 Jonathan Ernst <Jonathan@ErnstFamily.ch>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+IDD_UNINSTALLER DIALOG DISCARDABLE  0, 0, 330, 160
+STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "Wine Application Uninstaller"
+FONT 10, "MS Sans Serif"
+BEGIN
+    LTEXT           "Veuillez s�lectionner l'application  d�sinstaller:",IDC_PLEASESELECT,10,10,250,14
+    EDITTEXT        IDC_FILTER,10,25,250,14,ES_AUTOHSCROLL
+    LISTBOX         IDC_LIST,10,43,250,106,LBS_NOINTEGRALHEIGHT | 
+                    LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
+    PUSHBUTTON      "&Supprimer",IDC_UNINSTALL,270,48,50,14
+    PUSHBUTTON      "&A propos",IDC_ABOUT,270,65,50,14
+    PUSHBUTTON      "&Quitter",IDC_EXIT,270,81,50,14
+END
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "D�sinstalleur d'applications de Wine"
+     IDS_ABOUT, "D�sinstalleur d'applications de Wine (C) 2005 par Andreas Mohr <andi@lisas.de>, Hannu Valtonen <Hannu.Valtonen@hut.fi> et Jonathan Ernst <Jonathan@ErnstFamily.ch>"
+     IDS_ABOUTTITLE, "A propos du d�sinstalleur"
+     IDS_REGISTRYKEYNOTAVAILABLE, "Cl� de dsinstallation non disponible dans la base de registre (actuellement). Il n'y a rien  faire !"
+     IDS_UNINSTALLFAILED, "Erreur lors de l'excution de la commande de d�sinstallation '%s'. L'ex�cutable ne peut peut �tre pas �tre trouv�.\n\rSouhaitez-vous supprimmer l'entr�e de la base de registre ?"
+}
+
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ De.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * Uninstaller (German Resources)
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "Uninstaller"
+}
+
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ Cz.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * Uninstaller (Czech Resources)
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_CZECH, SUBLANG_NEUTRAL
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "Deinstaltor"
+}
+
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ It.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * Uninstaller (Italian Resources)
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "Disinstallatore"
+}
+
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ Pt.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * Uninstaller (Portuguese Resources)
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "Desinstalador"
+}
+
--- /dev/null	2005-03-08 09:38:59.765800256 +0100
+++ Sp.rc	2005-03-06 18:44:07.000000000 +0100
@@ -0,0 +1,27 @@
+/*
+ * Uninstaller (Spanish Resources)
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+
+
+STRINGTABLE DISCARDABLE {
+     IDS_APPNAME, "Desinstalador"
+}
+
