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

Last change on this file since 8706 was 8327, checked in by sandervl, 23 years ago

PH: memory leak fixes; extra checks for NULL pointers; CreateProcess changes for debug option; GetModuleFileName doesn't count 0 terminator

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