source: trunk/src/kernel32/handlenames.cpp@ 9975

Last change on this file since 9975 was 9975, checked in by sandervl, 22 years ago

YD: Changes for header updates

File size: 13.8 KB
Line 
1/* $Id: handlenames.cpp,v 1.6 2003-04-02 12:58:29 sandervl Exp $ */
2
3/*
4 * Win32 Handle Manager Object Namespace for OS/2
5 *
6 * 2001/11/23 Patrick Haller <patrick.haller@innotek.de>
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12//#undef DEBUG_LOCAL
13//#define DEBUG_LOCAL
14
15
16/*****************************************************************************
17 * Remark *
18 *****************************************************************************
19
20 */
21
22
23/*****************************************************************************
24 * Includes *
25 *****************************************************************************/
26
27#define INCL_DOSSEMAPHORES
28#define INCL_DOSERRORS
29#include <os2.h>
30
31#include <stdlib.h>
32#include <string.h>
33#include <win32type.h>
34
35#include <ccollection.h>
36#include "handlenames.h"
37#include <vmutex.h>
38
39
40/*****************************************************************************
41 * Defines *
42 *****************************************************************************/
43
44
45/*****************************************************************************
46 * Structures *
47 *****************************************************************************/
48
49typedef struct tagHandleName
50{
51 // the real "defined" target name (which can directly passed on
52 // to the device handlers or filesystems or ...
53 PSZ pszTarget;
54 ULONG ulTargetLength;
55
56 // the alias prefix
57 PSZ pszSymbolicLink;
58 ULONG ulSymbolicLinkLength;
59} HANDLENAME, *PHANDLENAME;
60
61
62class HandleNames
63{
64 protected:
65 VMutex mtxHandleNameMgr;
66 CLinearList* pSymbolicLinks;
67
68 PHANDLENAME findSymbolicLink(PSZ pszSymbolicLink,
69 BOOL fCaseInsensitive);
70
71 PHANDLENAME findSymbolicLinkExact(PSZ pszSymbolicLink);
72
73 public:
74 HandleNames(void);
75 ~HandleNames();
76
77 BOOL addSymbolicLink(PSZ pszSymbolicLink,
78 PSZ pszTarget);
79
80 BOOL removeSymbolicLink(PSZ pszSymbolicLink);
81
82 BOOL removeTarget(PSZ pszTarget);
83
84 BOOL resolveName(PSZ pszName,
85 PSZ pszTarget,
86 ULONG ulTargetLength,
87 BOOL fCaseInsensitive);
88};
89
90
91/*****************************************************************************
92 * Process Global Structures *
93 *****************************************************************************/
94
95
96static HandleNames handleNameMgr;
97static HandleNames* pHandleNameMgr = &handleNameMgr;
98
99
100/*****************************************************************************
101 * Local Prototypes *
102 *****************************************************************************/
103
104
105
106/*****************************************************************************
107 * Name : HandleNames::HandleNames
108 * Purpose : Constructor for handle name mapper
109 * Parameters:
110 * Variables :
111 * Result :
112 * Remark :
113 * Status :
114 *
115 * Author : Patrick Haller [2001/11/23]
116 *****************************************************************************/
117
118HandleNames::HandleNames(void)
119{
120 // Note: as handleNameMgr is a static object, the
121 // destructor will never be called, this memory is leaked.
122 pSymbolicLinks = new CLinearList();
123}
124
125
126/*****************************************************************************
127 * Name : HandleNames::~HandleNames
128 * Purpose : destructor for handle name mapper
129 * Parameters:
130 * Variables :
131 * Result :
132 * Remark :
133 * Status :
134 *
135 * Author : Patrick Haller [2001/11/23]
136 *****************************************************************************/
137
138HandleNames::~HandleNames()
139{
140 delete pSymbolicLinks;
141}
142
143
144/*****************************************************************************
145 * Name : HandleNames::findSymbolicLink
146 * Purpose : find the table entry with the specified symbolic link
147 * Parameters: PSZ pszSymbolicLink - the link to scan for
148 * BOOL fCaseInsensitive - TRUE for a case-insensitive lookup
149 * Variables :
150 * Result :
151 * Remark : The comparison here is not meant to be "identity" but
152 * "startsWith" because for the name resolver, the first
153 * symbolic link that the specified name starts with is used
154 * for name resolution.
155 * So the idea is to prevent ambiguous symbolic link names here.
156 *
157 * It is expected to enter this method in "locked" state
158 * Status :
159 *
160 * Author : Patrick Haller [2001/11/23]
161 *****************************************************************************/
162
163PHANDLENAME HandleNames::findSymbolicLink(PSZ pszSymbolicLink,
164 BOOL fCaseInsensitive)
165{
166 PLINEARLISTENTRY pLE = pSymbolicLinks->getFirst();
167 while (pLE)
168 {
169 PHANDLENAME pHandleName = (PHANDLENAME)pLE->pObject;
170
171 int iLen = strlen(pHandleName->pszSymbolicLink);
172
173 if (fCaseInsensitive)
174 {
175 // Note: pszSymbolicLink must either terminate at [iLen] or
176 // have a delimiter.
177 if ( (pszSymbolicLink[iLen] == '\\') ||
178 (pszSymbolicLink[iLen] == 0) )
179 if (strnicmp(pHandleName->pszSymbolicLink, pszSymbolicLink, iLen) == 0)
180 return pHandleName;
181 }
182 else
183 {
184 if ( (pszSymbolicLink[iLen] == '\\') ||
185 (pszSymbolicLink[iLen] == 0) )
186 if (strncmp(pHandleName->pszSymbolicLink, pszSymbolicLink, iLen) == 0)
187 return pHandleName;
188 }
189
190
191 // skip to the next entry
192 pLE = pSymbolicLinks->getNext(pLE);
193 }
194
195 // not found
196 return NULL;
197}
198
199
200/*****************************************************************************
201 * Name : HandleNames::findSymbolicLinkExact
202 * Purpose : find the table entry with the specified symbolic link
203 * Parameters: PSZ pszSymbolicLink - the link to scan for
204 * BOOL fCaseInsensitive - TRUE for a case-insensitive lookup
205 * Variables :
206 * Result :
207 * Remark : The comparison here is not meant to be "identity" but
208 * "startsWith" because for the name resolver, the first
209 * symbolic link that the specified name starts with is used
210 * for name resolution.
211 * So the idea is to prevent ambiguous symbolic link names here.
212 *
213 * It is expected to enter this method in "locked" state
214 * Status :
215 *
216 * Author : Patrick Haller [2001/11/23]
217 *****************************************************************************/
218
219PHANDLENAME HandleNames::findSymbolicLinkExact(PSZ pszSymbolicLink)
220{
221 PLINEARLISTENTRY pLE = pSymbolicLinks->getFirst();
222 while (pLE)
223 {
224 PHANDLENAME pHandleName = (PHANDLENAME)pLE->pObject;
225
226 if (strcmp(pHandleName->pszSymbolicLink, pszSymbolicLink) == 0)
227 return pHandleName;
228
229 // skip to the next entry
230 pLE = pSymbolicLinks->getNext(pLE);
231 }
232
233 // not found
234 return NULL;
235}
236
237
238/*****************************************************************************
239 * Name : HandleNames::addSymbolicLink
240 * Purpose : add a symbolic link definition to the table
241 * Parameters: PSZ pszSymbolicLink - the name of the symbolic link
242 * PSZ pszTarget - the name of the device/name to link on
243 * Variables :
244 * Result : TRUE if successful
245 * FALSE if otherwise (same link already exists)
246 * Remark :
247 * Status :
248 *
249 * Author : Patrick Haller [2001/11/23]
250 *****************************************************************************/
251
252BOOL HandleNames::addSymbolicLink(PSZ pszSymbolicLink,
253 PSZ pszTarget)
254{
255 BOOL rc = TRUE;
256
257 mtxHandleNameMgr.enter();
258
259 // 1 - find symbolic link with same name
260 PHANDLENAME pHandleName = findSymbolicLinkExact(pszSymbolicLink);
261
262 // 2 - if found
263 if (NULL != pHandleName)
264 {
265 // 2.1 - and targets are different, return FALSE
266 if (strcmp(pszTarget, pHandleName->pszTarget) == 0)
267 rc = TRUE;
268
269 // 2.2 - and targets are identical, return TRUE
270 else
271 rc = FALSE;
272 }
273 else
274 {
275 // 3 - add definition to table
276 pHandleName = (PHANDLENAME)malloc( sizeof(HANDLENAME) );
277 if (NULL == pHandleName)
278 rc = FALSE;
279 else
280 {
281 pHandleName->pszSymbolicLink = strdup(pszSymbolicLink);
282 if (NULL == pHandleName->pszSymbolicLink)
283 {
284 free (pHandleName);
285 rc = FALSE;
286 }
287 else
288 {
289 pHandleName->pszTarget = strdup(pszTarget);
290 if (NULL == pHandleName->pszTarget)
291 {
292 free (pHandleName->pszSymbolicLink);
293 free (pHandleName);
294 rc = FALSE;
295 }
296 else
297 {
298 // fill in these values
299 pHandleName->ulTargetLength = strlen(pszTarget);
300 pHandleName->ulSymbolicLinkLength = strlen(pszSymbolicLink);
301
302 // OK, finally add to the list
303 pSymbolicLinks->addFirst(pHandleName);
304 }
305 }
306 }
307 }
308
309 mtxHandleNameMgr.leave();
310
311 return rc;
312}
313
314
315/*****************************************************************************
316 * Name :
317 * Purpose :
318 * Parameters:
319 * Variables :
320 * Result : TRUE if successful, FALSE if otherwise
321 * Remark :
322 * Status :
323 *
324 * Author : Patrick Haller [2001/11/23]
325 *****************************************************************************/
326
327BOOL HandleNames::removeSymbolicLink(PSZ pszSymbolicLink)
328{
329 BOOL rc = TRUE;
330
331 mtxHandleNameMgr.enter();
332
333 // 1 - find symbolic name
334 PHANDLENAME pHandleName = findSymbolicLinkExact(pszSymbolicLink);
335 if (NULL == pHandleName)
336 rc = FALSE;
337 else
338 {
339 // 2 - remove the link
340 pSymbolicLinks->removeObject(pHandleName);
341
342 if (NULL != pHandleName->pszSymbolicLink )
343 free( pHandleName->pszSymbolicLink );
344
345 if (NULL != pHandleName->pszTarget )
346 free( pHandleName->pszTarget );
347
348 free( pHandleName );
349 }
350
351 mtxHandleNameMgr.leave();
352
353 return rc;
354}
355
356
357/*****************************************************************************
358 * Name : HandleNames::removeTarget
359 * Purpose : remove all links to the specified target
360 * Parameters: PSZ pszTarget - the name of the target to remove
361 * Variables :
362 * Result : TRUE if successful, FALSE if otherwise
363 * Remark :
364 * Status :
365 *
366 * Author : Patrick Haller [2001/11/23]
367 *****************************************************************************/
368
369BOOL HandleNames::removeTarget(PSZ pszTarget)
370{
371 BOOL rc = FALSE;
372
373 mtxHandleNameMgr.enter();
374
375 // iterate over all registered symbolic links
376 PLINEARLISTENTRY pLE = pSymbolicLinks->getFirst();
377 while (pLE)
378 {
379 PHANDLENAME pHandleName = (PHANDLENAME)pLE->pObject;
380
381 // check the name
382 if (strcmp(pszTarget, pHandleName->pszTarget) == 0)
383 {
384 pSymbolicLinks->removeElement(pLE);
385
386 // at least one removal succeeded
387 rc = TRUE;
388 }
389 }
390
391 mtxHandleNameMgr.leave();
392
393 return rc;
394}
395
396
397/*****************************************************************************
398 * Name : HandleNames::resolveName
399 * Purpose : resolve the specified name according to the symbolic links
400 * until we reach the "final" name
401 * Parameters: PSZ pszName
402 * PSZ pszTarget
403 * ULONG ulTargetLength
404 * BOOL fCaseInsensitive
405 * Variables :
406 * Result : FALSE if name was not modified, TRUE if name was resolved
407 * Remark : This is a very easy, cheesy implementation of a pathname
408 * cracker. Should be sufficient at the moment though.
409 * Status :
410 *
411 * Author : Patrick Haller [2001/11/23]
412 *****************************************************************************/
413
414BOOL HandleNames::resolveName(PSZ pszName,
415 PSZ pszTarget,
416 ULONG ulTargetLength,
417 BOOL fCaseInsensitive)
418{
419 BOOL rc = FALSE;
420
421 mtxHandleNameMgr.enter();
422
423 // scan through the names (case-insensitive)
424 PHANDLENAME pHandleName = findSymbolicLink(pszName, fCaseInsensitive);
425 if (NULL != pHandleName)
426 {
427 // rebuild the target name
428 int iNameLength = strlen(pszName);
429
430 // first copy the resolved target name fragment
431 strncpy(pszTarget,
432 pHandleName->pszTarget,
433 ulTargetLength);
434
435 // now append the rest of the specified name with the
436 // now resolved symbolic cut away
437 if (ulTargetLength != pHandleName->ulTargetLength)
438 strncpy(pszTarget + pHandleName->ulTargetLength,
439 pszName + pHandleName->ulSymbolicLinkLength,
440 ulTargetLength - pHandleName->ulTargetLength);
441
442 // tell caller the name has been resolved
443 // (is different from the source name)
444 rc = TRUE;
445 }
446
447 mtxHandleNameMgr.leave();
448
449 return rc;
450}
451
452
453
454
455/*****************************************************************************
456 * Exported Wrapper Functions
457 *****************************************************************************/
458
459BOOL HandleNamesResolveName(PSZ pszName,
460 PSZ pszTarget,
461 ULONG ulTargetLength,
462 BOOL fCaseInsensitive)
463{
464 return pHandleNameMgr->resolveName(pszName,
465 pszTarget,
466 ulTargetLength,
467 fCaseInsensitive);
468}
469
470
471BOOL HandleNamesAddSymbolicLink(PSZ pszSymbolicLink,
472 PSZ pszTarget)
473{
474 return pHandleNameMgr->addSymbolicLink(pszSymbolicLink,
475 pszTarget);
476}
477
478
479BOOL HandleNamesRemoveSymbolicLink(PSZ pszSymbolicLink)
480{
481 return pHandleNameMgr->removeSymbolicLink(pszSymbolicLink);
482}
483
484
485BOOL HandleNamesRemoveTarget(PSZ pszTarget)
486{
487 return pHandleNameMgr->removeTarget(pszTarget);
488}
Note: See TracBrowser for help on using the repository browser.