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

Last change on this file since 7465 was 7465, checked in by phaller, 24 years ago

fix in name resolver

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