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

Last change on this file since 8216 was 8216, checked in by phaller, 23 years ago

Fixed ID string

File size: 13.5 KB
Line 
1/* $Id: handlenames.cpp,v 1.4 2002-04-08 11:22:47 phaller 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
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 // Note: pszSymbolicLink must either terminate at [iLen] or
173 // have a delimiter.
174 if ( (pszSymbolicLink[iLen] == '\\') ||
175 (pszSymbolicLink[iLen] == 0) )
176 if (strnicmp(pHandleName->pszSymbolicLink, pszSymbolicLink, iLen) == 0)
177 return pHandleName;
178 }
179 else
180 {
181 if ( (pszSymbolicLink[iLen] == '\\') ||
182 (pszSymbolicLink[iLen] == 0) )
183 if (strncmp(pHandleName->pszSymbolicLink, pszSymbolicLink, iLen) == 0)
184 return pHandleName;
185 }
186
187
188 // skip to the next entry
189 pLE = pSymbolicLinks->getNext(pLE);
190 }
191
192 // not found
193 return NULL;
194}
195
196
197/*****************************************************************************
198 * Name : HandleNames::findSymbolicLinkExact
199 * Purpose : find the table entry with the specified symbolic link
200 * Parameters: PSZ pszSymbolicLink - the link to scan for
201 * BOOL fCaseInsensitive - TRUE for a case-insensitive lookup
202 * Variables :
203 * Result :
204 * Remark : The comparison here is not meant to be "identity" but
205 * "startsWith" because for the name resolver, the first
206 * symbolic link that the specified name starts with is used
207 * for name resolution.
208 * So the idea is to prevent ambiguous symbolic link names here.
209 *
210 * It is expected to enter this method in "locked" state
211 * Status :
212 *
213 * Author : Patrick Haller [2001/11/23]
214 *****************************************************************************/
215
216PHANDLENAME HandleNames::findSymbolicLinkExact(PSZ pszSymbolicLink)
217{
218 PLINEARLISTENTRY pLE = pSymbolicLinks->getFirst();
219 while (pLE)
220 {
221 PHANDLENAME pHandleName = (PHANDLENAME)pLE->pObject;
222
223 if (strcmp(pHandleName->pszSymbolicLink, pszSymbolicLink) == 0)
224 return pHandleName;
225
226 // skip to the next entry
227 pLE = pSymbolicLinks->getNext(pLE);
228 }
229
230 // not found
231 return NULL;
232}
233
234
235/*****************************************************************************
236 * Name : HandleNames::addSymbolicLink
237 * Purpose : add a symbolic link definition to the table
238 * Parameters: PSZ pszSymbolicLink - the name of the symbolic link
239 * PSZ pszTarget - the name of the device/name to link on
240 * Variables :
241 * Result : TRUE if successful
242 * FALSE if otherwise (same link already exists)
243 * Remark :
244 * Status :
245 *
246 * Author : Patrick Haller [2001/11/23]
247 *****************************************************************************/
248
249BOOL HandleNames::addSymbolicLink(PSZ pszSymbolicLink,
250 PSZ pszTarget)
251{
252 BOOL rc = TRUE;
253
254 mtxHandleNameMgr.enter();
255
256 // 1 - find symbolic link with same name
257 PHANDLENAME pHandleName = findSymbolicLinkExact(pszSymbolicLink);
258
259 // 2 - if found
260 if (NULL != pHandleName)
261 {
262 // 2.1 - and targets are different, return FALSE
263 if (strcmp(pszTarget, pHandleName->pszTarget) == 0)
264 rc = TRUE;
265
266 // 2.2 - and targets are identical, return TRUE
267 else
268 rc = FALSE;
269 }
270 else
271 {
272 // 3 - add definition to table
273 pHandleName = (PHANDLENAME)malloc( sizeof(HANDLENAME) );
274 if (NULL == pHandleName)
275 rc = FALSE;
276 else
277 {
278 pHandleName->pszSymbolicLink = strdup(pszSymbolicLink);
279 if (NULL == pHandleName->pszSymbolicLink)
280 {
281 free (pHandleName);
282 rc = FALSE;
283 }
284 else
285 {
286 pHandleName->pszTarget = strdup(pszTarget);
287 if (NULL == pHandleName->pszTarget)
288 {
289 free (pHandleName->pszSymbolicLink);
290 free (pHandleName);
291 rc = FALSE;
292 }
293 else
294 {
295 // fill in these values
296 pHandleName->ulTargetLength = strlen(pszTarget);
297 pHandleName->ulSymbolicLinkLength = strlen(pszSymbolicLink);
298
299 // OK, finally add to the list
300 pSymbolicLinks->addFirst(pHandleName);
301 }
302 }
303 }
304 }
305
306 mtxHandleNameMgr.leave();
307
308 return rc;
309}
310
311
312/*****************************************************************************
313 * Name :
314 * Purpose :
315 * Parameters:
316 * Variables :
317 * Result : TRUE if successful, FALSE if otherwise
318 * Remark :
319 * Status :
320 *
321 * Author : Patrick Haller [2001/11/23]
322 *****************************************************************************/
323
324BOOL HandleNames::removeSymbolicLink(PSZ pszSymbolicLink)
325{
326 BOOL rc = TRUE;
327
328 mtxHandleNameMgr.enter();
329
330 // 1 - find symbolic name
331 PHANDLENAME pHandleName = findSymbolicLinkExact(pszSymbolicLink);
332 if (NULL == pHandleName)
333 rc = FALSE;
334 else
335 // 2 - remove the link
336 pSymbolicLinks->removeObject(pHandleName);
337
338 mtxHandleNameMgr.leave();
339
340 return rc;
341}
342
343
344/*****************************************************************************
345 * Name : HandleNames::removeTarget
346 * Purpose : remove all links to the specified target
347 * Parameters: PSZ pszTarget - the name of the target to remove
348 * Variables :
349 * Result : TRUE if successful, FALSE if otherwise
350 * Remark :
351 * Status :
352 *
353 * Author : Patrick Haller [2001/11/23]
354 *****************************************************************************/
355
356BOOL HandleNames::removeTarget(PSZ pszTarget)
357{
358 BOOL rc = FALSE;
359
360 mtxHandleNameMgr.enter();
361
362 // iterate over all registered symbolic links
363 PLINEARLISTENTRY pLE = pSymbolicLinks->getFirst();
364 while (pLE)
365 {
366 PHANDLENAME pHandleName = (PHANDLENAME)pLE->pObject;
367
368 // check the name
369 if (strcmp(pszTarget, pHandleName->pszTarget) == 0)
370 {
371 pSymbolicLinks->removeElement(pLE);
372
373 // at least one removal succeeded
374 rc = TRUE;
375 }
376 }
377
378 mtxHandleNameMgr.leave();
379
380 return rc;
381}
382
383
384/*****************************************************************************
385 * Name : HandleNames::resolveName
386 * Purpose : resolve the specified name according to the symbolic links
387 * until we reach the "final" name
388 * Parameters: PSZ pszName
389 * PSZ pszTarget
390 * ULONG ulTargetLength
391 * BOOL fCaseInsensitive
392 * Variables :
393 * Result : FALSE if name was not modified, TRUE if name was resolved
394 * Remark : This is a very easy, cheesy implementation of a pathname
395 * cracker. Should be sufficient at the moment though.
396 * Status :
397 *
398 * Author : Patrick Haller [2001/11/23]
399 *****************************************************************************/
400
401BOOL HandleNames::resolveName(PSZ pszName,
402 PSZ pszTarget,
403 ULONG ulTargetLength,
404 BOOL fCaseInsensitive)
405{
406 BOOL rc = FALSE;
407
408 mtxHandleNameMgr.enter();
409
410 // scan through the names (case-insensitive)
411 PHANDLENAME pHandleName = findSymbolicLink(pszName, fCaseInsensitive);
412 if (NULL != pHandleName)
413 {
414 // rebuild the target name
415 int iNameLength = strlen(pszName);
416
417 // first copy the resolved target name fragment
418 strncpy(pszTarget,
419 pHandleName->pszTarget,
420 ulTargetLength);
421
422 // now append the rest of the specified name with the
423 // now resolved symbolic cut away
424 if (ulTargetLength != pHandleName->ulTargetLength)
425 strncpy(pszTarget + pHandleName->ulTargetLength,
426 pszName + pHandleName->ulSymbolicLinkLength,
427 ulTargetLength - pHandleName->ulTargetLength);
428
429 // tell caller the name has been resolved
430 // (is different from the source name)
431 rc = TRUE;
432 }
433
434 mtxHandleNameMgr.leave();
435
436 return rc;
437}
438
439
440
441
442/*****************************************************************************
443 * Exported Wrapper Functions
444 *****************************************************************************/
445
446BOOL HandleNamesResolveName(PSZ pszName,
447 PSZ pszTarget,
448 ULONG ulTargetLength,
449 BOOL fCaseInsensitive)
450{
451 return pHandleNameMgr->resolveName(pszName,
452 pszTarget,
453 ulTargetLength,
454 fCaseInsensitive);
455}
456
457
458BOOL HandleNamesAddSymbolicLink(PSZ pszSymbolicLink,
459 PSZ pszTarget)
460{
461 return pHandleNameMgr->addSymbolicLink(pszSymbolicLink,
462 pszTarget);
463}
464
465
466BOOL HandleNamesRemoveSymbolicLink(PSZ pszSymbolicLink)
467{
468 return pHandleNameMgr->removeSymbolicLink(pszSymbolicLink);
469}
470
471
472BOOL HandleNamesRemoveTarget(PSZ pszTarget)
473{
474 return pHandleNameMgr->removeTarget(pszTarget);
475}
Note: See TracBrowser for help on using the repository browser.