Changeset 106 for trunk/src/helpers/wphandle.c
- Timestamp:
- Oct 2, 2001, 8:28:47 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/wphandle.c
r21 r106 12 12 * -- wph* WPS object helper functions 13 13 * 14 * This code is mostly written by Henk Kelder and published 15 * with his kind permission. 14 * Thanks go out to Henk Kelder for telling me the 15 * format of the WPS INI data. With V0.9.16, this 16 * file was completely rewritten and no longer uses 17 * his code though. 16 18 * 17 19 * Note: Version numbering in this file relates to XWorkplace version … … 22 24 23 25 /* 24 * This file Copyright (C) 1997-2000 Ulrich Mller, 25 * Henk Kelder. 26 * This file Copyright (C) 1997-2001 Ulrich Mller, 26 27 * This file is part of the "XWorkplace helpers" source package. 27 28 * This is free software; you can redistribute it and/or modify … … 40 41 // as unsigned char 41 42 43 #define INCL_DOSEXCEPTIONS 44 #define INCL_DOSPROCESS 45 #define INCL_DOSERRORS 46 42 47 #define INCL_WINSHELLDATA 43 48 #include <os2.h> 44 45 #define OPTIONS_SIZE 3276746 49 47 50 #include <stdio.h> … … 49 52 #include <stdlib.h> 50 53 #include <io.h> 54 #include <setjmp.h> 51 55 52 56 #include "setup.h" // code generation and debugging options 53 57 58 #include "helpers\except.h" 59 #include "helpers\prfh.h" 60 #include "helpers\standards.h" 61 #include "helpers\stringh.h" 62 #define INCLUDE_WPHANDLE_PRIVATE 54 63 #include "helpers\wphandle.h" 55 56 /**************************************************** 57 * * 58 * helper functions * 59 * * 60 ****************************************************/ 61 62 static USHORT wphSearchBufferForHandle(PBYTE pHandlesBuffer, ULONG ulBufSize, USHORT usParent, PSZ pszFname); 63 PNODE wphFindPartName(PBYTE pHandlesBuffer, ULONG ulBufSize, USHORT usID, PSZ pszFname, USHORT usMax); 64 65 #define MakeDiskHandle(usObjID) (usObjID | 0x30000) 66 67 #define IsObjectDisk(hObject) ((hObject & 0x30000) == 0x30000) 64 #include "helpers\xstring.h" 68 65 69 66 /* … … 74 71 /* ****************************************************************** 75 72 * 76 * Helperfunctions73 * Load handles functions 77 74 * 78 75 ********************************************************************/ 79 76 80 77 /* 81 *@@ wphQueryProfileData:82 * like PrfQueryProfileData, but allocates sufficient83 * memory and returns a pointer to that buffer.84 * pulSize must point to a ULONG which will then85 * contain the no. of copied bytes.86 */87 88 PBYTE wphQueryProfileData(HINI hIniSystem, // in: can be HINI_USER or HINI_SYSTEM89 PSZ pApp, PSZ pKey, // in: load what?90 PULONG pulSize) // out: bytes loaded91 {92 PBYTE pData = NULL;93 if (PrfQueryProfileSize(hIniSystem, pApp, pKey, pulSize))94 {95 pData = (PBYTE)malloc(*pulSize);96 PrfQueryProfileData(hIniSystem, pApp, pKey, pData, pulSize);97 }98 // _Pmpf((" wphQueryProfileData(%lX, %s, %s, %d)", hIniSystem, pApp, pKey, *pulSize));99 return (pData);100 }101 102 /*103 *@@ wphEnumProfileKeys:104 * allocates memory for a buffer and copies the keys105 * for pApp into it.106 * Returns the pointer to the buffer.107 * pulKeysSize must point to a ULONG which will then108 * contain the size of the returned buffer.109 */110 111 PBYTE wphEnumProfileKeys(HINI hIniSystem, // in: can be HINI_USER or HINI_SYSTEM112 PSZ pApp, // in: app to query113 PULONG pulKeysSize) // out: sizeof(return buffer)114 {115 PBYTE pszKeys = NULL;116 if (PrfQueryProfileSize(hIniSystem, pApp, NULL, pulKeysSize))117 {118 pszKeys = (PBYTE)malloc(*pulKeysSize);119 if (pszKeys)120 PrfQueryProfileData(hIniSystem, pApp, NULL, pszKeys, pulKeysSize);121 }122 return (pszKeys);123 }124 125 /*126 * wphResetBlockBuffer:127 * Reset the block buffer, make sure the buffer is re-read.128 */129 130 /* VOID wphResetBlockBuffer(VOID)131 {132 if (pHandlesBuffer)133 {134 free(pHandlesBuffer);135 pHandlesBuffer = NULL;136 }137 } */138 139 /*140 78 *@@ wphQueryActiveHandles: 141 * this copies the contents of PM_Workplace:ActiveHandles 142 * in OS2SYS.INI into a given buffer. There are always two 143 * buffers in OS2SYS.INI for object handles, called 144 * "PM_Workplace:HandlesX" with "X" either being "0" or "1". 79 * returns the value of PM_Workplace:ActiveHandles 80 * in OS2SYS.INI as a new buffer. 81 * 82 * There are always two buffers in OS2SYS.INI for object 83 * handles, called "PM_Workplace:HandlesX" with "X" either 84 * being "0" or "1". 85 * 145 86 * It seems that every time the WPS does something in the 146 87 * handles section, it writes the data to the inactive … … 149 90 * by creating a shadow on your Desktop. 150 91 * 151 * This function copies the key only, but not the actual152 * handles blocks (use wphReadAllBlocks for that).92 * This returns a new PSZ which the caller must free() 93 * after use. 153 94 * 154 95 * This gets called by the one-shot function 155 96 * wphQueryHandleFromPath. 156 */ 157 158 BOOL wphQueryActiveHandles(HINI hIniSystem, // in: can be HINI_USER or HINI_SYSTEM 159 PSZ pszHandlesAppName, // out: active handles buffer. 160 USHORT usMax) // in: sizeof(pszHandlesAppName) 161 { 162 PBYTE pszHandles; 163 ULONG ulProfileSize; 164 165 pszHandles = wphQueryProfileData(hIniSystem, 166 ACTIVEHANDLES, HANDLESAPP, 167 &ulProfileSize); 168 if (!pszHandles) 169 { 170 strncpy(pszHandlesAppName, HANDLES, usMax-1); 171 return TRUE; 172 } 173 // fNewFormat = TRUE; 174 strncpy(pszHandlesAppName, pszHandles, usMax-1); 175 free(pszHandles); 176 return TRUE; 97 * 98 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten 99 */ 100 101 APIRET wphQueryActiveHandles(HINI hiniSystem, 102 PSZ *ppszActiveHandles) 103 { 104 PSZ pszActiveHandles; 105 if (pszActiveHandles = prfhQueryProfileData(hiniSystem, 106 WPINIAPP_ACTIVEHANDLES, 107 WPINIAPP_HANDLESAPP, 108 NULL)) 109 { 110 *ppszActiveHandles = pszActiveHandles; 111 return (NO_ERROR); 112 } 113 114 return (ERROR_WPH_NO_ACTIVEHANDLES_DATA); 115 } 116 117 /* 118 *@@ wphQueryBaseClassesHiwords: 119 * returns the hiwords for the WPS base 120 * classes. Unless the user's system is 121 * really badly configured, this should 122 * set 123 * 124 * -- pusHiwordAbstract to 2; 125 * -- pusHiwordFileSystem to 3. 126 * 127 * Returns: 128 * 129 * -- NO_ERROR 130 * 131 * -- ERROR_WPH_NO_BASECLASS_DATA 132 * 133 * -- ERROR_WPH_INCOMPLETE_BASECLASS_DATA 134 * 135 * This gets called automatically from wphLoadHandles. 136 * 137 *@@added V0.9.16 (2001-10-02) [umoeller] 138 */ 139 140 APIRET wphQueryBaseClassesHiwords(HINI hiniUser, 141 PUSHORT pusHiwordAbstract, 142 PUSHORT pusHiwordFileSystem) 143 { 144 APIRET arc = NO_ERROR; 145 146 // get the index of WPFileSystem from the base classes list... 147 // we need this to determine the hiword for file-system handles 148 // properly. Normally, this should be 3. 149 ULONG cbBaseClasses = 0; 150 PSZ pszBaseClasses; 151 if (pszBaseClasses = prfhQueryProfileData(hiniUser, 152 "PM_Workplace:BaseClass", 153 "ClassList", 154 &cbBaseClasses)) 155 { 156 // parse that buffer... these has the base class names, 157 // separated by 0. List is terminated by two zeroes. 158 PSZ pszClassThis = pszBaseClasses; 159 ULONG ulHiwordThis = 1; 160 while ( (*pszClassThis) 161 && (pszClassThis - pszBaseClasses < cbBaseClasses) 162 ) 163 { 164 if (!strcmp(pszClassThis, "WPFileSystem")) 165 *pusHiwordFileSystem = ulHiwordThis; 166 else if (!strcmp(pszClassThis, "WPAbstract")) 167 *pusHiwordAbstract = ulHiwordThis; 168 169 ulHiwordThis++; 170 pszClassThis += strlen(pszClassThis) + 1; 171 } 172 173 // now check if we found both 174 if ( (!(*pusHiwordFileSystem)) 175 || (!(*pusHiwordAbstract)) 176 ) 177 arc = ERROR_WPH_INCOMPLETE_BASECLASS_DATA; 178 179 free(pszBaseClasses); 180 } 181 else 182 arc = ERROR_WPH_NO_BASECLASS_DATA; 183 184 return (arc); 185 } 186 187 /* 188 *@@ wphRebuildNodeHashTable: 189 * 190 * Returns: 191 * 192 * -- NO_ERROR 193 * 194 * -- ERROR_INVALID_PARAMETER 195 * 196 * -- ERROR_WPH_CORRUPT_HANDLES_DATA 197 * 198 *@@added V0.9.16 (2001-10-02) [umoeller] 199 */ 200 201 APIRET wphRebuildNodeHashTable(PHANDLESBUF pHandlesBuf) 202 { 203 APIRET arc = NO_ERROR; 204 205 if ( (!pHandlesBuf) 206 || (!pHandlesBuf->pbData) 207 || (!pHandlesBuf->cbData) 208 ) 209 arc = ERROR_INVALID_PARAMETER; 210 else 211 { 212 // start at beginning of buffer 213 PBYTE pCur = pHandlesBuf->pbData + 4; 214 PBYTE pEnd = pHandlesBuf->pbData + pHandlesBuf->cbData; 215 216 memset(pHandlesBuf->NodeHashTable, 0, sizeof(pHandlesBuf->NodeHashTable)); 217 218 // now set up hash table 219 while (pCur < pEnd) 220 { 221 if (!memicmp(pCur, "DRIV", 4)) 222 { 223 // pCur points to a DRIVE node: 224 // these never have handles, so skip this 225 PDRIV pDriv = (PDRIV)pCur; 226 pCur += sizeof(DRIV) + strlen(pDriv->szName); 227 } 228 else if (!memicmp(pCur, "NODE", 4)) 229 { 230 // pCur points to a regular NODE: offset pointer first 231 PNODE pNode = (PNODE)pCur; 232 // store PNODE in hash table 233 pHandlesBuf->NodeHashTable[pNode->usHandle] = pNode; 234 pCur += sizeof (NODE) + pNode->usNameSize; 235 } 236 else 237 { 238 arc = ERROR_WPH_CORRUPT_HANDLES_DATA; 239 break; 240 } 241 } 242 } 243 244 if (!arc) 245 pHandlesBuf->fNodeHashTableValid = TRUE; 246 247 return (arc); 248 } 249 250 /* 251 *@@ wphLoadHandles: 252 * returns a HANDLESBUF structure which will hold 253 * all the handles from OS2SYS.INI. In addition, 254 * this calls wphQueryBaseClassesHiwords and puts 255 * the hiwords for WPAbstract and WPFileSystem into 256 * the HANDLESBUF as well. 257 * 258 * Prerequisite before using any of the other wph* 259 * functions. 260 * 261 * Call wphFreeHandles to free all data allocated 262 * by this function. 263 * 264 * Returns: 265 * 266 * -- NO_ERROR 267 * 268 * -- ERROR_NOT_ENOUGH_MEMORY 269 * 270 * -- ERROR_INVALID_PARAMETER 271 * 272 * -- ERROR_WPH_NO_HANDLES_DATA: cannot read handle blocks. 273 * 274 * -- ERROR_WPH_CORRUPT_HANDLES_DATA: cannot read handle blocks. 275 * 276 *@@added V0.9.16 (2001-10-02) [umoeller] 277 */ 278 279 APIRET wphLoadHandles(HINI hiniUser, // in: HINI_USER or other INI handle 280 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle 281 const char *pcszActiveHandles, 282 PHANDLESBUF *ppHandlesBuf) 283 { 284 APIRET arc = NO_ERROR; 285 286 if (!ppHandlesBuf) 287 arc = ERROR_INVALID_PARAMETER; 288 else 289 { 290 PSZ pszKeysList; 291 if (!(arc = prfhQueryKeysForApp(hiniSystem, 292 pcszActiveHandles, 293 &pszKeysList))) 294 { 295 PHANDLESBUF pReturn = NULL; 296 297 ULONG ulHighestBlock = 0, 298 ul, 299 cbTotal; 300 PBYTE pbData; 301 302 const char *pKey2 = pszKeysList; 303 while (*pKey2) 304 { 305 if (!memicmp((PVOID)pKey2, "BLOCK", 5)) 306 { 307 ULONG ulBlockThis = atoi(pKey2 + 5); 308 if (ulBlockThis > ulHighestBlock) 309 ulHighestBlock = ulBlockThis; 310 } 311 312 pKey2 += strlen(pKey2)+1; // next key 313 } 314 315 free(pszKeysList); 316 317 if (!ulHighestBlock) 318 arc = ERROR_WPH_NO_HANDLES_DATA; 319 else 320 { 321 // now go read the data 322 // (BLOCK1, BLOCK2, ..., BLOCKn) 323 cbTotal = 0; 324 pbData = NULL; 325 for (ul = 1; 326 ul <= ulHighestBlock; 327 ul++) 328 { 329 ULONG cbBlockThis; 330 CHAR szBlockThis[10]; 331 sprintf(szBlockThis, "BLOCK%d", ul); 332 if (!PrfQueryProfileSize(hiniSystem, 333 (PSZ)pcszActiveHandles, 334 szBlockThis, 335 &cbBlockThis)) 336 { 337 arc = ERROR_WPH_CORRUPT_HANDLES_DATA; 338 break; 339 } 340 else 341 { 342 ULONG cbTotalOld = cbTotal; 343 cbTotal += cbBlockThis; 344 if (!(pbData = realloc(pbData, cbTotal))) 345 // on first call, pbData is NULL and this 346 // behaves like malloc() 347 { 348 arc = ERROR_NOT_ENOUGH_MEMORY; 349 break; 350 } 351 352 if (!PrfQueryProfileData(hiniSystem, 353 (PSZ)pcszActiveHandles, 354 szBlockThis, 355 pbData + cbTotalOld, 356 &cbBlockThis)) 357 { 358 arc = ERROR_WPH_CORRUPT_HANDLES_DATA; 359 break; 360 } 361 } 362 } 363 } 364 365 if (!arc) 366 { 367 // all went OK: 368 if (pReturn = NEW(HANDLESBUF)) 369 { 370 ZERO(pReturn); 371 372 pReturn->pbData = pbData; 373 pReturn->cbData = cbTotal; 374 375 // and load the hiwords too 376 if (!(arc = wphQueryBaseClassesHiwords(hiniUser, 377 &pReturn->usHiwordAbstract, 378 &pReturn->usHiwordFileSystem))) 379 *ppHandlesBuf = pReturn; 380 } 381 else 382 arc = ERROR_NOT_ENOUGH_MEMORY; 383 } 384 385 if (arc) 386 // error: 387 wphFreeHandles(&pReturn); 388 } 389 } 390 391 return (arc); 392 } 393 394 /* 395 *@@ wphFreeHandles: 396 * frees all data allocated by wphLoadHandles 397 * and sets *ppHandlesBuf to NULL, for safety. 398 * 399 *@@added V0.9.16 (2001-10-02) [umoeller] 400 */ 401 402 APIRET wphFreeHandles(PHANDLESBUF *ppHandlesBuf) 403 { 404 APIRET arc = NO_ERROR; 405 406 if (ppHandlesBuf && *ppHandlesBuf) 407 { 408 PBYTE pbData; 409 if (pbData = (*ppHandlesBuf)->pbData) 410 free(pbData); 411 412 free(*ppHandlesBuf); 413 *ppHandlesBuf = NULL; 414 } 415 else 416 arc = ERROR_INVALID_PARAMETER; 417 418 return (arc); 177 419 } 178 420 … … 195 437 */ 196 438 197 BOOL wphReadAllBlocks(HINI hiniSystem, // in: can be HINI_USER or HINI_SYSTEM439 /* BOOL wphReadAllBlocks(HINI hiniSystem, // in: can be HINI_USER or HINI_SYSTEM 198 440 PSZ pszActiveHandles, // in: active handles section 199 441 PBYTE* ppBlock, // in/out: pointer to buffer, which … … 246 488 if (!(*ppBlock)) 247 489 { 248 /* MessageBox("wphReadAllBlocks", "Not enough memory for profile data!"); */249 490 free(pbAllBlocks); 250 491 return FALSE; … … 278 519 free(pbAllBlocks); 279 520 return TRUE; 280 } 521 } */ 281 522 282 523 /* ****************************************************************** … … 289 530 *@@ wphSearchBufferForHandle: 290 531 * returns the four-digit object handle which corresponds 291 * to pszF name, searching pHandlesBuffer. Note that you532 * to pszFilename, searching pHandlesBuffer. Note that you 292 533 * must OR the return value with 0x30000 to make this 293 534 * a valid WPS file-system handle. … … 304 545 USHORT usParent, // in: parent NODE ID; 305 546 // must be 0 initially 306 PSZ pszF name) // in: fully qlf'd filename to search for547 PSZ pszFilename) // in: fully qlf'd filename to search for 307 548 { 308 549 PDRIV pDriv; … … 313 554 USHORT usPartSize; 314 555 315 // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszF name));556 // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszFilename)); 316 557 317 558 // The composed BLOCKs in the handles buffer make up a tree of … … 334 575 // So first find the length of the first filename part (which 335 576 // should be 2 for the drive letter, "C:") 336 p = strchr(pszF name, '\\');577 p = strchr(pszFilename, '\\'); 337 578 if (p) 338 579 // backslash found: 339 usPartSize = p - pszF name; // extract first part580 usPartSize = p - pszFilename; // extract first part 340 581 else 341 usPartSize = strlen(pszF name);582 usPartSize = strlen(pszFilename); 342 583 343 584 // now set the pointer for the end of the BLOCKs buffer … … 348 589 pCur = pHandlesBuffer + 4; 349 590 350 // _Pmpf((" Searching for: %s, usPartSize: %d", pszF name, usPartSize));591 // _Pmpf((" Searching for: %s, usPartSize: %d", pszFilename, usPartSize)); 351 592 352 593 // go! … … 386 627 387 628 // do the partnames match too? 388 if (memicmp(pszF name, pNode->szName, usPartSize) == 0)629 if (memicmp(pszFilename, pNode->szName, usPartSize) == 0) 389 630 { 390 631 // OK!! proper NODE found! … … 393 634 // now check if this was the last NODE 394 635 // we were looking for 395 if (strlen(pszF name) == usPartSize)636 if (strlen(pszFilename) == usPartSize) 396 637 // yes: return ID 397 638 return (pNode->usHandle); … … 399 640 // else: update our status; 400 641 // get next partname 401 pszF name += usPartSize + 1;642 pszFilename += usPartSize + 1; 402 643 // calc next partname length 403 p = strchr(pszF name, '\\');644 p = strchr(pszFilename, '\\'); 404 645 if (p) 405 usPartSize = p - pszFname;646 usPartSize = p - pszFilename; 406 647 else 407 usPartSize = strlen(pszFname);648 usPartSize = strlen(pszFilename); 408 649 409 650 // get next parent to search for … … 426 667 /* 427 668 *@@ wphQueryHandleFromPath: 428 * find the object handle for pszName; this 429 * can either be an object ID ("<WP_DESKTOP>") 430 * or a fully qualified filename. 669 * finds the object handle for the given fully qualified 670 * filename. 431 671 * This is a one-shot function, using wphQueryActiveHandles, 432 672 * wphReadAllBlocks, and wphSearchBufferForHandle. 433 673 * 434 674 * Returns: 435 * -- -1: file does not exist 436 * -- -2: error querying handles buffer 437 * -- 0: object handle not found; might not exist 438 * -- other: found object handle 439 * 440 * NOTE: This function uses C runtime library 441 * string comparison functions. These only work 442 * properly if you have set the locale for the 443 * C runtime properly. This is, for example, a 444 * problem with file names containing German umlauts, 445 * which are not found properly. 446 * You should put some 447 + setlocale(LC_ALL, ""); 448 * statement somewhere, which reacts to the LANG 449 * variable which OS/2 puts into CONFIG.SYS per 450 * default. 451 */ 452 453 HOBJECT wphQueryHandleFromPath(HINI hIniUser, // in: user ini file 454 HINI hIniSystem, // in: system ini file 455 PSZ pszName) // in: fully qlf'd filename 456 { 457 PBYTE pHandlesBuffer = NULL; 458 ULONG cbHandlesBuffer = 0, 459 cbLocation = 0; 460 USHORT usObjID; 675 * 676 * -- NO_ERROR: *phobj has received the object handle. 677 * 678 * -- ERROR_FILE_NOT_FOUND: file does not exist. 679 * 680 * plus the error codes of the other wph* functions called. 681 * 682 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten 683 */ 684 685 APIRET wphQueryHandleFromPath(HINI hiniUser, // in: HINI_USER or other INI handle 686 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle 687 const char *pcszName, // in: fully qlf'd filename 688 HOBJECT *phobj) // out: object handle found if NO_ERROR 689 { 690 APIRET arc = NO_ERROR; 461 691 PVOID pvData; 462 HOBJECT hObject = 0L; 463 BYTE szFullPath[300]; 464 CHAR szActiveHandles[100]; 465 466 // _Pmpf(("wphQueryHandleFromPath: %s", pszName)); 467 468 // try to get the objectID via PM_Workplace:Location, since 469 // pszName might also be a "<WP_DESKTOP>" like thingy 470 pvData = wphQueryProfileData(hIniUser, 471 LOCATION, // "PM_Workplace:Location" (<WP_DESKTOP> etc.) 472 pszName, 473 &cbLocation); 474 if (pvData) 475 { 476 // found there: 477 if (cbLocation >= sizeof(HOBJECT)) 478 hObject = *(PULONG)pvData; 479 free(pvData); 480 // _Pmpf((" object ID found, hObject: %lX", hObject)); 481 } 482 if (hObject) 483 return (hObject); 484 485 // not found there: is pszName an existing pathname? 486 if (access(pszName, 0)) // check existence 487 { 488 // == -1: file does not exist 489 // _Pmpf((" path not found, returning -1")); 490 return (-1); 491 } 492 493 // else: make full path for pszName 494 _fullpath(szFullPath, pszName, sizeof(szFullPath)); 495 496 // check if the HandlesBlock is valid 497 wphQueryActiveHandles(hIniSystem, szActiveHandles, sizeof(szActiveHandles)); 498 // _Pmpf((" szActiveHandles: %s", szActiveHandles)); 499 500 // now load all the BLOCKs into a common buffer 501 if (!wphReadAllBlocks(hIniSystem, 502 szActiveHandles, 503 &pHandlesBuffer, &cbHandlesBuffer)) 504 // error: 505 return (-2); 506 507 // and search that buffer 508 usObjID = wphSearchBufferForHandle(pHandlesBuffer, 509 cbHandlesBuffer, 510 0, // usParent 511 szFullPath); 512 513 if (usObjID) 514 // found: OR 0x30000 515 hObject = MakeDiskHandle(usObjID); 516 517 free(pHandlesBuffer); 518 519 return (hObject); 692 693 TRY_LOUD(excpt1) 694 { 695 // not found there: check the handles then 696 PSZ pszActiveHandles; 697 if (arc = wphQueryActiveHandles(hiniSystem, &pszActiveHandles)) 698 _Pmpf((__FUNCTION__ ": wphQueryActiveHandles returned %d", arc)); 699 else 700 { 701 PHANDLESBUF pHandlesBuf; 702 if (arc = wphLoadHandles(hiniUser, 703 hiniSystem, 704 pszActiveHandles, 705 &pHandlesBuf)) 706 _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc)); 707 else 708 { 709 USHORT usObjID; 710 CHAR szFullPath[2*CCHMAXPATH]; 711 _fullpath(szFullPath, (PSZ)pcszName, sizeof(szFullPath)); 712 713 // search that buffer 714 if (usObjID = wphSearchBufferForHandle(pHandlesBuf->pbData, 715 pHandlesBuf->cbData, 716 0, // usParent 717 szFullPath)) 718 // found: OR 0x30000 719 *phobj = usObjID | (pHandlesBuf->usHiwordFileSystem << 16); 720 else 721 arc = ERROR_FILE_NOT_FOUND; 722 723 wphFreeHandles(&pHandlesBuf); 724 } 725 726 free(pszActiveHandles); 727 } 728 } 729 CATCH(excpt1) 730 { 731 arc = ERROR_WPH_CRASHED; 732 } END_CATCH(); 733 734 return (arc); 520 735 } 521 736 … … 527 742 528 743 /* 529 *@@ wphFindPartName: 530 * this searches pHandlesBuffer for usHandle and, if found, 531 * appends the object partname to pszFname. 532 * This function recurses, if neccessary. 533 * 534 * This gets called by the one-shot function 535 * wphQueryPathFromHandle. 536 */ 537 538 PNODE wphFindPartName(PBYTE pHandlesBuffer, // in: handles buffer 539 ULONG ulBufSize, // in: buffer size 540 USHORT usHandle, // in: handle to search for 541 PSZ pszFname, // out: object partname 542 USHORT usMax) // in: sizeof(pszFname) 543 { 544 PDRIV pDriv; 744 *@@ ComposeThis: 745 * helper for wphComposePath recursion. 746 * 747 *@@added V0.9.16 (2001-10-02) [umoeller] 748 */ 749 750 APIRET ComposeThis(PHANDLESBUF pHandlesBuf, 751 USHORT usHandle, // in: handle to search for 752 PXSTRING pstrFilename, // in/out: filename 753 PNODE *ppNode) // out: node found (ptr can be NULL) 754 { 755 APIRET arc = NO_ERROR; 545 756 PNODE pNode; 546 PBYTE p, pEnd; 547 USHORT usSize; 548 549 pEnd = pHandlesBuffer + ulBufSize; 550 p = pHandlesBuffer + 4; 551 while (p < pEnd) 552 { 553 if (!memicmp(p, "DRIV", 4)) 554 { 555 pDriv = (PDRIV)p; 556 p += sizeof(DRIV) + strlen(pDriv->szName); 557 } 558 else if (!memicmp(p, "NODE", 4)) 559 { 560 pNode = (PNODE)p; 561 p += sizeof (NODE) + pNode->usNameSize; 562 if (pNode->usHandle == usHandle) 563 { 564 usSize = usMax - strlen(pszFname); 565 if (usSize > pNode->usNameSize) 566 usSize = pNode->usNameSize; 567 if (pNode->usParentHandle) 568 { 569 if (!wphFindPartName(pHandlesBuffer, ulBufSize, 570 pNode->usParentHandle, 571 pszFname, 572 usMax)) 573 return (NULL); 574 strcat(pszFname, "\\"); 575 strncat(pszFname, pNode->szName, usSize); 576 return pNode; 577 } 757 if (pNode = pHandlesBuf->NodeHashTable[usHandle]) 758 { 759 // handle exists: 760 if (pNode->usParentHandle) 761 { 762 // node has parent: 763 // recurse first 764 if (arc = ComposeThis(pHandlesBuf, 765 pNode->usParentHandle, 766 pstrFilename, 767 ppNode)) 768 { 769 if (arc == ERROR_INVALID_HANDLE) 770 // parent handle not found: 771 arc = ERROR_WPH_INVALID_PARENT_HANDLE; 772 // else leave the APIRET, this might be dangerous 773 } 774 else 775 { 776 // no error: 777 xstrcatc(pstrFilename, '\\'); 778 xstrcat(pstrFilename, pNode->szName, pNode->usNameSize); 779 } 780 } 781 else 782 // no parent: 783 xstrcpy(pstrFilename, pNode->szName, pNode->usNameSize); 784 } 785 else 786 arc = ERROR_INVALID_HANDLE; 787 788 if (!arc) 789 if (ppNode) 790 *ppNode = pNode; 791 792 return (arc); 793 } 794 795 /* 796 *@@ wphComposePath: 797 * returns the fully qualified path name for the specified 798 * file-system handle. This function is very fast because 799 * it uses a hash table for all the handles internally. 800 * 801 * Warning: This calls a helper, which recurses. 802 * 803 * This returns: 804 * 805 * -- NO_ERROR 806 * 807 * -- ERROR_WPH_CORRUPT_HANDLES_DATA: buffer data cannot be parsed. 808 * 809 * -- ERROR_WPH_INVALID_HANDLE: usHandle cannot be found. 810 * 811 * -- ERROR_WPH_INVALID_PARENT_HANDLE: a handle was found 812 * that has a broken parent handle. 813 * 814 * -- ERROR_BUFFER_OVERFLOW: cbFilename is too small to 815 * hold the full path that was composed. 816 * 817 *@@added V0.9.16 (2001-10-02) [umoeller] 818 */ 819 820 APIRET wphComposePath(PHANDLESBUF pHandlesBuf, 821 USHORT usHandle, // in: loword of handle to search for 822 PSZ pszFilename, 823 ULONG cbFilename, 824 PNODE *ppNode) // out: node found (ptr can be NULL) 825 { 826 APIRET arc = NO_ERROR; 827 828 TRY_LOUD(excpt1) 829 { 830 if (!pHandlesBuf->fNodeHashTableValid) 831 arc = wphRebuildNodeHashTable(pHandlesBuf); 832 833 if (!arc) 834 { 835 XSTRING str; 836 xstrInit(&str, CCHMAXPATH); 837 if (!(arc = ComposeThis(pHandlesBuf, 838 usHandle, 839 &str, 840 ppNode))) 841 if (str.ulLength > cbFilename - 1) 842 arc = ERROR_BUFFER_OVERFLOW; 578 843 else 579 { 580 strncpy(pszFname, pNode->szName, usSize); 581 return pNode; 582 } 583 } 584 } 585 else 586 return (NULL); 587 } 588 return (NULL); 844 memcpy(pszFilename, 845 str.psz, 846 str.ulLength + 1); 847 } 848 } 849 CATCH(excpt1) 850 { 851 arc = ERROR_WPH_CRASHED; 852 } END_CATCH(); 853 854 return (arc); 589 855 } 590 856 … … 596 862 * wphReadAllBlocks, and wphFindPartName. 597 863 * 598 *@@changed V0.9.4 (2000-08-03) [umoeller]: now returning BOOL 599 */ 600 601 BOOL wphQueryPathFromHandle(HINI hIniSystem, // in: HINI_SYSTEM or other INI handle 602 HOBJECT hObject, // in: five-digit object handle 603 PSZ pszFname, // out: filename, if found 604 USHORT usMax) // in: sizeof(*pszFname) 605 { 606 BOOL brc = FALSE; 607 608 if (IsObjectDisk(hObject)) 609 { 610 // use lower byte only 611 USHORT usObjID = LOUSHORT(hObject); 612 613 PBYTE pHandlesBuffer = NULL; 614 ULONG cbHandlesBuffer = 0; 615 616 CHAR szActiveHandles[100]; 617 // PNODE pReturnNode = 0; 618 619 wphQueryActiveHandles(hIniSystem, szActiveHandles, sizeof(szActiveHandles)); 620 621 if (wphReadAllBlocks(hIniSystem, 622 szActiveHandles, 623 &pHandlesBuffer, 624 &cbHandlesBuffer)) 625 { 626 memset(pszFname, 0, usMax); 627 if (wphFindPartName(pHandlesBuffer, 628 cbHandlesBuffer, 629 usObjID, 630 pszFname, 631 usMax)) 632 brc = TRUE; 633 634 free(pHandlesBuffer); 635 } 636 } 637 638 return (brc); 864 * Returns: 865 * 866 * -- NO_ERROR 867 * 868 * -- ERROR_INVALID_HANDLE: hObject is invalid. 869 * 870 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten 871 */ 872 873 APIRET wphQueryPathFromHandle(HINI hiniUser, // in: HINI_USER or other INI handle 874 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle 875 HOBJECT hObject, // in: 32-bit object handle 876 PSZ pszFilename, // out: filename, if found 877 ULONG cbFilename) // in: sizeof(*pszFilename) 878 { 879 APIRET arc = NO_ERROR; 880 881 TRY_LOUD(excpt1) 882 { 883 PSZ pszActiveHandles; 884 if (arc = wphQueryActiveHandles(hiniSystem, &pszActiveHandles)) 885 _Pmpf((__FUNCTION__ ": wphQueryActiveHandles returned %d", arc)); 886 else 887 { 888 PHANDLESBUF pHandlesBuf; 889 if (arc = wphLoadHandles(hiniUser, 890 hiniSystem, 891 pszActiveHandles, 892 &pHandlesBuf)) 893 _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc)); 894 else 895 { 896 // is this really a file-system object? 897 if (HIUSHORT(hObject) == pHandlesBuf->usHiwordFileSystem) 898 { 899 // use loword only 900 USHORT usObjID = LOUSHORT(hObject); 901 902 memset(pszFilename, 0, cbFilename); 903 arc = wphComposePath(pHandlesBuf, 904 usObjID, 905 pszFilename, 906 cbFilename, 907 NULL); 908 909 _Pmpf((__FUNCTION__ ": wphFindPartName returned %d", arc)); 910 } 911 912 wphFreeHandles(&pHandlesBuf); 913 } 914 915 free(pszActiveHandles); 916 } 917 } 918 CATCH(excpt1) 919 { 920 arc = ERROR_WPH_CRASHED; 921 } END_CATCH(); 922 923 return (arc); 639 924 } 640 925 641 /* ****************************************************************** 642 * 643 * Manipulation functions 644 * 645 ********************************************************************/ 646 647 /* 648 *@@ WriteAllBlocks: 649 * writes all blocks back to OS2SYS.INI. 650 * 651 *@@added V0.9.5 (2000-08-20) [umoeller] 652 */ 653 654 BOOL WriteAllBlocks(HINI hini, PSZ pszHandles, PBYTE pBuffer, ULONG ulSize) 655 { 656 PSZ p, 657 pEnd; 658 BYTE szBlockName[10]; 659 INT iCurBlock; 660 ULONG ulCurSize; 661 PBYTE pStart; 662 PDRIV pDriv; 663 PNODE pNode; 664 665 pStart = pBuffer; 666 ulCurSize = 4; 667 p = pBuffer + 4; 668 pEnd = pBuffer + ulSize; 669 iCurBlock = 1; 670 while (p < pEnd) 671 { 672 // ULONG cbWrite = 0; 673 while (p < pEnd) 674 { 675 ULONG ulPartSize = 0; 676 if (!memicmp(p, "DRIV", 4)) 677 { 678 pDriv = (PDRIV)p; 679 ulPartSize = sizeof(DRIV) + strlen(pDriv->szName); 680 } 681 else if (!memicmp(p, "NODE", 4)) 682 { 683 pNode = (PNODE)p; 684 ulPartSize = sizeof (NODE) + pNode->usNameSize; 685 } 686 687 if (ulCurSize + ulPartSize > 0x0000FFFF) 688 break; 689 690 ulCurSize += ulPartSize; 691 p += ulPartSize; 692 } 693 sprintf(szBlockName, "BLOCK%d", iCurBlock++); 694 695 PrfWriteProfileData(hini, 696 pszHandles, // app 697 szBlockName, // key 698 pStart, 699 ulCurSize); 700 pStart = p; 701 ulCurSize = 0; 702 } 703 704 while (iCurBlock < 20) 705 { 706 ULONG ulBlockSize; 707 708 sprintf(szBlockName, "BLOCK%d", iCurBlock++); 709 710 if (PrfQueryProfileSize(hini, 711 pszHandles, 712 szBlockName, 713 &ulBlockSize) 714 && ulBlockSize > 0) 715 // delete block: 716 PrfWriteProfileData(hini, 717 pszHandles, 718 szBlockName, 719 NULL, 0); // delete 720 // WriteProfileData(pszHandles, szBlockName, hini, NULL, 0); 721 } 722 723 return TRUE; 724 } 725 726 /* 727 *@@ DeleteNode: 728 * deletes a NODE in the specified buffer. 729 * 730 *@@added V0.9.5 (2000-08-20) [umoeller] 731 */ 732 733 ULONG DeleteNode(PBYTE pBuffer, PNODE pNode, ULONG ulSize) 734 { 735 ULONG ulDelSize = sizeof (NODE) + pNode->usNameSize; 736 USHORT usID = pNode->usHandle; // pNode->usID; 737 ULONG ulMoveSize; 738 739 if (memcmp(pNode->chName, "NODE", 4)) 740 return ulSize; 741 742 ulMoveSize = (pBuffer + ulSize) - ((PBYTE)pNode + ulDelSize); 743 ulSize -= ulDelSize; 744 745 memmove(pNode, (PBYTE)pNode + ulDelSize, ulMoveSize); 746 747 while ( (PBYTE)pNode < pBuffer + ulSize 748 && !memcmp(pNode->chName, "NODE", 4) 749 && pNode->usParentHandle == usID) 750 ulSize = DeleteNode(pBuffer, pNode, ulSize); 751 752 return ulSize; 753 } 754 755 /* 756 *@@ DeleteDrive: 757 * delete all information about a drive. 758 * in the specified buffer. 759 * 760 *@@added V0.9.5 (2000-08-20) [umoeller] 761 */ 762 763 ULONG DeleteDrive(PBYTE pBuffer, PDRIV pDriv, ULONG ulSize) 764 { 765 ULONG ulDelSize; 766 ULONG ulMoveSize; 767 768 if (memcmp(pDriv->chName, "DRIV", 4)) 769 return ulSize; 770 771 ulDelSize = sizeof (DRIV) + strlen(pDriv->szName); 772 ulMoveSize = (pBuffer + ulSize) - ((PBYTE)pDriv + ulDelSize); 773 ulSize -= ulDelSize; 774 775 memmove(pDriv, (PBYTE)pDriv + ulDelSize, ulMoveSize); 776 return ulSize; 777 } 778 779 780 926 927
Note:
See TracChangeset
for help on using the changeset viewer.