Index: trunk/src/helpers/apps.c
===================================================================
--- trunk/src/helpers/apps.c	(revision 211)
+++ trunk/src/helpers/apps.c	(revision 212)
@@ -801,4 +801,5 @@
  *
  *@@added V0.9.20 (2002-07-03) [umoeller]
+ *@@changed V0.9.21 (2002-08-21) [umoeller]: now allowing for UNC
  */
 
@@ -811,6 +812,11 @@
     // check if the executable is fully qualified; if so,
     // check if the executable file exists
-    if (    (pDetails->pszExecutable[1] == ':')
-         && (strchr(pDetails->pszExecutable, '\\'))
+    if (    // allow UNC V0.9.21 (2002-08-21) [umoeller]
+            (    (pDetails->pszExecutable[0] == '\\')
+              && (pDetails->pszExecutable[1] == '\\')
+            )
+         || (    (pDetails->pszExecutable[1] == ':')
+              && (strchr(pDetails->pszExecutable, '\\'))
+            )
        )
     {
@@ -1180,9 +1186,15 @@
 
     PROGDETAILS     Details;
+    ULONG           ulIsWinApp;
+
+    // parameter checking extended V0.9.21 (2002-08-21) [umoeller]
+    if (    (!pcProgDetails)
+         || (!pcProgDetails->pszExecutable)
+         || (!pcProgDetails->pszExecutable[0])
+         || (!ppDetails)
+       )
+        return ERROR_INVALID_PARAMETER;
 
     *ppDetails = NULL;
-
-    if (!pcProgDetails && !ppDetails)
-        return ERROR_INVALID_PARAMETER;
 
     /*
@@ -1199,154 +1211,144 @@
     Details.progt.fbVisible = SHE_VISIBLE;
 
-    // all this only makes sense if this contains something...
-    // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller]
-    if (    (!Details.pszExecutable)
-         || (!Details.pszExecutable[0])
+    // memset(&Details.swpInitial, 0, sizeof(SWP));
+    // this wasn't a good idea... WPProgram stores stuff
+    // in here, such as the "minimize on startup" -> SWP_MINIMIZE
+
+    // duplicate parameters...
+    // we need this for string manipulations below...
+    if (    (Details.pszParameters)
+         && (Details.pszParameters[0])    // V0.9.18
        )
-        arc = ERROR_INVALID_PARAMETER;
-    else
-    {
-        ULONG           ulIsWinApp;
-
-        // memset(&Details.swpInitial, 0, sizeof(SWP));
-        // this wasn't a good idea... WPProgram stores stuff
-        // in here, such as the "minimize on startup" -> SWP_MINIMIZE
-
-        // duplicate parameters...
-        // we need this for string manipulations below...
-        if (    (Details.pszParameters)
-             && (Details.pszParameters[0])    // V0.9.18
-           )
-            xstrcpy(&strParamsPatched,
-                    Details.pszParameters,
-                    0);
-
-        #ifdef DEBUG_PROGRAMSTART
-            _PmpfF((" old progc: 0x%lX", pcProgDetails->progt.progc));
-            _Pmpf(("  pszTitle: %s", STRINGORNULL(Details.pszTitle)));
-            _Pmpf(("  pszExecutable: %s", STRINGORNULL(Details.pszExecutable)));
-            _Pmpf(("  pszParameters: %s", STRINGORNULL(Details.pszParameters)));
-            _Pmpf(("  pszIcon: %s", STRINGORNULL(Details.pszIcon)));
-        #endif
-
-        // program type fixups
-        switch (Details.progt.progc)        // that's a ULONG
-        {
-            case ((ULONG)-1):       // we get that sometimes...
-            case PROG_DEFAULT:
-            {
-                // V0.9.12 (2001-05-26) [umoeller]
-                ULONG ulDosAppType;
-                appQueryAppType(Details.pszExecutable,
-                                &ulDosAppType,
-                                &Details.progt.progc);
-            }
-            break;
-        }
-
-        // set session type from option flags
+        xstrcpy(&strParamsPatched,
+                Details.pszParameters,
+                0);
+
+    #ifdef DEBUG_PROGRAMSTART
+        _PmpfF((" old progc: 0x%lX", pcProgDetails->progt.progc));
+        _Pmpf(("  pszTitle: %s", STRINGORNULL(Details.pszTitle)));
+        _Pmpf(("  pszExecutable: %s", STRINGORNULL(Details.pszExecutable)));
+        _Pmpf(("  pszParameters: %s", STRINGORNULL(Details.pszParameters)));
+        _Pmpf(("  pszIcon: %s", STRINGORNULL(Details.pszIcon)));
+    #endif
+
+    // program type fixups
+    switch (Details.progt.progc)        // that's a ULONG
+    {
+        case ((ULONG)-1):       // we get that sometimes...
+        case PROG_DEFAULT:
+        {
+            // V0.9.12 (2001-05-26) [umoeller]
+            ULONG ulDosAppType;
+            appQueryAppType(Details.pszExecutable,
+                            &ulDosAppType,
+                            &Details.progt.progc);
+        }
+        break;
+    }
+
+    // set session type from option flags
+    if (ulFlags & APP_RUN_FULLSCREEN)
+    {
+        if (Details.progt.progc == PROG_WINDOWABLEVIO)
+            Details.progt.progc = PROG_FULLSCREEN;
+        else if (Details.progt.progc == PROG_WINDOWEDVDM)
+            Details.progt.progc = PROG_VDM;
+    }
+
+    if (ulIsWinApp = appIsWindowsApp(Details.progt.progc))
+    {
         if (ulFlags & APP_RUN_FULLSCREEN)
-        {
-            if (Details.progt.progc == PROG_WINDOWABLEVIO)
-                Details.progt.progc = PROG_FULLSCREEN;
-            else if (Details.progt.progc == PROG_WINDOWEDVDM)
-                Details.progt.progc = PROG_VDM;
-        }
-
-        if (ulIsWinApp = appIsWindowsApp(Details.progt.progc))
-        {
-            if (ulFlags & APP_RUN_FULLSCREEN)
-                Details.progt.progc = (ulFlags & APP_RUN_ENHANCED)
-                                                ? PROG_31_ENH
-                                                : PROG_31_STD;
-            else
-            {
-                if (ulFlags & APP_RUN_STANDARD)
-                    Details.progt.progc = (ulFlags & APP_RUN_SEPARATE)
-                                                ? PROG_31_STDSEAMLESSVDM
-                                                : PROG_31_STDSEAMLESSCOMMON;
-                else if (ulFlags & APP_RUN_ENHANCED)
-                    Details.progt.progc = (ulFlags & APP_RUN_SEPARATE)
-                                                ? PROG_31_ENHSEAMLESSVDM
-                                                : PROG_31_ENHSEAMLESSCOMMON;
-            }
-
-            // re-run V0.9.16 (2001-10-19) [umoeller]
-            ulIsWinApp = appIsWindowsApp(Details.progt.progc);
-        }
-
+            Details.progt.progc = (ulFlags & APP_RUN_ENHANCED)
+                                            ? PROG_31_ENH
+                                            : PROG_31_STD;
+        else
+        {
+            if (ulFlags & APP_RUN_STANDARD)
+                Details.progt.progc = (ulFlags & APP_RUN_SEPARATE)
+                                            ? PROG_31_STDSEAMLESSVDM
+                                            : PROG_31_STDSEAMLESSCOMMON;
+            else if (ulFlags & APP_RUN_ENHANCED)
+                Details.progt.progc = (ulFlags & APP_RUN_SEPARATE)
+                                            ? PROG_31_ENHSEAMLESSVDM
+                                            : PROG_31_ENHSEAMLESSCOMMON;
+        }
+
+        // re-run V0.9.16 (2001-10-19) [umoeller]
+        ulIsWinApp = appIsWindowsApp(Details.progt.progc);
+    }
+
+    /*
+     * command lines fixups:
+     *
+     */
+
+    if (!strcmp(Details.pszExecutable, "*"))
+    {
         /*
-         * command lines fixups:
+         * "*" for command sessions:
          *
          */
 
-        if (!strcmp(Details.pszExecutable, "*"))
-        {
-            /*
-             * "*" for command sessions:
-             *
-             */
-
-            if (ulIsWinApp)
+        if (ulIsWinApp)
+        {
+            // cheat: WinStartApp doesn't support NULL
+            // for Win-OS2 sessions, so manually start winos2.com
+            Details.pszExecutable = "WINOS2.COM";
+            // this is a DOS app, so fix this to DOS fullscreen
+            Details.progt.progc = PROG_VDM;
+
+            if (ulIsWinApp == 2)
             {
-                // cheat: WinStartApp doesn't support NULL
-                // for Win-OS2 sessions, so manually start winos2.com
-                Details.pszExecutable = "WINOS2.COM";
-                // this is a DOS app, so fix this to DOS fullscreen
-                Details.progt.progc = PROG_VDM;
-
-                if (ulIsWinApp == 2)
+                // enhanced Win-OS/2 session:
+                PSZ psz = NULL;
+                if (strParamsPatched.ulLength)
+                    // "/3 " + existing params
+                    psz = strdup(strParamsPatched.psz);
+
+                xstrcpy(&strParamsPatched, "/3 ", 0);
+
+                if (psz)
                 {
-                    // enhanced Win-OS/2 session:
-                    PSZ psz = NULL;
-                    if (strParamsPatched.ulLength)
-                        // "/3 " + existing params
-                        psz = strdup(strParamsPatched.psz);
-
-                    xstrcpy(&strParamsPatched, "/3 ", 0);
-
-                    if (psz)
-                    {
-                        xstrcat(&strParamsPatched, psz, 0);
-                        free(psz);
-                    }
+                    xstrcat(&strParamsPatched, psz, 0);
+                    free(psz);
                 }
             }
-            else
-                // for all other executable types
-                // (including OS/2 and DOS sessions),
-                // set pszExecutable to NULL; this will
-                // have WinStartApp start a cmd shell
-                Details.pszExecutable = NULL;
-
-        } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0)
-
-        // else
-
-        // no, this else breaks the WINOS2.COM hack above... we
-        // need to look for that on the PATH as well
-        // V0.9.20 (2002-07-03) [umoeller]
-        if (Details.pszExecutable)
-        {
-            // check the executable and look for it on the
-            // PATH if necessary
-            if (!(arc = CheckAndQualifyExecutable(&Details,
-                                                  &strExecutablePatched)))
+        }
+        else
+            // for all other executable types
+            // (including OS/2 and DOS sessions),
+            // set pszExecutable to NULL; this will
+            // have WinStartApp start a cmd shell
+            Details.pszExecutable = NULL;
+
+    } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0)
+
+    // else
+
+    // no, this else breaks the WINOS2.COM hack above... we
+    // need to look for that on the PATH as well
+    // V0.9.20 (2002-07-03) [umoeller]
+    if (Details.pszExecutable)
+    {
+        // check the executable and look for it on the
+        // PATH if necessary
+        if (!(arc = CheckAndQualifyExecutable(&Details,
+                                              &strExecutablePatched)))
+        {
+            PSZ pszExtension;
+
+            // make sure startup dir is really a directory
+            // V0.9.20 (2002-07-03) [umoeller]: moved this down
+            if (Details.pszStartupDir)
             {
-                PSZ pszExtension;
-
-                // make sure startup dir is really a directory
-                // V0.9.20 (2002-07-03) [umoeller]: moved this down
-                if (Details.pszStartupDir)
-                {
-                    ULONG ulAttr;
-                    // it is valid to specify a startup dir of "C:"
-                    if (    (strlen(Details.pszStartupDir) > 2)
-                         && (!(arc = doshQueryPathAttr(Details.pszStartupDir,
-                                                       &ulAttr)))
-                         && (!(ulAttr & FILE_DIRECTORY))
-                       )
-                        arc = ERROR_PATH_NOT_FOUND;
-                }
+                ULONG ulAttr;
+                // it is valid to specify a startup dir of "C:"
+                if (    (strlen(Details.pszStartupDir) > 2)
+                     && (!(arc = doshQueryPathAttr(Details.pszStartupDir,
+                                                   &ulAttr)))
+                     && (!(ulAttr & FILE_DIRECTORY))
+                   )
+                    arc = ERROR_PATH_NOT_FOUND;
+            }
 
 // V0.9.21: this define is never set. I have thus completely
@@ -1361,56 +1363,95 @@
 #ifdef ENABLEBATCHHACKS
 
-                // we frequently get here for BAT and CMD files
-                // with progtype == PROG_DEFAULT, so include
-                // that in the check, or all BAT files will fail
-                // V0.9.20 (2002-07-03) [umoeller]
-
-                switch (Details.progt.progc)
+            // we frequently get here for BAT and CMD files
+            // with progtype == PROG_DEFAULT, so include
+            // that in the check, or all BAT files will fail
+            // V0.9.20 (2002-07-03) [umoeller]
+
+            switch (Details.progt.progc)
+            {
+                /*
+                 *  .CMD files fixups
+                 *
+                 */
+
+                case PROG_DEFAULT:          // V0.9.20 (2002-07-03) [umoeller]
+                case PROG_FULLSCREEN:       // OS/2 fullscreen
+                case PROG_WINDOWABLEVIO:    // OS/2 window
                 {
-                    /*
-                     *  .CMD files fixups
-                     *
-                     */
-
-                    case PROG_DEFAULT:          // V0.9.20 (2002-07-03) [umoeller]
-                    case PROG_FULLSCREEN:       // OS/2 fullscreen
-                    case PROG_WINDOWABLEVIO:    // OS/2 window
+                    if (    (pszExtension = doshGetExtension(Details.pszExecutable))
+                         && (!stricmp(pszExtension, "CMD"))
+                       )
                     {
-                        if (    (pszExtension = doshGetExtension(Details.pszExecutable))
-                             && (!stricmp(pszExtension, "CMD"))
-                           )
-                        {
-                            arc = CallBatchCorrectly(&Details,
-                                                     &strExecutablePatched,
-                                                     &strParamsPatched,
-                                                     "OS2_SHELL",
-                                                     "CMD.EXE");
-                        }
+                        arc = CallBatchCorrectly(&Details,
+                                                 &strExecutablePatched,
+                                                 &strParamsPatched,
+                                                 "OS2_SHELL",
+                                                 "CMD.EXE");
                     }
-                    break;
                 }
-
-                switch (Details.progt.progc)
+                break;
+            }
+
+            switch (Details.progt.progc)
+            {
+                case PROG_DEFAULT:          // V0.9.20 (2002-07-03) [umoeller]
+                case PROG_VDM:              // DOS fullscreen
+                case PROG_WINDOWEDVDM:      // DOS window
                 {
-                    case PROG_DEFAULT:          // V0.9.20 (2002-07-03) [umoeller]
-                    case PROG_VDM:              // DOS fullscreen
-                    case PROG_WINDOWEDVDM:      // DOS window
+                    if (    (pszExtension = doshGetExtension(Details.pszExecutable))
+                         && (!stricmp(pszExtension, "BAT"))
+                       )
                     {
-                        if (    (pszExtension = doshGetExtension(Details.pszExecutable))
-                             && (!stricmp(pszExtension, "BAT"))
-                           )
-                        {
-                            arc = CallBatchCorrectly(&Details,
-                                                     &strExecutablePatched,
-                                                     &strParamsPatched,
-                                                     // there is no environment variable
-                                                     // for the DOS shell
-                                                     NULL,
-                                                     "COMMAND.COM");
-                        }
+                        arc = CallBatchCorrectly(&Details,
+                                                 &strExecutablePatched,
+                                                 &strParamsPatched,
+                                                 // there is no environment variable
+                                                 // for the DOS shell
+                                                 NULL,
+                                                 "COMMAND.COM");
                     }
-                    break;
-                } // end switch (Details.progt.progc)
+                }
+                break;
+            } // end switch (Details.progt.progc)
 #endif // ENABLEBATCHHACKS
+        }
+    }
+
+    if (!arc)
+    {
+        if (    (ulIsWinApp)
+             && (    (!(Details.pszEnvironment))
+                  || (!(*Details.pszEnvironment))
+                )
+           )
+        {
+            // this is a windoze app, and caller didn't bother
+            // to give us an environment:
+            // we MUST set one then, or we'll get the strangest
+            // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller]
+
+            DOSENVIRONMENT Env = {0};
+
+            // get standard WIN-OS/2 environment
+            PSZ pszTemp;
+            if (!(arc = appQueryDefaultWin31Environment(&pszTemp)))
+            {
+                if (!(arc = appParseEnvironment(pszTemp,
+                                                &Env)))
+                {
+                    // now override KBD_CTRL_BYPASS=CTRL_ESC
+                    if (    (!(arc = appSetEnvironmentVar(&Env,
+                                                          "KBD_CTRL_BYPASS=CTRL_ESC",
+                                                          FALSE)))        // add last
+                         && (!(arc = appConvertEnvironment(&Env,
+                                                           &pszWinOS2Env,   // freed at bottom
+                                                           NULL)))
+                       )
+                        Details.pszEnvironment = pszWinOS2Env;
+
+                    appFreeEnvironment(&Env);
+                }
+
+                free(pszTemp);
             }
         }
@@ -1418,76 +1459,36 @@
         if (!arc)
         {
-            if (    (ulIsWinApp)
-                 && (    (!(Details.pszEnvironment))
-                      || (!(*Details.pszEnvironment))
-                    )
-               )
+            // if no title is given, use the executable
+            if (!Details.pszTitle)
+                Details.pszTitle = Details.pszExecutable;
+
+            // make sure params have a leading space
+            // V0.9.18 (2002-03-27) [umoeller]
+            if (strParamsPatched.ulLength)
             {
-                // this is a windoze app, and caller didn't bother
-                // to give us an environment:
-                // we MUST set one then, or we'll get the strangest
-                // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller]
-
-                DOSENVIRONMENT Env = {0};
-
-                // get standard WIN-OS/2 environment
-                PSZ pszTemp;
-                if (!(arc = appQueryDefaultWin31Environment(&pszTemp)))
+                if (strParamsPatched.psz[0] != ' ')
                 {
-                    if (!(arc = appParseEnvironment(pszTemp,
-                                                    &Env)))
-                    {
-                        // now override KBD_CTRL_BYPASS=CTRL_ESC
-                        if (    (!(arc = appSetEnvironmentVar(&Env,
-                                                              "KBD_CTRL_BYPASS=CTRL_ESC",
-                                                              FALSE)))        // add last
-                             && (!(arc = appConvertEnvironment(&Env,
-                                                               &pszWinOS2Env,   // freed at bottom
-                                                               NULL)))
-                           )
-                            Details.pszEnvironment = pszWinOS2Env;
-
-                        appFreeEnvironment(&Env);
-                    }
-
-                    free(pszTemp);
+                    XSTRING str2;
+                    xstrInit(&str2, 0);
+                    xstrcpy(&str2, " ", 1);
+                    xstrcats(&str2, &strParamsPatched);
+                    xstrcpys(&strParamsPatched, &str2);
+                    xstrClear(&str2);
+                            // we really need xstrInsert or something
                 }
+                Details.pszParameters = strParamsPatched.psz;
             }
-
-            if (!arc)
-            {
-                // if no title is given, use the executable
-                if (!Details.pszTitle)
-                    Details.pszTitle = Details.pszExecutable;
-
-                // make sure params have a leading space
-                // V0.9.18 (2002-03-27) [umoeller]
-                if (strParamsPatched.ulLength)
-                {
-                    if (strParamsPatched.psz[0] != ' ')
-                    {
-                        XSTRING str2;
-                        xstrInit(&str2, 0);
-                        xstrcpy(&str2, " ", 1);
-                        xstrcats(&str2, &strParamsPatched);
-                        xstrcpys(&strParamsPatched, &str2);
-                        xstrClear(&str2);
-                                // we really need xstrInsert or something
-                    }
-                    Details.pszParameters = strParamsPatched.psz;
-                }
-                else
-                    // never pass null pointers
-                    Details.pszParameters = "";
-
+            else
                 // never pass null pointers
-                if (!Details.pszIcon)
-                    Details.pszIcon = "";
-
-                // never pass null pointers
-                if (!Details.pszStartupDir)
-                    Details.pszStartupDir = "";
-
-            }
+                Details.pszParameters = "";
+
+            // never pass null pointers
+            if (!Details.pszIcon)
+                Details.pszIcon = "";
+
+            // never pass null pointers
+            if (!Details.pszStartupDir)
+                Details.pszStartupDir = "";
+
         }
     }
@@ -2074,5 +2075,5 @@
     CHAR           szDir[CCHMAXPATH] = "";
     PCSZ           p;
-    HWND           hwndObject;
+    HWND           hwndObject = NULLHANDLE;
 
     pd.Length = sizeof(pd);
@@ -2092,5 +2093,9 @@
     }
 
-    if (    (hwndObject = winhCreateObjectWindow(WC_STATIC, NULL))
+    if (pulExitCode)
+        if (!(hwndObject = winhCreateObjectWindow(WC_STATIC, NULL)))
+            arc = ERROR_NOT_ENOUGH_MEMORY;
+
+    if (    (!arc)
          && (!(arc = appStartApp(hwndObject,
                                  &pd,
@@ -2105,7 +2110,8 @@
                           *phapp,
                           pulExitCode);
-
+    }
+
+    if (hwndObject)
         WinDestroyWindow(hwndObject);       // was missing V0.9.20 (2002-08-10) [umoeller]
-    }
 
     return arc;
@@ -2121,15 +2127,21 @@
  *
  *@@added V0.9.20 (2002-08-10) [umoeller]
+ *@@changed V0.9.21 (2002-08-21) [umoeller]: changed prototype to return browser
  */
 
 APIRET appOpenURL(PCSZ pcszURL,           // in: URL to open
-                  PSZ pszAppStarted,      // out: application that was started
+                  PSZ pszAppStarted,      // out: application that was started (req.)
                   ULONG cbAppStarted)     // in: size of that buffer
 {
-    APIRET      arc = NO_ERROR;
-
-    CHAR        szBrowser[CCHMAXPATH],
-                szStartupDir[CCHMAXPATH];
+    APIRET      arc = ERROR_NO_DATA;
+
+    CHAR        szStartupDir[CCHMAXPATH];
     XSTRING     strParameters;
+
+    if (    (!pcszURL)
+         || (!pszAppStarted)
+         || (!cbAppStarted)
+       )
+        return ERROR_INVALID_PARAMETER;
 
     xstrInit(&strParameters, 0);
@@ -2139,6 +2151,6 @@
                               "DefaultBrowserExe",
                               "NETSCAPE.EXE",
-                              szBrowser,
-                              sizeof(szBrowser)))
+                              pszAppStarted,
+                              cbAppStarted))
     {
         PSZ     pszDefParams;
@@ -2164,6 +2176,5 @@
                               sizeof(szStartupDir));
 
-
-        arc = appQuickStartApp(szBrowser,
+        arc = appQuickStartApp(pszAppStarted,
                                PROG_DEFAULT,
                                strParameters.psz,
@@ -2171,9 +2182,4 @@
                                &happ,
                                NULL);     // don't wait
-
-        if (pszAppStarted)
-            strhncpy0(pszAppStarted,
-                      szBrowser,
-                      cbAppStarted);
     }
 
Index: trunk/src/helpers/debug.c
===================================================================
--- trunk/src/helpers/debug.c	(revision 211)
+++ trunk/src/helpers/debug.c	(revision 212)
@@ -1,3 +1,2 @@
-
 /*
  *@@sourcefile debug.c:
@@ -44,4 +43,6 @@
  *      GNU General Public License for more details.
  */
+
+//#define DEBUG_SYMDUMP // enable to dump sym file to log V0.9.21 (2002-08-21) [paperino]
 
 #define OS2EMX_PLAIN_CHAR
@@ -1536,4 +1537,7 @@
 
     // open .SYM file
+#ifdef DEBUG_SYMDUMP    // V0.9.21 (2002-08-21) [paperino]
+    fprintf(LogFile,"Dump of '%s' for object %d\n",SymFileName,Object);
+#endif
     SymFile = fopen(SymFileName, "rb");
     if (SymFile == 0)
@@ -1542,6 +1546,15 @@
     // read in first map definition
     fread(&MapDef, sizeof(MAPDEF), 1, SymFile);
+#ifdef DEBUG_SYMDUMP
+    Buffer[0] = MapDef.achModName[0];
+    fread(&Buffer[1], 1, MapDef.cbModName-1, SymFile);
+    Buffer[MapDef.cbModName] = 0x00;
+    fprintf(LogFile,"Module name '%s'\n",Buffer);
+#endif
 
     SegOffset = SEGDEFOFFSET(MapDef);
+#ifdef DEBUG_SYMDUMP
+    fprintf(LogFile,"SegOffset %0x\n",SegOffset);
+#endif
 
     // go thru all segments
@@ -1550,5 +1563,7 @@
          SegNum++)
     {
-        // printf("Scanning segment #%d Offset %4.4hX\n",SegNum+1,SegOffset);
+#ifdef DEBUG_SYMDUMP
+        fprintf(LogFile,"Scanning segment #%d Offset %08X\n",SegNum,SegOffset);
+#endif
         if (fseek(SymFile, SegOffset, SEEK_SET))
             // seek error
@@ -1557,4 +1572,11 @@
         // read in segment definition
         fread(&SegDef, sizeof(SEGDEF), 1, SymFile);
+        Buffer[0] = SegDef.achSegName[0];
+        fread(&Buffer[1], 1, SegDef.cbSegName-1, SymFile);
+        Buffer[SegDef.cbSegName] = 0x00;
+#ifdef DEBUG_SYMDUMP
+        fprintf(LogFile,"Segment name '%s', number %d, flags %02x\n",Buffer,SegNum,SegDef.bFlags);
+#endif
+
         if (SegNum == Object)
         {
@@ -1564,15 +1586,10 @@
 
             // go thru all symbols in this object
+#ifdef DEBUG_SYMDUMP
+            fprintf(LogFile,"Scanning #%d symbols\n",SegDef.cSymbols);
+#endif
             for (SymNum = 0; SymNum < SegDef.cSymbols; SymNum++)
             {
-
-                // read in symbol offset USHORT
-                SymPtrOffset = SYMDEFOFFSET(SegOffset, SegDef, SymNum);
-                fseek(SymFile, SymPtrOffset, SEEK_SET);
-                fread(&SymOffset, sizeof(unsigned short int), 1, SymFile);
-
-                // go to symbol definition
-                fseek(SymFile, SymOffset + SegOffset, SEEK_SET);
-
+                // fixed syms > 64 K V0.9.21 (2002-08-21) [paperino]
                 if (SegDef.bFlags & 0x01)
                 {
@@ -1594,6 +1611,9 @@
                     LastVal = SymDef32.wSymVal;
                     Buffer[0] = SymDef32.achSymName[0];
-                    fread(&Buffer[1], 1, SymDef32.cbSymName, SymFile);
+                    fread(&Buffer[1], 1, SymDef32.cbSymName-1, SymFile);
                     Buffer[SymDef32.cbSymName] = 0x00;
+#ifdef DEBUG_SYMDUMP
+                    fprintf(LogFile,"32 Bit Symbol Address %08p <%s> \n",SymDef32.wSymVal,Buffer);
+#endif
 
                     if (SymDef32.wSymVal > TrapOffset)
@@ -1608,5 +1628,4 @@
                         break;
                     }
-                    /*printf("32 Bit Symbol <%s> Address %p\n",Buffer,SymDef32.wSymVal); */
                 }
                 else
@@ -1623,5 +1642,5 @@
                     LastVal = SymDef16.wSymVal;
                     Buffer[0] = SymDef16.achSymName[0];
-                    fread(&Buffer[1], 1, SymDef16.cbSymName, SymFile);
+                    fread(&Buffer[1], 1, SymDef16.cbSymName-1, SymFile);
                     Buffer[SymDef16.cbSymName] = 0x00;
                     if (SymDef16.wSymVal > TrapOffset)
@@ -1634,5 +1653,7 @@
                         break;
                     }
-                    /*printf("16 Bit Symbol <%s> Address %p\n",Buffer,SymDef16.wSymVal); */
+#ifdef DEBUG_SYMDUMP
+                    fprintf(LogFile,"16 Bit Symbol <%s> Address %p\n",Buffer,SymDef16.wSymVal);
+#endif
                 }               // endif
             }
Index: trunk/src/helpers/encodings.c
===================================================================
--- trunk/src/helpers/encodings.c	(revision 211)
+++ trunk/src/helpers/encodings.c	(revision 212)
@@ -67,4 +67,7 @@
  *      number and a descriptive string.
  *
+ *      For a way too extensive list of codepage
+ *      names, see "http://www.iana.org/assignments/character-sets".
+ *
  *@@added V [umoeller]
  */
@@ -76,4 +79,6 @@
     unsigned long       cEntries;           // entries in map (array item count)
     unsigned short      usCodepageOS2;      // corresponding OS/2 codepage or 0 if none
+                                            // V0.9.21 (2002-08-21) [umoeller]
+    unsigned short      usLatin;            // ISO 8859-X correspondance or 0
     ENCBYTECOUNT        bc;
     const char          *pcszDescription;   // description
@@ -82,53 +87,57 @@
         #define ENCODINGENTRY(id)   enc_ ## id, G_ ## id, ARRAYITEMCOUNT(G_ ## id)
 
-        ENCODINGENTRY(cp437), 437, SINGLE, "DOS Latin US",
-        ENCODINGENTRY(cp737), 737, SINGLE, "DOS Greek",
-        ENCODINGENTRY(cp775), 775, SINGLE, "DOS BaltRim",
-        ENCODINGENTRY(cp850), 850, SINGLE, "DOS Latin 1",
-        ENCODINGENTRY(cp852), 852, SINGLE, "DOS Latin 2",               // default in Hungary,
-                                                                // Romania, Poland
-        ENCODINGENTRY(cp855), 855, SINGLE, "DOS Cyrillic",
-        ENCODINGENTRY(cp857), 857, SINGLE, "DOS Latin 5 (Turkish)",
-        ENCODINGENTRY(cp860), 860, SINGLE, "DOS Portuguese",
-        ENCODINGENTRY(cp861), 861, SINGLE, "DOS Icelandic",
-        ENCODINGENTRY(cp862), 862, SINGLE, "DOS Hebrew",
-        ENCODINGENTRY(cp863), 863, SINGLE, "DOS Canadian French",
-        ENCODINGENTRY(cp864), 864, SINGLE, "DOS Arabic",                // default in Egypt
-        ENCODINGENTRY(cp865), 865, SINGLE, "DOS Nordic",
-        ENCODINGENTRY(cp866), 866, SINGLE, "DOS Cyrillic Russian",      // default in Russia
-        ENCODINGENTRY(cp869), 869, SINGLE, "DOS Greek2",
-        ENCODINGENTRY(cp874), 874, SINGLE, "DOS Thai (TIS-620)",        // default in Thailand
-
-        ENCODINGENTRY(cp932), 932 /* or 943?*/ , DOUBLE, "Japanese Windows",
-        ENCODINGENTRY(cp936), 936 /* or 946?*/ , DOUBLE, "Chinese",
-        ENCODINGENTRY(cp949), 951 /* or 949?*/ , DOUBLE, "Korean",
-        ENCODINGENTRY(cp950), 947 /* or 950?*/ , DOUBLE, "Taiwan Big-5",           // default in China?
-
-        ENCODINGENTRY(cp1004), 1004, SINGLE, "Windows Extended",
-        ENCODINGENTRY(cp1250), 1250, SINGLE, "Windows Latin 2",
-        ENCODINGENTRY(cp1251), 1251, SINGLE, "Windows Cyrillic",
-        ENCODINGENTRY(cp1252), 1252, SINGLE, "Windows Latin 1",
-        ENCODINGENTRY(cp1253), 1253, SINGLE, "Windows Greek",
-        ENCODINGENTRY(cp1254), 1254, SINGLE, "Windows Turkish",
-        ENCODINGENTRY(cp1255), 1255, SINGLE, "Windows Hebrew",
-        ENCODINGENTRY(cp1256), 1256, SINGLE, "Windows Arabic",
-        ENCODINGENTRY(cp1257), 1257, SINGLE, "Windows Latin-4",
-        ENCODINGENTRY(cp1258), 1258, UNKNOWN, "unknown",
-        ENCODINGENTRY(iso8859_1), 819, SINGLE, "ISO/IEC 8859-1:1998 (Latin-1)",
-        ENCODINGENTRY(iso8859_2), 912, SINGLE, "ISO 8859-2:1999 (Latin-2)",
-        ENCODINGENTRY(iso8859_3), 913, SINGLE, "ISO/IEC 8859-3:1999 (Latin-3)",
-        ENCODINGENTRY(iso8859_4), 914, SINGLE, "ISO/IEC 8859-4:1998 (Latin-4)",
-        ENCODINGENTRY(iso8859_5), 915, SINGLE, "ISO 8859-5:1999 (Cyrillic)",
-        ENCODINGENTRY(iso8859_6), 1089, SINGLE, "ISO 8859-6:1999 (Arabic)",
-        ENCODINGENTRY(iso8859_7), 813, SINGLE, "ISO 8859-7:1987 (Greek)",   // default in Greece
-        ENCODINGENTRY(iso8859_8), 916, SINGLE, "ISO/IEC 8859-8:1999 (Hebrew)",
-        ENCODINGENTRY(iso8859_9), 920, SINGLE, "ISO/IEC 8859-9:1999 (Latin-5)",
-        ENCODINGENTRY(iso8859_10), 0, SINGLE, "ISO/IEC 8859-10:1998",
-        ENCODINGENTRY(iso8859_13), 0, SINGLE, "ISO/IEC 8859-13:1998",
-        ENCODINGENTRY(iso8859_14), 0, SINGLE, "ISO/IEC 8859-14:1998",
-        ENCODINGENTRY(iso8859_15), 923, SINGLE, "ISO/IEC 8859-15:1999",
-
-        UNSUPPORTED, NULL, 0, 1200, MULTI_UNICODE, "Unicode UCS-2",
-        UNSUPPORTED, NULL, 0, 1208, MULTI_UNICODE, "Unicode UTF-8"
+        ENCODINGENTRY(cp437),      437,  0, SINGLE, "DOS Latin US",
+        ENCODINGENTRY(cp737),      737,  0, SINGLE, "DOS Greek",
+        ENCODINGENTRY(cp775),      775,  0, SINGLE, "DOS BaltRim",
+        ENCODINGENTRY(cp850),      850,  0, SINGLE, "DOS Latin 1",
+        ENCODINGENTRY(cp852),      852,  0, SINGLE, "DOS Latin 2",               // default in Hungary,
+                                                                                 // Romania, Poland
+        ENCODINGENTRY(cp855),      855,  0, SINGLE, "DOS Cyrillic",
+        ENCODINGENTRY(cp857),      857,  0, SINGLE, "DOS Latin 5 (Turkish)",
+        ENCODINGENTRY(cp860),      860,  0, SINGLE, "DOS Portuguese",
+        ENCODINGENTRY(cp861),      861,  0, SINGLE, "DOS Icelandic",
+        ENCODINGENTRY(cp862),      862,  0, SINGLE, "DOS Hebrew",
+        ENCODINGENTRY(cp863),      863,  0, SINGLE, "DOS Canadian French",
+        ENCODINGENTRY(cp864),      864,  0, SINGLE, "DOS Arabic",                // default in Egypt
+        ENCODINGENTRY(cp865),      865,  0, SINGLE, "DOS Nordic",
+        ENCODINGENTRY(cp866),      866,  0, SINGLE, "DOS Cyrillic Russian",      // default in Russia
+        ENCODINGENTRY(cp869),      869,  0, SINGLE, "DOS Greek2",
+        ENCODINGENTRY(cp874),      874,  0, SINGLE, "DOS Thai (TIS-620)",        // default in Thailand
+
+        ENCODINGENTRY(cp932),      932 /* or 943?*/ ,
+                                         0, DOUBLE, "Japanese Windows",
+        ENCODINGENTRY(cp936),      936 /* or 946?*/ ,
+                                         0, DOUBLE, "Chinese",
+        ENCODINGENTRY(cp949),      951 /* or 949?*/ ,
+                                         0, DOUBLE, "Korean",
+        ENCODINGENTRY(cp950),      947 /* or 950?*/ ,
+                                         0, DOUBLE, "Taiwan Big-5",           // default in China?
+
+        ENCODINGENTRY(cp1004),    1004,  0, SINGLE, "Windows Extended",
+        ENCODINGENTRY(cp1250),    1250,  0, SINGLE, "Windows Latin 2",
+        ENCODINGENTRY(cp1251),    1251,  0, SINGLE, "Windows Cyrillic",
+        ENCODINGENTRY(cp1252),    1252,  0, SINGLE, "Windows Latin 1",
+        ENCODINGENTRY(cp1253),    1253,  0, SINGLE, "Windows Greek",
+        ENCODINGENTRY(cp1254),    1254,  0, SINGLE, "Windows Turkish",
+        ENCODINGENTRY(cp1255),    1255,  0, SINGLE, "Windows Hebrew",
+        ENCODINGENTRY(cp1256),    1256,  0, SINGLE, "Windows Arabic",
+        ENCODINGENTRY(cp1257),    1257,  0, SINGLE, "Windows Latin-4",
+        ENCODINGENTRY(cp1258),    1258,  0, UNKNOWN, "unknown",
+        ENCODINGENTRY(iso8859_1),  819,  1, SINGLE, "ISO/IEC 8859-1:1998 (Latin-1)",
+        ENCODINGENTRY(iso8859_2),  912,  2, SINGLE, "ISO 8859-2:1999 (Latin-2)",
+        ENCODINGENTRY(iso8859_3),  913,  3, SINGLE, "ISO/IEC 8859-3:1999 (Latin-3)",
+        ENCODINGENTRY(iso8859_4),  914,  4, SINGLE, "ISO/IEC 8859-4:1998 (Latin-4)",
+        ENCODINGENTRY(iso8859_5),  915,  5, SINGLE, "ISO 8859-5:1999 (Cyrillic)",
+        ENCODINGENTRY(iso8859_6), 1089,  6, SINGLE, "ISO 8859-6:1999 (Arabic)",
+        ENCODINGENTRY(iso8859_7),  813,  7, SINGLE, "ISO 8859-7:1987 (Greek)",   // default in Greece
+        ENCODINGENTRY(iso8859_8),  916,  8, SINGLE, "ISO/IEC 8859-8:1999 (Hebrew)",
+        ENCODINGENTRY(iso8859_9),  920,  9, SINGLE, "ISO/IEC 8859-9:1999 (Latin-5)",
+        ENCODINGENTRY(iso8859_10),   0, 10, SINGLE, "ISO/IEC 8859-10:1998",
+        ENCODINGENTRY(iso8859_13),   0, 13, SINGLE, "ISO/IEC 8859-13:1998",
+        ENCODINGENTRY(iso8859_14),   0, 14, SINGLE, "ISO/IEC 8859-14:1998",
+        ENCODINGENTRY(iso8859_15), 923, 15, SINGLE, "ISO/IEC 8859-15:1999",
+
+        UNSUPPORTED, NULL, 0,     1200,  0, MULTI_UNICODE, "Unicode UCS-2",
+        UNSUPPORTED, NULL, 0,     1208,  0, MULTI_UNICODE, "Unicode UTF-8"
     };
 
Index: trunk/src/helpers/xml.c
===================================================================
--- trunk/src/helpers/xml.c	(revision 211)
+++ trunk/src/helpers/xml.c	(revision 212)
@@ -3101,4 +3101,83 @@
 
 /*
+ *@@ ESCAPES:
+ *
+ *@@added V0.9.21 (2002-08-21) [umoeller]
+ */
+
+typedef struct _ESCAPES
+{
+    XSTRING strQuot1,       // "
+            strQuot2,       // &quot;
+            strAmp1,        // &
+            strAmp2,        // &amp;
+            strLT1,         // <
+            strLT2,         // &lt;
+            strGT1,         // >
+            strGT2;         // &gt;
+
+    XSTRING strTemp;        // temp buffer
+
+} ESCAPES, *PESCAPES;
+
+/*
+ *@@ DoEscapes:
+ *
+ *@@added V0.9.21 (2002-08-21) [umoeller]
+ */
+
+VOID DoEscapes(PESCAPES pEscapes,
+               BOOL fQuotesToo)
+{
+    ULONG   ulOfs;
+    size_t  ShiftTable[256];
+    BOOL    fRepeat;
+
+    if (fQuotesToo)
+    {
+        ulOfs = 0;
+        fRepeat = FALSE;
+        while (xstrFindReplace(&pEscapes->strTemp,
+                               &ulOfs,
+                               &pEscapes->strQuot1,
+                               &pEscapes->strQuot2,
+                               ShiftTable,
+                               &fRepeat))
+            ;
+    }
+
+    ulOfs = 0;
+    fRepeat = FALSE;
+    while (xstrFindReplace(&pEscapes->strTemp,
+                           &ulOfs,
+                           &pEscapes->strLT1,
+                           &pEscapes->strLT2,
+                           ShiftTable,
+                           &fRepeat))
+        ;
+
+    ulOfs = 0;
+    fRepeat = FALSE;
+    while (xstrFindReplace(&pEscapes->strTemp,
+                           &ulOfs,
+                           &pEscapes->strGT1,
+                           &pEscapes->strGT2,
+                           ShiftTable,
+                           &fRepeat))
+        ;
+
+    // replace ampersands last
+    ulOfs = 0;
+    fRepeat = FALSE;
+    while (xstrFindReplace(&pEscapes->strTemp,
+                           &ulOfs,
+                           &pEscapes->strAmp1,
+                           &pEscapes->strAmp2,
+                           ShiftTable,
+                           &fRepeat))
+        ;
+}
+
+/*
  *@@ WriteNodes:
  *      internal helper for writing out the nodes.
@@ -3106,7 +3185,9 @@
  *
  *@@added V0.9.12 (2001-05-21) [umoeller]
+ *@@changed V0.9.21 (2002-08-21) [umoeller]: changed prototype, fixed unescaped characters in attributes and content
  */
 
 static VOID WriteNodes(PXSTRING pxstr,
+                       PESCAPES pEscapes,
                        PDOMNODE pDomNode)       // in: node whose children are to be written (initially DOCUMENT)
 {
@@ -3143,5 +3224,15 @@
                     xstrcats(pxstr, &pAttribNode->NodeBase.strNodeName);
                     xstrcat(pxstr, "=\"", 0);
-                    xstrcats(pxstr, pAttribNode->pstrNodeValue);
+
+                    // copy attribute value to temp buffer first
+                    // so we can escape quotes and ampersands
+                    // V0.9.21 (2002-08-21) [umoeller]
+                    xstrcpys(&pEscapes->strTemp, pAttribNode->pstrNodeValue);
+
+                    DoEscapes(pEscapes,
+                              TRUE);        // quotes too
+
+                    // alright, use that
+                    xstrcats(pxstr, &pEscapes->strTemp);
                     xstrcatc(pxstr, '\"');
                 }
@@ -3154,5 +3245,5 @@
 
                     // recurse into this child element
-                    WriteNodes(pxstr, pChildNode);
+                    WriteNodes(pxstr, pEscapes, pChildNode);
 
                     if (!fMixedContent)
@@ -3176,5 +3267,11 @@
             case DOMNODE_COMMENT:
                 // that's simple
-                xstrcats(pxstr, pChildNode->pstrNodeValue);
+                xstrcpys(&pEscapes->strTemp,
+                         pChildNode->pstrNodeValue);
+
+                DoEscapes(pEscapes,         // V0.9.21 (2002-08-21) [umoeller]
+                          FALSE);           // quotes not
+
+                xstrcats(pxstr, &pEscapes->strTemp);
             break;
 
@@ -3288,4 +3385,6 @@
     else
     {
+        ESCAPES esc;
+
         // <?xml version="1.0" encoding="ISO-8859-1"?>
         xstrcpy(pxstr, "<?xml version=\"1.0\" encoding=\"", 0);
@@ -3301,6 +3400,28 @@
         }
 
+        xstrInitCopy(&esc.strQuot1, "\"", 0);
+        xstrInitCopy(&esc.strQuot2, "&quot;", 0);
+        xstrInitCopy(&esc.strAmp1, "&", 0);
+        xstrInitCopy(&esc.strAmp2, "&amp;", 0);
+        xstrInitCopy(&esc.strLT1, "<", 0);
+        xstrInitCopy(&esc.strLT2, "&lt;", 0);
+        xstrInitCopy(&esc.strGT1, ">", 0);
+        xstrInitCopy(&esc.strGT2, "&gt;", 0);
+
+        xstrInit(&esc.strTemp, 0);       // temp buffer
+
         // write out children
-        WriteNodes(pxstr, (PDOMNODE)pDocument);
+        WriteNodes(pxstr, &esc, (PDOMNODE)pDocument);
+
+        xstrClear(&esc.strQuot1);
+        xstrClear(&esc.strQuot2);
+        xstrClear(&esc.strAmp1);
+        xstrClear(&esc.strAmp2);
+        xstrClear(&esc.strLT1);
+        xstrClear(&esc.strLT2);
+        xstrClear(&esc.strGT1);
+        xstrClear(&esc.strGT2);
+
+        xstrClear(&esc.strTemp);       // temp buffer
 
         xstrcatc(pxstr, '\n');
