Changeset 113 for trunk/src/helpers/wphandle.c
- Timestamp:
- Oct 23, 2001, 11:25:46 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/wphandle.c
r110 r113 46 46 47 47 #define INCL_WINSHELLDATA 48 #define INCL_WINNLS 48 49 #include <os2.h> 49 50 … … 57 58 58 59 #include "helpers\except.h" 60 #include "helpers\linklist.h" 59 61 #include "helpers\prfh.h" 60 62 #include "helpers\standards.h" 61 63 #include "helpers\stringh.h" 64 #include "helpers\tree.h" 65 #include "helpers\xstring.h" 66 67 #define INCLUDE_WPHANDLE_PRIVATE 62 68 #include "helpers\wphandle.h" 63 #include "helpers\xstring.h"64 69 65 70 /* … … 185 190 186 191 /* 192 *@@ FreeChildrenTree: 193 * called from NukeNameTrees for recursion. 194 * 195 *@@added V0.9.16 (2001-10-19) [umoeller] 196 */ 197 198 VOID FreeChildrenTree(TREE **ppChildrenTree, 199 PLONG plCount) 200 { 201 LONG cItems = *plCount; 202 TREE** papNodes = treeBuildArray(*ppChildrenTree, 203 &cItems); 204 if (papNodes) 205 { 206 ULONG ul; 207 for (ul = 0; ul < cItems; ul++) 208 { 209 PNODETREENODE pNodeThis = (PNODETREENODE)papNodes[ul]; 210 211 FreeChildrenTree(&pNodeThis->ChildrenTree, 212 &pNodeThis->cChildren); 213 214 free(pNodeThis); 215 } 216 217 free(papNodes); 218 *plCount = 0; 219 220 treeInit(ppChildrenTree, plCount); 221 } 222 } 223 224 /* 225 *@@ NukeNameTrees: 226 * frees all cache trees. 227 * 228 *@@added V0.9.16 (2001-10-19) [umoeller] 229 */ 230 231 APIRET NukeNameTrees(PHANDLESBUF pHandlesBuf) 232 { 233 APIRET arc = NO_ERROR; 234 235 LONG cItems = pHandlesBuf->cDrives; 236 TREE** papNodes = treeBuildArray(pHandlesBuf->DrivesTree, 237 &cItems); 238 if (papNodes) 239 { 240 ULONG ul; 241 for (ul = 0; ul < cItems; ul++) 242 { 243 PDRIVETREENODE pNodeThis = (PDRIVETREENODE)papNodes[ul]; 244 245 FreeChildrenTree(&pNodeThis->ChildrenTree, 246 &pNodeThis->cChildren); 247 248 free(pNodeThis); 249 } 250 251 free(papNodes); 252 253 treeInit(&pHandlesBuf->DrivesTree, 254 &pHandlesBuf->cDrives); 255 } 256 257 return (arc); 258 } 259 260 /* 187 261 *@@ wphRebuildNodeHashTable: 188 262 * … … 198 272 */ 199 273 200 APIRET wphRebuildNodeHashTable( PHANDLESBUF pHandlesBuf)274 APIRET wphRebuildNodeHashTable(HHANDLES hHandles) 201 275 { 202 276 APIRET arc = NO_ERROR; 203 277 204 if ( (!pHandlesBuf) 278 PHANDLESBUF pHandlesBuf; 279 280 if ( (!(pHandlesBuf = (PHANDLESBUF)hHandles)) 205 281 || (!pHandlesBuf->pbData) 206 282 || (!pHandlesBuf->cbData) … … 213 289 PBYTE pEnd = pHandlesBuf->pbData + pHandlesBuf->cbData; 214 290 291 PDRIVETREENODE pLastDriveTreeNode = NULL; 292 215 293 memset(pHandlesBuf->NodeHashTable, 0, sizeof(pHandlesBuf->NodeHashTable)); 294 NukeNameTrees(pHandlesBuf); 216 295 217 296 // now set up hash table 218 while (pCur < pEnd) 297 while ( (pCur < pEnd) 298 && (!arc) 299 ) 219 300 { 220 301 if (!memicmp(pCur, "DRIV", 4)) … … 222 303 // pCur points to a DRIVE node: 223 304 // these never have handles, so skip this 224 PDRIV pDriv = (PDRIV)pCur; 225 pCur += sizeof(DRIV) + strlen(pDriv->szName); 305 PDRIVE pDriv = (PDRIVE)pCur; 306 307 // upper the node name for string comparisons 308 strupr(pDriv->szName); 309 310 // create a drive tree node 311 // (stored so we can append to this) 312 if (!(pLastDriveTreeNode = NEW(DRIVETREENODE))) 313 arc = ERROR_NOT_ENOUGH_MEMORY; 314 else 315 { 316 pLastDriveTreeNode->Tree.ulKey = (ULONG)pDriv->szName; 317 pLastDriveTreeNode->pDriv = pDriv; 318 treeInit(&pLastDriveTreeNode->ChildrenTree, 319 &pLastDriveTreeNode->cChildren); 320 if (treeInsert(&pHandlesBuf->DrivesTree, 321 &pHandlesBuf->cDrives, 322 (TREE*)pLastDriveTreeNode, 323 treeCompareStrings)) 324 arc = ERROR_WPH_DRIV_TREEINSERT_FAILED; 325 } 326 327 // next item 328 pCur += sizeof(DRIVE) + strlen(pDriv->szName); 226 329 } 227 330 else if (!memicmp(pCur, "NODE", 4)) … … 229 332 // pCur points to a regular NODE: offset pointer first 230 333 PNODE pNode = (PNODE)pCur; 231 // store PNODE in hash table 232 pHandlesBuf->NodeHashTable[pNode->usHandle] = pNode; 334 PNODETREENODE pNew; 335 336 // upper the node name for string comparisons 337 strupr(pNode->szName); 338 339 // create a node tree node 340 if (!(pNew = NEW(NODETREENODE))) 341 arc = ERROR_NOT_ENOUGH_MEMORY; 342 else 343 { 344 TREE **ppTree = NULL; 345 PLONG pcChildren = NULL; 346 347 pNew->Tree.ulKey = (ULONG)pNode->szName; 348 pNew->pNode = pNode; 349 treeInit(&pNew->ChildrenTree, 350 &pNew->cChildren); 351 // now check where to insert this... 352 // does it have a parent? 353 if (pNode->usParentHandle) 354 { 355 PNODETREENODE pParent; 356 if (!(pParent = pHandlesBuf->NodeHashTable[pNode->usParentHandle])) 357 // this parent handle is invalid: 358 arc = ERROR_WPH_INVALID_PARENT_HANDLE; 359 else 360 { 361 ppTree = &pParent->ChildrenTree; 362 pcChildren = &pParent->cChildren; 363 } 364 } 365 else 366 // null parent handle: then the parent 367 // must be a DRIVE node 368 if (pLastDriveTreeNode) 369 { 370 ppTree = &pLastDriveTreeNode->ChildrenTree; 371 pcChildren = &pLastDriveTreeNode->cChildren; 372 } 373 else 374 arc = ERROR_WPH_NODE_BEFORE_DRIV; 375 376 if (!arc) 377 if (treeInsert(ppTree, 378 pcChildren, 379 (TREE*)pNew, 380 treeCompareStrings)) 381 ; // @@todo if this fails, there are 382 // several handles for short name!!! 383 // arc = ERROR_WPH_NODE_TREEINSERT_FAILED; 384 385 // store PNODE in hash table 386 pHandlesBuf->NodeHashTable[pNode->usHandle] = pNew; 387 } 388 233 389 pCur += sizeof(NODE) + pNode->usNameSize; 234 390 } … … 242 398 243 399 if (!arc) 244 pHandlesBuf->f NodeHashTableValid = TRUE;400 pHandlesBuf->fCacheValid = TRUE; 245 401 246 402 return (arc); … … 279 435 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle 280 436 const char *pcszActiveHandles, 281 PHANDLESBUF *ppHandlesBuf)437 HHANDLES *phHandles) 282 438 { 283 439 APIRET arc = NO_ERROR; 284 440 285 if (!p pHandlesBuf)441 if (!phHandles) 286 442 arc = ERROR_INVALID_PARAMETER; 287 443 else … … 369 525 ZERO(pReturn); 370 526 527 treeInit(&pReturn->DrivesTree, 528 &pReturn->cDrives); 529 371 530 pReturn->pbData = pbData; 372 531 pReturn->cbData = cbTotal; … … 376 535 &pReturn->usHiwordAbstract, 377 536 &pReturn->usHiwordFileSystem))) 378 *p pHandlesBuf =pReturn;537 *phHandles = (HHANDLES)pReturn; 379 538 } 380 539 else … … 384 543 if (arc) 385 544 // error: 386 wphFreeHandles( &pReturn);545 wphFreeHandles((HHANDLES*)&pReturn); 387 546 } 388 547 } … … 399 558 */ 400 559 401 APIRET wphFreeHandles( PHANDLESBUF *ppHandlesBuf)560 APIRET wphFreeHandles(HHANDLES *phHandles) 402 561 { 403 562 APIRET arc = NO_ERROR; 404 563 405 if (ppHandlesBuf && *ppHandlesBuf) 564 PHANDLESBUF pHandlesBuf; 565 if ( (phHandles) 566 && (pHandlesBuf = (PHANDLESBUF)*phHandles) 567 ) 406 568 { 407 569 PBYTE pbData; 408 if (pbData = (*ppHandlesBuf)->pbData) 570 571 NukeNameTrees(pHandlesBuf); 572 573 if (pbData = pHandlesBuf->pbData) 409 574 free(pbData); 410 575 411 free( *ppHandlesBuf);412 *p pHandlesBuf = NULL;576 free(pHandlesBuf); 577 *phHandles = NULLHANDLE; 413 578 } 414 579 else … … 426 591 /* 427 592 *@@ wphSearchBufferForHandle: 428 * returns the four-digit objecthandle which corresponds593 * returns the 16-bit file-system handle which corresponds 429 594 * to pszFilename, searching pHandlesBuffer. Note that you 430 * must OR the return value with 0x30000 to make this431 * a valid WPS file-system handle.595 * must OR the return value with the proper hiword to make 596 * this a valid WPS file-system handle. 432 597 * 433 598 * You must pass a handles buffer to this function which … … 436 601 * This gets called by the one-shot function 437 602 * wphQueryHandleFromPath. 438 */ 439 440 USHORT wphSearchBufferForHandle(PBYTE pHandlesBuffer, // in: handles buffer (all BLOCK's) 441 ULONG ulBufSize, // in: sizeof(pHandlesBuffer) 442 USHORT usParent, // in: parent NODE ID; 443 // must be 0 initially 444 PSZ pszFilename) // in: fully qlf'd filename to search for 445 { 446 PDRIV pDriv; 447 PNODE pNode; 448 PBYTE pCur; // current 449 PBYTE p, 450 pEnd; // *end of buffer 451 USHORT usPartSize; 452 453 // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszFilename)); 454 455 // The composed BLOCKs in the handles buffer make up a tree of 456 // DRIVE and NODE structures (see wphandle.h). Each NODE stands 457 // for either a directory or a file. (We don't care about the 458 // DRIVE structures because the root directory gets a NODE also.) 459 // Each NODE contains the non-qualified file name, an object ID, 460 // and the object ID of its parent NODE. 461 // We can thus work our way through the buffer by splitting the 462 // fully qualified filename that we're searching for into the 463 // different directory names and, each time, searching for the 464 // corresponding NODE. If we have found that, we go for the next. 465 // Example for C:\OS2\E.EXE: 466 // 1) first search for the "C:" NODE 467 // 2) then find the "OS2" node which has "C" as its parent NODE 468 // (we do this by comparing the parent object handles) 469 // 3) then find the "E.EXE" NODE the same way 470 // The "E.EXE" NODE then has the object handle we're looking for. 471 472 // So first find the length of the first filename part (which 473 // should be 2 for the drive letter, "C:") 474 p = strchr(pszFilename, '\\'); 475 if (p) 476 // backslash found: 477 usPartSize = p - pszFilename; // extract first part 603 * 604 * Returns: 605 * 606 * -- NO_ERROR 607 * 608 * -- ERROR_INVALID_PARAMETER 609 * 610 * -- ERROR_FILE_NOT_FOUND 611 * 612 * -- ERROR_INVALID_NAME 613 * 614 * -- ERROR_WPH_CORRUPT_HANDLES_DATA 615 * 616 * -- ERROR_WPH_CANNOT_FIND_HANDLE: no handle exists for the 617 * given filename. 618 * 619 *@@changed V0.9.16 (2001-10-19) [umoeller]: rewritten 620 */ 621 622 APIRET wphSearchBufferForHandle(HHANDLES hHandles, 623 PCSZ pcszFile, // in: fully qlf'd filename to search for 624 PUSHORT pusHandle) // out: 16-bit handle 625 { 626 APIRET arc = NO_ERROR; 627 628 PHANDLESBUF pHandlesBuf; 629 630 _Pmpf((__FUNCTION__ ": entering")); 631 632 if ( (hHandles) 633 && (pHandlesBuf = (PHANDLESBUF)hHandles) 634 ) 635 { 636 // rebuild cache 637 if (!pHandlesBuf->fCacheValid) 638 arc = wphRebuildNodeHashTable(hHandles); 639 640 if (!arc) 641 { 642 // We can thus work our way through the buffer by splitting the 643 // fully qualified filename that we're searching for into the 644 // different directory names and, each time, searching for the 645 // corresponding NODE. If we have found that, we go for the next. 646 // Example for C:\OS2\E.EXE: 647 // 1) first search for the "C:" NODE 648 // 2) then find the "OS2" node which has "C" as its parent NODE 649 // (we do this by comparing the parent object handles) 650 // 3) then find the "E.EXE" NODE the same way 651 // The "E.EXE" NODE then has the object handle we're looking for. 652 653 // make a copy of the filename so we can play 654 PSZ pszFilename = strdup(pcszFile), 655 pEnd = NULL; 656 657 strupr(pszFilename); 658 659 // 1) OK, find the drive. 660 661 // If this is an UNC name, the DRIVE node has the form 662 // \\SERVER\RESOURCE. 663 if ( (*pszFilename == '\\') 664 && (*(pszFilename + 1) == '\\') 665 ) 666 { 667 // UNC: 668 // @@todo 669 } 670 else if (*(pszFilename + 1) == ':') 671 // extract the drive then (without \) 672 pEnd = pszFilename + 2; 673 674 if (!pEnd) 675 arc = ERROR_INVALID_NAME; 676 else 677 { 678 PDRIVETREENODE pDrive = NULL; 679 PNODETREENODE pNode; 680 681 // find the DRIVE node 682 CHAR cOld = *pEnd; 683 *pEnd = 0; 684 685 _Pmpf((" searching for drive \"%s\"", pszFilename)); 686 687 if (!(pDrive = (PDRIVETREENODE)treeFind(pHandlesBuf->DrivesTree, 688 (ULONG)pszFilename, // drive name 689 treeCompareStrings))) 690 arc = ERROR_WPH_NO_MATCHING_DRIVE_BLOCK; 691 // find the root dir, which has the same name 692 else if (!(pNode = (PNODETREENODE)treeFind(pDrive->ChildrenTree, 693 (ULONG)pszFilename, 694 treeCompareStrings))) 695 arc = ERROR_WPH_NO_MATCHING_ROOT_DIR; 696 else 697 { 698 // now we got the root dir... go for next path component 699 while ( (pEnd) 700 && (*pEnd = cOld) // not null char 701 && (!arc) 702 ) 703 { 704 // got another path component to search: 705 PSZ pCurrent = pEnd + 1, 706 pNext; 707 708 if (pNext = strchr(pCurrent, '\\')) 709 { 710 cOld = *pNext; 711 *pNext = 0; 712 } 713 else 714 // done: 715 cOld = 0; 716 717 _Pmpf((" searching for node \"%s\"", pCurrent)); 718 719 // find the next node 720 if (!(pNode = (PNODETREENODE)treeFind(pNode->ChildrenTree, 721 (ULONG)pCurrent, 722 treeCompareStrings))) 723 arc = ERROR_WPH_CANNOT_FIND_HANDLE; 724 725 pEnd = pNext; 726 } 727 728 if (!arc && pNode) 729 // found everything: 730 *pusHandle = pNode->pNode->usHandle; 731 } 732 } // end while 733 734 free(pszFilename); 735 } 736 } 478 737 else 479 usPartSize = strlen(pszFilename); 480 481 // now set the pointer for the end of the BLOCKs buffer 482 pEnd = pHandlesBuffer + ulBufSize; 483 484 // pCur is our variable pointer where we're at now; there 485 // is some offset of 4 bytes at the beginning (duh) 486 pCur = pHandlesBuffer + 4; 487 488 // _Pmpf((" Searching for: %s, usPartSize: %d", pszFilename, usPartSize)); 489 490 // go! 491 while (pCur < pEnd) 492 { 493 // the first four chars tell us whether it's 494 // a DRIVE or a NODE structure 495 if (!memicmp(pCur, "DRIV", 4)) 496 { 497 // pCur points to a DRIVE node: 498 // we don't care about these, because the root 499 // directory has a real NODE too, so we just 500 // skip this 501 pDriv = (PDRIV)pCur; 502 pCur += sizeof(DRIV) + strlen(pDriv->szName); 503 } 504 else if (!memicmp(pCur, "NODE", 4)) 505 { 506 // pCur points to a regular NODE: offset pointer first 507 pNode = (PNODE)pCur; 508 pCur += sizeof (NODE) + pNode->usNameSize; 509 510 // does the NODE have the same parent that we 511 // are currently searching for? This is "0" 512 // for root directories (and initially for us 513 // too) 514 if (usParent == pNode->usParentHandle) 515 { 516 // yes: 517 // _Pmpf((" found matching parents (%lX): %s", usParent, pNode->szName)); 518 519 // does the NODE have the same partname length? 520 if (pNode->usNameSize == usPartSize) 521 { 522 // yes: 523 // _Pmpf((" found matching partnames sizes: %d", pNode->usNameSize)); 524 525 // do the partnames match too? 526 if (memicmp(pszFilename, pNode->szName, usPartSize) == 0) 527 { 528 // OK!! proper NODE found! 529 // _Pmpf((" FOUND %s!!", pNode->szName)); 530 531 // now check if this was the last NODE 532 // we were looking for 533 if (strlen(pszFilename) == usPartSize) 534 // yes: return ID 535 return (pNode->usHandle); 536 537 // else: update our status; 538 // get next partname 539 pszFilename += usPartSize + 1; 540 // calc next partname length 541 p = strchr(pszFilename, '\\'); 542 if (p) 543 usPartSize = p - pszFilename; 544 else 545 usPartSize = strlen(pszFilename); 546 547 // get next parent to search for 548 // (which is the current handle) 549 usParent = pNode->usHandle; 550 } 551 } 552 } 553 } 554 else 555 // neither DRIVE nor NODE: error 556 return (0); 557 558 } // end while 738 arc = ERROR_INVALID_PARAMETER; 739 740 _Pmpf((__FUNCTION__ ": returning %d", arc)); 559 741 560 742 // not found: end of buffer reached 561 return ( 0);743 return (arc); 562 744 } 563 745 … … 588 770 589 771 PSZ pszActiveHandles = NULL; 590 PHANDLESBUF pHandlesBuf = NULL;772 HHANDLES hHandles = NULLHANDLE; 591 773 592 774 TRY_LOUD(excpt1) … … 601 783 hiniSystem, 602 784 pszActiveHandles, 603 & pHandlesBuf))785 &hHandles)) 604 786 _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc)); 605 787 else … … 610 792 611 793 // search that buffer 612 if (usObjID = wphSearchBufferForHandle(pHandlesBuf->pbData, 613 pHandlesBuf->cbData, 614 0, // usParent 615 szFullPath)) 794 if (!(arc = wphSearchBufferForHandle(hHandles, 795 szFullPath, 796 &usObjID))) 616 797 // found: OR 0x30000 617 *phobj = usObjID | ( pHandlesBuf->usHiwordFileSystem << 16);798 *phobj = usObjID | (((PHANDLESBUF)hHandles)->usHiwordFileSystem << 16); 618 799 else 619 800 arc = ERROR_FILE_NOT_FOUND; … … 628 809 if (pszActiveHandles) 629 810 free(pszActiveHandles); 630 if ( pHandlesBuf)631 wphFreeHandles(& pHandlesBuf);811 if (hHandles) 812 wphFreeHandles(&hHandles); 632 813 633 814 return (arc); … … 652 833 PNODE *ppNode) // out: node found (ptr can be NULL) 653 834 { 654 APIRET arc = NO_ERROR; 655 PNODE pNode; 656 if (pNode = pHandlesBuf->NodeHashTable[usHandle]) 835 APIRET arc = NO_ERROR; 836 PNODETREENODE pTreeNode; 837 PNODE pNode; 838 if ( (pTreeNode = pHandlesBuf->NodeHashTable[usHandle]) 839 && (pNode = pTreeNode->pNode) 840 ) 657 841 { 658 842 // handle exists: … … 717 901 */ 718 902 719 APIRET wphComposePath( PHANDLESBUF pHandlesBuf,903 APIRET wphComposePath(HHANDLES hHandles, 720 904 USHORT usHandle, // in: loword of handle to search for 721 905 PSZ pszFilename, … … 725 909 APIRET arc = NO_ERROR; 726 910 727 TRY_LOUD(excpt1)728 {729 if (!pHandlesBuf->fNodeHashTableValid)730 arc = wphRebuildNodeHashTable(pHandlesBuf);731 732 if (!arc)911 PHANDLESBUF pHandlesBuf; 912 if ( (hHandles) 913 && (pHandlesBuf = (PHANDLESBUF)hHandles) 914 ) 915 { 916 TRY_LOUD(excpt1) 733 917 { 734 XSTRING str; 735 xstrInit(&str, CCHMAXPATH); 736 if (!(arc = ComposeThis(pHandlesBuf, 737 usHandle, 738 &str, 739 ppNode))) 740 if (str.ulLength > cbFilename - 1) 741 arc = ERROR_BUFFER_OVERFLOW; 742 else 743 memcpy(pszFilename, 744 str.psz, 745 str.ulLength + 1); 918 if (!pHandlesBuf->fCacheValid) 919 arc = wphRebuildNodeHashTable(hHandles); 920 921 if (!arc) 922 { 923 XSTRING str; 924 xstrInit(&str, CCHMAXPATH); 925 if (!(arc = ComposeThis(pHandlesBuf, 926 usHandle, 927 &str, 928 ppNode))) 929 if (str.ulLength > cbFilename - 1) 930 arc = ERROR_BUFFER_OVERFLOW; 931 else 932 memcpy(pszFilename, 933 str.psz, 934 str.ulLength + 1); 935 } 746 936 } 747 }748 CATCH(excpt1)749 {750 arc = ERROR_WPH_CRASHED;751 } END_CATCH();937 CATCH(excpt1) 938 { 939 arc = ERROR_WPH_CRASHED; 940 } END_CATCH(); 941 } 752 942 753 943 return (arc); … … 785 975 else 786 976 { 787 PHANDLESBUF pHandlesBuf;977 HHANDLES hHandles; 788 978 if (arc = wphLoadHandles(hiniUser, 789 979 hiniSystem, 790 980 pszActiveHandles, 791 & pHandlesBuf))981 &hHandles)) 792 982 _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc)); 793 983 else 794 984 { 795 985 // is this really a file-system object? 796 if (HIUSHORT(hObject) == pHandlesBuf->usHiwordFileSystem)986 if (HIUSHORT(hObject) == ((PHANDLESBUF)hHandles)->usHiwordFileSystem) 797 987 { 798 988 // use loword only … … 800 990 801 991 memset(pszFilename, 0, cbFilename); 802 arc = wphComposePath( pHandlesBuf,992 arc = wphComposePath(hHandles, 803 993 usObjID, 804 994 pszFilename, … … 809 999 } 810 1000 811 wphFreeHandles(& pHandlesBuf);1001 wphFreeHandles(&hHandles); 812 1002 } 813 1003
Note:
See TracChangeset
for help on using the changeset viewer.