Changeset 113 for trunk/src/helpers


Ignore:
Timestamp:
Oct 23, 2001, 11:25:46 PM (24 years ago)
Author:
umoeller
Message:

Misc updates.

Location:
trunk/src/helpers
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/apps.c

    r108 r113  
    4747#include "helpers\prfh.h"
    4848#include "helpers\stringh.h"
     49#include "helpers\winh.h"
    4950#include "helpers\xstring.h"
    5051
     
    797798 *          from the shell.
    798799 *
    799  +      --  However, if you specify an environment, you _must_
    800  *          specify a complemete environment. This function
     800 *      --  However, if you specify an environment, you _must_
     801 *          specify a complete environment. This function
    801802 *          will not merge environments. Use
    802803 *          appSetEnvironmentVar to change environment
     
    808809 *          See appQueryDefaultWin31Environment.
    809810 *
    810  *      --  WARNING: Since this uses WinStartApp internally,
    811  *          and WinStartApp completely hangs PM if a Win-OS/2
    812  *          full-screen session is started from a thread that
    813  *          is NOT thread1, THIS SHOULD ONLY BE CALLED ON
    814  *          THREAD 1 of your application.
    815  *
    816811 *      Even though this isn't clearly said in PMREF,
    817812 *      PROGDETAILS.swpInitial is important:
     
    823818 *         This flag is now in the newer toolkit headers.
    824819 *
     820 *      In addition, this supports the following session
     821 *      flags with ulFlags if PROG_DEFAULT is specified:
     822 *
     823 *      --  APP_RUN_FULLSCREEN
     824 *
     825 *      --  APP_RUN_ENHANCED
     826 *
     827 *      --  APP_RUN_STANDARD
     828 *
     829 *      --  APP_RUN_SEPARATE
     830 *
    825831 *      Since this calls WinStartApp in turn, this
    826832 *      requires a message queue on the calling thread.
     833 *
     834 *      Note that this also does minimal checking on
     835 *      the specified parameters so it can return something
     836 *      more meaningful than FALSE like WinStartApp.
     837 *      As a result, you get a DOS error code now (V0.9.16).
     838 *
     839 *      Most importantly:
     840 *
     841 *      --  ERROR_INVALID_THREADID: not running on thread 1.
     842 *          Since this uses WinStartApp internally and
     843 *          WinStartApp completely hangs the session manager
     844 *          if a Win-OS/2 full-screen session is started from
     845 *          a thread that is NOT thread1, this will fail
     846 *          with an error for safety (V0.9.16).
     847 *
     848 *      --  ERROR_INVALID_PARAMETER: pcProgDetails or
     849 *          phapp is NULL; or PROGDETAILS.pszExecutable is NULL.
     850 *
     851 *      --  ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND:
     852 *          PROGDETAILS.pszExecutable and/or PROGDETAILS.pszStartupDir
     853 *          are invalid.
     854 *          A NULL PROGDETAILS.pszStartupDir is supported though.
     855 *
     856 *      --  ERROR_NOT_ENOUGH_MEMORY
    827857 *
    828858 *@@added V0.9.6 (2000-10-16) [umoeller]
     
    834864 *@@changed V0.9.14 (2001-08-07) [pr]: removed some env. strings for Win. apps.
    835865 *@@changed V0.9.14 (2001-08-23) [pr]: added session type options
    836  */
    837 
    838 HAPP appStartApp(HWND hwndNotify,                  // in: notify window (as with WinStartApp)
    839                  const PROGDETAILS *pcProgDetails, // in: program data
    840                  ULONG ulFlags)                    // in: session type options
    841 {
    842     HAPP            happ = NULLHANDLE;
    843     XSTRING         strParamsPatched;
     866 *@@changed V0.9.16 (2001-10-19) [umoeller]: added prototype to return APIRET
     867 *@@changed V0.9.16 (2001-10-19) [umoeller]: added thread-1 check
     868 */
     869
     870APIRET appStartApp(HWND hwndNotify,        // in: notify window or NULLHANDLE
     871                   const PROGDETAILS *pcProgDetails, // in: program spec (req.)
     872                   ULONG ulFlags,          // in: APP_RUN_* flags
     873                   HAPP *phapp)            // out: application handle if NO_ERROR is returned
     874{
     875    APIRET          arc = NO_ERROR;
    844876    PROGDETAILS     ProgDetails;
    845877
    846     PSZ             pszWinOS2Env = 0;
     878    if (!pcProgDetails || !phapp)
     879        return (ERROR_INVALID_PARAMETER);
    847880
    848881    memcpy(&ProgDetails, pcProgDetails, sizeof(PROGDETAILS));
     
    850883    ProgDetails.Length = sizeof(PROGDETAILS);
    851884    ProgDetails.progt.fbVisible = SHE_VISIBLE;
    852     // ProgDetails.pszEnvironment = 0;
    853885
    854886    // all this only makes sense if this contains something...
    855887    // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller]
    856     if (ProgDetails.pszExecutable)
    857     {
    858         ULONG ulIsWinApp;
     888    if (!ProgDetails.pszExecutable)
     889        arc = ERROR_INVALID_PARAMETER;
     890    else if (doshMyTID() != 1)          // V0.9.16 (2001-10-19) [umoeller]
     891        arc = ERROR_INVALID_THREADID;
     892    else
     893    {
     894        ULONG           ulIsWinApp;
     895
     896        XSTRING         strParamsPatched;
     897        PSZ             pszWinOS2Env = 0;
    859898
    860899        // memset(&ProgDetails.swpInitial, 0, sizeof(SWP));
     
    891930        }
    892931
    893         // Set session type from option flags
     932        // set session type from option flags
    894933        if (ulFlags & APP_RUN_FULLSCREEN)
    895934        {
     
    919958                                                : PROG_31_ENHSEAMLESSCOMMON;
    920959            }
     960
     961            // re-run V0.9.16 (2001-10-19) [umoeller]
     962            ulIsWinApp = appIsWindowsApp(ProgDetails.progt.progc);
    921963        }
    922964
     
    9681010        else
    9691011        {
    970             PSZ pszExtension;
    971             switch (ProgDetails.progt.progc)
    972             {
    973                 /*
    974                  *  .CMD files fixups
    975                  *
    976                  */
    977 
    978                 case PROG_FULLSCREEN:       // OS/2 fullscreen
    979                 case PROG_WINDOWABLEVIO:    // OS/2 window
     1012            // now check if the executable is valid
     1013            // V0.9.16 (2001-10-19) [umoeller]
     1014            ULONG ulAttr;
     1015            _Pmpf(("  %d now, checking %s", arc, ProgDetails.pszExecutable));
     1016            if (!(arc = doshQueryPathAttr(ProgDetails.pszExecutable,
     1017                                          &ulAttr)))
     1018            {
     1019                // make sure startup dir is really a directory
     1020                if (ProgDetails.pszStartupDir)
    9801021                {
    981                     if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
    982                          && (!stricmp(pszExtension, "CMD"))
     1022                    _Pmpf(("  checking %s", ProgDetails.pszStartupDir));
     1023                    if (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir,
     1024                                                  &ulAttr)))
     1025                        if (!(ulAttr & FILE_DIRECTORY))
     1026                            arc = ERROR_PATH_NOT_FOUND;
     1027                                        // @@todo
     1028                }
     1029            }
     1030
     1031            _Pmpf(("  after checking %d", arc));
     1032
     1033            if (!arc)
     1034            {
     1035                PSZ pszExtension;
     1036                switch (ProgDetails.progt.progc)
     1037                {
     1038                    /*
     1039                     *  .CMD files fixups
     1040                     *
     1041                     */
     1042
     1043                    case PROG_FULLSCREEN:       // OS/2 fullscreen
     1044                    case PROG_WINDOWABLEVIO:    // OS/2 window
     1045                    {
     1046                        if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
     1047                             && (!stricmp(pszExtension, "CMD"))
     1048                           )
     1049                        {
     1050                            CallBatchCorrectly(&ProgDetails,
     1051                                               &strParamsPatched,
     1052                                               "OS2_SHELL",
     1053                                               "CMD.EXE");
     1054                        }
     1055                    break; }
     1056
     1057                    case PROG_VDM:              // DOS fullscreen
     1058                    case PROG_WINDOWEDVDM:      // DOS window
     1059                    {
     1060                        if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
     1061                             && (!stricmp(pszExtension, "BAT"))
     1062                           )
     1063                        {
     1064                            CallBatchCorrectly(&ProgDetails,
     1065                                               &strParamsPatched,
     1066                                               NULL,
     1067                                               "COMMAND.COM");
     1068                        }
     1069                    break; }
     1070                } // end switch (ProgDetails.progt.progc)
     1071            }
     1072        }
     1073
     1074        if (!arc)
     1075        {
     1076            if (    (ulIsWinApp)
     1077                 && (    (ProgDetails.pszEnvironment == NULL)
     1078                      || (!strlen(ProgDetails.pszEnvironment))
     1079                    )
     1080               )
     1081            {
     1082                // this is a windoze app, and caller didn't bother
     1083                // to give us an environment:
     1084                // we MUST set one then, or we'll get the strangest
     1085                // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller]
     1086
     1087                DOSENVIRONMENT Env = {0};
     1088
     1089                // get standard WIN-OS/2 environment
     1090                PSZ pszTemp = appQueryDefaultWin31Environment();
     1091
     1092                if (!(arc = appParseEnvironment(pszTemp,
     1093                                                &Env)))
     1094                {
     1095                    // now override KBD_CTRL_BYPASS=CTRL_ESC
     1096                    if (    (!(arc = appSetEnvironmentVar(&Env,
     1097                                                          "KBD_CTRL_BYPASS=CTRL_ESC",
     1098                                                          FALSE)))        // add last
     1099                         && (!(arc = appConvertEnvironment(&Env,
     1100                                                           &pszWinOS2Env,   // freed at bottom
     1101                                                           NULL)))
    9831102                       )
     1103                        ProgDetails.pszEnvironment = pszWinOS2Env;
     1104
     1105                    appFreeEnvironment(&Env);
     1106                }
     1107
     1108                free(pszTemp);
     1109            }
     1110
     1111            if (!arc)
     1112            {
     1113                if (!ProgDetails.pszTitle)
     1114                    ProgDetails.pszTitle = ProgDetails.pszExecutable;
     1115
     1116                ProgDetails.pszParameters = strParamsPatched.psz;
     1117
     1118                /*  _Pmpf(("progt.progc: %d", ProgDetails.progt.progc));
     1119                _Pmpf(("progt.fbVisible: 0x%lX", ProgDetails.progt.fbVisible));
     1120                _Pmpf(("progt.pszTitle: \"%s\"", (ProgDetails.pszTitle) ? ProgDetails.pszTitle : "NULL"));
     1121                _Pmpf(("exec: \"%s\"", (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL"));
     1122                _Pmpf(("params: \"%s\"", (ProgDetails.pszParameters) ? ProgDetails.pszParameters : "NULL"));
     1123                _Pmpf(("startup: \"%s\"", (ProgDetails.pszStartupDir) ? ProgDetails.pszStartupDir : "NULL"));
     1124                _Pmpf(("pszIcon: \"%s\"", (ProgDetails.pszIcon) ? ProgDetails.pszIcon : "NULL"));
     1125                _Pmpf(("environment: "));
     1126                {
     1127                    PSZ pszThis = ProgDetails.pszEnvironment;
     1128                    while (pszThis && *pszThis)
    9841129                    {
    985                         CallBatchCorrectly(&ProgDetails,
    986                                            &strParamsPatched,
    987                                            "OS2_SHELL",
    988                                            "CMD.EXE");
     1130                        _Pmpf(("  \"%s\"", pszThis));
     1131                        pszThis += strlen(pszThis) + 1;
    9891132                    }
    990                 break; }
    991 
    992                 case PROG_VDM:              // DOS fullscreen
    993                 case PROG_WINDOWEDVDM:      // DOS window
    994                 {
    995                     if (    (pszExtension = doshGetExtension(ProgDetails.pszExecutable))
    996                          && (!stricmp(pszExtension, "BAT"))
    997                        )
    998                     {
    999                         CallBatchCorrectly(&ProgDetails,
    1000                                            &strParamsPatched,
    1001                                            NULL,
    1002                                            "COMMAND.COM");
    1003                     }
    1004                 break; }
    1005             } // end switch (ProgDetails.progt.progc)
    1006         }
    1007 
    1008         if (    (ulIsWinApp)
    1009              && (    (ProgDetails.pszEnvironment == NULL)
    1010                   || (!strlen(ProgDetails.pszEnvironment))
    1011                 )
    1012            )
    1013         {
    1014             // this is a windoze app, and caller didn't bother
    1015             // to give us an environment:
    1016             // we MUST set one then, or we'll get the strangest
    1017             // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller]
    1018 
    1019             DOSENVIRONMENT Env = {0};
    1020 
    1021             // get standard WIN-OS/2 environment
    1022             PSZ pszTemp = appQueryDefaultWin31Environment();
    1023 
    1024             if (!appParseEnvironment(pszTemp,
    1025                                      &Env))
    1026             {
    1027                 // now override KBD_CTRL_BYPASS=CTRL_ESC
    1028                 appSetEnvironmentVar(&Env,
    1029                                      "KBD_CTRL_BYPASS=CTRL_ESC",
    1030                                      FALSE);        // add last
    1031                 /*
    1032                  * These should be set by the default environment. It is
    1033                  * not our business to override them really. V0.9.14
    1034                  *
    1035                 appSetEnvironmentVar(&Env,
    1036                                      "KBD_ALTHOME_BYPASS=1",
    1037                                      FALSE);        // add last
    1038                 appSetEnvironmentVar(&Env,
    1039                                      "INT_DURING_IO=1",
    1040                                      FALSE);        // add last
    1041                 appSetEnvironmentVar(&Env,
    1042                                      "HW_TIMER=1",
    1043                                      FALSE);        // add last
    1044                 appSetEnvironmentVar(&Env,
    1045                                      "MOUSE_EXCLUSIVE_ACCESS=0",
    1046                                      FALSE);        // add last
    1047                 appSetEnvironmentVar(&Env,
    1048                                      "VIDEO_RETRACE_EMULATION=1",
    1049                                      FALSE);        // add last
    1050                 appSetEnvironmentVar(&Env,
    1051                                      "VIDEO_SWITCH_NOTIFICATION=1",
    1052                                      FALSE);        // add last
    1053                 appSetEnvironmentVar(&Env,
    1054                                      "VIDEO_8514A_XGA_IOTRAP=0",
    1055                                      FALSE);        // add last
    1056                  */
    1057 
    1058                 if (!appConvertEnvironment(&Env,
    1059                                            &pszWinOS2Env,   // freed at bottom
    1060                                            NULL))
    1061                     ProgDetails.pszEnvironment = pszWinOS2Env;
    1062 
    1063                 appFreeEnvironment(&Env);
    1064             }
    1065 
    1066             free(pszTemp);
    1067         }
    1068 
    1069         if (!ProgDetails.pszTitle)
    1070             ProgDetails.pszTitle = ProgDetails.pszExecutable;
    1071 
    1072         ProgDetails.pszParameters = strParamsPatched.psz;
    1073 
    1074         /*  _Pmpf(("progt.progc: %d", ProgDetails.progt.progc));
    1075         _Pmpf(("progt.fbVisible: 0x%lX", ProgDetails.progt.fbVisible));
    1076         _Pmpf(("progt.pszTitle: \"%s\"", (ProgDetails.pszTitle) ? ProgDetails.pszTitle : "NULL"));
    1077         _Pmpf(("exec: \"%s\"", (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL"));
    1078         _Pmpf(("params: \"%s\"", (ProgDetails.pszParameters) ? ProgDetails.pszParameters : "NULL"));
    1079         _Pmpf(("startup: \"%s\"", (ProgDetails.pszStartupDir) ? ProgDetails.pszStartupDir : "NULL"));
    1080         _Pmpf(("pszIcon: \"%s\"", (ProgDetails.pszIcon) ? ProgDetails.pszIcon : "NULL"));
    1081         _Pmpf(("environment: "));
    1082         {
    1083             PSZ pszThis = ProgDetails.pszEnvironment;
    1084             while (pszThis && *pszThis)
    1085             {
    1086                 _Pmpf(("  \"%s\"", pszThis));
    1087                 pszThis += strlen(pszThis) + 1;
    1088             }
    1089         }
    1090 
    1091         _Pmpf(("swpInitial.fl = 0x%lX, x = %d, y = %d, cx = %d, cy = %d:",
    1092                     ProgDetails.swpInitial.fl,
    1093                     ProgDetails.swpInitial.x,
    1094                     ProgDetails.swpInitial.y,
    1095                     ProgDetails.swpInitial.cx,
    1096                     ProgDetails.swpInitial.cy));
    1097         _Pmpf(("  behind = %d, hwnd = %d, res1 = %d, res2 = %d",
    1098                     ProgDetails.swpInitial.hwndInsertBehind,
    1099                     ProgDetails.swpInitial.hwnd,
    1100                     ProgDetails.swpInitial.ulReserved1,
    1101                     ProgDetails.swpInitial.ulReserved2));
    1102             */
    1103 
    1104         /* if (WinMessageBox(HWND_DESKTOP,
    1105                           NULLHANDLE,
    1106                           (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL",
    1107                           "Start?",
    1108                           0,
    1109                           MB_YESNO | MB_MOVEABLE)
    1110                   == MBID_YES) */
    1111         happ = WinStartApp(hwndNotify,
    1112                                     // receives WM_APPTERMINATENOTIFY
    1113                            &ProgDetails,
    1114                            strParamsPatched.psz,
    1115                            NULL,            // "reserved", PMREF says...
    1116                            SAF_INSTALLEDCMDLINE);
    1117                                 // we MUST use SAF_INSTALLEDCMDLINE
    1118                                 // or no Win-OS/2 session will start...
    1119                                 // whatever is going on here... Warp 4 FP11
    1120 
    1121                                 // do not use SAF_STARTCHILDAPP, or the
    1122                                 // app will be terminated automatically
    1123                                 // when the WPS terminates!
    1124 
    1125         // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
     1133                }
     1134
     1135                _Pmpf(("swpInitial.fl = 0x%lX, x = %d, y = %d, cx = %d, cy = %d:",
     1136                            ProgDetails.swpInitial.fl,
     1137                            ProgDetails.swpInitial.x,
     1138                            ProgDetails.swpInitial.y,
     1139                            ProgDetails.swpInitial.cx,
     1140                            ProgDetails.swpInitial.cy));
     1141                _Pmpf(("  behind = %d, hwnd = %d, res1 = %d, res2 = %d",
     1142                            ProgDetails.swpInitial.hwndInsertBehind,
     1143                            ProgDetails.swpInitial.hwnd,
     1144                            ProgDetails.swpInitial.ulReserved1,
     1145                            ProgDetails.swpInitial.ulReserved2));
     1146                    */
     1147
     1148                /* if (WinMessageBox(HWND_DESKTOP,
     1149                                  NULLHANDLE,
     1150                                  (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL",
     1151                                  "Start?",
     1152                                  0,
     1153                                  MB_YESNO | MB_MOVEABLE)
     1154                          == MBID_YES) */
     1155                if (!(*phapp = WinStartApp(hwndNotify,
     1156                                                    // receives WM_APPTERMINATENOTIFY
     1157                                           &ProgDetails,
     1158                                           strParamsPatched.psz,
     1159                                           NULL,            // "reserved", PMREF says...
     1160                                           SAF_INSTALLEDCMDLINE)))
     1161                                                // we MUST use SAF_INSTALLEDCMDLINE
     1162                                                // or no Win-OS/2 session will start...
     1163                                                // whatever is going on here... Warp 4 FP11
     1164
     1165                                                // do not use SAF_STARTCHILDAPP, or the
     1166                                                // app will be terminated automatically
     1167                                                // when the WPS terminates!
     1168                    arc = ERROR_BAD_FORMAT;
     1169                            // @@todo we can probably do better
     1170                            // V0.9.16 (2001-10-19) [umoeller]
     1171
     1172                // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
     1173            }
     1174        }
    11261175
    11271176        xstrClear(&strParamsPatched);
     
    11301179    } // end if (ProgDetails.pszExecutable)
    11311180
    1132     return (happ);
    1133 }
    1134 
    1135 
     1181    _Pmpf((__FUNCTION__ ": returning %d", arc));
     1182
     1183    return (arc);
     1184}
     1185
     1186/*
     1187 *@@ appWaitForApp:
     1188 *      waits for the specified application to terminate
     1189 *      and returns its exit code.
     1190 *
     1191 *@@added V0.9.9 (2001-03-07) [umoeller]
     1192 */
     1193
     1194BOOL appWaitForApp(HWND hwndNotify,     // in: notify window
     1195                   HAPP happ,           // in: app to wait for
     1196                   PULONG pulExitCode)  // out: exit code (ptr can be NULL)
     1197{
     1198    BOOL brc = FALSE;
     1199
     1200    if (happ)
     1201    {
     1202        // app started:
     1203        // enter a modal message loop until we get the
     1204        // WM_APPTERMINATENOTIFY for happ. Then we
     1205        // know the app is done.
     1206        HAB     hab = WinQueryAnchorBlock(hwndNotify);
     1207        QMSG    qmsg;
     1208        // ULONG   ulXFixReturnCode = 0;
     1209        while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
     1210        {
     1211            if (    (qmsg.msg == WM_APPTERMINATENOTIFY)
     1212                 && (qmsg.hwnd == hwndNotify)
     1213                 && (qmsg.mp1 == (MPARAM)happ)
     1214               )
     1215            {
     1216                // xfix has terminated:
     1217                // get xfix return code from mp2... this is:
     1218                // -- 0: everything's OK, continue.
     1219                // -- 1: handle section was rewritten, restart Desktop
     1220                //       now.
     1221                if (pulExitCode)
     1222                    *pulExitCode = (ULONG)qmsg.mp2;
     1223                brc = TRUE;
     1224                // do not dispatch this
     1225                break;
     1226            }
     1227
     1228            WinDispatchMsg(hab, &qmsg);
     1229        }
     1230    }
     1231
     1232    return (brc);
     1233}
     1234
     1235/*
     1236 *@@ appQuickStartApp:
     1237 *      shortcut for simply starting an app and
     1238 *      waiting until it's finished.
     1239 *
     1240 *      On errors, NULLHANDLE is returned.
     1241 *
     1242 *      If pulReturnCode != NULL, it receives the
     1243 *      return code of the app.
     1244 *
     1245 *@@added V0.9.16 (2001-10-19) [umoeller]
     1246 */
     1247
     1248HAPP appQuickStartApp(const char *pcszFile,
     1249                      ULONG ulProgType,         // e.g. PROG_PM
     1250                      const char *pcszArgs,
     1251                      PULONG pulExitCode)
     1252{
     1253    PROGDETAILS    pd = {0};
     1254    HAPP           happ,
     1255                   happReturn = NULLHANDLE;
     1256    CHAR           szDir[CCHMAXPATH] = "";
     1257    PCSZ           p;
     1258    HWND           hwndObject;
     1259
     1260    pd.Length = sizeof(pd);
     1261    pd.progt.progc = ulProgType;
     1262    pd.progt.fbVisible = SHE_VISIBLE;
     1263    pd.pszExecutable = (PSZ)pcszFile;
     1264    pd.pszParameters = (PSZ)pcszArgs;
     1265    if (p = strrchr(pcszFile, '\\'))
     1266    {
     1267       strhncpy0(szDir,
     1268                 pcszFile,
     1269                 p - pcszFile);
     1270       pd.pszStartupDir = szDir;
     1271    }
     1272
     1273    if (    (hwndObject = winhCreateObjectWindow(WC_STATIC, NULL))
     1274         && (!appStartApp(hwndObject,
     1275                          &pd,
     1276                          0,
     1277                          &happ))
     1278       )
     1279    {
     1280        if (appWaitForApp(hwndObject,
     1281                          happ,
     1282                          pulExitCode))
     1283            happReturn = happ;
     1284    }
     1285
     1286    return (happReturn);
     1287}
  • trunk/src/helpers/dialog.c

    r111 r113  
    15761576 *          fl specifies formatting flags for the row. This
    15771577 *          can be one of ROW_VALIGN_BOTTOM, ROW_VALIGN_CENTER,
    1578  *          ROW_VALIGN_TOP and affects all items in the control.
     1578 *          ROW_VALIGN_TOP and affects all items in the row.
    15791579 *
    15801580 *      --  CONTROL_DEF(pDef) defines a control in a table row.
     
    18921892 *          dialog should be modified according to
    18931893 *          flFlags.
     1894 *
     1895 *      This is what's used in XWorkplace for notebook
     1896 *      settings pages since these always have to be
     1897 *      based on a resource dialog (which is loaded
     1898 *      empty).
    18941899 *
    18951900 *      flFlags can be any combination of the following:
  • trunk/src/helpers/dosh.c

    r108 r113  
    5151#define INCL_DOSSESMGR
    5252#define INCL_DOSQUEUES
     53#define INCL_DOSSEMAPHORES
    5354#define INCL_DOSMISC
    5455#define INCL_DOSDEVICES
     
    6263#include <string.h>
    6364#include <stdio.h>
     65#include <stdarg.h>
    6466
    6567#include "setup.h"                      // code generation and debugging options
    6668
    6769#include "helpers\dosh.h"
     70#include "helpers\standards.h"
    6871
    6972#pragma hdrstop
     
    286289 *
    287290 ********************************************************************/
     291
     292/*
     293 *@@ Allocate:
     294 *      wrapper around malloc() which automatically
     295 *      sets ERROR_NOT_ENOUGH_MEMORY.
     296 *
     297 *@@added V0.9.16 (2001-10-19) [umoeller]
     298 */
     299
     300PVOID doshMalloc(ULONG cb,
     301                 APIRET *parc)
     302{
     303    PVOID pv;
     304    *parc = NO_ERROR;
     305    if (!(pv = malloc(cb)))
     306        *parc = ERROR_NOT_ENOUGH_MEMORY;
     307
     308    return (pv);
     309}
    288310
    289311/*
     
    12811303 *      Use doshQueryPathSize to query the size of
    12821304 *      any file.
    1283  */
    1284 
    1285 ULONG doshQueryFileSize(HFILE hFile)
    1286 {
     1305 *
     1306 *@@changed V0.9.16 (2001-10-19) [umoeller]: now returning APIRET
     1307 */
     1308
     1309APIRET doshQueryFileSize(HFILE hFile,
     1310                         PULONG pulSize)
     1311{
     1312    APIRET arc;
    12871313    FILESTATUS3 fs3;
    1288     if (DosQueryFileInfo(hFile, FIL_STANDARD, &fs3, sizeof(fs3)))
    1289         return (0);
    1290     else
    1291         return (fs3.cbFile);
     1314    if (!(arc = DosQueryFileInfo(hFile, FIL_STANDARD, &fs3, sizeof(fs3))))
     1315        *pulSize = fs3.cbFile;
     1316    return (arc);
    12921317}
    12931318
     
    12991324 *      Use doshQueryFileSize instead to query the
    13001325 *      size if you have a HFILE.
    1301  */
    1302 
    1303 ULONG doshQueryPathSize(PSZ pszFile)
    1304 {
     1326 *
     1327 *@@changed V0.9.16 (2001-10-19) [umoeller]: now returning APIRET
     1328 */
     1329
     1330APIRET doshQueryPathSize(PCSZ pcszFile,
     1331                         PULONG pulSize)
     1332{
     1333    APIRET arc;
    13051334    FILESTATUS3 fs3;
    1306     if (DosQueryPathInfo(pszFile, FIL_STANDARD, &fs3, sizeof(fs3)))
    1307         return (0);
    1308     else
    1309         return (fs3.cbFile);
     1335    if (!(arc = DosQueryPathInfo((PSZ)pcszFile, FIL_STANDARD, &fs3, sizeof(fs3))))
     1336        *pulSize = fs3.cbFile;
     1337    return (arc);
    13101338}
    13111339
     
    14991527
    15001528/*
     1529 * doshOpen:
     1530 *      wrapper around DosOpen for simpler opening
     1531 *      of files.
     1532 *
     1533 *      ulOpenMode determines the mode to open the
     1534 *      file in:
     1535 *
     1536 +      +-------------------------+------+-----------+-----------+
     1537 +      |                         |      |           |           |
     1538 +      |  ulOpenMode             | mode | if exists | if new    |
     1539 +      +-------------------------+------+-----------+-----------+
     1540 +      |  XOPEN_READ_EXISTING    | read | opens     | fails     |
     1541 +      +-------------------------+------+-----------+-----------+
     1542 +      |  XOPEN_READWRITE_APPEND | r/w  | opens,    | creates   |
     1543 +      |                         |      | appends   |           |
     1544 +      +-------------------------+------+-----------+-----------+
     1545 +      |  XOPEN_READWRITE_NEW    | r/w  | replaces  | creates   |
     1546 +      +-------------------------+------+-----------+-----------+
     1547 *
     1548 *      *ppFile receives a new XFILE structure describing
     1549 *      the open file, if NO_ERROR is returned.
     1550 *
     1551 *@@added V0.9.16 (2001-10-19) [umoeller]
     1552 */
     1553
     1554APIRET doshOpen(const char *pcszFilename,   // in: filename to open
     1555                ULONG ulOpenMode,       // in: XOPEN_* mode
     1556                PULONG pcbFile,         // in: new file size (if new file is created)
     1557                                        // out: file size
     1558                PXFILE *ppFile)
     1559{
     1560    APIRET arc = NO_ERROR;
     1561
     1562    ULONG   fsOpenFlags = 0,
     1563            fsOpenMode =    OPEN_FLAGS_FAIL_ON_ERROR
     1564                          | OPEN_FLAGS_NO_LOCALITY
     1565                          | OPEN_FLAGS_NOINHERIT;
     1566
     1567    switch (ulOpenMode)
     1568    {
     1569        case XOPEN_READ_EXISTING:
     1570            fsOpenFlags =   OPEN_ACTION_FAIL_IF_NEW
     1571                          | OPEN_ACTION_OPEN_IF_EXISTS;
     1572            fsOpenMode |=   OPEN_SHARE_DENYWRITE
     1573                          | OPEN_ACCESS_READONLY;
     1574        break;
     1575
     1576        case XOPEN_READWRITE_APPEND:
     1577            fsOpenFlags =   OPEN_ACTION_CREATE_IF_NEW
     1578                          | OPEN_ACTION_OPEN_IF_EXISTS;
     1579            fsOpenMode |=   OPEN_SHARE_DENYREADWRITE
     1580                          | OPEN_ACCESS_READWRITE;
     1581        break;
     1582
     1583        case XOPEN_READWRITE_NEW:
     1584            fsOpenFlags =   OPEN_ACTION_CREATE_IF_NEW
     1585                          | OPEN_ACTION_REPLACE_IF_EXISTS;
     1586            fsOpenMode |=   OPEN_SHARE_DENYREADWRITE
     1587                          | OPEN_ACCESS_READWRITE;
     1588        break;
     1589    }
     1590
     1591    if (pcszFilename && fsOpenFlags && pcbFile && ppFile)
     1592    {
     1593        PXFILE pFile;
     1594        if (pFile = NEW(XFILE))
     1595        {
     1596            ULONG ulAction;
     1597
     1598            ZERO(pFile);
     1599
     1600            if (!(arc = DosOpen((PSZ)pcszFilename,
     1601                                &pFile->hf,
     1602                                &ulAction,
     1603                                *pcbFile,
     1604                                FILE_ARCHIVED,
     1605                                fsOpenFlags,
     1606                                fsOpenMode,
     1607                                NULL)))       // EAs
     1608            {
     1609                // alright, got the file:
     1610
     1611                if (    (ulAction == FILE_EXISTED)
     1612                     && (ulOpenMode == XOPEN_READWRITE_APPEND)
     1613                   )
     1614                    // get its size and set ptr to end for append
     1615                    arc = DosSetFilePtr(pFile->hf,
     1616                                        0,
     1617                                        FILE_END,
     1618                                        pcbFile);
     1619                else
     1620                    arc = doshQueryFileSize(pFile->hf,
     1621                                            pcbFile);
     1622                    // file ptr is at beginning
     1623
     1624                // store file size
     1625                pFile->cbInitial
     1626                = pFile->cbCurrent
     1627                = *pcbFile;
     1628            }
     1629
     1630            if (arc)
     1631                doshClose(&pFile);
     1632            else
     1633                *ppFile = pFile;
     1634        }
     1635        else
     1636            arc = ERROR_NOT_ENOUGH_MEMORY;
     1637    }
     1638    else
     1639        arc = ERROR_INVALID_PARAMETER;
     1640
     1641    return (arc);
     1642}
     1643
     1644/*
     1645 *@@ doshLockFile:
     1646 *
     1647 *@@added V0.9.16 (2001-10-19) [umoeller]
     1648 */
     1649
     1650APIRET doshLockFile(PXFILE pFile)
     1651{
     1652    if (!pFile)
     1653        return (ERROR_INVALID_PARAMETER);
     1654
     1655    if (!pFile->hmtx)
     1656        // first call:
     1657        return (DosCreateMutexSem(NULL,
     1658                                  &pFile->hmtx,
     1659                                  0,
     1660                                  TRUE));        // request!
     1661
     1662    return (DosRequestMutexSem(pFile->hmtx, SEM_INDEFINITE_WAIT));
     1663}
     1664
     1665/*
     1666 *@@ doshUnlockFile:
     1667 *
     1668 *@@added V0.9.16 (2001-10-19) [umoeller]
     1669 */
     1670
     1671APIRET doshUnlockFile(PXFILE pFile)
     1672{
     1673    if (pFile)
     1674        return (DosReleaseMutexSem(pFile->hmtx));
     1675
     1676    return (ERROR_INVALID_PARAMETER);
     1677}
     1678
     1679/*
     1680 *@@ doshWrite:
     1681 *      writes the specified data to the file.
     1682 *      If (cb == 0), this runs strlen on pcsz
     1683 *      to find out the length.
     1684 *
     1685 *@@added V0.9.16 (2001-10-19) [umoeller]
     1686 */
     1687
     1688APIRET doshWrite(PXFILE pFile,
     1689                 PCSZ pcsz,
     1690                 ULONG cb)
     1691{
     1692    APIRET arc;
     1693    if (!pcsz)
     1694        arc = ERROR_INVALID_PARAMETER;
     1695    else
     1696    {
     1697        if (!cb)
     1698            cb = strlen(pcsz);
     1699
     1700        if (!cb)
     1701            arc = ERROR_INVALID_PARAMETER;
     1702        else
     1703            if (!(arc = doshLockFile(pFile)))   // this checks for pFile
     1704            {
     1705                ULONG cbWritten;
     1706                if (!(arc = DosWrite(pFile->hf,
     1707                                     (PSZ)pcsz,
     1708                                     cb,
     1709                                     &cbWritten)))
     1710                    pFile->cbCurrent += cbWritten;
     1711
     1712                doshUnlockFile(pFile);
     1713            }
     1714    }
     1715
     1716    return (arc);
     1717}
     1718
     1719/*
     1720 *@@ doshWriteLogEntry
     1721 *      writes a log string to an XFILE, adding a
     1722 *      leading timestamp before the line.
     1723 *
     1724 *      The internal string buffer is limited to 2000
     1725 *      characters. \n is NOT translated to \r\n before
     1726 *      writing.
     1727 */
     1728
     1729APIRET doshWriteLogEntry(PXFILE pFile,
     1730                         const char* pcszFormat,
     1731                         ...)
     1732{
     1733    APIRET arc;
     1734
     1735    DATETIME dt;
     1736    CHAR szTemp[2000];
     1737    ULONG   ulLength;
     1738
     1739    DosGetDateTime(&dt);
     1740    if (ulLength = sprintf(szTemp,
     1741                           "%04d-%02d-%02d %02d:%02d:%02d:%02d ",
     1742                           dt.year, dt.month, dt.day,
     1743                           dt.hours, dt.minutes, dt.seconds, dt.hundredths))
     1744    {
     1745        if (!(arc = doshWrite(pFile,
     1746                              szTemp,
     1747                              ulLength)))
     1748        {
     1749            va_list arg_ptr;
     1750            va_start(arg_ptr, pcszFormat);
     1751            ulLength = vsprintf(szTemp, pcszFormat, arg_ptr);
     1752            va_end(arg_ptr);
     1753
     1754            szTemp[ulLength++] = '\r';
     1755            szTemp[ulLength++] = '\n';
     1756
     1757            arc = doshWrite(pFile,
     1758                            (PVOID)szTemp,
     1759                            ulLength);
     1760        }
     1761    }
     1762
     1763    return (arc);
     1764}
     1765
     1766/*
     1767 * doshClose:
     1768 *
     1769 *@@added V0.9.16 (2001-10-19) [umoeller]
     1770 */
     1771
     1772APIRET doshClose(PXFILE *ppFile)
     1773{
     1774    APIRET arc = NO_ERROR;
     1775    PXFILE pFile;
     1776
     1777    if (    (ppFile)
     1778         && (pFile = *ppFile)
     1779       )
     1780    {
     1781        // request the mutex so that we won't be
     1782        // taking the file away under someone's butt
     1783        if (!(arc = doshLockFile(pFile)))
     1784        {
     1785            HMTX hmtx = pFile->hmtx;
     1786            pFile->hmtx = NULLHANDLE;
     1787
     1788            // now that the file is locked,
     1789            // set the ptr to NULL
     1790            *ppFile = NULL;
     1791
     1792            if (pFile->hf)
     1793            {
     1794                DosSetFileSize(pFile->hf, pFile->cbCurrent);
     1795                DosClose(pFile->hf);
     1796                pFile->hf = NULLHANDLE;
     1797            }
     1798
     1799            doshUnlockFile(pFile);
     1800            DosCloseMutexSem(pFile->hmtx);
     1801        }
     1802
     1803        free(pFile);
     1804    }
     1805    else
     1806        arc = ERROR_INVALID_PARAMETER;
     1807
     1808    return (arc);
     1809}
     1810
     1811/*
    15011812 *@@ doshLoadTextFile:
    15021813 *      reads a text file from disk, allocates memory
     
    15211832    PSZ     pszContent = NULL;
    15221833
    1523     APIRET arc = DosOpen((PSZ)pcszFile,
    1524                          &hFile,
    1525                          &ulAction,                      // action taken
    1526                          5000L,                          // primary allocation size
    1527                          FILE_ARCHIVED | FILE_NORMAL,    // file attribute
    1528                          OPEN_ACTION_OPEN_IF_EXISTS,     // open flags
    1529                          OPEN_FLAGS_NOINHERIT
    1530                             | OPEN_SHARE_DENYNONE
    1531                             | OPEN_ACCESS_READONLY,      // read-only mode
    1532                          NULL);                          // no EAs
    1533 
    1534     if (arc == NO_ERROR)
    1535     {
    1536         ulSize = doshQueryFileSize(hFile);
    1537         pszContent = (PSZ)malloc(ulSize+1);
    1538         arc = DosSetFilePtr(hFile,
    1539                             0L,
    1540                             FILE_BEGIN,
    1541                             &ulLocal);
    1542         arc = DosRead(hFile,
    1543                       pszContent,
    1544                       ulSize,
    1545                       &ulBytesRead);
     1834    APIRET arc;
     1835
     1836    *ppszContent = 0;
     1837
     1838    if (!(arc = DosOpen((PSZ)pcszFile,
     1839                        &hFile,
     1840                        &ulAction,                      // action taken
     1841                        5000L,                          // primary allocation size
     1842                        FILE_ARCHIVED | FILE_NORMAL,    // file attribute
     1843                        OPEN_ACTION_OPEN_IF_EXISTS,     // open flags
     1844                        OPEN_FLAGS_NOINHERIT
     1845                           | OPEN_SHARE_DENYNONE
     1846                           | OPEN_ACCESS_READONLY,      // read-only mode
     1847                        NULL)))                         // no EAs
     1848    {
     1849        if (!(arc = doshQueryFileSize(hFile, &ulSize)))
     1850        {
     1851            pszContent = (PSZ)malloc(ulSize+1);
     1852
     1853            if (!(arc = DosSetFilePtr(hFile,
     1854                                      0L,
     1855                                      FILE_BEGIN,
     1856                                      &ulLocal)))
     1857                if (!(arc = DosRead(hFile,
     1858                                    pszContent,
     1859                                    ulSize,
     1860                                    &ulBytesRead)))
     1861                {
     1862                    *(pszContent+ulBytesRead) = 0;
     1863                    // set output buffer pointer
     1864                    *ppszContent = pszContent;
     1865                }
     1866
     1867            if (arc)
     1868                free(pszContent);
     1869        }
    15461870        DosClose(hFile);
    1547         *(pszContent+ulBytesRead) = 0;
    1548 
    1549         // set output buffer pointer
    1550         *ppszContent = pszContent;
    1551     }
    1552     else
    1553         *ppszContent = 0;
     1871    }
    15541872
    15551873    return (arc);
     
    15771895    ULONG   ulCount = 1;
    15781896    CHAR    szCount[5];
     1897    ULONG   ulDummy;
    15791898
    15801899    strcpy(szFilename, pszExisting);
     
    15881907        strcpy(pszLastDot, szCount);
    15891908        ulCount++;
    1590     } while (doshQueryPathSize(szFilename) != 0);
     1909    } while (!doshQueryPathSize(szFilename, &ulDummy));
    15911910
    15921911    return (strdup(szFilename));
     
    18032122        }
    18042123
    1805         arc = DosOpen((PSZ)pszFile,
    1806                       &hFile,
    1807                       &ulAction,                      // action taken
    1808                       ulSize,                         // primary allocation size
    1809                       FILE_ARCHIVED | FILE_NORMAL,    // file attribute
    1810                       OPEN_ACTION_CREATE_IF_NEW
    1811                          | OPEN_ACTION_REPLACE_IF_EXISTS,  // open flags
    1812                       OPEN_FLAGS_NOINHERIT
    1813                          | OPEN_FLAGS_SEQUENTIAL         // sequential, not random access
    1814                          | OPEN_SHARE_DENYWRITE          // deny write mode
    1815                          | OPEN_ACCESS_WRITEONLY,        // write mode
    1816                       NULL);                          // no EAs
    1817 
    1818         if (arc == NO_ERROR)
     2124        if (!(arc = DosOpen((PSZ)pszFile,
     2125                            &hFile,
     2126                            &ulAction,                      // action taken
     2127                            ulSize,                         // primary allocation size
     2128                            FILE_ARCHIVED | FILE_NORMAL,    // file attribute
     2129                            OPEN_ACTION_CREATE_IF_NEW
     2130                               | OPEN_ACTION_REPLACE_IF_EXISTS,  // open flags
     2131                            OPEN_FLAGS_NOINHERIT
     2132                               | OPEN_FLAGS_SEQUENTIAL         // sequential, not random access
     2133                               | OPEN_SHARE_DENYWRITE          // deny write mode
     2134                               | OPEN_ACCESS_WRITEONLY,        // write mode
     2135                            NULL)))                         // no EAs
    18192136        {
    1820             arc = DosSetFilePtr(hFile,
    1821                                 0L,
    1822                                 FILE_BEGIN,
    1823                                 &ulLocal);
    1824             if (arc == NO_ERROR)
    1825             {
    1826                 arc = DosWrite(hFile,
    1827                                (PVOID)pszContent,
    1828                                ulSize,
    1829                                &ulWritten);
    1830                 if (arc == NO_ERROR)
     2137            if (!(arc = DosSetFilePtr(hFile,
     2138                                      0L,
     2139                                      FILE_BEGIN,
     2140                                      &ulLocal)))
     2141                if (!(arc = DosWrite(hFile,
     2142                                     (PVOID)pszContent,
     2143                                     ulSize,
     2144                                     &ulWritten)))
    18312145                    arc = DosSetFileSize(hFile, ulSize);
    1832             }
    18332146
    18342147            DosClose(hFile);
     
    18402153
    18412154    return (arc);
    1842 }
    1843 
    1844 /*
    1845  *@@ doshOpenLogFile:
    1846  *      this opens a log file in the root directory of
    1847  *      the boot drive; it is titled pszFilename, and
    1848  *      the file handle is returned.
    1849  */
    1850 
    1851 HFILE doshOpenLogFile(const char* pcszFilename)
    1852 {
    1853     APIRET  rc;
    1854     CHAR    szFileName[CCHMAXPATH];
    1855     HFILE   hfLog;
    1856     ULONG   ulAction;
    1857     ULONG   ibActual;
    1858 
    1859     sprintf(szFileName, "%c:\\%s", doshQueryBootDrive(), pcszFilename);
    1860     rc = DosOpen(szFileName,
    1861                  &hfLog,
    1862                  &ulAction,
    1863                  0,             // file size
    1864                  FILE_NORMAL,
    1865                  OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
    1866                  OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYWRITE,
    1867                  (PEAOP2)NULL);
    1868     if (rc == NO_ERROR)
    1869     {
    1870         DosSetFilePtr(hfLog, 0, FILE_END, &ibActual);
    1871         return (hfLog);
    1872     }
    1873     else
    1874         return (0);
    1875 }
    1876 
    1877 /*
    1878  * doshWriteToLogFile
    1879  *      writes a string to a log file, adding a
    1880  *      leading timestamp.
    1881  */
    1882 
    1883 APIRET doshWriteToLogFile(HFILE hfLog, const char* pcsz)
    1884 {
    1885     if (hfLog)
    1886     {
    1887         DATETIME dt;
    1888         CHAR szTemp[2000];
    1889         ULONG   cbWritten;
    1890         DosGetDateTime(&dt);
    1891         sprintf(szTemp,
    1892                 "Time: %02d:%02d:%02d %s",
    1893                 dt.hours, dt.minutes, dt.seconds,
    1894                 pcsz);
    1895         return (DosWrite(hfLog, (PVOID)szTemp, strlen(szTemp), &cbWritten));
    1896     }
    1897     else return (ERROR_INVALID_HANDLE);
    18982155}
    18992156
  • trunk/src/helpers/helpers_pre.in

    r108 r113  
    5959$(OUTPUTDIR)\eah.obj \
    6060$(OUTPUTDIR)\except.obj \
     61$(OUTPUTDIR)\lan.obj \
    6162$(OUTPUTDIR)\level.obj \
    6263$(OUTPUTDIR)\nls.obj \
  • trunk/src/helpers/linklist.c

    r91 r113  
    585585        if (pList->ulMagic == LINKLISTMAGIC)
    586586        {
    587             pNewNode = (PLISTNODE)memdMalloc(sizeof(LISTNODE), file, line, function);
    588             if (pNewNode)
     587            if (pNewNode = (PLISTNODE)memdMalloc(sizeof(LISTNODE), file, line, function))
    589588            {
    590589                memset(pNewNode, 0, sizeof(LISTNODE));
     
    641640        if (pList->ulMagic == LINKLISTMAGIC)
    642641        {
    643             pNewNode = (PLISTNODE)malloc(sizeof(LISTNODE));
    644             if (pNewNode)
     642            if (pNewNode = (PLISTNODE)malloc(sizeof(LISTNODE)))
    645643            {
    646644                memset(pNewNode, 0, sizeof(LISTNODE));
     
    710708        if (pList->ulMagic == LINKLISTMAGIC)
    711709        {
    712             pNewNode = (PLISTNODE)malloc(sizeof(LISTNODE));
    713             if (pNewNode)
     710            if (pNewNode = (PLISTNODE)malloc(sizeof(LISTNODE)))
    714711            {
    715712                memset(pNewNode, 0, sizeof(LISTNODE));
  • trunk/src/helpers/nls.c

    r109 r113  
    1818 *
    1919 *@@header "helpers\nls.h"
     20 *@@added V0.9.16 (2001-10-11) [umoeller]
    2021 */
    2122
  • trunk/src/helpers/semaphores.c

    r83 r113  
    231231               )
    232232            {
    233                 treeInit(&pMutex->ReaderThreadsTree);
     233                treeInit(&pMutex->ReaderThreadsTree, NULL);
    234234            }
    235235        }
     
    281281                   )
    282282                {
    283                     ULONG cItems = pMutex->cReaderThreads;
     283                    LONG cItems = pMutex->cReaderThreads;
    284284                    TREE **papNodes = treeBuildArray(pMutex->ReaderThreadsTree,
    285285                                                     &cItems);
     
    424424
    425425                        treeInsert(&pMutex->ReaderThreadsTree,
     426                                   NULL,
    426427                                   (TREE*)pReader,
    427428                                   treeCompareKeys);
  • trunk/src/helpers/tmsgfile.c

    r108 r113  
    177177            ZERO(pFile);
    178178            pFile->pszFilename = strdup(pcszMessageFile);
    179             treeInit(&pFile->IDsTreeRoot);
     179            treeInit(&pFile->IDsTreeRoot, NULL);
    180180
    181181            xstrInitSet(&pFile->strContent, pszContent);
     
    294294                    // store this thing
    295295                    if (!treeInsert(&pFile->IDsTreeRoot,
     296                                    NULL,
    296297                                    (TREE*)pNew,
    297298                                    treeCompareStrings))
     
    332333    {
    333334        PTMFMSGFILE pFile = *ppMsgFile;
    334         ULONG   cItems;
     335        LONG   cItems;
    335336        TREE**  papNodes;
    336337
  • trunk/src/helpers/tree.c

    r106 r113  
    285285 *      initializes the root of a tree.
    286286 *
    287  */
    288 
    289 void treeInit(TREE **root)
     287 *@@changed V0.9.16 (2001-10-19) [umoeller]: added plCount
     288 */
     289
     290void treeInit(TREE **root,
     291              PLONG plCount)            // out: tree item count, set to 0 (ptr can be NULL)
    290292{
    291293    *root = LEAF;
     294
     295    if (plCount)
     296        *plCount = 0;       // V0.9.16 (2001-10-19) [umoeller]
    292297}
    293298
     
    511516 *      STATUS_DUPLICATE_KEY if a node with the
    512517 *      same ulKey already exists.
     518 *
     519 *@@changed V0.9.16 (2001-10-19) [umoeller]: added plCount
    513520 */
    514521
    515522int treeInsert(TREE **root,                     // in: root of the tree
     523               PLONG plCount,                 // in/out: item count (ptr can be NULL)
    516524               TREE *x,                         // in: new node to insert
    517525               FNTREE_COMPARE *pfnCompare)      // in: comparison func
     
    531539        if (0 == (iResult = pfnCompare(key, current->ulKey))) // if (compEQ(key, current->key))
    532540            return STATUS_DUPLICATE_KEY;
     541
    533542        parent = current;
    534543        current = (iResult < 0)    // compLT(key, current->key)
     
    561570                x);
    562571    // lastFind = NULL;
     572
     573    if (plCount)
     574        (*plCount)++;       // V0.9.16 (2001-10-19) [umoeller]
    563575
    564576    return STATUS_OK;
     
    740752 *      Returns 0 if the node was deleted or
    741753 *      STATUS_INVALID_NODE if not.
     754 *
     755 *@@changed V0.9.16 (2001-10-19) [umoeller]: added plCount
    742756 */
    743757
    744758int treeDelete(TREE **root,         // in: root of the tree
     759               PLONG plCount,     // in/out: item count (ptr can be NULL)
    745760               TREE *tree)          // in: tree node to delete
    746761{
     
    820835                    y);
    821836
     837    if (plCount)
     838        (*plCount)--;       // V0.9.16 (2001-10-19) [umoeller]
     839
    822840    return (STATUS_OK);
    823 
    824     /* TREE    *x,
    825             *y; */
    826             // *z;
    827 
    828    /*****************************
    829     *  delete node z from tree  *
    830     *****************************/
    831 
    832     // find node in tree
    833     /* if (lastFind && compEQ(lastFind->key, key))
    834         // if we just found node, use pointer
    835         z = lastFind;
    836     else {
    837         z = *root;
    838         while(z != LEAF)
    839         {
    840             int iResult = pfnCompare(key, z->key);
    841             if (iResult == 0)
    842             // if(compEQ(key, z->key))
    843                 break;
    844             else
    845                 z = (iResult < 0) // compLT(key, z->key)
    846                     ? z->left
    847                     : z->right;
    848         }
    849         if (z == LEAF)
    850             return STATUS_KEY_NOT_FOUND;
    851     }
    852 
    853     if (    z->left == LEAF
    854          || z->right == LEAF
    855        )
    856     {
    857         // y has a LEAF node as a child
    858         y = z;
    859     }
    860     else
    861     {
    862         // find tree successor with a LEAF node as a child
    863         y = z->right;
    864         while (y->left != LEAF)
    865             y = y->left;
    866     }
    867 
    868     // x is y's only child
    869     if (y->left != LEAF)
    870         x = y->left;
    871     else
    872         x = y->right;
    873 
    874     // remove y from the parent chain
    875     x->parent = y->parent;
    876     if (y->parent)
    877         if (y == y->parent->left)
    878             y->parent->left = x;
    879         else
    880             y->parent->right = x;
    881     else
    882         *root = x;
    883 
    884     // y is about to be deleted...
    885 
    886     if (y != z)
    887     {
    888         // now, the original code simply copied the data
    889         // from y to z... we can't safely do that since
    890         // we don't know about the real data in the
    891         // caller's TREE structure
    892         z->ulKey = y->ulKey;
    893         // z->rec = y->rec;         // hope this works...
    894                                     // the original implementation used rec
    895                                     // for the node's data
    896 
    897         if (cbStruct > sizeof(TREE))
    898         {
    899             memcpy(((char*)&z) + sizeof(TREE),
    900                    ((char*)&y) + sizeof(TREE),
    901                    cbStruct - sizeof(TREE));
    902         }
    903     }
    904 
    905     if (y->color == BLACK)
    906         deleteFixup(root,
    907                     x);
    908 
    909     // free(y);
    910     // lastFind = NULL;
    911 
    912     return STATUS_OK; */
    913841}
    914842
     
    11201048
    11211049TREE** treeBuildArray(TREE* pRoot,
    1122                       unsigned long *pulCount)  // in: item count, out: array item count
     1050                      PLONG plCount)  // in: item count, out: array item count
    11231051{
    11241052    TREE            **papNodes = NULL,
    11251053                    **papThis = NULL;
    1126     unsigned long   cb = (sizeof(TREE*) * (*pulCount)),
     1054    long            cb = (sizeof(TREE*) * (*plCount)),
    11271055                    cNodes = 0;
    11281056
     
    11401068            // copy nodes to array
    11411069            while (    pNode
    1142                     && cNodes < (*pulCount)     // just to make sure
     1070                    && cNodes < (*plCount)     // just to make sure
    11431071                  )
    11441072            {
     
    11511079
    11521080            // output count
    1153             *pulCount = cNodes;
     1081            *plCount = cNodes;
    11541082        }
    11551083    }
  • trunk/src/helpers/winh.c

    r111 r113  
    31883188{
    31893189    HAB hab = NULLHANDLE;
    3190     HWND hwnd = winhCreateObjectWindow(WC_BUTTON, NULL);
    3191     if (hwnd)
     3190    HWND hwnd;
     3191    if (hwnd = winhCreateObjectWindow(WC_BUTTON, NULL))
    31923192    {
    31933193        hab = WinQueryAnchorBlock(hwnd);
  • trunk/src/helpers/wphandle.c

    r110 r113  
    4646
    4747#define INCL_WINSHELLDATA
     48#define INCL_WINNLS
    4849#include <os2.h>
    4950
     
    5758
    5859#include "helpers\except.h"
     60#include "helpers\linklist.h"
    5961#include "helpers\prfh.h"
    6062#include "helpers\standards.h"
    6163#include "helpers\stringh.h"
     64#include "helpers\tree.h"
     65#include "helpers\xstring.h"
     66
     67#define INCLUDE_WPHANDLE_PRIVATE
    6268#include "helpers\wphandle.h"
    63 #include "helpers\xstring.h"
    6469
    6570/*
     
    185190
    186191/*
     192 *@@ FreeChildrenTree:
     193 *      called from NukeNameTrees for recursion.
     194 *
     195 *@@added V0.9.16 (2001-10-19) [umoeller]
     196 */
     197
     198VOID FreeChildrenTree(TREE **ppChildrenTree,
     199                      PLONG plCount)
     200{
     201    LONG    cItems = *plCount;
     202    TREE**  papNodes = treeBuildArray(*ppChildrenTree,
     203                                      &cItems);
     204    if (papNodes)
     205    {
     206        ULONG ul;
     207        for (ul = 0; ul < cItems; ul++)
     208        {
     209            PNODETREENODE pNodeThis = (PNODETREENODE)papNodes[ul];
     210
     211            FreeChildrenTree(&pNodeThis->ChildrenTree,
     212                             &pNodeThis->cChildren);
     213
     214            free(pNodeThis);
     215        }
     216
     217        free(papNodes);
     218        *plCount = 0;
     219
     220        treeInit(ppChildrenTree, plCount);
     221    }
     222}
     223
     224/*
     225 *@@ NukeNameTrees:
     226 *      frees all cache trees.
     227 *
     228 *@@added V0.9.16 (2001-10-19) [umoeller]
     229 */
     230
     231APIRET NukeNameTrees(PHANDLESBUF pHandlesBuf)
     232{
     233    APIRET arc = NO_ERROR;
     234
     235    LONG    cItems = pHandlesBuf->cDrives;
     236    TREE**  papNodes = treeBuildArray(pHandlesBuf->DrivesTree,
     237                                      &cItems);
     238    if (papNodes)
     239    {
     240        ULONG ul;
     241        for (ul = 0; ul < cItems; ul++)
     242        {
     243            PDRIVETREENODE pNodeThis = (PDRIVETREENODE)papNodes[ul];
     244
     245            FreeChildrenTree(&pNodeThis->ChildrenTree,
     246                             &pNodeThis->cChildren);
     247
     248            free(pNodeThis);
     249        }
     250
     251        free(papNodes);
     252
     253        treeInit(&pHandlesBuf->DrivesTree,
     254                 &pHandlesBuf->cDrives);
     255    }
     256
     257    return (arc);
     258}
     259
     260/*
    187261 *@@ wphRebuildNodeHashTable:
    188262 *
     
    198272 */
    199273
    200 APIRET wphRebuildNodeHashTable(PHANDLESBUF pHandlesBuf)
     274APIRET wphRebuildNodeHashTable(HHANDLES hHandles)
    201275{
    202276    APIRET arc = NO_ERROR;
    203277
    204     if (    (!pHandlesBuf)
     278    PHANDLESBUF pHandlesBuf;
     279
     280    if (    (!(pHandlesBuf = (PHANDLESBUF)hHandles))
    205281         || (!pHandlesBuf->pbData)
    206282         || (!pHandlesBuf->cbData)
     
    213289        PBYTE pEnd = pHandlesBuf->pbData + pHandlesBuf->cbData;
    214290
     291        PDRIVETREENODE  pLastDriveTreeNode = NULL;
     292
    215293        memset(pHandlesBuf->NodeHashTable, 0, sizeof(pHandlesBuf->NodeHashTable));
     294        NukeNameTrees(pHandlesBuf);
    216295
    217296        // now set up hash table
    218         while (pCur < pEnd)
     297        while (    (pCur < pEnd)
     298                && (!arc)
     299              )
    219300        {
    220301            if (!memicmp(pCur, "DRIV", 4))
     
    222303                // pCur points to a DRIVE node:
    223304                // these never have handles, so skip this
    224                 PDRIV pDriv = (PDRIV)pCur;
    225                 pCur += sizeof(DRIV) + strlen(pDriv->szName);
     305                PDRIVE pDriv = (PDRIVE)pCur;
     306
     307                // upper the node name for string comparisons
     308                strupr(pDriv->szName);
     309
     310                // create a drive tree node
     311                // (stored so we can append to this)
     312                if (!(pLastDriveTreeNode = NEW(DRIVETREENODE)))
     313                    arc = ERROR_NOT_ENOUGH_MEMORY;
     314                else
     315                {
     316                    pLastDriveTreeNode->Tree.ulKey = (ULONG)pDriv->szName;
     317                    pLastDriveTreeNode->pDriv = pDriv;
     318                    treeInit(&pLastDriveTreeNode->ChildrenTree,
     319                             &pLastDriveTreeNode->cChildren);
     320                    if (treeInsert(&pHandlesBuf->DrivesTree,
     321                                   &pHandlesBuf->cDrives,
     322                                   (TREE*)pLastDriveTreeNode,
     323                                   treeCompareStrings))
     324                        arc = ERROR_WPH_DRIV_TREEINSERT_FAILED;
     325                }
     326
     327                // next item
     328                pCur += sizeof(DRIVE) + strlen(pDriv->szName);
    226329            }
    227330            else if (!memicmp(pCur, "NODE", 4))
     
    229332                // pCur points to a regular NODE: offset pointer first
    230333                PNODE pNode = (PNODE)pCur;
    231                 // store PNODE in hash table
    232                 pHandlesBuf->NodeHashTable[pNode->usHandle] = pNode;
     334                PNODETREENODE pNew;
     335
     336                // upper the node name for string comparisons
     337                strupr(pNode->szName);
     338
     339                // create a node tree node
     340                if (!(pNew = NEW(NODETREENODE)))
     341                    arc = ERROR_NOT_ENOUGH_MEMORY;
     342                else
     343                {
     344                    TREE **ppTree = NULL;
     345                    PLONG pcChildren = NULL;
     346
     347                    pNew->Tree.ulKey = (ULONG)pNode->szName;
     348                    pNew->pNode = pNode;
     349                    treeInit(&pNew->ChildrenTree,
     350                             &pNew->cChildren);
     351                    // now check where to insert this...
     352                    // does it have a parent?
     353                    if (pNode->usParentHandle)
     354                    {
     355                        PNODETREENODE pParent;
     356                        if (!(pParent = pHandlesBuf->NodeHashTable[pNode->usParentHandle]))
     357                            // this parent handle is invalid:
     358                            arc = ERROR_WPH_INVALID_PARENT_HANDLE;
     359                        else
     360                        {
     361                            ppTree = &pParent->ChildrenTree;
     362                            pcChildren = &pParent->cChildren;
     363                        }
     364                    }
     365                    else
     366                        // null parent handle: then the parent
     367                        // must be a DRIVE node
     368                        if (pLastDriveTreeNode)
     369                        {
     370                            ppTree = &pLastDriveTreeNode->ChildrenTree;
     371                            pcChildren = &pLastDriveTreeNode->cChildren;
     372                        }
     373                        else
     374                            arc = ERROR_WPH_NODE_BEFORE_DRIV;
     375
     376                    if (!arc)
     377                        if (treeInsert(ppTree,
     378                                       pcChildren,
     379                                       (TREE*)pNew,
     380                                       treeCompareStrings))
     381                            ; // @@todo if this fails, there are
     382                            // several handles for short name!!!
     383                            // arc = ERROR_WPH_NODE_TREEINSERT_FAILED;
     384
     385                    // store PNODE in hash table
     386                    pHandlesBuf->NodeHashTable[pNode->usHandle] = pNew;
     387                }
     388
    233389                pCur += sizeof(NODE) + pNode->usNameSize;
    234390            }
     
    242398
    243399    if (!arc)
    244         pHandlesBuf->fNodeHashTableValid = TRUE;
     400        pHandlesBuf->fCacheValid = TRUE;
    245401
    246402    return (arc);
     
    279435                      HINI hiniSystem,    // in: HINI_SYSTEM or other INI handle
    280436                      const char *pcszActiveHandles,
    281                       PHANDLESBUF *ppHandlesBuf)
     437                      HHANDLES *phHandles)
    282438{
    283439    APIRET arc = NO_ERROR;
    284440
    285     if (!ppHandlesBuf)
     441    if (!phHandles)
    286442        arc = ERROR_INVALID_PARAMETER;
    287443    else
     
    369525                    ZERO(pReturn);
    370526
     527                    treeInit(&pReturn->DrivesTree,
     528                             &pReturn->cDrives);
     529
    371530                    pReturn->pbData = pbData;
    372531                    pReturn->cbData = cbTotal;
     
    376535                                                           &pReturn->usHiwordAbstract,
    377536                                                           &pReturn->usHiwordFileSystem)))
    378                         *ppHandlesBuf = pReturn;
     537                        *phHandles = (HHANDLES)pReturn;
    379538                }
    380539                else
     
    384543            if (arc)
    385544                // error:
    386                 wphFreeHandles(&pReturn);
     545                wphFreeHandles((HHANDLES*)&pReturn);
    387546        }
    388547    }
     
    399558 */
    400559
    401 APIRET wphFreeHandles(PHANDLESBUF *ppHandlesBuf)
     560APIRET wphFreeHandles(HHANDLES *phHandles)
    402561{
    403562    APIRET arc = NO_ERROR;
    404563
    405     if (ppHandlesBuf && *ppHandlesBuf)
     564    PHANDLESBUF pHandlesBuf;
     565    if (    (phHandles)
     566         && (pHandlesBuf = (PHANDLESBUF)*phHandles)
     567       )
    406568    {
    407569        PBYTE pbData;
    408         if (pbData = (*ppHandlesBuf)->pbData)
     570
     571        NukeNameTrees(pHandlesBuf);
     572
     573        if (pbData = pHandlesBuf->pbData)
    409574            free(pbData);
    410575
    411         free(*ppHandlesBuf);
    412         *ppHandlesBuf = NULL;
     576        free(pHandlesBuf);
     577        *phHandles = NULLHANDLE;
    413578    }
    414579    else
     
    426591/*
    427592 *@@ wphSearchBufferForHandle:
    428  *      returns the four-digit object handle which corresponds
     593 *      returns the 16-bit file-system handle which corresponds
    429594 *      to pszFilename, searching pHandlesBuffer. Note that you
    430  *      must OR the return value with 0x30000 to make this
    431  *      a valid WPS file-system handle.
     595 *      must OR the return value with the proper hiword to make
     596 *      this a valid WPS file-system handle.
    432597 *
    433598 *      You must pass a handles buffer to this function which
     
    436601 *      This gets called by the one-shot function
    437602 *      wphQueryHandleFromPath.
    438  */
    439 
    440 USHORT wphSearchBufferForHandle(PBYTE pHandlesBuffer, // in: handles buffer (all BLOCK's)
    441                                 ULONG ulBufSize,      // in: sizeof(pHandlesBuffer)
    442                                 USHORT usParent,      // in: parent NODE ID;
    443                                                       //     must be 0 initially
    444                                 PSZ pszFilename) // in: fully qlf'd filename to search for
    445 {
    446     PDRIV pDriv;
    447     PNODE pNode;
    448     PBYTE pCur;                 // current
    449     PBYTE p,
    450           pEnd;                 // *end of buffer
    451     USHORT usPartSize;
    452 
    453     // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszFilename));
    454 
    455     // The composed BLOCKs in the handles buffer make up a tree of
    456     // DRIVE and NODE structures (see wphandle.h). Each NODE stands
    457     // for either a directory or a file. (We don't care about the
    458     // DRIVE structures because the root directory gets a NODE also.)
    459     // Each NODE contains the non-qualified file name, an object ID,
    460     // and the object ID of its parent NODE.
    461     // We can thus work our way through the buffer by splitting the
    462     // fully qualified filename that we're searching for into the
    463     // different directory names and, each time, searching for the
    464     // corresponding NODE. If we have found that, we go for the next.
    465     // Example for C:\OS2\E.EXE:
    466     //   1) first search for the "C:" NODE
    467     //   2) then find the "OS2" node which has "C" as its parent NODE
    468     //      (we do this by comparing the parent object handles)
    469     //   3) then find the "E.EXE" NODE the same way
    470     // The "E.EXE" NODE then has the object handle we're looking for.
    471 
    472     // So first find the length of the first filename part (which
    473     // should be 2 for the drive letter, "C:")
    474     p = strchr(pszFilename, '\\');
    475     if (p)
    476         // backslash found:
    477         usPartSize = p - pszFilename;      // extract first part
     603 *
     604 *      Returns:
     605 *
     606 *      --  NO_ERROR
     607 *
     608 *      --  ERROR_INVALID_PARAMETER
     609 *
     610 *      --  ERROR_FILE_NOT_FOUND
     611 *
     612 *      --  ERROR_INVALID_NAME
     613 *
     614 *      --  ERROR_WPH_CORRUPT_HANDLES_DATA
     615 *
     616 *      --  ERROR_WPH_CANNOT_FIND_HANDLE: no handle exists for the
     617 *          given filename.
     618 *
     619 *@@changed V0.9.16 (2001-10-19) [umoeller]: rewritten
     620 */
     621
     622APIRET wphSearchBufferForHandle(HHANDLES hHandles,
     623                                PCSZ pcszFile,  // in: fully qlf'd filename to search for
     624                                PUSHORT pusHandle)  // out: 16-bit handle
     625{
     626    APIRET arc = NO_ERROR;
     627
     628    PHANDLESBUF pHandlesBuf;
     629
     630    _Pmpf((__FUNCTION__ ": entering"));
     631
     632    if (    (hHandles)
     633         && (pHandlesBuf = (PHANDLESBUF)hHandles)
     634       )
     635    {
     636        // rebuild cache
     637        if (!pHandlesBuf->fCacheValid)
     638            arc = wphRebuildNodeHashTable(hHandles);
     639
     640        if (!arc)
     641        {
     642            // We can thus work our way through the buffer by splitting the
     643            // fully qualified filename that we're searching for into the
     644            // different directory names and, each time, searching for the
     645            // corresponding NODE. If we have found that, we go for the next.
     646            // Example for C:\OS2\E.EXE:
     647            //   1) first search for the "C:" NODE
     648            //   2) then find the "OS2" node which has "C" as its parent NODE
     649            //      (we do this by comparing the parent object handles)
     650            //   3) then find the "E.EXE" NODE the same way
     651            // The "E.EXE" NODE then has the object handle we're looking for.
     652
     653            // make a copy of the filename so we can play
     654            PSZ     pszFilename = strdup(pcszFile),
     655                    pEnd = NULL;
     656
     657            strupr(pszFilename);
     658
     659            // 1) OK, find the drive.
     660
     661            // If this is an UNC name, the DRIVE node has the form
     662            // \\SERVER\RESOURCE.
     663            if (    (*pszFilename == '\\')
     664                 && (*(pszFilename + 1) == '\\')
     665               )
     666            {
     667                // UNC:
     668                // @@todo
     669            }
     670            else if (*(pszFilename + 1) == ':')
     671                // extract the drive then (without \)
     672                pEnd = pszFilename + 2;
     673
     674            if (!pEnd)
     675                arc = ERROR_INVALID_NAME;
     676            else
     677            {
     678                PDRIVETREENODE pDrive = NULL;
     679                PNODETREENODE pNode;
     680
     681                // find the DRIVE node
     682                CHAR cOld = *pEnd;
     683                *pEnd = 0;
     684
     685                _Pmpf(("  searching for drive \"%s\"", pszFilename));
     686
     687                if (!(pDrive = (PDRIVETREENODE)treeFind(pHandlesBuf->DrivesTree,
     688                                                        (ULONG)pszFilename,   // drive name
     689                                                        treeCompareStrings)))
     690                    arc = ERROR_WPH_NO_MATCHING_DRIVE_BLOCK;
     691                // find the root dir, which has the same name
     692                else if (!(pNode = (PNODETREENODE)treeFind(pDrive->ChildrenTree,
     693                                                           (ULONG)pszFilename,
     694                                                           treeCompareStrings)))
     695                    arc = ERROR_WPH_NO_MATCHING_ROOT_DIR;
     696                else
     697                {
     698                    // now we got the root dir... go for next path component
     699                    while (    (pEnd)
     700                            && (*pEnd = cOld)       // not null char
     701                            && (!arc)
     702                          )
     703                    {
     704                        // got another path component to search:
     705                        PSZ pCurrent = pEnd + 1,
     706                            pNext;
     707
     708                        if (pNext = strchr(pCurrent, '\\'))
     709                        {
     710                            cOld = *pNext;
     711                            *pNext = 0;
     712                        }
     713                        else
     714                            // done:
     715                            cOld = 0;
     716
     717                        _Pmpf(("  searching for node \"%s\"", pCurrent));
     718
     719                        // find the next node
     720                        if (!(pNode = (PNODETREENODE)treeFind(pNode->ChildrenTree,
     721                                                              (ULONG)pCurrent,
     722                                                              treeCompareStrings)))
     723                            arc = ERROR_WPH_CANNOT_FIND_HANDLE;
     724
     725                        pEnd = pNext;
     726                    }
     727
     728                    if (!arc && pNode)
     729                        // found everything:
     730                        *pusHandle = pNode->pNode->usHandle;
     731                }
     732            } // end while
     733
     734            free(pszFilename);
     735        }
     736    }
    478737    else
    479         usPartSize = strlen(pszFilename);
    480 
    481     // now set the pointer for the end of the BLOCKs buffer
    482     pEnd = pHandlesBuffer + ulBufSize;
    483 
    484     // pCur is our variable pointer where we're at now; there
    485     // is some offset of 4 bytes at the beginning (duh)
    486     pCur = pHandlesBuffer + 4;
    487 
    488     // _Pmpf(("  Searching for: %s, usPartSize: %d", pszFilename, usPartSize));
    489 
    490     // go!
    491     while (pCur < pEnd)
    492     {
    493         // the first four chars tell us whether it's
    494         // a DRIVE or a NODE structure
    495         if (!memicmp(pCur, "DRIV", 4))
    496         {
    497             // pCur points to a DRIVE node:
    498             // we don't care about these, because the root
    499             // directory has a real NODE too, so we just
    500             // skip this
    501             pDriv = (PDRIV)pCur;
    502             pCur += sizeof(DRIV) + strlen(pDriv->szName);
    503         }
    504         else if (!memicmp(pCur, "NODE", 4))
    505         {
    506             // pCur points to a regular NODE: offset pointer first
    507             pNode = (PNODE)pCur;
    508             pCur += sizeof (NODE) + pNode->usNameSize;
    509 
    510             // does the NODE have the same parent that we
    511             // are currently searching for? This is "0"
    512             // for root directories (and initially for us
    513             // too)
    514             if (usParent == pNode->usParentHandle)
    515             {
    516                 // yes:
    517                 // _Pmpf(("  found matching parents (%lX): %s", usParent, pNode->szName));
    518 
    519                 // does the NODE have the same partname length?
    520                 if (pNode->usNameSize == usPartSize)
    521                 {
    522                     // yes:
    523                     // _Pmpf(("    found matching partnames sizes: %d", pNode->usNameSize));
    524 
    525                     // do the partnames match too?
    526                     if (memicmp(pszFilename, pNode->szName, usPartSize) == 0)
    527                     {
    528                         // OK!! proper NODE found!
    529                         // _Pmpf(("      FOUND %s!!", pNode->szName));
    530 
    531                         // now check if this was the last NODE
    532                         // we were looking for
    533                         if (strlen(pszFilename) == usPartSize)
    534                            // yes: return ID
    535                            return (pNode->usHandle);
    536 
    537                         // else: update our status;
    538                         // get next partname
    539                         pszFilename += usPartSize + 1;
    540                         // calc next partname length
    541                         p = strchr(pszFilename, '\\');
    542                         if (p)
    543                             usPartSize = p - pszFilename;
    544                         else
    545                             usPartSize = strlen(pszFilename);
    546 
    547                         // get next parent to search for
    548                         // (which is the current handle)
    549                         usParent = pNode->usHandle;
    550                     }
    551                 }
    552             }
    553         }
    554         else
    555             // neither DRIVE nor NODE: error
    556             return (0);
    557 
    558     } // end while
     738        arc = ERROR_INVALID_PARAMETER;
     739
     740    _Pmpf((__FUNCTION__ ": returning %d", arc));
    559741
    560742    // not found: end of buffer reached
    561     return (0);
     743    return (arc);
    562744}
    563745
     
    588770
    589771    PSZ         pszActiveHandles = NULL;
    590     PHANDLESBUF pHandlesBuf = NULL;
     772    HHANDLES    hHandles = NULLHANDLE;
    591773
    592774    TRY_LOUD(excpt1)
     
    601783                                     hiniSystem,
    602784                                     pszActiveHandles,
    603                                      &pHandlesBuf))
     785                                     &hHandles))
    604786                _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc));
    605787            else
     
    610792
    611793                // search that buffer
    612                 if (usObjID = wphSearchBufferForHandle(pHandlesBuf->pbData,
    613                                                        pHandlesBuf->cbData,
    614                                                        0,                  // usParent
    615                                                        szFullPath))
     794                if (!(arc = wphSearchBufferForHandle(hHandles,
     795                                                     szFullPath,
     796                                                     &usObjID)))
    616797                    // found: OR 0x30000
    617                     *phobj = usObjID | (pHandlesBuf->usHiwordFileSystem << 16);
     798                    *phobj = usObjID | (((PHANDLESBUF)hHandles)->usHiwordFileSystem << 16);
    618799                else
    619800                    arc = ERROR_FILE_NOT_FOUND;
     
    628809    if (pszActiveHandles)
    629810        free(pszActiveHandles);
    630     if (pHandlesBuf)
    631         wphFreeHandles(&pHandlesBuf);
     811    if (hHandles)
     812        wphFreeHandles(&hHandles);
    632813
    633814    return (arc);
     
    652833                   PNODE *ppNode)           // out: node found (ptr can be NULL)
    653834{
    654     APIRET arc = NO_ERROR;
    655     PNODE pNode;
    656     if (pNode = pHandlesBuf->NodeHashTable[usHandle])
     835    APIRET          arc = NO_ERROR;
     836    PNODETREENODE   pTreeNode;
     837    PNODE           pNode;
     838    if (    (pTreeNode = pHandlesBuf->NodeHashTable[usHandle])
     839         && (pNode = pTreeNode->pNode)
     840       )
    657841    {
    658842        // handle exists:
     
    717901 */
    718902
    719 APIRET wphComposePath(PHANDLESBUF pHandlesBuf,
     903APIRET wphComposePath(HHANDLES hHandles,
    720904                      USHORT usHandle,      // in: loword of handle to search for
    721905                      PSZ pszFilename,
     
    725909    APIRET arc = NO_ERROR;
    726910
    727     TRY_LOUD(excpt1)
    728     {
    729         if (!pHandlesBuf->fNodeHashTableValid)
    730             arc = wphRebuildNodeHashTable(pHandlesBuf);
    731 
    732         if (!arc)
     911    PHANDLESBUF pHandlesBuf;
     912    if (    (hHandles)
     913         && (pHandlesBuf = (PHANDLESBUF)hHandles)
     914       )
     915    {
     916        TRY_LOUD(excpt1)
    733917        {
    734             XSTRING str;
    735             xstrInit(&str, CCHMAXPATH);
    736             if (!(arc = ComposeThis(pHandlesBuf,
    737                                     usHandle,
    738                                     &str,
    739                                     ppNode)))
    740                 if (str.ulLength > cbFilename - 1)
    741                     arc = ERROR_BUFFER_OVERFLOW;
    742                 else
    743                     memcpy(pszFilename,
    744                            str.psz,
    745                            str.ulLength + 1);
     918            if (!pHandlesBuf->fCacheValid)
     919                arc = wphRebuildNodeHashTable(hHandles);
     920
     921            if (!arc)
     922            {
     923                XSTRING str;
     924                xstrInit(&str, CCHMAXPATH);
     925                if (!(arc = ComposeThis(pHandlesBuf,
     926                                        usHandle,
     927                                        &str,
     928                                        ppNode)))
     929                    if (str.ulLength > cbFilename - 1)
     930                        arc = ERROR_BUFFER_OVERFLOW;
     931                    else
     932                        memcpy(pszFilename,
     933                               str.psz,
     934                               str.ulLength + 1);
     935            }
    746936        }
    747     }
    748     CATCH(excpt1)
    749     {
    750         arc = ERROR_WPH_CRASHED;
    751     } END_CATCH();
     937        CATCH(excpt1)
     938        {
     939            arc = ERROR_WPH_CRASHED;
     940        } END_CATCH();
     941    }
    752942
    753943    return (arc);
     
    785975        else
    786976        {
    787             PHANDLESBUF pHandlesBuf;
     977            HHANDLES hHandles;
    788978            if (arc = wphLoadHandles(hiniUser,
    789979                                     hiniSystem,
    790980                                     pszActiveHandles,
    791                                      &pHandlesBuf))
     981                                     &hHandles))
    792982                _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc));
    793983            else
    794984            {
    795985                // is this really a file-system object?
    796                 if (HIUSHORT(hObject) == pHandlesBuf->usHiwordFileSystem)
     986                if (HIUSHORT(hObject) == ((PHANDLESBUF)hHandles)->usHiwordFileSystem)
    797987                {
    798988                    // use loword only
     
    800990
    801991                    memset(pszFilename, 0, cbFilename);
    802                     arc = wphComposePath(pHandlesBuf,
     992                    arc = wphComposePath(hHandles,
    803993                                         usObjID,
    804994                                         pszFilename,
     
    809999                }
    8101000
    811                 wphFreeHandles(&pHandlesBuf);
     1001                wphFreeHandles(&hHandles);
    8121002            }
    8131003
  • trunk/src/helpers/xml.c

    r106 r113  
    522522                    // remove from parent's attributes map
    523523                    treeDelete(&pDomNode->pParentNode->AttributesMap,
     524                               NULL,
    524525                               (TREE*)pNode);
    525526                else
     
    619620                // add to parent's attributes list
    620621                if (treeInsert(&pParentNode->AttributesMap,
     622                               NULL,
    621623                               &pNewNode->NodeBase.Tree,
    622624                               CompareXStrings))
     
    648650
    649651        lstInit(&pNewNode->llChildren, FALSE);
    650         treeInit(&pNewNode->AttributesMap);
     652        treeInit(&pNewNode->AttributesMap, NULL);
    651653    }
    652654
     
    883885            pNew->fHasInternalSubset = fHasInternalSubset;
    884886
    885             treeInit(&pNew->ElementDeclsTree);
    886             treeInit(&pNew->AttribDeclBasesTree);
     887            treeInit(&pNew->ElementDeclsTree, NULL);
     888            treeInit(&pNew->AttribDeclBasesTree, NULL);
    887889
    888890            *ppNew = pNew;
     
    929931            xstrcpy(&pParticle->NodeBase.strNodeName, pModel->name, 0);
    930932            treeInsert(ppElementNamesTree,
     933                       NULL,
    931934                       &pParticle->NodeBase.Tree,
    932935                       CompareXStrings);
     
    10201023    if (!arc)
    10211024    {
    1022         treeInit(&pNew->ParticleNamesTree);
     1025        treeInit(&pNew->ParticleNamesTree, NULL);
    10231026
    10241027        // set up the "particle" member and recurse into sub-particles
     
    20282031                // add this to the doctype's declarations tree
    20292032                if (treeInsert(&pDocType->ElementDeclsTree,
     2033                               NULL,
    20302034                               (TREE*)pNew,
    20312035                               CompareXStrings))
     
    20612065    if (!arc)
    20622066        treeInsert(&pDecl->ValuesTree,
     2067                   NULL,
    20632068                   (TREE*)pNew,
    20642069                   CompareXStrings);
     
    21532158                    {
    21542159                        // initialize the subtree
    2155                         treeInit(&pThis->AttribDeclsTree);
     2160                        treeInit(&pThis->AttribDeclsTree, NULL);
    21562161
    21572162                        treeInsert(&pDocType->AttribDeclBasesTree,
     2163                                   NULL,
    21582164                                   (TREE*)pThis,
    21592165                                   CompareXStrings);
     
    21762182                if (!pDom->arcDOM)
    21772183                {
    2178                     treeInit(&pNew->ValuesTree);
     2184                    treeInit(&pNew->ValuesTree, NULL);
    21792185
    21802186                    // check the type... expat is too lazy to parse this for
     
    22422248
    22432249                        if (treeInsert(&pThis->AttribDeclsTree,
     2250                                       NULL,
    22442251                                       (TREE*)pNew,
    22452252                                       CompareXStrings))
Note: See TracChangeset for help on using the changeset viewer.