ReactOS 0.4.15-dev-5666-gc548b97
path.c File Reference
#include <k32.h>
#include <debug.h>
Include dependency graph for path.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PWCHAR WINAPI BasepEndOfDirName (IN PWCHAR FileName)
 
LPWSTR WINAPI BasepComputeProcessPath (IN PBASE_SEARCH_PATH_TYPE PathOrder, IN LPWSTR AppName, IN LPVOID Environment)
 
LPWSTR WINAPI BaseComputeProcessSearchPath (VOID)
 
LPWSTR WINAPI BaseComputeProcessExePath (IN LPWSTR FullPath)
 
LPWSTR WINAPI BaseComputeProcessDllPath (IN LPWSTR FullPath, IN PVOID Environment)
 
BOOLEAN WINAPI CheckForSameCurdir (IN PUNICODE_STRING DirName)
 
BOOL WINAPI IsShortName_U (IN PWCHAR Name, IN ULONG Length)
 
BOOL WINAPI IsLongName_U (IN PWCHAR FileName, IN ULONG Length)
 
BOOL WINAPI FindLFNorSFN_U (IN PWCHAR Path, OUT PWCHAR *First, OUT PWCHAR *Last, IN BOOL UseShort)
 
PWCHAR WINAPI SkipPathTypeIndicator_U (IN LPWSTR Path)
 
BOOL WINAPI BasepIsCurDirAllowedForPlainExeNames (VOID)
 
BOOL WINAPI SetDllDirectoryW (IN LPCWSTR lpPathName)
 
BOOL WINAPI SetDllDirectoryA (IN LPCSTR lpPathName)
 
DWORD WINAPI GetDllDirectoryW (IN DWORD nBufferLength, OUT LPWSTR lpBuffer)
 
DWORD WINAPI GetDllDirectoryA (IN DWORD nBufferLength, OUT LPSTR lpBuffer)
 
BOOL WINAPI NeedCurrentDirectoryForExePathW (IN LPCWSTR ExeName)
 
BOOL WINAPI NeedCurrentDirectoryForExePathA (IN LPCSTR ExeName)
 
DWORD WINAPI GetFullPathNameA (IN LPCSTR lpFileName, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart)
 
DWORD WINAPI GetFullPathNameW (IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
 
DWORD WINAPI SearchPathA (IN LPCSTR lpPath OPTIONAL, IN LPCSTR lpFileName, IN LPCSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart OPTIONAL)
 
DWORD WINAPI SearchPathW (IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
 
DWORD WINAPI GetLongPathNameW (IN LPCWSTR lpszShortPath, OUT LPWSTR lpszLongPath, IN DWORD cchBuffer)
 
DWORD WINAPI GetLongPathNameA (IN LPCSTR lpszShortPath, OUT LPSTR lpszLongPath, IN DWORD cchBuffer)
 
DWORD WINAPI GetShortPathNameA (IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
 
DWORD WINAPI GetShortPathNameW (IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
 
DWORD WINAPI GetTempPathA (IN DWORD nBufferLength, OUT LPSTR lpBuffer)
 
DWORD WINAPI GetTempPathW (IN DWORD count, OUT LPWSTR path)
 
DWORD WINAPI GetCurrentDirectoryA (IN DWORD nBufferLength, OUT LPSTR lpBuffer)
 
DWORD WINAPI GetCurrentDirectoryW (IN DWORD nBufferLength, OUT LPWSTR lpBuffer)
 
BOOL WINAPI SetCurrentDirectoryA (IN LPCSTR lpPathName)
 
BOOL WINAPI SetCurrentDirectoryW (IN LPCWSTR lpPathName)
 
UINT WINAPI GetSystemDirectoryA (OUT LPSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetSystemDirectoryW (OUT LPWSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetWindowsDirectoryA (OUT LPSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetWindowsDirectoryW (OUT LPWSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetSystemWindowsDirectoryA (OUT LPSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetSystemWindowsDirectoryW (OUT LPWSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetSystemWow64DirectoryW (OUT LPWSTR lpBuffer, IN UINT uSize)
 
UINT WINAPI GetSystemWow64DirectoryA (OUT LPSTR lpBuffer, IN UINT uSize)
 

Variables

UNICODE_STRING NoDefaultCurrentDirectoryInExePath = RTL_CONSTANT_STRING(L"NoDefaultCurrentDirectoryInExePath")
 
UNICODE_STRING BaseWindowsSystemDirectory
 
UNICODE_STRING BaseWindowsDirectory
 
UNICODE_STRING BaseDefaultPathAppend
 
UNICODE_STRING BaseDefaultPath
 
UNICODE_STRING BaseDllDirectory
 
PVOID gpTermsrvGetWindowsDirectoryA
 
PVOID gpTermsrvGetWindowsDirectoryW
 
DWORD IllegalMask [4]
 
BASE_SEARCH_PATH_TYPE BaseDllOrderCurrent [BaseCurrentDirPlacementMax][BaseSearchPathMax]
 
BASE_SEARCH_PATH_TYPE BaseProcessOrderNoCurrent [BaseSearchPathMax]
 
BASE_SEARCH_PATH_TYPE BaseDllOrderNoCurrent [BaseSearchPathMax]
 
BASE_SEARCH_PATH_TYPE BaseProcessOrder [BaseSearchPathMax]
 
BASE_CURRENT_DIR_PLACEMENT BasepDllCurrentDirPlacement = BaseCurrentDirPlacementInvalid
 
UNICODE_STRING BasePathVariableName
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file path.c.

Function Documentation

◆ BaseComputeProcessDllPath()

LPWSTR WINAPI BaseComputeProcessDllPath ( IN LPWSTR  FullPath,
IN PVOID  Environment 
)

Definition at line 420 of file path.c.

422{
424 UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager");
425 UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"SafeDllSearchMode");
427 CHAR PartialInfoBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(ULONG)];
431 BASE_CURRENT_DIR_PLACEMENT CurrentDirPlacement, OldCurrentDirPlacement;
432
433 /* Acquire DLL directory lock */
435
436 /* Check if we have a base dll directory */
438 {
439 /* Then compute the process path using DLL order (without curdir) */
441
442 /* Release DLL directory lock */
444
445 /* Return dll path */
446 return DllPath;
447 }
448
449 /* Release DLL directory lock */
451
452 /* Read the current placement */
453 CurrentDirPlacement = BasepDllCurrentDirPlacement;
454 if (CurrentDirPlacement == BaseCurrentDirPlacementInvalid)
455 {
456 /* Open the configuration key */
458 if (NT_SUCCESS(Status))
459 {
460 /* Query if safe search is enabled */
462 &ValueName,
464 PartialInfoBuffer,
465 sizeof(PartialInfoBuffer),
466 &ResultLength);
467 if (NT_SUCCESS(Status))
468 {
469 /* Read the value if the size is OK */
470 if (ResultLength == sizeof(PartialInfoBuffer))
471 {
472 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)PartialInfoBuffer;
473 CurrentDirPlacement = *(PULONG)PartialInfo->Data;
474 }
475 }
476
477 /* Close the handle */
479
480 /* Validate the registry value */
481 if ((CurrentDirPlacement <= BaseCurrentDirPlacementInvalid) ||
482 (CurrentDirPlacement >= BaseCurrentDirPlacementMax))
483 {
484 /* Default to safe search */
485 CurrentDirPlacement = BaseCurrentDirPlacementSafe;
486 }
487 }
488
489 /* Update the placement and read the old one */
491 CurrentDirPlacement,
493 if (OldCurrentDirPlacement != BaseCurrentDirPlacementInvalid)
494 {
495 /* If there already was a placement, use it */
496 CurrentDirPlacement = OldCurrentDirPlacement;
497 }
498 }
499
500 /* Check if the placement is invalid or not set */
501 if ((CurrentDirPlacement <= BaseCurrentDirPlacementInvalid) ||
502 (CurrentDirPlacement >= BaseCurrentDirPlacementMax))
503 {
504 /* Default to safe search */
505 CurrentDirPlacement = BaseCurrentDirPlacementSafe;
506 }
507
508 /* Compute the process path using either normal or safe search */
510 FullPath,
512
513 /* Return dll path */
514 return DllPath;
515}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
RTL_CRITICAL_SECTION BaseDllDirectoryLock
Definition: dllmain.c:32
BASE_SEARCH_PATH_TYPE BaseDllOrderNoCurrent[BaseSearchPathMax]
Definition: path.c:63
BASE_CURRENT_DIR_PLACEMENT BasepDllCurrentDirPlacement
Definition: path.c:81
LPWSTR WINAPI BasepComputeProcessPath(IN PBASE_SEARCH_PATH_TYPE PathOrder, IN LPWSTR AppName, IN LPVOID Environment)
Definition: path.c:116
UNICODE_STRING BaseDllDirectory
Definition: path.c:21
BASE_SEARCH_PATH_TYPE BaseDllOrderCurrent[BaseCurrentDirPlacementMax][BaseSearchPathMax]
Definition: path.c:36
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InterlockedCompareExchange
Definition: interlocked.h:104
@ BaseCurrentDirPlacementSafe
Definition: kernel32.h:95
@ BaseCurrentDirPlacementMax
Definition: kernel32.h:96
@ BaseCurrentDirPlacementInvalid
Definition: kernel32.h:93
enum _BASE_CURRENT_DIR_PLACEMENT BASE_CURRENT_DIR_PLACEMENT
unsigned int * PULONG
Definition: retypes.h:1
signed int * PLONG
Definition: retypes.h:5
unsigned int ULONG
Definition: retypes.h:1
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
static const char const char * DllPath
Definition: image.c:34
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyValuePartialInformation
Definition: nt_native.h:1182
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define L(x)
Definition: ntvdm.h:50
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175

Referenced by BasePushProcessParameters(), GetModuleHandleForUnicodeString(), and LoadLibraryExW().

◆ BaseComputeProcessExePath()

LPWSTR WINAPI BaseComputeProcessExePath ( IN LPWSTR  FullPath)

Definition at line 405 of file path.c.

406{
407 PBASE_SEARCH_PATH_TYPE PathOrder;
408 DPRINT("Computing EXE path: %S\n", FullPath);
409
410 /* Check if we should use the current directory */
411 PathOrder = NeedCurrentDirectoryForExePathW(FullPath) ?
413
414 /* And now compute the path */
415 return BasepComputeProcessPath(PathOrder, NULL, NULL);
416}
BASE_SEARCH_PATH_TYPE BaseProcessOrder[BaseSearchPathMax]
Definition: path.c:72
BASE_SEARCH_PATH_TYPE BaseProcessOrderNoCurrent[BaseSearchPathMax]
Definition: path.c:54
BOOL WINAPI NeedCurrentDirectoryForExePathW(IN LPCWSTR ExeName)
Definition: path.c:957
enum _BASE_SEARCH_PATH_TYPE * PBASE_SEARCH_PATH_TYPE
#define DPRINT
Definition: sndvol32.h:71

Referenced by CreateProcessInternalW().

◆ BaseComputeProcessSearchPath()

LPWSTR WINAPI BaseComputeProcessSearchPath ( VOID  )

Definition at line 395 of file path.c.

396{
397 DPRINT("Computing Process Search path\n");
398
399 /* Compute the path using default process order */
401}

Referenced by SearchPathW().

◆ BasepComputeProcessPath()

LPWSTR WINAPI BasepComputeProcessPath ( IN PBASE_SEARCH_PATH_TYPE  PathOrder,
IN LPWSTR  AppName,
IN LPVOID  Environment 
)

Definition at line 116 of file path.c.

119{
120 PWCHAR PathBuffer, Buffer, AppNameEnd, PathCurrent;
121 SIZE_T PathLengthInBytes;
123 UNICODE_STRING EnvPath;
125
126 /* Initialize state */
127 AppNameEnd = Buffer = PathBuffer = NULL;
129 PathLengthInBytes = 0;
130
131 /* Loop the ordering array */
132 for (Order = PathOrder; *Order != BaseSearchPathInvalid; Order++) {
133 switch (*Order)
134 {
135 /* Compute the size of the DLL path */
137
138 /* This path only gets called if SetDllDirectory was called */
140
141 /* Make sure there's a DLL directory size */
143 {
144 /* Add it, plus the separator */
145 PathLengthInBytes += BaseDllDirectory.Length + sizeof(L';');
146 }
147 break;
148
149 /* Compute the size of the current path */
151
152 /* Add ".;" */
153 PathLengthInBytes += (2 * sizeof(WCHAR));
154 break;
155
156 /* Compute the size of the "PATH" environment variable */
158
159 /* Grab PEB lock if one wasn't passed in */
161
162 /* Query the size first */
163 EnvPath.MaximumLength = 0;
166 &EnvPath);
168 {
169 /* Compute the size we'll need for the environment */
170 EnvPath.MaximumLength = EnvPath.Length + sizeof(WCHAR);
171 if ((EnvPath.Length + sizeof(WCHAR)) > UNICODE_STRING_MAX_BYTES)
172 {
173 /* Don't let it overflow */
174 EnvPath.MaximumLength = EnvPath.Length;
175 }
176
177 /* Allocate the environment buffer */
178 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
179 0,
180 EnvPath.MaximumLength);
181 if (Buffer)
182 {
183 /* Now query the PATH environment variable */
184 EnvPath.Buffer = Buffer;
187 &EnvPath);
188 }
189 else
190 {
191 /* Failure case */
193 }
194 }
195
196 /* Release the PEB lock from above */
198
199 /* There might not be a PATH */
201 {
202 /* In this case, skip this PathOrder */
203 EnvPath.Length = EnvPath.MaximumLength = 0;
205 }
206 else if (!NT_SUCCESS(Status))
207 {
208 /* An early failure, go to exit code */
209 goto Quickie;
210 }
211 else
212 {
213 /* Add the length of the PATH variable unless it's empty */
214 ASSERT(!(EnvPath.Length & 1));
215 if (EnvPath.Length)
216 {
217 /* Reserve space for the variable and a semicolon */
218 PathLengthInBytes += (EnvPath.Length + sizeof(L';'));
219 }
220 }
221 break;
222
223 /* Compute the size of the default search path */
225
226 /* Just add it... it already has a ';' at the end */
228 PathLengthInBytes += BaseDefaultPath.Length;
229 break;
230
231 /* Compute the size of the current app directory */
233 /* Find out where the app name ends, to get only the directory */
234 if (AppName) AppNameEnd = BasepEndOfDirName(AppName);
235
236 /* Check if there was no application name passed in */
237 if (!(AppName) || !(AppNameEnd))
238 {
239 /* Do we have a per-thread CURDIR to use? */
240 if (NtCurrentTeb()->NtTib.SubSystemTib)
241 {
242 /* This means someone added RTL_PERTHREAD_CURDIR */
244 }
245
246 /* We do not. Do we have the LDR_ENTRY for the executable? */
247 if (!BasepExeLdrEntry)
248 {
249 /* We do not. Grab it */
252 NtCurrentPeb()->ImageBaseAddress);
253 }
254
255 /* Now do we have it? */
257 {
258 /* Yes, so read the name out of it */
260 }
261
262 /* Find out where the app name ends, to get only the directory */
263 if (AppName) AppNameEnd = BasepEndOfDirName(AppName);
264 }
265
266 /* So, do we have an application name and its directory? */
267 if ((AppName) && (AppNameEnd))
268 {
269 /* Add the size of the app's directory, plus the separator */
270 PathLengthInBytes += ((AppNameEnd - AppName) * sizeof(WCHAR)) + sizeof(L';');
271 }
272 break;
273
274 default:
275 break;
276 }
277 }
278
279 /* Bam, all done, we now have the final path size */
280 ASSERT(PathLengthInBytes > 0);
281 ASSERT(!(PathLengthInBytes & 1));
282
283 /* Allocate the buffer to hold it */
284 PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLengthInBytes);
285 if (!PathBuffer)
286 {
287 /* Failure path */
289 goto Quickie;
290 }
291
292 /* Now we loop again, this time to copy the data */
293 PathCurrent = PathBuffer;
294 for (Order = PathOrder; *Order != BaseSearchPathInvalid; Order++) {
295 switch (*Order)
296 {
297 /* Add the DLL path */
300 {
301 /* Copy it in the buffer, ASSERT there's enough space */
302 ASSERT((((PathCurrent - PathBuffer + 1) * sizeof(WCHAR)) + BaseDllDirectory.Length) <= PathLengthInBytes);
303 RtlCopyMemory(PathCurrent,
306
307 /* Update the current pointer, add a separator */
308 PathCurrent += (BaseDllDirectory.Length / sizeof(WCHAR));
309 *PathCurrent++ = ';';
310 }
311 break;
312
313 /* Add the current application path */
315 if ((AppName) && (AppNameEnd))
316 {
317 /* Copy it in the buffer, ASSERT there's enough space */
318 ASSERT(((PathCurrent - PathBuffer + 1 + (AppNameEnd - AppName)) * sizeof(WCHAR)) <= PathLengthInBytes);
319 RtlCopyMemory(PathCurrent,
320 AppName,
321 (AppNameEnd - AppName) * sizeof(WCHAR));
322
323 /* Update the current pointer, add a separator */
324 PathCurrent += AppNameEnd - AppName;
325 *PathCurrent++ = ';';
326 }
327 break;
328
329 /* Add the default search path */
331 /* Copy it in the buffer, ASSERT there's enough space */
332 ASSERT((((PathCurrent - PathBuffer) * sizeof(WCHAR)) + BaseDefaultPath.Length) <= PathLengthInBytes);
334
335 /* Update the current pointer. The default path already has a ";" */
336 PathCurrent += (BaseDefaultPath.Length / sizeof(WCHAR));
337 break;
338
339 /* Add the path in the PATH environment variable */
341 if (EnvPath.Length)
342 {
343 /* Copy it in the buffer, ASSERT there's enough space */
344 ASSERT((((PathCurrent - PathBuffer + 1) * sizeof(WCHAR)) + EnvPath.Length) <= PathLengthInBytes);
345 RtlCopyMemory(PathCurrent, EnvPath.Buffer, EnvPath.Length);
346
347 /* Update the current pointer, add a separator */
348 PathCurrent += (EnvPath.Length / sizeof(WCHAR));
349 *PathCurrent++ = ';';
350 }
351 break;
352
353 /* Add the current directory */
355
356 /* Copy it in the buffer, ASSERT there's enough space */
357 ASSERT(((PathCurrent - PathBuffer + 2) * sizeof(WCHAR)) <= PathLengthInBytes);
358 *PathCurrent++ = '.';
359
360 /* Add the path separator */
361 *PathCurrent++ = ';';
362 break;
363
364 default:
365 break;
366 }
367 }
368
369 /* Everything should've perfectly fit in there */
370 ASSERT((PathCurrent - PathBuffer) * sizeof(WCHAR) == PathLengthInBytes);
371 ASSERT(PathCurrent > PathBuffer);
372
373 /* Terminate the whole thing */
374 PathCurrent[-1] = UNICODE_NULL;
375
376Quickie:
377 /* Exit path: free our buffers */
378 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
379 if (PathBuffer)
380 {
381 /* This only gets freed in the failure path, since caller wants it */
382 if (!NT_SUCCESS(Status))
383 {
384 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
385 PathBuffer = NULL;
386 }
387 }
388
389 /* Return the path! */
390 return PathBuffer;
391}
#define NtCurrentPeb()
Definition: FLS.c:22
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
Definition: bufpool.h:45
static CHAR AppName[MAX_PATH]
Definition: dem.c:252
UNICODE_STRING BasePathVariableName
Definition: proc.c:23
UNICODE_STRING BaseDefaultPath
Definition: path.c:21
PWCHAR WINAPI BasepEndOfDirName(IN PWCHAR FileName)
Definition: path.c:89
PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry
Definition: proc.c:25
VOID NTAPI BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry, IN PVOID Context, OUT BOOLEAN *StopEnumeration)
Definition: utils.c:156
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:82
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:72
#define NtCurrentTeb
@ BaseSearchPathDll
Definition: kernel32.h:83
@ BaseSearchPathInvalid
Definition: kernel32.h:82
@ BaseSearchPathApp
Definition: kernel32.h:84
@ BaseSearchPathDefault
Definition: kernel32.h:85
@ BaseSearchPathCurrent
Definition: kernel32.h:87
@ BaseSearchPathEnv
Definition: kernel32.h:86
NTSTATUS NTAPI LdrEnumerateLoadedModules(IN BOOLEAN ReservedFlag, IN PLDR_ENUM_CALLBACK EnumProc, IN PVOID Context)
Definition: ldrapi.c:1120
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI NTSTATUS NTAPI RtlQueryEnvironmentVariable_U(_In_opt_ PWSTR Environment, _In_ PCUNICODE_STRING Name, _Out_ PUNICODE_STRING Value)
#define UNICODE_NULL
#define UNICODE_STRING_MAX_BYTES
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_VARIABLE_NOT_FOUND
Definition: ntstatus.h:492
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by BaseComputeProcessDllPath(), BaseComputeProcessExePath(), and BaseComputeProcessSearchPath().

◆ BasepEndOfDirName()

PWCHAR WINAPI BasepEndOfDirName ( IN PWCHAR  FileName)

Definition at line 89 of file path.c.

90{
91 PWCHAR FileNameEnd, FileNameSeparator;
92
93 /* Find the first slash */
94 FileNameSeparator = wcschr(FileName, OBJ_NAME_PATH_SEPARATOR);
95 if (FileNameSeparator)
96 {
97 /* Find the last one */
98 FileNameEnd = wcsrchr(FileNameSeparator, OBJ_NAME_PATH_SEPARATOR);
99 ASSERT(FileNameEnd);
100
101 /* Handle the case where they are one and the same */
102 if (FileNameEnd == FileNameSeparator) FileNameEnd++;
103 }
104 else
105 {
106 /* No directory was specified */
107 FileNameEnd = NULL;
108 }
109
110 /* Return where the directory ends and the filename starts */
111 return FileNameEnd;
112}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define wcschr
Definition: compat.h:17
#define wcsrchr
Definition: compat.h:16

Referenced by BasepComputeProcessPath().

◆ BasepIsCurDirAllowedForPlainExeNames()

BOOL WINAPI BasepIsCurDirAllowedForPlainExeNames ( VOID  )

Definition at line 781 of file path.c.

782{
784 UNICODE_STRING EmptyString;
785
786 RtlInitEmptyUnicodeString(&EmptyString, NULL, 0);
789 &EmptyString);
791}
UNICODE_STRING NoDefaultCurrentDirectoryInExePath
Definition: path.c:18

Referenced by NeedCurrentDirectoryForExePathA(), and NeedCurrentDirectoryForExePathW().

◆ CheckForSameCurdir()

BOOLEAN WINAPI CheckForSameCurdir ( IN PUNICODE_STRING  DirName)

Definition at line 519 of file path.c.

520{
521 PUNICODE_STRING CurDir;
522 USHORT CurLength;
524 UNICODE_STRING CurDirCopy;
525
526 CurDir = &NtCurrentPeb()->ProcessParameters->CurrentDirectory.DosPath;
527
528 CurLength = CurDir->Length;
529 if (CurDir->Length <= 6)
530 {
531 if (CurLength != DirName->Length) return FALSE;
532 }
533 else
534 {
535 if ((CurLength - 2) != DirName->Length) return FALSE;
536 }
537
539
540 CurDirCopy = *CurDir;
541 if (CurDirCopy.Length > 6) CurDirCopy.Length -= 2;
542
543 Result = 0;
544
545 if (RtlEqualUnicodeString(&CurDirCopy, DirName, TRUE)) Result = TRUE;
546
548
549 return Result;
550}
unsigned char BOOLEAN
_In_ PFCB _In_ PCD_NAME DirName
Definition: cdprocs.h:737
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
unsigned short USHORT
Definition: pedump.c:61
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426

Referenced by SetCurrentDirectoryA(), and SetCurrentDirectoryW().

◆ FindLFNorSFN_U()

BOOL WINAPI FindLFNorSFN_U ( IN PWCHAR  Path,
OUT PWCHAR First,
OUT PWCHAR Last,
IN BOOL  UseShort 
)

Definition at line 682 of file path.c.

686{
687 PWCHAR p;
689 BOOL Found = 0;
690 ASSERT(Path);
691
692 /* Loop while there is something in the path */
693 while (TRUE)
694 {
695 /* Loop within the path skipping slashes */
696 while ((*Path == L'\\') || (*Path == L'/')) Path++;
697
698 /* Make sure there's something after the slashes too! */
699 if (*Path == UNICODE_NULL) break;
700
701 /* Now skip past the file name until we get to the first slash */
702 p = Path + 1;
703 while ((*p) && ((*p != L'\\') && (*p != L'/'))) p++;
704
705 /* Whatever is in between those two is now the file name length */
706 Length = p - Path;
707
708 /*
709 * Check if it is valid
710 * Note that !IsShortName != IsLongName, these two functions simply help
711 * us determine if a conversion is necessary or not.
712 * "Found" really means: "Is a conversion necessary?", hence the "!"
713 */
715 if (Found)
716 {
717 /* It is! did the caller request to know the markers? */
718 if ((First) && (Last))
719 {
720 /* Return them */
721 *First = Path;
722 *Last = p;
723 }
724 break;
725 }
726
727 /* Is there anything else following this sub-path/filename? */
728 if (*p == UNICODE_NULL) break;
729
730 /* Yes, keep going */
731 Path = p + 1;
732 }
733
734 /* Return if anything was found and valid */
735 return Found;
736}
WCHAR First[]
Definition: FormatMessage.c:11
PRTL_UNICODE_STRING_BUFFER Path
return Found
Definition: dirsup.c:1270
BOOL WINAPI IsLongName_U(IN PWCHAR FileName, IN ULONG Length)
Definition: path.c:648
BOOL WINAPI IsShortName_U(IN PWCHAR Name, IN ULONG Length)
Definition: path.c:561
unsigned int BOOL
Definition: ntddk_ex.h:94
GLfloat GLfloat p
Definition: glext.h:8902
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

Referenced by GetLongPathNameW(), and GetShortPathNameW().

◆ GetCurrentDirectoryA()

DWORD WINAPI GetCurrentDirectoryA ( IN DWORD  nBufferLength,
OUT LPSTR  lpBuffer 
)

Definition at line 2146 of file path.c.

2148{
2152 ULONG MaxLength;
2153
2154 StaticString = &NtCurrentTeb()->StaticUnicodeString;
2155
2156 MaxLength = nBufferLength;
2158 {
2159 MaxLength = UNICODE_STRING_MAX_BYTES - 1;
2160 }
2161
2167 if (!NT_SUCCESS(Status))
2168 {
2170 return 0;
2171 }
2172
2173 if (MaxLength <= nBufferLength)
2174 {
2175 return nBufferLength + 1;
2176 }
2177
2178 AnsiString.Buffer = lpBuffer;
2179 AnsiString.MaximumLength = (USHORT)MaxLength;
2181 if (!NT_SUCCESS(Status))
2182 {
2184 return 0;
2185 }
2186
2187 return AnsiString.Length;
2188}
IN PUNICODE_STRING StaticString
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
PRTL_CONVERT_STRINGA BasepUnicodeStringTo8BitString
Definition: utils.c:27
@ AnsiString
Definition: dnslib.h:19
NTSYSAPI ULONG NTAPI RtlGetCurrentDirectory_U(_In_ ULONG MaximumLength, _Out_bytecap_(MaximumLength) PWSTR Buffer)
Definition: path.c:1661
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteSize(_Out_ PULONG MbSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:145
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD nBufferLength
Definition: winbase.h:3060

Referenced by create_cache_file(), create_file(), create_test_files(), delnode_test(), doChild(), DosChangeDirectory(), DosKRNLInitialize(), FD31_WMInitDialog(), full_file_path_name_in_a_CWD(), get_directories(), get_temp_filename(), init(), init_shfo_tests(), LoadModuleWithSymbols(), make_tmp_file(), SheGetDirA(), START_TEST(), Test_AddFontResourceA(), test_binary_import(), test_BindToObject(), test_click_make_new_folder_button(), test_CurrentDirectoryA(), test_dbmerge(), test_define_dos_deviceA(), test_directory(), test_drive_letter_case(), test_embedded_nulls(), test_EnumObjects_and_CompareIDs(), test_extension(), Test_FindFirstFileA(), test_forcecodepage(), test_formatrecord_tables(), test_fullpath(), test_GetAttributesOf(), test_GetVolumeInformationA(), test_GetVolumePathNameA(), test_InitPathA(), test_invalid_functions(), test_listbox_dlgdir(), test_listbox_LB_DIR(), test_LoadImage_working_directory(), test_LocalizedNames(), test_mhtml_protocol_binding(), test_msiexport(), test_MsiGetProductProperty(), test_msiimport(), test_MsiOpenProduct(), test_MsiProvideQualifiedComponentEx(), test_ok(), test_OpenFile(), test_PathNameA(), test_RemoveDirectoryA(), test_SearchPathA(), test_setdir(), test_SetSearchPathMode(), test_SHCreateShellItem(), test_suminfo_import(), test_toplevel_stat(), TestGetCurrentDirectoryA(), testLoadLibraryEx(), TestSetCurrentDirectoryA(), and WINHELP_GetOpenFileName().

◆ GetCurrentDirectoryW()

DWORD WINAPI GetCurrentDirectoryW ( IN DWORD  nBufferLength,
OUT LPWSTR  lpBuffer 
)

Definition at line 2195 of file path.c.

2197{
2198 return RtlGetCurrentDirectory_U(nBufferLength * sizeof(WCHAR), lpBuffer) / sizeof(WCHAR);
2199}

◆ GetDllDirectoryA()

DWORD WINAPI GetDllDirectoryA ( IN DWORD  nBufferLength,
OUT LPSTR  lpBuffer 
)

Definition at line 915 of file path.c.

917{
919 ANSI_STRING AnsiDllDirectory;
921
922 RtlInitEmptyAnsiString(&AnsiDllDirectory, lpBuffer, (USHORT)nBufferLength);
923
925
927 if (Length > nBufferLength)
928 {
931 }
932 else
933 {
934 --Length;
935 Status = BasepUnicodeStringTo8BitString(&AnsiDllDirectory,
937 FALSE);
938 }
939
941
942 if (!NT_SUCCESS(Status))
943 {
945 Length = 0;
947 }
948
949 return Length;
950}
PRTL_COUNT_STRING BasepUnicodeStringTo8BitSize
Definition: utils.c:28
#define ANSI_NULL

Referenced by init_pointers().

◆ GetDllDirectoryW()

DWORD WINAPI GetDllDirectoryW ( IN DWORD  nBufferLength,
OUT LPWSTR  lpBuffer 
)

Definition at line 887 of file path.c.

Referenced by init_pointers().

◆ GetFullPathNameA()

DWORD WINAPI GetFullPathNameA ( IN LPCSTR  lpFileName,
IN DWORD  nBufferLength,
OUT LPSTR  lpBuffer,
OUT LPSTR lpFilePart 
)

Definition at line 993 of file path.c.

997{
1000 ULONG PathSize, FilePartSize;
1002 UNICODE_STRING FileNameString, UniString;
1003 PWCHAR LocalFilePart;
1004 PWCHAR* FilePart;
1005
1006 /* If the caller wants filepart, use a local wide buffer since this is A */
1007 FilePart = lpFilePart != NULL ? &LocalFilePart : NULL;
1008
1009 /* Initialize for Quickie */
1010 FilePartSize = PathSize = 0;
1011 FileNameString.Buffer = NULL;
1012
1013 /* First get our string in Unicode */
1015 if (!NT_SUCCESS(Status)) goto Quickie;
1016
1017 /* Allocate a buffer to hold teh path name */
1018 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
1019 0,
1020 MAX_PATH * sizeof(WCHAR) + sizeof(UNICODE_NULL));
1021 if (!Buffer)
1022 {
1024 goto Quickie;
1025 }
1026
1027 /* Call into RTL to get the full Unicode path name */
1028 PathSize = RtlGetFullPathName_U(FileNameString.Buffer,
1029 MAX_PATH * sizeof(WCHAR),
1030 Buffer,
1031 FilePart);
1032 if (PathSize <= (MAX_PATH * sizeof(WCHAR)))
1033 {
1034 /* The buffer will fit, get the real ANSI string size now */
1035 Status = RtlUnicodeToMultiByteSize(&PathSize, Buffer, PathSize);
1036 if (NT_SUCCESS(Status))
1037 {
1038 /* Now check if the user wanted file part size as well */
1039 if ((PathSize) && (lpFilePart) && (LocalFilePart))
1040 {
1041 /* Yep, so in this case get the length of the file part too */
1042 Status = RtlUnicodeToMultiByteSize(&FilePartSize,
1043 Buffer,
1044 (ULONG)(LocalFilePart - Buffer) *
1045 sizeof(WCHAR));
1046 if (!NT_SUCCESS(Status))
1047 {
1048 /* We failed to do that, so fail the whole call */
1050 PathSize = 0;
1051 }
1052 }
1053 }
1054 }
1055 else
1056 {
1057 /* Reset the path size since the buffer is not large enough */
1058 PathSize = 0;
1059 }
1060
1061 /* Either no path, or local buffer was too small, enter failure code */
1062 if (!PathSize) goto Quickie;
1063
1064 /* If the *caller's* buffer was too small, fail, but add in space for NULL */
1065 if (PathSize >= nBufferLength)
1066 {
1067 PathSize++;
1068 goto Quickie;
1069 }
1070
1071 /* So far so good, initialize a unicode string to convert back to ANSI/OEM */
1072 RtlInitUnicodeString(&UniString, Buffer);
1074 if (!NT_SUCCESS(Status))
1075 {
1076 /* Final conversion failed, fail the call */
1078 PathSize = 0;
1079 }
1080 else
1081 {
1082 /* Conversion worked, now copy the ANSI/OEM buffer into the buffer */
1083 RtlCopyMemory(lpBuffer, AnsiString.Buffer, PathSize + 1);
1085
1086 /* And finally, did the caller request file part information? */
1087 if (lpFilePart)
1088 {
1089 /* Use the size we computed earlier and add it to the buffer */
1090 *lpFilePart = LocalFilePart ? &lpBuffer[FilePartSize] : 0;
1091 }
1092 }
1093
1094Quickie:
1095 /* Cleanup and return the path size */
1096 if (FileNameString.Buffer) RtlFreeUnicodeString(&FileNameString);
1097 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1098 return PathSize;
1099}
#define MAX_PATH
Definition: compat.h:34
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
NTSYSAPI ULONG NTAPI RtlGetFullPathName_U(_In_ PCWSTR FileName, _In_ ULONG Size, _Out_z_bytecap_(Size) PWSTR Buffer, _Out_opt_ PWSTR *ShortName)
Definition: path.c:1987
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ LPCSTR lpFileName
Definition: winbase.h:3058
_In_ LPCSTR _In_opt_ LPCSTR _In_ DWORD _Out_opt_ LPSTR * lpFilePart
Definition: winbase.h:3062

Referenced by Dispatch_Invoke(), DosInt21h(), DosLoadExecutable(), main(), MMIO_Open(), OpenFile(), PathSearchAndQualifyA(), real_path(), set_outfile(), SetupIterateCabinetA(), START_TEST(), test_CommandLine(), test_drive_letter_case(), test_GetFullPathNameA(), test_PathNameA(), test_persiststreaminit(), test_top_level_action(), test_toplevel_stat(), test_ValidPathA(), test_xmldoc(), and test_xmlelem_collection().

◆ GetFullPathNameW()

DWORD WINAPI GetFullPathNameW ( IN LPCWSTR  lpFileName,
IN DWORD  nBufferLength,
OUT LPWSTR  lpBuffer,
OUT LPWSTR lpFilePart 
)

Definition at line 1106 of file path.c.

1110{
1111 /* Call Rtl to do the work */
1113 nBufferLength * sizeof(WCHAR),
1114 lpBuffer,
1115 lpFilePart) / sizeof(WCHAR);
1116}

Referenced by AppendFullPathURL(), BasePushProcessParameters(), CDirectoryWatcher::Create(), create_file(), create_manifest_file(), CreateDirectoryExW(), CreateDirectoryW(), CreateInternetShortcut(), CreateProcessInternalW(), CreateShortcut(), CreateSymbolicLinkW(), CZipCreator::DoAddItem(), CACListISF::Expand(), FILEDLG95_InitControls(), FileLockBytesImpl_Construct(), FileMoniker_CreateFromDisplayName(), filesys_GetAbsolutePathName(), fw_app_put_ProcessImageFileName(), getIconLocationForDrive(), getIconLocationForFolder(), GetTempPathW(), GetVolumePathNameW(), ImageView_Modify(), ImmInstallIMEW(), CZipCreatorImpl::JustDoIt(), MainWnd_OnInstall(), msi_set_original_database_property(), MSSTYLES_OpenThemeFile(), PathSearchAndQualifyW(), PROFILE_Open(), RecycleBin5_RecycleBin5_DeleteFile(), RecycleBinGeneric_RecycleBin_DeleteFile(), resolve_filename(), CShellLink::Save(), SetupCopyOEMInfW(), SetupDiBuildDriverInfoList(), SetupIterateCabinetW(), SetupOpenInfFileW(), SHAddToRecentDocs(), shellex_get_dataobj(), ShellExecCmdLine(), ShellLink_UpdatePath(), SHExplorerParseCmdLine(), SIC_GetIconIndex(), SIC_IconAppend(), StartDocDlgW(), test_createconfigstream(), test_GetAbsolutePathName(), test_GetFullPathNameW(), test_items(), test_namespace(), test_NetFwAuthorizedApplication(), test_PathSearchAndQualify(), TestCommandLine(), WhereDoPattern(), wmain(), wWinMain(), XCOPY_ProcessDestParm(), and XCOPY_ProcessSourceParm().

◆ GetLongPathNameA()

DWORD WINAPI GetLongPathNameA ( IN LPCSTR  lpszShortPath,
OUT LPSTR  lpszLongPath,
IN DWORD  cchBuffer 
)

Definition at line 1671 of file path.c.

1674{
1676 PWCHAR LongPath;
1678 UNICODE_STRING LongPathUni, ShortPathUni;
1679 ANSI_STRING LongPathAnsi;
1680 WCHAR LongPathBuffer[MAX_PATH];
1681
1682 LongPath = NULL;
1683 LongPathAnsi.Buffer = NULL;
1684 ShortPathUni.Buffer = NULL;
1685 Result = 0;
1686
1687 if (!lpszShortPath)
1688 {
1690 return 0;
1691 }
1692
1693 Status = Basep8BitStringToDynamicUnicodeString(&ShortPathUni, lpszShortPath);
1694 if (!NT_SUCCESS(Status)) goto Quickie;
1695
1696 LongPath = LongPathBuffer;
1697
1698 PathLength = GetLongPathNameW(ShortPathUni.Buffer, LongPathBuffer, MAX_PATH);
1699 if (PathLength >= MAX_PATH)
1700 {
1701 LongPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLength * sizeof(WCHAR));
1702 if (!LongPath)
1703 {
1704 PathLength = 0;
1706 }
1707 else
1708 {
1709 PathLength = GetLongPathNameW(ShortPathUni.Buffer, LongPath, PathLength);
1710 }
1711 }
1712
1713 if (!PathLength) goto Quickie;
1714
1715 ShortPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
1716 LongPathUni.Buffer = LongPath;
1717 LongPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
1718
1719 Status = BasepUnicodeStringTo8BitString(&LongPathAnsi, &LongPathUni, TRUE);
1720 if (!NT_SUCCESS(Status))
1721 {
1723 Result = 0;
1724 }
1725
1726 Result = LongPathAnsi.Length;
1727 if ((lpszLongPath) && (cchBuffer > LongPathAnsi.Length))
1728 {
1729 RtlMoveMemory(lpszLongPath, LongPathAnsi.Buffer, LongPathAnsi.Length);
1730 lpszLongPath[Result] = ANSI_NULL;
1731 }
1732 else
1733 {
1734 Result = LongPathAnsi.Length + sizeof(ANSI_NULL);
1735 }
1736
1737Quickie:
1738 if (ShortPathUni.Buffer) RtlFreeUnicodeString(&ShortPathUni);
1739 if (LongPathAnsi.Buffer) RtlFreeAnsiString(&LongPathAnsi);
1740 if ((LongPath) && (LongPath != LongPathBuffer))
1741 {
1742 RtlFreeHeap(RtlGetProcessHeap(), 0, LongPath);
1743 }
1744 return Result;
1745}
static USHORT PathLength
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
static DWORD cchBuffer
Definition: fusion.c:85
DWORD WINAPI GetLongPathNameW(IN LPCWSTR lpszShortPath, OUT LPWSTR lpszLongPath, IN DWORD cchBuffer)
Definition: path.c:1456
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by DoTestEntry(), init_pointers(), init_test(), okChildPath_(), test_GetFinalPathNameByHandleA(), test_PathNameA(), test_SdbGetPermLayerKeys(), and test_SetPermLayer().

◆ GetLongPathNameW()

DWORD WINAPI GetLongPathNameW ( IN LPCWSTR  lpszShortPath,
OUT LPWSTR  lpszLongPath,
IN DWORD  cchBuffer 
)

Definition at line 1456 of file path.c.

1459{
1460 PWCHAR Path, Original, First, Last, Buffer, Src, Dst;
1462 WCHAR LastChar;
1463 HANDLE FindHandle;
1464 ULONG ErrorMode;
1466 WIN32_FIND_DATAW FindFileData;
1467
1468 /* Initialize so Quickie knows there's nothing to do */
1469 Buffer = Original = NULL;
1470 ReturnLength = 0;
1471
1472 /* First check if the input path was obviously NULL */
1473 if (!lpszShortPath)
1474 {
1475 /* Fail the request */
1477 return 0;
1478 }
1479
1480 /* We will be touching removed, removable drives -- don't warn the user */
1482
1483 /* Do a simple check to see if the path exists */
1484 if (GetFileAttributesW(lpszShortPath) == INVALID_FILE_ATTRIBUTES)
1485 {
1486 /* It doesn't, so fail */
1487 ReturnLength = 0;
1488 goto Quickie;
1489 }
1490
1491 /* Now get a pointer to the actual path, skipping indicators */
1492 Path = SkipPathTypeIndicator_U((LPWSTR)lpszShortPath);
1493
1494 /* Is there any path or filename in there? */
1495 if (!(Path) ||
1496 (*Path == UNICODE_NULL) ||
1497 !(FindLFNorSFN_U(Path, &First, &Last, FALSE)))
1498 {
1499 /* There isn't, so the long path is simply the short path */
1500 ReturnLength = wcslen(lpszShortPath);
1501
1502 /* Is there space for it? */
1503 if ((cchBuffer > ReturnLength) && (lpszLongPath))
1504 {
1505 /* Make sure the pointers aren't already the same */
1506 if (lpszLongPath != lpszShortPath)
1507 {
1508 /* They're not -- copy the short path into the long path */
1509 RtlMoveMemory(lpszLongPath,
1510 lpszShortPath,
1511 ReturnLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
1512 }
1513 }
1514 else
1515 {
1516 /* Otherwise, let caller know we need a bigger buffer, include NULL */
1517 ReturnLength++;
1518 }
1519 goto Quickie;
1520 }
1521
1522 /* We are still in the game -- compute the current size */
1523 Length = wcslen(lpszShortPath) + sizeof(ANSI_NULL);
1524 Original = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
1525 if (!Original) goto ErrorQuickie;
1526
1527 /* Make a copy of it */
1528 RtlMoveMemory(Original, lpszShortPath, Length * sizeof(WCHAR));
1529
1530 /* Compute the new first and last markers */
1531 First = &Original[First - lpszShortPath];
1532 Last = &Original[Last - lpszShortPath];
1533
1534 /* Set the current destination pointer for a copy */
1535 Dst = lpszLongPath;
1536
1537 /*
1538 * Windows allows the paths to overlap -- we have to be careful with this and
1539 * see if it's same to do so, and if not, allocate our own internal buffer
1540 * that we'll return at the end.
1541 *
1542 * This is also why we use RtlMoveMemory everywhere. Don't use RtlCopyMemory!
1543 */
1544 if ((cchBuffer) && (lpszLongPath) &&
1545 (((lpszLongPath >= lpszShortPath) && (lpszLongPath < &lpszShortPath[Length])) ||
1546 ((lpszLongPath < lpszShortPath) && (&lpszLongPath[cchBuffer] >= lpszShortPath))))
1547 {
1548 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, cchBuffer * sizeof(WCHAR));
1549 if (!Buffer) goto ErrorQuickie;
1550
1551 /* New destination */
1552 Dst = Buffer;
1553 }
1554
1555 /* Prepare for the loop */
1556 Src = Original;
1557 ReturnLength = 0;
1558 while (TRUE)
1559 {
1560 /* Current delta in the loop */
1561 Length = First - Src;
1562
1563 /* Update the return length by it */
1565
1566 /* Is there a delta? If so, is there space and buffer for it? */
1567 if ((Length) && (cchBuffer > ReturnLength) && (lpszLongPath))
1568 {
1569 RtlMoveMemory(Dst, Src, Length * sizeof(WCHAR));
1570 Dst += Length;
1571 }
1572
1573 /* "Terminate" this portion of the path's substring so we can do a find */
1574 LastChar = *Last;
1575 *Last = UNICODE_NULL;
1576 FindHandle = FindFirstFileW(Original, &FindFileData);
1577 *Last = LastChar;
1578
1579 /* This portion wasn't found, so fail */
1580 if (FindHandle == INVALID_HANDLE_VALUE)
1581 {
1582 ReturnLength = 0;
1583 break;
1584 }
1585
1586 /* Close the find handle */
1587 FindClose(FindHandle);
1588
1589 /* Now check the length of the long name */
1590 Length = wcslen(FindFileData.cFileName);
1591 if (Length)
1592 {
1593 /* This is our new first marker */
1594 First = FindFileData.cFileName;
1595 }
1596 else
1597 {
1598 /* Otherwise, the name is the delta between our current markers */
1599 Length = Last - First;
1600 }
1601
1602 /* Update the return length with the short name length, if any */
1604
1605 /* Once again check for appropriate space and buffer */
1606 if ((cchBuffer > ReturnLength) && (lpszLongPath))
1607 {
1608 /* And do the copy if there is */
1609 RtlMoveMemory(Dst, First, Length * sizeof(WCHAR));
1610 Dst += Length;
1611 }
1612
1613 /* Now update the source pointer */
1614 Src = Last;
1615 if (*Src == UNICODE_NULL) break;
1616
1617 /* Are there more names in there? */
1618 Found = FindLFNorSFN_U(Src, &First, &Last, FALSE);
1619 if (!Found) break;
1620 }
1621
1622 /* The loop is done, is there anything left? */
1623 if (ReturnLength)
1624 {
1625 /* Get the length of the straggling path */
1626 Length = wcslen(Src);
1628
1629 /* Once again check for appropriate space and buffer */
1630 if ((cchBuffer > ReturnLength) && (lpszLongPath))
1631 {
1632 /* And do the copy if there is -- accounting for NULL here */
1633 RtlMoveMemory(Dst, Src, Length * sizeof(WCHAR) + sizeof(UNICODE_NULL));
1634
1635 /* What about our buffer? */
1636 if (Buffer)
1637 {
1638 /* Copy it into the caller's long path */
1639 RtlMoveMemory(lpszLongPath,
1640 Buffer,
1641 ReturnLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
1642 }
1643 }
1644 else
1645 {
1646 /* Buffer is too small, let the caller know, making space for NULL */
1647 ReturnLength++;
1648 }
1649 }
1650
1651 /* We're all done */
1652 goto Quickie;
1653
1654ErrorQuickie:
1655 /* This is the goto for memory failures */
1657
1658Quickie:
1659 /* General function end: free memory, restore error mode, return length */
1660 if (Original) RtlFreeHeap(RtlGetProcessHeap(), 0, Original);
1661 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1662 SetErrorMode(ErrorMode);
1663 return ReturnLength;
1664}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
UINT WINAPI SetErrorMode(IN UINT uMode)
Definition: except.c:749
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI FindLFNorSFN_U(IN PWCHAR Path, OUT PWCHAR *First, OUT PWCHAR *Last, IN BOOL UseShort)
Definition: path.c:682
PWCHAR WINAPI SkipPathTypeIndicator_U(IN LPWSTR Path)
Definition: path.c:740
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define Dst
Definition: mesh.h:153
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define SEM_NOOPENFILEERRORBOX
Definition: rtltypes.h:72
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23

Referenced by ConvertPath(), fw_app_put_ProcessImageFileName(), GetLongPathNameA(), init_pointers(), CDirectoryWatcher::ProcessNotification(), SdbpGetLongPathName(), test_GetFinalPathNameByHandleW(), test_items(), test_namespace(), test_NetFwAuthorizedApplication(), and test_ParseDisplayName().

◆ GetShortPathNameA()

DWORD WINAPI GetShortPathNameA ( IN LPCSTR  lpszLongPath,
OUT LPSTR  lpszShortPath,
IN DWORD  cchBuffer 
)

Definition at line 1752 of file path.c.

1755{
1757 PWCHAR ShortPath;
1759 UNICODE_STRING LongPathUni, ShortPathUni;
1760 ANSI_STRING ShortPathAnsi;
1761 WCHAR ShortPathBuffer[MAX_PATH];
1762
1763 ShortPath = NULL;
1764 ShortPathAnsi.Buffer = NULL;
1765 LongPathUni.Buffer = NULL;
1766 Result = 0;
1767
1768 if (!lpszLongPath)
1769 {
1771 return 0;
1772 }
1773
1774 Status = Basep8BitStringToDynamicUnicodeString(&LongPathUni, lpszLongPath);
1775 if (!NT_SUCCESS(Status)) goto Quickie;
1776
1777 ShortPath = ShortPathBuffer;
1778
1779 PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPathBuffer, MAX_PATH);
1780 if (PathLength >= MAX_PATH)
1781 {
1782 ShortPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathLength * sizeof(WCHAR));
1783 if (!ShortPath)
1784 {
1785 PathLength = 0;
1787 }
1788 else
1789 {
1790 PathLength = GetShortPathNameW(LongPathUni.Buffer, ShortPath, PathLength);
1791 }
1792 }
1793
1794 if (!PathLength) goto Quickie;
1795
1796 LongPathUni.MaximumLength = (USHORT)PathLength * sizeof(WCHAR) + sizeof(UNICODE_NULL);
1797 ShortPathUni.Buffer = ShortPath;
1798 ShortPathUni.Length = (USHORT)PathLength * sizeof(WCHAR);
1799
1800 Status = BasepUnicodeStringTo8BitString(&ShortPathAnsi, &ShortPathUni, TRUE);
1801 if (!NT_SUCCESS(Status))
1802 {
1804 Result = 0;
1805 }
1806
1807 Result = ShortPathAnsi.Length;
1808 if ((lpszShortPath) && (cchBuffer > ShortPathAnsi.Length))
1809 {
1810 RtlMoveMemory(lpszShortPath, ShortPathAnsi.Buffer, ShortPathAnsi.Length);
1811 lpszShortPath[Result] = ANSI_NULL;
1812 }
1813 else
1814 {
1815 Result = ShortPathAnsi.Length + sizeof(ANSI_NULL);
1816 }
1817
1818Quickie:
1819 if (LongPathUni.Buffer) RtlFreeUnicodeString(&LongPathUni);
1820 if (ShortPathAnsi.Buffer) RtlFreeAnsiString(&ShortPathAnsi);
1821 if ((ShortPath) && (ShortPath != ShortPathBuffer))
1822 {
1823 RtlFreeHeap(RtlGetProcessHeap(), 0, ShortPath);
1824 }
1825 return Result;
1826}
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833

Referenced by DosChangeDirectory(), DosKRNLInitialize(), DosLoadExecutable(), full_file_path_name_in_a_CWD(), okChildPath_(), PathGetShortPathA(), START_TEST(), StoreNameInSft(), test_drive_letter_case(), test_filenames(), test_GetLongPathNameA(), test_PathNameA(), test_relative_path(), test_SdbGetPermLayerKeys(), test_ShortPathCase(), and test_ValidPathA().

◆ GetShortPathNameW()

DWORD WINAPI GetShortPathNameW ( IN LPCWSTR  lpszLongPath,
OUT LPWSTR  lpszShortPath,
IN DWORD  cchBuffer 
)

Definition at line 1833 of file path.c.

1836{
1837 PWCHAR Path, Original, First, Last, Buffer, Src, Dst;
1839 WCHAR LastChar;
1840 HANDLE FindHandle;
1841 ULONG ErrorMode;
1843 WIN32_FIND_DATAW FindFileData;
1844
1845 /* Initialize so Quickie knows there's nothing to do */
1846 Buffer = Original = NULL;
1847 ReturnLength = 0;
1848
1849 /* First check if the input path was obviously NULL */
1850 if (!lpszLongPath)
1851 {
1852 /* Fail the request */
1854 return 0;
1855 }
1856
1857 /* We will be touching removed, removable drives -- don't warn the user */
1859
1860 /* Do a simple check to see if the path exists */
1861 if (GetFileAttributesW(lpszLongPath) == INVALID_FILE_ATTRIBUTES)
1862 {
1863 /* Windows checks for an application compatibility flag to allow this */
1864 if (!(NtCurrentPeb()) || !(NtCurrentPeb()->AppCompatFlags.LowPart & GetShortPathNameNT4))
1865 {
1866 /* It doesn't, so fail */
1867 ReturnLength = 0;
1868 goto Quickie;
1869 }
1870 }
1871
1872 /* Now get a pointer to the actual path, skipping indicators */
1873 Path = SkipPathTypeIndicator_U((LPWSTR)lpszLongPath);
1874
1875 /* Is there any path or filename in there? */
1876 if (!(Path) ||
1877 (*Path == UNICODE_NULL) ||
1878 !(FindLFNorSFN_U(Path, &First, &Last, TRUE)))
1879 {
1880 /* There isn't, so the long path is simply the short path */
1881 ReturnLength = wcslen(lpszLongPath);
1882
1883 /* Is there space for it? */
1884 if ((cchBuffer > ReturnLength) && (lpszShortPath))
1885 {
1886 /* Make sure the pointers aren't already the same */
1887 if (lpszLongPath != lpszShortPath)
1888 {
1889 /* They're not -- copy the short path into the long path */
1890 RtlMoveMemory(lpszShortPath,
1891 lpszLongPath,
1892 ReturnLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
1893 }
1894 }
1895 else
1896 {
1897 /* Otherwise, let caller know we need a bigger buffer, include NULL */
1898 ReturnLength++;
1899 }
1900 goto Quickie;
1901 }
1902
1903 /* We are still in the game -- compute the current size */
1904 Length = wcslen(lpszLongPath) + sizeof(ANSI_NULL);
1905 Original = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
1906 if (!Original) goto ErrorQuickie;
1907
1908 /* Make a copy of it */
1909 wcsncpy(Original, lpszLongPath, Length);
1910
1911 /* Compute the new first and last markers */
1912 First = &Original[First - lpszLongPath];
1913 Last = &Original[Last - lpszLongPath];
1914
1915 /* Set the current destination pointer for a copy */
1916 Dst = lpszShortPath;
1917
1918 /*
1919 * Windows allows the paths to overlap -- we have to be careful with this and
1920 * see if it's same to do so, and if not, allocate our own internal buffer
1921 * that we'll return at the end.
1922 *
1923 * This is also why we use RtlMoveMemory everywhere. Don't use RtlCopyMemory!
1924 */
1925 if ((cchBuffer) && (lpszShortPath) &&
1926 (((lpszShortPath >= lpszLongPath) && (lpszShortPath < &lpszLongPath[Length])) ||
1927 ((lpszShortPath < lpszLongPath) && (&lpszShortPath[cchBuffer] >= lpszLongPath))))
1928 {
1929 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, cchBuffer * sizeof(WCHAR));
1930 if (!Buffer) goto ErrorQuickie;
1931
1932 /* New destination */
1933 Dst = Buffer;
1934 }
1935
1936 /* Prepare for the loop */
1937 Src = Original;
1938 ReturnLength = 0;
1939 while (TRUE)
1940 {
1941 /* Current delta in the loop */
1942 Length = First - Src;
1943
1944 /* Update the return length by it */
1946
1947 /* Is there a delta? If so, is there space and buffer for it? */
1948 if ((Length) && (cchBuffer > ReturnLength) && (lpszShortPath))
1949 {
1950 RtlMoveMemory(Dst, Src, Length * sizeof(WCHAR));
1951 Dst += Length;
1952 }
1953
1954 /* "Terminate" this portion of the path's substring so we can do a find */
1955 LastChar = *Last;
1956 *Last = UNICODE_NULL;
1957 FindHandle = FindFirstFileW(Original, &FindFileData);
1958 *Last = LastChar;
1959
1960 /* This portion wasn't found, so fail */
1961 if (FindHandle == INVALID_HANDLE_VALUE)
1962 {
1963 ReturnLength = 0;
1964 break;
1965 }
1966
1967 /* Close the find handle */
1968 FindClose(FindHandle);
1969
1970 /* Now check the length of the short name */
1971 Length = wcslen(FindFileData.cAlternateFileName);
1972 if (Length)
1973 {
1974 /* This is our new first marker */
1975 First = FindFileData.cAlternateFileName;
1976 }
1977 else
1978 {
1979 /* Otherwise, the name is the delta between our current markers */
1980 Length = Last - First;
1981 }
1982
1983 /* Update the return length with the short name length, if any */
1985
1986 /* Once again check for appropriate space and buffer */
1987 if ((cchBuffer > ReturnLength) && (lpszShortPath))
1988 {
1989 /* And do the copy if there is */
1990 RtlMoveMemory(Dst, First, Length * sizeof(WCHAR));
1991 Dst += Length;
1992 }
1993
1994 /* Now update the source pointer */
1995 Src = Last;
1996 if (*Src == UNICODE_NULL) break;
1997
1998 /* Are there more names in there? */
1999 Found = FindLFNorSFN_U(Src, &First, &Last, TRUE);
2000 if (!Found) break;
2001 }
2002
2003 /* The loop is done, is there anything left? */
2004 if (ReturnLength)
2005 {
2006 /* Get the length of the straggling path */
2007 Length = wcslen(Src);
2009
2010 /* Once again check for appropriate space and buffer */
2011 if ((cchBuffer > ReturnLength) && (lpszShortPath))
2012 {
2013 /* And do the copy if there is -- accounting for NULL here */
2014 RtlMoveMemory(Dst, Src, Length * sizeof(WCHAR) + sizeof(UNICODE_NULL));
2015
2016 /* What about our buffer? */
2017 if (Buffer)
2018 {
2019 /* Copy it into the caller's long path */
2020 RtlMoveMemory(lpszShortPath,
2021 Buffer,
2022 ReturnLength * sizeof(WCHAR) + sizeof(UNICODE_NULL));
2023 }
2024 }
2025 else
2026 {
2027 /* Buffer is too small, let the caller know, making space for NULL */
2028 ReturnLength++;
2029 }
2030 }
2031
2032 /* We're all done */
2033 goto Quickie;
2034
2035ErrorQuickie:
2036 /* This is the goto for memory failures */
2038
2039Quickie:
2040 /* General function end: free memory, restore error mode, return length */
2041 if (Original) RtlFreeHeap(RtlGetProcessHeap(), 0, Original);
2042 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
2043 SetErrorMode(ErrorMode);
2044 return ReturnLength;
2045}
@ GetShortPathNameNT4
Definition: pstypes.h:759
_CRTIMP wchar_t *__cdecl wcsncpy(wchar_t *_Dest, const wchar_t *_Source, size_t _Count)

Referenced by BaseCheckVDM(), BaseCreateVDMEnvironment(), cache_containers_init(), deformat_file(), CShellLink::GetPath(), GetShortPathNameA(), PathGetShortPathW(), readdir_copy_shortname(), SetUserEnvironmentVariable(), and test_GetShortPathNameW().

◆ GetSystemDirectoryA()

UINT WINAPI GetSystemDirectoryA ( OUT LPSTR  lpBuffer,
IN UINT  uSize 
)

Definition at line 2283 of file path.c.

2285{
2288 ULONG AnsiLength;
2289
2290 /* Get the correct size of the Unicode Base directory */
2291 Status = RtlUnicodeToMultiByteSize(&AnsiLength,
2294 if (!NT_SUCCESS(Status)) return 0;
2295
2296 if (uSize < AnsiLength) return AnsiLength;
2297
2298 RtlInitEmptyAnsiString(&AnsiString, lpBuffer, uSize);
2299
2302 FALSE);
2303 if (!NT_SUCCESS(Status)) return 0;
2304
2305 return AnsiString.Length;
2306}
UNICODE_STRING BaseWindowsSystemDirectory
Definition: path.c:20

Referenced by check_for_files(), config_init(), copy_dll_file(), create_file_with_version(), DllMain(), DoTestEntries(), LoadCodePageData(), RunShell(), START_TEST(), test_autocreation(), test_BindToObject(), test_CreateDirectoryA(), test_data_cache(), test_dirid(), test_drive_letter_case(), test_find_executable(), test_find_file(), test_GetDiskInfoA(), test_getfolderpath(), test_GetSystemDirectory(), test_GetSystemDirectoryA(), test_info_size(), test_installprops(), test_MkParseDisplayName(), test_MsiGetFileVersion(), test_NtAreMappedFilesTheSame(), test_NtQuerySection(), test_PathUnExpandEnvStrings(), test_RunSetupCommand(), test_SetSearchPathMode(), test_SetupGetTargetPath(), test_SetupPromptForDiskA(), test_SQLInstallDriverEx(), test_SQLInstallTranslatorEx(), testing_status_routine(), testLoadLibraryEx(), testSystemDir(), VerFindFileA(), and WspiapiLoad().

◆ GetSystemDirectoryW()

UINT WINAPI GetSystemDirectoryW ( OUT LPWSTR  lpBuffer,
IN UINT  uSize 
)

Definition at line 2313 of file path.c.

Referenced by _InitializeLocalSpooler(), _SHExpandEnvironmentStrings(), ACTION_ForceReboot(), AllSysInfo(), BaseGetVdmConfigInfo(), BasepIsProcessAllowed(), build_directxfiles_tree(), Control_DoWindow(), CookupNodeId(), create_system_dirid(), CControlPanelEnum::CreateCPanelEnumList(), CryptCATAdminAcquireContext(), custom_start_server(), DoEntry(), DoRegServer(), filesys_GetSpecialFolder(), get_systemdirectory(), get_unknown_dirid(), GetColorDirectoryW(), GetMonitorUIFullName(), GetOwnerModuleFromTagEntry(), GetProcessExecutablePathById(), GetSystemLibraryPath(), Imm32GetSystemLibraryPath(), InitializePrinterDrivers(), install_wine_gecko(), InstallScreenSaverW(), IntGetCodePageEntry(), LayoutList_Create(), load_fusion_dlls(), LoadIMEIcon(), LocalGetPrinterDriverDirectory(), MMSYS_InstallDevice(), nsDirectoryServiceProvider2_GetFiles(), open_file_test(), OpenHostsFile(), PathMakeSystemFolderW(), ProcessSetupInf(), PropDialogHandler(), RetrieveQuote(), run_winemenubuilder(), set_firewall(), set_installer_properties(), SetupGetTargetPathW(), SHGetFolderPathAndSubDirW(), SHLWAPI_PathFindInOtherDirs(), SQLInstallDriverManagerW(), START_TEST(), StartShell(), test_CreateDirectoryW(), test_file_all_name_information(), test_file_name_information(), test_GetFileVersion(), test_GetSpecialFolder(), test_GetSystemDirectoryW(), test_interfaces(), test_PathUnExpandEnvStrings(), test_SearchPathW(), test_SetupPromptForDiskW(), test_SHParseDisplayName(), test_wshshell(), testKeyboardLayouts(), TestRedirection(), TLB_ReadTypeLib(), User32GetImmFileName(), VerFindFileW(), wmain(), write_registry_values(), and wWinMain().

◆ GetSystemWindowsDirectoryA()

UINT WINAPI GetSystemWindowsDirectoryA ( OUT LPSTR  lpBuffer,
IN UINT  uSize 
)

Definition at line 2367 of file path.c.

2369{
2372 ULONG AnsiLength;
2373
2374 /* Get the correct size of the Unicode Base directory */
2375 Status = RtlUnicodeToMultiByteSize(&AnsiLength,
2378 if (!NT_SUCCESS(Status)) return 0;
2379
2380 if (uSize < AnsiLength) return AnsiLength;
2381
2382 RtlInitEmptyAnsiString(&AnsiString, lpBuffer, uSize);
2383
2386 FALSE);
2387 if (!NT_SUCCESS(Status)) return 0;
2388
2389 return AnsiString.Length;
2390}
UNICODE_STRING BaseWindowsDirectory
Definition: path.c:20

Referenced by GetWindowsDirectoryA(), test_DefineDosDeviceA(), and test_QueryDosDeviceA().

◆ GetSystemWindowsDirectoryW()

◆ GetSystemWow64DirectoryA()

UINT WINAPI GetSystemWow64DirectoryA ( OUT LPSTR  lpBuffer,
IN UINT  uSize 
)

Definition at line 2438 of file path.c.

2440{
2441#ifdef _WIN64
2443 return 0;
2444#else
2446 return 0;
2447#endif
2448}
#define UNIMPLEMENTED
Definition: debug.h:115
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102

Referenced by test_installprops().

◆ GetSystemWow64DirectoryW()

UINT WINAPI GetSystemWow64DirectoryW ( OUT LPWSTR  lpBuffer,
IN UINT  uSize 
)

Definition at line 2421 of file path.c.

2423{
2424#ifdef _WIN64
2426 return 0;
2427#else
2429 return 0;
2430#endif
2431}

Referenced by custom_start_server(), set_installer_properties(), SHGetFolderPathAndSubDirW(), and test_SHParseDisplayName().

◆ GetTempPathA()

DWORD WINAPI GetTempPathA ( IN DWORD  nBufferLength,
OUT LPSTR  lpBuffer 
)

Definition at line 2054 of file path.c.

2056{
2057 WCHAR BufferW[MAX_PATH];
2058 DWORD ret;
2059
2060 ret = GetTempPathW(MAX_PATH, BufferW);
2061
2062 if (!ret) return 0;
2063
2064 if (ret > MAX_PATH)
2065 {
2067 return 0;
2068 }
2069
2070 return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
2071}
DWORD FilenameW2A_FitOrFail(LPSTR DestA, INT destLen, LPCWSTR SourceW, INT sourceLen)
Definition: fileutils.c:98
DWORD WINAPI GetTempPathW(IN DWORD count, OUT LPWSTR path)
Definition: path.c:2080
unsigned long DWORD
Definition: ntddk_ex.h:95
int ret
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263

Referenced by append_file_test(), copy_dll_file(), create_avi_file(), create_bitmap(), create_file(), create_temp_file(), create_test_dll(), create_test_dll_sections(), create_test_file(), delete_manifest_file(), find_tempfile(), get_file_name(), init_test(), prepare_and_run_test(), print_something(), START_TEST(), test___getmainargs(), test___getmainargs_parent(), test_actctx_classes(), test_amh_corruption(), test_ash1_corruption(), test_ash1_corruption2(), test_comctl32_class(), test_CopyFileA(), test_CopyFileEx(), test_CopyMetaFile(), test_CreateActCtx(), test_CreateDirectoryA(), test_CreateFile(), test_CreateFileA(), test_CreateFileMapping_protection(), test_CreateScalableFontResource(), test_default_data(), test_deferred_action(), test_DeleteFileA(), test_domdoc(), test_drive_letter_case(), test_DuplicateHandle(), test_ExitProcess(), test_ExtractIcon(), test_ffcn_directory_overlap(), test_ffcnMultipleThreads(), test_fgetwc_locale(), test_fgetwc_unicode(), test_file_access(), test_file_disposition_information(), test_file_security(), test_filemap_security(), test_filemodeT(), test_FileSecurity(), test_find_file(), test_FindFirstChangeNotification(), test_FindFirstFileA(), test_flush_buffers_file(), test_fputwc(), test_fullpath(), test_get_inf_class(), test_GetFileInformationByHandleEx(), test_GetFinalPathNameByHandleA(), test_GetLongPathNameA(), test_GetMappedFileName(), test_GetTempPathA(), test_GetVolumeNameForVolumeMountPointA(), test_import_resolution(), test_InitPathA(), test_invalid_callbackA(), test_invalid_parametersA(), test_iocp_callback(), test_listbox_LB_DIR(), test_load(), test_load_save(), test_LoadImage_working_directory(), test_LoadLibraryEx_search_flags(), test_mapping(), test_MoveFileA(), test_NtQueryDirectoryFile(), test_NtQueryDirectoryFile_case(), test_offset_in_overlapped_structure(), test_OleLoadPicturePath(), test_OpenFileById(), test_PlaySound(), test_profile_directory_readonly(), test_publish(), test_publish_product(), test_query_object(), test_query_recyclebin(), test_read_write(), test_register_product(), test_relative_path(), test_RemoveDirectoryA(), test_ReplaceFileA(), test_ResolveDelayLoadedAPI(), test_SdbGetPermLayerKeys(), test_searchenv(), test_SearchPathA(), test_section_access(), test_SetFileInformationByHandle(), test_SetFileValidData(), test_SetPermLayer(), test_SetSearchPathMode(), test_SetupAddInstallSectionToDiskSpaceListA(), test_SetupAddSectionToDiskSpaceListA(), test_SetupDecompressOrCopyFile(), test_SetupGetFileCompressionInfo(), test_SetupGetFileCompressionInfoEx(), test_SHCreateStreamOnFileA(), test_SHCreateStreamOnFileEx(), test_SHCreateStreamOnFileW(), test_Sign_Media(), test_simple_enumerationA(), test_SIPRetrieveSubjectGUID(), test_toplevel_stat(), test_TransformWithLoadingLocalFile(), test_WriteFileGather(), test_WritePrivateProfileString(), tmpdir(), write_manifest(), and write_tmp_file().

◆ GetTempPathW()

DWORD WINAPI GetTempPathW ( IN DWORD  count,
OUT LPWSTR  path 
)

Definition at line 2080 of file path.c.

2082{
2083 static const WCHAR tmp[] = { 'T', 'M', 'P', 0 };
2084 static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
2085 static const WCHAR userprofile[] = { 'U','S','E','R','P','R','O','F','I','L','E',0 };
2086 WCHAR tmp_path[MAX_PATH];
2087 WCHAR full_tmp_path[MAX_PATH];
2088 UINT ret;
2089
2090 DPRINT("%u,%p\n", count, path);
2091
2092 if (!(ret = GetEnvironmentVariableW( tmp, tmp_path, MAX_PATH )) &&
2093 !(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )) &&
2094 !(ret = GetEnvironmentVariableW( userprofile, tmp_path, MAX_PATH )) &&
2095 !(ret = GetWindowsDirectoryW( tmp_path, MAX_PATH )))
2096 {
2097 return 0;
2098 }
2099
2100 if (ret > MAX_PATH)
2101 {
2103 return 0;
2104 }
2105
2106 ret = GetFullPathNameW(tmp_path, MAX_PATH, full_tmp_path, NULL);
2107 if (!ret) return 0;
2108
2109 if (ret > MAX_PATH - 2)
2110 {
2112 return 0;
2113 }
2114
2115 if (full_tmp_path[ret-1] != '\\')
2116 {
2117 full_tmp_path[ret++] = '\\';
2118 full_tmp_path[ret] = '\0';
2119 }
2120
2121 ret++; /* add space for terminating 0 */
2122
2123 if (count >= ret)
2124 {
2125 lstrcpynW(path, full_tmp_path, count);
2126 /* the remaining buffer must be zeroed up to 32766 bytes in XP or 32767
2127 * bytes after it, we will assume the > XP behavior for now */
2128 memset(path + ret, 0, (min(count, 32767) - ret) * sizeof(WCHAR));
2129 ret--; /* return length without 0 */
2130 }
2131 else if (count)
2132 {
2133 /* the buffer must be cleared if contents will not fit */
2134 memset(path, 0, count * sizeof(WCHAR));
2135 }
2136
2137 DPRINT("GetTempPathW returning %u, %S\n", ret, path);
2138 return ret;
2139}
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define lstrcpynW
Definition: compat.h:738
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
static calc_node_t temp
Definition: rpn_ieee.c:38
#define memset(x, y, z)
Definition: compat.h:39

Referenced by create_file(), create_manifest_file(), create_storagefile(), create_temp_dir(), create_temp_file(), create_testfontfile(), create_tmp_file(), delete_file_test(), do_file_copyW(), DoEntry(), download_proc(), extract_cabinet_file(), extract_resource(), ExtractTTFFile(), filesys_GetSpecialFolder(), get_temp_filepath(), get_temp_ini_path(), get_temp_path(), GetTempPathA(), init_paths(), install_cab_file(), load_resource(), msi_create_temp_file(), OLECONVERT_GetOLE20FromOLE10(), OLECONVERT_WriteOLE20ToBuffer(), open_file_test(), processFile(), save_profile(), set_installer_properties(), START_TEST(), test_AddDllDirectory(), test_AtlAxCreateControl(), test_ax_win(), test_CopyFile2(), test_CopyFileW(), test_create(), test_CreateDirectoryW(), test_CreateFile2(), test_CreateFileW(), test_Data(), test_DeleteFileW(), Test_EmptyFile(), test_ExtractIcon(), test_ffcn(), test_file_link_information(), test_file_rename_information(), test_filesourcefilter(), test_GetFinalPathNameByHandleW(), test_GetLongPathNameW(), test_GetShortPathNameW(), test_GetSpecialFolder(), test_GetTempPathW(), test_int_widths(), test_invalid_callbackW(), test_invalid_parametersW(), test_items(), test_knownFolders(), test_LoadIconWithScaleDown(), test_MatchApplications(), test_MatchApplicationsEx(), test_MoveFileW(), test_MultipleFiles(), test_namespace(), test_NtCreateFile(), test_ntncdf(), test_ntncdf_async(), test_ParseDisplayName(), test_ParseName(), test_PathYetAnotherMakeUniqueName(), Test_RawSize(), test_readdirectorychanges(), test_readdirectorychanges_cr(), test_readdirectorychanges_filedir(), test_readdirectorychanges_null(), test_readonly(), test_RemoveDirectoryW(), test_ReplaceFileW(), Test_SectionContents(), test_SHCreateStreamOnFileEx_CopyTo(), test_ShellFolderViewDual(), test_SHGetSetFolderCustomSettings(), test_simple_enumerationW(), test_TagRef(), Test_Truncate(), test_Verbs(), test_wshshell(), unpack_avi_file(), wmain(), and write_raw_resources().

◆ GetWindowsDirectoryA()

UINT WINAPI GetWindowsDirectoryA ( OUT LPSTR  lpBuffer,
IN UINT  uSize 
)

◆ GetWindowsDirectoryW()

UINT WINAPI GetWindowsDirectoryW ( OUT LPWSTR  lpBuffer,
IN UINT  uSize 
)

Definition at line 2352 of file path.c.

2354{
2355 /* Is this a TS installation? */
2357
2358 /* Otherwise, call the System API */
2359 return GetSystemWindowsDirectoryW(lpBuffer, uSize);
2360}
PVOID gpTermsrvGetWindowsDirectoryW
Definition: path.c:24
UINT WINAPI GetSystemWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2397

Referenced by _SHRegisterFolders(), AddDelBackupEntryW(), AllSysInfo(), build_sxs_path(), build_systeminfo_tree(), CConfiguration::CConfiguration(), create_file_test(), create_system_dirid(), CWineTest::CWineTest(), DoEntry(), EditTypeDlg_OnChangeIcon(), File_RetrieveEncodedObjectW(), filesys_GetSpecialFolder(), FixupServiceBinaryPath(), GdiAddFontResourceW(), get_assembly_directory(), get_fusion_filename(), get_mono_path(), get_working_dir(), GetCachePath(), GetSystemDrive(), GetSystemFontDirectory(), GetTempPathW(), GetVersionFromFileExW(), InitializeFreeLDRDialog(), InitializeSetupActionLog(), InitializeSystemDialog(), InstallInfSections(), InstallReactOS(), IsLFNDriveW(), LoadSoundFiles(), MAIN_LoadSettings(), MainWnd_OnInstall(), MMSYS_InstallDevice(), msi_create_empty_local_file(), MsiCreateAndVerifyInstallerDirectory(), MsiEnumComponentCostsW(), open_file_test(), PathMakeSystemFolderW(), PathQualifyExW(), ProcessStartupItems(), PROFILE_Open(), resolve_filename(), RunLiveCD(), ScanForInfFile(), search_for_inf(), SetUnrelatedDirectory(), SetupCopyOEMInfW(), SetupOpenInfFileW(), SetupOpenLog(), SetupOpenMasterInf(), SetupUninstallOEMInfW(), SHExplorerParseCmdLine(), SHGetFolderPathAndSubDirW(), SHLWAPI_PathFindInOtherDirs(), START_TEST(), test_AddDllDirectory(), test_directory_filename(), test_GetFolder(), test_GetSpecialFolder(), test_GetWindowsDirectoryW(), test_knownFolders(), Test_NtGdiAddFontResourceW(), test_query_attribute_information_file(), test_query_volume_information_file(), test_SearchPathW(), test_SHParseDisplayName(), VerFindFileW(), WlxStartApplication(), and wmain().

◆ IsLongName_U()

BOOL WINAPI IsLongName_U ( IN PWCHAR  FileName,
IN ULONG  Length 
)

Definition at line 648 of file path.c.

650{
651 BOOLEAN HasExtension;
652 ULONG i, Dots;
653
654 /* More than 8.3, any combination of dots, and NULL names are all long */
655 if (!(Length) || (Length > 12) || (*FileName == L'.')) return TRUE;
656
657 /* Otherwise, initialize our scanning loop */
658 HasExtension = FALSE;
659 for (i = 0, Dots = Length - 1; i < Length; i++, Dots--)
660 {
661 /* Check if this could be an extension */
662 if (FileName[i] == L'.')
663 {
664 /* Unlike the short case, we WANT more than one extension, or a long one */
665 if ((HasExtension) || (Dots > 3))
666 {
667 return TRUE;
668 }
669 HasExtension = TRUE;
670 }
671
672 /* Check if this would violate the "8" in 8.3, ie. 9.2 */
673 if ((i >= 8) && (!HasExtension)) return TRUE;
674 }
675
676 /* The name *seems* to conform to 8.3 */
677 return FALSE;
678}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by FindLFNorSFN_U().

◆ IsShortName_U()

BOOL WINAPI IsShortName_U ( IN PWCHAR  Name,
IN ULONG  Length 
)

Definition at line 561 of file path.c.

563{
564 BOOLEAN HasExtension;
565 UCHAR c;
568 ANSI_STRING AnsiName;
569 ULONG i, Dots;
571 ASSERT(Name);
572
573 /* What do you think 8.3 means? */
574 if (Length > 12) return FALSE;
575
576 /* Sure, any empty name is a short name */
577 if (!Length) return TRUE;
578
579 /* This could be . or .. or something else */
580 if (*Name == L'.')
581 {
582 /* Which one is it */
583 if ((Length == 1) || ((Length == 2) && *(Name + 1) == L'.'))
584 {
585 /* . or .., this is good */
586 return TRUE;
587 }
588
589 /* Some other bizare dot-based name, not good */
590 return FALSE;
591 }
592
593 /* Initialize our two strings */
594 RtlInitEmptyAnsiString(&AnsiName, AnsiBuffer, MAX_PATH);
595 RtlInitEmptyUnicodeString(&UnicodeName, Name, (USHORT)Length * sizeof(WCHAR));
596 UnicodeName.Length = UnicodeName.MaximumLength;
597
598 /* Now do the conversion */
600 if (!NT_SUCCESS(Status)) return FALSE;
601
602 /* Now we loop the name */
603 HasExtension = FALSE;
604 for (i = 0, Dots = Length - 1; i < AnsiName.Length; i++, Dots--)
605 {
606 /* Read the current byte */
607 c = AnsiName.Buffer[i];
608
609 /* Is it DBCS? */
610 if (IsDBCSLeadByte(c))
611 {
612 /* If we're near the end of the string, we can't allow a DBCS */
613 if ((!(HasExtension) && (i >= 7)) || (i == AnsiName.Length - 1))
614 {
615 return FALSE;
616 }
617
618 /* Otherwise we skip over it */
619 continue;
620 }
621
622 /* Check for illegal characters */
623 if ((c > 0x7F) || (IllegalMask[c / 32] & (1 << (c % 32))))
624 {
625 return FALSE;
626 }
627
628 /* Check if this is perhaps an extension? */
629 if (c == '.')
630 {
631 /* Unless the extension is too large or there's more than one */
632 if ((HasExtension) || (Dots > 3)) return FALSE;
633
634 /* This looks like an extension */
635 HasExtension = TRUE;
636 }
637
638 /* 8.3 length was validated, but now we must guard against 9.2 or similar */
639 if ((i >= 8) && !(HasExtension)) return FALSE;
640 }
641
642 /* You survived the loop, this is a good short name */
643 return TRUE;
644}
CHAR AnsiBuffer[1024]
Definition: debug.c:15
DWORD IllegalMask[4]
Definition: path.c:28
BOOL WINAPI IsDBCSLeadByte(BYTE TestByte)
Definition: nls.c:2359
IN PDCB IN POEM_STRING IN PUNICODE_STRING UnicodeName
Definition: fatprocs.h:1305
const GLubyte * c
Definition: glext.h:8905
#define c
Definition: ke_i.h:80
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by FindLFNorSFN_U().

◆ NeedCurrentDirectoryForExePathA()

BOOL WINAPI NeedCurrentDirectoryForExePathA ( IN LPCSTR  ExeName)

Definition at line 969 of file path.c.

970{
971 if (strchr(ExeName, '\\')) return TRUE;
972
974}
WCHAR * ExeName
char * strchr(const char *String, int ch)
Definition: utclib.c:501
BOOL WINAPI BasepIsCurDirAllowedForPlainExeNames(VOID)
Definition: path.c:781

Referenced by init_pointers().

◆ NeedCurrentDirectoryForExePathW()

BOOL WINAPI NeedCurrentDirectoryForExePathW ( IN LPCWSTR  ExeName)

Definition at line 957 of file path.c.

958{
959 if (wcschr(ExeName, L'\\')) return TRUE;
960
962}

Referenced by BaseComputeProcessExePath(), and init_pointers().

◆ SearchPathA()

DWORD WINAPI SearchPathA ( IN LPCSTR lpPath  OPTIONAL,
IN LPCSTR  lpFileName,
IN LPCSTR lpExtension  OPTIONAL,
IN DWORD  nBufferLength,
OUT LPSTR  lpBuffer,
OUT LPSTR *lpFilePart  OPTIONAL 
)

Definition at line 1123 of file path.c.

1129{
1130 PUNICODE_STRING FileNameString;
1131 UNICODE_STRING PathString, ExtensionString;
1133 ULONG PathSize, FilePartSize, AnsiLength;
1134 PWCHAR LocalFilePart, Buffer;
1135 PWCHAR* FilePart;
1136
1137 /* If the caller wants filepart, use a local wide buffer since this is A */
1138 FilePart = lpFilePart != NULL ? &LocalFilePart : NULL;
1139
1140 /* Initialize stuff for Quickie */
1141 PathSize = 0;
1142 Buffer = NULL;
1143 ExtensionString.Buffer = PathString.Buffer = NULL;
1144
1145 /* Get the UNICODE_STRING file name */
1147 if (!FileNameString) return 0;
1148
1149 /* Did the caller specify an extension */
1150 if (lpExtension)
1151 {
1152 /* Yup, convert it into UNICODE_STRING */
1154 lpExtension);
1155 if (!NT_SUCCESS(Status)) goto Quickie;
1156 }
1157
1158 /* Did the caller specify a path */
1159 if (lpPath)
1160 {
1161 /* Yup, convert it into UNICODE_STRING */
1162 Status = Basep8BitStringToDynamicUnicodeString(&PathString, lpPath);
1163 if (!NT_SUCCESS(Status)) goto Quickie;
1164 }
1165
1166 /* Allocate our output buffer */
1167 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nBufferLength * sizeof(WCHAR));
1168 if (!Buffer)
1169 {
1170 /* It failed, bail out */
1172 goto Quickie;
1173 }
1174
1175 /* Now run the Wide search with the input buffer lengths */
1176 PathSize = SearchPathW(PathString.Buffer,
1177 FileNameString->Buffer,
1178 ExtensionString.Buffer,
1180 Buffer,
1181 FilePart);
1182 if (PathSize <= nBufferLength)
1183 {
1184 /* It fits, but is it empty? If so, bail out */
1185 if (!PathSize) goto Quickie;
1186
1187 /* The length above is inexact, we need it in ANSI */
1188 Status = RtlUnicodeToMultiByteSize(&AnsiLength, Buffer, PathSize * sizeof(WCHAR));
1189 if (!NT_SUCCESS(Status))
1190 {
1191 /* Conversion failed, fail the call */
1192 PathSize = 0;
1194 goto Quickie;
1195 }
1196
1197 /* If the correct ANSI size is too big, return required length plus a NULL */
1198 if (AnsiLength >= nBufferLength)
1199 {
1200 PathSize = AnsiLength + 1;
1201 goto Quickie;
1202 }
1203
1204 /* Now apply the final conversion to ANSI */
1206 nBufferLength - 1,
1207 &AnsiLength,
1208 Buffer,
1209 PathSize * sizeof(WCHAR));
1210 if (!NT_SUCCESS(Status))
1211 {
1212 /* Conversion failed, fail the whole call */
1213 PathSize = 0;
1215 goto Quickie;
1216 }
1217
1218 /* NULL-terminate and return the real ANSI length */
1219 lpBuffer[AnsiLength] = ANSI_NULL;
1220 PathSize = AnsiLength;
1221
1222 /* Now check if the user wanted file part size as well */
1223 if (lpFilePart)
1224 {
1225 /* If we didn't get a file part, clear the caller's */
1226 if (!LocalFilePart)
1227 {
1228 *lpFilePart = NULL;
1229 }
1230 else
1231 {
1232 /* Yep, so in this case get the length of the file part too */
1233 Status = RtlUnicodeToMultiByteSize(&FilePartSize,
1234 Buffer,
1235 (ULONG)(LocalFilePart - Buffer) *
1236 sizeof(WCHAR));
1237 if (!NT_SUCCESS(Status))
1238 {
1239 /* We failed to do that, so fail the whole call */
1241 PathSize = 0;
1242 }
1243
1244 /* Return the file part buffer */
1245 *lpFilePart = lpBuffer + FilePartSize;
1246 }
1247 }
1248 }
1249 else
1250 {
1251 /* Our initial buffer guess was too small, allocate a bigger one */
1252 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1253 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, PathSize * sizeof(WCHAR));
1254 if (!Buffer)
1255 {
1256 /* Out of memory, fail everything */
1258 goto Quickie;
1259 }
1260
1261 /* Do the search again -- it will fail, we just want the path size */
1262 PathSize = SearchPathW(PathString.Buffer,
1263 FileNameString->Buffer,
1264 ExtensionString.Buffer,
1265 PathSize,
1266 Buffer,
1267 FilePart);
1268 if (!PathSize) goto Quickie;
1269
1270 /* Convert it to a correct size */
1271 Status = RtlUnicodeToMultiByteSize(&PathSize, Buffer, PathSize * sizeof(WCHAR));
1272 if (NT_SUCCESS(Status))
1273 {
1274 /* Make space for the NULL-char */
1275 PathSize++;
1276 }
1277 else
1278 {
1279 /* Conversion failed for some reason, fail the call */
1281 PathSize = 0;
1282 }
1283 }
1284
1285Quickie:
1286 /* Cleanup/complete path */
1287 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1288 if (ExtensionString.Buffer) RtlFreeUnicodeString(&ExtensionString);
1289 if (PathString.Buffer) RtlFreeUnicodeString(&PathString);
1290 return PathSize;
1291}
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
_Use_decl_annotations_ NTSTATUS NTAPI RtlUnicodeToMultiByteN(_Out_ PCHAR MbString, _In_ ULONG MbSize, _Out_opt_ PULONG ResultSize, _In_ PCWCH UnicodeString, _In_ ULONG UnicodeSize)
Definition: nlsboot.c:107
_In_ LPCSTR _In_opt_ LPCSTR lpExtension
Definition: winbase.h:3059

Referenced by BindImageEx(), FindDebugInfoFile(), FindExecutableImageEx(), init_pointers(), LoadModule(), MapAndLoad(), PathSearchAndQualifyA(), test_get_file_info(), test_load_save(), test_SetSearchPathMode(), and WINHELP_LookupHelpFile().

◆ SearchPathW()

DWORD WINAPI SearchPathW ( IN LPCWSTR lpPath  OPTIONAL,
IN LPCWSTR  lpFileName,
IN LPCWSTR lpExtension  OPTIONAL,
IN DWORD  nBufferLength,
OUT LPWSTR  lpBuffer,
OUT LPWSTR *lpFilePart  OPTIONAL 
)

Definition at line 1298 of file path.c.

1304{
1305 UNICODE_STRING FileNameString, ExtensionString, PathString, CallerBuffer;
1306 ULONG Flags;
1307 SIZE_T LengthNeeded, FilePartSize;
1309 DWORD Result = 0;
1310
1311 /* Default flags for RtlDosSearchPath_Ustr */
1312 Flags = 6;
1313
1314 /* Clear file part in case we fail */
1315 if (lpFilePart) *lpFilePart = NULL;
1316
1317 /* Initialize path buffer for free later */
1318 PathString.Buffer = NULL;
1319
1320 /* Convert filename to a unicode string and eliminate trailing spaces */
1321 RtlInitUnicodeString(&FileNameString, lpFileName);
1322 while ((FileNameString.Length >= sizeof(WCHAR)) &&
1323 (FileNameString.Buffer[(FileNameString.Length / sizeof(WCHAR)) - 1] == L' '))
1324 {
1325 FileNameString.Length -= sizeof(WCHAR);
1326 }
1327
1328 /* Was it all just spaces? */
1329 if (!FileNameString.Length)
1330 {
1331 /* Fail out */
1333 goto Quickie;
1334 }
1335
1336 /* Convert extension to a unicode string */
1337 RtlInitUnicodeString(&ExtensionString, lpExtension);
1338
1339 /* Check if the user sent a path */
1340 if (lpPath)
1341 {
1342 /* Convert it to a unicode string too */
1343 Status = RtlInitUnicodeStringEx(&PathString, lpPath);
1344 if (NT_ERROR(Status))
1345 {
1346 /* Fail if it was too long */
1348 goto Quickie;
1349 }
1350 }
1351 else
1352 {
1353 /* A path wasn't sent, so compute it ourselves */
1354 PathString.Buffer = BaseComputeProcessSearchPath();
1355 if (!PathString.Buffer)
1356 {
1357 /* Fail if we couldn't compute it */
1359 goto Quickie;
1360 }
1361
1362 /* See how big the computed path is */
1363 LengthNeeded = lstrlenW(PathString.Buffer);
1365 {
1366 /* Fail if it's too long */
1368 goto Quickie;
1369 }
1370
1371 /* Set the path size now that we have it */
1372 PathString.MaximumLength = PathString.Length = (USHORT)LengthNeeded * sizeof(WCHAR);
1373
1374 /* Request SxS isolation from RtlDosSearchPath_Ustr */
1375 Flags |= 1;
1376 }
1377
1378 /* Create the string that describes the output buffer from the caller */
1379 CallerBuffer.Length = 0;
1380 CallerBuffer.Buffer = lpBuffer;
1381
1382 /* How much space does the caller have? */
1384 {
1385 /* Add it into the string */
1386 CallerBuffer.MaximumLength = (USHORT)nBufferLength * sizeof(WCHAR);
1387 }
1388 else
1389 {
1390 /* Caller wants too much, limit it to the maximum length of a string */
1392 }
1393
1394 /* Call Rtl to do the work */
1396 &PathString,
1397 &FileNameString,
1398 &ExtensionString,
1399 &CallerBuffer,
1400 NULL,
1401 NULL,
1402 &FilePartSize,
1403 &LengthNeeded);
1404 if (NT_ERROR(Status))
1405 {
1406 /* Check for unusual status codes */
1408 {
1409 /* Print them out since maybe an app needs fixing */
1410 DbgPrint("%s on file %wZ failed; NTSTATUS = %08lx\n",
1412 &FileNameString,
1413 Status);
1414 DbgPrint(" Path = %wZ\n", &PathString);
1415 }
1416
1417 /* Check if the failure was due to a small buffer */
1419 {
1420 /* Check if the length was actually too big for Rtl to work with */
1421 Result = LengthNeeded / sizeof(WCHAR);
1423 }
1424 else
1425 {
1426 /* Some other error, set the error code */
1428 }
1429 }
1430 else
1431 {
1432 /* It worked! Write the file part now */
1433 if (lpFilePart) *lpFilePart = &lpBuffer[FilePartSize];
1434
1435 /* Convert the final result length */
1436 Result = CallerBuffer.Length / sizeof(WCHAR);
1437 }
1438
1439Quickie:
1440 /* Check if there was a dynamic path string to free */
1441 if ((PathString.Buffer != lpPath) && (PathString.Buffer))
1442 {
1443 /* And free it */
1444 RtlFreeHeap(RtlGetProcessHeap(), 0, PathString.Buffer);
1445 }
1446
1447 /* Return the final result length */
1448 return Result;
1449}
#define lstrlenW
Definition: compat.h:750
LPWSTR WINAPI BaseComputeProcessSearchPath(VOID)
Definition: path.c:395
#define __FUNCTION__
Definition: types.h:112
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION _In_ ULONG _Out_opt_ PULONG LengthNeeded
Definition: fltkernel.h:1343
#define DbgPrint
Definition: hal.h:12
NTSYSAPI NTSTATUS WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING, PCWSTR)
NTSYSAPI NTSTATUS NTAPI RtlDosSearchPath_Ustr(_In_ ULONG Flags, _In_ PUNICODE_STRING PathString, _In_ PUNICODE_STRING FileNameString, _In_ PUNICODE_STRING ExtensionString, _In_ PUNICODE_STRING CallerBuffer, _Inout_opt_ PUNICODE_STRING DynamicString, _Out_opt_ PUNICODE_STRING *FullNameOut, _Out_opt_ PSIZE_T FilePartSize, _Out_opt_ PSIZE_T LengthNeeded)
#define UNICODE_STRING_MAX_CHARS
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define NT_ERROR(Status)
Definition: umtypes.h:106
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by _tWinMain(), BasepLoadLibraryAsDatafile(), CreateProcessInternalW(), dde_connect(), execute_command(), FindExecutableImageExW(), GdiAddFontResourceW(), get_mmioFromFile(), get_object_dll_path(), CQueryAssociations::GetExecutable(), ICO_ExtractIconExW(), init_pointers(), MSTASK_ITask_SetApplicationName(), OpenFile(), path_resolve_name(), PathSearchAndQualifyW(), PerformRegAction(), query_typelib_path(), res_sec_url_cmp(), ResProtocolInfo_ParseUrl(), SearchPathA(), SHELL_ArgifyW(), SHELL_FindExecutable(), ShellExecCmdLine(), test_PathSearchAndQualify(), TLB_ReadTypeLib(), and wmain().

◆ SetCurrentDirectoryA()

BOOL WINAPI SetCurrentDirectoryA ( IN LPCSTR  lpPathName)

Definition at line 2206 of file path.c.

2207{
2210
2211 if (!lpPathName)
2212 {
2214 return FALSE;
2215 }
2216
2218 if (!DirName) return FALSE;
2219
2220 if (CheckForSameCurdir(DirName)) return TRUE;
2221
2223 if (NT_SUCCESS(Status)) return TRUE;
2224
2225 if ((*DirName->Buffer != L'"') || (DirName->Length <= 2))
2226 {
2228 return 0;
2229 }
2230
2232 if (!DirName) return FALSE;
2233
2235 if (!NT_SUCCESS(Status))
2236 {
2238 return FALSE;
2239 }
2240
2241 return TRUE;
2242}
BOOLEAN WINAPI CheckForSameCurdir(IN PUNICODE_STRING DirName)
Definition: path.c:519
NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(_In_ PUNICODE_STRING name)

Referenced by DosChangeDirectory(), DosChangeDrive(), SheChangeDirA(), SheGetDirA(), SheGetDirW(), START_TEST(), test_CleanupPathA(), test_CreateActCtx(), test_CreateDirectoryA(), test_CreateFileA(), test_CurrentDirectoryA(), test_currentworkingdir(), test_directory(), test_find_file(), test_FindFirstFile_wildcards(), Test_FindFirstFileA(), test_fullpath(), test_GetTempPath(), test_GetVolumeInformationA(), test_inffilelist(), test_inffilelistA(), test_listbox_LB_DIR(), test_LoadImage_working_directory(), test_ok(), test_relative_path(), test_RemoveDirectory(), test_RemoveDirectoryA(), test_SearchPathA(), test_SetCurrentDirectoryA(), test_setdir(), test_SetSearchPathMode(), test_toplevel_stat(), TestGetCurrentDirectoryA(), and TestSetCurrentDirectoryA().

◆ SetCurrentDirectoryW()

◆ SetDllDirectoryA()

BOOL WINAPI SetDllDirectoryA ( IN LPCSTR  lpPathName)

Definition at line 838 of file path.c.

839{
840 ANSI_STRING AnsiDllDirectory;
841 UNICODE_STRING OldDirectory, DllDirectory;
843
844 if (lpPathName)
845 {
846 if (strchr(lpPathName, ';'))
847 {
849 return FALSE;
850 }
851
852 Status = RtlInitAnsiStringEx(&AnsiDllDirectory, lpPathName);
853 if (NT_SUCCESS(Status))
854 {
856 &AnsiDllDirectory,
857 TRUE);
858 }
859
860 if (!NT_SUCCESS(Status))
861 {
863 return FALSE;
864 }
865 }
866 else
867 {
868 RtlInitUnicodeString(&DllDirectory, NULL);
869 }
870
872
873 OldDirectory = BaseDllDirectory;
874 BaseDllDirectory = DllDirectory;
875
877
878 RtlFreeUnicodeString(&OldDirectory);
879 return TRUE;
880}
PRTL_CONVERT_STRING Basep8BitStringToUnicodeString
Definition: utils.c:26
NTSYSAPI NTSTATUS WINAPI RtlInitAnsiStringEx(PANSI_STRING, PCSZ)

Referenced by init_pointers().

◆ SetDllDirectoryW()

BOOL WINAPI SetDllDirectoryW ( IN LPCWSTR  lpPathName)

Definition at line 800 of file path.c.

801{
802 UNICODE_STRING OldDirectory, DllDirectory;
803
804 if (lpPathName)
805 {
806 if (wcschr(lpPathName, L';'))
807 {
809 return FALSE;
810 }
811 if (!RtlCreateUnicodeString(&DllDirectory, lpPathName))
812 {
814 return FALSE;
815 }
816 }
817 else
818 {
819 RtlInitUnicodeString(&DllDirectory, NULL);
820 }
821
823
824 OldDirectory = BaseDllDirectory;
825 BaseDllDirectory = DllDirectory;
826
828
829 RtlFreeUnicodeString(&OldDirectory);
830 return TRUE;
831}
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

◆ SkipPathTypeIndicator_U()

PWCHAR WINAPI SkipPathTypeIndicator_U ( IN LPWSTR  Path)

Definition at line 740 of file path.c.

741{
742 PWCHAR ReturnPath;
743 ULONG i;
744
745 /* Check what kind of path this is and how many slashes to skip */
747 {
750 {
751 /* Keep going until we bypass the path indicators */
752 for (ReturnPath = Path + 2, i = 2; (i > 0) && (*ReturnPath); ReturnPath++)
753 {
754 /* We look for 2 slashes, so keep at it until we find them */
755 if ((*ReturnPath == L'\\') || (*ReturnPath == L'/')) i--;
756 }
757
758 return ReturnPath;
759 }
760
762 return Path + 3;
763
765 return Path + 2;
766
768 return Path + 1;
769
771 return Path;
772
774 default:
775 return NULL;
776 }
777}
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
@ RtlPathTypeRootLocalDevice
Definition: rtltypes.h:478
@ RtlPathTypeDriveRelative
Definition: rtltypes.h:474
@ RtlPathTypeRelative
Definition: rtltypes.h:476
@ RtlPathTypeUncAbsolute
Definition: rtltypes.h:472
@ RtlPathTypeRooted
Definition: rtltypes.h:475
@ RtlPathTypeLocalDevice
Definition: rtltypes.h:477
@ RtlPathTypeDriveAbsolute
Definition: rtltypes.h:473

Referenced by GetLongPathNameW(), and GetShortPathNameW().

Variable Documentation

◆ BaseDefaultPath

UNICODE_STRING BaseDefaultPath

Definition at line 21 of file path.c.

Referenced by BasepComputeProcessPath(), and DllMain().

◆ BaseDefaultPathAppend

UNICODE_STRING BaseDefaultPathAppend

Definition at line 21 of file path.c.

Referenced by DllMain().

◆ BaseDllDirectory

◆ BaseDllOrderCurrent

◆ BaseDllOrderNoCurrent

◆ BasePathVariableName

UNICODE_STRING BasePathVariableName
extern

Definition at line 23 of file proc.c.

Referenced by BasepComputeProcessPath().

◆ BasepDllCurrentDirPlacement

Definition at line 81 of file path.c.

Referenced by BaseComputeProcessDllPath().

◆ BaseProcessOrder

◆ BaseProcessOrderNoCurrent

◆ BaseWindowsDirectory

UNICODE_STRING BaseWindowsDirectory

◆ BaseWindowsSystemDirectory

UNICODE_STRING BaseWindowsSystemDirectory

Definition at line 20 of file path.c.

Referenced by DllMain(), GetSystemDirectoryA(), and GetSystemDirectoryW().

◆ gpTermsrvGetWindowsDirectoryA

PVOID gpTermsrvGetWindowsDirectoryA

Definition at line 23 of file path.c.

Referenced by GetWindowsDirectoryA().

◆ gpTermsrvGetWindowsDirectoryW

PVOID gpTermsrvGetWindowsDirectoryW

Definition at line 24 of file path.c.

Referenced by GetWindowsDirectoryW().

◆ IllegalMask

DWORD IllegalMask[4]
Initial value:
=
{
0xFFFFFFFF,
0xFC009C05,
0x38000000,
0x10000000
}

Definition at line 28 of file path.c.

Referenced by IsShortName_U().

◆ NoDefaultCurrentDirectoryInExePath

UNICODE_STRING NoDefaultCurrentDirectoryInExePath = RTL_CONSTANT_STRING(L"NoDefaultCurrentDirectoryInExePath")

Definition at line 18 of file path.c.

Referenced by BasepIsCurDirAllowedForPlainExeNames().