Figure 1 Windows 卷管理函数 (有删节)
 
函数 描述
GetLogicalDrives 返回值:表示当前可用磁盘驱动器的位掩码。0=drive A, 1=drive B, 依次类推。 如果某一位为 ON, 则有一个逻辑驱动器盘符与之对应。

 

GetLogicalDriveStrings 用系统中有效的驱动器字符串填写字符串缓冲。例如,"C:\D:\F:\" 等。每个串以NULL字符结尾,最后再以一个NULL(表空字符串)结束。
GetDriveType 确定磁盘驱动器是否为可移动的,固定的,CD-ROM,RAM驱动器,或网络驱动器。返回下列值之一:
DRIVE_UNKNOWN
DRIVE_NO_ROOT_DIR
DRIVE_REMOVABLE
DRIVE_FIXED
DRIVE_REMOTE
DRIVE_CDROM
DRIVE_RAMDISK
GetVolumeInformation 获取文件系统和卷信息。
SetVolumeLabel 设置文件系统的卷标。

Figure 2 VolumeMaster.h
////////////////////////////////////////////////////////////////
// MSDN Magazine — January 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET on Windows XP. Tab size=3.
//

// Handy class to encapsulate logical disk drive functions in Windows.
class CVolumeMaster {
public:
   // Get bitmask of logical drives—same as Windows function.
   DWORD GetLogicalDrives() {
      return ::GetLogicalDrives();
   }
   // Get drive type—same as Windows function.
   UINT GetDriveType(LPCTSTR lpPath) {
      return ::GetDriveType(lpPath);
   }
   // Get logical drive strings as array of CStrings
   int GetLogicalDriveStrings(CStringArray& ar);

   // Get volume information using CStrings instead of LPTSTR
   BOOL GetVolumeInformation(LPCTSTR drive,   // for example, 
                                              // "\\Server\Share" or 
                                              // "C:\"
      CString& volname,                       // volume name (label)
      DWORD& VolumeSerialNumber,              // volume serial number
      DWORD& MaximumComponentLength,          // maximum component len 
                                              // (name between \'s)
      DWORD& FileSystemFlags,                 // flags
      CString& filesys);                      // file system, for 
                                              // example, FAT or NTFS

   // Handy helpers to get human-readable names of things
   static CString FormatDriveType(UINT type);
   static CString FormatBitMask(DWORD bitmap, int group=5);
   static CString FormatFileSystemFlags(DWORD flags, LPCTSTR sep);
};

Figure 4 GetVolumeInformation 标志(Flags)

含义
FILE_NAMED_STREAMS 文件系统支持命名流
FILE_READ_ONLY_VOLUME 指定的卷只读(Windows 2000, Windows NT 和 Windows Me, Windows 98, or Windows 95 不支持)
FILE_SUPPORTS_OBJECT_IDS 文件系统支持对象标示符
FILE_SUPPORTS_REPARSE_POINTS 文件系统支持再解析点(reparse points)
FILE_SUPPORTS_SPARSE_FILES 文件系统支持稀疏文件
FILE_VOLUME_QUOTAS 文件系统支持磁盘卷引用(disk quotas)
FS_CASE_IS_PRESERVED 文件系统预留文件名空间,以备在磁盘上存放名字时使用
FS_CASE_SENSITIVE 文件系统支持大小写敏感文件名
FS_FILE_COMPRESSION 文件系统支持基于文件的压缩
FS_FILE_ENCRYPTION 文件系统支持加密文件系统(EFS)
FS_PERSISTENT_ACLS 文件系统预留并强制ACLs;例如,NTFS预留并强制ACLs,而FAT则没有
FS_UNICODE_STORED_ON_DISK 文件系统支持在磁盘上的文件名可使用Unicode
FS_VOL_IS_COMPRESSED 指定的卷是一个压缩卷;例如DoubleSpace 卷

Figure 5 SysMenu
////////////////////////////////////////////////////////////////
// MSDN Magazine — January 2004
// If this code works, it was written by Paul DiLascia.
// If not, I don't know who wrote it.
// Compiles with Visual Studio .NET on Windows XP. Tab size=3.
//
using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using TraceWin;

//////////////////
// This class shows how to add items to the system menu in C#/.NET
//
public class SysMenu : Form
{
   // menu flags (from WinUser.h)
   public enum MenuFlags {
      MF_INSERT = 0x00000000,
      MF_CHANGE = 0x00000080,
      MF_APPEND = 0x00000100,
      MF_DELETE = 0x00000200,
      MF_REMOVE = 0x00001000,
      MF_BYCOMMAND = 0x00000000,
      MF_BYPOSITION = 0x00000400,
      MF_SEPARATOR = 0x00000800,
      MF_ENABLED = 0x00000000,
      MF_GRAYED = 0x00000001,
      MF_DISABLED = 0x00000002,
      MF_UNCHECKED = 0x00000000,
      MF_CHECKED = 0x00000008,
      MF_USECHECKBITMAPS = 0x00000200,
      MF_STRING = 0x00000000,
      MF_BITMAP = 0x00000004,
      MF_OWNERDRAW = 0x00000100,
      MF_POPUP = 0x00000010,
      MF_MENUBARBREAK = 0x00000020,
      MF_MENUBREAK = 0x00000040,
      MF_UNHILITE = 0x00000000,
      MF_HILITE = 0x00000080,
   }

   // WM_SYSCOMAND value from WinUser.h
   const int WM_SYSCOMMAND = 0x0112;

   // Windows API fns imported 
   [DllImport("user32.dll")] 
   private static extern IntPtr GetSystemMenu(IntPtr hwnd, int bRevert); 

   [DllImport("user32.dll")] 
   private static extern bool AppendMenu(IntPtr hMenu,
      MenuFlags uFlags, uint uIDNewItem, String lpNewItem); 

   // My new command ID.
   const int IDC_MYCOMMAND = 100;

   public SysMenu()
   {
      this.Text = "Check out the system menu, dude.";
      Debug.Listeners.Add(new TraceWinListener());

      IntPtr hSysMenu = GetSystemMenu(this.Handle, 0);  // get handle to 
                                                        // system menu 
      AppendMenu(hSysMenu,MenuFlags.MF_SEPARATOR,0,null);
      AppendMenu(hSysMenu,
         MenuFlags.MF_BYCOMMAND|MenuFlags.MF_STRING|MenuFlags.MF_CHECKED,
         IDC_MYCOMMAND,
         "Do you like interop?");
   }

   [STAThread]
      static void Main() 
   {
      Application.Run(new SysMenu());
   }

   protected override void WndProc(ref Message msg)
   {
      if (msg.Msg==WM_SYSCOMMAND) {
         if(msg.WParam.ToInt32() == IDC_MYCOMMAND) {
            Trace.WriteLine("Got IDC_MYCOMMAND");
            MessageBox.Show("Yeah, baby!");
            msg.Result = IntPtr.Zero; // (not really necessary)
            return;
         } 
      }
      base.WndProc(ref msg);
   }
}