xref: /reactos/sdk/lib/crt/stdlib/fullpath.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:   See COPYING in the top level directory
3*c2c66affSColin Finck  * PROJECT:     ReactOS CRT library
4*c2c66affSColin Finck  * FILE:        lib/sdk/crt/stdlib/fullpath.c
5*c2c66affSColin Finck  * PURPOSE:     Gets the fullpathname
6*c2c66affSColin Finck  * PROGRAMER:   Pierre Schweitzer (pierre.schweitzer@reactos.org)
7*c2c66affSColin Finck  */
8*c2c66affSColin Finck 
9*c2c66affSColin Finck #include <precomp.h>
10*c2c66affSColin Finck #include <tchar.h>
11*c2c66affSColin Finck 
12*c2c66affSColin Finck /*
13*c2c66affSColin Finck  * @implemented
14*c2c66affSColin Finck  */
_tfullpath(_TCHAR * absPath,const _TCHAR * relPath,size_t maxLength)15*c2c66affSColin Finck _TCHAR* _tfullpath(_TCHAR* absPath, const _TCHAR* relPath, size_t maxLength)
16*c2c66affSColin Finck {
17*c2c66affSColin Finck     _TCHAR* lpBuffer;
18*c2c66affSColin Finck     _TCHAR* lpFilePart;
19*c2c66affSColin Finck     DWORD retval;
20*c2c66affSColin Finck 
21*c2c66affSColin Finck     /* First check if entry relative path was given */
22*c2c66affSColin Finck     if (!relPath || relPath[0] == 0)
23*c2c66affSColin Finck     {
24*c2c66affSColin Finck         /* If not, just try to return current dir */
25*c2c66affSColin Finck         return _tgetcwd(absPath, maxLength);
26*c2c66affSColin Finck     }
27*c2c66affSColin Finck 
28*c2c66affSColin Finck     /* If no output buffer was given */
29*c2c66affSColin Finck     if (!absPath)
30*c2c66affSColin Finck     {
31*c2c66affSColin Finck         /* Allocate one with fixed length */
32*c2c66affSColin Finck         maxLength = MAX_PATH;
33*c2c66affSColin Finck         lpBuffer = malloc(maxLength);
34*c2c66affSColin Finck         if (!lpBuffer)
35*c2c66affSColin Finck         {
36*c2c66affSColin Finck             errno = ENOMEM;
37*c2c66affSColin Finck             return NULL;
38*c2c66affSColin Finck         }
39*c2c66affSColin Finck     }
40*c2c66affSColin Finck     else
41*c2c66affSColin Finck     {
42*c2c66affSColin Finck         lpBuffer = absPath;
43*c2c66affSColin Finck     }
44*c2c66affSColin Finck 
45*c2c66affSColin Finck     /* Really get full path */
46*c2c66affSColin Finck     retval = GetFullPathName(relPath, (DWORD)maxLength, lpBuffer, &lpFilePart);
47*c2c66affSColin Finck     /* Check for failures */
48*c2c66affSColin Finck     if (retval > maxLength)
49*c2c66affSColin Finck     {
50*c2c66affSColin Finck         /* Path too long, free (if needed) and return */
51*c2c66affSColin Finck         if (!absPath)
52*c2c66affSColin Finck         {
53*c2c66affSColin Finck             free(lpBuffer);
54*c2c66affSColin Finck         }
55*c2c66affSColin Finck 
56*c2c66affSColin Finck         errno = ERANGE;
57*c2c66affSColin Finck         return NULL;
58*c2c66affSColin Finck     }
59*c2c66affSColin Finck     else if (!retval)
60*c2c66affSColin Finck     {
61*c2c66affSColin Finck         /* Other error, free (if needed), translate error, and return */
62*c2c66affSColin Finck         if (!absPath)
63*c2c66affSColin Finck         {
64*c2c66affSColin Finck             free(lpBuffer);
65*c2c66affSColin Finck         }
66*c2c66affSColin Finck 
67*c2c66affSColin Finck         _dosmaperr(GetLastError());
68*c2c66affSColin Finck         return NULL;
69*c2c66affSColin Finck     }
70*c2c66affSColin Finck 
71*c2c66affSColin Finck     /* Return buffer. Up to the caller to free if needed */
72*c2c66affSColin Finck     return lpBuffer;
73*c2c66affSColin Finck }
74