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

Last change on this file since 21302 was 21302, checked in by ydario, 16 years ago

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