update for HEAD-2003091401
[reactos.git] / lib / kernel32 / file / volume.c
index 654d48c..fa4ec66 100644 (file)
@@ -77,6 +77,9 @@ InternalOpenDirW(LPCWSTR DirName,
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 GetLogicalDriveStringsA(DWORD nBufferLength,
                        LPSTR lpBuffer)
@@ -111,6 +114,9 @@ GetLogicalDriveStringsA(DWORD nBufferLength,
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 GetLogicalDriveStringsW(DWORD nBufferLength,
                        LPWSTR lpBuffer)
@@ -143,6 +149,9 @@ GetLogicalDriveStringsW(DWORD nBufferLength,
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 GetLogicalDrives(VOID)
 {
@@ -150,6 +159,9 @@ GetLogicalDrives(VOID)
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 GetDiskFreeSpaceA (
        LPCSTR  lpRootPathName,
@@ -199,6 +211,9 @@ GetDiskFreeSpaceA (
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 GetDiskFreeSpaceW(
     LPCWSTR lpRootPathName,
@@ -251,6 +266,9 @@ GetDiskFreeSpaceW(
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 GetDiskFreeSpaceExA (
        LPCSTR          lpDirectoryName,
@@ -298,6 +316,9 @@ GetDiskFreeSpaceExA (
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 GetDiskFreeSpaceExW(
     LPCWSTR lpDirectoryName,
@@ -361,6 +382,9 @@ GetDiskFreeSpaceExW(
 }
 
 
+/*
+ * @implemented
+ */
 UINT STDCALL
 GetDriveTypeA(LPCSTR lpRootPathName)
 {
@@ -390,6 +414,10 @@ GetDriveTypeA(LPCSTR lpRootPathName)
        return Result;
 }
 
+
+/*
+ * @implemented
+ */
 UINT STDCALL
 GetDriveTypeW(LPCWSTR lpRootPathName)
 {
@@ -421,6 +449,9 @@ GetDriveTypeW(LPCWSTR lpRootPathName)
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 GetVolumeInformationA(
        LPCSTR  lpRootPathName,
@@ -433,102 +464,131 @@ GetVolumeInformationA(
        DWORD   nFileSystemNameSize
        )
 {
-       UNICODE_STRING RootPathNameU;
-       UNICODE_STRING FileSystemNameU;
-       UNICODE_STRING VolumeNameU;
-       ANSI_STRING RootPathName;
-       ANSI_STRING VolumeName;
-       ANSI_STRING FileSystemName;
-       WINBOOL Result;
+  UNICODE_STRING RootPathNameU;
+  UNICODE_STRING FileSystemNameU;
+  UNICODE_STRING VolumeNameU;
+  ANSI_STRING RootPathName;
+  ANSI_STRING VolumeName;
+  ANSI_STRING FileSystemName;
+  WINBOOL Result;
+
+  RtlInitAnsiString (&RootPathName,
+                    (LPSTR)lpRootPathName);
+
+  /* convert ansi (or oem) string to unicode */
+  if (bIsFileApiAnsi)
+    RtlAnsiStringToUnicodeString (&RootPathNameU,
+                                 &RootPathName,
+                                 TRUE);
+  else
+    RtlOemStringToUnicodeString (&RootPathNameU,
+                                &RootPathName,
+                                TRUE);
+
+  if (lpVolumeNameBuffer)
+    {
+      VolumeNameU.Length = 0;
+      VolumeNameU.MaximumLength = nVolumeNameSize * sizeof(WCHAR);
+      VolumeNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
+                                           0,
+                                           VolumeNameU.MaximumLength);
+    }
 
-       RtlInitAnsiString (&RootPathName,
-                          (LPSTR)lpRootPathName);
+  if (lpFileSystemNameBuffer)
+    {
+      FileSystemNameU.Length = 0;
+      FileSystemNameU.MaximumLength = nFileSystemNameSize * sizeof(WCHAR);
+      FileSystemNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
+                                               0,
+                                               FileSystemNameU.MaximumLength);
+    }
 
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&RootPathNameU,
-                                             &RootPathName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&RootPathNameU,
-                                            &RootPathName,
-                                            TRUE);
+  Result = GetVolumeInformationW (RootPathNameU.Buffer,
+                                 lpVolumeNameBuffer ? VolumeNameU.Buffer : NULL,
+                                 nVolumeNameSize,
+                                 lpVolumeSerialNumber,
+                                 lpMaximumComponentLength,
+                                 lpFileSystemFlags,
+                                 lpFileSystemNameBuffer ? FileSystemNameU.Buffer : NULL,
+                                 nFileSystemNameSize);
 
-       VolumeNameU.Length = 0;
-       VolumeNameU.MaximumLength = nVolumeNameSize * sizeof(WCHAR);
-       VolumeNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
-                                             0,
-                                             VolumeNameU.MaximumLength);
-
-       FileSystemNameU.Length = 0;
-       FileSystemNameU.MaximumLength = nFileSystemNameSize * sizeof(WCHAR);
-       FileSystemNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
-                                                 0,
-                                                 FileSystemNameU.MaximumLength);
-
-       Result = GetVolumeInformationW (RootPathNameU.Buffer,
-                                       VolumeNameU.Buffer,
-                                       nVolumeNameSize,
-                                       lpVolumeSerialNumber,
-                                       lpMaximumComponentLength,
-                                       lpFileSystemFlags,
-                                       FileSystemNameU.Buffer,
-                                       nFileSystemNameSize);
-
-       if (Result)
-       {
-                VolumeNameU.Length = wcslen(VolumeNameU.Buffer) * sizeof(WCHAR);
-               VolumeName.Length = 0;
-               VolumeName.MaximumLength = nVolumeNameSize;
-               VolumeName.Buffer = lpVolumeNameBuffer;
+  if (Result)
+    {
+      if (lpVolumeNameBuffer)
+        {
+          VolumeNameU.Length = wcslen(VolumeNameU.Buffer) * sizeof(WCHAR);
+         VolumeName.Length = 0;
+         VolumeName.MaximumLength = nVolumeNameSize;
+         VolumeName.Buffer = lpVolumeNameBuffer;
+       }
 
-                FileSystemNameU.Length = wcslen(FileSystemNameU.Buffer) * sizeof(WCHAR);
-               FileSystemName.Length = 0;
-               FileSystemName.MaximumLength = nFileSystemNameSize;
-               FileSystemName.Buffer = lpFileSystemNameBuffer;
+      if (lpFileSystemNameBuffer)
+       {
+         FileSystemNameU.Length = wcslen(FileSystemNameU.Buffer) * sizeof(WCHAR);
+         FileSystemName.Length = 0;
+         FileSystemName.MaximumLength = nFileSystemNameSize;
+         FileSystemName.Buffer = lpFileSystemNameBuffer;
+       }
 
-               /* convert unicode strings to ansi (or oem) */
-               if (bIsFileApiAnsi)
-               {
-                       RtlUnicodeStringToAnsiString (&VolumeName,
-                                                     &VolumeNameU,
-                                                     FALSE);
-                       RtlUnicodeStringToAnsiString (&FileSystemName,
-                                                     &FileSystemNameU,
-                                                     FALSE);
-               }
-               else
-               {
-                       RtlUnicodeStringToOemString (&VolumeName,
-                                                    &VolumeNameU,
-                                                    FALSE);
-                       RtlUnicodeStringToOemString (&FileSystemName,
-                                                    &FileSystemNameU,
-                                                    FALSE);
-               }
+      /* convert unicode strings to ansi (or oem) */
+      if (bIsFileApiAnsi)
+        {
+         if (lpVolumeNameBuffer)
+           {
+             RtlUnicodeStringToAnsiString (&VolumeName,
+                                           &VolumeNameU,
+                                           FALSE);
+           }
+         if (lpFileSystemNameBuffer)
+           {
+             RtlUnicodeStringToAnsiString (&FileSystemName,
+                                           &FileSystemNameU,
+                                           FALSE);
+           }
+       }
+      else
+        {
+         if (lpVolumeNameBuffer)
+           {
+             RtlUnicodeStringToOemString (&VolumeName,
+                                          &VolumeNameU,
+                                          FALSE);
+           }
+          if (lpFileSystemNameBuffer)
+           {
+             RtlUnicodeStringToOemString (&FileSystemName,
+                                          &FileSystemNameU,
+                                          FALSE);
+           }
        }
+    }
 
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    RootPathNameU.Buffer);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    VolumeNameU.Buffer);
-       RtlFreeHeap (RtlGetProcessHeap (),
-                    0,
-                    FileSystemNameU.Buffer);
+  RtlFreeHeap (RtlGetProcessHeap (),
+              0,
+              RootPathNameU.Buffer);
+  if (lpVolumeNameBuffer)
+    {
+      RtlFreeHeap (RtlGetProcessHeap (),
+                  0,
+                  VolumeNameU.Buffer);
+    }
+  if (lpFileSystemNameBuffer)
+    {
+      RtlFreeHeap (RtlGetProcessHeap (),
+                  0,
+                  FileSystemNameU.Buffer);
+    }
 
-       return Result;
+  return Result;
 }
 
+#define FS_VOLUME_BUFFER_SIZE (MAX_PATH * sizeof(WCHAR) + sizeof(FILE_FS_VOLUME_INFORMATION))
 
+#define FS_ATTRIBUTE_BUFFER_SIZE (MAX_PATH * sizeof(WCHAR) + sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
 
-
-#define FS_VOLUME_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_VOLUME_INFORMATION))
-
-#define FS_ATTRIBUTE_BUFFER_SIZE (MAX_PATH + sizeof(FILE_FS_ATTRIBUTE_INFORMATION))
-
-
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 GetVolumeInformationW(
     LPCWSTR lpRootPathName,
@@ -541,21 +601,19 @@ GetVolumeInformationW(
     DWORD nFileSystemNameSize
     )
 {
-       PFILE_FS_VOLUME_INFORMATION FileFsVolume;
-       PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute;
-       IO_STATUS_BLOCK IoStatusBlock;
-        OBJECT_ATTRIBUTES ObjectAttributes;
-       USHORT Buffer[FS_VOLUME_BUFFER_SIZE];
-       USHORT Buffer2[FS_ATTRIBUTE_BUFFER_SIZE];
-
-       HANDLE hFile;
-       NTSTATUS errCode;
+  PFILE_FS_VOLUME_INFORMATION FileFsVolume;
+  PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute;
+  IO_STATUS_BLOCK IoStatusBlock;
+  UCHAR Buffer[max(FS_VOLUME_BUFFER_SIZE, FS_ATTRIBUTE_BUFFER_SIZE)];
 
-        FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
-        FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer2;
+  HANDLE hFile;
+  NTSTATUS errCode;
+  FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
+  FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
 
-        DPRINT("FileFsVolume %p\n", FileFsVolume);
-        DPRINT("FileFsAttribute %p\n", FileFsAttribute);
+  DPRINT("FileFsVolume %p\n", FileFsVolume);
+  DPRINT("FileFsAttribute %p\n", FileFsAttribute);
 
   hFile = InternalOpenDirW(lpRootPathName, FALSE);
   if (hFile == INVALID_HANDLE_VALUE)
@@ -563,52 +621,79 @@ GetVolumeInformationW(
       return FALSE;
     }
 
-        DPRINT("hFile: %x\n", hFile);
-        errCode = NtQueryVolumeInformationFile(hFile,
-                                               &IoStatusBlock,
-                                               FileFsVolume,
-                                               FS_VOLUME_BUFFER_SIZE,
-                                               FileFsVolumeInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-                DPRINT("Status: %x\n", errCode);
-                CloseHandle(hFile);
-               SetLastErrorByStatus (errCode);
-               return FALSE;
-       }
-
-        if (lpVolumeSerialNumber)
-                *lpVolumeSerialNumber = FileFsVolume->VolumeSerialNumber;
+  DPRINT("hFile: %x\n", hFile);
+  errCode = NtQueryVolumeInformationFile(hFile,
+                                         &IoStatusBlock,
+                                         FileFsVolume,
+                                         FS_VOLUME_BUFFER_SIZE,
+                                         FileFsVolumeInformation);
+  if ( !NT_SUCCESS(errCode) ) 
+    {
+      DPRINT("Status: %x\n", errCode);
+      CloseHandle(hFile);
+      SetLastErrorByStatus (errCode);
+      return FALSE;
+    }
 
-       if (lpVolumeNameBuffer)
-               wcsncpy (lpVolumeNameBuffer,
-                        FileFsVolume->VolumeLabel,
-                        min(nVolumeNameSize,MAX_PATH));
+  if (lpVolumeSerialNumber)
+    *lpVolumeSerialNumber = FileFsVolume->VolumeSerialNumber;
 
-       errCode = NtQueryVolumeInformationFile (hFile,
-                                               &IoStatusBlock,
-                                               FileFsAttribute,
-                                               FS_ATTRIBUTE_BUFFER_SIZE,
-                                               FileFsAttributeInformation);
-       if (!NT_SUCCESS(errCode))
-       {
-               DPRINT("Status: %x\n", errCode);
-               CloseHandle(hFile);
-               SetLastErrorByStatus (errCode);
-               return FALSE;
+  if (lpVolumeNameBuffer)
+    {
+      if (nVolumeNameSize * sizeof(WCHAR) >= FileFsVolume->VolumeLabelLength + sizeof(WCHAR))
+        {
+         memcpy(lpVolumeNameBuffer, 
+                FileFsVolume->VolumeLabel, 
+                FileFsVolume->VolumeLabelLength);
+         lpVolumeNameBuffer[FileFsVolume->VolumeLabelLength / sizeof(WCHAR)] = 0;
+       }
+      else
+        {
+         CloseHandle(hFile);
+         SetLastError(ERROR_MORE_DATA);
+         return FALSE;
        }
+    }
 
-        if (lpFileSystemFlags)
-                *lpFileSystemFlags = FileFsAttribute->FileSystemAttributes;
-        if (lpMaximumComponentLength)
-                *lpMaximumComponentLength = FileFsAttribute->MaximumComponentNameLength;
-        if (lpFileSystemNameBuffer)
-                wcsncpy(lpFileSystemNameBuffer, FileFsAttribute->FileSystemName,min(nFileSystemNameSize,MAX_PATH));
+  errCode = NtQueryVolumeInformationFile (hFile,
+                                         &IoStatusBlock,
+                                         FileFsAttribute,
+                                         FS_ATTRIBUTE_BUFFER_SIZE,
+                                         FileFsAttributeInformation);
+  CloseHandle(hFile);
+  if (!NT_SUCCESS(errCode))
+    {
+      DPRINT("Status: %x\n", errCode);
+      SetLastErrorByStatus (errCode);
+      return FALSE;
+    }
 
-       CloseHandle(hFile);
-       return TRUE;
+  if (lpFileSystemFlags)
+    *lpFileSystemFlags = FileFsAttribute->FileSystemAttributes;
+  if (lpMaximumComponentLength)
+    *lpMaximumComponentLength = FileFsAttribute->MaximumComponentNameLength;
+  if (lpFileSystemNameBuffer)
+    {
+      if (nFileSystemNameSize * sizeof(WCHAR) >= FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
+        {
+         memcpy(lpFileSystemNameBuffer, 
+                FileFsAttribute->FileSystemName, 
+                FileFsAttribute->FileSystemNameLength);
+         lpFileSystemNameBuffer[FileFsAttribute->FileSystemNameLength / sizeof(WCHAR)] = 0;
+       }
+      else
+        {
+         SetLastError(ERROR_MORE_DATA);
+         return FALSE;
+       }
+    }
+  return TRUE;
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL
 STDCALL
 SetVolumeLabelA (
@@ -661,6 +746,9 @@ SetVolumeLabelA (
 }
 
 
+/*
+ * @implemented
+ */
 WINBOOL STDCALL
 SetVolumeLabelW(LPCWSTR lpRootPathName,
                LPCWSTR lpVolumeName)
@@ -677,12 +765,16 @@ SetVolumeLabelW(LPCWSTR lpRootPathName,
                               sizeof(FILE_FS_LABEL_INFORMATION) +
                               LabelLength);
    LabelInfo->VolumeLabelLength = LabelLength;
-   wcscpy(LabelInfo->VolumeLabel,
-         lpVolumeName);
+   memcpy(LabelInfo->VolumeLabel,
+         lpVolumeName,
+         LabelLength);
 
    hFile = InternalOpenDirW(lpRootPathName, TRUE);
    if (INVALID_HANDLE_VALUE == hFile)
    {
+        RtlFreeHeap(RtlGetProcessHeap(),
+                   0,
+                   LabelInfo);
         return FALSE;
    }