Changeset 127
- Timestamp:
- Jan 5, 2002, 8:11:10 PM (24 years ago)
- Location:
- trunk
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/helpers/apps.h
r123 r127 103 103 const PROGDETAILS *pcProgDetails, 104 104 ULONG ulFlags, 105 HAPP *phapp); 105 HAPP *phapp, 106 ULONG cbFailingName, 107 PSZ pszFailingName); 106 108 107 109 BOOL XWPENTRY appWaitForApp(HWND hwndNotify, -
trunk/include/helpers/comctl.h
r115 r127 411 411 // caused by a mouse click. 412 412 } EMPHASISNOTIFY, *PEMPHASISNOTIFY; 413 414 /* ****************************************************************** 415 * 416 * Super Combo Box 417 * 418 ********************************************************************/ 419 420 BOOL ctlComboFromEntryField(HWND hwnd, 421 ULONG flStyle); 413 422 414 423 /* ****************************************************************** -
trunk/include/helpers/dosh.h
r125 r127 345 345 ULONG ulAttr); 346 346 347 APIRET doshOpenExisting(PCSZ pcszFilename,347 /* APIRET doshOpenExisting(PCSZ pcszFilename, 348 348 ULONG ulOpenFlags, 349 349 HFILE *phf); 350 351 APIRET doshWriteAt(HFILE hf, 352 LONG lOffset, 353 ULONG ulMethod, 354 ULONG cb, 355 PBYTE pbData); 356 357 APIRET doshReadAt(HFILE hf, 358 LONG lOffset, 359 ULONG ulMethod, 360 PULONG pcb, 361 PBYTE pbData); 350 */ 362 351 363 352 /* … … 377 366 378 367 #define XOPEN_READ_EXISTING 0x0001 379 #define XOPEN_READWRITE_APPEND 0x0002 380 #define XOPEN_READWRITE_NEW 0x0003 368 #define XOPEN_READWRITE_EXISTING 0x0002 369 #define XOPEN_READWRITE_APPEND 0x0003 370 #define XOPEN_READWRITE_NEW 0x0004 381 371 #define XOPEN_ACCESS_MASK 0xffff 382 372 … … 388 378 PXFILE *ppFile); 389 379 380 APIRET doshReadAt(PXFILE pFile, 381 ULONG ulOffset, 382 PULONG pcb, 383 PBYTE pbData); 384 390 385 APIRET doshWrite(PXFILE pFile, 391 PCSZ pcsz, 392 ULONG cb); 386 ULONG cb, 387 PCSZ pbData); 388 389 APIRET doshWriteAt(PXFILE pFile, 390 ULONG ulOffset, 391 ULONG cb, 392 PCSZ pbData); 393 393 394 394 APIRET doshWriteLogEntry(PXFILE pFile, … … 858 858 #define EXEFORMAT_LX 4 859 859 #define EXEFORMAT_TEXT_BATCH 5 860 #define EXEFORMAT_TEXT_REXX 6 860 #define EXEFORMAT_TEXT_CMD 6 // REXX or plain OS/2 batch 861 #define EXEFORMAT_COM 7 // added V0.9.16 (2002-01-04) [umoeller] 861 862 862 863 // target OS (in NE and LX) … … 869 870 #define EXEOS_WIN32 6 870 871 872 #ifndef __STRIP_DOWN_EXECUTABLE__ 873 // for mini stubs in warpin, which has its own 874 // implementation of this 875 871 876 /* 872 877 *@@ EXECUTABLE: … … 877 882 typedef struct _EXECUTABLE 878 883 { 879 HFILE hfExe; 884 // executable opened by doshOpen 885 PXFILE pFile; 880 886 881 887 /* All the following fields are set by … … 891 897 892 898 // New Executable (NE) header, if ulExeFormat == EXEFORMAT_NE 893 #ifndef __STRIP_DOWN_EXECUTABLE__ // for mini stubs in warpin, to reduce code size894 899 PNEHEADER pNEHeader; 895 900 ULONG cbNEHeader; 896 #endif897 901 898 902 // Linear Executable (LX) header, if ulExeFormat == EXEFORMAT_LX … … 901 905 902 906 // Portable Executable (PE) header, if ulExeFormat == EXEFORMAT_PE 903 #ifndef __STRIP_DOWN_EXECUTABLE__ // for mini stubs in warpin, to reduce code size904 907 PPEHEADER pPEHeader; 905 908 ULONG cbPEHeader; 906 #endif 909 907 910 // module analysis (always set): 908 911 ULONG ulExeFormat; … … 913 916 // EXEFORMAT_LX 4 914 917 // EXEFORMAT_TEXT_BATCH 5 915 // EXEFORMAT_TEXT_REXX 6 918 // EXEFORMAT_TEXT_CMD 6 919 // EXEFORMAT_COM 7 916 920 917 921 BOOL fLibrary, // TRUE if this is a DLL … … 942 946 // module info substring (if IBM BLDLEVEL format) 943 947 944 #ifndef __STRIP_DOWN_EXECUTABLE__ // for mini stubs in warpin, to reduce code size945 948 // if pszInfo is extended DESCRIPTION field, the following 946 949 // are set as well: … … 964 967 POS2NERESTBLENTRY paOS2NEResTblEntry; 965 968 POS2NESEGMENT paOS2NESegments; 966 967 #endif968 969 } EXECUTABLE, *PEXECUTABLE; 969 970 … … 1061 1062 PCSZ *papcszExtensions, 1062 1063 ULONG cExtensions); 1064 #endif 1063 1065 1064 1066 /******************************************************************** … … 1264 1266 VOID doshFreeLVMInfo(PLVMINFO pInfo); 1265 1267 1268 /* ****************************************************************** 1269 * 1270 * Wildcard matching 1271 * 1272 ********************************************************************/ 1273 1274 BOOL doshMatch(const char *pcszMask, 1275 const char *pcszName); 1276 1266 1277 #endif 1267 1278 -
trunk/include/helpers/gpih.h
r125 r127 270 270 HBITMAP XWPENTRY gpihCreateBitmap2(HPS hpsMem, ULONG cx, ULONG cy, ULONG cPlanes, ULONG cBitCount); 271 271 272 HBITMAP XWPENTRY gpihCreateBmpFromPS(HAB hab, HPS hpsScreen, PRECTL prcl);273 typedef HBITMAP XWPENTRY GPIHCREATEBMPFROMPS(HAB hab, HPS hpsScreen, PRECTL prcl);274 typedef GPIHCREATEBMPFROMPS *PGPIHCREATEBMPFROMPS;275 276 272 HBITMAP XWPENTRY gpihCreateHalftonedBitmap(HAB hab, HBITMAP hbmSource, LONG lColorGray); 277 273 typedef HBITMAP XWPENTRY GPIHCREATEHALFTONEDBITMAP(HAB hab, HBITMAP hbmSource, LONG lColorGray); … … 344 340 typedef GPIHDESTROYXBITMAP *PGPIHDESTROYXBITMAP; 345 341 342 PXBITMAP gpihCreateBmpFromPS(HAB hab, 343 HPS hpsScreen, 344 PRECTL prcl); 345 346 346 #endif 347 347 -
trunk/include/helpers/stringh.h
r123 r127 166 166 /* ****************************************************************** 167 167 * 168 * Wildcard matching169 *170 ********************************************************************/171 172 #define FNM_MATCH 0173 #define FNM_NOMATCH 1174 #define FNM_ERR 2175 176 #define FNM_NOESCAPE 16177 #define FNM_PATHNAME 32178 #define FNM_PERIOD 64179 180 #define FNM_STYLE_MASK 15181 182 #define FNM_POSIX 0183 #define FNM_OS2 1184 #define FNM_DOS 2185 186 #define FNM_IGNORECASE 128187 #define FNM_PATHPREFIX 256188 189 BOOL XWPENTRY strhMatchOS2(const char *pcszMask, const char *pcszName);190 191 BOOL XWPENTRY strhMatchExt(const char *pcszMask,192 const char *pcszName,193 unsigned flags);194 195 /* ******************************************************************196 *197 168 * Fast string searches 198 169 * -
trunk/include/helpers/undoc.h
r41 r127 113 113 #define ID_WPMI_REFRESH 0x1F7 114 114 115 /*116 * Return codes for wpConfirmObjectTitle:117 * only def'd in the Warp 4 Toolkit118 * (and partly in wpsystem.h).119 */120 121 #ifndef NAMECLASH_CANCEL122 #define NAMECLASH_CANCEL 0123 #endif124 #ifndef NAMECLASH_NONE125 #define NAMECLASH_NONE 1126 #endif127 #ifndef NAMECLASH_RENAME128 #define NAMECLASH_RENAME 2129 #endif130 #ifndef NAMECLASH_REPLACE131 #define NAMECLASH_REPLACE 8132 #endif133 115 #endif 134 116 -
trunk/include/helpers/winh.h
r113 r127 534 534 535 535 #define winhQueryLboxSelectedItem(hwndListBox, sItemStart) \ 536 (SHORT)(WinSendMsg(hwndListBox, \536 SHORT1FROMMR(WinSendMsg(hwndListBox, \ 537 537 LM_QUERYSELECTION, \ 538 538 (MPARAM)(sItemStart), \ -
trunk/include/helpers/wphandle.h
r113 r127 56 56 #define ERROR_WPH_NO_MATCHING_DRIVE_BLOCK (ERROR_WPH_FIRST + 11) 57 57 #define ERROR_WPH_NO_MATCHING_ROOT_DIR (ERROR_WPH_FIRST + 12) 58 #define ERROR_WPH_NOT_FILESYSTEM_HANDLE (ERROR_WPH_FIRST + 13) 58 59 59 60 /* ****************************************************************** -
trunk/src/helpers/apps.c
r123 r127 33 33 34 34 #define INCL_DOSPROCESS 35 #define INCL_DOSMODULEMGR 35 36 #define INCL_DOSSESMGR 36 37 #define INCL_DOSERRORS 37 38 38 39 #define INCL_WINPROGRAMLIST // needed for PROGDETAILS, wppgm.h 40 #define INCL_WINERRORS 41 #define INCL_SHLERRORS 39 42 #include <os2.h> 40 43 … … 107 110 108 111 APIRET appParseEnvironment(const char *pcszEnv, 109 PDOSENVIRONMENT pEnv) 112 PDOSENVIRONMENT pEnv) // out: new environment 110 113 { 111 114 APIRET arc = NO_ERROR; … … 123 126 } 124 127 125 pEnv->cVars = cVars;128 pEnv->cVars = 0; 126 129 pEnv->papszVars = 0; 127 130 128 131 if (cVars) 129 132 { 130 PSZ *papsz = (PSZ*)malloc(sizeof(PSZ) * cVars); 131 if (!papsz) 133 ULONG cbArray = sizeof(PSZ) * cVars; 134 PSZ *papsz; 135 if (!(papsz = (PSZ*)malloc(cbArray))) 132 136 arc = ERROR_NOT_ENOUGH_MEMORY; 133 137 else 134 138 { 135 139 PSZ *ppszTarget = papsz; 136 memset(papsz, 0, sizeof(PSZ) * cVars);140 memset(papsz, 0, cbArray); 137 141 pszVarThis = (PSZ)pcszEnv; 138 142 while (*pszVarThis) 139 143 { 140 *ppszTarget = strdup(pszVarThis); 144 ULONG ulThisLen; 145 if (!(*ppszTarget = strhdup(pszVarThis, &ulThisLen))) 146 { 147 arc = ERROR_NOT_ENOUGH_MEMORY; 148 break; 149 } 150 (pEnv->cVars)++; 141 151 ppszTarget++; 142 pszVarThis += strlen(pszVarThis)+ 1;152 pszVarThis += ulThisLen + 1; 143 153 } 144 154 … … 156 166 * process environment, which is retrieved from 157 167 * the info blocks. 168 * 169 * Returns: 170 * 171 * -- NO_ERROR: 172 * 173 * -- ERROR_INVALID_PARAMETER 174 * 175 * -- ERROR_BAD_ENVIRONMENT: no environment found in 176 * info blocks. 158 177 * 159 178 *@@added V0.9.4 (2000-07-19) [umoeller] … … 173 192 if (arc == NO_ERROR) 174 193 { 175 PSZ pszEnv = ppib->pib_pchenv;176 if (pszEnv )194 PSZ pszEnv; 195 if (pszEnv = ppib->pib_pchenv) 177 196 arc = appParseEnvironment(pszEnv, pEnv); 178 197 else … … 200 219 *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak 201 220 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from dosh2.c to apps.c 221 *@@changed V0.9.16 (2002-01-01) [umoeller]: removed extra heap allocation 202 222 */ 203 223 … … 205 225 PSZ pszVarName) 206 226 { 207 PSZ *ppszRet = 0; 208 if (pEnv) 209 { 210 if ((pEnv->papszVars) && (pszVarName)) 211 { 212 PSZ *ppszThis = pEnv->papszVars; 213 // PSZ pszThis; 214 ULONG ul = 0; 215 ULONG ulVarNameLen = 0; 216 217 PSZ pszSearch = NULL; // receives "VARNAME=" 218 PSZ pFirstEqual = strchr(pszVarName, '='); 219 if (pFirstEqual) 220 pszSearch = strhSubstr(pszVarName, pFirstEqual + 1); 221 else 222 { 223 ulVarNameLen = strlen(pszVarName); 224 pszSearch = (PSZ)malloc(ulVarNameLen + 2); 225 memcpy(pszSearch, pszVarName, ulVarNameLen); 226 *(pszSearch + ulVarNameLen) = '='; 227 *(pszSearch + ulVarNameLen + 1) = 0; 228 } 229 230 ulVarNameLen = strlen(pszSearch); 231 232 for (ul = 0; 233 ul < pEnv->cVars; 234 ul++) 235 { 236 if (strnicmp(*ppszThis, pszSearch, ulVarNameLen) == 0) 227 PSZ *ppszRet = 0; 228 229 if ( (pEnv) 230 && (pEnv->papszVars) 231 && (pszVarName) 232 ) 233 { 234 ULONG ul = 0; 235 ULONG ulVarNameLen = 0; 236 237 PSZ pFirstEqual; 238 // rewrote all the following for speed V0.9.16 (2002-01-01) [umoeller] 239 if (pFirstEqual = strchr(pszVarName, '=')) 240 // VAR=VALUE 241 // ^ pFirstEqual 242 ulVarNameLen = pFirstEqual - pszVarName; 243 else 244 ulVarNameLen = strlen(pszVarName); 245 246 for (ul = 0; 247 ul < pEnv->cVars; 248 ul++) 249 { 250 PSZ pszThis = pEnv->papszVars[ul]; 251 if (pFirstEqual = strchr(pszThis, '=')) 252 { 253 ULONG ulLenThis = pFirstEqual - pszThis; 254 if ( (ulLenThis == ulVarNameLen) 255 && (!memicmp(pszThis, 256 pszVarName, 257 ulVarNameLen)) 258 ) 237 259 { 238 ppszRet = ppszThis;260 ppszRet = &pEnv->papszVars[ul]; 239 261 break; 240 262 } 241 242 // next environment string 243 ppszThis++; 244 } 245 246 free(pszSearch); // was missing V0.9.12 (2001-05-21) [umoeller] 263 } 247 264 } 248 265 } … … 296 313 else 297 314 { 298 PSZ *ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv); 299 if (ppszEnvLine) 300 { 315 PSZ *ppszEnvLine; 316 if (ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv)) 301 317 // was set already: replace 302 free(*ppszEnvLine); 303 *ppszEnvLine = strdup(pszNewEnv); 304 if (!(*ppszEnvLine)) 305 arc = ERROR_NOT_ENOUGH_MEMORY; 306 } 318 arc = strhStore(ppszEnvLine, 319 pszNewEnv, 320 NULL); 307 321 else 308 322 { … … 312 326 // allocate new array, with one new entry 313 327 // fixed V0.9.12 (2001-05-26) [umoeller], this crashed 314 PSZ *papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1));315 316 if (! papszNew)328 PSZ *papszNew; 329 330 if (!(papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1)))) 317 331 arc = ERROR_NOT_ENOUGH_MEMORY; 318 332 else … … 339 353 } 340 354 341 if (pEnv->papszVars) 342 free(pEnv->papszVars); // was missing V0.9.12 (2001-05-21) [umoeller] 343 355 free(pEnv->papszVars); // was missing V0.9.12 (2001-05-21) [umoeller] 344 356 pEnv->papszVars = papszNew; 345 357 pEnv->cVars++; … … 374 386 { 375 387 APIRET arc = NO_ERROR; 376 if (!pEnv) 388 if ( (!pEnv) 389 || (!pEnv->papszVars) 390 ) 377 391 arc = ERROR_INVALID_PARAMETER; 378 392 else 379 393 { 380 if (!pEnv->papszVars) 381 arc = ERROR_INVALID_PARAMETER; 394 // count memory needed for all strings 395 ULONG cbNeeded = 0, 396 ul = 0; 397 PSZ *ppszThis = pEnv->papszVars; 398 399 for (ul = 0; 400 ul < pEnv->cVars; 401 ul++) 402 { 403 cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator 404 405 // next environment string 406 ppszThis++; 407 } 408 409 cbNeeded++; // for another null terminator 410 411 if (!(*ppszEnv = (PSZ)malloc(cbNeeded))) 412 arc = ERROR_NOT_ENOUGH_MEMORY; 382 413 else 383 414 { 384 // count memory needed for all strings 385 ULONG cbNeeded = 0, 386 ul = 0; 387 PSZ *ppszThis = pEnv->papszVars; 388 415 PSZ pTarget = *ppszEnv; 416 if (pulSize) 417 *pulSize = cbNeeded; 418 ppszThis = pEnv->papszVars; 419 420 // now copy each string 389 421 for (ul = 0; 390 422 ul < pEnv->cVars; 391 423 ul++) 392 424 { 393 cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator 425 PSZ pSource = *ppszThis; 426 427 while ((*pTarget++ = *pSource++)) 428 ; 429 430 // *pTarget++ = 0; // append null terminator per string 394 431 395 432 // next environment string … … 397 434 } 398 435 399 cbNeeded++; // for another null terminator 400 401 *ppszEnv = (PSZ)malloc(cbNeeded); 402 if (!(*ppszEnv)) 403 arc = ERROR_NOT_ENOUGH_MEMORY; 404 else 405 { 406 PSZ pTarget = *ppszEnv; 407 if (pulSize) 408 *pulSize = cbNeeded; 409 ppszThis = pEnv->papszVars; 410 411 // now copy each string 412 for (ul = 0; 413 ul < pEnv->cVars; 414 ul++) 415 { 416 PSZ pSource = *ppszThis; 417 418 while ((*pTarget++ = *pSource++)) 419 ; 420 421 // *pTarget++ = 0; // append null terminator per string 422 423 // next environment string 424 ppszThis++; 425 } 426 427 *pTarget++ = 0; // append second null terminator 428 } 436 *pTarget++ = 0; // append second null terminator 429 437 } 430 438 } … … 444 452 { 445 453 APIRET arc = NO_ERROR; 446 if (!pEnv) 454 if ( (!pEnv) 455 || (!pEnv->papszVars) 456 ) 447 457 arc = ERROR_INVALID_PARAMETER; 448 458 else 449 459 { 450 if (!pEnv->papszVars) 451 arc = ERROR_INVALID_PARAMETER; 452 else 453 { 454 PSZ *ppszThis = pEnv->papszVars; 455 PSZ pszThis; 456 ULONG ul = 0; 457 458 for (ul = 0; 459 ul < pEnv->cVars; 460 ul++) 461 { 462 pszThis = *ppszThis; 463 free(pszThis); 464 // *ppszThis = NULL; 465 // next environment string 466 ppszThis++; 467 } 468 469 free(pEnv->papszVars); 470 pEnv->cVars = 0; 471 } 460 PSZ *ppszThis = pEnv->papszVars; 461 PSZ pszThis; 462 ULONG ul = 0; 463 464 for (ul = 0; 465 ul < pEnv->cVars; 466 ul++) 467 { 468 pszThis = *ppszThis; 469 free(pszThis); 470 // *ppszThis = NULL; 471 // next environment string 472 ppszThis++; 473 } 474 475 free(pEnv->papszVars); 476 pEnv->cVars = 0; 472 477 } 473 478 … … 920 925 *@@changed V0.9.16 (2001-10-19) [umoeller]: added thread-1 check 921 926 *@@changed V0.9.16 (2001-12-06) [umoeller]: now using doshSearchPath for finding pszExecutable if not qualified 927 *@@changed V0.9.16 (2002-01-04) [umoeller]: removed error report if startup directory was drive letter only 928 *@@changed V0.9.16 (2002-01-04) [umoeller]: added more detailed error reports and *FailingName params 922 929 */ 923 930 … … 925 932 const PROGDETAILS *pcProgDetails, // in: program spec (req.) 926 933 ULONG ulFlags, // in: APP_RUN_* flags 927 HAPP *phapp) // out: application handle if NO_ERROR is returned 934 HAPP *phapp, // out: application handle if NO_ERROR is returned 935 ULONG cbFailingName, 936 PSZ pszFailingName) 928 937 { 929 938 APIRET arc = NO_ERROR; 930 939 PROGDETAILS ProgDetails; 940 941 if (pszFailingName) 942 *pszFailingName = '\0'; 931 943 932 944 if (!pcProgDetails || !phapp) … … 1081 1093 if (ProgDetails.pszStartupDir) 1082 1094 { 1083 if (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir, 1084 &ulAttr))) 1085 if (!(ulAttr & FILE_DIRECTORY)) 1086 arc = ERROR_PATH_NOT_FOUND; 1095 // it is valid to specify a startup dir of "C:" 1096 if ( (strlen(ProgDetails.pszStartupDir) > 2) 1097 && (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir, 1098 &ulAttr))) 1099 && (!(ulAttr & FILE_DIRECTORY)) 1100 ) 1101 arc = ERROR_PATH_NOT_FOUND; 1087 1102 } 1088 1103 } … … 1222 1237 MB_YESNO | MB_MOVEABLE) 1223 1238 == MBID_YES) */ 1239 1240 if (pszFailingName) 1241 strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName); 1242 1224 1243 if (!(*phapp = WinStartApp(hwndNotify, 1225 1244 // receives WM_APPTERMINATENOTIFY … … 1235 1254 // app will be terminated automatically 1236 1255 // when the WPS terminates! 1237 arc = ERROR_BAD_FORMAT; 1238 // @@todo we can probably do better 1239 // V0.9.16 (2001-10-19) [umoeller] 1240 1241 // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ)); 1256 { 1257 // cannot start app: unfortunately WinStartApp doesn't 1258 // return meaningful codes like DosStartSession, so 1259 // try to see what happened 1260 switch (ERRORIDERROR(WinGetLastError(0))) 1261 { 1262 case PMERR_DOS_ERROR: // (0x1200) 1263 { 1264 // this is probably the case where the module 1265 // couldn't be loaded, so try DosStartSession 1266 // to get a meaningful return code... note that 1267 // this cannot handle hwndNotify then 1268 RESULTCODES result; 1269 arc = DosExecPgm(pszFailingName, 1270 cbFailingName, 1271 EXEC_ASYNC, 1272 NULL, // ProgDetails.pszParameters, 1273 NULL, // ProgDetails.pszEnvironment, 1274 &result, 1275 ProgDetails.pszExecutable); 1276 1277 /* ULONG sid, pid; 1278 STARTDATA SData; 1279 SData.Length = sizeof(STARTDATA); 1280 SData.Related = SSF_RELATED_CHILD; //INDEPENDENT; 1281 SData.FgBg = SSF_FGBG_FORE; 1282 SData.TraceOpt = SSF_TRACEOPT_NONE; 1283 1284 SData.PgmTitle = ProgDetails.pszTitle; 1285 SData.PgmName = ProgDetails.pszExecutable; 1286 SData.PgmInputs = ProgDetails.pszParameters; 1287 1288 SData.TermQ = NULL; 1289 SData.Environment = ProgDetails.pszEnvironment; 1290 SData.InheritOpt = SSF_INHERTOPT_PARENT; // ignored 1291 SData.SessionType = SSF_TYPE_DEFAULT; 1292 SData.IconFile = 0; 1293 SData.PgmHandle = 0; 1294 1295 SData.PgmControl = SSF_CONTROL_VISIBLE; 1296 1297 SData.InitXPos = 30; 1298 SData.InitYPos = 40; 1299 SData.InitXSize = 200; 1300 SData.InitYSize = 140; 1301 SData.Reserved = 0; 1302 SData.ObjectBuffer = pszFailingName; 1303 SData.ObjectBuffLen = cbFailingName; 1304 1305 arc = DosStartSession(&SData, &sid, &pid); 1306 */ 1307 } 1308 break; 1309 1310 case PMERR_INVALID_APPL: // (0x1530) 1311 // Attempted to start an application whose type is not 1312 // recognized by OS/2. 1313 arc = ERROR_INVALID_EXE_SIGNATURE; 1314 break; 1315 1316 case PMERR_INVALID_PARAMETERS: // (0x1208) 1317 // An application parameter value is invalid for 1318 // its converted PM type. For example: a 4-byte 1319 // value outside the range -32 768 to +32 767 cannot be 1320 // converted to a SHORT, and a negative number cannot 1321 // be converted to a ULONG or USHORT. 1322 arc = ERROR_INVALID_DATA; 1323 break; 1324 1325 case PMERR_STARTED_IN_BACKGROUND: // (0x1532) 1326 // The application started a new session in the 1327 // background. 1328 arc = ERROR_SMG_START_IN_BACKGROUND; 1329 break; 1330 1331 case PMERR_INVALID_WINDOW: // (0x1206) 1332 // The window specified with a Window List call 1333 // is not a valid frame window. 1334 1335 default: 1336 arc = ERROR_BAD_FORMAT; 1337 break; 1338 } 1339 } 1242 1340 } 1243 1341 } … … 1344 1442 &pd, 1345 1443 0, 1346 &happ)) 1444 &happ, 1445 0, 1446 NULL)) 1347 1447 ) 1348 1448 { -
trunk/src/helpers/dosh.c
r126 r127 1640 1640 */ 1641 1641 1642 /* 1642 1643 APIRET doshOpenExisting(PCSZ pcszFilename, // in: file name 1643 1644 ULONG ulOpenFlags, // in: open flags … … 1654 1655 NULL)); // EAs 1655 1656 } 1656 1657 /* 1658 *@@ doshWriteAt: 1659 * writes cb bytes (pointed to by pbData) to the 1660 * position specified by ulMethod and lOffset into 1661 * the file specified by hf. 1662 * 1663 * If ulMethod is FILE_BEGIN, lOffset specifies the 1664 * offset from the beginning of the file. With 1665 * FILE_CURRENT, lOffset is considered from the 1666 * current file pointer, and with FILE_END, it is 1667 * considered from the end of the file. 1668 * 1669 *@@added V0.9.13 (2001-06-14) [umoeller] 1670 */ 1671 1672 APIRET doshWriteAt(HFILE hf, // in: OS/2 file handle 1673 LONG lOffset, // in: offset to write at (depends on ulMethod) 1674 ULONG ulMethod, // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END 1675 ULONG cb, // in: bytes to write 1676 PBYTE pbData) // in: ptr to bytes to write (must be cb bytes) 1677 { 1678 APIRET arc; 1679 ULONG ulDummy; 1680 if (!(arc = DosSetFilePtr(hf, 1681 lOffset, 1682 ulMethod, 1683 &ulDummy))) 1684 arc = DosWrite(hf, 1685 pbData, 1686 cb, 1687 &ulDummy); 1688 1689 return (arc); 1690 } 1691 1692 /* 1693 *@@ doshReadAt: 1694 * reads cb bytes from the position specified by 1695 * ulMethod and lOffset into the buffer pointed to 1696 * by pbData, which should be cb bytes in size. 1697 * 1698 * Use lOffset and ulMethod as with doshWriteAt. 1699 * 1700 *@@added V0.9.13 (2001-06-14) [umoeller] 1701 */ 1702 1703 APIRET doshReadAt(HFILE hf, // in: OS/2 file handle 1704 LONG lOffset, // in: offset to write at (depends on ulMethod) 1705 ULONG ulMethod, // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END 1706 PULONG pcb, // in: bytes to read, out: bytes read 1707 PBYTE pbData) // out: read buffer (must be cb bytes) 1708 { 1709 APIRET arc; 1710 ULONG cb = *pcb; 1711 ULONG ulDummy; 1712 1713 *pcb = 0; 1714 1715 if (!(arc = DosSetFilePtr(hf, 1716 lOffset, 1717 ulMethod, 1718 &ulDummy))) 1719 { 1720 if (!(arc = DosRead(hf, 1721 pbData, 1722 cb, 1723 &ulDummy))) 1724 *pcb = ulDummy; // bytes read 1725 } 1726 1727 return (arc); 1728 } 1657 */ 1729 1658 1730 1659 /* … … 1741 1670 + +-------------------------+------+------------+-----------+ 1742 1671 + | XOPEN_READ_EXISTING | read | opens | fails | 1672 + | | | fptr = 0 | | 1673 + +-------------------------+------+------------+-----------+ 1674 + | XOPEN_READWRITE_EXISTING r/w | opens | fails | 1743 1675 + | | | fptr = 0 | | 1744 1676 + +-------------------------+------+------------+-----------+ … … 1802 1734 fsOpenMode |= OPEN_SHARE_DENYWRITE 1803 1735 | OPEN_ACCESS_READONLY; 1804 // _Pmpf((__FUNCTION__ ": opening XOPEN_READ_EXISTING"));1805 1736 1806 1737 // run this first, because if the file doesn't … … 1808 1739 // which isn't that meaningful 1809 1740 // V0.9.16 (2001-12-08) [umoeller] 1741 arc = doshQueryPathSize(pcszFilename, 1742 pcbFile); 1743 break; 1744 1745 case XOPEN_READWRITE_EXISTING: 1746 fsOpenFlags = OPEN_ACTION_FAIL_IF_NEW 1747 | OPEN_ACTION_OPEN_IF_EXISTS; 1748 fsOpenMode |= OPEN_SHARE_DENYWRITE 1749 | OPEN_ACCESS_READWRITE; 1750 1810 1751 arc = doshQueryPathSize(pcszFilename, 1811 1752 pcbFile); … … 1928 1869 1929 1870 /* 1871 *@@ doshReadAt: 1872 * reads cb bytes from the position specified by 1873 * lOffset into the buffer pointed to by pbData, 1874 * which should be cb bytes in size. 1875 * 1876 * Note that lOffset is always considered to 1877 * be from the beginning of the file (FILE_BEGIN 1878 * method). 1879 * 1880 *@@added V0.9.13 (2001-06-14) [umoeller] 1881 *@@changed V0.9.16 (2001-12-18) [umoeller]: now with XFILE, and always using FILE_BEGIN 1882 */ 1883 1884 APIRET doshReadAt(PXFILE pFile, 1885 ULONG ulOffset, // in: offset to read from (from beginning of file) 1886 PULONG pcb, // in: bytes to read, out: bytes read 1887 PBYTE pbData) // out: read buffer (must be cb bytes) 1888 { 1889 APIRET arc; 1890 ULONG cb = *pcb; 1891 ULONG ulDummy; 1892 1893 if (!(arc = doshLockFile(pFile))) // this checks for pFile 1894 { 1895 *pcb = 0; 1896 1897 if (!(arc = DosSetFilePtr(pFile->hf, 1898 (LONG)ulOffset, 1899 FILE_BEGIN, 1900 &ulDummy))) 1901 { 1902 if (!(arc = DosRead(pFile->hf, 1903 pbData, 1904 cb, 1905 &ulDummy))) 1906 *pcb = ulDummy; // bytes read 1907 } 1908 1909 doshUnlockFile(pFile); 1910 } 1911 1912 return (arc); 1913 } 1914 1915 /* 1930 1916 *@@ doshWrite: 1931 1917 * writes the specified data to the file. … … 1937 1923 * writing. 1938 1924 * 1925 * Note that this expects that the file 1926 * pointer is at the end of the file, or 1927 * you will get garbage. 1928 * 1939 1929 *@@added V0.9.16 (2001-10-19) [umoeller] 1940 1930 *@@changed V0.9.16 (2001-12-02) [umoeller]: added XOPEN_BINARY \r\n support … … 1943 1933 1944 1934 APIRET doshWrite(PXFILE pFile, 1945 PCSZ pcsz,1946 ULONG cb)1935 ULONG cb, 1936 PCSZ pbData) 1947 1937 { 1948 1938 APIRET arc = NO_ERROR; 1949 if ((!pFile) || (!p csz))1939 if ((!pFile) || (!pbData)) 1950 1940 arc = ERROR_INVALID_PARAMETER; 1951 1941 else 1952 1942 { 1953 1943 if (!cb) 1954 cb = strlen(p csz);1944 cb = strlen(pbData); 1955 1945 1956 1946 if (!cb) … … 1967 1957 // count all \n first 1968 1958 ULONG cNewLines = 0; 1969 PCSZ pSource = p csz;1959 PCSZ pSource = pbData; 1970 1960 ULONG ul; 1971 1961 for (ul = 0; … … 1987 1977 { 1988 1978 PSZ pTarget = pszNew; 1989 pSource = p csz;1979 pSource = pbData; 1990 1980 for (ul = 0; 1991 1981 ul < cb; … … 2010 2000 (pszNew) 2011 2001 ? pszNew 2012 : (PSZ)p csz,2002 : (PSZ)pbData, 2013 2003 cb, 2014 2004 &cbWritten))) … … 2021 2011 free(pszNew); 2022 2012 } 2013 } 2014 2015 return (arc); 2016 } 2017 2018 /* 2019 *@@ doshWriteAt: 2020 * writes cb bytes (pointed to by pbData) to the 2021 * specified file at the position lOffset (from 2022 * the beginning of the file). 2023 * 2024 *@@added V0.9.13 (2001-06-14) [umoeller] 2025 */ 2026 2027 APIRET doshWriteAt(PXFILE pFile, 2028 ULONG ulOffset, // in: offset to write at 2029 ULONG cb, // in: bytes to write 2030 PCSZ pbData) // in: ptr to bytes to write (must be cb bytes) 2031 { 2032 APIRET arc; 2033 if (!(arc = doshLockFile(pFile))) // this checks for pFile 2034 { 2035 ULONG cbWritten; 2036 if (!(arc = DosSetFilePtr(pFile->hf, 2037 (LONG)ulOffset, 2038 FILE_BEGIN, 2039 &cbWritten))) 2040 { 2041 if (!(arc = DosWrite(pFile->hf, 2042 (PSZ)pbData, 2043 cb, 2044 &cbWritten))) 2045 { 2046 if (ulOffset + cbWritten > pFile->cbCurrent) 2047 pFile->cbCurrent = ulOffset + cbWritten; 2048 } 2049 } 2050 2051 doshUnlockFile(pFile); 2023 2052 } 2024 2053 … … 2059 2088 { 2060 2089 if (!(arc = doshWrite(pFile, 2061 szTemp,2062 ulLength)))2090 ulLength, 2091 szTemp))) 2063 2092 { 2064 2093 va_list arg_ptr; … … 2073 2102 2074 2103 arc = doshWrite(pFile, 2075 (PCSZ)szTemp,2076 ulLength);2104 ulLength, 2105 szTemp); 2077 2106 } 2078 2107 } -
trunk/src/helpers/dosh2.c
r126 r127 65 65 #include "helpers\dosh.h" 66 66 #include "helpers\ensure.h" 67 #include "helpers\nls.h" 67 68 #include "helpers\standards.h" 68 69 #include "helpers\stringh.h" … … 441 442 *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX and NE now 442 443 *@@changed V0.9.16 (2001-12-08) [umoeller]: some speed optimizations, changed some return codes 444 *@@changed V0.9.16 (2002-01-04) [umoeller]: added fixes for COM, BAT, CMD extensions 443 445 */ 444 446 … … 446 448 PEXECUTABLE* ppExec) 447 449 { 448 APIRET arc = NO_ERROR; 449 450 ULONG ulAction = 0; 451 HFILE hFile; 450 APIRET arc = NO_ERROR; 451 452 452 PEXECUTABLE pExec = NULL; 453 454 PXFILE pFile = NULL; 455 ULONG cbFile = 0; 456 PCSZ pExt; 457 BOOL fOpenFile = FALSE; 453 458 454 459 if (!ppExec) … … 460 465 memset(pExec, 0, sizeof(EXECUTABLE)); 461 466 462 if (!(arc = DosOpen((PSZ)pcszExecutable, 463 &hFile, 464 &ulAction, // out: action taken 465 0, // in: new file (ignored for read-mode) 466 0, // in: new file attribs (ignored) 467 // open-flags 468 OPEN_ACTION_FAIL_IF_NEW 469 | OPEN_ACTION_OPEN_IF_EXISTS, 470 // open-mode 471 OPEN_FLAGS_FAIL_ON_ERROR // report errors to caller 472 | OPEN_FLAGS_SEQUENTIAL 473 | OPEN_FLAGS_NOINHERIT 474 // | OPEN_SHARE_DENYNONE 475 | OPEN_SHARE_DENYWRITE // changed V0.9.16 (2001-12-08) [umoeller] 476 | OPEN_ACCESS_READONLY, // read-only mode 477 NULL))) // no EAs 467 // check some of the default extensions 468 // V0.9.16 (2002-01-04) [umoeller] 469 if (pExt = doshGetExtension(pcszExecutable)) 470 { 471 if (!stricmp(pExt, "COM")) 472 { 473 // I am not willing to find out more about the 474 // .COM executable format, so for this one case, 475 // let OS/2 determine what we have here 476 ULONG ulDosAppType = 0; 477 if (!(arc = DosQueryAppType((PSZ)pcszExecutable, &ulDosAppType))) 478 { 479 if (ulDosAppType & FAPPTYP_DOS) // 0x20 480 pExec->ulOS = EXEOS_DOS3; 481 else 482 pExec->ulOS = EXEOS_OS2; 483 484 pExec->ulExeFormat = EXEFORMAT_COM; 485 } 486 } 487 else if (!stricmp(pExt, "BAT")) 488 { 489 pExec->ulOS = EXEOS_DOS3; 490 pExec->ulExeFormat = EXEFORMAT_TEXT_BATCH; 491 } 492 else if (!stricmp(pExt, "CMD")) 493 { 494 pExec->ulOS = EXEOS_OS2; 495 pExec->ulExeFormat = EXEFORMAT_TEXT_CMD; 496 } 497 else 498 fOpenFile = TRUE; 499 } 500 501 if ( (fOpenFile) 502 && (!(arc = doshOpen((PSZ)pcszExecutable, 503 XOPEN_READ_EXISTING, 504 &cbFile, 505 &pFile))) 506 ) 478 507 { 479 508 // file opened successfully: 509 pExec->pFile = pFile; 480 510 481 511 // read old DOS EXE header … … 485 515 { 486 516 pExec->cbDosExeHeader = sizeof(DOSEXEHEADER); 487 if (!(arc = doshReadAt( hFile,517 if (!(arc = doshReadAt(pFile, 488 518 0, 489 FILE_BEGIN,490 519 &pExec->cbDosExeHeader, // in/out 491 520 (PBYTE)pExec->pDosExeHeader))) … … 554 583 if (!(pbHeader = (PBYTE)malloc(cbRead))) 555 584 arc = ERROR_NOT_ENOUGH_MEMORY; 556 else if (!(arc = doshReadAt( hFile,585 else if (!(arc = doshReadAt(pFile, 557 586 ulNewHeaderOfs, 558 FILE_BEGIN,559 587 &cbRead, 560 588 pbHeader))) … … 626 654 // plus an extended header, so check what 627 655 // we've got 628 ULONG cbPE = 24629 + ((PPEHEADER)pbHeader)->usHeaderSize;656 ULONG cbPE = sizeof(PEHEADER); // 24 657 // + ((PPEHEADER)pbHeader)->usHeaderSize; 630 658 pExec->pPEHeader = (PPEHEADER)realloc(pbHeader, 631 659 cbPE); … … 635 663 pExec->f32Bits = TRUE; 636 664 665 /* 637 666 // we have the first 24 bytes already, so 638 // go for the next chunk 639 if (cbRead = pExec->pPEHeader->usHeaderSize) 667 // go for the next chunk, if this is more 668 // than we have in PEHEADER 669 if ( (cbRead < cbPE) 670 && (cbRead = pExec->pPEHeader->usHeaderSize) 671 ) 640 672 { 673 _Pmpf((" usHdrSize %d, sizeof(PEHEADER) %d, cbRead %d, cbPE %d --> reading extended header", 674 pExec->pPEHeader->usHeaderSize, 675 sizeof(PEHEADER), 676 cbRead, 677 cbPE)); 641 678 if (!(arc = doshReadAt(hFile, 642 679 ulNewHeaderOfs + 24, … … 647 684 } 648 685 else 686 { 649 687 arc = ERROR_BAD_EXE_FORMAT; 688 FREE(pExec->pPEHeader); 689 } 650 690 } 691 else 692 _Pmpf((" already got extended header")); 693 */ 651 694 } 652 695 } 653 696 else 697 { 654 698 // strange type: 655 699 arc = ERROR_INVALID_EXE_SIGNATURE; 656 657 if (pbCheckOS) 700 FREE(pbHeader); 701 } 702 703 if ((!arc) && (pbCheckOS)) 658 704 { 659 705 // BYTE to check for operating system … … 681 727 } 682 728 } 683 } 684 } 685 } // end if (!(arc = DosSetFilePtr(hFile, 686 } // end if pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)); 687 688 // store exec's HFILE 689 pExec->hfExe = hFile; 729 } // end if (!(arc = doshReadAt(hFile, 730 } // end if (fLoadNewHeader) 731 } // end if (!(arc = doshReadAt(hFile, 732 } // end else if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER)))) 733 690 734 } // end if (!(arc = DosOpen((PSZ)pcszExecutable, 691 735 … … 941 985 else 942 986 { 987 PXFILE pFile = pExec->pFile; 988 943 989 ULONG ulNRNTOfs = 0; 944 990 … … 978 1024 // move EXE file pointer to offset of non-resident name table 979 1025 // (from LX header) 980 if (!(arc = DosSetFilePtr(p Exec->hfExe, // file is still open1026 if (!(arc = DosSetFilePtr(pFile->hf, // file is still open 981 1027 ulNRNTOfs, // ofs determined above 982 1028 FILE_BEGIN, … … 990 1036 else 991 1037 { 992 if (!(arc = DosRead(p Exec->hfExe,1038 if (!(arc = DosRead(pFile->hf, 993 1039 pszNameTable, 994 1040 2000, … … 1069 1115 PFSYSMODULE paModules = NULL; 1070 1116 int i; 1117 HFILE hfExe = pExec->pFile->hf; 1071 1118 1072 1119 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] … … 1092 1139 memset(paModules, 0, cb); // V0.9.9 (2001-04-03) [umoeller] 1093 1140 1094 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1141 ENSURE_SAFE(DosSetFilePtr(hfExe, 1095 1142 pExec->pLXHeader->ulImportModTblOfs 1096 1143 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1103 1150 1104 1151 // reading the length of the module name 1105 ENSURE_SAFE(DosRead( pExec->hfExe, &bLen, 1, &ulDummy));1152 ENSURE_SAFE(DosRead(hfExe, &bLen, 1, &ulDummy)); 1106 1153 1107 1154 // reading the module name 1108 ENSURE_SAFE(DosRead( pExec->hfExe,1155 ENSURE_SAFE(DosRead(hfExe, 1109 1156 paModules[i].achModuleName, 1110 1157 bLen, … … 1143 1190 // then we read the name in the import table 1144 1191 1145 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1192 ENSURE_SAFE(DosSetFilePtr(hfExe, 1146 1193 pExec->pNEHeader->usModRefTblOfs 1147 1194 + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller] … … 1150 1197 &ulDummy)); 1151 1198 1152 ENSURE_SAFE(DosRead( pExec->hfExe, &usOfs, 2, &ulDummy));1153 1154 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1199 ENSURE_SAFE(DosRead(hfExe, &usOfs, 2, &ulDummy)); 1200 1201 ENSURE_SAFE(DosSetFilePtr(hfExe, 1155 1202 pExec->pNEHeader->usImportTblOfs 1156 1203 + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller] … … 1159 1206 &ulDummy)); 1160 1207 1161 ENSURE_SAFE(DosRead( pExec->hfExe, &bLen, 1, &ulDummy));1162 1163 ENSURE_SAFE(DosRead( pExec->hfExe,1208 ENSURE_SAFE(DosRead(hfExe, &bLen, 1, &ulDummy)); 1209 1210 ENSURE_SAFE(DosRead(hfExe, 1164 1211 paModules[i].achModuleName, 1165 1212 bLen, … … 1224 1271 1225 1272 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] 1273 HFILE hfExe = pExec->pFile->hf; 1226 1274 1227 1275 if (pExec->pDosExeHeader) … … 1229 1277 ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs; 1230 1278 1231 ENSURE(DosSetFilePtr( pExec->hfExe,1279 ENSURE(DosSetFilePtr(hfExe, 1232 1280 pExec->pLXHeader->ulEntryTblOfs 1233 1281 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1241 1289 bFlag; 1242 1290 1243 ENSURE(DosRead( pExec->hfExe, &bCnt, 1, &ulDummy));1291 ENSURE(DosRead(hfExe, &bCnt, 1, &ulDummy)); 1244 1292 1245 1293 if (bCnt == 0) … … 1247 1295 break; 1248 1296 1249 ENSURE(DosRead( pExec->hfExe, &bType, 1, &ulDummy));1297 ENSURE(DosRead(hfExe, &bType, 1, &ulDummy)); 1250 1298 1251 1299 switch (bType & 0x7F) … … 1269 1317 1270 1318 case 1: 1271 ENSURE(DosSetFilePtr( pExec->hfExe,1319 ENSURE(DosSetFilePtr(hfExe, 1272 1320 sizeof(USHORT), 1273 1321 FILE_CURRENT, … … 1276 1324 for (i = 0; i < bCnt; i ++) 1277 1325 { 1278 ENSURE(DosRead( pExec->hfExe, &bFlag, 1, &ulDummy));1326 ENSURE(DosRead(hfExe, &bFlag, 1, &ulDummy)); 1279 1327 1280 1328 if (bFlag & 0x01) … … 1291 1339 usOrdinal++; 1292 1340 1293 ENSURE(DosSetFilePtr( pExec->hfExe,1341 ENSURE(DosSetFilePtr(hfExe, 1294 1342 sizeof(USHORT), 1295 1343 FILE_CURRENT, … … 1308 1356 1309 1357 case 2: 1310 ENSURE(DosSetFilePtr( pExec->hfExe,1358 ENSURE(DosSetFilePtr(hfExe, 1311 1359 sizeof(USHORT), 1312 1360 FILE_CURRENT, … … 1315 1363 for (i = 0; i < bCnt; i ++) 1316 1364 { 1317 ENSURE(DosRead( pExec->hfExe, &bFlag, 1, &ulDummy));1365 ENSURE(DosRead(hfExe, &bFlag, 1, &ulDummy)); 1318 1366 1319 1367 if (bFlag & 0x01) … … 1330 1378 usOrdinal++; 1331 1379 1332 ENSURE(DosSetFilePtr( pExec->hfExe,1380 ENSURE(DosSetFilePtr(hfExe, 1333 1381 sizeof(USHORT) + sizeof(USHORT), 1334 1382 FILE_CURRENT, … … 1347 1395 1348 1396 case 3: 1349 ENSURE(DosSetFilePtr( pExec->hfExe,1397 ENSURE(DosSetFilePtr(hfExe, 1350 1398 sizeof(USHORT), 1351 1399 FILE_CURRENT, … … 1354 1402 for (i = 0; i < bCnt; i ++) 1355 1403 { 1356 ENSURE(DosRead( pExec->hfExe, &bFlag, 1, &ulDummy));1404 ENSURE(DosRead(hfExe, &bFlag, 1, &ulDummy)); 1357 1405 1358 1406 if (bFlag & 0x01) … … 1369 1417 usOrdinal++; 1370 1418 1371 ENSURE(DosSetFilePtr( pExec->hfExe,1419 ENSURE(DosSetFilePtr(hfExe, 1372 1420 sizeof(ULONG), 1373 1421 FILE_CURRENT, … … 1385 1433 1386 1434 case 4: 1387 ENSURE(DosSetFilePtr( pExec->hfExe,1435 ENSURE(DosSetFilePtr(hfExe, 1388 1436 sizeof(USHORT), 1389 1437 FILE_CURRENT, … … 1392 1440 for (i = 0; i < bCnt; i ++) 1393 1441 { 1394 ENSURE(DosSetFilePtr( pExec->hfExe,1442 ENSURE(DosSetFilePtr(hfExe, 1395 1443 sizeof(BYTE) + sizeof(USHORT) + sizeof(ULONG), 1396 1444 FILE_CURRENT, … … 1464 1512 1465 1513 ULONG ulNewHeaderOfs = 0; 1514 HFILE hfExe = pExec->pFile->hf; 1466 1515 1467 1516 if (pExec->pDosExeHeader) … … 1469 1518 ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs; 1470 1519 1471 ENSURE(DosSetFilePtr( pExec->hfExe,1520 ENSURE(DosSetFilePtr(hfExe, 1472 1521 pExec->pNEHeader->usEntryTblOfs 1473 1522 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1481 1530 bFlag; 1482 1531 1483 ENSURE(DosRead( pExec->hfExe, &bCnt, 1, &ulDummy));1532 ENSURE(DosRead(hfExe, &bCnt, 1, &ulDummy)); 1484 1533 1485 1534 if (bCnt == 0) … … 1487 1536 break; 1488 1537 1489 ENSURE(DosRead( pExec->hfExe, &bType, 1, &ulDummy));1538 ENSURE(DosRead(hfExe, &bType, 1, &ulDummy)); 1490 1539 1491 1540 if (bType) … … 1493 1542 for (i = 0; i < bCnt; i++) 1494 1543 { 1495 ENSURE(DosRead( pExec->hfExe,1544 ENSURE(DosRead(hfExe, 1496 1545 &bFlag, 1497 1546 1, … … 1514 1563 { 1515 1564 // moveable segment 1516 ENSURE(DosSetFilePtr( pExec->hfExe,1565 ENSURE(DosSetFilePtr(hfExe, 1517 1566 5, 1518 1567 FILE_CURRENT, … … 1522 1571 { 1523 1572 // fixed segment or constant (0xFE) 1524 ENSURE(DosSetFilePtr( pExec->hfExe,1573 ENSURE(DosSetFilePtr(hfExe, 1525 1574 2, 1526 1575 FILE_CURRENT, … … 1585 1634 USHORT usOrdinal; 1586 1635 PFSYSFUNCTION pFunction; 1636 HFILE hfExe = pExec->pFile->hf; 1587 1637 1588 1638 while (TRUE) … … 1592 1642 // int i; 1593 1643 1594 ENSURE(DosRead( pExec->hfExe, &bLen, 1, &ulDummy));1644 ENSURE(DosRead(hfExe, &bLen, 1, &ulDummy)); 1595 1645 1596 1646 if (bLen == 0) … … 1598 1648 break; 1599 1649 1600 ENSURE(DosRead( pExec->hfExe, &achName, bLen, &ulDummy));1650 ENSURE(DosRead(hfExe, &achName, bLen, &ulDummy)); 1601 1651 achName[bLen] = 0; 1602 1652 1603 ENSURE(DosRead( pExec->hfExe, &usOrdinal, sizeof(USHORT), &ulDummy));1653 ENSURE(DosRead(hfExe, &usOrdinal, sizeof(USHORT), &ulDummy)); 1604 1654 1605 1655 if ((pFunction = (PFSYSFUNCTION)bsearch(&usOrdinal, … … 1668 1718 ULONG ulDummy; 1669 1719 1720 HFILE hfExe = pExec->pFile->hf; 1670 1721 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] 1671 1722 … … 1702 1753 // we now scan the resident name table entries 1703 1754 1704 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1755 ENSURE_SAFE(DosSetFilePtr(hfExe, 1705 1756 pExec->pLXHeader->ulResdNameTblOfs 1706 1757 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1713 1764 // whose offset is _from the begining of the file_ 1714 1765 1715 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1766 ENSURE_SAFE(DosSetFilePtr(hfExe, 1716 1767 pExec->pLXHeader->ulNonResdNameTblOfs, 1717 1768 FILE_BEGIN, … … 1750 1801 // we now scan the resident name table entries 1751 1802 1752 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1803 ENSURE_SAFE(DosSetFilePtr(hfExe, 1753 1804 pExec->pNEHeader->usResdNameTblOfs 1754 1805 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1761 1812 // whose offset is _from the begining of the file_ 1762 1813 1763 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1814 ENSURE_SAFE(DosSetFilePtr(hfExe, 1764 1815 pExec->pNEHeader->ulNonResdTblOfs, 1765 1816 FILE_BEGIN, … … 1842 1893 PFSYSRESOURCE paResources = NULL; 1843 1894 1895 HFILE hfExe = pExec->pFile->hf; 1844 1896 ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller] 1845 1897 … … 1886 1938 memset(paResources, 0, cb); // V0.9.9 (2001-04-03) [umoeller] 1887 1939 1888 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1940 ENSURE_SAFE(DosSetFilePtr(hfExe, 1889 1941 pLXHeader->ulResTblOfs 1890 1942 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1894 1946 for (i = 0; i < cResources; i++) 1895 1947 { 1896 ENSURE_SAFE(DosRead( pExec->hfExe, &rs, 14, &ulDummy));1948 ENSURE_SAFE(DosRead(hfExe, &rs, 14, &ulDummy)); 1897 1949 1898 1950 paResources[i].ulID = rs.name; … … 1912 1964 * (paResources[i].ulFlag - 1)); 1913 1965 1914 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,1966 ENSURE_SAFE(DosSetFilePtr(hfExe, 1915 1967 ulOfsThis, 1916 1968 FILE_BEGIN, 1917 1969 &ulDummy)); 1918 1970 1919 ENSURE_SAFE(DosRead( pExec->hfExe, &ot, sizeof(ot), &ulDummy));1971 ENSURE_SAFE(DosRead(hfExe, &ot, sizeof(ot), &ulDummy)); 1920 1972 1921 1973 paResources[i].ulFlag = ((ot.o32_flags & OBJWRITE) … … 1968 2020 // we first read the resources IDs and types 1969 2021 1970 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,2022 ENSURE_SAFE(DosSetFilePtr(hfExe, 1971 2023 pNEHeader->usResTblOfs 1972 2024 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 1976 2028 for (i = 0; i < cResources; i++) 1977 2029 { 1978 ENSURE_SAFE(DosRead( pExec->hfExe, &rti, sizeof(rti), &ulDummy));2030 ENSURE_SAFE(DosRead(hfExe, &rti, sizeof(rti), &ulDummy)); 1979 2031 1980 2032 paResources[i].ulID = rti.name; … … 1986 2038 for (i = 0; i < cResources; i++) 1987 2039 { 1988 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,2040 ENSURE_SAFE(DosSetFilePtr(hfExe, 1989 2041 ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller] 1990 2042 + pNEHeader->usSegTblOfs … … 1996 2048 &ulDummy)); 1997 2049 1998 ENSURE_SAFE(DosRead( pExec->hfExe, &ns, sizeof(ns), &ulDummy));2050 ENSURE_SAFE(DosRead(hfExe, &ns, sizeof(ns), &ulDummy)); 1999 2051 2000 2052 paResources[i].ulSize = ns.ns_cbseg; … … 2013 2065 ULONG ulDummy; 2014 2066 2015 ENSURE(DosSetFilePtr( pExec->hfExe,2067 ENSURE(DosSetFilePtr(hfExe, 2016 2068 pNEHeader->usResTblOfs 2017 2069 + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller] … … 2019 2071 &ulDummy)); 2020 2072 2021 ENSURE(DosRead( pExec->hfExe,2073 ENSURE(DosRead(hfExe, 2022 2074 &usAlignShift, 2023 2075 sizeof(usAlignShift), … … 2029 2081 USHORT usCount; 2030 2082 2031 ENSURE(DosRead( pExec->hfExe,2083 ENSURE(DosRead(hfExe, 2032 2084 &usTypeID, 2033 2085 sizeof(usTypeID), … … 2037 2089 break; 2038 2090 2039 ENSURE(DosRead( pExec->hfExe,2091 ENSURE(DosRead(hfExe, 2040 2092 &usCount, 2041 2093 sizeof(usCount), 2042 2094 &ulDummy)); 2043 2095 2044 ENSURE(DosSetFilePtr( pExec->hfExe,2096 ENSURE(DosSetFilePtr(hfExe, 2045 2097 sizeof(ULONG), 2046 2098 FILE_CURRENT, … … 2050 2102 2051 2103 // first pass, skip NAMEINFO table 2052 ENSURE(DosSetFilePtr( pExec->hfExe,2104 ENSURE(DosSetFilePtr(hfExe, 2053 2105 usCount*6*sizeof(USHORT), 2054 2106 FILE_CURRENT, … … 2067 2119 memset(paResources, 0, cb); 2068 2120 2069 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,2121 ENSURE_SAFE(DosSetFilePtr(hfExe, 2070 2122 pNEHeader->usResTblOfs 2071 2123 + ulNewHeaderOfs, … … 2073 2125 &ulDummy)); 2074 2126 2075 ENSURE_SAFE(DosRead( pExec->hfExe,2127 ENSURE_SAFE(DosRead(hfExe, 2076 2128 &usAlignShift, 2077 2129 sizeof(usAlignShift), … … 2084 2136 int i; 2085 2137 2086 ENSURE_SAFE(DosRead( pExec->hfExe,2138 ENSURE_SAFE(DosRead(hfExe, 2087 2139 &usTypeID, 2088 2140 sizeof(usTypeID), … … 2092 2144 break; 2093 2145 2094 ENSURE_SAFE(DosRead( pExec->hfExe,2146 ENSURE_SAFE(DosRead(hfExe, 2095 2147 &usCount, 2096 2148 sizeof(usCount), 2097 2149 &ulDummy)); 2098 2150 2099 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,2151 ENSURE_SAFE(DosSetFilePtr(hfExe, 2100 2152 sizeof(ULONG), 2101 2153 FILE_CURRENT, … … 2109 2161 usID; 2110 2162 2111 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,2163 ENSURE_SAFE(DosSetFilePtr(hfExe, 2112 2164 sizeof(USHORT), 2113 2165 FILE_CURRENT, 2114 2166 &ulDummy)); 2115 2167 2116 ENSURE_SAFE(DosRead( pExec->hfExe,2168 ENSURE_SAFE(DosRead(hfExe, 2117 2169 &usLength, 2118 2170 sizeof(USHORT), 2119 2171 &ulDummy)); 2120 ENSURE_SAFE(DosRead( pExec->hfExe,2172 ENSURE_SAFE(DosRead(hfExe, 2121 2173 &usFlags, 2122 2174 sizeof(USHORT), 2123 2175 &ulDummy)); 2124 ENSURE_SAFE(DosRead( pExec->hfExe,2176 ENSURE_SAFE(DosRead(hfExe, 2125 2177 &usID, 2126 2178 sizeof(USHORT), 2127 2179 &ulDummy)); 2128 2180 2129 ENSURE_SAFE(DosSetFilePtr( pExec->hfExe,2181 ENSURE_SAFE(DosSetFilePtr(hfExe, 2130 2182 2*sizeof(USHORT), 2131 2183 FILE_CURRENT, … … 2234 2286 else 2235 2287 { 2288 PXFILE pFile = pExec->pFile; 2236 2289 ULONG ulNewHeaderOfs = 0; 2237 2290 ULONG cb; … … 2246 2299 (PBYTE*)&pExec->pRsTbl, 2247 2300 &cb))) 2248 && (!(arc = doshReadAt(p Exec->hfExe,2301 && (!(arc = doshReadAt(pFile, 2249 2302 pLXHeader->ulResTblOfs 2250 2303 + ulNewHeaderOfs, 2251 FILE_BEGIN,2252 2304 &cb, 2253 2305 (PBYTE)pExec->pRsTbl))) … … 2259 2311 (PBYTE*)&pExec->pObjTbl, 2260 2312 &cb))) 2261 && (!(arc = doshReadAt(p Exec->hfExe,2313 && (!(arc = doshReadAt(pFile, 2262 2314 pLXHeader->ulObjTblOfs 2263 2315 + ulNewHeaderOfs, 2264 FILE_BEGIN,2265 2316 &cb, 2266 2317 (PBYTE)pExec->pObjTbl))) … … 2272 2323 (PBYTE*)&pExec->pObjPageTbl, 2273 2324 &cb))) 2274 && (!(arc = doshReadAt(p Exec->hfExe,2325 && (!(arc = doshReadAt(pFile, 2275 2326 pLXHeader->ulObjPageTblOfs 2276 2327 + ulNewHeaderOfs, 2277 FILE_BEGIN,2278 2328 &cb, 2279 2329 (PBYTE)pExec->pObjPageTbl))) … … 2341 2391 else 2342 2392 { 2393 PXFILE pFile = pExec->pFile; 2343 2394 ULONG ulNewHeaderOfs = 0; 2344 2395 ULONG cb; … … 2353 2404 (PBYTE*)&pExec->paOS2NEResTblEntry, 2354 2405 &cb))) 2355 && (!(arc = doshReadAt(p Exec->hfExe,2406 && (!(arc = doshReadAt(pFile, 2356 2407 pNEHeader->usResTblOfs 2357 2408 + ulNewHeaderOfs, 2358 FILE_BEGIN,2359 2409 &cb, 2360 2410 (PBYTE)pExec->paOS2NEResTblEntry))) … … 2366 2416 (PBYTE*)&pExec->paOS2NESegments, 2367 2417 &cb))) 2368 && (!(arc = doshReadAt(p Exec->hfExe,2418 && (!(arc = doshReadAt(pFile, 2369 2419 pNEHeader->usResTblOfs 2370 2420 + ulNewHeaderOfs 2371 2421 - cb, // pNEHeader->usResSegmCount * sizeof(struct new_seg) 2372 FILE_BEGIN,2373 2422 &cb, 2374 2423 (PBYTE)pExec->paOS2NESegments))) … … 2461 2510 } 2462 2511 2463 if (pExec->hfExe) 2464 arc = DosClose(pExec->hfExe); 2512 doshClose(&pExec->pFile); 2465 2513 2466 2514 free(pExec); … … 4113 4161 } 4114 4162 } 4163 4164 /* 4165 *@@category: Helpers\Control program helpers\Wildcard matching 4166 * See doshMatch. 4167 */ 4168 4169 /* ****************************************************************** 4170 * 4171 * Wildcard matching 4172 * 4173 ********************************************************************/ 4174 4175 /* 4176 * PerformMatch: 4177 * compares a single path component. The input strings must 4178 * not have slashes or backslashes in them. 4179 * 4180 * fHasDot must be true if pName contains at least one dot. 4181 * 4182 * Note that this function is recursive. 4183 */ 4184 4185 BOOL PerformMatch(PCSZ pMask, 4186 PCSZ pName, 4187 int fHasDot) 4188 { 4189 while (TRUE) 4190 { 4191 // go thru the pMask char by char 4192 switch (*pMask) 4193 { 4194 case 0: 4195 // if we've reached the end of the mask, 4196 // we better have the end of the name too 4197 if (*pName == 0) 4198 return TRUE; 4199 return FALSE; 4200 4201 case '?': 4202 // a question mark matches one single character; 4203 // it does _not_ match a dot; 4204 // at the end of the component, it also matches 4205 // no characters 4206 if ( (*pName != '.') 4207 && (*pName != 0) 4208 ) 4209 ++pName; 4210 ++pMask; 4211 break; 4212 4213 case '*': 4214 // asterisk matches zero or more characters 4215 4216 // skip extra asterisks 4217 do 4218 { 4219 ++pMask; 4220 } while (*pMask == '*'); 4221 4222 // pMask points to after '*'; 4223 // pName is unchanged... so for each pName 4224 // that follows, check if it matches 4225 while (TRUE) 4226 { 4227 if (PerformMatch(pMask, pName, fHasDot)) 4228 // the remainder matched: 4229 // then everything matches 4230 return TRUE; 4231 4232 if (*pName == 0) 4233 return FALSE; 4234 4235 // didn't match: try next pName 4236 ++pName; 4237 } 4238 4239 case '.': 4240 // a dot matches a dot only, even if the name doesn't 4241 // have one at the end 4242 ++pMask; 4243 if (*pName == '.') 4244 ++pName; 4245 else if ( (fHasDot) 4246 || (*pName != 0) 4247 ) 4248 return FALSE; 4249 break; 4250 4251 default: 4252 if (*pMask++ != *pName++) 4253 return FALSE; 4254 break; 4255 } 4256 } 4257 } 4258 4259 /* 4260 *@@ doshMatch: 4261 * this matches '*' and '?' wildcards, similar to what 4262 * DosEditName does. It returns TRUE if the given name 4263 * matches the given mask. 4264 * 4265 * However, this does not require a file to be present, but 4266 * works on strings only. 4267 * 4268 * This accepts both short and fully qualified masks and 4269 * names, but the following rules apply: 4270 * 4271 * -- Either both the mask and the name must be fully 4272 * qualified, or both must not. Otherwise the match fails. 4273 * 4274 * -- If fully qualified, only the last component may contain 4275 * wildcards. 4276 * 4277 * -- This compares without respect to case always. 4278 * 4279 * -- As opposed to the WPS, this handles multiple dots in 4280 * filenames correctly. For example, the WPS will not 4281 * match "*.ZIP" against "whatever-0.9.3.zip", but this 4282 * one will. 4283 * 4284 * This replaces strhMatchOS2 which has been removed with 4285 * V0.9.16 and is a lot faster than the old code, which has 4286 * been completely rewritten. 4287 * 4288 *@@added V0.9.16 (2002-01-01) [umoeller] 4289 */ 4290 4291 BOOL doshMatch(const char *pcszMask, // in: mask (e.g. "*.txt") 4292 const char *pcszName) // in: string to check (e.g. "test.txt") 4293 { 4294 BOOL brc = FALSE; 4295 4296 int iMaskDrive = -1, 4297 iNameDrive = -1; 4298 4299 ULONG cbMask = strlen(pcszMask), 4300 cbName = strlen(pcszName); 4301 PSZ pszMask = (PSZ)_alloca(cbMask + 1), 4302 pszName = (PSZ)_alloca(cbName + 1); 4303 4304 PCSZ pLastMaskComponent, 4305 pLastNameComponent; 4306 4307 ULONG cbMaskPath = 0, 4308 cbNamePath = 0; 4309 4310 CHAR c; 4311 4312 memcpy(pszMask, pcszMask, cbMask + 1); 4313 nlsUpper(pszMask, cbMask); 4314 memcpy(pszName, pcszName, cbName + 1); 4315 nlsUpper(pszName, cbName); 4316 4317 if (pLastMaskComponent = strrchr(pszMask, '\\')) 4318 { 4319 // length of path component 4320 cbMaskPath = pLastMaskComponent - pszMask; 4321 pLastMaskComponent++; 4322 } 4323 else 4324 pLastMaskComponent = pszMask; 4325 4326 if (pLastNameComponent = strrchr(pszName, '\\')) 4327 { 4328 // length of path component 4329 cbNamePath = pLastNameComponent - pszName; 4330 pLastNameComponent++; 4331 } 4332 else 4333 pLastNameComponent = pszName; 4334 4335 // compare paths; if the lengths are different 4336 // or memcmp fails, we can't match 4337 if ( (cbMaskPath == cbNamePath) // can both be null 4338 && ( (cbMaskPath == 0) 4339 || (!memcmp(pszMask, pszName, cbMaskPath)) 4340 ) 4341 ) 4342 { 4343 // alright, paths match: 4344 brc = PerformMatch(pLastMaskComponent, 4345 pLastNameComponent, 4346 // has dot? 4347 (strchr(pLastNameComponent, '.') != NULL)); 4348 4349 } 4350 4351 return brc; 4352 } 4353 4354 -
trunk/src/helpers/gpih.c
r126 r127 1555 1555 1556 1556 /* 1557 *@@ gpihCreateBmpFromPS:1558 * this creates a new bitmap and copies a screen rectangle1559 * into it. Consider this a "screen capture" function.1560 *1561 * The new bitmap (which is returned) is compatible with the1562 * device associated with hpsScreen. This function calls1563 * gpihCreateMemPS and gpihCreateBitmap to have it created.1564 * The memory PS is only temporary and freed again.1565 *1566 * This returns the handle of the new bitmap,1567 * which can then be used for WinDrawBitmap and such, or1568 * NULLHANDLE upon errors.1569 *1570 *@@changed V0.9.12 (2001-05-20) [umoeller]: fixed excessive mem PS size1571 */1572 1573 HBITMAP gpihCreateBmpFromPS(HAB hab, // in: anchor block1574 HPS hpsScreen, // in: screen PS to copy from1575 PRECTL prcl) // in: rectangle to copy1576 {1577 1578 /* To copy an image from a display screen to a bit map:1579 1. Associate the memory device context with a presentation space.1580 2. Create a bit map.1581 3. Select the bit map into the memory device context by calling GpiSetBitmap.1582 4. Determine the location (in device coordinates) of the image.1583 5. Call GpiBitBlt and copy the image to the bit map. */1584 1585 HDC hdcMem;1586 HPS hpsMem;1587 HBITMAP hbm = NULLHANDLE;1588 POINTL aptl[3];1589 1590 SIZEL szlPage = {prcl->xRight - prcl->xLeft,1591 prcl->yTop - prcl->yBottom}; // fixed V0.9.12 (2001-05-20) [umoeller]1592 if (gpihCreateMemPS(hab,1593 &szlPage,1594 &hdcMem,1595 &hpsMem))1596 {1597 if ((hbm = gpihCreateBitmap(hpsMem,1598 szlPage.cx,1599 szlPage.cy)))1600 {1601 // Associate the bit map and the memory presentation space.1602 if (GpiSetBitmap(hpsMem, hbm)1603 != HBM_ERROR)1604 {1605 // Copy the screen to the bit map.1606 aptl[0].x = 0; // lower-left corner of destination rectangle1607 aptl[0].y = 0;1608 aptl[1].x = prcl->xRight; // upper-right corner for both1609 aptl[1].y = prcl->yTop;1610 aptl[2].x = prcl->xLeft; // lower-left corner of source rectangle1611 aptl[2].y = prcl->yBottom;1612 1613 if (GpiBitBlt(hpsMem,1614 hpsScreen,1615 sizeof(aptl) / sizeof(POINTL), // Number of points in aptl1616 aptl,1617 ROP_SRCCOPY,1618 BBO_IGNORE)1619 == GPI_ERROR)1620 {1621 // error during bitblt:1622 GpiDeleteBitmap(hbm);1623 hbm = NULLHANDLE; // for return code1624 }1625 }1626 else1627 {1628 // error selecting bitmap for hpsMem:1629 GpiDeleteBitmap(hbm);1630 hbm = NULLHANDLE; // for return code1631 }1632 }1633 1634 GpiDestroyPS(hpsMem);1635 DevCloseDC(hdcMem);1636 } // end if (hdcMem = DevOpenDC())1637 1638 return (hbm);1639 }1640 1641 /*1642 1557 *@@ gpihCreateHalftonedBitmap: 1643 1558 * this creates a half-toned copy of the … … 2246 2161 } 2247 2162 2248 2163 /* 2164 *@@ gpihCreateBmpFromPS: 2165 * this creates a new bitmap and copies a screen rectangle 2166 * into it. Consider this a "screen capture" function. 2167 * 2168 * The new bitmap (which is returned) is compatible with the 2169 * device associated with hpsScreen. This function calls 2170 * gpihCreateMemPS and gpihCreateBitmap to have it created. 2171 * The memory PS is only temporary and freed again. 2172 * 2173 * This returns the handle of the new bitmap, 2174 * which can then be used for WinDrawBitmap and such, or 2175 * NULLHANDLE upon errors. 2176 * 2177 *@@changed V0.9.12 (2001-05-20) [umoeller]: fixed excessive mem PS size 2178 *@@changed V0.9.16 (2001-01-04) [umoeller]: now creating XBITMAP 2179 */ 2180 2181 PXBITMAP gpihCreateBmpFromPS(HAB hab, // in: anchor block 2182 HPS hpsScreen, // in: screen PS to copy from 2183 PRECTL prcl) // in: rectangle to copy 2184 { 2185 2186 /* To copy an image from a display screen to a bit map: 2187 1. Associate the memory device context with a presentation space. 2188 2. Create a bit map. 2189 3. Select the bit map into the memory device context by calling GpiSetBitmap. 2190 4. Determine the location (in device coordinates) of the image. 2191 5. Call GpiBitBlt and copy the image to the bit map. */ 2192 2193 PXBITMAP pBmp; 2194 2195 if (pBmp = gpihCreateXBitmap(hab, 2196 prcl->xRight - prcl->xLeft, 2197 prcl->yTop - prcl->yBottom)) 2198 { 2199 POINTL aptl[3]; 2200 // Copy the screen to the bit map. 2201 aptl[0].x = 0; // lower-left corner of destination rectangle 2202 aptl[0].y = 0; 2203 aptl[1].x = prcl->xRight; // upper-right corner for both 2204 aptl[1].y = prcl->yTop; 2205 aptl[2].x = prcl->xLeft; // lower-left corner of source rectangle 2206 aptl[2].y = prcl->yBottom; 2207 2208 if (GpiBitBlt(pBmp->hpsMem, 2209 hpsScreen, 2210 sizeof(aptl) / sizeof(POINTL), // Number of points in aptl 2211 aptl, 2212 ROP_SRCCOPY, 2213 BBO_IGNORE) 2214 == GPI_ERROR) 2215 { 2216 // error during bitblt: 2217 gpihDestroyXBitmap(&pBmp); 2218 } 2219 } 2220 2221 return (pBmp); 2222 } 2223 -
trunk/src/helpers/helpers_pre.in
r113 r127 80 80 $(OUTPUTDIR)\cctl_chart.obj \ 81 81 $(OUTPUTDIR)\cctl_checkcnr.obj \ 82 $(OUTPUTDIR)\cctl_combo.obj \ 82 83 $(OUTPUTDIR)\cctl_progbar.obj \ 83 84 $(OUTPUTDIR)\cctl_splitwin.obj \ -
trunk/src/helpers/stringh.c
r123 r127 152 152 *ppszTarget = NULL; 153 153 } 154 else 155 return (ERROR_INVALID_PARAMETER); 154 156 155 157 if (pulLength) … … 1659 1661 /* ****************************************************************** 1660 1662 * 1661 * Wildcard matching1662 *1663 ********************************************************************/1664 1665 /*1666 * The following code has been taken from "fnmatch.zip".1667 *1668 * (c) 1994-1996 by Eberhard Mattes.1669 */1670 1671 /* In OS/2 and DOS styles, both / and \ separate components of a path.1672 * This macro returns true iff C is a separator. */1673 1674 #define IS_OS2_COMP_SEP(C) ((C) == '/' || (C) == '\\')1675 1676 1677 /* This macro returns true if C is at the end of a component of a1678 * path. */1679 1680 #define IS_OS2_COMP_END(C) ((C) == 0 || IS_OS2_COMP_SEP (C))1681 1682 /*1683 * skip_comp_os2:1684 * Return a pointer to the next component of the path SRC, for OS/21685 * and DOS styles. When the end of the string is reached, a pointer1686 * to the terminating null character is returned.1687 *1688 * (c) 1994-1996 by Eberhard Mattes.1689 */1690 1691 static const unsigned char* skip_comp_os2(const unsigned char *src)1692 {1693 /* Skip characters until hitting a separator or the end of the1694 * string. */1695 1696 while (!IS_OS2_COMP_END(*src))1697 ++src;1698 1699 /* Skip the separator if we hit a separator. */1700 1701 if (*src != 0)1702 ++src;1703 return src;1704 }1705 1706 /*1707 * has_colon:1708 * returns true iff the path P contains a colon.1709 *1710 * (c) 1994-1996 by Eberhard Mattes.1711 */1712 1713 static int has_colon(const unsigned char *p)1714 {1715 while (*p != 0)1716 if (*p == ':')1717 return 1;1718 else1719 ++p;1720 return 0;1721 }1722 1723 /*1724 * match_comp_os2:1725 * compares a single component (directory name or file name)1726 * of the paths, for OS/2 and DOS styles. MASK and NAME point1727 * into a component of the wildcard and the name to be checked,1728 * respectively. Comparing stops at the next separator.1729 * The FLAGS argument is the same as that of fnmatch().1730 *1731 * HAS_DOT is true if a dot is in the current component of NAME.1732 * The number of dots is not restricted, even in DOS style.1733 *1734 * Returns FNM_MATCH iff MASK and NAME match.1735 *1736 * Note that this function is recursive.1737 *1738 * (c) 1994-1996 by Eberhard Mattes.1739 */1740 1741 static int match_comp_os2(const unsigned char *mask,1742 const unsigned char *name,1743 unsigned flags,1744 int has_dot)1745 {1746 int rc;1747 1748 for (;;)1749 switch (*mask)1750 {1751 case 0:1752 1753 /* There must be no extra characters at the end of NAME when1754 * reaching the end of MASK unless _FNM_PATHPREFIX is set:1755 * in that case, NAME may point to a separator. */1756 1757 if (*name == 0)1758 return FNM_MATCH;1759 if ((flags & FNM_PATHPREFIX) && IS_OS2_COMP_SEP(*name))1760 return FNM_MATCH;1761 return FNM_NOMATCH;1762 1763 case '/':1764 case '\\':1765 1766 /* Separators match separators. */1767 1768 if (IS_OS2_COMP_SEP(*name))1769 return FNM_MATCH;1770 1771 /* If _FNM_PATHPREFIX is set, a trailing separator in MASK1772 * is ignored at the end of NAME. */1773 1774 if ((flags & FNM_PATHPREFIX) && mask[1] == 0 && *name == 0)1775 return FNM_MATCH;1776 1777 /* Stop comparing at the separator. */1778 1779 return FNM_NOMATCH;1780 1781 case '?':1782 1783 /* A question mark matches one character. It does not match1784 * a dot. At the end of the component (and before a dot),1785 * it also matches zero characters. */1786 1787 if (*name != '.' && !IS_OS2_COMP_END(*name))1788 ++name;1789 ++mask;1790 break;1791 1792 case '*':1793 1794 /* An asterisk matches zero or more characters. In DOS1795 * mode, dots are not matched. */1796 1797 do1798 {1799 ++mask;1800 }1801 while (*mask == '*');1802 for (;;)1803 {1804 rc = match_comp_os2(mask, name, flags, has_dot);1805 if (rc != FNM_NOMATCH)1806 return rc;1807 if (IS_OS2_COMP_END(*name))1808 return FNM_NOMATCH;1809 if (*name == '.' && (flags & FNM_STYLE_MASK) == FNM_DOS)1810 return FNM_NOMATCH;1811 ++name;1812 }1813 1814 case '.':1815 1816 /* A dot matches a dot. It also matches the implicit dot at1817 * the end of a dot-less NAME. */1818 1819 ++mask;1820 if (*name == '.')1821 ++name;1822 else if (has_dot || !IS_OS2_COMP_END(*name))1823 return FNM_NOMATCH;1824 break;1825 1826 default:1827 1828 /* All other characters match themselves. */1829 1830 if (flags & FNM_IGNORECASE)1831 {1832 if (tolower(*mask) != tolower(*name))1833 return FNM_NOMATCH;1834 }1835 else1836 {1837 if (*mask != *name)1838 return FNM_NOMATCH;1839 }1840 ++mask;1841 ++name;1842 break;1843 }1844 }1845 1846 /*1847 * match_comp:1848 * compares a single component (directory name or file1849 * name) of the paths, for all styles which need1850 * component-by-component matching. MASK and NAME point1851 * to the start of a component of the wildcard and the1852 * name to be checked, respectively. Comparing stops at1853 * the next separator. The FLAGS argument is the same as1854 * that of fnmatch().1855 *1856 * Return FNM_MATCH iff MASK and NAME match.1857 *1858 * (c) 1994-1996 by Eberhard Mattes.1859 */1860 1861 static int match_comp(const unsigned char *mask,1862 const unsigned char *name,1863 unsigned flags)1864 {1865 const unsigned char *s;1866 1867 switch (flags & FNM_STYLE_MASK)1868 {1869 case FNM_OS2:1870 case FNM_DOS:1871 1872 /* For OS/2 and DOS styles, we add an implicit dot at the end of1873 * the component if the component doesn't include a dot. */1874 1875 s = name;1876 while (!IS_OS2_COMP_END(*s) && *s != '.')1877 ++s;1878 return match_comp_os2(mask, name, flags, *s == '.');1879 1880 default:1881 return FNM_ERR;1882 }1883 }1884 1885 /* In Unix styles, / separates components of a path. This macro1886 * returns true iff C is a separator. */1887 1888 #define IS_UNIX_COMP_SEP(C) ((C) == '/')1889 1890 1891 /* This macro returns true if C is at the end of a component of a1892 * path. */1893 1894 #define IS_UNIX_COMP_END(C) ((C) == 0 || IS_UNIX_COMP_SEP (C))1895 1896 /*1897 * match_unix:1898 * matches complete paths for Unix styles.1899 *1900 * The FLAGS argument is the same as that of fnmatch().1901 * COMP points to the start of the current component in1902 * NAME. Return FNM_MATCH iff MASK and NAME match. The1903 * backslash character is used for escaping ? and * unless1904 * FNM_NOESCAPE is set.1905 *1906 * (c) 1994-1996 by Eberhard Mattes.1907 */1908 1909 static int match_unix(const unsigned char *mask,1910 const unsigned char *name,1911 unsigned flags,1912 const unsigned char *comp)1913 {1914 unsigned char c1, c2;1915 char invert, matched;1916 const unsigned char *start;1917 int rc;1918 1919 for (;;)1920 switch (*mask)1921 {1922 case 0:1923 1924 /* There must be no extra characters at the end of NAME when1925 * reaching the end of MASK unless _FNM_PATHPREFIX is set:1926 * in that case, NAME may point to a separator. */1927 1928 if (*name == 0)1929 return FNM_MATCH;1930 if ((flags & FNM_PATHPREFIX) && IS_UNIX_COMP_SEP(*name))1931 return FNM_MATCH;1932 return FNM_NOMATCH;1933 1934 case '?':1935 1936 /* A question mark matches one character. It does not match1937 * the component separator if FNM_PATHNAME is set. It does1938 * not match a dot at the start of a component if FNM_PERIOD1939 * is set. */1940 1941 if (*name == 0)1942 return FNM_NOMATCH;1943 if ((flags & FNM_PATHNAME) && IS_UNIX_COMP_SEP(*name))1944 return FNM_NOMATCH;1945 if (*name == '.' && (flags & FNM_PERIOD) && name == comp)1946 return FNM_NOMATCH;1947 ++mask;1948 ++name;1949 break;1950 1951 case '*':1952 1953 /* An asterisk matches zero or more characters. It does not1954 * match the component separator if FNM_PATHNAME is set. It1955 * does not match a dot at the start of a component if1956 * FNM_PERIOD is set. */1957 1958 if (*name == '.' && (flags & FNM_PERIOD) && name == comp)1959 return FNM_NOMATCH;1960 do1961 {1962 ++mask;1963 }1964 while (*mask == '*');1965 for (;;)1966 {1967 rc = match_unix(mask, name, flags, comp);1968 if (rc != FNM_NOMATCH)1969 return rc;1970 if (*name == 0)1971 return FNM_NOMATCH;1972 if ((flags & FNM_PATHNAME) && IS_UNIX_COMP_SEP(*name))1973 return FNM_NOMATCH;1974 ++name;1975 }1976 1977 case '/':1978 1979 /* Separators match only separators. If _FNM_PATHPREFIX is1980 * set, a trailing separator in MASK is ignored at the end1981 * of NAME. */1982 1983 if (!(IS_UNIX_COMP_SEP(*name)1984 || ((flags & FNM_PATHPREFIX) && *name == 01985 && (mask[1] == 01986 || (!(flags & FNM_NOESCAPE) && mask[1] == '\\'1987 && mask[2] == 0)))))1988 return FNM_NOMATCH;1989 1990 ++mask;1991 if (*name != 0)1992 ++name;1993 1994 /* This is the beginning of a new component if FNM_PATHNAME1995 * is set. */1996 1997 if (flags & FNM_PATHNAME)1998 comp = name;1999 break;2000 2001 case '[':2002 2003 /* A set of characters. Always case-sensitive. */2004 2005 if (*name == 0)2006 return FNM_NOMATCH;2007 if ((flags & FNM_PATHNAME) && IS_UNIX_COMP_SEP(*name))2008 return FNM_NOMATCH;2009 if (*name == '.' && (flags & FNM_PERIOD) && name == comp)2010 return FNM_NOMATCH;2011 2012 invert = 0;2013 matched = 0;2014 ++mask;2015 2016 /* If the first character is a ! or ^, the set matches all2017 * characters not listed in the set. */2018 2019 if (*mask == '!' || *mask == '^')2020 {2021 ++mask;2022 invert = 1;2023 }2024 2025 /* Loop over all the characters of the set. The loop ends2026 * if the end of the string is reached or if a ] is2027 * encountered unless it directly follows the initial [ or2028 * [-. */2029 2030 start = mask;2031 while (!(*mask == 0 || (*mask == ']' && mask != start)))2032 {2033 /* Get the next character which is optionally preceded2034 * by a backslash. */2035 2036 c1 = *mask++;2037 if (!(flags & FNM_NOESCAPE) && c1 == '\\')2038 {2039 if (*mask == 0)2040 break;2041 c1 = *mask++;2042 }2043 2044 /* Ranges of characters are written as a-z. Don't2045 * forget to check for the end of the string and to2046 * handle the backslash. If the character after - is a2047 * ], it isn't a range. */2048 2049 if (*mask == '-' && mask[1] != ']')2050 {2051 ++mask; /* Skip the - character */2052 if (!(flags & FNM_NOESCAPE) && *mask == '\\')2053 ++mask;2054 if (*mask == 0)2055 break;2056 c2 = *mask++;2057 }2058 else2059 c2 = c1;2060 2061 /* Now check whether this character or range matches NAME. */2062 2063 if (c1 <= *name && *name <= c2)2064 matched = 1;2065 }2066 2067 /* If the end of the string is reached before a ] is found,2068 * back up to the [ and compare it to NAME. */2069 2070 if (*mask == 0)2071 {2072 if (*name != '[')2073 return FNM_NOMATCH;2074 ++name;2075 mask = start;2076 if (invert)2077 --mask;2078 }2079 else2080 {2081 if (invert)2082 matched = !matched;2083 if (!matched)2084 return FNM_NOMATCH;2085 ++mask; /* Skip the ] character */2086 if (*name != 0)2087 ++name;2088 }2089 break;2090 2091 case '\\':2092 ++mask;2093 if (flags & FNM_NOESCAPE)2094 {2095 if (*name != '\\')2096 return FNM_NOMATCH;2097 ++name;2098 }2099 else if (*mask == '*' || *mask == '?')2100 {2101 if (*mask != *name)2102 return FNM_NOMATCH;2103 ++mask;2104 ++name;2105 }2106 break;2107 2108 default:2109 2110 /* All other characters match themselves. */2111 2112 if (flags & FNM_IGNORECASE)2113 {2114 if (tolower(*mask) != tolower(*name))2115 return FNM_NOMATCH;2116 }2117 else2118 {2119 if (*mask != *name)2120 return FNM_NOMATCH;2121 }2122 ++mask;2123 ++name;2124 break;2125 }2126 }2127 2128 /*2129 * _fnmatch_unsigned:2130 * Check whether the path name NAME matches the wildcard MASK.2131 *2132 * Return:2133 * -- 0 (FNM_MATCH) if it matches,2134 * -- _FNM_NOMATCH if it doesn't,2135 * -- FNM_ERR on error.2136 *2137 * The operation of this function is controlled by FLAGS.2138 * This is an internal function, with unsigned arguments.2139 *2140 * (c) 1994-1996 by Eberhard Mattes.2141 */2142 2143 static int _fnmatch_unsigned(const unsigned char *mask,2144 const unsigned char *name,2145 unsigned flags)2146 {2147 int m_drive,2148 n_drive,2149 rc;2150 2151 /* Match and skip the drive name if present. */2152 2153 m_drive = ((isalpha(mask[0]) && mask[1] == ':') ? mask[0] : -1);2154 n_drive = ((isalpha(name[0]) && name[1] == ':') ? name[0] : -1);2155 2156 if (m_drive != n_drive)2157 {2158 if (m_drive == -1 || n_drive == -1)2159 return FNM_NOMATCH;2160 if (!(flags & FNM_IGNORECASE))2161 return FNM_NOMATCH;2162 if (tolower(m_drive) != tolower(n_drive))2163 return FNM_NOMATCH;2164 }2165 2166 if (m_drive != -1)2167 mask += 2;2168 if (n_drive != -1)2169 name += 2;2170 2171 /* Colons are not allowed in path names, except for the drive name,2172 * which was skipped above. */2173 2174 if (has_colon(mask) || has_colon(name))2175 return FNM_ERR;2176 2177 /* The name "\\server\path" should not be matched by mask2178 * "\*\server\path". Ditto for /. */2179 2180 switch (flags & FNM_STYLE_MASK)2181 {2182 case FNM_OS2:2183 case FNM_DOS:2184 2185 if (IS_OS2_COMP_SEP(name[0]) && IS_OS2_COMP_SEP(name[1]))2186 {2187 if (!(IS_OS2_COMP_SEP(mask[0]) && IS_OS2_COMP_SEP(mask[1])))2188 return FNM_NOMATCH;2189 name += 2;2190 mask += 2;2191 }2192 break;2193 2194 case FNM_POSIX:2195 2196 if (name[0] == '/' && name[1] == '/')2197 {2198 int i;2199 2200 name += 2;2201 for (i = 0; i < 2; ++i)2202 if (mask[0] == '/')2203 ++mask;2204 else if (mask[0] == '\\' && mask[1] == '/')2205 mask += 2;2206 else2207 return FNM_NOMATCH;2208 }2209 2210 /* In Unix styles, treating ? and * w.r.t. components is simple.2211 * No need to do matching component by component. */2212 2213 return match_unix(mask, name, flags, name);2214 }2215 2216 /* Now compare all the components of the path name, one by one.2217 * Note that the path separator must not be enclosed in brackets. */2218 2219 while (*mask != 0 || *name != 0)2220 {2221 2222 /* If _FNM_PATHPREFIX is set, the names match if the end of MASK2223 * is reached even if there are components left in NAME. */2224 2225 if (*mask == 0 && (flags & FNM_PATHPREFIX))2226 return FNM_MATCH;2227 2228 /* Compare a single component of the path name. */2229 2230 rc = match_comp(mask, name, flags);2231 if (rc != FNM_MATCH)2232 return rc;2233 2234 /* Skip to the next component or to the end of the path name. */2235 2236 mask = skip_comp_os2(mask);2237 name = skip_comp_os2(name);2238 }2239 2240 /* If we reached the ends of both strings, the names match. */2241 2242 if (*mask == 0 && *name == 0)2243 return FNM_MATCH;2244 2245 /* The names do not match. */2246 2247 return FNM_NOMATCH;2248 }2249 2250 /*2251 *@@ strhMatchOS2:2252 * this matches wildcards, similar to what DosEditName does.2253 * However, this does not require a file to be present, but2254 * works on strings only.2255 */2256 2257 BOOL strhMatchOS2(const char *pcszMask, // in: mask (e.g. "*.txt")2258 const char *pcszName) // in: string to check (e.g. "test.txt")2259 {2260 return ((BOOL)(_fnmatch_unsigned((const unsigned char *)pcszMask,2261 (const unsigned char *)pcszName,2262 FNM_OS2 | FNM_IGNORECASE)2263 == FNM_MATCH)2264 );2265 }2266 2267 /*2268 *@@ strhMatchExt:2269 * like strhMatchOS2, but this takes all the flags2270 * for input.2271 *2272 *@@added V0.9.15 (2001-09-14) [umoeller]2273 */2274 2275 BOOL strhMatchExt(const char *pcszMask, // in: mask (e.g. "*.txt")2276 const char *pcszName, // in: string to check (e.g. "test.txt")2277 unsigned flags) // in: FNM_* flags2278 {2279 return ((BOOL)(_fnmatch_unsigned((const unsigned char *)pcszMask,2280 (const unsigned char *)pcszName,2281 flags)2282 == FNM_MATCH)2283 );2284 }2285 2286 /* ******************************************************************2287 *2288 1663 * Fast string searches 2289 1664 * -
trunk/src/helpers/timer.c
r123 r127 12 12 * to those XTimers which have elapsed. 13 13 * 14 * So to use XTimers, do the following:15 *16 * 1. Create a timer set with tmrCreateSet. Specify17 * an owner window and the timer ID of the master18 * PM timer.19 *20 * 2. You can then start and stop XTimers for windows21 * on the same thread by calling tmrStartXTimer and22 * tmrStopXTimer, respectively.23 *24 * 3. In the window proc of the owner window, respond25 * to WM_TIMER for the master PM timer by calling26 * tmrTimerTick. This will call the window procs27 * of those windows with WM_TIMER messages directly28 * whose XTimers have elapsed.29 *30 14 * The main advantage of the XTimers is that these 31 15 * are not a limited resource (as opposed to PM timers). … … 34 18 * be queried with WinQuerySysValue(SV_CTIMERS). 35 19 * 20 * XTimers are used excessively by the default widgets 21 * of XWorkplace's XCenter. 22 * 36 23 * There are a few limitations with the XTimers though: 37 *38 * -- If you start a timer with a timeout < 100 ms,39 * the first WM_TIMER might not appear before40 * 100 ms have elapsed. This may or be not the41 * case, depending on whether other timers are42 * running.43 24 * 44 25 * -- tmrTimerTick (which you must call when the … … 62 43 * side, always call tmrStopAllTimers when WM_DESTROY 63 44 * comes into a window which has used timers. 45 * 46 * So to use XTimers, do the following: 47 * 48 * 1. Create a timer set with tmrCreateSet. Specify 49 * an owner window and the timer ID of the master 50 * PM timer. 51 * 52 * 2. You can then start and stop XTimers for windows 53 * on the same thread by calling tmrStartXTimer and 54 * tmrStopXTimer, respectively. 55 * 56 * 3. In the window proc of the owner window, respond 57 * to WM_TIMER for the master PM timer by calling 58 * tmrTimerTick. This will call the window procs 59 * of those windows with WM_TIMER messages directly 60 * whose XTimers have elapsed. 64 61 * 65 62 * Function prefixes: … … 195 192 USHORT usTimerID) // in: timer ID 196 193 { 197 if (pSet && pSet->pvllXTimers) 198 { 199 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 194 PLINKLIST pllXTimers; 195 if ( (pSet) 196 && (pllXTimers = (PLINKLIST)pSet->pvllXTimers) 197 ) 198 { 200 199 PLISTNODE pNode = lstQueryFirstNode(pllXTimers); 201 200 while (pNode) … … 227 226 PXTIMER pTimer) // in: timer to remove. 228 227 { 229 if (pSet && pSet->pvllXTimers) 230 { 231 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 228 PLINKLIST pllXTimers; 229 if ( (pSet) 230 && (pllXTimers = (PLINKLIST)pSet->pvllXTimers) 231 ) 232 { 232 233 lstRemoveItem(pllXTimers, 233 234 pTimer); // auto-free! … … 409 410 if (pSet) 410 411 { 411 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;412 if (pllXTimers )412 PLINKLIST pllXTimers; 413 if (pllXTimers = (PLINKLIST)pSet->pvllXTimers) 413 414 { 414 415 PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers); … … 424 425 pSet->pvllXTimers = NULL; 425 426 } 427 428 if (pSet->idPMTimerRunning) 429 { 430 WinStopTimer(pSet->hab, 431 pSet->hwndOwner, 432 pSet->idPMTimer); 433 pSet->idPMTimerRunning = 0; 434 } 435 436 free(pSet); 426 437 } 427 428 if (pSet->idPMTimerRunning)429 {430 WinStopTimer(pSet->hab,431 pSet->hwndOwner,432 pSet->idPMTimer);433 pSet->idPMTimerRunning = 0;434 }435 436 free(pSet);437 438 438 439 UnlockTimers(); … … 456 457 *@@changed V0.9.14 (2001-08-01) [umoeller]: fixed mem overwrite which might have caused crashes if this got called during tmrTimerTick 457 458 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed "half frequency" regression caused by frequency optimizations 459 *@@changed V0.9.16 (2001-12-18) [umoeller]: now using WinDispatchMsg to avoid crashes during win destruction 458 460 */ 459 461 … … 462 464 if (LockTimers()) 463 465 { 464 if (pSet) 465 { 466 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 467 if (pllXTimers) 466 PLINKLIST pllXTimers; 467 if ( (pSet) 468 && (pllXTimers = (PLINKLIST)pSet->pvllXTimers) 469 ) 470 { 471 // go thru all XTimers and see which one 472 // has elapsed; for all of these, post WM_TIMER 473 // to the target window proc 474 PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers); 475 476 if (!pTimerNode) 468 477 { 469 // go thru all XTimers and see which one 470 // has elapsed; for all of these, post WM_TIMER 471 // to the target window proc 472 PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers); 473 474 if (!pTimerNode) 478 // no timers left: 479 if (pSet->idPMTimerRunning) 475 480 { 476 // no timers left: 477 if (pSet->idPMTimerRunning) 481 // but PM timer running: 482 // stop it 483 WinStopTimer(pSet->hab, 484 pSet->hwndOwner, 485 pSet->idPMTimer); 486 pSet->idPMTimerRunning = 0; 487 } 488 489 pSet->ulPMTimeout = 0; 490 } 491 else 492 { 493 // we have timers: 494 BOOL fFoundInvalid = FALSE; 495 496 // get current time 497 ULONG ulTimeNow = 0; 498 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, 499 &ulTimeNow, sizeof(ulTimeNow)); 500 501 #ifdef DEBUG_XTIMERS 502 _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow)); 503 #endif 504 505 while (pTimerNode) 506 { 507 // get next node first because the 508 // list can get modified while processing 509 // V0.9.12 (2001-05-24) [umoeller] 510 PLISTNODE pNext = pTimerNode->pNext; 511 512 PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData; 513 514 #ifdef DEBUG_XTIMERS 515 _Pmpf((" timer %d: ulNextFire = %d", 516 lstIndexFromItem(pllXTimers, pTimer), 517 pTimer->ulNextFire)); 518 #endif 519 520 if ( (pTimer) 521 // && (pTimer->ulNextFire < ulTimeNow) 522 // V0.9.14 (2001-08-01) [umoeller] 523 // use <= because otherwise we'll get 524 // only half the frequency... 525 // we get here frequently where the 526 // two values are EXACTLY equal due 527 // to the above optimization (DosQuerySysInfo 528 // called once only for the entire loop) 529 && (pTimer->ulNextFire <= ulTimeNow) 530 ) 478 531 { 479 // but PM timer running: 480 // stop it 481 WinStopTimer(pSet->hab, 482 pSet->hwndOwner, 483 pSet->idPMTimer); 484 pSet->idPMTimerRunning = 0; 485 } 486 487 pSet->ulPMTimeout = 0; 488 } 489 else 490 { 491 // we have timers: 492 BOOL fFoundInvalid = FALSE; 493 494 // get current time 495 ULONG ulTimeNow = 0; 496 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, 497 &ulTimeNow, sizeof(ulTimeNow)); 498 499 #ifdef DEBUG_XTIMERS 500 _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow)); 501 #endif 502 503 while (pTimerNode) 504 { 505 // get next node first because the 506 // list can get modified while processing 507 // V0.9.12 (2001-05-24) [umoeller] 508 PLISTNODE pNext = pTimerNode->pNext; 509 510 PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData; 532 // this timer has elapsed: 533 // fire! 511 534 512 535 #ifdef DEBUG_XTIMERS 513 _Pmpf((" timer %d: ulNextFire = %d", 514 lstIndexFromItem(pllXTimers, pTimer), 515 pTimer->ulNextFire)); 536 _Pmpf((" --> fire!")); 516 537 #endif 517 538 518 if ( (pTimer) 519 // && (pTimer->ulNextFire < ulTimeNow) 520 // V0.9.14 (2001-08-01) [umoeller] 521 // use <= because otherwise we'll get 522 // only half the frequency... 523 // we get here frequently where the 524 // two values are EXACTLY equal due 525 // to the above optimization (DosQuerySysInfo 526 // called once only for the entire loop) 527 && (pTimer->ulNextFire <= ulTimeNow) 528 ) 539 if (WinIsWindow(pSet->hab, 540 pTimer->hwndTarget)) 529 541 { 530 // this timer has elapsed: 531 // fire! 532 533 #ifdef DEBUG_XTIMERS 534 _Pmpf((" --> fire!")); 535 #endif 536 537 if (WinIsWindow(pSet->hab, 538 pTimer->hwndTarget)) 539 { 540 // window still valid: 541 // get the window's window proc 542 QMSG qmsg; 543 /* PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget, 544 QWP_PFNWP); */ 545 546 // moved this up V0.9.14 (2001-08-01) [umoeller] 547 pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout; 548 549 // call the window proc DIRECTLY 550 qmsg.hwnd = pTimer->hwndTarget; 551 qmsg.msg = WM_TIMER; 552 qmsg.mp1 = (MPARAM)pTimer->usTimerID; 553 qmsg.mp2 = (MPARAM)0; 554 qmsg.time = 0; 555 qmsg.ptl.x = 0; 556 qmsg.ptl.y = 0; 557 qmsg.reserved = 0; 558 WinDispatchMsg(pSet->hab, 559 &qmsg); 560 /* pfnwp(pTimer->hwndTarget, 561 WM_TIMER, 562 (MPARAM)pTimer->usTimerID, 563 0); */ 564 // V0.9.12 (2001-05-24) [umoeller] 565 // if the winproc chooses to start or 566 // stop a timer, pNext still points 567 // to a valid node... 568 // -- if a timer is removed, that's OK 569 // -- if a timer is added, it is added to 570 // the list, so we'll see it in this loop 571 572 // V0.9.14 (2001-08-01) [umoeller] 573 574 // DO NOT REFERENCE pTimer AFTER THIS CODE; 575 // tmrTimerTick might have removed the timer, 576 // and since the list is auto-free, pTimer 577 // might have been freed!! 578 } 579 else 580 { 581 // window has been destroyed: 582 lstRemoveNode(pllXTimers, 583 pTimerNode); 584 // pNext is still valid 585 586 fFoundInvalid = TRUE; 587 } 588 589 } // end if (pTimer->ulNextFire < ulTimeNow) 590 591 // next timer 592 pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller] 593 } // end while (pTimerNode) 594 595 // destroy invalid timers, if any 596 if (fFoundInvalid) 597 AdjustPMTimer(pSet); 598 599 } // end else if (!pTimerNode) 600 } // end if (pllXTimers) 601 } // end if (pSet) 542 // window still valid: 543 // get the window's window proc 544 QMSG qmsg; 545 /* PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget, 546 QWP_PFNWP); */ 547 548 // moved this up V0.9.14 (2001-08-01) [umoeller] 549 pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout; 550 551 // call the window proc DIRECTLY 552 // V0.9.16 (2001-12-18) [umoeller]: 553 // now using WinDispatchMsg to avoid crashes 554 // while hwndTarget is being destroyed 555 qmsg.hwnd = pTimer->hwndTarget; 556 qmsg.msg = WM_TIMER; 557 qmsg.mp1 = (MPARAM)pTimer->usTimerID; 558 qmsg.mp2 = (MPARAM)0; 559 qmsg.time = 0; 560 qmsg.ptl.x = 0; 561 qmsg.ptl.y = 0; 562 qmsg.reserved = 0; 563 WinDispatchMsg(pSet->hab, 564 &qmsg); 565 566 /* pfnwp(pTimer->hwndTarget, 567 WM_TIMER, 568 (MPARAM)pTimer->usTimerID, 569 0); */ 570 // V0.9.12 (2001-05-24) [umoeller] 571 // if the winproc chooses to start or 572 // stop a timer, pNext still points 573 // to a valid node... 574 // -- if a timer is removed, that's OK 575 // -- if a timer is added, it is added to 576 // the list, so we'll see it in this loop 577 578 // V0.9.14 (2001-08-01) [umoeller] 579 580 // DO NOT REFERENCE pTimer AFTER THIS CODE; 581 // the winproc might have removed the timer, 582 // and since the list is auto-free, pTimer 583 // might have been freed!! 584 } 585 else 586 { 587 // window has been destroyed: 588 lstRemoveNode(pllXTimers, 589 pTimerNode); 590 // pNext is still valid 591 592 fFoundInvalid = TRUE; 593 } 594 595 } // end if (pTimer->ulNextFire < ulTimeNow) 596 597 // next timer 598 pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller] 599 } // end while (pTimerNode) 600 601 // destroy invalid timers, if any 602 if (fFoundInvalid) 603 AdjustPMTimer(pSet); 604 605 } // end else if (!pTimerNode) 606 } // end if (pllXTimers) 602 607 603 608 UnlockTimers(); … … 614 619 * XTimers is not limited. 615 620 * 616 * Returns a new timer or resets an existing 617 * timer (if usTimerID is already used with 618 * hwnd). Use tmrStopXTimer to stop the timer. 621 * Returns the ID of a new timer or resets an 622 * existing timer (if usTimerID is already used 623 * with hwnd). Use tmrStopXTimer to stop the timer. 624 * 625 * Returns 0 if an error occured. It is thus 626 * invalid to specify a timer ID of 0. 619 627 * 620 628 * The timer is _not_ stopped automatically … … 644 652 USHORT XWPENTRY tmrStartXTimer(PXTIMERSET pSet, // in: timer set (from tmrCreateSet) 645 653 HWND hwnd, // in: target window for XTimer 646 USHORT usTimerID, // in: timer ID for XTimer's WM_TIMER 654 USHORT usTimerID, // in: timer ID for XTimer's WM_TIMER (must be > 0) 647 655 ULONG ulTimeout) // in: XTimer's timeout 648 656 { … … 653 661 if (LockTimers()) 654 662 { 655 if (pSet) 656 { 657 PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 658 659 if ((pllXTimers) && (hwnd) && (ulTimeout)) 663 PLINKLIST pllXTimers; 664 if ( (pSet) 665 && (pllXTimers = (PLINKLIST)pSet->pvllXTimers) 666 && (hwnd) 667 && (ulTimeout) 668 && (usTimerID) // V0.9.16 (2001-12-18) [umoeller] 669 ) 670 { 671 PXTIMER pTimer; 672 ULONG ulTimeNow; 673 674 // fix the timeout... we allow only multiples of 675 // 25, and it must be at least 25 (otherwise our 676 // internal master timer calculations will fail) 677 // V0.9.14 (2001-07-07) [umoeller] 678 if (ulTimeout < 25) 679 ulTimeout = 25; 680 else 681 ulTimeout = (ulTimeout + 10) / 25 * 25; 682 683 DosQuerySysInfo(QSV_MS_COUNT, 684 QSV_MS_COUNT, 685 &ulTimeNow, 686 sizeof(ulTimeNow)); 687 688 // check if this timer exists already 689 if (pTimer = FindTimer(pSet, 690 hwnd, 691 usTimerID)) 660 692 { 661 PXTIMER pTimer; 662 663 // fix the timeout... we allow only multiples of 664 // 25, and it must be at least 25 (otherwise our 665 // internal master timer calculations will fail) 666 // V0.9.14 (2001-07-07) [umoeller] 667 if (ulTimeout < 25) 668 ulTimeout = 25; 669 else 670 ulTimeout = (ulTimeout + 10) / 25 * 25; 671 672 // check if this timer exists already 673 if (pTimer = FindTimer(pSet, 674 hwnd, 675 usTimerID)) 693 // exists already: reset only 694 pTimer->ulNextFire = ulTimeNow + ulTimeout; 695 usrc = usTimerID; 696 } 697 else 698 { 699 // new timer needed: 700 if (pTimer = NEW(XTIMER)) 676 701 { 677 // exists already: reset only 678 ULONG ulTimeNow; 679 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, 680 &ulTimeNow, sizeof(ulTimeNow)); 702 pTimer->usTimerID = usTimerID; 703 pTimer->hwndTarget = hwnd; 704 pTimer->ulTimeout = ulTimeout; 681 705 pTimer->ulNextFire = ulTimeNow + ulTimeout; 706 707 lstAppendItem(pllXTimers, 708 pTimer); 682 709 usrc = usTimerID; 683 710 } 684 else 685 { 686 // new timer needed: 687 if (pTimer = NEW(XTIMER)) 688 { 689 ULONG ulTimeNow; 690 DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, 691 &ulTimeNow, sizeof(ulTimeNow)); 692 pTimer->usTimerID = usTimerID; 693 pTimer->hwndTarget = hwnd; 694 pTimer->ulTimeout = ulTimeout; 695 pTimer->ulNextFire = ulTimeNow + ulTimeout; 696 697 lstAppendItem(pllXTimers, 698 pTimer); 699 usrc = usTimerID; 700 } 701 } 702 703 if (usrc) 704 // timer created or reset: 705 AdjustPMTimer(pSet); 706 707 } // if ((hwnd) && (ulTimeout)) 708 } 711 } 712 713 if (usrc) 714 // timer created or reset: 715 AdjustPMTimer(pSet); 716 717 } // if ((hwnd) && (ulTimeout)) 709 718 710 719 UnlockTimers(); … … 733 742 if (LockTimers()) 734 743 { 735 if (pSet && pSet->pvllXTimers) 736 { 737 // PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers; 738 739 PXTIMER pTimer = FindTimer(pSet, 740 hwnd, 741 usTimerID); 742 if (pTimer) 743 { 744 RemoveTimer(pSet, pTimer); 745 // recalculate 746 AdjustPMTimer(pSet); 747 brc = TRUE; 748 } 744 PXTIMER pTimer; 745 if (pTimer = FindTimer(pSet, 746 hwnd, 747 usTimerID)) 748 // FindTimer checks the params 749 { 750 RemoveTimer(pSet, pTimer); 751 // recalculate 752 AdjustPMTimer(pSet); 753 brc = TRUE; 749 754 } 750 755 -
trunk/src/helpers/wphandle.c
r116 r127 949 949 * filename for hObject. 950 950 * This is a one-shot function, using wphQueryActiveHandles, 951 * wphReadAllBlocks, and wphFindPartName. 951 * wphLoadHandles, and wphComposePath. 952 * As a result, this function is _very_ expensive. 952 953 * 953 954 * Returns: … … 956 957 * 957 958 * -- ERROR_INVALID_HANDLE: hObject is invalid. 959 * 960 * -- ERROR_WPH_NOT_FILESYSTEM_HANDLE: hObject's hiword is wrong. 958 961 * 959 962 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten … … 983 986 else 984 987 { 988 USHORT usHiwordFileSystem = ((PHANDLESBUF)hHandles)->usHiwordFileSystem; 989 985 990 // is this really a file-system object? 986 if (HIUSHORT(hObject) == ((PHANDLESBUF)hHandles)->usHiwordFileSystem)991 if (HIUSHORT(hObject) == usHiwordFileSystem) 987 992 { 988 993 // use loword only … … 998 1003 // _Pmpf((__FUNCTION__ ": wphFindPartName returned %d", arc)); 999 1004 } 1005 else 1006 arc = ERROR_WPH_NOT_FILESYSTEM_HANDLE; 1000 1007 1001 1008 wphFreeHandles(&hHandles); -
trunk/src/helpers/xml.c
r121 r127 1135 1135 { 1136 1136 // the element is allowed at all: now check for the 1137 // lists case... 1137 // lists case... @@todo 1138 1138 switch (ulDeclType) 1139 1139 {
Note:
See TracChangeset
for help on using the changeset viewer.