source: trunk/src/helpers/wphandle.c@ 111

Last change on this file since 111 was 110, checked in by umoeller, 24 years ago

Misc updates.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 26.8 KB
Line 
1
2/*
3 *@@sourcefile wphandle.c:
4 * this file contains the logic for dealing with
5 * those annoying WPS object handles in OS2SYS.INI.
6 * This does not use WPS interfaces, but parses
7 * the profiles directly.
8 *
9 * Usage: All OS/2 programs.
10 *
11 * Function prefixes (new with V0.81):
12 * -- wph* WPS object helper functions
13 *
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.
18 *
19 * Note: Version numbering in this file relates to XWorkplace version
20 * numbering.
21 *
22 *@@header "helpers\wphandle.h"
23 */
24
25/*
26 * This file Copyright (C) 1997-2001 Ulrich M”ller,
27 * This file is part of the "XWorkplace helpers" source package.
28 * This is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published
30 * by the Free Software Foundation, in version 2 as it comes in the
31 * "COPYING" file of the XWorkplace main distribution.
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 */
37
38#define OS2EMX_PLAIN_CHAR
39 // this is needed for "os2emx.h"; if this is defined,
40 // emx will define PSZ as _signed_ char, otherwise
41 // as unsigned char
42
43#define INCL_DOSEXCEPTIONS
44#define INCL_DOSPROCESS
45#define INCL_DOSERRORS
46
47#define INCL_WINSHELLDATA
48#include <os2.h>
49
50#include <stdio.h>
51#include <string.h>
52#include <stdlib.h>
53#include <io.h>
54#include <setjmp.h>
55
56#include "setup.h" // code generation and debugging options
57
58#include "helpers\except.h"
59#include "helpers\prfh.h"
60#include "helpers\standards.h"
61#include "helpers\stringh.h"
62#include "helpers\wphandle.h"
63#include "helpers\xstring.h"
64
65/*
66 *@@category: Helpers\PM helpers\Workplace Shell\Handles (OS2SYS.INI)
67 * See wphandle.c.
68 */
69
70/* ******************************************************************
71 *
72 * Load handles functions
73 *
74 ********************************************************************/
75
76/*
77 *@@ wphQueryActiveHandles:
78 * returns the value of PM_Workplace:ActiveHandles
79 * in OS2SYS.INI as a new buffer.
80 *
81 * There are always two buffers in OS2SYS.INI for object
82 * handles, called "PM_Workplace:HandlesX" with "X" either
83 * being "0" or "1".
84 *
85 * It seems that every time the WPS does something in the
86 * handles section, it writes the data to the inactive
87 * buffer first and then makes it the active buffer by
88 * changing the "active handles" key. You can test this
89 * by creating a shadow on your Desktop.
90 *
91 * This returns a new PSZ which the caller must free()
92 * after use.
93 *
94 * This gets called by the one-shot function
95 * wphQueryHandleFromPath.
96 *
97 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
98 */
99
100APIRET wphQueryActiveHandles(HINI hiniSystem,
101 PSZ *ppszActiveHandles) // out: active handles string (new buffer)
102{
103 PSZ pszActiveHandles;
104 if (pszActiveHandles = prfhQueryProfileData(hiniSystem,
105 WPINIAPP_ACTIVEHANDLES,
106 WPINIAPP_HANDLESAPP,
107 NULL))
108 {
109 *ppszActiveHandles = pszActiveHandles;
110 return (NO_ERROR);
111 }
112
113 return (ERROR_WPH_NO_ACTIVEHANDLES_DATA);
114}
115
116/*
117 *@@ wphQueryBaseClassesHiwords:
118 * returns the hiwords for the WPS base
119 * classes. Unless the user's system is
120 * really badly configured, this should
121 * set
122 *
123 * -- pusHiwordAbstract to 2;
124 * -- pusHiwordFileSystem to 3.
125 *
126 * Returns:
127 *
128 * -- NO_ERROR
129 *
130 * -- ERROR_WPH_NO_BASECLASS_DATA
131 *
132 * -- ERROR_WPH_INCOMPLETE_BASECLASS_DATA
133 *
134 * This gets called automatically from wphLoadHandles.
135 *
136 *@@added V0.9.16 (2001-10-02) [umoeller]
137 */
138
139APIRET wphQueryBaseClassesHiwords(HINI hiniUser,
140 PUSHORT pusHiwordAbstract,
141 PUSHORT pusHiwordFileSystem)
142{
143 APIRET arc = NO_ERROR;
144
145 // get the index of WPFileSystem from the base classes list...
146 // we need this to determine the hiword for file-system handles
147 // properly. Normally, this should be 3.
148 ULONG cbBaseClasses = 0;
149 PSZ pszBaseClasses;
150 if (pszBaseClasses = prfhQueryProfileData(hiniUser,
151 "PM_Workplace:BaseClass",
152 "ClassList",
153 &cbBaseClasses))
154 {
155 // parse that buffer... these has the base class names,
156 // separated by 0. List is terminated by two zeroes.
157 PSZ pszClassThis = pszBaseClasses;
158 ULONG ulHiwordThis = 1;
159 while ( (*pszClassThis)
160 && (pszClassThis - pszBaseClasses < cbBaseClasses)
161 )
162 {
163 if (!strcmp(pszClassThis, "WPFileSystem"))
164 *pusHiwordFileSystem = ulHiwordThis;
165 else if (!strcmp(pszClassThis, "WPAbstract"))
166 *pusHiwordAbstract = ulHiwordThis;
167
168 ulHiwordThis++;
169 pszClassThis += strlen(pszClassThis) + 1;
170 }
171
172 // now check if we found both
173 if ( (!(*pusHiwordFileSystem))
174 || (!(*pusHiwordAbstract))
175 )
176 arc = ERROR_WPH_INCOMPLETE_BASECLASS_DATA;
177
178 free(pszBaseClasses);
179 }
180 else
181 arc = ERROR_WPH_NO_BASECLASS_DATA;
182
183 return (arc);
184}
185
186/*
187 *@@ wphRebuildNodeHashTable:
188 *
189 * Returns:
190 *
191 * -- NO_ERROR
192 *
193 * -- ERROR_INVALID_PARAMETER
194 *
195 * -- ERROR_WPH_CORRUPT_HANDLES_DATA
196 *
197 *@@added V0.9.16 (2001-10-02) [umoeller]
198 */
199
200APIRET wphRebuildNodeHashTable(PHANDLESBUF pHandlesBuf)
201{
202 APIRET arc = NO_ERROR;
203
204 if ( (!pHandlesBuf)
205 || (!pHandlesBuf->pbData)
206 || (!pHandlesBuf->cbData)
207 )
208 arc = ERROR_INVALID_PARAMETER;
209 else
210 {
211 // start at beginning of buffer
212 PBYTE pCur = pHandlesBuf->pbData + 4;
213 PBYTE pEnd = pHandlesBuf->pbData + pHandlesBuf->cbData;
214
215 memset(pHandlesBuf->NodeHashTable, 0, sizeof(pHandlesBuf->NodeHashTable));
216
217 // now set up hash table
218 while (pCur < pEnd)
219 {
220 if (!memicmp(pCur, "DRIV", 4))
221 {
222 // pCur points to a DRIVE node:
223 // these never have handles, so skip this
224 PDRIV pDriv = (PDRIV)pCur;
225 pCur += sizeof(DRIV) + strlen(pDriv->szName);
226 }
227 else if (!memicmp(pCur, "NODE", 4))
228 {
229 // pCur points to a regular NODE: offset pointer first
230 PNODE pNode = (PNODE)pCur;
231 // store PNODE in hash table
232 pHandlesBuf->NodeHashTable[pNode->usHandle] = pNode;
233 pCur += sizeof(NODE) + pNode->usNameSize;
234 }
235 else
236 {
237 arc = ERROR_WPH_CORRUPT_HANDLES_DATA;
238 break;
239 }
240 }
241 }
242
243 if (!arc)
244 pHandlesBuf->fNodeHashTableValid = TRUE;
245
246 return (arc);
247}
248
249/*
250 *@@ wphLoadHandles:
251 * returns a HANDLESBUF structure which will hold
252 * all the handles from OS2SYS.INI. In addition,
253 * this calls wphQueryBaseClassesHiwords and puts
254 * the hiwords for WPAbstract and WPFileSystem into
255 * the HANDLESBUF as well.
256 *
257 * Prerequisite before using any of the other wph*
258 * functions.
259 *
260 * Call wphFreeHandles to free all data allocated
261 * by this function.
262 *
263 * Returns:
264 *
265 * -- NO_ERROR
266 *
267 * -- ERROR_NOT_ENOUGH_MEMORY
268 *
269 * -- ERROR_INVALID_PARAMETER
270 *
271 * -- ERROR_WPH_NO_HANDLES_DATA: cannot read handle blocks.
272 *
273 * -- ERROR_WPH_CORRUPT_HANDLES_DATA: cannot read handle blocks.
274 *
275 *@@added V0.9.16 (2001-10-02) [umoeller]
276 */
277
278APIRET wphLoadHandles(HINI hiniUser, // in: HINI_USER or other INI handle
279 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle
280 const char *pcszActiveHandles,
281 PHANDLESBUF *ppHandlesBuf)
282{
283 APIRET arc = NO_ERROR;
284
285 if (!ppHandlesBuf)
286 arc = ERROR_INVALID_PARAMETER;
287 else
288 {
289 PSZ pszKeysList;
290 if (!(arc = prfhQueryKeysForApp(hiniSystem,
291 pcszActiveHandles,
292 &pszKeysList)))
293 {
294 PHANDLESBUF pReturn = NULL;
295
296 ULONG ulHighestBlock = 0,
297 ul,
298 cbTotal;
299 PBYTE pbData;
300
301 const char *pKey2 = pszKeysList;
302 while (*pKey2)
303 {
304 if (!memicmp((PVOID)pKey2, "BLOCK", 5))
305 {
306 ULONG ulBlockThis = atoi(pKey2 + 5);
307 if (ulBlockThis > ulHighestBlock)
308 ulHighestBlock = ulBlockThis;
309 }
310
311 pKey2 += strlen(pKey2)+1; // next key
312 }
313
314 free(pszKeysList);
315
316 if (!ulHighestBlock)
317 arc = ERROR_WPH_NO_HANDLES_DATA;
318 else
319 {
320 // now go read the data
321 // (BLOCK1, BLOCK2, ..., BLOCKn)
322 cbTotal = 0;
323 pbData = NULL;
324 for (ul = 1;
325 ul <= ulHighestBlock;
326 ul++)
327 {
328 ULONG cbBlockThis;
329 CHAR szBlockThis[10];
330 sprintf(szBlockThis, "BLOCK%d", ul);
331 if (!PrfQueryProfileSize(hiniSystem,
332 (PSZ)pcszActiveHandles,
333 szBlockThis,
334 &cbBlockThis))
335 {
336 arc = ERROR_WPH_CORRUPT_HANDLES_DATA;
337 break;
338 }
339 else
340 {
341 ULONG cbTotalOld = cbTotal;
342 cbTotal += cbBlockThis;
343 if (!(pbData = (BYTE*)realloc(pbData, cbTotal)))
344 // on first call, pbData is NULL and this
345 // behaves like malloc()
346 {
347 arc = ERROR_NOT_ENOUGH_MEMORY;
348 break;
349 }
350
351 if (!PrfQueryProfileData(hiniSystem,
352 (PSZ)pcszActiveHandles,
353 szBlockThis,
354 pbData + cbTotalOld,
355 &cbBlockThis))
356 {
357 arc = ERROR_WPH_CORRUPT_HANDLES_DATA;
358 break;
359 }
360 }
361 }
362 }
363
364 if (!arc)
365 {
366 // all went OK:
367 if (pReturn = NEW(HANDLESBUF))
368 {
369 ZERO(pReturn);
370
371 pReturn->pbData = pbData;
372 pReturn->cbData = cbTotal;
373
374 // and load the hiwords too
375 if (!(arc = wphQueryBaseClassesHiwords(hiniUser,
376 &pReturn->usHiwordAbstract,
377 &pReturn->usHiwordFileSystem)))
378 *ppHandlesBuf = pReturn;
379 }
380 else
381 arc = ERROR_NOT_ENOUGH_MEMORY;
382 }
383
384 if (arc)
385 // error:
386 wphFreeHandles(&pReturn);
387 }
388 }
389
390 return (arc);
391}
392
393/*
394 *@@ wphFreeHandles:
395 * frees all data allocated by wphLoadHandles
396 * and sets *ppHandlesBuf to NULL, for safety.
397 *
398 *@@added V0.9.16 (2001-10-02) [umoeller]
399 */
400
401APIRET wphFreeHandles(PHANDLESBUF *ppHandlesBuf)
402{
403 APIRET arc = NO_ERROR;
404
405 if (ppHandlesBuf && *ppHandlesBuf)
406 {
407 PBYTE pbData;
408 if (pbData = (*ppHandlesBuf)->pbData)
409 free(pbData);
410
411 free(*ppHandlesBuf);
412 *ppHandlesBuf = NULL;
413 }
414 else
415 arc = ERROR_INVALID_PARAMETER;
416
417 return (arc);
418}
419
420/* ******************************************************************
421 *
422 * Get HOBJECT from filename
423 *
424 ********************************************************************/
425
426/*
427 *@@ wphSearchBufferForHandle:
428 * returns the four-digit object handle which corresponds
429 * to pszFilename, searching pHandlesBuffer. Note that you
430 * must OR the return value with 0x30000 to make this
431 * a valid WPS file-system handle.
432 *
433 * You must pass a handles buffer to this function which
434 * has been filled using wphReadAllBlocks above.
435 *
436 * This gets called by the one-shot function
437 * wphQueryHandleFromPath.
438 */
439
440USHORT 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
478 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
559
560 // not found: end of buffer reached
561 return (0);
562}
563
564/*
565 *@@ wphQueryHandleFromPath:
566 * finds the object handle for the given fully qualified
567 * filename.
568 * This is a one-shot function, using wphQueryActiveHandles,
569 * wphReadAllBlocks, and wphSearchBufferForHandle.
570 *
571 * Returns:
572 *
573 * -- NO_ERROR: *phobj has received the object handle.
574 *
575 * -- ERROR_FILE_NOT_FOUND: file does not exist.
576 *
577 * plus the error codes of the other wph* functions called.
578 *
579 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
580 */
581
582APIRET wphQueryHandleFromPath(HINI hiniUser, // in: HINI_USER or other INI handle
583 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle
584 const char *pcszName, // in: fully qlf'd filename
585 HOBJECT *phobj) // out: object handle found if NO_ERROR
586{
587 APIRET arc = NO_ERROR;
588
589 PSZ pszActiveHandles = NULL;
590 PHANDLESBUF pHandlesBuf = NULL;
591
592 TRY_LOUD(excpt1)
593 {
594 // not found there: check the handles then
595
596 if (arc = wphQueryActiveHandles(hiniSystem, &pszActiveHandles))
597 _Pmpf((__FUNCTION__ ": wphQueryActiveHandles returned %d", arc));
598 else
599 {
600 if (arc = wphLoadHandles(hiniUser,
601 hiniSystem,
602 pszActiveHandles,
603 &pHandlesBuf))
604 _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc));
605 else
606 {
607 USHORT usObjID;
608 CHAR szFullPath[2*CCHMAXPATH];
609 _fullpath(szFullPath, (PSZ)pcszName, sizeof(szFullPath));
610
611 // search that buffer
612 if (usObjID = wphSearchBufferForHandle(pHandlesBuf->pbData,
613 pHandlesBuf->cbData,
614 0, // usParent
615 szFullPath))
616 // found: OR 0x30000
617 *phobj = usObjID | (pHandlesBuf->usHiwordFileSystem << 16);
618 else
619 arc = ERROR_FILE_NOT_FOUND;
620 }
621 }
622 }
623 CATCH(excpt1)
624 {
625 arc = ERROR_WPH_CRASHED;
626 } END_CATCH();
627
628 if (pszActiveHandles)
629 free(pszActiveHandles);
630 if (pHandlesBuf)
631 wphFreeHandles(&pHandlesBuf);
632
633 return (arc);
634}
635
636/* ******************************************************************
637 *
638 * Get filename from HOBJECT
639 *
640 ********************************************************************/
641
642/*
643 *@@ ComposeThis:
644 * helper for wphComposePath recursion.
645 *
646 *@@added V0.9.16 (2001-10-02) [umoeller]
647 */
648
649APIRET ComposeThis(PHANDLESBUF pHandlesBuf,
650 USHORT usHandle, // in: handle to search for
651 PXSTRING pstrFilename, // in/out: filename
652 PNODE *ppNode) // out: node found (ptr can be NULL)
653{
654 APIRET arc = NO_ERROR;
655 PNODE pNode;
656 if (pNode = pHandlesBuf->NodeHashTable[usHandle])
657 {
658 // handle exists:
659 if (pNode->usParentHandle)
660 {
661 // node has parent:
662 // recurse first
663 if (arc = ComposeThis(pHandlesBuf,
664 pNode->usParentHandle,
665 pstrFilename,
666 ppNode))
667 {
668 if (arc == ERROR_INVALID_HANDLE)
669 // parent handle not found:
670 arc = ERROR_WPH_INVALID_PARENT_HANDLE;
671 // else leave the APIRET, this might be dangerous
672 }
673 else
674 {
675 // no error:
676 xstrcatc(pstrFilename, '\\');
677 xstrcat(pstrFilename, pNode->szName, pNode->usNameSize);
678 }
679 }
680 else
681 // no parent:
682 xstrcpy(pstrFilename, pNode->szName, pNode->usNameSize);
683 }
684 else
685 arc = ERROR_INVALID_HANDLE;
686
687 if (!arc)
688 if (ppNode)
689 *ppNode = pNode;
690
691 return (arc);
692}
693
694/*
695 *@@ wphComposePath:
696 * returns the fully qualified path name for the specified
697 * file-system handle. This function is very fast because
698 * it uses a hash table for all the handles internally.
699 *
700 * Warning: This calls a helper, which recurses.
701 *
702 * This returns:
703 *
704 * -- NO_ERROR
705 *
706 * -- ERROR_WPH_CORRUPT_HANDLES_DATA: buffer data cannot be parsed.
707 *
708 * -- ERROR_WPH_INVALID_HANDLE: usHandle cannot be found.
709 *
710 * -- ERROR_WPH_INVALID_PARENT_HANDLE: a handle was found
711 * that has a broken parent handle.
712 *
713 * -- ERROR_BUFFER_OVERFLOW: cbFilename is too small to
714 * hold the full path that was composed.
715 *
716 *@@added V0.9.16 (2001-10-02) [umoeller]
717 */
718
719APIRET wphComposePath(PHANDLESBUF pHandlesBuf,
720 USHORT usHandle, // in: loword of handle to search for
721 PSZ pszFilename,
722 ULONG cbFilename,
723 PNODE *ppNode) // out: node found (ptr can be NULL)
724{
725 APIRET arc = NO_ERROR;
726
727 TRY_LOUD(excpt1)
728 {
729 if (!pHandlesBuf->fNodeHashTableValid)
730 arc = wphRebuildNodeHashTable(pHandlesBuf);
731
732 if (!arc)
733 {
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);
746 }
747 }
748 CATCH(excpt1)
749 {
750 arc = ERROR_WPH_CRASHED;
751 } END_CATCH();
752
753 return (arc);
754}
755
756/*
757 *@@ wphQueryPathFromHandle:
758 * reverse to wphQueryHandleFromPath, this gets the
759 * filename for hObject.
760 * This is a one-shot function, using wphQueryActiveHandles,
761 * wphReadAllBlocks, and wphFindPartName.
762 *
763 * Returns:
764 *
765 * -- NO_ERROR
766 *
767 * -- ERROR_INVALID_HANDLE: hObject is invalid.
768 *
769 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
770 */
771
772APIRET wphQueryPathFromHandle(HINI hiniUser, // in: HINI_USER or other INI handle
773 HINI hiniSystem, // in: HINI_SYSTEM or other INI handle
774 HOBJECT hObject, // in: 32-bit object handle
775 PSZ pszFilename, // out: filename, if found
776 ULONG cbFilename) // in: sizeof(*pszFilename)
777{
778 APIRET arc = NO_ERROR;
779
780 TRY_LOUD(excpt1)
781 {
782 PSZ pszActiveHandles;
783 if (arc = wphQueryActiveHandles(hiniSystem, &pszActiveHandles))
784 _Pmpf((__FUNCTION__ ": wphQueryActiveHandles returned %d", arc));
785 else
786 {
787 PHANDLESBUF pHandlesBuf;
788 if (arc = wphLoadHandles(hiniUser,
789 hiniSystem,
790 pszActiveHandles,
791 &pHandlesBuf))
792 _Pmpf((__FUNCTION__ ": wphLoadHandles returned %d", arc));
793 else
794 {
795 // is this really a file-system object?
796 if (HIUSHORT(hObject) == pHandlesBuf->usHiwordFileSystem)
797 {
798 // use loword only
799 USHORT usObjID = LOUSHORT(hObject);
800
801 memset(pszFilename, 0, cbFilename);
802 arc = wphComposePath(pHandlesBuf,
803 usObjID,
804 pszFilename,
805 cbFilename,
806 NULL);
807
808 _Pmpf((__FUNCTION__ ": wphFindPartName returned %d", arc));
809 }
810
811 wphFreeHandles(&pHandlesBuf);
812 }
813
814 free(pszActiveHandles);
815 }
816 }
817 CATCH(excpt1)
818 {
819 arc = ERROR_WPH_CRASHED;
820 } END_CATCH();
821
822 return (arc);
823}
824
825
826
Note: See TracBrowser for help on using the repository browser.