Reactos
1/*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/client/pathansi.c
5 * PURPOSE: Handles path APIs
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <k32.h>
12
13/* FUNCTIONS ******************************************************************/
14
15/*
16 * @implemented
17 */
18DWORD
19WINAPI
20GetShortPathNameA(IN LPCSTR lpszLongPath,
21 OUT LPSTR lpszShortPath,
22 IN DWORD cchBuffer)
23{
24 ULONG Result, PathLength;
25 PWCHAR ShortPath;
26 NTSTATUS Status;
27 UNICODE_STRING LongPathUni, ShortPathUni;
28 ANSI_STRING ShortPathAnsi;
29 WCHAR ShortPathBuffer[MAX_PATH];
30
31 ShortPath = NULL;
32 ShortPathAnsi.Buffer = NULL;
33 LongPathUni.Buffer = NULL;
34 Result = 0;
35
36 if (!lpszLongPath)
37 {
38 SetLastError(ERROR_INVALID_PARAMETER);
39 return 0;
40 }
41
42 Status = Basep8BitStringToDynamicUnicodeString(&LongPathUni, lpszLongPath);
43 if (!NT_SUCCESS(Status)) goto Quickie;
44
45 ShortPath = ShortPathBuffer;
46
47 PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPathBuffer, MAX_PATH);
48 if (PathLength >= MAX_PATH)
49 {
50 ShortPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLength * sizeof(WCHAR));
51 if (!ShortPath)
52 {
53 PathLength = 0;
54 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
55 }
56 else
57 {
58 PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPath, PathLength);
59 }
60 }
61
62 if (!PathLength) goto Quickie;
63
64 LongPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
65 ShortPathUni.Buffer = ShortPath;
66 ShortPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
67
68 Status = BasepUnicodeStringTo8BitString(&ShortPathAnsi, &ShortPathUni, TRUE);
69 if (!NT_SUCCESS(Status))
70 {
71 BaseSetLastNTError(Status);
72 Result = 0;
73 }
74
75 Result = ShortPathAnsi.Length;
76 if ((lpszShortPath) && (cchBuffer > ShortPathAnsi.Length))
77 {
78 RtlMoveMemory(lpszShortPath, ShortPathAnsi.Buffer, ShortPathAnsi.Length);
79 lpszShortPath[Result] = ANSI_NULL;
80 }
81 else
82 {
83 Result = ShortPathAnsi.Length + sizeof(ANSI_NULL);
84 }
85
86Quickie:
87 if (LongPathUni.Buffer) RtlFreeUnicodeString(&LongPathUni);
88 if (ShortPathAnsi.Buffer) RtlFreeAnsiString(&ShortPathAnsi);
89 if ((ShortPath) && (ShortPath != ShortPathBuffer))
90 {
91 RtlFreeHeap(RtlGetProcessHeap(), 0, ShortPath);
92 }
93 return Result;
94}
95
96/* EOF */