📄 dir.c
字号:
}
if (DirectoryHandle != NULL)
{
NtClose(DirectoryHandle);
}
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
BOOL
STDCALL
RemoveDirectoryA (
LPCSTR lpPathName
)
{
PWCHAR PathNameW;
DPRINT("RemoveDirectoryA(%s)\n",lpPathName);
if (!(PathNameW = FilenameA2W(lpPathName, FALSE)))
return FALSE;
return RemoveDirectoryW (PathNameW);
}
/*
* @implemented
*/
BOOL
STDCALL
RemoveDirectoryW (
LPCWSTR lpPathName
)
{
FILE_DISPOSITION_INFORMATION FileDispInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING NtPathU;
HANDLE DirectoryHandle;
NTSTATUS Status;
DPRINT("lpPathName %S\n", lpPathName);
if (!RtlDosPathNameToNtPathName_U (lpPathName,
&NtPathU,
NULL,
NULL))
return FALSE;
InitializeObjectAttributes(&ObjectAttributes,
&NtPathU,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
DPRINT("NtPathU '%S'\n", NtPathU.Buffer);
Status = NtCreateFile (&DirectoryHandle,
DELETE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_DIRECTORY, /* 0x7 */
0,
FILE_OPEN,
FILE_DIRECTORY_FILE, /* 0x204021 */
NULL,
0);
RtlFreeHeap (RtlGetProcessHeap (),
0,
NtPathU.Buffer);
if (!NT_SUCCESS(Status))
{
CHECKPOINT;
SetLastErrorByStatus (Status);
return FALSE;
}
FileDispInfo.DeleteFile = TRUE;
Status = NtSetInformationFile (DirectoryHandle,
&IoStatusBlock,
&FileDispInfo,
sizeof(FILE_DISPOSITION_INFORMATION),
FileDispositionInformation);
NtClose(DirectoryHandle);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/
DWORD
STDCALL
GetFullPathNameA (
LPCSTR lpFileName,
DWORD nBufferLength,
LPSTR lpBuffer,
LPSTR *lpFilePart
)
{
WCHAR BufferW[MAX_PATH];
PWCHAR FileNameW;
DWORD ret;
LPWSTR FilePartW = NULL;
DPRINT("GetFullPathNameA(lpFileName %s, nBufferLength %d, lpBuffer %p, "
"lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
if (!lpFileName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
return 0;
ret = GetFullPathNameW(FileNameW, MAX_PATH, BufferW, &FilePartW);
if (!ret)
return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
ret = FilenameW2A_FitOrFail(lpBuffer, nBufferLength, BufferW, ret+1);
if (ret < nBufferLength && lpFilePart)
{
/* if the path closed with '\', FilePart is NULL */
if (!FilePartW)
*lpFilePart=NULL;
else
*lpFilePart = (FilePartW - BufferW) + lpBuffer;
}
DPRINT("GetFullPathNameA ret: lpBuffer %s lpFilePart %s\n",
lpBuffer, (lpFilePart == NULL) ? "NULL" : *lpFilePart);
return ret;
}
/*
* @implemented
*/
DWORD
STDCALL
GetFullPathNameW (
LPCWSTR lpFileName,
DWORD nBufferLength,
LPWSTR lpBuffer,
LPWSTR *lpFilePart
)
{
ULONG Length;
DPRINT("GetFullPathNameW(lpFileName %S, nBufferLength %d, lpBuffer %p, "
"lpFilePart %p)\n",lpFileName,nBufferLength,lpBuffer,lpFilePart);
Length = RtlGetFullPathName_U ((LPWSTR)lpFileName,
nBufferLength * sizeof(WCHAR),
lpBuffer,
lpFilePart);
DPRINT("GetFullPathNameW ret: lpBuffer %S lpFilePart %S Length %ld\n",
lpBuffer, (lpFilePart == NULL) ? L"NULL" : *lpFilePart, Length / sizeof(WCHAR));
return Length/sizeof(WCHAR);
}
/*
* NOTE: Copied from Wine.
* @implemented
*/
DWORD
STDCALL
GetShortPathNameA (
LPCSTR longpath,
LPSTR shortpath,
DWORD shortlen
)
{
PWCHAR LongPathW;
WCHAR ShortPathW[MAX_PATH];
DWORD ret;
if (!longpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!(LongPathW = FilenameA2W(longpath, FALSE)))
return 0;
ret = GetShortPathNameW(LongPathW, ShortPathW, MAX_PATH);
if (!ret)
return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return FilenameW2A_FitOrFail(shortpath, shortlen, ShortPathW, ret+1);
}
/*
* NOTE: Copied from Wine.
* @implemented
*/
DWORD
STDCALL
GetShortPathNameW (
LPCWSTR longpath,
LPWSTR shortpath,
DWORD shortlen
)
{
WCHAR tmpshortpath[MAX_PATH];
LPCWSTR p;
DWORD sp = 0, lp = 0;
DWORD tmplen;
WIN32_FIND_DATAW wfd;
HANDLE goit;
UNICODE_STRING ustr;
WCHAR ustr_buf[8+1+3+1];
DPRINT("GetShortPathNameW: %S\n",longpath);
if (!longpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!longpath[0])
{
SetLastError(ERROR_BAD_PATHNAME);
return 0;
}
/* check for drive letter */
if (longpath[1] == ':' )
{
tmpshortpath[0] = longpath[0];
tmpshortpath[1] = ':';
sp = lp = 2;
}
ustr.Buffer = ustr_buf;
ustr.Length = 0;
ustr.MaximumLength = sizeof(ustr_buf);
while (longpath[lp])
{
/* check for path delimiters and reproduce them */
if (longpath[lp] == '\\' || longpath[lp] == '/')
{
if (!sp || tmpshortpath[sp-1] != '\\')
{
/* strip double "\\" */
tmpshortpath[sp] = '\\';
sp++;
}
tmpshortpath[sp] = 0; /* terminate string */
lp++;
continue;
}
for (p = longpath + lp; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (longpath + lp);
lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
/* Check, if the current element is a valid dos name */
if (tmplen <= 8+1+3+1)
{
BOOLEAN spaces;
memcpy(ustr_buf, longpath + lp, tmplen * sizeof(WCHAR));
ustr_buf[tmplen] = '\0';
ustr.Length = (USHORT)tmplen * sizeof(WCHAR);
if (RtlIsNameLegalDOS8Dot3(&ustr, NULL, &spaces) && !spaces)
{
sp += tmplen;
lp += tmplen;
continue;
}
}
/* Check if the file exists and use the existing short file name */
goit = FindFirstFileW(tmpshortpath, &wfd);
if (goit == INVALID_HANDLE_VALUE) goto notfound;
FindClose(goit);
lstrcpyW(tmpshortpath + sp, wfd.cAlternateFileName);
sp += lstrlenW(tmpshortpath + sp);
lp += tmplen;
}
tmpshortpath[sp] = 0;
tmplen = lstrlenW(tmpshortpath) + 1;
if (tmplen <= shortlen)
{
lstrcpyW(shortpath, tmpshortpath);
tmplen--; /* length without 0 */
}
return tmplen;
notfound:
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
/*
* @implemented
*/
DWORD
STDCALL
SearchPathA (
LPCSTR lpPath,
LPCSTR lpFileName,
LPCSTR lpExtension,
DWORD nBufferLength,
LPSTR lpBuffer,
LPSTR *lpFilePart
)
{
UNICODE_STRING PathU = {0};
UNICODE_STRING FileNameU = {0};
UNICODE_STRING ExtensionU = {0};
UNICODE_STRING BufferU = {0};
ANSI_STRING Path;
ANSI_STRING FileName;
ANSI_STRING Extension;
ANSI_STRING Buffer;
PWCHAR FilePartW;
DWORD RetValue = 0;
NTSTATUS Status = STATUS_SUCCESS;
RtlInitAnsiString (&Path,
(LPSTR)lpPath);
RtlInitAnsiString (&FileName,
(LPSTR)lpFileName);
RtlInitAnsiString (&Extension,
(LPSTR)lpExtension);
/* convert ansi (or oem) strings to unicode */
if (bIsFileApiAnsi)
{
Status = RtlAnsiStringToUnicodeString (&PathU,
&Path,
TRUE);
if (!NT_SUCCESS(Status))
goto Cleanup;
Status = RtlAnsiStringToUnicodeString (&FileNameU,
&FileName,
TRUE);
if (!NT_SUCCESS(Status))
goto Cleanup;
Status = RtlAnsiStringToUnicodeString (&ExtensionU,
&Extension,
TRUE);
if (!NT_SUCCESS(Status))
goto Cleanup;
}
else
{
Status = RtlOemStringToUnicodeString (&PathU,
&Path,
TRUE);
if (!NT_SUCCESS(Status))
goto Cleanup;
Status = RtlOemStringToUnicodeString (&FileNameU,
&FileName,
TRUE);
if (!NT_SUCCESS(Status))
goto Cleanup;
Status = RtlOemStringToUnicodeString (&ExtensionU,
&Extension,
TRUE);
if (!NT_SUCCESS(Status))
goto Cleanup;
}
BufferU.MaximumLength = (USHORT)nBufferLength * sizeof(WCHAR);
BufferU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
0,
BufferU.MaximumLength);
if (BufferU.Buffer == NULL)
{
Status = STATUS_NO_MEMORY;
goto Cleanup;
}
Buffer.MaximumLength = (USHORT)nBufferLength;
Buffer.Buffer = lpBuffer;
RetValue = SearchPathW (NULL == lpPath ? NULL : PathU.Buffer,
NULL == lpFileName ? NULL : FileNameU.Buffer,
NULL == lpExtension ? NULL : ExtensionU.Buffer,
nBufferLength,
BufferU.Buffer,
&FilePartW);
if (0 != RetValue)
{
BufferU.Length = wcslen(BufferU.Buffer) * sizeof(WCHAR);
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlUnicodeStringToAnsiString (&Buffer,
&BufferU,
FALSE);
else
RtlUnicodeStringToOemString (&Buffer,
&BufferU,
FALSE);
/* nul-terminate ascii string */
Buffer.Buffer[BufferU.Length / sizeof(WCHAR)] = '\0';
if (NULL != lpFilePart && BufferU.Length != 0)
{
*lpFilePart = strrchr (lpBuffer, '\\') + 1;
}
}
Cleanup:
RtlFreeHeap (RtlGetProcessHeap (),
0,
PathU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
FileNameU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
ExtensionU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
BufferU.Buffer);
if (!NT_SUCCESS(Status))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -