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

Last change on this file since 53 was 21, checked in by umoeller, 25 years ago

Final changes for 0.9.7, i hope...

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 25.5 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 * This code is mostly written by Henk Kelder and published
15 * with his kind permission.
16 *
17 * Note: Version numbering in this file relates to XWorkplace version
18 * numbering.
19 *
20 *@@header "helpers\wphandle.h"
21 */
22
23/*
24 * This file Copyright (C) 1997-2000 Ulrich M”ller,
25 * Henk Kelder.
26 * This file is part of the "XWorkplace helpers" source package.
27 * This is free software; you can redistribute it and/or modify
28 * it under the terms of the GNU General Public License as published
29 * by the Free Software Foundation, in version 2 as it comes in the
30 * "COPYING" file of the XWorkplace main distribution.
31 * This program is distributed in the hope that it will be useful,
32 * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 * GNU General Public License for more details.
35 */
36
37#define OS2EMX_PLAIN_CHAR
38 // this is needed for "os2emx.h"; if this is defined,
39 // emx will define PSZ as _signed_ char, otherwise
40 // as unsigned char
41
42#define INCL_WINSHELLDATA
43#include <os2.h>
44
45#define OPTIONS_SIZE 32767
46
47#include <stdio.h>
48#include <string.h>
49#include <stdlib.h>
50#include <io.h>
51
52#include "setup.h" // code generation and debugging options
53
54#include "helpers\wphandle.h"
55
56/****************************************************
57 * *
58 * helper functions *
59 * *
60 ****************************************************/
61
62static USHORT wphSearchBufferForHandle(PBYTE pHandlesBuffer, ULONG ulBufSize, USHORT usParent, PSZ pszFname);
63PNODE 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)
68
69/*
70 *@@category: Helpers\PM helpers\Workplace Shell\Handles (OS2SYS.INI)
71 * See wphandle.c.
72 */
73
74/* ******************************************************************
75 *
76 * Helper functions
77 *
78 ********************************************************************/
79
80/*
81 *@@ wphQueryProfileData:
82 * like PrfQueryProfileData, but allocates sufficient
83 * memory and returns a pointer to that buffer.
84 * pulSize must point to a ULONG which will then
85 * contain the no. of copied bytes.
86 */
87
88PBYTE wphQueryProfileData(HINI hIniSystem, // in: can be HINI_USER or HINI_SYSTEM
89 PSZ pApp, PSZ pKey, // in: load what?
90 PULONG pulSize) // out: bytes loaded
91{
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 keys
105 * for pApp into it.
106 * Returns the pointer to the buffer.
107 * pulKeysSize must point to a ULONG which will then
108 * contain the size of the returned buffer.
109 */
110
111PBYTE wphEnumProfileKeys(HINI hIniSystem, // in: can be HINI_USER or HINI_SYSTEM
112 PSZ pApp, // in: app to query
113 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 *@@ 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".
145 * It seems that every time the WPS does something in the
146 * handles section, it writes the data to the inactive
147 * buffer first and then makes it the active buffer by
148 * changing the "active handles" key. You can test this
149 * by creating a shadow on your Desktop.
150 *
151 * This function copies the key only, but not the actual
152 * handles blocks (use wphReadAllBlocks for that).
153 *
154 * This gets called by the one-shot function
155 * wphQueryHandleFromPath.
156 */
157
158BOOL 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;
177}
178
179/*
180 *@@ wphReadAllBlocks:
181 * this reads all the BLOCK's in the active handles
182 * section in OS2SYS.INI into one common buffer, for
183 * which sufficient memory is allocated.
184 *
185 * Each of these blocks is a maximum of 64 KB, hell
186 * knows why, maybe the INIs can't handle more. This
187 * func combines all the BLOCK's into one buffer anyways,
188 * which can then be searched.
189 *
190 * Use wphQueryActiveHandles to pass the active handles
191 * section to this function.
192 *
193 * This gets called by the one-shot function
194 * wphQueryHandleFromPath.
195 */
196
197BOOL wphReadAllBlocks(HINI hiniSystem, // in: can be HINI_USER or HINI_SYSTEM
198 PSZ pszActiveHandles, // in: active handles section
199 PBYTE* ppBlock, // in/out: pointer to buffer, which
200 // will point to the allocated
201 // memory afterwards
202 PULONG pulSize) // out: size of the allocated buffer
203{
204 PBYTE pbAllBlocks,
205 pszBlockName,
206 p;
207 ULONG ulBlockSize;
208 ULONG ulTotalSize;
209 BYTE rgfBlock[100];
210 BYTE szAppName[10];
211 USHORT usBlockNo;
212
213 pbAllBlocks = wphEnumProfileKeys(hiniSystem, pszActiveHandles, &ulBlockSize);
214 if (!pbAllBlocks)
215 return FALSE;
216
217 // query size of all individual blocks and calculate total
218 memset(rgfBlock, 0, sizeof rgfBlock);
219 ulTotalSize = 0L;
220 pszBlockName = pbAllBlocks;
221 while (*pszBlockName)
222 {
223 if (!memicmp(pszBlockName, "BLOCK", 5))
224 {
225 usBlockNo = atoi(pszBlockName + 5);
226 if (usBlockNo < 100)
227 {
228 rgfBlock[usBlockNo] = TRUE;
229
230 if (!PrfQueryProfileSize(hiniSystem,
231 pszActiveHandles,
232 pszBlockName,
233 &ulBlockSize))
234 {
235 free(pbAllBlocks);
236 return FALSE;
237 }
238 ulTotalSize += ulBlockSize;
239 }
240 }
241 pszBlockName += strlen(pszBlockName) + 1;
242 }
243
244 // *pulSize now contains the total size of all blocks
245 *ppBlock = (PBYTE)malloc(ulTotalSize);
246 if (!(*ppBlock))
247 {
248 /* MessageBox("wphReadAllBlocks", "Not enough memory for profile data!"); */
249 free(pbAllBlocks);
250 return FALSE;
251 }
252
253 // now get all blocks into the memory we allocated
254 p = *ppBlock;
255 (*pulSize) = 0;
256 for (usBlockNo = 1; usBlockNo < 100; usBlockNo++)
257 {
258 if (!rgfBlock[usBlockNo])
259 break;
260
261 sprintf(szAppName, "BLOCK%u", (UINT)usBlockNo);
262 ulBlockSize = ulTotalSize;
263 if (!PrfQueryProfileData(hiniSystem,
264 pszActiveHandles,
265 szAppName,
266 p,
267 &ulBlockSize))
268 {
269 free(pbAllBlocks);
270 free(*ppBlock);
271 return FALSE;
272 }
273 p += ulBlockSize;
274 (*pulSize) += ulBlockSize;
275 ulTotalSize -= ulBlockSize;
276 }
277
278 free(pbAllBlocks);
279 return TRUE;
280}
281
282/* ******************************************************************
283 *
284 * Get HOBJECT from filename
285 *
286 ********************************************************************/
287
288/*
289 *@@ wphSearchBufferForHandle:
290 * returns the four-digit object handle which corresponds
291 * to pszFname, searching pHandlesBuffer. Note that you
292 * must OR the return value with 0x30000 to make this
293 * a valid WPS file-system handle.
294 *
295 * You must pass a handles buffer to this function which
296 * has been filled using wphReadAllBlocks above.
297 *
298 * This gets called by the one-shot function
299 * wphQueryHandleFromPath.
300 */
301
302USHORT wphSearchBufferForHandle(PBYTE pHandlesBuffer, // in: handles buffer (all BLOCK's)
303 ULONG ulBufSize, // in: sizeof(pHandlesBuffer)
304 USHORT usParent, // in: parent NODE ID;
305 // must be 0 initially
306 PSZ pszFname) // in: fully qlf'd filename to search for
307{
308 PDRIV pDriv;
309 PNODE pNode;
310 PBYTE pCur; // current
311 PBYTE p,
312 pEnd; // *end of buffer
313 USHORT usPartSize;
314
315 // _Pmpf(("Entering wphSearchBufferForHandle for %s", pszFname));
316
317 // The composed BLOCKs in the handles buffer make up a tree of
318 // DRIVE and NODE structures (see wphandle.h). Each NODE stands
319 // for either a directory or a file. (We don't care about the
320 // DRIVE structures because the root directory gets a NODE also.)
321 // Each NODE contains the non-qualified file name, an object ID,
322 // and the object ID of its parent NODE.
323 // We can thus work our way through the buffer by splitting the
324 // fully qualified filename that we're searching for into the
325 // different directory names and, each time, searching for the
326 // corresponding NODE. If we have found that, we go for the next.
327 // Example for C:\OS2\E.EXE:
328 // 1) first search for the "C:" NODE
329 // 2) then find the "OS2" node which has "C" as its parent NODE
330 // (we do this by comparing the parent object handles)
331 // 3) then find the "E.EXE" NODE the same way
332 // The "E.EXE" NODE then has the object handle we're looking for.
333
334 // So first find the length of the first filename part (which
335 // should be 2 for the drive letter, "C:")
336 p = strchr(pszFname, '\\');
337 if (p)
338 // backslash found:
339 usPartSize = p - pszFname; // extract first part
340 else
341 usPartSize = strlen(pszFname);
342
343 // now set the pointer for the end of the BLOCKs buffer
344 pEnd = pHandlesBuffer + ulBufSize;
345
346 // pCur is our variable pointer where we're at now; there
347 // is some offset of 4 bytes at the beginning (duh)
348 pCur = pHandlesBuffer + 4;
349
350 // _Pmpf((" Searching for: %s, usPartSize: %d", pszFname, usPartSize));
351
352 // go!
353 while (pCur < pEnd)
354 {
355 // the first four chars tell us whether it's
356 // a DRIVE or a NODE structure
357 if (!memicmp(pCur, "DRIV", 4))
358 {
359 // pCur points to a DRIVE node:
360 // we don't care about these, because the root
361 // directory has a real NODE too, so we just
362 // skip this
363 pDriv = (PDRIV)pCur;
364 pCur += sizeof(DRIV) + strlen(pDriv->szName);
365 }
366 else if (!memicmp(pCur, "NODE", 4))
367 {
368 // pCur points to a regular NODE: offset pointer first
369 pNode = (PNODE)pCur;
370 pCur += sizeof (NODE) + pNode->usNameSize;
371
372 // does the NODE have the same parent that we
373 // are currently searching for? This is "0"
374 // for root directories (and initially for us
375 // too)
376 if (usParent == pNode->usParentHandle)
377 {
378 // yes:
379 // _Pmpf((" found matching parents (%lX): %s", usParent, pNode->szName));
380
381 // does the NODE have the same partname length?
382 if (pNode->usNameSize == usPartSize)
383 {
384 // yes:
385 // _Pmpf((" found matching partnames sizes: %d", pNode->usNameSize));
386
387 // do the partnames match too?
388 if (memicmp(pszFname, pNode->szName, usPartSize) == 0)
389 {
390 // OK!! proper NODE found!
391 // _Pmpf((" FOUND %s!!", pNode->szName));
392
393 // now check if this was the last NODE
394 // we were looking for
395 if (strlen(pszFname) == usPartSize)
396 // yes: return ID
397 return (pNode->usHandle);
398
399 // else: update our status;
400 // get next partname
401 pszFname += usPartSize + 1;
402 // calc next partname length
403 p = strchr(pszFname, '\\');
404 if (p)
405 usPartSize = p - pszFname;
406 else
407 usPartSize = strlen(pszFname);
408
409 // get next parent to search for
410 // (which is the current handle)
411 usParent = pNode->usHandle;
412 }
413 }
414 }
415 }
416 else
417 // neither DRIVE nor NODE: error
418 return (0);
419
420 } // end while
421
422 // not found: end of buffer reached
423 return (0);
424}
425
426/*
427 *@@ wphQueryHandleFromPath:
428 * find the object handle for pszName; this
429 * can either be an object ID ("<WP_DESKTOP>")
430 * or a fully qualified filename.
431 * This is a one-shot function, using wphQueryActiveHandles,
432 * wphReadAllBlocks, and wphSearchBufferForHandle.
433 *
434 * 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
453HOBJECT 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;
461 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);
520}
521
522/* ******************************************************************
523 *
524 * Get filename from HOBJECT
525 *
526 ********************************************************************/
527
528/*
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
538PNODE 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;
545 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 }
578 else
579 {
580 strncpy(pszFname, pNode->szName, usSize);
581 return pNode;
582 }
583 }
584 }
585 else
586 return (NULL);
587 }
588 return (NULL);
589}
590
591/*
592 *@@ wphQueryPathFromHandle:
593 * reverse to wphQueryHandleFromPath, this gets the
594 * filename for hObject.
595 * This is a one-shot function, using wphQueryActiveHandles,
596 * wphReadAllBlocks, and wphFindPartName.
597 *
598 *@@changed V0.9.4 (2000-08-03) [umoeller]: now returning BOOL
599 */
600
601BOOL 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);
639}
640
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
654BOOL 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
733ULONG 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
763ULONG 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
Note: See TracBrowser for help on using the repository browser.