Reimplemented GetFileAttributesW, SetFileAttributesW and SetFileTime

using the corresponding ntdll functionality.
This commit is contained in:
Alexandre Julliard 2004-04-20 00:36:29 +00:00
parent ebf0eb3138
commit 174e2a6464
10 changed files with 325 additions and 233 deletions

View file

@ -367,6 +367,40 @@ BOOL WINAPI GetFileSizeEx( HANDLE hFile, PLARGE_INTEGER lpFileSize )
}
/***********************************************************************
* SetFileTime (KERNEL32.@)
*/
BOOL WINAPI SetFileTime( HANDLE hFile, const FILETIME *ctime,
const FILETIME *atime, const FILETIME *mtime )
{
FILE_BASIC_INFORMATION info;
IO_STATUS_BLOCK io;
NTSTATUS status;
memset( &info, 0, sizeof(info) );
if (ctime)
{
info.CreationTime.u.HighPart = ctime->dwHighDateTime;
info.CreationTime.u.LowPart = ctime->dwLowDateTime;
}
if (atime)
{
info.LastAccessTime.u.HighPart = atime->dwHighDateTime;
info.LastAccessTime.u.LowPart = atime->dwLowDateTime;
}
if (mtime)
{
info.LastWriteTime.u.HighPart = mtime->dwHighDateTime;
info.LastWriteTime.u.LowPart = mtime->dwLowDateTime;
}
status = NtSetInformationFile( hFile, &io, &info, sizeof(info), FileBasicInformation );
if (status == STATUS_SUCCESS) return TRUE;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/**************************************************************************
* LockFile (KERNEL32.@)
*/
@ -918,6 +952,135 @@ BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data )
}
/**************************************************************************
* GetFileAttributesW (KERNEL32.@)
*/
DWORD WINAPI GetFileAttributesW( LPCWSTR name )
{
FILE_BASIC_INFORMATION info;
UNICODE_STRING nt_name;
OBJECT_ATTRIBUTES attr;
NTSTATUS status;
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
{
SetLastError( ERROR_PATH_NOT_FOUND );
return INVALID_FILE_ATTRIBUTES;
}
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
status = NtQueryAttributesFile( &attr, &info );
RtlFreeUnicodeString( &nt_name );
if (status == STATUS_SUCCESS) return info.FileAttributes;
/* NtQueryAttributesFile fails on devices, but GetFileAttributesW succeeds */
if (RtlIsDosDeviceName_U( name )) return FILE_ATTRIBUTE_ARCHIVE;
SetLastError( RtlNtStatusToDosError(status) );
return INVALID_FILE_ATTRIBUTES;
}
/**************************************************************************
* GetFileAttributesA (KERNEL32.@)
*/
DWORD WINAPI GetFileAttributesA( LPCSTR name )
{
UNICODE_STRING nameW;
DWORD ret = INVALID_FILE_ATTRIBUTES;
if (!name)
{
SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_FILE_ATTRIBUTES;
}
if (RtlCreateUnicodeStringFromAsciiz(&nameW, name))
{
ret = GetFileAttributesW(nameW.Buffer);
RtlFreeUnicodeString(&nameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/**************************************************************************
* SetFileAttributesW (KERNEL32.@)
*/
BOOL WINAPI SetFileAttributesW( LPCWSTR name, DWORD attributes )
{
UNICODE_STRING nt_name;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
if (!RtlDosPathNameToNtPathName_U( name, &nt_name, NULL, NULL ))
{
SetLastError( ERROR_PATH_NOT_FOUND );
return FALSE;
}
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
status = NtOpenFile( &handle, 0, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
RtlFreeUnicodeString( &nt_name );
if (status == STATUS_SUCCESS)
{
FILE_BASIC_INFORMATION info;
memset( &info, 0, sizeof(info) );
info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL; /* make sure it's not zero */
status = NtSetInformationFile( handle, &io, &info, sizeof(info), FileBasicInformation );
NtClose( handle );
}
if (status == STATUS_SUCCESS) return TRUE;
SetLastError( RtlNtStatusToDosError(status) );
return FALSE;
}
/**************************************************************************
* SetFileAttributesA (KERNEL32.@)
*/
BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes )
{
UNICODE_STRING filenameW;
BOOL ret = FALSE;
if (!name)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name))
{
ret = SetFileAttributesW(filenameW.Buffer, attributes);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/***********************************************************************
* OpenFile (KERNEL32.@)
*/

View file

@ -110,10 +110,6 @@ static BOOL process_attach(void)
{
HMODULE16 hModule;
/* Get the umask */
FILE_umask = umask(0777);
umask( FILE_umask );
/* Setup registry locale information */
LOCALE_InitRegistry();

View file

@ -188,6 +188,29 @@ static void init_options(void)
}
/***********************************************************************
* DIR_is_hidden_file
*
* Check if the specified file should be hidden based on its name and the show dot files option.
*/
BOOL DIR_is_hidden_file( const UNICODE_STRING *name )
{
WCHAR *p, *end;
if (show_dir_symlinks == -1) init_options();
if (show_dot_files) return FALSE;
end = p = name->Buffer + name->Length/sizeof(WCHAR);
while (p > name->Buffer && IS_SEPARATOR(p[-1])) p--;
while (p > name->Buffer && !IS_SEPARATOR(p[-1])) p--;
if (p == end || *p != '.') return FALSE;
/* make sure it isn't '.' or '..' */
if (p + 1 == end) return FALSE;
if (p[1] == '.' && p + 2 == end) return FALSE;
return TRUE;
}
/***********************************************************************
* hash_short_file_name
*

View file

@ -39,6 +39,12 @@
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_UTIME_H
# include <utime.h>
#endif
#ifdef STATFS_DEFINED_BY_SYS_VFS
# include <sys/vfs.h>
#else
@ -64,6 +70,11 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
mode_t FILE_umask = 0;
#define SECSPERDAY 86400
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
/**************************************************************************
* NtOpenFile [NTDLL.@]
* ZwOpenFile [NTDLL.@]
@ -868,46 +879,143 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
* Set information about an open file handle.
*
* PARAMS
* FileHandle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
* IoStatusBlock [O] Receives information about the operation on return
* FileInformation [I] Source for file information
* Length [I] Size of FileInformation
* FileInformationClass [I] Type of file information to set
* handle [I] Handle returned from ZwOpenFile() or ZwCreateFile()
* io [O] Receives information about the operation on return
* ptr [I] Source for file information
* len [I] Size of FileInformation
* class [I] Type of file information to set
*
* RETURNS
* Success: 0. IoStatusBlock is updated.
* Success: 0. io is updated.
* Failure: An NTSTATUS error code describing the error.
*/
NTSTATUS WINAPI NtSetInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io_status,
PVOID ptr, ULONG len,
FILE_INFORMATION_CLASS class)
NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
PVOID ptr, ULONG len, FILE_INFORMATION_CLASS class)
{
NTSTATUS status = STATUS_INVALID_PARAMETER_3;
int fd;
TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", hFile, io_status, ptr, len, class);
TRACE("(%p,%p,%p,0x%08lx,0x%08x)\n", handle, io, ptr, len, class);
if ((io->u.Status = wine_server_handle_to_fd( handle, 0, &fd, NULL, NULL )))
return io->u.Status;
io->u.Status = STATUS_SUCCESS;
switch (class)
{
case FileBasicInformation:
if (len >= sizeof(FILE_BASIC_INFORMATION))
{
struct stat st;
const FILE_BASIC_INFORMATION *info = ptr;
#ifdef HAVE_FUTIMES
if (info->LastAccessTime.QuadPart || info->LastWriteTime.QuadPart)
{
ULONGLONG sec, nsec;
struct timeval tv[2];
if (!info->LastAccessTime.QuadPart || !info->LastWriteTime.QuadPart)
{
tv[0].tv_sec = tv[0].tv_usec = 0;
tv[1].tv_sec = tv[1].tv_usec = 0;
if (!fstat( fd, &st ))
{
tv[0].tv_sec = st.st_atime;
tv[1].tv_sec = st.st_mtime;
}
}
if (info->LastAccessTime.QuadPart)
{
sec = RtlLargeIntegerDivide( info->LastAccessTime.QuadPart, 10000000, &nsec );
tv[0].tv_sec = sec - SECS_1601_TO_1970;
tv[0].tv_usec = (UINT)nsec / 10;
}
if (info->LastWriteTime.QuadPart)
{
sec = RtlLargeIntegerDivide( info->LastWriteTime.QuadPart, 10000000, &nsec );
tv[1].tv_sec = sec - SECS_1601_TO_1970;
tv[1].tv_usec = (UINT)nsec / 10;
}
if (futimes( fd, tv ) == -1) io->u.Status = FILE_GetNtStatus();
}
#endif /* HAVE_FUTIMES */
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes)
{
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
else
{
if (info->FileAttributes & FILE_ATTRIBUTE_READONLY)
{
st.st_mode &= ~0222; /* clear write permission bits */
}
else
{
/* add write permission only where we already have read permission */
st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~FILE_umask);
}
if (fchmod( fd, st.st_mode ) == -1) io->u.Status = FILE_GetNtStatus();
}
}
}
else io->u.Status = STATUS_INVALID_PARAMETER_3;
break;
case FilePositionInformation:
if (len >= sizeof(FILE_POSITION_INFORMATION))
{
int fd;
FILE_POSITION_INFORMATION* fpi = (FILE_POSITION_INFORMATION*)ptr;
const FILE_POSITION_INFORMATION *info = ptr;
if (!(status = wine_server_handle_to_fd( hFile, 0, &fd, NULL, NULL )))
{
if (lseek( fd, fpi->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1)
status = FILE_GetNtStatus();
wine_server_release_fd( hFile, fd );
}
if (lseek( fd, info->CurrentByteOffset.QuadPart, SEEK_SET ) == (off_t)-1)
io->u.Status = FILE_GetNtStatus();
}
else io->u.Status = STATUS_INVALID_PARAMETER_3;
break;
default:
FIXME("Unsupported class (%d)\n", class);
return STATUS_NOT_IMPLEMENTED;
io->u.Status = STATUS_NOT_IMPLEMENTED;
break;
}
io_status->u.Status = status;
io_status->Information = 0;
wine_server_release_fd( handle, fd );
io->Information = 0;
return io->u.Status;
}
/******************************************************************************
* NtQueryAttributesFile (NTDLL.@)
* ZwQueryAttributesFile (NTDLL.@)
*/
NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC_INFORMATION *info )
{
ANSI_STRING unix_name;
NTSTATUS status;
if (!(status = DIR_nt_to_unix( attr->ObjectName, &unix_name,
TRUE, !(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
{
struct stat st;
if (stat( unix_name.Buffer, &st ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
else
{
if (S_ISDIR(st.st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
if (!(st.st_mode & S_IWUSR)) info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
RtlSecondsSince1970ToTime( st.st_mtime, &info->CreationTime );
RtlSecondsSince1970ToTime( st.st_mtime, &info->LastWriteTime );
RtlSecondsSince1970ToTime( st.st_ctime, &info->ChangeTime );
RtlSecondsSince1970ToTime( st.st_atime, &info->LastAccessTime );
if (DIR_is_hidden_file( attr->ObjectName ))
info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
RtlFreeAnsiString( &unix_name );
}
else WARN("%s not found (%lx)\n", debugstr_us(attr->ObjectName), status );
return status;
}

View file

@ -2016,10 +2016,15 @@ void __wine_process_init( int argc, char *argv[] )
ANSI_STRING func_name;
void (* DECLSPEC_NORETURN init_func)();
extern void __wine_dbg_ntdll_init(void);
extern mode_t FILE_umask;
thread_init();
__wine_dbg_ntdll_init(); /* hack: register debug channels early */
/* retrieve current umask */
FILE_umask = umask(0777);
umask( FILE_umask );
/* setup the load callback and create ntdll modref */
wine_dll_set_callback( load_builtin_callback );

View file

@ -159,7 +159,7 @@
@ stub NtPrivilegedServiceAuditAlarm
@ stdcall NtProtectVirtualMemory(long ptr ptr long ptr)
@ stdcall NtPulseEvent(long ptr)
@ stub NtQueryAttributesFile
@ stdcall NtQueryAttributesFile(ptr ptr)
@ stdcall NtQueryDefaultLocale(long ptr)
@ stdcall NtQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long)
@ stdcall NtQueryDirectoryObject(long ptr long long long ptr ptr)
@ -736,7 +736,7 @@
@ stub ZwPrivilegedServiceAuditAlarm
@ stdcall ZwProtectVirtualMemory(long ptr ptr long ptr) NtProtectVirtualMemory
@ stdcall ZwPulseEvent(long ptr) NtPulseEvent
@ stub ZwQueryAttributesFile
@ stdcall ZwQueryAttributesFile(ptr ptr) NtQueryAttributesFile
@ stdcall ZwQueryDefaultLocale(long ptr) NtQueryDefaultLocale
@ stdcall ZwQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long)NtQueryDirectoryFile
@ stdcall ZwQueryDirectoryObject(long ptr long long long ptr ptr) NtQueryDirectoryObject

View file

@ -84,6 +84,7 @@ extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
/* file I/O */
extern NTSTATUS FILE_GetNtStatus(void);
extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name );
extern NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
int check_last, int check_case );

View file

@ -86,8 +86,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
#define SECSPERDAY 86400
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
mode_t FILE_umask;
/***********************************************************************
* FILE_ConvertOFMode
*
@ -637,151 +635,6 @@ BOOL WINAPI GetFileInformationByHandle( HANDLE hFile, BY_HANDLE_FILE_INFORMATION
}
/**************************************************************************
* GetFileAttributesW (KERNEL32.@)
*/
DWORD WINAPI GetFileAttributesW( LPCWSTR name )
{
DOS_FULL_NAME full_name;
BY_HANDLE_FILE_INFORMATION info;
if (name == NULL)
{
SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_FILE_ATTRIBUTES;
}
if (!DOSFS_GetFullName( name, TRUE, &full_name) )
return INVALID_FILE_ATTRIBUTES;
if (!FILE_Stat( full_name.long_name, &info, NULL ))
return INVALID_FILE_ATTRIBUTES;
return info.dwFileAttributes;
}
/**************************************************************************
* GetFileAttributesA (KERNEL32.@)
*/
DWORD WINAPI GetFileAttributesA( LPCSTR name )
{
UNICODE_STRING nameW;
DWORD ret = INVALID_FILE_ATTRIBUTES;
if (!name)
{
SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_FILE_ATTRIBUTES;
}
if (RtlCreateUnicodeStringFromAsciiz(&nameW, name))
{
ret = GetFileAttributesW(nameW.Buffer);
RtlFreeUnicodeString(&nameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/**************************************************************************
* SetFileAttributesW (KERNEL32.@)
*/
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD attributes)
{
struct stat buf;
DOS_FULL_NAME full_name;
if (!lpFileName)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
TRACE("(%s,%lx)\n", debugstr_w(lpFileName), attributes);
if (!DOSFS_GetFullName( lpFileName, TRUE, &full_name ))
return FALSE;
if(stat(full_name.long_name,&buf)==-1)
{
FILE_SetDosError();
return FALSE;
}
if (attributes & FILE_ATTRIBUTE_READONLY)
{
if(S_ISDIR(buf.st_mode))
/* FIXME */
WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n");
else
buf.st_mode &= ~0222; /* octal!, clear write permission bits */
attributes &= ~FILE_ATTRIBUTE_READONLY;
}
else
{
/* add write permission */
buf.st_mode |= (0600 | ((buf.st_mode & 044) >> 1)) & (~FILE_umask);
}
if (attributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!S_ISDIR(buf.st_mode))
FIXME("SetFileAttributes expected the file %s to be a directory\n",
debugstr_w(lpFileName));
attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
}
attributes &= ~(FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|
FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY);
if (attributes)
FIXME("(%s):%lx attribute(s) not implemented.\n", debugstr_w(lpFileName), attributes);
if (-1==chmod(full_name.long_name,buf.st_mode))
{
if (GetDriveTypeW(lpFileName) == DRIVE_CDROM)
{
SetLastError( ERROR_ACCESS_DENIED );
return FALSE;
}
/*
* FIXME: We don't return FALSE here because of differences between
* Linux and Windows privileges. Under Linux only the owner of
* the file is allowed to change file attributes. Under Windows,
* applications expect that if you can write to a file, you can also
* change its attributes (see GENERIC_WRITE). We could try to be
* clever here but that would break multi-user installations where
* users share read-only DLLs. This is because some installers like
* to change attributes of already installed DLLs.
*/
FIXME("Couldn't set file attributes for existing file \"%s\".\n"
"Check permissions or set VFAT \"quiet\" mount flag\n", full_name.long_name);
}
return TRUE;
}
/**************************************************************************
* SetFileAttributesA (KERNEL32.@)
*/
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD attributes)
{
UNICODE_STRING filenameW;
BOOL ret = FALSE;
if (!lpFileName)
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, lpFileName))
{
ret = SetFileAttributesW(filenameW.Buffer, attributes);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
/******************************************************************************
* GetCompressedFileSizeA [KERNEL32.@]
*/
@ -1725,63 +1578,6 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename,
}
/***********************************************************************
* SetFileTime (KERNEL32.@)
*/
BOOL WINAPI SetFileTime( HANDLE hFile,
const FILETIME *ctime,
const FILETIME *atime,
const FILETIME *mtime )
{
BOOL ret = FALSE;
NTSTATUS status;
int fd;
if (!(status = wine_server_handle_to_fd( hFile, GENERIC_WRITE, &fd, NULL, NULL )))
{
#ifdef HAVE_FUTIMES
ULONGLONG sec, nsec;
struct timeval tv[2];
if (!atime || !mtime)
{
struct stat st;
tv[0].tv_sec = tv[0].tv_usec = 0;
tv[1].tv_sec = tv[1].tv_usec = 0;
if (!fstat( fd, &st ))
{
tv[0].tv_sec = st.st_atime;
tv[1].tv_sec = st.st_mtime;
}
}
if (atime)
{
sec = ((ULONGLONG)atime->dwHighDateTime << 32) | atime->dwLowDateTime;
sec = RtlLargeIntegerDivide( sec, 10000000, &nsec );
tv[0].tv_sec = sec - SECS_1601_TO_1970;
tv[0].tv_usec = (UINT)nsec / 10;
}
if (mtime)
{
sec = ((ULONGLONG)mtime->dwHighDateTime << 32) | mtime->dwLowDateTime;
sec = RtlLargeIntegerDivide( sec, 10000000, &nsec );
tv[1].tv_sec = sec - SECS_1601_TO_1970;
tv[1].tv_usec = (UINT)nsec / 10;
}
if (!futimes( fd, tv )) ret = TRUE;
else FILE_SetDosError();
#else
ret = TRUE; /* pretend it succeeded */
#endif
wine_server_release_fd( hFile, fd );
}
else SetLastError( RtlNtStatusToDosError(status) );
return ret;
}
/**************************************************************************
* GetFileAttributesExW (KERNEL32.@)
*/

View file

@ -36,7 +36,6 @@ typedef struct
} DOS_FULL_NAME;
/* files/file.c */
extern mode_t FILE_umask;
extern void FILE_SetDosError(void);
extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info, BOOL *is_symlink );
extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,

View file

@ -1171,6 +1171,7 @@ NTSTATUS WINAPI NtOpenTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*);
NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*);
NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG);
NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR);
NTSTATUS WINAPI NtQueryAttributesFile(const OBJECT_ATTRIBUTES*,FILE_BASIC_INFORMATION*);
NTSTATUS WINAPI NtQueryDefaultLocale(BOOLEAN,LCID*);
NTSTATUS WINAPI NtQueryDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
NTSTATUS WINAPI NtQueryInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,LONG,FILE_INFORMATION_CLASS);