update for HEAD-2003050101
[reactos.git] / lib / kernel32 / file / file.c
index 79061ad..72572f6 100644 (file)
@@ -245,75 +245,72 @@ SetFilePointer(HANDLE hFile,
 DWORD STDCALL
 GetFileType(HANDLE hFile)
 {
-   FILE_FS_DEVICE_INFORMATION DeviceInfo;
-   IO_STATUS_BLOCK StatusBlock;
-   NTSTATUS Status;
-
-   /* get real handle */
-   switch ((ULONG)hFile)
-     {
-       case STD_INPUT_HANDLE:
-         hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
-
-         break;
-
-       case STD_OUTPUT_HANDLE:
-         hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
-
-         break;
-
-       case STD_ERROR_HANDLE:
-         hFile = NtCurrentPeb()->ProcessParameters->hStdError;
-
-         break;
-     }
-
-   /* check console handles */
-   if (IsConsoleHandle(hFile))
-     {
-//     if (VerifyConsoleHandle(hFile))
-         return FILE_TYPE_CHAR;
-     }
-
-   Status = NtQueryVolumeInformationFile(hFile,
-                                        &StatusBlock,
-                                        &DeviceInfo,
-                                        sizeof(FILE_FS_DEVICE_INFORMATION),
-                                        FileFsDeviceInformation);
-   if (!NT_SUCCESS(Status))
-     {
-       SetLastErrorByStatus(Status);
-       return FILE_TYPE_UNKNOWN;
-     }
-
-   switch (DeviceInfo.DeviceType)
-     {
-       case FILE_DEVICE_CD_ROM:
-       case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
-       case FILE_DEVICE_CONTROLLER:
-       case FILE_DEVICE_DATALINK:
-       case FILE_DEVICE_DFS:
-       case FILE_DEVICE_DISK:
-       case FILE_DEVICE_DISK_FILE_SYSTEM:
-       case FILE_DEVICE_VIRTUAL_DISK:
-         return FILE_TYPE_DISK;
-
-       case FILE_DEVICE_KEYBOARD:
-       case FILE_DEVICE_MOUSE:
-       case FILE_DEVICE_NULL:
-       case FILE_DEVICE_PARALLEL_PORT:
-       case FILE_DEVICE_PRINTER:
-       case FILE_DEVICE_SERIAL_PORT:
-       case FILE_DEVICE_SCREEN:
-       case FILE_DEVICE_SOUND:
-       case FILE_DEVICE_MODEM:
-         return FILE_TYPE_CHAR;
-
-       case FILE_DEVICE_NAMED_PIPE:
-         return FILE_TYPE_PIPE;
-     }
-
-   return FILE_TYPE_UNKNOWN;
+  FILE_FS_DEVICE_INFORMATION DeviceInfo;
+  IO_STATUS_BLOCK StatusBlock;
+  NTSTATUS Status;
+
+  /* Get real handle */
+  switch ((ULONG)hFile)
+    {
+      case STD_INPUT_HANDLE:
+       hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
+       break;
+
+      case STD_OUTPUT_HANDLE:
+       hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+       break;
+
+      case STD_ERROR_HANDLE:
+       hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+       break;
+    }
+
+  /* Check for console handle */
+  if (IsConsoleHandle(hFile))
+    {
+      if (VerifyConsoleIoHandle(hFile))
+       return FILE_TYPE_CHAR;
+    }
+
+  Status = NtQueryVolumeInformationFile(hFile,
+                                       &StatusBlock,
+                                       &DeviceInfo,
+                                       sizeof(FILE_FS_DEVICE_INFORMATION),
+                                       FileFsDeviceInformation);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FILE_TYPE_UNKNOWN;
+    }
+
+  switch (DeviceInfo.DeviceType)
+    {
+      case FILE_DEVICE_CD_ROM:
+      case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
+      case FILE_DEVICE_CONTROLLER:
+      case FILE_DEVICE_DATALINK:
+      case FILE_DEVICE_DFS:
+      case FILE_DEVICE_DISK:
+      case FILE_DEVICE_DISK_FILE_SYSTEM:
+      case FILE_DEVICE_VIRTUAL_DISK:
+       return FILE_TYPE_DISK;
+
+      case FILE_DEVICE_KEYBOARD:
+      case FILE_DEVICE_MOUSE:
+      case FILE_DEVICE_NULL:
+      case FILE_DEVICE_PARALLEL_PORT:
+      case FILE_DEVICE_PRINTER:
+      case FILE_DEVICE_SERIAL_PORT:
+      case FILE_DEVICE_SCREEN:
+      case FILE_DEVICE_SOUND:
+      case FILE_DEVICE_MODEM:
+       return FILE_TYPE_CHAR;
+
+      case FILE_DEVICE_NAMED_PIPE:
+       return FILE_TYPE_PIPE;
+    }
+
+  return FILE_TYPE_UNKNOWN;
 }
 
 
@@ -526,36 +523,64 @@ GetFileAttributesA(LPCSTR lpFileName)
 DWORD STDCALL
 GetFileAttributesW(LPCWSTR lpFileName)
 {
-   IO_STATUS_BLOCK IoStatusBlock;
-   FILE_BASIC_INFORMATION FileBasic;
-   HANDLE hFile;
-   NTSTATUS errCode;
-
-   hFile = CreateFileW(lpFileName,
-                      FILE_READ_ATTRIBUTES,
-                      FILE_SHARE_READ,
-                      NULL,
-                      OPEN_EXISTING,
-                      FILE_ATTRIBUTE_NORMAL,
-                      NULL);
-   if (hFile == INVALID_HANDLE_VALUE)
-     {
-       return 0xFFFFFFFF;
-     }
-
-   errCode = NtQueryInformationFile(hFile,
-                                   &IoStatusBlock,
-                                   &FileBasic,
-                                   sizeof(FILE_BASIC_INFORMATION),
-                                   FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       CloseHandle(hFile);
-       SetLastErrorByStatus(errCode);
-       return 0xFFFFFFFF;
-     }
-   CloseHandle(hFile);
-   return (DWORD)FileBasic.FileAttributes;
+  FILE_BASIC_INFORMATION FileInformation;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
+  UNICODE_STRING FileName;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+
+  DPRINT ("GetFileAttributeW(%S) called\n", lpFileName);
+
+  /* Validate and translate the filename */
+  if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
+                                    &FileName,
+                                    NULL,
+                                    NULL))
+    {
+      DPRINT ("Invalid path\n");
+      SetLastError (ERROR_BAD_PATHNAME);
+      return 0xFFFFFFFF;
+    }
+  DPRINT ("FileName: \'%wZ\'\n", &FileName);
+
+  /* build the object attributes */
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &FileName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+
+  /* Open the file */
+  Status = NtOpenFile (&FileHandle,
+                      SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                      FILE_SYNCHRONOUS_IO_NONALERT);
+  RtlFreeUnicodeString (&FileName);
+  if (!NT_SUCCESS (Status))
+    {
+      DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
+      SetLastErrorByStatus (Status);
+      return 0xFFFFFFFF;
+    }
+
+  /* Get file attributes */
+  Status = NtQueryInformationFile (FileHandle,
+                                  &IoStatusBlock,
+                                  &FileInformation,
+                                  sizeof(FILE_BASIC_INFORMATION),
+                                  FileBasicInformation);
+  NtClose (FileHandle);
+  if (!NT_SUCCESS (Status))
+    {
+      DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status);
+      SetLastErrorByStatus (Status);
+      return 0xFFFFFFFF;
+    }
+
+  return (DWORD)FileInformation.FileAttributes;
 }
 
 
@@ -563,29 +588,29 @@ WINBOOL STDCALL
 SetFileAttributesA(LPCSTR lpFileName,
                   DWORD dwFileAttributes)
 {
-   UNICODE_STRING FileNameU;
-   ANSI_STRING FileName;
-   WINBOOL Result;
+  UNICODE_STRING FileNameU;
+  ANSI_STRING FileName;
+  WINBOOL Result;
 
-   RtlInitAnsiString(&FileName,
+  RtlInitAnsiString (&FileName,
                     (LPSTR)lpFileName);
 
-   /* convert ansi (or oem) string to unicode */
-   if (bIsFileApiAnsi)
-     RtlAnsiStringToUnicodeString(&FileNameU,
+  /* convert ansi (or oem) string to unicode */
+  if (bIsFileApiAnsi)
+    RtlAnsiStringToUnicodeString (&FileNameU,
                                  &FileName,
                                  TRUE);
    else
-     RtlOemStringToUnicodeString(&FileNameU,
+    RtlOemStringToUnicodeString (&FileNameU,
                                 &FileName,
                                 TRUE);
 
-   Result = SetFileAttributesW(FileNameU.Buffer,
+  Result = SetFileAttributesW (FileNameU.Buffer,
                               dwFileAttributes);
 
-   RtlFreeUnicodeString(&FileNameU);
+  RtlFreeUnicodeString (&FileNameU);
 
-   return Result;
+  return Result;
 }
 
 
@@ -593,51 +618,77 @@ WINBOOL STDCALL
 SetFileAttributesW(LPCWSTR lpFileName,
                   DWORD dwFileAttributes)
 {
-   IO_STATUS_BLOCK IoStatusBlock;
-   FILE_BASIC_INFORMATION FileBasic;
-   HANDLE hFile;
-   NTSTATUS errCode;
-   
-   hFile = CreateFileW(lpFileName,
-                      FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
-                      FILE_SHARE_READ,
-                      NULL,
-                      OPEN_EXISTING,
-                      FILE_ATTRIBUTE_NORMAL,
-                      NULL);
-   if (INVALID_HANDLE_VALUE == hFile)
-     {
-       DPRINT("SetFileAttributes CreateFileW failed with code %d\n", GetLastError());
-       return FALSE;
-     }
+  FILE_BASIC_INFORMATION FileInformation;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
+  UNICODE_STRING FileName;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+
+  DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
+
+  /* Validate and translate the filename */
+  if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
+                                    &FileName,
+                                    NULL,
+                                    NULL))
+    {
+      DPRINT ("Invalid path\n");
+      SetLastError (ERROR_BAD_PATHNAME);
+      return FALSE;
+    }
+  DPRINT ("FileName: \'%wZ\'\n", &FileName);
+
+  /* build the object attributes */
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &FileName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+
+  /* Open the file */
+  Status = NtOpenFile (&FileHandle,
+                      SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                      FILE_SYNCHRONOUS_IO_NONALERT);
+  RtlFreeUnicodeString (&FileName);
+  if (!NT_SUCCESS (Status))
+    {
+      DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
 
-   errCode = NtQueryInformationFile(hFile,
-                                   &IoStatusBlock,
-                                   &FileBasic,
-                                   sizeof(FILE_BASIC_INFORMATION),
-                                   FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       CloseHandle(hFile);
-       DPRINT("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", errCode);
-       SetLastErrorByStatus(errCode);
-       return FALSE;
-     }
-   FileBasic.FileAttributes = dwFileAttributes;
-   errCode = NtSetInformationFile(hFile,
+  Status = NtQueryInformationFile(FileHandle,
                                  &IoStatusBlock,
-                                 &FileBasic,
+                                 &FileInformation,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       CloseHandle(hFile);
-       DPRINT("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", errCode);
-       SetLastErrorByStatus(errCode);
-       return FALSE;
-     }
-   CloseHandle(hFile);
-   return TRUE;
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
+      NtClose (FileHandle);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  FileInformation.FileAttributes = dwFileAttributes;
+  Status = NtSetInformationFile(FileHandle,
+                               &IoStatusBlock,
+                               &FileInformation,
+                               sizeof(FILE_BASIC_INFORMATION),
+                               FileBasicInformation);
+  NtClose (FileHandle);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  return TRUE;
 }