📄 dir.c
字号:
SetLastErrorByStatus(Status);
return 0;
}
return RetValue;
}
/*
* @implemented
*/
DWORD
STDCALL
SearchPathW (
LPCWSTR lpPath,
LPCWSTR lpFileName,
LPCWSTR lpExtension,
DWORD nBufferLength,
LPWSTR lpBuffer,
LPWSTR *lpFilePart
)
/*
* FUNCTION: Searches for the specified file
* ARGUMENTS:
* lpPath = Points to a null-terminated string that specified the
* path to be searched. If this parameters is NULL then
* the following directories are searched
* The directory from which the application loaded
* The current directory
* The system directory
* The 16-bit system directory
* The windows directory
* The directories listed in the PATH environment
* variable
* lpFileName = Specifies the filename to search for
* lpExtension = Points to the null-terminated string that specifies
* an extension to be added to the filename when
* searching for the file. The first character of the
* filename extension must be a period (.). The
* extension is only added if the specified filename
* doesn't end with an extension
*
* If the filename extension is not required or if the
* filename contains an extension, this parameters can be
* NULL
* nBufferLength = The length in characters of the buffer for output
* lpBuffer = Points to the buffer for the valid path and filename of
* file found
* lpFilePart = Points to the last component of the valid path and
* filename
* RETURNS: On success, the length, in characters, of the string copied to the
* buffer
* On failure, zero.
*/
{
DWORD retCode = 0;
ULONG pos, len;
PWCHAR EnvironmentBufferW = NULL;
PWCHAR AppPathW = NULL;
WCHAR Buffer;
BOOL HasExtension;
LPCWSTR p;
PWCHAR Name;
DPRINT("SearchPath\n");
HasExtension = FALSE;
p = lpFileName + wcslen(lpFileName);
while (lpFileName < p &&
L'\\' != *(p - 1) &&
L'/' != *(p - 1) &&
L':' != *(p - 1))
{
HasExtension = HasExtension || L'.' == *(p - 1);
p--;
}
if (lpFileName < p)
{
if (HasExtension || NULL == lpExtension)
{
Name = (PWCHAR) lpFileName;
}
else
{
Name = RtlAllocateHeap(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS,
(wcslen(lpFileName) + wcslen(lpExtension) + 1)
* sizeof(WCHAR));
if (NULL == Name)
{
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
wcscat(wcscpy(Name, lpFileName), lpExtension);
}
if (RtlDoesFileExists_U(Name))
{
retCode = RtlGetFullPathName_U (Name,
nBufferLength * sizeof(WCHAR),
lpBuffer,
lpFilePart);
}
if (Name != lpFileName)
{
RtlFreeHeap(GetProcessHeap(), 0, Name);
}
}
else
{
if (lpPath == NULL)
{
AppPathW = (PWCHAR) RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
MAX_PATH * sizeof(WCHAR));
if (AppPathW == NULL)
{
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
wcscat (AppPathW, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
len = wcslen (AppPathW);
while (len && AppPathW[len - 1] != L'\\')
len--;
if (len) AppPathW[len-1] = L'\0';
len = GetEnvironmentVariableW(L"PATH", &Buffer, 0);
len += 1 + GetCurrentDirectoryW(0, &Buffer);
len += 1 + GetSystemDirectoryW(&Buffer, 0);
len += 1 + GetWindowsDirectoryW(&Buffer, 0);
len += 1 + wcslen(AppPathW) * sizeof(WCHAR);
EnvironmentBufferW = (PWCHAR) RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
len * sizeof(WCHAR));
if (EnvironmentBufferW == NULL)
{
RtlFreeHeap(RtlGetProcessHeap(), 0, AppPathW);
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
pos = GetCurrentDirectoryW(len, EnvironmentBufferW);
EnvironmentBufferW[pos++] = L';';
EnvironmentBufferW[pos] = 0;
pos += GetSystemDirectoryW(&EnvironmentBufferW[pos], len - pos);
EnvironmentBufferW[pos++] = L';';
EnvironmentBufferW[pos] = 0;
pos += GetWindowsDirectoryW(&EnvironmentBufferW[pos], len - pos);
EnvironmentBufferW[pos++] = L';';
EnvironmentBufferW[pos] = 0;
pos += GetEnvironmentVariableW(L"PATH", &EnvironmentBufferW[pos], len - pos);
EnvironmentBufferW[pos++] = L';';
EnvironmentBufferW[pos] = 0;
wcscat (EnvironmentBufferW, AppPathW);
RtlFreeHeap (RtlGetProcessHeap (),
0,
AppPathW);
lpPath = EnvironmentBufferW;
}
retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension,
nBufferLength * sizeof(WCHAR), lpBuffer, lpFilePart);
if (EnvironmentBufferW != NULL)
{
RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW);
}
if (retCode == 0)
{
SetLastError(ERROR_FILE_NOT_FOUND);
}
}
return retCode / sizeof(WCHAR);
}
/*
* @implemented
*/
BOOL
STDCALL
SetDllDirectoryW(
LPCWSTR lpPathName
)
{
UNICODE_STRING PathName;
RtlInitUnicodeString(&PathName, lpPathName);
RtlEnterCriticalSection(&DllLock);
if(PathName.Length > 0)
{
if(PathName.Length + sizeof(WCHAR) <= DllDirectory.MaximumLength)
{
RtlCopyUnicodeString(&DllDirectory, &PathName);
}
else
{
RtlFreeUnicodeString(&DllDirectory);
if(!(DllDirectory.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(),
0,
PathName.Length + sizeof(WCHAR))))
{
RtlLeaveCriticalSection(&DllLock);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
DllDirectory.Length = 0;
DllDirectory.MaximumLength = PathName.Length + sizeof(WCHAR);
RtlCopyUnicodeString(&DllDirectory, &PathName);
}
}
else
{
RtlFreeUnicodeString(&DllDirectory);
}
RtlLeaveCriticalSection(&DllLock);
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
SetDllDirectoryA(
LPCSTR lpPathName /* can be NULL */
)
{
PWCHAR PathNameW=NULL;
if(lpPathName)
{
if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
return FALSE;
}
return SetDllDirectoryW(PathNameW);
}
/*
* @implemented
*/
DWORD
STDCALL
GetDllDirectoryW(
DWORD nBufferLength,
LPWSTR lpBuffer
)
{
DWORD Ret;
RtlEnterCriticalSection(&DllLock);
if(nBufferLength > 0)
{
Ret = DllDirectory.Length / sizeof(WCHAR);
if(Ret > nBufferLength - 1)
{
Ret = nBufferLength - 1;
}
if(Ret > 0)
{
RtlCopyMemory(lpBuffer, DllDirectory.Buffer, Ret * sizeof(WCHAR));
}
lpBuffer[Ret] = L'\0';
}
else
{
/* include termination character, even if the string is empty! */
Ret = (DllDirectory.Length / sizeof(WCHAR)) + 1;
}
RtlLeaveCriticalSection(&DllLock);
return Ret;
}
/*
* @implemented
*/
DWORD
STDCALL
GetDllDirectoryA(
DWORD nBufferLength,
LPSTR lpBuffer
)
{
WCHAR BufferW[MAX_PATH];
DWORD ret;
ret = GetDllDirectoryW(MAX_PATH, BufferW);
if (!ret)
return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
}
/*
* @implemented
*/
BOOL STDCALL
NeedCurrentDirectoryForExePathW(LPCWSTR ExeName)
{
return (wcschr(ExeName,
L'\\') != NULL);
}
/*
* @implemented
*/
BOOL STDCALL
NeedCurrentDirectoryForExePathA(LPCSTR ExeName)
{
return (strchr(ExeName,
'\\') != NULL);
}
/***********************************************************************
* @implemented
*
* GetLongPathNameW (KERNEL32.@)
*
* NOTES
* observed (Win2000):
* shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* shortpath="": LastError=ERROR_PATH_NOT_FOUND, ret=0
*/
DWORD STDCALL GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen )
{
#define MAX_PATHNAME_LEN 1024
WCHAR tmplongpath[MAX_PATHNAME_LEN];
LPCWSTR p;
DWORD sp = 0, lp = 0;
DWORD tmplen;
BOOL unixabsolute = (shortpath[0] == '/');
WIN32_FIND_DATAW wfd;
HANDLE goit;
if (!shortpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!shortpath[0])
{
SetLastError(ERROR_PATH_NOT_FOUND);
return 0;
}
DPRINT("GetLongPathNameW(%s,%p,%ld)\n", shortpath, longpath, longlen);
if (shortpath[0] == '\\' && shortpath[1] == '\\')
{
DPRINT1("ERR: UNC pathname %s\n", shortpath);
lstrcpynW( longpath, shortpath, longlen );
return wcslen(longpath);
}
/* check for drive letter */
if (!unixabsolute && shortpath[1] == ':' )
{
tmplongpath[0] = shortpath[0];
tmplongpath[1] = ':';
lp = sp = 2;
}
while (shortpath[sp])
{
/* check for path delimiters and reproduce them */
if (shortpath[sp] == '\\' || shortpath[sp] == '/')
{
if (!lp || tmplongpath[lp-1] != '\\')
{
/* strip double "\\" */
tmplongpath[lp++] = '\\';
}
tmplongpath[lp] = 0; /* terminate string */
sp++;
continue;
}
p = shortpath + sp;
if (sp == 0 && p[0] == '.' && (p[1] == '/' || p[1] == '\\'))
{
tmplongpath[lp++] = *p++;
tmplongpath[lp++] = *p++;
}
for (; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (shortpath + sp);
lstrcpynW(tmplongpath + lp, shortpath + sp, tmplen + 1);
/* Check if the file exists and use the existing file name */
goit = FindFirstFileW(tmplongpath, &wfd);
if (goit == INVALID_HANDLE_VALUE)
{
DPRINT("not found %s!\n", tmplongpath);
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
FindClose(goit);
wcscpy(tmplongpath + lp, wfd.cFileName);
lp += wcslen(tmplongpath + lp);
sp += tmplen;
}
tmplen = wcslen(shortpath) - 1;
if ((shortpath[tmplen] == '/' || shortpath[tmplen] == '\\') &&
(tmplongpath[lp - 1] != '/' && tmplongpath[lp - 1] != '\\'))
tmplongpath[lp++] = shortpath[tmplen];
tmplongpath[lp] = 0;
tmplen = wcslen(tmplongpath) + 1;
if (tmplen <= longlen)
{
wcscpy(longpath, tmplongpath);
DPRINT("returning %s\n", longpath);
tmplen--; /* length without 0 */
}
return tmplen;
}
/***********************************************************************
* GetLongPathNameA (KERNEL32.@)
*/
DWORD STDCALL GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
{
WCHAR *shortpathW;
WCHAR longpathW[MAX_PATH];
DWORD ret;
DPRINT("GetLongPathNameA %s, %i\n",shortpath,longlen );
if (!(shortpathW = FilenameA2W( shortpath, FALSE )))
return 0;
ret = GetLongPathNameW(shortpathW, longpathW, MAX_PATH);
if (!ret) return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return FilenameW2A_FitOrFail(longpath, longlen, longpathW, ret+1 );
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -